Changeset: 20ef7e69f853 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=20ef7e69f853
Modified Files:
        MonetDB.spec
        common/stream/stream.h
        common/utils/mstring.h
        sql/include/sql_relation.h
        sql/server/rel_select.c
        sql/server/rel_unnest.c
        sql/test/BugTracker-2017/Tests/groupby_assertion.Bug-6338.stable.err
        sql/test/mergetables/Tests/sqlsmith-exists.stable.out
        sql/test/subquery/Tests/subquery5.sql
        sql/test/subquery/Tests/subquery5.stable.err
        sql/test/subquery/Tests/subquery5.stable.out
        tools/merovingian/daemon/forkmserver.c
Branch: default
Log Message:

Merged with Jun2020


diffs (truncated from 412 to 300 lines):

diff --git a/MonetDB.spec b/MonetDB.spec
--- a/MonetDB.spec
+++ b/MonetDB.spec
@@ -649,7 +649,9 @@ Recommends: %{name}-SQL-server5-hugeint%
 Suggests: %{name}-client%{?_isa} = %{version}-%{release}
 %endif
 %if %{?rhel:0}%{!?rhel:1} || 0%{?rhel} >= 7
-%systemd_requires
+Requires(post): systemd
+Requires(preun): systemd
+Requires(postun): systemd
 %endif
 
 %description SQL-server5
diff --git a/common/stream/stream.h b/common/stream/stream.h
--- a/common/stream/stream.h
+++ b/common/stream/stream.h
@@ -54,18 +54,11 @@ typedef __int128_t hge;
 /* Defines to help the compiler check printf-style format arguments.
  * These defines are also in our config.h, but we repeat them here so
  * that we don't need that for this file.*/
-#if !defined(__GNUC__) || __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 5)
+#ifndef __GNUC__
 /* This feature is available in gcc versions 2.5 and later.  */
 # ifndef __attribute__
 #  define __attribute__(Spec)  /* empty */
 # endif
-#else
-/* The __-protected variants of `format' and `printf' attributes are
- * accepted by gcc versions 2.6.4 (effectively 2.7) and later.  */
-# if !defined(__format__) && (__GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ 
< 7))
-#  define __format__ format
-#  define __printf__ printf
-# endif
 #endif
 #if !defined(_MSC_VER) && !defined(_In_z_)
 # define _In_z_
diff --git a/common/utils/mstring.h b/common/utils/mstring.h
--- a/common/utils/mstring.h
+++ b/common/utils/mstring.h
@@ -12,7 +12,8 @@
 #include <stdarg.h>            /* va_list etc. */
 #include <string.h>            /* strlen */
 
-#ifdef __GNUC__
+#if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 
4))
+/* not on CentOS 6 (GCC 4.4.7) */
 #define GCC_Pragma(pragma)     _Pragma(pragma)
 #else
 #define GCC_Pragma(pragma)
diff --git a/sql/include/sql_relation.h b/sql/include/sql_relation.h
--- a/sql/include/sql_relation.h
+++ b/sql/include/sql_relation.h
@@ -246,6 +246,9 @@ typedef enum operator_type {
 #define is_dependent(rel)      ((rel)->dependent)
 #define set_dependent(rel)     (rel)->dependent = 1
 #define reset_dependent(rel)   (rel)->dependent = 0
+#define is_outer(rel)          ((rel)->outer)
+#define set_outer(rel)         (rel)->outer = 1
+#define reset_outer(rel)       (rel)->outer = 0
 
 #define is_freevar(e)          ((e)->freevar)
 #define set_freevar(e,level)   (e)->freevar = level+1
@@ -267,6 +270,7 @@ typedef struct relation {
         dependent:1,   /* dependent join */
         distinct:1,    
         processed:1,   /* fully processed or still in the process of building 
*/
+        outer:1,       /* used as outer (ungrouped) */
         grouped:1,     /* groupby processed all the group by exps */
         subquery:1;    /* is this part a subquery, this is needed for proper 
name binding */
        void *p;        /* properties for the optimizer, distribution */
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
@@ -1197,6 +1197,8 @@ rel_column_ref(sql_query *query, sql_rel
                                else
                                        exp->card = CARD_ATOM;
                                set_freevar(exp, i);
+                               if (!is_sql_aggr(f) && !outer->grouped)
+                                       set_outer(outer);
                        }
                        if (exp && outer && is_join(outer->op))
                                set_dependent(outer);
@@ -1263,6 +1265,8 @@ rel_column_ref(sql_query *query, sql_rel
                                else
                                        exp->card = CARD_ATOM;
                                set_freevar(exp, i);
+                               if (!is_sql_aggr(f) && !outer->grouped)
+                                       set_outer(outer);
                        }
                        if (exp && outer && is_join(outer->op))
                                set_dependent(outer);
@@ -3475,6 +3479,8 @@ static sql_exp *
                                sql_exp *lu = query_outer_last_used(query, 
all_freevar-1);
                                return sql_error(sql, ERR_GROUPBY, 
SQLSTATE(42000) "SELECT: subquery uses ungrouped column \"%s.%s\" from outer 
query", exp_relname(lu), exp_name(lu));
                        }
+                       if (is_outer(groupby))
+                               return sql_error(sql, ERR_GROUPBY, 
SQLSTATE(42000) "SELECT: subquery uses ungrouped column from outer query");
                }
        }
 
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
@@ -1316,17 +1316,21 @@ push_up_set(mvc *sql, sql_rel *rel, list
                        set_dependent(n);
                        s->l = rel;
                        s->r = n;
-                       sexps = sa_list(sql->sa);
-                       for (m = d->exps->h; m; m = m->next) { 
-                               sql_exp *e = m->data, *pe;
-
-                               pe = exp_ref(sql, e);
-                               append(sexps, pe);
+                       if (is_join(rel->op)) {
+                               sexps = sa_list(sql->sa);
+                               for (m = d->exps->h; m; m = m->next) { 
+                                       sql_exp *e = m->data, *pe;
+       
+                                       pe = exp_ref(sql, e);
+                                       append(sexps, pe);
+                               }
+                               s->exps = list_merge(sexps, s->exps, 
(fdup)NULL);
                        }
-                       s->exps = list_merge(sexps, s->exps, (fdup)NULL);
-                       /* add projections to inner parts of the union */
+                       /* add/remove projections to inner parts of the union 
(as we push a join or semijoin down) */
                        s->l = rel_project(sql->sa, s->l, rel_projections(sql, 
s->l, NULL, 1, 1));
                        s->r = rel_project(sql->sa, s->r, rel_projections(sql, 
s->r, NULL, 1, 1));
+                       if (is_semi(rel->op))
+                               s->exps = rel_projections(sql, s->r, NULL, 1, 
1);
                        return s;
                }
        }
@@ -2467,7 +2471,7 @@ rewrite_exists(mvc *sql, sql_rel *rel, s
                                le = rel_nop_(sql, NULL, jc, null, le, NULL, 
NULL, "ifthenelse", card_value);
                        }
 
-                       if (is_project(rel->op) || depth > 0) {
+                       if (is_project(rel->op) || depth > 0 || 
is_outerjoin(rel->op)) {
                                sql_subfunc *ea = NULL;
                                sq = rel_groupby(sql, sq, NULL);
 
@@ -2785,6 +2789,65 @@ rewrite_groupings(mvc *sql, sql_rel *rel
        return rel;
 }
 
+static int
+include_tid(sql_rel *r)
+{
+       if (is_basetable(r->op))
+               r->nrcols = list_length(r->exps);
+       return r->nrcols;
+}
+
+static sql_rel *
+rewrite_outer2inner_union(mvc *sql, sql_rel *rel, int *changes)
+{
+       if (is_outerjoin(rel->op) && !list_empty(rel->exps) && 
rel_has_freevar(sql,rel)) {
+               sql_exp *f = exp_atom_bool(sql->sa, 0);
+               int nrcols = rel->nrcols;
+
+               (void)changes;
+               nrcols = include_tid(rel->l);
+               nrcols += include_tid(rel->r);
+               rel->nrcols = nrcols;
+               if (is_left(rel->op)) {
+                       sql_rel *except = rel_setop(sql->sa, rel_dup(rel->l), 
rel_project(sql->sa, rel_dup(rel), rel_projections(sql, rel->l, NULL, 1, 1)), 
op_except);
+                       except->exps = rel_projections(sql, rel->l, NULL, 1, 1);
+                       sql_rel *nrel = rel_crossproduct(sql->sa, except, 
rel_dup(rel->r),  op_left);
+                       rel_join_add_exp(sql->sa, nrel, f);
+                       rel->op = op_join;
+                       nrel = rel_setop(sql->sa, rel, nrel, op_union);
+                       rel_set_exps(nrel, rel_projections(sql, rel, NULL, 1, 
1));
+                       return nrel;
+               } else if (is_right(rel->op)) {
+                       sql_rel *except = rel_setop(sql->sa, rel_dup(rel->r), 
rel_project(sql->sa, rel_dup(rel), rel_projections(sql, rel->r, NULL, 1, 1)), 
op_except);
+                       except->exps = rel_projections(sql, rel->r, NULL, 1, 1);
+                       sql_rel *nrel = rel_crossproduct(sql->sa, 
rel_dup(rel->l), except, op_right);
+                       rel_join_add_exp(sql->sa, nrel, f);
+                       rel->op = op_join;
+                       nrel = rel_setop(sql->sa, rel, nrel, op_union);
+                       rel_set_exps(nrel, rel_projections(sql, rel, NULL, 1, 
1));
+                       return nrel;
+               } else if (is_full(rel->op)) {
+                       sql_rel *except = rel_setop(sql->sa, rel_dup(rel->l), 
rel_project(sql->sa, rel_dup(rel), rel_projections(sql, rel->l, NULL, 1, 1)), 
op_except);
+                       except->exps = rel_projections(sql, rel->l, NULL, 1, 1);
+                       sql_rel *lrel = rel_crossproduct(sql->sa, except, 
rel_dup(rel->r),  op_left);
+                       rel_join_add_exp(sql->sa, lrel, f);
+
+                       except = rel_setop(sql->sa, rel_dup(rel->r), 
rel_project(sql->sa, rel_dup(rel), rel_projections(sql, rel->r, NULL, 1, 1)), 
op_except);
+                       except->exps = rel_projections(sql, rel->r, NULL, 1, 1);
+                       sql_rel *rrel = rel_crossproduct(sql->sa, 
rel_dup(rel->l), except, op_right);
+                       rel_join_add_exp(sql->sa, rrel, f);
+                       lrel = rel_setop(sql->sa, lrel, rrel, op_union);
+                       rel_set_exps(lrel, rel_projections(sql, rel, NULL, 1, 
1));
+                       rel->op = op_join;
+                       lrel = rel_setop(sql->sa, rel, lrel, op_union);
+                       rel_set_exps(lrel, rel_projections(sql, rel, NULL, 1, 
1));
+                       return lrel;
+               }
+       }
+       return rel;
+}
+
+
 sql_rel *
 rel_unnest(mvc *sql, sql_rel *rel)
 {
@@ -2799,6 +2862,7 @@ rel_unnest(mvc *sql, sql_rel *rel)
                rel = rel_visitor_bottomup(sql, rel, &rel_remove_empty_select, 
&changes);
        rel = rel_visitor_bottomup(sql, rel, &rewrite_aggregates, &changes);
        rel = rel_exp_visitor_bottomup(sql, rel, &rewrite_rank);
+       rel = rel_visitor_bottomup(sql, rel, &rewrite_outer2inner_union, 
&changes);     
        rel = rel_exp_visitor_bottomup(sql, rel, &rewrite_anyequal);
        rel = rel_exp_visitor_bottomup(sql, rel, &rewrite_exists);
        rel = rel_exp_visitor_bottomup(sql, rel, &rewrite_compare);
diff --git 
a/sql/test/BugTracker-2017/Tests/groupby_assertion.Bug-6338.stable.err 
b/sql/test/BugTracker-2017/Tests/groupby_assertion.Bug-6338.stable.err
--- a/sql/test/BugTracker-2017/Tests/groupby_assertion.Bug-6338.stable.err
+++ b/sql/test/BugTracker-2017/Tests/groupby_assertion.Bug-6338.stable.err
@@ -36,7 +36,7 @@ QUERY = insert into source_attr select  
                   c.type,null 
                        from sys.tables as T, sys.columns as C 
                        where T.id = C.table_id and T.name = 'source_ac_0';
-ERROR = !SELECT: cannot use non GROUP BY column 'c.type' in query results 
without an aggregate function
+ERROR = !SELECT: subquery uses ungrouped column from outer query
 CODE  = 42000
 
 # 16:45:11 >  
diff --git a/sql/test/mergetables/Tests/sqlsmith-exists.stable.out 
b/sql/test/mergetables/Tests/sqlsmith-exists.stable.out
--- a/sql/test/mergetables/Tests/sqlsmith-exists.stable.out
+++ b/sql/test/mergetables/Tests/sqlsmith-exists.stable.out
@@ -141,8 +141,8 @@ stdout of test 'sqlsmith-exists` in dire
 # where ref_1.aa is null))
 # right join tab2 as ref_2
 # on (ref_0.col1 = ref_2.col0 );
-% . # table_name
-% single_value # name
+% .%27 # table_name
+% %27 # name
 % tinyint # type
 % 1 # length
 [ 1    ]
@@ -161,8 +161,8 @@ stdout of test 'sqlsmith-exists` in dire
 # tbl_ProductSales as ref_3
 # where ref_1.aa is null))
 # on (ref_0.col1 = ref_2.col0 );
-% . # table_name
-% single_value # name
+% .%41 # table_name
+% %41 # name
 % tinyint # type
 % 1 # length
 [ 1    ]
@@ -198,7 +198,7 @@ stdout of test 'sqlsmith-exists` in dire
 # where ref_1.aa is null))
 # on (ref_0.col1 = ref_2.col0 )
 # inner join tab0 as ref_4
-% sys.,        sys.,   .,      sys.,   sys.,   sys.,   sys.,   sys. # 
table_name
+% .,   .,      .,      .,      .,      .,      .,      . # table_name
 % c0,  c1,     c2,     c3,     c4,     c5,     c6,     c7 # name
 % int, int,    int,    int,    int,    int,    int,    int # type
 % 1,   1,      1,      1,      1,      1,      1,      1 # length
diff --git a/sql/test/subquery/Tests/subquery5.sql 
b/sql/test/subquery/Tests/subquery5.sql
--- a/sql/test/subquery/Tests/subquery5.sql
+++ b/sql/test/subquery/Tests/subquery5.sql
@@ -195,6 +195,15 @@ SELECT 1 FROM integers i1 RIGHT OUTER JO
        -- 1
        -- 1
 
+SELECT (SELECT 1 FROM integers i2 INNER JOIN integers i3 ON i1.i = 1) = 
(SELECT 1 FROM integers i2 INNER JOIN integers i3 ON MIN(i1.i) = 1) FROM 
integers i1;
+       --error, subquery uses ungrouped column "i1.i" from outer query
+
+SELECT (SELECT i1.i) = (SELECT SUM(i1.i)) FROM integers i1;
+       --error, subquery uses ungrouped column "i1.i" from outer query
+
+SELECT (VALUES(col1)), (VALUES(MAX(col2))) FROM another_t;
+       --error, subquery uses ungrouped column "another_t.col1" from outer 
query
+
 DROP FUNCTION evilfunction(INT);
 DROP TABLE tbl_ProductSales;
 DROP TABLE another_T;
diff --git a/sql/test/subquery/Tests/subquery5.stable.err 
b/sql/test/subquery/Tests/subquery5.stable.err
--- a/sql/test/subquery/Tests/subquery5.stable.err
+++ b/sql/test/subquery/Tests/subquery5.stable.err
@@ -130,6 +130,18 @@ MAPI  = (monetdb) /var/tmp/mtest-146231/
 QUERY = SELECT 1 FROM integers CROSS JOIN integers; --error table integers 
specified more than once
 ERROR = !SELECT: 'integers' on both sides of the CROSS JOIN expression
 CODE  = 42000
+MAPI  = (monetdb) /var/tmp/mtest-108024/.s.monetdb.38590
+QUERY = SELECT (SELECT 1 FROM integers i2 INNER JOIN integers i3 ON i1.i = 1) 
= (SELECT 1 FROM integers i2 INNER JOIN integers i3 ON MIN(i1.i) = 1) FROM 
integers i1;
+ERROR = !SELECT: subquery uses ungrouped column from outer query
+CODE  = 42000
+MAPI  = (monetdb) /var/tmp/mtest-295615/.s.monetdb.33475
+QUERY = SELECT (SELECT i1.i) = (SELECT SUM(i1.i)) FROM integers i1;
+ERROR = !SELECT: subquery uses ungrouped column from outer query
+CODE  = 42000
+MAPI  = (monetdb) /var/tmp/mtest-295615/.s.monetdb.33475
+QUERY = SELECT (VALUES(col1)), (VALUES(MAX(col2))) FROM another_t;
+ERROR = !SELECT: subquery uses ungrouped column from outer query
_______________________________________________
checkin-list mailing list
checkin-list@monetdb.org
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to