1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-09 22:41:56 +03:00

Add a heuristic to transformAExprIn() to make it prefer expanding "x IN (list)"

into an OR of equality comparisons, rather than x = ANY(ARRAY[...]), when there
are Vars in the right-hand side.  This avoids a performance regression compared
to pre-8.2 releases, in cases where the OR form can be optimized into scans
of multiple indexes.  Limit the possible downside by preferring this form only
when the list isn't very long (I set the cutoff at 32 elements, which is a
bit arbitrary but in the right ballpark).  Per discussion with Jim Nasby.

In passing, also make it try the OR form if it cannot select a common type
for the array elements; we've seen a complaint or two about how the OR form
worked for such cases and ARRAY doesn't.
This commit is contained in:
Tom Lane
2008-10-25 17:19:09 +00:00
parent 312b1a983f
commit ddbe8dca08
2 changed files with 35 additions and 15 deletions

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/parser/parse_coerce.c,v 2.169 2008/10/13 16:25:19 tgl Exp $
* $PostgreSQL: pgsql/src/backend/parser/parse_coerce.c,v 2.170 2008/10/25 17:19:09 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -1085,13 +1085,14 @@ parser_coercion_errposition(ParseState *pstate,
/*
* select_common_type()
* Determine the common supertype of a list of input expressions.
* This is used for determining the output type of CASE and UNION
* constructs.
* This is used for determining the output type of CASE, UNION,
* and similar constructs.
*
* 'exprs' is a *nonempty* list of expressions. Note that earlier items
* in the list will be preferred if there is doubt.
* 'context' is a phrase to use in the error message if we fail to select
* a usable type.
* a usable type. Pass NULL to have the routine return InvalidOid
* rather than throwing an error on failure.
* 'which_expr': if not NULL, receives a pointer to the particular input
* expression from which the result type was taken.
*/
@ -1166,6 +1167,8 @@ select_common_type(ParseState *pstate, List *exprs, const char *context,
/*
* both types in different categories? then not much hope...
*/
if (context == NULL)
return InvalidOid;
ereport(ERROR,
(errcode(ERRCODE_DATATYPE_MISMATCH),
/*------