Changeset: 23a00ecb5e48 for MonetDB URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=23a00ecb5e48 Added Files: sql/test/subquery/Tests/subquery6.sql sql/test/subquery/Tests/subquery6.stable.err sql/test/subquery/Tests/subquery6.stable.out Modified Files: sql/backends/monet5/rel_bin.c sql/backends/monet5/sql_execute.c sql/backends/monet5/sql_user.c sql/server/rel_dump.c sql/server/rel_optimizer.c sql/server/rel_rel.h sql/server/rel_select.c sql/server/rel_semantic.c sql/server/rel_updates.c sql/storage/sql_storage.h sql/storage/store.c sql/test/subquery/Tests/All Branch: default Log Message:
Merged with Jun2020 diffs (truncated from 747 to 300 lines): diff --git a/sql/backends/monet5/rel_bin.c b/sql/backends/monet5/rel_bin.c --- a/sql/backends/monet5/rel_bin.c +++ b/sql/backends/monet5/rel_bin.c @@ -1441,7 +1441,7 @@ rel_parse_value(backend *be, char *query *m = o; m->session->status = status; } else { - int label = m->label; + unsigned int label = m->label; while (m->topvars > o.topvars) { if (m->vars[--m->topvars].name) @@ -3632,7 +3632,7 @@ sql_parse(backend *be, sql_allocator *sa sa_destroy(m->sa); m->sym = NULL; { - int label = m->label; + unsigned int label = m->label; int status = m->session->status; int sizevars = m->sizevars, topvars = m->topvars; sql_var *vars = m->vars; @@ -4738,7 +4738,7 @@ cascade_updates(backend *be, sql_table * if (i->key) { if (!(sql->cascade_action && list_find_id(sql->cascade_action, i->key->base.id))) { sql_key *k = i->key; - int *local_id = SA_NEW(sql->sa, int); + sqlid *local_id = SA_NEW(sql->sa, sqlid); if (!sql->cascade_action) sql->cascade_action = sa_list(sql->sa); *local_id = i->key->base.id; @@ -5216,7 +5216,7 @@ sql_delete_keys(backend *be, sql_table * if (k->type == pkey || k->type == ukey) { if (!(sql->cascade_action && list_find_id(sql->cascade_action, k->base.id))) { - int *local_id = SA_NEW(sql->sa, int); + sqlid *local_id = SA_NEW(sql->sa, sqlid); if (!sql->cascade_action) sql->cascade_action = sa_list(sql->sa); diff --git a/sql/backends/monet5/sql_execute.c b/sql/backends/monet5/sql_execute.c --- a/sql/backends/monet5/sql_execute.c +++ b/sql/backends/monet5/sql_execute.c @@ -448,7 +448,8 @@ SQLescapeString(str s) str SQLstatementIntern(Client c, str *expr, str nme, bit execute, bit output, res_table **result) { - int status = 0, err = 0, oldvtop, oldstop = 1, inited = 0, label, ac, sizevars, topvars; + int status = 0, err = 0, oldvtop, oldstop = 1, inited = 0, ac, sizevars, topvars; + unsigned int label; mvc *o, *m; sql_var *vars; buffer *b; diff --git a/sql/backends/monet5/sql_user.c b/sql/backends/monet5/sql_user.c --- a/sql/backends/monet5/sql_user.c +++ b/sql/backends/monet5/sql_user.c @@ -542,9 +542,9 @@ monet5_user_set_def_schema(mvc *m, oid u rid = table_funcs.column_find_row(m->session->tr, auths_name, username, NULL); if (!is_oid_nil(rid)) { sql_column *auths_id = find_sql_column(auths, "id"); - int id; + sqlid id; p = table_funcs.column_find_value(m->session->tr, auths_id, rid); - id = *(int *) p; + id = *(sqlid *) p; _DELETE(p); m->user_id = m->role_id = id; diff --git a/sql/server/rel_dump.c b/sql/server/rel_dump.c --- a/sql/server/rel_dump.c +++ b/sql/server/rel_dump.c @@ -340,9 +340,8 @@ op2string(operator_type op) case op_delete: case op_truncate: return "modify op"; - default: - return "unknown"; } + return "unknown"; } static int @@ -838,7 +837,7 @@ read_exps(mvc *sql, sql_rel *lrel, sql_r static sql_exp* exp_read(mvc *sql, sql_rel *lrel, sql_rel *rrel, list *pexps, char *r, int *pos, int grp) { - int f = -1, not = 1, old, d=0, s=0, unique = 0, no_nils = 0, quote = 0; + int f = -1, not = 1, old, d=0, s=0, unique = 0, no_nils = 0, quote = 0, zero_if_empty = 0; char *tname = NULL, *cname = NULL, *var_cname = NULL, *e, *b = r + *pos, *st; sql_exp *exp = NULL; list *exps = NULL; @@ -894,7 +893,7 @@ exp_read(mvc *sql, sql_rel *lrel, sql_re } if (strncmp(r+*pos, "or", strlen("or")) == 0) { (*pos)+= (int) strlen("or"); - } else if (strncmp(r+*pos, "FILTER", strlen("FILTER")) == 0) { + } else if (strncasecmp(r+*pos, "FILTER", strlen("FILTER")) == 0) { (*pos)+= (int) strlen("FILTER"); filter = 1; } else { @@ -998,6 +997,11 @@ exp_read(mvc *sql, sql_rel *lrel, sql_re (*pos)+= (int) strlen("no nil"); skipWS(r, pos); } + if (r[*pos] == 'z') { + zero_if_empty = 1; + (*pos)+= (int) strlen("zero if empty"); + skipWS(r, pos); + } } if (r[*pos] == '(') { sql_schema *s; @@ -1016,10 +1020,12 @@ exp_read(mvc *sql, sql_rel *lrel, sql_re if (exps && exps->h) a = sql_bind_func(sql->sa, s, cname, exp_subtype(exps->h->data), NULL, F_AGGR); else - a = sql_bind_func(sql->sa, s, cname, sql_bind_localtype("void"), NULL, F_AGGR); + a = sql_bind_func(sql->sa, s, cname, sql_bind_localtype("void"), NULL, F_AGGR); /* count(*) */ if (!a) return sql_error(sql, -1, SQLSTATE(42000) "Aggregate %s%s%s not found\n", tname ? tname : "", tname ? "." : "", cname); exp = exp_aggr( sql->sa, exps, a, unique, no_nils, CARD_ATOM, 1); + if (zero_if_empty) + set_zero_if_empty(exp); } else { list *ops = sa_list(sql->sa); for( n = exps->h; n; n = n->next) @@ -1040,17 +1046,17 @@ exp_read(mvc *sql, sql_rel *lrel, sql_re } } /* fix scale of div function */ - if (f && f->func->fix_scale == SCALE_DIV && list_length(exps) == 2) { - sql_arg *ares = f->func->res->h->data; + if (f && f->func->fix_scale == SCALE_DIV && list_length(exps) == 2) { + sql_arg *ares = f->func->res->h->data; - if (strcmp(f->func->imp, "/") == 0 && ares->type.type->scale == SCALE_FIX) { - sql_subtype *res = f->res->h->data; - sql_subtype *lt = ops->h->data; - sql_subtype *rt = ops->h->next->data; + if (strcmp(f->func->imp, "/") == 0 && ares->type.type->scale == SCALE_FIX) { + sql_subtype *res = f->res->h->data; + sql_subtype *lt = ops->h->data; + sql_subtype *rt = ops->h->next->data; - res->scale = lt->scale - rt->scale; - } - } + res->scale = lt->scale - rt->scale; + } + } if (f) exp = exp_op( sql->sa, exps, f); @@ -1220,14 +1226,24 @@ exp_read(mvc *sql, sql_rel *lrel, sql_re f = mark_notin; } break; + case 'e': + if (strncmp(r+*pos, "exists", strlen("exists")) == 0) { + (*pos)+= (int) strlen("exists"); + f = mark_exists; + } else if (strncmp(r+*pos, "!exists", strlen("!exists")) == 0) { + (*pos)+= (int) strlen("!exists"); + f = mark_notexists; + } + break; case 'n': if (strncmp(r+*pos, "notin", strlen("notin")) == 0) { (*pos)+= (int) strlen("notin"); f = cmp_notin; } break; + case 'f': case 'F': - if (strncmp(r+*pos, "FILTER", strlen("FILTER")) == 0) { + if (strncasecmp(r+*pos, "FILTER", strlen("FILTER")) == 0) { (*pos)+= (int) strlen("FILTER"); f = cmp_filter; } @@ -1284,8 +1300,7 @@ exp_read(mvc *sql, sql_rel *lrel, sql_re list *exps = read_exps(sql, lrel, rrel, pexps, r, pos, '(', 0); if (!exps) return NULL; - if (f == cmp_in || f == cmp_notin) - return exp_in(sql->sa, exp, exps, f); + return exp_in(sql->sa, exp, exps, f); } else { int sym = 0, between = 0; sql_exp *e = exp_read(sql, lrel, rrel, pexps, r, pos, 0); @@ -1349,7 +1364,7 @@ rel_read(mvc *sql, char *r, int *pos, li { sql_rel *rel = NULL, *nrel, *lrel, *rrel; list *exps, *gexps; - int distinct = 0; + int distinct = 0, dependent = 0, single = 0; operator_type j = op_basetable; skipWS(r,pos); @@ -1489,11 +1504,22 @@ rel_read(mvc *sql, char *r, int *pos, li return rel_update(sql, lrel, rrel, NULL, nexps); } - if (r[*pos] == 'd') { + if (r[*pos] == 'd' && r[*pos+1] == 'i') { *pos += (int) strlen("distinct"); skipWS(r, pos); distinct = 1; } + if (r[*pos] == 's' && r[*pos+1] == 'i') { + *pos += (int) strlen("single"); + skipWS(r, pos); + single = 1; + } + if (r[*pos] == 'd' && r[*pos+1] == 'e') { + *pos += (int) strlen("dependent"); + skipWS(r, pos); + dependent = 1; + } + switch(r[*pos]) { case 't': if (r[*pos+1] == 'a') { @@ -1589,9 +1615,6 @@ rel_read(mvc *sql, char *r, int *pos, li if (r[*pos] == '[') if (!(rel->r = read_exps(sql, nrel, rel, NULL, r, pos, '[', 0))) return NULL; - if (distinct) - set_distinct(rel); - distinct = 0; break; case 'g': *pos += (int) strlen("group by"); @@ -1656,15 +1679,17 @@ rel_read(mvc *sql, char *r, int *pos, li rel = rel_select_copy(sql->sa, nrel, exps); /* semijoin or antijoin */ } else if (r[*pos+1] == 'e' || r[*pos+1] == 'n') { - j = op_semi; + if (r[*pos+1] == 'n') { + j = op_anti; + *pos += (int) strlen("antijoin"); + } else { + j = op_semi; + *pos += (int) strlen("semijoin"); + } - if (r[*pos+1] == 'n') - j = op_anti; - - *pos += (int) strlen("semijoin"); skipWS(r, pos); if (r[*pos] != '(') - return sql_error(sql, -1, SQLSTATE(42000) "Semijoin: missing '('\n"); + return sql_error(sql, -1, SQLSTATE(42000) "%s: missing '('\n", (j == op_semi)?"Semijoin":"Antijoin"); (*pos)++; skipWS(r, pos); if (!(lrel = rel_read(sql, r, pos, refs))) @@ -1672,7 +1697,7 @@ rel_read(mvc *sql, char *r, int *pos, li skipWS(r, pos); if (r[*pos] != ',') - return sql_error(sql, -1, SQLSTATE(42000) "Semijoin: missing ','\n"); + return sql_error(sql, -1, SQLSTATE(42000) "%s: missing ','\n", (j == op_semi)?"Semijoin":"Antijoin"); (*pos)++; skipWS(r, pos); if (!(rrel = rel_read(sql, r, pos, refs))) @@ -1680,7 +1705,7 @@ rel_read(mvc *sql, char *r, int *pos, li skipWS(r, pos); if (r[*pos] != ')') - return sql_error(sql, -1, SQLSTATE(42000) "Semijoin: missing ')'\n"); + return sql_error(sql, -1, SQLSTATE(42000) "%s: missing ')'\n", (j == op_semi)?"Semijoin":"Antijoin"); (*pos)++; skipWS(r, pos); @@ -1801,17 +1826,24 @@ rel_read(mvc *sql, char *r, int *pos, li if (r[*pos] == '[') if (!(rel->r = read_exps(sql, NULL, rel, NULL, r, pos, '[', 0))) return NULL; - if (distinct) - set_distinct(rel); - distinct = 0; break; case 'd': /* 'ddl' not supported */ default: - return NULL; + return sql_error(sql, -1, SQLSTATE(42000) "Could not determine the input relation\n"); } + + if (!rel) + return sql_error(sql, -1, SQLSTATE(42000) "Could not determine the input relation\n"); + if (distinct) + set_distinct(rel); + if (single) + set_single(rel); + if (dependent) + set_dependent(rel); + /* sometimes the properties are send */ - while (strncmp(r+*pos, "REMOTE", strlen("REMOTE")) == 0) { /* Remote tables under remote tables not supported, so remove REMOTE property */ + while (strncmp(r+*pos, "REMOTE", strlen("REMOTE")) == 0) { /* Remote tables under remote tables not supported, so remove REMOTE property */ _______________________________________________ checkin-list mailing list checkin-list@monetdb.org https://www.monetdb.org/mailman/listinfo/checkin-list