conn2.close();
}
@Test
public void testCreateViewOnExistingTable() throws Exception {
PhoenixConnection pconn = DriverManager.getConnection(getUrl(), PropertiesUtil.deepCopy(TEST_PROPERTIES)).unwrap(PhoenixConnection.class);
String tableName = MDTEST_NAME;
String schemaName = MDTEST_SCHEMA_NAME;
byte[] cfB = Bytes.toBytes(SchemaUtil.normalizeIdentifier("b"));
byte[] cfC = Bytes.toBytes("c");
byte[][] familyNames = new byte[][] {cfB, cfC};
byte[] htableName = SchemaUtil.getTableNameAsBytes(schemaName, tableName);
HBaseAdmin admin = pconn.getQueryServices().getAdmin();
try {
admin.disableTable(htableName);
admin.deleteTable(htableName);
admin.enableTable(htableName);
} catch (org.apache.hadoop.hbase.TableNotFoundException e) {
} finally {
admin.close();
}
HTableDescriptor descriptor = new HTableDescriptor(htableName);
for (byte[] familyName : familyNames) {
HColumnDescriptor columnDescriptor = new HColumnDescriptor(familyName);
descriptor.addFamily(columnDescriptor);
}
admin.createTable(descriptor);
long ts = nextTimestamp();
Properties props = new Properties();
props.setProperty(PhoenixRuntime.CURRENT_SCN_ATTRIB, Long.toString(ts + 5));
Connection conn1 = DriverManager.getConnection(getUrl(), props);
String createStmt = "create view bogusTable" +
" (id char(1) not null primary key,\n" +
" a.col1 integer,\n" +
" d.col2 bigint)\n";
try {
conn1.createStatement().execute(createStmt);
fail();
} catch (TableNotFoundException e) {
// expected to fail b/c table doesn't exist
}
createStmt = "create view " + MDTEST_NAME +
" (id char(1) not null primary key,\n" +
" a.col1 integer,\n" +
" b.col2 bigint)\n";
try {
conn1.createStatement().execute(createStmt);
fail();
} catch (ReadOnlyTableException e) {
// expected to fail b/c cf a doesn't exist
}
createStmt = "create view " + MDTEST_NAME +
" (id char(1) not null primary key,\n" +
" b.col1 integer,\n" +
" c.col2 bigint)\n";
try {
conn1.createStatement().execute(createStmt);
fail();
} catch (ReadOnlyTableException e) {
// expected to fail b/c cf C doesn't exist (case issue)
}
createStmt = "create view " + MDTEST_NAME +
" (id char(1) not null primary key,\n" +
" b.col1 integer,\n" +
" \"c\".col2 bigint) \n";
// should be ok now
conn1.createStatement().execute(createStmt);
conn1.close();
props.setProperty(PhoenixRuntime.CURRENT_SCN_ATTRIB, Long.toString(ts + 6));
PhoenixConnection conn2 = DriverManager.getConnection(getUrl(), props).unwrap(PhoenixConnection.class);
ResultSet rs = conn2.getMetaData().getTables(null, null, MDTEST_NAME, null);
assertTrue(rs.next());
assertEquals(ViewType.MAPPED.name(), rs.getString(PhoenixDatabaseMetaData.VIEW_TYPE));
assertFalse(rs.next());
String deleteStmt = "DELETE FROM " + MDTEST_NAME;
PreparedStatement ps = conn2.prepareStatement(deleteStmt);
try {
ps.execute();
fail();
} catch (ReadOnlyTableException e) {
// expected to fail b/c table is read-only
}
try {
String upsert = "UPSERT INTO " + MDTEST_NAME + "(id,col1,col2) VALUES(?,?,?)";
ps = conn2.prepareStatement(upsert);
try {
ps.setString(1, Integer.toString(0));
ps.setInt(2, 1);
ps.setInt(3, 2);
ps.execute();
fail();
} catch (ReadOnlyTableException e) {
// expected to fail b/c table is read-only
}
conn2.createStatement().execute("ALTER VIEW " + MDTEST_NAME + " SET IMMUTABLE_ROWS=TRUE");
HTableInterface htable = conn2.getQueryServices().getTable(SchemaUtil.getTableNameAsBytes(MDTEST_SCHEMA_NAME,MDTEST_NAME));
Put put = new Put(Bytes.toBytes("0"));
put.add(cfB, Bytes.toBytes("COL1"), ts+6, PDataType.INTEGER.toBytes(1));
put.add(cfC, Bytes.toBytes("COL2"), ts+6, PDataType.LONG.toBytes(2));
htable.put(put);
conn2.close();
props.setProperty(PhoenixRuntime.CURRENT_SCN_ATTRIB, Long.toString(ts + 10));
Connection conn7 = DriverManager.getConnection(getUrl(), props);
// Should be ok b/c we've marked the view with IMMUTABLE_ROWS=true
conn7.createStatement().execute("CREATE INDEX idx ON " + MDTEST_NAME + "(B.COL1)");