]> git.ipfire.org Git - thirdparty/postgresql.git/commitdiff
Fix StatisticsObjIsVisibleExt() for pg_temp.
authorNoah Misch <noah@leadboat.com>
Mon, 29 Sep 2025 18:15:44 +0000 (11:15 -0700)
committerNoah Misch <noah@leadboat.com>
Mon, 29 Sep 2025 18:15:47 +0000 (11:15 -0700)
Neighbor get_statistics_object_oid() ignores objects in pg_temp, as has
been the standard for non-relation, non-type namespace searches since
CVE-2007-2138.  Hence, most operations that name a statistics object
correctly decline to map an unqualified name to a statistics object in
pg_temp.  StatisticsObjIsVisibleExt() did not.  Consequently,
pg_statistics_obj_is_visible() wrongly returned true for such objects,
psql \dX wrongly listed them, and getObjectDescription()-based ereport()
and pg_describe_object() wrongly omitted namespace qualification.  Any
malfunction beyond that would depend on how a human or application acts
on those wrong indications.  Commit
d99d58cdc8c0b5b50ee92995e8575c100b1a458a introduced this.  Back-patch to
v13 (all supported versions).

Reviewed-by: Nathan Bossart <nathandbossart@gmail.com>
Discussion: https://postgr.es/m/20250920162116.2e.nmisch@google.com
Backpatch-through: 13

src/backend/catalog/namespace.c
src/test/regress/expected/stats_ext.out
src/test/regress/sql/stats_ext.sql

index d97d632a7ef55f90310959cbf0c5b41524dee72b..dd5d241dfe2a41e202ac6a893734a509624ca2f3 100644 (file)
@@ -2686,6 +2686,9 @@ StatisticsObjIsVisibleExt(Oid stxid, bool *is_missing)
                {
                        Oid                     namespaceId = lfirst_oid(l);
 
+                       if (namespaceId == myTempNamespace)
+                               continue;               /* do not look in temp namespace */
+
                        if (namespaceId == stxnamespace)
                        {
                                /* Found it first in path */
index fdc0aa130bdb8c5d606186efd853486b45a685d7..d225c0d0c3ff4a1af5e61121e8e4799a86d40884 100644 (file)
@@ -122,6 +122,20 @@ ALTER STATISTICS ab1_a_b_stats RENAME TO ab1_a_b_stats_new;
 ERROR:  must be owner of statistics object ab1_a_b_stats
 RESET SESSION AUTHORIZATION;
 DROP ROLE regress_stats_ext;
+CREATE STATISTICS pg_temp.stats_ext_temp ON a, b FROM ab1;
+SELECT regexp_replace(pg_describe_object(tableoid, oid, 0),
+                      'pg_temp_[0-9]*', 'pg_temp_REDACTED') AS descr,
+       pg_statistics_obj_is_visible(oid) AS visible
+  FROM pg_statistic_ext
+ WHERE stxname = 'stats_ext_temp';
+                       descr                       | visible 
+---------------------------------------------------+---------
+ statistics object pg_temp_REDACTED.stats_ext_temp | f
+(1 row)
+
+DROP STATISTICS stats_ext_temp;  -- shall fail
+ERROR:  statistics object "stats_ext_temp" does not exist
+DROP STATISTICS pg_temp.stats_ext_temp;
 CREATE STATISTICS IF NOT EXISTS ab1_a_b_stats ON a, b FROM ab1;
 NOTICE:  statistics object "ab1_a_b_stats" already exists, skipping
 DROP STATISTICS ab1_a_b_stats;
index 823c7db9dab49757207580006457c7b235942d5d..acbb4f93941be50318c40a0b9b4c2c54be27f05d 100644 (file)
@@ -83,6 +83,14 @@ DROP STATISTICS ab1_a_b_stats;
 ALTER STATISTICS ab1_a_b_stats RENAME TO ab1_a_b_stats_new;
 RESET SESSION AUTHORIZATION;
 DROP ROLE regress_stats_ext;
+CREATE STATISTICS pg_temp.stats_ext_temp ON a, b FROM ab1;
+SELECT regexp_replace(pg_describe_object(tableoid, oid, 0),
+                      'pg_temp_[0-9]*', 'pg_temp_REDACTED') AS descr,
+       pg_statistics_obj_is_visible(oid) AS visible
+  FROM pg_statistic_ext
+ WHERE stxname = 'stats_ext_temp';
+DROP STATISTICS stats_ext_temp;  -- shall fail
+DROP STATISTICS pg_temp.stats_ext_temp;
 
 CREATE STATISTICS IF NOT EXISTS ab1_a_b_stats ON a, b FROM ab1;
 DROP STATISTICS ab1_a_b_stats;