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 d35de01  HIVE-25594: Setup JDBC databases in tests via qt:database 
option (Stamatis Zampetakis, reviewed by Zoltan Haindrich, Alessandro Solimando)
d35de01 is described below

commit d35de014dd49fdcfe0aacb68e6c587beff6d1dea
Author: Stamatis Zampetakis <[email protected]>
AuthorDate: Wed Oct 6 12:18:18 2021 +0200

    HIVE-25594: Setup JDBC databases in tests via qt:database option (Stamatis 
Zampetakis, reviewed by Zoltan Haindrich, Alessandro Solimando)
    
    Main feature changes:
    1. Introduce QTestDatabaseHandler class for handling completely setup,
    init and cleanup of dockerized DBMS by using qt:database option.
    2. Drop TestMiniLlapExtDBCliDriver, with associated config, properties
    etc, and adapt tests to use the newly introduced qt:database option
    
    Code readability/extensibility changes:
    3. Refactor AbstractExternalDB and subclasses: (i) turn setters to
    getters; (ii) inline methods; (iii) reduce visibility when possibse
    (iv) drop redundant comments; (v) drop unnecessary logging and
    try/catch blocks; (vi) improve log messages, exceptions, and javadoc;
    (vii) always include SQLLine standard output/error in the logs; (viii)
    drop catch & print, log & throw patterns; (ix) use RuntimeException
    instead of checked IOException; (x) replace hard-coded string with
    class reference in logger; (xi) drop dependency to lang3.StringUtils
    
    Minor bug fixes & improvements:
    4. Ensure a root user is available when each database starts and rename
    methods in AbstractExternalDB accordingly.
    5. Do not create additional database users; it is not necessary.
    6. Use correct driver and docker image for MySQL database.
    7. Support additional databases (MariaDB, Oracle, MSSQLServer) for
    tests.
    
    Closes #2742
---
 data/scripts/derby/q_test_extDB_cleanup.derby.sql  |   3 -
 data/scripts/derby/q_test_extDB_init.derby.sql     |  27 ---
 data/scripts/mysql/q_test_extDB_cleanup.mysql.sql  |   3 -
 .../postgres/q_test_extDB_cleanup.postgres.sql     |   3 -
 .../postgres/q_test_extDB_init.postgres.sql        |  23 --
 data/scripts/q_test_author_table.sql               |   8 +
 data/scripts/q_test_book_table.sql                 |  10 +
 data/scripts/q_test_city_table.sql                 |  22 ++
 ...ql.sql => q_test_country_state_city_tables.sql} |   0
 data/scripts/q_test_country_table.sql              |  12 ++
 data/scripts/q_test_state_table.sql                |  18 ++
 itests/qtest/pom.xml                               |  12 ++
 .../hive/cli/TestMiniLlapExtDBCliDriver.java       |  65 ------
 .../test/resources/testconfiguration.properties    |   5 -
 .../hadoop/hive/cli/control/AbstractCliConfig.java |   6 -
 .../apache/hadoop/hive/cli/control/CliConfigs.java |  24 ---
 .../hadoop/hive/cli/control/CoreCliDriver.java     |   3 -
 .../org/apache/hadoop/hive/ql/QTestArguments.java  |  17 --
 .../org/apache/hadoop/hive/ql/QTestExternalDB.java |  57 -----
 .../java/org/apache/hadoop/hive/ql/QTestUtil.java  |  69 +-----
 .../hive/ql/externalDB/AbstractExternalDB.java     | 210 ++++++------------
 .../hadoop/hive/ql/externalDB/MSSQLServer.java     |  57 +++++
 .../apache/hadoop/hive/ql/externalDB/MariaDB.java  |  54 +++++
 .../hadoop/hive/ql/externalDB/MySQLExternalDB.java |  29 +--
 .../apache/hadoop/hive/ql/externalDB/Oracle.java   |  56 +++++
 .../hive/ql/externalDB/PostgresExternalDB.java     |  20 +-
 .../hive/ql/qoption/QTestDatabaseHandler.java      | 135 ++++++++++++
 .../ql/scheduled/QTestScheduledQueryCleaner.java   |   7 +-
 pom.xml                                            |   2 +
 .../queries/clientpositive/dataconnector_mysql.q   |   3 +-
 .../test/queries/clientpositive/qt_database_all.q  |  86 ++++++++
 .../queries/clientpositive/qt_database_mariadb.q   |  17 ++
 .../queries/clientpositive/qt_database_mssql.q     |  16 ++
 .../queries/clientpositive/qt_database_mysql.q     |  16 ++
 .../queries/clientpositive/qt_database_oracle.q    |  17 ++
 .../queries/clientpositive/qt_database_postgres.q  |  16 ++
 .../clientpositive/llap/dataconnector_mysql.q.out  |   4 +-
 .../clientpositive/llap/qt_database_all.q.out      | 235 +++++++++++++++++++++
 .../clientpositive/llap/qt_database_mariadb.q.out  |  45 ++++
 .../clientpositive/llap/qt_database_mssql.q.out    |  45 ++++
 .../clientpositive/llap/qt_database_mysql.q.out    |  45 ++++
 .../clientpositive/llap/qt_database_oracle.q.out   |  45 ++++
 .../clientpositive/llap/qt_database_postgres.q.out |  45 ++++
 43 files changed, 1117 insertions(+), 475 deletions(-)

diff --git a/data/scripts/derby/q_test_extDB_cleanup.derby.sql 
b/data/scripts/derby/q_test_extDB_cleanup.derby.sql
deleted file mode 100644
index e62f1f0..0000000
--- a/data/scripts/derby/q_test_extDB_cleanup.derby.sql
+++ /dev/null
@@ -1,3 +0,0 @@
-drop table country;
-drop table stats;
-drop table city;
diff --git a/data/scripts/derby/q_test_extDB_init.derby.sql 
b/data/scripts/derby/q_test_extDB_init.derby.sql
deleted file mode 100644
index b2a90d7..0000000
--- a/data/scripts/derby/q_test_extDB_init.derby.sql
+++ /dev/null
@@ -1,27 +0,0 @@
--- reference: 
https://medium.com/swlh/getting-started-with-apache-derby-9f6ca8dea873
-
-create table country (name char(30) not null unique);
-create table state (name char(30) not null unique,
-                    country_code int not null);
-create table city (name char(30) not null unique,
-                   state_code int not null);
-
-insert into country (name) values ('India');
-insert into country (name) values ('Russia');
-insert into country (name) values ('USA');
-
-insert into state (name,country_code) values ('Maharashtra',1);
-insert into state (name,country_code) values ('Madhya Pradesh',1);
-insert into state (name,country_code) values ('Moscow',3);
-insert into state (name,country_code) values ('Something',4);
-insert into state (name,country_code) values ('Florida',4);
-insert into state (name,country_code) values ('Texas',4);
-
-insert into city (name,state_code) values('Mumbai',1);
-insert into city (name,state_code) values('Pune',1);
-insert into city (name,state_code) values('Bhopal',2);
-insert into city (name,state_code) values('Indore',2);
-insert into city (name,state_code) values('Klin',3);
-insert into city (name,state_code) values('Los Angeles',5);
-insert into city (name,state_code) values('Plant City',5);
-insert into city (name,state_code) values('Arlington',6);
diff --git a/data/scripts/mysql/q_test_extDB_cleanup.mysql.sql 
b/data/scripts/mysql/q_test_extDB_cleanup.mysql.sql
deleted file mode 100644
index abe1cae..0000000
--- a/data/scripts/mysql/q_test_extDB_cleanup.mysql.sql
+++ /dev/null
@@ -1,3 +0,0 @@
-drop table if exists country;
-drop table if exists stats;
-drop table if exists city;
diff --git a/data/scripts/postgres/q_test_extDB_cleanup.postgres.sql 
b/data/scripts/postgres/q_test_extDB_cleanup.postgres.sql
deleted file mode 100644
index abe1cae..0000000
--- a/data/scripts/postgres/q_test_extDB_cleanup.postgres.sql
+++ /dev/null
@@ -1,3 +0,0 @@
-drop table if exists country;
-drop table if exists stats;
-drop table if exists city;
diff --git a/data/scripts/postgres/q_test_extDB_init.postgres.sql 
b/data/scripts/postgres/q_test_extDB_init.postgres.sql
deleted file mode 100644
index a9cb486..0000000
--- a/data/scripts/postgres/q_test_extDB_init.postgres.sql
+++ /dev/null
@@ -1,23 +0,0 @@
-create table if not exists country (name varchar(80) not null);
-create table if not exists state (name varchar(80) not null, country_code int 
not null);
-create table if not exists city (name varchar(80) not null, state_code int not 
null);
-
-insert into country (name) values ('India');
-insert into country (name) values ('Russia');
-insert into country (name) values ('USA');
-
-insert into state (name,country_code) values ('Maharashtra',1);
-insert into state (name,country_code) values ('Madhya Pradesh',1);
-insert into state (name,country_code) values ('Moscow',3);
-insert into state (name,country_code) values ('Something',4);
-insert into state (name,country_code) values ('Florida',4);
-insert into state (name,country_code) values ('Texas',4);
-
-insert into city (name,state_code) values('Mumbai',1);
-insert into city (name,state_code) values('Pune',1);
-insert into city (name,state_code) values('Bhopal',2);
-insert into city (name,state_code) values('Indore',2);
-insert into city (name,state_code) values('Klin',3);
-insert into city (name,state_code) values('Los Angeles',5);
-insert into city (name,state_code) values('Plant City',5);
-insert into city (name,state_code) values('Arlington',6);
diff --git a/data/scripts/q_test_author_table.sql 
b/data/scripts/q_test_author_table.sql
new file mode 100644
index 0000000..8f5e0d0
--- /dev/null
+++ b/data/scripts/q_test_author_table.sql
@@ -0,0 +1,8 @@
+create table author
+(
+    id int,
+    fname       varchar(20),
+    lname       varchar(20)
+);
+insert into author values (1, 'Victor', 'Hugo');
+insert into author values (2, 'Alexandre', 'Dumas');
diff --git a/data/scripts/q_test_book_table.sql 
b/data/scripts/q_test_book_table.sql
new file mode 100644
index 0000000..37686e1
--- /dev/null
+++ b/data/scripts/q_test_book_table.sql
@@ -0,0 +1,10 @@
+create table book
+(
+    id     int,
+    title  varchar(100),
+    author int
+);
+insert into book
+values (1, 'Les Miserables', 1);
+insert into book
+values (2, 'The Count Of Monte Cristo', 2);
diff --git a/data/scripts/q_test_city_table.sql 
b/data/scripts/q_test_city_table.sql
new file mode 100644
index 0000000..56a76a5
--- /dev/null
+++ b/data/scripts/q_test_city_table.sql
@@ -0,0 +1,22 @@
+create table if not exists city
+(
+    name       varchar(255) not null,
+    state int          not null
+);
+
+insert into city (name, state)
+values ('Mumbai', 1);
+insert into city (name, state)
+values ('Pune', 1);
+insert into city (name, state)
+values ('Bhopal', 2);
+insert into city (name, state)
+values ('Indore', 2);
+insert into city (name, state)
+values ('Klin', 3);
+insert into city (name, state)
+values ('Los Angeles', 5);
+insert into city (name, state)
+values ('Plant City', 5);
+insert into city (name, state)
+values ('Arlington', 6);
diff --git a/data/scripts/mysql/q_test_extDB_init.mysql.sql 
b/data/scripts/q_test_country_state_city_tables.sql
similarity index 100%
rename from data/scripts/mysql/q_test_extDB_init.mysql.sql
rename to data/scripts/q_test_country_state_city_tables.sql
diff --git a/data/scripts/q_test_country_table.sql 
b/data/scripts/q_test_country_table.sql
new file mode 100644
index 0000000..ce8010b
--- /dev/null
+++ b/data/scripts/q_test_country_table.sql
@@ -0,0 +1,12 @@
+CREATE TABLE country
+(
+    id   int,
+    name varchar(20)
+);
+
+insert into country
+values (1, 'India');
+insert into country
+values (2, 'Russia');
+insert into country
+values (3, 'USA');
diff --git a/data/scripts/q_test_state_table.sql 
b/data/scripts/q_test_state_table.sql
new file mode 100644
index 0000000..3f3edba
--- /dev/null
+++ b/data/scripts/q_test_state_table.sql
@@ -0,0 +1,18 @@
+create table state
+(
+    name    varchar(255) not null,
+    country int          not null
+);
+
+insert into state (name, country)
+values ('Maharashtra', 1);
+insert into state (name, country)
+values ('Madhya Pradesh', 1);
+insert into state (name, country)
+values ('Moscow', 3);
+insert into state (name, country)
+values ('Something', 4);
+insert into state (name, country)
+values ('Florida', 4);
+insert into state (name, country)
+values ('Texas', 4);
diff --git a/itests/qtest/pom.xml b/itests/qtest/pom.xml
index 53326dd..f772015 100644
--- a/itests/qtest/pom.xml
+++ b/itests/qtest/pom.xml
@@ -418,6 +418,18 @@
       <version>${postgres.version}</version>
       <scope>test</scope>
     </dependency>
+    <dependency>
+      <groupId>mysql</groupId>
+      <artifactId>mysql-connector-java</artifactId>
+      <version>${mysql.version}</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>com.oracle.database.jdbc</groupId>
+      <artifactId>ojdbc8</artifactId>
+      <version>${oracle.version}</version>
+      <scope>test</scope>
+    </dependency>
   </dependencies>
   <profiles>
     <profile>
diff --git 
a/itests/qtest/src/test/java/org/apache/hadoop/hive/cli/TestMiniLlapExtDBCliDriver.java
 
b/itests/qtest/src/test/java/org/apache/hadoop/hive/cli/TestMiniLlapExtDBCliDriver.java
deleted file mode 100644
index e1c804c..0000000
--- 
a/itests/qtest/src/test/java/org/apache/hadoop/hive/cli/TestMiniLlapExtDBCliDriver.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.hadoop.hive.cli;
-
-import java.io.File;
-import java.util.List;
-
-import org.apache.hadoop.hive.cli.control.CliAdapter;
-import org.apache.hadoop.hive.cli.control.CliConfigs;
-import org.apache.hadoop.hive.cli.control.SplitSupport;
-import org.junit.ClassRule;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.TestRule;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-import org.junit.runners.Parameterized.Parameters;
-
-@RunWith(Parameterized.class)
-public class TestMiniLlapExtDBCliDriver {
-
-    static CliAdapter adapter = new 
CliConfigs.MiniLlapExtDBCliConfig().getCliAdapter();
-
-    private static int N_SPLITS = 3;
-
-    @Parameters(name = "{0}")
-    public static List<Object[]> getParameters() throws Exception {
-        return SplitSupport.process(adapter.getParameters(), 
TestMiniLlapExtDBCliDriver.class, N_SPLITS);
-    }
-
-    @ClassRule
-    public static TestRule cliClassRule = adapter.buildClassRule();
-
-    @Rule
-    public TestRule cliTestRule = adapter.buildTestRule();
-
-    private String name;
-    private File qfile;
-
-    public TestMiniLlapExtDBCliDriver(String name, File qfile) {
-        this.name = name;
-        this.qfile = qfile;
-    }
-
-    @Test
-    public void testCliDriver() throws Exception {
-        adapter.runTest(name, qfile);
-    }
-
-}
diff --git a/itests/src/test/resources/testconfiguration.properties 
b/itests/src/test/resources/testconfiguration.properties
index 71b6fed..638af07 100644
--- a/itests/src/test/resources/testconfiguration.properties
+++ b/itests/src/test/resources/testconfiguration.properties
@@ -1251,11 +1251,6 @@ erasurecoding.only.query.files=\
   erasure_explain.q,\
   erasure_simple.q
 
-# tests that requires external database connection
-externalDB.llap.query.files=\
-  dataconnector.q,\
-  dataconnector_mysql.q
-
 iceberg.llap.query.files=\
   llap_iceberg_read.q,\
   vectorized_iceberg_read.q
diff --git 
a/itests/util/src/main/java/org/apache/hadoop/hive/cli/control/AbstractCliConfig.java
 
b/itests/util/src/main/java/org/apache/hadoop/hive/cli/control/AbstractCliConfig.java
index e21e40b..cc31ce9 100644
--- 
a/itests/util/src/main/java/org/apache/hadoop/hive/cli/control/AbstractCliConfig.java
+++ 
b/itests/util/src/main/java/org/apache/hadoop/hive/cli/control/AbstractCliConfig.java
@@ -36,7 +36,6 @@ import org.apache.commons.lang3.StringUtils;
 import org.apache.hadoop.hive.ql.QTestSystemProperties;
 import org.apache.hadoop.hive.ql.QTestMiniClusters.FsType;
 import org.apache.hadoop.hive.ql.QTestMiniClusters.MiniClusterType;
-import org.apache.hadoop.hive.ql.QTestExternalDB;
 import org.apache.hive.testutils.HiveTestEnvSetup;
 
 import com.google.common.base.Splitter;
@@ -61,7 +60,6 @@ public abstract class AbstractCliConfig {
   // these should have viable defaults
   private String cleanupScript;
   private String initScript;
-  private Set<QTestExternalDB> externalDBs = new LinkedHashSet<>();
   private String hiveConfDir;
   private MiniClusterType clusterType;
   private FsType fsType;
@@ -344,10 +342,6 @@ public abstract class AbstractCliConfig {
       this.initScript = initScript;
     }
   }
-  public Set<QTestExternalDB> getExternalDBs() { return externalDBs; }
-
-  protected void addExternalDB (QTestExternalDB externalDB) { 
this.externalDBs.add(externalDB); }
-
   public String getHiveConfDir() {
     return hiveConfDir;
   }
diff --git 
a/itests/util/src/main/java/org/apache/hadoop/hive/cli/control/CliConfigs.java 
b/itests/util/src/main/java/org/apache/hadoop/hive/cli/control/CliConfigs.java
index 3dbcf28..b69465c 100644
--- 
a/itests/util/src/main/java/org/apache/hadoop/hive/cli/control/CliConfigs.java
+++ 
b/itests/util/src/main/java/org/apache/hadoop/hive/cli/control/CliConfigs.java
@@ -24,7 +24,6 @@ import java.net.URL;
 import org.apache.hadoop.hive.ql.QTestMiniClusters;
 import org.apache.hadoop.hive.ql.QTestMiniClusters.MiniClusterType;
 import org.apache.hadoop.hive.ql.parse.CoreParseNegative;
-import org.apache.hadoop.hive.ql.QTestExternalDB;
 
 public class CliConfigs {
 
@@ -226,7 +225,6 @@ public class CliConfigs {
         excludesFrom(testConfigProps, "spark.only.query.files");
         excludesFrom(testConfigProps, "localSpark.only.query.files");
         excludesFrom(testConfigProps, "miniSparkOnYarn.only.query.files");
-        excludesFrom(testConfigProps, "externalDB.llap.query.files");
 
         setResultsDir("ql/src/test/results/clientpositive/llap");
         setLogDir("itests/qtest/target/qfile-results/clientpositive");
@@ -242,28 +240,6 @@ public class CliConfigs {
     }
   }
 
-  public static class MiniLlapExtDBCliConfig extends AbstractCliConfig {
-
-    public MiniLlapExtDBCliConfig() {
-      super(CoreCliDriver.class);
-      try {
-        setQueryDir("ql/src/test/queries/clientpositive");
-
-        includesFrom(testConfigProps, "externalDB.llap.query.files");
-
-        setResultsDir("ql/src/test/results/clientpositive/llap");
-        setLogDir("itests/qtest/target/qfile-results/clientpositive");
-
-        addExternalDB(QTestExternalDB.createDefaultExtDB("mysql"));
-
-        setHiveConfDir("data/conf/llap");
-        setClusterType(MiniClusterType.LLAP_LOCAL);
-      } catch (Exception e) {
-        throw new RuntimeException("can't construct cliconfig", e);
-      }
-    }
-  }
-
   public static class EncryptedHDFSCliConfig extends AbstractCliConfig {
     public EncryptedHDFSCliConfig() {
       super(CoreCliDriver.class);
diff --git 
a/itests/util/src/main/java/org/apache/hadoop/hive/cli/control/CoreCliDriver.java
 
b/itests/util/src/main/java/org/apache/hadoop/hive/cli/control/CoreCliDriver.java
index c868ce2..b1ee326 100644
--- 
a/itests/util/src/main/java/org/apache/hadoop/hive/cli/control/CoreCliDriver.java
+++ 
b/itests/util/src/main/java/org/apache/hadoop/hive/cli/control/CoreCliDriver.java
@@ -25,7 +25,6 @@ import java.util.concurrent.TimeUnit;
 
 import org.apache.hadoop.hive.conf.HiveConf;
 import org.apache.hadoop.hive.conf.HiveConf.ConfVars;
-import org.apache.hadoop.hive.ql.QTestExternalDB;
 import org.apache.hadoop.hive.ql.QTestArguments;
 import org.apache.hadoop.hive.ql.QTestProcessExecResult;
 import org.apache.hadoop.hive.ql.QTestUtil;
@@ -63,7 +62,6 @@ public class CoreCliDriver extends CliAdapter {
     String hiveConfDir = cliConfig.getHiveConfDir();
     String initScript = cliConfig.getInitScript();
     String cleanupScript = cliConfig.getCleanupScript();
-    Set<QTestExternalDB> externalDBs = cliConfig.getExternalDBs();
 
     qt = new ElapsedTimeLoggingWrapper<QTestUtil>() {
       @Override
@@ -76,7 +74,6 @@ public class CoreCliDriver extends CliAdapter {
               .withConfDir(hiveConfDir)
               .withInitScript(initScript)
               .withCleanupScript(cleanupScript)
-              .withExternalDBs(externalDBs)
               .withLlapIo(true)
               .withFsType(cliConfig.getFsType())
               .build());
diff --git 
a/itests/util/src/main/java/org/apache/hadoop/hive/ql/QTestArguments.java 
b/itests/util/src/main/java/org/apache/hadoop/hive/ql/QTestArguments.java
index 5c59b92..2941efa 100644
--- a/itests/util/src/main/java/org/apache/hadoop/hive/ql/QTestArguments.java
+++ b/itests/util/src/main/java/org/apache/hadoop/hive/ql/QTestArguments.java
@@ -18,9 +18,6 @@
 
 package org.apache.hadoop.hive.ql;
 
-import java.util.Set;
-import java.util.LinkedHashSet;
-import org.apache.hadoop.hive.ql.QTestExternalDB;
 import org.apache.hadoop.hive.ql.QTestMiniClusters.FsType;
 import org.apache.hadoop.hive.ql.QTestMiniClusters.QTestSetup;
 
@@ -37,7 +34,6 @@ public final class QTestArguments {
   private String cleanupScript;
   private boolean withLlapIo;
   private FsType fsType;
-  private Set<QTestExternalDB> externalDBs = new LinkedHashSet<>();
   private QTestSetup qtestSetup;
 
   private QTestArguments() {
@@ -83,10 +79,6 @@ public final class QTestArguments {
     return initScript;
   }
 
-  private void setExternalDBs(Set<QTestExternalDB> externalDBs) { 
this.externalDBs = externalDBs; }
-
-  public Set<QTestExternalDB> getExternalDBs() { return this.externalDBs; }
-
   private void setCleanupScript(String cleanupScript) {
     this.cleanupScript = cleanupScript;
   }
@@ -130,7 +122,6 @@ public final class QTestArguments {
     private QTestMiniClusters.MiniClusterType clusterType;
     private String initScript;
     private String cleanupScript;
-    private Set<QTestExternalDB> externalDBs = new LinkedHashSet<>();
     private boolean withLlapIo;
     private FsType fsType;
     private QTestSetup qtestSetup;
@@ -172,11 +163,6 @@ public final class QTestArguments {
       return this;
     }
 
-    public QTestArgumentsBuilder withExternalDBs(Set<QTestExternalDB> 
externalDBs) {
-      this.externalDBs = externalDBs;
-      return this;
-    }
-
     public QTestArgumentsBuilder withLlapIo(boolean withLlapIo) {
       this.withLlapIo = withLlapIo;
       return this;
@@ -202,9 +188,6 @@ public final class QTestArguments {
       testArguments.setCleanupScript(cleanupScript);
       testArguments.setWithLlapIo(withLlapIo);
       
-      testArguments.setExternalDBs(
-              externalDBs != null ? externalDBs : new LinkedHashSet<>());
-
       testArguments.setFsType(
           fsType != null ? fsType : clusterType.getDefaultFsType());
 
diff --git 
a/itests/util/src/main/java/org/apache/hadoop/hive/ql/QTestExternalDB.java 
b/itests/util/src/main/java/org/apache/hadoop/hive/ql/QTestExternalDB.java
deleted file mode 100644
index f50955b..0000000
--- a/itests/util/src/main/java/org/apache/hadoop/hive/ql/QTestExternalDB.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.hadoop.hive.ql;
-
-import java.io.File;
-
-/**
- * QTestExternalDB composite used as information holder for creating external 
databases of different types.
- */
-public final class QTestExternalDB {
-
-    private String externalDBType;
-    private String externalDBInitScript;
-    private String externalDBCleanupScript;
-
-    public QTestExternalDB() { }
-
-    public static QTestExternalDB createDefaultExtDB(String externalDBType) {
-
-        QTestExternalDB externalDB = new QTestExternalDB();
-
-        externalDB.setExternalDBType(externalDBType);
-        
externalDB.setExternalDBInitScript(String.format("q_test_extDB_init.%s.sql", 
externalDBType));
-        
externalDB.setExternalDBCleanupScript(String.format("q_test_extDB_cleanup.%s.sql",
 externalDBType));
-
-        return externalDB;
-    }
-
-    public void setExternalDBType(String dbType) { this.externalDBType = 
dbType; }
-
-    public String getExternalDBType() { return externalDBType; }
-
-    public void setExternalDBInitScript(String InitScript) { 
this.externalDBInitScript = InitScript; }
-
-    public String getExternalDBInitScript() { return externalDBInitScript; }
-
-    public void setExternalDBCleanupScript(String cleanupScript) { 
this.externalDBCleanupScript = cleanupScript; }
-
-    public String getExternalDBCleanupScript() { return 
externalDBCleanupScript; }
-
-}
diff --git a/itests/util/src/main/java/org/apache/hadoop/hive/ql/QTestUtil.java 
b/itests/util/src/main/java/org/apache/hadoop/hive/ql/QTestUtil.java
index a9e6b05..e6c1624 100644
--- a/itests/util/src/main/java/org/apache/hadoop/hive/ql/QTestUtil.java
+++ b/itests/util/src/main/java/org/apache/hadoop/hive/ql/QTestUtil.java
@@ -80,6 +80,7 @@ import 
org.apache.hadoop.hive.ql.processors.CommandProcessorResponse;
 import org.apache.hadoop.hive.ql.processors.HiveCommand;
 import org.apache.hadoop.hive.ql.qoption.QTestAuthorizerHandler;
 import org.apache.hadoop.hive.ql.qoption.QTestDisabledHandler;
+import org.apache.hadoop.hive.ql.qoption.QTestDatabaseHandler;
 import org.apache.hadoop.hive.ql.qoption.QTestOptionDispatcher;
 import org.apache.hadoop.hive.ql.qoption.QTestReplaceHandler;
 import org.apache.hadoop.hive.ql.qoption.QTestSysDbHandler;
@@ -88,7 +89,6 @@ import org.apache.hadoop.hive.ql.qoption.QTestTransactional;
 import org.apache.hadoop.hive.ql.scheduled.QTestScheduledQueryCleaner;
 import org.apache.hadoop.hive.ql.scheduled.QTestScheduledQueryServiceProvider;
 import org.apache.hadoop.hive.ql.session.SessionState;
-import org.apache.hadoop.hive.ql.externalDB.*;
 import org.apache.hive.common.util.ProcessUtils;
 import org.junit.Assert;
 import org.slf4j.Logger;
@@ -130,7 +130,6 @@ public class QTestUtil {
   protected QTestReplaceHandler replaceHandler;
   private final String initScript;
   private final String cleanupScript;
-  private final Set<QTestExternalDB> externalDBs = new LinkedHashSet<>();
   QTestOptionDispatcher dispatcher = new QTestOptionDispatcher();
 
   private boolean isSessionStateStarted = false;
@@ -181,14 +180,13 @@ public class QTestUtil {
 
   public QTestUtil(QTestArguments testArgs) throws Exception {
     LOG.info("Setting up QTestUtil with outDir={}, logDir={}, clusterType={}, 
confDir={},"
-            + " initScript={}, cleanupScript={}, externalDBs={}, 
withLlapIo={}, fsType={}",
+            + " initScript={}, cleanupScript={}, withLlapIo={}, fsType={}",
         testArgs.getOutDir(),
         testArgs.getLogDir(),
         testArgs.getClusterType(),
         testArgs.getConfDir(),
         testArgs.getInitScript(),
         testArgs.getCleanupScript(),
-        testArgs.getExternalDBs(),
         testArgs.isWithLlapIo(),
         testArgs.getFsType());
 
@@ -218,7 +216,8 @@ public class QTestUtil {
     conf = new HiveConf(IDriver.class);
     setMetaStoreProperties();
 
-    this.miniClusters.setup(testArgs, conf, getScriptsDir(), logDir);
+    final String scriptsDir = getScriptsDir(conf);
+    this.miniClusters.setup(testArgs, conf, scriptsDir, logDir);
 
     initConf();
 
@@ -235,21 +234,11 @@ public class QTestUtil {
     dispatcher.register("timezone", new QTestTimezoneHandler());
     dispatcher.register("authorizer", new QTestAuthorizerHandler());
     dispatcher.register("disabled", new QTestDisabledHandler());
-
-    String scriptsDir = getScriptsDir();
+    dispatcher.register("database", new QTestDatabaseHandler());
 
     this.initScript = scriptsDir + File.separator + testArgs.getInitScript();
     this.cleanupScript = scriptsDir + File.separator + 
testArgs.getCleanupScript();
 
-    QTestExternalDB newExternalDB;
-    for (QTestExternalDB externalDB : testArgs.getExternalDBs()) {
-      newExternalDB = new QTestExternalDB();
-      newExternalDB.setExternalDBType(externalDB.getExternalDBType());
-      newExternalDB.setExternalDBInitScript(scriptsDir + File.separator + 
externalDB.getExternalDBType() + File.separator + 
externalDB.getExternalDBInitScript());
-      newExternalDB.setExternalDBCleanupScript(scriptsDir + File.separator + 
externalDB.getExternalDBType() + File.separator + 
externalDB.getExternalDBCleanupScript());
-      this.externalDBs.add(newExternalDB);
-    }
-
     savedConf = new HiveConf(conf);
 
   }
@@ -278,7 +267,7 @@ public class QTestUtil {
     }
   }
 
-  private String getScriptsDir() {
+  public static String getScriptsDir(HiveConf conf) {
     // Use the current directory if it is not specified
     String scriptsDir = conf.get("test.data.scripts");
     if (scriptsDir == null) {
@@ -493,14 +482,6 @@ public class QTestUtil {
     }
     conf.setBoolean("hive.test.shutdown.phase", true);
 
-    // if has external database, clean up docker container
-    // connect to externalDB if size is not zero
-    if (this.externalDBs != null && this.externalDBs.size() != 0) {
-      for (QTestExternalDB externalDB : this.externalDBs) {
-        externalDBCleanupContainer(externalDB.getExternalDBType());
-      }
-    }
-
     clearKeysCreatedInTests();
 
     String metastoreDb = QTestSystemProperties.getMetaStoreDb();
@@ -528,18 +509,6 @@ public class QTestUtil {
     FunctionRegistry.unregisterTemporaryUDF("test_error");
   }
 
-  private void externalDBCleanupContainer(String externalDBType) throws 
IOException {
-    // get externalDB initScript
-    try {
-      AbstractExternalDB abstractExternalDB = 
AbstractExternalDB.initalizeExternalDB(externalDBType);
-      abstractExternalDB.cleanupDockerContainer();
-      LOG.info("cleanup externalDB docker container succeeed!");
-    } catch (Exception e) {
-      LOG.info("cleanup externalDB failed: " + e.getMessage());
-      Assert.fail("Failed during cleanup externalDB docker container");
-    }
-  }
-
   private void cleanupFromFile() throws IOException {
     File cleanupFile = new File(cleanupScript);
     if (cleanupFile.isFile()) {
@@ -562,13 +531,6 @@ public class QTestUtil {
       startSessionState(qTestResultProcessor.canReuseSession());
     }
 
-    // connect to externalDB if size is not zero
-    if (this.externalDBs != null && this.externalDBs.size() != 0) {
-      for (QTestExternalDB externalDB : this.externalDBs) {
-        externalDBLoadFromScript(externalDB.getExternalDBType(), 
externalDB.getExternalDBInitScript());
-      }
-    }
-
     getCliDriver().processLine("set test.data.dir=" + testFiles + ";");
 
     conf.setBoolean("hive.test.init.phase", true);
@@ -578,25 +540,6 @@ public class QTestUtil {
     conf.setBoolean("hive.test.init.phase", false);
   }
 
-  private void externalDBLoadFromScript(String externalDBType, String 
externalDBScript) throws IOException {
-    // get externalDB initScript
-    File scriptFile = new File(externalDBScript);
-    if (!scriptFile.isFile()) {
-      Assert.fail("cannot getting externaldb scirpt file");
-      LOG.info("No externalDB init script detected. Skipping");
-      return;
-    }
-
-    try {
-      AbstractExternalDB abstractExternalDB = 
AbstractExternalDB.initalizeExternalDB(externalDBType);
-      abstractExternalDB.launchDockerContainer();
-      abstractExternalDB.execute(externalDBScript);
-      LOG.info("initialize external databases succeed!");
-    } catch (Exception e) {
-      Assert.fail("Failed during initialize external database");
-    }
-  }
-
   private void initFromScript() throws IOException {
     File scriptFile = new File(this.initScript);
     if (!scriptFile.isFile()) {
diff --git 
a/itests/util/src/main/java/org/apache/hadoop/hive/ql/externalDB/AbstractExternalDB.java
 
b/itests/util/src/main/java/org/apache/hadoop/hive/ql/externalDB/AbstractExternalDB.java
index fd96776..ba0c7ad 100644
--- 
a/itests/util/src/main/java/org/apache/hadoop/hive/ql/externalDB/AbstractExternalDB.java
+++ 
b/itests/util/src/main/java/org/apache/hadoop/hive/ql/externalDB/AbstractExternalDB.java
@@ -17,49 +17,37 @@
  */
 package org.apache.hadoop.hive.ql.externalDB;
 
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import sqlline.SqlLine;
 
-import org.apache.commons.io.output.NullOutputStream;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.concurrent.TimeUnit;
 import java.io.BufferedReader;
-import java.io.InputStreamReader;
 import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.FileReader;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.PrintStream;
 import java.io.IOException;
-import java.net.URI;
+import java.io.InputStreamReader;
+import java.io.PrintStream;
 import java.sql.Connection;
 import java.sql.DriverManager;
 import java.sql.SQLException;
-
-import org.apache.commons.lang3.StringUtils;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
 
 /**
- * abstractExternalDB is incharge of connect to and populate externaal 
database for qtest
+ * The class is in charge of connecting and populating dockerized databases 
for qtest.
+ * 
+ * The database should have at least one root user (admin/superuser) able to 
modify every aspect of the system. The user
+ * either exists by default when the database starts or must created right 
after startup.
  */
 public abstract class AbstractExternalDB {
-    protected static final Logger LOG = 
LoggerFactory.getLogger("AbstractExternalDB");
+    protected static final Logger LOG = 
LoggerFactory.getLogger(AbstractExternalDB.class);
 
-    protected static final String userName = "qtestuser";
-    protected static final String password = "qtestpassword";
     protected static final String dbName = "qtestDB";
 
-    public String externalDBType = "mysql"; // default: mysql
-    protected String url = "jdbc:mysql://localhost:3306/" + dbName; // 
default: mysql
-    protected String driver = "org.mariadb.jdbc.Driver"; // default: mysql
     private static final int MAX_STARTUP_WAIT = 5 * 60 * 1000;
 
-    public static class ProcessResults {
+    protected static class ProcessResults {
         final String stdout;
         final String stderr;
         final int rc;
@@ -71,27 +59,8 @@ public abstract class AbstractExternalDB {
         }
     }
 
-    public static AbstractExternalDB initalizeExternalDB(String 
externalDBType) throws IOException {
-        AbstractExternalDB abstractExternalDB;
-        switch (externalDBType) {
-            case "mysql":
-                abstractExternalDB = new MySQLExternalDB();
-                break;
-            case "postgres":
-                abstractExternalDB = new PostgresExternalDB();
-                break;
-            default:
-                throw new IOException("unsupported external database type " + 
externalDBType);
-        }
-        return abstractExternalDB;
-    }
-
-    public AbstractExternalDB(String externalDBType) {
-        this.externalDBType = externalDBType;
-    }
-
-    protected String getDockerContainerName() {
-        return String.format("qtestExternalDB-%s", externalDBType);
+    private final String getDockerContainerName() {
+        return String.format("qtestExternalDB-%s", getClass().getSimpleName());
     }
 
     private String[] buildRunCmd() {
@@ -107,27 +76,17 @@ public abstract class AbstractExternalDB {
     }
 
     private String[] buildRmCmd() {
-        return buildArray(
-                "docker",
-                "rm",
-                "-f",
-                "-v",
-                getDockerContainerName()
-        );
+        return new String[] { "docker", "rm", "-f", "-v", 
getDockerContainerName() };
     }
 
     private String[] buildLogCmd() {
-        return buildArray(
-                "docker",
-                "logs",
-                getDockerContainerName()
-        );
+        return new String[] { "docker", "logs", getDockerContainerName() };
     }
 
 
     private ProcessResults runCmd(String[] cmd, long secondsToWait)
             throws IOException, InterruptedException {
-        LOG.info("Going to run: " + StringUtils.join(cmd, " "));
+        LOG.info("Going to run: " + String.join(" ", cmd));
         Process proc = Runtime.getRuntime().exec(cmd);
         if (!proc.waitFor(secondsToWait, TimeUnit.SECONDS)) {
             throw new RuntimeException(
@@ -152,7 +111,7 @@ public abstract class AbstractExternalDB {
     }
 
 
-    public void launchDockerContainer() throws Exception { //runDockerContainer
+    public void launchDockerContainer() throws Exception {
         runCmdAndPrintStreams(buildRmCmd(), 600);
         if (runCmdAndPrintStreams(buildRunCmd(), 600) != 0) {
             throw new RuntimeException("Unable to start docker container");
@@ -172,19 +131,14 @@ public abstract class AbstractExternalDB {
         }
     }
 
-    public void cleanupDockerContainer() { // stopAndRmDockerContainer
-        try {
-            if (runCmdAndPrintStreams(buildRmCmd(), 600) != 0) {
-                LOG.info("Unable to remove docker container");
-                throw new RuntimeException("Unable to remove docker 
container");
-            }
-        } catch (InterruptedException | IOException e) {
-            e.printStackTrace();
+    public void cleanupDockerContainer() throws IOException, 
InterruptedException {
+        if (runCmdAndPrintStreams(buildRmCmd(), 600) != 0) {
+            throw new RuntimeException("Unable to remove docker container");
         }
     }
 
 
-    public final String getContainerHostAddress() {
+    protected final String getContainerHostAddress() {
         String hostAddress = System.getenv("HIVE_TEST_DOCKER_HOST");
         if (hostAddress != null) {
             return hostAddress;
@@ -193,96 +147,62 @@ public abstract class AbstractExternalDB {
         }
     }
 
-    public abstract void setJdbcUrl(String hostAddress);
-
-    public abstract void setJdbcDriver();
-
-    public abstract String getDockerImageName();
-
-    public abstract String[] getDockerAdditionalArgs();
-
-    public abstract boolean isContainerReady(ProcessResults pr);
+    /**
+     * Return the name of the root user.
+     * 
+     * Override the method if the name of the root user must be different than 
the default.
+     */
+    protected String getRootUser() {
+        return "qtestuser";
+    }
 
-    protected String[] buildArray(String... strs) {
-        return strs;
+    /**
+     * Return the password of the root user.
+     * 
+     * Override the method if the password must be different than the default.
+     */
+    protected String getRootPassword() {
+        return  "qtestpassword";
     }
+    
+    protected abstract String getJdbcUrl();
 
-    public Connection getConnectionToExternalDB() throws SQLException, 
ClassNotFoundException {
-        try {
-            LOG.info("external database connection URL:\t " + url);
-            LOG.info("JDBC Driver :\t " + driver);
-            LOG.info("external database connection User:\t " + userName);
-            LOG.info("external database connection Password:\t " + password);
+    protected abstract String getJdbcDriver();
 
-            // load required JDBC driver
-            Class.forName(driver);
+    protected abstract String getDockerImageName();
 
-            // Connect using the JDBC URL and user/password
-            Connection conn = DriverManager.getConnection(url, userName, 
password);
-            return conn;
-        } catch (SQLException e) {
-            LOG.error("Failed to connect to external databse", e);
-            throw new SQLException(e);
-        } catch (ClassNotFoundException e) {
-            LOG.error("Unable to find driver class", e);
-            throw new ClassNotFoundException("Unable to find driver class");
-        }
-    }
+    protected abstract String[] getDockerAdditionalArgs();
 
-    public void testConnectionToExternalDB() throws SQLException, 
ClassNotFoundException {
-        Connection conn = getConnectionToExternalDB();
-        try {
-            conn.close();
-        } catch (SQLException e) {
-            LOG.error("Failed to close external database connection", e);
-        }
-    }
+    protected abstract boolean isContainerReady(ProcessResults pr);
 
-    protected String[] SQLLineCmdBuild(String sqlScriptFile) throws 
IOException {
-        return new String[] {"-u", url,
-                            "-d", driver,
-                            "-n", userName,
-                            "-p", password,
+    private String[] SQLLineCmdBuild(String sqlScriptFile) {
+        return new String[] {"-u", getJdbcUrl(),
+                            "-d", getJdbcDriver(),
+                            "-n", getRootUser(),
+                            "-p", getRootPassword(),
                             "--isolation=TRANSACTION_READ_COMMITTED",
                             "-f", sqlScriptFile};
 
     }
 
-    protected void execSql(String sqlScriptFile) throws IOException {
-        // run the script using SqlLine
-        SqlLine sqlLine = new SqlLine();
-        ByteArrayOutputStream outputForLog = null;
-        OutputStream out;
-        if (LOG.isDebugEnabled()) {
-            out = outputForLog = new ByteArrayOutputStream();
-        } else {
-            out = new NullOutputStream();
+    public void execute(String script) throws IOException, SQLException, 
ClassNotFoundException {
+        // Test we can connect to database
+        Class.forName(getJdbcDriver());
+        try (Connection ignored = DriverManager.getConnection(getJdbcUrl(), 
getRootUser(), getRootPassword())) {
+            LOG.info("Successfully connected to {} with user {} and password 
{}", getJdbcUrl(), getRootUser(), getRootPassword());
         }
+        LOG.info("Starting {} initialization", getClass().getSimpleName());
+        SqlLine sqlLine = new SqlLine();
+        ByteArrayOutputStream out = new ByteArrayOutputStream();
         sqlLine.setOutputStream(new PrintStream(out));
+        sqlLine.setErrorStream(new PrintStream(out));
         System.setProperty("sqlline.silent", "true");
-
-        SqlLine.Status status = sqlLine.begin(SQLLineCmdBuild(sqlScriptFile), 
null, false);
-        if (LOG.isDebugEnabled() && outputForLog != null) {
-            LOG.debug("Received following output from Sqlline:");
-            LOG.debug(outputForLog.toString("UTF-8"));
-        }
+        SqlLine.Status status = sqlLine.begin(SQLLineCmdBuild(script), null, 
false);
+        LOG.debug("Printing output from SQLLine:");
+        LOG.debug(out.toString());
         if (status != SqlLine.Status.OK) {
-            throw new IOException("external database script failed, errorcode 
" + status);
+            throw new RuntimeException("Database script " + script + " failed 
with status " + status);
         }
+        LOG.info("Completed {} initialization", getClass().getSimpleName());
     }
-
-    public void execute(String script) throws IOException, SQLException, 
ClassNotFoundException {
-        testConnectionToExternalDB();
-        LOG.info("Starting external database initialization to " + 
this.externalDBType);
-
-        try {
-            LOG.info("Initialization script " + script);
-            execSql(script);
-            LOG.info("Initialization script completed in external database");
-
-        } catch (IOException e) {
-            throw new IOException("initialization in external database 
FAILED!");
-        }
-
-    }
-}
\ No newline at end of file
+}
diff --git 
a/itests/util/src/main/java/org/apache/hadoop/hive/ql/externalDB/MSSQLServer.java
 
b/itests/util/src/main/java/org/apache/hadoop/hive/ql/externalDB/MSSQLServer.java
new file mode 100644
index 0000000..61dc014
--- /dev/null
+++ 
b/itests/util/src/main/java/org/apache/hadoop/hive/ql/externalDB/MSSQLServer.java
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.hadoop.hive.ql.externalDB;
+
+public class MSSQLServer extends AbstractExternalDB {
+
+  @Override
+  public String getRootUser() {
+    return "sa";
+  }
+
+  @Override
+  public String getRootPassword() {
+    return "Its-a-s3cret";
+  }
+
+  @Override
+  public String getJdbcUrl() {
+    return "jdbc:sqlserver://" + getContainerHostAddress() + ":1433";
+  }
+
+  @Override
+  public String getJdbcDriver() {
+    return "com.microsoft.sqlserver.jdbc.SQLServerDriver";
+  }
+
+  @Override
+  public String getDockerImageName() {
+    return "mcr.microsoft.com/mssql/server:2019-latest";
+  }
+
+  @Override
+  public String[] getDockerAdditionalArgs() {
+    return new String[] { "-p", "1433:1433", "-e", "ACCEPT_EULA=Y", "-e", 
"SA_PASSWORD=" + getRootPassword(), "-d" };
+  }
+
+  @Override
+  public boolean isContainerReady(ProcessResults pr) {
+    return pr.stdout
+        .contains("Recovery is complete. This is an informational message 
only. No user action is required.");
+  }
+}
diff --git 
a/itests/util/src/main/java/org/apache/hadoop/hive/ql/externalDB/MariaDB.java 
b/itests/util/src/main/java/org/apache/hadoop/hive/ql/externalDB/MariaDB.java
new file mode 100644
index 0000000..c0d4bde
--- /dev/null
+++ 
b/itests/util/src/main/java/org/apache/hadoop/hive/ql/externalDB/MariaDB.java
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.hadoop.hive.ql.externalDB;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class MariaDB extends AbstractExternalDB {
+
+  @Override
+  public String getRootUser() {
+    return "root";
+  }
+
+  @Override
+  public String getJdbcUrl() {
+    return "jdbc:mariadb://" + getContainerHostAddress() + ":3309/" + dbName;
+  }
+  
+  public String getJdbcDriver() {
+    return "org.mariadb.jdbc.Driver";
+  }
+
+  public String getDockerImageName() { return "mariadb:10.2"; }
+
+  public String[] getDockerAdditionalArgs() {
+    return new String[] {"-p", "3309:3306",
+        "-e", "MARIADB_ROOT_PASSWORD=" + getRootPassword(),
+        "-e", "MARIADB_DATABASE=" + dbName,
+        "-d"
+    };
+  }
+
+  public boolean isContainerReady(ProcessResults pr) {
+    Pattern pat = Pattern.compile("ready for connections");
+    Matcher m = pat.matcher(pr.stderr);
+    return m.find() && m.find();
+  }
+}
diff --git 
a/itests/util/src/main/java/org/apache/hadoop/hive/ql/externalDB/MySQLExternalDB.java
 
b/itests/util/src/main/java/org/apache/hadoop/hive/ql/externalDB/MySQLExternalDB.java
index 45668d9..ce7f3aa 100644
--- 
a/itests/util/src/main/java/org/apache/hadoop/hive/ql/externalDB/MySQLExternalDB.java
+++ 
b/itests/util/src/main/java/org/apache/hadoop/hive/ql/externalDB/MySQLExternalDB.java
@@ -21,34 +21,35 @@ import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
 /**
- * MySQLExternalDB is a extension of abstractExternalDB
  * Designed for MySQL external database connection
  */
 public class MySQLExternalDB extends AbstractExternalDB {
 
     public MySQLExternalDB() {
-        super("mysql");
-        setJdbcUrl(getContainerHostAddress());
-        setJdbcDriver();
     }
 
-    public void setJdbcUrl(String hostAddress) {
-        this.url = "jdbc:mysql://" + hostAddress + ":3306/" + dbName;
+    @Override
+    public String getRootUser() {
+        return "root";
     }
 
-    public void setJdbcDriver() {
-        this.driver = "org.mariadb.jdbc.Driver";
+    @Override
+    public String getJdbcUrl() {
+        return "jdbc:mysql://" + getContainerHostAddress() + ":3306/" + dbName;
     }
 
-    public String getDockerImageName() { return "mariadb:5.5"; }
+    public String getJdbcDriver() {
+        return "com.mysql.jdbc.Driver";
+    }
+
+    public String getDockerImageName() { return "mysql:5.7"; }
 
     public String[] getDockerAdditionalArgs() {
-        return buildArray("-p", "3306:3306",
-                          "-e", "MYSQL_ROOT_PASSWORD=its-a-secret",
-                          "-e", "MYSQL_USER=" + userName,
-                          "-e", "MYSQL_PASSWORD=" + password,
+        return new String[] {"-p", "3306:3306",
+                          "-e", "MYSQL_ROOT_PASSWORD=" + getRootPassword(),
                           "-e", "MYSQL_DATABASE=" + dbName,
-                          "-d");
+                          "-d"
+        };
     }
 
     public boolean isContainerReady(ProcessResults pr) {
diff --git 
a/itests/util/src/main/java/org/apache/hadoop/hive/ql/externalDB/Oracle.java 
b/itests/util/src/main/java/org/apache/hadoop/hive/ql/externalDB/Oracle.java
new file mode 100644
index 0000000..34961c7
--- /dev/null
+++ b/itests/util/src/main/java/org/apache/hadoop/hive/ql/externalDB/Oracle.java
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.hadoop.hive.ql.externalDB;
+
+public class Oracle extends AbstractExternalDB {
+  @Override
+  public String getRootUser() {
+    return "SYS as SYSDBA";
+  }
+
+  @Override
+  public String getRootPassword() {
+    return "oracle";
+  }
+
+  @Override
+  public String getJdbcUrl() {
+    return "jdbc:oracle:thin:@//" + getContainerHostAddress() + ":1521/xe";
+  }
+
+  @Override
+  public String getJdbcDriver() {
+    return "oracle.jdbc.OracleDriver";
+  }
+
+  @Override
+  protected String getDockerImageName() {
+    return "pvargacl/oracle-xe-18.4.0";
+  }
+
+  @Override
+  protected String[] getDockerAdditionalArgs() {
+    return new String[] { "-p", "1521:1521", "-d" };
+  }
+
+  @Override
+  public boolean isContainerReady(ProcessResults pr) {
+    return pr.stdout.contains("DATABASE IS READY TO USE!");
+  }
+
+}
diff --git 
a/itests/util/src/main/java/org/apache/hadoop/hive/ql/externalDB/PostgresExternalDB.java
 
b/itests/util/src/main/java/org/apache/hadoop/hive/ql/externalDB/PostgresExternalDB.java
index 9365cf1..eaa427b 100644
--- 
a/itests/util/src/main/java/org/apache/hadoop/hive/ql/externalDB/PostgresExternalDB.java
+++ 
b/itests/util/src/main/java/org/apache/hadoop/hive/ql/externalDB/PostgresExternalDB.java
@@ -17,8 +17,6 @@
  */
 package org.apache.hadoop.hive.ql.externalDB;
 
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
 import java.io.IOException;
 import java.net.InetSocketAddress;
 import java.net.Socket;
@@ -30,17 +28,14 @@ import java.net.Socket;
 public class PostgresExternalDB extends AbstractExternalDB {
 
     public PostgresExternalDB() {
-        super("postgres");
-        setJdbcUrl(getContainerHostAddress());
-        setJdbcDriver();
     }
 
-    public void setJdbcUrl(String hostAddress) {
-        this.url = "jdbc:postgresql://" + hostAddress + ":5432/" + dbName;
+    public String getJdbcUrl() {
+        return "jdbc:postgresql://" + getContainerHostAddress() + ":5432/" + 
dbName;
     }
 
-    public void setJdbcDriver() {
-        this.driver = "org.postgresql.Driver";
+    public String getJdbcDriver() {
+        return "org.postgresql.Driver";
     }
 
     public String getDockerImageName() {
@@ -48,7 +43,12 @@ public class PostgresExternalDB extends AbstractExternalDB {
     }
 
     public String[] getDockerAdditionalArgs() {
-        return buildArray("-p", "5432:5432", "-e", 
"POSTGRES_PASSWORD=its-a-secret", "-d");
+        return new String[] {"-p", "5432:5432",
+            "-e", "POSTGRES_PASSWORD=" + getRootPassword(),
+            "-e", "POSTGRES_USER=" + getRootUser(),
+            "-e", "POSTGRES_DB=" + dbName,
+            "-d"
+        };
     }
 
     public boolean isContainerReady(ProcessResults pr) {
diff --git 
a/itests/util/src/main/java/org/apache/hadoop/hive/ql/qoption/QTestDatabaseHandler.java
 
b/itests/util/src/main/java/org/apache/hadoop/hive/ql/qoption/QTestDatabaseHandler.java
new file mode 100644
index 0000000..1c1e7db
--- /dev/null
+++ 
b/itests/util/src/main/java/org/apache/hadoop/hive/ql/qoption/QTestDatabaseHandler.java
@@ -0,0 +1,135 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.hadoop.hive.ql.qoption;
+
+import org.apache.hadoop.hive.ql.QTestUtil;
+import org.apache.hadoop.hive.ql.externalDB.AbstractExternalDB;
+import org.apache.hadoop.hive.ql.externalDB.MSSQLServer;
+import org.apache.hadoop.hive.ql.externalDB.MariaDB;
+import org.apache.hadoop.hive.ql.externalDB.MySQLExternalDB;
+import org.apache.hadoop.hive.ql.externalDB.Oracle;
+import org.apache.hadoop.hive.ql.externalDB.PostgresExternalDB;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.Arrays;
+import java.util.EnumMap;
+import java.util.Map;
+
+/**
+ * An option handler for spinning (resp. stopping) databases before (resp. 
after) running a test.
+ *
+ * Syntax: qt:database:DatabaseType:path_to_init_script
+ *
+ * The database type ({@link DatabaseType}) is obligatory argument. The 
initialization script can be omitted.
+ *
+ * Current limitations:
+ * <ol>
+ *   <li>Only one test/file per run</li>
+ *   <li>Does not support parallel execution</li>
+ *   <li>Cannot instantiate more than one database of the same type per 
test</li>
+ * </ol>
+ */
+public class QTestDatabaseHandler implements QTestOptionHandler {
+  private static final Logger LOG = 
LoggerFactory.getLogger(QTestDatabaseHandler.class);
+
+  private enum DatabaseType {
+    POSTGRES {
+      @Override
+      AbstractExternalDB create() {
+        return new PostgresExternalDB();
+      }
+    }, MYSQL {
+      @Override
+      AbstractExternalDB create() {
+        return new MySQLExternalDB();
+      }
+    }, MARIADB {
+      @Override
+      AbstractExternalDB create() {
+        return new MariaDB();
+      }
+    }, MSSQL {
+      @Override
+      AbstractExternalDB create() {
+        return new MSSQLServer();
+      }
+    }, ORACLE {
+      @Override
+      AbstractExternalDB create() {
+        return new Oracle();
+      }
+    };
+
+    abstract AbstractExternalDB create();
+  }
+
+  private final Map<DatabaseType, String> databaseToScript = new 
EnumMap<>(DatabaseType.class);
+
+  @Override
+  public void processArguments(String arguments) {
+    String[] args = arguments.split(":");
+    if (args.length == 0) {
+      throw new IllegalArgumentException("No arguments provided");
+    }
+    if (args.length > 2) {
+      throw new IllegalArgumentException(
+          "Too many arguments. Expected {dbtype:script}. Found: " + 
Arrays.toString(args));
+    }
+    DatabaseType dbType = DatabaseType.valueOf(args[0].toUpperCase());
+    String initScript = args.length == 2 ? args[1] : "";
+    if (databaseToScript.containsKey(dbType)) {
+      throw new IllegalArgumentException(dbType + " database is already 
defined in this file.");
+    }
+    databaseToScript.put(dbType, initScript);
+  }
+
+  @Override
+  public void beforeTest(QTestUtil qt) throws Exception {
+    if (databaseToScript.isEmpty()) {
+      return;
+    }
+    for (Map.Entry<DatabaseType, String> dbEntry : 
databaseToScript.entrySet()) {
+      String scriptsDir = QTestUtil.getScriptsDir(qt.getConf());
+      Path dbScript = Paths.get(scriptsDir, dbEntry.getValue());
+      AbstractExternalDB db = dbEntry.getKey().create();
+      db.launchDockerContainer();
+      if (Files.exists(dbScript)) {
+        db.execute(dbScript.toString());
+      } else {
+        LOG.warn("Initialization script {} not found", dbScript);
+      }
+    }
+  }
+
+  @Override
+  public void afterTest(QTestUtil qt) throws Exception {
+    if (databaseToScript.isEmpty()) {
+      return;
+    }
+    for (Map.Entry<DatabaseType, String> dbEntry : 
databaseToScript.entrySet()) {
+      AbstractExternalDB db = dbEntry.getKey().create();
+      db.cleanupDockerContainer();
+    }
+    databaseToScript.clear();
+  }
+
+}
diff --git 
a/itests/util/src/main/java/org/apache/hadoop/hive/ql/scheduled/QTestScheduledQueryCleaner.java
 
b/itests/util/src/main/java/org/apache/hadoop/hive/ql/scheduled/QTestScheduledQueryCleaner.java
index de741f5..b9ac362 100644
--- 
a/itests/util/src/main/java/org/apache/hadoop/hive/ql/scheduled/QTestScheduledQueryCleaner.java
+++ 
b/itests/util/src/main/java/org/apache/hadoop/hive/ql/scheduled/QTestScheduledQueryCleaner.java
@@ -50,11 +50,11 @@ public class QTestScheduledQueryCleaner implements 
QTestOptionHandler {
 
   @Override
   public void afterTest(QTestUtil qt) throws Exception {
-    clearScheduledQueries(qt);
+    clearScheduledQueries(qt.getConf());
 
   }
 
-  public void clearScheduledQueries(QTestUtil qt) {
+  private void clearScheduledQueries(HiveConf conf) {
     if (System.getenv(QTestUtil.QTEST_LEAVE_FILES) != null) {
       return;
     }
@@ -63,10 +63,9 @@ public class QTestScheduledQueryCleaner implements 
QTestOptionHandler {
       ScheduledQueryMaintenanceRequest request = new 
ScheduledQueryMaintenanceRequest();
       request.setType(ScheduledQueryMaintenanceRequestType.DROP);
       ScheduledQuery schq = new ScheduledQuery();
-      schq.setScheduleKey(new ScheduledQueryKey(name, 
qt.getConf().getVar(ConfVars.HIVE_SCHEDULED_QUERIES_NAMESPACE)));
+      schq.setScheduleKey(new ScheduledQueryKey(name, 
conf.getVar(ConfVars.HIVE_SCHEDULED_QUERIES_NAMESPACE)));
       request.setScheduledQuery(schq);
       try {
-        HiveConf conf = qt.getConf();
         Hive db = Hive.get(conf); // propagate new conf to meta store
 
         db.getMSC().scheduledQueryMaintenance(request);
diff --git a/pom.xml b/pom.xml
index 23d24c0..b4e6ca4 100644
--- a/pom.xml
+++ b/pom.xml
@@ -182,7 +182,9 @@
     <libthrift.version>0.14.1</libthrift.version>
     <log4j2.version>2.13.2</log4j2.version>
     <mariadb.version>2.5.0</mariadb.version>
+    <mysql.version>8.0.27</mysql.version>
     <postgres.version>42.2.14</postgres.version>
+    <oracle.version>21.3.0.0</oracle.version>
     <opencsv.version>2.3</opencsv.version>
     <orc.version>1.6.9</orc.version>
     <mockito-core.version>3.4.4</mockito-core.version>
diff --git a/ql/src/test/queries/clientpositive/dataconnector_mysql.q 
b/ql/src/test/queries/clientpositive/dataconnector_mysql.q
index f2c77eb..edab15c 100644
--- a/ql/src/test/queries/clientpositive/dataconnector_mysql.q
+++ b/ql/src/test/queries/clientpositive/dataconnector_mysql.q
@@ -1,10 +1,11 @@
+--!qt:database:mysql:q_test_country_state_city_tables.sql
 -- CREATE with comment
 CREATE CONNECTOR mysql_qtest
 TYPE 'mysql'
 URL 'jdbc:mysql://localhost:3306/qtestDB'
 COMMENT 'test connector'
 WITH DCPROPERTIES (
-"hive.sql.dbcp.username"="qtestuser",
+"hive.sql.dbcp.username"="root",
 "hive.sql.dbcp.password"="qtestpassword");
 SHOW CONNECTORS;
 
diff --git a/ql/src/test/queries/clientpositive/qt_database_all.q 
b/ql/src/test/queries/clientpositive/qt_database_all.q
new file mode 100644
index 0000000..9695187
--- /dev/null
+++ b/ql/src/test/queries/clientpositive/qt_database_all.q
@@ -0,0 +1,86 @@
+--!qt:database:postgres:q_test_country_table.sql
+--!qt:database:mysql:q_test_state_table.sql
+--!qt:database:mariadb:q_test_city_table.sql
+--!qt:database:mssql:q_test_author_table.sql
+--!qt:database:oracle:q_test_book_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;
+
+CREATE EXTERNAL TABLE state
+(
+    name varchar(255),
+    country int
+)
+STORED BY 'org.apache.hive.storage.jdbc.JdbcStorageHandler'
+TBLPROPERTIES (
+    "hive.sql.database.type" = "MYSQL",
+    "hive.sql.jdbc.driver" = "com.mysql.jdbc.Driver",
+    "hive.sql.jdbc.url" = "jdbc:mysql://localhost:3306/qtestDB",
+    "hive.sql.dbcp.username" = "root",
+    "hive.sql.dbcp.password" = "qtestpassword",
+    "hive.sql.table" = "state"
+    );
+SELECT * FROM state;
+
+CREATE EXTERNAL TABLE city
+(
+    name       varchar(255),
+    state int
+)
+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/qtestDB",
+    "hive.sql.dbcp.username" = "root",
+    "hive.sql.dbcp.password" = "qtestpassword",
+    "hive.sql.table" = "city"
+);
+SELECT * FROM city;
+
+CREATE EXTERNAL TABLE author
+(
+    id    int,
+    fname varchar(20),
+    lname 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",
+    "hive.sql.dbcp.username" = "sa",
+    "hive.sql.dbcp.password" = "Its-a-s3cret",
+    "hive.sql.table" = "author"
+    );
+SELECT * FROM author;
+
+CREATE EXTERNAL TABLE book
+(
+    id int,
+    title varchar(100),
+    author int
+)
+    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/xe",
+        "hive.sql.dbcp.username" = "SYS as SYSDBA",
+        "hive.sql.dbcp.password" = "oracle",
+        "hive.sql.table" = "BOOK"
+        );
+SELECT * FROM book;
diff --git a/ql/src/test/queries/clientpositive/qt_database_mariadb.q 
b/ql/src/test/queries/clientpositive/qt_database_mariadb.q
new file mode 100644
index 0000000..5db9fd6
--- /dev/null
+++ b/ql/src/test/queries/clientpositive/qt_database_mariadb.q
@@ -0,0 +1,17 @@
+--!qt:database:mariadb: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" = "MYSQL", 
+    "hive.sql.jdbc.driver" = "org.mariadb.jdbc.Driver",
+    "hive.sql.jdbc.url" = "jdbc:mariadb://localhost:3309/qtestDB",
+    "hive.sql.dbcp.username" = "root",
+    "hive.sql.dbcp.password" = "qtestpassword",
+    "hive.sql.table" = "country"
+    );
+-- hive.sql.database.type above is not MARIADB cause at the moment it doesn't 
exist in org.apache.hive.storage.jdbc.conf.DatabaseType
+SELECT * FROM country;
diff --git a/ql/src/test/queries/clientpositive/qt_database_mssql.q 
b/ql/src/test/queries/clientpositive/qt_database_mssql.q
new file mode 100644
index 0000000..7240bb9
--- /dev/null
+++ b/ql/src/test/queries/clientpositive/qt_database_mssql.q
@@ -0,0 +1,16 @@
+--!qt:database:mssql: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" = "MSSQL", 
+    "hive.sql.jdbc.driver" = "com.microsoft.sqlserver.jdbc.SQLServerDriver",
+    "hive.sql.jdbc.url" = "jdbc:sqlserver://localhost:1433",
+    "hive.sql.dbcp.username" = "sa",
+    "hive.sql.dbcp.password" = "Its-a-s3cret",
+    "hive.sql.table" = "country"
+    );
+SELECT * FROM country;
diff --git a/ql/src/test/queries/clientpositive/qt_database_mysql.q 
b/ql/src/test/queries/clientpositive/qt_database_mysql.q
new file mode 100644
index 0000000..9803df8
--- /dev/null
+++ b/ql/src/test/queries/clientpositive/qt_database_mysql.q
@@ -0,0 +1,16 @@
+--!qt:database:mysql: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" = "MYSQL",
+    "hive.sql.jdbc.driver" = "com.mysql.jdbc.Driver",
+    "hive.sql.jdbc.url" = "jdbc:mysql://localhost:3306/qtestDB",
+    "hive.sql.dbcp.username" = "root",
+    "hive.sql.dbcp.password" = "qtestpassword",
+    "hive.sql.table" = "country"
+    );
+SELECT * FROM country;
diff --git a/ql/src/test/queries/clientpositive/qt_database_oracle.q 
b/ql/src/test/queries/clientpositive/qt_database_oracle.q
new file mode 100644
index 0000000..8ec6beb
--- /dev/null
+++ b/ql/src/test/queries/clientpositive/qt_database_oracle.q
@@ -0,0 +1,17 @@
+--!qt:database:oracle: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" = "ORACLE", 
+    "hive.sql.jdbc.driver" = "oracle.jdbc.OracleDriver",
+    "hive.sql.jdbc.url" = "jdbc:oracle:thin:@//localhost:1521/xe",
+    "hive.sql.dbcp.username" = "SYS as SYSDBA",
+    "hive.sql.dbcp.password" = "oracle",
+    "hive.sql.table" = "COUNTRY"
+);
+-- Case sensitivity is important in the default conf of Oracle. Notice the 
capital letters in hive.sql.table 
+SELECT * FROM country;
diff --git a/ql/src/test/queries/clientpositive/qt_database_postgres.q 
b/ql/src/test/queries/clientpositive/qt_database_postgres.q
new file mode 100644
index 0000000..afc89f9
--- /dev/null
+++ b/ql/src/test/queries/clientpositive/qt_database_postgres.q
@@ -0,0 +1,16 @@
+--!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;
diff --git a/ql/src/test/results/clientpositive/llap/dataconnector_mysql.q.out 
b/ql/src/test/results/clientpositive/llap/dataconnector_mysql.q.out
index 794fd2d..c771d29 100644
--- a/ql/src/test/results/clientpositive/llap/dataconnector_mysql.q.out
+++ b/ql/src/test/results/clientpositive/llap/dataconnector_mysql.q.out
@@ -3,7 +3,7 @@ TYPE 'mysql'
 URL 'jdbc:mysql://localhost:3306/qtestDB'
 COMMENT 'test connector'
 WITH DCPROPERTIES (
-"hive.sql.dbcp.username"="qtestuser",
+"hive.sql.dbcp.username"="root",
 "hive.sql.dbcp.password"="qtestpassword")
 PREHOOK: type: CREATEDATACONNECTOR
 PREHOOK: Output: connector:mysql_qtest
@@ -12,7 +12,7 @@ TYPE 'mysql'
 URL 'jdbc:mysql://localhost:3306/qtestDB'
 COMMENT 'test connector'
 WITH DCPROPERTIES (
-"hive.sql.dbcp.username"="qtestuser",
+"hive.sql.dbcp.username"="root",
 "hive.sql.dbcp.password"="qtestpassword")
 POSTHOOK: type: CREATEDATACONNECTOR
 POSTHOOK: Output: connector:mysql_qtest
diff --git a/ql/src/test/results/clientpositive/llap/qt_database_all.q.out 
b/ql/src/test/results/clientpositive/llap/qt_database_all.q.out
new file mode 100644
index 0000000..2458c31
--- /dev/null
+++ b/ql/src/test/results/clientpositive/llap/qt_database_all.q.out
@@ -0,0 +1,235 @@
+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: CREATE EXTERNAL TABLE state
+(
+    name varchar(255),
+    country int
+)
+STORED BY 'org.apache.hive.storage.jdbc.JdbcStorageHandler'
+TBLPROPERTIES (
+    "hive.sql.database.type" = "MYSQL",
+    "hive.sql.jdbc.driver" = "com.mysql.jdbc.Driver",
+    "hive.sql.jdbc.url" = "jdbc:mysql://localhost:3306/qtestDB",
+    "hive.sql.dbcp.username" = "root",
+    "hive.sql.dbcp.password" = "qtestpassword",
+    "hive.sql.table" = "state"
+    )
+PREHOOK: type: CREATETABLE
+PREHOOK: Output: database:default
+PREHOOK: Output: default@state
+POSTHOOK: query: CREATE EXTERNAL TABLE state
+(
+    name varchar(255),
+    country int
+)
+STORED BY 'org.apache.hive.storage.jdbc.JdbcStorageHandler'
+TBLPROPERTIES (
+    "hive.sql.database.type" = "MYSQL",
+    "hive.sql.jdbc.driver" = "com.mysql.jdbc.Driver",
+    "hive.sql.jdbc.url" = "jdbc:mysql://localhost:3306/qtestDB",
+    "hive.sql.dbcp.username" = "root",
+    "hive.sql.dbcp.password" = "qtestpassword",
+    "hive.sql.table" = "state"
+    )
+POSTHOOK: type: CREATETABLE
+POSTHOOK: Output: database:default
+POSTHOOK: Output: default@state
+PREHOOK: query: SELECT * FROM state
+PREHOOK: type: QUERY
+PREHOOK: Input: default@state
+#### A masked pattern was here ####
+POSTHOOK: query: SELECT * FROM state
+POSTHOOK: type: QUERY
+POSTHOOK: Input: default@state
+#### A masked pattern was here ####
+Maharashtra    1
+Madhya Pradesh 1
+Moscow 3
+Something      4
+Florida        4
+Texas  4
+PREHOOK: query: CREATE EXTERNAL TABLE city
+(
+    name       varchar(255),
+    state int
+)
+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/qtestDB",
+    "hive.sql.dbcp.username" = "root",
+    "hive.sql.dbcp.password" = "qtestpassword",
+    "hive.sql.table" = "city"
+)
+PREHOOK: type: CREATETABLE
+PREHOOK: Output: database:default
+PREHOOK: Output: default@city
+POSTHOOK: query: CREATE EXTERNAL TABLE city
+(
+    name       varchar(255),
+    state int
+)
+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/qtestDB",
+    "hive.sql.dbcp.username" = "root",
+    "hive.sql.dbcp.password" = "qtestpassword",
+    "hive.sql.table" = "city"
+)
+POSTHOOK: type: CREATETABLE
+POSTHOOK: Output: database:default
+POSTHOOK: Output: default@city
+PREHOOK: query: SELECT * FROM city
+PREHOOK: type: QUERY
+PREHOOK: Input: default@city
+#### A masked pattern was here ####
+POSTHOOK: query: SELECT * FROM city
+POSTHOOK: type: QUERY
+POSTHOOK: Input: default@city
+#### A masked pattern was here ####
+Mumbai 1
+Pune   1
+Bhopal 2
+Indore 2
+Klin   3
+Los Angeles    5
+Plant City     5
+Arlington      6
+PREHOOK: query: CREATE EXTERNAL TABLE author
+(
+    id    int,
+    fname varchar(20),
+    lname 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",
+    "hive.sql.dbcp.username" = "sa",
+    "hive.sql.dbcp.password" = "Its-a-s3cret",
+    "hive.sql.table" = "author"
+    )
+PREHOOK: type: CREATETABLE
+PREHOOK: Output: database:default
+PREHOOK: Output: default@author
+POSTHOOK: query: CREATE EXTERNAL TABLE author
+(
+    id    int,
+    fname varchar(20),
+    lname 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",
+    "hive.sql.dbcp.username" = "sa",
+    "hive.sql.dbcp.password" = "Its-a-s3cret",
+    "hive.sql.table" = "author"
+    )
+POSTHOOK: type: CREATETABLE
+POSTHOOK: Output: database:default
+POSTHOOK: Output: default@author
+PREHOOK: query: SELECT * FROM author
+PREHOOK: type: QUERY
+PREHOOK: Input: default@author
+#### A masked pattern was here ####
+POSTHOOK: query: SELECT * FROM author
+POSTHOOK: type: QUERY
+POSTHOOK: Input: default@author
+#### A masked pattern was here ####
+1      Victor  Hugo
+2      Alexandre       Dumas
+PREHOOK: query: CREATE EXTERNAL TABLE book
+(
+    id int,
+    title varchar(100),
+    author int
+)
+    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/xe",
+        "hive.sql.dbcp.username" = "SYS as SYSDBA",
+        "hive.sql.dbcp.password" = "oracle",
+        "hive.sql.table" = "BOOK"
+        )
+PREHOOK: type: CREATETABLE
+PREHOOK: Output: database:default
+PREHOOK: Output: default@book
+POSTHOOK: query: CREATE EXTERNAL TABLE book
+(
+    id int,
+    title varchar(100),
+    author int
+)
+    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/xe",
+        "hive.sql.dbcp.username" = "SYS as SYSDBA",
+        "hive.sql.dbcp.password" = "oracle",
+        "hive.sql.table" = "BOOK"
+        )
+POSTHOOK: type: CREATETABLE
+POSTHOOK: Output: database:default
+POSTHOOK: Output: default@book
+PREHOOK: query: SELECT * FROM book
+PREHOOK: type: QUERY
+PREHOOK: Input: default@book
+#### A masked pattern was here ####
+POSTHOOK: query: SELECT * FROM book
+POSTHOOK: type: QUERY
+POSTHOOK: Input: default@book
+#### A masked pattern was here ####
+1      Les Miserables  1
+2      The Count Of Monte Cristo       2
diff --git a/ql/src/test/results/clientpositive/llap/qt_database_mariadb.q.out 
b/ql/src/test/results/clientpositive/llap/qt_database_mariadb.q.out
new file mode 100644
index 0000000..f00db08
--- /dev/null
+++ b/ql/src/test/results/clientpositive/llap/qt_database_mariadb.q.out
@@ -0,0 +1,45 @@
+PREHOOK: query: CREATE EXTERNAL TABLE country
+(
+    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/qtestDB",
+    "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
+POSTHOOK: query: CREATE EXTERNAL TABLE country
+(
+    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/qtestDB",
+    "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
+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
diff --git a/ql/src/test/results/clientpositive/llap/qt_database_mssql.q.out 
b/ql/src/test/results/clientpositive/llap/qt_database_mssql.q.out
new file mode 100644
index 0000000..a125dd8
--- /dev/null
+++ b/ql/src/test/results/clientpositive/llap/qt_database_mssql.q.out
@@ -0,0 +1,45 @@
+PREHOOK: query: CREATE EXTERNAL TABLE country
+(
+    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",
+    "hive.sql.dbcp.username" = "sa",
+    "hive.sql.dbcp.password" = "Its-a-s3cret",
+    "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" = "MSSQL", 
+    "hive.sql.jdbc.driver" = "com.microsoft.sqlserver.jdbc.SQLServerDriver",
+    "hive.sql.jdbc.url" = "jdbc:sqlserver://localhost:1433",
+    "hive.sql.dbcp.username" = "sa",
+    "hive.sql.dbcp.password" = "Its-a-s3cret",
+    "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
diff --git a/ql/src/test/results/clientpositive/llap/qt_database_mysql.q.out 
b/ql/src/test/results/clientpositive/llap/qt_database_mysql.q.out
new file mode 100644
index 0000000..b5f1c86
--- /dev/null
+++ b/ql/src/test/results/clientpositive/llap/qt_database_mysql.q.out
@@ -0,0 +1,45 @@
+PREHOOK: query: CREATE EXTERNAL TABLE country
+(
+    id int,
+    name varchar(20)
+)
+STORED BY 'org.apache.hive.storage.jdbc.JdbcStorageHandler'
+TBLPROPERTIES (
+    "hive.sql.database.type" = "MYSQL",
+    "hive.sql.jdbc.driver" = "com.mysql.jdbc.Driver",
+    "hive.sql.jdbc.url" = "jdbc:mysql://localhost:3306/qtestDB",
+    "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
+POSTHOOK: query: CREATE EXTERNAL TABLE country
+(
+    id int,
+    name varchar(20)
+)
+STORED BY 'org.apache.hive.storage.jdbc.JdbcStorageHandler'
+TBLPROPERTIES (
+    "hive.sql.database.type" = "MYSQL",
+    "hive.sql.jdbc.driver" = "com.mysql.jdbc.Driver",
+    "hive.sql.jdbc.url" = "jdbc:mysql://localhost:3306/qtestDB",
+    "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
+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
diff --git a/ql/src/test/results/clientpositive/llap/qt_database_oracle.q.out 
b/ql/src/test/results/clientpositive/llap/qt_database_oracle.q.out
new file mode 100644
index 0000000..d63d30f
--- /dev/null
+++ b/ql/src/test/results/clientpositive/llap/qt_database_oracle.q.out
@@ -0,0 +1,45 @@
+PREHOOK: query: CREATE EXTERNAL TABLE country
+(
+    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/xe",
+    "hive.sql.dbcp.username" = "SYS as SYSDBA",
+    "hive.sql.dbcp.password" = "oracle",
+    "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" = "ORACLE", 
+    "hive.sql.jdbc.driver" = "oracle.jdbc.OracleDriver",
+    "hive.sql.jdbc.url" = "jdbc:oracle:thin:@//localhost:1521/xe",
+    "hive.sql.dbcp.username" = "SYS as SYSDBA",
+    "hive.sql.dbcp.password" = "oracle",
+    "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
diff --git a/ql/src/test/results/clientpositive/llap/qt_database_postgres.q.out 
b/ql/src/test/results/clientpositive/llap/qt_database_postgres.q.out
new file mode 100644
index 0000000..77ab839
--- /dev/null
+++ b/ql/src/test/results/clientpositive/llap/qt_database_postgres.q.out
@@ -0,0 +1,45 @@
+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

Reply via email to