use of org.teiid.api.exception.query.QueryResolverException in project teiid by teiid.
the class ResolverUtil method addTempGroup.
public static TempMetadataID addTempGroup(TempMetadataAdapter metadata, GroupSymbol symbol, List<? extends Expression> symbols, boolean tempTable) throws QueryResolverException {
Set<String> names = new TreeSet<String>(String.CASE_INSENSITIVE_ORDER);
for (Expression ses : symbols) {
if (!names.add(Symbol.getShortName(ses))) {
throw new QueryResolverException(QueryPlugin.Event.TEIID30091, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30091, symbol, Symbol.getShortName(ses)));
}
}
if (tempTable) {
resolveNullLiterals(symbols);
}
TempMetadataStore store = metadata.getMetadataStore();
return store.addTempGroup(symbol.getName(), symbols, !tempTable, tempTable);
}
use of org.teiid.api.exception.query.QueryResolverException in project teiid by teiid.
the class ResolverVisitor method handleUnresolvedElement.
private QueryResolverException handleUnresolvedElement(ElementSymbol symbol, String description) {
UnresolvedSymbolDescription usd = new UnresolvedSymbolDescription(symbol, description);
QueryResolverException e = new QueryResolverException(usd.getDescription());
e.setUnresolvedSymbols(Arrays.asList(usd));
return e;
}
use of org.teiid.api.exception.query.QueryResolverException in project teiid by teiid.
the class ResolverVisitor method resolveFunction.
/**
* Resolve function such that all functions are resolved and type-safe.
*/
void resolveFunction(Function function, FunctionLibrary library) throws QueryResolverException, TeiidComponentException {
// Check whether this function is already resolved
if (function.getFunctionDescriptor() != null) {
return;
}
// Look up types for all args
boolean hasArgWithoutType = false;
Expression[] args = function.getArgs();
Class<?>[] types = new Class[args.length];
for (int i = 0; i < args.length; i++) {
types[i] = args[i].getType();
if (types[i] == null) {
if (!(args[i] instanceof Reference)) {
throw new QueryResolverException(QueryPlugin.Event.TEIID30067, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30067, new Object[] { args[i], function }));
}
hasArgWithoutType = true;
}
}
// special case handling for convert of an untyped reference
if (FunctionLibrary.isConvert(function) && hasArgWithoutType) {
Constant constant = (Constant) function.getArg(1);
Class<?> type = metadata.getDataTypeClass((String) constant.getValue());
setDesiredType(function.getArg(0), type, function);
types[0] = type;
hasArgWithoutType = false;
}
// Attempt to get exact match of function for this signature
List<FunctionDescriptor> fds;
try {
fds = findWithImplicitConversions(library, function, args, types, hasArgWithoutType);
if (fds.isEmpty()) {
if (!library.hasFunctionMethod(function.getName(), args.length)) {
// Unknown function form
throw new QueryResolverException(QueryPlugin.Event.TEIID30068, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30068, function));
}
// Known function form - but without type information
if (hasArgWithoutType) {
throw new QueryResolverException(QueryPlugin.Event.TEIID30069, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30069, function));
}
// Known function form - unable to find implicit conversions
throw new QueryResolverException(QueryPlugin.Event.TEIID30070, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30070, function));
}
if (fds.size() > 1) {
throw new QueryResolverException(QueryPlugin.Event.TEIID31150, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID31150, function));
}
} catch (InvalidFunctionException e) {
// Known function form - but without type information
if (hasArgWithoutType) {
throw new QueryResolverException(QueryPlugin.Event.TEIID30069, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30069, function));
}
throw new QueryResolverException(QueryPlugin.Event.TEIID31150, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID31150, function));
}
FunctionDescriptor fd = fds.get(0);
if (fd.getMethod().isVarArgs() && fd.getTypes().length == types.length && library.isVarArgArrayParam(fd.getMethod(), types, types.length - 1, fd.getTypes()[types.length - 1])) {
fd = fd.clone();
fd.setCalledWithVarArgArrayParam(true);
}
if (fd.isSystemFunction(FunctionLibrary.CONVERT) || fd.isSystemFunction(FunctionLibrary.CAST)) {
String dataType = (String) ((Constant) args[1]).getValue();
Class<?> dataTypeClass = metadata.getDataTypeClass(dataType);
fd = library.findTypedConversionFunction(args[0].getType(), dataTypeClass);
// Verify that the type conversion from src to type is even valid
Class<?> srcTypeClass = args[0].getType();
if (srcTypeClass != null && dataTypeClass != null && !srcTypeClass.equals(dataTypeClass) && !DataTypeManager.isTransformable(srcTypeClass, dataTypeClass)) {
throw new QueryResolverException(QueryPlugin.Event.TEIID30071, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30071, new Object[] { DataTypeManager.getDataTypeName(srcTypeClass), dataType }));
}
} else if (fd.isSystemFunction(FunctionLibrary.LOOKUP)) {
ResolverUtil.ResolvedLookup lookup = ResolverUtil.resolveLookup(function, metadata);
fd = library.copyFunctionChangeReturnType(fd, lookup.getReturnElement().getType());
} else if (fd.isSystemFunction(FunctionLibrary.ARRAY_GET)) {
if (args[0].getType() != null && args[0].getType().isArray()) {
fd = library.copyFunctionChangeReturnType(fd, args[0].getType().getComponentType());
} else {
if (function.getType() != null) {
setDesiredType(args[0], function.getType(), function);
}
if (args[0].getType() != DataTypeManager.DefaultDataClasses.OBJECT) {
throw new QueryResolverException(QueryPlugin.Event.TEIID31145, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID31145, DataTypeManager.getDataTypeName(args[0].getType()), function));
}
}
} else if (Boolean.valueOf(fd.getMethod().getProperty(TEIID_PASS_THROUGH_TYPE, false))) {
// hack largely to support pg
fd = library.copyFunctionChangeReturnType(fd, args[0].getType());
}
function.setFunctionDescriptor(fd);
function.setType(fd.getReturnType());
if (CoreConstants.SYSTEM_MODEL.equals(fd.getSchema())) {
if (StringUtil.startsWithIgnoreCase(function.getName(), SYS_PREFIX)) {
function.setName(function.getName().substring(SYS_PREFIX.length()));
}
} else if (library.getSystemFunctions().hasFunctionWithName(function.getName()) && !StringUtil.startsWithIgnoreCase(function.getName(), function.getFunctionDescriptor().getSchema() + ElementSymbol.SEPARATOR)) {
function.setName(function.getFunctionDescriptor().getSchema() + ElementSymbol.SEPARATOR + function.getName());
}
}
use of org.teiid.api.exception.query.QueryResolverException in project teiid by teiid.
the class ResolverVisitor method resolveCaseExpression.
void resolveCaseExpression(CaseExpression obj) throws QueryResolverException {
// If already resolved, do nothing
if (obj.getType() != null) {
return;
}
final int whenCount = obj.getWhenCount();
Expression expr = obj.getExpression();
Class<?> whenType = null;
Class<?> thenType = null;
// Get the WHEN and THEN types, and get a candidate type for each (for the next step)
for (int i = 0; i < whenCount; i++) {
if (whenType == null) {
whenType = obj.getWhenExpression(i).getType();
}
if (thenType == null) {
thenType = obj.getThenExpression(i).getType();
}
}
Expression elseExpr = obj.getElseExpression();
if (elseExpr != null) {
if (thenType == null) {
thenType = elseExpr.getType();
}
}
// Invariant: All the expressions contained in the obj are resolved (except References)
// 2. Attempt to set the target types of all contained expressions,
// and collect their type names for the next step
ArrayList<String> whenTypeNames = new ArrayList<String>(whenCount + 1);
ArrayList<String> thenTypeNames = new ArrayList<String>(whenCount + 1);
setDesiredType(expr, whenType, obj);
// Add the expression's type to the WHEN types
whenTypeNames.add(DataTypeManager.getDataTypeName(expr.getType()));
Expression when = null;
Expression then = null;
// Set the types of the WHEN and THEN parts
boolean whenNotChar = false;
for (int i = 0; i < whenCount; i++) {
when = obj.getWhenExpression(i);
then = obj.getThenExpression(i);
setDesiredType(when, expr.getType(), obj);
setDesiredType(then, thenType, obj);
if (!whenTypeNames.contains(DataTypeManager.getDataTypeName(when.getType()))) {
whenTypeNames.add(DataTypeManager.getDataTypeName(when.getType()));
}
if (!isCharacter(when.getType(), true)) {
whenNotChar = true;
}
if (!thenTypeNames.contains(DataTypeManager.getDataTypeName(then.getType()))) {
thenTypeNames.add(DataTypeManager.getDataTypeName(then.getType()));
}
}
// Set the type of the else expression
if (elseExpr != null) {
setDesiredType(elseExpr, thenType, obj);
if (!thenTypeNames.contains(DataTypeManager.getDataTypeName(elseExpr.getType()))) {
thenTypeNames.add(DataTypeManager.getDataTypeName(elseExpr.getType()));
}
}
// Invariants: all the expressions' types are non-null
// 3. Perform implicit type conversions
String whenTypeName = ResolverUtil.getCommonRuntimeType(whenTypeNames.toArray(new String[whenTypeNames.size()]));
if (whenTypeName == null) {
// $NON-NLS-1$
throw new QueryResolverException(QueryPlugin.Event.TEIID30079, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30079, "WHEN", obj));
}
if (!metadata.widenComparisonToString() && whenNotChar && isCharacter(DataTypeManager.getDataTypeClass(whenTypeName), true)) {
throw new QueryResolverException(QueryPlugin.Event.TEIID31172, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID31172, obj));
}
String thenTypeName = ResolverUtil.getCommonRuntimeType(thenTypeNames.toArray(new String[thenTypeNames.size()]));
if (thenTypeName == null) {
// $NON-NLS-1$
throw new QueryResolverException(QueryPlugin.Event.TEIID30079, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30079, "THEN/ELSE", obj));
}
obj.setExpression(ResolverUtil.convertExpression(obj.getExpression(), whenTypeName, metadata));
ArrayList<Expression> whens = new ArrayList<Expression>(whenCount);
ArrayList<Expression> thens = new ArrayList<Expression>(whenCount);
for (int i = 0; i < whenCount; i++) {
whens.add(ResolverUtil.convertExpression(obj.getWhenExpression(i), whenTypeName, metadata));
thens.add(ResolverUtil.convertExpression(obj.getThenExpression(i), thenTypeName, metadata));
}
obj.setWhen(whens, thens);
if (elseExpr != null) {
obj.setElseExpression(ResolverUtil.convertExpression(elseExpr, thenTypeName, metadata));
}
// Set this CASE expression's type to the common THEN type, and we're done.
obj.setType(DataTypeManager.getDataTypeClass(thenTypeName));
}
use of org.teiid.api.exception.query.QueryResolverException in project teiid by teiid.
the class ResolverVisitor method resolveCompareCriteria.
void resolveCompareCriteria(BinaryComparison ccrit, LanguageObject surrounding) throws QueryResolverException {
Expression leftExpression = ccrit.getLeftExpression();
Expression rightExpression = ccrit.getRightExpression();
// Check typing between expressions
setDesiredType(leftExpression, rightExpression.getType(), surrounding);
setDesiredType(rightExpression, leftExpression.getType(), surrounding);
if (leftExpression.getType() == rightExpression.getType()) {
return;
}
// Try to apply an implicit conversion from one side to the other
String leftTypeName = DataTypeManager.getDataTypeName(leftExpression.getType());
String rightTypeName = DataTypeManager.getDataTypeName(rightExpression.getType());
if (leftExpression.getType() == DataTypeManager.DefaultDataClasses.NULL) {
ccrit.setLeftExpression(ResolverUtil.convertExpression(leftExpression, leftTypeName, rightTypeName, metadata));
return;
}
if (rightExpression.getType() == DataTypeManager.DefaultDataClasses.NULL) {
ccrit.setRightExpression(ResolverUtil.convertExpression(rightExpression, rightTypeName, leftTypeName, metadata));
return;
}
boolean leftChar = isCharacter(leftExpression, true);
boolean rightChar = isCharacter(rightExpression, true);
// Special cases when right expression is a constant
if (rightExpression instanceof Constant && (!leftChar || rightChar)) {
// Auto-convert constant string on right to expected type on left
try {
ccrit.setRightExpression(ResolverUtil.convertExpression(rightExpression, rightTypeName, leftTypeName, metadata));
return;
} catch (QueryResolverException qre) {
if (rightChar && !metadata.widenComparisonToString()) {
throw qre;
}
}
}
// Special cases when left expression is a constant
if (leftExpression instanceof Constant && (!rightChar || leftChar)) {
// Auto-convert constant string on left to expected type on right
try {
ccrit.setLeftExpression(ResolverUtil.convertExpression(leftExpression, leftTypeName, rightTypeName, metadata));
return;
} catch (QueryResolverException qre) {
if (leftChar && !metadata.widenComparisonToString()) {
throw qre;
}
}
}
if ((rightChar ^ leftChar) && !metadata.widenComparisonToString()) {
throw new QueryResolverException(QueryPlugin.Event.TEIID31172, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID31172, surrounding));
}
if (ResolverUtil.canImplicitlyConvert(leftTypeName, rightTypeName)) {
ccrit.setLeftExpression(ResolverUtil.convertExpression(leftExpression, leftTypeName, rightTypeName, metadata));
return;
}
if (ResolverUtil.canImplicitlyConvert(rightTypeName, leftTypeName)) {
ccrit.setRightExpression(ResolverUtil.convertExpression(rightExpression, rightTypeName, leftTypeName, metadata));
return;
}
String commonType = ResolverUtil.getCommonRuntimeType(new String[] { leftTypeName, rightTypeName });
if (commonType == null) {
// Neither are aggs, but types can't be reconciled
throw new QueryResolverException(QueryPlugin.Event.TEIID30072, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30072, new Object[] { leftTypeName, rightTypeName, surrounding }));
}
ccrit.setLeftExpression(ResolverUtil.convertExpression(leftExpression, leftTypeName, commonType, metadata));
ccrit.setRightExpression(ResolverUtil.convertExpression(rightExpression, rightTypeName, commonType, metadata));
}
Aggregations