Changeset: 565ec2f66a88 for MonetDB URL: https://dev.monetdb.org/hg/MonetDB/rev/565ec2f66a88 Modified Files: sql/backends/monet5/mal_backend.c sql/backends/monet5/mal_backend.h sql/backends/monet5/rel_bin.c sql/backends/monet5/rel_bin.h sql/backends/monet5/sql_execute.c sql/backends/monet5/sql_gencode.c sql/backends/monet5/sql_gencode.h sql/backends/monet5/sql_scenario.c sql/backends/monet5/sql_statement.c sql/backends/monet5/sql_statement.h sql/server/rel_dump.c sql/server/rel_prop.c sql/server/rel_prop.h sql/server/rel_propagate.c sql/server/rel_updates.c Branch: default Log Message:
Backporting fixes from pushcands into default If multiple insert/update/delete statements are present in a relation, then instead of using a SQL property update the total number of rows affected. The later one is more defensive. When generating MAL from SQL function/procedure backup the existing state of the code generation beforehand, otherwise there could be issues of re-using code generation variables. Also be more restricitve when to generate query result statments. diffs (truncated from 1273 to 300 lines): diff --git a/sql/backends/monet5/mal_backend.c b/sql/backends/monet5/mal_backend.c --- a/sql/backends/monet5/mal_backend.c +++ b/sql/backends/monet5/mal_backend.c @@ -17,11 +17,9 @@ backend_reset(backend *b) .mvc = b->mvc, .client = b->client, .out = b->client->fdout, - .first_statement_generated = false, .output_format = OFMT_CSV, .rowcnt = -1, .last_id = -1, - .sizeheader = false }; return b; } diff --git a/sql/backends/monet5/mal_backend.h b/sql/backends/monet5/mal_backend.h --- a/sql/backends/monet5/mal_backend.h +++ b/sql/backends/monet5/mal_backend.h @@ -45,7 +45,7 @@ typedef struct backend { MalBlkPtr mb; /* needed during mal generation */ int mvc_var; /* current variable holding the latest query context (used to create dependencies in mal statements) */ - int cur_append; /* The cur_append variable on an insert/update/delete on a partitioned table, tracks the current MAL variable holding + int rowcount; /* When multiple insert/update/delete/truncate statements are sent, use an accumulator to hold all the inserted rows * the total number of rows affected. */ int vtop; /* top of the variable stack before the current function */ int vid; /* old variable id top before the current function */ @@ -53,9 +53,9 @@ typedef struct backend { lng reloptimizer; /* timer for optimizer phase */ bool sizeheader:1, /* print size header in result set */ - no_mitosis:1, /* run query without mitosis */ - first_statement_generated:1, /* The first_statement_generated looks if the first of the sub-statements was generated or not */ - console:1; + no_mitosis:1, /* run query without mitosis */ + console:1, + silent:1; /* on some occasions we don't want to output the result set or the number of affected rows */ cq *q; /* pointer to the cached query */ int result_id; diff --git a/sql/backends/monet5/rel_bin.c b/sql/backends/monet5/rel_bin.c --- a/sql/backends/monet5/rel_bin.c +++ b/sql/backends/monet5/rel_bin.c @@ -39,6 +39,19 @@ clean_mal_statements(backend *be, int ol freeVariables(be->client, be->mb, NULL, oldvtop, oldvid); } +static int +add_to_rowcount_accumulator(backend *be, int nr) +{ + int prev = be->rowcount; + InstrPtr q = newStmt(be->mb, calcRef, plusRef); + + getArg(q, 0) = be->rowcount = newTmpVariable(be->mb, TYPE_lng); + q = pushArgument(be->mb, q, prev); + q = pushArgument(be->mb, q, nr); + + return getDestVar(q); +} + static stmt * stmt_selectnil( backend *be, stmt *col) { @@ -4234,8 +4247,8 @@ rel2bin_insert(backend *be, sql_rel *rel if (idx_ins) pin = refs_find_rel(refs, prel); - if (constraint && !be->first_statement_generated) - sql_insert_check_null(be, /*(be->cur_append && t->p) ? t->p :*/ t, inserts->op4.lval); + if (constraint && !be->rowcount) + sql_insert_check_null(be, t, inserts->op4.lval); l = sa_list(sql->sa); @@ -4247,14 +4260,6 @@ rel2bin_insert(backend *be, sql_rel *rel } /* before */ -#if 0 - if (be->cur_append && !be->first_statement_generated) { - for(sql_table *up = t->p ; up ; up = up->p) { - if (!sql_insert_triggers(be, up, updates, 0)) - return sql_error(sql, 02, SQLSTATE(27000) "INSERT INTO: triggers failed for table '%s'", up->base.name); - } - } -#endif if (!sql_insert_triggers(be, t, updates, 0)) return sql_error(sql, 02, SQLSTATE(27000) "INSERT INTO: triggers failed for table '%s'", t->base.name); @@ -4317,30 +4322,20 @@ rel2bin_insert(backend *be, sql_rel *rel if (!insert) return NULL; -#if 0 - if (be->cur_append && !be->first_statement_generated) { - for(sql_table *up = t->p ; up ; up = up->p) { - if (!sql_insert_triggers(be, up, updates, 1)) - return sql_error(sql, 02, SQLSTATE(27000) "INSERT INTO: triggers failed for table '%s'", up->base.name); - } - } -#endif if (!sql_insert_triggers(be, t, updates, 1)) return sql_error(sql, 02, SQLSTATE(27000) "INSERT INTO: triggers failed for table '%s'", t->base.name); if (ddl) { ret = ddl; list_prepend(l, ddl); + return stmt_list(be, l); } else { ret = cnt; - } - - if (be->cur_append) /* building the total number of rows affected across all tables */ - ret->nr = add_to_merge_partitions_accumulator(be, ret->nr); - - if (ddl) - return stmt_list(be, l); - else + if (!be->silent) { + /* if there are multiple update statements, update total count, otherwise use the the current count */ + be->rowcount = be->rowcount ? add_to_rowcount_accumulator(be, ret->nr) : ret->nr; + } return ret; + } } static int @@ -5164,8 +5159,8 @@ sql_update(backend *be, sql_table *t, st list *l = sa_list(sql->sa); node *n; - if (!be->first_statement_generated) - sql_update_check_null(be, /*(be->cur_append && t->p) ? t->p :*/ t, updates); + if (!be->rowcount) + sql_update_check_null(be, t, updates); /* check keys + get idx */ idx_updates = update_idxs_and_check_keys(be, t, rows, updates, l, NULL); @@ -5175,14 +5170,6 @@ sql_update(backend *be, sql_table *t, st } /* before */ -#if 0 - if (be->cur_append && !be->first_statement_generated) { - for(sql_table *up = t->p ; up ; up = up->p) { - if (!sql_update_triggers(be, up, rows, updates, 0)) - return sql_error(sql, 02, SQLSTATE(27000) "UPDATE: triggers failed for table '%s'", up->base.name); - } - } -#endif if (!sql_update_triggers(be, t, rows, updates, 0)) return sql_error(sql, 02, SQLSTATE(27000) "UPDATE: triggers failed for table '%s'", t->base.name); @@ -5197,14 +5184,6 @@ sql_update(backend *be, sql_table *t, st return sql_error(sql, 02, SQLSTATE(42000) "UPDATE: cascade failed for table '%s'", t->base.name); /* after */ -#if 0 - if (be->cur_append && !be->first_statement_generated) { - for(sql_table *up = t->p ; up ; up = up->p) { - if (!sql_update_triggers(be, up, rows, updates, 1)) - return sql_error(sql, 02, SQLSTATE(27000) "UPDATE: triggers failed for table '%s'", up->base.name); - } - } -#endif if (!sql_update_triggers(be, t, rows, updates, 1)) return sql_error(sql, 02, SQLSTATE(27000) "UPDATE: triggers failed for table '%s'", t->base.name); @@ -5217,7 +5196,7 @@ static stmt * rel2bin_update(backend *be, sql_rel *rel, list *refs) { mvc *sql = be->mvc; - stmt *update = NULL, **updates = NULL, *tids, *s, *ddl = NULL, *pup = NULL, *cnt; + stmt *update = NULL, **updates = NULL, *tids, *ddl = NULL, *pup = NULL, *cnt; list *l = sa_list(sql->sa); int nr_cols, updcol, idx_ups = 0; node *m; @@ -5265,8 +5244,8 @@ rel2bin_update(backend *be, sql_rel *rel if (c) updates[c->colnr] = bin_find_column(be, update, ce->l, ce->r); } - if (!be->first_statement_generated) - sql_update_check_null(be, /*(be->cur_append && t->p) ? t->p :*/ t, updates); + if (!be->rowcount) + sql_update_check_null(be, t, updates); /* check keys + get idx */ updcol = first_updated_col(updates, ol_length(t->columns)); @@ -5294,14 +5273,6 @@ rel2bin_update(backend *be, sql_rel *rel } /* before */ -#if 0 - if (be->cur_append && !be->first_statement_generated) { - for(sql_table *up = t->p ; up ; up = up->p) { - if (!sql_update_triggers(be, up, tids, updates, 0)) - return sql_error(sql, 02, SQLSTATE(27000) "UPDATE: triggers failed for table '%s'", up->base.name); - } - } -#endif if (!sql_update_triggers(be, t, tids, updates, 0)) { if (sql->cascade_action) sql->cascade_action = NULL; @@ -5324,14 +5295,6 @@ rel2bin_update(backend *be, sql_rel *rel } /* after */ -#if 0 - if (be->cur_append && !be->first_statement_generated) { - for(sql_table *up = t->p ; up ; up = up->p) { - if (!sql_update_triggers(be, up, tids, updates, 1)) - return sql_error(sql, 02, SQLSTATE(27000) "UPDATE: triggers failed for table '%s'", up->base.name); - } - } -#endif if (!sql_update_triggers(be, t, tids, updates, 1)) { if (sql->cascade_action) sql->cascade_action = NULL; @@ -5342,12 +5305,12 @@ rel2bin_update(backend *be, sql_rel *rel list_prepend(l, ddl); cnt = stmt_list(be, l); } else { - s = stmt_aggr(be, tids, NULL, NULL, sql_bind_func(sql, "sys", "count", sql_bind_localtype("void"), NULL, F_AGGR), 1, 0, 1); - cnt = s; - } - - if (be->cur_append) /* building the total number of rows affected across all tables */ - cnt->nr = add_to_merge_partitions_accumulator(be, cnt->nr); + cnt = stmt_aggr(be, tids, NULL, NULL, sql_bind_func(sql, "sys", "count", sql_bind_localtype("void"), NULL, F_AGGR), 1, 0, 1); + if (!be->silent) { + /* if there are multiple update statements, update total count, otherwise use the the current count */ + be->rowcount = be->rowcount ? add_to_rowcount_accumulator(be, cnt->nr) : cnt->nr; + } + } if (sql->cascade_action) sql->cascade_action = NULL; @@ -5539,14 +5502,6 @@ sql_delete(backend *be, sql_table *t, st } /* before */ -#if 0 - if (be->cur_append && !be->first_statement_generated) { - for(sql_table *up = t->p ; up ; up = up->p) { - if (!sql_delete_triggers(be, up, v, deleted_cols, 0, 1, 3)) - return sql_error(sql, 02, SQLSTATE(27000) "DELETE: triggers failed for table '%s'", up->base.name); - } - } -#endif if (!sql_delete_triggers(be, t, v, deleted_cols, 0, 1, 3)) return sql_error(sql, 02, SQLSTATE(27000) "DELETE: triggers failed for table '%s'", t->base.name); @@ -5554,28 +5509,16 @@ sql_delete(backend *be, sql_table *t, st return sql_error(sql, 02, SQLSTATE(42000) "DELETE: failed to delete indexes for table '%s'", t->base.name); if (rows) { - list_append(l, stmt_delete(be, t, rows)); + s = stmt_delete(be, t, rows); + if (!be->silent) + s = stmt_aggr(be, rows, NULL, NULL, sql_bind_func(sql, "sys", "count", sql_bind_localtype("void"), NULL, F_AGGR), 1, 0, 1); } else { /* delete all */ - /* first column */ - s = stmt_table_clear(be, t); - list_append(l, s); + s = stmt_table_clear(be, t); /* first column */ } /* after */ -#if 0 - if (be->cur_append && !be->first_statement_generated) { - for(sql_table *up = t->p ; up ; up = up->p) { - if (!sql_delete_triggers(be, up, v, deleted_cols, 1, 1, 3)) - return sql_error(sql, 02, SQLSTATE(27000) "DELETE: triggers failed for table '%s'", up->base.name); - } - } -#endif if (!sql_delete_triggers(be, t, v, deleted_cols, 1, 1, 3)) return sql_error(sql, 02, SQLSTATE(27000) "DELETE: triggers failed for table '%s'", t->base.name); - if (rows) - s = stmt_aggr(be, rows, NULL, NULL, sql_bind_func(sql, "sys", "count", sql_bind_localtype("void"), NULL, F_AGGR), 1, 0, 1); - if (be->cur_append) /* building the total number of rows affected across all tables */ - s->nr = add_to_merge_partitions_accumulator(be, s->nr); return s; } @@ -5583,7 +5526,7 @@ static stmt * rel2bin_delete(backend *be, sql_rel *rel, list *refs) { mvc *sql = be->mvc; - stmt *rows = NULL, *stdelete = NULL; + stmt *stdelete = NULL, *tids = NULL; sql_rel *tr = rel->l; sql_table *t = NULL; @@ -5593,18 +5536,23 @@ rel2bin_delete(backend *be, sql_rel *rel assert(0/*ddl statement*/); if (rel->r) { /* first construct the deletes relation */ - rows = subrel_bin(be, rel->r, refs); + stmt *rows = subrel_bin(be, rel->r, refs); rows = subrel_project(be, rows, refs, rel->r); _______________________________________________ checkin-list mailing list checkin-list@monetdb.org https://www.monetdb.org/mailman/listinfo/checkin-list