use of org.teiid.query.processor.CollectionTupleSource in project teiid by teiid.
the class SourceTriggerActionPlanner method optimize.
@Override
public ProcessorPlan optimize(Command command, IDGenerator idGenerator, QueryMetadataInterface metadata, CapabilitiesFinder capFinder, AnalysisRecord analysisRecord, CommandContext context) throws QueryPlannerException, QueryMetadataException, TeiidComponentException {
SourceEventCommand sec = (SourceEventCommand) command;
Map<Expression, Integer> lookup = new HashMap<Expression, Integer>();
Map<ElementSymbol, Expression> params = new HashMap<ElementSymbol, Expression>();
List<Object> tuple = new ArrayList<Object>();
Map<String, Integer> map = null;
if (sec.getColumnNames() != null) {
map = new TreeMap<String, Integer>(String.CASE_INSENSITIVE_ORDER);
for (String name : sec.getColumnNames()) {
map.put(name, map.size());
}
}
GroupSymbol changingGroup = new GroupSymbol(ProcedureReservedWords.CHANGING);
if (sec.newValues != null) {
GroupSymbol newGroup = new GroupSymbol(SQLConstants.Reserved.NEW);
newGroup.setMetadataID(sec.table);
for (int i = 0; i < sec.getTable().getColumns().size(); i++) {
Column c = sec.getTable().getColumns().get(i);
Integer index = null;
if (map != null) {
index = map.get(c.getName());
} else {
index = i;
}
ElementSymbol newElement = new ElementSymbol(c.getName(), newGroup);
newElement.setMetadataID(c);
ElementSymbol changingElement = new ElementSymbol(c.getName(), changingGroup);
lookup.put(newElement, tuple.size());
lookup.put(changingElement, tuple.size() + 1);
params.put(newElement, newElement);
params.put(changingElement, changingElement);
if (index == null) {
// not changing
tuple.add(new Constant(null));
tuple.add(new Constant(Boolean.FALSE));
} else {
// changing
tuple.add(new Constant(DataTypeManager.convertToRuntimeType(sec.newValues[index], true)));
tuple.add(new Constant(Boolean.TRUE));
}
}
}
if (sec.oldValues != null) {
GroupSymbol oldGroup = new GroupSymbol(SQLConstants.Reserved.OLD);
oldGroup.setMetadataID(sec.table);
for (int i = 0; i < sec.getTable().getColumns().size(); i++) {
Column c = sec.getTable().getColumns().get(i);
Integer index = null;
if (map != null) {
index = map.get(c.getName());
} else {
index = i;
}
ElementSymbol oldElement = new ElementSymbol(c.getName(), oldGroup);
oldElement.setMetadataID(c);
lookup.put(oldElement, tuple.size());
params.put(oldElement, oldElement);
if (index != null) {
tuple.add(new Constant(DataTypeManager.convertToRuntimeType(sec.oldValues[index], true)));
}
}
}
List<ProcessorPlan> plans = new ArrayList<ProcessorPlan>();
List<String> names = new ArrayList<String>();
for (Trigger tr : sec.getTable().getTriggers().values()) {
int updateType = Command.TYPE_UPDATE;
switch(tr.getEvent()) {
case DELETE:
updateType = Command.TYPE_DELETE;
if (sec.newValues != null) {
continue;
}
break;
case INSERT:
updateType = Command.TYPE_INSERT;
if (sec.oldValues != null) {
continue;
}
break;
case UPDATE:
if (sec.oldValues == null || sec.newValues == null) {
continue;
}
break;
}
// create plan
ForEachRowPlan result = new ForEachRowPlan();
result.setSingleRow(true);
result.setParams(params);
TriggerAction parseProcedure;
GroupSymbol gs = new GroupSymbol(sec.table.getFullName());
try {
parseProcedure = (TriggerAction) QueryParser.getQueryParser().parseProcedure(tr.getPlan(), true);
QueryResolver.resolveCommand(parseProcedure, gs, updateType, metadata.getDesignTimeMetadata(), false);
} catch (QueryParserException e) {
// should have been validated
throw new TeiidComponentException(e);
} catch (QueryResolverException e) {
// should have been validated
throw new TeiidComponentException(e);
}
CreateProcedureCommand cpc = new CreateProcedureCommand(parseProcedure.getBlock());
gs.setMetadataID(sec.table);
cpc.setVirtualGroup(gs);
cpc.setUpdateType(updateType);
ProcedurePlan rowProcedure = (ProcedurePlan) QueryOptimizer.optimizePlan(cpc, metadata, idGenerator, capFinder, analysisRecord, context);
rowProcedure.setRunInContext(false);
result.setRowProcedure(rowProcedure);
result.setLookupMap(lookup);
result.setTupleSource(new CollectionTupleSource(Arrays.asList(tuple).iterator()));
plans.add(result);
names.add(tr.getName());
}
return new CompositeProcessorPlan(plans, names, sec.table);
}
use of org.teiid.query.processor.CollectionTupleSource in project teiid by teiid.
the class TempTableDataManager method registerRequest.
TupleSource registerRequest(final CommandContext context, String modelName, final Command command) throws TeiidComponentException, TeiidProcessingException {
final TempTableStore contextStore = context.getTempTableStore();
if (command instanceof Query) {
Query query = (Query) command;
if (modelName != null && !modelName.equals(TempMetadataAdapter.TEMP_MODEL.getID())) {
return null;
}
return registerQuery(context, contextStore, query);
}
if (command instanceof ProcedureContainer) {
if (command instanceof StoredProcedure) {
StoredProcedure proc = (StoredProcedure) command;
if (CoreConstants.SYSTEM_ADMIN_MODEL.equals(modelName)) {
TupleSource result = handleSystemProcedures(context, proc);
if (result != null) {
return result;
}
} else if (proc.getGroup().isGlobalTable()) {
return handleCachedProcedure(context, proc);
}
// it's not a stored procedure we want to handle
return null;
}
final GroupSymbol group = ((ProcedureContainer) command).getGroup();
if (!modelName.equals(TempMetadataAdapter.TEMP_MODEL.getID()) || !group.isTempGroupSymbol()) {
return null;
}
return new ProxyTupleSource() {
@Override
protected TupleSource createTupleSource() throws TeiidComponentException, TeiidProcessingException {
final String groupKey = group.getNonCorrelationName();
final TempTable table = contextStore.getOrCreateTempTable(groupKey, command, bufferManager, true, true, context, group);
if (command instanceof Insert) {
Insert insert = (Insert) command;
TupleSource ts = insert.getTupleSource();
if (ts == null) {
Evaluator eval = new Evaluator(Collections.emptyMap(), TempTableDataManager.this, context);
List<Object> values = new ArrayList<Object>(insert.getValues().size());
for (Expression expr : (List<Expression>) insert.getValues()) {
values.add(eval.evaluate(expr, null));
}
ts = new CollectionTupleSource(Arrays.asList(values).iterator());
}
return table.insert(ts, insert.getVariables(), true, insert.isUpsert(), context);
}
if (command instanceof Update) {
final Update update = (Update) command;
final Criteria crit = update.getCriteria();
return table.update(crit, update.getChangeList());
}
if (command instanceof Delete) {
final Delete delete = (Delete) command;
final Criteria crit = delete.getCriteria();
if (crit == null) {
// TODO: we'll add a real truncate later
long rows = table.truncate(false);
return CollectionTupleSource.createUpdateCountTupleSource((int) Math.min(Integer.MAX_VALUE, rows));
}
return table.delete(crit);
}
// $NON-NLS-1$
throw new AssertionError("unknown command " + command);
}
};
}
if (command instanceof Create) {
Create create = (Create) command;
String tempTableName = create.getTable().getName();
if (contextStore.hasTempTable(tempTableName, true)) {
throw new QueryProcessingException(QueryPlugin.Event.TEIID30229, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30229, tempTableName));
}
if (create.getTableMetadata() != null) {
contextStore.addForeignTempTable(tempTableName, create);
} else {
contextStore.addTempTable(tempTableName, create, bufferManager, true, context);
}
return CollectionTupleSource.createUpdateCountTupleSource(0);
}
if (command instanceof Drop) {
String tempTableName = ((Drop) command).getTable().getName();
contextStore.removeTempTableByName(tempTableName, context);
return CollectionTupleSource.createUpdateCountTupleSource(0);
}
if (command instanceof AlterTempTable) {
// non longer used, was part of xml logic
AlterTempTable att = (AlterTempTable) command;
TempTable tt = contextStore.getTempTable(att.getTempTable());
// $NON-NLS-1$
Assertion.isNotNull(tt, "Table doesn't exist");
tt.setUpdatable(false);
if (att.getIndexColumns() != null && tt.getRowCount() > 2 * tt.getTree().getPageSize(true)) {
for (List<ElementSymbol> cols : att.getIndexColumns()) {
tt.addIndex(cols, false);
}
}
return CollectionTupleSource.createUpdateCountTupleSource(0);
}
return null;
}
use of org.teiid.query.processor.CollectionTupleSource in project teiid by teiid.
the class IndexInfo method createTupleBrowser.
TupleBrowser createTupleBrowser(NullOrder nullOrder, boolean readOnly) throws TeiidComponentException {
boolean direction = OrderBy.ASC;
if (ordering != null) {
// $NON-NLS-1$
LogManager.logDetail(LogConstants.CTX_DQP, "Using index for ordering");
direction = ordering;
}
if (valueTs != null) {
// $NON-NLS-1$
LogManager.logDetail(LogConstants.CTX_DQP, "Using index value set");
return new TupleBrowser(this.table.getTree(), valueTs, direction, readOnly);
}
if (!valueSet.isEmpty()) {
// $NON-NLS-1$
LogManager.logDetail(LogConstants.CTX_DQP, "Using index value set");
sortValueSet(direction, nullOrder);
CollectionTupleSource cts = new CollectionTupleSource(valueSet.iterator());
return new TupleBrowser(this.table.getTree(), cts, direction, readOnly);
}
if (lower != null || upper != null) {
// $NON-NLS-1$
LogManager.logDetail(LogConstants.CTX_DQP, "Using index for range query", lower, upper);
}
return new TupleBrowser(this.table.getTree(), lower, upper, direction, readOnly);
}
use of org.teiid.query.processor.CollectionTupleSource 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.processor.CollectionTupleSource in project teiid by teiid.
the class TestSTree method testTupleBrowserRemove.
@Test
public void testTupleBrowserRemove() throws Exception {
BufferManagerImpl bm = BufferManagerFactory.getTestBufferManager(1, 1);
ElementSymbol e1 = new ElementSymbol("x");
e1.setType(Integer.class);
ElementSymbol e2 = new ElementSymbol("x");
e2.setType(Integer.class);
List<ElementSymbol> elements = Arrays.asList(e1, e2);
STree map = bm.createSTree(elements, "1", 2);
map.insert(Arrays.asList(1, 1), InsertMode.NEW, -1);
TupleBrowser tb = new TupleBrowser(map, new CollectionTupleSource(Collections.singletonList(Arrays.asList(1)).iterator()), true, false);
assertNotNull(tb.nextTuple());
tb.removed();
assertEquals(Integer.valueOf(0), tb.getValueCount());
}
Aggregations