use of org.teiid.query.sql.symbol.Reference in project teiid by teiid.
the class PreparedStatementRequest method resolveParameterValues.
/**
* @param params
* @param values
* @throws QueryResolverException
* @throws QueryValidatorException
*/
public static void resolveParameterValues(List<Reference> params, List values, CommandContext context, QueryMetadataInterface metadata) throws QueryResolverException, TeiidComponentException, QueryValidatorException {
VariableContext result = new VariableContext();
// the size of the values must be the same as that of the parameters
if (params.size() != values.size()) {
// $NON-NLS-1$
String msg = QueryPlugin.Util.getString("QueryUtil.wrong_number_of_values", new Object[] { new Integer(values.size()), new Integer(params.size()) });
throw new QueryResolverException(QueryPlugin.Event.TEIID30556, msg);
}
boolean embedded = context != null && context.getSession() != null && context.getSession().isEmbedded();
// to that of the reference
for (int i = 0; i < params.size(); i++) {
Reference param = params.get(i);
Object value = values.get(i);
if (value != null) {
if (embedded && value instanceof BaseLob) {
createStreamCopy(context, i, param, value);
}
try {
String targetTypeName = DataTypeManager.getDataTypeName(param.getType());
Expression expr = ResolverUtil.convertExpression(new Constant(DataTypeManager.convertToRuntimeType(value, param.getType() != DataTypeManager.DefaultDataClasses.OBJECT)), targetTypeName, metadata);
value = Evaluator.evaluate(expr);
} catch (ExpressionEvaluationException e) {
// $NON-NLS-1$
String msg = QueryPlugin.Util.getString("QueryUtil.Error_executing_conversion_function_to_convert_value", i + 1, value, value.getClass(), DataTypeManager.getDataTypeName(param.getType()));
throw new QueryResolverException(QueryPlugin.Event.TEIID30557, e, msg);
} catch (QueryResolverException e) {
// $NON-NLS-1$
String msg = QueryPlugin.Util.getString("QueryUtil.Error_executing_conversion_function_to_convert_value", i + 1, value, value.getClass(), DataTypeManager.getDataTypeName(param.getType()));
throw new QueryResolverException(QueryPlugin.Event.TEIID30558, e, msg);
}
}
if (param.getConstraint() != null) {
param.getConstraint().validate(value);
}
// bind variable
result.setGlobalValue(param.getContextSymbol(), value);
}
context.setVariableContext(result);
}
use of org.teiid.query.sql.symbol.Reference in project teiid by teiid.
the class QueryProcessorFactoryImpl method getPreparedPlan.
@Override
public PreparedPlan getPreparedPlan(String query, String recursionGroup, CommandContext commandContext, QueryMetadataInterface metadata) throws TeiidComponentException, TeiidProcessingException {
if (recursionGroup != null) {
commandContext.pushCall(recursionGroup);
}
PreparedPlan pp = commandContext.getPlan(query);
if (pp == null) {
ParseInfo parseInfo = new ParseInfo();
Command newCommand = QueryParser.getQueryParser().parseCommand(query, parseInfo);
QueryResolver.resolveCommand(newCommand, metadata);
List<Reference> references = ReferenceCollectorVisitor.getReferences(newCommand);
AbstractValidationVisitor visitor = new ValidationVisitor();
Request.validateWithVisitor(visitor, metadata, newCommand);
newCommand = QueryRewriter.rewrite(newCommand, metadata, commandContext);
AnalysisRecord record = new AnalysisRecord(false, false);
ProcessorPlan plan = QueryOptimizer.optimizePlan(newCommand, metadata, idGenerator, finder, record, commandContext);
pp = new PreparedPlan();
pp.setPlan(plan, commandContext);
pp.setReferences(references);
pp.setAnalysisRecord(record);
pp.setCommand(newCommand);
commandContext.putPlan(query, pp, commandContext.getDeterminismLevel());
}
return pp;
}
use of org.teiid.query.sql.symbol.Reference in project teiid by teiid.
the class Request method generatePlan.
/**
* state side effects:
* creates the analysis record
* creates the command context
* sets the pre-rewrite command on the request
* adds a limit clause if the row limit is specified
* sets the processor plan
*
* @throws TeiidComponentException
* @throws TeiidProcessingException
*/
protected void generatePlan(boolean prepared) throws TeiidComponentException, TeiidProcessingException {
createCommandContext();
Command command = parseCommand();
List<Reference> references = ReferenceCollectorVisitor.getReferences(command);
getAnalysisRecord();
resolveCommand(command);
checkReferences(references);
validateAccess(requestMsg.getCommands(), command, CommandType.USER);
this.userCommand = (Command) command.clone();
Collection<GroupSymbol> groups = GroupCollectorVisitor.getGroups(command, true);
for (GroupSymbol groupSymbol : groups) {
if (groupSymbol.isTempTable()) {
this.context.setDeterminismLevel(Determinism.SESSION_DETERMINISTIC);
break;
}
}
validateQuery(command);
command = QueryRewriter.rewrite(command, metadata, context);
/*
* Adds a row limit to a query if Statement.setMaxRows has been called and the command
* doesn't already have a limit clause.
*/
if (!prepared && requestMsg.getRowLimit() > 0 && command instanceof QueryCommand) {
QueryCommand query = (QueryCommand) command;
if (query.getLimit() == null) {
query.setLimit(new Limit(null, new Constant(new Integer(requestMsg.getRowLimit()), DataTypeManager.DefaultDataClasses.INTEGER)));
this.addedLimit = true;
}
}
boolean debug = analysisRecord.recordDebug();
if (debug) {
// $NON-NLS-1$
analysisRecord.println("\n============================================================================");
// $NON-NLS-1$
analysisRecord.println("USER COMMAND:\n" + command);
}
// Run the optimizer
try {
CommandContext.pushThreadLocalContext(context);
processPlan = QueryOptimizer.optimizePlan(command, metadata, idGenerator, capabilitiesFinder, analysisRecord, context);
} finally {
CommandContext.popThreadLocalContext();
String debugLog = analysisRecord.getDebugLog();
if (debugLog != null && debugLog.length() > 0) {
LogManager.log(requestMsg.getShowPlan() == ShowPlan.DEBUG ? MessageLevel.INFO : MessageLevel.TRACE, LogConstants.CTX_QUERY_PLANNER, debugLog);
}
if (analysisRecord.recordAnnotations() && analysisRecord.getAnnotations() != null && !analysisRecord.getAnnotations().isEmpty()) {
LogManager.logDetail(LogConstants.CTX_QUERY_PLANNER, analysisRecord.getAnnotations());
}
}
// $NON-NLS-1$
LogManager.logDetail(LogConstants.CTX_DQP, new Object[] { QueryPlugin.Util.getString("BasicInterceptor.ProcessTree_for__4"), requestId, processPlan });
}
use of org.teiid.query.sql.symbol.Reference in project teiid by teiid.
the class RulePlanProcedures method findInputNodes.
private void findInputNodes(final HashSet<ElementSymbol> inputs, PlanNode critNode, final List<Criteria> conjuncts, final Set<ElementSymbol> params) {
while (critNode.getType() == NodeConstants.Types.SELECT) {
final PlanNode currentNode = critNode;
final Criteria crit = (Criteria) currentNode.getProperty(NodeConstants.Info.SELECT_CRITERIA);
critNode = currentNode.getParent();
if (!currentNode.getGroups().isEmpty()) {
continue;
}
LanguageVisitor visitor = new LanguageVisitor() {
public void visit(CompareCriteria compCrit) {
if (compCrit.getOperator() == CompareCriteria.EQ && checkForInput(compCrit.getLeftExpression()) && !checkForAnyInput(compCrit.getRightExpression())) {
addInputNode((Reference) compCrit.getLeftExpression());
}
}
private void addInputNode(Reference param) {
params.add(param.getExpression());
conjuncts.add(crit);
NodeEditor.removeChildNode(currentNode.getParent(), currentNode);
}
public void visit(IsNullCriteria isNull) {
if (!isNull.isNegated() && checkForInput(isNull.getExpression())) {
addInputNode((Reference) isNull.getExpression());
}
}
public void visit(SetCriteria obj) {
if (!obj.isNegated() && checkForInput(obj.getExpression()) && !checkForAnyInput(obj.getValues())) {
addInputNode((Reference) obj.getExpression());
}
}
public void visit(DependentSetCriteria obj) {
if (obj.isNegated()) {
// just a sanity check
return;
}
if (obj.hasMultipleAttributes()) {
for (AttributeComparison comp : obj.getAttributes()) {
if (!checkForInput(comp.dep)) {
return;
}
}
for (AttributeComparison comp : obj.getAttributes()) {
params.add(((Reference) comp.dep).getExpression());
}
conjuncts.add(crit);
NodeEditor.removeChildNode(currentNode.getParent(), currentNode);
} else if (checkForInput(obj.getExpression())) {
addInputNode((Reference) obj.getExpression());
}
}
boolean checkForInput(Expression expr) {
if (!(expr instanceof Reference)) {
return false;
}
// if the expr is a function containing a reference should give a warning
Reference ref = (Reference) expr;
return inputs.contains(ref.getExpression());
}
boolean checkForAnyInput(LanguageObject expr) {
for (Reference ref : ReferenceCollectorVisitor.getReferences(expr)) {
if (checkForInput(ref)) {
return true;
}
}
return false;
}
boolean checkForAnyInput(Collection<Expression> expressions) {
for (Expression expr : expressions) {
if (checkForAnyInput(expr)) {
return true;
}
}
return false;
}
};
for (Criteria conjunct : Criteria.separateCriteriaByAnd(crit)) {
conjunct.acceptVisitor(visitor);
}
}
}
use of org.teiid.query.sql.symbol.Reference in project teiid by teiid.
the class QueryResolver method resolveWithBindingMetadata.
/**
* 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. After resolving bindings will be replaced with their
* referenced symbols (input names will not be used) and those symbols will
* be marked as external references.
*/
public static TempMetadataStore resolveWithBindingMetadata(Command currentCommand, QueryMetadataInterface metadata, QueryNode queryNode, boolean replaceBindings) throws TeiidComponentException, QueryResolverException {
Map<ElementSymbol, ElementSymbol> symbolMap = null;
if (queryNode.getBindings() != null && queryNode.getBindings().size() > 0) {
symbolMap = new HashMap<ElementSymbol, ElementSymbol>();
// Create ElementSymbols for each InputParameter
final List<ElementSymbol> elements = new ArrayList<ElementSymbol>(queryNode.getBindings().size());
boolean positional = true;
for (Expression ses : parseBindings(queryNode)) {
String name = Symbol.getShortName(ses);
if (ses instanceof AliasSymbol) {
ses = ((AliasSymbol) ses).getSymbol();
positional = false;
}
ElementSymbol elementSymbol = (ElementSymbol) ses;
ResolverVisitor.resolveLanguageObject(elementSymbol, metadata);
elementSymbol.setIsExternalReference(true);
if (!positional) {
symbolMap.put(new ElementSymbol("INPUT" + Symbol.SEPARATOR + name), elementSymbol.clone());
symbolMap.put(new ElementSymbol(BINDING_GROUP + Symbol.SEPARATOR + name), elementSymbol.clone());
elementSymbol.setShortName(name);
}
elements.add(elementSymbol);
}
if (positional) {
ExpressionMappingVisitor emv = new ExpressionMappingVisitor(null) {
@Override
public Expression replaceExpression(Expression element) {
if (!(element instanceof Reference)) {
return element;
}
Reference ref = (Reference) element;
if (!ref.isPositional()) {
return ref;
}
return elements.get(ref.getIndex()).clone();
}
};
DeepPostOrderNavigator.doVisit(currentCommand, emv);
} else {
TempMetadataStore rootExternalStore = new TempMetadataStore();
GroupContext externalGroups = new GroupContext();
// $NON-NLS-1$
ProcedureContainerResolver.addScalarGroup("INPUT", rootExternalStore, externalGroups, elements);
ProcedureContainerResolver.addScalarGroup(BINDING_GROUP, rootExternalStore, externalGroups, elements);
QueryResolver.setChildMetadata(currentCommand, rootExternalStore, externalGroups);
}
}
TempMetadataStore result = resolveCommand(currentCommand, metadata, false);
if (replaceBindings && symbolMap != null && !symbolMap.isEmpty()) {
ExpressionMappingVisitor emv = new ExpressionMappingVisitor(symbolMap);
DeepPostOrderNavigator.doVisit(currentCommand, emv);
}
return result;
}
Aggregations