Changeset: 08124a306ac1 for MonetDB URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=08124a306ac1 Modified Files: sql/backends/monet5/rel_bin.c sql/server/rel_optimizer.c sql/test/bugs/Tests/rtrim_bug.sql sql/test/bugs/Tests/rtrim_bug.stable.out sql/test/miscellaneous/Tests/simple_plans.stable.out Branch: Oct2020 Log Message:
Undo my previous sqlancer fixes. Fixed regression for semijoin by disabling can_push_func on projections for now diffs (187 lines): diff --git a/sql/backends/monet5/rel_bin.c b/sql/backends/monet5/rel_bin.c --- a/sql/backends/monet5/rel_bin.c +++ b/sql/backends/monet5/rel_bin.c @@ -2516,8 +2516,6 @@ rel2bin_antijoin(backend *be, sql_rel *r return stmt_list(be, l); } -#define complex_join_expression(e) (exp_has_func(e) && (e)->flag != cmp_filter) || (e)->flag == cmp_or || ((e)->f && (e)->anti) - static stmt * rel2bin_semijoin(backend *be, sql_rel *rel, list *refs) { @@ -2562,7 +2560,7 @@ rel2bin_semijoin(backend *be, sql_rel *r int idx = 0, equality_only = 1; jexps = get_equi_joins_first(sql, jexps, &equality_only); - if (!equality_only || list_length(jexps) > 1 || complex_join_expression((sql_exp*)jexps->h->data)) + if (!equality_only || list_length(jexps) > 1 || exp_has_func((sql_exp*)jexps->h->data)) left = subrel_project(be, left, refs, rel->l); right = subrel_project(be, right, refs, rel->r); @@ -2572,7 +2570,7 @@ rel2bin_semijoin(backend *be, sql_rel *r stmt *s = NULL; /* only handle simple joins here */ - if (complex_join_expression(e)) { + if ((exp_has_func(e) && e->flag != cmp_filter) || e->flag == cmp_or || (e->f && e->anti)) { if (!join && !list_length(lje)) { stmt *l = bin_first_column(be, left); stmt *r = bin_first_column(be, right); diff --git a/sql/server/rel_optimizer.c b/sql/server/rel_optimizer.c --- a/sql/server/rel_optimizer.c +++ b/sql/server/rel_optimizer.c @@ -1350,16 +1350,16 @@ can_push_func(sql_exp *e, sql_rel *rel, { switch(e->type) { case e_cmp: { + int mustl = 0, mustr = 0, mustf = 0; sql_exp *l = e->l, *r = e->r, *f = e->f; - int res = 1, lmust = 0; - - if (e->flag == cmp_or || e->flag == cmp_in || e->flag == cmp_notin || e->flag == cmp_filter) + + if (is_project(rel->op) || e->flag == cmp_or || e->flag == cmp_in || e->flag == cmp_notin || e->flag == cmp_filter) return 0; - res = can_push_func(l, rel, &lmust) && can_push_func(r, rel, &lmust) && (!f || can_push_func(f, rel, &lmust)); - if (res && !lmust) - return 1; - (*must) |= lmust; - return res; + return ((l->type == e_column || can_push_func(l, rel, &mustl)) && (*must = mustl)) || + (!f && (r->type == e_column || can_push_func(r, rel, &mustr)) && (*must = mustr)) || + (f && + (r->type == e_column || can_push_func(r, rel, &mustr)) && + (f->type == e_column || can_push_func(f, rel, &mustf)) && (*must = (mustr || mustf))); } case e_convert: return can_push_func(e->l, rel, must); @@ -1378,8 +1378,7 @@ can_push_func(sql_exp *e, sql_rel *rel, return res; } case e_column: - /* aliases cannot be bound on the same level, ie same projection */ - if ((exp_name(e) && !has_label(e)) || (rel && !rel_find_exp(rel, e))) + if (rel && !rel_find_exp(rel, e)) return 0; (*must) = 1; /* fall through */ diff --git a/sql/test/bugs/Tests/rtrim_bug.sql b/sql/test/bugs/Tests/rtrim_bug.sql --- a/sql/test/bugs/Tests/rtrim_bug.sql +++ b/sql/test/bugs/Tests/rtrim_bug.sql @@ -12,6 +12,24 @@ SELECT length("m") as data_length, "m" a CREATE VIEW v2 as select "m" from t1 where rtrim(m) in (select rtrim(m) from sys.t1); SELECT * FROM v2; + +PLAN SELECT length("m") as data_length, "m" as data_value FROM "sys"."v2" WHERE "m" IS NOT NULL AND length("m") > 1; + +set optimizer = 'sequential_pipe'; +create procedure profiler.starttrace() external name profiler."starttrace"; +create procedure profiler.stoptrace() external name profiler.stoptrace; + +call profiler."starttrace"(); +SELECT length("m") as data_length, "m" as data_value FROM "sys"."v2" WHERE "m" IS NOT NULL AND length("m") > 1; +call profiler.stoptrace(); + +select count(*) from sys.tracelog() where stmt like '% algebra.crossproduct%'; -- don't do crossjoin +select count(*) from sys.tracelog() where stmt like '% algebra.join%'; -- do inner join + +drop procedure profiler.starttrace(); +drop procedure profiler.stoptrace(); +set optimizer = 'default_pipe'; + SELECT length("m") as data_length, "m" as data_value FROM "sys"."v2" WHERE "m" IS NOT NULL AND length("m") > 1; -- 2 rows returned !! should be 0 rows as with v1 !! -- This query produces wrong results!! diff --git a/sql/test/bugs/Tests/rtrim_bug.stable.out b/sql/test/bugs/Tests/rtrim_bug.stable.out --- a/sql/test/bugs/Tests/rtrim_bug.stable.out +++ b/sql/test/bugs/Tests/rtrim_bug.stable.out @@ -43,6 +43,48 @@ stdout of test 'rtrim_bug` in directory % 1 # length [ "0" ] [ "2" ] +#PLAN SELECT length("m") as data_length, "m" as data_value FROM "sys"."v2" WHERE "m" IS NOT NULL AND length("m") > 1; +% .plan # table_name +% rel # name +% clob # type +% 112 # length +project ( +| semijoin ( +| | project ( +| | | select ( +| | | | table("sys"."t1") [ "t1"."m" NOT NULL ] COUNT +| | | ) [ "sys"."length"("t1"."m" NOT NULL) NOT NULL > int "1" ] +| | ) [ "t1"."m" NOT NULL, "sys"."rtrim"("t1"."m" NOT NULL) NOT NULL as "%5"."%5" ], +| | project ( +| | | project ( +| | | | table("sys"."t1") [ "t1"."m" NOT NULL ] COUNT +| | | ) [ "sys"."rtrim"("t1"."m" NOT NULL) NOT NULL as "%1"."%1" ] +| | ) [ "%1"."%1" NOT NULL as "%4"."%4" ] +| ) [ "%5"."%5" NOT NULL any = "%4"."%4" NOT NULL ] +) [ "sys"."length"("t1"."m" NOT NULL as "v2"."m") NOT NULL as "data_length", "t1"."m" NOT NULL as "data_value" ] +#set optimizer = 'sequential_pipe'; +#create procedure profiler.starttrace() external name profiler."starttrace"; +#create procedure profiler.stoptrace() external name profiler.stoptrace; +#SELECT length("m") as data_length, "m" as data_value FROM "sys"."v2" WHERE "m" IS NOT NULL AND length("m") > 1; +% sys., sys. # table_name +% data_length, data_value # name +% int, varchar # type +% 1, 0 # length +#select count(*) from sys.tracelog() where stmt like '% algebra.crossproduct%'; -- don't do crossjoin +% .%2 # table_name +% %2 # name +% bigint # type +% 1 # length +[ 0 ] +#select count(*) from sys.tracelog() where stmt like '% algebra.join%'; -- do inner join +% .%2 # table_name +% %2 # name +% bigint # type +% 1 # length +[ 1 ] +#drop procedure profiler.starttrace(); +#drop procedure profiler.stoptrace(); +#set optimizer = 'default_pipe'; #SELECT length("m") as data_length, "m" as data_value FROM "sys"."v2" WHERE "m" IS NOT NULL AND length("m") > 1; % sys., sys. # table_name % data_length, data_value # name diff --git a/sql/test/miscellaneous/Tests/simple_plans.stable.out b/sql/test/miscellaneous/Tests/simple_plans.stable.out --- a/sql/test/miscellaneous/Tests/simple_plans.stable.out +++ b/sql/test/miscellaneous/Tests/simple_plans.stable.out @@ -252,23 +252,23 @@ end user.main; % clob # type % 177 # length function user.main():void; - X_1:void := querylog.define("explain select 1 from another_t t1 inner join another_t t2 on t1.col1 between t2.col1 - 1 and t2.col1 + 1;":str, "sequential_pipe":str, 27:int); - X_41:bat[:str] := bat.pack(".%1":str); - X_42:bat[:str] := bat.pack("%1":str); - X_43:bat[:str] := bat.pack("tinyint":str); - X_44:bat[:int] := bat.pack(1:int); - X_45:bat[:int] := bat.pack(0:int); + X_1:void := querylog.define("explain select 1 from another_t t1 inner join another_t t2 on t1.col1 between t2.col1 - 1 and t2.col1 + 1;":str, "sequential_pipe":str, 29:int); + X_43:bat[:str] := bat.pack(".%3":str); + X_44:bat[:str] := bat.pack("%3":str); + X_45:bat[:str] := bat.pack("tinyint":str); + X_46:bat[:int] := bat.pack(1:int); + X_47:bat[:int] := bat.pack(0:int); X_4:int := sql.mvc(); C_5:bat[:oid] := sql.tid(X_4:int, "sys":str, "another_t":str); X_8:bat[:int] := sql.bind(X_4:int, "sys":str, "another_t":str, "col1":str, 0:int); X_13:bat[:int] := algebra.projection(C_5:bat[:oid], X_8:bat[:int]); - X_15:bat[:lng] := batcalc.lng(X_13:bat[:int]); - X_19:bat[:lng] := batcalc.-(X_15:bat[:lng], 1:lng, nil:BAT); - X_24:bat[:lng] := batcalc.+(X_15:bat[:lng], 1:lng, nil:BAT); - X_26:bat[:oid] := algebra.rangejoin(X_15:bat[:lng], X_19:bat[:lng], X_24:bat[:lng], nil:BAT, nil:BAT, true:bit, true:bit, false:bit, false:bit, nil:lng); + X_14:bat[:lng] := batcalc.lng(X_13:bat[:int]); + X_17:bat[:lng] := batcalc.-(X_14:bat[:lng], 1:lng, nil:BAT); + X_22:bat[:lng] := batcalc.+(X_14:bat[:lng], 1:lng, nil:BAT); + X_26:bat[:oid] := algebra.rangejoin(X_14:bat[:lng], X_17:bat[:lng], X_22:bat[:lng], nil:BAT, nil:BAT, true:bit, true:bit, false:bit, false:bit, nil:lng); X_35:bat[:int] := algebra.projection(X_26:bat[:oid], X_13:bat[:int]); - X_39:bat[:bte] := algebra.project(X_35:bat[:int], 1:bte); - sql.resultSet(X_41:bat[:str], X_42:bat[:str], X_43:bat[:str], X_44:bat[:int], X_45:bat[:int], X_39:bat[:bte]); + X_41:bat[:bte] := algebra.project(X_35:bat[:int], 1:bte); + sql.resultSet(X_43:bat[:str], X_44:bat[:str], X_45:bat[:str], X_46:bat[:int], X_47:bat[:int], X_41:bat[:bte]); end user.main; #inline actions= 0 time=1 usec #remap actions= 2 time=106 usec _______________________________________________ checkin-list mailing list checkin-list@monetdb.org https://www.monetdb.org/mailman/listinfo/checkin-list