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
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list