| Lists: | pgsql-hackers |
|---|
| From: | Andrei Lepikhov <lepihov(at)gmail(dot)com> |
|---|---|
| To: | pgsql-hackers <pgsql-hackers(at)postgresql(dot)org> |
| Subject: | Prune partitions by ScalarArrayOpExpr with an array parameter (partkey = ANY($1)) |
| Date: | 2025-03-17 13:28:02 |
| Message-ID: | b8cdd20f-b34b-42b9-8c7c-dae864b7b3b2@gmail.com |
| Views: | Whole Thread | Raw Message | Download mbox | Resend email |
| Lists: | pgsql-hackers |
Hi,
As I see, initial pruning doesn't work in the case when a
ScalarArrayOpExpr contains a parameter as the RHS of the expression,
like following:
partkey = ANY($1)
As colleagues say, it is quite typical to use stored procedures, pass an
array of IDs as a parameter, and use it in a SELECT clause.
So, here I propose a patch that extends pruning machinery. It is nothing
innovative or complicated, but I'm not sure it is fully operational so
far: it may need some discussion, review and polishing.
I intended to add it to the next commitfest if this feature makes sense.
--
regards, Andrei Lepikhov
| Attachment | Content-Type | Size |
|---|---|---|
| 0001-Enhance-partition-pruning-for-an-array-parameter.patch | text/x-patch | 13.8 KB |
| From: | Pavel Stehule <pavel(dot)stehule(at)gmail(dot)com> |
|---|---|
| To: | Andrei Lepikhov <lepihov(at)gmail(dot)com> |
| Cc: | pgsql-hackers <pgsql-hackers(at)postgresql(dot)org> |
| Subject: | Re: Prune partitions by ScalarArrayOpExpr with an array parameter (partkey = ANY($1)) |
| Date: | 2025-03-17 17:01:22 |
| Message-ID: | CAFj8pRCUy6nipGfEBYrhAoOQbCJZtwCiWuvmL_u=Vh3qTxEgsg@mail.gmail.com |
| Views: | Whole Thread | Raw Message | Download mbox | Resend email |
| Lists: | pgsql-hackers |
po 17. 3. 2025 v 14:28 odesílatel Andrei Lepikhov <lepihov(at)gmail(dot)com>
napsal:
> Hi,
>
> As I see, initial pruning doesn't work in the case when a
> ScalarArrayOpExpr contains a parameter as the RHS of the expression,
> like following:
>
> partkey = ANY($1)
>
> As colleagues say, it is quite typical to use stored procedures, pass an
> array of IDs as a parameter, and use it in a SELECT clause.
>
> So, here I propose a patch that extends pruning machinery. It is nothing
> innovative or complicated, but I'm not sure it is fully operational so
> far: it may need some discussion, review and polishing.
>
> I intended to add it to the next commitfest if this feature makes sense.
>
+1
Pavel
> --
> regards, Andrei Lepikhov
>
| From: | Andrei Lepikhov <lepihov(at)gmail(dot)com> |
|---|---|
| To: | pgsql-hackers <pgsql-hackers(at)postgresql(dot)org> |
| Subject: | Re: Prune partitions by ScalarArrayOpExpr with an array parameter (partkey = ANY($1)) |
| Date: | 2025-03-31 07:01:28 |
| Message-ID: | 81c08183-88c6-40e9-81d3-3691a51a9325@gmail.com |
| Views: | Whole Thread | Raw Message | Download mbox | Resend email |
| Lists: | pgsql-hackers |
On 3/17/25 14:28, Andrei Lepikhov wrote:
> Hi,
>
> As I see, initial pruning doesn't work in the case when a
> ScalarArrayOpExpr contains a parameter as the RHS of the expression,
> like following:
>
> partkey = ANY($1)
>
> As colleagues say, it is quite typical to use stored procedures, pass an
> array of IDs as a parameter, and use it in a SELECT clause.
>
> So, here I propose a patch that extends pruning machinery. It is nothing
> innovative or complicated, but I'm not sure it is fully operational so
> far: it may need some discussion, review and polishing.
>
> I intended to add it to the next commitfest if this feature makes sense.
For the record, here I want to resolve a bit more general issue, than
just pruning on a "key op ANY($1)" expression. For example, a hashed
InitPlan also may be used for this purpose:
CREATE TABLE part (a int)
PARTITION BY RANGE (a);
CREATE TABLE part1 PARTITION OF part FOR VALUES FROM (0) to (101);
CREATE TABLE part2 PARTITION OF part FOR VALUES FROM (101) to (200);
INSERT INTO part (a) SELECT value%200 FROM generate_series(1,1000) AS value;
CREATE TABLE other (x int, y int);
INSERT INTO other (x,y) VALUES (1,1);
EXPLAIN (VERBOSE, ANALYZE, COSTS OFF, TIMING OFF, BUFFERS OFF)
SELECT * FROM part
WHERE a = ANY((SELECT array_agg(x) AS x
FROM other
WHERE y between 0 and 100)::integer[]);
I think subqueries is quite a common pattern and pruning in this case
makes sense.
--
regards, Andrei Lepikhov