Search in sources :

Example 11 with KeyRange

use of org.apache.phoenix.query.KeyRange in project phoenix by apache.

the class SkipScanFilter method readFields.

@Override
public void readFields(DataInput in) throws IOException {
    RowKeySchema schema = new RowKeySchema();
    schema.readFields(in);
    int andLen = in.readInt();
    boolean includeMultipleVersions = false;
    if (andLen < 0) {
        andLen = -andLen;
        includeMultipleVersions = true;
    }
    int[] slotSpan = new int[andLen];
    List<List<KeyRange>> slots = Lists.newArrayListWithExpectedSize(andLen);
    for (int i = 0; i < andLen; i++) {
        int orLenWithSlotSpan = in.readInt();
        int orLen = orLenWithSlotSpan;
        /*
             * For 4.2+ clients, we serialize the slotSpan array. To maintain backward
             * compatibility, we encode the slotSpan values with the size of the list
             * of key ranges. We reserve 21 bits for the key range list and 10 bits
             * for the slotSpan value (up to 1024 which should be plenty).
             */
        if (orLenWithSlotSpan < 0) {
            orLenWithSlotSpan = -orLenWithSlotSpan - 1;
            slotSpan[i] = orLenWithSlotSpan >>> KEY_RANGE_LENGTH_BITS;
            orLen = (orLenWithSlotSpan << SLOT_SPAN_BITS) >>> SLOT_SPAN_BITS;
        }
        List<KeyRange> orClause = Lists.newArrayListWithExpectedSize(orLen);
        slots.add(orClause);
        for (int j = 0; j < orLen; j++) {
            KeyRange range = KeyRange.read(in);
            orClause.add(range);
        }
    }
    this.init(slots, slotSpan, schema, includeMultipleVersions);
}
Also used : KeyRange(org.apache.phoenix.query.KeyRange) RowKeySchema(org.apache.phoenix.schema.RowKeySchema) List(java.util.List)

Example 12 with KeyRange

use of org.apache.phoenix.query.KeyRange in project phoenix by apache.

the class MultiCfQueryExecIT method testGuidePostsForMultiCFsOverUnevenDistrib.

@Test
public void testGuidePostsForMultiCFsOverUnevenDistrib() throws Exception {
    Properties props = PropertiesUtil.deepCopy(TEST_PROPERTIES);
    Connection conn = DriverManager.getConnection(getUrl(), props);
    conn.createStatement().execute("CREATE TABLE " + fullTableName + " (K1 CHAR(1) NOT NULL, " + "K2 VARCHAR NOT NULL, " + "CF1.A INTEGER, " + "CF2.B INTEGER, " + "CF3.C INTEGER, " + "CF4.D INTEGER, " + "CF5.E INTEGER, " + "CF6.F INTEGER " + "CONSTRAINT PK PRIMARY KEY (K1,K2)) SPLIT ON ('B','C','D')");
    for (int i = 0; i < 100; i++) {
        String upsert = "UPSERT INTO " + fullTableName + "(K1,K2,A) VALUES('" + Character.toString((char) ('A' + i % 10)) + "','" + (i * 10) + "'," + i + ")";
        conn.createStatement().execute(upsert);
        if (i % 10 == 0) {
            conn.createStatement().execute("UPSERT INTO " + fullTableName + "(K1,K2,F) VALUES('" + Character.toString((char) ('A' + i % 10)) + "','" + (i * 10) + "'," + (i * 10) + ")");
        }
    }
    conn.commit();
    try {
        analyzeTable(conn, fullTableName);
        PreparedStatement statement = conn.prepareStatement("select count(*) from " + fullTableName + " where f < 400");
        ResultSet rs = statement.executeQuery();
        assertTrue(rs.next());
        assertEquals(4, rs.getLong(1));
        assertFalse(rs.next());
        List<KeyRange> splits = getAllSplits(conn, fullTableName, "f < 400", "COUNT(*)");
        // Uses less populated column f
        assertEquals(14, splits.size());
        // Uses more populated column a
        splits = getAllSplits(conn, fullTableName, "a < 80", "COUNT(*)");
        assertEquals(104, splits.size());
    } finally {
        conn.close();
    }
}
Also used : KeyRange(org.apache.phoenix.query.KeyRange) Connection(java.sql.Connection) ResultSet(java.sql.ResultSet) PreparedStatement(java.sql.PreparedStatement) Properties(java.util.Properties) Test(org.junit.Test)

Example 13 with KeyRange

use of org.apache.phoenix.query.KeyRange in project phoenix by apache.

the class MultiCfQueryExecIT method testGuidePostsRetrievedForMultiCF.

@Test
public void testGuidePostsRetrievedForMultiCF() throws Exception {
    Connection conn;
    PreparedStatement stmt;
    ResultSet rs;
    Properties props = PropertiesUtil.deepCopy(TEST_PROPERTIES);
    conn = DriverManager.getConnection(getUrl(), props);
    conn.createStatement().execute("CREATE TABLE " + fullTableName + " (  k INTEGER PRIMARY KEY, A.V1 VARCHAR, B.V2 VARCHAR, C.V3 VARCHAR)");
    stmt = conn.prepareStatement("UPSERT INTO " + fullTableName + " VALUES(?,?,?,?)");
    stmt.setInt(1, 1);
    stmt.setString(2, "A");
    stmt.setString(3, "B");
    stmt.setString(4, "C");
    stmt.execute();
    conn.commit();
    stmt = conn.prepareStatement("UPSERT INTO " + fullTableName + " VALUES(?,?,?,?)");
    stmt.setInt(1, 2);
    stmt.setString(2, "D");
    stmt.setString(3, "E");
    stmt.setString(4, "F");
    stmt.execute();
    conn.commit();
    stmt = conn.prepareStatement("UPSERT INTO " + fullTableName + "(k, A.V1, C.V3) VALUES(?,?,?)");
    stmt.setInt(1, 3);
    stmt.setString(2, "E");
    stmt.setString(3, "X");
    stmt.execute();
    conn.commit();
    stmt = conn.prepareStatement("UPSERT INTO " + fullTableName + "(k, A.V1, C.V3) VALUES(?,?,?)");
    stmt.setInt(1, 4);
    stmt.setString(2, "F");
    stmt.setString(3, "F");
    stmt.execute();
    conn.commit();
    analyzeTable(conn, fullTableName);
    rs = conn.createStatement().executeQuery("SELECT B.V2 FROM " + fullTableName + " WHERE B.V2 = 'B'");
    assertTrue(rs.next());
    assertEquals("B", rs.getString(1));
    List<KeyRange> splits = getAllSplits(conn, fullTableName, "C.V3 = 'X'", "A.V1");
    assertEquals(5, splits.size());
    splits = getAllSplits(conn, fullTableName, "B.V2 = 'B'", "B.V2");
    assertEquals(3, splits.size());
    conn.close();
}
Also used : KeyRange(org.apache.phoenix.query.KeyRange) Connection(java.sql.Connection) ResultSet(java.sql.ResultSet) PreparedStatement(java.sql.PreparedStatement) Properties(java.util.Properties) Test(org.junit.Test)

Example 14 with KeyRange

use of org.apache.phoenix.query.KeyRange in project phoenix by apache.

the class AggregateIT method testAvgGroupByOrderPreserving.

private void testAvgGroupByOrderPreserving(Connection conn, String tableName, int nGuidePosts) throws SQLException, IOException {
    String query = "SELECT k1,avg(k2) FROM " + tableName + " GROUP BY k1";
    ResultSet rs = conn.createStatement().executeQuery(query);
    assertTrue(rs.next());
    assertEquals("a", rs.getString(1));
    assertEquals(3, rs.getInt(2));
    assertTrue(rs.next());
    assertEquals("b", rs.getString(1));
    assertEquals(5, rs.getInt(2));
    assertTrue(rs.next());
    assertEquals("j", rs.getString(1));
    assertEquals(4, rs.getInt(2));
    assertTrue(rs.next());
    assertEquals("n", rs.getString(1));
    assertEquals(2, rs.getInt(2));
    assertFalse(rs.next());
    rs = conn.createStatement().executeQuery("EXPLAIN " + query);
    assertEquals("CLIENT PARALLEL 1-WAY FULL SCAN OVER " + tableName + "\n" + "    SERVER FILTER BY FIRST KEY ONLY\n" + "    SERVER AGGREGATE INTO ORDERED DISTINCT ROWS BY [K1]", QueryUtil.getExplainPlan(rs));
    TestUtil.analyzeTable(conn, tableName);
    List<KeyRange> splits = TestUtil.getAllSplits(conn, tableName);
    assertEquals(nGuidePosts, splits.size());
}
Also used : KeyRange(org.apache.phoenix.query.KeyRange) ResultSet(java.sql.ResultSet)

Example 15 with KeyRange

use of org.apache.phoenix.query.KeyRange in project phoenix by apache.

the class RoundDecimalExpression method newKeyPart.

@Override
public KeyPart newKeyPart(final KeyPart childPart) {
    return new KeyPart() {

        private final List<Expression> extractNodes = Collections.<Expression>singletonList(RoundDecimalExpression.this);

        @Override
        public PColumn getColumn() {
            return childPart.getColumn();
        }

        @Override
        public List<Expression> getExtractNodes() {
            return extractNodes;
        }

        @Override
        public KeyRange getKeyRange(CompareFilter.CompareOp op, Expression rhs) {
            final BigDecimal rhsDecimal = (BigDecimal) PDecimal.INSTANCE.toObject(evaluateExpression(rhs));
            // than needed for a match, it's impossible for there to be any matches
            if (op == CompareFilter.CompareOp.EQUAL && !hasEnoughPrecisionToProduce(rhsDecimal)) {
                return KeyRange.EMPTY_RANGE;
            }
            // if the decimal needs to be rounded, round it such that the given 
            // operator will still be valid
            BigDecimal roundedDecimal = roundAndPreserveOperator(rhsDecimal, op);
            // the range of big decimals that could be rounded to produce the rounded result
            // alternatively, the "rounding bucket" that this decimal falls into
            final KeyRange equalityRange = getInputRangeProducing(roundedDecimal);
            boolean lowerInclusive = equalityRange.isLowerInclusive();
            boolean upperInclusive = equalityRange.isUpperInclusive();
            byte[] lowerRange = KeyRange.UNBOUND;
            byte[] upperRange = KeyRange.UNBOUND;
            switch(op) {
                case EQUAL:
                    return equalityRange;
                case GREATER:
                    // from the equality range and up, NOT including the equality range
                    lowerRange = equalityRange.getUpperRange();
                    lowerInclusive = !equalityRange.isUpperInclusive();
                    break;
                case GREATER_OR_EQUAL:
                    // from the equality range and up, including the equality range
                    lowerRange = equalityRange.getLowerRange();
                    break;
                case LESS:
                    // from the equality range and down, NOT including the equality range
                    upperRange = equalityRange.getLowerRange();
                    upperInclusive = !equalityRange.isLowerInclusive();
                    break;
                case LESS_OR_EQUAL:
                    // from the equality range and down, including the equality range
                    upperRange = equalityRange.getUpperRange();
                    break;
                default:
                    throw new AssertionError("Invalid CompareOp: " + op);
            }
            return KeyRange.getKeyRange(lowerRange, lowerInclusive, upperRange, upperInclusive);
        }

        /**
             * Produces a the given decimal rounded to this rounding expression's scale. If the 
             * decimal requires more scale precision to produce than this expression has, as in
             * ROUND(?, 2) &gt; 2.0098974, it ensures that the decimal is rounded such that the
             * given operator will still produce correct results.
             * @param decimal  the decimal to round with this expression's scale
             * @param op  the operator to preserve comparison with in the event of lost precision
             * @return  the rounded decimal
             */
        private BigDecimal roundAndPreserveOperator(BigDecimal decimal, CompareFilter.CompareOp op) {
            final BigDecimal rounded = roundToScale(decimal);
            // if we lost information, make sure that the rounding didn't break the operator
            if (!hasEnoughPrecisionToProduce(decimal)) {
                switch(op) {
                    case GREATER_OR_EQUAL:
                        // 'ROUND(dec, 2) >= 2.01' but should be 'ROUND(dec, 2) >= 2.02'
                        if (decimal.compareTo(rounded) > 0) {
                            return stepNextInScale(rounded);
                        }
                        break;
                    case GREATER:
                        // 'ROUND(dec, 2) > 2.02' but should be 'ROUND(dec, 2) > 2.01'
                        if (decimal.compareTo(rounded) < 0) {
                            return stepPrevInScale(rounded);
                        }
                        break;
                    case LESS_OR_EQUAL:
                        // 'ROUND(dec, 2) < 2.02' but should be 'ROUND(dec, 2) < 2.01'
                        if (decimal.compareTo(rounded) < 0) {
                            return stepPrevInScale(rounded);
                        }
                        break;
                    case LESS:
                        // 'ROUND(dec, 2) <= 2.01' but should be 'ROUND(dec, 2) <= 2.02'
                        if (decimal.compareTo(rounded) > 0) {
                            return stepNextInScale(rounded);
                        }
                        break;
                }
            }
            // otherwise, rounding has not affected the operator, so return normally
            return rounded;
        }

        @Override
        public PTable getTable() {
            return childPart.getTable();
        }
    };
}
Also used : Expression(org.apache.phoenix.expression.Expression) LiteralExpression(org.apache.phoenix.expression.LiteralExpression) KeyRange(org.apache.phoenix.query.KeyRange) KeyPart(org.apache.phoenix.compile.KeyPart) List(java.util.List) BigDecimal(java.math.BigDecimal)

Aggregations

KeyRange (org.apache.phoenix.query.KeyRange)51 Test (org.junit.Test)23 Connection (java.sql.Connection)16 ResultSet (java.sql.ResultSet)14 PreparedStatement (java.sql.PreparedStatement)9 ArrayList (java.util.ArrayList)9 List (java.util.List)8 Properties (java.util.Properties)7 Scan (org.apache.hadoop.hbase.client.Scan)7 ScanRanges (org.apache.phoenix.compile.ScanRanges)6 BigDecimal (java.math.BigDecimal)5 PhoenixConnection (org.apache.phoenix.jdbc.PhoenixConnection)5 KeyPart (org.apache.phoenix.compile.KeyPart)4 QueryPlan (org.apache.phoenix.compile.QueryPlan)4 PhoenixStatement (org.apache.phoenix.jdbc.PhoenixStatement)4 Field (org.apache.phoenix.schema.ValueSchema.Field)4 KeyValue (org.apache.hadoop.hbase.KeyValue)3 SkipScanFilter (org.apache.phoenix.filter.SkipScanFilter)3 IOException (java.io.IOException)2 Statement (java.sql.Statement)2