Package org.modeshape.jcr.query

Examples of org.modeshape.jcr.query.NodeSequence$RowAccessor


        try {
            QueryResults result = query.execute();
            if (result.isEmpty()) return false;
            if (result.getRowCount() < 0) {
                // Try to get the first row ...
                NodeSequence seq = result.getRows();
                Batch batch = seq.nextBatch();
                while (batch != null) {
                    if (batch.hasNext()) return true;
                    // It's not common for the first batch may be empty, but it's possible. So try the next batch ...
                    batch = seq.nextBatch();
                }
                return false;
            }
            return result.getRowCount() > 0;
        } catch (RepositoryException e) {
View Full Code Here


    }

    @Test
    public void shouldNotIncludeDuplicateNodesUsingOnHeapBuffer() {
        // print(true);
        NodeSequence nonDistinct = NodeSequence.append(allNodes(), allNodes());
        NodeSequence distinct = new DistinctSequence(nonDistinct, types, bufferMgr, true);
        assertNoDuplicates(distinct);
    }
View Full Code Here

    }

    @Test
    public void shouldNotIncludeDuplicateNodesUsingOffHeapBuffer() {
        // print(true);
        NodeSequence nonDistinct = NodeSequence.append(allNodes(), allNodes());
        NodeSequence distinct = new DistinctSequence(nonDistinct, types, bufferMgr, false);
        assertNoDuplicates(distinct);
    }
View Full Code Here

    @Test
    public void shouldProduceSameOrderWithOneBatchInMemory() {
        System.out.println("Number of rows: " + countRows(allNodes()));
        int numRowsInMemory = 4;
        int numRowsInBatch = 4;
        NodeSequence batches = allNodes(1.0f, numRowsInBatch);
        RestartableSequence restartable = new RestartableSequence(workspaceName(), batches, bufferMgr, cache, numRowsInMemory);
        assertSameOrder(restartable, allNodes(), false);
        restartable.restart();
        assertSameOrder(restartable, allNodes(), true);
    }
View Full Code Here

                                                        QuerySources sources ) {
        // The indexes should already be in the correct order, from lowest cost to highest cost ...
        for (PlanNode indexNode : sourceNode.getChildren()) {
            if (indexNode.getType() != Type.INDEX) continue;
            IndexPlan index = indexNode.getProperty(Property.INDEX_SPECIFICATION, IndexPlan.class);
            NodeSequence sequence = createNodeSequenceForSource(originalQuery, context, sourceNode, index, columns, sources);
            if (sequence != null) {
                // Mark the index as being used ...
                indexNode.setProperty(Property.INDEX_USED, Boolean.TRUE);
                return sequence;
            }
View Full Code Here

                                                        PlanNode sourceNode,
                                                        IndexPlan indexPlan,
                                                        Columns columns,
                                                        QuerySources sources ) {
        // First let the supertype try to determine a node sequence. This will find the native indexes ...
        NodeSequence sequence = super.createNodeSequenceForSource(originalQuery, context, sourceNode, indexPlan, columns, sources);
        if (sequence != null) return sequence;

        // Look up the index by name ...
        String providerName = indexPlan.getProviderName();
        IndexProvider provider = indexManager.getProvider(providerName);
View Full Code Here

            public Map<String, Object> getParameters() {
                return parameters;
            }
        };
        // Return a node sequence that will lazily get the results from the index ...
        return new NodeSequence() {
            private Index.Results results;
            private BatchWriter writer;
            private boolean more = true;
            private long rowCount = 0L;
View Full Code Here

                                                  QueryCommand command,
                                                  Statistics statistics,
                                                  PlanNode plan ) {
        long nanos = System.nanoTime();
        Columns columns = null;
        NodeSequence rows = null;
        final String workspaceName = context.getWorkspaceNames().iterator().next();
        try {

            // Find the topmost PROJECT node and build the Columns ...
            PlanNode project = plan.findAtOrBelow(Type.PROJECT);
View Full Code Here

    protected NodeSequence createNodeSequence( QueryCommand originalQuery,
                                               ScanQueryContext context,
                                               PlanNode plan,
                                               Columns columns,
                                               QuerySources sources ) {
        NodeSequence rows = null;
        final String workspaceName = sources.getWorkspaceName();
        final NodeCache cache = context.getNodeCache(workspaceName);
        final TypeSystem types = context.getTypeSystem();
        final BufferManager bufferManager = context.getBufferManager();

        switch (plan.getType()) {
            case ACCESS:
                // If the ACCESS node is known to never have results ...
                if (plan.hasProperty(Property.ACCESS_NO_RESULTS)) {
                    rows = NodeSequence.emptySequence(columns.getColumns().size());
                } else {
                    // Create the sequence for the plan node under the the ACCESS node ...
                    assert plan.getChildCount() == 1;
                    rows = createNodeSequence(originalQuery, context, plan.getFirstChild(), columns, sources);
                }
                break;
            case DEPENDENT_QUERY:
                assert plan.getChildCount() == 2;
                // Create the independent query from the left ...
                PlanNode indepPlan = plan.getFirstChild();
                Columns indepColumns = context.columnsFor(indepPlan);
                String variableName = indepPlan.getProperty(Property.VARIABLE_NAME, String.class);
                NodeSequence independent = createNodeSequence(originalQuery, context, indepPlan, indepColumns, sources);

                // Create an extractor to get the value specified in the columns ...
                Column column = indepColumns.getColumns().get(0);
                boolean allowMultiValued = false;
                String typeName = indepColumns.getColumnTypeForProperty(column.getSelectorName(), column.getPropertyName());
                TypeFactory<?> type = context.getTypeSystem().getTypeFactory(typeName);
                ExtractFromRow indepExtractor = createExtractFromRow(column.getSelectorName(), column.getPropertyName(), context,
                                                                     indepColumns, sources, type, allowMultiValued);
                // Create the sequence for the dependent query ...
                PlanNode depPlan = plan.getLastChild();
                Columns depColumns = context.columnsFor(depPlan);
                NodeSequence dependent = createNodeSequence(originalQuery, context, depPlan, depColumns, sources);

                // now create the dependent query ...
                rows = new DependentQuery(independent, indepExtractor, type, dependent, variableName, context.getVariables());
                break;
            case DUP_REMOVE:
                assert plan.getChildCount() == 1;
                if (plan.getFirstChild().getType() == Type.SORT) {
                    // There is a SORT below this DUP_REMOVE, and we can do that in one fell swoop with the sort ...
                    rows = createNodeSequence(originalQuery, context, plan.getFirstChild(), columns, sources);
                } else {
                    // Create the sequence for the plan node under the DUP_REMOVE ...
                    rows = createNodeSequence(originalQuery, context, plan.getFirstChild(), columns, sources);
                    if (!rows.isEmpty() && !(rows instanceof DistinctSequence)) {
                        // Wrap that with a sequence that removes duplicates ...
                        boolean useHeap = false;
                        rows = new DistinctSequence(rows, context.getTypeSystem(), context.getBufferManager(), useHeap);
                    }
                }
                break;
            case GROUP:
                throw new UnsupportedOperationException();
            case JOIN:
                // Create the components under the JOIN ...
                assert plan.getChildCount() == 2;
                PlanNode leftPlan = plan.getFirstChild();
                PlanNode rightPlan = plan.getLastChild();

                // Define the columns for each side, taken from the supplied columns ...
                Columns leftColumns = context.columnsFor(leftPlan);
                Columns rightColumns = context.columnsFor(rightPlan);

                // Query context for the join (must remove isExists condition).
                ScanQueryContext joinQueryContext = context;
                if (context.getHints().isExistsQuery) {
                    // must not push down a LIMIT 1 condition to joins.
                    PlanHints joinPlanHints = context.getHints().clone();
                    joinPlanHints.isExistsQuery = false;
                    joinQueryContext = context.with(joinPlanHints);
                }

                NodeSequence left = createNodeSequence(originalQuery, joinQueryContext, leftPlan, leftColumns, sources);
                NodeSequence right = createNodeSequence(originalQuery, joinQueryContext, rightPlan, rightColumns, sources);

                // Figure out the join algorithm ...
                JoinAlgorithm algorithm = plan.getProperty(Property.JOIN_ALGORITHM, JoinAlgorithm.class);
                JoinType joinType = plan.getProperty(Property.JOIN_TYPE, JoinType.class);
                JoinCondition joinCondition = plan.getProperty(Property.JOIN_CONDITION, JoinCondition.class);
                boolean pack = false;
                boolean useHeap = false;
                if (0 >= right.getRowCount() && right.getRowCount() < 100) useHeap = true;
                ExtractFromRow leftExtractor = null;
                ExtractFromRow rightExtractor = null;
                RangeProducer<?> rangeProducer = null;
                switch (algorithm) {
                    case NESTED_LOOP:
                        // rows = new NestedLoopJoinComponent(context, left, right, joinCondition, joinType);
                        // break;
                    case MERGE:
                        if (joinCondition instanceof SameNodeJoinCondition) {
                            SameNodeJoinCondition condition = (SameNodeJoinCondition)joinCondition;
                            // check if the JOIN was not reversed by an optimization
                            boolean joinReversed = !leftColumns.getSelectorNames().contains(condition.getSelector1Name());
                            int leftIndex;
                            int rightIndex;
                            if (joinReversed) {
                                // figure out the row indexes for the different selectors ...
                                leftIndex = leftColumns.getSelectorIndex(condition.getSelector2Name());
                                rightIndex = rightColumns.getSelectorIndex(condition.getSelector1Name());
                            } else {
                                leftIndex = leftColumns.getSelectorIndex(condition.getSelector1Name());
                                rightIndex = rightColumns.getSelectorIndex(condition.getSelector2Name());
                            }
                            String relativePath = condition.getSelector2Path();
                            if (relativePath != null) {
                                // Get extractors that will get the path of the nodes ...
                                PathFactory pathFactory = context.getExecutionContext().getValueFactories().getPathFactory();
                                Path relPath = pathFactory.create(relativePath);
                                if (joinReversed) {
                                    leftExtractor = RowExtractors.extractRelativePath(leftIndex, relPath, cache, types);
                                    rightExtractor = RowExtractors.extractPath(rightIndex, cache, types);
                                } else {
                                    leftExtractor = RowExtractors.extractPath(leftIndex, cache, types);
                                    rightExtractor = RowExtractors.extractRelativePath(rightIndex, relPath, cache, types);
                                }
                            } else {
                                // The nodes must be the same node ...
                                leftExtractor = RowExtractors.extractNodeKey(leftIndex, cache, types);
                                rightExtractor = RowExtractors.extractNodeKey(rightIndex, cache, types);
                            }
                        } else if (joinCondition instanceof ChildNodeJoinCondition) {
                            ChildNodeJoinCondition condition = (ChildNodeJoinCondition)joinCondition;
                            assert leftColumns.getSelectorNames().contains(condition.getParentSelectorName());
                            int leftIndex = leftColumns.getSelectorIndex(condition.getParentSelectorName());
                            int rightIndex = rightColumns.getSelectorIndex(condition.getChildSelectorName());
                            leftExtractor = RowExtractors.extractNodeKey(leftIndex, cache, types);
                            rightExtractor = RowExtractors.extractParentNodeKey(rightIndex, cache, types);
                        } else if (joinCondition instanceof EquiJoinCondition) {
                            EquiJoinCondition condition = (EquiJoinCondition)joinCondition;
                            // check if the JOIN was not reversed by an optimization
                            boolean joinReversed = !leftColumns.getSelectorNames().contains(condition.getSelector1Name());

                            String sel1 = condition.getSelector1Name();
                            String sel2 = condition.getSelector2Name();
                            String prop1 = condition.getProperty1Name();
                            String prop2 = condition.getProperty2Name();
                            if (joinReversed) {
                                leftExtractor = createExtractFromRow(sel2, prop2, joinQueryContext, leftColumns, sources, null,
                                                                     true);
                                rightExtractor = createExtractFromRow(sel1, prop1, joinQueryContext, rightColumns, sources, null,
                                                                      true);
                            } else {
                                leftExtractor = createExtractFromRow(sel1, prop1, joinQueryContext, leftColumns, sources, null,
                                                                     true);
                                rightExtractor = createExtractFromRow(sel2, prop2, joinQueryContext, rightColumns, sources, null,
                                                                      true);
                            }

                        } else if (joinCondition instanceof DescendantNodeJoinCondition) {
                            DescendantNodeJoinCondition condition = (DescendantNodeJoinCondition)joinCondition;
                            // For this to work, we want the ancestors to be on the left, so that the descendants can quickly
                            // be found given a path of each ancestor ...
                            assert leftColumns.getSelectorNames().contains(condition.getAncestorSelectorName());
                            String ancestorSelector = condition.getAncestorSelectorName();
                            String descendantSelector = condition.getDescendantSelectorName();
                            int ancestorSelectorIndex = leftColumns.getSelectorIndex(ancestorSelector);
                            int descendantSelectorIndex = rightColumns.getSelectorIndex(descendantSelector);
                            leftExtractor = RowExtractors.extractPath(ancestorSelectorIndex, cache, types);
                            rightExtractor = RowExtractors.extractPath(descendantSelectorIndex, cache, types);
                            // This is the only time we need a RangeProducer ...
                            final PathFactory paths = context.getExecutionContext().getValueFactories().getPathFactory();
                            rangeProducer = new RangeProducer<Path>() {
                                @Override
                                public Range<Path> getRange( Path leftPath ) {
                                    if (leftPath.isRoot()) {
                                        // All paths are descendants of the root
                                        return new Range<>(leftPath, false, null, true);
                                    }
                                    // Given the path of the node on the left side of the join, find the range of all paths
                                    // that might be considered descendants of the left path....
                                    boolean includeLower = false; // we don't want to include the left node; only descendants
                                    // The upper bound path is the same as the left path, just with an incremented SNS ...
                                    Path.Segment lastSegment = leftPath.getLastSegment();
                                    Path.Segment upperSegment = paths.createSegment(lastSegment.getName(),
                                                                                    lastSegment.getIndex() + 1);
                                    Path upperBoundPath = paths.create(leftPath.getParent(), upperSegment);
                                    return new Range<>(leftPath, includeLower, upperBoundPath, false);
                                }
                            };
                        } else {
                            assert false : "Unable to use merge algorithm with join conditions: " + joinCondition;
                            throw new UnsupportedOperationException();
                        }
                        break;
                }

                // Perform conversion if required ...
                assert leftExtractor != null;
                assert rightExtractor != null;
                TypeFactory<?> leftType = leftExtractor.getType();
                TypeFactory<?> rightType = rightExtractor.getType();
                if (!leftType.equals(rightType)) {
                    // wrap the right extractor with a converting extractor ...
                    final TypeFactory<?> commonType = context.getTypeSystem().getCompatibleType(leftType, rightType);
                    if (!leftType.equals(commonType)) leftExtractor = RowExtractors.convert(leftExtractor, commonType);
                    if (!rightType.equals(commonType)) rightExtractor = RowExtractors.convert(rightExtractor, commonType);
                }

                rows = new HashJoinSequence(workspaceName, left, right, leftExtractor, rightExtractor, joinType,
                                            context.getBufferManager(), cache, rangeProducer, pack, useHeap);
                // For each Constraint object applied to the JOIN, simply create a SelectComponent on top ...
                RowFilter filter = null;
                List<Constraint> constraints = plan.getPropertyAsList(Property.JOIN_CONSTRAINTS, Constraint.class);
                if (constraints != null) {
                    for (Constraint constraint : constraints) {
                        RowFilter constraintFilter = createRowFilter(constraint, context, columns, sources);
                        filter = NodeSequence.requireBoth(filter, constraintFilter);
                    }
                }
                rows = NodeSequence.filter(rows, filter); // even if filter is null
                break;
            case LIMIT:
                // Create the sequence for the plan node under the LIMIT ...
                assert plan.getChildCount() == 1;
                rows = createNodeSequence(originalQuery, context, plan.getFirstChild(), columns, sources);
                // Calculate the limit ...
                Integer rowLimit = plan.getProperty(Property.LIMIT_COUNT, Integer.class);
                Integer offset = plan.getProperty(Property.LIMIT_OFFSET, Integer.class);
                Limit limit = Limit.NONE;
                if (rowLimit != null) limit = limit.withRowLimit(rowLimit.intValue());
                if (offset != null) limit = limit.withOffset(offset.intValue());
                // Then create the limited sequence ...
                if (!limit.isUnlimited()) {
                    rows = NodeSequence.limit(rows, limit);
                }
                break;
            case NULL:
                // No results ...
                rows = NodeSequence.emptySequence(columns.getColumns().size());
                break;
            case PROJECT:
                // Nothing to do, since the projected columns will be accessed as needed when the results are processed. Instead,
                // just process the PROJECT node's only child ...
                PlanNode child = plan.getFirstChild();
                columns = context.columnsFor(child);
                rows = createNodeSequence(originalQuery, context, child, columns, sources);
                break;
            case SELECT:
                // Create the sequence for the plan node under the SELECT ...
                assert plan.getChildCount() == 1;
                rows = createNodeSequence(originalQuery, context, plan.getFirstChild(), columns, sources);
                Constraint constraint = plan.getProperty(Property.SELECT_CRITERIA, Constraint.class);
                filter = createRowFilter(constraint, context, columns, sources);
                rows = NodeSequence.filter(rows, filter);
                break;
            case SET_OPERATION:
                Operation operation = plan.getProperty(Property.SET_OPERATION, Operation.class);
                boolean all = plan.getProperty(Property.SET_USE_ALL, Boolean.class);
                PlanNode firstPlan = plan.getFirstChild();
                PlanNode secondPlan = plan.getLastChild();
                Columns firstColumns = context.columnsFor(firstPlan);
                Columns secondColumns = context.columnsFor(secondPlan);
                NodeSequence first = createNodeSequence(originalQuery, context, firstPlan, firstColumns, sources);
                NodeSequence second = createNodeSequence(originalQuery, context, secondPlan, secondColumns, sources);
                useHeap = 0 >= second.getRowCount() && second.getRowCount() < 100;
                if (first.width() != second.width()) {
                    // A set operation requires that the 'first' and 'second' sequences have the same width, but this is
                    // not necessarily the case (e.g., when one side involves a JOIN but the other does not). The columns
                    // will dictate which subset of selector indexes in the sequences should be used.
                    first = NodeSequence.slice(first, firstColumns);
                    second = NodeSequence.slice(second, secondColumns);
                    assert first.width() == second.width();
                }
                pack = false;
                switch (operation) {
                    case UNION: {
                        // If one of them is empty, return the other ...
                        if (first.isEmpty()) return second;
                        if (second.isEmpty()) return first;
                        // This is really just a sequence with the two parts ...
                        rows = NodeSequence.append(first, second);
                        break;
                    }
                    case INTERSECT: {
                        // If one of them is empty, there are no results ...
                        if (first.isEmpty()) return first;
                        if (second.isEmpty()) return second;
                        rows = new IntersectSequence(workspaceName, first, second, types, bufferManager, cache, pack, useHeap);
                        break;
                    }
                    case EXCEPT: {
                        // If the second is empty, there's nothing to exclude ...
                        if (second.isEmpty()) return first;
                        rows = new ExceptSequence(workspaceName, first, second, types, bufferManager, cache, pack, useHeap);
                        break;
                    }
                }
                if (!all) {
View Full Code Here

TOP

Related Classes of org.modeshape.jcr.query.NodeSequence$RowAccessor

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.