Search in sources :

Example 16 with QueryResolverException

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;
}
Also used : QueryResolverException(org.teiid.api.exception.query.QueryResolverException)

Example 17 with QueryResolverException

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);
    }
}
Also used : TempMetadataID(org.teiid.query.metadata.TempMetadataID) QueryResolverException(org.teiid.api.exception.query.QueryResolverException)

Example 18 with QueryResolverException

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;
}
Also used : TempMetadataID(org.teiid.query.metadata.TempMetadataID) QueryMetadataException(org.teiid.api.exception.query.QueryMetadataException) QueryResolverException(org.teiid.api.exception.query.QueryResolverException)

Example 19 with QueryResolverException

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;
}
Also used : FunctionDescriptor(org.teiid.query.function.FunctionDescriptor) QueryResolverException(org.teiid.api.exception.query.QueryResolverException)

Example 20 with QueryResolverException

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()
}
Also used : ExceptionExpression(org.teiid.query.sql.proc.ExceptionExpression) QueryResolverException(org.teiid.api.exception.query.QueryResolverException)

Aggregations

QueryResolverException (org.teiid.api.exception.query.QueryResolverException)62 GroupSymbol (org.teiid.query.sql.symbol.GroupSymbol)13 TempMetadataID (org.teiid.query.metadata.TempMetadataID)11 ExceptionExpression (org.teiid.query.sql.proc.ExceptionExpression)11 ArrayList (java.util.ArrayList)10 Test (org.junit.Test)10 TeiidComponentException (org.teiid.core.TeiidComponentException)10 Expression (org.teiid.query.sql.symbol.Expression)10 QueryMetadataException (org.teiid.api.exception.query.QueryMetadataException)8 CreateProcedureCommand (org.teiid.query.sql.proc.CreateProcedureCommand)7 Command (org.teiid.query.sql.lang.Command)6 ElementSymbol (org.teiid.query.sql.symbol.ElementSymbol)6 QueryParserException (org.teiid.api.exception.query.QueryParserException)5 TempMetadataStore (org.teiid.query.metadata.TempMetadataStore)5 LanguageObject (org.teiid.query.sql.LanguageObject)5 List (java.util.List)4 UnresolvedSymbolDescription (org.teiid.api.exception.query.UnresolvedSymbolDescription)4 TempMetadataAdapter (org.teiid.query.metadata.TempMetadataAdapter)4 StoredProcedure (org.teiid.query.sql.lang.StoredProcedure)4 HashSet (java.util.HashSet)3