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
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list