use of org.teiid.query.sql.lang.OrderByItem in project teiid by teiid.
the class RuleAssignOutputElements method determineSourceOutput.
/**
* A special case to consider is when the virtual group is defined by a
* UNION (no ALL) or a SELECT DISTINCT. In this case, the dup removal means
* that all columns need to be used to determine duplicates. So, filtering the
* columns at all will alter the number of rows flowing through the frame.
* So, in this case filtering should not occur. In fact the output columns
* that were set on root above are filtered, but we actually want all the
* virtual elements - so just reset it and proceed as before
* @throws TeiidComponentException
* @throws QueryMetadataException
* @throws QueryPlannerException
*/
static List<? extends Expression> determineSourceOutput(PlanNode root, List<Expression> outputElements, QueryMetadataInterface metadata, CapabilitiesFinder capFinder) throws QueryMetadataException, TeiidComponentException, QueryPlannerException {
PlanNode virtualRoot = root.getLastChild();
if (hasDupRemoval(virtualRoot)) {
// Reset the outputColumns for this source node to be all columns for the virtual group
SymbolMap symbolMap = (SymbolMap) root.getProperty(NodeConstants.Info.SYMBOL_MAP);
if (!symbolMap.asMap().keySet().containsAll(outputElements)) {
outputElements.removeAll(symbolMap.asMap().keySet());
throw new QueryPlannerException(QueryPlugin.Event.TEIID30259, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30259, outputElements));
}
return symbolMap.getKeys();
}
PlanNode limit = NodeEditor.findNodePreOrder(root, NodeConstants.Types.TUPLE_LIMIT, NodeConstants.Types.PROJECT);
if (limit == null) {
return outputElements;
}
// reset the output elements to be the output columns + what's required by the sort
PlanNode sort = NodeEditor.findNodePreOrder(limit, NodeConstants.Types.SORT, NodeConstants.Types.PROJECT);
if (sort == null) {
return outputElements;
}
PlanNode access = NodeEditor.findParent(sort, NodeConstants.Types.ACCESS);
if (sort.hasBooleanProperty(NodeConstants.Info.UNRELATED_SORT) || (access != null && capFinder != null && CapabilitiesUtil.supports(Capability.QUERY_ORDERBY_UNRELATED, RuleRaiseAccess.getModelIDFromAccess(access, metadata), metadata, capFinder))) {
return outputElements;
}
OrderBy sortOrder = (OrderBy) sort.getProperty(NodeConstants.Info.SORT_ORDER);
List<Expression> topCols = FrameUtil.findTopCols(sort);
SymbolMap symbolMap = (SymbolMap) root.getProperty(NodeConstants.Info.SYMBOL_MAP);
List<ElementSymbol> symbolOrder = symbolMap.getKeys();
for (OrderByItem item : sortOrder.getOrderByItems()) {
final Expression expr = item.getSymbol();
int index = topCols.indexOf(expr);
if (index < 0) {
continue;
}
ElementSymbol symbol = symbolOrder.get(index);
if (!outputElements.contains(symbol)) {
outputElements.add(symbol);
}
}
return outputElements;
}
use of org.teiid.query.sql.lang.OrderByItem in project teiid by teiid.
the class WindowFunctionProjectNode method init.
/**
* This state can be determined prior to initialize and is the same for all nodes,
* so it is moved into it's own init routine
*/
public void init() {
expressionIndexes = new LinkedHashMap<Expression, Integer>();
for (int i = 0; i < getElements().size(); i++) {
Expression ex = SymbolMap.getExpression(getElements().get(i));
if (ex instanceof WindowFunction) {
WindowFunction wf = (WindowFunction) ex;
WindowSpecification ws = wf.getWindowSpecification();
WindowSpecificationInfo wsi = windows.get(ws);
if (wsi == null) {
wsi = new WindowSpecificationInfo();
windows.put(wf.getWindowSpecification(), wsi);
if (ws.getPartition() != null) {
for (Expression ex1 : ws.getPartition()) {
Integer index = GroupingNode.getIndex(ex1, expressionIndexes);
wsi.groupIndexes.add(index);
wsi.orderType.add(OrderBy.ASC);
wsi.nullOrderings.add(null);
}
}
if (ws.getOrderBy() != null) {
for (OrderByItem item : ws.getOrderBy().getOrderByItems()) {
Expression ex1 = SymbolMap.getExpression(item.getSymbol());
Integer index = GroupingNode.getIndex(ex1, expressionIndexes);
wsi.sortIndexes.add(index);
wsi.orderType.add(item.isAscending());
wsi.nullOrderings.add(item.getNullOrdering());
}
}
}
WindowFunctionInfo wfi = new WindowFunctionInfo();
wfi.function = wf;
// collect the agg expressions
for (Expression e : wf.getFunction().getArgs()) {
GroupingNode.getIndex(e, expressionIndexes);
}
if (wf.getFunction().getOrderBy() != null) {
for (OrderByItem item : wf.getFunction().getOrderBy().getOrderByItems()) {
GroupingNode.getIndex(item.getSymbol(), expressionIndexes);
}
}
if (wf.getFunction().getCondition() != null) {
GroupingNode.getIndex(wf.getFunction().getCondition(), expressionIndexes);
}
wfi.outputIndex = i;
if (wf.getFunction().isRowValueFunction()) {
wsi.rowValuefunctions.add(wfi);
} else {
wsi.functions.add(wfi);
}
} else {
int index = GroupingNode.getIndex(ex, expressionIndexes);
passThrough.add(new int[] { i, index });
}
}
}
use of org.teiid.query.sql.lang.OrderByItem in project teiid by teiid.
the class GroupingNode method collectionPhase.
private void collectionPhase() {
if (this.orderBy == null) {
// No need to sort
this.groupTupleSource = getGroupSortTupleSource();
this.phase = GROUP;
} else {
List<NullOrdering> nullOrdering = new ArrayList<NullOrdering>(orderBy.size());
List<Boolean> sortTypes = new ArrayList<Boolean>(orderBy.size());
int size = orderBy.size();
if (this.removeDuplicates) {
// sort on all inputs
size = distinctCols;
}
int[] sortIndexes = new int[size];
for (int i = 0; i < size; i++) {
int index = i;
if (i < this.orderBy.size()) {
OrderByItem item = this.orderBy.get(i);
nullOrdering.add(item.getNullOrdering());
sortTypes.add(item.isAscending());
index = collectedExpressions.get(SymbolMap.getExpression(item.getSymbol()));
} else {
nullOrdering.add(null);
sortTypes.add(OrderBy.ASC);
}
sortIndexes[i] = index;
}
this.indexes = Arrays.copyOf(sortIndexes, orderBy.size());
if (rollup) {
this.indexMap = new HashMap<Integer, Integer>();
for (int i = 0; i < indexes.length; i++) {
this.indexMap.put(indexes[i], orderBy.size() - i);
}
} else if (!removeDuplicates) {
boolean groupSort = true;
List<AggregateFunction> aggs = new ArrayList<AggregateFunction>();
List<Class<?>> allTypes = new ArrayList<Class<?>>();
accumulatorStateCount = new int[this.functions.length];
for (AggregateFunction[] afs : this.functions) {
if (afs[0] instanceof ConstantFunction) {
continue;
}
aggs.add(afs[0]);
List<? extends Class<?>> types = afs[0].getStateTypes();
if (types == null) {
groupSort = false;
break;
}
accumulatorStateCount[aggs.size() - 1] = types.size();
allTypes.addAll(types);
}
if (groupSort) {
this.groupSortfunctions = aggs.toArray(new AggregateFunction[aggs.size()]);
List<Expression> schema = new ArrayList<Expression>();
for (OrderByItem item : this.orderBy) {
schema.add(SymbolMap.getExpression(item.getSymbol()));
}
List<? extends Expression> elements = getElements();
this.projection = new int[elements.size()];
int index = 0;
for (int i = 0; i < elements.size(); i++) {
Expression symbol = elements.get(i);
if (this.outputMapping != null) {
symbol = outputMapping.getMappedExpression((ElementSymbol) symbol);
}
if (symbol instanceof AggregateSymbol) {
projection[i] = schema.size() + index++;
} else {
projection[i] = schema.indexOf(symbol);
}
}
// add in accumulator value types
for (Class<?> type : allTypes) {
ElementSymbol es = new ElementSymbol("x");
es.setType(type);
schema.add(es);
}
tree = this.getBufferManager().createSTree(schema, this.getConnectionID(), orderBy.size());
// non-default order needs to update the comparator
tree.getComparator().setNullOrdering(nullOrdering);
tree.getComparator().setOrderTypes(sortTypes);
this.groupSortTupleSource = this.getGroupSortTupleSource();
this.phase = GROUP_SORT;
return;
}
}
this.sortUtility = new SortUtility(getGroupSortTupleSource(), removeDuplicates ? Mode.DUP_REMOVE_SORT : Mode.SORT, getBufferManager(), getConnectionID(), new ArrayList<Expression>(collectedExpressions.keySet()), sortTypes, nullOrdering, sortIndexes);
this.phase = SORT;
}
}
Aggregations