Changeset: 035e2d1156cf for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/035e2d1156cf
Modified Files:
        sql/include/sql_relation.h
        sql/server/rel_distribute.c
        sql/test/SQLancer/Tests/sqlancer19.SQL.py
Branch: Jul2021
Log Message:

Fixes for remote tables on merge statements. Don't copy the merge join, instead 
keep searching for remotes and don't propagate the property to the merge join


diffs (102 lines):

diff --git a/sql/include/sql_relation.h b/sql/include/sql_relation.h
--- a/sql/include/sql_relation.h
+++ b/sql/include/sql_relation.h
@@ -283,7 +283,13 @@ typedef struct relation {
         outer:1,       /* used as outer (ungrouped) */
         grouped:1,     /* groupby processed all the group by exps */
         single:1,
-        used:2;        /* used by rewriters at rel_unnest and rel_dce, so a 
relation is not modified twice */
+       /*
+        * Used by rewriters at rel_unnest, rel_optimizer and rel_distribute so 
a relation is not modified twice
+        * The first two bits are used by rel_unnest modifiers and always reset 
after.
+        * The first bit is also used by rel_dce and rel_merge_select_rse 
optimizers.
+        * The third bit is used by rel_remote_func only and it's not reset.
+        */
+        used:3;
        void *p;        /* properties for the optimizer, distribution */
 } sql_rel;
 
diff --git a/sql/server/rel_distribute.c b/sql/server/rel_distribute.c
--- a/sql/server/rel_distribute.c
+++ b/sql/server/rel_distribute.c
@@ -194,7 +194,8 @@ replica(mvc *sql, sql_rel *rel, char *ur
        if (!rel)
                return rel;
 
-       if (rel_is_ref(rel)) {
+       /* for merge statement join, ignore the multiple references */
+       if (rel_is_ref(rel) && !(rel->flag&MERGE_LEFT)) {
                if (has_remote_or_replica(rel)) {
                        sql_rel *nrel = rel_copy(sql, rel, 1);
 
@@ -365,7 +366,8 @@ distribute(mvc *sql, sql_rel *rel)
        if (!rel)
                return rel;
 
-       if (rel_is_ref(rel)) {
+       /* for merge statement join, ignore the multiple references */
+       if (rel_is_ref(rel) && !(rel->flag&MERGE_LEFT)) {
                if (has_remote_or_replica(rel)) {
                        sql_rel *nrel = rel_copy(sql, rel, 1);
 
@@ -434,6 +436,9 @@ distribute(mvc *sql, sql_rel *rel)
                        l = rel->l = distribute(sql, replica(sql, rel->l, 
pr->value));
                }
 
+               if (rel->flag&MERGE_LEFT) /* search for any remote tables but 
don't propagate over to this relation */
+                       return rel;
+
                if (l && (pl = find_prop(l->p, PROP_REMOTE)) != NULL &&
                    r && (pr = find_prop(r->p, PROP_REMOTE)) != NULL &&
                    strcmp(pl->value, pr->value) == 0) {
@@ -592,6 +597,13 @@ rel_remote_func(mvc *sql, sql_rel *rel)
        if (!rel)
                return rel;
 
+       if (rel_is_ref(rel)) { /* Don't modify the same relation twice */
+               int rused = 1 << 2;
+               if (rel->used & rused)
+                       return rel;
+               rel->used |= rused;
+       }
+
        switch (rel->op) {
        case op_basetable:
        case op_truncate:
diff --git a/sql/test/SQLancer/Tests/sqlancer19.SQL.py 
b/sql/test/SQLancer/Tests/sqlancer19.SQL.py
--- a/sql/test/SQLancer/Tests/sqlancer19.SQL.py
+++ b/sql/test/SQLancer/Tests/sqlancer19.SQL.py
@@ -9,17 +9,32 @@ with SQLTestCase() as cli:
     cli.connect(username="monetdb", password="monetdb")
     cli.execute("""
     START TRANSACTION;
+    CREATE TABLE "t0" ("c0" INTERVAL SECOND NOT NULL, "c1" JSON);
+    INSERT INTO "t0" VALUES (INTERVAL '9' SECOND, '""');
+
+    CREATE TABLE "t1" ("c0" BINARY LARGE OBJECT,"c1" BIGINT);
+    INSERT INTO "t1" VALUES (NULL, 1),(NULL, 6),(NULL, 0),(BINARY LARGE OBJECT 
'50', NULL),(BINARY LARGE OBJECT 'ACBC2EDEF0', NULL),
+    (BINARY LARGE OBJECT '65', NULL),(BINARY LARGE OBJECT 'EF43C0', 
NULL),(BINARY LARGE OBJECT '90', NULL),(BINARY LARGE OBJECT '', NULL);
+
     CREATE TABLE "t3" ("c0" BIGINT,"c1" INTERVAL MONTH);
     INSERT INTO "t3" VALUES (1, INTERVAL '9' MONTH),(5, INTERVAL '6' 
MONTH),(5, NULL),(7, NULL),(2, INTERVAL '1' MONTH),(2, INTERVAL '1' MONTH);
     COMMIT;
+
     START TRANSACTION;
+    CREATE REMOTE TABLE "rt1" ("c0" BINARY LARGE OBJECT,"c1" BIGINT) ON 
'mapi:monetdb://localhost:%s/%s/sys/t1';
     CREATE REMOTE TABLE "rt3" ("c0" BIGINT,"c1" INTERVAL MONTH) ON 
'mapi:monetdb://localhost:%s/%s/sys/t3';
-    COMMIT;""" % (port, db)).assertSucceeded()
+    COMMIT;""" % (port, db, port, db)).assertSucceeded()
 
     cli.execute('SELECT json."integer"(JSON \'1\') FROM 
rt3;').assertSucceeded().assertDataResultMatch([(1,),(1,),(1,),(1,),(1,),(1,)])
 
+    cli.execute('MERGE INTO t0 USING (SELECT 1 FROM rt1) AS mergejoined(c0) ON 
TRUE WHEN NOT MATCHED THEN INSERT (c0) VALUES (INTERVAL \'5\' SECOND);') \
+        .assertSucceeded().assertRowCount(0)
+
     cli.execute("""
     START TRANSACTION;
+    DROP TABLE rt1;
     DROP TABLE rt3;
+    DROP TABLE t0;
+    DROP TABLE t1;
     DROP TABLE t3;
     COMMIT;""").assertSucceeded()
_______________________________________________
checkin-list mailing list
checkin-list@monetdb.org
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to