pgsql: Allow HOT updates for some expression indexes
Hackorum builds and tests every patch posted to the lists, not only commitfest submissions. This is Hackorum's own CI rather than the PostgreSQL project's, and it is still under testing - please report anything that looks wrong.
You can run a PostgreSQL built from this patch straight from Docker, with no checkout and no build:
docker run --rm -p 5432:5432 ghcr.io/hackorum-dev/postgres-patch:t208280psql -h localhost -U postgresBuilt from patchset v7 (message #7), July 29, 2026 at 12:57 AM.
Every patchset is also pushed to a branch of our PostgreSQL fork, so you can check out the same tree CI built. Without a PostgreSQL checkout:
git clone --branch t208280_7 https://github.com/hackorum-dev/postgres.gitIn a checkout you already have, add the fork once:
git remote add hackorum https://github.com/hackorum-dev/postgres.gitthen, for this patchset and every later one:
git fetch hackorum t208280_7 && git checkout t208280_7Patchset v7 (message #7) is on t208280_7
Allow HOT updates for some expression indexes
If the value of an index expression is unchanged after UPDATE,
allow HOT updates where previously we disallowed them, giving
a significant performance boost in those cases.
Particularly useful for indexes such as JSON->>field where the
JSON value changes but the indexed value does not.
Submitted as "surjective indexes" patch, now enabled by use
of new "recheck_on_update" parameter.
Author: Konstantin Knizhnik
Reviewer: Simon Riggs, with much wordsmithing and some cleanup
Branch
------
master
Details
-------
https://git.postgresql.org/pg/commitdiff/c203d6cf81b4d7e43edb2b75ec1b741ba48e04e0
Modified Files
--------------
doc/src/sgml/ref/create_index.sgml | 37 +++++++++-
src/backend/access/common/reloptions.c | 45 ++++++++++++-
src/backend/access/heap/heapam.c | 105 +++++++++++++++++++++++++++--
src/backend/catalog/index.c | 3 +-
src/backend/utils/cache/relcache.c | 112 +++++++++++++++++++++++++++++--
src/bin/psql/tab-complete.c | 4 +-
src/include/access/reloptions.h | 2 +
src/include/utils/rel.h | 12 +++-
src/include/utils/relcache.h | 3 +-
src/test/regress/expected/func_index.out | 61 +++++++++++++++++
src/test/regress/parallel_schedule | 2 +-
src/test/regress/serial_schedule | 1 +
src/test/regress/sql/func_index.sql | 30 +++++++++
13 files changed, 395 insertions(+), 22 deletions(-)
Buildfarm failure seen, investigating
On 27 March 2018 at 20:01, Simon Riggs <simon@2ndquadrant.com> wrote:
Allow HOT updates for some expression indexes
If the value of an index expression is unchanged after UPDATE,
allow HOT updates where previously we disallowed them, giving
a significant performance boost in those cases.Particularly useful for indexes such as JSON->>field where the
JSON value changes but the indexed value does not.Submitted as "surjective indexes" patch, now enabled by use
of new "recheck_on_update" parameter.Author: Konstantin Knizhnik
Reviewer: Simon Riggs, with much wordsmithing and some cleanupBranch
------
masterDetails
-------
https://git.postgresql.org/pg/commitdiff/c203d6cf81b4d7e43edb2b75ec1b741ba48e04e0Modified Files
--------------
doc/src/sgml/ref/create_index.sgml | 37 +++++++++-
src/backend/access/common/reloptions.c | 45 ++++++++++++-
src/backend/access/heap/heapam.c | 105 +++++++++++++++++++++++++++--
src/backend/catalog/index.c | 3 +-
src/backend/utils/cache/relcache.c | 112 +++++++++++++++++++++++++++++--
src/bin/psql/tab-complete.c | 4 +-
src/include/access/reloptions.h | 2 +
src/include/utils/rel.h | 12 +++-
src/include/utils/relcache.h | 3 +-
src/test/regress/expected/func_index.out | 61 +++++++++++++++++
src/test/regress/parallel_schedule | 2 +-
src/test/regress/serial_schedule | 1 +
src/test/regress/sql/func_index.sql | 30 +++++++++
13 files changed, 395 insertions(+), 22 deletions(-)
--
Simon Riggs http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services
On 27 March 2018 at 20:11, Simon Riggs <simon@2ndquadrant.com> wrote:
Buildfarm failure seen, investigating
Error on FreeBSD only , perhaps timing-related as a result of using
pg_stat_get_xact_tuples_hot_updated()
in tests.
Will wait to collect other failures
--
Simon Riggs http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services
Simon Riggs <simon@2ndquadrant.com> writes:
On 27 March 2018 at 20:11, Simon Riggs <simon@2ndquadrant.com> wrote:
Buildfarm failure seen, investigating
Error on FreeBSD only , perhaps timing-related as a result of using
pg_stat_get_xact_tuples_hot_updated()
in tests.
It's by now obvious that it's not just "FreeBSD only".
The test script appears to imagine that pgstats outputs update
instantaneously. I'm rather astonished that it passes anywhere,
much less that it seemingly passes reliably enough for you
to have not been noticed in precommit testing.
The existing "stats" test moves mountains to get repeatable results,
and is pretty slow in consequence, and even so it doesn't always succeed.
I think that rather than going down that path, you should drop this test
approach and think of some other way.
regards, tom lane
I wrote:
The test script appears to imagine that pgstats outputs update
instantaneously.
Oh, wait, it's looking at pg_stat_xact, which is the *local*, unsent
stats information. So your problem is actually the reverse of that:
if the test runs too slowly, it fails, because at some point the
unsent stats information will get flushed out to the collector and
disappear from the pg_stat_xact view.
You could probably make this more reliable by wrapping each test
stanza in a transaction, ie instead of
create table keyvalue ...;
... do something to table ...
select pg_stat_get_xact_tuples_hot_updated('keyvalue'::regclass);
drop table keyvalue;
do
begin;
create table keyvalue ...;
... do something to table ...
select pg_stat_get_xact_tuples_hot_updated('keyvalue'::regclass);
rollback;
(no need for a DROP if you're rolling it all back)
regards, tom lane
On 27 March 2018 at 22:26, Tom Lane <tgl@sss.pgh.pa.us> wrote:
I wrote:
The test script appears to imagine that pgstats outputs update
instantaneously.Oh, wait, it's looking at pg_stat_xact, which is the *local*, unsent
stats information. So your problem is actually the reverse of that:
if the test runs too slowly, it fails, because at some point the
unsent stats information will get flushed out to the collector and
disappear from the pg_stat_xact view.You could probably make this more reliable by wrapping each test
stanza in a transaction, ie instead ofcreate table keyvalue ...;
... do something to table ...
select pg_stat_get_xact_tuples_hot_updated('keyvalue'::regclass);
drop table keyvalue;do
begin;
create table keyvalue ...;
... do something to table ...
select pg_stat_get_xact_tuples_hot_updated('keyvalue'::regclass);
rollback;(no need for a DROP if you're rolling it all back)
Oh wow, thanks. Fixed.
--
Simon Riggs http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services
On 28.03.2018 07:23, Simon Riggs wrote:
On 27 March 2018 at 22:26, Tom Lane <tgl@sss.pgh.pa.us> wrote:
I wrote:
The test script appears to imagine that pgstats outputs update
instantaneously.Oh, wait, it's looking at pg_stat_xact, which is the *local*, unsent
stats information. So your problem is actually the reverse of that:
if the test runs too slowly, it fails, because at some point the
unsent stats information will get flushed out to the collector and
disappear from the pg_stat_xact view.You could probably make this more reliable by wrapping each test
stanza in a transaction, ie instead ofcreate table keyvalue ...;
... do something to table ...
select pg_stat_get_xact_tuples_hot_updated('keyvalue'::regclass);
drop table keyvalue;do
begin;
create table keyvalue ...;
... do something to table ...
select pg_stat_get_xact_tuples_hot_updated('keyvalue'::regclass);
rollback;(no need for a DROP if you're rolling it all back)
Oh wow, thanks. Fixed.
I am sorry, I missed the fact that local stat information can be reset.
Attached please find updated version of the patch with func_index.sql
test fixed.
Also I have renamed rd_indexattr to rd_nprjindexattr to avoid confusions.
--
Konstantin Knizhnik
Postgres Professional: http://www.postgrespro.com
The Russian Postgres Company