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.94.2) (envelope-from ) id 1vBXRX-000I6K-Lg for pgsql-hackers@arkaria.postgresql.org; Wed, 22 Oct 2025 11:55:51 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.94.2) (envelope-from ) id 1vBXRU-00Fhgs-EP for pgsql-hackers@arkaria.postgresql.org; Wed, 22 Oct 2025 11:55:47 +0000 Received: from makus.postgresql.org ([2001:4800:3e1:1::229]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1vBXRT-00Fhgk-Ug for pgsql-hackers@lists.postgresql.org; Wed, 22 Oct 2025 11:55:47 +0000 Received: from mail-il1-x12b.google.com ([2607:f8b0:4864:20::12b]) by makus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.96) (envelope-from ) id 1vBXRQ-0039ZW-2t for pgsql-hackers@lists.postgresql.org; Wed, 22 Oct 2025 11:55:46 +0000 Received: by mail-il1-x12b.google.com with SMTP id e9e14a558f8ab-430cd27de3eso22729365ab.1 for ; Wed, 22 Oct 2025 04:55:44 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1761134144; x=1761738944; 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=PrVtIPqSzo03Ms365NeyCUqeeNBxQkP0fcNzhtN4oFg=; b=HH4Ljjs12MjzIZ4yq9N27Vj2ikBQxlZRtFqMW+IWg8nXJ6wYwP8LAwMkqPHJvxqNJf KKUqiKEty46zwTDfjl0S2Yle5npKT49qjm0Fp7mC8LrcmWGh3ilT8W8CPG5sil8/Te+i pMMRTjX/JHU0QR/yLAq3ze0i/P0REx3cub/Thf8gZNWUUZalFQJvDEjG9BE5zMXhMBCa GrOBkDI1uS9yOTAz1ZrRUQzt1MR+E5TmlhwDimBCw9Bzet578CIusRTYXp+THLFbxEkT ka+9eJic6Pn9swc6uX+LbQWoiZaFeHURc62Gh16VD4xFlR2IMXw+RY0cMcqzVfN4N3h6 rqhg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1761134144; x=1761738944; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=PrVtIPqSzo03Ms365NeyCUqeeNBxQkP0fcNzhtN4oFg=; b=FL4uG5X3L9PaXi4kTZBkqUD7z54mk0M9hRAEtaFpry1w96a5SrcYJEEDd+fWGs8N/b JRie+CDYYA2BRsEYhZUTEA1FjdLz2gfZquHCIi7wumAZY5JH9np+dkprkhCAu9FcG0k0 mlTCJhgI/OxZX12S+mn7l4JwtJN8pPirsrsJ+OBpMcywfFXTRVTNzCSpx/SF17qTa8IY PMsH2I+79ACHqrDqcHHmkEeRDs6CRills1Ru5FgW6RIzmPA7uriCsGc9PvvRI+bfCHZQ RdJlhUHTKJ21oW7DY9wXRdTLwNRAn714nawBiiBMTcRM+qJEdtKCRpV5CxebbhLY2Vxo uMfg== X-Forwarded-Encrypted: i=1; AJvYcCXo03OyqtzUgYIabljgosMnpx9fojCNXONdSsU48VWhefZbXg1uWHt+re39PqAP3DAyNdWgzm6Kmk9hbzPd@lists.postgresql.org X-Gm-Message-State: AOJu0YwhM53SkDdxisx+nukNiiHMs4/C7TENOBbbVj4tTiJhFOUAPOay R/R3jmboqFFY28EzzzY4K0JJsif8IGrsCwa0rNls/eSxHBAQYgyhSgiGEOvDPzwLDn0QU30jE4G +2UllKbR2+RC550fjT01dLkcvp+uCiAI= X-Gm-Gg: ASbGncupWGmRnQilwziaAukI2+sgVvZSquMYz3NB23yspKexgefMZSaq+8fAognzywM AWJV3jp5pJi6cX3CYGjDty3AvKL+o8BOO0z8Vj4CoLo4VSr1EVIVgWlEjrsx/eo69ADg2Cs6ia/ r82UhI/ay5lkT739teIwBThd7bnyVnVxGVbDv56NuRWZewt6ZRYOG2bs2hAdueds0KkdDuCyF5p y946Z30Nsczft+9DJ0WBmhcVkeDQ885vi4e1+IIUAaiUFpwKiVAd66+LZLGU7A= X-Google-Smtp-Source: AGHT+IG7Bgj8UpYo53l0IryhhG5PltjjWDas6IK20P5rYtTrYLkJlu8e6Z8WcKwuvAqnapawJ/I1DdWjTlRnMgy66Dc= X-Received: by 2002:a05:6e02:144d:b0:42f:8eeb:49a1 with SMTP id e9e14a558f8ab-430c523d6fdmr323274395ab.13.1761134144099; Wed, 22 Oct 2025 04:55:44 -0700 (PDT) MIME-Version: 1.0 References: In-Reply-To: From: Corey Huinker Date: Wed, 22 Oct 2025 14:55:31 +0300 X-Gm-Features: AS18NWCZB8Xa5YLM7BW0pggzzxzCO6vfUABuw8Bvqxssy2Z718pI5fBY_P6fXV8 Message-ID: Subject: Re: Extended Statistics set/restore/clear functions. To: Michael Paquier Cc: jian he , Tomas Vondra , pgsql-hackers@lists.postgresql.org, tgl@sss.pgh.pa.us Content-Type: multipart/alternative; boundary="0000000000000f9b210641bdff09" List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --0000000000000f9b210641bdff09 Content-Type: text/plain; charset="UTF-8" > > The functions exposed in 0003 should be renamed to match more with the > style of the rest, aka it is a bit hard to figure out what they do at > first sight. Presumably, these should be prefixed with some > "statext_", except text_to_stavalues() which could still be named the > same. > That prefix would probably be statatt_ or statattr_. > > Do you have some numbers regarding the increase in size this generates > for the catalogs? > Sorry, I don't understand. There shouldn't be any increase inside the catalogs as the internal storage of the datatypes hasn't changed, so I can only conclude that you're referring to something else. > > 0004 has been designed following the same model as the relation and > attribute stats. That sounds OK here. > > +enum extended_stats_argnum > [...] > +enum extended_stats_exprs_element > > It would be nice to document why such things are around. That would > be less guessing for somebody reading the code. > The equivalent structures in attribute_stats.c will need documenting too. > > Reusing this small sequence from your pg_dump patch, executed on a v14 > backend: > create schema dump_test; > CREATE TABLE dump_test.has_ext_stats > AS SELECT g.g AS x, g.g / 2 AS y FROM generate_series(1,100) AS g(g); > CREATE STATISTICS dump_test.es1 ON x, (y % 2) FROM dump_test.has_ext_stats; > ANALYZE dump_test.has_ext_stats; > > Then pg_dump fails: > pg_dump: error: query failed: ERROR: column e.inherited does not exist > LINE 2: ...hemaname = $1 AND e.statistics_name = $2 ORDER BY e.inherite... > Noted. > > > + * TODO: Until v18 is released the master branch has a > + * server_version_num of 180000. We will update this to 190000 > as soon > + * as the master branch updates. > > This part has not been updated. > > + Assert(item.nattributes > 0); /* TODO: elog? */ > [...] > + Assert(dependency->nattributes > 1); /* TODO: elog? */ > Yes and yes. It seems like it should be possible to craft some input > that triggers these.. > +1 > > +void > +free_pg_dependencies(MVDependencies *dependencies); > > Double declaration of this routine in dependencies.c. > > Perhaps some of the regression tests could use some jsonb_pretty() in > the outputs generated. Some of the results generated are very hard to > parse, something that would become harder in the buildfarm. This > comment starts with 0001 for stxdndistinct. > Can do. > > I have mixed feelings about 0005, FWIW. I am wondering if we should > not lift the needle a bit here and only support the dump of extended > statistics when dealing with a backend of at least v19. This would > mean that we would only get the full benefit of this feature once > people upgrade to v20 or dump from a pg_dump with --statistics from at > least v19, but with the long-term picture in mind this would also make > the dump/restore picture of the patch dead simple (spoiler: I like > simple). > I also like simple. Right now we have a situation where the vast majority of databases can carry forward all of their stats via pg_upgrade, except for those databases that have extended stats. The trouble is, most customers don't know if their database uses extended statistics or not, and those that do are in for some bad query plans if they haven't run vacuumdb --missing-stats-only. Explaining that to customers is complicated, especially when most of them do not know what extended stats are, let alone whether they have them. It would be a lot simpler to just say "all stats are carried over on upgrade", and vacuumdb becomes unnecessary, making upgrades one step simpler as well. Given that, I think that the admittedly ugly transformation is worth it, and sequestering it inside pg_dump is the smallest footprint it can have. Earlier in this thread I posted some functions that did the translation from the existing formats to the proposed new formats. We could include those as new system functions, and that would make the dump code very simple. Having said that, I don't know that there would be use for those functions except inside pg_dump, hence the decision to do the transforms right in the dump query. If the format translation is a barrier to fetching existing extended stats, then I'd be more inclined to keep the existing pg_ndistinct and pg_dependencies data formats as they are now. --0000000000000f9b210641bdff09 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
The functions exposed in 0003 shou= ld be renamed to match more with the
style of the rest, aka it is a bit hard to figure out what they do at
first sight.=C2=A0 Presumably, these should be prefixed with some
"statext_", except text_to_stavalues() which could still be named= the
same.

That prefix would probably be statatt_= or statattr_.=C2=A0
=C2=A0

Do you have some numbers regarding the increase in size this generates
for the catalogs?

Sorry, I don't underst= and. There shouldn't be any increase inside the catalogs as the interna= l storage of the datatypes=C2=A0hasn't changed, so I can only conclude = that you're referring to something else.
=C2=A0

0004 has been designed following the same model as the relation and
attribute stats.=C2=A0 That sounds OK here.

+enum extended_stats_argnum
[...]
+enum extended_stats_exprs_element

It would be nice to document why such things are around.=C2=A0 That would be less guessing for somebody reading the code.

The equivalent structures in attribute_stats.c will need documenting to= o.


=C2=A0

Reusing this small sequence from your pg_dump patch, executed on a v14
backend:
create schema dump_test;
CREATE TABLE dump_test.has_ext_stats
=C2=A0 AS SELECT g.g AS x, g.g / 2 AS y FROM generate_series(1,100) AS g(g)= ;
CREATE STATISTICS dump_test.es1 ON x, (y % 2) FROM dump_test.has_ext_stats;=
ANALYZE dump_test.has_ext_stats;

Then pg_dump fails:
pg_dump: error: query failed: ERROR:=C2=A0 column e.inherited does not exis= t
LINE 2: ...hemaname =3D $1 AND e.statistics_name =3D $2 ORDER BY e.inherite= ...

Noted.
=C2=A0


+=C2=A0 =C2=A0 =C2=A0 =C2=A0 * TODO: Until v18 is released the master branc= h has a
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 * server_version_num of 180000. We will update= this to 190000
as soon
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 * as the master branch updates.

This part has not been updated.

+=C2=A0 =C2=A0 =C2=A0 =C2=A0Assert(item.nattributes > 0);=C2=A0 =C2=A0/*= TODO: elog? */
[...]
+=C2=A0 =C2=A0 =C2=A0 =C2=A0Assert(dependency->nattributes > 1);=C2= =A0 =C2=A0 /* TODO: elog? */
Yes and yes.=C2=A0 It seems like it should be possible to craft some input<= br> that triggers these..

+1
=C2= =A0

+void
+free_pg_dependencies(MVDependencies *dependencies);

Double declaration of this routine in dependencies.c.

Perhaps some of the regression tests could use some jsonb_pretty() in
the outputs generated.=C2=A0 Some of the results generated are very hard to=
parse, something that would become harder in the buildfarm.=C2=A0 This
comment starts with 0001 for stxdndistinct.

= Can do.
=C2=A0

I have mixed feelings about 0005, FWIW.=C2=A0 I am wondering if we should not lift the needle a bit here and only support the dump of extended
statistics when dealing with a backend of at least v19.=C2=A0 This would mean that we would only get the full benefit of this feature once
people upgrade to v20 or dump from a pg_dump with --statistics from at
least v19, but with the long-term picture in mind this would also make
the dump/restore picture of the patch dead simple (spoiler: I like
simple).

I also like simple.

Right now we have a situation where the vast majority of da= tabases can carry forward all of their stats via pg_upgrade, except for tho= se databases that have extended stats. The trouble is, most customers don&#= 39;t know=C2=A0if their database uses extended statistics or not, and those= that do are in for some bad query plans if they haven't run vacuumdb -= -missing-stats-only. Explaining that to customers is complicated, especiall= y when most of them do not know what extended stats are, let alone whether = they have them. It would be a lot simpler to just say "all stats are c= arried over on upgrade", and vacuumdb becomes unnecessary, making upgr= ades one step simpler as well.

Given that, I think= that the admittedly ugly transformation is worth it, and sequestering it i= nside pg_dump is the smallest footprint it can have. Earlier in this thread= I posted some functions that did the translation from the existing formats= to the proposed new formats. We could include those as new system function= s, and that would make the dump code very simple. Having said that, I don&#= 39;t know that there would be use for those functions except inside pg_dump= , hence the decision to do the transforms right in the dump query.
If the format trans= lation is a barrier to fetching existing extended stats, then I'd be mo= re inclined to keep the existing pg_ndistinct and pg_dependencies data form= ats as they are now.
--0000000000000f9b210641bdff09--