Changeset: 9dce3e2e40ae for MonetDB URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=9dce3e2e40ae 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/atoms/json.c 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: timezone Log Message:
Merge with default branch. diffs (truncated from 2713 to 300 lines): diff --git a/monetdb5/modules/atoms/json.c b/monetdb5/modules/atoms/json.c --- a/monetdb5/modules/atoms/json.c +++ b/monetdb5/modules/atoms/json.c @@ -837,7 +837,7 @@ JSONtoken(JSON *jt, const char *j, const if (jt->error) return idx; if (jt->elm[nxt].kind != JSON_ELEMENT) { - jt->error = createException(MAL, "json.parser", "JSON syntax error: element expected at offset %ld", j - string_start); + jt->error = createException(MAL, "json.parser", "JSON syntax error: element expected at offset %td", j - string_start); return idx; } JSONappend(jt, idx, nxt); @@ -848,13 +848,13 @@ JSONtoken(JSON *jt, const char *j, const if (*j == '}') break; if (*j != '}' && *j != ',') { - jt->error = createException(MAL, "json.parser", "JSON syntax error: ',' or '}' expected at offset %ld", j - string_start); + jt->error = createException(MAL, "json.parser", "JSON syntax error: ',' or '}' expected at offset %td", j - string_start); return idx; } j++; } if (*j != '}') { - jt->error = createException(MAL, "json.parser", "JSON syntax error: '}' expected at offset %ld", j - string_start); + jt->error = createException(MAL, "json.parser", "JSON syntax error: '}' expected at offset %td", j - string_start); return idx; } else j++; @@ -905,18 +905,18 @@ JSONtoken(JSON *jt, const char *j, const if (*j == ']') break; if (jt->elm[nxt].kind == JSON_ELEMENT) { - jt->error = createException(MAL, "json.parser", "JSON syntax error: Array value expected at offset %ld", j - string_start); + jt->error = createException(MAL, "json.parser", "JSON syntax error: Array value expected at offset %td", j - string_start); return idx; } if (*j != ']' && *j != ',') { - jt->error = createException(MAL, "json.parser", "JSON syntax error: ',' or ']' expected at offset %ld (context: %c%c%c)", j - string_start, *(j - 1), *j, *(j + 1)); + jt->error = createException(MAL, "json.parser", "JSON syntax error: ',' or ']' expected at offset %td (context: %c%c%c)", j - string_start, *(j - 1), *j, *(j + 1)); return idx; } j++; skipblancs(j); } if (*j != ']') { - jt->error = createException(MAL, "json.parser", "JSON syntax error: ']' expected at offset %ld", j - string_start); + jt->error = createException(MAL, "json.parser", "JSON syntax error: ']' expected at offset %td", j - string_start); } else j++; *next = j; @@ -953,7 +953,7 @@ JSONtoken(JSON *jt, const char *j, const jt->elm[idx].valuelen = 4; return idx; } - jt->error = createException(MAL, "json.parser", "JSON syntax error: NULL expected at offset %ld", j - string_start); + jt->error = createException(MAL, "json.parser", "JSON syntax error: NULL expected at offset %td", j - string_start); return idx; case 't': if (strncmp("true", j, 4) == 0) { @@ -963,7 +963,7 @@ JSONtoken(JSON *jt, const char *j, const jt->elm[idx].valuelen = 4; return idx; } - jt->error = createException(MAL, "json.parser", "JSON syntax error: True expected at offset %ld", j - string_start); + jt->error = createException(MAL, "json.parser", "JSON syntax error: True expected at offset %td", j - string_start); return idx; case 'f': if (strncmp("false", j, 5) == 0) { @@ -973,7 +973,7 @@ JSONtoken(JSON *jt, const char *j, const jt->elm[idx].valuelen = 5; return idx; } - jt->error = createException(MAL, "json.parser", "JSON syntax error: False expected at offset %ld", j - string_start); + jt->error = createException(MAL, "json.parser", "JSON syntax error: False expected at offset %td", j - string_start); return idx; default: if (*j == '-' || isdigit((unsigned char) *j)) { @@ -985,7 +985,7 @@ JSONtoken(JSON *jt, const char *j, const jt->elm[idx].valuelen = *next - jt->elm[idx].value; return idx; } - jt->error = createException(MAL, "json.parser", "JSON syntax error: value expected at offset %ld", j - string_start); + jt->error = createException(MAL, "json.parser", "JSON syntax error: value expected at offset %td", j - string_start); return idx; } } 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 @@ -3255,6 +3255,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", @@ -3269,6 +3276,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", @@ -3310,21 +3324,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; + } } } @@ -3340,13 +3369,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"); } } _______________________________________________ checkin-list mailing list checkin-list@monetdb.org https://www.monetdb.org/mailman/listinfo/checkin-list