Changeset: 67dfea617859 for MonetDB URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=67dfea617859 Modified Files: 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_select.c sql/server/rel_select.h sql/server/rel_unnest.c sql/server/rel_updates.c sql/test/BugDay_2005-10-06_2.9.3/Tests/parser_crashes_server.SF-921996.stable.err sql/test/BugTracker-2018/Tests/multi-column-hash-wrongly-NIL.Bug-6638.stable.out sql/test/BugTracker-2020/Tests/global_table_propagation.Bug-6846.stable.err sql/test/BugTracker/Tests/ambiguous_join.SF-1580565.stable.err sql/test/BugTracker/Tests/full_join_crash.SF-1841754.stable.out sql/test/miscellaneous/Tests/simple_selects.sql sql/test/miscellaneous/Tests/simple_selects.stable.err sql/test/miscellaneous/Tests/update_delete_aliases.stable.err sql/test/subquery/Tests/subquery5.stable.err sql/test/subquery/Tests/subquery5.stable.out Branch: Jun2020 Log Message:
Backported ambiguous relations and columns checks from Oct2020 to Jun2020. Also approved tests diffs (truncated from 1548 to 300 lines): 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 @@ -861,11 +861,14 @@ exp_read(mvc *sql, sql_rel *lrel, sql_re cname = sa_strdup(sql->sa, cname); *e = old; skipWS(r, pos); - if (pexps) { - exp = exps_bind_column2(pexps, tname, cname); - if (exp) - exp = exp_alias_or_copy(sql, tname, cname, lrel, exp); - } + if (pexps) { + int mul = 0; + exp = exps_bind_column2(pexps, tname, cname, &mul); + if (exp) + exp = exp_alias_or_copy(sql, tname, cname, lrel, exp); + (void) mul; + assert(mul == 0); + } if (!exp && lrel) { exp = rel_bind_column2(sql, lrel, tname, cname, 0); if (!exp && rrel) @@ -1112,18 +1115,19 @@ exp_read(mvc *sql, sql_rel *lrel, sql_re *e = old; } if (!exp && lrel) { - int amb = 0; + int amb = 0, mul = 0; old = *e; *e = 0; var_cname = sa_strdup(sql->sa, b); if (pexps) { - exp = exps_bind_column(pexps, var_cname, &amb, 1); + exp = exps_bind_column(pexps, var_cname, &amb, &mul, 1); if (exp) exp = exp_alias_or_copy(sql, exp_relname(exp), var_cname, lrel, exp); } (void)amb; - assert(amb == 0); + (void)mul; + assert(amb == 0 && mul == 0); if (!exp && lrel) exp = rel_bind_column(sql, lrel, var_cname, 0, 1); if (!exp && rrel) 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 @@ -1529,9 +1529,9 @@ rel_find_exp_and_corresponding_rel_( sql case e_column: if (rel->exps && (is_project(rel->op) || is_base(rel->op))) { if (e->l) { - ne = exps_bind_column2(rel->exps, e->l, e->r); + ne = exps_bind_column2(rel->exps, e->l, e->r, NULL); } else { - ne = exps_bind_column(rel->exps, e->r, NULL, 1); + ne = exps_bind_column(rel->exps, e->r, NULL, NULL, 1); } } if (ne && res) @@ -1592,7 +1592,7 @@ rel_find_exp_and_corresponding_rel(sql_r *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)) + if (rel->exps && e->type == e_column && e->l && exps_bind_column2(rel->exps, e->l, e->r, NULL)) ne = e; if (ne && res) *res = rel; @@ -1604,11 +1604,11 @@ rel_find_exp_and_corresponding_rel(sql_r if (rel->l) 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); + ne = exps_bind_column2(rel->exps, e->l, e->r, NULL); if (ne && res) *res = rel; } else if (rel->exps) { - ne = exps_bind_column(rel->exps, e->r, NULL, 1); + ne = exps_bind_column(rel->exps, e->r, NULL, NULL, 1); if (ne && res) *res = rel; } @@ -1616,7 +1616,7 @@ rel_find_exp_and_corresponding_rel(sql_r break; case op_basetable: if (rel->exps && e->type == e_column && e->l) - ne = exps_bind_column2(rel->exps, e->l, e->r); + ne = exps_bind_column2(rel->exps, e->l, e->r, NULL); if (ne && res) *res = rel; break; @@ -2072,9 +2072,9 @@ exp_key( sql_exp *e ) } sql_exp * -exps_bind_column( list *exps, const char *cname, int *ambiguous, int no_tname) +exps_bind_column(list *exps, const char *cname, int *ambiguous, int *multiple, int no_tname) { - sql_exp *e = NULL; + sql_exp *res = NULL; if (exps && cname) { node *en; @@ -2104,41 +2104,54 @@ exps_bind_column( list *exps, const char sql_hash_e *he = exps->ht->buckets[key&(exps->ht->size-1)]; for (; he; he = he->chain) { - sql_exp *ce = he->value; + sql_exp *e = he->value; - if (ce->alias.name && strcmp(ce->alias.name, cname) == 0 && (!no_tname || !ce->alias.rname)) { - if (e && e != ce && ce->alias.rname && e->alias.rname && strcmp(ce->alias.rname, e->alias.rname) != 0 ) { + if (e->alias.name && strcmp(e->alias.name, cname) == 0 && (!no_tname || !e->alias.rname)) { + if (res && multiple) + *multiple = 1; + if (!res) + res = e; + + if (res && res != e && e->alias.rname && res->alias.rname && strcmp(e->alias.rname, res->alias.rname) != 0 ) { if (ambiguous) *ambiguous = 1; MT_lock_unset(&exps->ht_lock); return NULL; } - e = ce; + res = e; } } MT_lock_unset(&exps->ht_lock); - return e; + return res; } MT_lock_unset(&exps->ht_lock); } for (en = exps->h; en; en = en->next ) { - sql_exp *ce = en->data; - if (ce->alias.name && strcmp(ce->alias.name, cname) == 0 && (!no_tname || !ce->alias.rname)) { - if (e && e != ce && ce->alias.rname && e->alias.rname && strcmp(ce->alias.rname, e->alias.rname) != 0 ) { + sql_exp *e = en->data; + + if (e->alias.name && strcmp(e->alias.name, cname) == 0 && (!no_tname || !e->alias.rname)) { + if (res && multiple) + *multiple = 1; + if (!res) + res = e; + + if (res && res != e && e->alias.rname && res->alias.rname && strcmp(e->alias.rname, res->alias.rname) != 0 ) { if (ambiguous) *ambiguous = 1; return NULL; } - e = ce; + res = e; } } } - return e; + return res; } sql_exp * -exps_bind_column2( list *exps, const char *rname, const char *cname ) +exps_bind_column2(list *exps, const char *rname, const char *cname, int *multiple) { + sql_exp *res = NULL; + if (exps) { node *en; @@ -2148,7 +2161,7 @@ exps_bind_column2( list *exps, const cha exps->ht = hash_new(exps->sa, list_length(exps), (fkeyvalue)&exp_key); if (exps->ht == NULL) { MT_lock_unset(&exps->ht_lock); - return NULL; + return res; } for (en = exps->h; en; en = en->next ) { @@ -2158,7 +2171,7 @@ exps_bind_column2( list *exps, const cha if (hash_add(exps->ht, key, e) == NULL) { MT_lock_unset(&exps->ht_lock); - return NULL; + return res; } } } @@ -2170,24 +2183,30 @@ exps_bind_column2( list *exps, const cha for (; he; he = he->chain) { sql_exp *e = he->value; - if (e && is_column(e->type) && e->alias.name && e->alias.rname && strcmp(e->alias.name, cname) == 0 && strcmp(e->alias.rname, rname) == 0) { - MT_lock_unset(&exps->ht_lock); - return e; + if (e && e->alias.name && e->alias.rname && strcmp(e->alias.name, cname) == 0 && strcmp(e->alias.rname, rname) == 0) { + if (res && multiple) + *multiple = 1; + if (!res) + res = e; } } MT_lock_unset(&exps->ht_lock); - return NULL; + return res; } MT_lock_unset(&exps->ht_lock); } for (en = exps->h; en; en = en->next ) { sql_exp *e = en->data; - if (e && is_column(e->type) && e->alias.name && e->alias.rname && strcmp(e->alias.name, cname) == 0 && strcmp(e->alias.rname, rname) == 0) - return e; + if (e && e->alias.name && e->alias.rname && strcmp(e->alias.name, cname) == 0 && strcmp(e->alias.rname, rname) == 0) { + if (res && multiple) + *multiple = 1; + if (!res) + res = e; + } } } - return NULL; + return res; } /* find an column based on the original name, not the alias it got */ @@ -2296,9 +2315,9 @@ is_identity( sql_exp *e, sql_rel *r) if (r && is_project(r->op)) { sql_exp *re = NULL; if (e->l) - re = exps_bind_column2(r->exps, e->l, e->r); + re = exps_bind_column2(r->exps, e->l, e->r, NULL); if (!re && has_label(e)) - re = exps_bind_column(r->exps, e->r, NULL, 1); + re = exps_bind_column(r->exps, e->r, NULL, NULL, 1); if (re) return is_identity(re, r->l); } 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 @@ -170,9 +170,9 @@ extern int rel_has_all_exps(sql_rel *rel extern sql_rel *find_rel(list *rels, sql_exp *e); extern sql_rel *find_one_rel(list *rels, sql_exp *e); -extern sql_exp *exps_bind_column( list *exps, const char *cname, int *ambiguous, int no_tname /* set if expressions should be without a tname */); -extern sql_exp *exps_bind_column2( list *exps, const char *rname, const char *cname); -extern sql_exp *exps_bind_alias( list *exps, const char *rname, const char *cname); +extern sql_exp *exps_bind_column(list *exps, const char *cname, int *ambiguous, int *multiple, int no_tname /* set if expressions should be without a tname */); +extern sql_exp *exps_bind_column2(list *exps, const char *rname, const char *cname, int *multiple); +extern sql_exp *exps_bind_alias(list *exps, const char *rname, const char *cname); extern unsigned int exps_card( list *l ); extern void exps_fix_card( list *exps, unsigned int card); 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 @@ -50,9 +50,9 @@ name_find_column( sql_rel *rel, const ch sql_exp *e; if (rname) - e = exps_bind_column2(rel->exps, rname, name); + e = exps_bind_column2(rel->exps, rname, name, NULL); else - e = exps_bind_column(rel->exps, name, NULL, 0); + e = exps_bind_column(rel->exps, name, NULL, NULL, 0); if (!e || e->type != e_column) return NULL; if (e->l) @@ -129,14 +129,14 @@ name_find_column( sql_rel *rel, const ch if (!rel->exps) break; if (rname) - alias = exps_bind_column2(rel->exps, rname, name); + alias = exps_bind_column2(rel->exps, rname, name, NULL); else - alias = exps_bind_column(rel->exps, name, NULL, 1); + alias = exps_bind_column(rel->exps, name, NULL, NULL, 1); if (is_groupby(rel->op) && alias && alias->type == e_column && rel->r) { if (alias->l) - alias = exps_bind_column2(rel->r, alias->l, alias->r); + alias = exps_bind_column2(rel->r, alias->l, alias->r, NULL); else - alias = exps_bind_column(rel->r, alias->r, NULL, 1); + alias = exps_bind_column(rel->r, alias->r, NULL, NULL, 1); } if (is_groupby(rel->op) && !alias && rel->l) { /* Group by column not found as alias in projection @@ -197,8 +197,8 @@ list_find_exp( list *exps, sql_exp *e) if (e->type != e_column) return NULL; - if (( e->l && (ne=exps_bind_column2(exps, e->l, e->r)) != NULL) || - ((!e->l && (ne=exps_bind_column(exps, e->r, NULL, 1)) != NULL))) + if (( e->l && (ne=exps_bind_column2(exps, e->l, e->r, NULL)) != NULL) || + ((!e->l && (ne=exps_bind_column(exps, e->r, NULL, NULL, 1)) != NULL))) return ne; return NULL; } _______________________________________________ checkin-list mailing list checkin-list@monetdb.org https://www.monetdb.org/mailman/listinfo/checkin-list