Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit0aed62f

Browse files
committed
Better solution to the IN-list issue: instead of having an arbitrary cutoff,
treat Var and non-Var IN-list items differently. Only non-Var items arecandidates to go into an ANY(ARRAY) construct --- we put all Vars as separateOR conditions on the grounds that that leaves more scope for optimization.Per suggestion from Robert Haas.
1 parentaa0fb53 commit0aed62f

File tree

1 file changed

+30
-34
lines changed

1 file changed

+30
-34
lines changed

‎src/backend/parser/parse_expr.c

Lines changed: 30 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
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)
939939
staticNode*
940940
transformAExprIn(ParseState*pstate,A_Expr*a)
941941
{
942+
Node*result=NULL;
942943
Node*lexpr;
943944
List*rexprs;
945+
List*rvars;
946+
List*rnonvars;
944947
booluseOr;
945948
boolhaveRowExpr;
946-
Node*result;
947949
ListCell*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
*/
966971
lexpr=transformExpr(pstate,a->lexpr);
967972
haveRowExpr= (lexpr&&IsA(lexpr,RowExpr));
968-
rexprs=NIL;
973+
rexprs=rvars=rnonvars=NIL;
969974
foreach(l, (List*)a->rexpr)
970975
{
971976
Node*rexpr=transformExpr(pstate,lfirst(l));
972977

973978
haveRowExpr |= (rexpr&&IsA(rexpr,RowExpr));
974979
rexprs=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
{
998992
List*allexprs;
999993
Oidscalar_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);
10101004
scalar_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)
10171011
if (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-Varinputs to the common type
1015+
*andbuild an ArrayExpr for them.
10221016
*/
10231017
List*aexprs;
10241018
ArrayExpr*newa;
10251019

10261020
aexprs=NIL;
1027-
foreach(l,rexprs)
1021+
foreach(l,rnonvars)
10281022
{
10291023
Node*rexpr= (Node*)lfirst(l);
10301024

@@ -1040,19 +1034,21 @@ transformAExprIn(ParseState *pstate, A_Expr *a)
10401034
newa->multidims= false;
10411035
newa->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;
10561052
foreach(l,rexprs)
10571053
{
10581054
Node*rexpr= (Node*)lfirst(l);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp