FOR PORTION OF assertion failure in ExecInitPartitionInfo()

Started by Peter Eisentraut2 months ago5 messageshackers
Beta feature

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.

won't retrysuccessCI history

This thread has been committed, so CI has stopped here. Anything below is the last result it produced.

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:t253499
psql -h localhost -U postgres

Built from patchset v4 (message #4), September 01, 2026 at 05:55 PM.

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 t253499_4 https://github.com/hackorum-dev/postgres.git

In a checkout you already have, add the fork once:

git remote add hackorum https://github.com/hackorum-dev/postgres.git

then, for this patchset and every later one:

git fetch hackorum t253499_4 && git checkout t253499_4

Patchset v4 (message #4) is on t253499_4

Jump to latest
#1Peter Eisentraut
peter_e@gmx.net

The following test case triggers an assertion failure in
ExecInitPartitionInfo():

CREATE TABLE temporal_partitioned_by_range (
id int4range,
valid_at daterange,
name text
) PARTITION BY RANGE (valid_at);

CREATE TABLE temporal_partitioned_early
PARTITION OF temporal_partitioned_by_range
FOR VALUES FROM (MINVALUE) TO ('[2000-06-01,)');
CREATE TABLE temporal_partitioned_late
PARTITION OF temporal_partitioned_by_range
FOR VALUES FROM ('[2000-06-01,)') TO (MAXVALUE);

INSERT INTO temporal_partitioned_by_range (id, valid_at, name)
VALUES ('[1,2)', daterange('2000-01-01', '2010-01-01'), 'one');

DELETE FROM temporal_partitioned_by_range
FOR PORTION OF valid_at FROM '2000-03-01' TO '2000-07-01'
WHERE valid_at < '[2000-06-01,)'::daterange
RETURNING id, valid_at, name;

It appears to work correctly with assertions disabled, so maybe just
some of the Assert()s in ExecInitPartitionInfo() need some updates?

#2Paul A Jungwirth
pj@illuminatedcomputing.com
In reply to: Peter Eisentraut (#1)
Re: FOR PORTION OF assertion failure in ExecInitPartitionInfo()

On Wed, Aug 19, 2026 at 10:26 PM Peter Eisentraut <peter@eisentraut.org> wrote:

The following test case triggers an assertion failure in
ExecInitPartitionInfo():

CREATE TABLE temporal_partitioned_by_range (
id int4range,
valid_at daterange,
name text
) PARTITION BY RANGE (valid_at);

CREATE TABLE temporal_partitioned_early
PARTITION OF temporal_partitioned_by_range
FOR VALUES FROM (MINVALUE) TO ('[2000-06-01,)');
CREATE TABLE temporal_partitioned_late
PARTITION OF temporal_partitioned_by_range
FOR VALUES FROM ('[2000-06-01,)') TO (MAXVALUE);

INSERT INTO temporal_partitioned_by_range (id, valid_at, name)
VALUES ('[1,2)', daterange('2000-01-01', '2010-01-01'), 'one');

DELETE FROM temporal_partitioned_by_range
FOR PORTION OF valid_at FROM '2000-03-01' TO '2000-07-01'
WHERE valid_at < '[2000-06-01,)'::daterange
RETURNING id, valid_at, name;

It appears to work correctly with assertions disabled, so maybe just
some of the Assert()s in ExecInitPartitionInfo() need some updates?

Thanks for catching this! I'm on a family backpacking trip, so the
earliest I'll be able to look closely is after the 30th.

Yours,

--
Paul ~{:-)
pj@illuminatedcomputing.com

#3Nathan Bossart
nathandbossart@gmail.com
In reply to: Paul A Jungwirth (#2)
Re: FOR PORTION OF assertion failure in ExecInitPartitionInfo()

Does this one deserve a mention on the open items wiki [0]https://wiki.postgresql.org/wiki/PostgreSQL_19_Open_Items?

[0]: https://wiki.postgresql.org/wiki/PostgreSQL_19_Open_Items

--
nathan

#4Paul A Jungwirth
pj@illuminatedcomputing.com
In reply to: Peter Eisentraut (#1)
Re: FOR PORTION OF assertion failure in ExecInitPartitionInfo()

On Wed, Aug 19, 2026 at 10:26 PM Peter Eisentraut <peter@eisentraut.org> wrote:

The following test case triggers an assertion failure in
ExecInitPartitionInfo():

CREATE TABLE temporal_partitioned_by_range (
id int4range,
valid_at daterange,
name text
) PARTITION BY RANGE (valid_at);

CREATE TABLE temporal_partitioned_early
PARTITION OF temporal_partitioned_by_range
FOR VALUES FROM (MINVALUE) TO ('[2000-06-01,)');
CREATE TABLE temporal_partitioned_late
PARTITION OF temporal_partitioned_by_range
FOR VALUES FROM ('[2000-06-01,)') TO (MAXVALUE);

INSERT INTO temporal_partitioned_by_range (id, valid_at, name)
VALUES ('[1,2)', daterange('2000-01-01', '2010-01-01'), 'one');

DELETE FROM temporal_partitioned_by_range
FOR PORTION OF valid_at FROM '2000-03-01' TO '2000-07-01'
WHERE valid_at < '[2000-06-01,)'::daterange
RETURNING id, valid_at, name;

It appears to work correctly with assertions disabled, so maybe just
some of the Assert()s in ExecInitPartitionInfo() need some updates?

I looked into this a bit. Here is a patch.

The problem is that we hit this assert when the partition key depends
on the valid_at column. Then if the temporal leftover gets routed to a
different partition that was pruned away from the original query, we
call ExecInitPartitionInfo, which never needed to handle CMD_DELETE
before. Everything works, but the Assert is out of date. So I agree
that is the only change needed.

The same function has a similar Assert for WITH CHECK OPTION, and we
can trigger that too. This patch updates both and provides tests.

I changed the repro SQL to partition on lower(valid_at) instead of
valid_at, which I think is more natural and more likely to be used in
practice. Both versions trigger the Assert pre-fix and work post-fix.

I also considered GENERATED columns. Those can't be used as partition
keys today, so they are rejected well before the exec phase (or even
running a query).

Yours,

--
Paul ~{:-)
pj@illuminatedcomputing.com

Attachments:

t253499_4
v1-0001-Fix-assertion-failures-in-DELETE-FOR-PORTION-OF-t.patchtext/x-patch; charset=US-ASCII; name=v1-0001-Fix-assertion-failures-in-DELETE-FOR-PORTION-OF-t.patchDownload+195-7
#5Peter Eisentraut
peter_e@gmx.net
In reply to: Paul A Jungwirth (#4)
Re: FOR PORTION OF assertion failure in ExecInitPartitionInfo()

On 31.08.26 19:44, Paul A Jungwirth wrote:

On Wed, Aug 19, 2026 at 10:26 PM Peter Eisentraut <peter@eisentraut.org> wrote:

The following test case triggers an assertion failure in
ExecInitPartitionInfo():

CREATE TABLE temporal_partitioned_by_range (
id int4range,
valid_at daterange,
name text
) PARTITION BY RANGE (valid_at);

CREATE TABLE temporal_partitioned_early
PARTITION OF temporal_partitioned_by_range
FOR VALUES FROM (MINVALUE) TO ('[2000-06-01,)');
CREATE TABLE temporal_partitioned_late
PARTITION OF temporal_partitioned_by_range
FOR VALUES FROM ('[2000-06-01,)') TO (MAXVALUE);

INSERT INTO temporal_partitioned_by_range (id, valid_at, name)
VALUES ('[1,2)', daterange('2000-01-01', '2010-01-01'), 'one');

DELETE FROM temporal_partitioned_by_range
FOR PORTION OF valid_at FROM '2000-03-01' TO '2000-07-01'
WHERE valid_at < '[2000-06-01,)'::daterange
RETURNING id, valid_at, name;

It appears to work correctly with assertions disabled, so maybe just
some of the Assert()s in ExecInitPartitionInfo() need some updates?

I looked into this a bit. Here is a patch.

Committed, thanks.