@@ -834,7 +834,9 @@ inheritance_planner(PlannerInfo *root)
834834{
835835 Query * parse = root -> parse ;
836836 int parentRTindex = parse -> resultRelation ;
837- Bitmapset * resultRTindexes = NULL ;
837+ Bitmapset * resultRTindexes ;
838+ Bitmapset * subqueryRTindexes ;
839+ Bitmapset * modifiableARIindexes ;
838840 int nominalRelation = -1 ;
839841 List * final_rtable = NIL ;
840842 int save_rel_array_size = 0 ;
@@ -845,6 +847,7 @@ inheritance_planner(PlannerInfo *root)
845847 List * returningLists = NIL ;
846848 List * rowMarks ;
847849 ListCell * lc ;
850+ Index rti ;
848851
849852 Assert (parse -> commandType != CMD_INSERT );
850853
@@ -867,8 +870,10 @@ inheritance_planner(PlannerInfo *root)
867870 * subqueries during planning, and so we must create copies of them too,
868871 * except where they are target relations, which will each only be used in
869872 * a single plan.
873+ *
874+ * To begin with, we'll need a bitmapset of the target relation relids.
870875 */
871- resultRTindexes = bms_add_member ( resultRTindexes , parentRTindex );
876+ resultRTindexes = bms_make_singleton ( parentRTindex );
872877 foreach (lc , root -> append_rel_list )
873878 {
874879 AppendRelInfo * appinfo = (AppendRelInfo * ) lfirst (lc );
@@ -878,12 +883,57 @@ inheritance_planner(PlannerInfo *root)
878883 appinfo -> child_relid );
879884 }
880885
886+ /*
887+ * Now, generate a bitmapset of the relids of the subquery RTEs, including
888+ * security-barrier RTEs that will become subqueries, as just explained.
889+ */
890+ subqueryRTindexes = NULL ;
891+ rti = 1 ;
892+ foreach (lc , parse -> rtable )
893+ {
894+ RangeTblEntry * rte = (RangeTblEntry * ) lfirst (lc );
895+
896+ if (rte -> rtekind == RTE_SUBQUERY ||
897+ (rte -> securityQuals != NIL &&
898+ !bms_is_member (rti , resultRTindexes )))
899+ subqueryRTindexes = bms_add_member (subqueryRTindexes , rti );
900+ rti ++ ;
901+ }
902+
903+ /*
904+ * Next, we want to identify which AppendRelInfo items contain references
905+ * to any of the aforesaid subquery RTEs. These items will need to be
906+ * copied and modified to adjust their subquery references; whereas the
907+ * other ones need not be touched. It's worth being tense over this
908+ * because we can usually avoid processing most of the AppendRelInfo
909+ * items, thereby saving O(N^2) space and time when the target is a large
910+ * inheritance tree. We can identify AppendRelInfo items by their
911+ * child_relid, since that should be unique within the list.
912+ */
913+ modifiableARIindexes = NULL ;
914+ if (subqueryRTindexes != NULL )
915+ {
916+ foreach (lc , root -> append_rel_list )
917+ {
918+ AppendRelInfo * appinfo = (AppendRelInfo * ) lfirst (lc );
919+
920+ if (bms_is_member (appinfo -> parent_relid , subqueryRTindexes ) ||
921+ bms_is_member (appinfo -> child_relid , subqueryRTindexes ) ||
922+ bms_overlap (pull_varnos ((Node * ) appinfo -> translated_vars ),
923+ subqueryRTindexes ))
924+ modifiableARIindexes = bms_add_member (modifiableARIindexes ,
925+ appinfo -> child_relid );
926+ }
927+ }
928+
929+ /*
930+ * And now we can get on with generating a plan for each child table.
931+ */
881932 foreach (lc , root -> append_rel_list )
882933 {
883934 AppendRelInfo * appinfo = (AppendRelInfo * ) lfirst (lc );
884935 PlannerInfo subroot ;
885936 Plan * subplan ;
886- Index rti ;
887937
888938 /* append_rel_list contains all append rels; ignore others */
889939 if (appinfo -> parent_relid != parentRTindex )
@@ -917,9 +967,29 @@ inheritance_planner(PlannerInfo *root)
917967 /*
918968 * The append_rel_list likewise might contain references to subquery
919969 * RTEs (if any subqueries were flattenable UNION ALLs). So prepare
920- * to apply ChangeVarNodes to that, too.
970+ * to apply ChangeVarNodes to that, too. As explained above, we only
971+ * want to copy items that actually contain such references; the rest
972+ * can just get linked into the subroot's append_rel_list.
973+ *
974+ * If we know there are no such references, we can just use the outer
975+ * append_rel_list unmodified.
921976 */
922- subroot .append_rel_list = (List * ) copyObject (root -> append_rel_list );
977+ if (modifiableARIindexes != NULL )
978+ {
979+ ListCell * lc2 ;
980+
981+ subroot .append_rel_list = NIL ;
982+ foreach (lc2 , root -> append_rel_list )
983+ {
984+ AppendRelInfo * appinfo2 = (AppendRelInfo * ) lfirst (lc2 );
985+
986+ if (bms_is_member (appinfo2 -> child_relid , modifiableARIindexes ))
987+ appinfo2 = (AppendRelInfo * ) copyObject (appinfo2 );
988+
989+ subroot .append_rel_list = lappend (subroot .append_rel_list ,
990+ appinfo2 );
991+ }
992+ }
923993
924994 /*
925995 * Add placeholders to the child Query's rangetable list to fill the
@@ -933,13 +1003,13 @@ inheritance_planner(PlannerInfo *root)
9331003
9341004 /*
9351005 * If this isn't the first child Query, generate duplicates of all
936- * subquery RTEs, and adjust Var numbering to reference the
937- * duplicates. To simplify the loop logic, we scan the original rtable
938- * not the copy just made by adjust_appendrel_attrs; that should be OK
939- * since subquery RTEs couldn't contain any references to the target
940- * rel.
1006+ * subquery (or subquery-to-be) RTEs, and adjust Var numbering to
1007+ * reference the duplicates. To simplify the loop logic, we scan the
1008+ * original rtable not the copy just made by adjust_appendrel_attrs;
1009+ * that should be OK since subquery RTEs couldn't contain any
1010+ * references to the target rel.
9411011 */
942- if (final_rtable != NIL )
1012+ if (final_rtable != NIL && subqueryRTindexes != NULL )
9431013 {
9441014 ListCell * lr ;
9451015
@@ -948,14 +1018,7 @@ inheritance_planner(PlannerInfo *root)
9481018 {
9491019 RangeTblEntry * rte = (RangeTblEntry * ) lfirst (lr );
9501020
951- /*
952- * Copy subquery RTEs and RTEs with security barrier quals
953- * that will be turned into subqueries, except those that are
954- * target relations.
955- */
956- if (rte -> rtekind == RTE_SUBQUERY ||
957- (rte -> securityQuals != NIL &&
958- !bms_is_member (rti , resultRTindexes )))
1021+ if (bms_is_member (rti , subqueryRTindexes ))
9591022 {
9601023 Index newrti ;
9611024
@@ -968,7 +1031,20 @@ inheritance_planner(PlannerInfo *root)
9681031 newrti = list_length (subroot .parse -> rtable ) + 1 ;
9691032 ChangeVarNodes ((Node * ) subroot .parse , rti , newrti , 0 );
9701033 ChangeVarNodes ((Node * ) subroot .rowMarks , rti , newrti , 0 );
971- ChangeVarNodes ((Node * ) subroot .append_rel_list , rti , newrti , 0 );
1034+ /* Skip processing unchanging parts of append_rel_list */
1035+ if (modifiableARIindexes != NULL )
1036+ {
1037+ ListCell * lc2 ;
1038+
1039+ foreach (lc2 , subroot .append_rel_list )
1040+ {
1041+ AppendRelInfo * appinfo2 = (AppendRelInfo * ) lfirst (lc2 );
1042+
1043+ if (bms_is_member (appinfo2 -> child_relid ,
1044+ modifiableARIindexes ))
1045+ ChangeVarNodes ((Node * ) appinfo2 , rti , newrti , 0 );
1046+ }
1047+ }
9721048 rte = copyObject (rte );
9731049 ChangeVarNodes ((Node * ) rte -> securityQuals , rti , newrti , 0 );
9741050 subroot .parse -> rtable = lappend (subroot .parse -> rtable ,
0 commit comments