@Test public void testPushAcrossFrameWithAccessNode() throws Exception { QueryMetadataInterface metadata = new TempMetadataAdapter(RealMetadataFactory.example1Cached(), new TempMetadataStore()); Command command = TestOptimizer.helpGetCommand("select * from (select * from pm1.g1 union select * from pm1.g2) x where e1 = 1", metadata); Command subCommand = TestOptimizer.helpGetCommand("select * from pm1.g1 union select * from pm1.g2", metadata); RelationalPlanner p = new RelationalPlanner(); CommandContext cc = new CommandContext(); p.initialize(command, null, metadata, null, null, cc); PlanNode root = p.generatePlan(command); PlanNode child = p.generatePlan(subCommand); PlanNode sourceNode = NodeEditor.findNodePreOrder(root, NodeConstants.Types.SOURCE); sourceNode.addFirstChild(child); sourceNode.setProperty(NodeConstants.Info.SYMBOL_MAP, SymbolMap.createSymbolMap(sourceNode.getGroups().iterator().next(), (List<Expression>)child.getFirstChild().getProperty(Info.PROJECT_COLS), metadata)); PlanNode accessNode = NodeFactory.getNewNode(NodeConstants.Types.ACCESS); accessNode.addGroups(child.getFirstChild().getGroups()); child.getFirstChild().addAsParent(accessNode); new RulePushSelectCriteria().execute(root, metadata, new DefaultCapabilitiesFinder(), new RuleStack(), AnalysisRecord.createNonRecordingRecord(), cc); accessNode = NodeEditor.findNodePreOrder(root, NodeConstants.Types.ACCESS); assertEquals(NodeConstants.Types.SELECT, accessNode.getParent().getType()); assertNull(NodeEditor.findNodePreOrder(accessNode, NodeConstants.Types.SELECT)); }
public PlanNode execute(PlanNode plan, QueryMetadataInterface metadata, CapabilitiesFinder capFinder, RuleStack rules, AnalysisRecord analysisRecord, CommandContext context) throws QueryPlannerException, QueryMetadataException, TeiidComponentException { boolean movedAnyNode = true; Set<PlanNode> deadNodes = new HashSet<PlanNode>(); while(movedAnyNode) { movedAnyNode = false; List<PlanNode> critNodes = NodeEditor.findAllNodes(plan, NodeConstants.Types.SELECT); Collections.reverse(critNodes); for (PlanNode critNode : critNodes) { boolean isPhantom = critNode.hasBooleanProperty(NodeConstants.Info.IS_PHANTOM); boolean isCopied = critNode.hasBooleanProperty(NodeConstants.Info.IS_COPIED); boolean isPushed = critNode.hasBooleanProperty(NodeConstants.Info.IS_PUSHED); if (isPhantom || isCopied || isPushed || deadNodes.contains(critNode)) { continue; } PlanNode sourceNode = findOriginatingNode(metadata, capFinder, critNode, analysisRecord); if(sourceNode == null) { deadNodes.add(critNode); continue; } boolean moved = pushTowardOriginatingNode(sourceNode, critNode, metadata, capFinder); if(critNode.hasBooleanProperty(Info.IS_PUSHED) || (critNode.getGroups().isEmpty() && critNode.getSubqueryContainers().isEmpty()) || !atBoundary(critNode, sourceNode)) { deadNodes.add(critNode); movedAnyNode |= moved; continue; } switch (sourceNode.getType()) { case NodeConstants.Types.SOURCE: { Boolean acrossFrame = pushAcrossFrame(sourceNode, critNode, metadata, capFinder, context); if (acrossFrame != null) { moved = acrossFrame; } else { movedAnyNode = true; } break; } case NodeConstants.Types.JOIN: { if (NodeEditor.findParent(critNode, NodeConstants.Types.ACCESS) == null && critNode.getSubqueryContainers().isEmpty()) { moved = handleJoinCriteria(sourceNode, critNode, metadata); } break; } case NodeConstants.Types.GROUP: { moved = pushAcrossGroupBy(sourceNode, critNode, metadata, true, capFinder); } } if (!moved) { deadNodes.add(critNode); } else { movedAnyNode = true; } } } return plan; }
RulePushSelectCriteria implements OptimizerRule { public PlanNode execute(PlanNode plan, QueryMetadataInterface metadata, CapabilitiesFinder capFinder, RuleStack rules, AnalysisRecord analysisRecord, CommandContext context) throws QueryPlannerException, QueryMetadataException, TeiidComponentException { boolean movedAnyNode = true; Set<PlanNode> deadNodes = new HashSet<PlanNode>(); while(movedAnyNode) { movedAnyNode = false; List<PlanNode> critNodes = NodeEditor.findAllNodes(plan, NodeConstants.Types.SELECT); Collections.reverse(critNodes); for (PlanNode critNode : critNodes) { boolean isPhantom = critNode.hasBooleanProperty(NodeConstants.Info.IS_PHANTOM); boolean isCopied = critNode.hasBooleanProperty(NodeConstants.Info.IS_COPIED); boolean isPushed = critNode.hasBooleanProperty(NodeConstants.Info.IS_PUSHED); if (isPhantom || isCopied || isPushed || deadNodes.contains(critNode)) { continue; } PlanNode sourceNode = findOriginatingNode(metadata, capFinder, critNode, analysisRecord); if(sourceNode == null) { deadNodes.add(critNode); continue; } boolean moved = pushTowardOriginatingNode(sourceNode, critNode, metadata, capFinder); if(critNode.hasBooleanProperty(Info.IS_PUSHED) || (critNode.getGroups().isEmpty() && critNode.getSubqueryContainers().isEmpty()) || !atBoundary(critNode, sourceNode)) { deadNodes.add(critNode); movedAnyNode |= moved; continue; } switch (sourceNode.getType()) { case NodeConstants.Types.SOURCE: { Boolean acrossFrame = pushAcrossFrame(sourceNode, critNode, metadata, capFinder, context); if (acrossFrame != null) { moved = acrossFrame; } else { movedAnyNode = true; } break; } case NodeConstants.Types.JOIN: { if (NodeEditor.findParent(critNode, NodeConstants.Types.ACCESS) == null && critNode.getSubqueryContainers().isEmpty()) { moved = handleJoinCriteria(sourceNode, critNode, metadata); } break; } case NodeConstants.Types.GROUP: { moved = pushAcrossGroupBy(sourceNode, critNode, metadata, true, capFinder); } } if (!moved) { deadNodes.add(critNode); } else { movedAnyNode = true; } } } return plan; } }
RulePushSelectCriteria implements OptimizerRule { public PlanNode execute(PlanNode plan, QueryMetadataInterface metadata, CapabilitiesFinder capFinder, RuleStack rules, AnalysisRecord analysisRecord, CommandContext context) throws QueryPlannerException, QueryMetadataException, TeiidComponentException { boolean movedAnyNode = true; Set<PlanNode> deadNodes = new HashSet<PlanNode>(); while(movedAnyNode) { movedAnyNode = false; List<PlanNode> critNodes = NodeEditor.findAllNodes(plan, NodeConstants.Types.SELECT); Collections.reverse(critNodes); for (PlanNode critNode : critNodes) { boolean isPhantom = critNode.hasBooleanProperty(NodeConstants.Info.IS_PHANTOM); boolean isCopied = critNode.hasBooleanProperty(NodeConstants.Info.IS_COPIED); boolean isPushed = critNode.hasBooleanProperty(NodeConstants.Info.IS_PUSHED); if (isPhantom || isCopied || isPushed || deadNodes.contains(critNode)) { continue; } PlanNode sourceNode = findOriginatingNode(metadata, capFinder, critNode, analysisRecord); if(sourceNode == null) { deadNodes.add(critNode); continue; } boolean moved = pushTowardOriginatingNode(sourceNode, critNode, metadata, capFinder); if(critNode.hasBooleanProperty(Info.IS_PUSHED) || (critNode.getGroups().isEmpty() && critNode.getSubqueryContainers().isEmpty()) || !atBoundary(critNode, sourceNode)) { deadNodes.add(critNode); movedAnyNode |= moved; continue; } switch (sourceNode.getType()) { case NodeConstants.Types.SOURCE: { Boolean acrossFrame = pushAcrossFrame(sourceNode, critNode, metadata, capFinder, context); if (acrossFrame != null) { moved = acrossFrame; } else { movedAnyNode = true; } break; } case NodeConstants.Types.JOIN: { if (NodeEditor.findParent(critNode, NodeConstants.Types.ACCESS) == null && critNode.getSubqueryContainers().isEmpty()) { moved = handleJoinCriteria(sourceNode, critNode, metadata); } break; } case NodeConstants.Types.GROUP: { moved = pushAcrossGroupBy(sourceNode, critNode, metadata, true, capFinder); } } if (!moved) { deadNodes.add(critNode); } else { movedAnyNode = true; } } } return plan; }  }
RulePushSelectCriteria implements OptimizerRule { public PlanNode execute(PlanNode plan, QueryMetadataInterface metadata, CapabilitiesFinder capFinder, RuleStack rules, AnalysisRecord analysisRecord, CommandContext context) throws QueryPlannerException, QueryMetadataException, TeiidComponentException { boolean movedAnyNode = true; Set<PlanNode> deadNodes = new HashSet<PlanNode>(); while(movedAnyNode) { movedAnyNode = false; List<PlanNode> critNodes = NodeEditor.findAllNodes(plan, NodeConstants.Types.SELECT); Collections.reverse(critNodes); for (PlanNode critNode : critNodes) { boolean isPhantom = critNode.hasBooleanProperty(NodeConstants.Info.IS_PHANTOM); boolean isCopied = critNode.hasBooleanProperty(NodeConstants.Info.IS_COPIED); boolean isPushed = critNode.hasBooleanProperty(NodeConstants.Info.IS_PUSHED); if (isPhantom || isCopied || isPushed || deadNodes.contains(critNode)) { continue; } PlanNode sourceNode = findOriginatingNode(metadata, capFinder, critNode, analysisRecord); if(sourceNode == null) { deadNodes.add(critNode); continue; } boolean moved = pushTowardOriginatingNode(sourceNode, critNode, metadata, capFinder); if(critNode.hasBooleanProperty(Info.IS_PUSHED) || (critNode.getGroups().isEmpty() && critNode.getSubqueryContainers().isEmpty()) || !atBoundary(critNode, sourceNode)) { deadNodes.add(critNode); movedAnyNode |= moved; continue; } switch (sourceNode.getType()) { case NodeConstants.Types.SOURCE: { Boolean acrossFrame = pushAcrossFrame(sourceNode, critNode, metadata, capFinder, context); if (acrossFrame != null) { moved = acrossFrame; } else { movedAnyNode = true; } break; } case NodeConstants.Types.JOIN: { if (NodeEditor.findParent(critNode, NodeConstants.Types.ACCESS) == null && critNode.getSubqueryContainers().isEmpty()) { moved = handleJoinCriteria(sourceNode, critNode, metadata); } break; } case NodeConstants.Types.GROUP: { moved = pushAcrossGroupBy(sourceNode, critNode, metadata, true, capFinder); } } if (!moved) { deadNodes.add(critNode); } else { movedAnyNode = true; } } } return plan; }  List<PlanNode> getCreatedNodes(); void setCreatedNodes(List<PlanNode> createdNodes); PlanNode execute(PlanNode plan, QueryMetadataInterface metadata, CapabilitiesFinder capFinder, RuleStack rules, AnalysisRecord analysisRecord, CommandContext context); String toString(); }
RulePushSelectCriteria implements OptimizerRule { public PlanNode execute(PlanNode plan, QueryMetadataInterface metadata, CapabilitiesFinder capFinder, RuleStack rules, AnalysisRecord analysisRecord, CommandContext context) throws QueryPlannerException, QueryMetadataException, TeiidComponentException { boolean movedAnyNode = true; Set<PlanNode> deadNodes = new HashSet<PlanNode>(); while(movedAnyNode) { movedAnyNode = false; List<PlanNode> critNodes = NodeEditor.findAllNodes(plan, NodeConstants.Types.SELECT); Collections.reverse(critNodes); for (PlanNode critNode : critNodes) { boolean isPhantom = critNode.hasBooleanProperty(NodeConstants.Info.IS_PHANTOM); boolean isCopied = critNode.hasBooleanProperty(NodeConstants.Info.IS_COPIED); boolean isPushed = critNode.hasBooleanProperty(NodeConstants.Info.IS_PUSHED); if (isPhantom || isCopied || isPushed || deadNodes.contains(critNode)) { continue; } PlanNode sourceNode = findOriginatingNode(metadata, capFinder, critNode, analysisRecord); if(sourceNode == null) { deadNodes.add(critNode); continue; } boolean moved = pushTowardOriginatingNode(sourceNode, critNode, metadata, capFinder); if(critNode.hasBooleanProperty(Info.IS_PUSHED) || (critNode.getGroups().isEmpty() && critNode.getSubqueryContainers().isEmpty()) || !atBoundary(critNode, sourceNode)) { deadNodes.add(critNode); movedAnyNode |= moved; continue; } switch (sourceNode.getType()) { case NodeConstants.Types.SOURCE: { Boolean acrossFrame = pushAcrossFrame(sourceNode, critNode, metadata, capFinder, context); if (acrossFrame != null) { moved = acrossFrame; } else { movedAnyNode = true; } break; } case NodeConstants.Types.JOIN: { if (NodeEditor.findParent(critNode, NodeConstants.Types.ACCESS) == null && critNode.getSubqueryContainers().isEmpty()) { moved = handleJoinCriteria(sourceNode, critNode, metadata); } break; } case NodeConstants.Types.GROUP: { moved = pushAcrossGroupBy(sourceNode, critNode, metadata, true, capFinder); } } if (!moved) { deadNodes.add(critNode); } else { movedAnyNode = true; } } } return plan; }  List<PlanNode> getCreatedNodes(); void setCreatedNodes(List<PlanNode> createdNodes); PlanNode execute(PlanNode plan, QueryMetadataInterface metadata, CapabilitiesFinder capFinder, RuleStack rules, AnalysisRecord analysisRecord, CommandContext context); String toString();  }