@@ -834,7 +834,9 @@ inheritance_planner(PlannerInfo *root)
834834{
835835Query * parse = root -> parse ;
836836int parentRTindex = parse -> resultRelation ;
837- Bitmapset * resultRTindexes = NULL ;
837+ Bitmapset * resultRTindexes ;
838+ Bitmapset * subqueryRTindexes ;
839+ Bitmapset * modifiableARIindexes ;
838840int nominalRelation = -1 ;
839841List * final_rtable = NIL ;
840842int save_rel_array_size = 0 ;
@@ -845,6 +847,7 @@ inheritance_planner(PlannerInfo *root)
845847List * returningLists = NIL ;
846848List * rowMarks ;
847849ListCell * lc ;
850+ Index rti ;
848851
849852Assert (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 );
872877foreach (lc ,root -> append_rel_list )
873878{
874879AppendRelInfo * appinfo = (AppendRelInfo * )lfirst (lc );
@@ -878,12 +883,57 @@ inheritance_planner(PlannerInfo *root)
878883appinfo -> 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+ */
881932foreach (lc ,root -> append_rel_list )
882933{
883934AppendRelInfo * appinfo = (AppendRelInfo * )lfirst (lc );
884935PlannerInfo subroot ;
885936Plan * subplan ;
886- Index rti ;
887937
888938/* append_rel_list contains all append rels; ignore others */
889939if (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{
9441014ListCell * lr ;
9451015
@@ -948,14 +1018,7 @@ inheritance_planner(PlannerInfo *root)
9481018{
9491019RangeTblEntry * 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{
9601023Index newrti ;
9611024
@@ -968,7 +1031,20 @@ inheritance_planner(PlannerInfo *root)
9681031newrti = list_length (subroot .parse -> rtable )+ 1 ;
9691032ChangeVarNodes ((Node * )subroot .parse ,rti ,newrti ,0 );
9701033ChangeVarNodes ((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+ }
9721048rte = copyObject (rte );
9731049ChangeVarNodes ((Node * )rte -> securityQuals ,rti ,newrti ,0 );
9741050subroot .parse -> rtable = lappend (subroot .parse -> rtable ,