Examples of ExtractFromRow


Examples of org.modeshape.jcr.query.RowExtractors.ExtractFromRow

    public void shouldSortSequenceWithDuplicatesOnHeapBuffer() {
        // print(true);
        boolean useHeap = true;
        boolean pack = false;
        boolean allowDups = true;
        ExtractFromRow extractor = RowExtractors.extractPath(0, cache, types);
        SortingSequence sorted = new SortingSequence(workspaceName(), allNodes(), extractor, bufferMgr, cache, pack, useHeap,
                                                     allowDups, NullOrder.NULLS_LAST);
        assertThat(sorted.getRowCount(), is(countRows(allNodes())));
        assertSorted(sorted, extractor);
    }
View Full Code Here

Examples of org.modeshape.jcr.query.RowExtractors.ExtractFromRow

    public void shouldSortSequenceWithoutDuplicatesOnHeapBuffer() {
        // print(true);
        boolean useHeap = true;
        boolean pack = false;
        boolean allowDups = false;
        ExtractFromRow extractor = RowExtractors.extractPath(0, cache, types);
        SortingSequence sorted = new SortingSequence(workspaceName(), allNodes(), extractor, bufferMgr, cache, pack, useHeap,
                                                     allowDups, NullOrder.NULLS_LAST);
        assertThat(sorted.getRowCount(), is(countRows(allNodes())));
        assertSorted(sorted, extractor);
    }
View Full Code Here

Examples of org.modeshape.jcr.query.RowExtractors.ExtractFromRow

    public void shouldSortSequenceWithDuplicatesOffHeapBuffer() {
        // print(true);
        boolean useHeap = false;
        boolean pack = false;
        boolean allowDups = true;
        ExtractFromRow extractor = RowExtractors.extractPath(0, cache, types);
        SortingSequence sorted = new SortingSequence(workspaceName(), allNodes(), extractor, bufferMgr, cache, pack, useHeap,
                                                     allowDups, NullOrder.NULLS_LAST);
        assertThat(sorted.getRowCount(), is(countRows(allNodes())));
        assertSorted(sorted, extractor);
    }
View Full Code Here

Examples of org.modeshape.jcr.query.RowExtractors.ExtractFromRow

    public void shouldSortSequenceWithoutDuplicatesOffHeapBuffer() {
        // print(true);
        boolean useHeap = false;
        boolean pack = false;
        boolean allowDups = false;
        ExtractFromRow extractor = RowExtractors.extractPath(0, cache, types);
        SortingSequence sorted = new SortingSequence(workspaceName(), allNodes(), extractor, bufferMgr, cache, pack, useHeap,
                                                     allowDups, NullOrder.NULLS_LAST);
        assertThat(sorted.getRowCount(), is(countRows(allNodes())));
        assertSorted(sorted, extractor);
    }
View Full Code Here

Examples of org.modeshape.jcr.query.RowExtractors.ExtractFromRow

    public void shouldSortSequenceWithDuplicatesWithNullSortValues() {
        // print(true);
        boolean useHeap = true;
        boolean pack = false;
        boolean allowDups = true;
        ExtractFromRow extractor = RowExtractors.extractPropertyValue(name("propC"), 0, cache, types.getStringFactory());
        SortingSequence sorted = new SortingSequence(workspaceName(), allNodes(), extractor, bufferMgr, cache, pack, useHeap,
                                                     allowDups, NullOrder.NULLS_LAST);
        assertSorted(sorted, extractor);
    }
View Full Code Here

Examples of org.modeshape.jcr.query.RowExtractors.ExtractFromRow

                // 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) {
                    useHeap = false;
                    rows = new DistinctSequence(rows, context.getTypeSystem(), context.getBufferManager(), useHeap);
                }
                break;
            case SORT:
                assert plan.getChildCount() == 1;
                PlanNode delegate = plan.getFirstChild();
                boolean allowDuplicates = true;
                if (delegate.getType() == Type.DUP_REMOVE) {
                    // This SORT already removes duplicates, so we can skip the first child ...
                    delegate = delegate.getFirstChild();
                    allowDuplicates = false;
                }
                PlanNode parent = plan.getParent();
                if (parent != null && parent.getType() == Type.DUP_REMOVE) {
                    // The parent is a DUP_REMOVE (shouldn't really happen in an optimized plan), we should disallow duplicates
                    // ...
                    allowDuplicates = false;
                }
                // Create the sequence for the delegate plan node ...
                rows = createNodeSequence(originalQuery, context, delegate, columns, sources);
                if (!rows.isEmpty()) {
                    // Prepare to wrap this delegate sequence based upon the SORT_ORDER_BY ...
                    List<Object> orderBys = plan.getPropertyAsList(Property.SORT_ORDER_BY, Object.class);
                    if (!orderBys.isEmpty()) {
                        // Create an extractor from the orderings that we'll use for the sorting ...
                        ExtractFromRow sortExtractor = null;
                        pack = false;
                        useHeap = false;
                        NullOrder nullOrder = null;
                        if (orderBys.get(0) instanceof Ordering) {
                            List<Ordering> orderings = new ArrayList<Ordering>(orderBys.size());
                            for (Object orderBy : orderBys) {
                                orderings.add((Ordering)orderBy);
                            }
                            // Determine the alias-to-name mappings for the selectors in the orderings ...
                            Map<SelectorName, SelectorName> sourceNamesByAlias = new HashMap<SelectorName, SelectorName>();
                            for (PlanNode source : plan.findAllAtOrBelow(Type.SOURCE)) {
                                SelectorName name = source.getProperty(Property.SOURCE_NAME, SelectorName.class);
                                SelectorName alias = source.getProperty(Property.SOURCE_ALIAS, SelectorName.class);
                                if (alias != null) sourceNamesByAlias.put(alias, name);
                            }
                            // If there are multiple orderings, then we'll never have nulls. But if there is just one ordering,
                            // we have to handle nulls ...
                            if (orderings.size() == 1) {
                                nullOrder = orderings.get(0).nullOrder();
                            }
                            // Now create the single sorting extractor ...
                            sortExtractor = createSortingExtractor(orderings, sourceNamesByAlias, context, columns, sources);
                        } else {
                            // Order by the location(s) because it's before a merge-join ...
                            final TypeFactory<?> keyType = context.getTypeSystem().getReferenceFactory();
                            List<ExtractFromRow> extractors = new ArrayList<>();
                            for (Object ordering : orderBys) {
                                SelectorName selectorName = (SelectorName)ordering;
                                final int index = columns.getSelectorIndex(selectorName.name());
                                extractors.add(new ExtractFromRow() {
                                    @Override
                                    public TypeFactory<?> getType() {
                                        return keyType;
                                    }
View Full Code Here

Examples of org.modeshape.jcr.query.RowExtractors.ExtractFromRow

                                                     QuerySources sources ) {
        if (orderings.size() == 1) {
            return createSortingExtractor(orderings.get(0), sourceNamesByAlias, context, columns, sources);
        }
        if (orderings.size() == 2) {
            ExtractFromRow first = createSortingExtractor(orderings.get(0), sourceNamesByAlias, context, columns, sources);
            ExtractFromRow second = createSortingExtractor(orderings.get(1), sourceNamesByAlias, context, columns, sources);
            return RowExtractors.extractorWith(first, second);
        }
        if (orderings.size() == 3) {
            ExtractFromRow first = createSortingExtractor(orderings.get(0), sourceNamesByAlias, context, columns, sources);
            ExtractFromRow second = createSortingExtractor(orderings.get(1), sourceNamesByAlias, context, columns, sources);
            ExtractFromRow third = createSortingExtractor(orderings.get(2), sourceNamesByAlias, context, columns, sources);
            return RowExtractors.extractorWith(first, second, third);
        }
        if (orderings.size() == 4) {
            ExtractFromRow first = createSortingExtractor(orderings.get(0), sourceNamesByAlias, context, columns, sources);
            ExtractFromRow second = createSortingExtractor(orderings.get(1), sourceNamesByAlias, context, columns, sources);
            ExtractFromRow third = createSortingExtractor(orderings.get(2), sourceNamesByAlias, context, columns, sources);
            ExtractFromRow fourth = createSortingExtractor(orderings.get(3), sourceNamesByAlias, context, columns, sources);
            return RowExtractors.extractorWith(first, second, third, fourth);
        }
        List<ExtractFromRow> extractors = new ArrayList<>(orderings.size());
        for (Ordering ordering : orderings) {
            extractors.add(createSortingExtractor(ordering, sourceNamesByAlias, context, columns, sources));
View Full Code Here

Examples of org.modeshape.jcr.query.RowExtractors.ExtractFromRow

                                                     Columns columns,
                                                     QuerySources sources ) {
        DynamicOperand operand = ordering.getOperand();
        TypeFactory<?> defaultType = context.getTypeSystem().getStringFactory();// only when ordered column is residual or not
                                                                                // defined
        ExtractFromRow extractor = createExtractFromRow(operand, context, columns, sources, defaultType, false, false);
        return RowExtractors.extractorWith(extractor, ordering.order(), ordering.nullOrder());
    }
View Full Code Here

Examples of org.modeshape.jcr.query.RowExtractors.ExtractFromRow

            final StaticOperand upper = between.getUpperBound();
            final boolean includeLower = between.isLowerBoundIncluded();
            final boolean includeUpper = between.isUpperBoundIncluded();
            DynamicOperand dynamicOperand = between.getOperand();
            final TypeFactory<?> defaultType = determineType(dynamicOperand, context, columns);
            final ExtractFromRow operation = createExtractFromRow(dynamicOperand, context, columns, sources, defaultType, true,
                                                                  false);

            // Determine the literal value in the static operand ...
            return new RowFilterSupplier() {
                @Override
                protected RowFilter createFilter() {
                    // Evaluate the operand, which may have variables ...
                    final Object lowerLiteralValue = literalValue(lower, context, defaultType);
                    final Object upperLiteralValue = literalValue(upper, context, defaultType);
                    // Create the correct operation ...
                    final TypeFactory<?> expectedType = operation.getType();
                    final Object lowerValue = expectedType.create(lowerLiteralValue);
                    final Object upperValue = expectedType.create(upperLiteralValue);
                    @SuppressWarnings( "unchecked" )
                    final Comparator<Object> comparator = (Comparator<Object>)expectedType.getComparator();
                    if (includeLower) {
                        if (includeUpper) {
                            return new DynamicOperandFilter(operation) {
                                @Override
                                protected boolean evaluate( Object leftHandValue ) {
                                    if (leftHandValue == null) return false; // null values never match
                                    return comparator.compare(leftHandValue, lowerValue) >= 0
                                           && comparator.compare(leftHandValue, upperValue) <= 0;
                                }

                                @Override
                                public String toString() {
                                    return "(filter " + Visitors.readable(constraint) + ")";
                                }
                            };
                        }
                        // Don't include upper ...
                        return new DynamicOperandFilter(operation) {
                            @Override
                            protected boolean evaluate( Object leftHandValue ) {
                                if (leftHandValue == null) return false; // null values never match
                                return comparator.compare(leftHandValue, lowerValue) >= 0
                                       && comparator.compare(leftHandValue, upperValue) < 0;
                            }

                            @Override
                            public String toString() {
                                return "(filter " + Visitors.readable(constraint) + ")";
                            }
                        };
                    }
                    assert !includeLower;
                    // Don't include lower
                    if (includeUpper) {
                        return new DynamicOperandFilter(operation) {
                            @Override
                            protected boolean evaluate( Object leftHandValue ) {
                                if (leftHandValue == null) return false; // null values never match
                                return comparator.compare(leftHandValue, lowerValue) > 0
                                       && comparator.compare(leftHandValue, upperValue) <= 0;
                            }

                            @Override
                            public String toString() {
                                return "(filter " + Visitors.readable(constraint) + ")";
                            }
                        };
                    }
                    // Don't include upper or lower ...
                    return new DynamicOperandFilter(operation) {
                        @Override
                        protected boolean evaluate( Object leftHandValue ) {
                            if (leftHandValue == null) return false; // null values never match
                            return comparator.compare(leftHandValue, lowerValue) > 0
                                   && comparator.compare(leftHandValue, upperValue) < 0;
                        }

                        @Override
                        public String toString() {
                            return "(filter " + Visitors.readable(constraint) + ")";
                        }
                    };
                }
            };
        }
        if (constraint instanceof Comparison) {
            Comparison comparison = (Comparison)constraint;

            // Create the correct dynamic operation ...
            final DynamicOperand dynamicOperand = comparison.getOperand1();
            final Operator operator = comparison.operator();
            final StaticOperand staticOperand = comparison.getOperand2();
            final TypeFactory<?> actualType = determineType(dynamicOperand, context, columns);
            TypeFactory<?> expectedType = null;
            ExtractFromRow op = null;
            if (operator == Operator.LIKE) {
                expectedType = context.getTypeSystem().getStringFactory();
                op = createExtractFromRow(dynamicOperand, context, columns, sources, expectedType, true, true);
                if (op.getType() != expectedType) {
                    // Need to convert the extracted value(s) to strings because this is a LIKE operation ...
                    op = RowExtractors.convert(op, expectedType);
                }
            } else {
                expectedType = actualType;
                op = createExtractFromRow(dynamicOperand, context, columns, sources, expectedType, true, false);
            }
            final TypeFactory<?> defaultType = expectedType;
            final ExtractFromRow operation = op;
            // Determine the literal value in the static operand ...
            return new RowFilterSupplier() {
                @Override
                protected RowFilter createFilter() {
                    // Evaluate the operand, which may have variables ...
                    final Object literalValue = literalValue(staticOperand, context, defaultType);
                    // Create the correct operation ...
                    final TypeFactory<?> expectedType = operation.getType();
                    final Object rhs = expectedType.create(literalValue);
                    @SuppressWarnings( "unchecked" )
                    final Comparator<Object> comparator = (Comparator<Object>)expectedType.getComparator();
                    switch (operator) {
                        case EQUAL_TO:
                            return new DynamicOperandFilter(operation) {
                                @Override
                                protected boolean evaluate( Object leftHandValue ) {
                                    if (leftHandValue == null) return false; // null values never match
                                    return comparator.compare(leftHandValue, rhs) == 0;
                                }

                                @Override
                                public String toString() {
                                    return "(filter " + Visitors.readable(constraint) + ")";
                                }
                            };
                        case NOT_EQUAL_TO:
                            return new DynamicOperandFilter(operation) {
                                @Override
                                protected boolean evaluate( Object leftHandValue ) {
                                    if (leftHandValue == null) return false; // null values never match
                                    return comparator.compare(leftHandValue, rhs) != 0;
                                }

                                @Override
                                public String toString() {
                                    return "(filter " + Visitors.readable(constraint) + ")";
                                }
                            };
                        case GREATER_THAN:
                            return new DynamicOperandFilter(operation) {
                                @Override
                                protected boolean evaluate( Object leftHandValue ) {
                                    if (leftHandValue == null) return false; // null values never match
                                    return comparator.compare(leftHandValue, rhs) > 0;
                                }

                                @Override
                                public String toString() {
                                    return "(filter " + Visitors.readable(constraint) + ")";
                                }
                            };
                        case GREATER_THAN_OR_EQUAL_TO:
                            return new DynamicOperandFilter(operation) {
                                @Override
                                protected boolean evaluate( Object leftHandValue ) {
                                    if (leftHandValue == null) return false; // null values never match
                                    return comparator.compare(leftHandValue, rhs) >= 0;
                                }

                                @Override
                                public String toString() {
                                    return "(filter " + Visitors.readable(constraint) + ")";
                                }
                            };
                        case LESS_THAN:
                            return new DynamicOperandFilter(operation) {
                                @Override
                                protected boolean evaluate( Object leftHandValue ) {
                                    if (leftHandValue == null) return false; // null values never match
                                    return comparator.compare(leftHandValue, rhs) < 0;
                                }

                                @Override
                                public String toString() {
                                    return "(filter " + Visitors.readable(constraint) + ")";
                                }
                            };
                        case LESS_THAN_OR_EQUAL_TO:
                            return new DynamicOperandFilter(operation) {
                                @Override
                                protected boolean evaluate( Object leftHandValue ) {
                                    if (leftHandValue == null) return false; // null values never match
                                    return comparator.compare(leftHandValue, rhs) <= 0;
                                }

                                @Override
                                public String toString() {
                                    return "(filter " + Visitors.readable(constraint) + ")";
                                }
                            };
                        case LIKE:
                            // Convert the LIKE expression to a regular expression
                            final TypeSystem types = context.getTypeSystem();
                            String expression = types.asString(rhs).trim();
                            if ("%".equals(expression)) {
                                // We'll accept any non-null value ...
                                return new DynamicOperandFilter(operation) {
                                    @Override
                                    protected boolean evaluate( Object leftHandValue ) {
                                        return leftHandValue != null;
                                    }

                                    @Override
                                    public String toString() {
                                        return "(filter " + Visitors.readable(constraint) + ")";
                                    }
                                };
                            }
                            if (Path.class.isAssignableFrom(actualType.getType())) {
                                // This LIKE is dealing with paths and SNS wildcards, so we have to extract path values that
                                // have SNS indexes in all segments ...
                                final PathFactory paths = context.getExecutionContext().getValueFactories().getPathFactory();
                                expression = QueryUtil.addSnsIndexesToLikeExpression(expression);
                                String regex = QueryUtil.toRegularExpression(expression);
                                final Pattern pattern = Pattern.compile(regex);
                                return new DynamicOperandFilter(operation) {
                                    @Override
                                    protected boolean evaluate( Object leftHandValue ) {
                                        if (leftHandValue == null) return false; // null values never match
                                        // Get the value as a path and construct a string representation with SNS indexes
                                        // in the correct spot ...
                                        Path path = paths.create(leftHandValue);
                                        String strValue = null;
                                        if (path.isRoot()) {
                                            strValue = "/";
                                        } else {
                                            StringBuilder sb = new StringBuilder();
                                            for (Path.Segment segment : path) {
                                                sb.append('/').append(types.asString(segment.getName()));
                                                sb.append('[').append(segment.getIndex()).append(']');
                                            }
                                            strValue = sb.toString();
                                        }
                                        return pattern.matcher(strValue).matches();
                                    }

                                    @Override
                                    public String toString() {
                                        return "(filter " + Visitors.readable(constraint) + ")";
                                    }
                                };
                            }
                            String regex = QueryUtil.toRegularExpression(expression);
                            final Pattern pattern = Pattern.compile(regex);
                            return new DynamicOperandFilter(operation) {
                                @Override
                                protected boolean evaluate( Object leftHandValue ) {
                                    if (leftHandValue == null) return false; // null values never match
                                    String value = types.asString(leftHandValue);
                                    return pattern.matcher(value).matches();
                                }

                                @Override
                                public String toString() {
                                    return "(filter " + Visitors.readable(constraint) + ")";
                                }
                            };
                    }
                    assert false : "Should not get here";
                    return null;
                }
            };
        }
        if (constraint instanceof SetCriteria) {
            final SetCriteria setCriteria = (SetCriteria)constraint;
            DynamicOperand operand = setCriteria.getOperand();
            final TypeFactory<?> defaultType = determineType(operand, context, columns);
            // If the set criteria contains a bind variable, then the operand filter should lazily evaluate the bind variable ...
            final ExtractFromRow operation = createExtractFromRow(operand, context, columns, sources, defaultType, true, false);
            final boolean trace = LOGGER.isTraceEnabled() && !defaultType.getTypeName().equals("NAME");
            return new RowFilterSupplier() {

                @Override
                protected RowFilter createFilter() {
                    final Set<?> values = ScanningQueryEngine.literalValues(setCriteria, context, defaultType);
                    return new DynamicOperandFilter(operation) {
                        @Override
                        protected boolean evaluate( Object leftHandValue ) {
                            if (leftHandValue instanceof Object[]) {
                                for (Object leftValue : (Object[])leftHandValue) {
                                    if (values.contains(leftValue)) {
                                        if (trace) LOGGER.trace("Found '{0}' in values: {1}", leftHandValue, values);
                                        return true;
                                    }
                                }
                                if (trace) LOGGER.trace("Failed to find '{0}' in values: {1}", leftHandValue, values);
                                return false;
                            }

                            if (values.contains(leftHandValue)) {
                                if (trace) {
                                    LOGGER.trace("Found '{0}' in values: {1}", leftHandValue, values);
                                }
                                return true;
                            }
                            if (trace) {
                                LOGGER.trace("Failed to find '{0}' in values: {1}", leftHandValue, values);
                            }
                            return false;
                        }

                        @Override
                        public String toString() {
                            return "(filter " + Visitors.readable(constraint) + ")";
                        }
                    };
                }
            };
        }
        if (constraint instanceof FullTextSearch) {
            final TypeFactory<String> strings = context.getTypeSystem().getStringFactory();
            final StaticOperand ftsExpression = ((FullTextSearch)constraint).getFullTextSearchExpression();
            final FullTextSearch fts;
            if (ftsExpression instanceof BindVariableName) {
                Object searchExpression = literalValue(ftsExpression, context, strings);
                if (searchExpression != null) {
                    fts = ((FullTextSearch)constraint).withFullTextExpression(searchExpression.toString());
                } else {
                    fts = (FullTextSearch)constraint;
                }
            } else {
                fts = (FullTextSearch)constraint;
            }

            final NodeCache cache = context.getNodeCache(sources.getWorkspaceName());
            final BinaryStore binaries = context.getExecutionContext().getBinaryStore();
            String selectorName = fts.getSelectorName();
            String propertyName = fts.getPropertyName();
            final int index = columns.getSelectorIndex(selectorName);
            ExtractFromRow fullTextExtractor = null;
            if (propertyName != null) {
                // This is to search just the designated property of the node (name, all property values) ...
                final ExtractFromRow propertyValueExtractor = createExtractFromRow(selectorName, propertyName, context, columns,
                                                                                   sources, strings, true);
                fullTextExtractor = new ExtractFromRow() {
                    @Override
                    public TypeFactory<?> getType() {
                        return strings;
                    }

                    @Override
                    public Object getValueInRow( RowAccessor row ) {
                        Object result = propertyValueExtractor.getValueInRow(row);
                        if (result == null) return null;
                        StringBuilder fullTextString = new StringBuilder();
                        RowExtractors.extractFullTextFrom(result, strings, binaries, fullTextString);
                        return fullTextString.toString();
                    }
                };
            } else {
                // This is to search all aspects of the node (name, all property values) ...
                fullTextExtractor = RowExtractors.extractFullText(index, cache, context.getTypeSystem(), binaries);
            }
            // Return a filter that processes all of the text ...
            final ExtractFromRow extractor = fullTextExtractor;
            return new DynamicOperandFilter(extractor) {
                @Override
                protected boolean evaluate( Object leftHandValue ) {
                    /**
                     * The term will match the extracted value "as-is" via regex, without any stemming or punctuation removal.
View Full Code Here

Examples of org.modeshape.jcr.query.RowExtractors.ExtractFromRow

        if (operand instanceof Length) {
            Length length = (Length)operand;
            final PropertyValue value = length.getPropertyValue();
            String propertyName = value.getPropertyName();
            String selectorName = value.selectorName().name();
            final ExtractFromRow getPropValue = createExtractFromRow(selectorName, propertyName, context, columns, sources,
                                                                     defaultType, allowMultiValued);
            final TypeFactory<?> longType = context.getTypeSystem().getLongFactory();
            return new ExtractFromRow() {
                @Override
                public Object getValueInRow( RowAccessor row ) {
                    Object typedValue = getPropValue.getValueInRow(row);
                    return getPropValue.getType().length(typedValue);
                }

                @Override
                public TypeFactory<?> getType() {
                    return longType;
                }

                @Override
                public String toString() {
                    return "(length " + getPropValue + ")";
                }
            };
        }
        final TypeFactory<String> stringFactory = context.getTypeSystem().getStringFactory();
        if (operand instanceof LowerCase) {
            LowerCase lowerCase = (LowerCase)operand;
            final ExtractFromRow delegate = createExtractFromRow(lowerCase.getOperand(), context, columns, sources, defaultType,
                                                                 allowMultiValued, false);
            return new ExtractFromRow() {
                @Override
                public TypeFactory<?> getType() {
                    return stringFactory;
                }

                @Override
                public Object getValueInRow( RowAccessor row ) {
                    String result = stringFactory.create(delegate.getValueInRow(row));
                    return result != null ? result.toLowerCase() : null;
                }

                @Override
                public String toString() {
                    return "(lowercase " + delegate + ")";
                }
            };
        }
        if (operand instanceof UpperCase) {
            final UpperCase upperCase = (UpperCase)operand;
            final ExtractFromRow delegate = createExtractFromRow(upperCase.getOperand(), context, columns, sources, defaultType,
                                                                 allowMultiValued, false);
            return new ExtractFromRow() {
                @Override
                public TypeFactory<?> getType() {
                    return stringFactory;
                }

                @Override
                public Object getValueInRow( RowAccessor row ) {
                    String result = stringFactory.create(delegate.getValueInRow(row));
                    return result != null ? result.toUpperCase() : null;
                }

                @Override
                public String toString() {
                    return "(uppercase " + delegate + ")";
                }
            };
        }
        if (operand instanceof NodeDepth) {
            final NodeDepth nodeDepth = (NodeDepth)operand;
            final int indexInRow = columns.getSelectorIndex(nodeDepth.getSelectorName());
            final NodeCache cache = context.getNodeCache(sources.getWorkspaceName());
            final TypeFactory<?> longType = context.getTypeSystem().getLongFactory();
            return new ExtractFromRow() {
                @Override
                public TypeFactory<?> getType() {
                    return longType; // depth is always a long type
                }

                @Override
                public Object getValueInRow( RowAccessor row ) {
                    CachedNode node = row.getNode(indexInRow);
                    if (node == null) return null;
                    return new Long(node.getDepth(cache));
                }

                @Override
                public String toString() {
                    return "(nodeDepth " + nodeDepth.getSelectorName() + ")";
                }
            };
        }
        if (operand instanceof ChildCount) {
            final ChildCount childCount = (ChildCount)operand;
            final int indexInRow = columns.getSelectorIndex(childCount.getSelectorName());
            final NodeCache cache = context.getNodeCache(sources.getWorkspaceName());
            final TypeFactory<?> longType = context.getTypeSystem().getLongFactory();
            return new ExtractFromRow() {
                @Override
                public TypeFactory<?> getType() {
                    return longType; // count is always a long type
                }

                @Override
                public Object getValueInRow( RowAccessor row ) {
                    CachedNode node = row.getNode(indexInRow);
                    if (node == null) return null;
                    return new Long(node.getChildReferences(cache).size());
                }

                @Override
                public String toString() {
                    return "(childCount " + childCount.getSelectorName() + ")";
                }
            };
        }
        if (operand instanceof NodeId) {
            final NodeId nodeId = (NodeId)operand;
            final int indexInRow = columns.getSelectorIndex(nodeId.getSelectorName());
            final NodeCache cache = context.getNodeCache(sources.getWorkspaceName());
            final NodeKey root = cache.getRootKey();
            final TypeFactory<?> stringType = context.getTypeSystem().getStringFactory();
            return new ExtractFromRow() {
                @Override
                public TypeFactory<?> getType() {
                    return stringType; // ID is always a string type
                }

                @Override
                public Object getValueInRow( RowAccessor row ) {
                    CachedNode node = row.getNode(indexInRow);
                    if (node == null) return null;
                    return sources.getIdentifier(node, root);
                }

                @Override
                public String toString() {
                    return "(nodeId " + nodeId.getSelectorName() + ")";
                }
            };
        }
        if (operand instanceof NodePath) {
            final NodePath nodePath = (NodePath)operand;
            final int indexInRow = columns.getSelectorIndex(nodePath.getSelectorName());
            final NodeCache cache = context.getNodeCache(sources.getWorkspaceName());
            if (isLike) {
                return new ExtractFromRow() {
                    @Override
                    public TypeFactory<?> getType() {
                        return stringFactory;
                    }

                    @Override
                    public Object getValueInRow( RowAccessor row ) {
                        CachedNode node = row.getNode(indexInRow);
                        if (node == null) return null;
                        Path path = node.getPath(cache);
                        if (path.isRoot()) {
                            return stringFactory.create(path);
                        }
                        // And the path that always has the SNS index ...
                        StringBuilder sb = new StringBuilder();
                        for (Path.Segment segment : path) {
                            // Add the segment WITH the index ...
                            sb.append("/");
                            sb.append(stringFactory.create(segment.getName()));
                            sb.append('[').append(segment.getIndex()).append(']');
                        }
                        return sb.toString();
                    }

                    @Override
                    public String toString() {
                        return "(nodePath " + nodePath.getSelectorName() + ")";
                    }
                };
            }
            // Otherwise, just return the single path ...
            return new ExtractFromRow() {
                @Override
                public TypeFactory<?> getType() {
                    return stringFactory;
                }

                @Override
                public Object getValueInRow( RowAccessor row ) {
                    CachedNode node = row.getNode(indexInRow);
                    if (node == null) return null;
                    Path path = node.getPath(cache);
                    return stringFactory.create(path);
                }

                @Override
                public String toString() {
                    return "(nodePath " + nodePath.getSelectorName() + ")";
                }
            };
        }
        if (operand instanceof NodeName) {
            final NodeName nodeName = (NodeName)operand;
            final int indexInRow = columns.getSelectorIndex(nodeName.getSelectorName());
            final NodeCache cache = context.getNodeCache(sources.getWorkspaceName());
            return new ExtractFromRow() {
                @Override
                public TypeFactory<?> getType() {
                    return stringFactory;
                }

                @Override
                public Object getValueInRow( RowAccessor row ) {
                    CachedNode node = row.getNode(indexInRow);
                    if (node == null) return null;
                    Name name = node.getName(cache);
                    return stringFactory.create(name);
                }

                @Override
                public String toString() {
                    return "(nodeName " + nodeName.getSelectorName() + ")";
                }
            };
        }
        if (operand instanceof NodeLocalName) {
            final NodeLocalName nodeName = (NodeLocalName)operand;
            final int indexInRow = columns.getSelectorIndex(nodeName.getSelectorName());
            final NodeCache cache = context.getNodeCache(sources.getWorkspaceName());
            return new ExtractFromRow() {
                @Override
                public TypeFactory<?> getType() {
                    return stringFactory;
                }

                @Override
                public Object getValueInRow( RowAccessor row ) {
                    CachedNode node = row.getNode(indexInRow);
                    if (node == null) return null;
                    Name name = node.getName(cache);
                    return name.getLocalName(); // works even for root
                }

                @Override
                public String toString() {
                    return "(localName " + nodeName.getSelectorName() + ")";
                }
            };
        }
        if (operand instanceof FullTextSearchScore) {
            final FullTextSearchScore fts = (FullTextSearchScore)operand;
            final int indexInRow = columns.getSelectorIndex(fts.getSelectorName());
            final TypeFactory<Double> doubleType = context.getTypeSystem().getDoubleFactory();
            return new ExtractFromRow() {
                @Override
                public TypeFactory<?> getType() {
                    return doubleType;
                }

                @Override
                public Object getValueInRow( RowAccessor row ) {
                    return new Double(row.getScore(indexInRow)); // must convert the float to a double value
                }

                @Override
                public String toString() {
                    return "(fullTextScore " + fts.getSelectorName() + ")";
                }
            };
        }
        if (operand instanceof ArithmeticOperand) {
            // This works on single-valued properties only ...
            ArithmeticOperand arith = (ArithmeticOperand)operand;
            final ExtractFromRow leftOp = createExtractFromRow(arith.getLeft(), context, columns, sources, defaultType, false,
                                                               false);
            final ExtractFromRow rightOp = createExtractFromRow(arith.getRight(), context, columns, sources, defaultType, false,
                                                                false);
            // compute the expected (common) type ...
            TypeFactory<?> leftType = leftOp.getType();
            TypeFactory<?> rightType = rightOp.getType();
            final TypeSystem typeSystem = context.getTypeSystem();
            final String commonType = typeSystem.getCompatibleType(leftType.getTypeName(), rightType.getTypeName());
            if (typeSystem.getDoubleFactory().getTypeName().equals(commonType)) {
                final TypeFactory<Double> commonTypeFactory = typeSystem.getDoubleFactory();
                switch (arith.operator()) {
                    case ADD:
                        return new ExtractFromRow() {
                            @Override
                            public TypeFactory<?> getType() {
                                return commonTypeFactory;
                            }

                            @Override
                            public Object getValueInRow( RowAccessor row ) {
                                Double right = commonTypeFactory.create(rightOp.getValueInRow(row));
                                Double left = commonTypeFactory.create(leftOp.getValueInRow(row));
                                if (right == null) return left;
                                if (left == null) return right;
                                return left.doubleValue() / right.doubleValue();
                            }

                            @Override
                            public String toString() {
                                return "(double + " + leftOp + "," + rightOp + ")";
                            }
                        };
                    case SUBTRACT:
                        return new ExtractFromRow() {
                            @Override
                            public TypeFactory<?> getType() {
                                return commonTypeFactory;
                            }

                            @Override
                            public Object getValueInRow( RowAccessor row ) {
                                Double right = commonTypeFactory.create(rightOp.getValueInRow(row));
                                Double left = commonTypeFactory.create(leftOp.getValueInRow(row));
                                if (right == null) return left;
                                if (left == null) left = 0.0d;
                                return left.doubleValue() * right.doubleValue();
                            }

                            @Override
                            public String toString() {
                                return "(double - " + leftOp + "," + rightOp + ")";
                            }
                        };
                    case MULTIPLY:
                        return new ExtractFromRow() {
                            @Override
                            public TypeFactory<?> getType() {
                                return commonTypeFactory;
                            }

                            @Override
                            public Object getValueInRow( RowAccessor row ) {
                                Double right = commonTypeFactory.create(rightOp.getValueInRow(row));
                                Double left = commonTypeFactory.create(leftOp.getValueInRow(row));
                                if (right == null || left == null) return null;
                                return left.doubleValue() * right.doubleValue();
                            }

                            @Override
                            public String toString() {
                                return "(double x " + leftOp + "," + rightOp + ")";
                            }
                        };
                    case DIVIDE:
                        return new ExtractFromRow() {
                            @Override
                            public TypeFactory<?> getType() {
                                return commonTypeFactory;
                            }

                            @Override
                            public Object getValueInRow( RowAccessor row ) {
                                Double right = commonTypeFactory.create(rightOp.getValueInRow(row));
                                Double left = commonTypeFactory.create(leftOp.getValueInRow(row));
                                if (right == null || left == null) return null;
                                return left.doubleValue() / right.doubleValue();
                            }

                            @Override
                            public String toString() {
                                return "(double / " + leftOp + "," + rightOp + ")";
                            }
                        };
                }
            } else if (typeSystem.getLongFactory().getTypeName().equals(commonType)) {
                final TypeFactory<Long> commonTypeFactory = typeSystem.getLongFactory();
                switch (arith.operator()) {
                    case ADD:
                        return new ExtractFromRow() {
                            @Override
                            public TypeFactory<?> getType() {
                                return commonTypeFactory;
                            }

                            @Override
                            public Object getValueInRow( RowAccessor row ) {
                                Long right = commonTypeFactory.create(rightOp.getValueInRow(row));
                                Long left = commonTypeFactory.create(leftOp.getValueInRow(row));
                                if (right == null) return left;
                                if (left == null) return right;
                                return left.longValue() / right.longValue();
                            }

                            @Override
                            public String toString() {
                                return "(long + " + leftOp + "," + rightOp + ")";
                            }
                        };
                    case SUBTRACT:
                        return new ExtractFromRow() {
                            @Override
                            public TypeFactory<?> getType() {
                                return commonTypeFactory;
                            }

                            @Override
                            public Object getValueInRow( RowAccessor row ) {
                                Long right = commonTypeFactory.create(rightOp.getValueInRow(row));
                                Long left = commonTypeFactory.create(leftOp.getValueInRow(row));
                                if (right == null) return left;
                                if (left == null) left = 0L;
                                return left.longValue() * right.longValue();
                            }

                            @Override
                            public String toString() {
                                return "(long - " + leftOp + "," + rightOp + ")";
                            }
                        };
                    case MULTIPLY:
                        return new ExtractFromRow() {
                            @Override
                            public TypeFactory<?> getType() {
                                return commonTypeFactory;
                            }

                            @Override
                            public Object getValueInRow( RowAccessor row ) {
                                Long right = commonTypeFactory.create(rightOp.getValueInRow(row));
                                Long left = commonTypeFactory.create(leftOp.getValueInRow(row));
                                if (right == null || left == null) return null;
                                return left.longValue() * right.longValue();
                            }

                            @Override
                            public String toString() {
                                return "(long x " + leftOp + "," + rightOp + ")";
                            }
                        };
                    case DIVIDE:
                        return new ExtractFromRow() {
                            @Override
                            public TypeFactory<?> getType() {
                                return commonTypeFactory;
                            }

                            @Override
                            public Object getValueInRow( RowAccessor row ) {
                                Long right = commonTypeFactory.create(rightOp.getValueInRow(row));
                                Long left = commonTypeFactory.create(leftOp.getValueInRow(row));
                                if (right == null || left == null) return null;
                                return left.longValue() / right.longValue();
                            }

View Full Code Here
TOP
Copyright © 2018 www.massapi.com. 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.