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