firtst release
Révision | 95b5f892eebda65ab17ba127cdd57ea88ecc07c6 (tree) |
---|---|
l'heure | 2016-01-15 11:54:15 |
Auteur | Kyotaro Horiguchi <horiguchi.kyotaro@lab....> |
Commiter | Kyotaro Horiguchi |
Followed the changes of 9.5.0 release.
There was some changes in 9.5.0 release affect
pg_hint_plan. set_append_rel_pathlist() no longer sets cheapest path
and it became a business of the caller. So rebuild_scan_path() does
so. core.c gets changed from changing lateral join infrastracture
(acfcd45cacb6df23edba4cb3753a2be594238a99) and a change related to custom path(c2ea2285e978d9289084846a3343cef7d261d880).
@@ -20,7 +20,7 @@ | ||
20 | 20 | * mark_dummy_rel() |
21 | 21 | * restriction_is_constant_false() |
22 | 22 | * |
23 | - * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group | |
23 | + * Portions Copyright (c) 1996-2016, PostgreSQL Global Development Group | |
24 | 24 | * Portions Copyright (c) 1994, Regents of the University of California |
25 | 25 | * |
26 | 26 | *------------------------------------------------------------------------- |
@@ -215,9 +215,6 @@ set_append_rel_pathlist(PlannerInfo *root, RelOptInfo *rel, | ||
215 | 215 | add_path(rel, (Path *) |
216 | 216 | create_append_path(rel, subpaths, required_outer)); |
217 | 217 | } |
218 | - | |
219 | - /* Select cheapest paths */ | |
220 | - set_cheapest(rel); | |
221 | 218 | } |
222 | 219 | |
223 | 220 | /* |
@@ -720,7 +717,7 @@ join_search_one_level(PlannerInfo *root, int level) | ||
720 | 717 | */ |
721 | 718 | if (joinrels[level] == NIL && |
722 | 719 | root->join_info_list == NIL && |
723 | - root->lateral_info_list == NIL) | |
720 | + !root->hasLateralRTEs) | |
724 | 721 | elog(ERROR, "failed to build any %d-way joins", level); |
725 | 722 | } |
726 | 723 | } |
@@ -819,9 +816,7 @@ join_is_legal(PlannerInfo *root, RelOptInfo *rel1, RelOptInfo *rel2, | ||
819 | 816 | SpecialJoinInfo *match_sjinfo; |
820 | 817 | bool reversed; |
821 | 818 | bool unique_ified; |
822 | - bool is_valid_inner; | |
823 | - bool lateral_fwd; | |
824 | - bool lateral_rev; | |
819 | + bool must_be_leftjoin; | |
825 | 820 | ListCell *l; |
826 | 821 | |
827 | 822 | /* |
@@ -834,12 +829,12 @@ join_is_legal(PlannerInfo *root, RelOptInfo *rel1, RelOptInfo *rel2, | ||
834 | 829 | /* |
835 | 830 | * If we have any special joins, the proposed join might be illegal; and |
836 | 831 | * in any case we have to determine its join type. Scan the join info |
837 | - * list for conflicts. | |
832 | + * list for matches and conflicts. | |
838 | 833 | */ |
839 | 834 | match_sjinfo = NULL; |
840 | 835 | reversed = false; |
841 | 836 | unique_ified = false; |
842 | - is_valid_inner = true; | |
837 | + must_be_leftjoin = false; | |
843 | 838 | |
844 | 839 | foreach(l, root->join_info_list) |
845 | 840 | { |
@@ -890,7 +885,8 @@ join_is_legal(PlannerInfo *root, RelOptInfo *rel1, RelOptInfo *rel2, | ||
890 | 885 | * If one input contains min_lefthand and the other contains |
891 | 886 | * min_righthand, then we can perform the SJ at this join. |
892 | 887 | * |
893 | - * Barf if we get matches to more than one SJ (is that possible?) | |
888 | + * Reject if we get matches to more than one SJ; that implies we're | |
889 | + * considering something that's not really valid. | |
894 | 890 | */ |
895 | 891 | if (bms_is_subset(sjinfo->min_lefthand, rel1->relids) && |
896 | 892 | bms_is_subset(sjinfo->min_righthand, rel2->relids)) |
@@ -955,90 +951,168 @@ join_is_legal(PlannerInfo *root, RelOptInfo *rel1, RelOptInfo *rel2, | ||
955 | 951 | } |
956 | 952 | else |
957 | 953 | { |
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 | - *---------- | |
954 | + /* | |
955 | + * Otherwise, the proposed join overlaps the RHS but isn't a valid | |
956 | + * implementation of this SJ. But don't panic quite yet: the RHS | |
957 | + * violation might have occurred previously, in one or both input | |
958 | + * relations, in which case we must have previously decided that | |
959 | + * it was OK to commute some other SJ with this one. If we need | |
960 | + * to perform this join to finish building up the RHS, rejecting | |
961 | + * it could lead to not finding any plan at all. (This can occur | |
962 | + * because of the heuristics elsewhere in this file that postpone | |
963 | + * clauseless joins: we might not consider doing a clauseless join | |
964 | + * within the RHS until after we've performed other, validly | |
965 | + * commutable SJs with one or both sides of the clauseless join.) | |
966 | + * This consideration boils down to the rule that if both inputs | |
967 | + * overlap the RHS, we can allow the join --- they are either | |
968 | + * fully within the RHS, or represent previously-allowed joins to | |
969 | + * rels outside it. | |
982 | 970 | */ |
983 | - if (sjinfo->jointype != JOIN_SEMI && | |
984 | - bms_overlap(rel1->relids, sjinfo->min_righthand) && | |
971 | + if (bms_overlap(rel1->relids, sjinfo->min_righthand) && | |
985 | 972 | 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; | |
973 | + continue; /* assume valid previous violation of RHS */ | |
974 | + | |
975 | + /* | |
976 | + * The proposed join could still be legal, but only if we're | |
977 | + * allowed to associate it into the RHS of this SJ. That means | |
978 | + * this SJ must be a LEFT join (not SEMI or ANTI, and certainly | |
979 | + * not FULL) and the proposed join must not overlap the LHS. | |
980 | + */ | |
981 | + if (sjinfo->jointype != JOIN_LEFT || | |
982 | + bms_overlap(joinrelids, sjinfo->min_lefthand)) | |
983 | + return false; /* invalid join path */ | |
984 | + | |
985 | + /* | |
986 | + * To be valid, the proposed join must be a LEFT join; otherwise | |
987 | + * it can't associate into this SJ's RHS. But we may not yet have | |
988 | + * found the SpecialJoinInfo matching the proposed join, so we | |
989 | + * can't test that yet. Remember the requirement for later. | |
990 | + */ | |
991 | + must_be_leftjoin = true; | |
992 | 992 | } |
993 | 993 | } |
994 | 994 | |
995 | 995 | /* |
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). | |
996 | + * Fail if violated any SJ's RHS and didn't match to a LEFT SJ: the | |
997 | + * proposed join can't associate into an SJ's RHS. | |
998 | + * | |
999 | + * Also, fail if the proposed join's predicate isn't strict; we're | |
1000 | + * essentially checking to see if we can apply outer-join identity 3, and | |
1001 | + * that's a requirement. (This check may be redundant with checks in | |
1002 | + * make_outerjoininfo, but I'm not quite sure, and it's cheap to test.) | |
999 | 1003 | */ |
1000 | - if (!is_valid_inner && | |
1001 | - (match_sjinfo == NULL || unique_ified)) | |
1004 | + if (must_be_leftjoin && | |
1005 | + (match_sjinfo == NULL || | |
1006 | + match_sjinfo->jointype != JOIN_LEFT || | |
1007 | + !match_sjinfo->lhs_strict)) | |
1002 | 1008 | return false; /* invalid join path */ |
1003 | 1009 | |
1004 | 1010 | /* |
1005 | 1011 | * 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. | |
1011 | 1012 | */ |
1012 | - lateral_fwd = lateral_rev = false; | |
1013 | - foreach(l, root->lateral_info_list) | |
1013 | + if (root->hasLateralRTEs) | |
1014 | 1014 | { |
1015 | - LateralJoinInfo *ljinfo = (LateralJoinInfo *) lfirst(l); | |
1015 | + bool lateral_fwd; | |
1016 | + bool lateral_rev; | |
1017 | + Relids join_lateral_rels; | |
1016 | 1018 | |
1017 | - if (bms_is_subset(ljinfo->lateral_rhs, rel2->relids) && | |
1018 | - bms_overlap(ljinfo->lateral_lhs, rel1->relids)) | |
1019 | + /* | |
1020 | + * The proposed rels could each contain lateral references to the | |
1021 | + * other, in which case the join is impossible. If there are lateral | |
1022 | + * references in just one direction, then the join has to be done with | |
1023 | + * a nestloop with the lateral referencer on the inside. If the join | |
1024 | + * matches an SJ that cannot be implemented by such a nestloop, the | |
1025 | + * join is impossible. | |
1026 | + * | |
1027 | + * Also, if the lateral reference is only indirect, we should reject | |
1028 | + * the join; whatever rel(s) the reference chain goes through must be | |
1029 | + * joined to first. | |
1030 | + * | |
1031 | + * Another case that might keep us from building a valid plan is the | |
1032 | + * implementation restriction described by have_dangerous_phv(). | |
1033 | + */ | |
1034 | + lateral_fwd = bms_overlap(rel1->relids, rel2->lateral_relids); | |
1035 | + lateral_rev = bms_overlap(rel2->relids, rel1->lateral_relids); | |
1036 | + if (lateral_fwd && lateral_rev) | |
1037 | + return false; /* have lateral refs in both directions */ | |
1038 | + if (lateral_fwd) | |
1019 | 1039 | { |
1020 | 1040 | /* 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 */ | |
1026 | 1041 | if (match_sjinfo && |
1027 | - (reversed || match_sjinfo->jointype == JOIN_FULL)) | |
1042 | + (reversed || | |
1043 | + unique_ified || | |
1044 | + match_sjinfo->jointype == JOIN_FULL)) | |
1028 | 1045 | return false; /* not implementable as nestloop */ |
1046 | + /* check there is a direct reference from rel2 to rel1 */ | |
1047 | + if (!bms_overlap(rel1->relids, rel2->direct_lateral_relids)) | |
1048 | + return false; /* only indirect refs, so reject */ | |
1049 | + /* check we won't have a dangerous PHV */ | |
1050 | + if (have_dangerous_phv(root, rel1->relids, rel2->lateral_relids)) | |
1051 | + return false; /* might be unable to handle required PHV */ | |
1029 | 1052 | } |
1030 | - if (bms_is_subset(ljinfo->lateral_rhs, rel1->relids) && | |
1031 | - bms_overlap(ljinfo->lateral_lhs, rel2->relids)) | |
1053 | + else if (lateral_rev) | |
1032 | 1054 | { |
1033 | 1055 | /* 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 */ | |
1039 | 1056 | if (match_sjinfo && |
1040 | - (!reversed || match_sjinfo->jointype == JOIN_FULL)) | |
1057 | + (!reversed || | |
1058 | + unique_ified || | |
1059 | + match_sjinfo->jointype == JOIN_FULL)) | |
1041 | 1060 | return false; /* not implementable as nestloop */ |
1061 | + /* check there is a direct reference from rel1 to rel2 */ | |
1062 | + if (!bms_overlap(rel2->relids, rel1->direct_lateral_relids)) | |
1063 | + return false; /* only indirect refs, so reject */ | |
1064 | + /* check we won't have a dangerous PHV */ | |
1065 | + if (have_dangerous_phv(root, rel2->relids, rel1->lateral_relids)) | |
1066 | + return false; /* might be unable to handle required PHV */ | |
1067 | + } | |
1068 | + | |
1069 | + /* | |
1070 | + * LATERAL references could also cause problems later on if we accept | |
1071 | + * this join: if the join's minimum parameterization includes any rels | |
1072 | + * that would have to be on the inside of an outer join with this join | |
1073 | + * rel, then it's never going to be possible to build the complete | |
1074 | + * query using this join. We should reject this join not only because | |
1075 | + * it'll save work, but because if we don't, the clauseless-join | |
1076 | + * heuristics might think that legality of this join means that some | |
1077 | + * other join rel need not be formed, and that could lead to failure | |
1078 | + * to find any plan at all. We have to consider not only rels that | |
1079 | + * are directly on the inner side of an OJ with the joinrel, but also | |
1080 | + * ones that are indirectly so, so search to find all such rels. | |
1081 | + */ | |
1082 | + join_lateral_rels = min_join_parameterization(root, joinrelids, | |
1083 | + rel1, rel2); | |
1084 | + if (join_lateral_rels) | |
1085 | + { | |
1086 | + Relids join_plus_rhs = bms_copy(joinrelids); | |
1087 | + bool more; | |
1088 | + | |
1089 | + do | |
1090 | + { | |
1091 | + more = false; | |
1092 | + foreach(l, root->join_info_list) | |
1093 | + { | |
1094 | + SpecialJoinInfo *sjinfo = (SpecialJoinInfo *) lfirst(l); | |
1095 | + | |
1096 | + if (bms_overlap(sjinfo->min_lefthand, join_plus_rhs) && | |
1097 | + !bms_is_subset(sjinfo->min_righthand, join_plus_rhs)) | |
1098 | + { | |
1099 | + join_plus_rhs = bms_add_members(join_plus_rhs, | |
1100 | + sjinfo->min_righthand); | |
1101 | + more = true; | |
1102 | + } | |
1103 | + /* full joins constrain both sides symmetrically */ | |
1104 | + if (sjinfo->jointype == JOIN_FULL && | |
1105 | + bms_overlap(sjinfo->min_righthand, join_plus_rhs) && | |
1106 | + !bms_is_subset(sjinfo->min_lefthand, join_plus_rhs)) | |
1107 | + { | |
1108 | + join_plus_rhs = bms_add_members(join_plus_rhs, | |
1109 | + sjinfo->min_lefthand); | |
1110 | + more = true; | |
1111 | + } | |
1112 | + } | |
1113 | + } while (more); | |
1114 | + if (bms_overlap(join_plus_rhs, join_lateral_rels)) | |
1115 | + return false; /* will not be able to join to some RHS rel */ | |
1042 | 1116 | } |
1043 | 1117 | } |
1044 | 1118 |
@@ -1052,7 +1126,7 @@ join_is_legal(PlannerInfo *root, RelOptInfo *rel1, RelOptInfo *rel2, | ||
1052 | 1126 | * has_join_restriction |
1053 | 1127 | * Detect whether the specified relation has join-order restrictions, |
1054 | 1128 | * due to being inside an outer join or an IN (sub-SELECT), |
1055 | - * or participating in any LATERAL references. | |
1129 | + * or participating in any LATERAL references or multi-rel PHVs. | |
1056 | 1130 | * |
1057 | 1131 | * Essentially, this tests whether have_join_order_restriction() could |
1058 | 1132 | * succeed with this rel and some other one. It's OK if we sometimes |
@@ -1064,12 +1138,15 @@ has_join_restriction(PlannerInfo *root, RelOptInfo *rel) | ||
1064 | 1138 | { |
1065 | 1139 | ListCell *l; |
1066 | 1140 | |
1067 | - foreach(l, root->lateral_info_list) | |
1141 | + if (rel->lateral_relids != NULL || rel->lateral_referencers != NULL) | |
1142 | + return true; | |
1143 | + | |
1144 | + foreach(l, root->placeholder_list) | |
1068 | 1145 | { |
1069 | - LateralJoinInfo *ljinfo = (LateralJoinInfo *) lfirst(l); | |
1146 | + PlaceHolderInfo *phinfo = (PlaceHolderInfo *) lfirst(l); | |
1070 | 1147 | |
1071 | - if (bms_is_subset(ljinfo->lateral_rhs, rel->relids) || | |
1072 | - bms_overlap(ljinfo->lateral_lhs, rel->relids)) | |
1148 | + if (bms_is_subset(rel->relids, phinfo->ph_eval_at) && | |
1149 | + !bms_equal(rel->relids, phinfo->ph_eval_at)) | |
1073 | 1150 | return true; |
1074 | 1151 | } |
1075 | 1152 |
@@ -3785,6 +3785,8 @@ rebuild_scan_path(HintState *hstate, PlannerInfo *root, int level, | ||
3785 | 3785 | { |
3786 | 3786 | set_plain_rel_pathlist(root, rel, rte); |
3787 | 3787 | } |
3788 | + | |
3789 | + set_cheapest(rel); | |
3788 | 3790 | } |
3789 | 3791 | |
3790 | 3792 | /* |