Search in sources :

Example 16 with Constant

use of org.teiid.query.sql.symbol.Constant in project teiid by teiid.

the class TestJoinWithFunction method testDeterministicPreJoin.

/**
 * <p>The function should be executed prior to the JOIN being executed and should
 * result in the projected symbol becoming a constant.</p>
 *
 * <p>Test the use of a deterministic function on the source command of a JOIN
 * defined by a user command which performs a JOIN of two sources.</p>
 *
 * <p>The function should be executed prior to the commands from either side of the
 * JOIN being executed and merged into user command prior to the JOIN actually being
 * executed.</p>
 * @throws TeiidComponentException
 * @throws QueryValidatorException
 * @throws QueryResolverException
 * @throws QueryParserException
 */
public void testDeterministicPreJoin() throws Exception {
    // source query for one side of a JOIN
    String leftQuery = // $NON-NLS-1$
    "SELECT pm1.g1.e1 as ID, pm1.g1.e2, pm1.g1.e3, pm1.g1.e4, SQRT(100) AS SqrtLeft " + // $NON-NLS-1$
    "FROM pm1.g1";
    // source query for other side of a JOIN
    String rightQuery = // $NON-NLS-1$
    "SELECT pm2.g2.e1 as ID, pm2.g2.e2, pm2.g2.e3, pm2.g2.e4 " + // $NON-NLS-1$
    "FROM pm2.g2";
    // User Command
    /*
		 * Return everything from the JOIN. SqrtLeft is the use of SQRT() 
		 * within a source node.
		 */
    String sql = // $NON-NLS-1$
    "SELECT l.ID, l.e2, l.e3, l.e4, r.ID, r.e2, r.e3, r.e4, l.SqrtLeft " + "FROM (" + leftQuery + // $NON-NLS-1$ //$NON-NLS-2$
    ") AS l, " + "(" + rightQuery + // $NON-NLS-1$ //$NON-NLS-2$
    ") AS r " + // $NON-NLS-1$
    "WHERE l.ID = r.ID";
    // The user command should result in two atomic commands
    String[] expected = new String[] { // $NON-NLS-1$
    "SELECT g_0.e1 AS c_0, g_0.e2 AS c_1, g_0.e3 AS c_2, g_0.e4 AS c_3 FROM pm1.g1 AS g_0 ORDER BY c_0", // $NON-NLS-1$
    "SELECT g_0.e1 AS c_0, g_0.e2 AS c_1, g_0.e3 AS c_2, g_0.e4 AS c_3 FROM pm2.g2 AS g_0 ORDER BY c_0" };
    // create a plan and assert our atomic queries
    ProcessorPlan plan = TestOptimizer.helpPlan(sql, TestOptimizer.example1(), expected, ComparisonMode.EXACT_COMMAND_STRING);
    TestOptimizer.checkNodeTypes(plan, new int[] { // Access
    2, // DependentAccess
    0, // DependentSelect
    0, // DependentProject
    0, // DupRemove
    0, // Grouping
    0, // NestedLoopJoinStrategy
    0, // MergeJoinStrategy
    1, // Null
    0, // PlanExecution
    0, // Project
    1, // Select
    0, // Sort
    0, // UnionAll
    0 });
    /*
		 * Retrieve root nodes elements to assert that a constant has 
		 * has replaced the SQRT() function. 
		 */
    List<?> elem = ((RelationalPlan) plan).getRootNode().getElements();
    Constant expectedConst = new Constant(new Double(10.0));
    assertEquals(// $NON-NLS-1$
    "Did not get expected constant value for SqrtLeft in root node of plan: ", expectedConst, // should be a AliasSymbol containing an expression
    ((ExpressionSymbol) elem.get(8)).getExpression());
}
Also used : Constant(org.teiid.query.sql.symbol.Constant) ProcessorPlan(org.teiid.query.processor.ProcessorPlan)

Example 17 with Constant

use of org.teiid.query.sql.symbol.Constant in project teiid by teiid.

the class TestJoinWithFunction method testDeterministicPrePostJoin.

/**
 * <p>Test the use of a deterministic function on the sub-command of a user
 * command and the user command itself, which performs a JOIN of two sources.</p>
 *
 * <p>This test combines the PostJoin and PreJoin test cases.</p>
 * @throws TeiidComponentException
 * @throws QueryValidatorException
 * @throws QueryResolverException
 * @throws QueryParserException
 * @see #testDeterministicPostJoin
 * @see #testDeterministicPreJoin
 */
public void testDeterministicPrePostJoin() throws Exception {
    // sub-query for one side of a JOIN
    String leftQuery = // $NON-NLS-1$
    "SELECT pm1.g1.e1 as ID, pm1.g1.e2, pm1.g1.e3, pm1.g1.e4, SQRT(100) AS SqrtLeft " + // $NON-NLS-1$
    "FROM pm1.g1";
    // sub-query for other side of a JOIN
    String rightQuery = // $NON-NLS-1$
    "SELECT pm2.g2.e1 as ID, pm2.g2.e2, pm2.g2.e3, pm2.g2.e4 " + // $NON-NLS-1$
    "FROM pm2.g2";
    // User Command
    /*
		 * Return everything from the JOIN. SqrtTop is the use of SQRT(100) on
		 * the user command while SqrtLeft is the use of SQRT() within a
		 * source node.
		 */
    String sql = // $NON-NLS-1$
    "SELECT l.ID, l.e2, l.e3, l.e4, r.ID, r.e2, r.e3, r.e4, l.SqrtLeft, SQRT(100) AS SqrtTop " + "FROM (" + leftQuery + // $NON-NLS-1$ //$NON-NLS-2$
    ") AS l, " + "(" + rightQuery + // $NON-NLS-1$ //$NON-NLS-2$
    ") AS r " + // $NON-NLS-1$
    "WHERE l.ID = r.ID";
    // The user command should result in two atomic commands
    String[] expected = new String[] { // $NON-NLS-1$
    "SELECT g_0.e1 AS c_0, g_0.e2 AS c_1, g_0.e3 AS c_2, g_0.e4 AS c_3 FROM pm1.g1 AS g_0 ORDER BY c_0", // $NON-NLS-1$
    "SELECT g_0.e1 AS c_0, g_0.e2 AS c_1, g_0.e3 AS c_2, g_0.e4 AS c_3 FROM pm2.g2 AS g_0 ORDER BY c_0" };
    // create a plan and assert our atomic queries
    ProcessorPlan plan = TestOptimizer.helpPlan(sql, TestOptimizer.example1(), expected, ComparisonMode.EXACT_COMMAND_STRING);
    TestOptimizer.checkNodeTypes(plan, new int[] { // Access
    2, // DependentAccess
    0, // DependentSelect
    0, // DependentProject
    0, // DupRemove
    0, // Grouping
    0, // NestedLoopJoinStrategy
    0, // MergeJoinStrategy
    1, // Null
    0, // PlanExecution
    0, // Project
    1, // Select
    0, // Sort
    0, // UnionAll
    0 });
    /*
		 * Retrieve root nodes elements to assert that a constant has 
		 * replaced the SQRT() function for both SqrtTop and SqrtLeft. 
		 */
    List<?> elem = ((RelationalPlan) plan).getRootNode().getElements();
    Constant expectedConst = new Constant(new Double(10.0));
    assertEquals(// $NON-NLS-1$
    "Did not get expected constant value for SqrtLeft in root node of plan: ", expectedConst, // should be a AliasSymbol containing an expression
    SymbolMap.getExpression((Expression) elem.get(8)));
    assertEquals(// $NON-NLS-1$
    "Did not get expected constant value for SqrtTop in root node of plan: ", expectedConst, // should be a AliasSymbol containing an expression
    SymbolMap.getExpression((Expression) elem.get(9)));
}
Also used : Expression(org.teiid.query.sql.symbol.Expression) Constant(org.teiid.query.sql.symbol.Constant) ProcessorPlan(org.teiid.query.processor.ProcessorPlan)

Example 18 with Constant

use of org.teiid.query.sql.symbol.Constant 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);
}
Also used : ElementSymbol(org.teiid.query.sql.symbol.ElementSymbol) ScalarSubquery(org.teiid.query.sql.symbol.ScalarSubquery) Query(org.teiid.query.sql.lang.Query) Constant(org.teiid.query.sql.symbol.Constant) SymbolMap(org.teiid.query.sql.util.SymbolMap) FunctionDescriptor(org.teiid.query.function.FunctionDescriptor) ModelMetaData(org.teiid.adminapi.impl.ModelMetaData) Function(org.teiid.query.sql.symbol.Function) CapabilitiesFinder(org.teiid.query.optimizer.capabilities.CapabilitiesFinder) FunctionExecutionException(org.teiid.api.exception.query.FunctionExecutionException) Expression(org.teiid.query.sql.symbol.Expression) VDBMetaData(org.teiid.adminapi.impl.VDBMetaData) Select(org.teiid.query.sql.lang.Select) SourceCapabilities(org.teiid.query.optimizer.capabilities.SourceCapabilities)

Example 19 with Constant

use of org.teiid.query.sql.symbol.Constant in project teiid by teiid.

the class AccessNode method minimizeProject.

public void minimizeProject(Command atomicCommand) {
    if (!(atomicCommand instanceof Query)) {
        return;
    }
    Query query = (Query) atomicCommand;
    Select select = query.getSelect();
    List<Expression> symbols = select.getSymbols();
    if (symbols.size() == 1) {
        return;
    }
    boolean shouldProject = false;
    LinkedHashMap<Expression, Integer> uniqueSymbols = new LinkedHashMap<Expression, Integer>();
    projection = new Object[symbols.size()];
    this.originalSelect = new ArrayList<Expression>(query.getSelect().getSymbols());
    int i = 0;
    int j = 0;
    for (Iterator<Expression> iter = symbols.iterator(); iter.hasNext(); ) {
        Expression ss = iter.next();
        Expression ex = SymbolMap.getExpression(ss);
        if (ex instanceof Constant) {
            projection[i] = ex;
            if (iter.hasNext() || j != 0) {
                iter.remove();
                shouldProject = true;
            } else {
                projection[i] = j++;
            }
        } else {
            Integer index = uniqueSymbols.get(ex);
            if (index == null) {
                uniqueSymbols.put(ex, j);
                index = j++;
            } else {
                iter.remove();
                shouldProject = true;
            }
            projection[i] = index;
        }
        i++;
    }
    if (!shouldProject) {
        this.projection = NO_PROJECTION;
    } else if (query.getOrderBy() != null) {
        for (OrderByItem item : query.getOrderBy().getOrderByItems()) {
            Integer index = uniqueSymbols.get(SymbolMap.getExpression(item.getSymbol()));
            if (index != null) {
                item.setExpressionPosition(index);
                item.setSymbol(select.getSymbols().get(index));
            }
        }
    }
}
Also used : Query(org.teiid.query.sql.lang.Query) Constant(org.teiid.query.sql.symbol.Constant) OrderByItem(org.teiid.query.sql.lang.OrderByItem) Expression(org.teiid.query.sql.symbol.Expression) Select(org.teiid.query.sql.lang.Select)

Example 20 with Constant

use of org.teiid.query.sql.symbol.Constant in project teiid by teiid.

the class DependentCriteriaProcessor method replaceDependentValueIterators.

/**
 * Replace the dependentSet value iterators with the next set of values from the independent tuple source
 *
 * @param dependentSets
 * @param replacementValueIterators
 * @throws TeiidComponentException
 */
private void replaceDependentValueIterators() throws TeiidComponentException {
    int currentPredicates = 0;
    for (int run = 0; currentPredicates < totalPredicates; run++) {
        currentPredicates = 0;
        if (!restartIndexes.isEmpty()) {
            currentIndex = restartIndexes.removeLast().intValue();
        }
        int possible = 0;
        for (int i = 0; i < sources.size(); i++) {
            List<SetState> source = sources.get(i);
            if (i == currentIndex) {
                currentIndex++;
                int doneCount = 0;
                while (doneCount < source.size()) {
                    boolean isNull = false;
                    boolean lessThanMax = true;
                    for (SetState state : source) {
                        if (state.overMax) {
                            doneCount++;
                            continue;
                        }
                        if (state.nextValue == null && !state.isNull) {
                            if (state.valueIterator.hasNext()) {
                                state.nextValue = state.valueIterator.next();
                                state.isNull = state.nextValue == null;
                            } else {
                                state.valueIterator.reset();
                                // should be true for each iterator from this source
                                doneCount++;
                                continue;
                            }
                        }
                        isNull |= state.isNull;
                        lessThanMax &= state.replacementSize() < maxSize * (run + 1);
                    }
                    if (doneCount == source.size()) {
                        if (!restartIndexes.isEmpty() && restartIndexes.getLast().intValue() == i) {
                            restartIndexes.removeLast();
                        }
                        break;
                    }
                    if (lessThanMax || isNull) {
                        for (SetState state : source) {
                            if (!isNull) {
                                Constant constant = newConstant(state.nextValue);
                                if (state.existingSet == null || state.existingSet.getValues().contains(constant)) {
                                    state.replacement.add(constant);
                                }
                            }
                            state.nextValue = null;
                            state.isNull = false;
                        }
                    } else {
                        restartIndexes.add(i);
                        break;
                    }
                }
            }
            for (SetState setState : source) {
                currentPredicates += setState.replacementSize() / maxSize + (setState.replacementSize() % maxSize != 0 ? 1 : 0);
            }
            possible += source.size();
        }
        if (currentPredicates + possible > totalPredicates) {
            // don't exceed the max
            break;
        }
        if (restartIndexes.isEmpty()) {
            break;
        }
    }
    hasNextCommand = !restartIndexes.isEmpty();
    if (hasNextCommand && dependentState.size() > 1) {
        for (TupleState state : dependentState.values()) {
            state.originalVs.setUnused(true);
        }
    }
}
Also used : Constant(org.teiid.query.sql.symbol.Constant)

Aggregations

Constant (org.teiid.query.sql.symbol.Constant)203 ElementSymbol (org.teiid.query.sql.symbol.ElementSymbol)94 Test (org.junit.Test)88 ArrayList (java.util.ArrayList)61 GroupSymbol (org.teiid.query.sql.symbol.GroupSymbol)48 List (java.util.List)38 Expression (org.teiid.query.sql.symbol.Expression)38 Function (org.teiid.query.sql.symbol.Function)31 CompareCriteria (org.teiid.query.sql.lang.CompareCriteria)25 Query (org.teiid.query.sql.lang.Query)22 Select (org.teiid.query.sql.lang.Select)15 Reference (org.teiid.query.sql.symbol.Reference)14 From (org.teiid.query.sql.lang.From)12 HashMap (java.util.HashMap)11 FunctionDescriptor (org.teiid.query.function.FunctionDescriptor)11 Criteria (org.teiid.query.sql.lang.Criteria)11 SetQuery (org.teiid.query.sql.lang.SetQuery)11 LinkedList (java.util.LinkedList)10 Limit (org.teiid.query.sql.lang.Limit)10 StoredProcedure (org.teiid.query.sql.lang.StoredProcedure)9