| From: | Shin Berg <sjh910805(at)gmail(dot)com> |
|---|---|
| To: | pgsql-hackers(at)lists(dot)postgresql(dot)org |
| Subject: | Re: Inconsistency in owner assignment between INDEX and STATISTICS |
| Date: | 2026-03-09 11:02:56 |
| Message-ID: | CACSdjfOyVWALYwb4QrLhAurqo5Ft9XU6zc6SSe=2FoG1DO0WWg@mail.gmail.com |
| Views: | Whole Thread | Raw Message | Download mbox | Resend email |
| Thread: | |
| Lists: | pgsql-hackers |
Hi,
Following up on my earlier proposal — I've gone ahead and written a patch
rather than waiting for feedback.
The fix is in CreateStatistics(): after opening the relation, stxowner is
set to rel->rd_rel->relowner instead of GetUserId(). The permission check
is left using GetUserId() so that only the relation owner (or a superuser)
can create statistics, but the ownership recorded in pg_statistic_ext now
matches what CREATE INDEX does.
A regression test is included in stats_ext.sql to verify that the
statistics owner equals the table owner when a superuser creates the
statistics object.
Patch attached.
Thanks,
Joshua-Shin
On Thu, Feb 26, 2026 at 6:52 PM Shin Berg <sjh910805(at)gmail(dot)com> wrote:
> Gentle ping on this thread — any thoughts or concerns about the
> proposed alignment?
>
> Thanks.
>
> On Sat, Feb 14, 2026 at 5:48 PM Shin Berg <sjh910805(at)gmail(dot)com> wrote:
>
>> Hi,
>>
>> I'd like to raise a small consistency issue between how INDEX and
>> extended STATISTICS handle object ownership, and ask whether aligning them
>> would be desirable.
>>
>> Current behavior (tested on REL_17_STABLE):
>>
>> - When a superuser creates an INDEX on another user's table, the index is
>> owned by the *table owner* (see catalog/index.c: index relation's relowner
>> is set from the heap relation's relowner).
>> - When a superuser creates STATISTICS on another user's table, the
>> statistics object is owned by the *current user* (statscmds.c: stxowner =
>> GetUserId()).
>>
>> So in a scenario where a DBA creates both an index and extended
>> statistics on a user's table, the table owner can DROP the index (because
>> they own it) but cannot DROP the statistics object (they get "does not
>> exist" when lacking ownership, which hides the real permission issue). That
>> can cause operational friction in multi-tenant or shared-schema setups
>> (e.g. the table owner cannot drop the statistics to resolve dependency
>> issues before altering the table).
>>
>> Reproduction (as superuser, then as table owner):
>>
>> CREATE SCHEMA shared_schema;
>> CREATE USER bob;
>> GRANT USAGE, CREATE ON SCHEMA shared_schema TO bob;
>>
>> SET ROLE bob;
>> CREATE TABLE shared_schema.bob_table (a int, b int);
>> RESET ROLE;
>>
>> CREATE INDEX idx_bob ON shared_schema.bob_table(a);
>> CREATE STATISTICS stat_bob ON a, b FROM shared_schema.bob_table;
>>
>> SELECT 'INDEX', c.relname, pg_get_userbyid(c.relowner) FROM pg_index i
>> JOIN pg_class c ON c.oid = i.indexrelid
>> WHERE indrelid = 'shared_schema.bob_table'::regclass
>> UNION ALL
>> SELECT 'STATISTICS', stxname, pg_get_userbyid(stxowner) FROM
>> pg_statistic_ext
>> WHERE stxrelid = 'shared_schema.bob_table'::regclass;
>> -- INDEX owner = bob, STATISTICS owner = superuser
>>
>> SET ROLE bob;
>> DROP INDEX shared_schema.idx_bob; -- succeeds
>> DROP STATISTICS shared_schema.stat_bob; -- ERROR: statistics object
>> "..." does not exist
>>
>> I'm not sure if the current STATISTICS ownership behavior was
>> intentional. If it wasn't, would it make sense to assign the statistics
>> object's owner to the relation owner (same as INDEX) for consistency and to
>> avoid the above scenario?
>>
>> Thanks for your time.
>>
>
| Attachment | Content-Type | Size |
|---|---|---|
| 0001-Make-CREATE-STATISTICS-assign-ownership-to-the-relat.patch | application/octet-stream | 4.1 KB |
| From | Date | Subject | |
|---|---|---|---|
| Next Message | Heikki Linnakangas | 2026-03-09 11:17:40 | Re: Refactor recovery conflict signaling a little |
| Previous Message | vignesh C | 2026-03-09 10:53:37 | Re: Skipping schema changes in publication |