private void addBranchLimit(PlanNode limitNode, List<PlanNode> limitNodes, QueryMetadataInterface metadata, Expression parentLimit, Expression parentOffset, PlanNode grandChild) { PlanNode newLimit = newLimit(limitNode); newLimit.setProperty(NodeConstants.Info.MAX_TUPLE_LIMIT, op(SourceSystemFunctions.ADD_OP, parentLimit, parentOffset, metadata.getFunctionLibrary())); grandChild.addAsParent(newLimit); newLimit.setProperty(NodeConstants.Info.OUTPUT_COLS, newLimit.getFirstChild().getProperty(NodeConstants.Info.OUTPUT_COLS)); if (NodeEditor.findParent(newLimit, NodeConstants.Types.ACCESS) == null) { limitNodes.add(newLimit); } if (grandChild.getType() == NodeConstants.Types.SET_OP) { newLimit.setProperty(Info.IS_COPIED, true); } newLimit.setProperty(Info.IS_PUSHED, true); }
private PlanNode createJoinNode(PlanNode accessNode1, PlanNode accessNode2, List<Criteria> joinCriteria, JoinType joinType) { PlanNode joinNode = createJoinNode(); joinNode.getGroups().addAll(accessNode1.getGroups()); joinNode.getGroups().addAll(accessNode2.getGroups()); joinNode.addFirstChild(accessNode2); joinNode.addLastChild(accessNode1); joinNode.setProperty(NodeConstants.Info.JOIN_TYPE, joinType); joinNode.setProperty(NodeConstants.Info.JOIN_CRITERIA, joinCriteria); return joinNode; }
/** * Add the node as this node's parent. * @param node */ public void addAsParent(PlanNode node) { modified = true; if (this.parent != null) { this.parent.replaceChild(this, node); } assert node.getChildCount() == 0; node.addLastChild(this); }
/** * all of child's children become children of parent */ public static final void removeChildNode(PlanNode parent, PlanNode child) { if (child.getChildCount() == 0) { parent.removeChild(child); } else if (child.getChildCount() == 1){ PlanNode grandChild = child.getFirstChild(); parent.replaceChild(child, grandChild); } else { throw new AssertionError("Cannot promote a multinode child"); //$NON-NLS-1$ } }
private void updateGroups(PlanNode node) { node.addGroups(GroupsUsedByElementsVisitor.getGroups(node.getCorrelatedReferenceElements())); node.addGroups(FrameUtil.findJoinSourceNode(node.getFirstChild()).getGroups()); node.addGroups(FrameUtil.findJoinSourceNode(node.getLastChild()).getGroups()); }
static PlanNode createSource(GroupSymbol group, PlanNode child, List<ElementSymbol> newProject) { PlanNode branchSource = NodeFactory.getNewNode(NodeConstants.Types.SOURCE); branchSource.addGroup(group); PlanNode projectNode = NodeEditor.findNodePreOrder(child, NodeConstants.Types.PROJECT); branchSource.setProperty(Info.SYMBOL_MAP, SymbolMap.createSymbolMap(newProject, (List<? extends Expression>)projectNode.getProperty(Info.PROJECT_COLS))); child.addAsParent(branchSource); return branchSource; }
FromClause fromClause = mergeClauseTrees(query.getFrom()); PlanNode dummyRoot = new PlanNode(); plan = dummyRoot.getFirstChild(); hints.hasJoin |= plan.getType() == NodeConstants.Types.JOIN; plan.setProperty(Info.HAS_WINDOW_FUNCTIONS, true);
@Test public void testProjectLiteral4() throws Exception { PlanNode project = NodeFactory.getNewNode(NodeConstants.Types.PROJECT); project.setProperty(Info.PROJECT_COLS, Arrays.asList(new Constant(1))); PlanNode access = NodeFactory.getNewNode(NodeConstants.Types.ACCESS); project.addFirstChild(access); access.setProperty(NodeConstants.Info.EST_CARDINALITY, NewCalculateCostUtil.UNKNOWN_VALUE); PlanNode dup = NodeFactory.getNewNode(NodeConstants.Types.DUP_REMOVE); dup.addFirstChild(project); float cost = NewCalculateCostUtil.computeCostForTree(dup, RealMetadataFactory.example1Cached()); assertEquals(NewCalculateCostUtil.UNKNOWN_VALUE, cost, 0); ColStats colStats = (ColStats)dup.getProperty(Info.EST_COL_STATS); assertEquals("{1=[1.0, 1.0, 0.0]}", colStats.toString()); }
private static void estimateSetOpCost(PlanNode node, QueryMetadataInterface metadata) throws QueryMetadataException, TeiidComponentException { float cost = 0; SetQuery.Operation op = (SetQuery.Operation)node.getProperty(NodeConstants.Info.SET_OPERATION); float leftCost = (Float)node.getFirstChild().getProperty(NodeConstants.Info.EST_CARDINALITY); float rightCost = (Float)node.getLastChild().getProperty(NodeConstants.Info.EST_CARDINALITY); if (!node.hasBooleanProperty(NodeConstants.Info.USE_ALL)) { leftCost = getDistinctEstimate(node.getFirstChild(), metadata, leftCost); rightCost = getDistinctEstimate(node.getLastChild(), metadata, rightCost); } cost = getCombinedSetEstimate(op, leftCost, rightCost, !node.hasBooleanProperty(NodeConstants.Info.USE_ALL)); setCardinalityEstimate(node, new Float(cost), true, metadata); }
/** * Can be called after join planning on a join node to get the inner sides of the join * @param joinNode * @return */ static PlanNode[] getInnerSideJoinNodes(PlanNode joinNode) { Assertion.assertTrue(joinNode.getType() == NodeConstants.Types.JOIN); JoinType jt = (JoinType)joinNode.getProperty(NodeConstants.Info.JOIN_TYPE); if (jt == JoinType.JOIN_INNER || jt == JoinType.JOIN_CROSS) { return new PlanNode[] {joinNode.getFirstChild(), joinNode.getLastChild()}; } if (jt == JoinType.JOIN_RIGHT_OUTER) { return new PlanNode[] {joinNode.getFirstChild()}; } if (jt == JoinType.JOIN_LEFT_OUTER) { return new PlanNode[] {joinNode.getLastChild()}; } //must be full outer, so there is no inner side return new PlanNode[] {}; }
@Test public void testValidJoin2() throws Exception { PlanNode accessNode = NodeFactory.getNewNode(NodeConstants.Types.ACCESS); accessNode.addGroup(getPhysicalGroup(1)); PlanNode joinNode = NodeFactory.getNewNode(NodeConstants.Types.JOIN); joinNode.setProperty(NodeConstants.Info.JOIN_TYPE, JoinType.JOIN_FULL_OUTER); joinNode.setProperty(NodeConstants.Info.JOIN_CRITERIA, Arrays.asList(QueryRewriter.FALSE_CRITERIA)); joinNode.addFirstChild(accessNode); helpTestValidJoin(joinNode, accessNode, false); }
/** * Computes the cost of a Dependent Join * * The worst possible cost will arise from a high independent ndv (many dependent sets) and a low dependent ndv (possibly many matches per set) * * This logic uses the same assumption as criteria in that ndv is used as a divisor of cardinality. * @throws QueryPlannerException * */ public static DependentCostAnalysis computeCostForDepJoin(PlanNode joinNode, boolean leftIndependent, QueryMetadataInterface metadata, CapabilitiesFinder capFinder, CommandContext context) throws TeiidComponentException, QueryMetadataException, QueryPlannerException { PlanNode independentNode = leftIndependent?joinNode.getFirstChild():joinNode.getLastChild(); PlanNode dependentNode = leftIndependent?joinNode.getLastChild():joinNode.getFirstChild(); List independentExpressions = (List)(leftIndependent?joinNode.getProperty(NodeConstants.Info.LEFT_EXPRESSIONS):joinNode.getProperty(NodeConstants.Info.RIGHT_EXPRESSIONS)); List dependentExpressions = (List)(leftIndependent?joinNode.getProperty(NodeConstants.Info.RIGHT_EXPRESSIONS):joinNode.getProperty(NodeConstants.Info.LEFT_EXPRESSIONS)); return computeCostForDepJoin(independentNode, dependentNode, independentExpressions, dependentExpressions, metadata, capFinder, context); }
private static final void findAllNodesHelper(PlanNode node, int types, List<PlanNode> foundNodes, int stopTypes) { if((node.getType() & types) == node.getType()) { foundNodes.add(node); } if(node.getChildCount() > 0 && (stopTypes == NodeConstants.Types.NO_TYPE || (stopTypes & node.getType()) != node.getType() ) ) { for (PlanNode child : node.getChildren()) { findAllNodesHelper(child, types, foundNodes, stopTypes); } } }
static boolean isProcedure(PlanNode projectNode) { if(projectNode != null && projectNode.getType() == NodeConstants.Types.PROJECT && projectNode.getChildCount() > 0) { PlanNode accessNode = projectNode.getFirstChild(); Command command = getNonQueryCommand(accessNode); return command instanceof StoredProcedure; } return false; }
static PlanNode performRaise(PlanNode rootNode, PlanNode accessNode, PlanNode parentNode) { if (!checkConformedSubqueries(accessNode, parentNode, true)) { return rootNode; } accessNode.removeProperty(NodeConstants.Info.EST_CARDINALITY); combineSourceHints(accessNode, parentNode); NodeEditor.removeChildNode(parentNode, accessNode); parentNode.addAsParent(accessNode); PlanNode grandparentNode = accessNode.getParent(); if(grandparentNode != null) { return rootNode; } return accessNode; }
private void setCriteria(DependentSetCriteria dsc, PlanNode copyNode) { copyNode.setProperty(NodeConstants.Info.SELECT_CRITERIA, dsc); copyNode.getGroups().clear(); copyNode.addGroups(GroupsUsedByElementsVisitor.getGroups(dsc)); }
private boolean clean(PlanNode plan, boolean removeAllPhantom) throws TeiidComponentException { boolean pushRaiseNull = false; plan.setProperty(Info.OUTPUT_COLS, null); for (PlanNode node : plan.getChildren()) { pushRaiseNull |= clean(node, removeAllPhantom); } if (plan.getType() == NodeConstants.Types.SELECT) { pushRaiseNull |= cleanCriteria(plan, removeAllPhantom); } return pushRaiseNull; }
@Test public void testValidJoin6() throws Exception { PlanNode accessNode1 = NodeFactory.getNewNode(NodeConstants.Types.ACCESS); PlanNode accessNode2 = NodeFactory.getNewNode(NodeConstants.Types.ACCESS); accessNode1.addGroup(getPhysicalGroup(1)); accessNode2.addGroup(getPhysicalGroup(2)); PlanNode joinNode = NodeFactory.getNewNode(NodeConstants.Types.JOIN); joinNode.setProperty(NodeConstants.Info.JOIN_TYPE, JoinType.JOIN_LEFT_OUTER); List crits = new ArrayList(); crits.add(new CompareCriteria(getElementSymbol(1,1), CompareCriteria.EQ, getElementSymbol(2,1))); joinNode.setProperty(NodeConstants.Info.JOIN_CRITERIA, crits); joinNode.addLastChild(accessNode1); joinNode.addLastChild(accessNode2); helpTestValidJoin(joinNode, accessNode2, true); }
private void connectSubqueryContainers(PlanNode plan, boolean skipPlanning) throws QueryPlannerException, QueryMetadataException, TeiidComponentException { for (PlanNode node : getAllPossibleSubqueryNodes(plan)) { Set<GroupSymbol> groupSymbols = getGroupSymbols(node); List<SubqueryContainer<?>> subqueryContainers = node.getSubqueryContainers(); planSubqueries(groupSymbols, node, subqueryContainers, false, skipPlanning); node.addGroups(GroupsUsedByElementsVisitor.getGroups(node.getCorrelatedReferenceElements())); } }