You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@phoenix.apache.org by ya...@apache.org on 2020/11/09 18:11:44 UTC
[phoenix] branch master updated: PHOENIX-6203 : Add new CQS method
to return Table instance only if table exists
This is an automated email from the ASF dual-hosted git repository.
yanxinyi pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/phoenix.git
The following commit(s) were added to refs/heads/master by this push:
new bf36eb1 PHOENIX-6203 : Add new CQS method to return Table instance only if table exists
bf36eb1 is described below
commit bf36eb11a6c1cfb9eebe6489fa61af40b9ebdaaf
Author: Viraj Jasani <vj...@apache.org>
AuthorDate: Mon Nov 9 00:24:02 2020 +0530
PHOENIX-6203 : Add new CQS method to return Table instance only if table exists
Signed-off-by: Xinyi Yan <ya...@apache.org>
---
.../org/apache/phoenix/end2end/AlterTableIT.java | 76 +++++++++++++++++++++-
.../phoenix/query/ConnectionQueryServices.java | 16 +++++
.../phoenix/query/ConnectionQueryServicesImpl.java | 43 ++++++++----
.../query/ConnectionlessQueryServicesImpl.java | 5 ++
.../query/DelegateConnectionQueryServices.java | 5 ++
.../java/org/apache/phoenix/query/BaseTest.java | 4 +-
.../query/ConnectionQueryServicesImplTest.java | 2 +
7 files changed, 133 insertions(+), 18 deletions(-)
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/AlterTableIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/AlterTableIT.java
index b2269c1..42dd897 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/AlterTableIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/AlterTableIT.java
@@ -50,13 +50,14 @@ import java.util.Properties;
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.Table;
import org.apache.hadoop.hbase.client.TableDescriptor;
import org.apache.hadoop.hbase.util.Bytes;
-import org.apache.phoenix.exception.PhoenixParserException;
import org.apache.phoenix.exception.SQLExceptionCode;
import org.apache.phoenix.jdbc.PhoenixConnection;
import org.apache.phoenix.jdbc.PhoenixDatabaseMetaData;
import org.apache.phoenix.query.BaseTest;
+import org.apache.phoenix.query.ConnectionQueryServices;
import org.apache.phoenix.query.QueryConstants;
import org.apache.phoenix.query.QueryServices;
import org.apache.phoenix.schema.PTable;
@@ -1440,5 +1441,74 @@ public class AlterTableIT extends ParallelStatsDisabledIT {
stmt.execute(alterDdl2);
}
}
-}
-
+
+ @Test
+ public void testTableExists() throws Exception {
+ try (Connection conn = DriverManager.getConnection(getUrl())) {
+ ConnectionQueryServices cqs =
+ conn.unwrap(PhoenixConnection.class).getQueryServices();
+ String tableName = "randomTable";
+ // table never existed, still cqs.getTable() does not throw TNFE
+ Table randomTable = cqs.getTable(Bytes.toBytes(tableName));
+ assertNotNull(randomTable);
+ assertEquals(randomTable.getName(), TableName.valueOf(tableName));
+ try {
+ // this is correct check for existence of table
+ cqs.getTableIfExists(Bytes.toBytes(tableName));
+ fail("Should have thrown TableNotFoundException");
+ } catch (TableNotFoundException e) {
+ assertEquals(tableName, e.getTableName());
+ }
+
+ String fullTableName1 = SchemaUtil.getTableName(schemaName,
+ dataTableName);
+ String ddl = "CREATE TABLE " + fullTableName1
+ + " (col1 INTEGER PRIMARY KEY, col2 INTEGER)";
+ conn.createStatement().execute(ddl);
+ String schemaName2 = generateUniqueName();
+ String tableName2 = generateUniqueName();
+ String fullTableName2 = SchemaUtil.getTableName(schemaName2,
+ tableName2);
+ ddl = "CREATE TABLE " + fullTableName2
+ + " (col1 INTEGER PRIMARY KEY, col2 INTEGER)";
+ conn.createStatement().execute(ddl);
+
+ // table does exist and cqs.getTable() does not throw TNFE
+ Table table1 = cqs.getTable(Bytes.toBytes(fullTableName1));
+ assertNotNull(table1);
+ try {
+ cqs.getTableIfExists(Bytes.toBytes(fullTableName1));
+ } catch (TableNotFoundException e) {
+ fail("Should not throw TableNotFoundException");
+ }
+
+ disableAndDropNonSystemTables();
+ // tables have been dropped, still cqs.getTable()
+ // does not throw TNFE for tableName1 and tableName2
+ Table t1 = cqs.getTable(Bytes.toBytes(fullTableName1));
+ assertEquals(t1.getName().getNameAsString(), fullTableName1);
+ Table t2 = cqs.getTable(Bytes.toBytes(fullTableName2));
+ assertEquals(t2.getName().getNameAsString(), fullTableName2);
+
+ // this is correct check for existence of table
+ try {
+ cqs.getTableIfExists(Bytes.toBytes(fullTableName1));
+ fail("Should have thrown TableNotFoundException");
+ } catch (TableNotFoundException e) {
+ // match table and schema
+ assertEquals(dataTableName, e.getTableName());
+ assertEquals(schemaName, e.getSchemaName());
+ }
+ try {
+ cqs.getTableIfExists(Bytes.toBytes(fullTableName2));
+ fail("Should have thrown TableNotFoundException");
+ } catch (TableNotFoundException e) {
+ // match table and schema
+ assertEquals(tableName2, e.getTableName());
+ assertEquals(schemaName2, e.getSchemaName());
+ }
+
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/query/ConnectionQueryServices.java b/phoenix-core/src/main/java/org/apache/phoenix/query/ConnectionQueryServices.java
index 4bae8ed..d600556 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/query/ConnectionQueryServices.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/query/ConnectionQueryServices.java
@@ -73,6 +73,22 @@ public interface ConnectionQueryServices extends QueryServices, MetaDataMutated
*/
public Table getTable(byte[] tableName) throws SQLException;
+ /**
+ * Get Table by the given name. It is the responsibility of callers
+ * to close the returned Table interface. This method uses additional Admin
+ * API to ensure if table exists before returning Table interface from
+ * Connection. If table does not exist, this method will throw
+ * {@link org.apache.phoenix.schema.TableNotFoundException}
+ *
+ * @param tableName the name of the Table
+ * @return Table interface
+ * @throws SQLException If something goes wrong while retrieving table
+ * interface from connection managed by implementor. If table does not
+ * exist, {@link org.apache.phoenix.schema.TableNotFoundException} will
+ * be thrown.
+ */
+ Table getTableIfExists(byte[] tableName) throws SQLException;
+
public TableDescriptor getTableDescriptor(byte[] tableName) throws SQLException;
public HRegionLocation getTableRegionLocation(byte[] tableName, byte[] row) throws SQLException;
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/query/ConnectionQueryServicesImpl.java b/phoenix-core/src/main/java/org/apache/phoenix/query/ConnectionQueryServicesImpl.java
index 7ccbac7..00cdb65 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/query/ConnectionQueryServicesImpl.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/query/ConnectionQueryServicesImpl.java
@@ -483,15 +483,28 @@ public class ConnectionQueryServicesImpl extends DelegateQueryServices implement
@Override
public Table getTable(byte[] tableName) throws SQLException {
try {
- return HBaseFactoryProvider.getHTableFactory().getTable(tableName, connection, null);
- } catch (org.apache.hadoop.hbase.TableNotFoundException e) {
- throw new TableNotFoundException(SchemaUtil.getSchemaNameFromFullName(tableName), SchemaUtil.getTableNameFromFullName(tableName));
+ return HBaseFactoryProvider.getHTableFactory().getTable(tableName,
+ connection, null);
} catch (IOException e) {
throw new SQLException(e);
}
}
@Override
+ public Table getTableIfExists(byte[] tableName) throws SQLException {
+ try (Admin admin = getAdmin()) {
+ if (!admin.tableExists(TableName.valueOf(tableName))) {
+ throw new TableNotFoundException(
+ SchemaUtil.getSchemaNameFromFullName(tableName),
+ SchemaUtil.getTableNameFromFullName(tableName));
+ }
+ } catch (IOException e) {
+ throw new SQLException(e);
+ }
+ return getTable(tableName);
+ }
+
+ @Override
public TableDescriptor getTableDescriptor(byte[] tableName) throws SQLException {
Table htable = getTable(tableName);
try {
@@ -4522,17 +4535,21 @@ public class ConnectionQueryServicesImpl extends DelegateQueryServices implement
}
@VisibleForTesting
- public Table getSysMutexTable() throws SQLException, IOException {
- String table = SYSTEM_MUTEX_NAME;
- TableName tableName = TableName.valueOf(table);
- try (Admin admin = getAdmin()) {
- if (!admin.tableExists(tableName)) {
- table = table.replace(QueryConstants.NAME_SEPARATOR,
- QueryConstants.NAMESPACE_SEPARATOR);
- tableName = TableName.valueOf(table);
- }
- return connection.getTable(tableName);
+ public Table getSysMutexTable() throws SQLException {
+ String tableNameAsString = SYSTEM_MUTEX_NAME;
+ Table table;
+ try {
+ table = getTableIfExists(Bytes.toBytes(tableNameAsString));
+ } catch (TableNotFoundException e) {
+ tableNameAsString = tableNameAsString.replace(
+ QueryConstants.NAME_SEPARATOR,
+ QueryConstants.NAMESPACE_SEPARATOR);
+ // if SYSTEM.MUTEX does not exist, we don't need to check
+ // for the existence of SYSTEM:MUTEX as it must exist, hence
+ // we can call getTable() here instead of getTableIfExists()
+ table = getTable(Bytes.toBytes(tableNameAsString));
}
+ return table;
}
private String addColumn(String columnsToAddSoFar, String columns) {
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/query/ConnectionlessQueryServicesImpl.java b/phoenix-core/src/main/java/org/apache/phoenix/query/ConnectionlessQueryServicesImpl.java
index 8bd810f..382af01 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/query/ConnectionlessQueryServicesImpl.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/query/ConnectionlessQueryServicesImpl.java
@@ -213,6 +213,11 @@ public class ConnectionlessQueryServicesImpl extends DelegateQueryServices imple
}
@Override
+ public Table getTableIfExists(byte[] tableName) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
public List<HRegionLocation> getAllTableRegions(byte[] tableName) throws SQLException {
List<HRegionLocation> regions = tableSplits.get(Bytes.toString(tableName));
if (regions != null) {
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/query/DelegateConnectionQueryServices.java b/phoenix-core/src/main/java/org/apache/phoenix/query/DelegateConnectionQueryServices.java
index b4c04ae..a9a26ad 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/query/DelegateConnectionQueryServices.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/query/DelegateConnectionQueryServices.java
@@ -76,6 +76,11 @@ public class DelegateConnectionQueryServices extends DelegateQueryServices imple
}
@Override
+ public Table getTableIfExists(byte[] tableName) throws SQLException {
+ return getDelegate().getTableIfExists(tableName);
+ }
+
+ @Override
public List<HRegionLocation> getAllTableRegions(byte[] tableName) throws SQLException {
return getDelegate().getAllTableRegions(tableName);
}
diff --git a/phoenix-core/src/test/java/org/apache/phoenix/query/BaseTest.java b/phoenix-core/src/test/java/org/apache/phoenix/query/BaseTest.java
index 92cce1e..6b6518f 100644
--- a/phoenix-core/src/test/java/org/apache/phoenix/query/BaseTest.java
+++ b/phoenix-core/src/test/java/org/apache/phoenix/query/BaseTest.java
@@ -1553,9 +1553,9 @@ public abstract class BaseTest {
}
/**
- * Disable and drop all the tables except SYSTEM.CATALOG and SYSTEM.SEQUENCE
+ * Disable and drop all non system tables
*/
- private static void disableAndDropNonSystemTables() throws Exception {
+ protected static void disableAndDropNonSystemTables() throws Exception {
if (driver == null) return;
Admin admin = driver.getConnectionQueryServices(null, null).getAdmin();
try {
diff --git a/phoenix-core/src/test/java/org/apache/phoenix/query/ConnectionQueryServicesImplTest.java b/phoenix-core/src/test/java/org/apache/phoenix/query/ConnectionQueryServicesImplTest.java
index 2052676..b411fce 100644
--- a/phoenix-core/src/test/java/org/apache/phoenix/query/ConnectionQueryServicesImplTest.java
+++ b/phoenix-core/src/test/java/org/apache/phoenix/query/ConnectionQueryServicesImplTest.java
@@ -113,6 +113,8 @@ public class ConnectionQueryServicesImplTest {
.thenCallRealMethod();
when(mockCqs.getSysMutexTable()).thenCallRealMethod();
when(mockCqs.getAdmin()).thenCallRealMethod();
+ when(mockCqs.getTable(Mockito.any())).thenCallRealMethod();
+ when(mockCqs.getTableIfExists(Mockito.any())).thenCallRealMethod();
}
@SuppressWarnings("unchecked")