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
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list