This is an automated email from the ASF dual-hosted git repository.
zabetak pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/hive.git
The following commit(s) were added to refs/heads/master by this push:
new 0616bca HIVE-25591: CREATE EXTERNAL TABLE fails for JDBC tables
stored in non-default schema (Stamatis Zampetakis, Chiran Ravani, reviewed by
Krisztian Kasa)
0616bca is described below
commit 0616bcaa2436ccbf388b635bfea160b47849553c
Author: Stamatis Zampetakis <[email protected]>
AuthorDate: Mon Oct 25 14:51:30 2021 +0200
HIVE-25591: CREATE EXTERNAL TABLE fails for JDBC tables stored in
non-default schema (Stamatis Zampetakis, Chiran Ravani, reviewed by Krisztian
Kasa)
1. Refactor getOriQueryToExecute, getQueryToExecute methods into
GenericJdbcDatabaseAccessor for better encapsulation and easier
documentation
2. Add comments regarding the query generation highlighting important
differences between JDBC_QUERY and SELECT * FROM t
3. Introduce getQualifiedTableName for consistently obtaining the table
exploiting also hive.sql.schena if available to avoid failures when the
table is in non-default schema.
4. Add tests/usage samples of hive.sql.schema property in different
DBMS.
5. Add tests with EXPLAIN plans for INSERT on external (Postgres) JDBC
table
Co-authored-by: Chiran Ravani <[email protected]>
Closes #2759
---
.../q_test_country_table_with_schema.mariadb.sql | 29 ++++
.../q_test_country_table_with_schema.mssql.sql | 38 +++++
.../q_test_country_table_with_schema.oracle.sql | 55 ++++++
.../q_test_country_table_with_schema.postgres.sql | 36 ++++
.../jdbc/conf/JdbcStorageConfigManager.java | 28 ---
.../jdbc/dao/GenericJdbcDatabaseAccessor.java | 38 ++++-
.../clientpositive/jdbc_table_dml_postgres.q | 17 ++
.../jdbc_table_with_schema_mariadb.q | 72 ++++++++
.../clientpositive/jdbc_table_with_schema_mssql.q | 54 ++++++
.../clientpositive/jdbc_table_with_schema_oracle.q | 57 +++++++
.../jdbc_table_with_schema_postgres.q | 54 ++++++
.../llap/jdbc_table_dml_postgres.q.out | 126 ++++++++++++++
.../llap/jdbc_table_with_schema_mariadb.q.out | 188 +++++++++++++++++++++
.../llap/jdbc_table_with_schema_mssql.q.out | 163 ++++++++++++++++++
.../llap/jdbc_table_with_schema_oracle.q.out | 169 ++++++++++++++++++
.../llap/jdbc_table_with_schema_postgres.q.out | 163 ++++++++++++++++++
16 files changed, 1253 insertions(+), 34 deletions(-)
diff --git a/data/scripts/q_test_country_table_with_schema.mariadb.sql
b/data/scripts/q_test_country_table_with_schema.mariadb.sql
new file mode 100644
index 0000000..8d029c0
--- /dev/null
+++ b/data/scripts/q_test_country_table_with_schema.mariadb.sql
@@ -0,0 +1,29 @@
+CREATE SCHEMA bob;
+CREATE TABLE bob.country
+(
+ id int,
+ name varchar(20)
+);
+
+insert into bob.country
+values (1, 'India');
+insert into bob.country
+values (2, 'Russia');
+insert into bob.country
+values (3, 'USA');
+
+CREATE SCHEMA alice;
+CREATE TABLE alice.country
+(
+ id int,
+ name varchar(20)
+);
+
+insert into alice.country
+values (4, 'Italy');
+insert into alice.country
+values (5, 'Greece');
+insert into alice.country
+values (6, 'China');
+insert into alice.country
+values (7, 'Japan');
diff --git a/data/scripts/q_test_country_table_with_schema.mssql.sql
b/data/scripts/q_test_country_table_with_schema.mssql.sql
new file mode 100644
index 0000000..ffc2c45
--- /dev/null
+++ b/data/scripts/q_test_country_table_with_schema.mssql.sql
@@ -0,0 +1,38 @@
+CREATE DATABASE world;
+USE world;
+
+CREATE SCHEMA bob;
+CREATE TABLE bob.country
+(
+ id int,
+ name varchar(20)
+);
+
+insert into bob.country
+values (1, 'India');
+insert into bob.country
+values (2, 'Russia');
+insert into bob.country
+values (3, 'USA');
+
+CREATE SCHEMA alice;
+CREATE TABLE alice.country
+(
+ id int,
+ name varchar(20)
+);
+
+insert into alice.country
+values (4, 'Italy');
+insert into alice.country
+values (5, 'Greece');
+insert into alice.country
+values (6, 'China');
+insert into alice.country
+values (7, 'Japan');
+
+-- Create a user and associate them with a default schema
+CREATE LOGIN greg WITH PASSWORD = 'GregPass123!$';
+CREATE USER greg FOR LOGIN greg WITH DEFAULT_SCHEMA=bob;
+-- Allow the user to connect to the database and run queries
+GRANT CONNECT, SELECT TO greg;
diff --git a/data/scripts/q_test_country_table_with_schema.oracle.sql
b/data/scripts/q_test_country_table_with_schema.oracle.sql
new file mode 100644
index 0000000..74aa0d9
--- /dev/null
+++ b/data/scripts/q_test_country_table_with_schema.oracle.sql
@@ -0,0 +1,55 @@
+-- In Oracle diving the tables in different namespaces/schemas is achieved via
different users. The CREATE SCHEMA
+-- statement exists in Oracle but has different semantics than those defined
by SQL Standard and those adopted in other
+-- DBMS.
+
+-- In order to create the so-called "local" users in oracle you need to be
connected to the Pluggable Database (PDB)
+-- and not to the Container Database (CDB). In Oracle XE edition, used by this
tests, the default and only PDB is
+-- XEPDB1.
+ALTER SESSION SET CONTAINER = XEPDB1;
+
+-- Create the bob schema/user and give appropriate connections to be able to
connect to the database
+CREATE USER bob IDENTIFIED BY bobpass;
+ALTER USER bob QUOTA UNLIMITED ON users;
+GRANT CREATE SESSION TO bob;
+
+CREATE TABLE bob.country
+(
+ id int,
+ name varchar(20)
+);
+
+insert into bob.country
+values (1, 'India');
+insert into bob.country
+values (2, 'Russia');
+insert into bob.country
+values (3, 'USA');
+
+-- Create the alice schema/user and give appropriate connections to be able to
connect to the database
+CREATE USER alice IDENTIFIED BY alicepass;
+ALTER USER alice QUOTA UNLIMITED ON users;
+
+GRANT CREATE SESSION TO alice;
+CREATE TABLE alice.country
+(
+ id int,
+ name varchar(20)
+);
+
+insert into alice.country
+values (4, 'Italy');
+insert into alice.country
+values (5, 'Greece');
+insert into alice.country
+values (6, 'China');
+insert into alice.country
+values (7, 'Japan');
+
+-- Without the SELECT ANY privilege a user cannot see the tables/views of
another user. In other words when a user
+-- connects to the database using a specific user and schema it is not
possible refer to tables in another user/schema
+-- namespace.
+GRANT SELECT ANY TABLE TO bob;
+GRANT SELECT ANY TABLE TO alice;
+-- Allow the users to perform inserts on any table/view in the database, and
not only those present on their own schema
+GRANT INSERT ANY TABLE TO bob;
+GRANT INSERT ANY TABLE TO alice;
\ No newline at end of file
diff --git a/data/scripts/q_test_country_table_with_schema.postgres.sql
b/data/scripts/q_test_country_table_with_schema.postgres.sql
new file mode 100644
index 0000000..60875f2
--- /dev/null
+++ b/data/scripts/q_test_country_table_with_schema.postgres.sql
@@ -0,0 +1,36 @@
+CREATE SCHEMA bob;
+CREATE TABLE bob.country
+(
+ id int,
+ name varchar(20)
+);
+
+insert into bob.country
+values (1, 'India');
+insert into bob.country
+values (2, 'Russia');
+insert into bob.country
+values (3, 'USA');
+
+CREATE SCHEMA alice;
+CREATE TABLE alice.country
+(
+ id int,
+ name varchar(20)
+);
+
+insert into alice.country
+values (4, 'Italy');
+insert into alice.country
+values (5, 'Greece');
+insert into alice.country
+values (6, 'China');
+insert into alice.country
+values (7, 'Japan');
+
+-- Create a user and associate them with a default schema <=> search_path
+CREATE ROLE greg WITH LOGIN PASSWORD 'GregPass123!$';
+ALTER ROLE greg SET search_path TO bob;
+-- Grant the necessary permissions to be able to access the schema
+GRANT USAGE ON SCHEMA bob TO greg;
+GRANT SELECT ON ALL TABLES IN SCHEMA bob TO greg;
diff --git
a/jdbc-handler/src/main/java/org/apache/hive/storage/jdbc/conf/JdbcStorageConfigManager.java
b/jdbc-handler/src/main/java/org/apache/hive/storage/jdbc/conf/JdbcStorageConfigManager.java
index 182ccfd..f7f3dd6 100644
---
a/jdbc-handler/src/main/java/org/apache/hive/storage/jdbc/conf/JdbcStorageConfigManager.java
+++
b/jdbc-handler/src/main/java/org/apache/hive/storage/jdbc/conf/JdbcStorageConfigManager.java
@@ -160,34 +160,6 @@ public class JdbcStorageConfigManager {
return config.get(key.getPropertyName());
}
- public static String getOrigQueryToExecute(Configuration config) {
- String query;
- String tableName = config.get(Constants.JDBC_TABLE);
- if (tableName != null) {
- // We generate query as select *
- query = "select * from " + tableName;
- } else {
- query = config.get(Constants.JDBC_QUERY);
- }
-
- return query;
- }
-
- public static String getQueryToExecute(Configuration config) {
- String query = config.get(Constants.JDBC_QUERY);
- if (query != null) {
- // Already defined query, we return it
- return query;
- }
-
- // We generate query as select *
- String tableName = config.get(JdbcStorageConfig.TABLE.getPropertyName());
- query = "select * from " + tableName;
-
- return query;
- }
-
-
private static boolean isEmptyString(String value) {
return ((value == null) || (value.trim().isEmpty()));
}
diff --git
a/jdbc-handler/src/main/java/org/apache/hive/storage/jdbc/dao/GenericJdbcDatabaseAccessor.java
b/jdbc-handler/src/main/java/org/apache/hive/storage/jdbc/dao/GenericJdbcDatabaseAccessor.java
index 1574853..3193378 100644
---
a/jdbc-handler/src/main/java/org/apache/hive/storage/jdbc/dao/GenericJdbcDatabaseAccessor.java
+++
b/jdbc-handler/src/main/java/org/apache/hive/storage/jdbc/dao/GenericJdbcDatabaseAccessor.java
@@ -50,6 +50,8 @@ import java.util.Properties;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
+import static com.google.common.base.MoreObjects.firstNonNull;
+
/**
* A data accessor that should in theory work with all JDBC compliant database
drivers.
*/
@@ -74,7 +76,10 @@ public class GenericJdbcDatabaseAccessor implements
DatabaseAccessor {
try {
initializeDatabaseConnection(conf);
- String query = JdbcStorageConfigManager.getOrigQueryToExecute(conf);
+ String tableName = getQualifiedTableName(conf);
+ // Order is important since we need to obtain the original (as specified
by the user) column names. JDBC_QUERY
+ // may be a generated/optimized query set by CBO with potentially
different aliases than the original columns.
+ String query = firstNonNull(selectAllFromTable(tableName),
conf.get(Constants.JDBC_QUERY));
String metadataQuery = getMetaDataQuery(query);
LOGGER.debug("Query to execute is [{}]", metadataQuery);
@@ -114,7 +119,10 @@ public class GenericJdbcDatabaseAccessor implements
DatabaseAccessor {
try {
initializeDatabaseConnection(conf);
- String sql = JdbcStorageConfigManager.getQueryToExecute(conf);
+ String tableName = getQualifiedTableName(conf);
+ // Always use JDBC_QUERY if available both for correctness and
performance. JDBC_QUERY can be set by the user
+ // or the CBO including pushdown optimizations. SELECT all query should
be used only when JDBC_QUERY is null.
+ String sql = firstNonNull(conf.get(Constants.JDBC_QUERY),
selectAllFromTable(tableName));
String countQuery = "SELECT COUNT(*) FROM (" + sql + ") tmptable";
LOGGER.info("Query to execute is [{}]", countQuery);
@@ -154,8 +162,10 @@ public class GenericJdbcDatabaseAccessor implements
DatabaseAccessor {
try {
initializeDatabaseConnection(conf);
- String tableName = conf.get(Constants.JDBC_TABLE);
- String sql = JdbcStorageConfigManager.getQueryToExecute(conf);
+ String tableName = getQualifiedTableName(conf);
+ // Always use JDBC_QUERY if available both for correctness and
performance. JDBC_QUERY can be set by the user
+ // or the CBO including pushdown optimizations. SELECT all query should
be used only when JDBC_QUERY is null.
+ String sql = firstNonNull(conf.get(Constants.JDBC_QUERY),
selectAllFromTable(tableName));
String partitionQuery;
if (partitionColumn != null) {
partitionQuery = addBoundaryToQuery(tableName, sql, partitionColumn,
lowerBound, upperBound);
@@ -181,7 +191,7 @@ public class GenericJdbcDatabaseAccessor implements
DatabaseAccessor {
public RecordWriter getRecordWriter(TaskAttemptContext context)
throws IOException {
Configuration conf = context.getConfiguration();
- String tableName = conf.get(JdbcStorageConfig.TABLE.getPropertyName());
+ String tableName = getQualifiedTableName(conf);
if (tableName == null || tableName.isEmpty()) {
throw new IllegalArgumentException("Table name should be defined");
@@ -404,7 +414,10 @@ public class GenericJdbcDatabaseAccessor implements
DatabaseAccessor {
try {
Preconditions.checkArgument(retrieveMin || retrieveMax);
initializeDatabaseConnection(conf);
- String sql = JdbcStorageConfigManager.getOrigQueryToExecute(conf);
+ String tableName = getQualifiedTableName(conf);
+ // Order is important since we need to retain the original (as specified
by the user) column names. The partition
+ // column, used below, is user specified so the column names should
match.
+ String sql = firstNonNull(selectAllFromTable(tableName),
conf.get(Constants.JDBC_QUERY));
String minClause = "MIN(" + quote() + partitionColumn + quote() + ")";
String maxClause = "MAX(" + quote() + partitionColumn + quote() + ")";
String countQuery = "SELECT ";
@@ -464,4 +477,17 @@ public class GenericJdbcDatabaseAccessor implements
DatabaseAccessor {
public boolean needColumnQuote() {
return true;
}
+
+ private static String getQualifiedTableName(Configuration conf) {
+ String tableName = conf.get(Constants.JDBC_TABLE);
+ if (tableName == null) {
+ return null;
+ }
+ String schemaName = conf.get(Constants.JDBC_SCHEMA);
+ return schemaName == null ? tableName : schemaName + "." + tableName;
+ }
+
+ private static String selectAllFromTable(String tableName) {
+ return tableName == null ? null : "select * from " + tableName;
+ }
}
diff --git a/ql/src/test/queries/clientpositive/jdbc_table_dml_postgres.q
b/ql/src/test/queries/clientpositive/jdbc_table_dml_postgres.q
new file mode 100644
index 0000000..b224d06
--- /dev/null
+++ b/ql/src/test/queries/clientpositive/jdbc_table_dml_postgres.q
@@ -0,0 +1,17 @@
+--! qt:database:postgres:q_test_country_table.sql
+
+CREATE EXTERNAL TABLE country (id int, name varchar(20))
+STORED BY 'org.apache.hive.storage.jdbc.JdbcStorageHandler'
+TBLPROPERTIES (
+ "hive.sql.database.type" = "POSTGRES",
+ "hive.sql.jdbc.driver" = "org.postgresql.Driver",
+ "hive.sql.jdbc.url" = "jdbc:postgresql://localhost:5432/qtestDB",
+ "hive.sql.dbcp.username" = "qtestuser",
+ "hive.sql.dbcp.password" = "qtestpassword",
+ "hive.sql.table" = "country");
+
+SELECT * FROM country;
+EXPLAIN CBO INSERT INTO country VALUES (8, 'Hungary');
+EXPLAIN INSERT INTO country VALUES (8, 'Hungary');
+INSERT INTO country VALUES (8, 'Hungary');
+SELECT * FROM country;
diff --git
a/ql/src/test/queries/clientpositive/jdbc_table_with_schema_mariadb.q
b/ql/src/test/queries/clientpositive/jdbc_table_with_schema_mariadb.q
new file mode 100644
index 0000000..b83ee6c
--- /dev/null
+++ b/ql/src/test/queries/clientpositive/jdbc_table_with_schema_mariadb.q
@@ -0,0 +1,72 @@
+--! qt:database:mariadb:q_test_country_table_with_schema.mariadb.sql
+
+-- In MariaDB (and MySQL) CREATE SCHEMA is a synonym to CREATE DATABASE so the
use of hive.sql.schema is not required.
+-- A MariaDB table can be uniquely identified by including the database/schema
name in the JDBC URL and specifying the
+-- hive.sql.table property.
+
+-- Connecting to MariaDB without specifying a database name (e.g.,
jdbc:mariadb://localhost:3309/) may create problems
+-- when a table with the same name exists in multiple databases. The problem
could be avoided by setting the
+-- hive.sql.schema property but unfortunately the JDBC driver of MariaDB
ignores schema information.
+
+-- Some JDBC APIs require the catalog, schema, and table names to be passed
exactly as they are stored in the database.
+-- MariaDB stores unquoted identifiers by first converting them to lowercase
thus the hive.sql.schema and
+-- hive.sql.table properties below are specified in lowercase.
+
+-- The hive.sql.schema property is optional; bob schema is inferred from the
JDBC URL
+CREATE EXTERNAL TABLE country_0 (id int, name varchar(20))
+ STORED BY 'org.apache.hive.storage.jdbc.JdbcStorageHandler'
+ TBLPROPERTIES (
+ "hive.sql.database.type" = "MYSQL",
+ "hive.sql.jdbc.driver" = "org.mariadb.jdbc.Driver",
+ "hive.sql.jdbc.url" = "jdbc:mariadb://localhost:3309/bob",
+ "hive.sql.dbcp.username" = "root",
+ "hive.sql.dbcp.password" = "qtestpassword",
+ "hive.sql.table" = "country");
+
+EXPLAIN CBO SELECT COUNT(*) FROM country_0;
+SELECT COUNT(*) FROM country_0;
+
+-- The hive.sql.schema property can be specified with the same value as the
database name in the URL but does not
+-- provide any additional benefits.
+CREATE EXTERNAL TABLE country_1 (id int, name varchar(20))
+ STORED BY 'org.apache.hive.storage.jdbc.JdbcStorageHandler'
+ TBLPROPERTIES (
+ "hive.sql.database.type" = "MYSQL",
+ "hive.sql.jdbc.driver" = "org.mariadb.jdbc.Driver",
+ "hive.sql.jdbc.url" = "jdbc:mariadb://localhost:3309/bob",
+ "hive.sql.dbcp.username" = "root",
+ "hive.sql.dbcp.password" = "qtestpassword",
+ "hive.sql.schema" = "bob",
+ "hive.sql.table" = "country");
+
+EXPLAIN CBO SELECT COUNT(*) FROM country_1;
+SELECT COUNT(*) FROM country_1;
+
+CREATE EXTERNAL TABLE country_2 (id int, name varchar(20))
+ STORED BY 'org.apache.hive.storage.jdbc.JdbcStorageHandler'
+ TBLPROPERTIES (
+ "hive.sql.database.type" = "MYSQL",
+ "hive.sql.jdbc.driver" = "org.mariadb.jdbc.Driver",
+ "hive.sql.jdbc.url" = "jdbc:mariadb://localhost:3309/alice",
+ "hive.sql.dbcp.username" = "root",
+ "hive.sql.dbcp.password" = "qtestpassword",
+ "hive.sql.table" = "country");
+
+EXPLAIN CBO SELECT COUNT(*) FROM country_2;
+SELECT COUNT(*) FROM country_2;
+
+-- It is possible to have the JDBC URL and hive.sql.schema pointing to
different databases/schemas but it is confusing
+-- and leads to the same result which could be achieved by using exclusively
the URL.
+CREATE EXTERNAL TABLE country_3 (id int, name varchar(20))
+ STORED BY 'org.apache.hive.storage.jdbc.JdbcStorageHandler'
+ TBLPROPERTIES (
+ "hive.sql.database.type" = "MYSQL",
+ "hive.sql.jdbc.driver" = "org.mariadb.jdbc.Driver",
+ "hive.sql.jdbc.url" = "jdbc:mariadb://localhost:3309/bob",
+ "hive.sql.dbcp.username" = "root",
+ "hive.sql.dbcp.password" = "qtestpassword",
+ "hive.sql.schema" = "alice",
+ "hive.sql.table" = "country");
+
+EXPLAIN CBO SELECT COUNT(*) FROM country_3;
+SELECT COUNT(*) FROM country_3;
diff --git a/ql/src/test/queries/clientpositive/jdbc_table_with_schema_mssql.q
b/ql/src/test/queries/clientpositive/jdbc_table_with_schema_mssql.q
new file mode 100644
index 0000000..9594061
--- /dev/null
+++ b/ql/src/test/queries/clientpositive/jdbc_table_with_schema_mssql.q
@@ -0,0 +1,54 @@
+--! qt:database:mssql:q_test_country_table_with_schema.mssql.sql
+-- Microsoft SQL server allows multiple schemas per database so to
disambiguate between tables in different schemas it
+-- is necessary to set the hive.sql.schema property properly.
+
+-- Some JDBC APIs require the catalog, schema, and table names to be passed
exactly as they are stored in the database.
+-- MSSQL stores unquoted identifiers by first converting them to lowercase
thus the hive.sql.schema and
+-- hive.sql.table properties below are specified in lowercase.
+
+CREATE EXTERNAL TABLE country_0 (id int, name varchar(20))
+STORED BY 'org.apache.hive.storage.jdbc.JdbcStorageHandler'
+TBLPROPERTIES (
+ "hive.sql.database.type" = "MSSQL",
+ "hive.sql.jdbc.driver" = "com.microsoft.sqlserver.jdbc.SQLServerDriver",
+ "hive.sql.jdbc.url" =
"jdbc:sqlserver://localhost:1433;DatabaseName=world;",
+ "hive.sql.dbcp.username" = "sa",
+ "hive.sql.dbcp.password" = "Its-a-s3cret",
+ "hive.sql.schema" = "bob",
+ "hive.sql.table" = "country");
+
+EXPLAIN CBO SELECT COUNT(*) FROM country_0;
+SELECT COUNT(*) FROM country_0;
+
+CREATE EXTERNAL TABLE country_1 (id int, name varchar(20))
+STORED BY 'org.apache.hive.storage.jdbc.JdbcStorageHandler'
+TBLPROPERTIES (
+ "hive.sql.database.type" = "MSSQL",
+ "hive.sql.jdbc.driver" = "com.microsoft.sqlserver.jdbc.SQLServerDriver",
+ "hive.sql.jdbc.url" =
"jdbc:sqlserver://localhost:1433;DatabaseName=world;",
+ "hive.sql.dbcp.username" = "sa",
+ "hive.sql.dbcp.password" = "Its-a-s3cret",
+ "hive.sql.schema" = "alice",
+ "hive.sql.table" = "country");
+
+EXPLAIN CBO SELECT COUNT(*) FROM country_1;
+SELECT COUNT(*) FROM country_1;
+
+-- Test DML statements are working fine when accessing table in non-default
schema
+INSERT INTO country_1 VALUES (8, 'Hungary');
+SELECT * FROM country_1;
+
+-- A user in MSSQL server can be assigned a default schema. In that case
specifying the hive.sql.schema property is
+-- redundant.
+CREATE EXTERNAL TABLE country_2 (id int, name varchar(20))
+STORED BY 'org.apache.hive.storage.jdbc.JdbcStorageHandler'
+TBLPROPERTIES (
+ "hive.sql.database.type" = "MSSQL",
+ "hive.sql.jdbc.driver" = "com.microsoft.sqlserver.jdbc.SQLServerDriver",
+ "hive.sql.jdbc.url" =
"jdbc:sqlserver://localhost:1433;DatabaseName=world;",
+ "hive.sql.dbcp.username" = "greg",
+ "hive.sql.dbcp.password" = "GregPass123!$",
+ "hive.sql.table" = "country");
+
+EXPLAIN CBO SELECT COUNT(*) FROM country_2;
+SELECT COUNT(*) FROM country_2;
diff --git a/ql/src/test/queries/clientpositive/jdbc_table_with_schema_oracle.q
b/ql/src/test/queries/clientpositive/jdbc_table_with_schema_oracle.q
new file mode 100644
index 0000000..805c066
--- /dev/null
+++ b/ql/src/test/queries/clientpositive/jdbc_table_with_schema_oracle.q
@@ -0,0 +1,57 @@
+--! qt:database:oracle:q_test_country_table_with_schema.oracle.sql
+-- Oracle does not allow explicitly the creation of different
namespaces/schemas in the same database. This can be
+-- achieved by creating different users where each user is associated with a
schema having the same name.
+
+-- Some JDBC APIs require the catalog, schema, and table names to be passed
exactly as they are stored in the database.
+-- Oracle stores unquoted identifiers by first converting them to uppercase
thus the hive.sql.schema and hive.sql.table
+-- properties below are specified in uppercase.
+
+-- Accessing table in the same namespace/schema with the user with explicit
schema declaration
+CREATE EXTERNAL TABLE country_0 (id int, name varchar(20))
+STORED BY 'org.apache.hive.storage.jdbc.JdbcStorageHandler'
+TBLPROPERTIES (
+ "hive.sql.database.type" = "ORACLE",
+ "hive.sql.jdbc.driver" = "oracle.jdbc.OracleDriver",
+ "hive.sql.jdbc.url" = "jdbc:oracle:thin:@//localhost:1521/XEPDB1",
+ "hive.sql.dbcp.username" = "bob",
+ "hive.sql.dbcp.password" = "bobpass",
+ "hive.sql.schema" = "BOB",
+ "hive.sql.table" = "COUNTRY"
+ );
+EXPLAIN CBO SELECT COUNT(*) FROM country_0;
+SELECT COUNT(*) FROM country_0;
+
+-- Accessing table in the same namespace/schema with the user without explicit
schema declaration; schema inferred
+-- automatically by Oracle.
+CREATE EXTERNAL TABLE country_1 (id int, name varchar(20))
+ STORED BY 'org.apache.hive.storage.jdbc.JdbcStorageHandler'
+ TBLPROPERTIES (
+ "hive.sql.database.type" = "ORACLE",
+ "hive.sql.jdbc.driver" = "oracle.jdbc.OracleDriver",
+ "hive.sql.jdbc.url" = "jdbc:oracle:thin:@//localhost:1521/XEPDB1",
+ "hive.sql.dbcp.username" = "bob",
+ "hive.sql.dbcp.password" = "bobpass",
+ "hive.sql.table" = "COUNTRY"
+ );
+EXPLAIN CBO SELECT COUNT(*) FROM country_1;
+SELECT COUNT(*) FROM country_1;
+
+-- Accessing table in a different namespace/schema with the user; schema
declaration is mandatory.
+-- User must have the necessary permissions to access another schema
+CREATE EXTERNAL TABLE country_2 (id int, name varchar(20))
+STORED BY 'org.apache.hive.storage.jdbc.JdbcStorageHandler'
+TBLPROPERTIES (
+ "hive.sql.database.type" = "ORACLE",
+ "hive.sql.jdbc.driver" = "oracle.jdbc.OracleDriver",
+ "hive.sql.jdbc.url" = "jdbc:oracle:thin:@//localhost:1521/XEPDB1",
+ "hive.sql.dbcp.username" = "bob",
+ "hive.sql.dbcp.password" = "bobpass",
+ "hive.sql.schema" = "ALICE",
+ "hive.sql.table" = "COUNTRY"
+ );
+EXPLAIN CBO SELECT COUNT(*) FROM country_2;
+SELECT COUNT(*) FROM country_2;
+
+-- Test DML statements are working fine when accessing table in non-default
schema
+INSERT INTO country_2 VALUES (8, 'Hungary');
+SELECT * FROM country_2;
diff --git
a/ql/src/test/queries/clientpositive/jdbc_table_with_schema_postgres.q
b/ql/src/test/queries/clientpositive/jdbc_table_with_schema_postgres.q
new file mode 100644
index 0000000..17010a0
--- /dev/null
+++ b/ql/src/test/queries/clientpositive/jdbc_table_with_schema_postgres.q
@@ -0,0 +1,54 @@
+--! qt:database:postgres:q_test_country_table_with_schema.postgres.sql
+-- Postgres allows multiple schemas per database so to disambiguate between
tables in different schemas it
+-- is necessary to set the hive.sql.schema property properly.
+
+-- Some JDBC APIs require the catalog, schema, and table names to be passed
exactly as they are stored in the database.
+-- Postgres stores unquoted identifiers by first converting them to lowercase
thus the hive.sql.schema and
+-- hive.sql.table properties below are specified in lowercase.
+
+CREATE EXTERNAL TABLE country_0 (id int, name varchar(20))
+STORED BY 'org.apache.hive.storage.jdbc.JdbcStorageHandler'
+TBLPROPERTIES (
+ "hive.sql.database.type" = "POSTGRES",
+ "hive.sql.jdbc.driver" = "org.postgresql.Driver",
+ "hive.sql.jdbc.url" = "jdbc:postgresql://localhost:5432/qtestDB",
+ "hive.sql.dbcp.username" = "qtestuser",
+ "hive.sql.dbcp.password" = "qtestpassword",
+ "hive.sql.schema" = "bob",
+ "hive.sql.table" = "country");
+
+EXPLAIN CBO SELECT COUNT(*) FROM country_0;
+SELECT COUNT(*) FROM country_0;
+
+CREATE EXTERNAL TABLE country_1 (id int, name varchar(20))
+ STORED BY 'org.apache.hive.storage.jdbc.JdbcStorageHandler'
+ TBLPROPERTIES (
+ "hive.sql.database.type" = "POSTGRES",
+ "hive.sql.jdbc.driver" = "org.postgresql.Driver",
+ "hive.sql.jdbc.url" = "jdbc:postgresql://localhost:5432/qtestDB",
+ "hive.sql.dbcp.username" = "qtestuser",
+ "hive.sql.dbcp.password" = "qtestpassword",
+ "hive.sql.schema" = "alice",
+ "hive.sql.table" = "country");
+
+EXPLAIN CBO SELECT COUNT(*) FROM country_1;
+SELECT COUNT(*) FROM country_1;
+
+-- Test DML statements are working fine when accessing table in non-default
schema
+INSERT INTO country_1 VALUES (8, 'Hungary');
+SELECT * FROM country_1;
+
+-- A user in Postgres can be assigned a default schema (aka. search_path). In
that case specifying the
+-- hive.sql.schema property is redundant.
+CREATE EXTERNAL TABLE country_2 (id int, name varchar(20))
+ STORED BY 'org.apache.hive.storage.jdbc.JdbcStorageHandler'
+ TBLPROPERTIES (
+ "hive.sql.database.type" = "POSTGRES",
+ "hive.sql.jdbc.driver" = "org.postgresql.Driver",
+ "hive.sql.jdbc.url" = "jdbc:postgresql://localhost:5432/qtestDB",
+ "hive.sql.dbcp.username" = "greg",
+ "hive.sql.dbcp.password" = "GregPass123!$",
+ "hive.sql.table" = "country");
+
+EXPLAIN CBO SELECT COUNT(*) FROM country_2;
+SELECT COUNT(*) FROM country_2;
diff --git
a/ql/src/test/results/clientpositive/llap/jdbc_table_dml_postgres.q.out
b/ql/src/test/results/clientpositive/llap/jdbc_table_dml_postgres.q.out
new file mode 100644
index 0000000..5628ab9
--- /dev/null
+++ b/ql/src/test/results/clientpositive/llap/jdbc_table_dml_postgres.q.out
@@ -0,0 +1,126 @@
+PREHOOK: query: CREATE EXTERNAL TABLE country (id int, name varchar(20))
+STORED BY 'org.apache.hive.storage.jdbc.JdbcStorageHandler'
+TBLPROPERTIES (
+ "hive.sql.database.type" = "POSTGRES",
+ "hive.sql.jdbc.driver" = "org.postgresql.Driver",
+ "hive.sql.jdbc.url" = "jdbc:postgresql://localhost:5432/qtestDB",
+ "hive.sql.dbcp.username" = "qtestuser",
+ "hive.sql.dbcp.password" = "qtestpassword",
+ "hive.sql.table" = "country")
+PREHOOK: type: CREATETABLE
+PREHOOK: Output: database:default
+PREHOOK: Output: default@country
+POSTHOOK: query: CREATE EXTERNAL TABLE country (id int, name varchar(20))
+STORED BY 'org.apache.hive.storage.jdbc.JdbcStorageHandler'
+TBLPROPERTIES (
+ "hive.sql.database.type" = "POSTGRES",
+ "hive.sql.jdbc.driver" = "org.postgresql.Driver",
+ "hive.sql.jdbc.url" = "jdbc:postgresql://localhost:5432/qtestDB",
+ "hive.sql.dbcp.username" = "qtestuser",
+ "hive.sql.dbcp.password" = "qtestpassword",
+ "hive.sql.table" = "country")
+POSTHOOK: type: CREATETABLE
+POSTHOOK: Output: database:default
+POSTHOOK: Output: default@country
+PREHOOK: query: SELECT * FROM country
+PREHOOK: type: QUERY
+PREHOOK: Input: default@country
+#### A masked pattern was here ####
+POSTHOOK: query: SELECT * FROM country
+POSTHOOK: type: QUERY
+POSTHOOK: Input: default@country
+#### A masked pattern was here ####
+1 India
+2 Russia
+3 USA
+PREHOOK: query: EXPLAIN CBO INSERT INTO country VALUES (8, 'Hungary')
+PREHOOK: type: QUERY
+PREHOOK: Input: _dummy_database@_dummy_table
+PREHOOK: Output: default@country
+POSTHOOK: query: EXPLAIN CBO INSERT INTO country VALUES (8, 'Hungary')
+POSTHOOK: type: QUERY
+POSTHOOK: Input: _dummy_database@_dummy_table
+POSTHOOK: Output: default@country
+CBO PLAN:
+HiveTableFunctionScan(invocation=[inline(ARRAY(ROW(8,
_UTF-16LE'Hungary':VARCHAR(2147483647) CHARACTER SET "UTF-16LE")))],
rowType=[RecordType(INTEGER col1, VARCHAR(2147483647) col2)])
+ HiveTableScan(table=[[_dummy_database, _dummy_table]],
table:alias=[_dummy_table])
+
+PREHOOK: query: EXPLAIN INSERT INTO country VALUES (8, 'Hungary')
+PREHOOK: type: QUERY
+PREHOOK: Input: _dummy_database@_dummy_table
+PREHOOK: Output: default@country
+POSTHOOK: query: EXPLAIN INSERT INTO country VALUES (8, 'Hungary')
+POSTHOOK: type: QUERY
+POSTHOOK: Input: _dummy_database@_dummy_table
+POSTHOOK: Output: default@country
+STAGE DEPENDENCIES:
+ Stage-0 is a root stage
+ Stage-1 is a root stage
+ Stage-2 is a root stage
+ Stage-4 depends on stages: Stage-2
+
+STAGE PLANS:
+ Stage: Stage-0
+ Unset Properties
+ table name: default.country
+ properties:
+ COLUMN_STATS_ACCURATE
+
+ Stage: Stage-1
+ Pre-Insert task
+
+ Stage: Stage-2
+ Tez
+#### A masked pattern was here ####
+ Vertices:
+ Map 1
+ Map Operator Tree:
+ TableScan
+ alias: _dummy_table
+ Row Limit Per Split: 1
+ Statistics: Num rows: 1 Data size: 10 Basic stats: COMPLETE
Column stats: COMPLETE
+ Select Operator
+ expressions: array(const struct(8,'Hungary')) (type:
array<struct<col1:int,col2:string>>)
+ outputColumnNames: _col0
+ Statistics: Num rows: 1 Data size: 48 Basic stats:
COMPLETE Column stats: COMPLETE
+ UDTF Operator
+ Statistics: Num rows: 1 Data size: 48 Basic stats:
COMPLETE Column stats: COMPLETE
+ function name: inline
+ Select Operator
+ expressions: col1 (type: int), CAST( col2 AS
varchar(20)) (type: varchar(20))
+ outputColumnNames: _col0, _col1
+ Statistics: Num rows: 1 Data size: 104 Basic stats:
COMPLETE Column stats: COMPLETE
+ File Output Operator
+ compressed: false
+ Statistics: Num rows: 1 Data size: 104 Basic stats:
COMPLETE Column stats: COMPLETE
+ table:
+ input format:
org.apache.hive.storage.jdbc.JdbcInputFormat
+ output format:
org.apache.hive.storage.jdbc.JdbcOutputFormat
+ serde: org.apache.hive.storage.jdbc.JdbcSerDe
+ name: default.country
+ Execution mode: llap
+ LLAP IO: no inputs
+
+ Stage: Stage-4
+ Commit Insert Hook
+
+PREHOOK: query: INSERT INTO country VALUES (8, 'Hungary')
+PREHOOK: type: QUERY
+PREHOOK: Input: _dummy_database@_dummy_table
+PREHOOK: Output: default@country
+POSTHOOK: query: INSERT INTO country VALUES (8, 'Hungary')
+POSTHOOK: type: QUERY
+POSTHOOK: Input: _dummy_database@_dummy_table
+POSTHOOK: Output: default@country
+PREHOOK: query: SELECT * FROM country
+PREHOOK: type: QUERY
+PREHOOK: Input: default@country
+#### A masked pattern was here ####
+POSTHOOK: query: SELECT * FROM country
+POSTHOOK: type: QUERY
+POSTHOOK: Input: default@country
+#### A masked pattern was here ####
+1 India
+2 Russia
+3 USA
+8 Hungary
diff --git
a/ql/src/test/results/clientpositive/llap/jdbc_table_with_schema_mariadb.q.out
b/ql/src/test/results/clientpositive/llap/jdbc_table_with_schema_mariadb.q.out
new file mode 100644
index 0000000..510accb
--- /dev/null
+++
b/ql/src/test/results/clientpositive/llap/jdbc_table_with_schema_mariadb.q.out
@@ -0,0 +1,188 @@
+PREHOOK: query: CREATE EXTERNAL TABLE country_0 (id int, name varchar(20))
+ STORED BY 'org.apache.hive.storage.jdbc.JdbcStorageHandler'
+ TBLPROPERTIES (
+ "hive.sql.database.type" = "MYSQL",
+ "hive.sql.jdbc.driver" = "org.mariadb.jdbc.Driver",
+ "hive.sql.jdbc.url" = "jdbc:mariadb://localhost:3309/bob",
+ "hive.sql.dbcp.username" = "root",
+ "hive.sql.dbcp.password" = "qtestpassword",
+ "hive.sql.table" = "country")
+PREHOOK: type: CREATETABLE
+PREHOOK: Output: database:default
+PREHOOK: Output: default@country_0
+POSTHOOK: query: CREATE EXTERNAL TABLE country_0 (id int, name varchar(20))
+ STORED BY 'org.apache.hive.storage.jdbc.JdbcStorageHandler'
+ TBLPROPERTIES (
+ "hive.sql.database.type" = "MYSQL",
+ "hive.sql.jdbc.driver" = "org.mariadb.jdbc.Driver",
+ "hive.sql.jdbc.url" = "jdbc:mariadb://localhost:3309/bob",
+ "hive.sql.dbcp.username" = "root",
+ "hive.sql.dbcp.password" = "qtestpassword",
+ "hive.sql.table" = "country")
+POSTHOOK: type: CREATETABLE
+POSTHOOK: Output: database:default
+POSTHOOK: Output: default@country_0
+PREHOOK: query: EXPLAIN CBO SELECT COUNT(*) FROM country_0
+PREHOOK: type: QUERY
+PREHOOK: Input: default@country_0
+#### A masked pattern was here ####
+POSTHOOK: query: EXPLAIN CBO SELECT COUNT(*) FROM country_0
+POSTHOOK: type: QUERY
+POSTHOOK: Input: default@country_0
+#### A masked pattern was here ####
+CBO PLAN:
+HiveJdbcConverter(convention=[JDBC.MYSQL])
+ JdbcAggregate(group=[{}], agg#0=[count()])
+ JdbcHiveTableScan(table=[[default, country_0]], table:alias=[country_0])
+
+PREHOOK: query: SELECT COUNT(*) FROM country_0
+PREHOOK: type: QUERY
+PREHOOK: Input: default@country_0
+#### A masked pattern was here ####
+POSTHOOK: query: SELECT COUNT(*) FROM country_0
+POSTHOOK: type: QUERY
+POSTHOOK: Input: default@country_0
+#### A masked pattern was here ####
+3
+PREHOOK: query: CREATE EXTERNAL TABLE country_1 (id int, name varchar(20))
+ STORED BY 'org.apache.hive.storage.jdbc.JdbcStorageHandler'
+ TBLPROPERTIES (
+ "hive.sql.database.type" = "MYSQL",
+ "hive.sql.jdbc.driver" = "org.mariadb.jdbc.Driver",
+ "hive.sql.jdbc.url" = "jdbc:mariadb://localhost:3309/bob",
+ "hive.sql.dbcp.username" = "root",
+ "hive.sql.dbcp.password" = "qtestpassword",
+ "hive.sql.schema" = "bob",
+ "hive.sql.table" = "country")
+PREHOOK: type: CREATETABLE
+PREHOOK: Output: database:default
+PREHOOK: Output: default@country_1
+POSTHOOK: query: CREATE EXTERNAL TABLE country_1 (id int, name varchar(20))
+ STORED BY 'org.apache.hive.storage.jdbc.JdbcStorageHandler'
+ TBLPROPERTIES (
+ "hive.sql.database.type" = "MYSQL",
+ "hive.sql.jdbc.driver" = "org.mariadb.jdbc.Driver",
+ "hive.sql.jdbc.url" = "jdbc:mariadb://localhost:3309/bob",
+ "hive.sql.dbcp.username" = "root",
+ "hive.sql.dbcp.password" = "qtestpassword",
+ "hive.sql.schema" = "bob",
+ "hive.sql.table" = "country")
+POSTHOOK: type: CREATETABLE
+POSTHOOK: Output: database:default
+POSTHOOK: Output: default@country_1
+PREHOOK: query: EXPLAIN CBO SELECT COUNT(*) FROM country_1
+PREHOOK: type: QUERY
+PREHOOK: Input: default@country_1
+#### A masked pattern was here ####
+POSTHOOK: query: EXPLAIN CBO SELECT COUNT(*) FROM country_1
+POSTHOOK: type: QUERY
+POSTHOOK: Input: default@country_1
+#### A masked pattern was here ####
+CBO PLAN:
+HiveJdbcConverter(convention=[JDBC.MYSQL])
+ JdbcAggregate(group=[{}], agg#0=[count()])
+ JdbcHiveTableScan(table=[[default, country_1]], table:alias=[country_1])
+
+PREHOOK: query: SELECT COUNT(*) FROM country_1
+PREHOOK: type: QUERY
+PREHOOK: Input: default@country_1
+#### A masked pattern was here ####
+POSTHOOK: query: SELECT COUNT(*) FROM country_1
+POSTHOOK: type: QUERY
+POSTHOOK: Input: default@country_1
+#### A masked pattern was here ####
+3
+PREHOOK: query: CREATE EXTERNAL TABLE country_2 (id int, name varchar(20))
+ STORED BY 'org.apache.hive.storage.jdbc.JdbcStorageHandler'
+ TBLPROPERTIES (
+ "hive.sql.database.type" = "MYSQL",
+ "hive.sql.jdbc.driver" = "org.mariadb.jdbc.Driver",
+ "hive.sql.jdbc.url" = "jdbc:mariadb://localhost:3309/alice",
+ "hive.sql.dbcp.username" = "root",
+ "hive.sql.dbcp.password" = "qtestpassword",
+ "hive.sql.table" = "country")
+PREHOOK: type: CREATETABLE
+PREHOOK: Output: database:default
+PREHOOK: Output: default@country_2
+POSTHOOK: query: CREATE EXTERNAL TABLE country_2 (id int, name varchar(20))
+ STORED BY 'org.apache.hive.storage.jdbc.JdbcStorageHandler'
+ TBLPROPERTIES (
+ "hive.sql.database.type" = "MYSQL",
+ "hive.sql.jdbc.driver" = "org.mariadb.jdbc.Driver",
+ "hive.sql.jdbc.url" = "jdbc:mariadb://localhost:3309/alice",
+ "hive.sql.dbcp.username" = "root",
+ "hive.sql.dbcp.password" = "qtestpassword",
+ "hive.sql.table" = "country")
+POSTHOOK: type: CREATETABLE
+POSTHOOK: Output: database:default
+POSTHOOK: Output: default@country_2
+PREHOOK: query: EXPLAIN CBO SELECT COUNT(*) FROM country_2
+PREHOOK: type: QUERY
+PREHOOK: Input: default@country_2
+#### A masked pattern was here ####
+POSTHOOK: query: EXPLAIN CBO SELECT COUNT(*) FROM country_2
+POSTHOOK: type: QUERY
+POSTHOOK: Input: default@country_2
+#### A masked pattern was here ####
+CBO PLAN:
+HiveJdbcConverter(convention=[JDBC.MYSQL])
+ JdbcAggregate(group=[{}], agg#0=[count()])
+ JdbcHiveTableScan(table=[[default, country_2]], table:alias=[country_2])
+
+PREHOOK: query: SELECT COUNT(*) FROM country_2
+PREHOOK: type: QUERY
+PREHOOK: Input: default@country_2
+#### A masked pattern was here ####
+POSTHOOK: query: SELECT COUNT(*) FROM country_2
+POSTHOOK: type: QUERY
+POSTHOOK: Input: default@country_2
+#### A masked pattern was here ####
+4
+PREHOOK: query: CREATE EXTERNAL TABLE country_3 (id int, name varchar(20))
+ STORED BY 'org.apache.hive.storage.jdbc.JdbcStorageHandler'
+ TBLPROPERTIES (
+ "hive.sql.database.type" = "MYSQL",
+ "hive.sql.jdbc.driver" = "org.mariadb.jdbc.Driver",
+ "hive.sql.jdbc.url" = "jdbc:mariadb://localhost:3309/bob",
+ "hive.sql.dbcp.username" = "root",
+ "hive.sql.dbcp.password" = "qtestpassword",
+ "hive.sql.schema" = "alice",
+ "hive.sql.table" = "country")
+PREHOOK: type: CREATETABLE
+PREHOOK: Output: database:default
+PREHOOK: Output: default@country_3
+POSTHOOK: query: CREATE EXTERNAL TABLE country_3 (id int, name varchar(20))
+ STORED BY 'org.apache.hive.storage.jdbc.JdbcStorageHandler'
+ TBLPROPERTIES (
+ "hive.sql.database.type" = "MYSQL",
+ "hive.sql.jdbc.driver" = "org.mariadb.jdbc.Driver",
+ "hive.sql.jdbc.url" = "jdbc:mariadb://localhost:3309/bob",
+ "hive.sql.dbcp.username" = "root",
+ "hive.sql.dbcp.password" = "qtestpassword",
+ "hive.sql.schema" = "alice",
+ "hive.sql.table" = "country")
+POSTHOOK: type: CREATETABLE
+POSTHOOK: Output: database:default
+POSTHOOK: Output: default@country_3
+PREHOOK: query: EXPLAIN CBO SELECT COUNT(*) FROM country_3
+PREHOOK: type: QUERY
+PREHOOK: Input: default@country_3
+#### A masked pattern was here ####
+POSTHOOK: query: EXPLAIN CBO SELECT COUNT(*) FROM country_3
+POSTHOOK: type: QUERY
+POSTHOOK: Input: default@country_3
+#### A masked pattern was here ####
+CBO PLAN:
+HiveJdbcConverter(convention=[JDBC.MYSQL])
+ JdbcAggregate(group=[{}], agg#0=[count()])
+ JdbcHiveTableScan(table=[[default, country_3]], table:alias=[country_3])
+
+PREHOOK: query: SELECT COUNT(*) FROM country_3
+PREHOOK: type: QUERY
+PREHOOK: Input: default@country_3
+#### A masked pattern was here ####
+POSTHOOK: query: SELECT COUNT(*) FROM country_3
+POSTHOOK: type: QUERY
+POSTHOOK: Input: default@country_3
+#### A masked pattern was here ####
+4
diff --git
a/ql/src/test/results/clientpositive/llap/jdbc_table_with_schema_mssql.q.out
b/ql/src/test/results/clientpositive/llap/jdbc_table_with_schema_mssql.q.out
new file mode 100644
index 0000000..0690e03
--- /dev/null
+++ b/ql/src/test/results/clientpositive/llap/jdbc_table_with_schema_mssql.q.out
@@ -0,0 +1,163 @@
+PREHOOK: query: CREATE EXTERNAL TABLE country_0 (id int, name varchar(20))
+STORED BY 'org.apache.hive.storage.jdbc.JdbcStorageHandler'
+TBLPROPERTIES (
+ "hive.sql.database.type" = "MSSQL",
+ "hive.sql.jdbc.driver" = "com.microsoft.sqlserver.jdbc.SQLServerDriver",
+ "hive.sql.jdbc.url" =
"jdbc:sqlserver://localhost:1433;DatabaseName=world;",
+ "hive.sql.dbcp.username" = "sa",
+ "hive.sql.dbcp.password" = "Its-a-s3cret",
+ "hive.sql.schema" = "bob",
+ "hive.sql.table" = "country")
+PREHOOK: type: CREATETABLE
+PREHOOK: Output: database:default
+PREHOOK: Output: default@country_0
+POSTHOOK: query: CREATE EXTERNAL TABLE country_0 (id int, name varchar(20))
+STORED BY 'org.apache.hive.storage.jdbc.JdbcStorageHandler'
+TBLPROPERTIES (
+ "hive.sql.database.type" = "MSSQL",
+ "hive.sql.jdbc.driver" = "com.microsoft.sqlserver.jdbc.SQLServerDriver",
+ "hive.sql.jdbc.url" =
"jdbc:sqlserver://localhost:1433;DatabaseName=world;",
+ "hive.sql.dbcp.username" = "sa",
+ "hive.sql.dbcp.password" = "Its-a-s3cret",
+ "hive.sql.schema" = "bob",
+ "hive.sql.table" = "country")
+POSTHOOK: type: CREATETABLE
+POSTHOOK: Output: database:default
+POSTHOOK: Output: default@country_0
+PREHOOK: query: EXPLAIN CBO SELECT COUNT(*) FROM country_0
+PREHOOK: type: QUERY
+PREHOOK: Input: default@country_0
+#### A masked pattern was here ####
+POSTHOOK: query: EXPLAIN CBO SELECT COUNT(*) FROM country_0
+POSTHOOK: type: QUERY
+POSTHOOK: Input: default@country_0
+#### A masked pattern was here ####
+CBO PLAN:
+HiveJdbcConverter(convention=[JDBC.MSSQL])
+ JdbcAggregate(group=[{}], agg#0=[count()])
+ JdbcHiveTableScan(table=[[default, country_0]], table:alias=[country_0])
+
+PREHOOK: query: SELECT COUNT(*) FROM country_0
+PREHOOK: type: QUERY
+PREHOOK: Input: default@country_0
+#### A masked pattern was here ####
+POSTHOOK: query: SELECT COUNT(*) FROM country_0
+POSTHOOK: type: QUERY
+POSTHOOK: Input: default@country_0
+#### A masked pattern was here ####
+3
+PREHOOK: query: CREATE EXTERNAL TABLE country_1 (id int, name varchar(20))
+STORED BY 'org.apache.hive.storage.jdbc.JdbcStorageHandler'
+TBLPROPERTIES (
+ "hive.sql.database.type" = "MSSQL",
+ "hive.sql.jdbc.driver" = "com.microsoft.sqlserver.jdbc.SQLServerDriver",
+ "hive.sql.jdbc.url" =
"jdbc:sqlserver://localhost:1433;DatabaseName=world;",
+ "hive.sql.dbcp.username" = "sa",
+ "hive.sql.dbcp.password" = "Its-a-s3cret",
+ "hive.sql.schema" = "alice",
+ "hive.sql.table" = "country")
+PREHOOK: type: CREATETABLE
+PREHOOK: Output: database:default
+PREHOOK: Output: default@country_1
+POSTHOOK: query: CREATE EXTERNAL TABLE country_1 (id int, name varchar(20))
+STORED BY 'org.apache.hive.storage.jdbc.JdbcStorageHandler'
+TBLPROPERTIES (
+ "hive.sql.database.type" = "MSSQL",
+ "hive.sql.jdbc.driver" = "com.microsoft.sqlserver.jdbc.SQLServerDriver",
+ "hive.sql.jdbc.url" =
"jdbc:sqlserver://localhost:1433;DatabaseName=world;",
+ "hive.sql.dbcp.username" = "sa",
+ "hive.sql.dbcp.password" = "Its-a-s3cret",
+ "hive.sql.schema" = "alice",
+ "hive.sql.table" = "country")
+POSTHOOK: type: CREATETABLE
+POSTHOOK: Output: database:default
+POSTHOOK: Output: default@country_1
+PREHOOK: query: EXPLAIN CBO SELECT COUNT(*) FROM country_1
+PREHOOK: type: QUERY
+PREHOOK: Input: default@country_1
+#### A masked pattern was here ####
+POSTHOOK: query: EXPLAIN CBO SELECT COUNT(*) FROM country_1
+POSTHOOK: type: QUERY
+POSTHOOK: Input: default@country_1
+#### A masked pattern was here ####
+CBO PLAN:
+HiveJdbcConverter(convention=[JDBC.MSSQL])
+ JdbcAggregate(group=[{}], agg#0=[count()])
+ JdbcHiveTableScan(table=[[default, country_1]], table:alias=[country_1])
+
+PREHOOK: query: SELECT COUNT(*) FROM country_1
+PREHOOK: type: QUERY
+PREHOOK: Input: default@country_1
+#### A masked pattern was here ####
+POSTHOOK: query: SELECT COUNT(*) FROM country_1
+POSTHOOK: type: QUERY
+POSTHOOK: Input: default@country_1
+#### A masked pattern was here ####
+4
+PREHOOK: query: INSERT INTO country_1 VALUES (8, 'Hungary')
+PREHOOK: type: QUERY
+PREHOOK: Input: _dummy_database@_dummy_table
+PREHOOK: Output: default@country_1
+POSTHOOK: query: INSERT INTO country_1 VALUES (8, 'Hungary')
+POSTHOOK: type: QUERY
+POSTHOOK: Input: _dummy_database@_dummy_table
+POSTHOOK: Output: default@country_1
+PREHOOK: query: SELECT * FROM country_1
+PREHOOK: type: QUERY
+PREHOOK: Input: default@country_1
+#### A masked pattern was here ####
+POSTHOOK: query: SELECT * FROM country_1
+POSTHOOK: type: QUERY
+POSTHOOK: Input: default@country_1
+#### A masked pattern was here ####
+4 Italy
+5 Greece
+6 China
+7 Japan
+8 Hungary
+PREHOOK: query: CREATE EXTERNAL TABLE country_2 (id int, name varchar(20))
+STORED BY 'org.apache.hive.storage.jdbc.JdbcStorageHandler'
+TBLPROPERTIES (
+ "hive.sql.database.type" = "MSSQL",
+ "hive.sql.jdbc.driver" = "com.microsoft.sqlserver.jdbc.SQLServerDriver",
+ "hive.sql.jdbc.url" =
"jdbc:sqlserver://localhost:1433;DatabaseName=world;",
+ "hive.sql.dbcp.username" = "greg",
+ "hive.sql.dbcp.password" = "GregPass123!$",
+ "hive.sql.table" = "country")
+PREHOOK: type: CREATETABLE
+PREHOOK: Output: database:default
+PREHOOK: Output: default@country_2
+POSTHOOK: query: CREATE EXTERNAL TABLE country_2 (id int, name varchar(20))
+STORED BY 'org.apache.hive.storage.jdbc.JdbcStorageHandler'
+TBLPROPERTIES (
+ "hive.sql.database.type" = "MSSQL",
+ "hive.sql.jdbc.driver" = "com.microsoft.sqlserver.jdbc.SQLServerDriver",
+ "hive.sql.jdbc.url" =
"jdbc:sqlserver://localhost:1433;DatabaseName=world;",
+ "hive.sql.dbcp.username" = "greg",
+ "hive.sql.dbcp.password" = "GregPass123!$",
+ "hive.sql.table" = "country")
+POSTHOOK: type: CREATETABLE
+POSTHOOK: Output: database:default
+POSTHOOK: Output: default@country_2
+PREHOOK: query: EXPLAIN CBO SELECT COUNT(*) FROM country_2
+PREHOOK: type: QUERY
+PREHOOK: Input: default@country_2
+#### A masked pattern was here ####
+POSTHOOK: query: EXPLAIN CBO SELECT COUNT(*) FROM country_2
+POSTHOOK: type: QUERY
+POSTHOOK: Input: default@country_2
+#### A masked pattern was here ####
+CBO PLAN:
+HiveJdbcConverter(convention=[JDBC.MSSQL])
+ JdbcAggregate(group=[{}], agg#0=[count()])
+ JdbcHiveTableScan(table=[[default, country_2]], table:alias=[country_2])
+
+PREHOOK: query: SELECT COUNT(*) FROM country_2
+PREHOOK: type: QUERY
+PREHOOK: Input: default@country_2
+#### A masked pattern was here ####
+POSTHOOK: query: SELECT COUNT(*) FROM country_2
+POSTHOOK: type: QUERY
+POSTHOOK: Input: default@country_2
+#### A masked pattern was here ####
+3
diff --git
a/ql/src/test/results/clientpositive/llap/jdbc_table_with_schema_oracle.q.out
b/ql/src/test/results/clientpositive/llap/jdbc_table_with_schema_oracle.q.out
new file mode 100644
index 0000000..a980eee
--- /dev/null
+++
b/ql/src/test/results/clientpositive/llap/jdbc_table_with_schema_oracle.q.out
@@ -0,0 +1,169 @@
+PREHOOK: query: CREATE EXTERNAL TABLE country_0 (id int, name varchar(20))
+STORED BY 'org.apache.hive.storage.jdbc.JdbcStorageHandler'
+TBLPROPERTIES (
+ "hive.sql.database.type" = "ORACLE",
+ "hive.sql.jdbc.driver" = "oracle.jdbc.OracleDriver",
+ "hive.sql.jdbc.url" = "jdbc:oracle:thin:@//localhost:1521/XEPDB1",
+ "hive.sql.dbcp.username" = "bob",
+ "hive.sql.dbcp.password" = "bobpass",
+ "hive.sql.schema" = "BOB",
+ "hive.sql.table" = "COUNTRY"
+ )
+PREHOOK: type: CREATETABLE
+PREHOOK: Output: database:default
+PREHOOK: Output: default@country_0
+POSTHOOK: query: CREATE EXTERNAL TABLE country_0 (id int, name varchar(20))
+STORED BY 'org.apache.hive.storage.jdbc.JdbcStorageHandler'
+TBLPROPERTIES (
+ "hive.sql.database.type" = "ORACLE",
+ "hive.sql.jdbc.driver" = "oracle.jdbc.OracleDriver",
+ "hive.sql.jdbc.url" = "jdbc:oracle:thin:@//localhost:1521/XEPDB1",
+ "hive.sql.dbcp.username" = "bob",
+ "hive.sql.dbcp.password" = "bobpass",
+ "hive.sql.schema" = "BOB",
+ "hive.sql.table" = "COUNTRY"
+ )
+POSTHOOK: type: CREATETABLE
+POSTHOOK: Output: database:default
+POSTHOOK: Output: default@country_0
+PREHOOK: query: EXPLAIN CBO SELECT COUNT(*) FROM country_0
+PREHOOK: type: QUERY
+PREHOOK: Input: default@country_0
+#### A masked pattern was here ####
+POSTHOOK: query: EXPLAIN CBO SELECT COUNT(*) FROM country_0
+POSTHOOK: type: QUERY
+POSTHOOK: Input: default@country_0
+#### A masked pattern was here ####
+CBO PLAN:
+HiveJdbcConverter(convention=[JDBC.ORACLE])
+ JdbcAggregate(group=[{}], agg#0=[count()])
+ JdbcHiveTableScan(table=[[default, country_0]], table:alias=[country_0])
+
+PREHOOK: query: SELECT COUNT(*) FROM country_0
+PREHOOK: type: QUERY
+PREHOOK: Input: default@country_0
+#### A masked pattern was here ####
+POSTHOOK: query: SELECT COUNT(*) FROM country_0
+POSTHOOK: type: QUERY
+POSTHOOK: Input: default@country_0
+#### A masked pattern was here ####
+3
+PREHOOK: query: CREATE EXTERNAL TABLE country_1 (id int, name varchar(20))
+ STORED BY 'org.apache.hive.storage.jdbc.JdbcStorageHandler'
+ TBLPROPERTIES (
+ "hive.sql.database.type" = "ORACLE",
+ "hive.sql.jdbc.driver" = "oracle.jdbc.OracleDriver",
+ "hive.sql.jdbc.url" = "jdbc:oracle:thin:@//localhost:1521/XEPDB1",
+ "hive.sql.dbcp.username" = "bob",
+ "hive.sql.dbcp.password" = "bobpass",
+ "hive.sql.table" = "COUNTRY"
+ )
+PREHOOK: type: CREATETABLE
+PREHOOK: Output: database:default
+PREHOOK: Output: default@country_1
+POSTHOOK: query: CREATE EXTERNAL TABLE country_1 (id int, name varchar(20))
+ STORED BY 'org.apache.hive.storage.jdbc.JdbcStorageHandler'
+ TBLPROPERTIES (
+ "hive.sql.database.type" = "ORACLE",
+ "hive.sql.jdbc.driver" = "oracle.jdbc.OracleDriver",
+ "hive.sql.jdbc.url" = "jdbc:oracle:thin:@//localhost:1521/XEPDB1",
+ "hive.sql.dbcp.username" = "bob",
+ "hive.sql.dbcp.password" = "bobpass",
+ "hive.sql.table" = "COUNTRY"
+ )
+POSTHOOK: type: CREATETABLE
+POSTHOOK: Output: database:default
+POSTHOOK: Output: default@country_1
+PREHOOK: query: EXPLAIN CBO SELECT COUNT(*) FROM country_1
+PREHOOK: type: QUERY
+PREHOOK: Input: default@country_1
+#### A masked pattern was here ####
+POSTHOOK: query: EXPLAIN CBO SELECT COUNT(*) FROM country_1
+POSTHOOK: type: QUERY
+POSTHOOK: Input: default@country_1
+#### A masked pattern was here ####
+CBO PLAN:
+HiveJdbcConverter(convention=[JDBC.ORACLE])
+ JdbcAggregate(group=[{}], agg#0=[count()])
+ JdbcHiveTableScan(table=[[default, country_1]], table:alias=[country_1])
+
+PREHOOK: query: SELECT COUNT(*) FROM country_1
+PREHOOK: type: QUERY
+PREHOOK: Input: default@country_1
+#### A masked pattern was here ####
+POSTHOOK: query: SELECT COUNT(*) FROM country_1
+POSTHOOK: type: QUERY
+POSTHOOK: Input: default@country_1
+#### A masked pattern was here ####
+3
+PREHOOK: query: CREATE EXTERNAL TABLE country_2 (id int, name varchar(20))
+STORED BY 'org.apache.hive.storage.jdbc.JdbcStorageHandler'
+TBLPROPERTIES (
+ "hive.sql.database.type" = "ORACLE",
+ "hive.sql.jdbc.driver" = "oracle.jdbc.OracleDriver",
+ "hive.sql.jdbc.url" = "jdbc:oracle:thin:@//localhost:1521/XEPDB1",
+ "hive.sql.dbcp.username" = "bob",
+ "hive.sql.dbcp.password" = "bobpass",
+ "hive.sql.schema" = "ALICE",
+ "hive.sql.table" = "COUNTRY"
+ )
+PREHOOK: type: CREATETABLE
+PREHOOK: Output: database:default
+PREHOOK: Output: default@country_2
+POSTHOOK: query: CREATE EXTERNAL TABLE country_2 (id int, name varchar(20))
+STORED BY 'org.apache.hive.storage.jdbc.JdbcStorageHandler'
+TBLPROPERTIES (
+ "hive.sql.database.type" = "ORACLE",
+ "hive.sql.jdbc.driver" = "oracle.jdbc.OracleDriver",
+ "hive.sql.jdbc.url" = "jdbc:oracle:thin:@//localhost:1521/XEPDB1",
+ "hive.sql.dbcp.username" = "bob",
+ "hive.sql.dbcp.password" = "bobpass",
+ "hive.sql.schema" = "ALICE",
+ "hive.sql.table" = "COUNTRY"
+ )
+POSTHOOK: type: CREATETABLE
+POSTHOOK: Output: database:default
+POSTHOOK: Output: default@country_2
+PREHOOK: query: EXPLAIN CBO SELECT COUNT(*) FROM country_2
+PREHOOK: type: QUERY
+PREHOOK: Input: default@country_2
+#### A masked pattern was here ####
+POSTHOOK: query: EXPLAIN CBO SELECT COUNT(*) FROM country_2
+POSTHOOK: type: QUERY
+POSTHOOK: Input: default@country_2
+#### A masked pattern was here ####
+CBO PLAN:
+HiveJdbcConverter(convention=[JDBC.ORACLE])
+ JdbcAggregate(group=[{}], agg#0=[count()])
+ JdbcHiveTableScan(table=[[default, country_2]], table:alias=[country_2])
+
+PREHOOK: query: SELECT COUNT(*) FROM country_2
+PREHOOK: type: QUERY
+PREHOOK: Input: default@country_2
+#### A masked pattern was here ####
+POSTHOOK: query: SELECT COUNT(*) FROM country_2
+POSTHOOK: type: QUERY
+POSTHOOK: Input: default@country_2
+#### A masked pattern was here ####
+4
+PREHOOK: query: INSERT INTO country_2 VALUES (8, 'Hungary')
+PREHOOK: type: QUERY
+PREHOOK: Input: _dummy_database@_dummy_table
+PREHOOK: Output: default@country_2
+POSTHOOK: query: INSERT INTO country_2 VALUES (8, 'Hungary')
+POSTHOOK: type: QUERY
+POSTHOOK: Input: _dummy_database@_dummy_table
+POSTHOOK: Output: default@country_2
+PREHOOK: query: SELECT * FROM country_2
+PREHOOK: type: QUERY
+PREHOOK: Input: default@country_2
+#### A masked pattern was here ####
+POSTHOOK: query: SELECT * FROM country_2
+POSTHOOK: type: QUERY
+POSTHOOK: Input: default@country_2
+#### A masked pattern was here ####
+4 Italy
+5 Greece
+6 China
+7 Japan
+8 Hungary
diff --git
a/ql/src/test/results/clientpositive/llap/jdbc_table_with_schema_postgres.q.out
b/ql/src/test/results/clientpositive/llap/jdbc_table_with_schema_postgres.q.out
new file mode 100644
index 0000000..6de6607
--- /dev/null
+++
b/ql/src/test/results/clientpositive/llap/jdbc_table_with_schema_postgres.q.out
@@ -0,0 +1,163 @@
+PREHOOK: query: CREATE EXTERNAL TABLE country_0 (id int, name varchar(20))
+STORED BY 'org.apache.hive.storage.jdbc.JdbcStorageHandler'
+TBLPROPERTIES (
+ "hive.sql.database.type" = "POSTGRES",
+ "hive.sql.jdbc.driver" = "org.postgresql.Driver",
+ "hive.sql.jdbc.url" = "jdbc:postgresql://localhost:5432/qtestDB",
+ "hive.sql.dbcp.username" = "qtestuser",
+ "hive.sql.dbcp.password" = "qtestpassword",
+ "hive.sql.schema" = "bob",
+ "hive.sql.table" = "country")
+PREHOOK: type: CREATETABLE
+PREHOOK: Output: database:default
+PREHOOK: Output: default@country_0
+POSTHOOK: query: CREATE EXTERNAL TABLE country_0 (id int, name varchar(20))
+STORED BY 'org.apache.hive.storage.jdbc.JdbcStorageHandler'
+TBLPROPERTIES (
+ "hive.sql.database.type" = "POSTGRES",
+ "hive.sql.jdbc.driver" = "org.postgresql.Driver",
+ "hive.sql.jdbc.url" = "jdbc:postgresql://localhost:5432/qtestDB",
+ "hive.sql.dbcp.username" = "qtestuser",
+ "hive.sql.dbcp.password" = "qtestpassword",
+ "hive.sql.schema" = "bob",
+ "hive.sql.table" = "country")
+POSTHOOK: type: CREATETABLE
+POSTHOOK: Output: database:default
+POSTHOOK: Output: default@country_0
+PREHOOK: query: EXPLAIN CBO SELECT COUNT(*) FROM country_0
+PREHOOK: type: QUERY
+PREHOOK: Input: default@country_0
+#### A masked pattern was here ####
+POSTHOOK: query: EXPLAIN CBO SELECT COUNT(*) FROM country_0
+POSTHOOK: type: QUERY
+POSTHOOK: Input: default@country_0
+#### A masked pattern was here ####
+CBO PLAN:
+HiveJdbcConverter(convention=[JDBC.POSTGRES])
+ JdbcAggregate(group=[{}], agg#0=[count()])
+ JdbcHiveTableScan(table=[[default, country_0]], table:alias=[country_0])
+
+PREHOOK: query: SELECT COUNT(*) FROM country_0
+PREHOOK: type: QUERY
+PREHOOK: Input: default@country_0
+#### A masked pattern was here ####
+POSTHOOK: query: SELECT COUNT(*) FROM country_0
+POSTHOOK: type: QUERY
+POSTHOOK: Input: default@country_0
+#### A masked pattern was here ####
+3
+PREHOOK: query: CREATE EXTERNAL TABLE country_1 (id int, name varchar(20))
+ STORED BY 'org.apache.hive.storage.jdbc.JdbcStorageHandler'
+ TBLPROPERTIES (
+ "hive.sql.database.type" = "POSTGRES",
+ "hive.sql.jdbc.driver" = "org.postgresql.Driver",
+ "hive.sql.jdbc.url" = "jdbc:postgresql://localhost:5432/qtestDB",
+ "hive.sql.dbcp.username" = "qtestuser",
+ "hive.sql.dbcp.password" = "qtestpassword",
+ "hive.sql.schema" = "alice",
+ "hive.sql.table" = "country")
+PREHOOK: type: CREATETABLE
+PREHOOK: Output: database:default
+PREHOOK: Output: default@country_1
+POSTHOOK: query: CREATE EXTERNAL TABLE country_1 (id int, name varchar(20))
+ STORED BY 'org.apache.hive.storage.jdbc.JdbcStorageHandler'
+ TBLPROPERTIES (
+ "hive.sql.database.type" = "POSTGRES",
+ "hive.sql.jdbc.driver" = "org.postgresql.Driver",
+ "hive.sql.jdbc.url" = "jdbc:postgresql://localhost:5432/qtestDB",
+ "hive.sql.dbcp.username" = "qtestuser",
+ "hive.sql.dbcp.password" = "qtestpassword",
+ "hive.sql.schema" = "alice",
+ "hive.sql.table" = "country")
+POSTHOOK: type: CREATETABLE
+POSTHOOK: Output: database:default
+POSTHOOK: Output: default@country_1
+PREHOOK: query: EXPLAIN CBO SELECT COUNT(*) FROM country_1
+PREHOOK: type: QUERY
+PREHOOK: Input: default@country_1
+#### A masked pattern was here ####
+POSTHOOK: query: EXPLAIN CBO SELECT COUNT(*) FROM country_1
+POSTHOOK: type: QUERY
+POSTHOOK: Input: default@country_1
+#### A masked pattern was here ####
+CBO PLAN:
+HiveJdbcConverter(convention=[JDBC.POSTGRES])
+ JdbcAggregate(group=[{}], agg#0=[count()])
+ JdbcHiveTableScan(table=[[default, country_1]], table:alias=[country_1])
+
+PREHOOK: query: SELECT COUNT(*) FROM country_1
+PREHOOK: type: QUERY
+PREHOOK: Input: default@country_1
+#### A masked pattern was here ####
+POSTHOOK: query: SELECT COUNT(*) FROM country_1
+POSTHOOK: type: QUERY
+POSTHOOK: Input: default@country_1
+#### A masked pattern was here ####
+4
+PREHOOK: query: INSERT INTO country_1 VALUES (8, 'Hungary')
+PREHOOK: type: QUERY
+PREHOOK: Input: _dummy_database@_dummy_table
+PREHOOK: Output: default@country_1
+POSTHOOK: query: INSERT INTO country_1 VALUES (8, 'Hungary')
+POSTHOOK: type: QUERY
+POSTHOOK: Input: _dummy_database@_dummy_table
+POSTHOOK: Output: default@country_1
+PREHOOK: query: SELECT * FROM country_1
+PREHOOK: type: QUERY
+PREHOOK: Input: default@country_1
+#### A masked pattern was here ####
+POSTHOOK: query: SELECT * FROM country_1
+POSTHOOK: type: QUERY
+POSTHOOK: Input: default@country_1
+#### A masked pattern was here ####
+4 Italy
+5 Greece
+6 China
+7 Japan
+8 Hungary
+PREHOOK: query: CREATE EXTERNAL TABLE country_2 (id int, name varchar(20))
+ STORED BY 'org.apache.hive.storage.jdbc.JdbcStorageHandler'
+ TBLPROPERTIES (
+ "hive.sql.database.type" = "POSTGRES",
+ "hive.sql.jdbc.driver" = "org.postgresql.Driver",
+ "hive.sql.jdbc.url" = "jdbc:postgresql://localhost:5432/qtestDB",
+ "hive.sql.dbcp.username" = "greg",
+ "hive.sql.dbcp.password" = "GregPass123!$",
+ "hive.sql.table" = "country")
+PREHOOK: type: CREATETABLE
+PREHOOK: Output: database:default
+PREHOOK: Output: default@country_2
+POSTHOOK: query: CREATE EXTERNAL TABLE country_2 (id int, name varchar(20))
+ STORED BY 'org.apache.hive.storage.jdbc.JdbcStorageHandler'
+ TBLPROPERTIES (
+ "hive.sql.database.type" = "POSTGRES",
+ "hive.sql.jdbc.driver" = "org.postgresql.Driver",
+ "hive.sql.jdbc.url" = "jdbc:postgresql://localhost:5432/qtestDB",
+ "hive.sql.dbcp.username" = "greg",
+ "hive.sql.dbcp.password" = "GregPass123!$",
+ "hive.sql.table" = "country")
+POSTHOOK: type: CREATETABLE
+POSTHOOK: Output: database:default
+POSTHOOK: Output: default@country_2
+PREHOOK: query: EXPLAIN CBO SELECT COUNT(*) FROM country_2
+PREHOOK: type: QUERY
+PREHOOK: Input: default@country_2
+#### A masked pattern was here ####
+POSTHOOK: query: EXPLAIN CBO SELECT COUNT(*) FROM country_2
+POSTHOOK: type: QUERY
+POSTHOOK: Input: default@country_2
+#### A masked pattern was here ####
+CBO PLAN:
+HiveJdbcConverter(convention=[JDBC.POSTGRES])
+ JdbcAggregate(group=[{}], agg#0=[count()])
+ JdbcHiveTableScan(table=[[default, country_2]], table:alias=[country_2])
+
+PREHOOK: query: SELECT COUNT(*) FROM country_2
+PREHOOK: type: QUERY
+PREHOOK: Input: default@country_2
+#### A masked pattern was here ####
+POSTHOOK: query: SELECT COUNT(*) FROM country_2
+POSTHOOK: type: QUERY
+POSTHOOK: Input: default@country_2
+#### A masked pattern was here ####
+3