From b30ed46068dbfe153121321ccc764f21baf86b58 Mon Sep 17 00:00:00 2001 From: Ahmet Gedemenli Date: Thu, 4 Nov 2021 16:14:05 +0300 Subject: [PATCH] Fixes ALTER STATISTICS IF EXISTS bug (#5435) * Fix ALTER STATISTICS IF EXISTS bug --- src/backend/distributed/commands/statistics.c | 13 ++++++++++++- .../regress/expected/pg13_propagate_statistics.out | 11 +++++++++++ src/test/regress/sql/pg13_propagate_statistics.sql | 7 +++++++ 3 files changed, 30 insertions(+), 1 deletion(-) diff --git a/src/backend/distributed/commands/statistics.c b/src/backend/distributed/commands/statistics.c index 030cd0269..ed2525bdb 100644 --- a/src/backend/distributed/commands/statistics.c +++ b/src/backend/distributed/commands/statistics.c @@ -348,7 +348,18 @@ PreprocessAlterStatisticsStmt(Node *node, const char *queryString, { AlterStatsStmt *stmt = castNode(AlterStatsStmt, node); - Oid statsOid = get_statistics_object_oid(stmt->defnames, false); + Oid statsOid = get_statistics_object_oid(stmt->defnames, stmt->missing_ok); + + if (!OidIsValid(statsOid)) + { + /* + * If statsOid is invalid, here we can assume that the query includes + * IF EXISTS clause, since get_statistics_object_oid would error out otherwise. + * So here we can safely return NIL here without checking stmt->missing_ok. + */ + return NIL; + } + Oid relationId = GetRelIdByStatsOid(statsOid); if (!IsCitusTable(relationId) || !ShouldPropagate()) diff --git a/src/test/regress/expected/pg13_propagate_statistics.out b/src/test/regress/expected/pg13_propagate_statistics.out index c75eb333f..b490e6c55 100644 --- a/src/test/regress/expected/pg13_propagate_statistics.out +++ b/src/test/regress/expected/pg13_propagate_statistics.out @@ -108,5 +108,16 @@ ORDER BY stxstattarget, stxrelid::regclass ASC; (64 rows) \c - - - :master_port +-- the first one should log a notice that says statistics object does not exist +ALTER STATISTICS IF EXISTS stats_that_doesnt_exists SET STATISTICS 0; +NOTICE: statistics object "stats_that_doesnt_exists" does not exist, skipping +-- these three should error out as ALTER STATISTICS syntax doesn't support these with IF EXISTS clause +-- if output of any of these three changes, we should support them and update the test output here +ALTER STATISTICS IF EXISTS stats_that_doesnt_exists RENAME TO this_should_error_out; +ERROR: syntax error at or near "RENAME" +ALTER STATISTICS IF EXISTS stats_that_doesnt_exists OWNER TO CURRENT_USER; +ERROR: syntax error at or near "OWNER" +ALTER STATISTICS IF EXISTS stats_that_doesnt_exists SET SCHEMA "statistics'Test"; +ERROR: syntax error at or near "SCHEMA" SET client_min_messages TO WARNING; DROP SCHEMA "statistics'TestTarget" CASCADE; diff --git a/src/test/regress/sql/pg13_propagate_statistics.sql b/src/test/regress/sql/pg13_propagate_statistics.sql index 9716d3289..f32cbcb77 100644 --- a/src/test/regress/sql/pg13_propagate_statistics.sql +++ b/src/test/regress/sql/pg13_propagate_statistics.sql @@ -41,5 +41,12 @@ WHERE stxnamespace IN ( ORDER BY stxstattarget, stxrelid::regclass ASC; \c - - - :master_port +-- the first one should log a notice that says statistics object does not exist +ALTER STATISTICS IF EXISTS stats_that_doesnt_exists SET STATISTICS 0; +-- these three should error out as ALTER STATISTICS syntax doesn't support these with IF EXISTS clause +-- if output of any of these three changes, we should support them and update the test output here +ALTER STATISTICS IF EXISTS stats_that_doesnt_exists RENAME TO this_should_error_out; +ALTER STATISTICS IF EXISTS stats_that_doesnt_exists OWNER TO CURRENT_USER; +ALTER STATISTICS IF EXISTS stats_that_doesnt_exists SET SCHEMA "statistics'Test"; SET client_min_messages TO WARNING; DROP SCHEMA "statistics'TestTarget" CASCADE;