Changeset: 358c36e2fd92 for MonetDB URL: https://dev.monetdb.org/hg/MonetDB/rev/358c36e2fd92 Added Files: sql/test/BugTracker-2021/Tests/merge-stmt.wrong-error.Bug-7109.test Removed Files: sql/test/BugTracker-2021/Tests/merge-stmt.wrong-error.Bug-7109.sql sql/test/BugTracker-2021/Tests/merge-stmt.wrong-error.Bug-7109.stable.err sql/test/BugTracker-2021/Tests/merge-stmt.wrong-error.Bug-7109.stable.out sql/test/BugTracker-2021/Tests/remote-table-groupby.Bug-7110.stable.err sql/test/BugTracker-2021/Tests/remote-table-groupby.Bug-7110.stable.out Modified Files: sql/backends/monet5/sql_upgrades.c sql/server/rel_basetable.c sql/server/rel_basetable.h sql/server/rel_dump.c sql/server/rel_exp.c sql/server/rel_rel.c sql/server/rel_updates.c sql/storage/bat/bat_storage.c sql/storage/sql_storage.h Branch: default Log Message:
Merging Oct2020 into default diffs (truncated from 607 to 300 lines): diff --git a/sql/backends/monet5/sql_upgrades.c b/sql/backends/monet5/sql_upgrades.c --- a/sql/backends/monet5/sql_upgrades.c +++ b/sql/backends/monet5/sql_upgrades.c @@ -765,9 +765,8 @@ sql_update_apr2019_sp1(Client c) } BBPunfix(b->batCacheid); } + res_tables_destroy(output); } - if (output != NULL) - res_tables_destroy(output); return err; /* usually MAL_SUCCEED */ } diff --git a/sql/server/rel_basetable.c b/sql/server/rel_basetable.c --- a/sql/server/rel_basetable.c +++ b/sql/server/rel_basetable.c @@ -119,14 +119,10 @@ rel_basetable(mvc *sql, sql_table *t, co } sql_rel * -rel_base_bind_column_( sql_rel *rel, const char *cname, int *exp_has_nil) +rel_base_bind_column_( sql_rel *rel, const char *cname) { sql_table *t = rel->l; node *n = ol_find_name(t->columns, cname); - if (n && exp_has_nil) { - sql_column *c = n->data; - *exp_has_nil = c->null; - } if (n) return rel; return NULL; diff --git a/sql/server/rel_basetable.h b/sql/server/rel_basetable.h --- a/sql/server/rel_basetable.h +++ b/sql/server/rel_basetable.h @@ -29,7 +29,7 @@ extern char *rel_base_name(sql_rel *r); extern char *rel_base_rename(sql_rel *r, char *name); extern sql_exp * rel_base_bind_colnr( mvc *sql, sql_rel *rel, int nr); -extern sql_rel *rel_base_bind_column_( sql_rel *rel, const char *cname, int *exp_has_nil); +extern sql_rel *rel_base_bind_column_( sql_rel *rel, const char *cname); extern sql_exp *rel_base_bind_column( mvc *sql, sql_rel *rel, const char *cname, int no_tname); extern sql_rel *rel_base_bind_column2_( sql_rel *rel, const char *tname, const char *cname); extern sql_exp *rel_base_bind_column2( mvc *sql, sql_rel *rel, const char *tname, const char *cname); 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 @@ -1862,9 +1862,11 @@ rel_read(mvc *sql, char *r, int *pos, li return NULL; rel = rel_project(sql->sa, nrel, exps); /* order by ? */ - if (r[*pos] == '[') - if (!(rel->r = read_exps(sql, nrel, rel, NULL, r, pos, '[', 0, 1))) + if (r[*pos] == '[') { + /* first projected expressions, then left relation projections */ + if (!(rel->r = read_exps(sql, rel, nrel, NULL, r, pos, '[', 0, 1))) return NULL; + } break; case 'g': *pos += (int) strlen("group by"); @@ -1885,11 +1887,14 @@ rel_read(mvc *sql, char *r, int *pos, li if (!(gexps = read_exps(sql, nrel, NULL, NULL, r, pos, '[', 0, 1))) return NULL; skipWS(r, pos); - if (!(exps = read_exps(sql, nrel, NULL, gexps, r, pos, '[', 1, 1))) + rel = rel_groupby(sql, nrel, gexps); + rel->exps = new_exp_list(sql->sa); /* empty projection list for now */ + set_processed(rel); /* don't search beyond the group by */ + /* first group projected expressions, then group by columns, then left relation projections */ + if (!(exps = read_exps(sql, rel, nrel, NULL, r, pos, '[', 1, 1))) return NULL; - - rel = rel_groupby(sql, nrel, gexps); rel->exps = exps; + rel->nrcols = list_length(exps); break; case 's': case 'a': 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 @@ -1646,7 +1646,7 @@ rel_find_exp_and_corresponding_rel_(sql_ if (e->l) { if (rel_base_bind_column2_(rel, e->l, e->r)) ne = e; - } else if (rel_base_bind_column_(rel, e->r, NULL)) + } else if (rel_base_bind_column_(rel, e->r)) ne = e; } else if (rel->exps && (is_project(rel->op) || is_base(rel->op))) { if (e->l) { 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 @@ -233,104 +233,73 @@ rel_select_copy(sql_allocator *sa, sql_r return rel; } -static sql_rel * -rel_bind_column_(mvc *sql, int *exp_has_nil, sql_rel *rel, const char *cname, int no_tname) +sql_exp * +rel_bind_column( mvc *sql, sql_rel *rel, const char *cname, int f, int no_tname) { int ambiguous = 0, multi = 0; - sql_rel *l = NULL, *r = NULL; + if (!rel) + return NULL; if (mvc_highwater(sql)) return sql_error(sql, 10, SQLSTATE(42000) "Query too complex: running out of stack space"); - switch(rel->op) { - case op_join: - case op_left: - case op_right: - case op_full: { - r = rel_bind_column_(sql, exp_has_nil, rel->r, cname, no_tname); - sql_exp *e = r?exps_bind_column(r->exps, cname, &ambiguous, &multi, 0):NULL; + if ((is_project(rel->op) || is_base(rel->op))) { + sql_exp *e = NULL; - if (!r || !e || !is_freevar(e)) { - l = rel_bind_column_(sql, exp_has_nil, rel->l, cname, no_tname); - if (l && r && !is_dependent(rel)) + if (is_base(rel->op) && !rel->exps) + return rel_base_bind_column(sql, rel, cname, no_tname); + if (!list_empty(rel->exps)) { + e = exps_bind_column(rel->exps, cname, &ambiguous, &multi, no_tname); + if (ambiguous || multi) + return sql_error(sql, ERR_AMBIGUOUS, SQLSTATE(42000) "SELECT: identifier '%s' ambiguous", cname); + if (!e && is_groupby(rel->op) && rel->r) { + e = exps_bind_alias(rel->r, NULL, cname); + if (e) { + e = exps_bind_column(rel->r, cname, &ambiguous, &multi, no_tname); + if (ambiguous || multi) + return sql_error(sql, ERR_AMBIGUOUS, SQLSTATE(42000) "SELECT: identifier '%s' ambiguous", cname); + return e; + } + } + } + if (!e && (is_sql_sel(f) || is_sql_having(f) || !f) && is_groupby(rel->op) && rel->r) { + e = exps_bind_column(rel->r, cname, &ambiguous, &multi, no_tname); + if (ambiguous || multi) + return sql_error(sql, ERR_AMBIGUOUS, SQLSTATE(42000) "SELECT: identifier '%s' ambiguous", cname); + if (e) { + e = exp_ref(sql, e); + e->card = rel->card; + return e; + } + } + if (e) + return exp_alias_or_copy(sql, exp_relname(e), cname, rel, e); + } + if ((is_simple_project(rel->op) || is_groupby(rel->op)) && rel->l) { + if (!is_processed(rel)) + return rel_bind_column(sql, rel->l, cname, f, no_tname); + } else if (is_set(rel->op)) { + assert(is_processed(rel)); + return NULL; + } else if (is_join(rel->op)) { + sql_exp *e1 = rel_bind_column(sql, rel->l, cname, f, no_tname), *e2 = NULL; + + if (e1 && (is_right(rel->op) || is_full(rel->op))) + set_has_nil(e1); + if (!e1 || !is_freevar(e1)) { + e2 = rel_bind_column(sql, rel->r, cname, f, no_tname); + if (e2 && (is_left(rel->op) || is_full(rel->op))) + set_has_nil(e2); + if (e1 && e2 && !is_dependent(rel)) return sql_error(sql, ERR_AMBIGUOUS, SQLSTATE(42000) "SELECT: identifier '%s' ambiguous", cname); } - if (sql->session->status == -ERR_AMBIGUOUS) - return NULL; - if (l && !r) { - if (is_full(rel->op) || is_right(rel->op)) - *exp_has_nil = 1; - return l; - } - if (r && (is_full(rel->op) || is_left(rel->op))) - *exp_has_nil = 1; - return r; - } - case op_basetable: - if (!rel->exps) - return rel_base_bind_column_(rel, cname, exp_has_nil); - /* fall through */ - case op_union: - case op_except: - case op_inter: - case op_groupby: - case op_project: - case op_table: { - sql_exp *found = NULL; - - if (rel->exps) - found = exps_bind_column(rel->exps, cname, &ambiguous, &multi, no_tname); - if (!found && rel->r && is_groupby(rel->op)) - found = exps_bind_column(rel->r, cname, &ambiguous, &multi, no_tname); - if (ambiguous || multi) - return sql_error(sql, ERR_AMBIGUOUS, SQLSTATE(42000) "SELECT: identifier '%s' ambiguous", cname); - if (found) - return rel; - if (is_processed(rel)) - return NULL; - if (rel->l && !(is_base(rel->op))) - return rel_bind_column_(sql, exp_has_nil, rel->l, cname, no_tname); - } break; - case op_semi: - case op_anti: - - case op_select: - case op_topn: - case op_sample: + return e1 ? e1 : e2; + } else if (is_semi(rel->op) || + is_select(rel->op) || + is_topn(rel->op) || + is_sample(rel->op)) { if (rel->l) - return rel_bind_column_(sql, exp_has_nil, rel->l, cname, no_tname); - /* fall through */ - default: - return NULL; - } - return NULL; -} - -sql_exp * -rel_bind_column( mvc *sql, sql_rel *rel, const char *cname, int f, int no_tname) -{ - int exp_has_nil = 0; /* mark if we passed any outer joins */ - - if (is_sql_sel(f) && rel && is_simple_project(rel->op) && !is_processed(rel)) - rel = rel->l; - - if (!rel || (rel = rel_bind_column_(sql, &exp_has_nil, rel, cname, no_tname)) == NULL) - return NULL; - - if (is_basetable(rel->op) && !rel->exps) - return rel_base_bind_column(sql, rel, cname, no_tname); - if ((is_project(rel->op) || is_base(rel->op)) && rel->exps) { - sql_exp *e = exps_bind_column(rel->exps, cname, NULL, NULL, no_tname); - if (e) - e = exp_alias_or_copy(sql, exp_relname(e), cname, rel, e); - if (!e && is_groupby(rel->op) && rel->r) { - sql_exp *e = exps_bind_column(rel->r, cname, NULL, NULL, no_tname); - if (e) - e = exp_alias_or_copy(sql, exp_relname(e), cname, rel, e); - } - if (e && exp_has_nil) - set_has_nil(e); - return e; + return rel_bind_column(sql, rel->l, cname, f, no_tname); } return NULL; } @@ -342,6 +311,8 @@ rel_bind_column2( mvc *sql, sql_rel *rel if (!rel) return NULL; + if (mvc_highwater(sql)) + return sql_error(sql, 10, SQLSTATE(42000) "Query too complex: running out of stack space"); if ((is_project(rel->op) || is_base(rel->op))) { sql_exp *e = NULL; @@ -1075,7 +1046,7 @@ rel_bind_path_(mvc *sql, sql_rel *rel, s if (e->l) found = (rel_base_bind_column2_(rel, e->l, e->r) != NULL); else - found = (rel_base_bind_column_(rel, e->r, NULL) != NULL); + found = (rel_base_bind_column_(rel, e->r) != NULL); break; case op_union: case op_inter: diff --git a/sql/server/rel_updates.c b/sql/server/rel_updates.c --- a/sql/server/rel_updates.c +++ b/sql/server/rel_updates.c @@ -1211,43 +1211,103 @@ truncate_table(mvc *sql, dlist *qname, i return NULL; } +static sql_exp * +null_check_best_score(list *exps) +{ + int max = 0; + sql_exp *res = exps->h->data; + + for (node *n = exps->h ; n ; n = n->next) { + sql_exp *e = n->data; + sql_subtype *t = exp_subtype(e); + int score = 0; + + if (find_prop(e->p, PROP_HASHCOL)) /* distinct columns */ + score += 700; + if (find_prop(e->p, PROP_SORTIDX)) /* has sort index */ + score += 400; + if (find_prop(e->p, PROP_HASHIDX)) /* has hash index */ + score += 300; + _______________________________________________ checkin-list mailing list checkin-list@monetdb.org https://www.monetdb.org/mailman/listinfo/checkin-list