Changeset: 4ae287228851 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=4ae287228851
Added Files:
        sql/test/Tests/appendtwice.sql
        sql/test/Tests/appendtwice.stable.err
        sql/test/Tests/appendtwice.stable.out
Modified Files:
        monetdb5/optimizer/opt_parappend.c
        sql/test/Tests/All
Branch: copybinary
Log Message:

Keep subsequent append to the same table separate


diffs (160 lines):

diff --git a/monetdb5/optimizer/opt_parappend.c 
b/monetdb5/optimizer/opt_parappend.c
--- a/monetdb5/optimizer/opt_parappend.c
+++ b/monetdb5/optimizer/opt_parappend.c
@@ -72,7 +72,7 @@ OPTparappendImplementation(Client cntxt,
                        pushInstruction(mb, p);
                }
                if (msg != MAL_SUCCEED)
-                       return msg;
+                       goto end;
        }
        assert(state.prep_stmt == NULL);
 
@@ -125,6 +125,7 @@ transform(parstate *state, Client cntxt,
 
        if (!sname_constant || !tname_constant || !cname_constant) {
                // cannot transform this
+               flush_finish_stmt(state, mb);
                pushInstruction(mb, old);
                return MAL_SUCCEED;
        }
@@ -132,6 +133,7 @@ transform(parstate *state, Client cntxt,
        const char *cname = getVarConstant(mb, cname_var).val.sval;
        if (cname[0] == '%') {
                // don't touch indices
+               flush_finish_stmt(state, mb);
                pushInstruction(mb, old);
                return MAL_SUCCEED;
        }
@@ -168,44 +170,46 @@ setup_append_prep(parstate *state, Clien
 
        // check if the state refers to a sql.append_prep statement that can be
        // reused.
-       InstrPtr prep_stmt = NULL;
+       InstrPtr prep_stmt = state->prep_stmt;
        do {
-               if (state->prep_stmt == NULL)
+               if (prep_stmt == NULL)
                        break;
 
-               InstrPtr prev = state->prep_stmt;
-
-               int existing_sname_var = getArg(prev, prev->retc + 1);
-               int existing_tname_var = getArg(prev, prev->retc + 2);
+               int existing_sname_var = getArg(prep_stmt, prep_stmt->retc + 1);
+               int existing_tname_var = getArg(prep_stmt, prep_stmt->retc + 2);
 
                const char *existing_sname = getVarConstant(mb, 
existing_sname_var).val.sval;
                const char *incoming_sname = getVarConstant(mb, 
sname_var).val.sval;
-               if (strcmp(existing_sname, incoming_sname) != 0)
+               if (strcmp(existing_sname, incoming_sname) != 0) {
+                       prep_stmt = NULL;
                        break;
+               }
 
                const char *existing_tname = getVarConstant(mb, 
existing_tname_var).val.sval;
                const char *incoming_tname = getVarConstant(mb, 
tname_var).val.sval;
-               if (strcmp(existing_tname, incoming_tname) != 0)
+               if (strcmp(existing_tname, incoming_tname) != 0) {
+                       prep_stmt = NULL;
                        break;
+               }
 
                const char *incoming_cname = getVarConstant(mb, 
cname_var).val.sval;
-               int existing_cols = prev->retc - 1;
-               for (int i = prev->argc - existing_cols; i < prev->argc; i++) {
-                       int var = getArg(prev, i);
+               int existing_cols = prep_stmt->retc - 1;
+               for (int i = prep_stmt->argc - existing_cols; i < 
prep_stmt->argc; i++) {
+                       int var = getArg(prep_stmt, i);
                        const char *existing_cname = getVarConstant(mb, 
var).val.sval;
                        if (strcmp(existing_cname, incoming_cname) == 0) {
                                // We're not prepared for the complications 
that may arise
                                // when there are multiple appends to the same 
column.
-                               // In particular we would have to track down 
where the previous
+                               // In particular we would have to track down 
where the prep_stmtious
                                // cookie is used and make sure we execute the 
next append
                                // after that use.
                                // This is unlikely to occur in practice, so 
instead we just start over.
+                               prep_stmt = NULL;
                                break;
                        }
                }
 
                // It seems there is no objection to reusing the existing 
sql.append_prep.
-               prep_stmt = prev;
        } while (0);
 
        int cookie_var = newTmpVariable(mb, TYPE_ptr);
diff --git a/sql/test/Tests/All b/sql/test/Tests/All
--- a/sql/test/Tests/All
+++ b/sql/test/Tests/All
@@ -128,3 +128,5 @@ HAVE_PYMONETDB&HAVE_LIBBZ2?hot_snapshot_
 HAVE_PYMONETDB&HAVE_LIBLZMA?hot_snapshot_xz
 HAVE_PYTHON_LZ4&HAVE_PYMONETDB&HAVE_LIBLZ4?hot_snapshot_lz4
 !HAVE_PYTHON_LZ4&HAVE_PYMONETDB&HAVE_LIBLZ4?hot_snapshot_lz4_lite
+
+appendtwice
diff --git a/sql/test/Tests/appendtwice.sql b/sql/test/Tests/appendtwice.sql
new file mode 100644
--- /dev/null
+++ b/sql/test/Tests/appendtwice.sql
@@ -0,0 +1,10 @@
+
+DROP TABLE IF EXISTS foo CASCADE;
+CREATE TABLE foo(i INT, j INT DEFAULT 42);
+
+CREATE PROCEDURE append_twice() BEGIN INSERT INTO foo(i) VALUES (0), (1), (2); 
INSERT INTO foo(i) VALUES (10), (11), (12); END;
+
+-- if optimizer.parappend does not keep the appends separate, data may get lost
+CALL append_twice();
+
+SELECT * FROM foo;
diff --git a/sql/test/Tests/appendtwice.stable.err 
b/sql/test/Tests/appendtwice.stable.err
new file mode 100644
--- /dev/null
+++ b/sql/test/Tests/appendtwice.stable.err
@@ -0,0 +1,12 @@
+stderr of test 'appendtwice` in directory 'sql/test` itself:
+
+
+# 14:57:08 >  
+# 14:57:08 >  "mclient" "-lsql" "-ftest" "-tnone" "-Eutf-8" "-i" "-e" 
"--host=/var/tmp/mtest-11017" "--port=36169"
+# 14:57:08 >  
+
+
+# 14:57:08 >  
+# 14:57:08 >  "Done."
+# 14:57:08 >  
+
diff --git a/sql/test/Tests/appendtwice.stable.out 
b/sql/test/Tests/appendtwice.stable.out
new file mode 100644
--- /dev/null
+++ b/sql/test/Tests/appendtwice.stable.out
@@ -0,0 +1,26 @@
+stdout of test 'appendtwice` in directory 'sql/test` itself:
+
+
+# 14:57:08 >  
+# 14:57:08 >  "mclient" "-lsql" "-ftest" "-tnone" "-Eutf-8" "-i" "-e" 
"--host=/var/tmp/mtest-11017" "--port=36169"
+# 14:57:08 >  
+
+#DROP TABLE IF EXISTS foo CASCADE;
+#CREATE TABLE foo(i INT, j INT DEFAULT 42);
+#CREATE PROCEDURE append_twice() BEGIN INSERT INTO foo(i) VALUES (0), (1), 
(2); INSERT INTO foo(i) VALUES (10), (11), (12); END;
+#SELECT * FROM foo;
+% sys.foo,     sys.foo # table_name
+% i,   j # name
+% int, int # type
+% 2,   2 # length
+[ 0,   42      ]
+[ 1,   42      ]
+[ 2,   42      ]
+[ 10,  42      ]
+[ 11,  42      ]
+[ 12,  42      ]
+
+# 14:57:08 >  
+# 14:57:08 >  "Done."
+# 14:57:08 >  
+
_______________________________________________
checkin-list mailing list
checkin-list@monetdb.org
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to