diff --git a/src/backend/distributed/deparser/qualify_statistics_stmt.c b/src/backend/distributed/deparser/qualify_statistics_stmt.c index b8a7ce30e..b176b66c2 100644 --- a/src/backend/distributed/deparser/qualify_statistics_stmt.c +++ b/src/backend/distributed/deparser/qualify_statistics_stmt.c @@ -15,15 +15,19 @@ #include "postgres.h" #include "catalog/namespace.h" +#include "catalog/pg_statistic_ext.h" #include "distributed/commands.h" #include "distributed/deparser.h" #include "distributed/listutils.h" #include "nodes/parsenodes.h" #include "nodes/value.h" +#include "utils/syscache.h" #include "utils/lsyscache.h" #include "utils/rel.h" #include "utils/relcache.h" +static Oid GetStatsNamespaceOid(Oid statsOid); + void QualifyCreateStatisticsStmt(Node *node) { @@ -68,8 +72,14 @@ QualifyDropStatisticsStmt(Node *node) if (stat->schemaname == NULL) { - Oid schemaOid = RangeVarGetCreationNamespace(stat); - stat->schemaname = get_namespace_name(schemaOid); + Oid statsOid = get_statistics_object_oid(objectNameList, + dropStatisticsStmt->missing_ok); + + if (OidIsValid(statsOid)) + { + Oid schemaOid = GetStatsNamespaceOid(statsOid); + stat->schemaname = get_namespace_name(schemaOid); + } } objectNameListWithSchema = lappend(objectNameListWithSchema, @@ -94,7 +104,14 @@ QualifyAlterStatisticsRenameStmt(Node *node) if (list_length(nameList) == 1) { RangeVar *stat = makeRangeVarFromNameList(nameList); - Oid schemaOid = RangeVarGetCreationNamespace(stat); + Oid statsOid = get_statistics_object_oid(nameList, renameStmt->missing_ok); + + if (!OidIsValid(statsOid)) + { + return; + } + + Oid schemaOid = GetStatsNamespaceOid(statsOid); stat->schemaname = get_namespace_name(schemaOid); renameStmt->object = (Node *) MakeNameListFromRangeVar(stat); } @@ -115,7 +132,14 @@ QualifyAlterStatisticsSchemaStmt(Node *node) if (list_length(nameList) == 1) { RangeVar *stat = makeRangeVarFromNameList(nameList); - Oid schemaOid = RangeVarGetCreationNamespace(stat); + Oid statsOid = get_statistics_object_oid(nameList, stmt->missing_ok); + + if (!OidIsValid(statsOid)) + { + return; + } + + Oid schemaOid = GetStatsNamespaceOid(statsOid); stat->schemaname = get_namespace_name(schemaOid); stmt->object = (Node *) MakeNameListFromRangeVar(stat); } @@ -136,7 +160,14 @@ QualifyAlterStatisticsStmt(Node *node) if (list_length(stmt->defnames) == 1) { RangeVar *stat = makeRangeVarFromNameList(stmt->defnames); - Oid schemaOid = RangeVarGetCreationNamespace(stat); + Oid statsOid = get_statistics_object_oid(stmt->defnames, stmt->missing_ok); + + if (!OidIsValid(statsOid)) + { + return; + } + + Oid schemaOid = GetStatsNamespaceOid(statsOid); stat->schemaname = get_namespace_name(schemaOid); stmt->defnames = MakeNameListFromRangeVar(stat); } @@ -159,8 +190,40 @@ QualifyAlterStatisticsOwnerStmt(Node *node) if (list_length(nameList) == 1) { RangeVar *stat = makeRangeVarFromNameList(nameList); - Oid schemaOid = RangeVarGetCreationNamespace(stat); + Oid statsOid = get_statistics_object_oid(nameList, /* missing_ok */ true); + + if (!OidIsValid(statsOid)) + { + return; + } + + Oid schemaOid = GetStatsNamespaceOid(statsOid); stat->schemaname = get_namespace_name(schemaOid); stmt->object = (Node *) MakeNameListFromRangeVar(stat); } } + + +/* + * GetStatsNamespaceOid takes the id of a Statistics object and returns + * the id of the schema that the statistics object belongs to. + * Errors out if the stats object is not found. + */ +static Oid +GetStatsNamespaceOid(Oid statsOid) +{ + HeapTuple heapTuple = SearchSysCache1(STATEXTOID, ObjectIdGetDatum(statsOid)); + if (!HeapTupleIsValid(heapTuple)) + { + ereport(ERROR, (errmsg("cache lookup failed for statistics " + "object with oid %u", statsOid))); + } + FormData_pg_statistic_ext *statisticsForm = + (FormData_pg_statistic_ext *) GETSTRUCT(heapTuple); + + Oid result = statisticsForm->stxnamespace; + + ReleaseSysCache(heapTuple); + + return result; +} diff --git a/src/test/regress/expected/citus_local_tables_mx.out b/src/test/regress/expected/citus_local_tables_mx.out index 0a50232ba..8923d3e82 100644 --- a/src/test/regress/expected/citus_local_tables_mx.out +++ b/src/test/regress/expected/citus_local_tables_mx.out @@ -224,7 +224,7 @@ ERROR: operation is not allowed on this node CREATE STATISTICS stx9 ON a, b FROM citus_local_table_stats2; DROP STATISTICS stx8; DROP STATISTICS stx4; -ERROR: statistics object "citus_local_tables_mx.stx4" does not exist +ERROR: statistics object "stx4" does not exist SELECT stxname FROM pg_statistic_ext ORDER BY stxname; stxname --------------------------------------------------------------------- diff --git a/src/test/regress/expected/propagate_statistics.out b/src/test/regress/expected/propagate_statistics.out index 8a1255406..80e944bc8 100644 --- a/src/test/regress/expected/propagate_statistics.out +++ b/src/test/regress/expected/propagate_statistics.out @@ -70,12 +70,12 @@ CREATE STATISTICS s5 ON a,b FROM test_stats4; -- s6 doesn't exist DROP STATISTICS IF EXISTS s3, sc2.s4, s6; DROP STATISTICS s5,s6; -ERROR: statistics object "statistics'Test.s6" does not exist +ERROR: statistics object "s6" does not exist DROP STATISTICS IF EXISTS s5,s5,s6,s6; -- test renaming statistics CREATE STATISTICS s6 ON a,b FROM test_stats4; DROP STATISTICS s7; -ERROR: statistics object "statistics'Test.s7" does not exist +ERROR: statistics object "s7" does not exist ALTER STATISTICS s6 RENAME TO s7; ALTER STATISTICS sc1.st1 RENAME TO st1_new; -- test altering stats schema