Changeset: 2cf57a162ab7 for MonetDB URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=2cf57a162ab7 Added Files: sql/test/miscellaneous/Tests/three_level_lookup.sql Modified Files: sql/server/rel_dump.c sql/server/rel_optimizer.c sql/server/rel_rel.c sql/server/rel_rel.h sql/server/rel_select.c sql/test/miscellaneous/Tests/All Branch: groupby-expressions Log Message:
Closing groupby-expressions branch after merge into default diffs (236 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 @@ -816,9 +816,9 @@ exp_read(mvc *sql, sql_rel *lrel, sql_re exp = exp_alias_or_copy(sql, tname, cname, lrel, exp); } if (!exp && lrel) { - exp = rel_bind_column2(sql, lrel, tname, cname, 0); + exp = rel_bind_column23(sql, lrel, NULL, tname, cname, 0); if (!exp && rrel) - exp = rel_bind_column2(sql, rrel, tname, cname, 0); + exp = rel_bind_column23(sql, rrel, NULL, tname, cname, 0); } else if (!exp) { exp = exp_column(sql->sa, tname, cname, NULL, CARD_ATOM, 1, (strchr(cname,'%') != NULL)); } 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 @@ -1229,7 +1229,7 @@ exp_rename(mvc *sql, sql_exp *e, sql_rel return e; e = NULL; if (ne->name && ne->r && ne->l) - e = rel_bind_column2(sql, t, ne->l, ne->r, 0); + e = rel_bind_column23(sql, t, NULL, ne->l, ne->r, 0); if (!e && ne->r) e = rel_bind_column(sql, t, ne->r, 0); if (!e && ne->type == e_column) { @@ -1339,7 +1339,7 @@ static sql_exp * return list_fetch(t->exps, p); } if (e->l) { - ne = rel_bind_column2(sql, f, e->l, e->r, 0); + ne = rel_bind_column23(sql, f, NULL, e->l, e->r, 0); /* if relation name matches expressions relation name, find column based on column name alone */ } if (!ne && !e->l) @@ -1349,16 +1349,16 @@ static sql_exp * e = NULL; /* if (ne->name && ne->rname) - e = rel_bind_column2(sql, t, ne->rname, ne->name, 0); + e = rel_bind_column23(sql, t, NULL, ne->rname, ne->name, 0); if (!e && ne->name && !ne->rname) e = rel_bind_column(sql, t, ne->name, 0); if (!e && ne->name && ne->r && ne->l) - e = rel_bind_column2(sql, t, ne->l, ne->r, 0); + e = rel_bind_column23(sql, t, NULL, ne->l, ne->r, 0); if (!e && ne->r && !ne->l) e = rel_bind_column(sql, t, ne->r, 0); */ if (ne->l && ne->r) - e = rel_bind_column2(sql, t, ne->l, ne->r, 0); + e = rel_bind_column23(sql, t, NULL, ne->l, ne->r, 0); if (!e && ne->r && !ne->l) e = rel_bind_column(sql, t, ne->r, 0); sql->session->status = 0; 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 @@ -280,25 +280,40 @@ rel_bind_column( mvc *sql, sql_rel *rel, } sql_exp * -rel_bind_column2( mvc *sql, sql_rel *rel, const char *tname, const char *cname, int f ) +rel_bind_column23( mvc *sql, sql_rel *rel, const char *sname, const char *tname, const char *cname, int f ) { (void)f; + bool is_table_on_schema = false; if (!rel) return NULL; - if (rel->exps && (is_project(rel->op) || is_base(rel->op))) { + if (sname && is_base(rel->op)) { //sname parameter is optional, if provided then do a schema lookup + if (rel->op == op_basetable) { + sql_table *t = (sql_table*)rel->l; + is_table_on_schema = strcmp(t->s->base.name, sname) == 0; + } else if (rel->op == op_table) { + if (rel->flag == 0) { //table returning function + sql_exp *op = (sql_exp*) rel->r; + sql_func *func = ((sql_subfunc*) op->f)->func; + is_table_on_schema = strcmp(func->s->base.name, sname) == 0; + } + } else { + assert(0); + } + } + if (rel->exps && (((is_project(rel->op) || is_base(rel->op)) && !sname) || is_table_on_schema)) { sql_exp *e = exps_bind_column2(rel->exps, tname, cname); if (e) return exp_alias_or_copy(sql, tname, cname, rel, e); } if (is_project(rel->op) && rel->l) { if (!is_processed(rel)) - return rel_bind_column2(sql, rel->l, tname, cname, f); + return rel_bind_column23(sql, rel->l, sname, tname, cname, f); } else if (is_join(rel->op)) { - sql_exp *e = rel_bind_column2(sql, rel->l, tname, cname, f); + sql_exp *e = rel_bind_column23(sql, rel->l, sname, tname, cname, f); if (!e) - e = rel_bind_column2(sql, rel->r, tname, cname, f); + e = rel_bind_column23(sql, rel->r, sname, tname, cname, f); return e; } else if (is_set(rel->op) || is_sort(rel) || @@ -306,14 +321,14 @@ rel_bind_column2( mvc *sql, sql_rel *rel is_select(rel->op) || is_topn(rel->op)) { if (rel->l) - return rel_bind_column2(sql, rel->l, tname, cname, f); + return rel_bind_column23(sql, rel->l, sname, tname, cname, f); } else if (is_apply(rel->op)) { sql_exp *e = NULL; if (!e && rel->l) - e = rel_bind_column2(sql, rel->l, tname, cname, f); + e = rel_bind_column23(sql, rel->l, sname, tname, cname, f); if (!e && rel->r && (rel->flag == APPLY_JOIN || rel->flag == APPLY_LOJ)) - return rel_bind_column2(sql, rel->r, tname, cname, f); + return rel_bind_column23(sql, rel->r, sname, tname, cname, f); return e; } return NULL; diff --git a/sql/server/rel_rel.h b/sql/server/rel_rel.h --- a/sql/server/rel_rel.h +++ b/sql/server/rel_rel.h @@ -47,7 +47,7 @@ extern sql_rel *rel_copy(sql_allocator * extern sql_rel *rel_select_copy(sql_allocator *sa, sql_rel *l, list *exps); extern sql_exp *rel_bind_column( mvc *sql, sql_rel *rel, const char *cname, int f ); -extern sql_exp *rel_bind_column2( mvc *sql, sql_rel *rel, const char *tname, const char *cname, int f ); +extern sql_exp *rel_bind_column23( mvc *sql, sql_rel *rel, const char *sname, const char *tname, const char *cname, int f ); extern sql_rel *rel_inplace_setop(sql_rel *rel, sql_rel *l, sql_rel *r, operator_type setop, list *exps); extern sql_rel *rel_inplace_project(sql_allocator *sa, sql_rel *rel, sql_rel *l, list *e); 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 @@ -1115,24 +1115,26 @@ rel_column_ref(mvc *sql, sql_rel **rel, return sql_error(sql, 02, SQLSTATE(42000) "SELECT: identifier '%s' unknown", name); } - } else if (dlist_length(l) == 2) { - char *tname = l->h->data.sval; - char *cname = l->h->next->data.sval; + } else if (dlist_length(l) == 2 || dlist_length(l) == 3) { + bool depth2 = dlist_length(l) == 2; + char *sname = depth2 ? NULL : l->h->data.sval; + char *tname = depth2 ? l->h->data.sval : l->h->next->data.sval; + char *cname = depth2 ? l->h->next->data.sval : l->h->next->next->data.sval; if (rel && *rel) - exp = rel_bind_column2(sql, *rel, tname, cname, f); + exp = rel_bind_column23(sql, *rel, sname, tname, cname, f); /* some views are just in the stack, like before and after updates views */ if (rel && !exp && sql->use_views) { - sql_rel *v = stack_find_rel_view(sql, tname); + sql_rel *v = stack_find_rel_view(sql, tname); //schema lookup is not needed here (this is used for with statements) if (v) { if (*rel) *rel = rel_crossproduct(sql->sa, *rel, v, op_join); else *rel = v; - exp = rel_bind_column2(sql, *rel, tname, cname, f); + exp = rel_bind_column23(sql, *rel, sname, tname, cname, f); } } if (!exp) { @@ -1141,15 +1143,15 @@ rel_column_ref(mvc *sql, sql_rel **rel, while(gb->l && !is_groupby(gb->op) && is_project(gb->op)) gb = gb->l; - if (gb && is_groupby(gb->op) && gb->l && rel_bind_column2(sql, gb->l, tname, cname, f)) - return sql_error(sql, 02, SQLSTATE(42000) "SELECT: cannot use non GROUP BY column '%s.%s' in query results without an aggregate function", tname, cname); + if (gb && is_groupby(gb->op) && gb->l && rel_bind_column23(sql, gb->l, sname, tname, cname, f)) + return sql_error(sql, 02, SQLSTATE(42000) "SELECT: cannot use non GROUP BY column '%s%s%s.%s' in query results without an aggregate function", depth2 ? "" : sname, depth2 ? "" : ".", tname, cname); } if (is_sql_having(f)) - return sql_error(sql, 02, SQLSTATE(42S22) "SELECT: cannot use non GROUP BY column '%s.%s' in query results without an aggregate function", tname, cname); - return sql_error(sql, 02, SQLSTATE(42S22) "SELECT: no such column '%s.%s'", tname, cname); - } - } else if (dlist_length(l) >= 3) { - return sql_error(sql, 02, SQLSTATE(42000) "TODO: column names of level >= 3"); + return sql_error(sql, 02, SQLSTATE(42S22) "SELECT: cannot use non GROUP BY column '%s%s%s.%s' in query results without an aggregate function", depth2 ? "" : sname, depth2 ? "" : ".", tname, cname); + return sql_error(sql, 02, SQLSTATE(42S22) "SELECT: no such column '%s%s%s.%s'", depth2 ? "" : sname, depth2 ? "" : ".", tname, cname); + } + } else if (dlist_length(l) > 3) { + assert(0); } return exp; } @@ -4161,7 +4163,7 @@ rel_order_by_simple_column_exp(mvc *sql, char *tname = l->h->data.sval; char *name = l->h->next->data.sval; - e = rel_bind_column2(sql, r, tname, name, sql_sel | sql_orderby); + e = rel_bind_column23(sql, r, NULL, tname, name, sql_sel | sql_orderby); } if (!e) { /* now we need to rewrite r @@ -5179,7 +5181,7 @@ rel_value_exp2(mvc *sql, sql_rel **rel, sql_exp *ne = NULL; if (e->l && e->r) - ne = rel_bind_column2(sql, r, e->l, e->r, 0); + ne = rel_bind_column23(sql, r, NULL, e->l, e->r, 0); else if (!e->l && e->r && /* DISABLES CODE */ (0)) { ne = rel_bind_column(sql, r, e->r, 0); } diff --git a/sql/test/miscellaneous/Tests/All b/sql/test/miscellaneous/Tests/All --- a/sql/test/miscellaneous/Tests/All +++ b/sql/test/miscellaneous/Tests/All @@ -3,3 +3,4 @@ declared_tables trace_test simple_selects groupby_expressions +three_level_lookup diff --git a/sql/test/miscellaneous/Tests/three_level_lookup.sql b/sql/test/miscellaneous/Tests/three_level_lookup.sql new file mode 100644 --- /dev/null +++ b/sql/test/miscellaneous/Tests/three_level_lookup.sql @@ -0,0 +1,11 @@ +start transaction; +create schema testme; +create table sys.testme (aa int); +create table testme.testme (aa int); +insert into sys.testme values (1), (2), (3); +insert into testme.testme values (4), (12); +select sys.testme.aa from sys.testme; +select testme.testme.aa from testme.testme; +select sys.testme.aa, testme.testme.aa from sys.testme, testme.testme; +select count(testme.testme.aa) from sys.testme, testme.testme where sys.testme.aa = 1; +rollback; _______________________________________________ checkin-list mailing list checkin-list@monetdb.org https://www.monetdb.org/mailman/listinfo/checkin-list