Changeset 19093
- Timestamp:
- 07/29/18 15:18:30 (6 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/FACT++/src/rootifysql.cc
r19092 r19093 137 137 vector<string> queries; 138 138 139 string backsubstitute(const size_t &_idx,const size_t &indent)140 { 141 string str = vec[_idx];142 143 regex reg0("\\/\\*\\ select\\#[0-9]+\\ \\*\\/\\ select\\ "); 144 139 string resub(string str, size_t indent) 140 { 141 // search for "KEYWORD expression" 142 regex reg("\\{[0-9]+\\}"); 143 144 //smatch match; 145 145 smatch match; 146 if (regex_search(str, match, reg0)) 147 { 148 if (match.position(0)<2) 149 { 150 // substitute all expressions (blah AS blah) 151 str = substitute(str, "([0-9]+|\\{[0-9]+\\})\\ AS\\ \\{[0-9]+\\}"); 152 153 if (str[match.position(0)-1]=='(') 154 cout << '(' << endl; 155 156 keywords(str.substr(match.position(0)), indent+4); 157 158 if (str[match.position(0)-1]=='(') 159 cout << setw(indent+1) << ')' << endl; 160 161 return "";//"("+to_string(_idx)+")"; 162 } 163 } 164 165 166 // search for "KEYWORD expression" 167 regex reg1("\\{[0-9]+\\}"); 168 169 //smatch match; 170 while (regex_search(str, match, reg1, regex_constants::format_first_only)) 146 while (regex_search(str, match, reg, regex_constants::format_first_only)) 171 147 { 172 148 const auto &len = match.length(0); … … 176 152 const auto idx = atoi(arg.c_str()+1); 177 153 178 str.replace(pos, len, backsubstitute(idx, indent));154 str.replace(pos, len, resub(vec[idx], indent)); 179 155 } 180 156 … … 182 158 } 183 159 184 void keywords(string str, const size_t &indent=0) 185 { 186 // search for "KEYWORD expression" 187 regex reg("(\\/\\*\\ [a-z]+\\#[0-9]+\\ \\*\\/)?\\ ([a-z ]+)\\ (\\{[0-9]+\\}([, ]\\{[0-9]+\\})*)?"); 160 void expression(string expr, size_t indent=0) 161 { 162 if (expr[0]=='{') 163 { 164 const auto idx = atoi(expr.c_str()+1); 165 166 // This is a subquery 167 if (vec[idx].substr(0,3)=="(/*") 168 { 169 cout << setw(indent) << ' ' << "(\n"; 170 find_tokens(vec[idx], indent+4); 171 cout << setw(indent) << ' ' << ") "; 172 } 173 else 174 // This is just something to substitute back 175 if (vec[idx].substr(0,2)=="({") 176 { 177 cout << setw(indent) << ' ' << "(" << resub(vec[idx], indent+4) << ") "; 178 } 179 else 180 { 181 if (indent>0) 182 cout << setw(indent) << ' '; 183 cout << vec[idx]; 184 } 185 } 186 else 187 { 188 if (indent>0) 189 cout << setw(indent) << ' '; 190 cout << expr; 191 } 192 } 193 194 void find_tokens(string str, size_t indent=0) 195 { 196 // ( COMMENT )?( TOKEN )?(( {NNN} | NNN )( AS|ON ( {NNN}) ))?(,)?) 197 //regex reg("(\\/\\*\\ select\\#[0-9]+\\ \\*\\/\\ *)?([a-zA-Z ]+)?((\\{[0-9]+\\}|[0-9]+)(\\ ?([Aa][Ss]|[Oo][Nn])\\ ?(\\{[0-9]+\\}))?(,)?)"); 198 199 const string _com = "\\/\\*\\ select\\#[0-9]+\\ \\*\\/\\ *"; 200 201 const string _tok = "[a-zA-Z ]+"; 202 203 const string _nnn = "\\{[0-9]+\\}|[0-9]+"; 204 205 const string _as = "\\ ?([Aa][Ss])\\ ?"; 206 207 // ( _nnn ) ( _as ( _nnn ))?(,)? // can also match noting in between two {NNN} 208 const string _exp = "("+_nnn+")" + "("+_as+"("+_nnn+"))?(,)?"; 209 210 // Matche: ( _com )? ( ( _tok )? ( _exp ) | ( _tok ) ) 211 regex reg("("+_com+")?" + "(" + "("+_tok+")?"+"("+_exp+")" + "|" + "("+_tok+")" + ")"); 188 212 189 213 smatch match; 190 while (regex_search(str, match, reg)) 191 { 192 //const auto &len = match.length(0); 193 //const auto &pos = match.position(0); 194 const auto &com = match.str(1); // Comment 195 const auto &tok = match.str(2); // Token 196 const auto &arg = match.str(3); // Argument 214 while (regex_search(str, match, reg, regex_constants::format_first_only)) 215 { 216 217 const auto &com = match.str(1); // comment 218 const auto &tok1 = Tools::Trim(match.str(3)); // token with expression 219 const auto &arg1 = match.str(5); // argument 1 220 const auto &as = match.str(7); // as 221 const auto &arg2 = match.str(8); // argument 2 222 const auto &comma = match.str(9); // comma 223 const auto &tok2 = Tools::Trim(match.str(10)); // token without expression 197 224 198 225 if (!com.empty()) 199 226 cout << setw(indent) << ' ' << "\033[34m" << com << "\033[0m" << '\n'; 200 227 201 cout << setw(indent) << ' ' << "\033[33m" << tok << "\033[0m" << '\n';202 //cout << " " << arg<< '\n';203 204 vector<string> exprs;205 boost::split(exprs, arg, boost::is_any_of(", ")); 206 for (auto &expr : exprs)228 if (!tok1.empty()) 229 cout << setw(indent) << ' ' << "\033[32m" << tok1 << "\033[0m" << '\n'; 230 if (!tok2.empty()) 231 cout << setw(indent) << ' ' << "\033[32m" << tok2 << "\033[0m" << '\n'; 232 233 if (!arg1.empty()) 207 234 { 208 if (expr.empty()) 209 continue; 210 211 const auto idx = atoi(expr.c_str()+1); 212 213 cout << setw(indent+4) << ' ' << backsubstitute(idx, indent+4) << (tok=="select"?',':' ') << endl; 235 expression(arg1, indent+4); 236 237 if (!as.empty()) 238 cout << " \033[33m" << as << "\033[0m "; 239 240 if (!arg2.empty()) 241 expression(arg2); 242 243 if (!comma.empty()) 244 cout << ','; 245 246 cout << '\n'; 214 247 } 215 248 216 249 str = str.substr(match.position(0)+match.length(0)); 217 250 } 218 219 251 } 220 252 … … 225 257 sql = substitute(sql, "'[^']*'"); 226 258 227 // substitute all escaped sequences 228 sql = substitute(sql, "`[^`]*` ");259 // substitute all escaped sequences (`something`.`something-else`) 260 sql = substitute(sql, "`[^`]*`(\\.`[^`]*`)*"); 229 261 230 262 // substitute all paranthesis 231 263 sql = substitute(sql, "\\([^\\(\\)]*\\)"); 232 264 233 // substitute all names (xxx.yyy.zzz) 234 sql = substitute(sql, "\\{[0-9]+\\}(\\.\\{[0-9]+\\})+"); 235 236 // substitute all expressions (blah AS blah) 237 sql = substitute(sql, "([0-9]+|\\{[0-9]+\\}) AS\\ \\{[0-9]+\\}"); 238 239 sql = regex_replace(sql, regex("\\ on\\{"), " on {"); 240 241 keywords(sql); 242 265 //cout << sql << "\n\n"; 266 find_tokens(sql); 243 267 cout << endl; 244 268 } 245 269 }; 246 247 void print(string sql)248 {249 250 }251 270 252 271 // Remove queries... … … 254 273 { 255 274 ExplainParser p(sql); 256 257 // (COMMENT)?(TOKEN\\ *|,\\ *|\\ *)?expr[ ]*258 259 // TOKEN = [:alnum: _]260 // expr = {[0-9]+}261 // Special case "expr AS expr"262 // Special case "expr AND expr"263 264 /*265 COMMENT266 TOKEN267 expr AS expr,268 expr AS expr,269 expr270 TOKEN271 expr272 TOKEN273 expr AND expr274 */275 275 276 276 /* … … 573 573 // 1003 // 574 574 cout << row["Level"] << '[' << row["Code"] << "]:\n"; 575 cout << row["Message"] << '\n' << endl;576 577 575 if (uint32_t(row["Code"])==1003) 578 576 format(row["Message"].c_str()); 577 else 578 cout << row["Message"] << '\n' << endl; 579 579 580 580 }
Note:
See TracChangeset
for help on using the changeset viewer.