Changeset 19091


Ignore:
Timestamp:
07/28/18 19:25:27 (6 years ago)
Author:
tbretz
Message:
Added some code for profiling and explaining the query. The EXPLAIN code is still under development and not yet ready.
File:
1 edited

Legend:

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

    r19090 r19091  
    44
    55#include <boost/algorithm/string/join.hpp>
     6#include <boost/tokenizer.hpp>
     7#include <boost/algorithm/string.hpp>
    68
    79#include "tools.h"
     
    3739        ("delimiter",     var<string>(""),             "The delimiter used if contents are displayed with --display (default=\\t)")
    3840        ("explain",       po_switch(),                 "Requests an EXPLAIN from the server (shows the serveroptimized query)")
     41        ("profiling",     po_switch(),                 "Turn on profiling and print profile")
    3942        ("var.*",         var<string>(),               "Predefined SQL user variables (@VAR)")
    4043        ("env.*",         vars<string>(),              "Predefined environment for substitutions in the query ($ENV)")
     
    98101        ;
    99102    cout << endl;
     103}
     104
     105void print(string sql)
     106{
     107
     108}
     109
     110// Remove queries...
     111void format(string sql)
     112{
     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/*
     273
     274    SELECT
     275    [ALL | DISTINCT | DISTINCTROW ]
     276      [HIGH_PRIORITY]
     277      [STRAIGHT_JOIN]
     278      [SQL_SMALL_RESULT] [SQL_BIG_RESULT] [SQL_BUFFER_RESULT]
     279      [SQL_CACHE | SQL_NO_CACHE] [SQL_CALC_FOUND_ROWS]
     280    select_expr [, select_expr ...]
     281    [FROM table_references
     282      [PARTITION partition_list]
     283    [WHERE where_condition]
     284    [GROUP BY {col_name | expr | position}, ... [WITH ROLLUP]]
     285    [HAVING where_condition]
     286    [WINDOW window_name AS (window_spec)
     287        [, window_name AS (window_spec)] ...]
     288    [ORDER BY {col_name | expr | position}
     289      [ASC | DESC], ... [WITH ROLLUP]]
     290    [LIMIT {[offset,] row_count | row_count OFFSET offset}]
     291    [INTO OUTFILE 'file_name'
     292        [CHARACTER SET charset_name]
     293        export_options
     294      | INTO DUMPFILE 'file_name'
     295      | INTO var_name [, var_name]]
     296    [FOR {UPDATE | SHARE} [OF tbl_name [, tbl_name] ...] [NOWAIT | SKIP LOCKED]
     297      | LOCK IN SHARE MODE]]
     298      */
     299
     300    /*
     301table_references:
     302    escaped_table_reference [, escaped_table_reference] ...
     303
     304escaped_table_reference:
     305    table_reference
     306  | { OJ table_reference }
     307
     308table_reference:
     309    table_factor
     310  | join_table
     311
     312table_factor:
     313    tbl_name [PARTITION (partition_names)]
     314        [[AS] alias] [index_hint_list]
     315  | table_subquery [AS] alias [(col_list)]
     316  | ( table_references )
     317
     318join_table:
     319    table_reference [INNER | CROSS] JOIN table_factor [join_condition]
     320  | table_reference STRAIGHT_JOIN table_factor
     321  | table_reference STRAIGHT_JOIN table_factor ON conditional_expr
     322  | table_reference {LEFT|RIGHT} [OUTER] JOIN table_reference join_condition
     323  | table_reference NATURAL [INNER | {LEFT|RIGHT} [OUTER]] JOIN table_factor
     324
     325join_condition:
     326    ON conditional_expr
     327  | USING (column_list)
     328
     329index_hint_list:
     330    index_hint [, index_hint] ...
     331
     332index_hint:
     333    USE {INDEX|KEY}
     334      [FOR {JOIN|ORDER BY|GROUP BY}] ([index_list])
     335  | IGNORE {INDEX|KEY}
     336      [FOR {JOIN|ORDER BY|GROUP BY}] (index_list)
     337  | FORCE {INDEX|KEY}
     338      [FOR {JOIN|ORDER BY|GROUP BY}] (index_list)
     339
     340index_list:
     341    index_name [, index_name] ...
     342    */
     343
    100344}
    101345
     
    125369    const bool     nofill      = conf.Get<bool>("no-fill");
    126370    const bool     explain     = conf.Get<bool>("explain");
     371    const bool     profiling   = conf.Get<bool>("profiling");
    127372    const uint16_t verbose     = conf.Get<uint16_t>("verbose");
    128373    const uint16_t compression = conf.Get<uint16_t>("compression");
     
    222467    Database connection(uri); // Keep alive while fetching rows
    223468
     469    try
     470    {
     471        if (profiling)
     472            connection.query("SET PROFILING=1").execute();
     473    }
     474    catch (const exception &e)
     475    {
     476        cerr << "\nSET profiling=1\n\n";
     477        cerr << "SQL query failed:\n" << e.what() << endl;
     478        return 6;
     479    }
     480
    224481    // -------------------------- Set user defined variables -------------------
    225482    if (variables.size()>0)
     
    237494        catch (const exception &e)
    238495        {
    239             cerr << varset << "\n\n";
     496            cerr << '\n' << varset << "\n\n";
    240497            cerr << "SQL query failed:\n" << e.what() << endl;
    241             return 5;
     498            return 7;
    242499        }
    243500
     
    303560            cout << endl;
    304561
    305             return 0;
    306 
    307562            const mysqlpp::StoreQueryResult res2 =
    308563                connection.query("SHOW WARNINGS").store();
     
    316571                cout << row["Message"] << '\n' << endl;
    317572
     573                if (uint32_t(row["Code"])==1003)
     574                    format(row["Message"].c_str());
     575
    318576            }
    319577
     
    321579        catch (const exception &e)
    322580        {
    323             cerr << query << "\n\n";
     581            cerr << '\n' << query << "\n\n";
    324582            cerr << "SQL query failed:\n" << e.what() << endl;
    325             return 6;
     583            return 8;
    326584        }
    327585
     
    347605    TFile tfile(path, update?"UPDATE":(force?"RECREATE":"CREATE"), "Rootify SQL", compression);
    348606    if (tfile.IsZombie())
    349         return 7;
     607        return 9;
    350608
    351609    // -------------------------------------------------------------------------
     
    356614    {
    357615        cerr << "Empty set returned... nothing to write." << endl;
    358         return 8;
     616        return 10;
    359617    }
    360618
     
    540798    }
    541799
     800    if (profiling)
     801    {
     802        try
     803        {
     804            const auto resp =
     805                connection.query("SHOW PROFILE ALL").store();
     806
     807            cout << '\n';
     808            cout << left;
     809            cout << setw(20) << "Status"     << ' ';
     810            cout << right;
     811            cout << setw(11) << "Duration"   << ' ';
     812            cout << setw(11) << "CPU User"   << ' ';
     813            cout << setw(11) << "CPU System" << '\n';
     814            cout << "--------------------------------------------------------\n";
     815            for (size_t i=0; i<resp.num_rows(); i++)
     816            {
     817                const mysqlpp::Row &rowp = resp[i];
     818
     819                cout << left;
     820                cout << setw(20) << rowp["Status"] << ' ';
     821                cout << right;
     822                cout << setw(11) << rowp["Duration"] << ' ';
     823                cout << setw(11) << rowp["CPU_user"] << ' ';
     824                cout << setw(11) << rowp["CPU_system"] << '\n';
     825            }
     826            cout << "--------------------------------------------------------\n";
     827            cout << endl;
     828        }
     829        catch (const exception &e)
     830        {
     831            cerr << "\nSHOW PROFILE ALL\n\n";
     832            cerr << "SQL query failed:\n" << e.what() << endl;
     833            return 11;
     834        }
     835    }
     836
    542837    return 0;
    543838}
Note: See TracChangeset for help on using the changeset viewer.