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

Reply via email to