| From: | Kirill Reshke <reshkekirill(at)gmail(dot)com> |
|---|---|
| To: | Tomas Vondra <tomas(at)vondra(dot)me> |
| Cc: | Ayush Tiwari <ayushtiwari(dot)slg01(at)gmail(dot)com>, PostgreSQL Hackers <pgsql-hackers(at)postgresql(dot)org> |
| Subject: | Re: reconsider_full_join_clause fails to consider if COALESCE() arguments are NULL-preserving |
| Date: | 2026-11-12 06:38:29 |
| Message-ID: | CALdSSPgug3Bgnp+1GU+qomqz6yARYHKdjxGt=xwSReX=s2ejfg@mail.gmail.com |
| Views: | Whole Thread | Raw Message | Download mbox | Resend email |
| Thread: | |
| Lists: | pgsql-hackers |
On Thu, 12 Nov 2026 at 02:48, Tomas Vondra <tomas(at)vondra(dot)me> wrote:
>
> Hi,
>
> Here's a rebased version of the patch(es). I've made no change to the
> code itself, I've tried to improve the commit message to explain why the
> expressions need to be null-preserving, handling of COALESCE clauses and
> placeholders.
Hi!
> 1) Is is_full_join_expr_null_preserving() necessary? Or is there some
existing piece of code checking the expression preserves NULLs? Possibly
with some additional smartness I haven't thought of?
I think it is. There is find_nonnullable_rels which solves similar
task, but I don't see any additional smartness in it.
There is also is_standard_join_alias_expression function but it
doesn't check for functions strictness
> 2) Is is_full_join_expr_null_preserving() correct?
I think it is.
It does lose some optimizations for safe filter pushdows, because
this doesn't recurse
+ if (IsA(node, PlaceHolderVar))
+ return ((PlaceHolderVar *) node)->phlevelsup == 0;
With v2:
CREATE TEMP TABLE a(x int);
CREATE TEMP TABLE b(x int);
EXPLAIN (COSTS OFF)
SELECT *
FROM (SELECT coalesce(x, 0) AS k FROM a) s
FULL JOIN b ON s.k + 0 = b.x
WHERE coalesce(s.k + 0, b.x) = 0;
CREATE TABLE
CREATE TABLE
QUERY PLAN
---------------------------------------------------------
Merge Full Join
Merge Cond: (((COALESCE(a.x, 0) + 0)) = b.x)
Filter: (COALESCE(((COALESCE(a.x, 0)) + 0), b.x) = 0)
-> Sort
Sort Key: ((COALESCE(a.x, 0) + 0))
-> Seq Scan on a
-> Sort
Sort Key: b.x
-> Seq Scan on b
(9 rows)
before, there is two filters
QUERY PLAN
--------------------------------------------
Merge Full Join
-> Seq Scan on a
Filter: ((COALESCE(x, 0) + 0) = 0)
-> Materialize
-> Seq Scan on b
Filter: (x = 0)
(6 rows)
Is this regression important? or can we accept this for sake of simplicity?
--
Best regards,
Kirill Reshke
| From | Date | Subject | |
|---|---|---|---|
| Next Message | vignesh C | 2026-11-12 06:39:15 | Re: Hash index: stop registering pin-only bucket pages in WAL (remove REGBUF_NO_CHANGE) |
| Previous Message | Bertrand Drouvot | 2026-11-12 06:17:56 | Re: Assertion failure in update_local_synced_slot(), slotsync.c:364 |