Hashed IN only applied to first encountered IN

Started by David Geier10 months ago4 messages
#1David Geier
geidav.pg@gmail.com
2 attachment(s)

Hi hackers,

The hashed IN optimization is only applied to the first encountered
ScalarArrayOpExpr during the expression tree traversal in
convert_saop_to_hashed_saop_walker(). Reason being that the walker
returns true which aborts the traversal.

This can be exhibited by running a query with two IN statements vs the
same query with just a single IN statement. The IN statements are
combined via OR and both statements return no rows to prevent any kind
of lazy evaluation optimizations. The query with two IN statements is 6x
slower than the the query with the single IN statement. See the attached
example.

I've also attached a patch with a fix.

--
David Geier
(ServiceNow)

Attachments:

example.sqltext/plain; charset=UTF-8; name=example.sqlDownload
0001-Fixed-hashed-SAOP.patchtext/plain; charset=UTF-8; name=0001-Fixed-hashed-SAOP.patchDownload
From 7de592928acada597f6e4314036abd87a6af6403 Mon Sep 17 00:00:00 2001
From: David Geier <geidav.pg@gmail.com>
Date: Tue, 1 Apr 2025 13:47:27 +0200
Subject: [PATCH] Fixed hashed SAOP

---
 src/backend/optimizer/util/clauses.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/backend/optimizer/util/clauses.c b/src/backend/optimizer/util/clauses.c
index 43dfecfb47f..05d33461163 100644
--- a/src/backend/optimizer/util/clauses.c
+++ b/src/backend/optimizer/util/clauses.c
@@ -2326,7 +2326,7 @@ convert_saop_to_hashed_saop_walker(Node *node, void *context)
 						/* Looks good. Fill in the hash functions */
 						saop->hashfuncid = lefthashfunc;
 					}
-					return true;
+					return false;
 				}
 			}
 			else				/* !saop->useOr */
@@ -2364,7 +2364,7 @@ convert_saop_to_hashed_saop_walker(Node *node, void *context)
 						 */
 						saop->negfuncid = get_opcode(negator);
 					}
-					return true;
+					return false;
 				}
 			}
 		}
-- 
2.34.1

#2David Rowley
dgrowleyml@gmail.com
In reply to: David Geier (#1)
Re: Hashed IN only applied to first encountered IN

On Wed, 2 Apr 2025 at 00:51, David Geier <geidav.pg@gmail.com> wrote:

The hashed IN optimization is only applied to the first encountered
ScalarArrayOpExpr during the expression tree traversal in
convert_saop_to_hashed_saop_walker(). Reason being that the walker
returns true which aborts the traversal.

I've also attached a patch with a fix.

Thanks for the report and fix. On first inspection your patch looks
fine. I'll have a closer look tomorrow.

David

#3David Rowley
dgrowleyml@gmail.com
In reply to: David Rowley (#2)
Re: Hashed IN only applied to first encountered IN

On Wed, 2 Apr 2025 at 01:31, David Rowley <dgrowleyml@gmail.com> wrote:

On Wed, 2 Apr 2025 at 00:51, David Geier <geidav.pg@gmail.com> wrote:

The hashed IN optimization is only applied to the first encountered
ScalarArrayOpExpr during the expression tree traversal in
convert_saop_to_hashed_saop_walker(). Reason being that the walker
returns true which aborts the traversal.

I've also attached a patch with a fix.

Thanks for the report and fix. On first inspection your patch looks
fine. I'll have a closer look tomorrow.

I've now pushed and backpatched the relevant portion of this back to v14.

Thanks again.

David

#4David Geier
geidav.pg@gmail.com
In reply to: David Rowley (#3)
Re: Hashed IN only applied to first encountered IN

Great!

Thank you!

Show quoted text

On 4/2/2025 1:00 AM, David Rowley wrote:

On Wed, 2 Apr 2025 at 01:31, David Rowley <dgrowleyml@gmail.com> wrote:

On Wed, 2 Apr 2025 at 00:51, David Geier <geidav.pg@gmail.com> wrote:

The hashed IN optimization is only applied to the first encountered
ScalarArrayOpExpr during the expression tree traversal in
convert_saop_to_hashed_saop_walker(). Reason being that the walker
returns true which aborts the traversal.
I've also attached a patch with a fix.

Thanks for the report and fix. On first inspection your patch looks
fine. I'll have a closer look tomorrow.

I've now pushed and backpatched the relevant portion of this back to v14.

Thanks again.

David