Changeset: 6ff09b4366ee for MonetDB URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=6ff09b4366ee Modified Files: sql/backends/monet5/rel_bin.c sql/backends/monet5/sql_scenario.c sql/server/rel_dump.c sql/server/rel_exp.c sql/server/rel_exp.h sql/server/rel_optimizer.c sql/server/rel_rel.c sql/server/rel_rel.h sql/server/rel_select.c sql/server/rel_unnest.c sql/server/rel_updates.c sql/server/sql_atom.c sql/storage/bat/bat_storage.c sql/storage/store.c sql/test/BugTracker-2016/Tests/storagemodel.stable.out sql/test/SQLancer/Tests/sqlancer03.stable.out sql/test/subquery/Tests/subquery6.stable.out Branch: default Log Message:
Merged with oscar diffs (truncated from 875 to 300 lines): 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 @@ -3716,13 +3716,13 @@ insert_check_ukey(backend *be, list *ins stmt *sel = NULL; /* remove any nils as in stmt_order NULL = NULL, instead of NULL != NULL */ - if ((k->type == ukey) && stmt_has_null(col)) { - + if (k->type == ukey) { for (m = k->columns->h; m; m = m->next) { sql_kc *c = m->data; stmt *cs = list_fetch(inserts, c->c->colnr); - sel = stmt_selectnonil(be, cs, sel); + if (stmt_has_null(cs)) + sel = stmt_selectnonil(be, cs, sel); } } /* implementation uses sort key check */ diff --git a/sql/backends/monet5/sql_scenario.c b/sql/backends/monet5/sql_scenario.c --- a/sql/backends/monet5/sql_scenario.c +++ b/sql/backends/monet5/sql_scenario.c @@ -1162,10 +1162,12 @@ SQLparser(Client c) msg = SQLoptimizeQuery(c, c->curprg->def); if (msg != MAL_SUCCEED) { + str other = c->curprg->def->errors; c->curprg->def->errors = 0; MSresetInstructions(c->curprg->def, oldstop); freeVariables(c, c->curprg->def, NULL, oldvtop); - sqlcleanup(be, err); + if (other != msg) + freeException(other); goto finalize; } } diff --git a/sql/server/rel_dump.c b/sql/server/rel_dump.c --- a/sql/server/rel_dump.c +++ b/sql/server/rel_dump.c @@ -1805,7 +1805,7 @@ rel_read(mvc *sql, char *r, int *pos, li if (!(exps = read_exps(sql, NULL, NULL, NULL, r, pos, '[', 0))) return NULL; rel = rel_setop(sql->sa, lrel, rrel, j); - rel->exps = exps; + rel_setop_set_exps(sql, rel, exps); if (rel_set_types(sql, rel) < 0) return sql_error(sql, -1, SQLSTATE(42000) "Setop: number of expressions don't match\n"); set_processed(rel); 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 @@ -701,16 +701,16 @@ exp_alias_or_copy( mvc *sql, const char tname = exp_relname(old); if (!cname && exp_name(old) && has_label(old)) { - ne = exp_column(sql->sa, exp_relname(old), exp_name(old), exp_subtype(old), orel?orel->card:CARD_ATOM, has_nil(old), is_intern(old)); + ne = exp_column(sql->sa, exp_relname(old), exp_name(old), exp_subtype(old), orel && old->card != CARD_ATOM?orel->card:CARD_ATOM, has_nil(old), is_intern(old)); return exp_propagate(sql->sa, ne, old); } else if (!cname) { exp_label(sql->sa, old, ++sql->label); - ne = exp_column(sql->sa, exp_relname(old), exp_name(old), exp_subtype(old), orel?orel->card:CARD_ATOM, has_nil(old), is_intern(old)); + ne = exp_column(sql->sa, exp_relname(old), exp_name(old), exp_subtype(old), orel && old->card != CARD_ATOM?orel->card:CARD_ATOM, has_nil(old), is_intern(old)); return exp_propagate(sql->sa, ne, old); } else if (cname && !old->alias.name) { exp_setname(sql->sa, old, tname, cname); } - ne = exp_column(sql->sa, tname, cname, exp_subtype(old), orel?orel->card:CARD_ATOM, has_nil(old), is_intern(old)); + ne = exp_column(sql->sa, tname, cname, exp_subtype(old), orel && old->card != CARD_ATOM?orel->card:CARD_ATOM, has_nil(old), is_intern(old)); return exp_propagate(sql->sa, ne, old); } @@ -1603,7 +1603,7 @@ rel_find_exp_and_corresponding_rel_( sql } 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, sql_rel **res, bool *under_join) { sql_exp *ne = rel_find_exp_and_corresponding_rel_(rel, e, res); @@ -1613,9 +1613,11 @@ rel_find_exp_and_corresponding_rel(sql_r case op_right: case op_full: case op_join: - ne = rel_find_exp_and_corresponding_rel(rel->l, e, res); + ne = rel_find_exp_and_corresponding_rel(rel->l, e, res, under_join); if (!ne) - ne = rel_find_exp_and_corresponding_rel(rel->r, e, res); + ne = rel_find_exp_and_corresponding_rel(rel->r, e, res, under_join); + if (ne && under_join) + *under_join = true; break; case op_table: if (rel->exps && e->type == e_column && e->l && exps_bind_column2(rel->exps, e->l, e->r)) @@ -1628,7 +1630,7 @@ rel_find_exp_and_corresponding_rel(sql_r case op_inter: { if (rel->l) - ne = rel_find_exp_and_corresponding_rel(rel->l, e, res); + ne = rel_find_exp_and_corresponding_rel(rel->l, e, res, under_join); else if (rel->exps && e->l) { ne = exps_bind_column2(rel->exps, e->l, e->r); if (ne && res) @@ -1648,7 +1650,9 @@ 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); + ne = rel_find_exp_and_corresponding_rel(rel->l, e, res, under_join); + if (ne && (rel->op == op_semi || rel->op == op_anti) && under_join) + *under_join = true; } } return ne; @@ -1657,7 +1661,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); + return rel_find_exp_and_corresponding_rel(rel, e, 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 @@ -126,7 +126,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); +extern sql_exp *rel_find_exp_and_corresponding_rel(sql_rel *rel, sql_exp *e, 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); 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 @@ -4133,8 +4133,7 @@ rel_push_aggr_down(visitor *v, sql_rel * } u = rel_setop(v->sql->sa, ul, ur, op_union); - u->exps = rel_projections(v->sql, ul, NULL, 1, 1); - u->nrcols = list_length(u->exps); + rel_setop_set_exps(v->sql, u, rel_projections(v->sql, ul, NULL, 1, 1)); set_processed(u); if (rel->r) { @@ -4650,12 +4649,13 @@ find_simple_projection_for_join2semi(sql if (e->type == e_column) { sql_rel *res = NULL; sql_exp *found = NULL; + bool underjoin = false; if (is_groupby(rel->op) || need_distinct(rel) || find_prop(e->p, PROP_HASHCOL)) return true; - found = rel_find_exp_and_corresponding_rel(rel->l, e, &res); /* grouping column on inner relation */ - if (found) { + found = rel_find_exp_and_corresponding_rel(rel->l, e, &res, &underjoin); /* grouping column on inner relation */ + if (found && !underjoin) { if (find_prop(found->p, PROP_HASHCOL)) /* primary key always unique */ return true; if (found->type == e_column && found->card <= CARD_AGGR) { @@ -5643,6 +5643,8 @@ score_gbe(mvc *sql, sql_rel *rel, sql_ex sql_subtype *t = exp_subtype(e); sql_column *c = NULL; + if (e->card == CARD_ATOM) /* constants are trivial to group */ + res += 1000; /* can we find out if the underlying table is sorted */ if ((c = exp_find_column(rel, e, -2)) && mvc_is_sorted(sql, c)) res += 600; @@ -8547,8 +8549,7 @@ rel_split_outerjoin(visitor *v, sql_rel add_nulls( v->sql, nr, r); exps = rel_projections(v->sql, nl, NULL, 1, 1); nl = rel_setop(v->sql->sa, nl, nr, op_union); - nl->exps = exps; - nr->nrcols = list_length(exps); + rel_setop_set_exps(v->sql, nl, exps); set_processed(nl); } if (rel->op == op_right || rel->op == op_full) { @@ -8567,8 +8568,7 @@ rel_split_outerjoin(visitor *v, sql_rel (fdup)NULL); exps = rel_projections(v->sql, nl, NULL, 1, 1); nl = rel_setop(v->sql->sa, nl, nr, op_union); - nl->exps = exps; - nl->nrcols = list_length(exps); + rel_setop_set_exps(v->sql, nl, exps); set_processed(nl); } @@ -8726,52 +8726,38 @@ find_col_exp( list *exps, sql_exp *e) } static int -exp_range_overlap( mvc *sql, sql_exp *e, char *min, char *max, atom *emin, atom *emax) +exp_range_overlap(mvc *sql, sql_exp *e, char *min, char *max, atom *emin, atom *emax) { sql_subtype *t = exp_subtype(e); - - if (!min || !max || !emin || !emax) - return 0; - - if (strNil(min)) - return 0; - if (strNil(max)) + int localtype = t->type->localtype; + + if (!min || !max || !emin || !emax || strNil(min) || strNil(max) || emin->isnull || emax->isnull || !ATOMlinear(localtype)) return 0; - if (t->type->localtype == TYPE_dbl) { - atom *cmin = atom_general(sql->sa, t, min); - atom *cmax = atom_general(sql->sa, t, max); - - if (emax->d < cmin->data.val.dval || emin->d > cmax->data.val.dval) - return 0; - } - if (t->type->localtype == TYPE_bte) { - atom *cmin = atom_general(sql->sa, t, min); - atom *cmax = atom_general(sql->sa, t, max); - - if (emax->data.val.btval < cmin->data.val.btval || emin->data.val.btval > cmax->data.val.btval) + switch (ATOMstorage(localtype)) { + case TYPE_bte: + case TYPE_sht: + case TYPE_int: + case TYPE_lng: +#ifdef HAVE_HGE + case TYPE_hge: +#endif + case TYPE_flt: + case TYPE_dbl: + case TYPE_str: { + atom *cmin, *cmax; + +#ifdef HAVE_HGE + if (localtype == TYPE_hge && !have_hge) return 0; - } - if (t->type->localtype == TYPE_sht) { - atom *cmin = atom_general(sql->sa, t, min); - atom *cmax = atom_general(sql->sa, t, max); - - if (emax->data.val.shval < cmin->data.val.shval || emin->data.val.shval > cmax->data.val.shval) +#endif + cmin = atom_general(sql->sa, t, min); + cmax = atom_general(sql->sa, t, max); + if (VALcmp(&(emax->data), &(cmin->data)) < 0 || VALcmp(&(emin->data), &(cmax->data)) > 0) return 0; - } - if (t->type->localtype == TYPE_int || t->type->localtype == TYPE_date) { - atom *cmin = atom_general(sql->sa, t, min); - atom *cmax = atom_general(sql->sa, t, max); - - if (emax->data.val.ival < cmin->data.val.ival || emin->data.val.ival > cmax->data.val.ival) - return 0; - } - if (t->type->localtype == TYPE_lng || t->type->localtype == TYPE_timestamp) { - atom *cmin = atom_general(sql->sa, t, min); - atom *cmax = atom_general(sql->sa, t, max); - - if (emax->data.val.lval < cmin->data.val.lval || emin->data.val.lval > cmax->data.val.lval) - return 0; + } break; + default: + return 0; } return 1; } @@ -8982,7 +8968,7 @@ rel_merge_table_rewrite(visitor *v, sql_ sql_rel *l = n->data; sql_rel *r = n->next->data; nrel = rel_setop(v->sql->sa, l, r, op_union); - rel_set_exps(nrel, rel_projections(v->sql, rel, NULL, 1, 1)); + rel_setop_set_exps(v->sql, nrel, rel_projections(v->sql, rel, NULL, 1, 1)); set_processed(nrel); append(ntables, nrel); } 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 @@ -480,15 +480,9 @@ rel_setop(sql_allocator *sa, sql_rel *l, rel->r = r; rel->op = setop; rel->exps = NULL; - if (setop == op_union) { - rel->card = CARD_MULTI; - } else { - rel->card = l->card; - } - if (l && r) { - assert(l->nrcols == r->nrcols); - rel->nrcols = l->nrcols; - } + rel->card = is_union(setop) ? CARD_MULTI : l->card; + assert(l->nrcols == r->nrcols); _______________________________________________ checkin-list mailing list checkin-list@monetdb.org https://www.monetdb.org/mailman/listinfo/checkin-list