Changeset: 102d34b2ff38 for MonetDB URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=102d34b2ff38 Added Files: sql/test/BugTracker-2016/Tests/innerjoin-leftjoin-or.Bug-4049.sql sql/test/BugTracker-2016/Tests/innerjoin-leftjoin-or.Bug-4049.stable.err sql/test/BugTracker-2016/Tests/innerjoin-leftjoin-or.Bug-4049.stable.out Modified Files: common/stream/stream.c monetdb5/modules/mal/tablet.c sql/common/sql_list.c sql/include/sql_list.h sql/server/rel_optimizer.c sql/server/rel_rel.c sql/server/rel_select.c sql/test/BugTracker-2015/Tests/mserver-crashes-under-specific-combination-of-JOIN-and-WHERE-conditions.Bug-3872.stable.out sql/test/BugTracker-2016/Tests/All sql/test/BugTracker-2016/Tests/memory-consumption-query-PLAN-25joins.Bug-3972.stable.out Branch: default Log Message:
Merge with Jun2016 branch. diffs (truncated from 462 to 300 lines): diff --git a/common/stream/stream.c b/common/stream/stream.c --- a/common/stream/stream.c +++ b/common/stream/stream.c @@ -1539,8 +1539,8 @@ stream_xzclose(stream *s) if (fwrite(xz->buf, 1, sz, xz->fp) != sz) s->errnr = MNSTR_WRITE_ERROR; } + fflush(xz->fp); } - fflush(xz->fp); fclose(xz->fp); lzma_end(&xz->strm); free(xz); @@ -3236,7 +3236,8 @@ ic_close(stream *s) struct icstream *ic = (struct icstream *) s->stream_data.p; if (ic) { - ic_flush(s); + if (ic->access == ST_WRITE) + ic_flush(s); iconv_close(ic->cd); mnstr_close(ic->s); mnstr_destroy(ic->s); diff --git a/monetdb5/modules/mal/tablet.c b/monetdb5/modules/mal/tablet.c --- a/monetdb5/modules/mal/tablet.c +++ b/monetdb5/modules/mal/tablet.c @@ -59,7 +59,7 @@ void_bat_create(int adt, BUN nr) /* check for correct structures */ if (b == NULL) - return b; + return NULL; BATsetaccess(b, BAT_APPEND); if (nr > BATTINY && adt && BATextend(b, nr) != GDK_SUCCEED) { BBPunfix(b->batCacheid); @@ -202,13 +202,13 @@ TABLETcreate_bats(Tablet *as, BUN est) if (fmt[i].skip) continue; fmt[i].c = void_bat_create(fmt[i].adt, est); - fmt[i].ci = bat_iterator(fmt[i].c); if (!fmt[i].c) { for (j = 0; j < i; j++) if (!fmt[i].skip) BBPdecref(fmt[j].c->batCacheid, FALSE); throw(SQL, "copy", "Failed to create bat of size " BUNFMT "\n", as->nr); } + fmt[i].ci = bat_iterator(fmt[i].c); } return MAL_SUCCEED; } diff --git a/sql/common/sql_list.c b/sql/common/sql_list.c --- a/sql/common/sql_list.c +++ b/sql/common/sql_list.c @@ -256,6 +256,15 @@ list_remove_data(list *s, void *data) } void +list_remove_list(list *l, list *data) +{ + node *n; + + for (n=data->h; n; n = n->next) + list_remove_data(l, n->data); +} + +void list_move_data(list *s, list *d, void *data) { node *n; diff --git a/sql/include/sql_list.h b/sql/include/sql_list.h --- a/sql/include/sql_list.h +++ b/sql/include/sql_list.h @@ -47,6 +47,7 @@ extern list *list_prepend(list *l, void extern node *list_remove_node(list *l, node *n); extern void list_remove_data(list *l, void *data); +extern void list_remove_list(list *l, list *data); extern void list_move_data(list *l, list *d, void *data); 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 @@ -6701,7 +6701,7 @@ rel_split_outerjoin(int *changes, mvc *s e = rel->exps->h->data; nll->exps = exps_copy(sql->sa, e->l); nlr->exps = exps_copy(sql->sa, e->r); - nl = rel_or( sql, nll, nlr, NULL, e->l, e->r); + nl = rel_or( sql, nll, nlr, NULL, NULL, NULL); if (rel->op == op_full) { l = rel_dup(l); @@ -7928,6 +7928,7 @@ static sql_rel * if (level <= 0) rel = rewrite_topdown(sql, rel, &rel_semijoin_use_fk, &changes); } + if (gp.cnt[op_left] || gp.cnt[op_right] || gp.cnt[op_full]) rel = rewrite_topdown(sql, rel, &rel_split_outerjoin, &changes); diff --git a/sql/server/rel_rel.c b/sql/server/rel_rel.c --- a/sql/server/rel_rel.c +++ b/sql/server/rel_rel.c @@ -1054,34 +1054,41 @@ rel_or(mvc *sql, sql_rel *l, sql_rel *r, { sql_rel *rel, *ll = l->l, *rl = r->l; - if (l == r && is_outerjoin(l->op)) { /* merge both lists */ + assert(!lexps || l == r); + if (l == r && lexps) { /* merge both lists */ sql_exp *e = exp_or(sql->sa, lexps, rexps); list *nl = oexps?oexps:new_exp_list(sql->sa); rel_destroy(r); append(nl, e); + if (is_outerjoin(l->op) && is_processed(l)) + l = rel_select(sql->sa, l, NULL); l->exps = nl; return l; } - if (l->op == r->op && - ((ll == rl && l->r == r->r && l->r == NULL /* or check if columns are equal*/) || - - (exps_card(l->exps) == exps_card(r->exps) && exps_card(l->exps) <= CARD_ATOM))) { + /* favor or expressions over union */ + if (l->op == r->op && l->op == op_select && + ll == rl && !rel_is_ref(l) && !rel_is_ref(r)) { sql_exp *e = exp_or(sql->sa, l->exps, r->exps); list *nl = new_exp_list(sql->sa); rel_destroy(r); append(nl, e); l->exps = nl; - if (ll->op == l->op) { - list_merge(ll->exps,l->exps, (fdup)NULL); - l->l = NULL; - rel_destroy(l); - return ll; + + /* merge and expressions */ + ll = l->l; + while (ll && ll->op == op_select && !rel_is_ref(ll)) { + list_merge(l->exps, ll->exps, (fdup)NULL); + l->l = ll->l; + ll->l = NULL; + rel_destroy(ll); + ll = l->l; } return l; } + l = rel_project(sql->sa, l, rel_projections(sql, l, NULL, 1, 1)); r = rel_project(sql->sa, r, rel_projections(sql, r, NULL, 1, 1)); set_processed(l); 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 @@ -1502,7 +1502,7 @@ rel_filter(mvc *sql, sql_rel *rel, list /* push select into the given relation */ return rel_push_select(sql, rel, L, e); } else { /* join */ - if (is_semi(rel->op) || is_outerjoin(rel->op)) { + if (is_semi(rel->op) || (is_outerjoin(rel->op) && !is_processed(rel))) { rel_join_add_exp(sql->sa, rel, e); return rel; } @@ -2263,7 +2263,7 @@ rel_logical_exp(mvc *sql, sql_rel *rel, lr = rel; rr = rel_dup(lr); - if (is_outerjoin(rel->op)) { + if (is_outerjoin(rel->op) && !is_processed(rel)) { int pushdown = sql->pushdown; exps = rel->exps; diff --git a/sql/test/BugTracker-2016/Tests/All b/sql/test/BugTracker-2016/Tests/All --- a/sql/test/BugTracker-2016/Tests/All +++ b/sql/test/BugTracker-2016/Tests/All @@ -41,3 +41,4 @@ boolean-evaluation.Bug-4025 HAVE_GEOM?nested-mal-with-multiplex.Bug-4035 querylog trigger_bulk.Bug-4045 +innerjoin-leftjoin-or.Bug-4049 diff --git a/sql/test/BugTracker-2016/Tests/innerjoin-leftjoin-or.Bug-4049.sql b/sql/test/BugTracker-2016/Tests/innerjoin-leftjoin-or.Bug-4049.sql new file mode 100644 --- /dev/null +++ b/sql/test/BugTracker-2016/Tests/innerjoin-leftjoin-or.Bug-4049.sql @@ -0,0 +1,59 @@ +start transaction; + +create table test1 (a int, b int, d int); +create table test_dic1 (a int, c int); +insert into test_dic1 values (1, 1), (1, 2); +insert into test1 values (1, 2, 1), (1, 3, 2), (2, 2, 1), (2, 3, 2); + +select dd.* + from test_dic1 as dd +inner join test1 as d1 on d1.a = dd.a and d1.d = 1 + left join test1 as d2 on d2.a = dd.a and d2.d = 2 +where dd.c = 1; +-- Get 1 row as expected + +select dd.* + from test_dic1 as dd +inner join test1 as d1 on d1.a = dd.a and d1.d = 1 + left join test1 as d2 on d2.a = dd.a and d2.d = 2 +where dd.c = 1 + or dd.c = 3; +-- should get 1 row instead of 2 rows + +select * + from test_dic1 as dd +inner join test1 as d1 on d1.a = dd.a and d1.d = 1 + left join test1 as d2 on d2.a = dd.a and d2.d = 2 +where dd.c = 1 + or dd.c = 3; +-- shows 2 rows instead of 1 + +select * + from test_dic1 as dd +inner join test1 as d1 on d1.a = dd.a and d1.d = 1 + left join test1 as d2 on d2.a = dd.a and d2.d = 2 +where dd.c in (1, 3); +-- shows 1 row correctly + +select * + from test_dic1 as dd +inner join test1 as d1 on d1.a = dd.a + left join test1 as d2 on d2.a = dd.a and d2.d = 2 +where dd.c = 1 + or dd.c = 3 + and d1.d = 1 + and (((dd.c = 1 or dd.c = 3) and d2.d is null) or ((dd.c = 1 or dd.c = 3) and d2.d = 2)); +-- shows 4 rows instead of 2 + +select * + from test_dic1 as dd +inner join test1 as d1 on d1.a = dd.a and d1.d = 1 +inner join test1 as d2 on d2.a = dd.a and d2.d = 2 +where dd.c = 1 + or dd.c = 3; +-- shows 1 row correctly + +drop table test1; +drop table test_dic1; + +rollback; diff --git a/sql/test/BugTracker-2016/Tests/innerjoin-leftjoin-or.Bug-4049.stable.err b/sql/test/BugTracker-2016/Tests/innerjoin-leftjoin-or.Bug-4049.stable.err new file mode 100644 --- /dev/null +++ b/sql/test/BugTracker-2016/Tests/innerjoin-leftjoin-or.Bug-4049.stable.err @@ -0,0 +1,37 @@ +stderr of test 'innerjoin-leftjoin-or.Bug-4049` in directory 'sql/test/BugTracker-2016` itself: + + +# 12:30:58 > +# 12:30:58 > "mserver5" "--debug=10" "--set" "gdk_nr_threads=0" "--set" "mapi_open=true" "--set" "mapi_port=37683" "--set" "mapi_usock=/var/tmp/mtest-32537/.s.monetdb.37683" "--set" "monet_prompt=" "--forcemito" "--dbpath=/export/scratch2/dinther/INSTALL/var/MonetDB/mTests_sql_test_BugTracker-2016" "--set" "embedded_r=yes" "--set" "embedded_py=true" +# 12:30:58 > + +# builtin opt gdk_dbpath = /export/scratch2/dinther/INSTALL/var/monetdb5/dbfarm/demo +# builtin opt gdk_debug = 0 +# builtin opt gdk_vmtrim = no +# builtin opt monet_prompt = > +# builtin opt monet_daemon = no +# builtin opt mapi_port = 50000 +# builtin opt mapi_open = false +# builtin opt mapi_autosense = false +# builtin opt sql_optimizer = default_pipe +# builtin opt sql_debug = 0 +# cmdline opt gdk_nr_threads = 0 +# cmdline opt mapi_open = true +# cmdline opt mapi_port = 37683 +# cmdline opt mapi_usock = /var/tmp/mtest-32537/.s.monetdb.37683 +# cmdline opt monet_prompt = +# cmdline opt gdk_dbpath = /export/scratch2/dinther/INSTALL/var/MonetDB/mTests_sql_test_BugTracker-2016 +# cmdline opt embedded_r = yes +# cmdline opt embedded_py = true +# cmdline opt gdk_debug = 536870922 + +# 12:30:59 > +# 12:30:59 > "mclient" "-lsql" "-ftest" "-Eutf-8" "-i" "-e" "--host=/var/tmp/mtest-32537" "--port=37683" +# 12:30:59 > + + + +# 12:30:59 > +# 12:30:59 > "Done." +# 12:30:59 > + diff --git a/sql/test/BugTracker-2016/Tests/innerjoin-leftjoin-or.Bug-4049.stable.out b/sql/test/BugTracker-2016/Tests/innerjoin-leftjoin-or.Bug-4049.stable.out new file mode 100644 --- /dev/null +++ b/sql/test/BugTracker-2016/Tests/innerjoin-leftjoin-or.Bug-4049.stable.out @@ -0,0 +1,148 @@ +stdout of test 'innerjoin-leftjoin-or.Bug-4049` in directory 'sql/test/BugTracker-2016` itself: + + +# 12:30:58 > +# 12:30:58 > "mserver5" "--debug=10" "--set" "gdk_nr_threads=0" "--set" "mapi_open=true" "--set" "mapi_port=37683" "--set" "mapi_usock=/var/tmp/mtest-32537/.s.monetdb.37683" "--set" "monet_prompt=" "--forcemito" "--dbpath=/export/scratch2/dinther/INSTALL/var/MonetDB/mTests_sql_test_BugTracker-2016" "--set" "embedded_r=yes" "--set" "embedded_py=true" _______________________________________________ checkin-list mailing list checkin-list@monetdb.org https://www.monetdb.org/mailman/listinfo/checkin-list