Update of /cvsroot/monetdb/sql/src/server
In directory sc8-pr-cvs16.sourceforge.net:/tmp/cvs-serv9286/src/server
Modified Files:
Tag: SQL_2-18
sql_select.mx
Log Message:
cleaned up the IN code (unused case is gone)
give error on Outer reference in selection (fixes crash)
Index: sql_select.mx
===================================================================
RCS file: /cvsroot/monetdb/sql/src/server/sql_select.mx,v
retrieving revision 1.191.2.1
retrieving revision 1.191.2.2
diff -u -d -r1.191.2.1 -r1.191.2.2
--- sql_select.mx 8 Jun 2007 09:48:29 -0000 1.191.2.1
+++ sql_select.mx 21 Jun 2007 08:05:37 -0000 1.191.2.2
@@ -2825,7 +2825,32 @@
return NULL;
}
-static void
+/*
+void
+subset_add_outer(stmt *ptable, stmt *s)
+{
+ while (ptable_parent(ptable))
+ ptable = ptable_parent(ptable);
+
+ if (!ptable_statements(ptable)) {
+ ptable_statements(ptable) = stmt_set(s);
+ } else {
+ stmt *ps = ptable_statements(ptable);
+
+ if (ps->type != st_set) {
+ ps = stmt_set(ps);
+ ptable_statements(ptable) = ps;
+ }
+
+ list_append(ps->op1.lval, s);
+ if (ps->nrcols < s->nrcols)
+ ps->nrcols = s->nrcols;
+ ps->key &= s->key;
+ }
+}
+*/
+
+void
filter(stmt *ptable, stmt *s)
{
@@ -2946,7 +2971,6 @@
}
/* todo keep both sets aligned */
-
if (f == sql_sel || (ls->nrcols <= 0 && rs->nrcols <= 0))
return sql_binop_(sql, NULL, NULL, "or", ls, rs);
@@ -3172,7 +3196,6 @@
if (!ls)
return NULL;
- /* TODO fix parsing, ie subquery seperate from values */
ek.card = card_set;
if (l->h->next->type == type_list) {
dnode *n = l->h->next->data.lval->h;
@@ -3188,7 +3211,47 @@
stmt_destroy(temp);
return NULL;
}
- temp = stmt_append(temp, check_types(sql, ct,
v, type_equal));
+ if (v->type == st_list) {
+ stmt_destroy(temp);
+ if (n->next) {
+ stmt_destroy(ls);
+ return sql_error(sql, 02,
"SELECT: multiple subqueries with outer references in IN is not supported");
+ }
+ if (list_length(v->op1.lval) > 2) {
+ stmt_destroy(v);
+ return sql_error(sql, 02,
"SELECT: comparision between incompatible types");
+ }
+ temp = v;
+ } else {
+ temp = stmt_append(temp,
check_types(sql, ct, v, type_equal));
+ }
+ }
+ /* outer references */
+ if (temp->type == st_list) {
+ //return sql_error(sql, 02, "IN: with outer
references is not supported");
+ node *o = temp->op1.lval->h;
+ stmt *oref = stmt_dup(o->next->data);
+ stmt *sqa = stmt_dup(o->data);
+ stmt *cmp = NULL, *h;
+ char *comp = NULL;
+
+ cmp = stmt_join(stmt_reverse(oref), sqa,
cmp_equal);
+ /* need to fix the cmp head */
+ h = stmt_dup(cmp->h->t);
+ stmt_destroy(cmp->h);
+ cmp->h = h;
+
+ if (sc->token == SQL_IN)
+ comp = "=";
+ else
+ comp = "<>";
+
+ if (subset)
+ cmp = stmt_join(find_pivot(subset,
cmp->h), cmp, cmp_equal);
+ else
+ cmp = stmt_join(scope_find_pivot(scp,
cmp->h), cmp, cmp_equal);
+ cmp = sql_compare(sql, scp, ls, cmp, comp, f);
+ return cmp;
}
if (sc->token == SQL_IN) {
/* predicate case ? */
@@ -3234,100 +3297,6 @@
return stmt_diff(stmt_dup(ls),
stmt_join(ls, stmt_reverse(temp), cmp_equal));
}
}
- } else if (l->h->next->type == type_symbol) {
- symbol *ro = l->h->next->data.sym;
- stmt *sq = scope_subquery(sql, scp, ro, ek);
-
- if (!sq)
- return NULL;
-
- if (sq->type != st_list || list_length(sq->op1.lval) ==
0) {
- stmt_destroy(sq);
- return sql_error(sql, 02, "SELECT: subquery
result wrong");
- }
-
- if (list_length(sq->op1.lval) == 1) {
- stmt *rs = stmt_dup(sq->op1.lval->h->data);
-
- stmt_destroy(sq);
- /* predicate case ? */
- if (ls->nrcols == 0) {
- sql_subtype *tp = tail_type(ls);
- sql_subaggr *exist;
-
- if (sc->token == SQL_IN) {
- /* exist(rs,ls) */
- exist =
sql_bind_aggr(sql->session->schema, "exist", tp);
- } else {
- /* exist(rs,ls) */
- exist =
sql_bind_aggr(sql->session->schema, "not_exist", tp);
- }
- rs = stmt_reverse(rs);
- return stmt_aggr2(rs, ls, exist);
- } else if (f != sql_sel) {
- if (sc->token == SQL_IN) {
- if (rs->nrcols) { /* set
in (select set) */
- return
stmt_reverse(stmt_semijoin(stmt_reverse(ls), stmt_reverse(rs)));
- } else {
- /* v1 in (select v2)
- * and
- * set in (select
value)
- */
- return sql_compare(sql,
scp, ls, rs, "=", f);
- }
- } else { /* SQL_NOT_IN */
- if (rs->nrcols) { /* set
not in (select set) */
- return
stmt_reverse(stmt_diff(stmt_reverse(ls), stmt_reverse(rs)));
- } else {
- /* v1 not in (select
v2)
- * and
- * set not in (select
v1)
- */
- return sql_compare(sql,
scp, ls, rs, "<>", f);
- }
- }
- } else if (ls->nrcols == 0) {
- sql_subtype *tp = tail_type(ls);
- sql_subaggr *exist;
-
- if (sc->token == SQL_IN) {
- /* exist(rs,ls) */
- exist =
sql_bind_aggr(sql->session->schema, "exist", tp);
- } else {
- /* [not_exist](temp,ls) */
- /* not_exit needed to handle
null correctly */
- exist =
sql_bind_aggr(sql->session->schema, "not_exist", tp);
- }
- rs = stmt_reverse(rs);
- return stmt_aggr2(rs, ls, exist);
-
- } else if (rs->nrcols == 0) {
- /* SELECT name [not] in (select 'a') FROM
tables */
- /* single value */
- if (sc->token == SQL_IN) {
- return sql_compare(sql, scp,
ls, rs, "=", f);
- } else {
- return sql_compare(sql, scp,
ls, rs, "<>", f);
- }
- /* set of values */
- } else {
- sql_subtype *bt =
sql_bind_localtype("bit");
- sql_subtype *tp = tail_type(ls);
- sql_subfunc *isnul;
-
- isnul =
sql_bind_func_result(sql->session->schema, "isnull", tp, NULL, bt);
- if (sc->token == SQL_IN) {
- sql_subfunc *not =
sql_bind_func_result(sql->session->schema, "not", bt, NULL, bt);
- return
stmt_unop(stmt_unop(stmt_outerjoin(ls, stmt_reverse(rs), cmp_equal), isnul),
not);
- } else {
- return
stmt_unop(stmt_outerjoin(ls, stmt_reverse(rs), cmp_equal), isnul);
- }
- }
- } else {
- /* TODO fix this broken impl ! */
- return sql_error(sql, 03, "time to implement
(NOT) IN with outer refs\n");
- }
- return NULL;
} else {
return sql_error(sql, 02, "IN: missing inner query");
}
@@ -3836,7 +3805,7 @@
}
}
- if (s && list_length(scp->outers) > 0) {
+ if (s && ek.card != card_set && list_length(scp->outers) > 0) {
assert(!grp);
grp = query_groupby_outers(sql, scp, s);
if (!grp) {
@@ -3883,6 +3852,11 @@
dnode *n;
node *m;
int nrcols = 0, aggr = 0;
+ void *outer = NULL;
+
+
+ if (scp->outers->t)
+ outer = scp->outers->t->data;
for (n = sn->selection->h; n; n = n->next) {
stmt *cs = sql_column_exp(sql, scp, n->data.sym, grp,
subset, sql_sel);
@@ -3898,6 +3872,17 @@
if (nrcols < cs->nrcols)
nrcols = cs->nrcols;
aggr |= cs->aggr;
+
+ if (scp->outers->t && outer != scp->outers->t->data) {
+ /* new outer reference */
+ outer = scp->outers->t->data;
+
+ list_destroy(sl);
+ list_destroy(rl);
+ sql_select_cleanup(sql, s, subset, grp);
+ return sql_error(sql, 02, "SELECT: outer
reference in the selection part is not supported");
+ /*subset_add_outer(subset, outer);*/
+ }
}
for (m = sl->h, n = sn->selection->h; m && n; m = m->next, n =
n->next) {
@@ -4029,7 +4014,10 @@
sql_select_cleanup(sql, s, subset, grp);
return sql_error(sql, 02, "SELECT: subquery
result missing");
}
- list_append(rl, stmt_join(stmt_dup(grp->ext),
foundsubset, cmp_equal));
+ if (ek.card != card_set)
+ list_append(rl, stmt_join(stmt_dup(grp->ext),
foundsubset, cmp_equal));
+ else
+ list_append(rl, foundsubset);
}
}
stmt_destroy(s);
-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
Monetdb-sql-checkins mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/monetdb-sql-checkins