diff options
-rw-r--r-- | doc/src/sgml/ref/analyze.sgml | 12 | ||||
-rw-r--r-- | src/backend/parser/gram.y | 28 | ||||
-rw-r--r-- | src/backend/tcop/utility.c | 9 | ||||
-rw-r--r-- | src/include/nodes/parsenodes.h | 6 |
4 files changed, 50 insertions, 5 deletions
diff --git a/doc/src/sgml/ref/analyze.sgml b/doc/src/sgml/ref/analyze.sgml index 27ab4fca42..f2f3f97e0a 100644 --- a/doc/src/sgml/ref/analyze.sgml +++ b/doc/src/sgml/ref/analyze.sgml @@ -22,6 +22,7 @@ PostgreSQL documentation <refsynopsisdiv> <synopsis> ANALYZE [ VERBOSE ] [ <replaceable class="PARAMETER">table_name</replaceable> [ ( <replaceable class="PARAMETER">column_name</replaceable> [, ...] ) ] ] +ANALYZE [ ( { VERBOSE | COORDINATOR } ) ] [ <replaceable class="PARAMETER">table_name</replaceable> [ ( <replaceable class="PARAMETER">column_name</replaceable> [, ...] ) ] ] </synopsis> </refsynopsisdiv> @@ -59,6 +60,17 @@ ANALYZE [ VERBOSE ] [ <replaceable class="PARAMETER">table_name</replaceable> [ </varlistentry> <varlistentry> + <term><literal>COORDINATOR</literal></term> + <listitem> + <para> + Only updates statistics on the coordinator side using current statistics +on the datanodes. The datanode statistics are not updated and the current +values are used as they are. + </para> + </listitem> + </varlistentry> + + <varlistentry> <term><replaceable class="PARAMETER">table_name</replaceable></term> <listitem> <para> diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index 00744a4980..54af976917 100644 --- a/src/backend/parser/gram.y +++ b/src/backend/parser/gram.y @@ -308,6 +308,7 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query); %type <ival> opt_lock lock_type cast_context %type <ival> vacuum_option_list vacuum_option_elem +%type <ival> analyze_option_list analyze_option_elem %type <boolean> opt_force opt_or_replace opt_grant_grant_option opt_grant_admin_option opt_nowait opt_if_exists opt_with_data @@ -9766,6 +9767,22 @@ AnalyzeStmt: n->va_cols = $4; $$ = (Node *)n; } + | analyze_keyword '(' analyze_option_list ')' + { + VacuumStmt *n = makeNode(VacuumStmt); + n->options = VACOPT_ANALYZE | $3; + n->relation = NULL; + n->va_cols = NIL; + $$ = (Node *)n; + } + | analyze_keyword '(' analyze_option_list ')' qualified_name opt_name_list + { + VacuumStmt *n = makeNode(VacuumStmt); + n->options = VACOPT_ANALYZE | $3; + n->relation = $5; + n->va_cols = $6; + $$ = (Node *)n; + } ; analyze_keyword: @@ -9786,6 +9803,17 @@ opt_freeze: FREEZE { $$ = TRUE; } | /*EMPTY*/ { $$ = FALSE; } ; + +analyze_option_list: + analyze_option_elem { $$ = $1; } + | analyze_option_list ',' analyze_option_elem { $$ = $1 | $3; } + ; + +analyze_option_elem: + VERBOSE { $$ = VACOPT_VERBOSE; } + | COORDINATOR { $$ = VACOPT_COORDINATOR; } + ; + opt_name_list: '(' name_list ')' { $$ = $2; } | /*EMPTY*/ { $$ = NIL; } diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 0f42512466..7680a6451a 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -893,14 +893,15 @@ standard_ProcessUtility(Node *parsetree, /* we choose to allow this during "read only" transactions */ PreventCommandDuringRecovery((stmt->options & VACOPT_VACUUM) ? "VACUUM" : "ANALYZE"); -#ifdef PGXC /* * We have to run the command on nodes before Coordinator because * vacuum() pops active snapshot and we can not send it to nodes */ - if (IS_PGXC_LOCAL_COORDINATOR) - ExecUtilityStmtOnNodes(queryString, NULL, sentToRemote, true, EXEC_ON_DATANODES, false); -#endif + if (IS_PGXC_LOCAL_COORDINATOR && + !(stmt->options & VACOPT_COORDINATOR)) + ExecUtilityStmtOnNodes(queryString, NULL, sentToRemote, + true, + EXEC_ON_DATANODES, false); /* forbidden in parallel mode due to CommandIsReadOnly */ ExecVacuum(stmt, isTopLevel); } diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h index 751f67285a..8c78e3eb2b 100644 --- a/src/include/nodes/parsenodes.h +++ b/src/include/nodes/parsenodes.h @@ -2855,7 +2855,11 @@ typedef enum VacuumOption VACOPT_FULL = 1 << 4, /* FULL (non-concurrent) vacuum */ VACOPT_NOWAIT = 1 << 5, /* don't wait to get lock (autovacuum only) */ VACOPT_SKIPTOAST = 1 << 6, /* don't process the TOAST table, if any */ - VACOPT_DISABLE_PAGE_SKIPPING = 1 << 7 /* don't skip any pages */ + VACOPT_DISABLE_PAGE_SKIPPING = 1 << 7, /* don't skip any pages */ + VACOPT_COORDINATOR = 1 << 8 /* don't trigger analyze on the datanodes, but + * just collect existing info and populate + * coordinator side stats. + */ } VacuumOption; typedef struct VacuumStmt |