Package org.apache.phoenix.query

Examples of org.apache.phoenix.query.KeyRange


        for (; i < slots.size(); i++) {
            List<KeyRange> keyRanges = slots.get(i);
            if (keyRanges.size() != 1) {
                return false;
            }
            KeyRange keyRange = keyRanges.get(0);
            if (!keyRange.isSingleKey()) {
                return false;
            }
            if (keyRange.getLowerRange().length != 0) {
                return false;
            }
        }
        return true;
    }
View Full Code Here


        for (int i=0; i<andLen; i++) {
            int orlen = in.readInt();
            List<KeyRange> orclause = Lists.newArrayListWithExpectedSize(orlen);
            slots.add(orclause);
            for (int j=0; j<orlen; j++) {
                KeyRange range = new KeyRange();
                range.readFields(in);
                orclause.add(range);
            }
        }
        this.init(slots, schema);
    }
View Full Code Here

        }
        int[] position = new int[slots.size()];
        int maxLength = 0;
        for (int i = 0; i < position.length; i++) {
            position[i] = bound == Bound.LOWER ? 0 : slots.get(i).size()-1;
            KeyRange range = slots.get(i).get(position[i]);
            maxLength += range.getRange(bound).length + (schema.getField(i + slotSpan[i]).getDataType().isFixedWidth() ? 0 : 1);
        }
        byte[] key = new byte[maxLength];
        int length = setKey(schema, slots, slotSpan, position, bound, key, 0, 0, position.length);
        if (length == 0) {
            return null;
View Full Code Here

        // slotSpan stores the number of columns beyond one that the range spans
        int i = slotStartIndex, fieldIndex = slotStartIndex;
        for (i = slotStartIndex; i < slotEndIndex; i++) {
            // Build up the key by appending the bound of each key range
            // from the current position of each slot.
            KeyRange range = slots.get(i).get(position[i]);
            // Use last slot in a multi-span column to determine if fixed width
            boolean isFixedWidth = schema.getField(fieldIndex + slotSpan[i]).getDataType().isFixedWidth();
            fieldIndex += slotSpan[i] + 1;
            /*
             * If the current slot is unbound then stop if:
             * 1) setting the upper bound. There's no value in
             *    continuing because nothing will be filtered.
             * 2) setting the lower bound when the type is fixed length
             *    for the same reason. However, if the type is variable width
             *    continue building the key because null values will be filtered
             *    since our separator byte will be appended and incremented.
             */
            if range.isUnbound(bound) &&
                ( bound == Bound.UPPER || isFixedWidth) ){
                break;
            }
            byte[] bytes = range.getRange(bound);
            System.arraycopy(bytes, 0, key, offset, bytes.length);
            offset += bytes.length;
            /*
             * We must add a terminator to a variable length key even for the last PK column if
             * the lower key is non inclusive or the upper key is inclusive. Otherwise, we'd be
             * incrementing the key value itself, and thus bumping it up too much.
             */
            boolean inclusiveUpper = range.isInclusive(bound) && bound == Bound.UPPER;
            boolean exclusiveLower = !range.isInclusive(bound) && bound == Bound.LOWER;
            // If we are setting the upper bound of using inclusive single key, we remember
            // to increment the key if we exit the loop after this iteration.
            //
            // We remember to increment the last slot if we are setting the upper bound with an
            // inclusive range key.
            //
            // We cannot combine the two flags together in case for single-inclusive key followed
            // by the range-exclusive key. In that case, we do not need to increment the end at the
            // end. But if we combine the two flag, the single inclusive key in the middle of the
            // key slots would cause the flag to become true.
            lastInclusiveUpperSingleKey = range.isSingleKey() && inclusiveUpper;
            anyInclusiveUpperRangeKey |= !range.isSingleKey() && inclusiveUpper;
           
            if (!isFixedWidth && ( fieldIndex < schema.getMaxFields() || inclusiveUpper || exclusiveLower)) {
                key[offset++] = QueryConstants.SEPARATOR_BYTE;
                // Set lastInclusiveUpperSingleKey back to false if this is the last pk column
                // as we don't want to increment the null byte in this case
                lastInclusiveUpperSingleKey &= i < schema.getMaxFields()-1;
            }
            // If we are setting the lower bound with an exclusive range key, we need to bump the
            // slot up for each key part. For an upper bound, we bump up an inclusive key, but
            // only after the last key part.
            if (!range.isSingleKey() && exclusiveLower) {
                if (!ByteUtil.nextKey(key, offset)) {
                    // Special case for not being able to increment.
                    // In this case we return a negative byteOffset to
                    // remove this part from the key being formed. Since the
                    // key has overflowed, this means that we should not
View Full Code Here

        filter = scan.getFilter();
        assertTrue(filter instanceof SkipScanFilter);
        ScanRanges scanRanges = context.getScanRanges();
        assertEquals(2,scanRanges.getPointLookupCount());
        Iterator<KeyRange> iterator = scanRanges.getPointLookupKeyIterator();
        KeyRange k1 = iterator.next();
        assertTrue(k1.isSingleKey());
        assertArrayEquals(ByteUtil.concat(StringUtil.padChar(PDataType.CHAR.toBytes(orgId), 15), StringUtil.padChar(PDataType.CHAR.toBytes(entityId), 15)), k1.getLowerRange());
        KeyRange k2 = iterator.next();
        assertTrue(k2.isSingleKey());
        assertArrayEquals(ByteUtil.concat(StringUtil.padChar(PDataType.CHAR.toBytes(orgId2), 15), StringUtil.padChar(PDataType.CHAR.toBytes(entityId2), 15)), k2.getLowerRange());
    }
View Full Code Here

        for (int i=0; i<expectedSlots.size(); i++) {
            List<KeyRange> expectedSlot = expectedSlots.get(i);
            List<KeyRange> slot = slots.get(i);
            assertEquals("index: " + i, expectedSlot.size(), slot.size());
            for (int j=0; j<expectedSlot.size(); j++) {
                KeyRange expectedRange = expectedSlot.get(j);
                KeyRange range = slot.get(j);
                assertArrayEquals(expectedRange.getLowerRange(), range.getLowerRange());
                assertArrayEquals(expectedRange.getUpperRange(), range.getUpperRange());
                assertEquals(expectedRange.isLowerInclusive(), range.isLowerInclusive());
                assertEquals(expectedRange.isUpperInclusive(), range.isUpperInclusive());
            }
        }
    }
View Full Code Here

            if (keyRange == null) {
                return DEGENERATE_KEY_PARTS;
            }
           
            List<KeyRange> keyRanges = slot.getPKSpan() == 1 ? Collections.<KeyRange>singletonList(keyRange) : EVERYTHING_RANGES;
            KeyRange minMaxRange = null;
            if (slot.getPKSpan() > 1) {
                int initPosition = (table.getBucketNum() ==null ? 0 : 1) + (this.context.getConnection().getTenantId() != null && table.isMultiTenant() ? 1 : 0) + (table.getViewIndexId() == null ? 0 : 1);
                if (initPosition == slot.getPKPosition()) {
                    minMaxRange = keyRange;
                }
View Full Code Here

            final ImmutableBytesWritable ptr = context.getTempPtr();
            return new SingleKeySlot(new KeyPart() {

                @Override
                public KeyRange getKeyRange(CompareOp op, Expression rhs) {
                    KeyRange range = childPart.getKeyRange(op, rhs);
                    byte[] lower = range.getLowerRange();
                    if (!range.lowerUnbound()) {
                        ptr.set(lower);
                        // Do the reverse translation so we can optimize out the coerce expression
                        // For the actual type of the coerceBytes call, we use the node type instead of the rhs type, because
                        // for IN, the rhs type will be VARBINARY and no coerce will be done in that case (and we need it to
                        // be done).
                        node.getChild().getDataType().coerceBytes(ptr, node.getDataType(), rhs.getSortOrder(), node.getChild().getSortOrder());
                        lower = ByteUtil.copyKeyBytesIfNecessary(ptr);
                    }
                    byte[] upper = range.getUpperRange();
                    if (!range.upperUnbound()) {
                        ptr.set(upper);
                        // Do the reverse translation so we can optimize out the coerce expression
                        node.getChild().getDataType().coerceBytes(ptr, node.getDataType(), rhs.getSortOrder(), node.getChild().getSortOrder());
                        upper = ByteUtil.copyKeyBytesIfNecessary(ptr);
                    }
                    return KeyRange.getKeyRange(lower, range.isLowerInclusive(), upper, range.isUpperInclusive());
                }

                @Override
                public List<Expression> getExtractNodes() {
                    return childPart.getExtractNodes();
View Full Code Here

        }
       
        private KeySlots andKeySlots(AndExpression andExpression, List<KeySlots> childSlots) {
            int nColumns = table.getPKColumns().size();
            KeySlot[] keySlot = new KeySlot[nColumns];
            KeyRange minMaxRange = KeyRange.EVERYTHING_RANGE;
            List<Expression> minMaxExtractNodes = Lists.<Expression>newArrayList();
            int initPosition = (table.getBucketNum() ==null ? 0 : 1) + (this.context.getConnection().getTenantId() != null && table.isMultiTenant() ? 1 : 0) + (table.getViewIndexId() == null ? 0 : 1);
            for (KeySlots childSlot : childSlots) {
                if (childSlot == DEGENERATE_KEY_PARTS) {
                    return DEGENERATE_KEY_PARTS;
                }
                // FIXME: get rid of this min/max range BS now that a key range can span multiple columns
                if (childSlot.getMinMaxRange() != null) { // Only set if in initial pk position
                    // TODO: potentially use KeySlot.intersect here. However, we can't intersect the key ranges in the slot
                    // with our minMaxRange, since it spans columns and this would mess up our skip scan.
                    minMaxRange = minMaxRange.intersect(childSlot.getMinMaxRange());
                    for (KeySlot slot : childSlot) {
                        minMaxExtractNodes.addAll(slot.getKeyPart().getExtractNodes());
                    }
                } else {
                    for (KeySlot slot : childSlot) {
View Full Code Here

            int thePosition = -1;
            boolean extractAll = true;
            // TODO: Have separate list for single span versus multi span
            // For multi-span, we only need to keep a single range.
            List<KeyRange> slotRanges = Lists.newArrayList();
            KeyRange minMaxRange = KeyRange.EMPTY_RANGE;
            for (KeySlots childSlot : childSlots) {
                if (childSlot == DEGENERATE_KEY_PARTS) {
                    // TODO: can this ever happen and can we safely filter the expression tree?
                    continue;
                }
                if (childSlot.getMinMaxRange() != null) {
                    if (!slotRanges.isEmpty() && thePosition != initialPos) { // ORing together rvc in initial slot with other slots
                        return null;
                    }
                    minMaxRange = minMaxRange.union(childSlot.getMinMaxRange());
                    thePosition = initialPos;
                    for (KeySlot slot : childSlot) {
                        List<Expression> extractNodes = slot.getKeyPart().getExtractNodes();
                        extractAll &= !extractNodes.isEmpty();
                        slotExtractNodes.addAll(extractNodes);
                    }
                } else {
                    // TODO: Do the same optimization that we do for IN if the childSlots specify a fully qualified row key
                    for (KeySlot slot : childSlot) {
                        // We have a nested OR with nothing for this slot, so continue
                        if (slot == null) {
                            continue; // FIXME: I don't think this is ever necessary
                        }
                        /*
                         * If we see a different PK column than before, we can't
                         * optimize it because our SkipScanFilter only handles
                         * top level expressions that are ANDed together (where in
                         * the same column expressions may be ORed together).
                         * For example, WHERE a=1 OR b=2 cannot be handled, while
                         *  WHERE (a=1 OR a=2) AND (b=2 OR b=3) can be handled.
                         * TODO: We could potentially handle these cases through
                         * multiple, nested SkipScanFilters, where each OR expression
                         * is handled by its own SkipScanFilter and the outer one
                         * increments the child ones and picks the one with the smallest
                         * key.
                         */
                        if (thePosition == -1) {
                            theSlot = slot;
                            thePosition = slot.getPKPosition();
                        } else if (thePosition != slot.getPKPosition()) {
                            return null;
                        }
                        List<Expression> extractNodes = slot.getKeyPart().getExtractNodes();
                        extractAll &= !extractNodes.isEmpty();
                        slotExtractNodes.addAll(extractNodes);
                        slotRanges.addAll(slot.getKeyRanges());
                    }
                }
            }

            if (thePosition == -1) {
                return null;
            }
            // With a mix of both, we can't use skip scan, so empty out the union
            // and only extract the min/max nodes.
            if (!slotRanges.isEmpty() && minMaxRange != KeyRange.EMPTY_RANGE) {
                boolean clearExtracts = false;
                // Union the minMaxRanges together with the slotRanges.
                for (KeyRange range : slotRanges) {
                    if (!clearExtracts) {
                        /*
                         * Detect when to clear the extract nodes by determining if there
                         * are gaps left by combining the ranges. If there are gaps, we
                         * cannot extract the nodes, but must them as filters instead.
                         */
                        KeyRange intersection = minMaxRange.intersect(range);
                        if (intersection == KeyRange.EMPTY_RANGE
                                || !range.equals(intersection.union(range))
                                || !minMaxRange.equals(intersection.union(minMaxRange))) {
                            clearExtracts = true;
                        }
                    }
                    minMaxRange = minMaxRange.union(range);
                }
View Full Code Here

TOP

Related Classes of org.apache.phoenix.query.KeyRange

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.