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

Reply via email to