use of org.apache.phoenix.compile.QueryPlan in project phoenix by apache.
the class PhoenixInputFormat method getRecordReader.
@Override
public RecordReader<WritableComparable, T> getRecordReader(InputSplit split, JobConf job, Reporter reporter) throws IOException {
final QueryPlan queryPlan = getQueryPlan(job, ((PhoenixInputSplit) split).getQuery());
@SuppressWarnings("unchecked") final Class<T> inputClass = (Class<T>) job.getClass(PhoenixConfigurationUtil.INPUT_CLASS, PhoenixResultWritable.class);
PhoenixRecordReader<T> recordReader = new PhoenixRecordReader<T>(inputClass, job, queryPlan);
recordReader.initialize(split);
return recordReader;
}
use of org.apache.phoenix.compile.QueryPlan in project phoenix by apache.
the class QuerySchemaParserFunction method apply.
@Override
public Pair<String, String> apply(final String selectStatement) {
Preconditions.checkNotNull(selectStatement);
Preconditions.checkArgument(!selectStatement.isEmpty(), "Select Query is empty!!");
Connection connection = null;
try {
connection = ConnectionUtil.getInputConnection(this.configuration);
final Statement statement = connection.createStatement();
final PhoenixStatement pstmt = statement.unwrap(PhoenixStatement.class);
final QueryPlan queryPlan = pstmt.compileQuery(selectStatement);
isValidStatement(queryPlan);
final String tableName = queryPlan.getTableRef().getTable().getName().getString();
final List<? extends ColumnProjector> projectedColumns = queryPlan.getProjector().getColumnProjectors();
final List<String> columns = Lists.transform(projectedColumns, new Function<ColumnProjector, String>() {
@Override
public String apply(ColumnProjector column) {
return column.getName();
}
});
final String columnsAsStr = Joiner.on(",").join(columns);
return new Pair<String, String>(tableName, columnsAsStr);
} catch (SQLException e) {
LOG.error(String.format(" Error [%s] parsing SELECT query [%s] ", e.getMessage(), selectStatement));
throw new RuntimeException(e);
} finally {
if (connection != null) {
try {
connection.close();
} catch (SQLException sqle) {
LOG.error(" Error closing connection ");
throw new RuntimeException(sqle);
}
}
}
}
use of org.apache.phoenix.compile.QueryPlan in project phoenix by apache.
the class PhoenixInputFormat method createRecordReader.
@Override
public RecordReader<NullWritable, T> createRecordReader(InputSplit split, TaskAttemptContext context) throws IOException, InterruptedException {
final Configuration configuration = context.getConfiguration();
final QueryPlan queryPlan = getQueryPlan(context, configuration);
@SuppressWarnings("unchecked") final Class<T> inputClass = (Class<T>) PhoenixConfigurationUtil.getInputClass(configuration);
return new PhoenixRecordReader<T>(inputClass, configuration, queryPlan);
}
use of org.apache.phoenix.compile.QueryPlan in project phoenix by apache.
the class CorrelatePlanTest method testCorrelatePlan.
private void testCorrelatePlan(Object[][] leftRelation, Object[][] rightRelation, int leftCorrelColumn, int rightCorrelColumn, JoinType type, Object[][] expectedResult, Integer offset) throws SQLException {
TableRef leftTable = createProjectedTableFromLiterals(leftRelation[0]);
TableRef rightTable = createProjectedTableFromLiterals(rightRelation[0]);
String varName = "$cor0";
RuntimeContext runtimeContext = new RuntimeContextImpl();
runtimeContext.defineCorrelateVariable(varName, leftTable);
QueryPlan leftPlan = newLiteralResultIterationPlan(leftRelation, offset);
QueryPlan rightPlan = newLiteralResultIterationPlan(rightRelation, offset);
Expression columnExpr = new ColumnRef(rightTable, rightCorrelColumn).newColumnExpression();
Expression fieldAccess = new CorrelateVariableFieldAccessExpression(runtimeContext, varName, new ColumnRef(leftTable, leftCorrelColumn).newColumnExpression());
Expression filter = ComparisonExpression.create(CompareOp.EQUAL, Arrays.asList(columnExpr, fieldAccess), CONTEXT.getTempPtr(), false);
rightPlan = new ClientScanPlan(CONTEXT, SelectStatement.SELECT_ONE, rightTable, RowProjector.EMPTY_PROJECTOR, null, null, filter, OrderBy.EMPTY_ORDER_BY, rightPlan);
PTable joinedTable = JoinCompiler.joinProjectedTables(leftTable.getTable(), rightTable.getTable(), type);
CorrelatePlan correlatePlan = new CorrelatePlan(leftPlan, rightPlan, varName, type, false, runtimeContext, joinedTable, leftTable.getTable(), rightTable.getTable(), leftTable.getTable().getColumns().size());
ResultIterator iter = correlatePlan.iterator();
ImmutableBytesWritable ptr = new ImmutableBytesWritable();
for (Object[] row : expectedResult) {
Tuple next = iter.next();
assertNotNull(next);
for (int i = 0; i < row.length; i++) {
PColumn column = joinedTable.getColumns().get(i);
boolean eval = new ProjectedColumnExpression(column, joinedTable, column.getName().getString()).evaluate(next, ptr);
Object o = eval ? column.getDataType().toObject(ptr) : null;
assertEquals(row[i], o);
}
}
}
use of org.apache.phoenix.compile.QueryPlan in project phoenix by apache.
the class AlterMultiTenantTableWithViewsIT method testAddingPkAndKeyValueColumnsToBaseTableWithDivergedView.
@Test
public void testAddingPkAndKeyValueColumnsToBaseTableWithDivergedView() throws Exception {
String baseTable = "testAlteringPkOfBaseTableWithDivergedView".toUpperCase();
String view1 = generateUniqueName();
String divergedView = generateUniqueName();
String divergedViewIndex = divergedView + "_IDX";
/* baseTable
/ |
view1(tenant1) divergedView(tenant2)
*/
try (Connection conn = DriverManager.getConnection(getUrl())) {
String baseTableDDL = "CREATE TABLE " + baseTable + " (TENANT_ID VARCHAR NOT NULL, PK1 VARCHAR NOT NULL, V1 VARCHAR, V2 VARCHAR, V3 VARCHAR CONSTRAINT NAME_PK PRIMARY KEY(TENANT_ID, PK1)) MULTI_TENANT = true ";
conn.createStatement().execute(baseTableDDL);
try (Connection tenant1Conn = getTenantConnection("tenant1")) {
String view1DDL = "CREATE VIEW " + view1 + " ( VIEW_COL1 DECIMAL(10,2), VIEW_COL2 CHAR(256)) AS SELECT * FROM " + baseTable;
tenant1Conn.createStatement().execute(view1DDL);
}
try (Connection tenant2Conn = getTenantConnection("tenant2")) {
String divergedViewDDL = "CREATE VIEW " + divergedView + " ( VIEW_COL1 DECIMAL(10,2), VIEW_COL2 CHAR(256)) AS SELECT * FROM " + baseTable;
tenant2Conn.createStatement().execute(divergedViewDDL);
// Drop column V2 from the view to have it diverge from the base table
tenant2Conn.createStatement().execute("ALTER VIEW " + divergedView + " DROP COLUMN V2");
// create an index on the diverged view
String indexDDL = "CREATE INDEX " + divergedViewIndex + " ON " + divergedView + " (V1) include (V3)";
tenant2Conn.createStatement().execute(indexDDL);
}
String alterBaseTable = "ALTER TABLE " + baseTable + " ADD KV VARCHAR, PK2 VARCHAR PRIMARY KEY";
conn.createStatement().execute(alterBaseTable);
// verify that the both columns were added to view1
try (Connection tenant1Conn = getTenantConnection("tenant1")) {
tenant1Conn.createStatement().execute("SELECT KV from " + view1);
tenant1Conn.createStatement().execute("SELECT PK2 from " + view1);
}
// verify that only the primary key column PK2 was added to diverged view
try (Connection tenant2Conn = getTenantConnection("tenant2")) {
tenant2Conn.createStatement().execute("SELECT PK2 from " + divergedView);
try {
tenant2Conn.createStatement().execute("SELECT KV FROM " + divergedView);
} catch (SQLException e) {
assertEquals(SQLExceptionCode.COLUMN_NOT_FOUND.getErrorCode(), e.getErrorCode());
}
}
// Upsert records in diverged view. Verify that the PK column was added to the index on it.
String upsert = "UPSERT INTO " + divergedView + " (PK1, PK2, V1, V3) VALUES ('PK1', 'PK2', 'V1', 'V3')";
try (Connection viewConn = getTenantConnection("tenant2")) {
viewConn.createStatement().executeUpdate(upsert);
viewConn.commit();
Statement stmt = viewConn.createStatement();
String sql = "SELECT V3 FROM " + divergedView + " WHERE V1 = 'V1' AND PK2 = 'PK2'";
QueryPlan plan = stmt.unwrap(PhoenixStatement.class).optimizeQuery(sql);
assertTrue(plan.getTableRef().getTable().getName().getString().equals(SchemaUtil.normalizeIdentifier(divergedViewIndex)));
ResultSet rs = viewConn.createStatement().executeQuery(sql);
verifyNewColumns(rs, "V3");
}
// For non-diverged view, base table columns will be added at the same position as base table
assertTableDefinition(conn, view1, PTableType.VIEW, baseTable, 1, 9, 7, "TENANT_ID", "PK1", "V1", "V2", "V3", "KV", "PK2", "VIEW_COL1", "VIEW_COL2");
// For a diverged view, only base table's pk column will be added and that too at the end.
assertTableDefinition(conn, divergedView, PTableType.VIEW, baseTable, 2, 7, DIVERGED_VIEW_BASE_COLUMN_COUNT, "TENANT_ID", "PK1", "V1", "V3", "VIEW_COL1", "VIEW_COL2", "PK2");
// Adding existing column VIEW_COL2 to the base table isn't allowed.
try {
alterBaseTable = "ALTER TABLE " + baseTable + " ADD VIEW_COL2 CHAR(256)";
conn.createStatement().execute(alterBaseTable);
fail();
} catch (SQLException e) {
assertEquals("Unexpected exception", SQLExceptionCode.CANNOT_MUTATE_TABLE.getErrorCode(), e.getErrorCode());
}
}
}
Aggregations