Changeset: 1cab9874ca18 for MonetDB URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=1cab9874ca18 Modified Files: sql/backends/monet5/sql.c sql/backends/monet5/sql_execute.c sql/backends/monet5/sql_gencode.c sql/server/rel_exp.c sql/server/rel_exp.h sql/server/rel_propagate.c sql/server/rel_psm.c sql/server/rel_rel.c sql/server/rel_rel.h sql/server/rel_schema.c sql/server/rel_select.c sql/server/rel_select.h sql/server/rel_sequence.c sql/server/rel_updates.c sql/server/rel_xml.c sql/storage/store.c sql/test/BugTracker-2017/Tests/prepare.Bug-6133.stable.err sql/test/BugTracker-2019/Tests/correlated-subquery-aggregation.Bug-6714.sql sql/test/BugTracker-2019/Tests/correlated-subquery-aggregation.Bug-6714.stable.out sql/test/BugTracker-2019/Tests/prepared-merge-statement.Bug-6706.sql sql/test/BugTracker-2019/Tests/prepared-merge-statement.Bug-6706.stable.err sql/test/BugTracker-2019/Tests/prepared-merge-statement.Bug-6706.stable.out Branch: context Log Message:
merged with default diffs (truncated from 2384 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 @@ -343,7 +343,8 @@ create_table_or_view(mvc *sql, char* sna snprintf(buf, BUFSIZ, "select cast(%s as %s);", c->def, typestr); _DELETE(typestr); r = rel_parse(sql, s, buf, m_deps); - if (!r || !is_project(r->op) || !r->exps || list_length(r->exps) != 1 || rel_check_type(sql, &c->type, r->exps->h->data, type_equal) == NULL) { + if (!r || !is_project(r->op) || !r->exps || list_length(r->exps) != 1 || + rel_check_type(sql, &c->type, r, r->exps->h->data, type_equal) == NULL) { if(r) rel_destroy(r); sa_destroy(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 @@ -195,7 +195,7 @@ SQLrun(Client c, mvc *m) { str msg= MAL_SUCCEED; MalBlkPtr mb=c->curprg->def; - + if (*m->errstr){ if (strlen(m->errstr) > 6 && m->errstr[5] == '!') msg = createException(PARSE, "SQLparser", "%s", m->errstr); @@ -208,6 +208,7 @@ SQLrun(Client c, mvc *m) // locate and inline the query template instruction mb = copyMalBlk(c->curprg->def); if (!mb) { + MT_thread_setworking(NULL); throw(SQL, "sql.prepare", SQLSTATE(HY001) MAL_MALLOC_FAIL); } mb->history = c->curprg->def->history; @@ -514,7 +515,6 @@ SQLstatementIntern(Client c, str *expr, msg = SQLrun(c,m); MSresetInstructions(c->curprg->def, oldstop); freeVariables(c, c->curprg->def, NULL, oldvtop); - sqlcleanup(sql, 0); /* construct a mock result set to determine schema */ 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 @@ -8,6 +8,7 @@ #include "monetdb_config.h" #include "sql_relation.h" +#include "sql_semantic.h" #include "rel_exp.h" #include "rel_prop.h" /* for prop_copy() */ #include "rel_unnest.h" @@ -2172,3 +2173,171 @@ exps_reset_freevar(list *exps) } } +static int +exp_set_list_recurse(mvc *sql, sql_subtype *type, sql_exp *e, const char **relname, const char** expname) +{ + if (THRhighwater()) { + (void) sql_error(sql, 10, SQLSTATE(42000) "query too complex: running out of stack space"); + return -1; + } + assert(*relname && *expname); + if (!e) + return 0; + + if (e->f) { + const char *next_rel = exp_relname(e), *next_exp = exp_name(e); + if (next_rel && next_exp && !strcmp(next_rel, *relname) && !strcmp(next_exp, *expname)) + for (node *n = ((list *) e->f)->h; n; n = n->next) + exp_set_list_recurse(sql, type, (sql_exp *) n->data, relname, expname); + } + if ((e->f || (!e->l && !e->r && !e->f)) && !e->tpe.type) { + if (set_type_param(sql, type, e->flag) == 0) + e->tpe = *type; + else + return -1; + } + return 0; +} + +static int +exp_set_type_recurse(mvc *sql, sql_subtype *type, sql_exp *e, const char **relname, const char** expname) +{ + if (THRhighwater()) { + (void) sql_error(sql, 10, SQLSTATE(42000) "query too complex: running out of stack space"); + return -1; + } + assert(*relname && *expname); + if (!e) + return 0; + + switch (e->type) { + case e_atom: { + return exp_set_list_recurse(sql, type, e, relname, expname); + } break; + case e_convert: + case e_column: { + /* if the column pretended is found, set its type */ + const char *next_rel = exp_relname(e), *next_exp = exp_name(e); + if (next_rel && !strcmp(next_rel, *relname)) { + *relname = next_rel; + if (next_exp && !strcmp(next_exp, *expname)) { + *expname = next_exp; + if (e->type == e_column && !e->tpe.type) { + if (set_type_param(sql, type, e->flag) == 0) + e->tpe = *type; + else + return -1; + } + } + } + if (e->type == e_convert) + exp_set_type_recurse(sql, type, e->l, relname, expname); + } break; + case e_psm: { + if (e->flag & PSM_RETURN) { + for(node *n = ((list*)e->r)->h ; n ; n = n->next) + exp_set_type_recurse(sql, type, (sql_exp*) n->data, relname, expname); + } else if (e->flag & PSM_WHILE) { + exp_set_type_recurse(sql, type, e->l, relname, expname); + for(node *n = ((list*)e->r)->h ; n ; n = n->next) + exp_set_type_recurse(sql, type, (sql_exp*) n->data, relname, expname); + } else if (e->flag & PSM_IF) { + exp_set_type_recurse(sql, type, e->l, relname, expname); + for(node *n = ((list*)e->r)->h ; n ; n = n->next) + exp_set_type_recurse(sql, type, (sql_exp*) n->data, relname, expname); + if (e->f) + for(node *n = ((list*)e->f)->h ; n ; n = n->next) + exp_set_type_recurse(sql, type, (sql_exp*) n->data, relname, expname); + } else if (e->flag & PSM_REL) { + rel_set_type_recurse(sql, type, e->l, relname, expname); + } else if (e->flag & PSM_EXCEPTION) { + exp_set_type_recurse(sql, type, e->l, relname, expname); + } + } break; + case e_func: { + for(node *n = ((list*)e->l)->h ; n ; n = n->next) + exp_set_type_recurse(sql, type, (sql_exp*) n->data, relname, expname); + if (e->r) + for(node *n = ((list*)e->r)->h ; n ; n = n->next) + exp_set_type_recurse(sql, type, (sql_exp*) n->data, relname, expname); + } break; + case e_aggr: { + if (e->l) + for(node *n = ((list*)e->l)->h ; n ; n = n->next) + exp_set_type_recurse(sql, type, (sql_exp*) n->data, relname, expname); + } break; + case e_cmp: { + if (e->flag == cmp_in || e->flag == cmp_notin) { + exp_set_type_recurse(sql, type, e->l, relname, expname); + for(node *n = ((list*)e->r)->h ; n ; n = n->next) + exp_set_type_recurse(sql, type, (sql_exp*) n->data, relname, expname); + } else if (get_cmp(e) == cmp_or || get_cmp(e) == cmp_filter) { + for(node *n = ((list*)e->l)->h ; n ; n = n->next) + exp_set_type_recurse(sql, type, (sql_exp*) n->data, relname, expname); + for(node *n = ((list*)e->r)->h ; n ; n = n->next) + exp_set_type_recurse(sql, type, (sql_exp*) n->data, relname, expname); + } else { + if(e->l) + exp_set_type_recurse(sql, type, e->l, relname, expname); + if(e->r) + exp_set_type_recurse(sql, type, e->r, relname, expname); + if(e->f) + exp_set_type_recurse(sql, type, e->f, relname, expname); + } + } break; + } + return 0; +} + +int +rel_set_type_recurse(mvc *sql, sql_subtype *type, sql_rel *rel, const char **relname, const char **expname) +{ + if (THRhighwater()) { + (void) sql_error(sql, 10, SQLSTATE(42000) "query too complex: running out of stack space"); + return -1; + } + assert(*relname && *expname); + if (!rel) + return 0; + + if (rel->exps) + for(node *n = rel->exps->h; n; n = n->next) + exp_set_type_recurse(sql, type, (sql_exp*) n->data, relname, expname); + + switch (rel->op) { + case op_basetable: + case op_table: + case op_ddl: + break; + case op_join: + case op_left: + case op_right: + case op_full: + case op_semi: + case op_anti: + case op_union: + case op_inter: + case op_except: + if (rel->l) + rel_set_type_recurse(sql, type, rel->l, relname, expname); + if (rel->r) + rel_set_type_recurse(sql, type, rel->r, relname, expname); + break; + case op_groupby: + case op_project: + case op_select: + case op_topn: + case op_sample: + if (rel->l) + rel_set_type_recurse(sql, type, rel->l, relname, expname); + break; + case op_insert: + case op_update: + case op_delete: + case op_truncate: + if (rel->r) + rel_set_type_recurse(sql, type, rel->r, relname, expname); + break; + } + return 0; +} 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 @@ -163,4 +163,5 @@ extern int exp_aggr_is_count(sql_exp *e) extern void exps_reset_freevar(list *exps); +extern int rel_set_type_recurse(mvc *sql, sql_subtype *type, sql_rel *rel, const char **relname, const char **expname); #endif /* _REL_EXP_H_ */ diff --git a/sql/server/rel_propagate.c b/sql/server/rel_propagate.c --- a/sql/server/rel_propagate.c +++ b/sql/server/rel_propagate.c @@ -164,10 +164,9 @@ generate_partition_limits(sql_query *que exp_kind ek = {type_value, card_value, FALSE}; sql_exp *e = rel_value_exp2(query, r, s, sql_sel, ek, &is_last); - if (!e) { + if (!e) return NULL; - } - return rel_check_type(sql, &tpe, e, type_equal); + return rel_check_type(sql, &tpe, r ? *r : NULL, e, type_equal); } } @@ -184,7 +183,7 @@ create_range_partition_anti_rel(sql_quer find_partition_type(&tpe, mt); anti_le = rel_generate_anti_expression(sql, &anti_rel, mt, pt); - anti_nils = rel_unop_(query, anti_le, NULL, "isnull", card_value); + anti_nils = rel_unop_(query, anti_rel, anti_le, NULL, "isnull", card_value); if (pmin && pmax) { sql_exp *range1, *range2; @@ -237,7 +236,7 @@ create_list_partition_anti_rel(sql_query find_partition_type(&tpe, mt); anti_le = rel_generate_anti_expression(sql, &anti_rel, mt, pt); - anti_nils = rel_unop_(query, anti_le, NULL, "isnull", card_value); + anti_nils = rel_unop_(query, anti_rel, anti_le, NULL, "isnull", card_value); if(list_length(anti_exps) > 0) { anti_exp = exp_in(sql->sa, anti_le, anti_exps, cmp_notin); @@ -678,7 +677,7 @@ rel_generate_subinserts(sql_query *query assert(pt->with_nills); } if (pt->with_nills) { /* handle the nulls case */ - sql_exp *nils = rel_unop_(query, le, NULL, "isnull", card_value); + sql_exp *nils = rel_unop_(query, dup, le, NULL, "isnull", card_value); nils = exp_compare(sql->sa, nils, exp_atom_bool(sql->sa, 1), cmp_equal); if (full_range) { full_range = exp_or(sql->sa, list_append(new_exp_list(sql->sa), full_range), @@ -711,7 +710,7 @@ rel_generate_subinserts(sql_query *query assert(pt->with_nills); } if (pt->with_nills) { /* handle the nulls case */ - sql_exp *nils = rel_unop_(query, le, NULL, "isnull", card_value); + sql_exp *nils = rel_unop_(query, dup, le, NULL, "isnull", card_value); nils = exp_compare(sql->sa, nils, exp_atom_bool(sql->sa, 1), cmp_equal); if (ein) { ein = exp_or(sql->sa, list_append(new_exp_list(sql->sa), ein), @@ -760,12 +759,12 @@ rel_generate_subinserts(sql_query *query } if (!found_nils) { assert(anti_exp); - anti_nils = rel_unop_(query, anti_le, NULL, "isnull", card_value); + anti_nils = rel_unop_(query, NULL, anti_le, NULL, "isnull", card_value); anti_nils = exp_compare(sql->sa, anti_nils, exp_atom_bool(sql->sa, 1), cmp_equal); anti_exp = exp_or(sql->sa, list_append(new_exp_list(sql->sa), anti_exp), list_append(new_exp_list(sql->sa), anti_nils), 0); } else if (!anti_exp) { - anti_nils = rel_unop_(query, exp_copy(sql->sa, anti_le), NULL, "isnull", card_value); + anti_nils = rel_unop_(query, NULL, exp_copy(sql->sa, anti_le), NULL, "isnull", card_value); anti_exp = exp_compare(sql->sa, anti_nils, exp_atom_bool(sql->sa, 1), cmp_notequal); } //generate a count aggregation for the values not present in any of the partitions _______________________________________________ checkin-list mailing list checkin-list@monetdb.org https://www.monetdb.org/mailman/listinfo/checkin-list