Changeset: 565ac0732555 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=565ac0732555
Modified Files:
        sql/server/rel_exp.c
        sql/server/rel_select.c
        sql/test/subquery/Tests/subquery6.stable.err
Branch: default
Log Message:

Cleaning cardinalities for IN/ANY operators. Look for the cardinalities of the 
right expressions, excluding the relation ones


diffs (133 lines):

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
@@ -224,10 +224,19 @@ sql_exp *
 exp_in(sql_allocator *sa, sql_exp *l, list *r, int cmptype)
 {
        sql_exp *e = exp_create(sa, e_cmp);
+       unsigned int exps_card = CARD_ATOM;
 
        if (e == NULL)
                return NULL;
-       e->card = l->card;
+
+       /* ignore the cardinalites of sub-relations */
+       for (node *n = r->h; n ; n = n->next) {
+               sql_exp *next = n->data;
+
+               if (!exp_is_rel(next) && exps_card < next->card)
+                       exps_card = next->card;
+       }
+       e->card = MAX(l->card, exps_card);
        e->l = l;
        e->r = r;
        assert( cmptype == cmp_in || cmptype == cmp_notin);
@@ -245,16 +254,26 @@ exp_in_func(mvc *sql, sql_exp *le, sql_e
                list *l = exp_get_values(e);
                e = l->h->data;
        }
-       if (anyequal)
-               a_func = sql_bind_func(sql->sa, sql->session->schema, 
"sql_anyequal", exp_subtype(e), exp_subtype(e), F_FUNC);
-       else
-               a_func = sql_bind_func(sql->sa, sql->session->schema, 
"sql_not_anyequal", exp_subtype(e), exp_subtype(e), F_FUNC);
-
+       a_func = sql_bind_func(sql->sa, sql->session->schema, anyequal ? 
"sql_anyequal" : "sql_not_anyequal", exp_subtype(e), exp_subtype(e), F_FUNC);
        if (!a_func)
                return sql_error(sql, 02, SQLSTATE(42000) "(NOT) IN operator on 
type %s missing", exp_subtype(le)->type->sqlname);
        e = exp_binop(sql->sa, le, vals, a_func);
-       if (e)
-               e->card = le->card;
+       if (e) {
+               unsigned int exps_card = CARD_ATOM;
+
+               /* ignore the cardinalites of sub-relations */
+               if (vals->type == e_atom && vals->f) {
+                       for (node *n = ((list*)vals->f)->h ; n ; n = n->next) {
+                               sql_exp *next = n->data;
+
+                               if (!exp_is_rel(next) && exps_card < next->card)
+                                       exps_card = next->card;
+                       }
+               } else if (!exp_is_rel(vals))
+                       exps_card = vals->card;
+
+               e->card = MAX(le->card, exps_card);
+       }
        return e;
 }
 
@@ -268,10 +287,8 @@ exp_compare_func(mvc *sql, sql_exp *le, 
        e = exp_binop(sql->sa, le, re, cmp_func);
        if (e) {
                e->flag = quantifier;
-               if (quantifier)
-                       e->card = le->card; /* At ANY and ALL operators, the 
cardinality on the right side is ignored */
-               else
-                       e->card = MAX(le->card, re->card);
+               /* At ANY and ALL operators, the cardinality on the right side 
is ignored if it is a sub-relation */
+               e->card = quantifier && exp_is_rel(re) ? le->card : 
MAX(le->card, re->card);
        }
        return 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
@@ -1928,18 +1928,6 @@ rel_in_value_exp(sql_query *query, sql_r
                        append(vals, re);
                }
 
-               if (rel && *rel)
-                       for (node *n = vals->h ; n ; n = n->next) {
-                               sql_exp *e = n->data;
-
-                               if (!exp_is_rel(e) && e->card > (*rel)->card) {
-                                       if (exp_name(e))
-                                               return sql_error(sql, 
ERR_GROUPBY, SQLSTATE(42000) "SELECT: cannot use non GROUP BY column '%s' in 
query results without an aggregate function", exp_name(e));
-                                       else
-                                               return sql_error(sql, 
ERR_GROUPBY, SQLSTATE(42000) "SELECT: cannot use non GROUP BY column in query 
results without an aggregate function");
-                               }
-                       }
-
                values = exp_values(sql->sa, vals);
                exp_label(sql->sa, values, ++sql->label);
                if (is_tuple) {
@@ -1979,8 +1967,6 @@ rel_in_value_exp(sql_query *query, sql_r
                if (!e)
                        e = exp_in_func(sql, le, values, (sc->token == SQL_IN), 
is_tuple);
        }
-       if (e && le)
-               e->card = le->card;
        return e;
 }
 
diff --git a/sql/test/subquery/Tests/subquery6.stable.err 
b/sql/test/subquery/Tests/subquery6.stable.err
--- a/sql/test/subquery/Tests/subquery6.stable.err
+++ b/sql/test/subquery/Tests/subquery6.stable.err
@@ -25,7 +25,7 @@ QUERY = SELECT i FROM integers i1 WHERE 
 ERROR = !GDK reported error: mergejoin: more than one match
 MAPI  = (monetdb) /var/tmp/mtest-308774/.s.monetdb.32939
 QUERY = SELECT 1 IN (col4, MIN(col2)) FROM another_t;
-ERROR = !SELECT: cannot use non GROUP BY column 'col4' in query results 
without an aggregate function
+ERROR = !SELECT: cannot use non GROUP BY column in query results without an 
aggregate function
 CODE  = 42000
 MAPI  = (monetdb) /var/tmp/mtest-25203/.s.monetdb.33709
 QUERY = SELECT (SELECT col1) IN ('not a number') FROM another_t;
@@ -54,6 +54,18 @@ ERROR = !GDK reported error: BATsubcross
 MAPI  = (monetdb) /var/tmp/mtest-184851/.s.monetdb.32392
 QUERY = SELECT debugme5(); --error, cannot fetch a single row from an empty 
input
 ERROR = !Illegal argument: cannot fetch a single row from an empty input
+MAPI  = (monetdb) /var/tmp/mtest-137383/.s.monetdb.39088
+QUERY = select 1 = any(ColID), max(totalsales) from tbl_ProductSales;
+ERROR = !SELECT: cannot use non GROUP BY column in query results without an 
aggregate function
+CODE  = 42000
+MAPI  = (monetdb) /var/tmp/mtest-137383/.s.monetdb.39088
+QUERY = select 1 in (ColID), max(totalsales) from tbl_ProductSales;
+ERROR = !SELECT: cannot use non GROUP BY column in query results without an 
aggregate function
+CODE  = 42000
+MAPI  = (monetdb) /var/tmp/mtest-137383/.s.monetdb.39088
+QUERY = select 1 in (ColID, (select 1)), max(totalsales) from tbl_ProductSales;
+ERROR = !SELECT: cannot use non GROUP BY column in query results without an 
aggregate function
+CODE  = 42000
 
 # 11:45:43 >  
 # 11:45:43 >  "Done."
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to