Changeset: 371c5b74dbb1 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/371c5b74dbb1
Modified Files:
        sql/server/rel_dump.c
        sql/test/BugTracker-2013/Tests/rangejoin_optimizer.Bug-3411.test
        sql/test/BugTracker-2015/Tests/crash.Bug-3736.test
        sql/test/BugTracker-2015/Tests/large_join.Bug-3809.test
        
sql/test/BugTracker-2016/Tests/memory-consumption-query-PLAN-25joins.Bug-3972.test
        sql/test/BugTracker-2016/Tests/merge_project.Bug-3955.test
        sql/test/BugTracker-2017/Tests/caching_stats_bug.6374.test
        
sql/test/BugTracker-2017/Tests/sqlitelogictest-aggregation-having-avg.Bug-6428.test
        
sql/test/BugTracker-2018/Tests/count_from_commented_function_signatures.Bug-6542.test
        sql/test/BugTracker-2021/Tests/plan-not-optimal-view.Bug-7140.test
        sql/test/BugTracker/Tests/jdbc_no_debug.SF-1739356.test
        
sql/test/FeatureRequests/Tests/foreign_key_outer_join_dead_code_elimination-plan-1join-query.test
        
sql/test/FeatureRequests/Tests/foreign_key_outer_join_dead_code_elimination-plan-1join-view.test
        
sql/test/FeatureRequests/Tests/foreign_key_outer_join_dead_code_elimination-plan-2join-query.test
        
sql/test/FeatureRequests/Tests/foreign_key_outer_join_dead_code_elimination-plan-2join-view.test
        sql/test/SQLancer/Tests/sqlancer17.test
        sql/test/SQLancer/Tests/sqlancer19.SQL.py
        sql/test/SQLancer/Tests/sqlancer20.SQL.py
        sql/test/astro/Tests/astro.test
        sql/test/bugs/Tests/rtrim_bug.test
        sql/test/merge-partitions/Tests/mergepart31.test
        sql/test/mergetables/Tests/mergequery.test
        sql/test/mergetables/Tests/part-elim.test
        sql/test/miscellaneous/Tests/groupby_error.test
        sql/test/miscellaneous/Tests/simple_plans.test
        sql/test/out2in/Tests/out2in.test
Branch: default
Log Message:

Improve dump of comparison expressions. Addd '(' delimiter, so nested 
comparisons get parsed without ambiguity and add schema of filter function 
used. Approved output


diffs (truncated from 2561 to 300 lines):

diff --git a/sql/server/rel_dump.c b/sql/server/rel_dump.c
--- a/sql/server/rel_dump.c
+++ b/sql/server/rel_dump.c
@@ -241,7 +241,9 @@ exp_print(mvc *sql, stream *fout, sql_ex
                break;
        case e_cmp:
                if (e->flag == cmp_in || e->flag == cmp_notin) {
-                       exp_print(sql, fout, e->l, depth, refs, 0, 0);
+                       mnstr_printf(fout, "(");
+                       exp_print(sql, fout, e->l, depth+1, refs, 0, 0);
+                       mnstr_printf(fout, ")");
                        if (is_anti(e))
                                mnstr_printf(fout, " !");
                        cmp_print(sql, fout, e->flag);
@@ -258,30 +260,41 @@ exp_print(mvc *sql, stream *fout, sql_ex
                        exps_print(sql, fout, e->l, depth, refs, 0, 1);
                        if (is_anti(e))
                                mnstr_printf(fout, " !");
-                       mnstr_printf(fout, " FILTER \"%s\" ", 
dump_escape_ident(sql->ta, f->func->base.name));
+                       mnstr_printf(fout, " FILTER \"%s\".\"%s\"",
+                                       f->func->s?dump_escape_ident(sql->ta, 
f->func->s->base.name):"sys",
+                                       dump_escape_ident(sql->ta, 
f->func->base.name));
                        exps_print(sql, fout, e->r, depth, refs, 0, 1);
                } else if (e->f) {
+                       mnstr_printf(fout, "(");
                        exp_print(sql, fout, e->r, depth+1, refs, 0, 0);
+                       mnstr_printf(fout, ")");
                        if (is_anti(e))
                                mnstr_printf(fout, " !");
-                       cmp_print(sql, fout, 
swap_compare(range2lcompare(e->flag)) );
+                       cmp_print(sql, fout, 
swap_compare(range2lcompare(e->flag)));
+                       mnstr_printf(fout, "(");
                        exp_print(sql, fout, e->l, depth+1, refs, 0, 0);
+                       mnstr_printf(fout, ")");
                        if (is_anti(e))
                                mnstr_printf(fout, " !");
-                       cmp_print(sql, fout, range2rcompare(e->flag) );
+                       cmp_print(sql, fout, range2rcompare(e->flag));
+                       mnstr_printf(fout, "(");
                        exp_print(sql, fout, e->f, depth+1, refs, 0, 0);
-                       mnstr_printf(fout, " BETWEEN ");
+                       mnstr_printf(fout, ")");
                        if (is_symmetric(e))
-                               mnstr_printf(fout, " SYM ");
+                               mnstr_printf(fout, " SYM");
                } else {
+                       mnstr_printf(fout, "(");
                        exp_print(sql, fout, e->l, depth+1, refs, 0, 0);
+                       mnstr_printf(fout, ")");
                        if (is_anti(e))
                                mnstr_printf(fout, " !");
                        if (is_semantics(e))
                                mnstr_printf(fout, " *");
                        cmp_print(sql, fout, e->flag);
 
+                       mnstr_printf(fout, "(");
                        exp_print(sql, fout, e->r, depth+1, refs, 0, 0);
+                       mnstr_printf(fout, ")");
                }
                break;
        default:
@@ -293,10 +306,6 @@ exp_print(mvc *sql, stream *fout, sql_ex
                mnstr_printf(fout, " NULLS LAST");
        if (e->type != e_atom && e->type != e_cmp && !has_nil(e))
                mnstr_printf(fout, " NOT NULL");
-       /*
-       if (is_basecol(e))
-               mnstr_printf(fout, " BASECOL");
-               */
        if (e->p) {
                prop *p = e->p;
                char *pv;
@@ -802,7 +811,7 @@ readString( char *r, int *pos)
        return st;
 }
 
-static sql_exp* exp_read(mvc *sql, sql_rel *lrel, sql_rel *rrel, list 
*top_exps, char *r, int *pos, int grp, int in_cmp);
+static sql_exp* exp_read(mvc *sql, sql_rel *lrel, sql_rel *rrel, list 
*top_exps, char *r, int *pos, int grp);
 
 static sql_exp*
 read_prop(mvc *sql, sql_exp *exp, char *r, int *pos, bool *found)
@@ -863,7 +872,7 @@ read_exps(mvc *sql, sql_rel *lrel, sql_r
 
                (*pos)++;
                skipWS( r, pos);
-               e = exp_read(sql, lrel, rrel, top ? exps : top_exps, r, pos, 
grp, 0);
+               e = exp_read(sql, lrel, rrel, top ? exps : top_exps, r, pos, 
grp);
                if (!e && r[*pos] != ebracket) {
                        return sql_error(sql, -1, SQLSTATE(42000) "Missing 
closing %c\n", ebracket);
                } else if (!e) {
@@ -879,7 +888,7 @@ read_exps(mvc *sql, sql_rel *lrel, sql_r
 
                        (*pos)++;
                        skipWS( r, pos);
-                       e = exp_read(sql, lrel, rrel, top ? exps : top_exps, r, 
pos, grp, 0);
+                       e = exp_read(sql, lrel, rrel, top ? exps : top_exps, r, 
pos, grp);
                        if (!e)
                                return NULL;
                        append(exps, e);
@@ -999,9 +1008,9 @@ function_error_string(mvc *sql, const ch
 }
 
 static sql_exp*
-exp_read(mvc *sql, sql_rel *lrel, sql_rel *rrel, list *top_exps, char *r, int 
*pos, int grp, int in_cmp)
+exp_read(mvc *sql, sql_rel *lrel, sql_rel *rrel, list *top_exps, char *r, int 
*pos, int grp)
 {
-       int f = -1, old, d=0, s=0, unique = 0, no_nils = 0, quote = 0, 
zero_if_empty = 0, sem = 0, anti = 0;
+       int old, d=0, s=0, unique = 0, no_nils = 0, quote = 0, zero_if_empty = 
0;
        char *tname = NULL, *cname = NULL, *var_cname = NULL, *e, *b = r + *pos;
        sql_exp *exp = NULL;
        list *exps = NULL;
@@ -1052,10 +1061,11 @@ exp_read(mvc *sql, sql_rel *lrel, sql_re
                break;
        /* atom */
        case '(':
-               if (b == (r+*pos)) { /* or */
-                       int filter = 0, anti = 0;
-                       list *lexps,*rexps;
-                       char *fname = NULL;
+               if (b == (r+*pos)) { /* comparison expression */
+                       int anti = 0, sym = 0, semantics = 0;
+                       comp_type ctype = cmp_all, ctype2 = cmp_all;
+                       list *lexps = NULL, *rexps = NULL, *fexps = NULL;
+                       char *sname = NULL, *fname = NULL;
 
                        if (!(lexps = read_exps(sql, lrel, rrel, top_exps, r, 
pos, '(', 0, 0)))
                                return NULL;
@@ -1065,48 +1075,182 @@ exp_read(mvc *sql, sql_rel *lrel, sql_re
                                (*pos)++;
                                skipWS(r, pos);
                        }
-                       if (strncmp(r+*pos, "or",  strlen("or")) == 0) {
-                               (*pos)+= (int) strlen("or");
-                       } else if (strncasecmp(r+*pos, "FILTER",  
strlen("FILTER")) == 0) {
-                               (*pos)+= (int) strlen("FILTER");
-                               filter = 1;
-                       } else {
-                               return sql_error(sql, -1, SQLSTATE(42000) 
"Type: missing 'or'\n");
-                       }
-                       skipWS(r, pos);
-                       if (filter) {
-                               fname = r+*pos + 1;
-
-                               skipIdent(r,pos);
-                               convertIdent(fname);
+                       if (r[*pos] == '*') {
+                               semantics = 1;
                                (*pos)++;
-                               skipWS(r,pos);
+                               skipWS(r, pos);
                        }
 
+                       switch(r[*pos]) {
+                       case 'a':
+                               if (strncmp(r+*pos, "any =",  strlen("any =")) 
== 0) {
+                                       (*pos)+= (int) strlen("any =");
+                                       ctype = mark_in;
+                               } else if (strncmp(r+*pos, "all <>",  
strlen("all <>")) == 0) {
+                                       (*pos)+= (int) strlen("all <>");
+                                       ctype = mark_notin;
+                               }
+                               break;
+                       case 'n':
+                               if (strncmp(r+*pos, "notin",  strlen("notin")) 
== 0) {
+                                       (*pos)+= (int) strlen("notin");
+                                       ctype = cmp_notin;
+                               }
+                               break;
+                       case 'F':
+                               if (strncmp(r+*pos, "FILTER",  
strlen("FILTER")) == 0) {
+                                       (*pos)+= (int) strlen("FILTER");
+                                       ctype = cmp_filter;
+                                       skipWS(r, pos);
+                                       sname = r+*pos + 1;
+                                       skipIdent(r, pos);
+                                       convertIdent(sname);
+                                       (*pos)+=2;
+                                       fname = r+*pos + 1;
+                                       skipIdent(r, pos);
+                                       convertIdent(fname);
+                                       (*pos)++;
+                               }
+                               break;
+                       case 'i':
+                               if (strncmp(r+*pos, "in",  strlen("in")) == 0) {
+                                       (*pos)+= (int) strlen("in");
+                                       ctype = cmp_in;
+                               }
+                               break;
+                       case 'o':
+                               if (strncmp(r+*pos, "or",  strlen("or")) == 0) {
+                                       (*pos)+= (int) strlen("or");
+                                       ctype = cmp_or;
+                               }
+                               break;
+                       case '!':
+                               ctype = cmp_notequal;
+                               (*pos)++;
+                               if (r[(*pos)] == '=')
+                                       (*pos)++;
+                               break;
+                       case '=':
+                               ctype = cmp_equal;
+                               (*pos)++;
+                               break;
+                       case '<':
+                               ctype = cmp_lt;
+                               (*pos)++;
+                               if (r[(*pos)] == '=') {
+                                       ctype = cmp_lte;
+                                       (*pos)++;
+                               }
+                               break;
+                       case '>':
+                               ctype = cmp_gt;
+                               (*pos)++;
+                               if (r[(*pos)] == '=') {
+                                       ctype = cmp_gte;
+                                       (*pos)++;
+                               }
+                               break;
+                       default:
+                               return sql_error(sql, -1, SQLSTATE(42000) 
"Type: missing comparison type\n");
+                       }
+
+                       skipWS(r, pos);
                        if (!(rexps = read_exps(sql, lrel, rrel, top_exps, r, 
pos, '(', 0, 0)))
                                return NULL;
-                       if (filter) {
-                               sql_subfunc *f = NULL;
-                               list *tl = sa_list(sql->sa);
-
-                               for (node *n = lexps->h; n; n = n->next){
-                                       sql_exp *e = n->data;
+                       skipWS(r, pos);
 
-                                       list_append(tl, exp_subtype(e));
-                               }
-                               for (node *n = rexps->h; n; n = n->next){
-                                       sql_exp *e = n->data;
-
-                                       list_append(tl, exp_subtype(e));
-                               }
+                       switch (ctype) {
+                               case cmp_gt:
+                               case cmp_gte:
+                               case cmp_lte:
+                               case cmp_lt:
+                               case cmp_equal:
+                               case cmp_notequal:
+                               case mark_in:
+                               case mark_notin:
+                                       if (r[*pos] == '!' || r[*pos] == '<' || 
r[*pos] == '>') { /* BETWEEN case */
+                                               if (r[*pos] == '!') { /* ignore 
next anti */
+                                                       (*pos)++;
+                                                       skipWS(r, pos);
+                                               }
+                                               switch(r[*pos]) {
+                                               case '<':
+                                                       ctype2 = cmp_lt;
+                                                       (*pos)++;
+                                                       if (r[(*pos)] == '=') {
+                                                               ctype2 = 
cmp_lte;
+                                                               (*pos)++;
+                                                       }
+                                                       break;
+                                               case '>':
+                                                       ctype2 = cmp_gt;
+                                                       (*pos)++;
+                                                       if (r[(*pos)] == '=') {
+                                                               ctype2 = 
cmp_gte;
+                                                               (*pos)++;
+                                                       }
+                                                       break;
+                                               default:
+                                                       return sql_error(sql, 
-1, SQLSTATE(42000) "Type: missing comparison type\n");
+                                               }
+                                               skipWS(r, pos);
+                                               if (!(fexps = read_exps(sql, 
lrel, rrel, top_exps, r, pos, '(', 0, 0)))
+                                                       return NULL;
+                                               skipWS(r, pos);
+                                               if (strncmp(r+*pos, "SYM",  
strlen("SYM")) == 0) {
+                                                       (*pos)+= (int) 
strlen("SYM");
+                                                       skipWS(r, pos);
+                                                       sym = 1;
+                                               }
+                                               exp = exp_compare2(sql->sa, 
rexps->h->data, lexps->h->data, fexps->h->data, 
compare2range(swap_compare(ctype), ctype2), sym);
+                                       } else {
+                                               exp = exp_compare(sql->sa, 
lexps->h->data, rexps->h->data, ctype);
+                                               if (semantics)
+                                                       set_semantics(exp);
+                                       }
+                                       if (anti)
+                                               set_anti(exp);
+                                       assert(list_length(lexps) == 1 && 
list_length(rexps) == 1 && (!fexps || list_length(fexps) == 1));
+                                       break;
+                               case cmp_in:
+                               case cmp_notin:
+                                       assert(list_length(lexps) == 1);
+                                       exp = exp_in(sql->sa, lexps->h->data, 
rexps, ctype);
_______________________________________________
checkin-list mailing list
checkin-list@monetdb.org
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to