Changeset: f585fa27f65e for MonetDB URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=f585fa27f65e Modified Files: sql/backends/monet5/rel_bin.c sql/backends/monet5/sql.c sql/server/rel_dump.c sql/server/rel_optimizer.c sql/server/rel_rel.c sql/server/rel_select.c sql/server/rel_unnest.c sql/server/rel_updates.c Branch: nospare Log Message:
merged diffs (truncated from 776 to 300 lines): diff --git a/monetdb5/modules/atoms/xml.c b/monetdb5/modules/atoms/xml.c --- a/monetdb5/modules/atoms/xml.c +++ b/monetdb5/modules/atoms/xml.c @@ -376,7 +376,7 @@ XMLparse(xml *x, str *doccont, str *val, } str -XMLpi(str *ret, str *target, str *value) +XMLpi(xml *ret, str *target, str *value) { size_t len; str buf; diff --git a/monetdb5/modules/mal/mdb.c b/monetdb5/modules/mal/mdb.c --- a/monetdb5/modules/mal/mdb.c +++ b/monetdb5/modules/mal/mdb.c @@ -735,7 +735,7 @@ static str MDBdump(Client cntxt, MalBlkP } static str -MDBdummy(int *ret) +MDBdummy(void *ret) { (void) ret; throw(MAL, "mdb.dummy", OPERATION_FAILED); 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 @@ -2563,10 +2563,8 @@ 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) { + if (!equality_only || list_length(jexps) > 1 || exp_has_func((sql_exp*)jexps->h->data)) left = subrel_project(be, left, refs, rel->l); - equality_only = 0; - } right = subrel_project(be, right, refs, rel->r); for( en = jexps->h; en; en = en->next ) { @@ -2575,8 +2573,7 @@ rel2bin_semijoin(backend *be, sql_rel *r stmt *s = NULL; /* only handle simple joins here */ - if ((exp_has_func(e) && e->flag != cmp_filter) || - e->flag == cmp_or || (e->f && e->anti)) { + 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 @@ -1358,16 +1358,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); @@ -1386,8 +1386,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/server/rel_select.c b/sql/server/rel_select.c --- a/sql/server/rel_select.c +++ b/sql/server/rel_select.c @@ -5719,22 +5719,22 @@ rel_joinquery_(sql_query *query, sql_rel } lateral = check_is_lateral(tab2); - t1 = table_ref(query, NULL, tab1, 0, NULL); + t1 = table_ref(query, NULL, tab1, 0, refs); if (rel && !t1 && sql->session->status != -ERR_AMBIGUOUS) { /* reset error */ sql->session->status = 0; sql->errstr[0] = 0; - t1 = table_ref(query, NULL, tab1, 0, NULL); + t1 = table_ref(query, NULL, tab1, 0, refs); } if (t1) { - t2 = table_ref(query, NULL, tab2, 0, NULL); + t2 = table_ref(query, NULL, tab2, 0, refs); if (lateral && !t2 && sql->session->status != -ERR_AMBIGUOUS) { /* reset error */ sql->session->status = 0; sql->errstr[0] = 0; query_push_outer(query, t1, sql_from); - t2 = table_ref(query, NULL, tab2, 0, NULL); + t2 = table_ref(query, NULL, tab2, 0, refs); t1 = query_pop_outer(query); } } @@ -5743,9 +5743,6 @@ rel_joinquery_(sql_query *query, sql_rel if (!t1 || !t2) return NULL; - if (!lateral && rel_name(t1) && rel_name(t2) && strcmp(rel_name(t1), rel_name(t2)) == 0) - return sql_error(sql, 02, SQLSTATE(42000) "SELECT: '%s' on both sides of the JOIN expression", rel_name(t1)); - inner = rel = rel_crossproduct(sql->sa, t1, t2, op_join); inner->op = op; if (lateral) @@ -5833,17 +5830,6 @@ rel_joinquery_(sql_query *query, sql_rel } if (!rel) return NULL; - if (!lateral) { /* if this relation is under a FROM clause, check for duplicate names */ - const char *rname1 = rel_name(t1), *rname2 = rel_name(t2); - if (refs) { - if (list_find(refs, (char *)rname1, (fcmp) &strcmp)) - return sql_error(sql, 02, SQLSTATE(42000) "SELECT: relation name \"%s\" specified more than once", rname1); - if (list_find(refs, (char *)rname2, (fcmp) &strcmp)) - return sql_error(sql, 02, SQLSTATE(42000) "SELECT: relation name \"%s\" specified more than once", rname2); - list_append(refs, (char *)rname1); - list_append(refs, (char *)rname2); - } - } if (inner && is_outerjoin(inner->op)) set_processed(inner); set_processed(rel); @@ -5871,28 +5857,12 @@ rel_crossquery(sql_query *query, sql_rel mvc *sql = query->sql; dnode *n = q->data.lval->h; symbol *tab1 = n->data.sym, *tab2 = n->next->data.sym; - sql_rel *t1 = table_ref(query, rel, tab1, 0, NULL), *t2 = NULL; - const char *rname1, *rname2; + sql_rel *t1 = table_ref(query, rel, tab1, 0, refs), *t2 = NULL; if (t1) - t2 = table_ref(query, rel, tab2, 0, NULL); + t2 = table_ref(query, rel, tab2, 0, refs); if (!t1 || !t2) return NULL; - - rname1 = rel_name(t1); - rname2 = rel_name(t2); - if (rname1 && rname2 && strcmp(rname1, rname2) == 0) - return sql_error(sql, 02, SQLSTATE(42000) "SELECT: '%s' on both sides of the CROSS JOIN expression", rname1); - - if (refs) { - if (list_find(refs, (char *)rname1, (fcmp) &strcmp)) - return sql_error(sql, 02, SQLSTATE(42000) "SELECT: relation name \"%s\" specified more than once", rname1); - if (list_find(refs, (char *)rname2, (fcmp) &strcmp)) - return sql_error(sql, 02, SQLSTATE(42000) "SELECT: relation name \"%s\" specified more than once", rname2); - list_append(refs, (char *)rname1); - list_append(refs, (char *)rname2); - } - return rel_crossproduct(sql->sa, t1, t2, op_join); } diff --git a/sql/test/BugTracker/Tests/ambiguous_join.SF-1580565.stable.err b/sql/test/BugTracker/Tests/ambiguous_join.SF-1580565.stable.err --- a/sql/test/BugTracker/Tests/ambiguous_join.SF-1580565.stable.err +++ b/sql/test/BugTracker/Tests/ambiguous_join.SF-1580565.stable.err @@ -12,11 +12,11 @@ stderr of test 'ambiguous_join.SF-158056 MAPI = (monetdb) /var/tmp/mtest-27483/.s.monetdb.35395 QUERY = select * from B left join B on B.id = B.id; -ERROR = !SELECT: 'b' on both sides of the JOIN expression +ERROR = !SELECT: relation name "b" specified more than once CODE = 42000 MAPI = (monetdb) /var/tmp/mtest-30274/.s.monetdb.37685 QUERY = select * from A, B left join B on B.id = A.id; -ERROR = !SELECT: 'b' on both sides of the JOIN expression +ERROR = !SELECT: relation name "b" specified more than once CODE = 42000 MAPI = (monetdb) /var/tmp/mtest-30274/.s.monetdb.37685 QUERY = select * from A, B left join B as b2 on B.id = A.id; diff --git a/sql/test/SQLancer/Tests/sqlancer02.sql b/sql/test/SQLancer/Tests/sqlancer02.sql --- a/sql/test/SQLancer/Tests/sqlancer02.sql +++ b/sql/test/SQLancer/Tests/sqlancer02.sql @@ -364,3 +364,22 @@ SELECT CAST(COUNT(*) - (SELECT cc FROM m -- 0 DROP TABLE mycount; + +START TRANSACTION; +create view v20(vc0) as (values (-214362849)); + +create view v40(vc0) as (values (false), (true)); + +create view v43(vc0) as (values (null), (true)); + +create view v54(vc0, vc1, vc2) as (values ('S12^h)y{[]', false, 9.000000000000),('0.9516513734508343', true, null)); + +create view v1(vc0) as (with cte0(c0,c1,c2) as ((select 7, 0, 2.00000000) union all +(select 5, 5.1, 4)) select '8#<Fk#]R' from v40 as l0v40, v43 as l0v43, cte0 as l0cte0); + +create view v27(vc0, vc1, vc2, vc3, vc4) as (select 1, 2, 1, 0.920, -4 from v40 as l0v40 right outer join ( +select true, case l1v54.vc0 when 'a' then -1 when 'b' then 3 end, 1 +from v54 as l1v54, v1 as l1v1 where l1v54.vc1) as sub1 on not l0v40.vc0 where l0v40.vc0); + +select 1 from v20 as l0v20, v27 as l0v27, v1 as l0v1 where (l0v20.vc0) in (-3, l0v20.vc0, l0v27.vc1); +ROLLBACK; diff --git a/sql/test/SQLancer/Tests/sqlancer02.test b/sql/test/SQLancer/Tests/sqlancer02.test --- a/sql/test/SQLancer/Tests/sqlancer02.test +++ b/sql/test/SQLancer/Tests/sqlancer02.test @@ -639,4 +639,35 @@ 0 statement ok DROP TABLE mycount +statement ok +START TRANSACTION +statement ok +create view v20(vc0) as (values (-214362849)) + +statement ok +create view v40(vc0) as (values (false), (true)) + +statement ok +create view v43(vc0) as (values (null), (true)) + +statement ok +create view v54(vc0, vc1, vc2) as (values ('S12^h)y{[]', false, 9.000000000000),('0.9516513734508343', true, null)) + +statement ok +create view v1(vc0) as (with cte0(c0,c1,c2) as ((select 7, 0, 2.00000000) union all +(select 5, 5.1, 4)) select '8#<Fk#]R' from v40 as l0v40, v43 as l0v43, cte0 as l0cte0) + +statement ok +create view v27(vc0, vc1, vc2, vc3, vc4) as (select 1, 2, 1, 0.920, -4 from v40 as l0v40 right outer join ( +select true, case l1v54.vc0 when 'a' then -1 when 'b' then 3 end, 1 +from v54 as l1v54, v1 as l1v1 where l1v54.vc1) as sub1 on not l0v40.vc0 where l0v40.vc0) + +query I rowsort +select 1 from v20 as l0v20, v27 as l0v27, v1 as l0v1 where (l0v20.vc0) in (-3, l0v20.vc0, l0v27.vc1); +---- +1 + +statement ok +ROLLBACK + diff --git a/sql/test/bugs/Tests/All b/sql/test/bugs/Tests/All --- a/sql/test/bugs/Tests/All +++ b/sql/test/bugs/Tests/All @@ -111,3 +111,4 @@ WHERE_IN_subquery_incorrect_results-JIRA select_select_bug HAVE_GEOM?filter_error in +rtrim_bug diff --git a/sql/test/bugs/Tests/rtrim_bug.sql b/sql/test/bugs/Tests/rtrim_bug.sql new file mode 100644 --- /dev/null +++ b/sql/test/bugs/Tests/rtrim_bug.sql @@ -0,0 +1,40 @@ +CREATE TABLE t1 (m varchar (1) NOT NULL); +INSERT into t1 values ('0'); +INSERT into t1 values ('2'); +SELECT * FROM sys.t1; +SELECT length("m") as data_length, "m" as data_value FROM "sys"."t1" WHERE "m" IS NOT NULL AND length("m") > 1; +-- no rows is expected + +CREATE VIEW v1 as select "m" from t1 where m in (select m from sys.t1); +SELECT * FROM v1; +SELECT length("m") as data_length, "m" as data_value FROM "sys"."v1" WHERE "m" IS NOT NULL AND length("m") > 1; +-- no rows is expected + +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(); _______________________________________________ checkin-list mailing list checkin-list@monetdb.org https://www.monetdb.org/mailman/listinfo/checkin-list