Changeset 19092
- Timestamp:
- 07/29/18 00:03:19 (6 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/FACT++/src/rootifysql.cc
r19091 r19092 103 103 } 104 104 105 struct ExplainParser 106 { 107 string sql; 108 109 vector<string> vec; 110 111 string substitute(string _str, const regex &expr) 112 { 113 smatch match; 114 while (regex_search(_str, match, expr, regex_constants::format_first_only)) 115 { 116 const auto &len = match.length(0); 117 const auto &pos = match.position(0); 118 const auto &str = match.str(0); 119 120 const auto it = find(vec.cbegin(), vec.cend(), str); 121 const size_t id = it==vec.cend() ? vec.size() : it-vec.cbegin(); 122 123 _str.replace(pos, len, "{"+to_string(id)+"}"); 124 125 if (it==vec.cend()) 126 vec.push_back(str);//.substr(1, str.size()-2)); 127 } 128 129 return _str; 130 } 131 132 string substitute(const string &str, const string &expr) 133 { 134 return substitute(str, regex(expr)); 135 } 136 137 vector<string> queries; 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 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)) 171 { 172 const auto &len = match.length(0); 173 const auto &pos = match.position(0); 174 const auto &arg = match.str(0); // Argument 175 176 const auto idx = atoi(arg.c_str()+1); 177 178 str.replace(pos, len, backsubstitute(idx, indent)); 179 } 180 181 return str; 182 } 183 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]+\\})*)?"); 188 189 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 197 198 if (!com.empty()) 199 cout << setw(indent) << ' ' << "\033[34m" << com << "\033[0m" << '\n'; 200 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) 207 { 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; 214 } 215 216 str = str.substr(match.position(0)+match.length(0)); 217 } 218 219 } 220 221 222 ExplainParser(const string &_sql) : sql(_sql) 223 { 224 // substitute all strings 225 sql = substitute(sql, "'[^']*'"); 226 227 // substitute all escaped sequences 228 sql = substitute(sql, "`[^`]*`"); 229 230 // substitute all paranthesis 231 sql = substitute(sql, "\\([^\\(\\)]*\\)"); 232 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 243 cout << endl; 244 } 245 }; 246 105 247 void print(string sql) 106 248 { … … 111 253 void format(string sql) 112 254 { 113 regex reg1("`[^`]*`"); 114 115 vector<string> vec; 116 117 cout << "[" << endl; 118 smatch match; 119 while (regex_search(sql, match, reg1, regex_constants::format_first_only)) 120 { 121 const auto &len = match.length(0); 122 const auto &pos = match.position(0); 123 const auto &str = match.str(0); 124 125 126 const auto it = find(vec.cbegin(), vec.cend(), str); 127 const size_t id = it==vec.cend() ? vec.size() : it-vec.cbegin(); 128 129 sql.replace(pos, len, "{"+to_string(id)+"}"); 130 131 if (it==vec.cend()) 132 { 133 cout << match.size() << "|"; 134 cout << id << "|" << len << "|" << pos << "|" << str << endl; 135 136 vec.push_back(str);//.substr(1, str.size()-2)); 137 } 138 } 139 140 141 cout << "]" << endl; 142 143 cout << endl << sql << endl; 144 145 146 regex reg2("\\([^\\(\\)]*\\)"); 147 148 cout << "[" << endl; 149 while (regex_search(sql, match, reg2, regex_constants::format_first_only)) 150 { 151 const auto &len = match.length(0); 152 const auto &pos = match.position(0); 153 const auto &str = match.str(0); 154 155 const auto it = find(vec.cbegin(), vec.cend(), str); 156 const size_t id = it==vec.cend() ? vec.size() : it-vec.cbegin(); 157 158 sql.replace(pos, len, "{"+to_string(id)+"}"); 159 160 if (it==vec.cend()) 161 { 162 cout << match.size() << "|"; 163 cout << id << "|" << len << "|" << pos << "|" << str << endl; 164 165 vec.push_back(str);//.substr(1, str.size()-2)); 166 } 167 } 168 169 cout << "]" << endl; 170 171 cout << endl << sql << endl; 172 173 174 regex reg3a("\\{[0-9]+\\}(\\.\\{[0-9]+\\})+"); 175 176 cout << "[" << endl; 177 while (regex_search(sql, match, reg3a, regex_constants::format_first_only)) 178 { 179 const auto &len = match.length(0); 180 const auto &pos = match.position(0); 181 const auto &str = match.str(0); 182 183 const auto it = find(vec.cbegin(), vec.cend(), str); 184 const size_t id = it==vec.cend() ? vec.size() : it-vec.cbegin(); 185 186 sql.replace(pos, len, "{"+to_string(id)+"}"); 187 188 if (it==vec.cend()) 189 { 190 cout << match.size() << "|"; 191 cout << id << "|" << len << "|" << pos << "|" << str << endl; 192 193 vec.push_back(str);//.substr(1, str.size()-2)); 194 } 195 } 196 197 cout << "]" << endl; 198 199 cout << endl << sql << endl; 200 201 202 regex reg3("\\{[0-9]+\\}+\\ AS\\ \\{[0-9]+\\}"); 203 204 cout << "[" << endl; 205 while (regex_search(sql, match, reg3, regex_constants::format_first_only)) 206 { 207 const auto &len = match.length(0); 208 const auto &pos = match.position(0); 209 const auto &str = match.str(0); 210 211 const auto it = find(vec.cbegin(), vec.cend(), str); 212 const size_t id = it==vec.cend() ? vec.size() : it-vec.cbegin(); 213 214 sql.replace(pos, len, "{"+to_string(id)+"}"); 215 216 if (it==vec.cend()) 217 { 218 cout << match.size() << "|"; 219 cout << id << "|" << len << "|" << pos << "|" << str << endl; 220 221 vec.push_back(str);//.substr(1, str.size()-2)); 222 } 223 } 224 225 cout << "]" << endl; 226 227 cout << endl << sql << endl; 228 229 regex reg4("(\\/\\*\\ [a-z]+\\#[0-9]+\\ \\*\\/)?\\ ([a-z ]+)\\ (\\{[0-9]+\\}(,\\{[0-9]+\\})*)"); 230 231 while (regex_search(sql, match, reg4)) 232 { 233 //const auto &len = match.length(0); 234 //const auto &pos = match.position(0); 235 const auto &com = match.str(1); // Comment 236 const auto &tok = match.str(2); // Token 237 const auto &arg = match.str(3); // Argument 238 239 if (!com.empty()) 240 cout << '\n' << com << '\n'; 241 242 cout << tok << '\n'; 243 //cout << " " << arg << '\n'; 244 245 vector<string> exprs; 246 boost::split(exprs, arg, boost::is_any_of(",")); 247 for (auto &expr : exprs) 248 cout << " " << expr << " | " << vec[atoi(expr.c_str()+1)] << "," << endl; 249 250 sql = sql.substr(match.position(0)+match.length(0)); 251 } 252 253 cout << endl; 254 255 256 /* 257 258 regex reg5("\\{[0-9]+\\}"); 259 260 cout << "SELECT\n"; 261 262 const string select = match.str(0); 263 264 vector<string> exprs; 265 boost::split(exprs, select, boost::is_any_of(",")); 266 for (auto &expr : exprs) 267 cout << " " << expr << " | " << vec[atoi(expr.c_str()+1)] << "," << endl; 268 } 269 270 */ 271 272 /* 255 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 COMMENT 266 TOKEN 267 expr AS expr, 268 expr AS expr, 269 expr 270 TOKEN 271 expr 272 TOKEN 273 expr AND expr 274 */ 275 276 /* 273 277 274 278 SELECT
Note:
See TracChangeset
for help on using the changeset viewer.