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

Commit944d53f

Browse files
tglsfdcpull[bot]
authored andcommitted
Fix "wrong varnullingrels" for Memoize's lateral references, too.
The issue fixed in commitbfd332b can also bite Memoize plans,because of the separate copies of lateral reference Vars madeby paraminfo_get_equal_hashops. Apply the same hacky fix there.(In passing, clean up shaky grammar in the existing commentsfor this function.)Richard GuoDiscussion:https://postgr.es/m/CAMbWs4-krwk0Wbd6WdufMAupuou_Ua73ijQ4XQCr1Mb5BaVtKQ@mail.gmail.com
1 parent56216ee commit944d53f

File tree

4 files changed

+81
-12
lines changed

4 files changed

+81
-12
lines changed

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

Lines changed: 48 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -421,12 +421,33 @@ have_unsafe_outer_join_ref(PlannerInfo *root,
421421

422422
/*
423423
* paraminfo_get_equal_hashops
424-
*Determine if param_info and innerrel's lateral_vars can be hashed.
425-
*Returns true the hashing is possible, otherwise return false.
424+
*Determine if the clauses in param_info and innerrel's lateral_vars
425+
*can be hashed.
426+
*Returns true if hashing is possible, otherwise false.
426427
*
427-
* Additionally we also collect the outer exprs and the hash operators for
428-
* each parameter to innerrel. These set in 'param_exprs', 'operators' and
429-
* 'binary_mode' when we return true.
428+
* Additionally, on success we collect the outer expressions and the
429+
* appropriate equality operators for each hashable parameter to innerrel.
430+
* These are returned in parallel lists in *param_exprs and *operators.
431+
* We also set *binary_mode to indicate whether strict binary matching is
432+
* required.
433+
*
434+
* A complication is that innerrel's lateral_vars may contain nullingrel
435+
* markers that need adjustment. This occurs if we have applied outer join
436+
* identity 3,
437+
*(A leftjoin B on (Pab)) leftjoin C on (Pb*c)
438+
*= A leftjoin (B leftjoin C on (Pbc)) on (Pab)
439+
* and C contains lateral references to B. It's still safe to apply the
440+
* identity, but the parser will have created those references in the form
441+
* "b*" (i.e., with varnullingrels listing the A/B join), while what we will
442+
* have available from the nestloop's outer side is just "b". We deal with
443+
* that here by stripping the nullingrels down to what is available from the
444+
* outer side according to outerrel->relids.
445+
* That fixes matters for the case of forward application of identity 3.
446+
* If the identity was applied in the reverse direction, we will have
447+
* innerrel's lateral_vars containing too few nullingrel bits rather than
448+
* too many. Currently, that causes no problems because setrefs.c applies
449+
* only a subset check to nullingrels in NestLoopParams, but we'd have to
450+
* work harder if we ever want to tighten that check.
430451
*/
431452
staticbool
432453
paraminfo_get_equal_hashops(PlannerInfo*root,ParamPathInfo*param_info,
@@ -441,6 +462,7 @@ paraminfo_get_equal_hashops(PlannerInfo *root, ParamPathInfo *param_info,
441462
*operators=NIL;
442463
*binary_mode= false;
443464

465+
/* Add join clauses from param_info to the hash key */
444466
if (param_info!=NULL)
445467
{
446468
List*clauses=param_info->ppi_clauses;
@@ -510,7 +532,7 @@ paraminfo_get_equal_hashops(PlannerInfo *root, ParamPathInfo *param_info,
510532
Node*expr= (Node*)lfirst(lc);
511533
TypeCacheEntry*typentry;
512534

513-
/* Reject if there are any volatile functions */
535+
/* Reject if there are any volatile functionsin PHVs*/
514536
if (contain_volatile_functions(expr))
515537
{
516538
list_free(*operators);
@@ -521,14 +543,33 @@ paraminfo_get_equal_hashops(PlannerInfo *root, ParamPathInfo *param_info,
521543
typentry=lookup_type_cache(exprType(expr),
522544
TYPECACHE_HASH_PROC |TYPECACHE_EQ_OPR);
523545

524-
/* can't useamemoizenodewithout a valid hash equals operator */
546+
/* can't use memoize without a valid hash proc and equals operator */
525547
if (!OidIsValid(typentry->hash_proc)|| !OidIsValid(typentry->eq_opr))
526548
{
527549
list_free(*operators);
528550
list_free(*param_exprs);
529551
return false;
530552
}
531553

554+
/* OK, but adjust its nullingrels before adding it to result */
555+
expr=copyObject(expr);
556+
if (IsA(expr,Var))
557+
{
558+
Var*var= (Var*)expr;
559+
560+
var->varnullingrels=bms_intersect(var->varnullingrels,
561+
outerrel->relids);
562+
}
563+
elseif (IsA(expr,PlaceHolderVar))
564+
{
565+
PlaceHolderVar*phv= (PlaceHolderVar*)expr;
566+
567+
phv->phnullingrels=bms_intersect(phv->phnullingrels,
568+
outerrel->relids);
569+
}
570+
else
571+
Assert(false);
572+
532573
*operators=lappend_oid(*operators,typentry->eq_opr);
533574
*param_exprs=lappend(*param_exprs,expr);
534575

‎src/backend/optimizer/plan/setrefs.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2289,11 +2289,11 @@ set_join_references(PlannerInfo *root, Join *join, int rtoffset)
22892289
* the outer-join level at which they are used, Vars seen in the
22902290
* NestLoopParam expression may have nullingrels that are just a
22912291
* subset of those in the Vars actually available from the outer
2292-
* side.Another case thatcancause that to happen is explained
2293-
* in the comments for process_subquery_nestloop_params. Not
2294-
*checking this exactly is a bit grotty, but the work needed to
2295-
*make things match up perfectly seems well out of proportion to
2296-
* the value.
2292+
* side.Lateral referencescancreate the same situation, as
2293+
*explainedin the comments for process_subquery_nestloop_params
2294+
*and paraminfo_get_equal_hashops. Not checking this exactly is
2295+
*a bit grotty, but the work needed to make things match up
2296+
*perfectly seems well out of proportion tothe value.
22972297
*/
22982298
nlp->paramval= (Var*)fix_upper_expr(root,
22992299
(Node*)nlp->paramval,

‎src/test/regress/expected/join.out

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2607,6 +2607,27 @@ select * from int8_tbl t1
26072607
Filter: (q1 = t2.q1)
26082608
(8 rows)
26092609

2610+
explain (costs off)
2611+
select * from onek t1
2612+
left join onek t2 on true
2613+
left join lateral
2614+
(select * from onek t3 where t3.two = t2.two offset 0) s
2615+
on t2.unique1 = 1;
2616+
QUERY PLAN
2617+
--------------------------------------------------
2618+
Nested Loop Left Join
2619+
-> Seq Scan on onek t1
2620+
-> Materialize
2621+
-> Nested Loop Left Join
2622+
Join Filter: (t2.unique1 = 1)
2623+
-> Seq Scan on onek t2
2624+
-> Memoize
2625+
Cache Key: t2.two
2626+
Cache Mode: binary
2627+
-> Seq Scan on onek t3
2628+
Filter: (two = t2.two)
2629+
(11 rows)
2630+
26102631
--
26112632
-- check a case where we formerly got confused by conflicting sort orders
26122633
-- in redundant merge join path keys

‎src/test/regress/sql/join.sql

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -521,6 +521,13 @@ select * from int8_tbl t1
521521
(select*from int8_tbl t3wheret3.q1=t2.q1 offset0) s
522522
ont2.q1=1;
523523

524+
explain (costs off)
525+
select*from onek t1
526+
left join onek t2on true
527+
left join lateral
528+
(select*from onek t3wheret3.two=t2.two offset0) s
529+
ont2.unique1=1;
530+
524531
--
525532
-- check a case where we formerly got confused by conflicting sort orders
526533
-- in redundant merge join path keys

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp