return plan;
}
boolean canPushLimit(PlanNode rootNode, PlanNode limitNode, List<PlanNode> limitNodes, QueryMetadataInterface metadata, CapabilitiesFinder capFinder) throws QueryMetadataException, TeiidComponentException {
PlanNode child = limitNode.getFirstChild();
if (child == null || child.getChildCount() == 0) {
return false;
}
Expression parentLimit = (Expression)limitNode.getProperty(NodeConstants.Info.MAX_TUPLE_LIMIT);
Expression parentOffset = (Expression)limitNode.getProperty(NodeConstants.Info.OFFSET_TUPLE_COUNT);
switch (child.getType()) {
case NodeConstants.Types.TUPLE_LIMIT:
{
//combine the limits
Expression childLimit = (Expression)child.getProperty(NodeConstants.Info.MAX_TUPLE_LIMIT);
Expression childOffset = (Expression)child.getProperty(NodeConstants.Info.OFFSET_TUPLE_COUNT);
combineLimits(limitNode, metadata, parentLimit, parentOffset, childLimit, childOffset);
NodeEditor.removeChildNode(limitNode, child);
limitNodes.remove(child);
return canPushLimit(rootNode, limitNode, limitNodes, metadata, capFinder);
}
case NodeConstants.Types.SET_OP:
{
if (!SetQuery.Operation.UNION.equals(child.getProperty(NodeConstants.Info.SET_OPERATION))
|| !child.hasBooleanProperty(NodeConstants.Info.USE_ALL)) {
return false;
}
//distribute the limit
List<PlanNode> grandChildren = new LinkedList<PlanNode>(child.getChildren());
for (PlanNode grandChild : grandChildren) {
PlanNode newLimit = NodeFactory.getNewNode(NodeConstants.Types.TUPLE_LIMIT);
newLimit.setProperty(NodeConstants.Info.MAX_TUPLE_LIMIT, op(SourceSystemFunctions.ADD_OP, parentLimit, parentOffset, metadata.getFunctionLibrary()));
grandChild.addAsParent(newLimit);
limitNodes.add(newLimit);
}
return false;