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
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list