#include "executor/spi.h"
#include "miscadmin.h"
#include "parser/parse_relation.h"
+#include "pgstat.h"
#include "rewrite/rewriteHandler.h"
#include "storage/lmgr.h"
#include "storage/smgr.h"
static bool transientrel_receive(TupleTableSlot *slot, DestReceiver *self);
static void transientrel_shutdown(DestReceiver *self);
static void transientrel_destroy(DestReceiver *self);
-static void refresh_matview_datafill(DestReceiver *dest, Query *query,
+static uint64 refresh_matview_datafill(DestReceiver *dest, Query *query,
const char *queryString);
static char *make_temptable_name_n(char *tempname, int n);
Oid relowner;
Oid OIDNewHeap;
DestReceiver *dest;
+ uint64 processed = 0;
bool concurrent;
LOCKMODE lockmode;
char relpersistence;
/* Generate the data, if wanted. */
if (!stmt->skipData)
- refresh_matview_datafill(dest, dataQuery, queryString);
+ processed = refresh_matview_datafill(dest, dataQuery, queryString);
heap_close(matviewRel, NoLock);
Assert(matview_maintenance_depth == old_depth);
}
else
+ {
refresh_by_heap_swap(matviewOid, OIDNewHeap, relpersistence);
+ /*
+ * Inform stats collector about our activity: basically, we truncated
+ * the matview and inserted some new data. (The concurrent code path
+ * above doesn't need to worry about this because the inserts and
+ * deletes it issues get counted by lower-level code.)
+ */
+ pgstat_count_truncate(matviewRel);
+ if (!stmt->skipData)
+ pgstat_count_heap_insert(matviewRel, processed);
+ }
+
/* Roll back any GUC changes */
AtEOXact_GUC(false, save_nestlevel);
/*
* refresh_matview_datafill
+ *
+ * Execute the given query, sending result rows to "dest" (which will
+ * insert them into the target matview).
+ *
+ * Returns number of rows inserted.
*/
-static void
+static uint64
refresh_matview_datafill(DestReceiver *dest, Query *query,
const char *queryString)
{
PlannedStmt *plan;
QueryDesc *queryDesc;
Query *copied_query;
+ uint64 processed;
/* Lock and rewrite, using a copy to preserve the original query. */
copied_query = copyObject(query);
/* run the plan */
ExecutorRun(queryDesc, ForwardScanDirection, 0L);
+ processed = queryDesc->estate->es_processed;
+
/* and clean up */
ExecutorFinish(queryDesc);
ExecutorEnd(queryDesc);
FreeQueryDesc(queryDesc);
PopActiveSnapshot();
+
+ return processed;
}
DestReceiver *