Changeset: e19db285059e for MonetDB URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=e19db285059e Modified Files: sql/server/rel_psm.c sql/server/rel_select.c sql/server/rel_unnest.c sql/test/subquery/Tests/all.stable.out sql/test/subquery/Tests/any_all.stable.out sql/test/subquery/Tests/subquery2.stable.out sql/test/subquery/Tests/subquery3.stable.out Branch: sq2 Log Message:
subquery tests are passing, but some others need work.. diffs (truncated from 391 to 300 lines): diff --git a/sql/server/rel_psm.c b/sql/server/rel_psm.c --- a/sql/server/rel_psm.c +++ b/sql/server/rel_psm.c @@ -89,6 +89,7 @@ psm_set_exp(sql_query *query, dnode *n) if (!e) return NULL; + /* if (rel || exp_is_rel(e)) { sql_exp *er = rel?exp_rel(sql, rel):e; list *b = sa_list(sql->sa); @@ -99,8 +100,9 @@ psm_set_exp(sql_query *query, dnode *n) append(b, exp_set(sql->sa, name, e, level)); res = exp_rel(sql, rel_psm_block(sql->sa, b)); } else { + */ res = exp_set(sql->sa, name, e, level); - } + //} } else { /* multi assignment */ exp_kind ek = {type_value, card_relation, FALSE}; sql_rel *rel_val = rel_subquery(query, NULL, val, ek); @@ -109,6 +111,8 @@ psm_set_exp(sql_query *query, dnode *n) node *n; list *b; + assert(0); + if (!rel_val || !is_project(rel_val->op) || dlist_length(vars) != list_length(rel_val->exps)) return sql_error(sql, 02, SQLSTATE(42000) "SET: Number of variables not equal to number of supplied values"); 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 @@ -3454,6 +3454,7 @@ static sql_exp * if (!group && !all_freevar) return e; if (all_freevar) { + exps_reset_freevar(exps); if (is_simple_project(res->op)) { assert(0); e = rel_project_add_exp(sql, res, e); 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 @@ -1122,7 +1122,7 @@ rel_general_unnest(mvc *sql, sql_rel *re set_distinct(D); r = rel_crossproduct(sql->sa, D, r, rel->op); - r->op = is_semi(rel->op)?op_left:op_join; + 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)); @@ -1217,7 +1217,7 @@ rel_unnest_dependent(mvc *sql, sql_rel * if (rel_has_freevar(sql, r)) { list *ad = rel_dependent_var(sql, rel->l, rel->r); - if (r && is_simple_project(r->op)) { + if (r && is_simple_project(r->op) && (!exps_have_freevar(sql, r->exps) || is_distinct_set(sql, l, ad))) { rel = push_up_project(sql, rel, ad); return rel_unnest_dependent(sql, rel); } @@ -1253,7 +1253,7 @@ rel_unnest_dependent(mvc *sql, sql_rel * } /* fallback */ - if ((ad = rel_dependent_var(sql, rel->l, rel->r)) != NULL) + if (ad != NULL) rel = rel_general_unnest(sql, rel, ad); /* no dependent variables */ @@ -1431,6 +1431,36 @@ rewrite_exp_rel(mvc *sql, sql_rel *rel, return e; } +#define is_not_func(sf) (strcmp(sf->func->base.name, "not") == 0) + +/* simplify expressions, such as not(not(x)) */ +/* exp visitor */ +static sql_exp * +rewrite_simplify_exp(mvc *sql, sql_rel *rel, sql_exp *e, int depth) +{ + if (!e) + return e; + + (void)sql; (void)rel; (void)depth; + + sql_subfunc *sf = e->f; + if (is_func(e->type) && list_length(e->l) == 1 && is_not_func(sf)) { + list *args = e->l; + sql_exp *ie = args->h->data; + + if (!ie) + return e; + + sql_subfunc *sf = ie->f; + if (is_func(ie->type) && list_length(ie->l) == 1 && is_not_func(sf)) { + args = ie->l; + + return args->h->data; + } + } + return e; +} + /* add an dummy true projection column */ static sql_rel * rewrite_empty_project(mvc *sql, sql_rel *rel) @@ -1770,7 +1800,7 @@ rewrite_anyequal(mvc *sql, sql_rel *rel, rsq = rel_union_exps(sql, &le, re->f, is_tuple); re = rsq->exps->t->data; - if (!is_tuple) { + if (!is_tuple && !is_freevar(re)) { re = exp_label(sql->sa, re, ++sql->label); /* unique name */ list_hash_clear(rsq->exps); re = exp_ref(sql->sa, re); @@ -1968,12 +1998,14 @@ rewrite_compare(mvc *sql, sql_rel *rel, if (is_notequal_func(sf)) op = "="; - if (op[0] == '<') + if (op[0] == '<') { a = sql_bind_aggr(sql->sa, sql->session->schema, (quantifier==1)?"max":"min", exp_subtype(re)); - else if (op[0] == '>') + } else if (op[0] == '>') { a = sql_bind_aggr(sql->sa, sql->session->schema, (quantifier==1)?"min":"max", exp_subtype(re)); - else /* (op[0] == '=')*/ /* only = ALL */ + } else /* (op[0] == '=')*/ /* only = ALL */ { 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_ATOM, 0); re = rel_groupby_add_aggr(sql, rsq, re); } else if (rsq && exp_card(re) > CARD_ATOM) { @@ -2303,6 +2335,7 @@ sql_rel * rel_unnest(mvc *sql, sql_rel *rel) { rel_reset_subquery(rel); + rel = rel_exp_visitor(sql, rel, &rewrite_simplify_exp); rel = rel_visitor(sql, rel, &rewrite_aggregates); rel = rel_visitor(sql, rel, &rewrite_or_exp); rel = rel_exp_visitor(sql, rel, &rewrite_rank); diff --git a/sql/test/subquery/Tests/all.stable.out b/sql/test/subquery/Tests/all.stable.out --- a/sql/test/subquery/Tests/all.stable.out +++ b/sql/test/subquery/Tests/all.stable.out @@ -86,7 +86,7 @@ stdout of test 'all` in directory 'sql/t % 1 # length [ 1 ] #SELECT i FROM integers WHERE i = ALL(SELECT i FROM integers WHERE i=1); -- 1 -% sys.integers # table_name +% .integers # table_name % i # name % int # type % 1 # length @@ -99,7 +99,7 @@ stdout of test 'all` in directory 'sql/t [ 2 ] [ 3 ] #SELECT i FROM integers WHERE i = ALL(SELECT i FROM integers WHERE i IS NOT NULL); -- empty -% sys.integers # table_name +% .integers # table_name % i # name % int # type % 1 # length diff --git a/sql/test/subquery/Tests/any_all.stable.out b/sql/test/subquery/Tests/any_all.stable.out --- a/sql/test/subquery/Tests/any_all.stable.out +++ b/sql/test/subquery/Tests/any_all.stable.out @@ -183,7 +183,7 @@ stdout of test 'any_all` in directory 's [ 2 ] [ 3 ] #SELECT i FROM integers i1 WHERE i<>ANY(SELECT i FROM integers WHERE i=i1.i) ORDER BY i; -% sys.i1 # table_name +% .i1 # table_name % i # name % int # type % 1 # length @@ -296,20 +296,20 @@ stdout of test 'any_all` in directory 's [ NULL ] [ NULL ] #SELECT MIN(i)>ANY(SELECT i FROM integers WHERE i>MIN(i1.i)) FROM integers i1; -% .L22 # table_name -% L22 # name +% .L21 # table_name +% L21 # name % boolean # type % 5 # length [ false ] #SELECT SUM(i)>ANY(SELECT i FROM integers WHERE i>MIN(i1.i)) FROM integers i1; -% .L22 # table_name -% L22 # name +% .L21 # table_name +% L21 # name % boolean # type % 5 # length [ true ] #SELECT (SELECT SUM(i)+SUM(i1.i) FROM integers)>ANY(SELECT i FROM integers WHERE i>MIN(i1.i)) FROM integers i1; -% .L33 # table_name -% L33 # name +% .L36 # table_name +% L36 # name % boolean # type % 5 # length [ true ] diff --git a/sql/test/subquery/Tests/subquery2.stable.out b/sql/test/subquery/Tests/subquery2.stable.out --- a/sql/test/subquery/Tests/subquery2.stable.out +++ b/sql/test/subquery/Tests/subquery2.stable.out @@ -102,8 +102,8 @@ stdout of test 'subquery2` in directory #SELECT # EXISTS (SELECT col2 FROM tbl_ProductSales WHERE tbl_ProductSales.ColID = another_T.col1) #FROM another_T GROUP BY col1, col2, col5, col8; -% .L20 # table_name -% L20 # name +% .L17 # table_name +% L17 # name % boolean # type % 5 # length [ true ] @@ -114,8 +114,8 @@ stdout of test 'subquery2` in directory # -col1 IN (SELECT ColID FROM tbl_ProductSales), # col5 = ALL (SELECT 1 FROM tbl_ProductSales HAVING MIN(col8) IS NULL) #FROM another_T GROUP BY col1, col2, col5, col8; -% .L13, .L43 # table_name -% L13, L43 # name +% .L13, .L42 # table_name +% L13, L42 # name % boolean, boolean # type % 5, 5 # length [ false, true ] @@ -128,8 +128,8 @@ stdout of test 'subquery2` in directory # (SELECT MAX(ColID + col2) FROM tbl_ProductSales) * DENSE_RANK() OVER (PARTITION BY AVG(DISTINCT col5)) #FROM another_T #GROUP BY col1, col2, col5, col8; -% .L62, .L4, .L64 # table_name -% L62, L4, L64 # name +% .L57, .L4, .L61 # table_name +% L57, L4, L61 # name % boolean, bigint, hugeint # type % 5, 4, 4 # length [ false, 1, 6 ] @@ -163,8 +163,8 @@ stdout of test 'subquery2` in directory [ true, false ] [ true, false ] #SELECT NOT col2 <> ANY (SELECT 20 FROM tbl_ProductSales GROUP BY ColID HAVING NOT MAX(col1) <> col1 * AVG(col1 + ColID) * ColID) FROM another_T GROUP BY col1, col2, col5, col8; -% .L33 # table_name -% L33 # name +% .L32 # table_name +% L32 # name % boolean # type % 5 # length [ true ] @@ -178,8 +178,8 @@ stdout of test 'subquery2` in directory # NOT EXISTS (SELECT ColID - 12 FROM tbl_ProductSales GROUP BY ColID HAVING MAX(col2) IS NULL OR NOT col8 <> 2 / col1) #FROM another_T #GROUP BY col1, col2, col5, col8; -% .L170, .L171, .L172, .L173 # table_name -% L170, L171, L172, L173 # name +% .L161, .L162, .L163, .L164 # table_name +% L161, L162, L163, L164 # name % boolean, boolean, boolean, boolean # type % 5, 5, 5, 5 # length [ false, true, true, true ] @@ -192,8 +192,8 @@ stdout of test 'subquery2` in directory # NOT AVG(col2) * col1 <> ANY (SELECT 20 FROM tbl_ProductSales HAVING MAX(col1) IS NOT NULL OR MIN(col1) < MIN(col2)), # CAST (NOT col1 IN (SELECT col2 FROM another_T GROUP BY col2) AS INTEGER) | CAST (col2 IN (SELECT col2 FROM another_T GROUP BY col2) AS INTEGER), # CAST (EXISTS (SELECT MAX(col5) * MAX(col4) FROM another_T GROUP BY col5, col4) AS INTEGER) & CAST (AVG(col1) IN (SELECT DISTINCT col2 FROM another_T GROUP BY col2) AS INTEGER) -% .L140, .L141, .L142, .L143 # table_name -% L140, L141, L142, L143 # name +% .L135, .L136, .L137, .L140 # table_name +% L135, L136, L137, L140 # name % boolean, boolean, int, int # type % 5, 5, 1, 1 # length [ true, false, 1, 0 ] @@ -225,8 +225,8 @@ stdout of test 'subquery2` in directory # t1.col1 = ALL (SELECT col4 + SUM(t1.col5) FROM another_T INNER JOIN tbl_ProductSales ON another_T.col1 = tbl_ProductSales.ColID) #FROM another_T t1 #GROUP BY t1.col1; -% .L23 # table_name -% L23 # name +% .L22 # table_name +% L22 # name % boolean # type % 5 # length [ false ] @@ -240,8 +240,8 @@ stdout of test 'subquery2` in directory # t1.col6 IN (SELECT SUM(t1.col7) FROM tbl_ProductSales) #FROM another_T t1 #GROUP BY t1.col6, t1.col7; -% .L20, .L33, .L46, .L60 # table_name -% L20, L33, L46, L60 # name +% .L20, .L32, .L44, .L55 # table_name +% L20, L32, L44, L55 # name % boolean, boolean, boolean, boolean # type % 5, 5, 5, 5 # length [ true, true, false, false ] @@ -266,10 +266,10 @@ stdout of test 'subquery2` in directory #FROM another_T #GROUP BY col1 #HAVING NOT col1 <> ANY (SELECT 0 FROM tbl_ProductSales GROUP BY ColID HAVING NOT MAX(col1) <> col1 * AVG(col1 + ColID) * ColID); -% sys.L34 # table_name _______________________________________________ checkin-list mailing list checkin-list@monetdb.org https://www.monetdb.org/mailman/listinfo/checkin-list