From: | Zahir Lalani <ZahirLalani(at)oliver(dot)agency> |
---|---|
To: | Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us> |
Cc: | Ron Johnson <ronljohnsonjr(at)gmail(dot)com>, pgsql-generallists(dot)postgresql(dot)org <pgsql-general(at)lists(dot)postgresql(dot)org> |
Subject: | RE: Odd Shortcut behaviour in PG14 |
Date: | 2023-11-25 11:41:38 |
Message-ID: | DB9P251MB05462136EB2B92C4A628BC60A7BFA@DB9P251MB0546.EURP251.PROD.OUTLOOK.COM |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Thread: | |
Lists: | pgsql-general |
> -----Original Message-----
> From: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
> Sent: Friday, November 24, 2023 6:44 PM
> To: Zahir Lalani <ZahirLalani(at)oliver(dot)agency>
> Cc: Ron Johnson <ronljohnsonjr(at)gmail(dot)com>; pgsql-
> generallists.postgresql.org <pgsql-general(at)lists(dot)postgresql(dot)org>
> Subject: Re: Odd Shortcut behaviour in PG14
>
> OK, so if this is a plpgsql function and ekey is a function variable, the planner
> will definitely perceive this as a query parameterized by the value of "ekey".
> We will consider a "custom" plan where the value is directly substituted into
> the query (allowing plan-time folding based on whether ekey is zero or not),
> but we will also consider a "generic" plan where the value of ekey is not known
> at plan time so no such folding occurs, and that's probably where your failure
> is happening. Replanning for every query execution is expensive so there's a
> preference for using generic plans if we can.
>
> I don't really understand why you wrote
>
> > SELECT
> > CASE WHEN (ekey > 0) THEN convert_from(crypto_secretbox_open,
> 'utf8')::JSON ELSE NULL END AS edata
> > FROM crypto_secretbox_open(
> > sc.data,
> > sc.nonce,
> > boxkey)
>
> rather than just
>
> SELECT
> CASE WHEN (ekey > 0) THEN convert_from(
> crypto_secretbox_open(sc.data,
> sc.nonce,
> boxkey),
> 'utf8')::JSON ELSE NULL END AS edata
>
> I see no reason why you should feel entitled to assume that
> crypto_secretbox_open won't get called in the first formulation.
> The normal understanding of such a SELECT is that we evaluate FROM and
> then apply the SELECT expressions to its result, so the existence of a CASE in
> the SELECT expression doesn't cause the function call in FROM to get
> bypassed.
>
> Likewise, the fact that the JOIN ON condition is false seems like a poor reason
> to assume that the join's input relation won't get evaluated.
>
> Another approach could be to force matters in the plpgsql logic:
>
> IF ekey > 0 THEN
> RETURN QUERY query-with-decryption;
> ELSE
> RETURN QUERY query-without-decryption;
> END IF;
>
> which seems a good deal safer than relying on undocumented details of
> planner optimization behavior.
>
> I also wonder why you don't make crypto_secretbox_open a bit more robust -
> -- at the very least mark it strict (RETURNS NULL ON NULL INPUT).
>
> regards, tom lane
Thank you for the detailed explanation Tom - much appreciated.
So our assumption was made as it worked for so long - ok - so we have learnt not to do that again....
> IF ekey > 0 THEN
> RETURN QUERY query-with-decryption;
> ELSE
> RETURN QUERY query-without-decryption;
> END IF;
This is indeed what we have done - we were trying to keep code maintenance down as the above requires updates in two places rather than 1 - but better that than a broken system!
> I also wonder why you don't make crypto_secretbox_open a bit more robust -
> -- at the very least mark it strict (RETURNS NULL ON NULL INPUT).
This is a third party plugin (pgsodium).
Thank you to this group for your expertise!
Z
From | Date | Subject | |
---|---|---|---|
Next Message | Andreas Joseph Krogh | 2023-11-25 13:26:56 | How to eliminate extra "NOT EXISTS"-query here? |
Previous Message | Peter J. Holzer | 2023-11-25 09:49:42 | Re: Can user specification of a column value be required when querying a view ? |