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

Commit73fc2e5

Browse files
committed
Fix pull_varnos' miscomputation of relids set for a PlaceHolderVar.
Previously, pull_varnos() took the relids of a PlaceHolderVar as beingequal to the relids in its contents, but that fails to account for thepossibility that we have to postpone evaluation of the PHV due to outerjoins. This could result in a malformed plan. The known cases end uptriggering the "failed to assign all NestLoopParams to plan nodes"sanity check in createplan.c, but other symptoms may be possible.The right value to use is the join level we actually intend to evaluatethe PHV at. We can get that from the ph_eval_at field of the associatedPlaceHolderInfo. However, there are some places that call pull_varnos()before the PlaceHolderInfos have been created; in that case, fall backto the conservative assumption that the PHV will be evaluated at itssyntactic level. (In principle this might result in missing some legaloptimization, but I'm not aware of any cases where it's an issue inpractice.) Things are also a bit ticklish for calls occurring duringdeconstruct_jointree(), but AFAICS the ph_eval_at fields should havereached their final values by the time we need them.The main problem in making this work is that pull_varnos() has noway to get at the PlaceHolderInfos. We can fix that easily, if abit tediously, in HEAD by passing it the planner "root" pointer.In the back branches that'd cause an unacceptable API/ABI break forextensions, so leave the existing entry points alone and add new oneswith the additional parameter. (If an old entry point is called andencounters a PHV, it'll fall back to using the syntactic level,again possibly missing some valid optimization.)Back-patch to v12. The computation is surely also wrong before that,but it appears that we cannot reach a bad plan thanks to join orderrestrictions imposed on the subquery that the PlaceHolderVar came from.The error only became reachable when commit4be058f allowed trivialsubqueries to be collapsed out completely, eliminating their join orderrestrictions.Per report from Stephan Springl.Discussion:https://postgr.es/m/171041.1610849523@sss.pgh.pa.us
1 parent6671e81 commit73fc2e5

File tree

25 files changed

+358
-117
lines changed

25 files changed

+358
-117
lines changed

‎contrib/postgres_fdw/postgres_fdw.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,9 @@
4545
#include"utils/sampling.h"
4646
#include"utils/selfuncs.h"
4747

48+
/* source-code-compatibility hacks for pull_varnos() API change */
49+
#definemake_restrictinfo(a,b,c,d,e,f,g,h,i) make_restrictinfo_new(a,b,c,d,e,f,g,h,i)
50+
4851
PG_MODULE_MAGIC;
4952

5053
/* Default CPU cost to start up a foreign query. */
@@ -5716,7 +5719,8 @@ foreign_grouping_ok(PlannerInfo *root, RelOptInfo *grouped_rel,
57165719
* RestrictInfos, so we must make our own.
57175720
*/
57185721
Assert(!IsA(expr,RestrictInfo));
5719-
rinfo=make_restrictinfo(expr,
5722+
rinfo=make_restrictinfo(root,
5723+
expr,
57205724
true,
57215725
false,
57225726
false,

‎src/backend/optimizer/path/clausesel.c

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@
2626
#include"utils/lsyscache.h"
2727
#include"utils/selfuncs.h"
2828

29+
/* source-code-compatibility hacks for pull_varnos() API change */
30+
#defineNumRelids(a,b) NumRelids_new(a,b)
31+
2932
/*
3033
* Data structure for accumulating info about possible range-query
3134
* clause pairs in clauselist_selectivity.
@@ -235,7 +238,7 @@ clauselist_selectivity_simple(PlannerInfo *root,
235238
}
236239
else
237240
{
238-
ok= (NumRelids(clause)==1)&&
241+
ok= (NumRelids(root,clause)==1)&&
239242
(is_pseudo_constant_clause(lsecond(expr->args))||
240243
(varonleft= false,
241244
is_pseudo_constant_clause(linitial(expr->args))));
@@ -519,7 +522,7 @@ bms_is_subset_singleton(const Bitmapset *s, int x)
519522
* restriction or join estimator. Subroutine for clause_selectivity().
520523
*/
521524
staticinlinebool
522-
treat_as_join_clause(Node*clause,RestrictInfo*rinfo,
525+
treat_as_join_clause(PlannerInfo*root,Node*clause,RestrictInfo*rinfo,
523526
intvarRelid,SpecialJoinInfo*sjinfo)
524527
{
525528
if (varRelid!=0)
@@ -553,7 +556,7 @@ treat_as_join_clause(Node *clause, RestrictInfo *rinfo,
553556
if (rinfo)
554557
return (bms_membership(rinfo->clause_relids)==BMS_MULTIPLE);
555558
else
556-
return (NumRelids(clause)>1);
559+
return (NumRelids(root,clause)>1);
557560
}
558561
}
559562

@@ -759,7 +762,7 @@ clause_selectivity(PlannerInfo *root,
759762
OpExpr*opclause= (OpExpr*)clause;
760763
Oidopno=opclause->opno;
761764

762-
if (treat_as_join_clause(clause,rinfo,varRelid,sjinfo))
765+
if (treat_as_join_clause(root,clause,rinfo,varRelid,sjinfo))
763766
{
764767
/* Estimate selectivity for a join clause. */
765768
s1=join_selectivity(root,opno,
@@ -795,7 +798,7 @@ clause_selectivity(PlannerInfo *root,
795798
funcclause->funcid,
796799
funcclause->args,
797800
funcclause->inputcollid,
798-
treat_as_join_clause(clause,rinfo,
801+
treat_as_join_clause(root,clause,rinfo,
799802
varRelid,sjinfo),
800803
varRelid,
801804
jointype,
@@ -806,7 +809,7 @@ clause_selectivity(PlannerInfo *root,
806809
/* Use node specific selectivity calculation function */
807810
s1=scalararraysel(root,
808811
(ScalarArrayOpExpr*)clause,
809-
treat_as_join_clause(clause,rinfo,
812+
treat_as_join_clause(root,clause,rinfo,
810813
varRelid,sjinfo),
811814
varRelid,
812815
jointype,

‎src/backend/optimizer/path/costsize.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,9 @@
9898
#include"utils/tuplesort.h"
9999

100100

101+
/* source-code-compatibility hacks for pull_varnos() API change */
102+
#definepull_varnos(a,b) pull_varnos_new(a,b)
103+
101104
#defineLOG2(x) (log(x) / 0.693147180559945)
102105

103106
/*
@@ -1848,7 +1851,7 @@ cost_incremental_sort(Path *path,
18481851
* Check if the expression contains Var with "varno 0" so that we
18491852
* don't call estimate_num_groups in that case.
18501853
*/
1851-
if (bms_is_member(0,pull_varnos((Node*)member->em_expr)))
1854+
if (bms_is_member(0,pull_varnos(root,(Node*)member->em_expr)))
18521855
{
18531856
unknown_varno= true;
18541857
break;

‎src/backend/optimizer/path/equivclass.c

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@
3232
#include"utils/lsyscache.h"
3333

3434

35+
/* source-code-compatibility hacks for pull_varnos() API change */
36+
#definepull_varnos(a,b) pull_varnos_new(a,b)
37+
#definemake_restrictinfo(a,b,c,d,e,f,g,h,i) make_restrictinfo_new(a,b,c,d,e,f,g,h,i)
38+
3539
staticEquivalenceMember*add_eq_member(EquivalenceClass*ec,
3640
Expr*expr,Relidsrelids,Relidsnullable_relids,
3741
boolis_child,Oiddatatype);
@@ -195,7 +199,8 @@ process_equivalence(PlannerInfo *root,
195199
ntest->location=-1;
196200

197201
*p_restrictinfo=
198-
make_restrictinfo((Expr*)ntest,
202+
make_restrictinfo(root,
203+
(Expr*)ntest,
199204
restrictinfo->is_pushed_down,
200205
restrictinfo->outerjoin_delayed,
201206
restrictinfo->pseudoconstant,
@@ -713,7 +718,7 @@ get_eclass_for_sort_expr(PlannerInfo *root,
713718
/*
714719
* Get the precise set of nullable relids appearing in the expression.
715720
*/
716-
expr_relids=pull_varnos((Node*)expr);
721+
expr_relids=pull_varnos(root,(Node*)expr);
717722
nullable_relids=bms_intersect(nullable_relids,expr_relids);
718723

719724
newem=add_eq_member(newec,copyObject(expr),expr_relids,
@@ -1661,7 +1666,8 @@ create_join_clause(PlannerInfo *root,
16611666
*/
16621667
oldcontext=MemoryContextSwitchTo(root->planner_cxt);
16631668

1664-
rinfo=build_implied_join_equality(opno,
1669+
rinfo=build_implied_join_equality(root,
1670+
opno,
16651671
ec->ec_collation,
16661672
leftem->em_expr,
16671673
rightem->em_expr,
@@ -1961,7 +1967,8 @@ reconsider_outer_join_clause(PlannerInfo *root, RestrictInfo *rinfo,
19611967
cur_em->em_datatype);
19621968
if (!OidIsValid(eq_op))
19631969
continue;/* can't generate equality */
1964-
newrinfo=build_implied_join_equality(eq_op,
1970+
newrinfo=build_implied_join_equality(root,
1971+
eq_op,
19651972
cur_ec->ec_collation,
19661973
innervar,
19671974
cur_em->em_expr,
@@ -2104,7 +2111,8 @@ reconsider_full_join_clause(PlannerInfo *root, RestrictInfo *rinfo)
21042111
cur_em->em_datatype);
21052112
if (OidIsValid(eq_op))
21062113
{
2107-
newrinfo=build_implied_join_equality(eq_op,
2114+
newrinfo=build_implied_join_equality(root,
2115+
eq_op,
21082116
cur_ec->ec_collation,
21092117
leftvar,
21102118
cur_em->em_expr,
@@ -2119,7 +2127,8 @@ reconsider_full_join_clause(PlannerInfo *root, RestrictInfo *rinfo)
21192127
cur_em->em_datatype);
21202128
if (OidIsValid(eq_op))
21212129
{
2122-
newrinfo=build_implied_join_equality(eq_op,
2130+
newrinfo=build_implied_join_equality(root,
2131+
eq_op,
21232132
cur_ec->ec_collation,
21242133
rightvar,
21252134
cur_em->em_expr,

‎src/backend/optimizer/path/indxpath.c

Lines changed: 48 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,12 @@
3636
#include"utils/selfuncs.h"
3737

3838

39+
/* source-code-compatibility hacks for pull_varnos() API change */
40+
#definepull_varnos(a,b) pull_varnos_new(a,b)
41+
#undef make_simple_restrictinfo
42+
#definemake_simple_restrictinfo(root,clause) \
43+
make_restrictinfo_new(root, clause, true, false, false, 0, NULL, NULL, NULL)
44+
3945
/* XXX see PartCollMatchesExprColl */
4046
#defineIndexCollMatchesExprColl(idxcollation,exprcollation) \
4147
((idxcollation) == InvalidOid || (idxcollation) == (exprcollation))
@@ -153,7 +159,8 @@ static IndexClause *match_clause_to_indexcol(PlannerInfo *root,
153159
RestrictInfo*rinfo,
154160
intindexcol,
155161
IndexOptInfo*index);
156-
staticIndexClause*match_boolean_index_clause(RestrictInfo*rinfo,
162+
staticIndexClause*match_boolean_index_clause(PlannerInfo*root,
163+
RestrictInfo*rinfo,
157164
intindexcol,IndexOptInfo*index);
158165
staticIndexClause*match_opclause_to_indexcol(PlannerInfo*root,
159166
RestrictInfo*rinfo,
@@ -169,13 +176,16 @@ static IndexClause *get_index_clause_from_support(PlannerInfo *root,
169176
intindexarg,
170177
intindexcol,
171178
IndexOptInfo*index);
172-
staticIndexClause*match_saopclause_to_indexcol(RestrictInfo*rinfo,
179+
staticIndexClause*match_saopclause_to_indexcol(PlannerInfo*root,
180+
RestrictInfo*rinfo,
173181
intindexcol,
174182
IndexOptInfo*index);
175-
staticIndexClause*match_rowcompare_to_indexcol(RestrictInfo*rinfo,
183+
staticIndexClause*match_rowcompare_to_indexcol(PlannerInfo*root,
184+
RestrictInfo*rinfo,
176185
intindexcol,
177186
IndexOptInfo*index);
178-
staticIndexClause*expand_indexqual_rowcompare(RestrictInfo*rinfo,
187+
staticIndexClause*expand_indexqual_rowcompare(PlannerInfo*root,
188+
RestrictInfo*rinfo,
179189
intindexcol,
180190
IndexOptInfo*index,
181191
Oidexpr_op,
@@ -2305,7 +2315,7 @@ match_clause_to_indexcol(PlannerInfo *root,
23052315
opfamily=index->opfamily[indexcol];
23062316
if (IsBooleanOpfamily(opfamily))
23072317
{
2308-
iclause=match_boolean_index_clause(rinfo,indexcol,index);
2318+
iclause=match_boolean_index_clause(root,rinfo,indexcol,index);
23092319
if (iclause)
23102320
returniclause;
23112321
}
@@ -2325,11 +2335,11 @@ match_clause_to_indexcol(PlannerInfo *root,
23252335
}
23262336
elseif (IsA(clause,ScalarArrayOpExpr))
23272337
{
2328-
returnmatch_saopclause_to_indexcol(rinfo,indexcol,index);
2338+
returnmatch_saopclause_to_indexcol(root,rinfo,indexcol,index);
23292339
}
23302340
elseif (IsA(clause,RowCompareExpr))
23312341
{
2332-
returnmatch_rowcompare_to_indexcol(rinfo,indexcol,index);
2342+
returnmatch_rowcompare_to_indexcol(root,rinfo,indexcol,index);
23332343
}
23342344
elseif (index->amsearchnulls&&IsA(clause,NullTest))
23352345
{
@@ -2368,7 +2378,8 @@ match_clause_to_indexcol(PlannerInfo *root,
23682378
* index's key, and if so, build a suitable IndexClause.
23692379
*/
23702380
staticIndexClause*
2371-
match_boolean_index_clause(RestrictInfo*rinfo,
2381+
match_boolean_index_clause(PlannerInfo*root,
2382+
RestrictInfo*rinfo,
23722383
intindexcol,
23732384
IndexOptInfo*index)
23742385
{
@@ -2438,7 +2449,7 @@ match_boolean_index_clause(RestrictInfo *rinfo,
24382449
IndexClause*iclause=makeNode(IndexClause);
24392450

24402451
iclause->rinfo=rinfo;
2441-
iclause->indexquals=list_make1(make_simple_restrictinfo(op));
2452+
iclause->indexquals=list_make1(make_simple_restrictinfo(root,op));
24422453
iclause->lossy= false;
24432454
iclause->indexcol=indexcol;
24442455
iclause->indexcols=NIL;
@@ -2663,7 +2674,8 @@ get_index_clause_from_support(PlannerInfo *root,
26632674
{
26642675
Expr*clause= (Expr*)lfirst(lc);
26652676

2666-
indexquals=lappend(indexquals,make_simple_restrictinfo(clause));
2677+
indexquals=lappend(indexquals,
2678+
make_simple_restrictinfo(root,clause));
26672679
}
26682680

26692681
iclause->rinfo=rinfo;
@@ -2684,7 +2696,8 @@ get_index_clause_from_support(PlannerInfo *root,
26842696
* which see for comments.
26852697
*/
26862698
staticIndexClause*
2687-
match_saopclause_to_indexcol(RestrictInfo*rinfo,
2699+
match_saopclause_to_indexcol(PlannerInfo*root,
2700+
RestrictInfo*rinfo,
26882701
intindexcol,
26892702
IndexOptInfo*index)
26902703
{
@@ -2703,7 +2716,7 @@ match_saopclause_to_indexcol(RestrictInfo *rinfo,
27032716
returnNULL;
27042717
leftop= (Node*)linitial(saop->args);
27052718
rightop= (Node*)lsecond(saop->args);
2706-
right_relids=pull_varnos(rightop);
2719+
right_relids=pull_varnos(root,rightop);
27072720
expr_op=saop->opno;
27082721
expr_coll=saop->inputcollid;
27092722

@@ -2751,7 +2764,8 @@ match_saopclause_to_indexcol(RestrictInfo *rinfo,
27512764
* is handled by expand_indexqual_rowcompare().
27522765
*/
27532766
staticIndexClause*
2754-
match_rowcompare_to_indexcol(RestrictInfo*rinfo,
2767+
match_rowcompare_to_indexcol(PlannerInfo*root,
2768+
RestrictInfo*rinfo,
27552769
intindexcol,
27562770
IndexOptInfo*index)
27572771
{
@@ -2796,14 +2810,14 @@ match_rowcompare_to_indexcol(RestrictInfo *rinfo,
27962810
* These syntactic tests are the same as in match_opclause_to_indexcol()
27972811
*/
27982812
if (match_index_to_operand(leftop,indexcol,index)&&
2799-
!bms_is_member(index_relid,pull_varnos(rightop))&&
2813+
!bms_is_member(index_relid,pull_varnos(root,rightop))&&
28002814
!contain_volatile_functions(rightop))
28012815
{
28022816
/* OK, indexkey is on left */
28032817
var_on_left= true;
28042818
}
28052819
elseif (match_index_to_operand(rightop,indexcol,index)&&
2806-
!bms_is_member(index_relid,pull_varnos(leftop))&&
2820+
!bms_is_member(index_relid,pull_varnos(root,leftop))&&
28072821
!contain_volatile_functions(leftop))
28082822
{
28092823
/* indexkey is on right, so commute the operator */
@@ -2822,7 +2836,8 @@ match_rowcompare_to_indexcol(RestrictInfo *rinfo,
28222836
caseBTLessEqualStrategyNumber:
28232837
caseBTGreaterEqualStrategyNumber:
28242838
caseBTGreaterStrategyNumber:
2825-
returnexpand_indexqual_rowcompare(rinfo,
2839+
returnexpand_indexqual_rowcompare(root,
2840+
rinfo,
28262841
indexcol,
28272842
index,
28282843
expr_op,
@@ -2856,7 +2871,8 @@ match_rowcompare_to_indexcol(RestrictInfo *rinfo,
28562871
* but we split it out for comprehensibility.
28572872
*/
28582873
staticIndexClause*
2859-
expand_indexqual_rowcompare(RestrictInfo*rinfo,
2874+
expand_indexqual_rowcompare(PlannerInfo*root,
2875+
RestrictInfo*rinfo,
28602876
intindexcol,
28612877
IndexOptInfo*index,
28622878
Oidexpr_op,
@@ -2926,7 +2942,7 @@ expand_indexqual_rowcompare(RestrictInfo *rinfo,
29262942
if (expr_op==InvalidOid)
29272943
break;/* operator is not usable */
29282944
}
2929-
if (bms_is_member(index->rel->relid,pull_varnos(constop)))
2945+
if (bms_is_member(index->rel->relid,pull_varnos(root,constop)))
29302946
break;/* no good, Var on wrong side */
29312947
if (contain_volatile_functions(constop))
29322948
break;/* no good, volatile comparison value */
@@ -3036,7 +3052,8 @@ expand_indexqual_rowcompare(RestrictInfo *rinfo,
30363052
matching_cols);
30373053
rc->rargs=list_truncate(copyObject(non_var_args),
30383054
matching_cols);
3039-
iclause->indexquals=list_make1(make_simple_restrictinfo((Expr*)rc));
3055+
iclause->indexquals=list_make1(make_simple_restrictinfo(root,
3056+
(Expr*)rc));
30403057
}
30413058
else
30423059
{
@@ -3050,7 +3067,7 @@ expand_indexqual_rowcompare(RestrictInfo *rinfo,
30503067
copyObject(linitial(non_var_args)),
30513068
InvalidOid,
30523069
linitial_oid(clause->inputcollids));
3053-
iclause->indexquals=list_make1(make_simple_restrictinfo(op));
3070+
iclause->indexquals=list_make1(make_simple_restrictinfo(root,op));
30543071
}
30553072
}
30563073

@@ -3667,7 +3684,9 @@ relation_has_unique_index_for(PlannerInfo *root, RelOptInfo *rel,
36673684
* specified index column matches a boolean restriction clause.
36683685
*/
36693686
bool
3670-
indexcol_is_bool_constant_for_query(IndexOptInfo*index,intindexcol)
3687+
indexcol_is_bool_constant_for_query(PlannerInfo*root,
3688+
IndexOptInfo*index,
3689+
intindexcol)
36713690
{
36723691
ListCell*lc;
36733692

@@ -3689,7 +3708,7 @@ indexcol_is_bool_constant_for_query(IndexOptInfo *index, int indexcol)
36893708
continue;
36903709

36913710
/* See if we can match the clause's expression to the index column */
3692-
if (match_boolean_index_clause(rinfo,indexcol,index))
3711+
if (match_boolean_index_clause(root,rinfo,indexcol,index))
36933712
return true;
36943713
}
36953714

@@ -3802,9 +3821,15 @@ match_index_to_operand(Node *operand,
38023821
*/
38033822
bool
38043823
is_pseudo_constant_for_index(Node*expr,IndexOptInfo*index)
3824+
{
3825+
returnis_pseudo_constant_for_index_new(NULL,expr,index);
3826+
}
3827+
3828+
bool
3829+
is_pseudo_constant_for_index_new(PlannerInfo*root,Node*expr,IndexOptInfo*index)
38053830
{
38063831
/* pull_varnos is cheaper than volatility check, so do that first */
3807-
if (bms_is_member(index->rel->relid,pull_varnos(expr)))
3832+
if (bms_is_member(index->rel->relid,pull_varnos(root,expr)))
38083833
return false;/* no good, contains Var of table */
38093834
if (contain_volatile_functions(expr))
38103835
return false;/* no good, volatile comparison value */

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp