Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1w0GGh-001l2b-2W for pgsql-hackers@arkaria.postgresql.org; Wed, 11 Mar 2026 09:54:19 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.96) (envelope-from ) id 1w0GGf-008HOj-0C for pgsql-hackers@arkaria.postgresql.org; Wed, 11 Mar 2026 09:54:17 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1w0GGe-008HOb-2N for pgsql-hackers@lists.postgresql.org; Wed, 11 Mar 2026 09:54:17 +0000 Received: from mail-yw1-x1130.google.com ([2607:f8b0:4864:20::1130]) by magus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.98.2) (envelope-from ) id 1w0GGc-000000027EI-3Fv8 for pgsql-hackers@lists.postgresql.org; Wed, 11 Mar 2026 09:54:16 +0000 Received: by mail-yw1-x1130.google.com with SMTP id 00721157ae682-7991db3dc98so1283677b3.0 for ; Wed, 11 Mar 2026 02:54:14 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1773222853; cv=none; d=google.com; s=arc-20240605; b=PnZxAiPUUXrfGxPWNgz+FoxSsADRLmX/Eq47o+gX571eHw/FfUfKo5xHU2sujk+6Zu t5UnINduki/KbbhLb56Cv/1KYhnid7+zVhcTQVf0e5DakPvPsJdiEeZ2/UFge/pVIXg9 qf6j6UI37+4SZwls1wsTWFyQUk3twaa7pKI0pTsphu89OUI1Bv0FGE9pEZH2F28XRHk8 GVSPToSZex70tEKvo1mGDUJOuwr1DincXzsk6a3ZbcdILqAGYSyzHuSJtEEE/arubs1c bvgkk5bSMiwjcFFkdywRvRmTXGP0pc1K2jKDy4HsFvuOIz02I6TJRwzKwhDIZIjC6YAx 4DuQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:dkim-signature; bh=oKH8XpQpWwtlt0xk4jEfr1/4GE1xfGI0usPCBbg0+wI=; fh=2R30/eUds1wti5PSrkak3BAtSiEjCqO4Azrc/O+KQRs=; b=I305jUFaysvHMdABDbyDv++YtEDicXyPL65VljCuDB3gnIYJYbYndQtQ1wLFhFozrh YXnfOeM+4Q0/IXrL/Ntd+UaDP4+lOm839BjWp7r3QHaMR0o8TpQswj1runyrBMfpyjDK UftKaaYLbHbzfvRbUTvVG2y/WdpN+Tk9CUUGRGidxbUBSq7vWvPQLXtkRUijt4tx2DVp JEo9aqoLA33KI0Id3kdi+V6vlO6svUTYCZAhxdwVQ2pBFqfFZ+cZ86u2Q3eXlQ8obgv0 UKqt3znsQrLDSzm38WqgNAIMON3Sw40Fj7tvGib4f7jsOjN31j7wdzCrjouT9q93evGD A3SQ==; darn=lists.postgresql.org ARC-Authentication-Results: i=1; mx.google.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1773222853; x=1773827653; darn=lists.postgresql.org; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:from:to:cc:subject:date:message-id:reply-to; bh=oKH8XpQpWwtlt0xk4jEfr1/4GE1xfGI0usPCBbg0+wI=; b=I6rU3GlPFfiiyrtYcVZC61YYhZuOJ2iK9KpwfQad7E0hRRTRke6/PlTA0/JObhOZ/H 47EO0E43GqZ3MpIx7wPy4tsXYe8pBuqBpOK3oXL9rYJbnOvePLWiWlXgpSByTSVNBvA3 2DoBT+KbEnM2O5tRQMjinXn0kYjIxKK3PfpE3OlosRxPSnNewvFAkF1XySaIyzKs9fFP wL+VN3NsfhQcG6f+tthrRwvEeevYYIAt0by5eOeK1GzcKJtCTUUyEKjuHqde5qlzBqOR rR8Q+1AYUC0fiUbnPPwDO9nBvCd1sExVZstnS3HXmxYI60UTF9RzddvnFou1SbKAp3Qe PNjQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1773222853; x=1773827653; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=oKH8XpQpWwtlt0xk4jEfr1/4GE1xfGI0usPCBbg0+wI=; b=LliZCcwL8AV0awE8yorklP/mbFjvXqVp4eKGn9oxeJfVcz0XzuzEJX/vKNiIxAAhjJ G8GNLnHRLUl6BG0nxcT7GrssvG2nFADDxGQ8LOXmQmDaNNxuxVHsFYXuuyZNRo485oJG YRdu9twiQJ2O+V5m74/KFLhQQpnu3NrjodjdCHTjyb30oQ23Lh/UYL1zD74bOXmop/cb O6isqK3ZWf0/AKr11WMzIIJnVRkA/X+5p2nYNO4sRL594sje/mO/9R34kwB138/wiZq1 aC0PTGgQ+oKse2G92MF54yB05v/sw90VPVy/fPPuj3htE3ZEF7OzUQglwk2FHHHz1vI7 bRuA== X-Gm-Message-State: AOJu0Yz4PHCxPstan8qgZDH1AMCX6u7A43ReRKNZNNBEalvEhhd863Zk n5ymZqp7oqaIXl4emejVusVt/ls4aVpBjY9JsbYRZJDB3rd6wYbieQu8NMFjqrS42TRZ/L9X1J9 Ki6lM3tI8JDRlu5EUBwAdSmB7p6AfLhA= X-Gm-Gg: ATEYQzyKCRsLmbPg+bfEsEhql2eLatbA2lEMKxBWoRuwslmyC8Zrbz6szgSIKdyTfQw vEBe+8kQ3FZZAKlSgnrIUlzrFf2CtZT/JGegVAeZSRWMo9LzWJB4LZbe2pCTz+ydQzXyDHx2Hcc VxQqIFq94YCnB4+zULe5iAdP9OweNLVCEzKhyP8iXe1lQ/7tnreT/uAwpmxi0hLTIXYt0hSe5JL CEDkHXPj6pty+rTfi0yA2RRkuW/Cv7WhPdo8T9bcDmoxqv/wGxOErRBnWGd6KUjOEOVsGmE7X/L qFY1XIyinKDUjv0Gdg== X-Received: by 2002:a05:690c:6d84:b0:794:d4c3:3152 with SMTP id 00721157ae682-79917f5dd3dmr16953127b3.31.1773222853173; Wed, 11 Mar 2026 02:54:13 -0700 (PDT) MIME-Version: 1.0 References: In-Reply-To: From: Shin Berg Date: Wed, 11 Mar 2026 18:54:01 +0900 X-Gm-Features: AaiRm52rAnUJv4_S3juYYTqQqN_Z4ggerun5EReKbx8swVZv9658jHQDLInERYo Message-ID: Subject: Re: Inconsistency in owner assignment between INDEX and STATISTICS To: Amit Khandekar Cc: pgsql-hackers@lists.postgresql.org Content-Type: multipart/alternative; boundary="0000000000004563d4064cbc9ee1" List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --0000000000004563d4064cbc9ee1 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Thank you for the detailed feedback, Amit. You're right on both points. I had been comparing STATISTICS against INDEX and treating the difference as an inconsistency, but as you point out, INDEX ownership is special =E2=80=94 it's tied to the table and intentional= ly not user-adjustable. STATISTICS follows the same ownership model as VIEW (the creator becomes the owner), which is consistent and by design. I also verified locally that my reproduction script was flawed: the "must be owner" error was caused by a schema search path issue, not an ownership restriction. The script did not demonstrate what I claimed. I'm withdrawing this proposal. Thanks again for taking the time to review it. On Tue, Mar 10, 2026 at 11:07=E2=80=AFPM Amit Khandekar wrote: > On Sat, 14 Feb 2026 at 14:18, Shin Berg wrote: > > > > Hi, > > > > I'd like to raise a small consistency issue between how INDEX and > extended STATISTICS handle object ownership, and ask whether aligning the= m > 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 = =3D > GetUserId()). > > I will try to divide the problem into two questions: > > 1. Should the statistics object's owner be permanently associated with > the table owner? > > From the docs, it does look like the current behaviour is intentional. > > https://www.postgresql.org/docs/current/sql-createstatistics.html : > "You must be the owner of a table to create a statistics object > reading it. Once created, however, the ownership of the statistics > object is independent of the underlying table(s)." > > So I think we should not change the behaviour where the statistics > object is created with independent ownership. > > With indexes, the behaviour has always been that it is associated with > the table: > > postgres=3D# alter INDEX shared_schema.idx_bob owner to bob1; > WARNING: cannot change owner of index "idx_bob" > HINT: Change the ownership of the index's table instead. > > 2. Regardless of that, should the "create statistics" create the stat > object with the same ownership as the table's, if it's the superuser > who is creating the statistics? > > I think, since there is no permanent association of ownership between > the table and the statistics, it makes sense for the user who is > running the create command to own the statistics, regardless of who > the user is, provided that the user has privileges. > > > > > 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). > > The permission error should be emitted if the DROP is on the right > schema. See below. > > > 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). > > Maybe, make sure the table owner (and not the superuser) is creating > the statistics? > > > > > 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 =3D i.indexrelid > > WHERE indrelid =3D 'shared_schema.bob_table'::regclass > > UNION ALL > > SELECT 'STATISTICS', stxname, pg_get_userbyid(stxowner) FROM > pg_statistic_ext > > WHERE stxrelid =3D 'shared_schema.bob_table'::regclass; > > -- INDEX owner =3D bob, STATISTICS owner =3D superuser > > > > SET ROLE bob; > > DROP INDEX shared_schema.idx_bob; -- succeeds > > DROP STATISTICS shared_schema.stat_bob; -- ERROR: statistics object > "..." does not exist > > The statistics object is created in the default schema, not the table's > schema. > postgres=3D> DROP STATISTICS public.stat_bob; > ERROR: must be owner of statistics object public.stat_bob > > Thanks > -Amit Khandekar > --0000000000004563d4064cbc9ee1 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
Thank you for the detailed feedback, Amit= .

You're right on both points. I had been comparing STATISTICS a= gainst INDEX
and treating the difference as an inconsistency, but as you= point out,
INDEX ownership is special =E2=80=94 it's tied to the ta= ble and intentionally not
user-adjustable. STATISTICS follows the same o= wnership model as VIEW (the
creator becomes the owner), which is consist= ent and by design.

I also verified locally that my reproduction scri= pt was flawed: the
"must be owner" error was caused by a schem= a search path issue, not an
ownership restriction. The script did not de= monstrate what I claimed.

I'm withdrawing this proposal. Thanks = again for taking the time to review it.

On Tue, Mar 10= , 2026 at 11:07=E2=80=AFPM Amit Khandekar <amitdkhan.pg@gmail.com> wrote:
On Sat, 14 Feb 2026 at 14:18, Shin Berg = <sjh910805@gmai= l.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 i= ndex 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 = =3D GetUserId()).

I will try to divide the problem into two questions:

1. Should the statistics object's owner be permanently associated with<= br> the table owner?