Changeset: 3e37f91aafc7 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=3e37f91aafc7
Modified Files:
        sql/server/rel_rel.c
        sql/server/rel_select.c
        sql/server/rel_unnest.c
        sql/test/subquery/Tests/subquery3.stable.out
Branch: default
Log Message:

correctly set the cardinality of set relational operators
properly propagate the has_nil into the aggregators
limit the projection list inside a general unnest to expressions not
in the ad list (ie no freevars)


diffs (229 lines):

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
@@ -441,7 +441,11 @@ rel_setop(sql_allocator *sa, sql_rel *l,
        rel->r = r;
        rel->op = setop;
        rel->exps = NULL;
-       rel->card = CARD_MULTI;
+       if (setop == op_union) {
+               rel->card = CARD_MULTI;
+       } else {
+               rel->card = l->card;
+       }
        if (l && r)
                rel->nrcols = l->nrcols + r->nrcols;
        return rel;
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
@@ -536,7 +536,7 @@ find_table_function_type(mvc *sql, sql_s
                                if (e->card > CARD_ATOM) {
                                        sql_subaggr *zero_or_one = 
sql_bind_aggr(sql->sa, sql->session->schema, "zero_or_one", exp_subtype(e));
 
-                                       e = exp_aggr1(sql->sa, e, zero_or_one, 
0, 0, CARD_ATOM, 0);
+                                       e = exp_aggr1(sql->sa, e, zero_or_one, 
0, 0, CARD_ATOM, has_nil(e));
                                }
                                append(nexps, e);
                        }
@@ -1845,7 +1845,7 @@ static sql_exp*
                                if (table_func && e->card > CARD_ATOM) {
                                        sql_subaggr *zero_or_one = 
sql_bind_aggr(sql->sa, sql->session->schema, "zero_or_one", exp_subtype(e));
 
-                                       e = exp_aggr1(sql->sa, e, zero_or_one, 
0, 0, CARD_ATOM, 0);
+                                       e = exp_aggr1(sql->sa, e, zero_or_one, 
0, 0, CARD_ATOM, has_nil(e));
                                }
                                append(nexps, e);
                        }
@@ -2690,7 +2690,7 @@ rel_unop_(mvc *sql, sql_rel *rel, sql_ex
                if (card == card_relation && e->card > CARD_ATOM) {
                        sql_subaggr *zero_or_one = sql_bind_aggr(sql->sa, 
sql->session->schema, "zero_or_one", exp_subtype(e));
 
-                       e = exp_aggr1(sql->sa, e, zero_or_one, 0, 0, CARD_ATOM, 
0);
+                       e = exp_aggr1(sql->sa, e, zero_or_one, 0, 0, CARD_ATOM, 
has_nil(e));
                }
                return exp_unop(sql->sa, e, f);
        } else if (e) {
@@ -2860,12 +2860,12 @@ rel_binop_(mvc *sql, sql_rel *rel, sql_e
                if (card == card_relation && l->card > CARD_ATOM) {
                        sql_subaggr *zero_or_one = sql_bind_aggr(sql->sa, 
sql->session->schema, "zero_or_one", exp_subtype(l));
 
-                       l = exp_aggr1(sql->sa, l, zero_or_one, 0, 0, CARD_ATOM, 
0);
+                       l = exp_aggr1(sql->sa, l, zero_or_one, 0, 0, CARD_ATOM, 
has_nil(l));
                }
                if (card == card_relation && r->card > CARD_ATOM) {
                        sql_subaggr *zero_or_one = sql_bind_aggr(sql->sa, 
sql->session->schema, "zero_or_one", exp_subtype(r));
 
-                       r = exp_aggr1(sql->sa, r, zero_or_one, 0, 0, CARD_ATOM, 
0);
+                       r = exp_aggr1(sql->sa, r, zero_or_one, 0, 0, CARD_ATOM, 
has_nil(r));
                }
                /* bind types of l and r */
                t1 = exp_subtype(l);
@@ -4661,7 +4661,7 @@ rel_value_exp2(sql_query *query, sql_rel
                                sql_subaggr *zero_or_one = 
sql_bind_aggr(sql->sa, sql->session->schema, "zero_or_one", exp_subtype(e));
 
                                e = exp_ref(sql->sa, e);
-                               e = exp_aggr1(sql->sa, e, zero_or_one, 0, 0, 
CARD_ATOM, 0);
+                               e = exp_aggr1(sql->sa, e, zero_or_one, 0, 0, 
CARD_ATOM, has_nil(e));
                                r = rel_groupby(sql, r, NULL);
                                (void)rel_groupby_add_aggr(sql, r, e);
                        }
@@ -4886,7 +4886,7 @@ rel_having_limits_nodes(sql_query *query
                        if ((ek.card != card_relation && sn->limit) &&
                                (ek.card == card_value && sn->limit)) {
                                sql_subaggr *zero_or_one = 
sql_bind_aggr(sql->sa, sql->session->schema, "zero_or_one", exp_subtype(l));
-                               l = exp_aggr1(sql->sa, l, zero_or_one, 0, 0, 
CARD_ATOM, 0);
+                               l = exp_aggr1(sql->sa, l, zero_or_one, 0, 0, 
CARD_ATOM, has_nil(l));
                        }
                        append(exps, l);
                } else
diff --git a/sql/server/rel_unnest.c b/sql/server/rel_unnest.c
--- a/sql/server/rel_unnest.c
+++ b/sql/server/rel_unnest.c
@@ -601,7 +601,7 @@ rel_general_unnest(mvc *sql, sql_rel *re
                node *n, *m;
                int nr;
 
-               sql_rel *l = rel->l, *r = rel->r;
+               sql_rel *l = rel->l, *r = rel->r, *inner_r;
                /* rewrite T1 dependent join T2 -> T1 join D dependent join T2, 
where the T1/D join adds (equality) predicates (for the Domain (ad)) and D is 
are the distinct(projected(ad) from T1)  */
                sql_rel *D = rel_project(sql->sa, rel_dup(l), exps_copy(sql, 
ad));
                set_distinct(D);
@@ -610,7 +610,26 @@ rel_general_unnest(mvc *sql, sql_rel *re
                r->op = /*is_semi(rel->op)?op_left:*/op_join;
                move_join_exps(sql, rel, r);
                set_dependent(r);
-               r = rel_project(sql->sa, r, 
(is_semi(r->op))?sa_list(sql->sa):rel_projections(sql, r->r, NULL, 1, 1));
+               inner_r = r;
+               r = rel_project(sql->sa, r, 
(is_semi(inner_r->op))?sa_list(sql->sa):rel_projections(sql, r->r, NULL, 1, 1));
+
+               if (!is_semi(inner_r->op))  { /* skip the free vars */
+                       list *exps = sa_list(sql->sa);
+
+                       for(node *n=r->exps->h; n; n = n->next) {
+                               sql_exp *e = n->data, *ne = NULL;
+
+                               if (e->l) {
+                                       ne = exps_bind_column2(ad, e->l, e->r );
+                               } else {
+                                       ne = exps_bind_column(ad, e->r, NULL);
+                               }
+                               if (!ne)
+                                       append(exps,e);
+                       }
+                       r->exps = exps;
+               }
+
                /* append ad + rename */
                nr = sql->label+1;
                sql->label += list_length(ad);
@@ -1897,7 +1916,7 @@ rewrite_anyequal(mvc *sql, sql_rel *rel,
                                        lsq->exps = exps; 
 
                                sql_subaggr *ea = sql_bind_aggr(sql->sa, 
sql->session->schema, is_anyequal(sf)?"anyequal":"allnotequal", 
exp_subtype(re));
-                               sql_exp *a = exp_aggr1(sql->sa, le, ea, 0, 0, 
CARD_AGGR, 0);
+                               sql_exp *a = exp_aggr1(sql->sa, le, ea, 0, 0, 
CARD_AGGR, has_nil(le));
                                append(a->l, re);
                                append(a->l, rid);
                                le = rel_groupby_add_aggr(sql, lsq, a);
@@ -2059,14 +2078,14 @@ rewrite_compare(mvc *sql, sql_rel *rel, 
                                                a = sql_bind_aggr(sql->sa, 
sql->session->schema, "all", exp_subtype(re));
                                                is_cnt = 1;
                                        }
-                                       re = exp_aggr1(sql->sa, re, a, 0, 1, 
CARD_AGGR, 0);
+                                       re = exp_aggr1(sql->sa, re, a, 0, 1, 
CARD_AGGR, has_nil(re));
                                        re = rel_groupby_add_aggr(sql, rsq, re);
                                } else if (rsq && exp_card(re) > CARD_ATOM) { 
                                        sql_subaggr *zero_or_one = 
sql_bind_aggr(sql->sa, NULL, compare_aggr_op(op, quantifier), exp_subtype(re));
        
                                        rsq = rel_groupby(sql, rsq, NULL);
        
-                                       re = exp_aggr1(sql->sa, re, 
zero_or_one, 0, 0, CARD_AGGR, 0);
+                                       re = exp_aggr1(sql->sa, re, 
zero_or_one, 0, 0, CARD_AGGR, has_nil(re));
                                        re = rel_groupby_add_aggr(sql, rsq, re);
                                }
                                if (rsq) 
@@ -2272,7 +2291,7 @@ rewrite_exists(mvc *sql, sql_rel *rel, s
                        if (exp_is_rel(ie)) /* TODO add set rel function */
                                ie->l = sq;
                        ea = sql_bind_aggr(sql->sa, sql->session->schema, 
is_exists(sf)?"exist":"not_exist", exp_subtype(le));
-                       le = exp_aggr1(sql->sa, le, ea, 0, 0, CARD_AGGR, 0);
+                       le = exp_aggr1(sql->sa, le, ea, 0, 0, CARD_AGGR, 
has_nil(le));
                        le = rel_groupby_add_aggr(sql, sq, le);
                        if (rel_has_freevar(sql, sq))
                                ne = le;
diff --git a/sql/test/subquery/Tests/subquery3.stable.out 
b/sql/test/subquery/Tests/subquery3.stable.out
--- a/sql/test/subquery/Tests/subquery3.stable.out
+++ b/sql/test/subquery/Tests/subquery3.stable.out
@@ -249,6 +249,71 @@ stdout of test 'subquery3` in directory 
 [ 1    ]
 [ 1    ]
 [ 1    ]
+#SELECT
+#    1
+#FROM another_T t1
+#GROUP BY t1.col1, t1.col2, t1.col4
+#HAVING (t1.col1 = ANY (SELECT MAX(ColID + col2) FROM tbl_ProductSales)) <
+#    ((SELECT NOT EXISTS (SELECT t1.col2 FROM tbl_ProductSales WHERE 
tbl_ProductSales.ColID = t1.col1)) INTERSECT
+#     (SELECT NOT t1.col1 IN (SELECT MAX(t1.col7) EXCEPT SELECT tp.ColID FROM 
tbl_ProductSales tp)));
+% . # table_name
+% single_value # name
+% tinyint # type
+% 1 # length
+[ 1    ]
+[ 1    ]
+[ 1    ]
+#SELECT
+#    col6,
+#    col7,
+#    NOT SUM(t1.col6) NOT IN (SELECT MAX(t2.col6) FROM another_T t2 GROUP BY 
t1.col6 HAVING t1.col7 < MAX(t1.col6))
+#FROM another_T t1
+#GROUP BY t1.col7, t1.col6;
+% .t1, .t1,    .%15 # table_name
+% col6,        col7,   %15 # name
+% int, int,    boolean # type
+% 4,   4,      5 # length
+[ 6,   7,      false   ]
+[ 66,  77,     false   ]
+[ 666, 777,    false   ]
+[ 6666,        7777,   false   ]
+#SELECT
+#    col6,
+#    col7,
+#    NOT SUM(t1.col6) NOT IN (SELECT MAX(t2.col6) FROM another_T t2 GROUP BY 
t1.col6 HAVING t1.col7 < MAX(t2.col7 - t1.col6))
+#FROM another_T t1
+#GROUP BY t1.col7, t1.col6;
+% .t1, .t1,    .%15 # table_name
+% col6,        col7,   %15 # name
+% int, int,    boolean # type
+% 4,   4,      5 # length
+[ 6,   7,      false   ]
+[ 66,  77,     false   ]
+[ 666, 777,    false   ]
+[ 6666,        7777,   false   ]
+#SELECT
+#    CASE WHEN NULL IN (SELECT MIN(ColID) FROM tbl_ProductSales tp LEFT JOIN 
another_T t2 ON tp.ColID = t1.col1) THEN 1 ELSE 2 END
+#FROM another_T t1
+#GROUP BY t1.col1, t1.col2;
+% .%32 # table_name
+% %32 # name
+% tinyint # type
+% 1 # length
+[ 2    ]
+[ 2    ]
+[ 2    ]
+[ 2    ]
+#SELECT
+#    CASE WHEN NULL NOT IN (SELECT 1 FROM tbl_ProductSales tp FULL OUTER JOIN 
another_T t2 ON tp.ColID = t1.col1) THEN 1 ELSE 2 END
+#FROM another_T t1;
+% .%34 # table_name
+% %34 # name
+% tinyint # type
+% 1 # length
+[ 2    ]
+[ 2    ]
+[ 2    ]
+[ 2    ]
 #DROP TABLE tbl_ProductSales;
 #DROP TABLE another_T;
 
_______________________________________________
checkin-list mailing list
checkin-list@monetdb.org
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to