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