Changeset: f67a17674f06 for MonetDB URL: https://dev.monetdb.org/hg/MonetDB/rev/f67a17674f06 Modified Files: sql/server/rel_exp.c sql/server/rel_optimizer.c sql/storage/bat/bat_storage.c Branch: default Log Message:
merged with jan2022 diffs (truncated from 436 to 300 lines): diff --git a/monetdb5/optimizer/opt_for.c b/monetdb5/optimizer/opt_for.c --- a/monetdb5/optimizer/opt_for.c +++ b/monetdb5/optimizer/opt_for.c @@ -197,9 +197,11 @@ OPTforImplementation(Client cntxt, MalBl freeInstruction(p); done = 1; break; - } else if ((isMapOp(p) || isMap2Op(p)) && (getFunctionId(p) == plusRef || getFunctionId(p) == minusRef) && allConstExcept(mb, p, j)) { + } else if ((isMapOp(p) || isMap2Op(p)) && (getFunctionId(p) == plusRef || getFunctionId(p) == minusRef) && + p->argc > 2 && getBatType(getArgType(mb, p, 2)) != TYPE_oid && allConstExcept(mb, p, j)) { + /* filter out unary batcalc.- with and without a candidate list */ /* batcalc.-(1, col) with col = for.decompress(o,min_val) - * v1 = batcalc.-(1, min_val) + * v1 = calc.-(1, min_val) * for.decompress(o, v1) */ /* we assume binary operators only ! */ InstrPtr r = newInstructionArgs(mb, calcRef, getFunctionId(p), 3); 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 @@ -1541,20 +1541,20 @@ distinct_rel(sql_exp *e, const char **rn } int -rel_has_exp(sql_rel *rel, sql_exp *e) +rel_has_exp(sql_rel *rel, sql_exp *e, bool subexp) { - if (rel_find_exp(rel, e) != NULL) + if (rel_find_exp_and_corresponding_rel(rel, e, subexp, NULL, NULL)) return 0; return -1; } int -rel_has_exps(sql_rel *rel, list *exps) +rel_has_exps(sql_rel *rel, list *exps, bool subexp) { if (list_empty(exps)) return 0; for (node *n = exps->h; n; n = n->next) - if (rel_has_exp(rel, n->data) >= 0) + if (rel_has_exp(rel, n->data, subexp) >= 0) return 0; return -1; } @@ -1565,15 +1565,21 @@ rel_has_all_exps(sql_rel *rel, list *exp if (list_empty(exps)) return 1; for (node *n = exps->h; n; n = n->next) - if (rel_has_exp(rel, n->data) < 0) + if (rel_has_exp(rel, n->data, false) < 0) return 0; return 1; } +static int +rel_has_exp2(sql_rel *rel, sql_exp *e) +{ + return rel_has_exp(rel, e, false); +} + sql_rel * find_rel(list *rels, sql_exp *e) { - node *n = list_find(rels, e, (fcmp)&rel_has_exp); + node *n = list_find(rels, e, (fcmp)&rel_has_exp2); if (n) return n->data; return NULL; @@ -1586,7 +1592,7 @@ find_one_rel(list *rels, sql_exp *e) sql_rel *fnd = NULL; for(n = rels->h; n; n = n->next) { - if (rel_has_exp(n->data, e) == 0) { + if (rel_has_exp(n->data, e, false) == 0) { if (fnd) return NULL; fnd = n->data; @@ -1658,7 +1664,7 @@ exps_find_prop(list *exps, rel_prop kind } static sql_exp * -rel_find_exp_and_corresponding_rel_(sql_rel *rel, sql_exp *e, sql_rel **res) +rel_find_exp_and_corresponding_rel_(sql_rel *rel, sql_exp *e, bool subexp, sql_rel **res) { sql_exp *ne = NULL; @@ -1683,7 +1689,7 @@ rel_find_exp_and_corresponding_rel_(sql_ *res = rel; return ne; case e_convert: - return rel_find_exp_and_corresponding_rel_(rel, e->l, res); + return rel_find_exp_and_corresponding_rel_(rel, e->l, subexp, res); case e_aggr: case e_func: if (e->l) { @@ -1691,8 +1697,10 @@ rel_find_exp_and_corresponding_rel_(sql_ node *n = l->h; ne = n->data; - while (ne != NULL && n != NULL) { - ne = rel_find_exp_and_corresponding_rel_(rel, n->data, res); + while ((subexp || ne != NULL) && n != NULL) { + ne = rel_find_exp_and_corresponding_rel_(rel, n->data, subexp, res); + if (subexp && ne) + break; n = n->next; } return ne; @@ -1708,8 +1716,10 @@ rel_find_exp_and_corresponding_rel_(sql_ node *n = l->h; ne = n->data; - while (ne != NULL && n != NULL) { - ne = rel_find_exp_and_corresponding_rel_(rel, n->data, res); + while ((subexp || ne != NULL) && n != NULL) { + ne = rel_find_exp_and_corresponding_rel_(rel, n->data, subexp, res); + if (subexp && ne) + break; n = n->next; } return ne; @@ -1720,9 +1730,9 @@ rel_find_exp_and_corresponding_rel_(sql_ } sql_exp * -rel_find_exp_and_corresponding_rel(sql_rel *rel, sql_exp *e, sql_rel **res, bool *under_join) +rel_find_exp_and_corresponding_rel(sql_rel *rel, sql_exp *e, bool subexp, sql_rel **res, bool *under_join) { - sql_exp *ne = rel_find_exp_and_corresponding_rel_(rel, e, res); + sql_exp *ne = rel_find_exp_and_corresponding_rel_(rel, e, subexp, res); if (rel && !ne) { switch(rel->op) { @@ -1732,9 +1742,9 @@ rel_find_exp_and_corresponding_rel(sql_r case op_join: case op_semi: case op_anti: - ne = rel_find_exp_and_corresponding_rel(rel->l, e, res, under_join); + ne = rel_find_exp_and_corresponding_rel(rel->l, e, subexp, res, under_join); if (!ne && is_join(rel->op)) - ne = rel_find_exp_and_corresponding_rel(rel->r, e, res, under_join); + ne = rel_find_exp_and_corresponding_rel(rel->r, e, subexp, res, under_join); if (ne && under_join && is_join(rel->op)) *under_join = true; break; @@ -1743,7 +1753,7 @@ rel_find_exp_and_corresponding_rel(sql_r break; default: if (!is_project(rel->op) && rel->l) - ne = rel_find_exp_and_corresponding_rel(rel->l, e, res, under_join); + ne = rel_find_exp_and_corresponding_rel(rel->l, e, subexp, res, under_join); } } return ne; @@ -1752,7 +1762,7 @@ rel_find_exp_and_corresponding_rel(sql_r sql_exp * rel_find_exp(sql_rel *rel, sql_exp *e) { - return rel_find_exp_and_corresponding_rel(rel, e, NULL, NULL); + return rel_find_exp_and_corresponding_rel(rel, e, false, NULL, NULL); } int diff --git a/sql/server/rel_exp.h b/sql/server/rel_exp.h --- a/sql/server/rel_exp.h +++ b/sql/server/rel_exp.h @@ -129,7 +129,7 @@ extern unsigned int exp_card(sql_exp *e) extern const char *exp_find_rel_name(sql_exp *e); extern sql_exp *rel_find_exp(sql_rel *rel, sql_exp *e); -extern sql_exp *rel_find_exp_and_corresponding_rel(sql_rel *rel, sql_exp *e, sql_rel **res, bool *under_join); +extern sql_exp *rel_find_exp_and_corresponding_rel(sql_rel *rel, sql_exp *e, bool subexp, sql_rel **res, bool *under_join); extern int exp_cmp( sql_exp *e1, sql_exp *e2); extern int exp_equal( sql_exp *e1, sql_exp *e2); @@ -170,10 +170,10 @@ extern int exp_has_sideeffect(sql_exp *e extern sql_exp *exps_find_prop(list *exps, rel_prop kind); -/* returns 0 when the relation contain the passed expression else < 0 */ -extern int rel_has_exp(sql_rel *rel, sql_exp *e); -/* return 0 when the relation contain atleast one of the passed expressions else < 0 */ -extern int rel_has_exps(sql_rel *rel, list *e); +/* returns 0 when the relation contain the passed expression (or sub expressions if subexp is set) else < 0 */ +extern int rel_has_exp(sql_rel *rel, sql_exp *e, bool subexp); +/* return 0 when the relation contain atleast one of the passed expressions (or sub expressions if subexp is set) else < 0 */ +extern int rel_has_exps(sql_rel *rel, list *e, bool subexp); /* return 1 when the relation contains all of the passed expressions else 0 */ extern int rel_has_all_exps(sql_rel *rel, list *e); 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 @@ -386,7 +386,7 @@ static sql_exp * joinexp_col(sql_exp *e, sql_rel *r) { if (e->type == e_cmp) { - if (rel_has_exp(r, e->l) >= 0) + if (rel_has_exp(r, e->l, false) >= 0) return e->l; return e->r; } @@ -394,6 +394,12 @@ joinexp_col(sql_exp *e, sql_rel *r) return NULL; } +static int +rel_has_exp2(sql_rel *r, sql_exp *e) +{ + return rel_has_exp(r, e, false); +} + static sql_column * table_colexp(sql_exp *e, sql_rel *r) { @@ -831,8 +837,8 @@ order_joins(visitor *v, list *rels, list node *ln, *rn, *en; cje = djn->data; - ln = list_find(n_rels, cje->l, (fcmp)&rel_has_exp); - rn = list_find(n_rels, cje->r, (fcmp)&rel_has_exp); + ln = list_find(n_rels, cje->l, (fcmp)&rel_has_exp2); + rn = list_find(n_rels, cje->r, (fcmp)&rel_has_exp2); if (ln && rn) { assert(0); @@ -996,7 +1002,7 @@ push_in_join_down(mvc *sql, list *rels, if (e->type == e_cmp && e->flag == cmp_equal) { /* in values are on the right of the join */ - if (rel_has_exp(r, e->r) >= 0) + if (rel_has_exp(r, e->r, false) >= 0) je = e; } } @@ -4299,7 +4305,7 @@ gen_push_groupby_down(mvc *sql, sql_rel if (exp_is_atom(ce)) list_append(aliases, ce); else if (ce->type == e_column) { - if (rel_has_exp(cl, ce) == 0) /* collect aliases outside groupby */ + if (rel_has_exp(cl, ce, false) == 0) /* collect aliases outside groupby */ list_append(aliases, ce); else list_append(aggrs, ce); @@ -4307,7 +4313,7 @@ gen_push_groupby_down(mvc *sql, sql_rel list *args = ce->l; /* check args are part of left/right */ - if (!list_empty(args) && rel_has_exps(cl, args) == 0) + if (!list_empty(args) && rel_has_exps(cl, args, false) == 0) return rel; if (rel->op != op_join && exp_aggr_is_count(ce)) ce->p = prop_create(sql->sa, PROP_COUNT, ce->p); @@ -5432,7 +5438,7 @@ find_projection_for_join2semi(sql_rel *r return has_nil(e) ? MAY_HAVE_DUPLICATE_NULLS : ALL_VALUES_DISTINCT; if ((is_simple_project(rel->op) || is_groupby(rel->op) || is_inter(rel->op) || is_except(rel->op)) && - (found = rel_find_exp_and_corresponding_rel(rel->l, e, &res, &underjoin)) && !underjoin) { /* grouping column on inner relation */ + (found = rel_find_exp_and_corresponding_rel(rel->l, e, false, &res, &underjoin)) && !underjoin) { /* grouping column on inner relation */ if (need_distinct(res) && list_length(res->exps) == 1) return ALL_VALUES_DISTINCT; if (is_unique(found)) 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 @@ -3395,7 +3395,7 @@ static sql_exp * sql_rel *groupby = rel ? *rel : NULL, *sel = NULL, *gr, *og = NULL, *res = groupby; sql_rel *subquery = NULL; list *exps = NULL; - bool is_grouping = !strcmp(aname, "grouping"), has_args = false, found = false; + bool is_grouping = !strcmp(aname, "grouping"), has_args = false, found = false, used_rel = false; if (!query_has_outer(query)) { if (!groupby) { @@ -3443,6 +3443,7 @@ static sql_exp * if (!e) return NULL; + used_rel |= (rel_has_exp(gl, e, true) == 0); has_args = true; if (gl && gl != ogl) { if (gl->grouped) { @@ -3506,6 +3507,9 @@ static sql_exp * return sql_error(sql, ERR_GROUPBY, SQLSTATE(42000) "SELECT: subquery uses ungrouped column \"%s.%s\" from outer query", exp_relname(e), exp_name(e)); return sql_error(sql, ERR_GROUPBY, SQLSTATE(42000) "SELECT: subquery uses ungrouped column from outer query"); } + } else if (!used_rel && is_sql_where(of)) { + char *uaname = SA_NEW_ARRAY(sql->ta, char, strlen(aname) + 1); + return sql_error(sql, 02, SQLSTATE(42000) "%s: aggregate functions not allowed in WHERE clause", toUpperCopy(uaname, aname)); } else if (!is_sql_aggr(of)) { set_outer(outer); } diff --git a/sql/server/rel_unnest.c b/sql/server/rel_unnest.c --- a/sql/server/rel_unnest.c +++ b/sql/server/rel_unnest.c @@ -1945,9 +1945,9 @@ exp_reset_card_and_freevar_set_physical_ sql_exp *le = NULL, *re = NULL; bool underjoinl = false, underjoinr = false; _______________________________________________ checkin-list mailing list checkin-list@monetdb.org https://www.monetdb.org/mailman/listinfo/checkin-list