use of org.apache.phoenix.query.KeyRange in project phoenix by apache.
the class ExplainTable method appendScanRow.
private void appendScanRow(StringBuilder buf, Bound bound) {
ScanRanges scanRanges = context.getScanRanges();
// TODO: review this and potentially intersect the scan ranges
// with the minMaxRange in ScanRanges to prevent having to do all this.
KeyRange minMaxRange = scanRanges.getMinMaxRange();
Iterator<byte[]> minMaxIterator = Iterators.emptyIterator();
if (minMaxRange != KeyRange.EVERYTHING_RANGE) {
RowKeySchema schema = tableRef.getTable().getRowKeySchema();
if (!minMaxRange.isUnbound(bound)) {
minMaxIterator = new RowKeyValueIterator(schema, minMaxRange.getRange(bound));
}
}
boolean isLocalIndex = ScanUtil.isLocalIndex(context.getScan());
boolean forceSkipScan = this.hint.hasHint(Hint.SKIP_SCAN);
int nRanges = forceSkipScan ? scanRanges.getRanges().size() : scanRanges.getBoundSlotCount();
for (int i = 0, minPos = 0; minPos < nRanges || minMaxIterator.hasNext(); i++) {
List<KeyRange> ranges = minPos >= nRanges ? EVERYTHING : scanRanges.getRanges().get(minPos++);
KeyRange range = bound == Bound.LOWER ? ranges.get(0) : ranges.get(ranges.size() - 1);
byte[] b = range.getRange(bound);
Boolean isNull = KeyRange.IS_NULL_RANGE == range ? Boolean.TRUE : KeyRange.IS_NOT_NULL_RANGE == range ? Boolean.FALSE : null;
if (minMaxIterator.hasNext()) {
byte[] bMinMax = minMaxIterator.next();
int cmp = Bytes.compareTo(bMinMax, b) * (bound == Bound.LOWER ? 1 : -1);
if (cmp > 0) {
minPos = nRanges;
b = bMinMax;
isNull = null;
} else if (cmp < 0) {
minMaxIterator = Iterators.emptyIterator();
}
}
if (isLocalIndex && i == 0) {
appendPKColumnValue(buf, b, isNull, i, true);
} else {
appendPKColumnValue(buf, b, isNull, i, false);
}
buf.append(',');
}
}
use of org.apache.phoenix.query.KeyRange in project phoenix by apache.
the class ExplainTable method explainSkipScan.
private boolean explainSkipScan(StringBuilder buf) {
ScanRanges scanRanges = context.getScanRanges();
if (scanRanges.isPointLookup()) {
int keyCount = scanRanges.getPointLookupCount();
buf.append("POINT LOOKUP ON " + keyCount + " KEY" + (keyCount > 1 ? "S " : " "));
} else if (scanRanges.useSkipScanFilter()) {
buf.append("SKIP SCAN ");
int count = 1;
boolean hasRanges = false;
int nSlots = scanRanges.getBoundSlotCount();
for (int i = 0; i < nSlots; i++) {
List<KeyRange> ranges = scanRanges.getRanges().get(i);
count *= ranges.size();
for (KeyRange range : ranges) {
hasRanges |= !range.isSingleKey();
}
}
buf.append("ON ");
buf.append(count);
buf.append(hasRanges ? " RANGE" : " KEY");
buf.append(count > 1 ? "S " : " ");
} else {
buf.append("RANGE SCAN ");
}
return scanRanges.useSkipScanFilter();
}
use of org.apache.phoenix.query.KeyRange in project phoenix by apache.
the class KeyOnlyIT method testKeyOnly.
@Test
public void testKeyOnly() throws Exception {
Properties props = PropertiesUtil.deepCopy(TEST_PROPERTIES);
Connection conn = DriverManager.getConnection(getUrl(), props);
initTableValues(conn);
analyzeTable(conn, tableName);
String query = "SELECT i1, i2 FROM " + tableName;
PreparedStatement statement = conn.prepareStatement(query);
ResultSet rs = statement.executeQuery();
assertTrue(rs.next());
assertEquals(1, rs.getInt(1));
assertEquals(2, rs.getInt(2));
assertTrue(rs.next());
assertEquals(3, rs.getInt(1));
assertEquals(4, rs.getInt(2));
assertFalse(rs.next());
List<KeyRange> splits = getAllSplits(conn, tableName);
assertEquals(3, splits.size());
conn.createStatement().execute("ALTER TABLE " + tableName + " ADD s1 varchar");
PreparedStatement stmt = conn.prepareStatement("upsert into " + tableName + " VALUES (?, ?, ?)");
stmt.setInt(1, 5);
stmt.setInt(2, 6);
stmt.setString(3, "foo");
stmt.execute();
conn.commit();
analyzeTable(conn, tableName);
query = "SELECT i1 FROM " + tableName;
statement = conn.prepareStatement(query);
rs = statement.executeQuery();
assertTrue(rs.next());
assertEquals(1, rs.getInt(1));
assertTrue(rs.next());
assertEquals(3, rs.getInt(1));
assertTrue(rs.next());
assertEquals(5, rs.getInt(1));
assertFalse(rs.next());
query = "SELECT i1,s1 FROM " + tableName;
statement = conn.prepareStatement(query);
rs = statement.executeQuery();
assertTrue(rs.next());
assertEquals(1, rs.getInt(1));
assertEquals(null, rs.getString(2));
assertTrue(rs.next());
assertEquals(3, rs.getInt(1));
assertEquals(null, rs.getString(2));
assertTrue(rs.next());
assertEquals(5, rs.getInt(1));
assertEquals("foo", rs.getString(2));
assertFalse(rs.next());
}
use of org.apache.phoenix.query.KeyRange in project phoenix by apache.
the class MultiCfQueryExecIT method testGuidePostsForMultiCFs.
@Test
public void testGuidePostsForMultiCFs() throws Exception {
String query = "SELECT F.RESPONSE_TIME,G.RESPONSE_TIME from " + fullTableName + " where F.RESPONSE_TIME = 2222";
Properties props = PropertiesUtil.deepCopy(TEST_PROPERTIES);
Connection conn = DriverManager.getConnection(url, props);
try {
createTable(conn);
initTableValues(conn);
analyzeTable(conn, fullTableName);
PreparedStatement statement = conn.prepareStatement(query);
ResultSet rs = statement.executeQuery();
assertTrue(rs.next());
assertEquals(2222, rs.getLong(1));
assertEquals(22222, rs.getLong(2));
assertFalse(rs.next());
// Use E column family. Since the column family with the empty key value (the first one, A)
// is always added to the scan, we never really use other guideposts (but this may change).
List<KeyRange> splits = getAllSplits(conn, fullTableName, "e.cpu_utilization IS NOT NULL", "COUNT(*)");
// Since the E column family is not populated, it won't have as many splits
assertEquals(3, splits.size());
// Same as above for G column family.
splits = getAllSplits(conn, fullTableName, "g.response_time IS NOT NULL", "COUNT(*)");
assertEquals(3, splits.size());
} finally {
conn.close();
}
}
use of org.apache.phoenix.query.KeyRange in project phoenix by apache.
the class ParallelIteratorsIT method testGuidePostsLifeCycle.
@Test
public void testGuidePostsLifeCycle() throws Exception {
Connection conn = DriverManager.getConnection(getUrl(), TEST_PROPERTIES);
byte[][] splits = new byte[][] { K3, K9, KR };
createTable(conn, splits);
// create index
conn.createStatement().execute("CREATE INDEX " + indexName + " ON " + tableName + "( \"value\")");
// before upserting
List<KeyRange> keyRanges = getAllSplits(conn, tableName);
assertEquals(4, keyRanges.size());
upsert(conn, new byte[][] { KMIN, K4, K11 });
// Analyze table alone
analyzeTableColumns(conn, tableName);
keyRanges = getAllSplits(conn, tableName);
assertEquals(7, keyRanges.size());
// Get all splits on the index table before calling analyze on the index table
List<KeyRange> indexSplits = getAllSplits(conn, indexName);
assertEquals(1, indexSplits.size());
// Analyze the index table alone
analyzeTableIndex(conn, tableName);
// check the splits of the main table
keyRanges = getAllSplits(conn, tableName);
assertEquals(7, keyRanges.size());
// check the splits on the index table
indexSplits = getAllSplits(conn, indexName);
assertEquals(4, indexSplits.size());
upsert(conn, new byte[][] { KMIN2, K5, K12 });
// Update the stats for both the table and the index table
analyzeTable(conn, tableName);
keyRanges = getAllSplits(conn, tableName);
assertEquals(10, keyRanges.size());
// the above analyze should have udpated the index splits also
indexSplits = getAllSplits(conn, indexName);
assertEquals(7, indexSplits.size());
upsert(conn, new byte[][] { K1, K6, KP });
// Update only the table
analyzeTableColumns(conn, tableName);
keyRanges = getAllSplits(conn, tableName);
assertEquals(13, keyRanges.size());
// No change to the index splits
indexSplits = getAllSplits(conn, indexName);
assertEquals(7, indexSplits.size());
analyzeTableIndex(conn, tableName);
indexSplits = getAllSplits(conn, indexName);
// the above analyze should have udpated the index splits only
assertEquals(10, indexSplits.size());
// No change in main table splits
keyRanges = getAllSplits(conn, tableName);
assertEquals(13, keyRanges.size());
conn.close();
}
Aggregations