88 *
99 *
1010 * IDENTIFICATION
11- * $PostgreSQL: pgsql/src/backend/parser/parse_expr.c,v 1.236 2008/10/25 17:19:09 tgl Exp $
11+ * $PostgreSQL: pgsql/src/backend/parser/parse_expr.c,v 1.237 2008/10/26 02:46:25 tgl Exp $
1212 *
1313 *-------------------------------------------------------------------------
1414 */
@@ -939,11 +939,13 @@ transformAExprOf(ParseState *pstate, A_Expr *a)
939939static Node *
940940transformAExprIn (ParseState * pstate ,A_Expr * a )
941941{
942+ Node * result = NULL ;
942943Node * lexpr ;
943944List * rexprs ;
945+ List * rvars ;
946+ List * rnonvars ;
944947bool useOr ;
945948bool haveRowExpr ;
946- Node * result ;
947949ListCell * l ;
948950
949951/*
@@ -959,41 +961,33 @@ transformAExprIn(ParseState *pstate, A_Expr *a)
959961 * possible if the inputs are all scalars (no RowExprs) and there is a
960962 * suitable array type available. If not, we fall back to a boolean
961963 * condition tree with multiple copies of the lefthand expression.
964+ * Also, any IN-list items that contain Vars are handled as separate
965+ * boolean conditions, because that gives the planner more scope for
966+ * optimization on such clauses.
962967 *
963968 * First step: transform all the inputs, and detect whether any are
964- * RowExprs.
969+ * RowExprs or contain Vars .
965970 */
966971lexpr = transformExpr (pstate ,a -> lexpr );
967972haveRowExpr = (lexpr && IsA (lexpr ,RowExpr ));
968- rexprs = NIL ;
973+ rexprs = rvars = rnonvars = NIL ;
969974foreach (l , (List * )a -> rexpr )
970975{
971976Node * rexpr = transformExpr (pstate ,lfirst (l ));
972977
973978haveRowExpr |= (rexpr && IsA (rexpr ,RowExpr ));
974979rexprs = lappend (rexprs ,rexpr );
980+ if (contain_vars_of_level (rexpr ,0 ))
981+ rvars = lappend (rvars ,rexpr );
982+ else
983+ rnonvars = lappend (rnonvars ,rexpr );
975984}
976985
977986/*
978- * We prefer a boolean tree to ScalarArrayOpExpr if any of these are true:
979- *
980- * 1. We have a RowExpr anywhere.
981- *
982- * 2. There's only one righthand expression --- best to just generate a
983- * simple = comparison.
984- *
985- * 3. There's a reasonably small number of righthand expressions and
986- * they contain any Vars. This is a heuristic to support cases like
987- * WHERE '555-1212' IN (tab.home_phone, tab.work_phone), which can be
988- * optimized into an OR of indexscans on different indexes so long as
989- * it's left as an OR tree. (It'd be better to leave this decision
990- * to the planner, no doubt, but the amount of code required to reformat
991- * the expression later on seems out of proportion to the benefit.)
987+ * ScalarArrayOpExpr is only going to be useful if there's more than
988+ * one non-Var righthand item. Also, it won't work for RowExprs.
992989 */
993- if (!(haveRowExpr ||
994- list_length (rexprs )== 1 ||
995- (list_length (rexprs ) <=32 &&
996- contain_vars_of_level ((Node * )rexprs ,0 ))))
990+ if (!haveRowExpr && list_length (rnonvars )> 1 )
997991{
998992List * allexprs ;
999993Oid scalar_type ;
@@ -1004,9 +998,9 @@ transformAExprIn(ParseState *pstate, A_Expr *a)
1004998 * since the LHS' type is first in the list, it will be preferred when
1005999 * there is doubt (eg, when all the RHS items are unknown literals).
10061000 *
1007- * Note: use list_concat here not lcons, to avoid damagingrexprs .
1001+ * Note: use list_concat here not lcons, to avoid damagingrnonvars .
10081002 */
1009- allexprs = list_concat (list_make1 (lexpr ),rexprs );
1003+ allexprs = list_concat (list_make1 (lexpr ),rnonvars );
10101004scalar_type = select_common_type (pstate ,allexprs ,NULL ,NULL );
10111005
10121006/* Do we have an array type to use? */
@@ -1017,14 +1011,14 @@ transformAExprIn(ParseState *pstate, A_Expr *a)
10171011if (array_type != InvalidOid )
10181012{
10191013/*
1020- * OK: coerce all the right-hand inputs to the common type and
1021- * build an ArrayExpr for them.
1014+ * OK: coerce all the right-handnon-Var inputs to the common type
1015+ *and build an ArrayExpr for them.
10221016 */
10231017List * aexprs ;
10241018ArrayExpr * newa ;
10251019
10261020aexprs = NIL ;
1027- foreach (l ,rexprs )
1021+ foreach (l ,rnonvars )
10281022{
10291023Node * rexpr = (Node * )lfirst (l );
10301024
@@ -1040,19 +1034,21 @@ transformAExprIn(ParseState *pstate, A_Expr *a)
10401034newa -> multidims = false;
10411035newa -> location = -1 ;
10421036
1043- return (Node * )make_scalar_array_op (pstate ,
1044- a -> name ,
1045- useOr ,
1046- lexpr ,
1047- (Node * )newa ,
1048- a -> location );
1037+ result = (Node * )make_scalar_array_op (pstate ,
1038+ a -> name ,
1039+ useOr ,
1040+ lexpr ,
1041+ (Node * )newa ,
1042+ a -> location );
1043+
1044+ /* Consider only the Vars (if any) in the loop below */
1045+ rexprs = rvars ;
10491046}
10501047}
10511048
10521049/*
10531050 * Must do it the hard way, ie, with a boolean expression tree.
10541051 */
1055- result = NULL ;
10561052foreach (l ,rexprs )
10571053{
10581054Node * rexpr = (Node * )lfirst (l );