Changeset: 83fe6822b8d7 for MonetDB URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=83fe6822b8d7 Modified Files: sql/server/rel_select.c sql/server/rel_updates.c sql/server/sql_mvc.h Branch: default Log Message:
handle multivalue update statements with subqueries with cardinality problems diffs (104 lines): diff --git a/sql/server/rel_select.c b/sql/server/rel_select.c --- a/sql/server/rel_select.c +++ b/sql/server/rel_select.c @@ -163,17 +163,27 @@ rel_lastexp(mvc *sql, sql_rel *rel ) static sql_rel * rel_zero_or_one(mvc *sql, sql_rel *rel, exp_kind ek) { - sql_exp *e = lastexp(rel); - if (!has_label(e)) - exp_label(sql->sa, e, ++sql->label); + if (is_topn(rel->op)) + rel = rel_project(sql->sa, rel, rel_projections(sql, rel, NULL, 1, 0)); if (ek.card < card_set && rel->card > CARD_ATOM) { - sql_subtype *t = exp_subtype(e); /* parameters don't have a type defined, for those use 'void' one */ - sql_subfunc *zero_or_one = sql_bind_func(sql->sa, sql->session->schema, "zero_or_one", t ? t : sql_bind_localtype("void"), NULL, F_AGGR); - - e = exp_ref(sql->sa, e); - e = exp_aggr1(sql->sa, e, zero_or_one, 0, 0, CARD_ATOM, has_nil(e)); + assert (is_simple_project(rel->op) || is_set(rel->op)); + list *exps = rel->exps; rel = rel_groupby(sql, rel, NULL); - (void)rel_groupby_add_aggr(sql, rel, e); + for(node *n = exps->h; n; n=n->next) { + sql_exp *e = n->data; + if (!has_label(e)) + exp_label(sql->sa, e, ++sql->label); + sql_subtype *t = exp_subtype(e); /* parameters don't have a type defined, for those use 'void' one */ + sql_subfunc *zero_or_one = sql_bind_func(sql->sa, sql->session->schema, "zero_or_one", t ? t : sql_bind_localtype("void"), NULL, F_AGGR); + + e = exp_ref(sql->sa, e); + e = exp_aggr1(sql->sa, e, zero_or_one, 0, 0, CARD_ATOM, has_nil(e)); + (void)rel_groupby_add_aggr(sql, rel, e); + } + } else { + sql_exp *e = lastexp(rel); + if (!has_label(e)) + exp_label(sql->sa, e, ++sql->label); } return rel; } @@ -5897,6 +5907,9 @@ rel_subquery(sql_query *query, sql_rel * rel = rel_query(query, rel, sq, toplevel, ek); stack_pop_frame(sql); + + if (rel && ek.type == type_relation && ek.card < card_set && rel->card >= CARD_MULTI) + return rel_zero_or_one(sql, rel, ek); return rel; } 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 @@ -959,8 +959,7 @@ update_generate_assignments(sql_query *q a = assignment->h->data.sym; if (a) { - int status = sql->session->status; - exp_kind ek = {type_value, (single)?card_column:card_relation, FALSE}; + exp_kind ek = { (single)?type_value:type_relation, card_column, FALSE}; if (single && a->token == SQL_DEFAULT) { char *colname = assignment->h->next->data.sval; @@ -978,16 +977,12 @@ update_generate_assignments(sql_query *q v = rel_value_exp(query, &r, a, sql_sel | sql_update_set, ek); outer = 1; } else { + if (r) + query_push_outer(query, r, sql_sel); rel_val = rel_subquery(query, NULL, a, ek); - } - if (!single && !rel_val && r) { + if (r) + r = query_pop_outer(query); outer = 1; - sql->errstr[0] = 0; - sql->session->status = status; - /* TODO put in else above */ - query_push_outer(query, r, sql_sel); - rel_val = rel_subquery(query, NULL, a, ek); - r = query_pop_outer(query); } if ((single && !v) || (!single && !rel_val)) return NULL; diff --git a/sql/server/sql_mvc.h b/sql/server/sql_mvc.h --- a/sql/server/sql_mvc.h +++ b/sql/server/sql_mvc.h @@ -31,7 +31,7 @@ /* value vs predicate (boolean) */ #define type_value 0 -#define type_predicate 1 +#define type_relation 1 /* cardinality expected by enclosing operator */ #define card_none -1 /* psm call doesn't return anything */ @@ -40,6 +40,7 @@ #define card_column 2 #define card_set 3 /* some operators require only a set (IN/EXISTS) */ #define card_exists 4 +/* to be removed ie are in type (aka dimention) */ #define card_relation 5 #define card_loader 6 _______________________________________________ checkin-list mailing list checkin-list@monetdb.org https://www.monetdb.org/mailman/listinfo/checkin-list