Changeset: 579cf718c5ec for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=579cf718c5ec
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/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: default
Log Message:
Merge with Apr2019.
diffs (truncated from 2346 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
@@ -330,7 +330,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
@@ -285,7 +285,7 @@ SQLrun(Client c, backend *be, mvc *m)
InstrPtr p=0;
int i,j, retc;
ValPtr val;
-
+
if (*m->errstr){
if (strlen(m->errstr) > 6 && m->errstr[5] == '!')
msg = createException(PARSE, "SQLparser", "%s",
m->errstr);
@@ -294,10 +294,13 @@ SQLrun(Client c, backend *be, mvc *m)
*m->errstr=0;
return msg;
}
+ if (m->emode == m_execute && be->q->paramlen != m->argc)
+ throw(SQL, "sql.prepare", SQLSTATE(42000) "EXEC called with
wrong number of arguments: expected %d, got %d", be->q->paramlen, m->argc);
MT_thread_setworking(c->query);
// 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;
@@ -316,6 +319,7 @@ SQLrun(Client c, backend *be, mvc *m)
mc = copyMalBlk(p->blk);
if (!mc) {
freeMalBlk(mb);
+ MT_thread_setworking(NULL);
throw(SQL, "sql.prepare", SQLSTATE(HY001)
MAL_MALLOC_FAIL);
}
retc = p->retc;
@@ -326,14 +330,16 @@ SQLrun(Client c, backend *be, mvc *m)
for (j = 0; j < m->argc; j++) {
sql_subtype *pt = be->q->params + j;
atom *arg = m->args[j];
-
+
if (!atom_cast(m->sa, arg, pt)) {
freeMalBlk(mb);
+ MT_thread_setworking(NULL);
throw(SQL, "sql.prepare",
SQLSTATE(07001) "EXEC: wrong type for argument %d of " "query template : %s,
expected %s", i + 1, atom_type(arg)->type->sqlname, pt->type->sqlname);
}
val= (ValPtr) &arg->data;
if (VALcopy(&mb->var[j+retc].value, val) ==
NULL){
freeMalBlk(mb);
+ MT_thread_setworking(NULL);
throw(MAL, "sql.prepare",
SQLSTATE(HY001) MAL_MALLOC_FAIL);
}
setVarConstant(mb, j+retc);
diff --git a/sql/backends/monet5/sql_gencode.c
b/sql/backends/monet5/sql_gencode.c
--- a/sql/backends/monet5/sql_gencode.c
+++ b/sql/backends/monet5/sql_gencode.c
@@ -813,6 +813,10 @@ backend_call(backend *be, Client c, cq *
m->session->status = -3;
return;
}
+ if (m->emode == m_execute && be->q->paramlen != m->argc) {
+ sql_error(m, 003, SQLSTATE(42000) "EXEC called with wrong
number of arguments: expected %d, got %d", be->q->paramlen, m->argc);
+ return;
+ }
/* cached (factorized queries return bit??) */
if (cq->code && getInstrPtr(((Symbol)cq->code)->def, 0)->token ==
FACTORYsymbol) {
setVarType(mb, getArg(q, 0), TYPE_bit);
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"
@@ -2176,3 +2177,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
@@ -162,4 +162,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
@@ -168,10 +168,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);
}
}
@@ -188,7 +187,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;
@@ -241,7 +240,7 @@ create_list_partition_anti_rel(sql_query
find_partition_type(&tpe, mt);
anti_le = rel_generate_anti_expression(sql, &anti_rel, mt, pt);
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list