use of org.teiid.query.sql.symbol.Expression in project teiid by teiid.
the class SubqueryAwareEvaluator method evaluatePushdown.
/**
* Implements must pushdown function handling if supported by the source.
*
* The basic strategy is to create a dummy subquery to represent the evaluation
*/
@Override
protected Object evaluatePushdown(Function function, List<?> tuple, Object[] values) throws TeiidComponentException, TeiidProcessingException {
final FunctionDescriptor fd = function.getFunctionDescriptor();
if (fd.getMethod() == null) {
throw new FunctionExecutionException(QueryPlugin.Event.TEIID30341, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30341, fd.getFullName()));
}
String schema = null;
if (fd.getMethod().getParent() == null || !fd.getMethod().getParent().isPhysical()) {
// find a suitable target
// TODO: do better than a linear search
VDBMetaData vdb = this.context.getVdb();
CapabilitiesFinder capabiltiesFinder = this.context.getQueryProcessorFactory().getCapabiltiesFinder();
for (ModelMetaData mmd : vdb.getModelMetaDatas().values()) {
if (!mmd.isSource()) {
continue;
}
SourceCapabilities caps = capabiltiesFinder.findCapabilities(mmd.getName());
if (caps.supportsCapability(Capability.SELECT_WITHOUT_FROM) && caps.supportsFunction(fd.getMethod().getFullName())) {
schema = mmd.getName();
break;
}
}
if (schema == null) {
throw new FunctionExecutionException(QueryPlugin.Event.TEIID30341, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30341, fd.getFullName()));
}
} else {
if (!CapabilitiesUtil.supports(Capability.SELECT_WITHOUT_FROM, fd.getMethod().getParent(), context.getMetadata(), context.getQueryProcessorFactory().getCapabiltiesFinder())) {
if (elements != null) {
Integer index = (Integer) elements.get(function);
if (index != null) {
return tuple.get(index.intValue());
}
}
throw new FunctionExecutionException(QueryPlugin.Event.TEIID30341, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30341, fd.getFullName()));
}
schema = fd.getSchema();
}
ScalarSubquery ss = null;
if (functionState != null) {
ss = functionState.get(function);
}
Expression[] functionArgs = new Expression[values.length];
for (int i = 0; i < values.length; i++) {
functionArgs[i] = new Constant(values[i]);
}
if (ss == null) {
final Query command = new Query();
Select select = new Select();
command.setSelect(select);
Function f = new Function(function.getName(), functionArgs);
f.setType(function.getType());
f.setFunctionDescriptor(fd);
select.addSymbol(f);
ss = new ScalarSubquery(command);
SymbolMap correlatedReferences = new SymbolMap();
Collection<ElementSymbol> elements = ElementCollectorVisitor.getElements(function, true);
if (!elements.isEmpty()) {
for (ElementSymbol es : elements) {
correlatedReferences.addMapping(es, es);
}
command.setCorrelatedReferences(correlatedReferences);
}
command.setProcessorPlan(new SimpleProcessorPlan(command, schema, fd, Arrays.asList(new Constant(null, fd.getReturnType()))));
} else {
((Function) ((ExpressionSymbol) ss.getCommand().getProjectedSymbols().get(0)).getExpression()).setArgs(functionArgs);
}
if (functionState == null) {
this.functionState = new HashMap<Function, ScalarSubquery>(2);
}
functionState.put(function, ss);
return internalEvaluate(ss, tuple);
}
use of org.teiid.query.sql.symbol.Expression in project teiid by teiid.
the class TextTableNode method initialize.
@Override
public void initialize(CommandContext context, BufferManager bufferManager, ProcessorDataManager dataMgr) {
super.initialize(context, bufferManager, dataMgr);
if (projectionIndexes != null) {
return;
}
if (table.getSkip() != null) {
skip = table.getSkip();
}
if (table.getHeader() != null) {
skip = Math.max(table.getHeader(), skip);
header = table.getHeader() - 1;
}
if (table.isFixedWidth()) {
for (TextColumn col : table.getColumns()) {
lineWidth += col.getWidth();
}
} else {
if (table.getDelimiter() == null) {
delimiter = ',';
} else {
delimiter = table.getDelimiter();
}
if (table.getQuote() == null) {
quote = '"';
} else {
noQuote = table.isEscape();
quote = table.getQuote();
}
for (TextColumn column : table.getColumns()) {
if (column.getSelector() != null) {
if (parentLines == null) {
parentLines = new HashMap<String, List<String>>();
}
parentLines.put(column.getSelector(), null);
}
}
lineWidth = table.getColumns().size() * DataTypeManager.MAX_STRING_LENGTH;
}
if (table.isUsingRowDelimiter()) {
Character c = table.getRowDelimiter();
if (c != null) {
this.newLine = c;
this.crNewLine = false;
}
}
Map<Expression, Integer> elementMap = createLookupMap(table.getProjectedSymbols());
this.projectionIndexes = getProjectionIndexes(elementMap, getElements());
}
use of org.teiid.query.sql.symbol.Expression in project teiid by teiid.
the class WindowFunctionProjectNode method saveInput.
/**
* Save the input generating any necessary expressions and adding a row id
* @param collectedExpressions
* @return
* @throws TeiidComponentException
* @throws TeiidProcessingException
*/
private void saveInput() throws TeiidComponentException, TeiidProcessingException {
if (inputTs == null) {
List<Expression> collectedExpressions = new ArrayList<Expression>(expressionIndexes.keySet());
Evaluator eval = new Evaluator(elementMap, getDataManager(), getContext());
final RelationalNode sourceNode = this.getChildren()[0];
inputTs = new ProjectingTupleSource(sourceNode, eval, collectedExpressions, elementMap) {
int index = 0;
@Override
public List<Object> nextTuple() throws TeiidComponentException, TeiidProcessingException {
List<Object> tuple = super.nextTuple();
if (tuple != null) {
tuple.add(index++);
}
return tuple;
}
};
List<ElementSymbol> schema = new ArrayList<ElementSymbol>(collectedExpressions.size() + 1);
int index = 0;
for (Expression ex : collectedExpressions) {
ElementSymbol es = new ElementSymbol(String.valueOf(index++));
es.setType(ex.getType());
schema.add(es);
}
// add in the row id
ElementSymbol es = new ElementSymbol(String.valueOf(index++));
es.setType(DataTypeManager.DefaultDataClasses.INTEGER);
schema.add(es);
tb = this.getBufferManager().createTupleBuffer(schema, this.getConnectionID(), TupleSourceType.PROCESSOR);
}
List<?> tuple = null;
while ((tuple = inputTs.nextTuple()) != null) {
tb.addTuple(tuple);
}
tb.close();
inputTs.closeSource();
inputTs = null;
}
use of org.teiid.query.sql.symbol.Expression in project teiid by teiid.
the class QueryResolver method parseBindings.
/**
* Bindings are a poor mans input parameters. They are represented in legacy metadata
* by ElementSymbols and placed positionally into the command or by alias symbols
* and matched by names.
* @param planNode
* @return
* @throws TeiidComponentException
*/
public static List<Expression> parseBindings(QueryNode planNode) throws TeiidComponentException {
Collection<String> bindingsCol = planNode.getBindings();
if (bindingsCol == null) {
return Collections.emptyList();
}
List<Expression> parsedBindings = new ArrayList<Expression>(bindingsCol.size());
for (Iterator<String> bindings = bindingsCol.iterator(); bindings.hasNext(); ) {
try {
Expression binding = QueryParser.getQueryParser().parseSelectExpression(bindings.next());
parsedBindings.add(binding);
} catch (QueryParserException err) {
throw new TeiidComponentException(QueryPlugin.Event.TEIID30063, err);
}
}
return parsedBindings;
}
use of org.teiid.query.sql.symbol.Expression in project teiid by teiid.
the class QueryResolver method validateProjectedSymbols.
public static void validateProjectedSymbols(GroupSymbol virtualGroup, List<? extends Expression> symbols, List<? extends Expression> projectedSymbols) throws QueryValidatorException {
if (symbols.size() != projectedSymbols.size()) {
throw new QueryValidatorException(QueryPlugin.Event.TEIID30066, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30066, virtualGroup, symbols.size(), projectedSymbols.size()));
}
for (int i = 0; i < projectedSymbols.size(); i++) {
Expression projectedSymbol = projectedSymbols.get(i);
ResolverUtil.setTypeIfNull(projectedSymbol, symbols.get(i).getType());
if (projectedSymbol.getType() != symbols.get(i).getType()) {
throw new QueryValidatorException(// $NON-NLS-1$
QueryPlugin.Util.getString(// $NON-NLS-1$
"QueryResolver.wrong_view_symbol_type", // $NON-NLS-1$
virtualGroup, // $NON-NLS-1$
i + 1, DataTypeManager.getDataTypeName(symbols.get(i).getType()), DataTypeManager.getDataTypeName(projectedSymbol.getType())));
}
}
}
Aggregations