diff --git a/src/backend/distributed/commands/distribute_object_ops.c b/src/backend/distributed/commands/distribute_object_ops.c index 7e140a13d..258986327 100644 --- a/src/backend/distributed/commands/distribute_object_ops.c +++ b/src/backend/distributed/commands/distribute_object_ops.c @@ -14,6 +14,7 @@ #include "distributed/commands.h" #include "distributed/deparser.h" +#include "distributed/pg_version_constants.h" static DistributeObjectOps NoDistributeOps = { .deparse = NULL, @@ -414,6 +415,15 @@ static DistributeObjectOps Schema_Rename = { .postprocess = NULL, .address = AlterSchemaRenameStmtObjectAddress, }; +#if PG_VERSION_NUM >= PG_VERSION_13 +static DistributeObjectOps Statistics_Alter = { + .deparse = DeparseAlterStatisticsStmt, + .qualify = QualifyAlterStatisticsStmt, + .preprocess = PreprocessAlterStatisticsStmt, + .postprocess = NULL, + .address = NULL, +}; +#endif static DistributeObjectOps Statistics_AlterObjectSchema = { .deparse = DeparseAlterStatisticsSchemaStmt, .qualify = QualifyAlterStatisticsSchemaStmt, @@ -683,6 +693,13 @@ GetDistributeObjectOps(Node *node) return &Any_AlterRoleSet; } +#if PG_VERSION_NUM >= PG_VERSION_13 + case T_AlterStatsStmt: + { + return &Statistics_Alter; + } + +#endif case T_AlterTableStmt: { AlterTableStmt *stmt = castNode(AlterTableStmt, node); diff --git a/src/backend/distributed/commands/statistics.c b/src/backend/distributed/commands/statistics.c index 7db7e06c4..95c63d900 100644 --- a/src/backend/distributed/commands/statistics.c +++ b/src/backend/distributed/commands/statistics.c @@ -318,6 +318,49 @@ AlterStatisticsSchemaStmtObjectAddress(Node *node, bool missingOk) } +#if PG_VERSION_NUM >= PG_VERSION_13 + +/* + * PreprocessAlterStatisticsStmt is called during the planning phase for + * ALTER STATISTICS .. SET STATISTICS command has been executed + * by standard process utility. + */ +List * +PreprocessAlterStatisticsStmt(Node *node, const char *queryString) +{ + AlterStatsStmt *stmt = castNode(AlterStatsStmt, node); + + Oid statsOid = get_statistics_object_oid(stmt->defnames, false); + Oid relationId = GetRelIdByStatsOid(statsOid); + + if (!IsCitusTable(relationId) || !ShouldPropagate()) + { + return NIL; + } + + EnsureCoordinator(); + + QualifyTreeNode((Node *) stmt); + + char *ddlCommand = DeparseTreeNode((Node *) stmt); + + DDLJob *ddlJob = palloc0(sizeof(DDLJob)); + + ddlJob->targetRelationId = relationId; + ddlJob->concurrentIndexCmd = false; + ddlJob->startNewTransaction = false; + ddlJob->commandString = ddlCommand; + ddlJob->taskList = DDLTaskList(relationId, ddlCommand); + + List *ddlJobs = list_make1(ddlJob); + + return ddlJobs; +} + + +#endif + + /* * GetExplicitStatisticsCommandList returns the list of DDL commands to create * statistics that are explicitly created for the table with relationId. See diff --git a/src/backend/distributed/deparser/deparse_statistics_stmts.c b/src/backend/distributed/deparser/deparse_statistics_stmts.c index b085f027f..1473980db 100644 --- a/src/backend/distributed/deparser/deparse_statistics_stmts.c +++ b/src/backend/distributed/deparser/deparse_statistics_stmts.c @@ -24,6 +24,9 @@ static void AppendCreateStatisticsStmt(StringInfo buf, CreateStatsStmt *stmt); static void AppendDropStatisticsStmt(StringInfo buf, List *nameList, bool ifExists); static void AppendAlterStatisticsRenameStmt(StringInfo buf, RenameStmt *stmt); static void AppendAlterStatisticsSchemaStmt(StringInfo buf, AlterObjectSchemaStmt *stmt); +#if PG_VERSION_NUM >= PG_VERSION_13 +static void AppendAlterStatisticsStmt(StringInfo buf, AlterStatsStmt *stmt); +#endif static void AppendStatisticsName(StringInfo buf, CreateStatsStmt *stmt); static void AppendStatTypes(StringInfo buf, CreateStatsStmt *stmt); static void AppendColumnNames(StringInfo buf, CreateStatsStmt *stmt); @@ -83,6 +86,24 @@ DeparseAlterStatisticsSchemaStmt(Node *node) } +#if PG_VERSION_NUM >= PG_VERSION_13 +char * +DeparseAlterStatisticsStmt(Node *node) +{ + AlterStatsStmt *stmt = castNode(AlterStatsStmt, node); + + StringInfoData str; + initStringInfo(&str); + + AppendAlterStatisticsStmt(&str, stmt); + + return str.data; +} + + +#endif + + static void AppendCreateStatisticsStmt(StringInfo buf, CreateStatsStmt *stmt) { @@ -139,6 +160,18 @@ AppendAlterStatisticsSchemaStmt(StringInfo buf, AlterObjectSchemaStmt *stmt) } +#if PG_VERSION_NUM >= PG_VERSION_13 +static void +AppendAlterStatisticsStmt(StringInfo buf, AlterStatsStmt *stmt) +{ + appendStringInfo(buf, "ALTER STATISTICS %s SET STATISTICS %d", NameListToQuotedString( + stmt->defnames), stmt->stxstattarget); +} + + +#endif + + static void AppendStatisticsName(StringInfo buf, CreateStatsStmt *stmt) { diff --git a/src/backend/distributed/deparser/qualify_statistics_stmt.c b/src/backend/distributed/deparser/qualify_statistics_stmt.c index eb7d19080..ad60b42a3 100644 --- a/src/backend/distributed/deparser/qualify_statistics_stmt.c +++ b/src/backend/distributed/deparser/qualify_statistics_stmt.c @@ -120,3 +120,27 @@ QualifyAlterStatisticsSchemaStmt(Node *node) stmt->object = (Node *) MakeNameListFromRangeVar(stat); } } + + +#if PG_VERSION_NUM >= PG_VERSION_13 + +/* + * QualifyAlterStatisticsStmt qualifies AlterObjectSchemaStmt's with schema name for + * ALTER STATISTICS .. SET STATISTICS statements. + */ +void +QualifyAlterStatisticsStmt(Node *node) +{ + AlterStatsStmt *stmt = castNode(AlterStatsStmt, node); + + if (list_length(stmt->defnames) == 1) + { + RangeVar *stat = makeRangeVarFromNameList(stmt->defnames); + Oid schemaOid = RangeVarGetCreationNamespace(stat); + stat->schemaname = get_namespace_name(schemaOid); + stmt->defnames = MakeNameListFromRangeVar(stat); + } +} + + +#endif diff --git a/src/backend/distributed/relay/relay_event_utility.c b/src/backend/distributed/relay/relay_event_utility.c index 4d0a9104e..6db69297b 100644 --- a/src/backend/distributed/relay/relay_event_utility.c +++ b/src/backend/distributed/relay/relay_event_utility.c @@ -111,6 +111,21 @@ RelayEventExtendNames(Node *parseTree, char *schemaName, uint64 shardId) break; } +#if PG_VERSION_NUM >= PG_VERSION_13 + case T_AlterStatsStmt: + { + AlterStatsStmt *alterStatsStmt = (AlterStatsStmt *) parseTree; + RangeVar *stat = makeRangeVarFromNameList(alterStatsStmt->defnames); + + AppendShardIdToName(&stat->relname, shardId); + SetSchemaNameIfNotExist(&stat->schemaname, schemaName); + + alterStatsStmt->defnames = MakeNameListFromRangeVar(stat); + + break; + } +#endif + case T_AlterTableStmt: { /* diff --git a/src/include/distributed/commands.h b/src/include/distributed/commands.h index 054ea5fc0..e25aee2d2 100644 --- a/src/include/distributed/commands.h +++ b/src/include/distributed/commands.h @@ -286,6 +286,7 @@ extern List * PreprocessAlterStatisticsRenameStmt(Node *node, const char *queryS extern List * PreprocessAlterStatisticsSchemaStmt(Node *node, const char *queryString); extern List * PostprocessAlterStatisticsSchemaStmt(Node *node, const char *queryString); extern ObjectAddress AlterStatisticsSchemaStmtObjectAddress(Node *node, bool missingOk); +extern List * PreprocessAlterStatisticsStmt(Node *node, const char *queryString); extern List * GetExplicitStatisticsCommandList(Oid relationId); extern List * GetExplicitStatisticsSchemaIdList(Oid relationId); diff --git a/src/include/distributed/deparser.h b/src/include/distributed/deparser.h index 59227a658..7ff42b6e3 100644 --- a/src/include/distributed/deparser.h +++ b/src/include/distributed/deparser.h @@ -60,11 +60,13 @@ extern char * DeparseCreateStatisticsStmt(Node *node); extern char * DeparseDropStatisticsStmt(List *nameList, bool ifExists); extern char * DeparseAlterStatisticsRenameStmt(Node *node); extern char * DeparseAlterStatisticsSchemaStmt(Node *node); +extern char * DeparseAlterStatisticsStmt(Node *node); extern void QualifyCreateStatisticsStmt(Node *node); extern void QualifyDropStatisticsStmt(Node *node); extern void QualifyAlterStatisticsRenameStmt(Node *node); extern void QualifyAlterStatisticsSchemaStmt(Node *node); +extern void QualifyAlterStatisticsStmt(Node *node); /* forward declarations for deparse_type_stmts.c */ extern char * DeparseCompositeTypeStmt(Node *stmt); diff --git a/src/test/regress/expected/propagate_statistics.out b/src/test/regress/expected/propagate_statistics.out index 9516d0b4a..18367b5d0 100644 --- a/src/test/regress/expected/propagate_statistics.out +++ b/src/test/regress/expected/propagate_statistics.out @@ -79,6 +79,11 @@ ALTER STATISTICS s6 RENAME TO s7; CREATE SCHEMA test_alter_schema; ALTER STATISTICS s7 SET SCHEMA test_alter_schema; DROP STATISTICS test_alter_schema.s7; +-- test altering stats target +ALTER STATISTICS s1 SET STATISTICS 3; +-- since max value for target is 10000, this will automatically be lowered +ALTER STATISTICS s2 SET STATISTICS 999999; +WARNING: lowering statistics target to 10000 \c - - - :worker_1_port SELECT stxname FROM pg_statistic_ext @@ -168,6 +173,82 @@ WHERE stxnamespace IN ( 3 (1 row) +SELECT stxstattarget +FROM pg_statistic_ext +WHERE stxnamespace IN ( + SELECT oid + FROM pg_namespace + WHERE nspname IN ('public', 'statistics''Test', 'sc1', 'sc2') +) +ORDER BY stxstattarget ASC; + stxstattarget +--------------------------------------------------------------------- + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + 3 + 3 + 3 + 3 + 3 + 3 + 3 + 3 + 3 + 3 + 3 + 3 + 3 + 3 + 3 + 3 + 10000 + 10000 + 10000 + 10000 + 10000 + 10000 + 10000 + 10000 + 10000 + 10000 + 10000 + 10000 + 10000 + 10000 + 10000 + 10000 +(64 rows) + \c - - - :master_port SET client_min_messages TO WARNING; DROP SCHEMA "statistics'Test" CASCADE; diff --git a/src/test/regress/sql/propagate_statistics.sql b/src/test/regress/sql/propagate_statistics.sql index ffdd3dd29..dda73c368 100644 --- a/src/test/regress/sql/propagate_statistics.sql +++ b/src/test/regress/sql/propagate_statistics.sql @@ -67,6 +67,11 @@ CREATE SCHEMA test_alter_schema; ALTER STATISTICS s7 SET SCHEMA test_alter_schema; DROP STATISTICS test_alter_schema.s7; +-- test altering stats target +ALTER STATISTICS s1 SET STATISTICS 3; +-- since max value for target is 10000, this will automatically be lowered +ALTER STATISTICS s2 SET STATISTICS 999999; + \c - - - :worker_1_port SELECT stxname FROM pg_statistic_ext @@ -85,6 +90,15 @@ WHERE stxnamespace IN ( WHERE nspname IN ('public', 'statistics''Test', 'sc1', 'sc2') ); +SELECT stxstattarget +FROM pg_statistic_ext +WHERE stxnamespace IN ( + SELECT oid + FROM pg_namespace + WHERE nspname IN ('public', 'statistics''Test', 'sc1', 'sc2') +) +ORDER BY stxstattarget ASC; + \c - - - :master_port SET client_min_messages TO WARNING; DROP SCHEMA "statistics'Test" CASCADE;