Search in sources :

Example 16 with CompareCriteria

use of org.teiid.query.sql.lang.CompareCriteria in project teiid by teiid.

the class TestJoinNode method helpCreateJoin.

protected void helpCreateJoin() {
    // $NON-NLS-1$
    ElementSymbol es1 = new ElementSymbol("e1");
    es1.setType(DataTypeManager.DefaultDataClasses.INTEGER);
    // $NON-NLS-1$
    ElementSymbol es2 = new ElementSymbol("e2");
    es2.setType(DataTypeManager.DefaultDataClasses.INTEGER);
    List leftElements = new ArrayList();
    leftElements.add(es1);
    leftNode = new BlockingFakeRelationalNode(1, leftTuples);
    leftNode.setElements(leftElements);
    List rightElements = new ArrayList();
    rightElements.add(es2);
    rightNode = new BlockingFakeRelationalNode(2, rightTuples) {

        @Override
        public boolean hasBuffer() {
            return false;
        }

        @Override
        public TupleBuffer getBufferDirect(int maxRows) throws BlockedException, TeiidComponentException, TeiidProcessingException {
            fail();
            throw new AssertionError();
        }
    };
    rightNode.setElements(rightElements);
    List joinElements = new ArrayList();
    joinElements.add(es1);
    joinElements.add(es2);
    join = new JoinNode(3);
    joinStrategy = new NestedLoopJoinStrategy();
    join.setJoinStrategy(joinStrategy);
    join.setElements(joinElements);
    join.setJoinType(joinType);
    switch(criteriaType) {
        case NO_CRITERIA:
            break;
        case EQUAL_CRITERIA:
            join.setJoinExpressions(Arrays.asList(es1), Arrays.asList(es2));
            joinStrategy = new MergeJoinStrategy(SortOption.SORT, SortOption.SORT, false);
            join.setJoinStrategy(joinStrategy);
            break;
        case FUNCTION_CRITERIA:
            // $NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
            Function func = new Function("lookup", new Expression[] { new Constant("pm1.g1"), new Constant("e2"), new Constant("e1"), es1 });
            // $NON-NLS-1$
            FunctionDescriptor desc = RealMetadataFactory.SFM.getSystemFunctionLibrary().findFunction("lookup", new Class[] { String.class, String.class, String.class, Integer.class });
            func.setFunctionDescriptor(desc);
            func.setType(DataTypeManager.DefaultDataClasses.INTEGER);
            CompareCriteria joinCriteria = new CompareCriteria(es2, CompareCriteria.EQ, func);
            join.setJoinCriteria(joinCriteria);
            break;
    }
}
Also used : ElementSymbol(org.teiid.query.sql.symbol.ElementSymbol) Constant(org.teiid.query.sql.symbol.Constant) ArrayList(java.util.ArrayList) TupleBuffer(org.teiid.common.buffer.TupleBuffer) FunctionDescriptor(org.teiid.query.function.FunctionDescriptor) BlockedException(org.teiid.common.buffer.BlockedException) CompareCriteria(org.teiid.query.sql.lang.CompareCriteria) TeiidProcessingException(org.teiid.core.TeiidProcessingException) Function(org.teiid.query.sql.symbol.Function) ArrayList(java.util.ArrayList) List(java.util.List) TeiidComponentException(org.teiid.core.TeiidComponentException)

Example 17 with CompareCriteria

use of org.teiid.query.sql.lang.CompareCriteria in project teiid by teiid.

the class TestSelectNode method testTimeslicing.

@Test
public void testTimeslicing() throws TeiidComponentException, TeiidProcessingException {
    // $NON-NLS-1$
    ElementSymbol es1 = new ElementSymbol("e1");
    es1.setType(DataTypeManager.DefaultDataClasses.INTEGER);
    List elements = new ArrayList();
    elements.add(es1);
    CompareCriteria crit = new CompareCriteria(es1, CompareCriteria.EQ, new Constant(new Integer(1)));
    List[] data = new List[] { Arrays.asList(1), Arrays.asList(1), Arrays.asList(1) };
    List childElements = new ArrayList();
    childElements.add(es1);
    helpTestSelect(elements, crit, childElements, null, data, new FakeRelationalNode(2, data), new SelectNode(3) {

        int i = 0;

        @Override
        protected Evaluator getEvaluator(Map elementMap) {
            return new Evaluator(elementMap, getDataManager(), getContext()) {

                @Override
                public Boolean evaluateTVL(Criteria criteria, List<?> tuple) throws ExpressionEvaluationException, BlockedException, TeiidComponentException {
                    if (i++ == 1) {
                        throw new QueryProcessor.ExpiredTimeSliceException();
                    }
                    return super.evaluateTVL(criteria, tuple);
                }
            };
        }
    });
}
Also used : ElementSymbol(org.teiid.query.sql.symbol.ElementSymbol) ExpressionEvaluationException(org.teiid.api.exception.query.ExpressionEvaluationException) Constant(org.teiid.query.sql.symbol.Constant) ArrayList(java.util.ArrayList) Criteria(org.teiid.query.sql.lang.Criteria) CompareCriteria(org.teiid.query.sql.lang.CompareCriteria) Evaluator(org.teiid.query.eval.Evaluator) CompareCriteria(org.teiid.query.sql.lang.CompareCriteria) BlockedException(org.teiid.common.buffer.BlockedException) QueryProcessor(org.teiid.query.processor.QueryProcessor) ArrayList(java.util.ArrayList) List(java.util.List) TeiidComponentException(org.teiid.core.TeiidComponentException) HashMap(java.util.HashMap) Map(java.util.Map) Test(org.junit.Test)

Example 18 with CompareCriteria

use of org.teiid.query.sql.lang.CompareCriteria in project teiid by teiid.

the class TestRuleValidateWhereAll method testHasNoCriteria2.

public void testHasNoCriteria2() {
    Query query = new Query();
    // $NON-NLS-1$ //$NON-NLS-2$
    CompareCriteria crit = new CompareCriteria(new Constant("a"), CompareCriteria.EQ, new Constant("b"));
    query.setCriteria(crit);
    // $NON-NLS-1$
    assertEquals("Got incorrect answer checking for no criteria", false, RuleValidateWhereAll.hasNoCriteria(query));
}
Also used : Query(org.teiid.query.sql.lang.Query) Constant(org.teiid.query.sql.symbol.Constant) CompareCriteria(org.teiid.query.sql.lang.CompareCriteria)

Example 19 with CompareCriteria

use of org.teiid.query.sql.lang.CompareCriteria in project teiid by teiid.

the class RuleImplementJoinStrategy method execute.

/**
 * @see org.teiid.query.optimizer.relational.OptimizerRule#execute(org.teiid.query.optimizer.relational.plantree.PlanNode, org.teiid.query.metadata.QueryMetadataInterface, org.teiid.query.optimizer.capabilities.CapabilitiesFinder, org.teiid.query.optimizer.relational.RuleStack, org.teiid.query.analysis.AnalysisRecord, org.teiid.query.util.CommandContext)
 */
public PlanNode execute(PlanNode plan, QueryMetadataInterface metadata, CapabilitiesFinder capabilitiesFinder, RuleStack rules, AnalysisRecord analysisRecord, CommandContext context) throws QueryPlannerException, QueryMetadataException, TeiidComponentException {
    for (PlanNode sourceNode : NodeEditor.findAllNodes(plan, NodeConstants.Types.SOURCE, NodeConstants.Types.ACCESS)) {
        SymbolMap references = (SymbolMap) sourceNode.getProperty(NodeConstants.Info.CORRELATED_REFERENCES);
        if (references != null) {
            Set<GroupSymbol> groups = GroupsUsedByElementsVisitor.getGroups(references.getValues());
            PlanNode joinNode = NodeEditor.findParent(sourceNode, NodeConstants.Types.JOIN, NodeConstants.Types.SOURCE);
            while (joinNode != null) {
                if (joinNode.getGroups().containsAll(groups)) {
                    joinNode.setProperty(NodeConstants.Info.JOIN_STRATEGY, JoinStrategyType.NESTED_TABLE);
                    Info info = Info.RIGHT_NESTED_REFERENCES;
                    if (!FrameUtil.findJoinSourceNode(joinNode.getFirstChild()).getGroups().containsAll(groups)) {
                        // $NON-NLS-1$
                        throw new AssertionError("Should not have reordered the join tree to reverse the lateral join");
                    }
                    SymbolMap map = (SymbolMap) joinNode.getProperty(info);
                    if (map == null) {
                        map = new SymbolMap();
                    }
                    joinNode.setProperty(info, map);
                    map.asUpdatableMap().putAll(references.asMap());
                    if (joinNode.getProperty(NodeConstants.Info.DEPENDENT_VALUE_SOURCE) != null) {
                        // $NON-NLS-1$
                        throw new AssertionError("Cannot use a depenedent join when the join involves a correlated nested table.");
                    }
                    break;
                }
                joinNode = NodeEditor.findParent(joinNode, NodeConstants.Types.JOIN, NodeConstants.Types.SOURCE);
            }
        }
    }
    for (PlanNode joinNode : NodeEditor.findAllNodes(plan, NodeConstants.Types.JOIN, NodeConstants.Types.ACCESS)) {
        JoinStrategyType stype = (JoinStrategyType) joinNode.getProperty(NodeConstants.Info.JOIN_STRATEGY);
        if (!JoinStrategyType.MERGE.equals(stype)) {
            continue;
        }
        List<Expression> leftExpressions = (List<Expression>) joinNode.getProperty(NodeConstants.Info.LEFT_EXPRESSIONS);
        List<Expression> rightExpressions = (List<Expression>) joinNode.getProperty(NodeConstants.Info.RIGHT_EXPRESSIONS);
        int origExpressionCount = leftExpressions.size();
        // check index information on each side
        // TODO: don't do null order compensation - in fact we should check what the order actually is, but we don't have that metadata
        Object key = null;
        boolean right = true;
        // we check the right first, since it should be larger
        if (joinNode.getLastChild().getType() == NodeConstants.Types.ACCESS && NewCalculateCostUtil.isSingleTable(joinNode.getLastChild())) {
            key = NewCalculateCostUtil.getKeyUsed(rightExpressions, null, metadata, null);
        }
        if (key == null && joinNode.getFirstChild().getType() == NodeConstants.Types.ACCESS && NewCalculateCostUtil.isSingleTable(joinNode.getFirstChild())) {
            key = NewCalculateCostUtil.getKeyUsed(leftExpressions, null, metadata, null);
            right = false;
        }
        JoinType joinType = (JoinType) joinNode.getProperty(NodeConstants.Info.JOIN_TYPE);
        /**
         * Don't push sorts for unbalanced inner joins, we prefer to use a processing time cost based decision
         */
        boolean pushLeft = true;
        boolean pushRight = true;
        if ((joinType == JoinType.JOIN_INNER || joinType == JoinType.JOIN_LEFT_OUTER) && context != null) {
            float leftCost = NewCalculateCostUtil.computeCostForTree(joinNode.getFirstChild(), metadata);
            float rightCost = NewCalculateCostUtil.computeCostForTree(joinNode.getLastChild(), metadata);
            if (leftCost != NewCalculateCostUtil.UNKNOWN_VALUE && rightCost != NewCalculateCostUtil.UNKNOWN_VALUE && (leftCost > context.getProcessorBatchSize() || rightCost > context.getProcessorBatchSize())) {
                // we use a larger constant here to ensure that we don't unwisely prevent pushdown
                pushLeft = leftCost < context.getProcessorBatchSize() || leftCost / rightCost < 8 || (key != null && !right);
                pushRight = rightCost < context.getProcessorBatchSize() || rightCost / leftCost < 8 || joinType == JoinType.JOIN_LEFT_OUTER || (key != null && right);
            }
        }
        if (key != null && joinNode.getProperty(NodeConstants.Info.DEPENDENT_VALUE_SOURCE) == null) {
            // redo the join predicates based upon the key alone
            List<Object> keyCols = metadata.getElementIDsInKey(key);
            int[] reorder = new int[keyCols.size()];
            LinkedHashSet<Integer> toCriteria = new LinkedHashSet<Integer>();
            List<Expression> keyExpressions = right ? rightExpressions : leftExpressions;
            Map<Object, Integer> indexMap = new LinkedHashMap<Object, Integer>();
            for (int i = 0; i < keyExpressions.size(); i++) {
                Expression ses = keyExpressions.get(i);
                if (!(ses instanceof ElementSymbol)) {
                    toCriteria.add(i);
                    continue;
                }
                Integer existing = indexMap.put(((ElementSymbol) ses).getMetadataID(), i);
                if (existing != null) {
                    toCriteria.add(existing);
                }
            }
            boolean found = true;
            for (int i = 0; i < keyCols.size(); i++) {
                Object id = keyCols.get(i);
                Integer index = indexMap.remove(id);
                if (index == null) {
                    found = false;
                    break;
                }
                reorder[i] = index;
            }
            if (found) {
                toCriteria.addAll(indexMap.values());
                List<Criteria> joinCriteria = (List<Criteria>) joinNode.getProperty(Info.NON_EQUI_JOIN_CRITERIA);
                for (int index : toCriteria) {
                    Expression lses = leftExpressions.get(index);
                    Expression rses = rightExpressions.get(index);
                    CompareCriteria cc = new CompareCriteria(lses, CompareCriteria.EQ, rses);
                    if (joinCriteria == null || joinCriteria.isEmpty()) {
                        joinCriteria = new ArrayList<Criteria>();
                    }
                    joinCriteria.add(cc);
                }
                joinNode.setProperty(Info.NON_EQUI_JOIN_CRITERIA, joinCriteria);
                leftExpressions = RelationalNode.projectTuple(reorder, leftExpressions);
                rightExpressions = RelationalNode.projectTuple(reorder, rightExpressions);
                joinNode.setProperty(NodeConstants.Info.LEFT_EXPRESSIONS, leftExpressions);
                joinNode.setProperty(NodeConstants.Info.RIGHT_EXPRESSIONS, rightExpressions);
            }
        }
        boolean pushedLeft = insertSort(joinNode.getFirstChild(), leftExpressions, joinNode, metadata, capabilitiesFinder, pushLeft, context);
        if (origExpressionCount == 1 && joinType == JoinType.JOIN_INNER && joinNode.getProperty(NodeConstants.Info.DEPENDENT_VALUE_SOURCE) != null && !joinNode.hasCollectionProperty(Info.NON_EQUI_JOIN_CRITERIA)) {
            Collection<Expression> output = (Collection<Expression>) joinNode.getProperty(NodeConstants.Info.OUTPUT_COLS);
            Collection<GroupSymbol> groups = GroupsUsedByElementsVisitor.getGroups(output);
            if (Collections.disjoint(groups, FrameUtil.findJoinSourceNode(joinNode.getFirstChild()).getGroups())) {
                pushRight = false;
                joinNode.setProperty(Info.IS_SEMI_DEP, Boolean.TRUE);
            }
        }
        boolean pushedRight = insertSort(joinNode.getLastChild(), rightExpressions, joinNode, metadata, capabilitiesFinder, pushRight, context);
        if ((!pushedRight || !pushedLeft) && (joinType == JoinType.JOIN_INNER || (joinType == JoinType.JOIN_LEFT_OUTER && !pushedLeft))) {
            joinNode.setProperty(NodeConstants.Info.JOIN_STRATEGY, JoinStrategyType.ENHANCED_SORT);
        }
    }
    return plan;
}
Also used : LinkedHashSet(java.util.LinkedHashSet) ElementSymbol(org.teiid.query.sql.symbol.ElementSymbol) Criteria(org.teiid.query.sql.lang.Criteria) CompareCriteria(org.teiid.query.sql.lang.CompareCriteria) LinkedHashMap(java.util.LinkedHashMap) PlanNode(org.teiid.query.optimizer.relational.plantree.PlanNode) ArrayList(java.util.ArrayList) List(java.util.List) JoinStrategyType(org.teiid.query.processor.relational.JoinNode.JoinStrategyType) JoinType(org.teiid.query.sql.lang.JoinType) SymbolMap(org.teiid.query.sql.util.SymbolMap) Info(org.teiid.query.optimizer.relational.plantree.NodeConstants.Info) CompareCriteria(org.teiid.query.sql.lang.CompareCriteria) Expression(org.teiid.query.sql.symbol.Expression) GroupSymbol(org.teiid.query.sql.symbol.GroupSymbol) Collection(java.util.Collection)

Example 20 with CompareCriteria

use of org.teiid.query.sql.lang.CompareCriteria in project teiid by teiid.

the class RulePushAggregates method buildAggregateMap.

private static Map<AggregateSymbol, Expression> buildAggregateMap(Collection<? extends AggregateSymbol> aggregateExpressions, QueryMetadataInterface metadata, Set<AggregateSymbol> nestedAggregates, boolean join) throws QueryResolverException, TeiidComponentException {
    Map<AggregateSymbol, Expression> aggMap = new LinkedHashMap<AggregateSymbol, Expression>();
    for (AggregateSymbol partitionAgg : aggregateExpressions) {
        Expression newExpression = null;
        Type aggFunction = partitionAgg.getAggregateFunction();
        if (aggFunction == Type.COUNT) {
            // COUNT(x) -> IFNULL(CONVERT(SUM(COUNT(x)), INTEGER), 0)
            AggregateSymbol newAgg = null;
            if (isCountStar(partitionAgg) && join) {
                // count * case (if on the inner side of an outer join)
                Function ifnull = new Function(FunctionLibrary.IFNULL, new Expression[] { partitionAgg, new Constant(1, DataTypeManager.DefaultDataClasses.INTEGER) });
                newAgg = new AggregateSymbol(NonReserved.SUM, false, ifnull);
            } else {
                newAgg = new AggregateSymbol(NonReserved.SUM, false, partitionAgg);
            }
            // Build conversion function to convert SUM (which returns LONG) back to INTEGER
            Function func = new Function(FunctionLibrary.CONVERT, new Expression[] { newAgg, new Constant(DataTypeManager.getDataTypeName(partitionAgg.getType())) });
            if (join) {
                func = new Function(FunctionLibrary.IFNULL, new Expression[] { func, new Constant(0, DataTypeManager.DefaultDataClasses.INTEGER) });
            }
            ResolverVisitor.resolveLanguageObject(func, metadata);
            newExpression = func;
            nestedAggregates.add(partitionAgg);
        } else if (aggFunction == Type.AVG) {
            // AVG(x) -> SUM(SUM(x)) / SUM(COUNT(x))
            AggregateSymbol countAgg = new AggregateSymbol(NonReserved.COUNT, false, partitionAgg.getArg(0));
            AggregateSymbol sumAgg = new AggregateSymbol(NonReserved.SUM, false, partitionAgg.getArg(0));
            AggregateSymbol sumSumAgg = new AggregateSymbol(NonReserved.SUM, false, sumAgg);
            AggregateSymbol sumCountAgg = new AggregateSymbol(NonReserved.SUM, false, countAgg);
            Expression convertedSum = new Function(FunctionLibrary.CONVERT, new Expression[] { sumSumAgg, new Constant(DataTypeManager.getDataTypeName(partitionAgg.getType())) });
            Expression convertCount = new Function(FunctionLibrary.CONVERT, new Expression[] { sumCountAgg, new Constant(DataTypeManager.getDataTypeName(partitionAgg.getType())) });
            // $NON-NLS-1$
            Function divideFunc = new Function("/", new Expression[] { convertedSum, convertCount });
            ResolverVisitor.resolveLanguageObject(divideFunc, metadata);
            newExpression = divideFunc;
            nestedAggregates.add(countAgg);
            nestedAggregates.add(sumAgg);
        } else if (partitionAgg.isEnhancedNumeric()) {
            // e.g. STDDEV_SAMP := CASE WHEN COUNT(X) > 1 THEN SQRT((SUM(X^2) - SUM(X)^2/COUNT(X))/(COUNT(X) - 1))
            AggregateSymbol countAgg = new AggregateSymbol(NonReserved.COUNT, false, partitionAgg.getArg(0));
            AggregateSymbol sumAgg = new AggregateSymbol(NonReserved.SUM, false, partitionAgg.getArg(0));
            AggregateSymbol sumSqAgg = new AggregateSymbol(NonReserved.SUM, false, new Function(SourceSystemFunctions.POWER, new Expression[] { partitionAgg.getArg(0), new Constant(2) }));
            AggregateSymbol sumSumAgg = new AggregateSymbol(NonReserved.SUM, false, sumAgg);
            AggregateSymbol sumCountAgg = new AggregateSymbol(NonReserved.SUM, false, countAgg);
            AggregateSymbol sumSumSqAgg = new AggregateSymbol(NonReserved.SUM, false, sumSqAgg);
            Expression convertedSum = new Function(FunctionLibrary.CONVERT, new Expression[] { sumSumAgg, new Constant(DataTypeManager.DefaultDataTypes.DOUBLE) });
            Function divideFunc = new Function(SourceSystemFunctions.DIVIDE_OP, new Expression[] { new Function(SourceSystemFunctions.POWER, new Expression[] { convertedSum, new Constant(2) }), sumCountAgg });
            Function minusFunc = new Function(SourceSystemFunctions.SUBTRACT_OP, new Expression[] { sumSumSqAgg, divideFunc });
            Expression divisor = null;
            if (aggFunction == Type.STDDEV_SAMP || aggFunction == Type.VAR_SAMP) {
                divisor = new Function(SourceSystemFunctions.SUBTRACT_OP, new Expression[] { sumCountAgg, new Constant(1) });
            } else {
                divisor = sumCountAgg;
            }
            Expression result = new Function(SourceSystemFunctions.DIVIDE_OP, new Expression[] { minusFunc, divisor });
            if (aggFunction == Type.STDDEV_POP || aggFunction == Type.STDDEV_SAMP) {
                result = new Function(SourceSystemFunctions.SQRT, new Expression[] { result });
            } else {
                result = new Function(FunctionLibrary.CONVERT, new Expression[] { result, new Constant(DataTypeManager.DefaultDataTypes.DOUBLE) });
            }
            Expression n = new Constant(0);
            if (aggFunction == Type.STDDEV_SAMP || aggFunction == Type.VAR_SAMP) {
                n = new Constant(1);
            }
            result = new SearchedCaseExpression(Arrays.asList(new CompareCriteria(sumCountAgg, CompareCriteria.GT, n)), Arrays.asList(result));
            ResolverVisitor.resolveLanguageObject(result, metadata);
            newExpression = result;
            nestedAggregates.add(countAgg);
            nestedAggregates.add(sumAgg);
            nestedAggregates.add(sumSqAgg);
        } else {
            // AGG(X) -> AGG(AGG(X))
            newExpression = new AggregateSymbol(aggFunction.name(), false, partitionAgg);
            if (partitionAgg.getFunctionDescriptor() != null) {
                ((AggregateSymbol) newExpression).setFunctionDescriptor(partitionAgg.getFunctionDescriptor().clone());
            }
            nestedAggregates.add(partitionAgg);
        }
        aggMap.put(partitionAgg, newExpression);
    }
    return aggMap;
}
Also used : Type(org.teiid.query.sql.symbol.AggregateSymbol.Type) JoinType(org.teiid.query.sql.lang.JoinType) CompareCriteria(org.teiid.query.sql.lang.CompareCriteria)

Aggregations

CompareCriteria (org.teiid.query.sql.lang.CompareCriteria)52 ElementSymbol (org.teiid.query.sql.symbol.ElementSymbol)25 Constant (org.teiid.query.sql.symbol.Constant)24 Criteria (org.teiid.query.sql.lang.Criteria)21 ArrayList (java.util.ArrayList)15 GroupSymbol (org.teiid.query.sql.symbol.GroupSymbol)11 Test (org.junit.Test)10 PlanNode (org.teiid.query.optimizer.relational.plantree.PlanNode)9 CompoundCriteria (org.teiid.query.sql.lang.CompoundCriteria)9 Expression (org.teiid.query.sql.symbol.Expression)9 IsNullCriteria (org.teiid.query.sql.lang.IsNullCriteria)8 List (java.util.List)7 HashMap (java.util.HashMap)6 Query (org.teiid.query.sql.lang.Query)6 SetCriteria (org.teiid.query.sql.lang.SetCriteria)6 From (org.teiid.query.sql.lang.From)5 Select (org.teiid.query.sql.lang.Select)5 DependentSetCriteria (org.teiid.query.sql.lang.DependentSetCriteria)4 Collection (java.util.Collection)3 JoinType (org.teiid.query.sql.lang.JoinType)3