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