[prev in list] [next in list] [prev in thread] [next in thread] 

List:       monetdb-checkins
Subject:    MonetDB: default - Merge with Nov2019 branch.
From:       Sjoerd Mullender <commits+sjoerd=acm.org () monetdb ! org>
Date:       2019-09-30 12:57:35
Message-ID: hg.9712353dd761.1569848255.6315528441665844383 () monetdb-vm0 ! spin-off ! cwi ! nl
[Download RAW message or body]

Changeset: 9712353dd761 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=9712353dd761
Added Files:
	sql/test/BugTracker-2019/Tests/grant-select-column.Bug-6765.py
	sql/test/BugTracker-2019/Tests/next-get-value-bulk.Bug-6766.sql
	sql/test/BugTracker-2019/Tests/next-get-value-bulk.Bug-6766.stable.out
	sql/test/miscellaneous/Tests/groupby_error.sql
	sql/test/miscellaneous/Tests/groupby_error.stable.err
	sql/test/miscellaneous/Tests/groupby_error.stable.out
Modified Files:
	sql/backends/monet5/sql.c
	sql/include/sql_relation.h
	sql/server/rel_exp.c
	sql/server/rel_exp.h
	sql/server/rel_rel.c
	sql/server/rel_rel.h
	sql/server/rel_select.c
	sql/server/rel_unnest.c
	sql/test/BugTracker-2015/Tests/crash.Bug-3736.stable.out
	sql/test/BugTracker-2019/Tests/All
	sql/test/BugTracker-2019/Tests/correlated-subquery-aggregation.Bug-6714.stable.out
	sql/test/miscellaneous/Tests/All
	sql/test/subquery/Tests/correlated.stable.out
	sql/test/subquery/Tests/subquery2.sql
Branch: default
Log Message:

Merge with Nov2019 branch.


diffs (truncated from 813 to 300 lines):

diff --git a/sql/backends/monet5/sql.c b/sql/backends/monet5/sql.c
--- a/sql/backends/monet5/sql.c
+++ b/sql/backends/monet5/sql.c
@@ -3512,6 +3512,7 @@ SQLnil_grp(bat *ret, const bat *bid, con
 	BAT *l, *g, *e, *res;
 	bit F = FALSE;
 	BUN offset = 0;
+	bit has_nil = 0;
 
 	(void)no_nil;
 	if ((l = BATdescriptor(*bid)) == NULL) {
@@ -3546,14 +3547,16 @@ SQLnil_grp(bat *ret, const bat *bid, con
 			oid id = *(oid*)BUNtail(gi, s);
 
 			if (ret[id] != TRUE) {
-				if (ocmp(lv, nilp) == 0)
-					ret[id] = TRUE;
+				if (ocmp(lv, nilp) == 0) {
+					ret[id] = bit_nil;
+					has_nil = 1;
+				}
 			}
 		}
 	}
 	res->hseqbase = g->hseqbase;
-	res->tnil = 0;
-	res->tnonil = 1;
+	res->tnil = has_nil != 0;
+	res->tnonil = has_nil == 0;
 	res->tsorted = res->trevsorted = 0;
 	res->tkey = 0;
 	BBPunfix(l->batCacheid);
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
@@ -242,18 +242,18 @@ typedef enum operator_type {
 
 /* does the expression (possibly) have nils */
 #define has_nil(e) \
-	((e->flag&HAS_NO_NIL) == 0)
+	(((e)->flag&HAS_NO_NIL) == 0)
 #define set_has_no_nil(e) \
-	e->flag |= HAS_NO_NIL
+	(e)->flag |= HAS_NO_NIL
 #define set_has_nil(e) \
-	e->flag &= (~HAS_NO_NIL)
+	(e)->flag &= (~HAS_NO_NIL)
 
 #define is_ascending(e) \
-	((e->flag&ASCENDING)==ASCENDING)
+	(((e)->flag&ASCENDING)==ASCENDING)
 #define nulls_last(e) \
-	((e->flag&NULLS_LAST)==NULLS_LAST)
+	(((e)->flag&NULLS_LAST)==NULLS_LAST)
 #define set_direction(e, dir) \
-	e->flag |= ((dir&1)?ASCENDING:0) | ((dir&2)?NULLS_LAST:0)
+	(e)->flag |= ((dir&1)?ASCENDING:0) | ((dir&2)?NULLS_LAST:0)
 
 #define is_anti(e) \
 	((e)->anti)
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
@@ -991,7 +991,7 @@ exps_match_col_exps( sql_exp *e1, sql_ex
 	return 0;
 }
 
-static int 
+int 
 exp_match_list( list *l, list *r)
 {
 	node *n, *m;
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
@@ -120,6 +120,8 @@ extern int exp_match_exp( sql_exp *e1, s
 /* 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);
+/* todo rename */
+extern int exp_match_list( list *l, list *r);
 extern int exp_is_join(sql_exp *e, list *rels);
 extern int exp_is_eqjoin(sql_exp *e);
 extern int exp_is_correlation(sql_exp *e, sql_rel *r );
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
@@ -11,6 +11,7 @@
 #include "rel_exp.h"
 #include "rel_prop.h"
 #include "rel_remote.h"
+#include "rel_unnest.h"
 #include "sql_semantic.h"
 #include "sql_mvc.h"
 
@@ -1364,6 +1365,56 @@ rel_add_identity(mvc *sql, sql_rel *rel,
 	return _rel_add_identity(sql, rel, exp);
 }
 
+static sql_rel *
+_rel_add_identity2(mvc *sql, sql_rel *rel, sql_exp **exp)
+{
+	list *exps = rel_projections(sql, rel, NULL, 1, 2);
+	sql_exp *e;
+
+	if (list_length(exps) == 0) {
+		*exp = NULL;
+		return rel;
+	}
+	rel = rel_project(sql->sa, rel, exps);
+	e = rel->exps->h->data;
+	e = exp_column(sql->sa, exp_relname(e), exp_name(e), exp_subtype(e), rel->card, \
has_nil(e), is_intern(e)); +	e = exp_unop(sql->sa, e, sql_bind_func(sql->sa, NULL, \
"identity", exp_subtype(e), NULL, F_FUNC)); +	set_intern(e);
+	e->p = prop_create(sql->sa, PROP_HASHCOL, e->p);
+	*exp = exp_label(sql->sa, e, ++sql->label);
+	(void) rel_project_add_exp(sql, rel, e);
+	return rel;
+}
+
+sql_rel *
+rel_add_identity2(mvc *sql, sql_rel *rel, sql_exp **exp)
+{
+	sql_rel *l = rel, *p = rel;
+
+	if (rel && is_project(rel->op) && (*exp = exps_find_identity(rel->exps, rel->l)) != \
NULL) +		return rel;
+	while(l && !is_set(l->op) && rel_has_freevar(sql, l) && l->l) {
+		p = l;
+		l = l->l;
+	}
+	if (l != p) {
+		sql_rel *o = rel;
+		sql_exp *id;
+
+		p->l = _rel_add_identity2(sql, l, exp);
+		l = p->l;
+		id = exp_ref(sql->sa, *exp);
+		while (o && o != l) {
+			*exp = id;
+			if (is_project(o->op))
+				rel_project_add_exp(sql, o, id);
+			o = o->l;
+		}
+		return rel;
+	}
+	return _rel_add_identity2(sql, rel, exp);
+}
+
 sql_exp *
 rel_find_column( sql_allocator *sa, sql_rel *rel, const char *tname, const char \
*cname )  {
diff --git a/sql/server/rel_rel.h b/sql/server/rel_rel.h
--- a/sql/server/rel_rel.h
+++ b/sql/server/rel_rel.h
@@ -95,6 +95,7 @@ extern sql_rel *rel_or(mvc *sql, sql_rel
 extern sql_table *rel_ddl_table_get(sql_rel *r);
 
 extern sql_rel *rel_add_identity(mvc *sql, sql_rel *rel, sql_exp **exp);
+extern sql_rel *rel_add_identity2(mvc *sql, sql_rel *rel, sql_exp **exp);
 extern sql_exp * rel_find_column( sql_allocator *sa, sql_rel *rel, const char \
*tname, const char *cname );  
 extern int rel_in_rel(sql_rel *super, sql_rel *sub);
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
@@ -1062,16 +1062,16 @@ rel_column_ref(sql_query *query, sql_rel
 			return rel_var_ref(sql, name, 0);
 		}
 		if (!exp && !var) {
-			if (rel && *rel && (*rel)->card <= CARD_AGGR && is_sql_sel(f) && !is_sql_aggr(f)) \
{ +			if (rel && *rel && (*rel)->card <= CARD_AGGR && !is_sql_aggr(f) && \
(is_sql_sel(f) || is_sql_having(f))) {  sql_rel *gb = *rel;
 
-				while(gb->l && !is_groupby(gb->op))
+				while (gb->l && !is_groupby(gb->op))
+					gb = gb->l;
+				if (gb && is_select(gb->op)) /* check for having clause generated selection */
 					gb = gb->l;
 				if (gb && gb->l && rel_bind_column(sql, gb->l, name, f)) 
 					return sql_error(sql, 05, SQLSTATE(42000) "SELECT: cannot use non GROUP BY \
column '%s' in query results without an aggregate function", name);  }
-			if (is_sql_having(f))
-				return sql_error(sql, 05, SQLSTATE(42000) "SELECT: cannot use non GROUP BY \
column '%s' in query results without an aggregate function", name);  return \
sql_error(sql, 02, SQLSTATE(42000) "SELECT: identifier '%s' unknown", name);  }
 		if (exp && rel && *rel && (*rel)->card <= CARD_AGGR && exp->card > CARD_AGGR && \
is_sql_sel(f) && !is_sql_aggr(f)) { @@ -1112,16 +1112,16 @@ rel_column_ref(sql_query \
*query, sql_rel  }
 		}
 		if (!exp) {
-			if (rel && *rel && (*rel)->card == CARD_AGGR && is_sql_sel(f) && !is_sql_aggr(f)) \
{ +			if (rel && *rel && (*rel)->card == CARD_AGGR && !is_sql_aggr(f) && \
(is_sql_sel(f) || is_sql_having(f))) {  sql_rel *gb = *rel;
 
-				while(gb->l && !is_groupby(gb->op) && is_project(gb->op))
+				while (gb->l && !is_groupby(gb->op) && is_project(gb->op))
+					gb = gb->l;
+				if (gb && is_select(gb->op)) /* check for having clause generated selection */
 					gb = gb->l;
 				if (gb && is_groupby(gb->op) && gb->l && rel_bind_column2(sql, gb->l, tname, \
                cname, f))
 					return sql_error(sql, 05, SQLSTATE(42000) "SELECT: cannot use non GROUP BY \
column '%s.%s' in query results without an aggregate function", tname, cname);  }
-			if (is_sql_having(f))
-				return sql_error(sql, 05, SQLSTATE(42S22) "SELECT: cannot use non GROUP BY \
column '%s.%s' in query results without an aggregate function", tname, cname);  \
return sql_error(sql, 02, SQLSTATE(42S22) "SELECT: no such column '%s.%s'", tname, \
cname);  }
 		if (exp && rel && *rel && (*rel)->card == CARD_AGGR && exp->card > CARD_AGGR && \
is_sql_sel(f) && !is_sql_aggr(f)) { @@ -2084,7 +2084,7 @@ rel_in_value_exp(sql_query \
*query, sql_r  z = rel_label(sql, z, 0);
 					r = rel_lastexp(sql, z);
 				}
-				z = rel_add_identity(sql, z, &tid);
+				z = rel_add_identity2(sql, z, &tid);
 				tid = exp_ref(sql->sa, tid);
 				exps = rel_projections(sql, left, NULL, 1/*keep names */, 1);
 				left = rel_add_identity(sql, left, &id);
@@ -2139,7 +2139,7 @@ rel_in_value_exp(sql_query *query, sql_r
 					exps = rel_projections(sql, left, NULL, 1/*keep names */, 1);
 					left = rel_add_identity(sql, left, &id);
 					id = exp_ref(sql->sa, id);
-					z = rel_add_identity(sql, z, &tid);
+					z = rel_add_identity2(sql, z, &tid);
 					tid = exp_ref(sql->sa, tid);
 					left = rel_crossproduct(sql->sa, left, z, is_sql_sel(f)?op_left:op_join);
 					if (rel_has_freevar(sql, z))
@@ -2387,14 +2387,6 @@ rel_logical_value_exp(sql_query *query, 
 				if (r) {
 					rs = rel_lastexp(sql, r);
 
-					if (is_sql_sel(f) && ek.card <= card_column && r->card > CARD_ATOM) {
-						sql_subaggr *zero_or_one = sql_bind_aggr(sql->sa, sql->session->schema, \
                "zero_or_one", exp_subtype(rs));
-						rs = exp_aggr1(sql->sa, rs, zero_or_one, 0, 0, CARD_ATOM, 0);
-
-						r = rel_groupby(sql, r, NULL);
-						rs = rel_groupby_add_aggr(sql, r, rs);
-						rs = exp_ref(sql->sa, rs);
-					}
 					if (quantifier) {
 						/* flatten the quantifier */
 						sql_subaggr *a;
@@ -2416,6 +2408,13 @@ rel_logical_value_exp(sql_query *query, 
 							/* do not skip nulls in case of >,>=,<=,< */
 							//append(rs1->l, exp_atom_bool(sql->sa, 0));
 						rs = rel_groupby_add_aggr(sql, r, rs);
+					} else if (is_sql_sel(f) && ek.card <= card_column && r->card > CARD_ATOM) {
+						sql_subaggr *zero_or_one = sql_bind_aggr(sql->sa, sql->session->schema, \
"zero_or_one", exp_subtype(rs)); +						rs = exp_aggr1(sql->sa, rs, zero_or_one, 0, \
0, CARD_ATOM, 0); +
+						r = rel_groupby(sql, r, NULL);
+						rs = rel_groupby_add_aggr(sql, r, rs);
+						rs = exp_ref(sql->sa, rs);
 					}
 					/* remove empty projects */
 					if (!is_processed(*rel) && is_sql_sel(f) && (*rel)->op == op_project && \
list_length((*rel)->exps) == 0 && !(*rel)->r && (*rel)->l)  @@ -2936,7 +2935,7 @@ \
rel_in_exp(sql_query *query, sql_rel *re  }
 					set_freevar(l);
 					/* label to solve name conflicts with outer query */
-					z = rel_add_identity(sql, z, &tid);
+					z = rel_add_identity2(sql, z, &tid);
 					tid = exp_ref(sql->sa, tid);
 					if (!exp_is_atom(r) && exp_name(r)) {
 						z = rel_label(sql, z, 0);
@@ -4986,7 +4985,7 @@ rel_order_by(sql_query *query, sql_rel *
 					} else if (e->type == e_atom) {
 						return sql_error(sql, 02, SQLSTATE(42000) "order not of type SQL_COLUMN");
 					}
-				} else if (e && exp_card(e) != rel->card) {
+				} else if (e && exp_card(e) > rel->card) {
 					if (e && exp_name(e)) {
 						return sql_error(sql, 05, SQLSTATE(42000) "SELECT: cannot use non GROUP BY \
column '%s' in query results without an aggregate function", exp_name(e));  } else {
@@ -5001,7 +5000,7 @@ rel_order_by(sql_query *query, sql_rel *
 				sql->errstr[0] = '\0';
 
 				e = rel_order_by_simple_column_exp(sql, rel, col);
-				if (e && e->card != rel->card) 
+				if (e && e->card > rel->card) 
 					e = NULL;
 				if (e)
 					e = rel_project_add_exp(sql, rel, e);
@@ -5021,7 +5020,7 @@ rel_order_by(sql_query *query, sql_rel *
 						g = s->l;
 					if (is_groupby(g->op)) { /* check for is processed */
 						e = rel_order_by_column_exp(query, &g, col, sql_sel);
-						if (e && e->card != rel->card && e->card != CARD_ATOM)
+						if (e && e->card > rel->card && e->card != CARD_ATOM)
 							e = NULL;
 						if (e && !is_select(p->op)) {
 							e = rel_project_add_exp(sql, p, e);
@@ -5038,7 +5037,7 @@ rel_order_by(sql_query *query, sql_rel *
 					e = rel_order_by_column_exp(query, &rel, col, f);
 				if (!e)
 					e = rel_order_by_column_exp(query, &rel, col, sql_sel);
-				if (e && e->card != rel->card && e->card != CARD_ATOM)
+				if (e && e->card > rel->card && e->card != CARD_ATOM)
 					e = NULL;
 			}
 			if (!e) 
_______________________________________________
checkin-list mailing list
checkin-list@monetdb.org
https://www.monetdb.org/mailman/listinfo/checkin-list


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic