use of org.teiid.query.sql.symbol.AggregateSymbol in project teiid by teiid.
the class AccessNode method multiSourceModify.
private static RelationalNode multiSourceModify(AccessNode accessNode, Expression ex, QueryMetadataInterface metadata, List<String> sourceNames) throws TeiidComponentException, TeiidProcessingException {
List<AccessNode> accessNodes = new ArrayList<AccessNode>();
boolean hasOutParams = RelationalNodeUtil.hasOutputParams(accessNode.getCommand());
if (!Constant.NULL_CONSTANT.equals(ex)) {
for (String sourceName : sourceNames) {
Command command = accessNode.getCommand();
// Modify the command to pull the instance column and evaluate the criteria
if (!(command instanceof Insert || command instanceof StoredProcedure)) {
command = (Command) command.clone();
MultiSourceElementReplacementVisitor.visit(sourceName, metadata, command);
if (!RelationalNodeUtil.shouldExecute(command, false, true)) {
continue;
}
}
// Create a new cloned version of the access node and set it's model name to be the bindingUUID
AccessNode instanceNode = (AccessNode) accessNode.clone();
instanceNode.setMultiSource(false);
instanceNode.setCommand(command);
accessNodes.add(instanceNode);
if (accessNodes.size() > 1 && command instanceof Insert) {
// $NON-NLS-1$
throw new AssertionError("Multi-source insert must target a single source. Should have been caught in validation");
}
instanceNode.setConnectorBindingId(sourceName);
}
}
if (hasOutParams && accessNodes.size() != 1) {
throw new QueryProcessingException(QueryPlugin.Event.TEIID30561, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30561, accessNode.getCommand()));
}
switch(accessNodes.size()) {
case 0:
{
if (RelationalNodeUtil.isUpdate(accessNode.getCommand())) {
// should return a 0 update count
ProjectNode pnode = new ProjectNode(accessNode.getID());
pnode.setSelectSymbols(Arrays.asList(new Constant(0)));
return pnode;
}
// Replace existing access node with a NullNode
NullNode nullNode = new NullNode(accessNode.getID());
return nullNode;
}
case 1:
{
// Replace existing access node with new access node (simplified command)
return accessNodes.get(0);
}
default:
{
UnionAllNode unionNode = new UnionAllNode(accessNode.getID());
unionNode.setElements(accessNode.getElements());
for (AccessNode newNode : accessNodes) {
unionNode.addChild(newNode);
}
RelationalNode parent = unionNode;
// More than 1 access node - replace with a union
if (RelationalNodeUtil.isUpdate(accessNode.getCommand())) {
GroupingNode groupNode = new GroupingNode(accessNode.getID());
AggregateSymbol sumCount = new AggregateSymbol(NonReserved.SUM, false, accessNode.getElements().get(0));
groupNode.setElements(Arrays.asList(sumCount));
groupNode.addChild(unionNode);
ProjectNode projectNode = new ProjectNode(accessNode.getID());
Expression intSum = ResolverUtil.getConversion(sumCount, DataTypeManager.getDataTypeName(sumCount.getType()), DataTypeManager.DefaultDataTypes.INTEGER, false, metadata.getFunctionLibrary());
List<Expression> outputElements = Arrays.asList(intSum);
projectNode.setElements(outputElements);
projectNode.setSelectSymbols(outputElements);
projectNode.addChild(groupNode);
parent = projectNode;
}
return parent;
}
}
}
use of org.teiid.query.sql.symbol.AggregateSymbol 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;
}
}
use of org.teiid.query.sql.symbol.AggregateSymbol in project teiid by teiid.
the class TempTable method createTupleSource.
public TupleSource createTupleSource(final List<? extends Expression> projectedCols, final Criteria condition, OrderBy orderBy) throws TeiidComponentException, TeiidProcessingException {
// special handling for count(*)
boolean agg = false;
for (Expression singleElementSymbol : projectedCols) {
if (singleElementSymbol instanceof ExpressionSymbol && ((ExpressionSymbol) singleElementSymbol).getExpression() instanceof AggregateSymbol) {
agg = true;
break;
}
}
if (agg) {
if (condition == null) {
long count = this.getRowCount();
return new CollectionTupleSource(Arrays.asList(Collections.nCopies(projectedCols.size(), (int) Math.min(Integer.MAX_VALUE, count))).iterator());
}
orderBy = null;
}
IndexInfo primary = new IndexInfo(this, projectedCols, condition, orderBy, true);
IndexInfo ii = primary;
if ((indexTables != null || (!this.updatable && allowImplicitIndexing && condition != null && this.getRowCount() > 2 * this.getTree().getPageSize(true))) && (condition != null || orderBy != null) && ii.valueSet.size() != 1) {
// $NON-NLS-1$ //$NON-NLS-2$
LogManager.logDetail(LogConstants.CTX_DQP, "Considering indexes on table", this, "for query", projectedCols, condition, orderBy);
long rowCost = this.tree.getRowCount();
long bestCost = estimateCost(orderBy, ii, rowCost);
if (this.indexTables != null) {
for (TempTable table : this.indexTables.values()) {
IndexInfo secondary = new IndexInfo(table, projectedCols, condition, orderBy, false);
long cost = estimateCost(orderBy, secondary, rowCost);
if (cost < bestCost) {
ii = secondary;
bestCost = cost;
}
}
}
if (ii == primary && allowImplicitIndexing) {
// TODO: detect if it should be covering
if (createImplicitIndexIfNeeded(condition)) {
IndexInfo secondary = new IndexInfo(this.indexTables.values().iterator().next(), projectedCols, condition, orderBy, false);
// $NON-NLS-1$
LogManager.logDetail(LogConstants.CTX_DQP, "Created an implicit index ", secondary.table);
long cost = estimateCost(orderBy, secondary, rowCost);
if (cost < bestCost) {
ii = secondary;
bestCost = cost;
} else {
// $NON-NLS-1$ //$NON-NLS-2$
LogManager.logDetail(LogConstants.CTX_DQP, "Did not utilize the implicit index");
}
}
}
// $NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
LogManager.logDetail(LogConstants.CTX_DQP, "Choose index", ii.table, "covering:", ii.coveredCriteria, "ordering:", ii.ordering);
if (ii.covering) {
return ii.table.createTupleSource(projectedCols, condition, orderBy, ii, agg);
}
List<ElementSymbol> pkColumns = this.columns.subList(0, this.tree.getKeyLength());
if (ii.ordering != null) {
// use order and join
primary.valueTs = ii.table.createTupleSource(pkColumns, ii.coveredCriteria, orderBy, ii, agg);
primary.ordering = null;
return createTupleSource(projectedCols, ii.nonCoveredCriteria, null, primary, agg);
}
// order by pk to localize lookup costs, then join
OrderBy pkOrderBy = new OrderBy();
for (ElementSymbol elementSymbol : pkColumns) {
pkOrderBy.addVariable(elementSymbol);
}
primary.valueTs = ii.table.createTupleSource(pkColumns, ii.coveredCriteria, pkOrderBy, ii, agg);
return createTupleSource(projectedCols, ii.nonCoveredCriteria, orderBy, primary, agg);
}
return createTupleSource(projectedCols, condition, orderBy, ii, agg);
}
use of org.teiid.query.sql.symbol.AggregateSymbol in project teiid by teiid.
the class TestCapabilitiesUtil method testSupportsAggregate6.
// Test where capabilities support only COUNT
@Test
public void testSupportsAggregate6() throws Exception {
BasicSourceCapabilities caps = new BasicSourceCapabilities();
caps.setCapabilitySupport(Capability.QUERY_AGGREGATES, true);
caps.setCapabilitySupport(Capability.QUERY_AGGREGATES_COUNT, true);
caps.setCapabilitySupport(Capability.QUERY_AGGREGATES_COUNT_STAR, false);
// $NON-NLS-1$ //$NON-NLS-2$
AggregateSymbol aggregate = new AggregateSymbol(NonReserved.COUNT, false, new ElementSymbol("x"));
helpTestSupportsAggregateFunction(caps, aggregate, true);
}
use of org.teiid.query.sql.symbol.AggregateSymbol in project teiid by teiid.
the class TestCapabilitiesUtil method testSupportsAggregate2.
// Test where capabilities don't support COUNT
@Test
public void testSupportsAggregate2() throws Exception {
BasicSourceCapabilities caps = new BasicSourceCapabilities();
caps.setCapabilitySupport(Capability.QUERY_AGGREGATES, true);
caps.setCapabilitySupport(Capability.QUERY_AGGREGATES_COUNT, false);
caps.setCapabilitySupport(Capability.QUERY_AGGREGATES_COUNT_STAR, false);
// $NON-NLS-1$
AggregateSymbol aggregate = new AggregateSymbol(NonReserved.COUNT, false, null);
helpTestSupportsAggregateFunction(caps, aggregate, false);
}
Aggregations