char *matviewname;
char *tempname;
char *diffname;
+ char *qualified_diffname;
+ char *tempschema;
TupleDesc tupdesc;
bool foundUniqueIndex;
List *indexoidlist;
matviewname = quote_qualified_identifier(get_namespace_name(RelationGetNamespace(matviewRel)),
RelationGetRelationName(matviewRel));
tempRel = heap_open(tempOid, NoLock);
- tempname = quote_qualified_identifier(get_namespace_name(RelationGetNamespace(tempRel)),
+ tempschema = get_namespace_name(RelationGetNamespace(tempRel));
+ tempname = quote_qualified_identifier(tempschema,
RelationGetRelationName(tempRel));
- diffname = make_temptable_name_n(tempname, 2);
+ diffname = make_temptable_name_n(RelationGetRelationName(tempRel), 2);
+ qualified_diffname = quote_qualified_identifier(tempschema, diffname);
relnatts = matviewRel->rd_rel->relnatts;
usedForQual = (bool *) palloc0(sizeof(bool) * relnatts);
#endif
"SELECT mv.ctid AS tid, newdata "
"FROM %s mv FULL JOIN %s newdata ON (",
- diffname, matviewname, tempname);
+ qualified_diffname,
+ matviewname, tempname);
/*
* Get the list of index OIDs for the table from the relcache, and look up
* must keep it around because its type is referenced from the diff table.
*/
+#ifndef PGXC
/* Analyze the diff table. */
resetStringInfo(&querybuf);
- appendStringInfo(&querybuf, "ANALYZE %s", diffname);
+ appendStringInfo(&querybuf, "ANALYZE %s", qualified_diffname);
if (SPI_exec(querybuf.data, 0) != SPI_OK_UTILITY)
elog(ERROR, "SPI_exec failed: %s", querybuf.data);
+#else
+ {
+ /*
+ * Don't want to send down the ANALYZE on the remote nodes because the
+ * temporary table was not created there to start with. See above.
+ */
+ VacuumStmt *stmt = makeNode(VacuumStmt);
+ RangeVar *rv = makeRangeVar(tempschema, diffname, -1);
+ stmt->relation = rv;
+ stmt->options = VACOPT_ANALYZE;
+ ExecVacuum(stmt, true);
+ }
+#endif
OpenMatViewIncrementalMaintenance();
"(SELECT diff.tid FROM %s diff "
"WHERE diff.tid IS NOT NULL "
"AND diff.newdata IS NULL)",
- matviewname, diffname);
+ matviewname,
+ qualified_diffname);
if (SPI_exec(querybuf.data, 0) != SPI_OK_DELETE)
elog(ERROR, "SPI_exec failed: %s", querybuf.data);
appendStringInfo(&querybuf,
"INSERT INTO %s SELECT (diff.newdata).* "
"FROM %s diff WHERE tid IS NULL",
- matviewname, diffname);
+ matviewname,
+ qualified_diffname);
if (SPI_exec(querybuf.data, 0) != SPI_OK_INSERT)
elog(ERROR, "SPI_exec failed: %s", querybuf.data);
/* Clean up temp tables. */
resetStringInfo(&querybuf);
- appendStringInfo(&querybuf, "DROP TABLE %s, %s", diffname, tempname);
+ appendStringInfo(&querybuf, "DROP TABLE %s, %s",
+ qualified_diffname, tempname);
if (SPI_exec(querybuf.data, 0) != SPI_OK_UTILITY)
elog(ERROR, "SPI_exec failed: %s", querybuf.data);
z | 11
(3 rows)
+REFRESH MATERIALIZED VIEW CONCURRENTLY tm;
REFRESH MATERIALIZED VIEW tvm;
SELECT * FROM tm ORDER BY type;
type | totamt
------+--------
x | 5
y | 12
- z | 11
+ z | 24
(3 rows)
SELECT * FROM tvm ORDER BY type;
SELECT * FROM tmm;
grandtot
----------
- 28
+ 41
(1 row)
SELECT * FROM tvmm;
------+------+------
x | 5 | 5
y | 12 | 12
- z | 11 | 24
+ z | 24 | 24
(3 rows)
-- make sure that dependencies are reported properly when they block the drop
REFRESH MATERIALIZED VIEW mv;
ERROR: could not create unique index "mv_a_idx"
DETAIL: Key (a)=(1) is duplicated.
+REFRESH MATERIALIZED VIEW CONCURRENTLY mv;
+ERROR: new data for materialized view "mv" contains duplicate rows without any null columns
+DETAIL: Row: (1,10)
DROP TABLE foo CASCADE;
NOTICE: drop cascades to materialized view mv
-- make sure that all columns covered by unique indexes works
INSERT INTO foo VALUES(2, 3, 4);
INSERT INTO foo VALUES(3, 4, 5);
REFRESH MATERIALIZED VIEW mv;
+REFRESH MATERIALIZED VIEW CONCURRENTLY mv;
DROP TABLE foo CASCADE;
NOTICE: drop cascades to materialized view mv
-- allow subquery to reference unpopulated matview if WITH NO DATA is specified
CREATE MATERIALIZED VIEW boxmv AS SELECT * FROM boxes;
CREATE UNIQUE INDEX boxmv_id ON boxmv (id);
UPDATE boxes SET b = '(2,2),(1,1)' WHERE id = 2;
+REFRESH MATERIALIZED VIEW CONCURRENTLY boxmv;
SELECT * FROM boxmv ORDER BY id;
id | b
----+-----------------------------
1 | (32,32),(31,31)
- 2 | (2.0000004,2.0000004),(1,1)
+ 2 | (2,2),(1,1)
3 | (1.9999996,1.9999996),(1,1)
(3 rows)
DROP TABLE boxes CASCADE;
NOTICE: drop cascades to materialized view boxmv
+-- make sure that column names are handled correctly
CREATE TABLE mvtest_v (i int, j int);
CREATE MATERIALIZED VIEW mvtest_mv_v (ii, jj, kk) AS SELECT i, j FROM mvtest_v; -- error
ERROR: too many column names were specified
CREATE UNIQUE INDEX mvtest_mv_v_ii ON mvtest_mv_v (ii);
REFRESH MATERIALIZED VIEW mvtest_mv_v;
UPDATE mvtest_v SET j = 3 WHERE x = 1;
--- REFRESH MATERIALIZED VIEW CONCURRENTLY mvtest_mv_v;
+REFRESH MATERIALIZED VIEW CONCURRENTLY mvtest_mv_v;
REFRESH MATERIALIZED VIEW mvtest_mv_v_2;
REFRESH MATERIALIZED VIEW mvtest_mv_v_3;
REFRESH MATERIALIZED VIEW mvtest_mv_v_4;
SELECT * FROM mvtest_mv_v;
ii | jj
----+----
- 1 | 2
+ 1 | 3
(1 row)
SELECT * FROM mvtest_mv_v_2;
CREATE UNIQUE INDEX ON mv_foo (i);
RESET ROLE;
REFRESH MATERIALIZED VIEW mv_foo;
+REFRESH MATERIALIZED VIEW CONCURRENTLY mv_foo;
DROP OWNED BY user_dw CASCADE;
DROP ROLE user_dw;
-- make sure that create WITH NO DATA works via SPI
-- confirm pre- and post-refresh contents of fairly simple materialized views
SELECT * FROM tm ORDER BY type;
SELECT * FROM tvm ORDER BY type;
+REFRESH MATERIALIZED VIEW CONCURRENTLY tm;
REFRESH MATERIALIZED VIEW tvm;
SELECT * FROM tm ORDER BY type;
SELECT * FROM tvm ORDER BY type;
CREATE UNIQUE INDEX ON mv(a);
INSERT INTO foo SELECT * FROM foo;
REFRESH MATERIALIZED VIEW mv;
+REFRESH MATERIALIZED VIEW CONCURRENTLY mv;
DROP TABLE foo CASCADE;
-- make sure that all columns covered by unique indexes works
INSERT INTO foo VALUES(2, 3, 4);
INSERT INTO foo VALUES(3, 4, 5);
REFRESH MATERIALIZED VIEW mv;
+REFRESH MATERIALIZED VIEW CONCURRENTLY mv;
DROP TABLE foo CASCADE;
-- allow subquery to reference unpopulated matview if WITH NO DATA is specified
CREATE MATERIALIZED VIEW boxmv AS SELECT * FROM boxes;
CREATE UNIQUE INDEX boxmv_id ON boxmv (id);
UPDATE boxes SET b = '(2,2),(1,1)' WHERE id = 2;
+REFRESH MATERIALIZED VIEW CONCURRENTLY boxmv;
SELECT * FROM boxmv ORDER BY id;
DROP TABLE boxes CASCADE;
-
+-- make sure that column names are handled correctly
CREATE TABLE mvtest_v (i int, j int);
CREATE MATERIALIZED VIEW mvtest_mv_v (ii, jj, kk) AS SELECT i, j FROM mvtest_v; -- error
CREATE MATERIALIZED VIEW mvtest_mv_v (ii, jj) AS SELECT i, j FROM mvtest_v; -- ok
CREATE UNIQUE INDEX mvtest_mv_v_ii ON mvtest_mv_v (ii);
REFRESH MATERIALIZED VIEW mvtest_mv_v;
UPDATE mvtest_v SET j = 3 WHERE x = 1;
--- REFRESH MATERIALIZED VIEW CONCURRENTLY mvtest_mv_v;
+REFRESH MATERIALIZED VIEW CONCURRENTLY mvtest_mv_v;
REFRESH MATERIALIZED VIEW mvtest_mv_v_2;
REFRESH MATERIALIZED VIEW mvtest_mv_v_3;
REFRESH MATERIALIZED VIEW mvtest_mv_v_4;
CREATE UNIQUE INDEX ON mv_foo (i);
RESET ROLE;
REFRESH MATERIALIZED VIEW mv_foo;
+REFRESH MATERIALIZED VIEW CONCURRENTLY mv_foo;
DROP OWNED BY user_dw CASCADE;
DROP ROLE user_dw;