Changeset: 1cb74d115c00 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=1cb74d115c00
Removed Files:
sql/test/rdf/Tests/q8_v_small.reqtests
sql/test/rdf/Tests/q8_v_small.sql
sql/test/rdf/Tests/q8_v_small.stable.err
sql/test/rdf/Tests/q8_v_small.stable.out
Modified Files:
monetdb5/modules/mal/mkey.c
monetdb5/modules/mal/pcre.c
sql/server/rel_rel.h
sql/server/rel_select.c
sql/server/rel_updates.c
sql/server/sql_atom.c
sql/server/sql_semantic.c
sql/test/BugTracker-2009/Tests/AVG_of_SQRT.SF-2757642.timeout
sql/test/BugTracker-2015/Tests/window_function_crash.Bug-3861.sql
sql/test/BugTracker-2015/Tests/window_function_crash.Bug-3861.stable.err
sql/test/BugTracker-2015/Tests/window_function_crash.Bug-3861.stable.out
sql/test/merge-partitions/Tests/mergepart20.sql
sql/test/merge-partitions/Tests/mergepart20.stable.out
sql/test/miscellaneous/Tests/simple_selects.sql
sql/test/miscellaneous/Tests/simple_selects.stable.out
sql/test/rdf/Tests/All
sql/test/rdf/Tests/q8_v.stable.err
sql/test/rdf/Tests/q8_v.stable.out
sql/test/rdf/Tests/q8_v.timeout
sql/test/subquery/Tests/correlated.stable.err
sql/test/subquery/Tests/subquery.sql
sql/test/subquery/Tests/subquery.stable.err
sql/test/subquery/Tests/subquery.stable.out
sql/test/subquery/Tests/subquery3.sql
sql/test/subquery/Tests/subquery3.stable.err
sql/test/subquery/Tests/subquery3.stable.out
sql/test/subquery/Tests/subquery4.sql
sql/test/subquery/Tests/subquery4.stable.err
sql/test/subquery/Tests/subquery4.stable.out
Branch: default
Log Message:
Merged with linear-hashing
diffs (truncated from 2627 to 300 lines):
diff --git a/monetdb5/modules/mal/mkey.c b/monetdb5/modules/mal/mkey.c
--- a/monetdb5/modules/mal/mkey.c
+++ b/monetdb5/modules/mal/mkey.c
@@ -51,6 +51,8 @@ MKEYhash(Client cntxt, MalBlkPtr mb, Mal
val= getArgReference(stk,p,1);
switch (ATOMstorage(tpe)) {
case TYPE_void:
+ *res = lng_nil; /* It can be called from SQL */
+ break;
case TYPE_bat:
case TYPE_ptr:
// illegal types, avoid falling into the default case.
diff --git a/monetdb5/modules/mal/pcre.c b/monetdb5/modules/mal/pcre.c
--- a/monetdb5/modules/mal/pcre.c
+++ b/monetdb5/modules/mal/pcre.c
@@ -1542,7 +1542,6 @@ PCREindex(int *res, const pcre *pattern,
#endif
}
-
str
PCREpatindex(int *ret, const str *pat, const str *val)
{
@@ -1550,6 +1549,11 @@ PCREpatindex(int *ret, const str *pat, c
pcre *re = NULL;
char *ppat = NULL, *msg;
+ if (strNil(*pat) || strNil(*val)) {
+ *ret = int_nil;
+ return MAL_SUCCEED;
+ }
+
if ((msg = pat2pcre(&ppat, *pat)) != MAL_SUCCEED)
return msg;
if ((msg = pcre_compile_wrap(&re, ppat, FALSE)) != MAL_SUCCEED) {
@@ -1591,7 +1595,6 @@ PCREquote(str *ret, const str *val)
return MAL_SUCCEED;
}
-
str
PCREsql2pcre(str *ret, const str *pat, const str *esc)
{
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
@@ -13,31 +13,35 @@
#include "sql_relation.h"
#include "sql_semantic.h"
-#define sql_from 1
-#define sql_where 2
-#define sql_sel 4
-#define sql_having 8
-#define sql_orderby 16
-#define sql_groupby 32 //ORed
-#define sql_aggr 64 //ORed
-#define sql_farg 128 //ORed
-#define sql_window 256 //ORed
-#define sql_join 512 //ORed
-#define sql_outer 1024 //ORed
-#define sql_group_totals 2048 //ORed
+#define sql_from (1 << 0)
+#define sql_where (1 << 1)
+#define sql_sel (1 << 2)
+#define sql_having (1 << 3)
+#define sql_orderby (1 << 4)
+#define sql_groupby (1 << 5) //ORed
+#define sql_aggr (1 << 6) //ORed
+#define sql_farg (1 << 7) //ORed
+#define sql_window (1 << 8) //ORed
+#define sql_join (1 << 9) //ORed
+#define sql_outer (1 << 10) //ORed
+#define sql_group_totals (1 << 11) //ORed
+#define sql_update_set (1 << 12) //ORed
+#define sql_update_where (1 << 13) //ORed
-#define is_sql_from(X) ((X & sql_from) == sql_from)
-#define is_sql_where(X) ((X & sql_where) == sql_where)
-#define is_sql_sel(X) ((X & sql_sel) == sql_sel)
-#define is_sql_having(X) ((X & sql_having) == sql_having)
-#define is_sql_orderby(X) ((X & sql_orderby) == sql_orderby)
-#define is_sql_groupby(X) ((X & sql_groupby) == sql_groupby)
-#define is_sql_aggr(X) ((X & sql_aggr) == sql_aggr)
-#define is_sql_farg(X) ((X & sql_farg) == sql_farg)
-#define is_sql_window(X) ((X & sql_window) == sql_window)
-#define is_sql_join(X) ((X & sql_join) == sql_join)
-#define is_sql_outer(X) ((X & sql_outer) == sql_outer)
+#define is_sql_from(X) ((X & sql_from) == sql_from)
+#define is_sql_where(X) ((X & sql_where) == sql_where)
+#define is_sql_sel(X) ((X & sql_sel) == sql_sel)
+#define is_sql_having(X) ((X & sql_having) == sql_having)
+#define is_sql_orderby(X) ((X & sql_orderby) == sql_orderby)
+#define is_sql_groupby(X) ((X & sql_groupby) == sql_groupby)
+#define is_sql_aggr(X) ((X & sql_aggr) == sql_aggr)
+#define is_sql_farg(X) ((X & sql_farg) == sql_farg)
+#define is_sql_window(X) ((X & sql_window) == sql_window)
+#define is_sql_join(X) ((X & sql_join) == sql_join)
+#define is_sql_outer(X) ((X & sql_outer) == sql_outer)
#define is_sql_group_totals(X) ((X & sql_group_totals) == sql_group_totals)
+#define is_sql_update_set(X) ((X & sql_update_set) == sql_update_set)
+#define is_sql_update_where(X) ((X & sql_update_where) == sql_update_where)
#define is_updateble(rel) \
(rel->op == op_basetable || \
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
@@ -3246,6 +3246,13 @@ static sql_exp *
if (uaname)
GDKfree(uaname);
return e;
+ } else if (is_sql_update_where(f)) { /* the is_sql_update_where
test must come before is_sql_where, because is_sql_update_where are handled
with sql_where */
+ char *uaname = GDKmalloc(strlen(aname) + 1);
+ sql_exp *e = sql_error(sql, 02, SQLSTATE(42000) "%s:
aggregate functions not allowed in WHERE clauses inside UPDATE statements (use
subquery)",
+ uaname ? toUpperCopy(uaname,
aname) : aname);
+ if (uaname)
+ GDKfree(uaname);
+ return e;
} else if (is_sql_join(f)) { /* the is_sql_join test must come
before is_sql_where, because the join conditions are handled with sql_where */
char *uaname = GDKmalloc(strlen(aname) + 1);
sql_exp *e = sql_error(sql, 02, SQLSTATE(42000) "%s:
aggregate functions not allowed in JOIN conditions",
@@ -3260,6 +3267,13 @@ static sql_exp *
if (uaname)
GDKfree(uaname);
return e;
+ } else if (is_sql_update_set(f)) {
+ char *uaname = GDKmalloc(strlen(aname) + 1);
+ sql_exp *e = sql_error(sql, 02, SQLSTATE(42000) "%s:
aggregate functions not allowed in UPDATE SET clause (use subquery)",
+ uaname ? toUpperCopy(uaname,
aname) : aname);
+ if (uaname)
+ GDKfree(uaname);
+ return e;
} else if (is_sql_aggr(f)) {
char *uaname = GDKmalloc(strlen(aname) + 1);
sql_exp *e = sql_error(sql, 02, SQLSTATE(42000) "%s:
aggregate functions cannot be nested",
@@ -3301,21 +3315,36 @@ static sql_exp *
all_freevar &= (is_freevar(e)>0);
list_append(exps, e);
}
- if (all_aggr && !all_freevar) {
- char *uaname = GDKmalloc(strlen(aname) + 1);
- sql_exp *e = sql_error(sql, 02, SQLSTATE(42000) "%s:
aggregate functions cannot be nested",
- uaname ? toUpperCopy(uaname, aname) :
aname);
- if (uaname)
- GDKfree(uaname);
- return e;
- }
- if (is_sql_groupby(f) && !all_freevar) {
- char *uaname = GDKmalloc(strlen(aname) + 1);
- sql_exp *e = sql_error(sql, 02, SQLSTATE(42000) "%s:
aggregate function '%s' not allowed in GROUP BY clause",
- uaname ?
toUpperCopy(uaname, aname) : aname, aname);
- if (uaname)
- GDKfree(uaname);
- return e;
+ if (!all_freevar) {
+ if (all_aggr) {
+ char *uaname = GDKmalloc(strlen(aname) + 1);
+ sql_exp *e = sql_error(sql, 02, SQLSTATE(42000)
"%s: aggregate functions cannot be nested",
+ uaname ? toUpperCopy(uaname,
aname) : aname);
+ if (uaname)
+ GDKfree(uaname);
+ return e;
+ } else if (is_sql_groupby(f)) {
+ char *uaname = GDKmalloc(strlen(aname) + 1);
+ sql_exp *e = sql_error(sql, 02, SQLSTATE(42000)
"%s: aggregate function '%s' not allowed in GROUP BY clause",
+ uaname ?
toUpperCopy(uaname, aname) : aname, aname);
+ if (uaname)
+ GDKfree(uaname);
+ return e;
+ } else if (is_sql_join(f)) { /* the is_sql_join test
must come before is_sql_where, because the join conditions are handled with
sql_where */
+ char *uaname = GDKmalloc(strlen(aname) + 1);
+ sql_exp *e = sql_error(sql, 02, SQLSTATE(42000)
"%s: aggregate functions not allowed in JOIN conditions",
+ uaname ?
toUpperCopy(uaname, aname) : aname);
+ if (uaname)
+ GDKfree(uaname);
+ return e;
+ } else if (is_sql_where(f)) {
+ char *uaname = GDKmalloc(strlen(aname) + 1);
+ sql_exp *e = sql_error(sql, 02, SQLSTATE(42000)
"%s: aggregate functions not allowed in WHERE clause",
+ uaname ?
toUpperCopy(uaname, aname) : aname);
+ if (uaname)
+ GDKfree(uaname);
+ return e;
+ }
}
}
@@ -3331,13 +3360,19 @@ static sql_exp *
}
int sql_state = query_fetch_outer_state(query,all_freevar-1);
res = groupby = query_fetch_outer(query, all_freevar-1);
- if (exp && is_sql_aggr(sql_state) && !is_groupby_col(res, exp))
{
- char *uaname = GDKmalloc(strlen(aname) + 1);
- sql_exp *e = sql_error(sql, 05, SQLSTATE(42000) "%s:
aggregate function calls cannot be nested",
- uaname ?
toUpperCopy(uaname, aname) : aname);
- if (uaname)
- GDKfree(uaname);
- return e;
+ if (exp && !is_groupby_col(res, exp)) {
+ if (is_sql_groupby(sql_state))
+ return sql_error(sql, 05, SQLSTATE(42000)
"SELECT: aggregate function '%s' not allowed in GROUP BY clause", aname);
+ if (is_sql_aggr(sql_state))
+ return sql_error(sql, 05, SQLSTATE(42000)
"SELECT: aggregate function calls cannot be nested");
+ if (is_sql_update_where(sql_state))
+ return sql_error(sql, 05, SQLSTATE(42000)
"SELECT: aggregate functions not allowed in WHERE clauses inside UPDATE
statements");
+ if (is_sql_update_set(sql_state))
+ return sql_error(sql, 05, SQLSTATE(42000)
"SELECT: aggregate functions not allowed in UPDATE SET clause");
+ if (is_sql_join(sql_state))
+ return sql_error(sql, 05, SQLSTATE(42000)
"SELECT: aggregate functions not allowed in JOIN conditions");
+ if (is_sql_where(sql_state))
+ return sql_error(sql, 05, SQLSTATE(42000)
"SELECT: aggregate functions not allowed in WHERE clause");
}
}
@@ -4570,9 +4605,10 @@ rel_rankop(sql_query *query, sql_rel **r
is_nth_value = !strcmp(aname, "nth_value");
supports_frames = window_function->token != SQL_RANK || is_nth_value ||
!strcmp(aname, "first_value") || !strcmp(aname, "last_value");
- if (is_sql_join(f) || is_sql_where(f) || is_sql_groupby(f) ||
is_sql_having(f)) {
+ if (is_sql_update_set(f) || is_sql_update_where(f) || is_sql_join(f) ||
is_sql_where(f) || is_sql_groupby(f) || is_sql_having(f)) {
char *uaname = GDKmalloc(strlen(aname) + 1);
- const char *clause = is_sql_join(f)?"JOIN
conditions":is_sql_where(f)?"WHERE clause":is_sql_groupby(f)?"GROUP BY
clause":"HAVING clause";
+ const char *clause = is_sql_update_set(f)?"UPDATE SET clause
(use subquery)":is_sql_update_where(f)?"WHERE clause inside updates (use
subquery)":
+ is_sql_join(f)?"JOIN
conditions":is_sql_where(f)?"WHERE clause":is_sql_groupby(f)?"GROUP BY
clause":"HAVING clause";
(void) sql_error(sql, 02, SQLSTATE(42000) "%s: window function
'%s' not allowed in %s",
uaname ? toUpperCopy(uaname,
aname) : aname, aname, clause);
if (uaname)
diff --git a/sql/server/rel_updates.c b/sql/server/rel_updates.c
--- a/sql/server/rel_updates.c
+++ b/sql/server/rel_updates.c
@@ -964,12 +964,12 @@ update_generate_assignments(sql_query *q
int status = sql->session->status;
exp_kind ek = {type_value,
(single)?card_column:card_relation, FALSE};
- if(single && a->token == SQL_DEFAULT) {
+ if (single && a->token == SQL_DEFAULT) {
char *colname = assignment->h->next->data.sval;
sql_column *col = mvc_bind_column(sql, t,
colname);
if (col->def) {
char *typestr =
subtype2string2(&col->type);
- if(!typestr)
+ if (!typestr)
return sql_error(sql, 02,
SQLSTATE(HY013) MAL_MALLOC_FAIL);
v = rel_parse_val(sql,
sa_message(sql->sa, "select cast(%s as %s);", col->def, typestr), sql->emode,
NULL);
_DELETE(typestr);
@@ -977,7 +977,7 @@ update_generate_assignments(sql_query *q
return sql_error(sql, 02,
SQLSTATE(42000) "%s: column '%s' has no valid default value", action,
col->base.name);
}
} else if (single) {
- v = rel_value_exp(query, &rel_val, a, sql_sel,
ek);
+ v = rel_value_exp(query, &rel_val, a, sql_sel |
sql_update_set, ek);
outer = 1;
} else {
rel_val = rel_subquery(query, NULL, a, ek);
@@ -988,9 +988,9 @@ update_generate_assignments(sql_query *q
assert(!rel_val);
outer = 1;
if (single) {
- v = rel_value_exp(query, &r, a,
sql_sel, ek);
+ v = rel_value_exp(query, &r, a, sql_sel
| sql_update_set, ek);
} else if (!rel_val && r) {
- query_push_outer(query, r, sql_sel);
+ query_push_outer(query, r, sql_sel |
sql_update_set);
rel_val = rel_subquery(query, NULL, a,
ek);
r = query_pop_outer(query);
if (/* DISABLES CODE */ (0) && r) {
@@ -1157,11 +1157,11 @@ update_table(sql_query *query, dlist *qn
if (!table_privs(sql, t, PRIV_SELECT))
return sql_error(sql, 02, SQLSTATE(42000)
"UPDATE: insufficient privileges for user '%s' to update table '%s'",
stack_get_string(sql, "current_user"), tname);
- r = rel_logical_exp(query, NULL, opt_where, sql_where);
+ r = rel_logical_exp(query, NULL, opt_where, sql_where |
sql_update_where);
if (!r) {
sql->errstr[0] = 0;
sql->session->status = status;
- r = rel_logical_exp(query, res, opt_where,
sql_where);
+ r = rel_logical_exp(query, res, opt_where,
sql_where | sql_update_where);
if (!r)
return NULL;
/* handle join */
@@ -1240,7 +1240,7 @@ delete_table(sql_query *query, dlist *qn
if (!table_privs(sql, t, PRIV_SELECT))
return sql_error(sql, 02, SQLSTATE(42000)
"DELETE FROM: insufficient privileges for user '%s' to delete from table '%s'",
stack_get_string(sql, "current_user"), tname);
- r = rel_logical_exp(query, NULL, opt_where, sql_where);
+ r = rel_logical_exp(query, NULL, opt_where, sql_where |
sql_update_where);
if (r) { /* simple predicate which is not using the to
be updated table. We add a select
all */
sql_rel *l = rel_basetable(sql, t, t->base.name
);
@@ -1253,7 +1253,7 @@ delete_table(sql_query *query, dlist *qn
for (node *nn = r->exps->h ; nn ; nn =
nn->next)
exp_setname(sql->sa, (sql_exp*)
nn->data, alias, NULL); //the last parameter is optional, hence NULL
}
- r = rel_logical_exp(query, r, opt_where,
sql_where);
+ r = rel_logical_exp(query, r, opt_where,
sql_where | sql_update_where);
}
if (!r)
return NULL;
@@ -1412,7 +1412,7 @@ merge_into_table(sql_query *query, dlist
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list