Package org.voltdb.plannodes

Examples of org.voltdb.plannodes.IndexScanPlanNode


        pn = pn.getChild(0);
        if (pn != null) {
            System.out.println(pn.toJSONString());
        }
        assertTrue(pn instanceof IndexScanPlanNode);
        IndexScanPlanNode ispn = (IndexScanPlanNode)pn;
        assertEquals("COVER2_TREE", ispn.getTargetIndexName());
        assertEquals(IndexLookupType.EQ, ispn.getLookupType());
        assertEquals(2, ispn.getSearchKeyExpressions().size());
    }
View Full Code Here


        pn = pn.getChild(0);
        if (pn != null) {
            System.out.println(pn.toJSONString());
        }
        assertTrue(pn instanceof IndexScanPlanNode);
        IndexScanPlanNode ispn = (IndexScanPlanNode)pn;
        assertEquals("COVER3_TREE", ispn.getTargetIndexName());
        assertEquals(IndexLookupType.LT, ispn.getLookupType());
        assertEquals(3, ispn.getSearchKeyExpressions().size());
    }
View Full Code Here

        pn = pn.getChild(0);
        if (pn != null) {
            System.out.println(pn.toJSONString());
        }
        assertTrue(pn instanceof IndexScanPlanNode);
        IndexScanPlanNode ispn = (IndexScanPlanNode)pn;
        assertEquals("COVER3_TREE", ispn.getTargetIndexName());
        assertEquals(IndexLookupType.GTE, ispn.getLookupType());
        assertEquals(2, ispn.getSearchKeyExpressions().size());
    }
View Full Code Here

        pn = pn.getChild(0);
        if (pn != null) {
            System.out.println(pn.toJSONString());
        }
        assertTrue(pn instanceof IndexScanPlanNode);
        IndexScanPlanNode ispn = (IndexScanPlanNode)pn;
        assertEquals("COVER3_TREE", ispn.getTargetIndexName());
        assertEquals(IndexLookupType.GTE, ispn.getLookupType());
        assertEquals(2, ispn.getSearchKeyExpressions().size());
    }
View Full Code Here

        pn = pn.getChild(0);
        if (pn != null) {
            System.out.println(pn.toJSONString());
        }
        assertTrue(pn instanceof IndexScanPlanNode);
        IndexScanPlanNode ispn = (IndexScanPlanNode)pn;
        assertEquals("IDX_1_TREE", ispn.getTargetIndexName());
        assertEquals(IndexLookupType.LT, ispn.getLookupType());
        assertEquals(3, ispn.getSearchKeyExpressions().size());
    }
View Full Code Here

        if (subPlanGraph != null) {
            ixscans.addAll(subPlanGraph.findAllNodesOfType(PlanNodeType.INDEXSCAN));
        }
        for (AbstractPlanNode apn : ixscans) {
            assert(apn instanceof IndexScanPlanNode);
            IndexScanPlanNode ixs = (IndexScanPlanNode) apn;
            setParamIndexes(ints, ixs.getBindings());
        }

        ArrayList<AbstractPlanNode> ixcounts = rootPlanGraph.findAllNodesOfType(PlanNodeType.INDEXCOUNT);
        if (subPlanGraph != null) {
            ixcounts.addAll(subPlanGraph.findAllNodesOfType(PlanNodeType.INDEXCOUNT));
View Full Code Here

        // Otherwise, optimized counts only replace particular cases of index scan.
        if ((child instanceof IndexScanPlanNode) == false)
            return plan;

        IndexScanPlanNode isp = (IndexScanPlanNode)child;

        // Guard against (possible future?) cases of indexable subquery.
        if (((IndexScanPlanNode)child).isSubQuery()) {
            return plan;
        }

        // An index count or table count can replace an index scan only if it has no (post-)predicates
        // except those (post-)predicates are artifact predicates we added for reverse scan purpose only
        if (isp.getPredicate() != null && !isp.isPredicatesOptimizableForAggregate()) {
            return plan;
        }

        // With no start or end keys, there's not much a counting index can do.
        if (isp.getEndExpression() == null && isp.getSearchKeyExpressions().size() == 0) {
            // An indexed query without a where clause can fall back to a plain old table count.
            // This can only happen when a confused query like
            // "select count(*) from table order by index_key;"
            // meets a naive planner that doesn't just cull the no-op ORDER BY. Who, us?
            return new TableCountPlanNode(isp, aggplan);
        }

        // check for the index's support for counting
        Index idx = isp.getCatalogIndex();
        if ( ! idx.getCountable()) {
            return plan;
        }

        // The core idea is that counting index needs to know the start key and end key to
View Full Code Here

        if (child.getPlanNodeType() == PlanNodeType.INDEXSCAN) {
            // Currently do not conflict with the optimized MIN/MAX
            // because of the big amount of tests changed.

            IndexScanPlanNode isp = (IndexScanPlanNode)child;
            LimitPlanNode limit = (LimitPlanNode)isp.getInlinePlanNode(PlanNodeType.LIMIT);
            if (limit != null && (aggplan.isTableMin() || aggplan.isTableMax())) {
                // Optimized MIN/MAX
                if (limit.getLimit() == 1 && limit.getOffset() == 0) {
                    return plan;
                }
View Full Code Here

            } else {
                // 1. create one INDEXSCAN plan node with inlined LIMIT
                // and replace the SEQSCAN node with it
                // 2. we know which end row we want to fetch, so it's safe to
                // specify sorting direction here
                IndexScanPlanNode ispn = new IndexScanPlanNode((SeqScanPlanNode) child, aggplan, ret, sortDirection);
                ispn.setBindings(bindings);
                assert(ispn.getSearchKeyExpressions().size() == 0);
                if (sortDirection == SortDirectionType.ASC) {
                    assert(aggplan.isTableMin());
                    ispn.setSkipNullPredicate(0);
                }

                LimitPlanNode lpn = new LimitPlanNode();
                lpn.setLimit(1);
                lpn.setOffset(0);

                ispn.addInlinePlanNode(lpn);

                // remove old SeqScan node and link the new generated IndexScan node
                plan.clearChildren();
                plan.addAndLinkChild(ispn);

                return plan;
            }
        }

        if ((child instanceof IndexScanPlanNode) == false) {
            return plan;
        }

        // already have the IndexScanPlanNode
        IndexScanPlanNode ispn = (IndexScanPlanNode)child;

        // can do optimization only if it has no (post-)predicates
        // except those (post-)predicates are artifact predicates
        // we added for reverse scan purpose only
        if (((IndexScanPlanNode)child).getPredicate() != null &&
                !((IndexScanPlanNode)child).isPredicatesOptimizableForAggregate()) {
            return plan;
        }

        // Guard against (possible future?) cases of indexable subquery.
        if (((AbstractScanPlanNode)child).isSubQuery()) {
            return plan;
        }

        // 1. Handle ALL equality filters case.
        // In the IndexScanPlanNode:
        //      -- EQFilterExprs were put in searchkeyExpressions and endExpressions
        //      -- startCondition is only in searchKeyExpressions
        //      -- endCondition is only in endExpressions
        // So, if the lookup type is EQ, then all filters must be equality; or if
        // there are extra startCondition / endCondition, some filters are not equality
        // 2. Handle equality filters and one other comparison operator (<, <=, >, >=), see comments below
        if (ispn.getLookupType() != IndexLookupType.EQ &&
                Math.abs(ispn.getSearchKeyExpressions().size() - ExpressionUtil.uncombine(ispn.getEndExpression()).size()) > 1) {
            return plan;
        }

        // exprs will be used as filterExprs to check the index
        // For forward scan, the initial value is endExprs and might be changed in different values in variant cases
        // For reverse scan, the initial value is initialExprs which is the "old" endExprs
        List<AbstractExpression> exprs;
        int numOfSearchKeys = ispn.getSearchKeyExpressions().size();
        if (ispn.getLookupType() == IndexLookupType.LT || ispn.getLookupType() == IndexLookupType.LTE) {
            exprs = ExpressionUtil.uncombine(ispn.getInitialExpression());
            numOfSearchKeys -= 1;
        } else {
            exprs = ExpressionUtil.uncombine(ispn.getEndExpression());
        }
        int numberOfExprs = exprs.size();

        // If there is only 1 difference between searchkeyExprs and endExprs,
        // 1. trivial filters can be discarded, 2 possibilities:
        //      a. SELECT MIN(X) FROM T WHERE [other prefix filters] X < / <= ?
        //         <=> SELECT MIN(X) FROM T WHERE [other prefix filters] && the X < / <= ? filter
        //      b. SELECT MAX(X) FROM T WHERE X > / >= ?
        //         <=> SELECT MAX(X) FROM T with post-filter
        // 2. filter should act as equality filter, 2 possibilities
        //      SELECT MIN(X) FROM T WHERE [other prefix filters] X > / >= ?
        //      SELECT MAX(X) FROM T WHERE [other prefix filters] X < / <= ?

        // check if there is other filters for SELECT MAX(X) FROM T WHERE [other prefix filter AND ] X > / >= ?
        // but we should allow SELECT MAX(X) FROM T WHERE X = ?
        if (sortDirection == SortDirectionType.DESC && ispn.getSortDirection() == SortDirectionType.INVALID) {
            if (numberOfExprs > 1 ||
                    (numberOfExprs == 1 && aggExpr.bindingToIndexedExpression(exprs.get(0).getLeft()) == null)) {
                return plan;
            }
        }

        // have an upper bound: # of endingExpr is more than # of searchExpr
        if (numberOfExprs > numOfSearchKeys) {
            // check last ending condition, see whether it is
            //      SELECT MIN(X) FROM T WHERE [other prefix filters] X < / <= ? or
            // other filters will be checked later
            AbstractExpression lastEndExpr = exprs.get(numberOfExprs - 1);
            if ((lastEndExpr.getExpressionType() == ExpressionType.COMPARE_LESSTHAN ||
                 lastEndExpr.getExpressionType() == ExpressionType.COMPARE_LESSTHANOREQUALTO)
                    && lastEndExpr.getLeft().equals(aggExpr)) {
                exprs.remove(lastEndExpr);
            }
        }

        // do not aggressively evaluate all indexes, just examine the index currently in use;
        // because for all qualified indexes, one access plan must have been generated already,
        // and we can take advantage of that
        if (!checkIndex(ispn.getCatalogIndex(), aggExpr, exprs, ispn.getBindings(), ispn.getTargetTableAlias())) {
            return plan;
        } else {
            // we know which end we want to fetch, set the sort direction
            ispn.setSortDirection(sortDirection);

            // for SELECT MIN(X) FROM T WHERE [prefix filters] = ?
            if (numberOfExprs == numOfSearchKeys && sortDirection == SortDirectionType.ASC) {
                if (ispn.getLookupType() == IndexLookupType.GTE) {
                    assert(aggplan.isTableMin());
                    ispn.setSkipNullPredicate(numOfSearchKeys);
                }
            }

            // for SELECT MIN(X) FROM T WHERE [...] X < / <= ?
            // reset the IndexLookupType, remove "added" searchKey, add back to endExpression, and clear "added" predicate
            if (sortDirection == SortDirectionType.ASC &&
                    (ispn.getLookupType() == IndexLookupType.LT || ispn.getLookupType() == IndexLookupType.LTE)){
                ispn.setLookupType(IndexLookupType.GTE);
                ispn.removeLastSearchKey();
                ispn.addEndExpression(ExpressionUtil.uncombine(ispn.getInitialExpression()).get(numberOfExprs - 1));
                ispn.resetPredicate();
            }
            // add an inline LIMIT plan node to this index scan plan node
            LimitPlanNode lpn = new LimitPlanNode();
            lpn.setLimit(1);
            lpn.setOffset(0);
            ispn.addInlinePlanNode(lpn);

            // ENG-1565: For SELECT MAX(X) FROM T WHERE X > / >= ?, turn the pre-filter to post filter.
            // There are two choices:
            // AggregatePlanNode                AggregatePlanNode
            //  |__ IndexScanPlanNode       =>      |__FilterPlanNode
            //                                              |__IndexScanPlanNode with no filter
            //                                                      |__LimitPlanNode
            //                          OR
            // AggregatePlanNode                AggregatePlanNode with filter
            //  |__ IndexScanPlanNode       =>      |__IndexScanPlanNode with no filter
            //                                              |__LimitPlanNode
            // For now, we take the second approach.
            if (sortDirection == SortDirectionType.DESC &&
                    !ispn.getSearchKeyExpressions().isEmpty() &&
                    exprs.isEmpty() &&
                    ExpressionUtil.uncombine(ispn.getInitialExpression()).isEmpty()) {
                AbstractExpression newPredicate = new ComparisonExpression();
                if (ispn.getLookupType() == IndexLookupType.GT)
                    newPredicate.setExpressionType(ExpressionType.COMPARE_GREATERTHAN);
                if (ispn.getLookupType() == IndexLookupType.GTE)
                    newPredicate.setExpressionType(ExpressionType.COMPARE_GREATERTHANOREQUALTO);
                newPredicate.setRight(ispn.getSearchKeyExpressions().get(0));
                newPredicate.setLeft(aggExpr);
                newPredicate.setValueType(aggExpr.getValueType());
                ispn.clearSearchKeyExpression();
                aggplan.setPrePredicate(newPredicate);
            }

            return plan;
        }
View Full Code Here

            ajNode = nljNode;
        }
        else if (canHaveNLIJ) {
            NestLoopIndexPlanNode nlijNode = new NestLoopIndexPlanNode();

            IndexScanPlanNode innerNode = (IndexScanPlanNode) innerPlan;
            // Set IndexScan predicate
            innerNode.setPredicate(ExpressionUtil.combine(innerAccessPath.otherExprs));

            nlijNode.addInlinePlanNode(innerPlan);

            // combine the tails plan graph with the new head node
            nlijNode.addAndLinkChild(outerPlan);
View Full Code Here

TOP

Related Classes of org.voltdb.plannodes.IndexScanPlanNode

Copyright © 2018 www.massapicom. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.