Convert 'x IN (VALUES ...)' to 'x = ANY ...' then appropriate
authorAlexander Korotkov <[email protected]>
Fri, 4 Apr 2025 13:01:50 +0000 (16:01 +0300)
committerAlexander Korotkov <[email protected]>
Fri, 4 Apr 2025 13:01:50 +0000 (16:01 +0300)
commitc0962a113d1f2f94cb7222a7ca025a67e9ce3860
tree6da1bad29d2394bca13b4c29c4df5ae9a4ceee67
parentd48d2e2dc8be50d3ca13305b5699384329b15433
Convert 'x IN (VALUES ...)' to 'x = ANY ...' then appropriate

This commit implements the automatic conversion of 'x IN (VALUES ...)' into
ScalarArrayOpExpr.  That simplifies the query tree, eliminating the appearance
of an unnecessary join.

Since VALUES describes a relational table, and the value of such a list is
a table row, the optimizer will likely face an underestimation problem due to
the inability to estimate cardinality through MCV statistics.  The cardinality
evaluation mechanism can work with the array inclusion check operation.
If the array is small enough (< 100 elements), it will perform a statistical
evaluation element by element.

We perform the transformation in the convert_ANY_sublink_to_join() if VALUES
RTE is proper and the transformation is convertible.  The conversion is only
possible for operations on scalar values, not rows.  Also, we currently
support the transformation only when it ends up with a constant array.
Otherwise, the evaluation of non-hashed SAOP might be slower than the
corresponding Hash Join with VALUES.

Discussion: https://postgr.es/m/0184212d-1248-4f1f-a42d-f5cb1c1976d2%40tantorlabs.com
Author: Alena Rybakina <[email protected]>
Author: Andrei Lepikhov <[email protected]>
Reviewed-by: Ivan Kush <[email protected]>
Reviewed-by: Alexander Korotkov <[email protected]>
src/backend/optimizer/plan/subselect.c
src/backend/optimizer/prep/prepjointree.c
src/backend/optimizer/util/clauses.c
src/include/optimizer/subselect.h
src/test/regress/expected/subselect.out
src/test/regress/sql/subselect.sql