Changeset 19092


Ignore:
Timestamp:
07/29/18 00:03:19 (6 years ago)
Author:
tbretz
Message:
Some improvemnts to the EXPLAIN formating.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/FACT++/src/rootifysql.cc

    r19091 r19092  
    103103}
    104104
     105struct 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
    105247void print(string sql)
    106248{
     
    111253void format(string sql)
    112254{
    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    /*
    273277
    274278    SELECT
Note: See TracChangeset for help on using the changeset viewer.