Changeset: 6013fa661bae for MonetDB URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=6013fa661bae Modified Files: gdk/gdk_batop.c gdk/gdk_bbp.c gdk/gdk_logger.c gdk/gdk_orderidx.c monetdb5/mal/mal_stack.c sql/benchmarks/tpch/LOCKED/Tests/01-22.stable.out sql/benchmarks/tpch/LOCKED/Tests/01-22.stable.out.int128 sql/benchmarks/tpch/LOCKED/Tests/02.stable.out sql/benchmarks/tpch/Tests/01-22.stable.out sql/benchmarks/tpch/Tests/01-22.stable.out.int128 sql/benchmarks/tpch/Tests/02.stable.out sql/server/rel_optimizer.c sql/server/rel_updates.c sql/storage/store.c sql/test/BugTracker-2015/Tests/crash.Bug-3736.stable.out sql/test/BugTracker-2016/Tests/storagemodel.stable.out sql/test/sql_xml/Tests/xml.reqtests Branch: protocol Log Message:
Merge with default. diffs (truncated from 593 to 300 lines): diff --git a/gdk/gdk_batop.c b/gdk/gdk_batop.c --- a/gdk/gdk_batop.c +++ b/gdk/gdk_batop.c @@ -74,8 +74,7 @@ insert_string_bat(BAT *b, BAT *n, BAT *s assert(b->ttype == TYPE_str); /* only transient bats can use some other bat's string heap */ - assert(b->batRole == TRANSIENT || - b->tvheap->parentid == abs(b->batCacheid)); + assert(b->batRole == TRANSIENT || b->tvheap->parentid == b->batCacheid); if (n->batCount == 0 || (s && s->batCount == 0)) return GDK_SUCCEED; ni = bat_iterator(n); diff --git a/gdk/gdk_logger.c b/gdk/gdk_logger.c --- a/gdk/gdk_logger.c +++ b/gdk/gdk_logger.c @@ -1297,7 +1297,7 @@ bm_subcommit(logger *lg, BAT *list_bid, name, (list_bid == catalog_bid) ? BUNtvar(iter, p) : "snapshot"); assert(BBPindex(name)); - n[i++] = abs(BBPindex(name)); + n[i++] = BBPindex(name); } } /* now commit catalog, so it's also up to date on disk */ diff --git a/gdk/gdk_orderidx.c b/gdk/gdk_orderidx.c --- a/gdk/gdk_orderidx.c +++ b/gdk/gdk_orderidx.c @@ -173,6 +173,7 @@ BATorderidx(BAT *b, int stable) oid *restrict mv; oid seq; BUN p, q; + BAT *bn = NULL; if (BATcheckorderidx(b)) return GDK_SUCCEED; @@ -195,7 +196,7 @@ BATorderidx(BAT *b, int stable) if (!BATtdense(b)) { /* we need to sort a copy of the column so as not to * change the original */ - BAT *bn = COLcopy(b, b->ttype, TRUE, TRANSIENT); + bn = COLcopy(b, b->ttype, TRUE, TRANSIENT); if (bn == NULL) { HEAPfree(m, 1); GDKfree(m); @@ -219,7 +220,11 @@ BATorderidx(BAT *b, int stable) BATcount(bn), Tsize(bn), SIZEOF_OID, bn->ttype); } - BBPunfix(bn->batCacheid); + /* we must unfix after releasing the lock since we + * might get deadlock otherwise (we're holding a lock + * based on b->batCacheid; unfix tries to get a lock + * based on bn->batCacheid, usually but (crucially) + * not always a different lock) */ } b->torderidx = m; @@ -227,6 +232,9 @@ BATorderidx(BAT *b, int stable) persistOIDX(b); MT_lock_unset(&GDKhashLock(b->batCacheid)); + if (bn) + BBPunfix(bn->batCacheid); + return GDK_SUCCEED; } @@ -514,7 +522,10 @@ OIDXdestroy(BAT *b) Heap *hp; MT_lock_set(&GDKhashLock(b->batCacheid)); - if ((hp = b->torderidx) == (Heap *) 1) { + hp = b->torderidx; + b->torderidx = NULL; + MT_lock_unset(&GDKhashLock(b->batCacheid)); + if (hp == (Heap *) 1) { GDKunlink(BBPselectfarm(b->batRole, b->ttype, orderidxheap), BATDIR, BBP_physical(b->batCacheid), @@ -523,7 +534,5 @@ OIDXdestroy(BAT *b) HEAPdelete(hp, BBP_physical(b->batCacheid), "torderidx"); GDKfree(hp); } - b->torderidx = NULL; - MT_lock_unset(&GDKhashLock(b->batCacheid)); } } diff --git a/monetdb5/mal/mal_stack.c b/monetdb5/mal/mal_stack.c --- a/monetdb5/mal/mal_stack.c +++ b/monetdb5/mal/mal_stack.c @@ -115,6 +115,10 @@ clearStack(MalStkPtr s) GDKfree(v->val.pval); v->vtype = 0; v->val.pval = NULL; + } else if (BATatoms[v->vtype].atomUnfix) { + BATatoms[v->vtype].atomUnfix(VALget(v)); + v->vtype = 0; + v->val.pval = NULL; } s->stkbot = 0; } 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 @@ -1650,7 +1650,6 @@ rel_push_count_down(int *changes, mvc *s r && !r->exps && r->op == op_join && !(rel_is_ref(r)) && ((sql_exp *) rel->exps->h->data)->type == e_aggr && strcmp(((sql_subaggr *) ((sql_exp *) rel->exps->h->data)->f)->aggr->base.name, "count") == 0) { -/* TODO check for count(*) */ sql_exp *nce, *oce; sql_rel *gbl, *gbr; /* Group By */ sql_rel *cp; /* Cross Product */ @@ -3631,97 +3630,6 @@ rel_push_aggr_down(int *changes, mvc *sq } /* - * Rewrite group(project(join(A,Dict)[a.i==dict.i])[...dict.n])[dict.n][ ... dict.n ] - * into - * project(join(groupby (A)[a.i],[a.i]), Dict)[a.i==dict.i])[dict.n] - * - */ - -static sql_rel * -rel_push_groupby_down(int *changes, mvc *sql, sql_rel *rel) -{ - sql_rel *p = rel->l, *j = rel->l; - list *gbe = rel->r; - - if (rel->op == op_groupby && gbe && p && p->op == op_project) { - sql_rel *j = p->l; - sql_rel *jl, *jr; - node *n; - - if (!j || j->op != op_join || list_length(j->exps) != 1) - return rel; - jl = j->l; - jr = j->r; - - /* check if jr is a dict with index and var still used */ - if (jr->op != op_basetable || jr->l || !jr->r || list_length(jr->exps) != 2) - return rel; - - /* check if group by is done on dict column */ - for(n = gbe->h; n; n = n->next) { - sql_exp *ge = n->data, *pe = NULL, *e = NULL; - - /* find group by exp in project, then in dict */ - pe = rel_find_exp(p, ge); - if (pe) /* find project exp in right hand of join, ie dict */ - e = rel_find_exp(jr, pe); - if (pe && e) { /* Rewrite: join with dict after the group by */ - list *pexps = rel_projections(sql, rel, NULL, 1, 1), *npexps; - node *m; - sql_exp *ne = j->exps->h->data; /* join exp */ - p->l = jl; /* Project now only on the left side of the join */ - - ne = ne->l; /* The left side of the compare is the index of the left */ - - /* find ge reference in new projection list */ - npexps = sa_list(sql->sa); - for (m = pexps->h; m; m = m->next) { - sql_exp *a = m->data; - - if (exp_refers(ge, a)) { - sql_exp *sc = jr->exps->t->data; - sql_exp *e = exp_column(sql->sa, exp_relname(sc), exp_name(sc), exp_subtype(sc), sc->card, has_nil(sc), is_intern(sc)); - exp_setname(sql->sa, e, exp_relname(a), exp_name(a)); - a = e; - } - append(npexps, a); - } - - /* find ge in aggr list */ - for (m = rel->exps->h; m; m = m->next) { - sql_exp *a = m->data; - - if (exp_match_exp(a, ge) || exp_refers(ge, a)) { - a = exp_column(sql->sa, exp_relname(ne), exp_name(ne), exp_subtype(ne), ne->card, has_nil(ne), is_intern(ne)); - exp_setname(sql->sa, a, exp_relname(ne), exp_name(ne)); - m->data = a; - } - } - - /* change alias pe, ie project out the index */ - pe->l = (void*)exp_relname(ne); - pe->r = (void*)exp_name(ne); - exp_setname(sql->sa, pe, exp_relname(ne), exp_name(ne)); - - /* change alias ge */ - ge->l = (void*)exp_relname(pe); - ge->r = (void*)exp_name(pe); - exp_setname(sql->sa, ge, exp_relname(pe), exp_name(pe)); - - /* zap both project and groupby name hash tables (as we changed names above) */ - rel->exps->ht = NULL; - ((list*)rel->r)->ht = NULL; - p->exps->ht = NULL; - - /* add join */ - j->l = rel; - rel = rel_project(sql->sa, j, npexps); - (*changes)++; - } - } - (void)sql; - } -/* * More general * groupby( * [ outer ] join( @@ -3743,6 +3651,13 @@ rel_push_groupby_down(int *changes, mvc * ) [ B.c1 ] [ a1, a2, .. ] * ) [ A.c1 = B.c1 ] */ +static sql_rel * +gen_push_groupby_down(int *changes, mvc *sql, sql_rel *rel) +{ + sql_rel *j = rel->l; + list *gbe = rel->r; + + (void)changes; if (rel->op == op_groupby && list_length(gbe) == 1 && is_outerjoin(j->op)) { sql_rel *jl = j->l, *jr = j->r, *cr; sql_exp *gb = gbe->h->data, *e; @@ -3812,6 +3727,99 @@ rel_push_groupby_down(int *changes, mvc } /* + * Rewrite group(project(join(A,Dict)[a.i==dict.i])[...dict.n])[dict.n][ ... dict.n ] + * into + * project(join(groupby (A)[a.i],[a.i]), Dict)[a.i==dict.i])[dict.n] + * + */ +static sql_rel * +rel_push_groupby_down(int *changes, mvc *sql, sql_rel *rel) +{ + sql_rel *p = rel->l; + list *gbe = rel->r; + + if (rel->op == op_groupby && gbe && p && p->op == op_project) { + sql_rel *j = p->l; + sql_rel *jl, *jr; + node *n; + + if (!j || j->op != op_join || list_length(j->exps) != 1) + return gen_push_groupby_down(changes, sql, rel); + jl = j->l; + jr = j->r; + + /* check if jr is a dict with index and var still used */ + if (jr->op != op_basetable || jr->l || !jr->r || list_length(jr->exps) != 2) + return gen_push_groupby_down(changes, sql, rel); + + /* check if group by is done on dict column */ + for(n = gbe->h; n; n = n->next) { + sql_exp *ge = n->data, *pe = NULL, *e = NULL; + + /* find group by exp in project, then in dict */ + pe = rel_find_exp(p, ge); + if (pe) /* find project exp in right hand of join, ie dict */ + e = rel_find_exp(jr, pe); + if (pe && e) { /* Rewrite: join with dict after the group by */ + list *pexps = rel_projections(sql, rel, NULL, 1, 1), *npexps; + node *m; + sql_exp *ne = j->exps->h->data; /* join exp */ + p->l = jl; /* Project now only on the left side of the join */ + + ne = ne->l; /* The left side of the compare is the index of the left */ + + /* find ge reference in new projection list */ + npexps = sa_list(sql->sa); + for (m = pexps->h; m; m = m->next) { + sql_exp *a = m->data; + + if (exp_refers(ge, a)) { + sql_exp *sc = jr->exps->t->data; + sql_exp *e = exp_column(sql->sa, exp_relname(sc), exp_name(sc), exp_subtype(sc), sc->card, has_nil(sc), is_intern(sc)); + exp_setname(sql->sa, e, exp_relname(a), exp_name(a)); + a = e; + } + append(npexps, a); + } + + /* find ge in aggr list */ + for (m = rel->exps->h; m; m = m->next) { + sql_exp *a = m->data; + + if (exp_match_exp(a, ge) || exp_refers(ge, a)) { + a = exp_column(sql->sa, exp_relname(ne), exp_name(ne), exp_subtype(ne), ne->card, has_nil(ne), is_intern(ne)); + exp_setname(sql->sa, a, exp_relname(ne), exp_name(ne)); + m->data = a; + } + } + + /* change alias pe, ie project out the index */ + pe->l = (void*)exp_relname(ne); + pe->r = (void*)exp_name(ne); + exp_setname(sql->sa, pe, exp_relname(ne), exp_name(ne)); + _______________________________________________ checkin-list mailing list checkin-list@monetdb.org https://www.monetdb.org/mailman/listinfo/checkin-list