Changeset: a4fc114bb5f7 for MonetDB URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=a4fc114bb5f7 Modified Files: monetdb5/mal/mal_authorize.c sql/backends/monet5/rel_bin.c sql/server/rel_exp.c sql/server/rel_optimizer.c sql/server/sql_atom.c tools/mserver/mserver5.c Branch: default Log Message:
Merged with Oct2020 diffs (truncated from 419 to 300 lines): diff --git a/monetdb5/optimizer/opt_pushselect.c b/monetdb5/optimizer/opt_pushselect.c --- a/monetdb5/optimizer/opt_pushselect.c +++ b/monetdb5/optimizer/opt_pushselect.c @@ -132,6 +132,8 @@ no_updates(InstrPtr *old, int *vars, int return 1; } +#define isIntersect(p) (getModuleId(p) == algebraRef && getFunctionId(p) == intersectRef) + str OPTpushselectImplementation(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci) { @@ -169,7 +171,7 @@ OPTpushselectImplementation(Client cntxt } if (getModuleId(p) == algebraRef && - (getFunctionId(p) == intersectRef || + ((!no_mito && getFunctionId(p) == intersectRef) || getFunctionId(p) == differenceRef)) { GDKfree(vars); goto wrapup; @@ -181,6 +183,9 @@ OPTpushselectImplementation(Client cntxt if (isLikeOp(p)) nr_likes++; + if (no_mito && isIntersect(p)) + push_down_delta++; + if ((getModuleId(p) == sqlRef && getFunctionId(p) == deltaRef) || (no_mito && getModuleId(p) == matRef && getFunctionId(p) == packRef && p->argc == (p->retc+2))) push_down_delta++; @@ -804,6 +809,74 @@ OPTpushselectImplementation(Client cntxt oclean[i] = 1; actions++; } + } else if (isIntersect(p) && p->retc == 1 && lastbat == 4) { + /* c = delta(b, uid, uvl, ins) + * s = intersect(l, r, li, ..) + * + * nc = intersect(b, r, li..) + * ni = intersect(ins, r, li..) + * nu = intersect(uvl, r, ..) + * s = subdelta(nc, uid, nu, ni); + */ + int var = getArg(p, 1); + InstrPtr q = old[vars[var]]; + + if (q && q->token == ASSIGNsymbol) { + var = getArg(q, 1); + q = old[vars[var]]; + } + if (q && getModuleId(q) == sqlRef && getFunctionId(q) == deltaRef) { + InstrPtr r = copyInstruction(p); + InstrPtr s = copyInstruction(p); + InstrPtr t = copyInstruction(p); + InstrPtr u = copyInstruction(q); + + if( r == NULL || s == NULL || t== NULL ||u == NULL){ + freeInstruction(r); + freeInstruction(s); + freeInstruction(t); + freeInstruction(u); + GDKfree(vars); + GDKfree(nvars); + GDKfree(slices); + GDKfree(rslices); + GDKfree(oclean); + GDKfree(old); + throw(MAL,"optimizer.pushselect", SQLSTATE(HY013) MAL_MALLOC_FAIL); + } + getArg(r, 0) = newTmpVariable(mb, newBatType(TYPE_oid)); + setVarCList(mb,getArg(r,0)); + getArg(r, 1) = getArg(q, 1); /* column */ + r->typechk = TYPE_UNKNOWN; + pushInstruction(mb,r); + getArg(s, 0) = newTmpVariable(mb, newBatType(TYPE_oid)); + setVarCList(mb,getArg(s,0)); + getArg(s, 1) = getArg(q, 3); /* updates */ + s = ReplaceWithNil(mb, s, 3, TYPE_bat); /* no candidate list */ + setArgType(mb, s, 3, newBatType(TYPE_oid)); + /* make sure to resolve again */ + s->token = ASSIGNsymbol; + s->typechk = TYPE_UNKNOWN; + s->fcn = NULL; + s->blk = NULL; + pushInstruction(mb,s); + getArg(t, 0) = newTmpVariable(mb, newBatType(TYPE_oid)); + setVarCList(mb,getArg(t,0)); + getArg(t, 1) = getArg(q, 4); /* inserts */ + pushInstruction(mb,t); + + setFunctionId(u, subdeltaRef); + getArg(u, 0) = getArg(p,0); + getArg(u, 1) = getArg(r,0); + getArg(u, 2) = getArg(p,3); /* pre-cands */ + getArg(u, 3) = getArg(q,2); /* update ids */ + getArg(u, 4) = getArg(s,0); + u = pushArgument(mb, u, getArg(t,0)); + u->typechk = TYPE_UNKNOWN; + pushInstruction(mb,u); + oclean[i] = 1; + continue; + } } assert (p == old[i] || oclean[i]); pushInstruction(mb,p); 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 @@ -2202,6 +2202,7 @@ split_join_exps(sql_rel *rel, list *join } #define is_equi_exp(e) ((e)->flag == cmp_equal || (e)->flag == mark_in || (e)->flag == mark_notin) +#define is_equi_exp_(e) ((e)->flag == cmp_equal || (e)->flag == mark_in) static list * get_equi_joins_first(mvc *sql, list *exps, int *equality_only) @@ -2212,7 +2213,7 @@ get_equi_joins_first(mvc *sql, list *exp sql_exp *e = n->data; assert(e->type == e_cmp && e->flag != cmp_in && e->flag != cmp_notin && e->flag != cmp_or); - if (is_equi_exp(e)) + if (is_equi_exp_(e)) list_append(new_exps, e); else *equality_only = 0; @@ -2220,7 +2221,7 @@ get_equi_joins_first(mvc *sql, list *exp for( node *n = exps->h; n; n = n->next ) { sql_exp *e = n->data; - if (!is_equi_exp(e)) + if (!is_equi_exp_(e)) list_append(new_exps, e); } return new_exps; @@ -2526,12 +2527,16 @@ rel2bin_semijoin(backend *be, sql_rel *r list *l, *sexps = NULL; node *en = NULL, *n; stmt *left = NULL, *right = NULL, *join = NULL, *jl, *jr, *c, *lcand = NULL; + int semijoin_only = 0, l_is_base = 0; if (rel->op == op_anti && !list_empty(rel->exps) && list_length(rel->exps) == 1 && ((sql_exp*)rel->exps->h->data)->flag == mark_notin) return rel2bin_antijoin(be, rel, refs); - if (rel->l) /* first construct the left sub relation */ - left = subrel_bin(be, rel->l, refs); + if (rel->l) { /* first construct the left sub relation */ + sql_rel *l = rel->l; + l_is_base = is_basetable(l->op); + left = subrel_bin(be, l, refs); + } if (rel->r) /* first construct the right sub relation */ right = subrel_bin(be, rel->r, refs); if (!left || !right) @@ -2604,7 +2609,13 @@ rel2bin_semijoin(backend *be, sql_rel *r if (!l || !r) return NULL; - s = stmt_join_cand(be, column(be, l), column(be, r), left->cand, NULL/*right->cand*/, e->anti, (comp_type) e->flag, 0, is_semantics(e), false); + if (be->no_mitosis && list_length(jexps) == 1 && list_empty(sexps) && rel->op == op_semi && !e->anti && is_equi_exp_(e)) { + join = stmt_semijoin(be, column(be, l), column(be, r), left->cand, NULL/*right->cand*/, is_semantics(e), false); + semijoin_only = 1; + en = NULL; + break; + } else + s = stmt_join_cand(be, column(be, l), column(be, r), left->cand, NULL/*right->cand*/, e->anti, (comp_type) e->flag, 0, is_semantics(e), false); lcand = left->cand; } else { s = exp_bin(be, e, left, right, NULL, NULL, NULL, NULL, 0, 1, 0); @@ -2711,22 +2722,28 @@ rel2bin_semijoin(backend *be, sql_rel *r /* We did a full join, thats too much. Reduce this using difference and intersect */ - c = stmt_mirror(be, bin_first_column(be, left)); - if (rel->op == op_anti) { - join = stmt_tdiff(be, c, jl, lcand); - } else { - if (lcand) - join = stmt_semijoin(be, c, jl, lcand, NULL/*right->cand*/, 0, false); - else - join = stmt_tinter(be, c, jl, false); + if (!semijoin_only) { + c = stmt_mirror(be, bin_first_column(be, left)); + if (rel->op == op_anti) { + join = stmt_tdiff(be, c, jl, lcand); + } else { + if (lcand) + join = stmt_semijoin(be, c, jl, lcand, NULL/*right->cand*/, 0, false); + else + join = stmt_tinter(be, c, jl, false); + } } /* project all the left columns */ for( n = left->op4.lval->h; n; n = n->next ) { - stmt *c = n->data; + stmt *c = n->data, *s; const char *rnme = table_name(sql->sa, c); const char *nme = column_name(sql->sa, c); - stmt *s = stmt_project(be, join, column(be, c)); + + if (l_is_base && nme[0] == '%' && strcmp(nme, TID) == 0) + s = join; + else + s = stmt_project(be, join, column(be, c)); s = stmt_alias(be, s, rnme, nme); list_append(l, s); diff --git a/sql/server/rel_exp.c b/sql/server/rel_exp.c --- a/sql/server/rel_exp.c +++ b/sql/server/rel_exp.c @@ -2903,7 +2903,7 @@ exp_convert_inplace(mvc *sql, sql_subtyp return NULL; a = exp->l; - if (t->scale && t->type->eclass != EC_FLT) + if (!a->isnull && t->scale && t->type->eclass != EC_FLT) return NULL; if (a && atom_cast(sql->sa, a, t)) { 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 @@ -1400,7 +1400,7 @@ can_push_func(sql_exp *e, sql_rel *rel, static int exps_can_push_func(list *exps, sql_rel *rel, bool *push_left, bool *push_right) { - for(node *n = exps->h; n && !*push_left && !*push_right; n = n->next) { + for(node *n = exps->h; n; n = n->next) { sql_exp *e = n->data; int mustl = 0, mustr = 0; diff --git a/sql/server/sql_atom.c b/sql/server/sql_atom.c --- a/sql/server/sql_atom.c +++ b/sql/server/sql_atom.c @@ -758,60 +758,112 @@ atom_cast(sql_allocator *sa, atom *a, sq *at = *tp; return 1; } - if (at->type->eclass == EC_NUM && tp->type->eclass == EC_NUM && - at->type->localtype <= tp->type->localtype) { - /* cast numerics */ - switch ( tp->type->localtype) { - case TYPE_bte: - if (at->type->localtype != TYPE_bte) - return 0; - break; - case TYPE_sht: - if (at->type->localtype == TYPE_bte) - a->data.val.shval = a->data.val.btval; - else if (at->type->localtype != TYPE_sht) - return 0; - break; - case TYPE_int: + if (at->type->eclass == EC_NUM && tp->type->eclass == EC_NUM) { + if (at->type->localtype <= tp->type->localtype) { /* cast to a larger numeric */ + switch (tp->type->localtype) { + case TYPE_bte: + if (at->type->localtype != TYPE_bte) + return 0; + break; + case TYPE_sht: + if (at->type->localtype == TYPE_bte) + a->data.val.shval = a->data.val.btval; + else if (at->type->localtype != TYPE_sht) + return 0; + break; + case TYPE_int: #if SIZEOF_OID == SIZEOF_INT - case TYPE_oid: + case TYPE_oid: #endif - if (at->type->localtype == TYPE_bte) - a->data.val.ival = a->data.val.btval; - else if (at->type->localtype == TYPE_sht) - a->data.val.ival = a->data.val.shval; - else if (at->type->localtype != TYPE_int) - return 0; - break; - case TYPE_lng: + if (at->type->localtype == TYPE_bte) + a->data.val.ival = a->data.val.btval; + else if (at->type->localtype == TYPE_sht) + a->data.val.ival = a->data.val.shval; + else if (at->type->localtype != TYPE_int) + return 0; + break; + case TYPE_lng: #if SIZEOF_OID == SIZEOF_LNG - case TYPE_oid: + case TYPE_oid: #endif - if (at->type->localtype == TYPE_bte) - a->data.val.lval = a->data.val.btval; - else if (at->type->localtype == TYPE_sht) - a->data.val.lval = a->data.val.shval; - else if (at->type->localtype == TYPE_int) - a->data.val.lval = a->data.val.ival; - else if (at->type->localtype != TYPE_lng) + if (at->type->localtype == TYPE_bte) _______________________________________________ checkin-list mailing list checkin-list@monetdb.org https://www.monetdb.org/mailman/listinfo/checkin-list