| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package org.apache.phoenix.end2end; |
| |
| import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.SYSTEM_CATALOG_SCHEMA; |
| import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.SYSTEM_CATALOG_TABLE; |
| import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.SYSTEM_FUNCTION_TABLE; |
| import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.TYPE_SEQUENCE; |
| import static org.apache.phoenix.util.TestUtil.ATABLE_NAME; |
| import static org.apache.phoenix.util.TestUtil.ATABLE_SCHEMA_NAME; |
| import static org.apache.phoenix.util.TestUtil.BTABLE_NAME; |
| import static org.apache.phoenix.util.TestUtil.CUSTOM_ENTITY_DATA_FULL_NAME; |
| import static org.apache.phoenix.util.TestUtil.CUSTOM_ENTITY_DATA_NAME; |
| import static org.apache.phoenix.util.TestUtil.CUSTOM_ENTITY_DATA_SCHEMA_NAME; |
| import static org.apache.phoenix.util.TestUtil.GROUPBYTEST_NAME; |
| import static org.apache.phoenix.util.TestUtil.MDTEST_NAME; |
| import static org.apache.phoenix.util.TestUtil.MDTEST_SCHEMA_NAME; |
| import static org.apache.phoenix.util.TestUtil.PTSDB_NAME; |
| import static org.apache.phoenix.util.TestUtil.STABLE_NAME; |
| import static org.apache.phoenix.util.TestUtil.TABLE_WITH_SALTING; |
| import static org.apache.phoenix.util.TestUtil.TEST_PROPERTIES; |
| import static org.apache.phoenix.util.TestUtil.createGroupByTestTable; |
| import static org.junit.Assert.assertEquals; |
| import static org.junit.Assert.assertFalse; |
| import static org.junit.Assert.assertNotEquals; |
| import static org.junit.Assert.assertNotNull; |
| import static org.junit.Assert.assertNull; |
| import static org.junit.Assert.assertTrue; |
| import static org.junit.Assert.fail; |
| |
| import java.sql.Connection; |
| import java.sql.DatabaseMetaData; |
| import java.sql.DriverManager; |
| import java.sql.PreparedStatement; |
| import java.sql.ResultSet; |
| import java.sql.SQLException; |
| import java.util.Map; |
| import java.util.Properties; |
| |
| import org.apache.hadoop.hbase.HColumnDescriptor; |
| import org.apache.hadoop.hbase.HTableDescriptor; |
| import org.apache.hadoop.hbase.client.HBaseAdmin; |
| import org.apache.hadoop.hbase.client.HTableInterface; |
| import org.apache.hadoop.hbase.client.Put; |
| import org.apache.hadoop.hbase.client.Scan; |
| import org.apache.hadoop.hbase.filter.FirstKeyOnlyFilter; |
| import org.apache.hadoop.hbase.io.encoding.DataBlockEncoding; |
| import org.apache.hadoop.hbase.util.Bytes; |
| import org.apache.phoenix.coprocessor.GroupedAggregateRegionObserver; |
| import org.apache.phoenix.coprocessor.ServerCachingEndpointImpl; |
| import org.apache.phoenix.coprocessor.UngroupedAggregateRegionObserver; |
| import org.apache.phoenix.exception.SQLExceptionCode; |
| import org.apache.phoenix.jdbc.PhoenixConnection; |
| import org.apache.phoenix.jdbc.PhoenixDatabaseMetaData; |
| import org.apache.phoenix.query.QueryServices; |
| import org.apache.phoenix.schema.ColumnNotFoundException; |
| import org.apache.phoenix.schema.PTable.ViewType; |
| import org.apache.phoenix.schema.PTableType; |
| import org.apache.phoenix.schema.ReadOnlyTableException; |
| import org.apache.phoenix.schema.TableNotFoundException; |
| import org.apache.phoenix.schema.types.PChar; |
| import org.apache.phoenix.schema.types.PDecimal; |
| import org.apache.phoenix.schema.types.PInteger; |
| import org.apache.phoenix.schema.types.PLong; |
| import org.apache.phoenix.util.PhoenixRuntime; |
| import org.apache.phoenix.util.PropertiesUtil; |
| import org.apache.phoenix.util.ReadOnlyProps; |
| import org.apache.phoenix.util.SchemaUtil; |
| import org.apache.phoenix.util.StringUtil; |
| import org.apache.phoenix.util.TestUtil; |
| import org.junit.BeforeClass; |
| import org.junit.Test; |
| |
| |
| public class QueryDatabaseMetaDataIT extends BaseClientManagedTimeIT { |
| |
| @BeforeClass |
| @Shadower(classBeingShadowed = BaseClientManagedTimeIT.class) |
| public static void doSetup() throws Exception { |
| Map<String,String> props = getDefaultProps(); |
| props.put(QueryServices.DEFAULT_KEEP_DELETED_CELLS_ATTRIB, "true"); |
| setUpTestDriver(new ReadOnlyProps(props.entrySet().iterator())); |
| } |
| |
| @Test |
| public void testTableMetadataScan() throws SQLException { |
| long ts = nextTimestamp(); |
| ensureTableCreated(getUrl(), ATABLE_NAME, ATABLE_NAME, ts); |
| ensureTableCreated(getUrl(), STABLE_NAME, STABLE_NAME, ts); |
| ensureTableCreated(getUrl(), CUSTOM_ENTITY_DATA_FULL_NAME, CUSTOM_ENTITY_DATA_FULL_NAME, ts); |
| |
| Properties props = new Properties(); |
| props.setProperty(PhoenixRuntime.CURRENT_SCN_ATTRIB, Long.toString(ts + 5)); |
| Connection conn = DriverManager.getConnection(getUrl(), props); |
| DatabaseMetaData dbmd = conn.getMetaData(); |
| String aTableName = StringUtil.escapeLike(TestUtil.ATABLE_NAME); |
| String aSchemaName = TestUtil.ATABLE_SCHEMA_NAME; |
| ResultSet rs = dbmd.getTables(null, aSchemaName, aTableName, null); |
| assertTrue(rs.next()); |
| assertEquals(rs.getString("TABLE_NAME"),aTableName); |
| assertEquals(PTableType.TABLE.toString(), rs.getString("TABLE_TYPE")); |
| assertEquals(rs.getString(3),aTableName); |
| assertEquals(PTableType.TABLE.toString(), rs.getString(4)); |
| assertFalse(rs.next()); |
| |
| rs = dbmd.getTables(null, null, null, null); |
| assertTrue(rs.next()); |
| assertEquals(rs.getString("TABLE_SCHEM"),SYSTEM_CATALOG_SCHEMA); |
| assertEquals(rs.getString("TABLE_NAME"),SYSTEM_CATALOG_TABLE); |
| assertEquals(PTableType.SYSTEM.toString(), rs.getString("TABLE_TYPE")); |
| assertTrue(rs.next()); |
| assertEquals(rs.getString("TABLE_SCHEM"),SYSTEM_CATALOG_SCHEMA); |
| assertEquals(rs.getString("TABLE_NAME"),SYSTEM_FUNCTION_TABLE); |
| assertEquals(PTableType.SYSTEM.toString(), rs.getString("TABLE_TYPE")); |
| assertTrue(rs.next()); |
| assertEquals(rs.getString("TABLE_SCHEM"),SYSTEM_CATALOG_SCHEMA); |
| assertEquals(rs.getString("TABLE_NAME"),TYPE_SEQUENCE); |
| assertEquals(PTableType.SYSTEM.toString(), rs.getString("TABLE_TYPE")); |
| assertTrue(rs.next()); |
| assertEquals(rs.getString("TABLE_SCHEM"),SYSTEM_CATALOG_SCHEMA); |
| assertEquals(rs.getString("TABLE_NAME"),PhoenixDatabaseMetaData.SYSTEM_STATS_TABLE); |
| assertEquals(PTableType.SYSTEM.toString(), rs.getString("TABLE_TYPE")); |
| assertTrue(rs.next()); |
| assertEquals(rs.getString("TABLE_SCHEM"),null); |
| assertEquals(rs.getString("TABLE_NAME"),ATABLE_NAME); |
| assertEquals(PTableType.TABLE.toString(), rs.getString("TABLE_TYPE")); |
| assertTrue(rs.next()); |
| assertEquals(rs.getString("TABLE_SCHEM"),null); |
| assertEquals(rs.getString("TABLE_NAME"),STABLE_NAME); |
| assertEquals(PTableType.TABLE.toString(), rs.getString("TABLE_TYPE")); |
| assertTrue(rs.next()); |
| assertEquals(CUSTOM_ENTITY_DATA_SCHEMA_NAME, rs.getString("TABLE_SCHEM")); |
| assertEquals(CUSTOM_ENTITY_DATA_NAME, rs.getString("TABLE_NAME")); |
| assertEquals(PTableType.TABLE.toString(), rs.getString("TABLE_TYPE")); |
| assertEquals("false", rs.getString(PhoenixDatabaseMetaData.TRANSACTIONAL)); |
| assertEquals(Boolean.FALSE, rs.getBoolean(PhoenixDatabaseMetaData.IS_NAMESPACE_MAPPED)); |
| |
| rs = dbmd.getTables(null, CUSTOM_ENTITY_DATA_SCHEMA_NAME, CUSTOM_ENTITY_DATA_NAME, null); |
| assertTrue(rs.next()); |
| try { |
| rs.getString("RANDOM_COLUMN_NAME"); |
| fail(); |
| } catch (ColumnNotFoundException e) { |
| // expected |
| } |
| assertEquals(rs.getString("TABLE_SCHEM"),CUSTOM_ENTITY_DATA_SCHEMA_NAME); |
| assertEquals(rs.getString("TABLE_NAME"),CUSTOM_ENTITY_DATA_NAME); |
| assertEquals(PTableType.TABLE.toString(), rs.getString("TABLE_TYPE")); |
| assertFalse(rs.next()); |
| |
| rs = dbmd.getTables(null, "", "_TABLE", new String[] {PTableType.TABLE.toString()}); |
| assertTrue(rs.next()); |
| assertEquals(rs.getString("TABLE_SCHEM"),null); |
| assertEquals(rs.getString("TABLE_NAME"),ATABLE_NAME); |
| assertEquals(PTableType.TABLE.toString(), rs.getString("TABLE_TYPE")); |
| assertTrue(rs.next()); |
| assertEquals(rs.getString("TABLE_SCHEM"),null); |
| assertEquals(rs.getString("TABLE_NAME"),STABLE_NAME); |
| assertEquals(PTableType.TABLE.toString(), rs.getString("TABLE_TYPE")); |
| assertFalse(rs.next()); |
| } |
| |
| @Test |
| public void testTableTypes() throws SQLException { |
| long ts = nextTimestamp(); |
| Properties props = new Properties(); |
| props.setProperty(PhoenixRuntime.CURRENT_SCN_ATTRIB, Long.toString(ts + 10)); |
| Connection conn = DriverManager.getConnection(getUrl(), props); |
| DatabaseMetaData dbmd = conn.getMetaData(); |
| ResultSet rs = dbmd.getTableTypes(); |
| assertTrue(rs.next()); |
| assertEquals("INDEX",rs.getString(1)); |
| assertTrue(rs.next()); |
| assertEquals("SEQUENCE",rs.getString(1)); |
| assertTrue(rs.next()); |
| assertEquals("SYSTEM TABLE",rs.getString(1)); |
| assertTrue(rs.next()); |
| assertEquals("TABLE",rs.getString(1)); |
| assertTrue(rs.next()); |
| assertEquals("VIEW",rs.getString(1)); |
| assertFalse(rs.next()); |
| } |
| |
| @Test |
| public void testSequenceMetadataScan() throws SQLException { |
| long ts = nextTimestamp(); |
| Properties props = new Properties(); |
| props.setProperty(PhoenixRuntime.CURRENT_SCN_ATTRIB, Long.toString(ts + 10)); |
| Connection conn = DriverManager.getConnection(getUrl(), props); |
| conn.createStatement().execute("CREATE SEQUENCE b.s1"); |
| conn.createStatement().execute("CREATE SEQUENCE a.s2"); |
| conn.createStatement().execute("CREATE SEQUENCE b.s3"); |
| conn.createStatement().execute("CREATE SEQUENCE c.s1"); |
| |
| props.setProperty(PhoenixRuntime.CURRENT_SCN_ATTRIB, Long.toString(ts + 20)); |
| conn = DriverManager.getConnection(getUrl(), props); |
| DatabaseMetaData dbmd = conn.getMetaData(); |
| ResultSet rs = dbmd.getTables(null, null, null, new String[] {"FOO"}); |
| assertFalse(rs.next()); |
| |
| rs = dbmd.getTables(null, null, null, new String[] {"FOO",PhoenixDatabaseMetaData.SEQUENCE_TABLE_TYPE}); |
| assertTrue(rs.next()); |
| assertNull(rs.getString("TABLE_CAT")); |
| assertEquals("A", rs.getString("TABLE_SCHEM")); |
| assertEquals("S2", rs.getString("TABLE_NAME")); |
| assertTrue(rs.next()); |
| assertNull(rs.getString("TABLE_CAT")); |
| assertEquals("B", rs.getString("TABLE_SCHEM")); |
| assertEquals("S1", rs.getString("TABLE_NAME")); |
| assertTrue(rs.next()); |
| assertNull(rs.getString("TABLE_CAT")); |
| assertEquals("B", rs.getString("TABLE_SCHEM")); |
| assertEquals("S3", rs.getString("TABLE_NAME")); |
| assertTrue(rs.next()); |
| assertNull(rs.getString("TABLE_CAT")); |
| assertEquals("C", rs.getString("TABLE_SCHEM")); |
| assertEquals("S1", rs.getString("TABLE_NAME")); |
| assertFalse(rs.next()); |
| |
| conn.createStatement().execute("CREATE TABLE foo (k bigint primary key)"); |
| conn.createStatement().execute("CREATE TABLE z.bas (k bigint primary key)"); |
| |
| props.setProperty(PhoenixRuntime.CURRENT_SCN_ATTRIB, Long.toString(ts + 30)); |
| conn = DriverManager.getConnection(getUrl(), props); |
| dbmd = conn.getMetaData(); |
| rs = dbmd.getTables(null, null, null, new String[] {PTableType.TABLE.toString(),PhoenixDatabaseMetaData.SEQUENCE_TABLE_TYPE}); |
| assertTrue(rs.next()); |
| assertNull(rs.getString("TABLE_CAT")); |
| assertEquals("A", rs.getString("TABLE_SCHEM")); |
| assertEquals("S2", rs.getString("TABLE_NAME")); |
| assertEquals(PhoenixDatabaseMetaData.SEQUENCE_TABLE_TYPE, rs.getString("TABLE_TYPE")); |
| assertTrue(rs.next()); |
| assertNull(rs.getString("TABLE_CAT")); |
| assertEquals("B", rs.getString("TABLE_SCHEM")); |
| assertEquals("S1", rs.getString("TABLE_NAME")); |
| assertEquals(PhoenixDatabaseMetaData.SEQUENCE_TABLE_TYPE, rs.getString("TABLE_TYPE")); |
| assertTrue(rs.next()); |
| assertNull(rs.getString("TABLE_CAT")); |
| assertEquals("B", rs.getString("TABLE_SCHEM")); |
| assertEquals("S3", rs.getString("TABLE_NAME")); |
| assertEquals(PhoenixDatabaseMetaData.SEQUENCE_TABLE_TYPE, rs.getString("TABLE_TYPE")); |
| assertTrue(rs.next()); |
| assertNull(rs.getString("TABLE_CAT")); |
| assertEquals("C", rs.getString("TABLE_SCHEM")); |
| assertEquals("S1", rs.getString("TABLE_NAME")); |
| assertEquals(PhoenixDatabaseMetaData.SEQUENCE_TABLE_TYPE, rs.getString("TABLE_TYPE")); |
| assertTrue(rs.next()); |
| assertNull(rs.getString("TABLE_CAT")); |
| assertNull(rs.getString("TABLE_SCHEM")); |
| assertEquals("FOO", rs.getString("TABLE_NAME")); |
| assertEquals(PTableType.TABLE.toString(), rs.getString("TABLE_TYPE")); |
| assertTrue(rs.next()); |
| assertNull(rs.getString("TABLE_CAT")); |
| assertEquals("Z", rs.getString("TABLE_SCHEM")); |
| assertEquals("BAS", rs.getString("TABLE_NAME")); |
| assertEquals(PTableType.TABLE.toString(), rs.getString("TABLE_TYPE")); |
| assertFalse(rs.next()); |
| } |
| |
| @Test |
| public void testSchemaMetadataScan() throws SQLException { |
| long ts = nextTimestamp(); |
| ensureTableCreated(getUrl(), CUSTOM_ENTITY_DATA_FULL_NAME, CUSTOM_ENTITY_DATA_FULL_NAME, ts); |
| ensureTableCreated(getUrl(), PTSDB_NAME, PTSDB_NAME, ts); |
| Properties props = new Properties(); |
| props.setProperty(PhoenixRuntime.CURRENT_SCN_ATTRIB, Long.toString(ts + 5)); |
| Connection conn = DriverManager.getConnection(getUrl(), props); |
| DatabaseMetaData dbmd = conn.getMetaData(); |
| ResultSet rs; |
| rs = dbmd.getSchemas(null, CUSTOM_ENTITY_DATA_SCHEMA_NAME); |
| assertTrue(rs.next()); |
| assertEquals(rs.getString(1),CUSTOM_ENTITY_DATA_SCHEMA_NAME); |
| assertEquals(rs.getString(2),null); |
| assertFalse(rs.next()); |
| |
| rs = dbmd.getSchemas(null, null); |
| assertTrue(rs.next()); |
| assertEquals(rs.getString("TABLE_SCHEM"),null); |
| assertEquals(rs.getString("TABLE_CATALOG"),null); |
| assertTrue(rs.next()); |
| assertEquals(rs.getString("TABLE_SCHEM"),CUSTOM_ENTITY_DATA_SCHEMA_NAME); |
| assertEquals(rs.getString("TABLE_CATALOG"),null); |
| assertTrue(rs.next()); |
| assertEquals(rs.getString("TABLE_SCHEM"),PhoenixDatabaseMetaData.SYSTEM_CATALOG_SCHEMA); |
| assertEquals(rs.getString("TABLE_CATALOG"),null); |
| assertFalse(rs.next()); |
| } |
| |
| @Test |
| public void testColumnMetadataScan() throws SQLException { |
| long ts = nextTimestamp(); |
| ensureTableCreated(getUrl(), MDTEST_NAME, MDTEST_NAME, ts); |
| Properties props = new Properties(); |
| props.setProperty(PhoenixRuntime.CURRENT_SCN_ATTRIB, Long.toString(ts + 5)); |
| Connection conn = DriverManager.getConnection(getUrl(), props); |
| DatabaseMetaData dbmd = conn.getMetaData(); |
| ResultSet rs; |
| rs = dbmd.getColumns(null, "", MDTEST_NAME, null); |
| assertTrue(rs.next()); |
| |
| assertEquals(rs.getString("TABLE_SCHEM"),null); |
| assertEquals(MDTEST_NAME, rs.getString("TABLE_NAME")); |
| assertEquals(null, rs.getString("TABLE_CAT")); |
| assertEquals(SchemaUtil.normalizeIdentifier("id"), rs.getString("COLUMN_NAME")); |
| assertEquals(DatabaseMetaData.attributeNoNulls, rs.getShort("NULLABLE")); |
| assertEquals(PChar.INSTANCE.getSqlType(), rs.getInt("DATA_TYPE")); |
| assertEquals(1, rs.getInt("ORDINAL_POSITION")); |
| assertEquals(1, rs.getInt("COLUMN_SIZE")); |
| assertEquals(0, rs.getInt("DECIMAL_DIGITS")); |
| |
| assertTrue(rs.next()); |
| assertEquals(rs.getString("TABLE_SCHEM"),null); |
| assertEquals(MDTEST_NAME, rs.getString("TABLE_NAME")); |
| assertEquals(SchemaUtil.normalizeIdentifier("a"), rs.getString("COLUMN_FAMILY")); |
| assertEquals(SchemaUtil.normalizeIdentifier("col1"), rs.getString("COLUMN_NAME")); |
| assertEquals(DatabaseMetaData.attributeNullable, rs.getShort("NULLABLE")); |
| assertEquals(PInteger.INSTANCE.getSqlType(), rs.getInt("DATA_TYPE")); |
| assertEquals(2, rs.getInt("ORDINAL_POSITION")); |
| assertEquals(0, rs.getInt("COLUMN_SIZE")); |
| assertTrue(rs.wasNull()); |
| assertEquals(0, rs.getInt("DECIMAL_DIGITS")); |
| assertTrue(rs.wasNull()); |
| |
| assertTrue(rs.next()); |
| assertEquals(rs.getString("TABLE_SCHEM"),null); |
| assertEquals(MDTEST_NAME, rs.getString("TABLE_NAME")); |
| assertEquals(SchemaUtil.normalizeIdentifier("b"), rs.getString("COLUMN_FAMILY")); |
| assertEquals(SchemaUtil.normalizeIdentifier("col2"), rs.getString("COLUMN_NAME")); |
| assertEquals(DatabaseMetaData.attributeNullable, rs.getShort("NULLABLE")); |
| assertEquals(PLong.INSTANCE.getSqlType(), rs.getInt("DATA_TYPE")); |
| assertEquals(3, rs.getInt("ORDINAL_POSITION")); |
| assertEquals(0, rs.getInt("COLUMN_SIZE")); |
| assertTrue(rs.wasNull()); |
| assertEquals(0, rs.getInt("DECIMAL_DIGITS")); |
| assertTrue(rs.wasNull()); |
| |
| assertTrue(rs.next()); |
| assertEquals(rs.getString("TABLE_SCHEM"),null); |
| assertEquals(MDTEST_NAME, rs.getString("TABLE_NAME")); |
| assertEquals(SchemaUtil.normalizeIdentifier("b"), rs.getString("COLUMN_FAMILY")); |
| assertEquals(SchemaUtil.normalizeIdentifier("col3"), rs.getString("COLUMN_NAME")); |
| assertEquals(DatabaseMetaData.attributeNullable, rs.getShort("NULLABLE")); |
| assertEquals(PDecimal.INSTANCE.getSqlType(), rs.getInt("DATA_TYPE")); |
| assertEquals(4, rs.getInt("ORDINAL_POSITION")); |
| assertEquals(0, rs.getInt("COLUMN_SIZE")); |
| assertTrue(rs.wasNull()); |
| assertEquals(0, rs.getInt("DECIMAL_DIGITS")); |
| assertTrue(rs.wasNull()); |
| |
| assertTrue(rs.next()); |
| assertEquals(rs.getString("TABLE_SCHEM"),null); |
| assertEquals(MDTEST_NAME, rs.getString("TABLE_NAME")); |
| assertEquals(SchemaUtil.normalizeIdentifier("b"), rs.getString("COLUMN_FAMILY")); |
| assertEquals(SchemaUtil.normalizeIdentifier("col4"), rs.getString("COLUMN_NAME")); |
| assertEquals(DatabaseMetaData.attributeNullable, rs.getShort("NULLABLE")); |
| assertEquals(PDecimal.INSTANCE.getSqlType(), rs.getInt("DATA_TYPE")); |
| assertEquals(5, rs.getInt("ORDINAL_POSITION")); |
| assertEquals(5, rs.getInt("COLUMN_SIZE")); |
| assertEquals(0, rs.getInt("DECIMAL_DIGITS")); |
| |
| assertTrue(rs.next()); |
| assertEquals(rs.getString("TABLE_SCHEM"),null); |
| assertEquals(MDTEST_NAME, rs.getString("TABLE_NAME")); |
| assertEquals(SchemaUtil.normalizeIdentifier("b"), rs.getString("COLUMN_FAMILY")); |
| assertEquals(SchemaUtil.normalizeIdentifier("col5"), rs.getString("COLUMN_NAME")); |
| assertEquals(DatabaseMetaData.attributeNullable, rs.getShort("NULLABLE")); |
| assertEquals(PDecimal.INSTANCE.getSqlType(), rs.getInt("DATA_TYPE")); |
| assertEquals(6, rs.getInt("ORDINAL_POSITION")); |
| assertEquals(6, rs.getInt("COLUMN_SIZE")); |
| assertEquals(3, rs.getInt("DECIMAL_DIGITS")); |
| |
| assertFalse(rs.next()); |
| |
| // Look up only columns in a column family |
| rs = dbmd.getColumns(null, "", MDTEST_NAME, "A."); |
| assertTrue(rs.next()); |
| assertEquals(rs.getString("TABLE_SCHEM"),null); |
| assertEquals(MDTEST_NAME, rs.getString("TABLE_NAME")); |
| assertEquals(SchemaUtil.normalizeIdentifier("a"), rs.getString("COLUMN_FAMILY")); |
| assertEquals(SchemaUtil.normalizeIdentifier("col1"), rs.getString("COLUMN_NAME")); |
| assertEquals(DatabaseMetaData.attributeNullable, rs.getShort("NULLABLE")); |
| assertEquals(PInteger.INSTANCE.getSqlType(), rs.getInt("DATA_TYPE")); |
| assertEquals(2, rs.getInt("ORDINAL_POSITION")); |
| assertEquals(0, rs.getInt("COLUMN_SIZE")); |
| assertTrue(rs.wasNull()); |
| assertEquals(0, rs.getInt("DECIMAL_DIGITS")); |
| assertTrue(rs.wasNull()); |
| |
| assertFalse(rs.next()); |
| |
| // Look up KV columns in a column family |
| rs = dbmd.getColumns("", "", MDTEST_NAME, "%.COL%"); |
| assertTrue(rs.next()); |
| assertEquals(rs.getString("TABLE_SCHEM"),null); |
| assertEquals(MDTEST_NAME, rs.getString("TABLE_NAME")); |
| assertEquals(SchemaUtil.normalizeIdentifier("a"), rs.getString("COLUMN_FAMILY")); |
| assertEquals(SchemaUtil.normalizeIdentifier("col1"), rs.getString("COLUMN_NAME")); |
| assertEquals(DatabaseMetaData.attributeNullable, rs.getShort("NULLABLE")); |
| assertEquals(PInteger.INSTANCE.getSqlType(), rs.getInt("DATA_TYPE")); |
| assertEquals(2, rs.getInt("ORDINAL_POSITION")); |
| assertEquals(0, rs.getInt("COLUMN_SIZE")); |
| assertTrue(rs.wasNull()); |
| assertEquals(0, rs.getInt("DECIMAL_DIGITS")); |
| assertTrue(rs.wasNull()); |
| |
| assertTrue(rs.next()); |
| assertEquals(rs.getString("TABLE_SCHEM"),null); |
| assertEquals(MDTEST_NAME, rs.getString("TABLE_NAME")); |
| assertEquals(SchemaUtil.normalizeIdentifier("b"), rs.getString("COLUMN_FAMILY")); |
| assertEquals(SchemaUtil.normalizeIdentifier("col2"), rs.getString("COLUMN_NAME")); |
| assertEquals(DatabaseMetaData.attributeNullable, rs.getShort("NULLABLE")); |
| assertEquals(PLong.INSTANCE.getSqlType(), rs.getInt("DATA_TYPE")); |
| assertEquals(3, rs.getInt("ORDINAL_POSITION")); |
| assertEquals(0, rs.getInt("COLUMN_SIZE")); |
| assertTrue(rs.wasNull()); |
| assertEquals(0, rs.getInt("DECIMAL_DIGITS")); |
| assertTrue(rs.wasNull()); |
| |
| assertTrue(rs.next()); |
| assertEquals(rs.getString("TABLE_SCHEM"),null); |
| assertEquals(MDTEST_NAME, rs.getString("TABLE_NAME")); |
| assertEquals(SchemaUtil.normalizeIdentifier("b"), rs.getString("COLUMN_FAMILY")); |
| assertEquals(SchemaUtil.normalizeIdentifier("col3"), rs.getString("COLUMN_NAME")); |
| assertEquals(DatabaseMetaData.attributeNullable, rs.getShort("NULLABLE")); |
| assertEquals(PDecimal.INSTANCE.getSqlType(), rs.getInt("DATA_TYPE")); |
| assertEquals(4, rs.getInt("ORDINAL_POSITION")); |
| assertEquals(0, rs.getInt("COLUMN_SIZE")); |
| assertTrue(rs.wasNull()); |
| assertEquals(0, rs.getInt("DECIMAL_DIGITS")); |
| assertTrue(rs.wasNull()); |
| |
| assertTrue(rs.next()); |
| assertEquals(rs.getString("TABLE_SCHEM"),null); |
| assertEquals(MDTEST_NAME, rs.getString("TABLE_NAME")); |
| assertEquals(SchemaUtil.normalizeIdentifier("b"), rs.getString("COLUMN_FAMILY")); |
| assertEquals(SchemaUtil.normalizeIdentifier("col4"), rs.getString("COLUMN_NAME")); |
| assertEquals(DatabaseMetaData.attributeNullable, rs.getShort("NULLABLE")); |
| assertEquals(PDecimal.INSTANCE.getSqlType(), rs.getInt("DATA_TYPE")); |
| assertEquals(5, rs.getInt("ORDINAL_POSITION")); |
| assertEquals(5, rs.getInt("COLUMN_SIZE")); |
| assertEquals(0, rs.getInt("DECIMAL_DIGITS")); |
| assertFalse(rs.wasNull()); |
| |
| assertTrue(rs.next()); |
| assertEquals(rs.getString("TABLE_SCHEM"),null); |
| assertEquals(MDTEST_NAME, rs.getString("TABLE_NAME")); |
| assertEquals(SchemaUtil.normalizeIdentifier("b"), rs.getString("COLUMN_FAMILY")); |
| assertEquals(SchemaUtil.normalizeIdentifier("col5"), rs.getString("COLUMN_NAME")); |
| assertEquals(DatabaseMetaData.attributeNullable, rs.getShort("NULLABLE")); |
| assertEquals(PDecimal.INSTANCE.getSqlType(), rs.getInt("DATA_TYPE")); |
| assertEquals(6, rs.getInt("ORDINAL_POSITION")); |
| assertEquals(6, rs.getInt("COLUMN_SIZE")); |
| assertEquals(3, rs.getInt("DECIMAL_DIGITS")); |
| |
| assertFalse(rs.next()); |
| |
| // Look up KV columns in a column family |
| rs = dbmd.getColumns("", "", MDTEST_NAME, "B.COL2"); |
| assertTrue(rs.next()); |
| assertEquals(rs.getString("TABLE_SCHEM"),null); |
| assertEquals(MDTEST_NAME, rs.getString("TABLE_NAME")); |
| assertEquals(SchemaUtil.normalizeIdentifier("b"), rs.getString("COLUMN_FAMILY")); |
| assertEquals(SchemaUtil.normalizeIdentifier("col2"), rs.getString("COLUMN_NAME")); |
| assertFalse(rs.next()); |
| |
| ensureTableCreated(getUrl(), TABLE_WITH_SALTING, TABLE_WITH_SALTING, ts); |
| rs = dbmd.getColumns("", "", TABLE_WITH_SALTING, StringUtil.escapeLike("A_INTEGER")); |
| assertTrue(rs.next()); |
| assertEquals(1, rs.getInt("ORDINAL_POSITION")); |
| assertFalse(rs.next()); |
| |
| } |
| |
| @Test |
| public void testPrimaryKeyMetadataScan() throws SQLException { |
| long ts = nextTimestamp(); |
| ensureTableCreated(getUrl(), MDTEST_NAME, MDTEST_NAME, ts); |
| ensureTableCreated(getUrl(), CUSTOM_ENTITY_DATA_FULL_NAME, CUSTOM_ENTITY_DATA_FULL_NAME, ts); |
| Properties props = new Properties(); |
| props.setProperty(PhoenixRuntime.CURRENT_SCN_ATTRIB, Long.toString(ts + 5)); |
| Connection conn = DriverManager.getConnection(getUrl(), props); |
| DatabaseMetaData dbmd = conn.getMetaData(); |
| ResultSet rs; |
| rs = dbmd.getPrimaryKeys(null, "", MDTEST_NAME); |
| assertTrue(rs.next()); |
| assertEquals(rs.getString("TABLE_SCHEM"),null); |
| assertEquals(MDTEST_NAME, rs.getString("TABLE_NAME")); |
| assertEquals(null, rs.getString("TABLE_CAT")); |
| assertEquals(SchemaUtil.normalizeIdentifier("id"), rs.getString("COLUMN_NAME")); |
| assertEquals(1, rs.getInt("KEY_SEQ")); |
| assertEquals(null, rs.getString("PK_NAME")); |
| assertFalse(rs.next()); |
| |
| rs = dbmd.getPrimaryKeys(null, CUSTOM_ENTITY_DATA_SCHEMA_NAME, CUSTOM_ENTITY_DATA_NAME); |
| assertTrue(rs.next()); |
| assertEquals(CUSTOM_ENTITY_DATA_SCHEMA_NAME, rs.getString("TABLE_SCHEM")); |
| assertEquals(CUSTOM_ENTITY_DATA_NAME, rs.getString("TABLE_NAME")); |
| assertEquals(null, rs.getString("TABLE_CAT")); |
| assertEquals(SchemaUtil.normalizeIdentifier("custom_entity_data_id"), rs.getString("COLUMN_NAME")); |
| assertEquals(3, rs.getInt("KEY_SEQ")); |
| assertEquals(SchemaUtil.normalizeIdentifier("pk"), rs.getString("PK_NAME")); |
| |
| assertTrue(rs.next()); |
| assertEquals(CUSTOM_ENTITY_DATA_SCHEMA_NAME, rs.getString("TABLE_SCHEM")); |
| assertEquals(CUSTOM_ENTITY_DATA_NAME, rs.getString("TABLE_NAME")); |
| assertEquals(null, rs.getString("TABLE_CAT")); |
| assertEquals(SchemaUtil.normalizeIdentifier("key_prefix"), rs.getString("COLUMN_NAME")); |
| assertEquals(2, rs.getInt("KEY_SEQ")); |
| assertEquals(SchemaUtil.normalizeIdentifier("pk"), rs.getString("PK_NAME")); |
| |
| assertTrue(rs.next()); |
| assertEquals(CUSTOM_ENTITY_DATA_SCHEMA_NAME, rs.getString("TABLE_SCHEM")); |
| assertEquals(CUSTOM_ENTITY_DATA_NAME, rs.getString("TABLE_NAME")); |
| assertEquals(null, rs.getString("TABLE_CAT")); |
| assertEquals(SchemaUtil.normalizeIdentifier("organization_id"), rs.getString("COLUMN_NAME")); |
| assertEquals(1, rs.getInt("KEY_SEQ")); |
| assertEquals(SchemaUtil.normalizeIdentifier("pk"), rs.getString("PK_NAME")); // TODO: this is on the table row |
| |
| assertFalse(rs.next()); |
| |
| rs = dbmd.getColumns("", CUSTOM_ENTITY_DATA_SCHEMA_NAME, CUSTOM_ENTITY_DATA_NAME, null); |
| assertTrue(rs.next()); |
| assertEquals(CUSTOM_ENTITY_DATA_SCHEMA_NAME, rs.getString("TABLE_SCHEM")); |
| assertEquals(CUSTOM_ENTITY_DATA_NAME, rs.getString("TABLE_NAME")); |
| assertEquals(null, rs.getString("TABLE_CAT")); |
| assertEquals(SchemaUtil.normalizeIdentifier("organization_id"), rs.getString("COLUMN_NAME")); |
| assertEquals(rs.getInt("COLUMN_SIZE"), 15); |
| |
| assertTrue(rs.next()); |
| assertEquals(CUSTOM_ENTITY_DATA_SCHEMA_NAME, rs.getString("TABLE_SCHEM")); |
| assertEquals(CUSTOM_ENTITY_DATA_NAME, rs.getString("TABLE_NAME")); |
| assertEquals(null, rs.getString("TABLE_CAT")); |
| assertEquals(SchemaUtil.normalizeIdentifier("key_prefix"), rs.getString("COLUMN_NAME")); |
| assertEquals(rs.getInt("COLUMN_SIZE"), 3); |
| |
| assertTrue(rs.next()); |
| assertEquals(CUSTOM_ENTITY_DATA_SCHEMA_NAME, rs.getString("TABLE_SCHEM")); |
| assertEquals(CUSTOM_ENTITY_DATA_NAME, rs.getString("TABLE_NAME")); |
| assertEquals(null, rs.getString("TABLE_CAT")); |
| assertEquals(SchemaUtil.normalizeIdentifier("custom_entity_data_id"), rs.getString("COLUMN_NAME")); |
| |
| // The above returns all columns, starting with the PK columns |
| assertTrue(rs.next()); |
| |
| rs = dbmd.getColumns("", CUSTOM_ENTITY_DATA_SCHEMA_NAME, CUSTOM_ENTITY_DATA_NAME, "KEY_PREFIX"); |
| assertTrue(rs.next()); |
| assertEquals(CUSTOM_ENTITY_DATA_SCHEMA_NAME, rs.getString("TABLE_SCHEM")); |
| assertEquals(CUSTOM_ENTITY_DATA_NAME, rs.getString("TABLE_NAME")); |
| assertEquals(null, rs.getString("TABLE_CAT")); |
| assertEquals(SchemaUtil.normalizeIdentifier("key_prefix"), rs.getString("COLUMN_NAME")); |
| |
| rs = dbmd.getColumns("", CUSTOM_ENTITY_DATA_SCHEMA_NAME, CUSTOM_ENTITY_DATA_NAME, "KEY_PREFIX"); |
| assertTrue(rs.next()); |
| assertEquals(CUSTOM_ENTITY_DATA_SCHEMA_NAME, rs.getString("TABLE_SCHEM")); |
| assertEquals(CUSTOM_ENTITY_DATA_NAME, rs.getString("TABLE_NAME")); |
| assertEquals(null, rs.getString("TABLE_CAT")); |
| assertEquals(SchemaUtil.normalizeIdentifier("key_prefix"), rs.getString("COLUMN_NAME")); |
| |
| assertFalse(rs.next()); |
| |
| conn.createStatement().execute("CREATE TABLE SALTEDTABLE123 (k INTEGER PRIMARY KEY, v VARCHAR) SALT_BUCKETS=3"); |
| conn.close(); |
| props.setProperty(PhoenixRuntime.CURRENT_SCN_ATTRIB, Long.toString(ts + 10)); |
| conn = DriverManager.getConnection(getUrl(), props); |
| dbmd = conn.getMetaData(); |
| rs = dbmd.getPrimaryKeys(null, "", "SALTEDTABLE123"); |
| assertTrue(rs.next()); |
| assertEquals(null, rs.getString("TABLE_SCHEM")); |
| assertEquals("SALTEDTABLE123", rs.getString("TABLE_NAME")); |
| assertEquals(null, rs.getString("TABLE_CAT")); |
| assertEquals("K", rs.getString("COLUMN_NAME")); |
| assertEquals(1, rs.getInt("KEY_SEQ")); |
| assertEquals(null, rs.getString("PK_NAME")); |
| assertFalse(rs.next()); |
| } |
| |
| @Test |
| public void testMultiTableColumnsMetadataScan() throws SQLException { |
| long ts = nextTimestamp(); |
| Properties props = new Properties(); |
| props.setProperty(PhoenixRuntime.CURRENT_SCN_ATTRIB, Long.toString(ts)); |
| Connection conn = DriverManager.getConnection(getUrl(), props); |
| createGroupByTestTable(conn, GROUPBYTEST_NAME); |
| ensureTableCreated(getUrl(), MDTEST_NAME, MDTEST_NAME, ts); |
| ensureTableCreated(getUrl(), PTSDB_NAME, PTSDB_NAME, ts); |
| ensureTableCreated(getUrl(), CUSTOM_ENTITY_DATA_FULL_NAME, CUSTOM_ENTITY_DATA_FULL_NAME, ts); |
| props.setProperty(PhoenixRuntime.CURRENT_SCN_ATTRIB, Long.toString(ts + 5)); |
| conn = DriverManager.getConnection(getUrl(), props); |
| DatabaseMetaData dbmd = conn.getMetaData(); |
| ResultSet rs = dbmd.getColumns(null, "", "%TEST%", null); |
| assertTrue(rs.next()); |
| assertEquals(rs.getString("TABLE_SCHEM"),null); |
| assertEquals(rs.getString("TABLE_NAME"),GROUPBYTEST_NAME); |
| assertEquals(null, rs.getString("COLUMN_FAMILY")); |
| assertEquals(SchemaUtil.normalizeIdentifier("id"), rs.getString("COLUMN_NAME")); |
| assertTrue(rs.next()); |
| assertEquals(rs.getString("TABLE_SCHEM"),null); |
| assertEquals(rs.getString("TABLE_NAME"),GROUPBYTEST_NAME); |
| assertEquals(PhoenixDatabaseMetaData.TABLE_FAMILY, rs.getString("COLUMN_FAMILY")); |
| assertEquals(SchemaUtil.normalizeIdentifier("uri"), rs.getString("COLUMN_NAME")); |
| assertTrue(rs.next()); |
| assertEquals(rs.getString("TABLE_SCHEM"),null); |
| assertEquals(rs.getString("TABLE_NAME"),GROUPBYTEST_NAME); |
| assertEquals(PhoenixDatabaseMetaData.TABLE_FAMILY, rs.getString("COLUMN_FAMILY")); |
| assertEquals(SchemaUtil.normalizeIdentifier("appcpu"), rs.getString("COLUMN_NAME")); |
| assertTrue(rs.next()); |
| assertEquals(rs.getString("TABLE_SCHEM"),null); |
| assertEquals(rs.getString("TABLE_NAME"),MDTEST_NAME); |
| assertEquals(null, rs.getString("COLUMN_FAMILY")); |
| assertEquals(SchemaUtil.normalizeIdentifier("id"), rs.getString("COLUMN_NAME")); |
| assertTrue(rs.next()); |
| assertEquals(rs.getString("TABLE_SCHEM"),null); |
| assertEquals(rs.getString("TABLE_NAME"),MDTEST_NAME); |
| assertEquals(SchemaUtil.normalizeIdentifier("a"), rs.getString("COLUMN_FAMILY")); |
| assertEquals(SchemaUtil.normalizeIdentifier("col1"), rs.getString("COLUMN_NAME")); |
| assertTrue(rs.next()); |
| assertEquals(rs.getString("TABLE_SCHEM"),null); |
| assertEquals(rs.getString("TABLE_NAME"),MDTEST_NAME); |
| assertEquals(SchemaUtil.normalizeIdentifier("b"), rs.getString("COLUMN_FAMILY")); |
| assertEquals(SchemaUtil.normalizeIdentifier("col2"), rs.getString("COLUMN_NAME")); |
| assertTrue(rs.next()); |
| assertEquals(rs.getString("TABLE_SCHEM"),null); |
| assertEquals(rs.getString("TABLE_NAME"),MDTEST_NAME); |
| assertEquals(SchemaUtil.normalizeIdentifier("b"), rs.getString("COLUMN_FAMILY")); |
| assertEquals(SchemaUtil.normalizeIdentifier("col3"), rs.getString("COLUMN_NAME")); |
| assertTrue(rs.next()); |
| assertEquals(rs.getString("TABLE_SCHEM"),null); |
| assertEquals(rs.getString("TABLE_NAME"),MDTEST_NAME); |
| assertEquals(SchemaUtil.normalizeIdentifier("b"), rs.getString("COLUMN_FAMILY")); |
| assertEquals(SchemaUtil.normalizeIdentifier("col4"), rs.getString("COLUMN_NAME")); |
| assertTrue(rs.next()); |
| assertEquals(rs.getString("TABLE_SCHEM"),null); |
| assertEquals(rs.getString("TABLE_NAME"),MDTEST_NAME); |
| assertEquals(SchemaUtil.normalizeIdentifier("b"), rs.getString("COLUMN_FAMILY")); |
| assertEquals(SchemaUtil.normalizeIdentifier("col5"), rs.getString("COLUMN_NAME")); |
| assertFalse(rs.next()); |
| } |
| |
| @Test |
| public void testCreateDropTable() throws Exception { |
| long ts = nextTimestamp(); |
| String tenantId = getOrganizationId(); |
| initATableValues(ATABLE_NAME, tenantId, getDefaultSplits(tenantId), null, ts, getUrl(), null); |
| |
| ensureTableCreated(getUrl(), BTABLE_NAME, BTABLE_NAME, ts-2); |
| ensureTableCreated(getUrl(), PTSDB_NAME, PTSDB_NAME, ts-2); |
| |
| Properties props = new Properties(); |
| props.setProperty(PhoenixRuntime.CURRENT_SCN_ATTRIB, Long.toString(ts + 5)); |
| Connection conn5 = DriverManager.getConnection(getUrl(), props); |
| String query = "SELECT a_string FROM aTable"; |
| // Data should still be there b/c we only dropped the schema |
| props.setProperty(PhoenixRuntime.CURRENT_SCN_ATTRIB, Long.toString(ts + 8)); |
| assertTrue(conn5.prepareStatement(query).executeQuery().next()); |
| conn5.createStatement().executeUpdate("DROP TABLE " + ATABLE_NAME); |
| |
| // Confirm that data is no longer there because we dropped the table |
| // This needs to be done natively b/c the metadata is gone |
| HTableInterface htable = conn5.unwrap(PhoenixConnection.class).getQueryServices().getTable(SchemaUtil.getTableNameAsBytes(ATABLE_SCHEMA_NAME, ATABLE_NAME)); |
| Scan scan = new Scan(); |
| scan.setFilter(new FirstKeyOnlyFilter()); |
| scan.setTimeRange(0, ts+9); |
| assertNull(htable.getScanner(scan).next()); |
| conn5.close(); |
| |
| // Still should work b/c we're at an earlier timestamp than when table was deleted |
| props.setProperty(PhoenixRuntime.CURRENT_SCN_ATTRIB, Long.toString(ts + 2)); |
| Connection conn2 = DriverManager.getConnection(getUrl(), props); |
| assertTrue(conn2.prepareStatement(query).executeQuery().next()); |
| conn2.close(); |
| |
| props.setProperty(PhoenixRuntime.CURRENT_SCN_ATTRIB, Long.toString(ts + 10)); |
| Connection conn10 = DriverManager.getConnection(getUrl(), props); |
| try { |
| conn10.prepareStatement(query).executeQuery().next(); |
| fail(); |
| } catch (TableNotFoundException e) { |
| } |
| } |
| |
| @Test |
| public void testCreateOnExistingTable() throws Exception { |
| PhoenixConnection pconn = DriverManager.getConnection(getUrl(), PropertiesUtil.deepCopy(TEST_PROPERTIES)).unwrap(PhoenixConnection.class); |
| String tableName = MDTEST_NAME; |
| String schemaName = MDTEST_SCHEMA_NAME; |
| byte[] cfA = Bytes.toBytes(SchemaUtil.normalizeIdentifier("a")); |
| 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) { |
| } |
| |
| @SuppressWarnings("deprecation") |
| 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)); |
| PhoenixConnection conn1 = DriverManager.getConnection(getUrl(), props).unwrap(PhoenixConnection.class); |
| ensureTableCreated(getUrl(), tableName, tableName, ts); |
| |
| descriptor = admin.getTableDescriptor(htableName); |
| assertEquals(3,descriptor.getColumnFamilies().length); |
| HColumnDescriptor cdA = descriptor.getFamily(cfA); |
| assertNotEquals(HColumnDescriptor.DEFAULT_KEEP_DELETED, cdA.getKeepDeletedCells()); |
| assertEquals(DataBlockEncoding.NONE, cdA.getDataBlockEncoding()); // Overriden using WITH |
| assertEquals(1,cdA.getMaxVersions());// Overriden using WITH |
| HColumnDescriptor cdB = descriptor.getFamily(cfB); |
| // Allow KEEP_DELETED_CELLS to be false for VIEW |
| assertEquals(HColumnDescriptor.DEFAULT_KEEP_DELETED, cdB.getKeepDeletedCells()); |
| assertEquals(DataBlockEncoding.NONE, cdB.getDataBlockEncoding()); // Should keep the original value. |
| // CF c should stay the same since it's not a Phoenix cf. |
| HColumnDescriptor cdC = descriptor.getFamily(cfC); |
| assertNotNull("Column family not found", cdC); |
| assertEquals(HColumnDescriptor.DEFAULT_KEEP_DELETED, cdC.getKeepDeletedCells()); |
| assertFalse(SchemaUtil.DEFAULT_DATA_BLOCK_ENCODING == cdC.getDataBlockEncoding()); |
| assertTrue(descriptor.hasCoprocessor(UngroupedAggregateRegionObserver.class.getName())); |
| assertTrue(descriptor.hasCoprocessor(GroupedAggregateRegionObserver.class.getName())); |
| assertTrue(descriptor.hasCoprocessor(ServerCachingEndpointImpl.class.getName())); |
| admin.close(); |
| |
| int rowCount = 5; |
| String upsert = "UPSERT INTO " + tableName + "(id,col1,col2) VALUES(?,?,?)"; |
| PreparedStatement ps = conn1.prepareStatement(upsert); |
| for (int i = 0; i < rowCount; i++) { |
| ps.setString(1, Integer.toString(i)); |
| ps.setInt(2, i+1); |
| ps.setInt(3, i+2); |
| ps.execute(); |
| } |
| conn1.commit(); |
| conn1.close(); |
| |
| props.setProperty(PhoenixRuntime.CURRENT_SCN_ATTRIB, Long.toString(ts + 6)); |
| Connection conn2 = DriverManager.getConnection(getUrl(), props); |
| String query = "SELECT count(1) FROM " + tableName; |
| ResultSet rs = conn2.createStatement().executeQuery(query); |
| assertTrue(rs.next()); |
| assertEquals(rowCount, rs.getLong(1)); |
| |
| query = "SELECT id, col1,col2 FROM " + tableName; |
| rs = conn2.createStatement().executeQuery(query); |
| for (int i = 0; i < rowCount; i++) { |
| assertTrue(rs.next()); |
| assertEquals(Integer.toString(i),rs.getString(1)); |
| assertEquals(i+1, rs.getInt(2)); |
| assertEquals(i+2, rs.getInt(3)); |
| } |
| assertFalse(rs.next()); |
| conn2.close(); |
| } |
| |
| @SuppressWarnings("deprecation") |
| @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); |
| } catch (org.apache.hadoop.hbase.TableNotFoundException e) { |
| } |
| |
| HTableDescriptor descriptor = new HTableDescriptor(htableName); |
| for (byte[] familyName : familyNames) { |
| HColumnDescriptor columnDescriptor = new HColumnDescriptor(familyName); |
| descriptor.addFamily(columnDescriptor); |
| } |
| admin.createTable(descriptor); |
| admin.close(); |
| |
| 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 |
| } catch (ReadOnlyTableException 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) IMMUTABLE_ROWS=true \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 |
| } |
| |
| 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 |
| } |
| |
| 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, PInteger.INSTANCE.toBytes(1)); |
| put.add(cfC, Bytes.toBytes("COL2"), ts+6, PLong.INSTANCE.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)"); |
| String select = "SELECT col1 FROM " + MDTEST_NAME + " WHERE col2=?"; |
| ps = conn7.prepareStatement(select); |
| ps.setInt(1, 2); |
| rs = ps.executeQuery(); |
| assertTrue(rs.next()); |
| assertEquals(1, rs.getInt(1)); |
| assertFalse(rs.next()); |
| |
| props.setProperty(PhoenixRuntime.CURRENT_SCN_ATTRIB, Long.toString(ts + 12)); |
| Connection conn75 = DriverManager.getConnection(getUrl(), props); |
| String dropTable = "DROP TABLE " + MDTEST_NAME ; |
| ps = conn75.prepareStatement(dropTable); |
| try { |
| ps.execute(); |
| fail(); |
| } catch (TableNotFoundException e) { |
| // expected to fail b/c it is a view |
| } |
| |
| String dropView = "DROP VIEW " + MDTEST_NAME ; |
| ps = conn75.prepareStatement(dropView); |
| ps.execute(); |
| conn75.close(); |
| |
| props.setProperty(PhoenixRuntime.CURRENT_SCN_ATTRIB, Long.toString(ts + 15)); |
| Connection conn8 = DriverManager.getConnection(getUrl(), props); |
| createStmt = "create view " + MDTEST_NAME + |
| " (id char(1) not null primary key,\n" + |
| " b.col1 integer,\n" + |
| " \"c\".col2 bigint) IMMUTABLE_ROWS=true\n"; |
| // should be ok to create a view with IMMUTABLE_ROWS = true |
| conn8.createStatement().execute(createStmt); |
| conn8.close(); |
| |
| props.setProperty(PhoenixRuntime.CURRENT_SCN_ATTRIB, Long.toString(ts + 20)); |
| Connection conn9 = DriverManager.getConnection(getUrl(), props); |
| conn9.createStatement().execute("CREATE INDEX idx ON " + MDTEST_NAME + "(B.COL1)"); |
| |
| props.setProperty(PhoenixRuntime.CURRENT_SCN_ATTRIB, Long.toString(ts + 30)); |
| Connection conn91 = DriverManager.getConnection(getUrl(), props); |
| ps = conn91.prepareStatement(dropView); |
| ps.execute(); |
| conn91.close(); |
| |
| props.setProperty(PhoenixRuntime.CURRENT_SCN_ATTRIB, Long.toString(ts + 35)); |
| Connection conn92 = DriverManager.getConnection(getUrl(), props); |
| createStmt = "create view " + MDTEST_NAME + |
| " (id char(1) not null primary key,\n" + |
| " b.col1 integer,\n" + |
| " \"c\".col2 bigint) as\n" + |
| " select * from " + MDTEST_NAME + |
| " where b.col1 = 1"; |
| conn92.createStatement().execute(createStmt); |
| conn92.close(); |
| |
| put = new Put(Bytes.toBytes("1")); |
| put.add(cfB, Bytes.toBytes("COL1"), ts+39, PInteger.INSTANCE.toBytes(3)); |
| put.add(cfC, Bytes.toBytes("COL2"), ts+39, PLong.INSTANCE.toBytes(4)); |
| htable.put(put); |
| |
| props.setProperty(PhoenixRuntime.CURRENT_SCN_ATTRIB, Long.toString(ts + 40)); |
| Connection conn92a = DriverManager.getConnection(getUrl(), props); |
| rs = conn92a.createStatement().executeQuery("select count(*) from " + MDTEST_NAME); |
| assertTrue(rs.next()); |
| assertEquals(1,rs.getInt(1)); |
| conn92a.close(); |
| |
| props.setProperty(PhoenixRuntime.CURRENT_SCN_ATTRIB, Long.toString(ts + 45)); |
| Connection conn93 = DriverManager.getConnection(getUrl(), props); |
| try { |
| String alterView = "alter view " + MDTEST_NAME + " drop column b.col1"; |
| conn93.createStatement().execute(alterView); |
| fail(); |
| } catch (SQLException e) { |
| assertEquals(SQLExceptionCode.CANNOT_MUTATE_TABLE.getErrorCode(), e.getErrorCode()); |
| } |
| conn93.close(); |
| |
| props.setProperty(PhoenixRuntime.CURRENT_SCN_ATTRIB, Long.toString(ts + 50)); |
| Connection conn94 = DriverManager.getConnection(getUrl(), props); |
| String alterView = "alter view " + MDTEST_NAME + " drop column \"c\".col2"; |
| conn94.createStatement().execute(alterView); |
| conn94.close(); |
| |
| } |
| |
| @Test |
| public void testAddKVColumnToExistingFamily() throws Throwable { |
| long ts = nextTimestamp(); |
| String tenantId = getOrganizationId(); |
| initATableValues(ATABLE_NAME, tenantId, getDefaultSplits(tenantId), null, ts, getUrl(), null); |
| |
| Properties props = new Properties(); |
| props.setProperty(PhoenixRuntime.CURRENT_SCN_ATTRIB, Long.toString(ts + 5)); |
| Connection conn1 = DriverManager.getConnection(getUrl(), props); |
| // Failed attempt to repro table not found bug |
| // TestUtil.clearMetaDataCache(conn1); |
| // PhoenixConnection pconn = conn1.unwrap(PhoenixConnection.class); |
| // pconn.removeTable(ATABLE_SCHEMA_NAME, ATABLE_NAME); |
| conn1.createStatement().executeUpdate("ALTER TABLE " + ATABLE_NAME + " ADD z_integer integer"); |
| conn1.close(); |
| |
| props.setProperty(PhoenixRuntime.CURRENT_SCN_ATTRIB, Long.toString(ts + 6)); |
| Connection conn2 = DriverManager.getConnection(getUrl(), props); |
| String query = "SELECT z_integer FROM aTable"; |
| assertTrue(conn2.prepareStatement(query).executeQuery().next()); |
| conn2.close(); |
| |
| props.setProperty(PhoenixRuntime.CURRENT_SCN_ATTRIB, Long.toString(ts + 3)); |
| Connection conn3 = DriverManager.getConnection(getUrl(), props); |
| try { |
| conn3.prepareStatement(query).executeQuery().next(); |
| fail(); |
| } catch (ColumnNotFoundException e) { |
| } |
| } |
| |
| @Test |
| public void testAddKVColumnToNewFamily() throws Exception { |
| long ts = nextTimestamp(); |
| String tenantId = getOrganizationId(); |
| initATableValues(ATABLE_NAME, tenantId, getDefaultSplits(tenantId), null, ts, getUrl(), null); |
| Properties props = new Properties(); |
| props.setProperty(PhoenixRuntime.CURRENT_SCN_ATTRIB, Long.toString(ts + 5)); |
| Connection conn1 = DriverManager.getConnection(getUrl(), props); |
| conn1.createStatement().executeUpdate("ALTER TABLE " + ATABLE_NAME + " ADD newcf.z_integer integer"); |
| conn1.close(); |
| |
| props.setProperty(PhoenixRuntime.CURRENT_SCN_ATTRIB, Long.toString(ts + 6)); |
| Connection conn2 = DriverManager.getConnection(getUrl(), props); |
| String query = "SELECT z_integer FROM aTable"; |
| assertTrue(conn2.prepareStatement(query).executeQuery().next()); |
| conn2.close(); |
| |
| props.setProperty(PhoenixRuntime.CURRENT_SCN_ATTRIB, Long.toString(ts + 3)); |
| Connection conn3 = DriverManager.getConnection(getUrl(), props); |
| try { |
| conn3.prepareStatement(query).executeQuery().next(); |
| fail(); |
| } catch (ColumnNotFoundException e) { |
| } |
| } |
| |
| @Test |
| public void testAddPKColumn() throws Exception { |
| long ts = nextTimestamp(); |
| String tenantId = getOrganizationId(); |
| initATableValues(ATABLE_NAME, tenantId, getDefaultSplits(tenantId), null, ts, getUrl(), null); |
| |
| Properties props = new Properties(); |
| props.setProperty(PhoenixRuntime.CURRENT_SCN_ATTRIB, Long.toString(ts + 5)); |
| Connection conn1 = DriverManager.getConnection(getUrl(), props); |
| try { |
| conn1.createStatement().executeUpdate("ALTER TABLE " + ATABLE_NAME + " ADD z_string varchar not null primary key"); |
| fail(); |
| } catch (SQLException e) { |
| assertTrue(e.getMessage(), e.getMessage().contains("ERROR 1006 (42J04): Only nullable columns may be added to a multi-part row key.")); |
| } |
| conn1.createStatement().executeUpdate("ALTER TABLE " + ATABLE_NAME + " ADD z_string varchar primary key"); |
| conn1.close(); |
| |
| props.setProperty(PhoenixRuntime.CURRENT_SCN_ATTRIB, Long.toString(ts + 6)); |
| Connection conn2 = DriverManager.getConnection(getUrl(), props); |
| String query = "SELECT z_string FROM aTable"; |
| assertTrue(conn2.prepareStatement(query).executeQuery().next()); |
| conn2.close(); |
| |
| props.setProperty(PhoenixRuntime.CURRENT_SCN_ATTRIB, Long.toString(ts + 3)); |
| Connection conn3 = DriverManager.getConnection(getUrl(), props); |
| try { |
| conn3.prepareStatement(query).executeQuery().next(); |
| fail(); |
| } catch (ColumnNotFoundException e) { |
| } |
| } |
| |
| @Test |
| public void testDropKVColumn() throws Exception { |
| long ts = nextTimestamp(); |
| String tenantId = getOrganizationId(); |
| initATableValues(ATABLE_NAME, tenantId, getDefaultSplits(tenantId), null, ts, getUrl(), null); |
| |
| Properties props = new Properties(); |
| props.setProperty(PhoenixRuntime.CURRENT_SCN_ATTRIB, Long.toString(ts + 5)); |
| Connection conn5 = DriverManager.getConnection(getUrl(), props); |
| assertTrue(conn5.createStatement().executeQuery("SELECT 1 FROM atable WHERE b_string IS NOT NULL").next()); |
| conn5.createStatement().executeUpdate("ALTER TABLE " + ATABLE_NAME + " DROP COLUMN b_string"); |
| conn5.close(); |
| |
| props.setProperty(PhoenixRuntime.CURRENT_SCN_ATTRIB, Long.toString(ts + 6)); |
| Connection conn2 = DriverManager.getConnection(getUrl(), props); |
| String query = "SELECT b_string FROM aTable"; |
| try { |
| conn2.prepareStatement(query).executeQuery().next(); |
| fail(); |
| } catch (ColumnNotFoundException e) { |
| } |
| conn2.close(); |
| |
| props.setProperty(PhoenixRuntime.CURRENT_SCN_ATTRIB, Long.toString(ts + 3)); |
| Connection conn3 = DriverManager.getConnection(getUrl(), props); |
| assertTrue(conn3.prepareStatement(query).executeQuery().next()); |
| conn3.close(); |
| |
| props.setProperty(PhoenixRuntime.CURRENT_SCN_ATTRIB, Long.toString(ts + 7)); |
| Connection conn7 = DriverManager.getConnection(getUrl(), props); |
| conn7.createStatement().executeUpdate("ALTER TABLE " + ATABLE_NAME + " ADD b_string VARCHAR"); |
| conn7.close(); |
| |
| props.setProperty(PhoenixRuntime.CURRENT_SCN_ATTRIB, Long.toString(ts + 8)); |
| Connection conn8 = DriverManager.getConnection(getUrl(), props); |
| assertFalse(conn8.createStatement().executeQuery("SELECT 1 FROM atable WHERE b_string IS NOT NULL").next()); |
| conn8.close(); |
| |
| } |
| |
| @Test |
| public void testDropPKColumn() throws Exception { |
| long ts = nextTimestamp(); |
| String tenantId = getOrganizationId(); |
| initATableValues(ATABLE_NAME, tenantId, getDefaultSplits(tenantId), null, ts, getUrl(), null); |
| |
| Properties props = new Properties(); |
| props.setProperty(PhoenixRuntime.CURRENT_SCN_ATTRIB, Long.toString(ts + 5)); |
| Connection conn1 = DriverManager.getConnection(getUrl(), props); |
| try { |
| conn1.createStatement().executeUpdate("ALTER TABLE " + ATABLE_NAME + " DROP COLUMN entity_id"); |
| fail(); |
| } catch (SQLException e) { |
| assertTrue(e.getMessage(), e.getMessage().contains("ERROR 506 (42817): Primary key column may not be dropped.")); |
| } |
| conn1.close(); |
| } |
| |
| @Test |
| public void testDropAllKVCols() throws Exception { |
| ResultSet rs; |
| long ts = nextTimestamp(); |
| ensureTableCreated(getUrl(), MDTEST_NAME, MDTEST_NAME, null, ts, null); |
| |
| Properties props = new Properties(); |
| |
| props.setProperty(PhoenixRuntime.CURRENT_SCN_ATTRIB, Long.toString(ts + 2)); |
| Connection conn2 = DriverManager.getConnection(getUrl(), props); |
| conn2.createStatement().executeUpdate("UPSERT INTO " + MDTEST_NAME + " VALUES('a',1,1)"); |
| conn2.createStatement().executeUpdate("UPSERT INTO " + MDTEST_NAME + " VALUES('b',2,2)"); |
| conn2.commit(); |
| conn2.close(); |
| |
| props.setProperty(PhoenixRuntime.CURRENT_SCN_ATTRIB, Long.toString(ts + 3)); |
| Connection conn3 = DriverManager.getConnection(getUrl(), props); |
| rs = conn3.createStatement().executeQuery("SELECT count(1) FROM " + MDTEST_NAME); |
| assertTrue(rs.next()); |
| assertEquals(2, rs.getLong(1)); |
| conn3.close(); |
| |
| props.setProperty(PhoenixRuntime.CURRENT_SCN_ATTRIB, Long.toString(ts + 5)); |
| Connection conn5 = DriverManager.getConnection(getUrl(), props); |
| conn5.createStatement().executeUpdate("ALTER TABLE " + MDTEST_NAME + " DROP COLUMN col1"); |
| conn5.close(); |
| |
| props.setProperty(PhoenixRuntime.CURRENT_SCN_ATTRIB, Long.toString(ts + 6)); |
| Connection conn6 = DriverManager.getConnection(getUrl(), props); |
| rs = conn6.createStatement().executeQuery("SELECT count(1) FROM " + MDTEST_NAME); |
| assertTrue(rs.next()); |
| assertEquals(2, rs.getLong(1)); |
| conn6.close(); |
| |
| props.setProperty(PhoenixRuntime.CURRENT_SCN_ATTRIB, Long.toString(ts + 7)); |
| Connection conn7 = DriverManager.getConnection(getUrl(), props); |
| conn7.createStatement().executeUpdate("ALTER TABLE " + MDTEST_NAME + " DROP COLUMN col2"); |
| conn7.close(); |
| |
| props.setProperty(PhoenixRuntime.CURRENT_SCN_ATTRIB, Long.toString(ts + 8)); |
| Connection conn8 = DriverManager.getConnection(getUrl(), props); |
| rs = conn8.createStatement().executeQuery("SELECT count(1) FROM " + MDTEST_NAME); |
| assertTrue(rs.next()); |
| assertEquals(2, rs.getLong(1)); |
| conn8.close(); |
| } |
| |
| @Test |
| public void testNewerTableDisallowed() throws Exception { |
| long ts = nextTimestamp(); |
| ensureTableCreated(getUrl(), ATABLE_NAME, ATABLE_NAME, null, ts, null); |
| |
| Properties props = new Properties(); |
| props.setProperty(PhoenixRuntime.CURRENT_SCN_ATTRIB, Long.toString(ts + 5)); |
| Connection conn5 = DriverManager.getConnection(getUrl(), props); |
| conn5.createStatement().executeUpdate("ALTER TABLE " + ATABLE_NAME + " DROP COLUMN x_integer"); |
| try { |
| conn5.createStatement().executeUpdate("ALTER TABLE " + ATABLE_NAME + " DROP COLUMN y_integer"); |
| fail(); |
| } catch (SQLException e) { |
| assertTrue(e.getMessage(), e.getMessage().contains("ERROR 1013 (42M04): Table already exists. tableName=ATABLE")); |
| } |
| conn5.close(); |
| } |
| |
| |
| @Test |
| public void testTableWithScemaMetadataScan() throws SQLException { |
| long ts = nextTimestamp(); |
| Properties props = new Properties(); |
| props.setProperty(PhoenixRuntime.CURRENT_SCN_ATTRIB, Long.toString(ts)); |
| Connection conn = DriverManager.getConnection(getUrl(), props); |
| |
| conn.createStatement().execute("create table foo.bar(k varchar primary key)"); |
| conn.createStatement().execute("create table bar(k varchar primary key)"); |
| conn.close(); |
| |
| props.setProperty(PhoenixRuntime.CURRENT_SCN_ATTRIB, Long.toString(ts + 10)); |
| conn = DriverManager.getConnection(getUrl(), props); |
| |
| DatabaseMetaData metaData = conn.getMetaData(); |
| ResultSet rs; |
| |
| // Tricky case that requires returning false for null AND true expression |
| rs = metaData.getTables(null, "FOO", "BAR", null); |
| assertTrue(rs.next()); |
| assertEquals("FOO",rs.getString("TABLE_SCHEM")); |
| assertEquals("BAR", rs.getString("TABLE_NAME")); |
| assertFalse(rs.next()); |
| |
| // Tricky case that requires end key to maintain trailing nulls |
| rs = metaData.getTables("", "FOO", "BAR", null); |
| assertTrue(rs.next()); |
| assertEquals("FOO",rs.getString("TABLE_SCHEM")); |
| assertEquals("BAR", rs.getString("TABLE_NAME")); |
| assertFalse(rs.next()); |
| |
| rs = metaData.getTables("", null, "BAR", null); |
| assertTrue(rs.next()); |
| assertEquals(null,rs.getString("TABLE_SCHEM")); |
| assertEquals("BAR", rs.getString("TABLE_NAME")); |
| assertTrue(rs.next()); |
| assertEquals("FOO",rs.getString("TABLE_SCHEM")); |
| assertEquals("BAR", rs.getString("TABLE_NAME")); |
| assertFalse(rs.next()); |
| } |
| |
| @Test |
| public void testRemarkColumn() throws SQLException { |
| long ts = nextTimestamp(); |
| Properties props = new Properties(); |
| props.setProperty(PhoenixRuntime.CURRENT_SCN_ATTRIB, Long.toString(ts + 5)); |
| Connection conn = DriverManager.getConnection(getUrl(), props); |
| |
| // Retrieve the database metadata |
| DatabaseMetaData dbmd = conn.getMetaData(); |
| ResultSet rs = dbmd.getColumns(null, null, null, null); |
| rs.next(); |
| |
| // Lookup column by name, this should return null but not throw an exception |
| String remarks = rs.getString("REMARKS"); |
| assertNull(remarks); |
| |
| // Same as above, but lookup by position |
| remarks = rs.getString(12); |
| assertNull(remarks); |
| |
| // Iterate through metadata columns to find 'COLUMN_NAME' == 'REMARKS' |
| boolean foundRemarksColumn = false; |
| while(rs.next()) { |
| String colName = rs.getString("COLUMN_NAME"); |
| if(PhoenixDatabaseMetaData.REMARKS.equals(colName)) { |
| foundRemarksColumn = true; |
| break; |
| } |
| } |
| assertTrue("Could not find REMARKS column", foundRemarksColumn); |
| } |
| } |