Changeset: 29ec5d6aa7c5 for MonetDB URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=29ec5d6aa7c5 Modified Files: sql/server/rel_exp.c sql/server/rel_exp.h sql/server/rel_rel.c sql/test/BugTracker-2015/Tests/crash_in_reduce_groupby.Bug-3818.sql sql/test/BugTracker-2015/Tests/crash_in_reduce_groupby.Bug-3818.stable.out sql/test/miscellaneous/Tests/groupby_expressions.sql sql/test/miscellaneous/Tests/groupby_expressions.stable.out Branch: octbugs Log Message:
Be more precise looking for identical grouping columns when building a group by relation. Also check for expression properties when attempting to match diffs (241 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 @@ -1091,15 +1091,20 @@ exp_cmp( sql_exp *e1, sql_exp *e2) return (e1 == e2)?0:-1; } +#define alias_cmp(e1, e2) \ + do { \ + if (e1->alias.rname && e2->alias.rname && strcmp(e1->alias.rname, e2->alias.rname) == 0) \ + return strcmp(e1->alias.name, e2->alias.name); \ + if (!e1->alias.rname && !e2->alias.rname && e1->alias.label == e2->alias.label && e1->alias.name && e2->alias.name) \ + return strcmp(e1->alias.name, e2->alias.name); \ + } while (0); + int exp_equal( sql_exp *e1, sql_exp *e2) { if (e1 == e2) return 0; - if (e1->alias.rname && e2->alias.rname && strcmp(e1->alias.rname, e2->alias.rname) == 0) - return strcmp(e1->alias.name, e2->alias.name); - if (!e1->alias.rname && !e2->alias.rname && e1->alias.label == e2->alias.label && e1->alias.name && e2->alias.name) - return strcmp(e1->alias.name, e2->alias.name); + alias_cmp(e1, e2); return -1; } @@ -1288,6 +1293,9 @@ exp_match_exp( sql_exp *e1, sql_exp *e2) { if (exp_match(e1, e2)) return 1; + if (e1->ascending != e2->ascending || e1->nulls_last != e2->nulls_last || e1->zero_if_empty != e2->zero_if_empty || + e1->anti != e2->anti || e1->semantics != e2->semantics || e1->distinct != e2->distinct) + return 0; if (e1->type == e2->type) { switch(e1->type) { case e_cmp: @@ -1300,7 +1308,7 @@ exp_match_exp( sql_exp *e1, sql_exp *e2) exp_match_list(e1->l, e2->l) && exp_match_list(e1->r, e2->r)) return 1; - else if (e1->flag == e2->flag && is_anti(e1) == is_anti(e2) && + else if (e1->flag == e2->flag && (e1->flag == cmp_in || e1->flag == cmp_notin) && exp_match_exp(e1->l, e2->l) && exp_match_list(e1->r, e2->r)) @@ -1357,6 +1365,27 @@ exps_any_match(list *l, sql_exp *e) } static int +exp_no_alias(sql_exp *e1, sql_exp *e2) +{ + alias_cmp(e1, e2); + /* at least one of the expressions don't have an alias, so there's a match */ + return 0; +} + +sql_exp * +exps_any_match_same_or_no_alias(list *l, sql_exp *e) +{ + if (!l) + return NULL; + for (node *n = l->h; n ; n = n->next) { + sql_exp *ne = (sql_exp *) n->data; + if ((exp_match(ne, e) || exp_refers(ne, e) || exp_match_exp(ne, e)) && exp_no_alias(e, ne) == 0) + return ne; + } + return NULL; +} + +static int exps_are_joins( list *l ) { if (l) diff --git a/sql/server/rel_exp.h b/sql/server/rel_exp.h --- a/sql/server/rel_exp.h +++ b/sql/server/rel_exp.h @@ -135,6 +135,7 @@ extern int exp_match( sql_exp *e1, sql_e extern sql_exp* exps_find_exp( list *l, sql_exp *e); extern int exp_match_exp( sql_exp *e1, sql_exp *e2); extern sql_exp* exps_any_match(list *l, sql_exp *e); +extern sql_exp *exps_any_match_same_or_no_alias(list *l, sql_exp *e); /* match just the column (cmp equality) expressions */ extern int exp_match_col_exps( sql_exp *e, list *l); extern int exps_match_col_exps( sql_exp *e1, sql_exp *e2); 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 @@ -862,11 +862,9 @@ rel_groupby(mvc *sql, sql_rel *l, list * list *gexps = sa_list(sql->sa); for (en = groupbyexps->h; en; en = en->next) { - sql_exp *e = en->data, *ne; + sql_exp *e = en->data; - if ((ne=exps_find_exp(gexps, e)) == NULL || - strcmp(exp_relname(e),exp_relname(ne)) != 0 || - strcmp(exp_name(e),exp_name(ne)) != 0 ) + if (!exps_any_match_same_or_no_alias(gexps, e)) append(gexps, e); } groupbyexps = gexps; diff --git a/sql/test/BugTracker-2015/Tests/crash_in_reduce_groupby.Bug-3818.sql b/sql/test/BugTracker-2015/Tests/crash_in_reduce_groupby.Bug-3818.sql --- a/sql/test/BugTracker-2015/Tests/crash_in_reduce_groupby.Bug-3818.sql +++ b/sql/test/BugTracker-2015/Tests/crash_in_reduce_groupby.Bug-3818.sql @@ -14,5 +14,9 @@ SELECT 0 AS cods, 0 AS elrik, 0 AS ether FROM t2a GROUP BY cods, elrik, ether, jaelen, sora; +PLAN SELECT 0 AS cods, 0 AS elrik, 0 AS ether, 0 AS jaelen, 0 AS sora, cast( SUM(tib0) as bigint) + FROM t2a +GROUP BY cods, elrik, ether, jaelen, sora; + drop table t2a; drop table t1a; diff --git a/sql/test/BugTracker-2015/Tests/crash_in_reduce_groupby.Bug-3818.stable.out b/sql/test/BugTracker-2015/Tests/crash_in_reduce_groupby.Bug-3818.stable.out --- a/sql/test/BugTracker-2015/Tests/crash_in_reduce_groupby.Bug-3818.stable.out +++ b/sql/test/BugTracker-2015/Tests/crash_in_reduce_groupby.Bug-3818.stable.out @@ -37,17 +37,29 @@ stdout of test 'crash_in_reduce_groupby. # SELECT 0 AS cods, 0 AS elrik, 0 AS ether, 0 AS jaelen, 0 AS sora, cast( SUM(tib0) as bigint) # FROM t2a # GROUP BY cods, elrik, ether, jaelen, sora; -% .%7, .%7, .%7, .%7, .%7, .%7 # table_name -% cods, elrik, ether, jaelen, sora, %1 # name +% .%11, .%11, .%11, .%11, .%11, .%11 # table_name +% cods, elrik, ether, jaelen, sora, %2 # name % int, int, int, int, int, bigint # type % 1, 1, 1, 1, 1, 1 # length #SELECT 0 AS cods, 0 AS elrik, 0 AS ether, 0 AS jaelen, 0 AS sora, cast( SUM(tib0) as bigint) # FROM t2a #GROUP BY cods, elrik, ether, jaelen, sora; -% ., ., ., ., ., sys.%1 # table_name -% cods, elrik, ether, jaelen, sora, %1 # name +% ., ., ., ., ., sys.%2 # table_name +% cods, elrik, ether, jaelen, sora, %2 # name % tinyint, tinyint, tinyint, tinyint, tinyint, bigint # type % 1, 1, 1, 1, 1, 1 # length +#PLAN SELECT 0 AS cods, 0 AS elrik, 0 AS ether, 0 AS jaelen, 0 AS sora, cast( SUM(tib0) as bigint) +# FROM t2a +#GROUP BY cods, elrik, ether, jaelen, sora; +% .plan # table_name +% rel # name +% clob # type +% 180 # length +project ( +| group by ( +| | table(sys.t2a) [ "t2a"."tib0" ] COUNT +| ) [ tinyint "0" as "sora" ] [ tinyint "0" as "cods", tinyint "0" as "elrik", tinyint "0" as "ether", tinyint "0" as "jaelen", "sora", sys.sum no nil ("t2a"."tib0") as "%1"."%1" ] +) [ "cods", "elrik", "ether", "jaelen", "sora", bigint["%1"."%1"] as "%2"."%2" ] #drop table t2a; #drop table t1a; diff --git a/sql/test/miscellaneous/Tests/groupby_expressions.sql b/sql/test/miscellaneous/Tests/groupby_expressions.sql --- a/sql/test/miscellaneous/Tests/groupby_expressions.sql +++ b/sql/test/miscellaneous/Tests/groupby_expressions.sql @@ -4,6 +4,8 @@ start transaction; insert into "groupings" values (1, 1), (2, 2), (1, 3); select cast("aa"+1 as bigint) from "groupings" group by "aa"+1; select cast("aa"+1 as bigint) from "groupings" group by "aa"+1, "aa"+1; +plan select cast("aa"+1 as bigint) from "groupings" group by "aa"+1, "aa"+1; + select cast(("aa"+1) + ("bb"+1) as bigint) from "groupings" group by "aa"+1, "bb"+1; select cast(("aa"+1) + ("bb"+1) as bigint) from "groupings" group by ("aa"+1) + ("bb"+1); diff --git a/sql/test/miscellaneous/Tests/groupby_expressions.stable.out b/sql/test/miscellaneous/Tests/groupby_expressions.stable.out --- a/sql/test/miscellaneous/Tests/groupby_expressions.stable.out +++ b/sql/test/miscellaneous/Tests/groupby_expressions.stable.out @@ -83,6 +83,18 @@ stdout of test 'groupby_expressions` in % 1 # length [ 2 ] [ 3 ] +#plan select cast("aa"+1 as bigint) from "groupings" group by "aa"+1, "aa"+1; +% .plan # table_name +% rel # name +% clob # type +% 96 # length +project ( +| group by ( +| | project ( +| | | table(sys.groupings) [ "groupings"."aa" ] COUNT +| | ) [ bigint["groupings"."aa"] as "%2"."%2", sys.sql_add("%2"."%2", bigint "1") as "%1"."%1" ] +| ) [ "%1"."%1" ] [ "%1"."%1" ] +) [ "%1"."%1" ] #select cast(("aa"+1) + ("bb"+1) as bigint) from "groupings" group by "aa"+1, "bb"+1; % sys.%3 # table_name % %3 # name @@ -264,8 +276,8 @@ stdout of test 'groupby_expressions` in % 1 # length [ 3 ] #select "aa" + "bb" from "groupings" order by case when "aa" > 1 then "aa" else "aa" + 10 end; -% sys.%2 # table_name -% %2 # name +% sys.%1 # table_name +% %1 # name % bigint # type % 1 # length [ 4 ] @@ -278,8 +290,8 @@ stdout of test 'groupby_expressions` in % 2 # length [ 10 ] #select "aa" + "bb" from "groupings" order by "aa" between "bb" and NULL; -% sys.%2 # table_name -% %2 # name +% sys.%1 # table_name +% %1 # name % bigint # type % 1 # length [ 2 ] @@ -329,8 +341,8 @@ stdout of test 'groupby_expressions` in [ 2 ] [ 4 ] #select 1 from "groupings" group by "aa" + "bb" order by "aa" + "bb"; -% .%3 # table_name -% %3 # name +% .%2 # table_name +% %2 # name % tinyint # type % 1 # length [ 1 ] @@ -344,16 +356,16 @@ stdout of test 'groupby_expressions` in [ 2, 2, 4 ] [ 1, 3, 4 ] #select sumints("aa","bb") from "groupings" order by "aa" > "bb" or "aa" < "bb", sumints("aa","bb"); -% sys.%2 # table_name -% %2 # name +% sys.%1 # table_name +% %1 # name % int # type % 1 # length [ 2 ] [ 4 ] [ 4 ] #select 1 order by 1 < any(select sum("bb") from "groupings"); -% .%2 # table_name -% %2 # name +% .%1 # table_name +% %1 # name % tinyint # type % 1 # length [ 1 ] _______________________________________________ checkin-list mailing list checkin-list@monetdb.org https://www.monetdb.org/mailman/listinfo/checkin-list