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

Reply via email to