private AbstractPlanNode recursivelyApply(AbstractPlanNode plan, int childIdx) {
        // If this is an insert plan node, then try to
        // inline it.  There will only ever by one insert
        // node, so if we can't inline it we just return the
        // given plan.
        if (plan instanceof InsertPlanNode) {
            InsertPlanNode insertNode = (InsertPlanNode)plan;
            assert(insertNode.getChildCount() == 1);
            AbstractPlanNode abstractChild = insertNode.getChild(0);
            ScanPlanNodeWhichCanHaveInlineInsert targetNode
                  = (abstractChild instanceof ScanPlanNodeWhichCanHaveInlineInsert)
                        ? ((ScanPlanNodeWhichCanHaveInlineInsert)abstractChild)
                        : null;
            // If we have a sequential/index scan node without an inline aggregate
            // node then we can inline the insert node.
            if ( targetNode != null
                 && ! insertNode.isUpsert()
                 && ! targetNode.hasInlineAggregateNode()
                 // If INSERT INTO and SELECT FROM have the same target table name,
                 // then it could be a recursive insert into select.
                 // Currently, our scan executor implementations cannot handle it well. (ENG-13036)
                 && ! targetNode.getTargetTableName().equalsIgnoreCase(insertNode.getTargetTableName()) ) {
                AbstractPlanNode parent = (insertNode.getParentCount() > 0) ? insertNode.getParent(0) : null;
                AbstractPlanNode abstractTargetNode = targetNode.getAbstractNode();
                abstractTargetNode.addInlinePlanNode(insertNode);
                // Don't call removeFromGraph.  That
                // screws up the order of the children.
                insertNode.clearChildren();
                insertNode.clearParents();
                // Remvoe all the abstractTarget node's parents.
                // It used to be the insertNode, which is now
                // dead to us.
                abstractTargetNode.clearParents();
                if (parent != null) {
                    parent.setAndLinkChild(childIdx, abstractTargetNode);
                }
                plan = abstractTargetNode;
            }
            return plan;
        }
        for (int idx = 0; idx < plan.getChildCount(); idx += 1) {
            AbstractPlanNode child = plan.getChild(idx);
            recursivelyApply(child, idx);
        }
        return plan;
    }
private AbstractPlanNode recursivelyApply ( AbstractPlanNode plan , int childIdx ) { if ( plan instanceof InsertPlanNode ) { InsertPlanNode insertNode = ( InsertPlanNode ) plan ; assert ( insertNode . getChildCount ( ) == 1 ) ; AbstractPlanNode abstractChild = insertNode . getChild ( 0 ) ; ScanPlanNodeWhichCanHaveInlineInsert targetNode = ( abstractChild instanceof ScanPlanNodeWhichCanHaveInlineInsert ) ? ( ( ScanPlanNodeWhichCanHaveInlineInsert ) abstractChild ) : null ; if ( targetNode != null && ! insertNode . isUpsert ( ) && ! targetNode . hasInlineAggregateNode ( ) && ! targetNode . getTargetTableName ( ) . equalsIgnoreCase ( insertNode . getTargetTableName ( ) ) ) { AbstractPlanNode parent = ( insertNode . getParentCount ( ) > 0 ) ? insertNode . getParent ( 0 ) : null ; AbstractPlanNode abstractTargetNode = targetNode . getAbstractNode ( ) ; abstractTargetNode . addInlinePlanNode ( insertNode ) ; insertNode . clearChildren ( ) ; insertNode . clearParents ( ) ; abstractTargetNode . clearParents ( ) ; if ( parent != null ) { parent . setAndLinkChild ( childIdx , abstractTargetNode ) ; } plan = abstractTargetNode ; } return plan ; } for ( int idx = 0 ; idx < plan . getChildCount ( ) ; idx += 1 ) { AbstractPlanNode child = plan . getChild ( idx ) ; recursivelyApply ( child , idx ) ; } return plan ; }
This helper function is called when we recurse down the childIdx-th
child of a parent node.
@param plan
@param parentIdx
@return