v2-0001-Avoid-alias-name-collisions-in-REFRESH-MAT-VIEW.patch
application/octet-stream
Filename: v2-0001-Avoid-alias-name-collisions-in-REFRESH-MAT-VIEW.patch
Type: application/octet-stream
Part: 0
Patch
Format: format-patch
Series: patch v2-0001
Subject: Avoid alias name collisions in REFRESH MAT VIEW
| File | + | − |
|---|---|---|
| src/backend/commands/matview.c | 37 | 25 |
From 08b1714dad14d08eac3da09dd3eac23b99302220 Mon Sep 17 00:00:00 2001
From: Bharath Rupireddy <bharath.rupireddyforpostgres@gmail.com>
Date: Mon, 31 May 2021 21:30:53 -0700
Subject: [PATCH v2] Avoid alias name collisions in REFRESH MAT VIEW
---
src/backend/commands/matview.c | 62 ++++++++++++++++++++--------------
1 file changed, 37 insertions(+), 25 deletions(-)
diff --git a/src/backend/commands/matview.c b/src/backend/commands/matview.c
index 172ec6e982..c97c4a6685 100644
--- a/src/backend/commands/matview.c
+++ b/src/backend/commands/matview.c
@@ -599,6 +599,10 @@ refresh_by_match_merge(Oid matviewOid, Oid tempOid, Oid relowner,
ListCell *indexoidscan;
int16 relnatts;
Oid *opUsedForQual;
+ char *matviewalias;
+ char *newdataalias;
+ char *newdata2alias;
+ char *diffalias;
initStringInfo(&querybuf);
matviewRel = table_open(matviewOid, NoLock);
@@ -608,7 +612,10 @@ refresh_by_match_merge(Oid matviewOid, Oid tempOid, Oid relowner,
tempname = quote_qualified_identifier(get_namespace_name(RelationGetNamespace(tempRel)),
RelationGetRelationName(tempRel));
diffname = make_temptable_name_n(tempname, 2);
-
+ matviewalias = make_temptable_name_n("pg_matview_", MyProcPid);
+ newdataalias = make_temptable_name_n("pg_newdata_", MyProcPid);
+ newdata2alias = make_temptable_name_n("pg_newdata2_", MyProcPid);
+ diffalias = make_temptable_name_n("pg_diff_", MyProcPid);
relnatts = RelationGetNumberOfAttributes(matviewRel);
/* Open SPI context. */
@@ -629,13 +636,15 @@ refresh_by_match_merge(Oid matviewOid, Oid tempOid, Oid relowner,
*/
resetStringInfo(&querybuf);
appendStringInfo(&querybuf,
- "SELECT newdata FROM %s newdata "
- "WHERE newdata IS NOT NULL AND EXISTS "
- "(SELECT 1 FROM %s newdata2 WHERE newdata2 IS NOT NULL "
- "AND newdata2 OPERATOR(pg_catalog.*=) newdata "
- "AND newdata2.ctid OPERATOR(pg_catalog.<>) "
- "newdata.ctid)",
- tempname, tempname);
+ "SELECT %s FROM %s %s "
+ "WHERE %s IS NOT NULL AND EXISTS "
+ "(SELECT 1 FROM %s %s WHERE %s IS NOT NULL "
+ "AND %s OPERATOR(pg_catalog.*=) %s "
+ "AND %s.ctid OPERATOR(pg_catalog.<>) "
+ "%s.ctid)",
+ newdataalias,tempname, newdataalias, newdataalias,
+ tempname, newdata2alias, newdata2alias, newdata2alias,
+ newdataalias, newdata2alias, newdataalias);
if (SPI_execute(querybuf.data, false, 1) != SPI_OK_SELECT)
elog(ERROR, "SPI_exec failed: %s", querybuf.data);
if (SPI_processed > 0)
@@ -662,9 +671,10 @@ refresh_by_match_merge(Oid matviewOid, Oid tempOid, Oid relowner,
resetStringInfo(&querybuf);
appendStringInfo(&querybuf,
"CREATE TEMP TABLE %s AS "
- "SELECT mv.ctid AS tid, newdata "
- "FROM %s mv FULL JOIN %s newdata ON (",
- diffname, matviewname, tempname);
+ "SELECT %s.ctid AS tid, %s "
+ "FROM %s %s FULL JOIN %s %s ON (",
+ diffname, matviewalias, newdataalias, matviewname,
+ matviewalias, tempname, newdataalias);
/*
* Get the list of index OIDs for the table from the relcache, and look up
@@ -756,9 +766,9 @@ refresh_by_match_merge(Oid matviewOid, Oid tempOid, Oid relowner,
if (foundUniqueIndex)
appendStringInfoString(&querybuf, " AND ");
- leftop = quote_qualified_identifier("newdata",
+ leftop = quote_qualified_identifier(newdataalias,
NameStr(attr->attname));
- rightop = quote_qualified_identifier("mv",
+ rightop = quote_qualified_identifier(matviewalias,
NameStr(attr->attname));
generate_operator_clause(&querybuf,
@@ -785,10 +795,10 @@ refresh_by_match_merge(Oid matviewOid, Oid tempOid, Oid relowner,
*/
Assert(foundUniqueIndex);
- appendStringInfoString(&querybuf,
- " AND newdata OPERATOR(pg_catalog.*=) mv) "
- "WHERE newdata IS NULL OR mv IS NULL "
- "ORDER BY tid");
+ appendStringInfo(&querybuf,
+ " AND %s OPERATOR(pg_catalog.*=) %s) "
+ "WHERE %s IS NULL OR %s IS NULL ORDER BY tid",
+ newdataalias, matviewalias, newdataalias, matviewalias);
/* Create the temporary "diff" table. */
if (SPI_exec(querybuf.data, 0) != SPI_OK_UTILITY)
@@ -813,20 +823,22 @@ refresh_by_match_merge(Oid matviewOid, Oid tempOid, Oid relowner,
/* Deletes must come before inserts; do them first. */
resetStringInfo(&querybuf);
appendStringInfo(&querybuf,
- "DELETE FROM %s mv WHERE ctid OPERATOR(pg_catalog.=) ANY "
- "(SELECT diff.tid FROM %s diff "
- "WHERE diff.tid IS NOT NULL "
- "AND diff.newdata IS NULL)",
- matviewname, diffname);
+ "DELETE FROM %s %s WHERE ctid OPERATOR(pg_catalog.=) ANY "
+ "(SELECT %s.tid FROM %s %s "
+ "WHERE %s.tid IS NOT NULL "
+ "AND %s.%s IS NULL)",
+ matviewname, matviewalias, diffalias, diffname,
+ diffalias, diffalias, diffalias, newdataalias);
if (SPI_exec(querybuf.data, 0) != SPI_OK_DELETE)
elog(ERROR, "SPI_exec failed: %s", querybuf.data);
/* Inserts go last. */
resetStringInfo(&querybuf);
appendStringInfo(&querybuf,
- "INSERT INTO %s SELECT (diff.newdata).* "
- "FROM %s diff WHERE tid IS NULL",
- matviewname, diffname);
+ "INSERT INTO %s SELECT (%s.%s).* "
+ "FROM %s %s WHERE tid IS NULL",
+ matviewname, diffalias, newdataalias,
+ diffname, diffalias);
if (SPI_exec(querybuf.data, 0) != SPI_OK_INSERT)
elog(ERROR, "SPI_exec failed: %s", querybuf.data);
--
2.25.1