Changeset: 9bf73165983e for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=9bf73165983e
Modified Files:
        sql/server/rel_psm.c
        sql/server/rel_updates.c
        sql/test/pg_regress/Tests/alter_table.stable.err
Branch: Nov2019
Log Message:

Backported some of the recent fixes in rel_updates and rel_psm from Jun2020 to 
Nov2019 branch


diffs (221 lines):

diff --git a/sql/server/rel_psm.c b/sql/server/rel_psm.c
--- a/sql/server/rel_psm.c
+++ b/sql/server/rel_psm.c
@@ -108,7 +108,9 @@ psm_set_exp(sql_query *query, dnode *n)
 
                if (!rel_val)
                        return NULL;
-               if (!is_project(rel_val->op) || dlist_length(vars) != 
list_length(rel_val->exps))
+               if (!is_project(rel_val->op))
+                       return sql_error(sql, 02, SQLSTATE(42000) "SET: The 
subquery is not a projection");
+               if (dlist_length(vars) != list_length(rel_val->exps))
                        return sql_error(sql, 02, SQLSTATE(42000) "SET: Number 
of variables not equal to number of supplied values");
 
                b = sa_list(sql->sa);
@@ -480,6 +482,8 @@ rel_psm_return( sql_query *query, sql_su
                        oexps_rel = l;
                        oexps = l->exps;
                }
+               if (list_length(oexps) != list_length(restypelist))
+                       return sql_error(sql, 02, SQLSTATE(42000) "RETURN: 
number of columns do not match");
                for (n = oexps->h, m = restypelist->h; n && m; n = n->next, m = 
m->next) {
                        sql_exp *e = n->data;
                        sql_arg *ce = m->data;
@@ -541,6 +545,10 @@ rel_select_into( sql_query *query, symbo
        r = rel_subquery(query, NULL, sq, ek);
        if (!r) 
                return NULL;
+       if (!is_project(r->op))
+               return sql_error(sql, 02, SQLSTATE(42000) "SELECT INTO: The 
subquery is not a projection");
+       if (list_length(r->exps) != dlist_length(into))
+               return sql_error(sql, 02, SQLSTATE(21S01) "SELECT INTO: number 
of values doesn't match number of variables to set");
        nl = sa_list(sql->sa);
        append(nl, exp_rel(sql, r));
        for (m = r->exps->h, n = into->h; m && n; m = m->next, n = n->next) {
@@ -1323,7 +1331,8 @@ create_trigger(sql_query *query, dlist *
                if (old_name)
                        stack_update_rel_view(sql, old_name, 
new_name?rel_dup(rel):rel);
        }
-       sq = sequential_block(query, NULL, NULL, stmts, NULL, 1);
+       if (!(sq = sequential_block(query, NULL, NULL, stmts, NULL, 1)))
+               return NULL;
        r = rel_psm_block(sql->sa, sq);
 
        if (!instantiate)
diff --git a/sql/server/rel_updates.c b/sql/server/rel_updates.c
--- a/sql/server/rel_updates.c
+++ b/sql/server/rel_updates.c
@@ -314,7 +314,9 @@ rel_inserts(mvc *sql, sql_table *t, sql_
                        for (n = r->exps->h, m = collist->h; n && m; n = 
n->next, m = m->next) {
                                sql_column *c = m->data;
                                sql_exp *e = n->data;
-               
+
+                               if (inserts[c->colnr])
+                                       return sql_error(sql, 02, 
SQLSTATE(42000) "%s: column '%s' specified more than once", action, 
c->base.name);
                                inserts[c->colnr] = rel_check_type(sql, 
&c->type, r, e, type_equal);
                        }
                } else {
@@ -323,8 +325,11 @@ rel_inserts(mvc *sql, sql_table *t, sql_
                                sql_exp *e;
 
                                e = exps_bind_column2( r->exps, 
c->t->base.name, c->base.name);
-                               if (e)
+                               if (e) {
+                                       if (inserts[c->colnr])
+                                               return sql_error(sql, 02, 
SQLSTATE(42000) "%s: column '%s' specified more than once", action, 
c->base.name);
                                        inserts[c->colnr] = exp_ref(sql->sa, e);
+                               }
                        }
                }
        }
@@ -911,16 +916,10 @@ rel_update(mvc *sql, sql_rel *t, sql_rel
 static sql_exp *
 update_check_column(mvc *sql, sql_table *t, sql_column *c, sql_exp *v, sql_rel 
*r, char *cname, const char *action)
 {
-       if (!c) {
-               rel_destroy(r);
-               return sql_error(sql, 02, SQLSTATE(42S22) "%s: no such column 
'%s.%s'", action, t->base.name, cname);
-       }
        if (!table_privs(sql, t, PRIV_UPDATE) && !sql_privilege(sql, 
sql->user_id, c->base.id, PRIV_UPDATE)) 
                return sql_error(sql, 02, SQLSTATE(42000) "%s: insufficient 
privileges for user '%s' to update table '%s' on column '%s'", action, 
stack_get_string(sql, "current_user"), t->base.name, cname);
-       if (!v || (v = rel_check_type(sql, &c->type, r, v, type_equal)) == 
NULL) {
-               rel_destroy(r);
+       if (!v || (v = rel_check_type(sql, &c->type, r, v, type_equal)) == NULL)
                return NULL;
-       }
        return v;
 }
 
@@ -929,7 +928,7 @@ update_generate_assignments(sql_query *q
 {
        mvc *sql = query->sql;
        sql_table *mt = NULL;
-       sql_exp *e = NULL, **updates = SA_ZNEW_ARRAY(sql->sa, sql_exp*, 
list_length(t->columns.set));
+       sql_exp **updates = SA_ZNEW_ARRAY(sql->sa, sql_exp*, 
list_length(t->columns.set));
        list *exps, *pcols = NULL;
        dnode *n;
        const char *rname = NULL;
@@ -948,9 +947,7 @@ update_generate_assignments(sql_query *q
                pcols = mt->part.pexp->cols;
        }
        /* first create the project */
-       e = exp_column(sql->sa, rname = rel_name(r), TID, 
sql_bind_localtype("oid"), CARD_MULTI, 0, 1);
-       exps = new_exp_list(sql->sa);
-       append(exps, e);
+       exps = list_append(new_exp_list(sql->sa), exp_column(sql->sa, rname = 
rel_name(r), TID, sql_bind_localtype("oid"), CARD_MULTI, 0, 1));
 
        for (n = assignmentlist->h; n; n = n->next) {
                symbol *a = NULL;
@@ -965,9 +962,12 @@ update_generate_assignments(sql_query *q
                        int status = sql->session->status;
                        exp_kind ek = {type_value, 
(single)?card_column:card_relation, FALSE};
 
-                       if(single && a->token == SQL_DEFAULT) {
+                       if (single && a->token == SQL_DEFAULT) {
                                char *colname = assignment->h->next->data.sval;
                                sql_column *col = mvc_bind_column(sql, t, 
colname);
+
+                               if (!col)
+                                       return sql_error(sql, 02, 
SQLSTATE(42S22) "%s: no such column '%s.%s'", action, t->base.name, colname);
                                if (col->def) {
                                        char *typestr = 
subtype2string2(&col->type);
                                        if(!typestr)
@@ -1029,23 +1029,22 @@ update_generate_assignments(sql_query *q
                        dlist *cols = assignment->h->next->data.lval;
                        dnode *m;
                        node *n;
-                       int nr;
 
                        if (!rel_val)
                                rel_val = r;
-                       if (!rel_val || !is_project(rel_val->op) ||
-                               dlist_length(cols) > 
list_length(rel_val->exps)) {
-                               rel_destroy(r);
-                               return sql_error(sql, 02, SQLSTATE(42000) "%s: 
too many columns specified", action);
-                       }
-                       nr = (list_length(rel_val->exps)-dlist_length(cols));
-                       for (n=rel_val->exps->h; nr; nr--, n = n->next)
-                               ;
-                       for (m = cols->h; n && m; n = n->next, m = m->next) {
+                       if (!rel_val || !is_project(rel_val->op))
+                               return sql_error(sql, 02, SQLSTATE(42000) "%s: 
Invalid right side of the SET clause", action);
+                       if (dlist_length(cols) != list_length(rel_val->exps))
+                               return sql_error(sql, 02, SQLSTATE(42000) "%s: 
The number of specified columns between the SET clause and the right side don't 
match (%d != %d)", action, dlist_length(cols), list_length(rel_val->exps));
+                       for (n = rel_val->exps->h, m = cols->h; n && m; n = 
n->next, m = m->next) {
                                char *cname = m->data.sval;
                                sql_column *c = mvc_bind_column(sql, t, cname);
                                sql_exp *v = n->data;
 
+                               if (!c)
+                                       return sql_error(sql, 02, 
SQLSTATE(42S22) "%s: no such column '%s.%s'", action, t->base.name, cname);
+                               if (updates[c->colnr])
+                                       return sql_error(sql, 02, 
SQLSTATE(42000) "%s: Multiple assignments to same column '%s'", action, 
c->base.name);
                                if (mt && pcols) {
                                        for (node *nn = pcols->h; nn; nn = 
n->next) {
                                                int next = *(int*) nn->data;
@@ -1062,13 +1061,11 @@ update_generate_assignments(sql_query *q
                                        exp_label(sql->sa, v, ++sql->label);
                                if (!exp_is_atom(v) || outer)
                                        v = exp_ref(sql->sa, v);
-                               if (!v) { /* check for NULL */
+                               if (!v) /* check for NULL */
                                        v = exp_atom(sql->sa, 
atom_general(sql->sa, &c->type, NULL));
-                               } else if ((v = update_check_column(sql, t, c, 
v, r, cname, action)) == NULL) {
+                               if (!(v = update_check_column(sql, t, c, v, r, 
cname, action)))
                                        return NULL;
-                               }
                                list_append(exps, exp_column(sql->sa, 
t->base.name, cname, &c->type, CARD_MULTI, 0, 0));
-                               assert(!updates[c->colnr]);
                                exp_setname(sql->sa, v, c->t->base.name, 
c->base.name);
                                updates[c->colnr] = v;
                        }
@@ -1076,6 +1073,10 @@ update_generate_assignments(sql_query *q
                        char *cname = assignment->h->next->data.sval;
                        sql_column *c = mvc_bind_column(sql, t, cname);
 
+                       if (!c)
+                               return sql_error(sql, 02, SQLSTATE(42S22) "%s: 
no such column '%s.%s'", action, t->base.name, cname);
+                       if (updates[c->colnr])
+                               return sql_error(sql, 02, SQLSTATE(42000) "%s: 
Multiple assignments to same column '%s'", action, c->base.name);
                        if (mt && pcols) {
                                for (node *nn = pcols->h; nn; nn = nn->next) {
                                        int next = *(int*) nn->data;
@@ -1088,18 +1089,16 @@ update_generate_assignments(sql_query *q
                                        }
                                }
                        }
-                       if (!v) {
+                       if (!v)
                                v = exp_atom(sql->sa, atom_general(sql->sa, 
&c->type, NULL));
-                       } else if ((v = update_check_column(sql, t, c, v, r, 
cname, action)) == NULL) {
+                       if (!(v = update_check_column(sql, t, c, v, r, cname, 
action)))
                                return NULL;
-                       }
                        list_append(exps, exp_column(sql->sa, t->base.name, 
cname, &c->type, CARD_MULTI, 0, 0));
                        exp_setname(sql->sa, v, c->t->base.name, c->base.name);
                        updates[c->colnr] = v;
                }
        }
-       e = exp_column(sql->sa, rname, TID, sql_bind_localtype("oid"), 
CARD_MULTI, 0, 1);
-       r = rel_project(sql->sa, r, append(new_exp_list(sql->sa),e));
+       r = rel_project(sql->sa, r, list_append(new_exp_list(sql->sa), 
exp_column(sql->sa, rname, TID, sql_bind_localtype("oid"), CARD_MULTI, 0, 1)));
        r = rel_update(sql, bt, r, updates, exps);
        return r;
 }
diff --git a/sql/test/pg_regress/Tests/alter_table.stable.err 
b/sql/test/pg_regress/Tests/alter_table.stable.err
--- a/sql/test/pg_regress/Tests/alter_table.stable.err
+++ b/sql/test/pg_regress/Tests/alter_table.stable.err
@@ -593,9 +593,9 @@ ERROR = !CREATE INDEX: no such column '.
 CODE  = 42S22
 MAPI  = (monetdb) /var/tmp/mtest-30274/.s.monetdb.37685
 QUERY = select * into test2 from atacc1;
-ERROR = !SELECT INTO: variable 'test2' unknown
-CODE  = 42000
-MAPI  = (monetdb) /var/tmp/mtest-30274/.s.monetdb.37685
+ERROR = !SELECT INTO: number of values doesn't match number of variables to set
+CODE  = 21S01
+MAPI  = (monetdb) /var/tmp/mtest-46638/.s.monetdb.39274
 QUERY = select * from test2;
 ERROR = !SELECT: no such table 'test2'
 CODE  = 42S02
_______________________________________________
checkin-list mailing list
checkin-list@monetdb.org
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to