@Override public boolean evaluate(Tuple tuple, ImmutableBytesWritable ptr) { if (!children.get(0).evaluate(tuple, ptr)) { return false; } String timezone = Bytes.toString(ptr.get(), ptr.getOffset(), ptr.getLength()); if (!children.get(1).evaluate(tuple, ptr)) { return false; } if (!cachedTimeZones.containsKey(timezone)) { TimeZone tz = TimeZone.getTimeZone(timezone); if (!tz.getID().equals(timezone)) { throw new IllegalDataException("Invalid timezone " + timezone); } cachedTimeZones.put(timezone, tz); } Date date = (Date) PDate.INSTANCE.toObject(ptr, children.get(1).getSortOrder()); int offset = cachedTimeZones.get(timezone).getOffset(date.getTime()); ptr.set(PInteger.INSTANCE.toBytes(offset / MILLIS_TO_MINUTES)); return true; }
@Ignore @Test public void testNonTxToTxTableFailure() throws Exception { Connection conn = DriverManager.getConnection(getUrl()); // Put table in SYSTEM schema to prevent attempts to update the cache after we disable // SYSTEM.CATALOG conn.createStatement() .execute("CREATE TABLE SYSTEM.NON_TX_TABLE(k INTEGER PRIMARY KEY, v VARCHAR)"); conn.createStatement().execute("UPSERT INTO SYSTEM.NON_TX_TABLE VALUES (1)"); conn.commit(); // Reset empty column value to an empty value like it is pre-transactions HTableInterface htable = conn.unwrap(PhoenixConnection.class) .getQueryServices() .getTable(Bytes.toBytes("SYSTEM.NON_TX_TABLE")); Put put = new Put(PInteger.INSTANCE.toBytes(1)); put.add( QueryConstants.DEFAULT_COLUMN_FAMILY_BYTES, QueryConstants.EMPTY_COLUMN_BYTES, ByteUtil.EMPTY_BYTE_ARRAY); htable.put(put); HBaseAdmin admin = conn.unwrap(PhoenixConnection.class).getQueryServices().getAdmin(); admin.disableTable(PhoenixDatabaseMetaData.SYSTEM_CATALOG_NAME); try { // This will succeed initially in updating the HBase metadata, but then will fail when // the SYSTEM.CATALOG table is attempted to be updated, exercising the code to restore // the coprocessors back to the non transactional ones. conn.createStatement().execute("ALTER TABLE SYSTEM.NON_TX_TABLE SET TRANSACTIONAL=true"); fail(); } catch (SQLException e) { assertTrue( e.getMessage().contains(PhoenixDatabaseMetaData.SYSTEM_CATALOG_NAME + " is disabled")); } finally { admin.enableTable(PhoenixDatabaseMetaData.SYSTEM_CATALOG_NAME); admin.close(); } ResultSet rs = conn.createStatement().executeQuery("SELECT k FROM SYSTEM.NON_TX_TABLE WHERE v IS NULL"); assertTrue(rs.next()); assertEquals(1, rs.getInt(1)); assertFalse(rs.next()); htable = conn.unwrap(PhoenixConnection.class) .getQueryServices() .getTable(Bytes.toBytes("SYSTEM.NON_TX_TABLE")); assertFalse( htable .getTableDescriptor() .getCoprocessors() .contains(TransactionProcessor.class.getName())); assertEquals( 1, conn.unwrap(PhoenixConnection.class) .getQueryServices() .getTableDescriptor(Bytes.toBytes("SYSTEM.NON_TX_TABLE")) .getFamily(QueryConstants.DEFAULT_COLUMN_FAMILY_BYTES) .getMaxVersions()); }
@Test public void testNonTxToTxTable() throws Exception { Connection conn = DriverManager.getConnection(getUrl()); conn.createStatement().execute("CREATE TABLE NON_TX_TABLE(k INTEGER PRIMARY KEY, v VARCHAR)"); conn.createStatement().execute("UPSERT INTO NON_TX_TABLE VALUES (1)"); conn.createStatement().execute("UPSERT INTO NON_TX_TABLE VALUES (2, 'a')"); conn.createStatement().execute("UPSERT INTO NON_TX_TABLE VALUES (3, 'b')"); conn.commit(); conn.createStatement().execute("CREATE INDEX IDX ON NON_TX_TABLE(v)"); // Reset empty column value to an empty value like it is pre-transactions HTableInterface htable = conn.unwrap(PhoenixConnection.class) .getQueryServices() .getTable(Bytes.toBytes("NON_TX_TABLE")); List<Put> puts = Lists.newArrayList( new Put(PInteger.INSTANCE.toBytes(1)), new Put(PInteger.INSTANCE.toBytes(2)), new Put(PInteger.INSTANCE.toBytes(3))); for (Put put : puts) { put.add( QueryConstants.DEFAULT_COLUMN_FAMILY_BYTES, QueryConstants.EMPTY_COLUMN_BYTES, ByteUtil.EMPTY_BYTE_ARRAY); } htable.put(puts); conn.createStatement().execute("ALTER TABLE NON_TX_TABLE SET TRANSACTIONAL=true"); htable = conn.unwrap(PhoenixConnection.class) .getQueryServices() .getTable(Bytes.toBytes("NON_TX_TABLE")); assertTrue( htable .getTableDescriptor() .getCoprocessors() .contains(TransactionProcessor.class.getName())); htable = conn.unwrap(PhoenixConnection.class).getQueryServices().getTable(Bytes.toBytes("IDX")); assertTrue( htable .getTableDescriptor() .getCoprocessors() .contains(TransactionProcessor.class.getName())); conn.createStatement().execute("UPSERT INTO NON_TX_TABLE VALUES (4, 'c')"); ResultSet rs = conn.createStatement() .executeQuery("SELECT /*+ NO_INDEX */ k FROM NON_TX_TABLE WHERE v IS NULL"); assertTrue( conn.unwrap(PhoenixConnection.class) .getTable(new PTableKey(null, "NON_TX_TABLE")) .isTransactional()); assertTrue(rs.next()); assertEquals(1, rs.getInt(1)); assertFalse(rs.next()); conn.commit(); conn.createStatement().execute("UPSERT INTO NON_TX_TABLE VALUES (5, 'd')"); rs = conn.createStatement().executeQuery("SELECT k FROM NON_TX_TABLE"); assertTrue( conn.unwrap(PhoenixConnection.class) .getTable(new PTableKey(null, "IDX")) .isTransactional()); assertTrue(rs.next()); assertEquals(1, rs.getInt(1)); assertTrue(rs.next()); assertEquals(2, rs.getInt(1)); assertTrue(rs.next()); assertEquals(3, rs.getInt(1)); assertTrue(rs.next()); assertEquals(4, rs.getInt(1)); assertTrue(rs.next()); assertEquals(5, rs.getInt(1)); assertFalse(rs.next()); conn.rollback(); rs = conn.createStatement().executeQuery("SELECT k FROM NON_TX_TABLE"); assertTrue(rs.next()); assertEquals(1, rs.getInt(1)); assertTrue(rs.next()); assertEquals(2, rs.getInt(1)); assertTrue(rs.next()); assertEquals(3, rs.getInt(1)); assertTrue(rs.next()); assertEquals(4, rs.getInt(1)); assertFalse(rs.next()); }