@@ -112,15 +112,44 @@ SetMatViewPopulatedState(Relation relation, bool newstate)
112112/*
113113 * ExecRefreshMatView -- execute a REFRESH MATERIALIZED VIEW command
114114 *
115+ * If WITH NO DATA was specified, this is effectively like a TRUNCATE;
116+ * otherwise it is like a TRUNCATE followed by an INSERT using the SELECT
117+ * statement associated with the materialized view. The statement node's
118+ * skipData field shows whether the clause was used.
119+ */
120+ ObjectAddress
121+ ExecRefreshMatView (RefreshMatViewStmt * stmt , const char * queryString ,
122+ ParamListInfo params , QueryCompletion * qc )
123+ {
124+ Oid matviewOid ;
125+ LOCKMODE lockmode ;
126+
127+ /* Determine strength of lock needed. */
128+ lockmode = stmt -> concurrent ? ExclusiveLock : AccessExclusiveLock ;
129+
130+ /*
131+ * Get a lock until end of transaction.
132+ */
133+ matviewOid = RangeVarGetRelidExtended (stmt -> relation ,
134+ lockmode , 0 ,
135+ RangeVarCallbackMaintainsTable ,
136+ NULL );
137+
138+ return RefreshMatViewByOid (matviewOid , stmt -> skipData , stmt -> concurrent ,
139+ queryString , params , qc );
140+ }
141+
142+ /*
143+ * RefreshMatViewByOid -- refresh materialized view by OID
144+ *
115145 * This refreshes the materialized view by creating a new table and swapping
116146 * the relfilenumbers of the new table and the old materialized view, so the OID
117147 * of the original materialized view is preserved. Thus we do not lose GRANT
118148 * nor references to this materialized view.
119149 *
120- * If WITH NO DATA was specified, this is effectively like a TRUNCATE;
121- * otherwise it is like a TRUNCATE followed by an INSERT using the SELECT
122- * statement associated with the materialized view. The statement node's
123- * skipData field shows whether the clause was used.
150+ * If skipData is true, this is effectively like a TRUNCATE; otherwise it is
151+ * like a TRUNCATE followed by an INSERT using the SELECT statement associated
152+ * with the materialized view.
124153 *
125154 * Indexes are rebuilt too, via REINDEX. Since we are effectively bulk-loading
126155 * the new heap, it's better to create the indexes afterwards than to fill them
@@ -130,10 +159,10 @@ SetMatViewPopulatedState(Relation relation, bool newstate)
130159 * reflect the result set of the materialized view's query.
131160 */
132161ObjectAddress
133- ExecRefreshMatView (RefreshMatViewStmt * stmt , const char * queryString ,
134- ParamListInfo params , QueryCompletion * qc )
162+ RefreshMatViewByOid (Oid matviewOid , bool skipData , bool concurrent ,
163+ const char * queryString , ParamListInfo params ,
164+ QueryCompletion * qc )
135165{
136- Oid matviewOid ;
137166 Relation matviewRel ;
138167 RewriteRule * rule ;
139168 List * actions ;
@@ -143,25 +172,12 @@ ExecRefreshMatView(RefreshMatViewStmt *stmt, const char *queryString,
143172 Oid OIDNewHeap ;
144173 DestReceiver * dest ;
145174 uint64 processed = 0 ;
146- bool concurrent ;
147- LOCKMODE lockmode ;
148175 char relpersistence ;
149176 Oid save_userid ;
150177 int save_sec_context ;
151178 int save_nestlevel ;
152179 ObjectAddress address ;
153180
154- /* Determine strength of lock needed. */
155- concurrent = stmt -> concurrent ;
156- lockmode = concurrent ? ExclusiveLock : AccessExclusiveLock ;
157-
158- /*
159- * Get a lock until end of transaction.
160- */
161- matviewOid = RangeVarGetRelidExtended (stmt -> relation ,
162- lockmode , 0 ,
163- RangeVarCallbackMaintainsTable ,
164- NULL );
165181 matviewRel = table_open (matviewOid , NoLock );
166182 relowner = matviewRel -> rd_rel -> relowner ;
167183
@@ -190,7 +206,7 @@ ExecRefreshMatView(RefreshMatViewStmt *stmt, const char *queryString,
190206 errmsg ("CONCURRENTLY cannot be used when the materialized view is not populated" )));
191207
192208 /* Check that conflicting options have not been specified. */
193- if (concurrent && stmt -> skipData )
209+ if (concurrent && skipData )
194210 ereport (ERROR ,
195211 (errcode (ERRCODE_SYNTAX_ERROR ),
196212 errmsg ("%s and %s options cannot be used together" ,
@@ -275,7 +291,7 @@ ExecRefreshMatView(RefreshMatViewStmt *stmt, const char *queryString,
275291 * Tentatively mark the matview as populated or not (this will roll back
276292 * if we fail later).
277293 */
278- SetMatViewPopulatedState (matviewRel , !stmt -> skipData );
294+ SetMatViewPopulatedState (matviewRel , !skipData );
279295
280296 /* Concurrent refresh builds new data in temp tablespace, and does diff. */
281297 if (concurrent )
@@ -301,7 +317,7 @@ ExecRefreshMatView(RefreshMatViewStmt *stmt, const char *queryString,
301317 dest = CreateTransientRelDestReceiver (OIDNewHeap );
302318
303319 /* Generate the data, if wanted. */
304- if (!stmt -> skipData )
320+ if (!skipData )
305321 processed = refresh_matview_datafill (dest , dataQuery , queryString );
306322
307323 /* Make the matview match the newly generated data. */
@@ -333,7 +349,7 @@ ExecRefreshMatView(RefreshMatViewStmt *stmt, const char *queryString,
333349 * inserts and deletes it issues get counted by lower-level code.)
334350 */
335351 pgstat_count_truncate (matviewRel );
336- if (!stmt -> skipData )
352+ if (!skipData )
337353 pgstat_count_heap_insert (matviewRel , processed );
338354 }
339355
0 commit comments