Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
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.CUSTOM_ENTITY_DATA_FULL_NAME;
import static org.apache.phoenix.util.TestUtil.ENTITY_HISTORY_TABLE_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;
Expand All @@ -44,14 +45,17 @@
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashSet;
import java.util.Properties;
import java.util.Set;

import org.apache.hadoop.hbase.HConstants;
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.client.Admin;
import org.apache.hadoop.hbase.client.ColumnFamilyDescriptor;
import org.apache.hadoop.hbase.client.ColumnFamilyDescriptorBuilder;
import org.apache.hadoop.hbase.client.Put;
import org.apache.hadoop.hbase.client.Result;
import org.apache.hadoop.hbase.client.Table;
import org.apache.hadoop.hbase.client.TableDescriptor;
import org.apache.hadoop.hbase.client.TableDescriptorBuilder;
Expand Down Expand Up @@ -355,6 +359,60 @@ public void testSequenceMetadataScan() throws SQLException {
}
}

@Test
public void testShowSchemas() throws SQLException {
try (Connection conn = DriverManager.getConnection(getUrl())) {
ResultSet rs = conn.prepareStatement("show schemas").executeQuery();
assertTrue(rs.next());
assertEquals("SYSTEM", rs.getString("TABLE_SCHEM"));
assertEquals(null, rs.getString("TABLE_CATALOG"));
assertFalse(rs.next());
// Create another schema and make sure it is listed.
String schema = "showschemastest_" + generateUniqueName();
String fullTable = schema + "." + generateUniqueName();
ensureTableCreated(getUrl(), fullTable, ENTITY_HISTORY_TABLE_NAME, null);
// show schemas
rs = conn.prepareStatement("show schemas").executeQuery();
Set<String> schemas = new HashSet<>();
while (rs.next()) {
schemas.add(rs.getString("TABLE_SCHEM"));
assertEquals(null, rs.getString("TABLE_CATALOG"));
}
assertEquals(2, schemas.size());
assertTrue(schemas.contains("SYSTEM"));
assertTrue(schemas.contains(schema.toUpperCase()));
// show schemas like 'SYST%' and only SYSTEM should show up.
rs = conn.prepareStatement("show schemas like 'SYST%'").executeQuery();
assertTrue(rs.next());
assertEquals("SYSTEM", rs.getString("TABLE_SCHEM"));
assertEquals(null, rs.getString("TABLE_CATALOG"));
assertFalse(rs.next());
}
}

@Test
public void testShowTables() throws SQLException {
try (Connection conn = DriverManager.getConnection(getUrl())) {
// List all the tables in a particular schema.
ResultSet rs = conn.prepareStatement("show tables in SYSTEM").executeQuery();
Set<String> tables = new HashSet<>();
while (rs.next()) {
tables.add(rs.getString("TABLE_NAME"));
assertEquals("SYSTEM", rs.getString("TABLE_SCHEM"));
}
assertEquals(8, tables.size());
assertTrue(tables.contains("CATALOG"));
assertTrue(tables.contains("FUNCTION"));

tables.clear();
// Add a filter on the table name.
rs = conn.prepareStatement("show tables in SYSTEM like 'FUNC%'").executeQuery();
while (rs.next()) tables.add(rs.getString("TABLE_NAME"));
assertEquals(1, tables.size());
assertTrue(tables.contains("FUNCTION"));
}
}

@Test
public void testSchemaMetadataScan() throws SQLException {
String table1 = generateUniqueName();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@

import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.Driver;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
Expand Down Expand Up @@ -430,14 +431,51 @@ private void validateTenantViewIsDropped(Connection connTenant) throws SQLExcept
//Expected
}
}


@Test
public void testShowTablesMultiTenant() throws Exception {
// Each tenant should only be able list tables corresponding to their TENANT_ID
String tenantId2 = "T_" + generateUniqueName();
String secondTenantConnectionURL =
PHOENIX_JDBC_TENANT_SPECIFIC_URL.replace(TENANT_ID, tenantId2);
String tenantTable2 = "V_" + generateUniqueName();
createTestTable(
secondTenantConnectionURL, TENANT_TABLE_DDL.replace(TENANT_TABLE_NAME, tenantTable2));

Properties props = PropertiesUtil.deepCopy(TEST_PROPERTIES);
// Non-tenant connections should list all the tables.
try (Connection conn = DriverManager.getConnection(getUrl(), props)) {
Set<String> tables = new HashSet<>();
ResultSet rs = conn.prepareStatement("show tables").executeQuery();
while (rs.next()) {
tables.add(rs.getString("TABLE_NAME"));
}
assertTrue(tables.contains(PARENT_TABLE_NAME));
assertTrue(tables.contains(TENANT_TABLE_NAME));
assertTrue(tables.contains(tenantTable2));
}
// Tenant specific connections should not list tables from other tenants.
try (Connection conn = DriverManager.getConnection(secondTenantConnectionURL, props)) {
Set<String> tables = new HashSet<>();
ResultSet rs = conn.prepareStatement("show tables").executeQuery();
while (rs.next()) {
tables.add(rs.getString("TABLE_NAME"));
}
assertTrue(tables.contains(PARENT_TABLE_NAME));
assertFalse(tables.contains(TENANT_TABLE_NAME));
assertTrue(tables.contains(tenantTable2));
}
}

@Test
public void testTableMetadataScan() throws Exception {
// create a tenant table with same name for a different tenant to make sure we are not picking it up in metadata scans for TENANT_ID
String tenantId2 = "T_" + generateUniqueName();
String secondTenatConnectionURL = PHOENIX_JDBC_TENANT_SPECIFIC_URL.replace(TENANT_ID, tenantId2);
String secondTenantConnectionURL =
PHOENIX_JDBC_TENANT_SPECIFIC_URL.replace(TENANT_ID, tenantId2);
String tenantTable2 = "V_" + generateUniqueName();
createTestTable(secondTenatConnectionURL, TENANT_TABLE_DDL.replace(TENANT_TABLE_NAME, tenantTable2));
createTestTable(
secondTenantConnectionURL, TENANT_TABLE_DDL.replace(TENANT_TABLE_NAME, tenantTable2));

Properties props = PropertiesUtil.deepCopy(TEST_PROPERTIES);
Connection conn = DriverManager.getConnection(getUrl(), props);
Expand Down
14 changes: 14 additions & 0 deletions phoenix-core/src/main/antlr3/PhoenixSQL.g
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ tokens
SESSION='session';
TABLE='table';
SCHEMA='schema';
SCHEMAS='schemas';
ADD='add';
SPLIT='split';
EXPLAIN='explain';
Expand Down Expand Up @@ -147,6 +148,7 @@ tokens
IMMUTABLE = 'immutable';
GRANT = 'grant';
REVOKE = 'revoke';
SHOW = 'show';
}


Expand Down Expand Up @@ -425,6 +427,7 @@ oneStatement returns [BindableStatement ret]
| s=drop_index_node
| s=alter_index_node
| s=alter_table_node
| s=show_node
| s=trace_node
| s=create_function_node
| s=drop_function_node
Expand Down Expand Up @@ -487,6 +490,12 @@ revoke_permission_node returns [ChangePermsStatement ret]
}
;

// Parse a show statement. SHOW TABLES, SHOW SCHEMAS ...
show_node returns [ShowStatement ret]
: SHOW TABLES (IN schema=identifier)? (LIKE pattern=string_literal)? { $ret = factory.showTablesStatement(schema, pattern); }
| SHOW SCHEMAS (LIKE pattern=string_literal)? { $ret = factory.showSchemasStatement(pattern); }
;

// Parse a create view statement.
create_view_node returns [CreateTableStatement ret]
: CREATE VIEW (IF NOT ex=EXISTS)? t=from_table_name
Expand Down Expand Up @@ -526,6 +535,11 @@ int_literal_or_bind returns [ParseNode ret]
| b=bind_expression { $ret = b; }
;

// Returns the normalized string literal
string_literal returns [String ret]
: s=STRING_LITERAL { ret = SchemaUtil.normalizeLiteral(factory.literal(s.getText())); }
;

// Parse a drop sequence statement.
drop_sequence_node returns [DropSequenceStatement ret]
: DROP SEQUENCE (IF ex=EXISTS)? t=from_table_name
Expand Down
Loading