• R/O
  • HTTP
  • SSH
  • HTTPS

pg_hint_plan: コミット

firtst release


コミットメタ情報

リビジョン5355f71bd540e524b4279d08b37ae020aadc3745 (tree)
日時2017-07-27 19:19:21
作者Kyotaro Horiguchi <horiguchi.kyotaro@lab....>
コミッターKyotaro Horiguchi

ログメッセージ

Make core.c up to date.

Apply changes in corresponding core code.

変更サマリ

差分

--- a/core.c
+++ b/core.c
@@ -819,9 +819,7 @@ join_is_legal(PlannerInfo *root, RelOptInfo *rel1, RelOptInfo *rel2,
819819 SpecialJoinInfo *match_sjinfo;
820820 bool reversed;
821821 bool unique_ified;
822- bool is_valid_inner;
823- bool lateral_fwd;
824- bool lateral_rev;
822+ bool must_be_leftjoin;
825823 ListCell *l;
826824
827825 /*
@@ -834,12 +832,12 @@ join_is_legal(PlannerInfo *root, RelOptInfo *rel1, RelOptInfo *rel2,
834832 /*
835833 * If we have any special joins, the proposed join might be illegal; and
836834 * in any case we have to determine its join type. Scan the join info
837- * list for conflicts.
835+ * list for matches and conflicts.
838836 */
839837 match_sjinfo = NULL;
840838 reversed = false;
841839 unique_ified = false;
842- is_valid_inner = true;
840+ must_be_leftjoin = false;
843841
844842 foreach(l, root->join_info_list)
845843 {
@@ -890,7 +888,8 @@ join_is_legal(PlannerInfo *root, RelOptInfo *rel1, RelOptInfo *rel2,
890888 * If one input contains min_lefthand and the other contains
891889 * min_righthand, then we can perform the SJ at this join.
892890 *
893- * Barf if we get matches to more than one SJ (is that possible?)
891+ * Reject if we get matches to more than one SJ; that implies we're
892+ * considering something that's not really valid.
894893 */
895894 if (bms_is_subset(sjinfo->min_lefthand, rel1->relids) &&
896895 bms_is_subset(sjinfo->min_righthand, rel2->relids))
@@ -955,90 +954,184 @@ join_is_legal(PlannerInfo *root, RelOptInfo *rel1, RelOptInfo *rel2,
955954 }
956955 else
957956 {
958- /*----------
959- * Otherwise, the proposed join overlaps the RHS but isn't
960- * a valid implementation of this SJ. It might still be
961- * a legal join, however. If both inputs overlap the RHS,
962- * assume that it's OK. Since the inputs presumably got past
963- * this function's checks previously, they can't overlap the
964- * LHS and their violations of the RHS boundary must represent
965- * SJs that have been determined to commute with this one.
966- * We have to allow this to work correctly in cases like
967- * (a LEFT JOIN (b JOIN (c LEFT JOIN d)))
968- * when the c/d join has been determined to commute with the join
969- * to a, and hence d is not part of min_righthand for the upper
970- * join. It should be legal to join b to c/d but this will appear
971- * as a violation of the upper join's RHS.
972- * Furthermore, if one input overlaps the RHS and the other does
973- * not, we should still allow the join if it is a valid
974- * implementation of some other SJ. We have to allow this to
975- * support the associative identity
976- * (a LJ b on Pab) LJ c ON Pbc = a LJ (b LJ c ON Pbc) on Pab
977- * since joining B directly to C violates the lower SJ's RHS.
978- * We assume that make_outerjoininfo() set things up correctly
979- * so that we'll only match to some SJ if the join is valid.
980- * Set flag here to check at bottom of loop.
981- *----------
957+ /*
958+ * Otherwise, the proposed join overlaps the RHS but isn't a valid
959+ * implementation of this SJ. But don't panic quite yet: the RHS
960+ * violation might have occurred previously, in one or both input
961+ * relations, in which case we must have previously decided that
962+ * it was OK to commute some other SJ with this one. If we need
963+ * to perform this join to finish building up the RHS, rejecting
964+ * it could lead to not finding any plan at all. (This can occur
965+ * because of the heuristics elsewhere in this file that postpone
966+ * clauseless joins: we might not consider doing a clauseless join
967+ * within the RHS until after we've performed other, validly
968+ * commutable SJs with one or both sides of the clauseless join.)
969+ * This consideration boils down to the rule that if both inputs
970+ * overlap the RHS, we can allow the join --- they are either
971+ * fully within the RHS, or represent previously-allowed joins to
972+ * rels outside it.
982973 */
983- if (sjinfo->jointype != JOIN_SEMI &&
984- bms_overlap(rel1->relids, sjinfo->min_righthand) &&
974+ if (bms_overlap(rel1->relids, sjinfo->min_righthand) &&
985975 bms_overlap(rel2->relids, sjinfo->min_righthand))
986- {
987- /* seems OK */
988- Assert(!bms_overlap(joinrelids, sjinfo->min_lefthand));
989- }
990- else
991- is_valid_inner = false;
976+ continue; /* assume valid previous violation of RHS */
977+
978+ /*
979+ * The proposed join could still be legal, but only if we're
980+ * allowed to associate it into the RHS of this SJ. That means
981+ * this SJ must be a LEFT join (not SEMI or ANTI, and certainly
982+ * not FULL) and the proposed join must not overlap the LHS.
983+ */
984+ if (sjinfo->jointype != JOIN_LEFT ||
985+ bms_overlap(joinrelids, sjinfo->min_lefthand))
986+ return false; /* invalid join path */
987+
988+ /*
989+ * To be valid, the proposed join must be a LEFT join; otherwise
990+ * it can't associate into this SJ's RHS. But we may not yet have
991+ * found the SpecialJoinInfo matching the proposed join, so we
992+ * can't test that yet. Remember the requirement for later.
993+ */
994+ must_be_leftjoin = true;
992995 }
993996 }
994997
995998 /*
996- * Fail if violated some SJ's RHS and didn't match to another SJ. However,
997- * "matching" to a semijoin we are implementing by unique-ification
998- * doesn't count (think: it's really an inner join).
999+ * Fail if violated any SJ's RHS and didn't match to a LEFT SJ: the
1000+ * proposed join can't associate into an SJ's RHS.
1001+ *
1002+ * Also, fail if the proposed join's predicate isn't strict; we're
1003+ * essentially checking to see if we can apply outer-join identity 3, and
1004+ * that's a requirement. (This check may be redundant with checks in
1005+ * make_outerjoininfo, but I'm not quite sure, and it's cheap to test.)
9991006 */
1000- if (!is_valid_inner &&
1001- (match_sjinfo == NULL || unique_ified))
1007+ if (must_be_leftjoin &&
1008+ (match_sjinfo == NULL ||
1009+ match_sjinfo->jointype != JOIN_LEFT ||
1010+ !match_sjinfo->lhs_strict))
10021011 return false; /* invalid join path */
10031012
10041013 /*
10051014 * We also have to check for constraints imposed by LATERAL references.
1006- * The proposed rels could each contain lateral references to the other,
1007- * in which case the join is impossible. If there are lateral references
1008- * in just one direction, then the join has to be done with a nestloop
1009- * with the lateral referencer on the inside. If the join matches an SJ
1010- * that cannot be implemented by such a nestloop, the join is impossible.
10111015 */
1012- lateral_fwd = lateral_rev = false;
1013- foreach(l, root->lateral_info_list)
1016+ if (root->hasLateralRTEs)
10141017 {
1015- LateralJoinInfo *ljinfo = (LateralJoinInfo *) lfirst(l);
1018+ bool lateral_fwd;
1019+ bool lateral_rev;
1020+ Relids join_lateral_rels;
10161021
1017- if (bms_is_subset(ljinfo->lateral_rhs, rel2->relids) &&
1018- bms_overlap(ljinfo->lateral_lhs, rel1->relids))
1022+ /*
1023+ * The proposed rels could each contain lateral references to the
1024+ * other, in which case the join is impossible. If there are lateral
1025+ * references in just one direction, then the join has to be done with
1026+ * a nestloop with the lateral referencer on the inside. If the join
1027+ * matches an SJ that cannot be implemented by such a nestloop, the
1028+ * join is impossible.
1029+ *
1030+ * Also, if the lateral reference is only indirect, we should reject
1031+ * the join; whatever rel(s) the reference chain goes through must be
1032+ * joined to first.
1033+ *
1034+ * Another case that might keep us from building a valid plan is the
1035+ * implementation restriction described by have_dangerous_phv().
1036+ */
1037+ lateral_fwd = bms_overlap(rel1->relids, rel2->lateral_relids);
1038+ lateral_rev = bms_overlap(rel2->relids, rel1->lateral_relids);
1039+ if (lateral_fwd && lateral_rev)
1040+ return false; /* have lateral refs in both directions */
1041+ if (lateral_fwd)
10191042 {
10201043 /* has to be implemented as nestloop with rel1 on left */
1021- if (lateral_rev)
1022- return false; /* have lateral refs in both directions */
1023- lateral_fwd = true;
1024- if (!bms_is_subset(ljinfo->lateral_lhs, rel1->relids))
1025- return false; /* rel1 can't compute the required parameter */
10261044 if (match_sjinfo &&
1027- (reversed || match_sjinfo->jointype == JOIN_FULL))
1045+ (reversed ||
1046+ unique_ified ||
1047+ match_sjinfo->jointype == JOIN_FULL))
10281048 return false; /* not implementable as nestloop */
1049+ /* check there is a direct reference from rel2 to rel1 */
1050+ foreach(l, root->lateral_info_list)
1051+ {
1052+ LateralJoinInfo *ljinfo = (LateralJoinInfo *) lfirst(l);
1053+
1054+ if (bms_is_subset(ljinfo->lateral_rhs, rel2->relids) &&
1055+ bms_is_subset(ljinfo->lateral_lhs, rel1->relids))
1056+ break;
1057+ }
1058+ if (l == NULL)
1059+ return false; /* only indirect refs, so reject */
1060+ /* check we won't have a dangerous PHV */
1061+ if (have_dangerous_phv(root, rel1->relids, rel2->lateral_relids))
1062+ return false; /* might be unable to handle required PHV */
10291063 }
1030- if (bms_is_subset(ljinfo->lateral_rhs, rel1->relids) &&
1031- bms_overlap(ljinfo->lateral_lhs, rel2->relids))
1064+ else if (lateral_rev)
10321065 {
10331066 /* has to be implemented as nestloop with rel2 on left */
1034- if (lateral_fwd)
1035- return false; /* have lateral refs in both directions */
1036- lateral_rev = true;
1037- if (!bms_is_subset(ljinfo->lateral_lhs, rel2->relids))
1038- return false; /* rel2 can't compute the required parameter */
10391067 if (match_sjinfo &&
1040- (!reversed || match_sjinfo->jointype == JOIN_FULL))
1068+ (!reversed ||
1069+ unique_ified ||
1070+ match_sjinfo->jointype == JOIN_FULL))
10411071 return false; /* not implementable as nestloop */
1072+ /* check there is a direct reference from rel1 to rel2 */
1073+ foreach(l, root->lateral_info_list)
1074+ {
1075+ LateralJoinInfo *ljinfo = (LateralJoinInfo *) lfirst(l);
1076+
1077+ if (bms_is_subset(ljinfo->lateral_rhs, rel1->relids) &&
1078+ bms_is_subset(ljinfo->lateral_lhs, rel2->relids))
1079+ break;
1080+ }
1081+ if (l == NULL)
1082+ return false; /* only indirect refs, so reject */
1083+ /* check we won't have a dangerous PHV */
1084+ if (have_dangerous_phv(root, rel2->relids, rel1->lateral_relids))
1085+ return false; /* might be unable to handle required PHV */
1086+ }
1087+
1088+ /*
1089+ * LATERAL references could also cause problems later on if we accept
1090+ * this join: if the join's minimum parameterization includes any rels
1091+ * that would have to be on the inside of an outer join with this join
1092+ * rel, then it's never going to be possible to build the complete
1093+ * query using this join. We should reject this join not only because
1094+ * it'll save work, but because if we don't, the clauseless-join
1095+ * heuristics might think that legality of this join means that some
1096+ * other join rel need not be formed, and that could lead to failure
1097+ * to find any plan at all. We have to consider not only rels that
1098+ * are directly on the inner side of an OJ with the joinrel, but also
1099+ * ones that are indirectly so, so search to find all such rels.
1100+ */
1101+ join_lateral_rels = min_join_parameterization(root, joinrelids,
1102+ rel1, rel2);
1103+ if (join_lateral_rels)
1104+ {
1105+ Relids join_plus_rhs = bms_copy(joinrelids);
1106+ bool more;
1107+
1108+ do
1109+ {
1110+ more = false;
1111+ foreach(l, root->join_info_list)
1112+ {
1113+ SpecialJoinInfo *sjinfo = (SpecialJoinInfo *) lfirst(l);
1114+
1115+ if (bms_overlap(sjinfo->min_lefthand, join_plus_rhs) &&
1116+ !bms_is_subset(sjinfo->min_righthand, join_plus_rhs))
1117+ {
1118+ join_plus_rhs = bms_add_members(join_plus_rhs,
1119+ sjinfo->min_righthand);
1120+ more = true;
1121+ }
1122+ /* full joins constrain both sides symmetrically */
1123+ if (sjinfo->jointype == JOIN_FULL &&
1124+ bms_overlap(sjinfo->min_righthand, join_plus_rhs) &&
1125+ !bms_is_subset(sjinfo->min_lefthand, join_plus_rhs))
1126+ {
1127+ join_plus_rhs = bms_add_members(join_plus_rhs,
1128+ sjinfo->min_lefthand);
1129+ more = true;
1130+ }
1131+ }
1132+ } while (more);
1133+ if (bms_overlap(join_plus_rhs, join_lateral_rels))
1134+ return false; /* will not be able to join to some RHS rel */
10421135 }
10431136 }
10441137
@@ -1048,11 +1141,12 @@ join_is_legal(PlannerInfo *root, RelOptInfo *rel1, RelOptInfo *rel2,
10481141 return true;
10491142 }
10501143
1144+
10511145 /*
10521146 * has_join_restriction
10531147 * Detect whether the specified relation has join-order restrictions,
10541148 * due to being inside an outer join or an IN (sub-SELECT),
1055- * or participating in any LATERAL references.
1149+ * or participating in any LATERAL references or multi-rel PHVs.
10561150 *
10571151 * Essentially, this tests whether have_join_order_restriction() could
10581152 * succeed with this rel and some other one. It's OK if we sometimes
@@ -1064,12 +1158,15 @@ has_join_restriction(PlannerInfo *root, RelOptInfo *rel)
10641158 {
10651159 ListCell *l;
10661160
1067- foreach(l, root->lateral_info_list)
1161+ if (rel->lateral_relids != NULL || rel->lateral_referencers != NULL)
1162+ return true;
1163+
1164+ foreach(l, root->placeholder_list)
10681165 {
1069- LateralJoinInfo *ljinfo = (LateralJoinInfo *) lfirst(l);
1166+ PlaceHolderInfo *phinfo = (PlaceHolderInfo *) lfirst(l);
10701167
1071- if (bms_is_subset(ljinfo->lateral_rhs, rel->relids) ||
1072- bms_overlap(ljinfo->lateral_lhs, rel->relids))
1168+ if (bms_is_subset(rel->relids, phinfo->ph_eval_at) &&
1169+ !bms_equal(rel->relids, phinfo->ph_eval_at))
10731170 return true;
10741171 }
10751172
旧リポジトリブラウザで表示