use of org.teiid.api.exception.query.QueryResolverException in project teiid by teiid.
the class ResolverUtil method resolveComparision.
private static Expression resolveComparision(Expression expression, SubqueryContainer crit, QueryMetadataInterface metadata, Class<?> subqueryType) throws QueryResolverException {
// Check that type of the expression is same as the type of the
// single projected symbol of the subquery
Class<?> exprType = expression.getType();
if (exprType == null) {
throw new QueryResolverException(QueryPlugin.Event.TEIID30075, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30075, expression));
}
String exprTypeName = DataTypeManager.getDataTypeName(exprType);
String subqueryTypeName = DataTypeManager.getDataTypeName(subqueryType);
Expression result = null;
try {
if (!metadata.widenComparisonToString() && ResolverVisitor.isCharacter(subqueryType, true) && !ResolverVisitor.isCharacter(expression, true)) {
throw new QueryResolverException(QueryPlugin.Event.TEIID31172, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID31172, crit));
}
result = convertExpression(expression, exprTypeName, subqueryTypeName, metadata);
} catch (QueryResolverException qre) {
throw new QueryResolverException(QueryPlugin.Event.TEIID30094, qre, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30094, crit));
}
return result;
}
use of org.teiid.api.exception.query.QueryResolverException in project teiid by teiid.
the class ResolverUtil method resolveOrderBy.
/**
* Attempt to resolve the order by throws QueryResolverException if the
* symbol is not of SingleElementSymbol type
*
* @param orderBy
* @param fromClauseGroups
* groups of the FROM clause of the query (for resolving
* ambiguous unqualified element names), or empty List if a Set
* Query Order By is being resolved
* @param knownElements
* resolved elements from SELECT clause, which are only ones
* allowed to be in ORDER BY
* @param metadata
* QueryMetadataInterface
*/
public static void resolveOrderBy(OrderBy orderBy, QueryCommand command, TempMetadataAdapter metadata) throws QueryResolverException, QueryMetadataException, TeiidComponentException {
List<Expression> knownElements = command.getProjectedQuery().getSelect().getProjectedSymbols();
boolean isSimpleQuery = false;
List<GroupSymbol> fromClauseGroups = Collections.emptyList();
GroupBy groupBy = null;
if (command instanceof Query) {
Query query = (Query) command;
isSimpleQuery = !query.getSelect().isDistinct() && !query.hasAggregates();
if (query.getFrom() != null) {
fromClauseGroups = query.getFrom().getGroups();
}
if (!query.getSelect().isDistinct()) {
groupBy = query.getGroupBy();
}
}
// Cached state, if needed
String[] knownShortNames = new String[knownElements.size()];
List<Expression> expressions = new ArrayList<Expression>(knownElements.size());
for (int i = 0; i < knownElements.size(); i++) {
Expression knownSymbol = knownElements.get(i);
expressions.add(SymbolMap.getExpression(knownSymbol));
if (knownSymbol instanceof ElementSymbol || knownSymbol instanceof AliasSymbol) {
String name = ((Symbol) knownSymbol).getShortName();
knownShortNames[i] = name;
}
}
for (int i = 0; i < orderBy.getVariableCount(); i++) {
Expression sortKey = orderBy.getVariable(i);
if (sortKey instanceof ElementSymbol) {
ElementSymbol symbol = (ElementSymbol) sortKey;
String groupPart = null;
if (symbol.getGroupSymbol() != null) {
groupPart = symbol.getGroupSymbol().getName();
}
String symbolName = symbol.getName();
String shortName = symbol.getShortName();
if (groupPart == null) {
int position = -1;
Expression matchedSymbol = null;
// walk the SELECT col short names, looking for a match on the current ORDER BY 'short name'
for (int j = 0; j < knownShortNames.length; j++) {
if (!shortName.equalsIgnoreCase(knownShortNames[j])) {
continue;
}
// if we already have a matched symbol, matching again here means it is duplicate/ambiguous
if (matchedSymbol != null) {
if (!matchedSymbol.equals(knownElements.get(j))) {
throw new QueryResolverException(QueryPlugin.Event.TEIID30084, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30084, symbolName));
}
continue;
}
matchedSymbol = knownElements.get(j);
position = j;
}
if (matchedSymbol != null) {
TempMetadataID tempMetadataID = new TempMetadataID(symbol.getName(), matchedSymbol.getType());
symbol.setMetadataID(tempMetadataID);
symbol.setType(matchedSymbol.getType());
}
if (position != -1) {
orderBy.setExpressionPosition(i, position);
continue;
}
}
} else if (sortKey instanceof Constant) {
// check for legacy positional
Constant c = (Constant) sortKey;
int elementOrder = Integer.valueOf(c.getValue().toString()).intValue();
// adjust for the 1 based index.
if (elementOrder > knownElements.size() || elementOrder < 1) {
throw new QueryResolverException(QueryPlugin.Event.TEIID30085, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30085, c));
}
orderBy.setExpressionPosition(i, elementOrder - 1);
continue;
}
// handle order by expressions
if (command instanceof SetQuery) {
throw new QueryResolverException(QueryPlugin.Event.TEIID30086, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30086, sortKey));
}
// resolve subqueries
for (SubqueryContainer container : ValueIteratorProviderCollectorVisitor.getValueIteratorProviders(sortKey)) {
Command c = container.getCommand();
QueryResolver.setChildMetadata(c, command);
c.pushNewResolvingContext(fromClauseGroups);
QueryResolver.resolveCommand(c, metadata.getMetadata(), false);
}
for (ElementSymbol symbol : ElementCollectorVisitor.getElements(sortKey, false)) {
try {
ResolverVisitor.resolveLanguageObject(symbol, fromClauseGroups, command.getExternalGroupContexts(), metadata);
} catch (QueryResolverException e) {
throw new QueryResolverException(QueryPlugin.Event.TEIID30087, e, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30087, symbol.getName()));
}
}
ResolverVisitor.resolveLanguageObject(sortKey, metadata);
int index = expressions.indexOf(SymbolMap.getExpression(sortKey));
// if unrelated and not a simple query - that is more than just a grouping, throw an exception
if (index == -1 && !isSimpleQuery && groupBy == null) {
throw new QueryResolverException(QueryPlugin.Event.TEIID30088, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30088, sortKey));
}
orderBy.setExpressionPosition(i, index);
}
}
use of org.teiid.api.exception.query.QueryResolverException in project teiid by teiid.
the class ResolverUtil method resolveLookup.
public static ResolvedLookup resolveLookup(Function lookup, QueryMetadataInterface metadata) throws QueryResolverException, TeiidComponentException {
Expression[] args = lookup.getArgs();
ResolvedLookup result = new ResolvedLookup();
// Special code to handle setting return type of the lookup function to match the type of the return element
if (!(args[0] instanceof Constant) || !(args[1] instanceof Constant) || !(args[2] instanceof Constant)) {
throw new QueryResolverException(QueryPlugin.Event.TEIID30095, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30095));
}
// If code table name in lookup function refers to temp group throw exception
GroupSymbol groupSym = new GroupSymbol((String) ((Constant) args[0]).getValue());
try {
groupSym.setMetadataID(metadata.getGroupID((String) ((Constant) args[0]).getValue()));
if (groupSym.getMetadataID() instanceof TempMetadataID) {
throw new QueryResolverException(QueryPlugin.Event.TEIID30096, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30096, ((Constant) args[0]).getValue()));
}
} catch (QueryMetadataException e) {
throw new QueryResolverException(QueryPlugin.Event.TEIID30097, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30097, ((Constant) args[0]).getValue()));
}
result.setGroup(groupSym);
List<GroupSymbol> groups = Arrays.asList(groupSym);
// $NON-NLS-1$
String returnElementName = (String) ((Constant) args[0]).getValue() + "." + (String) ((Constant) args[1]).getValue();
ElementSymbol returnElement = new ElementSymbol(returnElementName);
try {
ResolverVisitor.resolveLanguageObject(returnElement, groups, metadata);
} catch (QueryMetadataException e) {
throw new QueryResolverException(QueryPlugin.Event.TEIID30098, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30098, returnElementName));
}
result.setReturnElement(returnElement);
// $NON-NLS-1$
String keyElementName = (String) ((Constant) args[0]).getValue() + "." + (String) ((Constant) args[2]).getValue();
ElementSymbol keyElement = new ElementSymbol(keyElementName);
try {
ResolverVisitor.resolveLanguageObject(keyElement, groups, metadata);
} catch (QueryMetadataException e) {
throw new QueryResolverException(QueryPlugin.Event.TEIID30099, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30099, keyElementName));
}
result.setKeyElement(keyElement);
args[3] = convertExpression(args[3], DataTypeManager.getDataTypeName(keyElement.getType()), metadata);
return result;
}
use of org.teiid.api.exception.query.QueryResolverException in project teiid by teiid.
the class ResolverUtil method getConversion.
/**
* IMPORTANT: source and target must be basic runtime types
* @param sourceExpression
* @param sourceTypeName
* @param targetTypeName
* @param implicit
* @param library
* @return
*/
public static Function getConversion(Expression sourceExpression, String sourceTypeName, String targetTypeName, boolean implicit, FunctionLibrary library) {
Class<?> srcType = DataTypeManager.getDataTypeClass(sourceTypeName);
Class<?> targetType = DataTypeManager.getDataTypeClass(targetTypeName);
try {
setDesiredType(sourceExpression, targetType, sourceExpression);
} catch (QueryResolverException e) {
}
FunctionDescriptor fd = library.findTypedConversionFunction(srcType, DataTypeManager.getDataTypeClass(targetTypeName));
Function conversion = new Function(fd.getName(), new Expression[] { sourceExpression, new Constant(targetTypeName) });
conversion.setType(DataTypeManager.getDataTypeClass(targetTypeName));
conversion.setFunctionDescriptor(fd);
if (implicit) {
conversion.makeImplicit();
}
return conversion;
}
use of org.teiid.api.exception.query.QueryResolverException in project teiid by teiid.
the class ResolverVisitor method resolveBetweenCriteria.
/**
* Resolves criteria "a BETWEEN b AND c". If type conversions are necessary,
* this method attempts the following implicit conversions:
* <br/>
* <ol type="1" start="1">
* <li>convert the lower and upper expressions to the criteria expression's type, or</li>
* <li>convert the criteria and upper expressions to the lower expression's type, or</li>
* <li>convert the criteria and lower expressions to the upper expression's type, or</li>
* <li>convert all expressions to a common type to which all three expressions' types can be implicitly converted.</li>
* </ol>
* @param criteria
* @throws QueryResolverException
* @throws TeiidComponentException
* @throws TeiidComponentException
*/
void resolveBetweenCriteria(BetweenCriteria criteria) throws QueryResolverException, TeiidComponentException {
Expression exp = criteria.getExpression();
Expression lower = criteria.getLowerExpression();
Expression upper = criteria.getUpperExpression();
// invariants: none of the expressions is an aggregate symbol
setDesiredType(exp, (lower.getType() == null) ? upper.getType() : lower.getType(), criteria);
// invariants: exp.getType() != null
setDesiredType(lower, exp.getType(), criteria);
setDesiredType(upper, exp.getType(), criteria);
if (exp.getType() == lower.getType() && exp.getType() == upper.getType()) {
return;
}
String expTypeName = DataTypeManager.getDataTypeName(exp.getType());
String lowerTypeName = DataTypeManager.getDataTypeName(lower.getType());
String upperTypeName = DataTypeManager.getDataTypeName(upper.getType());
// check if all types are the same, or if there is a common type
String[] types = new String[2];
types[0] = lowerTypeName;
types[1] = upperTypeName;
Class<?> type = null;
String commonType = ResolverUtil.getCommonRuntimeType(types);
if (commonType != null) {
type = DataTypeManager.getDataTypeClass(commonType);
}
boolean exprChar = isCharacter(exp, true);
if (exp.getType() != DataTypeManager.DefaultDataClasses.NULL) {
boolean success = true;
// Apply cast and replace current value
if (!exprChar || metadata.widenComparisonToString() || isCharacter(lower, true)) {
try {
criteria.setLowerExpression(ResolverUtil.convertExpression(lower, lowerTypeName, expTypeName, metadata));
lower = criteria.getLowerExpression();
lowerTypeName = DataTypeManager.getDataTypeName(lower.getType());
} catch (QueryResolverException e) {
if (lower instanceof Constant && isCharacter(lower, true) && !metadata.widenComparisonToString()) {
throw e;
}
if (type == null) {
type = lower.getType();
}
success = false;
}
} else {
success = false;
}
// Apply cast and replace current value
if (!exprChar || metadata.widenComparisonToString() || isCharacter(upper, true)) {
try {
criteria.setUpperExpression(ResolverUtil.convertExpression(upper, upperTypeName, expTypeName, metadata));
upper = criteria.getUpperExpression();
upperTypeName = DataTypeManager.getDataTypeName(upper.getType());
} catch (QueryResolverException e) {
if (lower instanceof Constant && isCharacter(lower, true) && !metadata.widenComparisonToString()) {
throw e;
}
if (type == null) {
type = upper.getType();
}
success = false;
}
} else {
success = false;
}
if (success) {
return;
}
}
// set is the same and the convert can be placed on the left side
if (type == null) {
// Couldn't find a common type to implicitly convert to
throw new QueryResolverException(QueryPlugin.Event.TEIID30072, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30077, criteria));
}
// Is there a possible conversion from left to right?
String typeName = DataTypeManager.getDataTypeName(type);
if (!isCharacter(type, true) || metadata.widenComparisonToString() || exp.getType() == DataTypeManager.DefaultDataClasses.NULL) {
criteria.setExpression(ResolverUtil.convertExpression(exp, expTypeName, typeName, metadata));
} else if (type != exp.getType()) {
throw new QueryResolverException(QueryPlugin.Event.TEIID31172, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID31172, criteria));
}
if (lower.getType() != type) {
if (!metadata.widenComparisonToString() && exprChar ^ isCharacter(lower, true)) {
throw new QueryResolverException(QueryPlugin.Event.TEIID31172, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID31172, criteria));
}
criteria.setLowerExpression(ResolverUtil.convertExpression(lower, lowerTypeName, typeName, metadata));
}
if (upper.getType() != type) {
if (!metadata.widenComparisonToString() && exprChar ^ isCharacter(lower, true)) {
throw new QueryResolverException(QueryPlugin.Event.TEIID31172, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID31172, criteria));
}
criteria.setUpperExpression(ResolverUtil.convertExpression(upper, upperTypeName, typeName, metadata));
}
// invariants: exp.getType() == lower.getType() == upper.getType()
}
Aggregations