Hi,
pg_stat_statements tracks the number of rows processed
by some utility commands.
But, currently, it does not track the number of rows
processed by REFRESH MATERIALIZED VIEW.
Attached patch enables pg_stat_statements to track
processed rows by REFRESH MATERIALIZED VIEW.
Regards,
Katsuragi Yuta
diff --git a/contrib/pg_stat_statements/expected/pg_stat_statements.out b/contrib/pg_stat_statements/expected/pg_stat_statements.out
index e0edb134f3..2a303a7f07 100644
--- a/contrib/pg_stat_statements/expected/pg_stat_statements.out
+++ b/contrib/pg_stat_statements/expected/pg_stat_statements.out
@@ -530,8 +530,8 @@ SELECT query, calls, rows FROM pg_stat_statements ORDER BY query COLLATE "C";
--
-- Track the total number of rows retrieved or affected by the utility
--- commands of COPY, FETCH, CREATE TABLE AS, CREATE MATERIALIZED VIEW
--- and SELECT INTO
+-- commands of COPY, FETCH, CREATE TABLE AS, CREATE MATERIALIZED VIEW,
+-- REFRESH MATERIALIZED VIEW and SELECT INTO
--
SELECT pg_stat_statements_reset();
pg_stat_statements_reset
@@ -543,6 +543,7 @@ CREATE TABLE pgss_ctas AS SELECT a, 'ctas' b FROM generate_series(1, 10) a;
SELECT generate_series(1, 10) c INTO pgss_select_into;
COPY pgss_ctas (a, b) FROM STDIN;
CREATE MATERIALIZED VIEW pgss_matv AS SELECT * FROM pgss_ctas;
+REFRESH MATERIALIZED VIEW pgss_matv;
BEGIN;
DECLARE pgss_cursor CURSOR FOR SELECT * FROM pgss_matv;
FETCH NEXT pgss_cursor;
@@ -586,10 +587,11 @@ SELECT query, plans, calls, rows FROM pg_stat_statements ORDER BY query COLLATE
FETCH FORWARD 5 pgss_cursor | 0 | 1 | 5
FETCH FORWARD ALL pgss_cursor | 0 | 1 | 7
FETCH NEXT pgss_cursor | 0 | 1 | 1
+ REFRESH MATERIALIZED VIEW pgss_matv | 0 | 1 | 13
SELECT generate_series(1, 10) c INTO pgss_select_into | 0 | 1 | 10
SELECT pg_stat_statements_reset() | 0 | 1 | 1
SELECT query, plans, calls, rows FROM pg_stat_statements ORDER BY query COLLATE "C" | 1 | 0 | 0
-(12 rows)
+(13 rows)
--
-- Track user activity and reset them
diff --git a/contrib/pg_stat_statements/pg_stat_statements.c b/contrib/pg_stat_statements/pg_stat_statements.c
index 1eac9edaee..1c2ac24cf6 100644
--- a/contrib/pg_stat_statements/pg_stat_statements.c
+++ b/contrib/pg_stat_statements/pg_stat_statements.c
@@ -1173,11 +1173,12 @@ pgss_ProcessUtility(PlannedStmt *pstmt, const char *queryString,
/*
* Track the total number of rows retrieved or affected by
* the utility statements of COPY, FETCH, CREATE TABLE AS,
- * CREATE MATERIALIZED VIEW and SELECT INTO.
+ * CREATE MATERIALIZED VIEW, REFRESH MATERIALIZED VIEW and SELECT INTO.
*/
rows = (qc && (qc->commandTag == CMDTAG_COPY ||
qc->commandTag == CMDTAG_FETCH ||
- qc->commandTag == CMDTAG_SELECT)) ?
+ qc->commandTag == CMDTAG_SELECT ||
+ qc->commandTag == CMDTAG_REFRESH_MATERIALIZED_VIEW)) ?
qc->nprocessed : 0;
/* calc differences of buffer counters. */
diff --git a/contrib/pg_stat_statements/sql/pg_stat_statements.sql b/contrib/pg_stat_statements/sql/pg_stat_statements.sql
index 996a24a293..e9f5bb84e3 100644
--- a/contrib/pg_stat_statements/sql/pg_stat_statements.sql
+++ b/contrib/pg_stat_statements/sql/pg_stat_statements.sql
@@ -252,8 +252,8 @@ SELECT query, calls, rows FROM pg_stat_statements ORDER BY query COLLATE "C";
--
-- Track the total number of rows retrieved or affected by the utility
--- commands of COPY, FETCH, CREATE TABLE AS, CREATE MATERIALIZED VIEW
--- and SELECT INTO
+-- commands of COPY, FETCH, CREATE TABLE AS, CREATE MATERIALIZED VIEW,
+-- REFRESH MATERIALIZED VIEW and SELECT INTO
--
SELECT pg_stat_statements_reset();
@@ -265,6 +265,7 @@ COPY pgss_ctas (a, b) FROM STDIN;
13 copy
\.
CREATE MATERIALIZED VIEW pgss_matv AS SELECT * FROM pgss_ctas;
+REFRESH MATERIALIZED VIEW pgss_matv;
BEGIN;
DECLARE pgss_cursor CURSOR FOR SELECT * FROM pgss_matv;
FETCH NEXT pgss_cursor;
diff --git a/src/backend/commands/matview.c b/src/backend/commands/matview.c
index f80a9e96a9..cdc2e62ad4 100644
--- a/src/backend/commands/matview.c
+++ b/src/backend/commands/matview.c
@@ -136,7 +136,7 @@ SetMatViewPopulatedState(Relation relation, bool newstate)
*/
ObjectAddress
ExecRefreshMatView(RefreshMatViewStmt *stmt, const char *queryString,
- ParamListInfo params, QueryCompletion *qc)
+ ParamListInfo params, QueryCompletion *qc, uint64 *processed)
{
Oid matviewOid;
Relation matviewRel;
@@ -147,7 +147,6 @@ ExecRefreshMatView(RefreshMatViewStmt *stmt, const char *queryString,
Oid relowner;
Oid OIDNewHeap;
DestReceiver *dest;
- uint64 processed = 0;
bool concurrent;
LOCKMODE lockmode;
char relpersistence;
@@ -311,7 +310,7 @@ ExecRefreshMatView(RefreshMatViewStmt *stmt, const char *queryString,
/* Generate the data, if wanted. */
if (!stmt->skipData)
- processed = refresh_matview_datafill(dest, dataQuery, queryString);
+ *processed = refresh_matview_datafill(dest, dataQuery, queryString);
/* Make the matview match the newly generated data. */
if (concurrent)
@@ -343,7 +342,7 @@ ExecRefreshMatView(RefreshMatViewStmt *stmt, const char *queryString,
*/
pgstat_count_truncate(matviewRel);
if (!stmt->skipData)
- pgstat_count_heap_insert(matviewRel, processed);
+ pgstat_count_heap_insert(matviewRel, *processed);
}
table_close(matviewRel, NoLock);
diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c
index 9713a7ac41..19e964ea5c 100644
--- a/src/backend/tcop/utility.c
+++ b/src/backend/tcop/utility.c
@@ -1638,24 +1638,27 @@ ProcessUtilitySlow(ParseState *pstate,
break;
case T_RefreshMatViewStmt:
-
- /*
- * REFRESH CONCURRENTLY executes some DDL commands internally.
- * Inhibit DDL command collection here to avoid those commands
- * from showing up in the deparsed command queue. The refresh
- * command itself is queued, which is enough.
- */
- EventTriggerInhibitCommandCollection();
- PG_TRY();
{
- address = ExecRefreshMatView((RefreshMatViewStmt *) parsetree,
- queryString, params, qc);
- }
- PG_FINALLY();
- {
- EventTriggerUndoInhibitCommandCollection();
+ uint64 processed = 0;
+ /*
+ * REFRESH CONCURRENTLY executes some DDL commands internally.
+ * Inhibit DDL command collection here to avoid those commands
+ * from showing up in the deparsed command queue. The refresh
+ * command itself is queued, which is enough.
+ */
+ EventTriggerInhibitCommandCollection();
+ PG_TRY();
+ {
+ address = ExecRefreshMatView((RefreshMatViewStmt *) parsetree,
+ queryString, params, qc, &processed);
+ }
+ PG_FINALLY();
+ {
+ EventTriggerUndoInhibitCommandCollection();
+ }
+ PG_END_TRY();
+ SetQueryCompletion(qc, CMDTAG_REFRESH_MATERIALIZED_VIEW, processed);
}
- PG_END_TRY();
break;
case T_CreateTrigStmt:
diff --git a/src/include/commands/matview.h b/src/include/commands/matview.h
index 3ea4f5c80b..9407883261 100644
--- a/src/include/commands/matview.h
+++ b/src/include/commands/matview.h
@@ -24,7 +24,7 @@
extern void SetMatViewPopulatedState(Relation relation, bool newstate);
extern ObjectAddress ExecRefreshMatView(RefreshMatViewStmt *stmt, const char *queryString,
- ParamListInfo params, QueryCompletion *qc);
+ ParamListInfo params, QueryCompletion *qc, uint64 *processed);
extern DestReceiver *CreateTransientRelDestReceiver(Oid oid);