Index: trunk/FACT++/src/rootifysql.cc
===================================================================
--- trunk/FACT++/src/rootifysql.cc	(revision 19092)
+++ trunk/FACT++/src/rootifysql.cc	(revision 19093)
@@ -137,36 +137,12 @@
     vector<string> queries;
 
-    string backsubstitute(const size_t &_idx,const size_t &indent)
-    {
-        string str = vec[_idx];
-
-        regex reg0("\\/\\*\\ select\\#[0-9]+\\ \\*\\/\\ select\\ ");
-
+    string resub(string str, size_t indent)
+    {
+        // search for "KEYWORD expression"
+        regex reg("\\{[0-9]+\\}");
+
+        //smatch match;
         smatch match;
-        if (regex_search(str, match, reg0))
-        {
-            if (match.position(0)<2)
-            {
-                // substitute all expressions (blah AS blah)
-                str = substitute(str, "([0-9]+|\\{[0-9]+\\})\\ AS\\ \\{[0-9]+\\}");
-
-                if (str[match.position(0)-1]=='(')
-                    cout << '(' << endl;
-
-                keywords(str.substr(match.position(0)), indent+4);
-
-                if (str[match.position(0)-1]=='(')
-                    cout << setw(indent+1) << ')' << endl;
-
-                return "";//"("+to_string(_idx)+")";
-            }
-        }
-
-
-        // search for "KEYWORD expression"
-        regex reg1("\\{[0-9]+\\}");
-
-        //smatch match;
-        while (regex_search(str, match, reg1, regex_constants::format_first_only))
+        while (regex_search(str, match, reg, regex_constants::format_first_only))
         {
             const auto &len = match.length(0);
@@ -176,5 +152,5 @@
             const auto idx = atoi(arg.c_str()+1);
 
-            str.replace(pos, len, backsubstitute(idx, indent));
+            str.replace(pos, len, resub(vec[idx], indent));
         }
 
@@ -182,39 +158,95 @@
     }
 
-    void keywords(string str, const size_t &indent=0)
-    {
-        // search for "KEYWORD expression"
-        regex reg("(\\/\\*\\ [a-z]+\\#[0-9]+\\ \\*\\/)?\\ ([a-z ]+)\\ (\\{[0-9]+\\}([, ]\\{[0-9]+\\})*)?");
+    void expression(string expr, size_t indent=0)
+    {
+        if (expr[0]=='{')
+        {
+            const auto idx = atoi(expr.c_str()+1);
+
+            // This is a subquery
+            if (vec[idx].substr(0,3)=="(/*")
+            {
+                cout << setw(indent) << ' ' << "(\n";
+                find_tokens(vec[idx], indent+4);
+                cout << setw(indent) << ' ' << ") ";
+            }
+            else
+                // This is just something to substitute back
+                if (vec[idx].substr(0,2)=="({")
+                {
+                    cout << setw(indent) << ' ' << "(" << resub(vec[idx], indent+4) << ") ";
+                }
+                else
+                {
+                    if (indent>0)
+                        cout << setw(indent) << ' ';
+                    cout << vec[idx];
+                }
+        }
+        else
+        {
+            if (indent>0)
+                cout << setw(indent) << ' ';
+            cout << expr;
+        }
+    }
+
+    void find_tokens(string str, size_t indent=0)
+    {
+        //         (            COMMENT                  )?(  TOKEN   )?((  {NNN}     | NNN  )(           AS|ON           (   {NNN})   ))?(,)?)
+        //regex reg("(\\/\\*\\ select\\#[0-9]+\\ \\*\\/\\ *)?([a-zA-Z ]+)?((\\{[0-9]+\\}|[0-9]+)(\\ ?([Aa][Ss]|[Oo][Nn])\\ ?(\\{[0-9]+\\}))?(,)?)");
+
+        const string _com = "\\/\\*\\ select\\#[0-9]+\\ \\*\\/\\ *";
+
+        const string _tok = "[a-zA-Z ]+";
+
+        const string _nnn = "\\{[0-9]+\\}|[0-9]+";
+
+        const string _as  = "\\ ?([Aa][Ss])\\ ?";
+
+        //                   (  _nnn  )     (  _as  (  _nnn  ))?(,)?     // can also match noting in between two {NNN}
+        const string _exp = "("+_nnn+")" + "("+_as+"("+_nnn+"))?(,)?";
+
+        // Matche: (  _com  )?       (     (  _tok  )?   (  _exp  )      |      (  _tok  )     )
+        regex reg("("+_com+")?"  +  "(" + "("+_tok+")?"+"("+_exp+")"  + "|" +  "("+_tok+")" + ")");
 
         smatch match;
-        while (regex_search(str, match, reg))
-        {
-            //const auto &len = match.length(0);
-            //const auto &pos = match.position(0);
-            const auto &com = match.str(1);      // Comment
-            const auto &tok = match.str(2);      // Token
-            const auto &arg = match.str(3);      // Argument
+        while (regex_search(str, match, reg, regex_constants::format_first_only))
+        {
+
+            const auto &com   = match.str(1);               // comment
+            const auto &tok1  = Tools::Trim(match.str(3));  // token with expression
+            const auto &arg1  = match.str(5);               // argument 1
+            const auto &as    = match.str(7);               // as
+            const auto &arg2  = match.str(8);               // argument 2
+            const auto &comma = match.str(9);               // comma
+            const auto &tok2  = Tools::Trim(match.str(10)); // token without expression
 
             if (!com.empty())
                 cout << setw(indent) << ' ' << "\033[34m" << com << "\033[0m" << '\n';
 
-            cout << setw(indent) << ' ' << "\033[33m" << tok << "\033[0m" << '\n';
-            //cout << "   " << arg << '\n';
-
-            vector<string> exprs;
-            boost::split(exprs, arg, boost::is_any_of(", "));
-            for (auto &expr : exprs)
+            if (!tok1.empty())
+                cout << setw(indent) << ' ' << "\033[32m" << tok1 << "\033[0m" << '\n';
+            if (!tok2.empty())
+                cout << setw(indent) << ' ' << "\033[32m" << tok2 << "\033[0m" << '\n';
+
+            if (!arg1.empty())
             {
-                if (expr.empty())
-                    continue;
-
-                const auto idx = atoi(expr.c_str()+1);
-
-                cout << setw(indent+4) << ' ' << backsubstitute(idx, indent+4) << (tok=="select"?',':' ') << endl;
+                expression(arg1, indent+4);
+
+                if (!as.empty())
+                    cout << " \033[33m" << as << "\033[0m ";
+
+                if (!arg2.empty())
+                    expression(arg2);
+
+                if (!comma.empty())
+                    cout << ',';
+
+                cout << '\n';
             }
 
             str = str.substr(match.position(0)+match.length(0));
         }
-
     }
 
@@ -225,28 +257,15 @@
         sql = substitute(sql, "'[^']*'");
 
-        // substitute all escaped sequences
-        sql = substitute(sql, "`[^`]*`");
+        // substitute all escaped sequences  (`something`.`something-else`)
+        sql = substitute(sql, "`[^`]*`(\\.`[^`]*`)*");
 
         // substitute all paranthesis
         sql = substitute(sql, "\\([^\\(\\)]*\\)");
 
-        // substitute all names (xxx.yyy.zzz)
-        sql = substitute(sql, "\\{[0-9]+\\}(\\.\\{[0-9]+\\})+");
-
-        // substitute all expressions (blah AS blah)
-        sql = substitute(sql, "([0-9]+|\\{[0-9]+\\}) AS\\ \\{[0-9]+\\}");
-
-        sql = regex_replace(sql, regex("\\ on\\{"), " on {");
-
-        keywords(sql);
-
+        //cout << sql << "\n\n";
+        find_tokens(sql);
         cout << endl;
     }
 };
-
-void print(string sql)
-{
-
-}
 
 // Remove queries...
@@ -254,23 +273,4 @@
 {
     ExplainParser p(sql);
-
-    // (COMMENT)?(TOKEN\\ *|,\\ *|\\ *)?expr[ ]*
-
-    // TOKEN = [:alnum: _]
-    // expr  = {[0-9]+}
-    // Special case "expr AS expr"
-    // Special case "expr AND expr"
-
-    /*
-     COMMENT
-     TOKEN
-        expr AS expr,
-        expr AS expr,
-        expr
-     TOKEN
-        expr
-     TOKEN
-        expr AND expr
-     */
 
     /*
@@ -573,8 +573,8 @@
                 // 1003 //
                 cout << row["Level"] << '[' << row["Code"] << "]:\n";
-                cout << row["Message"] << '\n' << endl;
-
                 if (uint32_t(row["Code"])==1003)
                     format(row["Message"].c_str());
+                else
+                    cout << row["Message"] << '\n' << endl;
 
             }
