use of org.apache.phoenix.compile.QueryPlan in project phoenix by apache.
the class PhoenixInputFormat method getQueryPlan.
/**
* Returns the query plan associated with the select query.
*/
private QueryPlan getQueryPlan(final Configuration configuration, String selectStatement) throws IOException {
try {
final String currentScnValue = configuration.get(PhoenixConfigurationUtil.CURRENT_SCN_VALUE);
final Properties overridingProps = new Properties();
if (currentScnValue != null) {
overridingProps.put(PhoenixRuntime.CURRENT_SCN_ATTRIB, currentScnValue);
}
final Connection connection = PhoenixConnectionUtil.getInputConnection(configuration, overridingProps);
Preconditions.checkNotNull(selectStatement);
final Statement statement = connection.createStatement();
final PhoenixStatement pstmt = statement.unwrap(PhoenixStatement.class);
if (LOG.isDebugEnabled()) {
LOG.debug("Compiled query : " + selectStatement);
}
// Optimize the query plan so that we potentially use secondary indexes
final QueryPlan queryPlan = pstmt.optimizeQuery(selectStatement);
// Initialize the query plan so it sets up the parallel scans
queryPlan.iterator(MapReduceParallelScanGrouper.getInstance());
return queryPlan;
} catch (Exception exception) {
LOG.error(String.format("Failed to get the query plan with error [%s]", exception.getMessage()));
throw new RuntimeException(exception);
}
}
use of org.apache.phoenix.compile.QueryPlan in project phoenix by apache.
the class PhoenixInputFormat method getSplits.
@Override
public InputSplit[] getSplits(JobConf jobConf, int numSplits) throws IOException {
String tableName = jobConf.get(PhoenixStorageHandlerConstants.PHOENIX_TABLE_NAME);
String query;
String executionEngine = jobConf.get(HiveConf.ConfVars.HIVE_EXECUTION_ENGINE.varname, HiveConf.ConfVars.HIVE_EXECUTION_ENGINE.getDefaultValue());
if (LOG.isDebugEnabled()) {
LOG.debug("Target table name at split phase : " + tableName + "with whereCondition :" + jobConf.get(TableScanDesc.FILTER_TEXT_CONF_STR) + " and " + HiveConf.ConfVars.HIVE_EXECUTION_ENGINE.varname + " : " + executionEngine);
}
if (PhoenixStorageHandlerConstants.MR.equals(executionEngine)) {
List<IndexSearchCondition> conditionList = null;
String filterExprSerialized = jobConf.get(TableScanDesc.FILTER_EXPR_CONF_STR);
if (filterExprSerialized != null) {
ExprNodeGenericFuncDesc filterExpr = Utilities.deserializeExpression(filterExprSerialized);
PhoenixPredicateDecomposer predicateDecomposer = PhoenixPredicateDecomposer.create(Arrays.asList(jobConf.get(serdeConstants.LIST_COLUMNS).split(",")));
predicateDecomposer.decomposePredicate(filterExpr);
if (predicateDecomposer.isCalledPPD()) {
conditionList = predicateDecomposer.getSearchConditionList();
}
}
query = PhoenixQueryBuilder.getInstance().buildQuery(jobConf, tableName, PhoenixStorageHandlerUtil.getReadColumnNames(jobConf), conditionList);
} else if (PhoenixStorageHandlerConstants.TEZ.equals(executionEngine)) {
Map<String, TypeInfo> columnTypeMap = PhoenixStorageHandlerUtil.createColumnTypeMap(jobConf);
if (LOG.isDebugEnabled()) {
LOG.debug("Column type map for TEZ : " + columnTypeMap);
}
String whereClause = jobConf.get(TableScanDesc.FILTER_TEXT_CONF_STR);
query = PhoenixQueryBuilder.getInstance().buildQuery(jobConf, tableName, PhoenixStorageHandlerUtil.getReadColumnNames(jobConf), whereClause, columnTypeMap);
} else {
throw new IOException(executionEngine + " execution engine unsupported yet.");
}
final QueryPlan queryPlan = getQueryPlan(jobConf, query);
final List<KeyRange> allSplits = queryPlan.getSplits();
final List<InputSplit> splits = generateSplits(jobConf, queryPlan, allSplits, query);
return splits.toArray(new InputSplit[splits.size()]);
}
use of org.apache.phoenix.compile.QueryPlan in project phoenix by apache.
the class UpsertValuesIT method testAutomaticallySettingRowTimestampForImmutableTableAndIndexes.
private void testAutomaticallySettingRowTimestampForImmutableTableAndIndexes(String sortOrder) throws Exception {
String tableName = "testSettingRowTimestampForImmutableTableAndIndexes".toUpperCase();
String indexName = "testSettingRowTimestampForImmutableTableAndIndexes_index".toUpperCase();
long ts = nextTimestamp();
try (Connection conn = getConnection(ts)) {
conn.createStatement().execute("CREATE TABLE IF NOT EXISTS " + tableName + " (PK1 VARCHAR NOT NULL, PK2 DATE NOT NULL, KV1 VARCHAR, KV2 VARCHAR CONSTRAINT PK PRIMARY KEY(PK1, PK2 " + sortOrder + " ROW_TIMESTAMP)) " + " IMMUTABLE_ROWS=true");
}
ts = nextTimestamp();
try (Connection conn = getConnection(ts)) {
conn.createStatement().execute("CREATE INDEX IF NOT EXISTS " + indexName + " ON " + tableName + " (PK2, KV1) INCLUDE (KV2)");
}
ts = nextTimestamp();
try (Connection conn = getConnection(ts)) {
// Upsert values where row_timestamp column PK2 is not set and the column names are specified
// This should upsert data with the value for PK2 as new Date(ts);
PreparedStatement stmt = conn.prepareStatement("UPSERT INTO " + tableName + " (PK1, KV1, KV2) VALUES (?, ?, ?)");
stmt.setString(1, "PK1");
stmt.setString(2, "KV1");
stmt.setString(3, "KV2");
stmt.executeUpdate();
conn.commit();
}
Date upsertedDate = new Date(ts);
ts = nextTimestamp();
try (Connection conn = getConnection(ts)) {
// Now query for data that was upserted above. If the row key was generated correctly then we should be able to see
// the data in this query.
PreparedStatement stmt = conn.prepareStatement("SELECT KV1, KV2 FROM " + tableName + " WHERE PK1 = ? AND PK2 = ?");
stmt.setString(1, "PK1");
stmt.setDate(2, upsertedDate);
ResultSet rs = stmt.executeQuery();
assertTrue(rs.next());
assertEquals("KV1", rs.getString(1));
assertEquals("KV2", rs.getString(2));
assertFalse(rs.next());
// Verify now that the data was correctly added to the immutable index too.
stmt = conn.prepareStatement("SELECT KV2 FROM " + tableName + " WHERE PK2 = ? AND KV1 = ?");
stmt.setDate(1, upsertedDate);
stmt.setString(2, "KV1");
rs = stmt.executeQuery();
QueryPlan plan = stmt.unwrap(PhoenixStatement.class).getQueryPlan();
assertTrue(plan.getTableRef().getTable().getName().getString().equals(indexName));
assertTrue(rs.next());
assertEquals("KV2", rs.getString(1));
assertFalse(rs.next());
}
}
use of org.apache.phoenix.compile.QueryPlan in project phoenix by apache.
the class UpsertValuesIT method testWithUpsertingRowTimestampColSpecified.
private void testWithUpsertingRowTimestampColSpecified(boolean desc) throws Exception {
String tableName = "testUpsertingRowTimestampCol".toUpperCase();
String indexName = "testUpsertingRowTimestampCol_idx".toUpperCase();
long ts = nextTimestamp();
String sortOrder = desc ? "DESC" : "";
try (Connection conn = getConnection(ts)) {
conn.createStatement().execute("CREATE TABLE IF NOT EXISTS " + tableName + " (PK1 VARCHAR NOT NULL, PK2 DATE NOT NULL, KV1 VARCHAR, KV2 VARCHAR CONSTRAINT PK PRIMARY KEY(PK1, PK2 " + sortOrder + " ROW_TIMESTAMP " + ")) ");
}
ts = nextTimestamp();
try (Connection conn = getConnection(ts)) {
conn.createStatement().execute("CREATE INDEX IF NOT EXISTS " + indexName + " ON " + tableName + " (PK2, KV1) INCLUDE (KV2)");
}
ts = nextTimestamp();
long rowTimestamp = ts + 10000;
Date rowTimestampDate = new Date(rowTimestamp);
try (Connection conn = getConnection(ts)) {
// Upsert data with scn set on the connection. However, the timestamp of the put will be the value of the row_timestamp column.
PreparedStatement stmt = conn.prepareStatement("UPSERT INTO " + tableName + " (PK1, PK2, KV1, KV2) VALUES (?, ?, ?, ?)");
stmt.setString(1, "PK1");
stmt.setDate(2, rowTimestampDate);
stmt.setString(3, "KV1");
stmt.setString(4, "KV2");
stmt.executeUpdate();
conn.commit();
}
ts = nextTimestamp();
try (Connection conn = getConnection(ts)) {
// Verify that the connection with the next time stamp isn't able to see the data inserted above. This
// is because the timestamp of the put was rowTimestamp and not connection scn.
PreparedStatement stmt = conn.prepareStatement("SELECT * FROM " + tableName + " WHERE PK1 = ? AND PK2 = ?");
stmt.setString(1, "PK1");
stmt.setDate(2, rowTimestampDate);
ResultSet rs = stmt.executeQuery();
assertFalse(rs.next());
// Same holds when querying the index table too
stmt = conn.prepareStatement("SELECT KV1 FROM " + tableName + " WHERE PK2 = ?");
stmt.setDate(1, rowTimestampDate);
rs = stmt.executeQuery();
assertFalse(rs.next());
}
// data that we upserted above.
try (Connection conn = getConnection(rowTimestamp + 5)) {
PreparedStatement stmt = conn.prepareStatement("SELECT * FROM " + tableName + " WHERE PK1 = ? AND PK2 = ?");
stmt.setString(1, "PK1");
stmt.setDate(2, rowTimestampDate);
ResultSet rs = stmt.executeQuery();
assertTrue(rs.next());
assertEquals("PK1", rs.getString("PK1"));
assertEquals(rowTimestampDate, rs.getDate("PK2"));
assertEquals("KV1", rs.getString("KV1"));
// Data visible when querying the index table too.
stmt = conn.prepareStatement("SELECT KV2 FROM " + tableName + " WHERE PK2 = ? AND KV1 = ?");
stmt.setDate(1, rowTimestampDate);
stmt.setString(2, "KV1");
rs = stmt.executeQuery();
QueryPlan plan = stmt.unwrap(PhoenixStatement.class).getQueryPlan();
assertTrue(plan.getTableRef().getTable().getName().getString().equals(indexName));
assertTrue(rs.next());
assertEquals("KV2", rs.getString("KV2"));
}
}
use of org.apache.phoenix.compile.QueryPlan in project phoenix by apache.
the class UpsertValuesIT method testAutomaticallySettingRowtimestamp.
private void testAutomaticallySettingRowtimestamp(String sortOrder) throws Exception {
String tableName = "testAutomaticallySettingRowtimestamp".toUpperCase();
String indexName = "testAutomaticallySettingRowtimestamp_index".toUpperCase();
long ts = nextTimestamp();
try (Connection conn = getConnection(ts)) {
conn.createStatement().execute("CREATE TABLE IF NOT EXISTS " + tableName + " (PK1 VARCHAR NOT NULL, PK2 DATE NOT NULL, KV1 VARCHAR, KV2 VARCHAR CONSTRAINT PK PRIMARY KEY(PK1, PK2 " + sortOrder + " ROW_TIMESTAMP " + ")) ");
}
ts = nextTimestamp();
try (Connection conn = getConnection(ts)) {
conn.createStatement().execute("CREATE INDEX IF NOT EXISTS " + indexName + " ON " + tableName + " (PK2, KV1) INCLUDE (KV2)");
}
ts = nextTimestamp();
try (Connection conn = getConnection(ts)) {
// Upsert values where row_timestamp column PK2 is not set and the column names are specified
// This should upsert data with the value for PK2 as new Date(ts);
PreparedStatement stmt = conn.prepareStatement("UPSERT INTO " + tableName + " (PK1, KV1, KV2) VALUES (?, ?, ?)");
stmt.setString(1, "PK1");
stmt.setString(2, "KV1");
stmt.setString(3, "KV2");
stmt.executeUpdate();
conn.commit();
}
Date upsertedDate = new Date(ts);
ts = nextTimestamp();
try (Connection conn = getConnection(ts)) {
// Now query for data that was upserted above. If the row key was generated correctly then we should be able to see
// the data in this query.
PreparedStatement stmt = conn.prepareStatement("SELECT KV1, KV2 FROM " + tableName + " WHERE PK1 = ? AND PK2 = ?");
stmt.setString(1, "PK1");
stmt.setDate(2, upsertedDate);
ResultSet rs = stmt.executeQuery();
assertTrue(rs.next());
assertEquals("KV1", rs.getString(1));
assertEquals("KV2", rs.getString(2));
assertFalse(rs.next());
// Verify now that the data was correctly added to the mutable index too.
stmt = conn.prepareStatement("SELECT KV2 FROM " + tableName + " WHERE PK2 = ? AND KV1 = ?");
stmt.setDate(1, upsertedDate);
stmt.setString(2, "KV1");
rs = stmt.executeQuery();
QueryPlan plan = stmt.unwrap(PhoenixStatement.class).getQueryPlan();
assertTrue(plan.getTableRef().getTable().getName().getString().equals(indexName));
assertTrue(rs.next());
assertEquals("KV2", rs.getString(1));
assertFalse(rs.next());
}
}
Aggregations