From 179ffe409f8030e98ab99c4ec558779b3d2764da Mon Sep 17 00:00:00 2001 From: Piotr Findeisen Date: Tue, 28 May 2019 10:56:46 +0200 Subject: [PATCH] Fix getting views for Hive 2.3+ metastore Hive 2.3 metastore provides more space for table parameter values. On certain databases (e.g. Derby, Oracle) it uses CLOB and these databases disallow `=` predicates over CLOB values. At the same time, they allow `LIKE` predicates over them. This fixes `SHOW TABLES` and queries over `information_schema.tables`. --- .../metastore/thrift/ThriftHiveMetastore.java | 50 +++++++++++++++++-- 1 file changed, 46 insertions(+), 4 deletions(-) diff --git a/presto-hive/src/main/java/io/prestosql/plugin/hive/metastore/thrift/ThriftHiveMetastore.java b/presto-hive/src/main/java/io/prestosql/plugin/hive/metastore/thrift/ThriftHiveMetastore.java index 363339ca8a601..9671008cd4dfe 100644 --- a/presto-hive/src/main/java/io/prestosql/plugin/hive/metastore/thrift/ThriftHiveMetastore.java +++ b/presto-hive/src/main/java/io/prestosql/plugin/hive/metastore/thrift/ThriftHiveMetastore.java @@ -117,6 +117,9 @@ public class ThriftHiveMetastore private final Duration maxRetryTime; private final int maxRetries; + private volatile boolean metastoreKnownToSupportTableParamEqualsPredicate; + private volatile boolean metastoreKnownToSupportTableParamLikePredicate; + @Inject public ThriftHiveMetastore(MetastoreLocator metastoreLocator, ThriftHiveMetastoreConfig thriftConfig) { @@ -722,10 +725,7 @@ public Optional> getAllViews(String databaseName) .stopOn(UnknownDBException.class) .stopOnIllegalExceptions() .run("getAllViews", stats.getGetAllViews().wrap(() -> { - try (ThriftMetastoreClient client = clientProvider.createMetastoreClient()) { - String filter = HIVE_FILTER_FIELD_PARAMS + PRESTO_VIEW_FLAG + " = \"true\""; - return Optional.of(client.getTableNamesByFilter(databaseName, filter)); - } + return Optional.of(getPrestoViews(databaseName)); })); } catch (UnknownDBException e) { @@ -739,6 +739,48 @@ public Optional> getAllViews(String databaseName) } } + private List getPrestoViews(String databaseName) + throws TException + { + /* + * Thrift call `get_table_names_by_filter` may be translated by Metastore to a SQL query against Metastore database. + * Hive 2.3 on some databases uses CLOB for table parameter value column and some databases disallow `=` predicate over + * CLOB values. At the same time, they allow `LIKE` predicates over them. + */ + String filterWithEquals = HIVE_FILTER_FIELD_PARAMS + PRESTO_VIEW_FLAG + " = \"true\""; + String filterWithLike = HIVE_FILTER_FIELD_PARAMS + PRESTO_VIEW_FLAG + " LIKE \"true\""; + + if (metastoreKnownToSupportTableParamEqualsPredicate) { + try (ThriftMetastoreClient client = clientProvider.createMetastoreClient()) { + return client.getTableNamesByFilter(databaseName, filterWithEquals); + } + } + if (metastoreKnownToSupportTableParamLikePredicate) { + try (ThriftMetastoreClient client = clientProvider.createMetastoreClient()) { + return client.getTableNamesByFilter(databaseName, filterWithLike); + } + } + + try (ThriftMetastoreClient client = clientProvider.createMetastoreClient()) { + List views = client.getTableNamesByFilter(databaseName, filterWithEquals); + metastoreKnownToSupportTableParamEqualsPredicate = true; + return views; + } + catch (TException | RuntimeException firstException) { + try (ThriftMetastoreClient client = clientProvider.createMetastoreClient()) { + List views = client.getTableNamesByFilter(databaseName, filterWithLike); + metastoreKnownToSupportTableParamLikePredicate = true; + return views; + } + catch (TException | RuntimeException secondException) { + if (firstException != secondException) { + firstException.addSuppressed(secondException); + } + } + throw firstException; + } + } + @Override public void createDatabase(Database database) {