Fetch the target remote nodes to run CREATE STATISTICS command
authorPavan Deolasee <[email protected]>
Wed, 30 Aug 2017 05:40:19 +0000 (11:10 +0530)
committerPavan Deolasee <[email protected]>
Wed, 30 Aug 2017 05:40:19 +0000 (11:10 +0530)
Some database objects are created only on a subset of nodes. For example, views
are created only on the coordinators. Similarly, temp tables are created on the
local coordinator and all datanodes. So we must consult the relation kind
before executing the CREATE STATISTICS command on the remote nodes. Otherwise
we might try to execute it on a node where the underlying object is missing,
resulting in errors.

Patch by senhu ([email protected]) which was later reworked by me.

src/backend/tcop/utility.c

index e65ffc7fc1494ec7cf9aaab091c1ed8231c243d6..8bdcf810b93985baa1369b6f81118182ef569ae7 100644 (file)
@@ -2576,7 +2576,26 @@ ProcessUtilitySlow(ParseState *pstate,
                                address = CreateStatistics((CreateStatsStmt *) parsetree);
 #ifdef PGXC
                                if (IS_PGXC_LOCAL_COORDINATOR)
-                                       ExecUtilityStmtOnNodes(queryString, NULL, sentToRemote, false, EXEC_ON_ALL_NODES, false);
+                               {
+                                       bool is_temp;
+                                       CreateStatsStmt *stmt = (CreateStatsStmt *) parsetree;
+                                       RangeVar *rln = linitial(stmt->relations);
+                                       Relation rel = relation_openrv((RangeVar *) rln, ShareUpdateExclusiveLock);
+
+                                       /*
+                                        * Get the target nodes to run the CREATE STATISTICS
+                                        * command. Since the grammar does not tell us about the
+                                        * underlying object type, we use the other variant to
+                                        * fetch the nodes. This is ok because the command must
+                                        * only be even used on some kind of relation.
+                                        */ 
+                                       RemoteQueryExecType exec_type =
+                                               ExecUtilityFindNodesRelkind(RelationGetRelid(rel), &is_temp);
+
+                                       ExecUtilityStmtOnNodes(queryString, NULL, sentToRemote,
+                                               false, exec_type, false);
+                                       relation_close(rel, NoLock);
+                               }
 #endif
                                break;