Add is_create parameter to RefreshMatviewByOid().
authorJeff Davis <jdavis@postgresql.org>
Wed, 31 Jul 2024 23:42:19 +0000 (16:42 -0700)
committerJeff Davis <jdavis@postgresql.org>
Wed, 31 Jul 2024 23:42:19 +0000 (16:42 -0700)
RefreshMatviewByOid is used for both REFRESH and CREATE MATERIALIZED
VIEW.  This flag is currently just used for handling internal error
messages, but also aimed to improve code-readability.

Author: Yugo Nagata
Discussion: https://postgr.es/m/20240726122630.70e889f63a4d7e26f8549de8@sraoss.co.jp

src/backend/commands/createas.c
src/backend/commands/matview.c
src/include/commands/matview.h

index 6fb92a312bbcda2c02451a3d830a167d4b06806d..36e192b79b25289f1bb71a4b7a703b2794545218 100644 (file)
@@ -346,11 +346,8 @@ ExecCreateTableAs(ParseState *pstate, CreateTableAsStmt *stmt,
         */
        if (do_refresh)
        {
-               RefreshMatViewByOid(address.objectId, false, false,
+               RefreshMatViewByOid(address.objectId, true, false, false,
                                                        pstate->p_sourcetext, qc);
-
-               if (qc)
-                       qc->commandTag = CMDTAG_SELECT;
        }
 
        return address;
index 45a2a80181d5a5627eeb8054c5c3738a7c04f956..91f0fd6ea3e24e01413e19afc585f4509fe982f4 100644 (file)
@@ -60,7 +60,7 @@ static bool transientrel_receive(TupleTableSlot *slot, DestReceiver *self);
 static void transientrel_shutdown(DestReceiver *self);
 static void transientrel_destroy(DestReceiver *self);
 static uint64 refresh_matview_datafill(DestReceiver *dest, Query *query,
-                                                                          const char *queryString);
+                                                                          const char *queryString, bool is_create);
 static char *make_temptable_name_n(char *tempname, int n);
 static void refresh_by_match_merge(Oid matviewOid, Oid tempOid, Oid relowner,
                                                                   int save_sec_context);
@@ -135,8 +135,8 @@ ExecRefreshMatView(RefreshMatViewStmt *stmt, const char *queryString,
                                                                                  RangeVarCallbackMaintainsTable,
                                                                                  NULL);
 
-       return RefreshMatViewByOid(matviewOid, stmt->skipData, stmt->concurrent,
-                                                          queryString, qc);
+       return RefreshMatViewByOid(matviewOid, false, stmt->skipData,
+                                                          stmt->concurrent, queryString, qc);
 }
 
 /*
@@ -157,10 +157,14 @@ ExecRefreshMatView(RefreshMatViewStmt *stmt, const char *queryString,
  *
  * The matview's "populated" state is changed based on whether the contents
  * reflect the result set of the materialized view's query.
+ *
+ * This is also used to populate the materialized view created by CREATE
+ * MATERIALIZED VIEW command.
  */
 ObjectAddress
-RefreshMatViewByOid(Oid matviewOid, bool skipData, bool concurrent,
-                                       const char *queryString, QueryCompletion *qc)
+RefreshMatViewByOid(Oid matviewOid, bool is_create, bool skipData,
+                                       bool concurrent, const char *queryString,
+                                       QueryCompletion *qc)
 {
        Relation        matviewRel;
        RewriteRule *rule;
@@ -169,7 +173,6 @@ RefreshMatViewByOid(Oid matviewOid, bool skipData, bool concurrent,
        Oid                     tableSpace;
        Oid                     relowner;
        Oid                     OIDNewHeap;
-       DestReceiver *dest;
        uint64          processed = 0;
        char            relpersistence;
        Oid                     save_userid;
@@ -248,6 +251,8 @@ RefreshMatViewByOid(Oid matviewOid, bool skipData, bool concurrent,
                ListCell   *indexoidscan;
                bool            hasUniqueIndex = false;
 
+               Assert(!is_create);
+
                foreach(indexoidscan, indexoidlist)
                {
                        Oid                     indexoid = lfirst_oid(indexoidscan);
@@ -284,7 +289,9 @@ RefreshMatViewByOid(Oid matviewOid, bool skipData, bool concurrent,
         * NB: We count on this to protect us against problems with refreshing the
         * data using TABLE_INSERT_FROZEN.
         */
-       CheckTableNotInUse(matviewRel, "REFRESH MATERIALIZED VIEW");
+       CheckTableNotInUse(matviewRel,
+                                          is_create ? "CREATE MATERIALIZED VIEW" :
+                                          "REFRESH MATERIALIZED VIEW");
 
        /*
         * Tentatively mark the matview as populated or not (this will roll back
@@ -313,11 +320,16 @@ RefreshMatViewByOid(Oid matviewOid, bool skipData, bool concurrent,
                                                           matviewRel->rd_rel->relam,
                                                           relpersistence, ExclusiveLock);
        LockRelationOid(OIDNewHeap, AccessExclusiveLock);
-       dest = CreateTransientRelDestReceiver(OIDNewHeap);
 
        /* Generate the data, if wanted. */
        if (!skipData)
-               processed = refresh_matview_datafill(dest, dataQuery, queryString);
+       {
+               DestReceiver *dest;
+
+               dest = CreateTransientRelDestReceiver(OIDNewHeap);
+               processed = refresh_matview_datafill(dest, dataQuery, queryString,
+                                                                                        is_create);
+       }
 
        /* Make the matview match the newly generated data. */
        if (concurrent)
@@ -369,9 +381,14 @@ RefreshMatViewByOid(Oid matviewOid, bool skipData, bool concurrent,
         * i.e., the display_rowcount flag of CMDTAG_REFRESH_MATERIALIZED_VIEW
         * command tag is left false in cmdtaglist.h. Otherwise, the change of
         * completion tag output might break applications using it.
+        *
+        * When called from CREATE MATERIALIZED VIEW comand, the rowcount is
+        * displayed with the command tag CMDTAG_SELECT.
         */
        if (qc)
-               SetQueryCompletion(qc, CMDTAG_REFRESH_MATERIALIZED_VIEW, processed);
+               SetQueryCompletion(qc,
+                                                  is_create ? CMDTAG_SELECT : CMDTAG_REFRESH_MATERIALIZED_VIEW,
+                                                  processed);
 
        return address;
 }
@@ -386,7 +403,7 @@ RefreshMatViewByOid(Oid matviewOid, bool skipData, bool concurrent,
  */
 static uint64
 refresh_matview_datafill(DestReceiver *dest, Query *query,
-                                                const char *queryString)
+                                                const char *queryString, bool is_create)
 {
        List       *rewritten;
        PlannedStmt *plan;
@@ -401,7 +418,8 @@ refresh_matview_datafill(DestReceiver *dest, Query *query,
 
        /* SELECT should never rewrite to more or less than one SELECT query */
        if (list_length(rewritten) != 1)
-               elog(ERROR, "unexpected rewrite result for REFRESH MATERIALIZED VIEW");
+               elog(ERROR, "unexpected rewrite result for %s",
+                        is_create ? "CREATE MATERIALIZED VIEW " : "REFRESH MATERIALIZED VIEW");
        query = (Query *) linitial(rewritten);
 
        /* Check for user-requested abort. */
index 7916df3039361d53e5885d4ec82db2aee2a54275..c8811e8fc715c4703dd83d07f0a762223d4d3ed5 100644 (file)
@@ -25,8 +25,9 @@ extern void SetMatViewPopulatedState(Relation relation, bool newstate);
 
 extern ObjectAddress ExecRefreshMatView(RefreshMatViewStmt *stmt, const char *queryString,
                                                                                QueryCompletion *qc);
-extern ObjectAddress RefreshMatViewByOid(Oid matviewOid, bool skipData, bool concurrent,
-                                                                                const char *queryString, QueryCompletion *qc);
+extern ObjectAddress RefreshMatViewByOid(Oid matviewOid, bool is_create, bool skipData,
+                                                                                bool concurrent, const char *queryString,
+                                                                                QueryCompletion *qc);
 
 extern DestReceiver *CreateTransientRelDestReceiver(Oid transientoid);