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
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list