diff --git a/data/scripts/q_test_case_sensitive.mariadb.sql b/data/scripts/q_test_case_sensitive.mariadb.sql new file mode 100644 index 000000000000..0b8a8e1ee9ad --- /dev/null +++ b/data/scripts/q_test_case_sensitive.mariadb.sql @@ -0,0 +1,30 @@ +-- Create a case-sensitive schema (database) +CREATE SCHEMA `WorldData`; + +-- Case-Sensitive Schema and Table +CREATE TABLE `WorldData`.`Country` +( + id int, + name varchar(20) +); + +INSERT INTO `WorldData`.`Country` VALUES (1, 'India'), (2, 'USA'), (3, 'Japan'), (4, 'Germany'); + + +-- Case-Sensitive Partition Column +CREATE TABLE `WorldData`.`Cities` +( + id int, + name varchar(20), + `RegionID` int +); +INSERT INTO `WorldData`.`Cities` VALUES (1, 'Mumbai', 10), (2, 'New York', 20), (3, 'Tokyo', 30), (4, 'Berlin', 40), (5, 'New Delhi', 10), (6, 'Kyoto', 30); + + +-- Case-Sensitive Query Field Names +CREATE TABLE `WorldData`.`Geography` +( + id int, + `Description` varchar(50) +); +INSERT INTO `WorldData`.`Geography` VALUES (1, 'Asia'), (2, 'North America'), (3, 'Asia'), (4, 'Europe'); diff --git a/data/scripts/q_test_case_sensitive.mssql.sql b/data/scripts/q_test_case_sensitive.mssql.sql new file mode 100644 index 000000000000..c4cf053a9c17 --- /dev/null +++ b/data/scripts/q_test_case_sensitive.mssql.sql @@ -0,0 +1,34 @@ +CREATE SCHEMA [WorldData]; + +-- Case-Sensitive Schema and Table +CREATE TABLE [WorldData].[Country] +( + id int, + name varchar(20) +); +INSERT INTO [WorldData].[Country] VALUES (1, 'India'), (2, 'USA'), (3, 'Japan'), (4, 'Germany'); + + +-- Case-Sensitive Partition Column +CREATE TABLE [WorldData].[Cities] +( + id int, + name varchar(20), + [RegionID] int +); +INSERT INTO [WorldData].[Cities] VALUES (1, 'Mumbai', 10), (2, 'New York', 20), (3, 'Tokyo', 30), (4, 'Berlin', 40), (5, 'New Delhi', 10), (6, 'Kyoto', 30); + + +-- Case-Sensitive Query Field Names +CREATE TABLE [WorldData].[Geography] +( + id int, + [Description] varchar(50) +); +INSERT INTO [WorldData].[Geography] VALUES (1, 'Asia'), (2, 'North America'), (3, 'Asia'), (4, 'Europe'); + +-- 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_case_sensitive.oracle.sql b/data/scripts/q_test_case_sensitive.oracle.sql new file mode 100644 index 000000000000..116762c297a5 --- /dev/null +++ b/data/scripts/q_test_case_sensitive.oracle.sql @@ -0,0 +1,53 @@ +-- The comments below are from q_test_country_table_with_schema.oracle.sql + +-- In Oracle dividing 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 a case-sensitive user, which also acts as the schema +CREATE USER "WorldData" IDENTIFIED BY QTestPassword123; +ALTER USER "WorldData" QUOTA UNLIMITED ON users; +GRANT CREATE SESSION, CREATE TABLE, CREATE VIEW TO "WorldData"; + +-- Case-Sensitive Schema and Table +CREATE TABLE "WorldData"."Country" +( + id int, + name varchar(20) +); +INSERT INTO "WorldData"."Country" VALUES (1, 'India'); +INSERT INTO "WorldData"."Country" VALUES (2, 'USA'); +INSERT INTO "WorldData"."Country" VALUES (3, 'Japan'); +INSERT INTO "WorldData"."Country" VALUES (4, 'Germany'); + + +-- Case-Sensitive Partition Column +CREATE TABLE "WorldData"."Cities" +( + id int, + name varchar(20), + "RegionID" int +); +INSERT INTO "WorldData"."Cities" VALUES (1, 'Mumbai', 10); +INSERT INTO "WorldData"."Cities" VALUES (2, 'New York', 20); +INSERT INTO "WorldData"."Cities" VALUES (3, 'Tokyo', 30); +INSERT INTO "WorldData"."Cities" VALUES (4, 'Berlin', 40); +INSERT INTO "WorldData"."Cities" VALUES (5, 'New Delhi', 10); +INSERT INTO "WorldData"."Cities" VALUES (6, 'Kyoto', 30); + + +-- Case-Sensitive Query Field Names +CREATE TABLE "WorldData"."Geography" +( + id int, + "Description" varchar(50) +); +INSERT INTO "WorldData"."Geography" VALUES (1, 'Asia'); +INSERT INTO "WorldData"."Geography" VALUES (2, 'North America'); +INSERT INTO "WorldData"."Geography" VALUES (3, 'Asia'); +INSERT INTO "WorldData"."Geography" VALUES (4, 'Europe'); diff --git a/data/scripts/q_test_case_sensitive.postgres.sql b/data/scripts/q_test_case_sensitive.postgres.sql new file mode 100644 index 000000000000..814b9e3a4e39 --- /dev/null +++ b/data/scripts/q_test_case_sensitive.postgres.sql @@ -0,0 +1,37 @@ +-- Create a case-sensitive schema +CREATE SCHEMA "WorldData"; + +-- Case-Sensitive Schema and Table +CREATE TABLE "WorldData"."Country" +( + id int, + name varchar(20) +); + +INSERT INTO "WorldData"."Country" VALUES (1, 'India'), (2, 'USA'), (3, 'Japan'), (4, 'Germany'); + + +-- Case-Sensitive Partition Column +CREATE TABLE "WorldData"."Cities" +( + id int, + name varchar(20), + "RegionID" int +); +INSERT INTO "WorldData"."Cities" VALUES (1, 'Mumbai', 10), (2, 'New York', 20), (3, 'Tokyo', 30), (4, 'Berlin', 40), (5, 'New Delhi', 10), (6, 'Kyoto', 30); + + +-- Case-Sensitive Query Field Names +CREATE TABLE "WorldData"."Geography" +( + id int, + "Description" varchar(50) +); +INSERT INTO "WorldData"."Geography" VALUES (1, 'Asia'), (2, 'North America'), (3, 'Asia'), (4, 'Europe'); + +-- 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 "WorldData"; +-- Grant the necessary permissions to be able to access the schema +GRANT USAGE ON SCHEMA "WorldData" TO greg; +GRANT SELECT ON ALL TABLES IN SCHEMA "WorldData" TO greg; diff --git a/jdbc-handler/src/main/java/org/apache/hive/storage/jdbc/JdbcStorageHandler.java b/jdbc-handler/src/main/java/org/apache/hive/storage/jdbc/JdbcStorageHandler.java index bcb051b62995..3841a34afcbe 100644 --- a/jdbc-handler/src/main/java/org/apache/hive/storage/jdbc/JdbcStorageHandler.java +++ b/jdbc-handler/src/main/java/org/apache/hive/storage/jdbc/JdbcStorageHandler.java @@ -44,6 +44,8 @@ import java.net.URI; import java.net.URISyntaxException; +import static org.apache.hadoop.hive.ql.exec.Utilities.unescapeHiveJdbcIdentifier; + public class JdbcStorageHandler implements HiveStorageHandler { private static final Logger LOGGER = LoggerFactory.getLogger(JdbcStorageHandler.class); @@ -101,12 +103,12 @@ public void configureInputJobProperties(TableDesc tableDesc, Map @Override public URI getURIForAuth(Table table) throws URISyntaxException { Map tableProperties = HiveCustomStorageHandlerUtils.getTableProperties(table); - DatabaseType dbType = DatabaseType.valueOf( + DatabaseType dbType = DatabaseType.from( tableProperties.get(JdbcStorageConfig.DATABASE_TYPE.getPropertyName())); - String host_url = DatabaseType.METASTORE == dbType ? + String hostUrl = DatabaseType.METASTORE == dbType ? "jdbc:metastore://" : tableProperties.get(Constants.JDBC_URL); - String table_name = tableProperties.get(Constants.JDBC_TABLE); - return new URI(host_url+"/"+table_name); + String tableName = unescapeHiveJdbcIdentifier(tableProperties.get(Constants.JDBC_TABLE)); + return new URI(hostUrl+"/" + tableName); } @Override diff --git a/jdbc-handler/src/main/java/org/apache/hive/storage/jdbc/conf/DatabaseType.java b/jdbc-handler/src/main/java/org/apache/hive/storage/jdbc/conf/DatabaseType.java index 4a6deed1d3aa..d32cdc608679 100644 --- a/jdbc-handler/src/main/java/org/apache/hive/storage/jdbc/conf/DatabaseType.java +++ b/jdbc-handler/src/main/java/org/apache/hive/storage/jdbc/conf/DatabaseType.java @@ -15,14 +15,68 @@ package org.apache.hive.storage.jdbc.conf; public enum DatabaseType { - MYSQL, + // Default quote is " H2, DB2, DERBY, ORACLE, POSTGRES, - MSSQL, - METASTORE, JETHRO_DATA, - HIVE + MSSQL, + + // Special quote cases + MYSQL("`"), + MARIADB("`"), + HIVE("`"), + + // METASTORE will be resolved to another type + METASTORE(null, null); + + // Keeping start and end quote separate to allow for future DBs + // that may have different start and end quotes + private final String startQuote; + private final String endQuote; + + DatabaseType() { + this("\"", "\""); + } + + DatabaseType(String quote) { + this(quote, quote); + } + + DatabaseType(String startQuote, String endQuote) { + this.startQuote = startQuote; + this.endQuote = endQuote; + } + + /** + * Helper to safely get the DatabaseType from a string. + * + * @param dbType The string from configuration properties. + * @return The matching DatabaseType. + * @throws IllegalArgumentException if the dbType is null or not a valid type. + */ + public static DatabaseType from(String dbType) { + if (dbType == null) { + throw new IllegalArgumentException("Database type string cannot be null"); + } + // METASTORE must be handled before valueOf + if (METASTORE.name().equalsIgnoreCase(dbType)) { + return METASTORE; + } + try { + return valueOf(dbType.toUpperCase()); + } catch (IllegalArgumentException e) { + throw new IllegalArgumentException("Invalid database type: " + dbType, e); + } + } + + public String getStartQuote() { + return startQuote; + } + + public String getEndQuote() { + return endQuote; + } } 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 c85f49c28852..6c660003fcc0 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 @@ -67,8 +67,7 @@ public static void copyConfigurationToJob(Properties props, Map if (!key.equals(CONFIG_PWD) && !key.equals(CONFIG_PWD_KEYSTORE) && !key.equals(CONFIG_PWD_KEY) && - !key.equals(CONFIG_PWD_URI) && - !key.equals(CONFIG_USERNAME) + !key.equals(CONFIG_PWD_URI) ) { jobProps.put(String.valueOf(entry.getKey()), String.valueOf(entry.getValue())); } 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 1b98075e859f..3b09b5ee2bdd 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 @@ -26,6 +26,7 @@ import org.apache.hadoop.mapreduce.RecordWriter; import org.apache.hadoop.mapreduce.TaskAttemptContext; +import org.apache.hive.storage.jdbc.conf.DatabaseType; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -52,6 +53,7 @@ import java.util.regex.Pattern; import static com.google.common.base.MoreObjects.firstNonNull; +import static org.apache.hadoop.hive.ql.exec.Utilities.unescapeHiveJdbcIdentifier; /** * A data accessor that should in theory work with all JDBC compliant database drivers. @@ -364,7 +366,7 @@ protected String addBoundaryToQuery(String tableName, String sql, String partiti Matcher m = fromPattern.matcher(sql); Preconditions.checkArgument(m.matches()); - if (!tableName.equals(m.group(2).replaceAll("[`\"]", ""))) { + if (!tableName.equals(m.group(2))) { throw new RuntimeException("Cannot find " + tableName + " in sql query " + sql); } result = String.format("%s (%s) tmptable %s", m.group(1), boundaryQuery, m.group(3)); @@ -537,12 +539,27 @@ public boolean needColumnQuote() { return true; } + /** + * Quotes an identifier based on the database type. + * + * @param identifier The identifier to quote + * @param dbType The DatabaseType enum + * @return A database-specific quoted identifier (e.g., "\"Country\"" or "`Country`") + */ + protected static String quoteIdentifier(String identifier, DatabaseType dbType) { + if (identifier == null || dbType == null || dbType.getStartQuote() == null) { + return identifier; + } + return dbType.getStartQuote() + identifier + dbType.getEndQuote(); + } + private static String getQualifiedTableName(Configuration conf) { - String tableName = conf.get(Constants.JDBC_TABLE); + DatabaseType dbType = DatabaseType.from(conf.get(JdbcStorageConfig.DATABASE_TYPE.getPropertyName())); + String tableName = quoteIdentifier(unescapeHiveJdbcIdentifier(conf.get(Constants.JDBC_TABLE)), dbType); if (tableName == null) { return null; } - String schemaName = conf.get(Constants.JDBC_SCHEMA); + String schemaName = quoteIdentifier(unescapeHiveJdbcIdentifier(conf.get(Constants.JDBC_SCHEMA)), dbType); return schemaName == null ? tableName : schemaName + "." + tableName; } diff --git a/ql/src/java/org/apache/hadoop/hive/ql/exec/Utilities.java b/ql/src/java/org/apache/hadoop/hive/ql/exec/Utilities.java index 7e91d0bfb419..aac38a362879 100644 --- a/ql/src/java/org/apache/hadoop/hive/ql/exec/Utilities.java +++ b/ql/src/java/org/apache/hadoop/hive/ql/exec/Utilities.java @@ -5094,4 +5094,32 @@ public static String getTableOrMVSuffix(Context context, boolean createTableOrMV } return suffix; } + + /** + * Unescape a Hive JDBC identifier, removing surrounding double quotes if present. + * @param identifier the identifier to unescape + * @return the unescaped identifier + */ + public static String unescapeHiveJdbcIdentifier(String identifier) { + return unescapeIdentifier(identifier, '"'); + } + + /** + * Unescape an identifier, removing surrounding characters if present. + * + * @param identifier any identifier + * @param ch the surrounding character to remove + * @return the unescaped identifier + */ + public static String unescapeIdentifier(String identifier, Character ch) { + if (identifier == null || identifier.length() < 2) { + return identifier; + } + + if (identifier.charAt(0) == ch && identifier.charAt(identifier.length() - 1) == ch) { + return identifier.substring(1, identifier.length() - 1); + } + + return identifier; + } } diff --git a/ql/src/java/org/apache/hadoop/hive/ql/parse/CalcitePlanner.java b/ql/src/java/org/apache/hadoop/hive/ql/parse/CalcitePlanner.java index 00e96773fa83..251f0ed970c1 100644 --- a/ql/src/java/org/apache/hadoop/hive/ql/parse/CalcitePlanner.java +++ b/ql/src/java/org/apache/hadoop/hive/ql/parse/CalcitePlanner.java @@ -368,6 +368,7 @@ import javax.sql.DataSource; +import static org.apache.hadoop.hive.ql.exec.Utilities.unescapeHiveJdbcIdentifier; import static org.apache.hadoop.hive.ql.optimizer.calcite.HiveMaterializedViewASTSubQueryRewriteShuttle.getMaterializedViewByAST; import static org.apache.hadoop.hive.ql.metadata.RewriteAlgorithm.ANY; @@ -3179,8 +3180,8 @@ private RelNode genTableLogicalPlan(String tableAlias, QB qb) throws SemanticExc LOG.warn("No password found for accessing {} table via JDBC", fullyQualifiedTabName); } final String catalogName = tabMetaData.getProperty(Constants.JDBC_CATALOG); - final String schemaName = tabMetaData.getProperty(Constants.JDBC_SCHEMA); - final String tableName = tabMetaData.getProperty(Constants.JDBC_TABLE); + final String schemaName = unescapeHiveJdbcIdentifier(tabMetaData.getProperty(Constants.JDBC_SCHEMA)); + final String tableName = unescapeHiveJdbcIdentifier(tabMetaData.getProperty(Constants.JDBC_TABLE)); DataSource ds = JdbcSchema.dataSource(url, driver, user, pswd); SqlDialect jdbcDialect = JdbcSchema.createDialect(SqlDialectFactoryImpl.INSTANCE, ds); diff --git a/ql/src/test/queries/clientpositive/jdbc_case_sensitive_mariadb.q b/ql/src/test/queries/clientpositive/jdbc_case_sensitive_mariadb.q new file mode 100644 index 000000000000..def91a3696c4 --- /dev/null +++ b/ql/src/test/queries/clientpositive/jdbc_case_sensitive_mariadb.q @@ -0,0 +1,72 @@ +--! qt:database:mariadb:qdb:q_test_case_sensitive.mariadb.sql + +-- ============================================================== +-- Test with AUTHORIZATION ENABLED +-- ============================================================== + +set hive.test.authz.sstd.hs2.mode=true; +set hive.security.authorization.manager=org.apache.hadoop.hive.ql.security.authorization.plugin.sqlstd.SQLStdHiveAuthorizerFactoryForTest; +set hive.security.authorization.enabled=true; + +-- Test Case-Sensitive Schema and Table +CREATE EXTERNAL TABLE country_test (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://${system:hive.test.database.qdb.host}:${system:hive.test.database.qdb.port}/WorldData", + "hive.sql.dbcp.username" = "${system:hive.test.database.qdb.jdbc.username}", + "hive.sql.dbcp.password" = "${system:hive.test.database.qdb.jdbc.password}", + "hive.sql.schema" = "\"WorldData\"", + "hive.sql.table" = "\"Country\"" +); +SELECT * FROM country_test; + + +-- Test Case-Sensitive Partition Column +CREATE EXTERNAL TABLE cities_test (id int, name varchar(20), regionid 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://${system:hive.test.database.qdb.host}:${system:hive.test.database.qdb.port}/WorldData", + "hive.sql.dbcp.username" = "${system:hive.test.database.qdb.jdbc.username}", + "hive.sql.dbcp.password" = "${system:hive.test.database.qdb.jdbc.password}", + "hive.sql.schema" = "\"WorldData\"", + "hive.sql.table" = "\"Cities\"", + "hive.sql.partitionColumn" = "RegionID", + "hive.sql.numPartitions" = "2" +); +SELECT * FROM cities_test where regionid >= 20; + + +-- Test Case-Sensitive Query Field Names +CREATE EXTERNAL TABLE geography_test (id int, description varchar(50)) +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://${system:hive.test.database.qdb.host}:${system:hive.test.database.qdb.port}/WorldData", + "hive.sql.dbcp.username" = "${system:hive.test.database.qdb.jdbc.username}", + "hive.sql.dbcp.password" = "${system:hive.test.database.qdb.jdbc.password}", + "hive.sql.query" = "SELECT id, `Description` FROM `WorldData`.`Geography`" +); +SELECT * FROM geography_test; + +-- ============================================================== +-- Test with AUTHORIZATION DISABLED +-- ============================================================== + +set hive.security.authorization.enabled=false; + +SELECT * FROM country_test; + +SELECT * FROM cities_test where regionid >= 20; + +SELECT * FROM geography_test; + + +-- Cleanup +DROP TABLE country_test; +DROP TABLE cities_test; +DROP TABLE geography_test; \ No newline at end of file diff --git a/ql/src/test/queries/clientpositive/jdbc_case_sensitive_mssql.q b/ql/src/test/queries/clientpositive/jdbc_case_sensitive_mssql.q new file mode 100644 index 000000000000..479455a40ec9 --- /dev/null +++ b/ql/src/test/queries/clientpositive/jdbc_case_sensitive_mssql.q @@ -0,0 +1,72 @@ +--! qt:database:mssql:qdb:q_test_case_sensitive.mssql.sql + +-- ============================================================== +-- Test with AUTHORIZATION ENABLED +-- ============================================================== + +set hive.test.authz.sstd.hs2.mode=true; +set hive.security.authorization.manager=org.apache.hadoop.hive.ql.security.authorization.plugin.sqlstd.SQLStdHiveAuthorizerFactoryForTest; +set hive.security.authorization.enabled=true; + +-- Test Case-Sensitive Schema and Table +CREATE EXTERNAL TABLE country_test (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" = "${system:hive.test.database.qdb.jdbc.url}", + "hive.sql.dbcp.username" = "${system:hive.test.database.qdb.jdbc.username}", + "hive.sql.dbcp.password" = "${system:hive.test.database.qdb.jdbc.password}", + "hive.sql.schema" = "\"WorldData\"", + "hive.sql.table" = "\"Country\"" +); +SELECT * FROM country_test; + + +-- Test Case-Sensitive Partition Column +CREATE EXTERNAL TABLE cities_test (id int, name varchar(20), regionid int) +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" = "${system:hive.test.database.qdb.jdbc.url}", + "hive.sql.dbcp.username" = "${system:hive.test.database.qdb.jdbc.username}", + "hive.sql.dbcp.password" = "${system:hive.test.database.qdb.jdbc.password}", + "hive.sql.schema" = "\"WorldData\"", + "hive.sql.table" = "\"Cities\"", + "hive.sql.partitionColumn" = "RegionID", + "hive.sql.numPartitions" = "2" +); +SELECT * FROM cities_test where regionid >= 20; + + +-- Test Case-Sensitive Query Field Names +CREATE EXTERNAL TABLE geography_test (id int, description varchar(50)) +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" = "${system:hive.test.database.qdb.jdbc.url}", + "hive.sql.dbcp.username" = "${system:hive.test.database.qdb.jdbc.username}", + "hive.sql.dbcp.password" = "${system:hive.test.database.qdb.jdbc.password}", + "hive.sql.query" = "SELECT id, \"Description\" FROM \"WorldData\".\"Geography\"" +); +SELECT * FROM geography_test; + +-- ============================================================== +-- Test with AUTHORIZATION DISABLED +-- ============================================================== + +set hive.security.authorization.enabled=false; + +SELECT * FROM country_test; + +SELECT * FROM cities_test where regionid >= 20; + +SELECT * FROM geography_test; + + +-- Cleanup +DROP TABLE country_test; +DROP TABLE cities_test; +DROP TABLE geography_test; \ No newline at end of file diff --git a/ql/src/test/queries/clientpositive/jdbc_case_sensitive_oracle.q b/ql/src/test/queries/clientpositive/jdbc_case_sensitive_oracle.q new file mode 100644 index 000000000000..193db0cea565 --- /dev/null +++ b/ql/src/test/queries/clientpositive/jdbc_case_sensitive_oracle.q @@ -0,0 +1,72 @@ +--! qt:database:oracle:qdb:q_test_case_sensitive.oracle.sql + +-- ============================================================== +-- Test with AUTHORIZATION ENABLED +-- ============================================================== + +set hive.test.authz.sstd.hs2.mode=true; +set hive.security.authorization.manager=org.apache.hadoop.hive.ql.security.authorization.plugin.sqlstd.SQLStdHiveAuthorizerFactoryForTest; +set hive.security.authorization.enabled=true; + +-- Test Case-Sensitive Schema and Table +CREATE EXTERNAL TABLE country_test (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:@//${system:hive.test.database.qdb.host}:${system:hive.test.database.qdb.port}/XEPDB1", + "hive.sql.dbcp.username" = "\"WorldData\"", + "hive.sql.dbcp.password" = "QTestPassword123", + "hive.sql.schema" = "\"WorldData\"", + "hive.sql.table" = "\"Country\"" +); +SELECT * FROM country_test; + + +-- Test Case-Sensitive Partition Column +CREATE EXTERNAL TABLE cities_test (id int, name varchar(20), regionid 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:@//${system:hive.test.database.qdb.host}:${system:hive.test.database.qdb.port}/XEPDB1", + "hive.sql.dbcp.username" = "\"WorldData\"", + "hive.sql.dbcp.password" = "QTestPassword123", + "hive.sql.schema" = "\"WorldData\"", + "hive.sql.table" = "\"Cities\"", + "hive.sql.partitionColumn" = "RegionID", + "hive.sql.numPartitions" = "2" +); +SELECT * FROM cities_test where regionid >= 20; + + +-- Test Case-Sensitive Query Field Names +CREATE EXTERNAL TABLE geography_test (id int, description varchar(50)) +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:@//${system:hive.test.database.qdb.host}:${system:hive.test.database.qdb.port}/XEPDB1", + "hive.sql.dbcp.username" = "\"WorldData\"", + "hive.sql.dbcp.password" = "QTestPassword123", + "hive.sql.query" = "SELECT id, \"Description\" FROM \"WorldData\".\"Geography\"" +); +SELECT * FROM geography_test; + +-- ============================================================== +-- Test with AUTHORIZATION DISABLED +-- ============================================================== + +set hive.security.authorization.enabled=false; + +SELECT * FROM country_test; + +SELECT * FROM cities_test where regionid >= 20; + +SELECT * FROM geography_test; + + +-- Cleanup +DROP TABLE country_test; +DROP TABLE cities_test; +DROP TABLE geography_test; \ No newline at end of file diff --git a/ql/src/test/queries/clientpositive/jdbc_case_sensitive_postgres.q b/ql/src/test/queries/clientpositive/jdbc_case_sensitive_postgres.q new file mode 100644 index 000000000000..18262e35ce73 --- /dev/null +++ b/ql/src/test/queries/clientpositive/jdbc_case_sensitive_postgres.q @@ -0,0 +1,76 @@ +--! qt:database:postgres:qdb:q_test_case_sensitive.postgres.sql + +-- ============================================================== +-- Test with AUTHORIZATION ENABLED +-- ============================================================== + +set hive.test.authz.sstd.hs2.mode=true; +set hive.security.authorization.manager=org.apache.hadoop.hive.ql.security.authorization.plugin.sqlstd.SQLStdHiveAuthorizerFactoryForTest; +set hive.security.authorization.enabled=true; + +-- Test Case-Sensitive Schema and Table +-- This CREATE will pass, but the SELECT will fail authorization. +CREATE EXTERNAL TABLE country_test (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" = "${system:hive.test.database.qdb.jdbc.url}", + "hive.sql.dbcp.username" = "${system:hive.test.database.qdb.jdbc.username}", + "hive.sql.dbcp.password" = "${system:hive.test.database.qdb.jdbc.password}", + "hive.sql.schema" = "\"WorldData\"", + "hive.sql.table" = "\"Country\"" +); +SELECT * FROM country_test; + + +-- Test Case-Sensitive Partition Column +-- This CREATE will pass, but the SELECT will fail authorization. +CREATE EXTERNAL TABLE cities_test (id int, name varchar(20), regionid int) +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" = "${system:hive.test.database.qdb.jdbc.url}", + "hive.sql.dbcp.username" = "${system:hive.test.database.qdb.jdbc.username}", + "hive.sql.dbcp.password" = "${system:hive.test.database.qdb.jdbc.password}", + "hive.sql.schema" = "\"WorldData\"", + "hive.sql.table" = "\"Cities\"", + "hive.sql.partitionColumn" = "RegionID", + "hive.sql.numPartitions" = "2" +); +SELECT * FROM cities_test where regionid >= 20; + + +-- Test Case-Sensitive Query Field Names +-- (Should fail in SerDe/Iterator with Column not found) +-- This tests the bug in JdbcSerDe and JdbcRecordIterator +CREATE EXTERNAL TABLE geography_test (id int, description varchar(50)) +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" = "${system:hive.test.database.qdb.jdbc.url}", + "hive.sql.dbcp.username" = "${system:hive.test.database.qdb.jdbc.username}", + "hive.sql.dbcp.password" = "${system:hive.test.database.qdb.jdbc.password}", + "hive.sql.query" = "SELECT id, \"Description\" FROM \"WorldData\".\"Geography\"" +); +SELECT * FROM geography_test; + +-- ============================================================== +-- Test with AUTHORIZATION DISABLED +-- ============================================================== + +set hive.security.authorization.enabled=false; + +SELECT * FROM country_test; + +SELECT * FROM cities_test where regionid >= 20; + +SELECT * FROM geography_test; + + +-- Cleanup +DROP TABLE country_test; +DROP TABLE cities_test; +DROP TABLE geography_test; \ No newline at end of file diff --git a/ql/src/test/results/clientpositive/llap/explain_jdbc.q.out b/ql/src/test/results/clientpositive/llap/explain_jdbc.q.out index 36289efb4772..a1fd8fe7949c 100644 Binary files a/ql/src/test/results/clientpositive/llap/explain_jdbc.q.out and b/ql/src/test/results/clientpositive/llap/explain_jdbc.q.out differ diff --git a/ql/src/test/results/clientpositive/llap/jdbc_case_sensitive_mariadb.q.out b/ql/src/test/results/clientpositive/llap/jdbc_case_sensitive_mariadb.q.out new file mode 100644 index 000000000000..02de9911ef54 --- /dev/null +++ b/ql/src/test/results/clientpositive/llap/jdbc_case_sensitive_mariadb.q.out @@ -0,0 +1,188 @@ +PREHOOK: query: CREATE EXTERNAL TABLE country_test (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/WorldData", + "hive.sql.dbcp.username" = "root", + "hive.sql.dbcp.password" = "qtestpassword", + "hive.sql.schema" = "\"WorldData\"", + "hive.sql.table" = "\"Country\"" +) +PREHOOK: type: CREATETABLE +PREHOOK: Output: database:default +PREHOOK: Output: default@country_test +POSTHOOK: query: CREATE EXTERNAL TABLE country_test (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/WorldData", + "hive.sql.dbcp.username" = "root", + "hive.sql.dbcp.password" = "qtestpassword", + "hive.sql.schema" = "\"WorldData\"", + "hive.sql.table" = "\"Country\"" +) +POSTHOOK: type: CREATETABLE +POSTHOOK: Output: database:default +POSTHOOK: Output: default@country_test +PREHOOK: query: SELECT * FROM country_test +PREHOOK: type: QUERY +PREHOOK: Input: default@country_test +#### A masked pattern was here #### +POSTHOOK: query: SELECT * FROM country_test +POSTHOOK: type: QUERY +POSTHOOK: Input: default@country_test +#### A masked pattern was here #### +1 India +2 USA +3 Japan +4 Germany +PREHOOK: query: CREATE EXTERNAL TABLE cities_test (id int, name varchar(20), regionid 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/WorldData", + "hive.sql.dbcp.username" = "root", + "hive.sql.dbcp.password" = "qtestpassword", + "hive.sql.schema" = "\"WorldData\"", + "hive.sql.table" = "\"Cities\"", + "hive.sql.partitionColumn" = "RegionID", + "hive.sql.numPartitions" = "2" +) +PREHOOK: type: CREATETABLE +PREHOOK: Output: database:default +PREHOOK: Output: default@cities_test +POSTHOOK: query: CREATE EXTERNAL TABLE cities_test (id int, name varchar(20), regionid 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/WorldData", + "hive.sql.dbcp.username" = "root", + "hive.sql.dbcp.password" = "qtestpassword", + "hive.sql.schema" = "\"WorldData\"", + "hive.sql.table" = "\"Cities\"", + "hive.sql.partitionColumn" = "RegionID", + "hive.sql.numPartitions" = "2" +) +POSTHOOK: type: CREATETABLE +POSTHOOK: Output: database:default +POSTHOOK: Output: default@cities_test +PREHOOK: query: SELECT * FROM cities_test where regionid >= 20 +PREHOOK: type: QUERY +PREHOOK: Input: default@cities_test +#### A masked pattern was here #### +POSTHOOK: query: SELECT * FROM cities_test where regionid >= 20 +POSTHOOK: type: QUERY +POSTHOOK: Input: default@cities_test +#### A masked pattern was here #### +2 New York 20 +3 Tokyo 30 +4 Berlin 40 +6 Kyoto 30 +PREHOOK: query: CREATE EXTERNAL TABLE geography_test (id int, description varchar(50)) +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/WorldData", + "hive.sql.dbcp.username" = "root", + "hive.sql.dbcp.password" = "qtestpassword", + "hive.sql.query" = "SELECT id, `Description` FROM `WorldData`.`Geography`" +) +PREHOOK: type: CREATETABLE +PREHOOK: Output: database:default +PREHOOK: Output: default@geography_test +POSTHOOK: query: CREATE EXTERNAL TABLE geography_test (id int, description varchar(50)) +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/WorldData", + "hive.sql.dbcp.username" = "root", + "hive.sql.dbcp.password" = "qtestpassword", + "hive.sql.query" = "SELECT id, `Description` FROM `WorldData`.`Geography`" +) +POSTHOOK: type: CREATETABLE +POSTHOOK: Output: database:default +POSTHOOK: Output: default@geography_test +PREHOOK: query: SELECT * FROM geography_test +PREHOOK: type: QUERY +PREHOOK: Input: default@geography_test +#### A masked pattern was here #### +POSTHOOK: query: SELECT * FROM geography_test +POSTHOOK: type: QUERY +POSTHOOK: Input: default@geography_test +#### A masked pattern was here #### +1 Asia +2 North America +3 Asia +4 Europe +PREHOOK: query: SELECT * FROM country_test +PREHOOK: type: QUERY +PREHOOK: Input: default@country_test +#### A masked pattern was here #### +POSTHOOK: query: SELECT * FROM country_test +POSTHOOK: type: QUERY +POSTHOOK: Input: default@country_test +#### A masked pattern was here #### +1 India +2 USA +3 Japan +4 Germany +PREHOOK: query: SELECT * FROM cities_test where regionid >= 20 +PREHOOK: type: QUERY +PREHOOK: Input: default@cities_test +#### A masked pattern was here #### +POSTHOOK: query: SELECT * FROM cities_test where regionid >= 20 +POSTHOOK: type: QUERY +POSTHOOK: Input: default@cities_test +#### A masked pattern was here #### +2 New York 20 +3 Tokyo 30 +4 Berlin 40 +6 Kyoto 30 +PREHOOK: query: SELECT * FROM geography_test +PREHOOK: type: QUERY +PREHOOK: Input: default@geography_test +#### A masked pattern was here #### +POSTHOOK: query: SELECT * FROM geography_test +POSTHOOK: type: QUERY +POSTHOOK: Input: default@geography_test +#### A masked pattern was here #### +1 Asia +2 North America +3 Asia +4 Europe +PREHOOK: query: DROP TABLE country_test +PREHOOK: type: DROPTABLE +PREHOOK: Input: default@country_test +PREHOOK: Output: database:default +PREHOOK: Output: default@country_test +POSTHOOK: query: DROP TABLE country_test +POSTHOOK: type: DROPTABLE +POSTHOOK: Input: default@country_test +POSTHOOK: Output: database:default +POSTHOOK: Output: default@country_test +PREHOOK: query: DROP TABLE cities_test +PREHOOK: type: DROPTABLE +PREHOOK: Input: default@cities_test +PREHOOK: Output: database:default +PREHOOK: Output: default@cities_test +POSTHOOK: query: DROP TABLE cities_test +POSTHOOK: type: DROPTABLE +POSTHOOK: Input: default@cities_test +POSTHOOK: Output: database:default +POSTHOOK: Output: default@cities_test +PREHOOK: query: DROP TABLE geography_test +PREHOOK: type: DROPTABLE +PREHOOK: Input: default@geography_test +PREHOOK: Output: database:default +PREHOOK: Output: default@geography_test +POSTHOOK: query: DROP TABLE geography_test +POSTHOOK: type: DROPTABLE +POSTHOOK: Input: default@geography_test +POSTHOOK: Output: database:default +POSTHOOK: Output: default@geography_test diff --git a/ql/src/test/results/clientpositive/llap/jdbc_case_sensitive_mssql.q.out b/ql/src/test/results/clientpositive/llap/jdbc_case_sensitive_mssql.q.out new file mode 100644 index 000000000000..350220a774e6 --- /dev/null +++ b/ql/src/test/results/clientpositive/llap/jdbc_case_sensitive_mssql.q.out @@ -0,0 +1,188 @@ +PREHOOK: query: CREATE EXTERNAL TABLE country_test (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.schema" = "\"WorldData\"", + "hive.sql.table" = "\"Country\"" +) +PREHOOK: type: CREATETABLE +PREHOOK: Output: database:default +PREHOOK: Output: default@country_test +POSTHOOK: query: CREATE EXTERNAL TABLE country_test (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.schema" = "\"WorldData\"", + "hive.sql.table" = "\"Country\"" +) +POSTHOOK: type: CREATETABLE +POSTHOOK: Output: database:default +POSTHOOK: Output: default@country_test +PREHOOK: query: SELECT * FROM country_test +PREHOOK: type: QUERY +PREHOOK: Input: default@country_test +#### A masked pattern was here #### +POSTHOOK: query: SELECT * FROM country_test +POSTHOOK: type: QUERY +POSTHOOK: Input: default@country_test +#### A masked pattern was here #### +1 India +2 USA +3 Japan +4 Germany +PREHOOK: query: CREATE EXTERNAL TABLE cities_test (id int, name varchar(20), regionid int) +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.schema" = "\"WorldData\"", + "hive.sql.table" = "\"Cities\"", + "hive.sql.partitionColumn" = "RegionID", + "hive.sql.numPartitions" = "2" +) +PREHOOK: type: CREATETABLE +PREHOOK: Output: database:default +PREHOOK: Output: default@cities_test +POSTHOOK: query: CREATE EXTERNAL TABLE cities_test (id int, name varchar(20), regionid int) +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.schema" = "\"WorldData\"", + "hive.sql.table" = "\"Cities\"", + "hive.sql.partitionColumn" = "RegionID", + "hive.sql.numPartitions" = "2" +) +POSTHOOK: type: CREATETABLE +POSTHOOK: Output: database:default +POSTHOOK: Output: default@cities_test +PREHOOK: query: SELECT * FROM cities_test where regionid >= 20 +PREHOOK: type: QUERY +PREHOOK: Input: default@cities_test +#### A masked pattern was here #### +POSTHOOK: query: SELECT * FROM cities_test where regionid >= 20 +POSTHOOK: type: QUERY +POSTHOOK: Input: default@cities_test +#### A masked pattern was here #### +2 New York 20 +3 Tokyo 30 +4 Berlin 40 +6 Kyoto 30 +PREHOOK: query: CREATE EXTERNAL TABLE geography_test (id int, description varchar(50)) +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.query" = "SELECT id, \"Description\" FROM \"WorldData\".\"Geography\"" +) +PREHOOK: type: CREATETABLE +PREHOOK: Output: database:default +PREHOOK: Output: default@geography_test +POSTHOOK: query: CREATE EXTERNAL TABLE geography_test (id int, description varchar(50)) +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.query" = "SELECT id, \"Description\" FROM \"WorldData\".\"Geography\"" +) +POSTHOOK: type: CREATETABLE +POSTHOOK: Output: database:default +POSTHOOK: Output: default@geography_test +PREHOOK: query: SELECT * FROM geography_test +PREHOOK: type: QUERY +PREHOOK: Input: default@geography_test +#### A masked pattern was here #### +POSTHOOK: query: SELECT * FROM geography_test +POSTHOOK: type: QUERY +POSTHOOK: Input: default@geography_test +#### A masked pattern was here #### +1 Asia +2 North America +3 Asia +4 Europe +PREHOOK: query: SELECT * FROM country_test +PREHOOK: type: QUERY +PREHOOK: Input: default@country_test +#### A masked pattern was here #### +POSTHOOK: query: SELECT * FROM country_test +POSTHOOK: type: QUERY +POSTHOOK: Input: default@country_test +#### A masked pattern was here #### +1 India +2 USA +3 Japan +4 Germany +PREHOOK: query: SELECT * FROM cities_test where regionid >= 20 +PREHOOK: type: QUERY +PREHOOK: Input: default@cities_test +#### A masked pattern was here #### +POSTHOOK: query: SELECT * FROM cities_test where regionid >= 20 +POSTHOOK: type: QUERY +POSTHOOK: Input: default@cities_test +#### A masked pattern was here #### +2 New York 20 +3 Tokyo 30 +4 Berlin 40 +6 Kyoto 30 +PREHOOK: query: SELECT * FROM geography_test +PREHOOK: type: QUERY +PREHOOK: Input: default@geography_test +#### A masked pattern was here #### +POSTHOOK: query: SELECT * FROM geography_test +POSTHOOK: type: QUERY +POSTHOOK: Input: default@geography_test +#### A masked pattern was here #### +1 Asia +2 North America +3 Asia +4 Europe +PREHOOK: query: DROP TABLE country_test +PREHOOK: type: DROPTABLE +PREHOOK: Input: default@country_test +PREHOOK: Output: database:default +PREHOOK: Output: default@country_test +POSTHOOK: query: DROP TABLE country_test +POSTHOOK: type: DROPTABLE +POSTHOOK: Input: default@country_test +POSTHOOK: Output: database:default +POSTHOOK: Output: default@country_test +PREHOOK: query: DROP TABLE cities_test +PREHOOK: type: DROPTABLE +PREHOOK: Input: default@cities_test +PREHOOK: Output: database:default +PREHOOK: Output: default@cities_test +POSTHOOK: query: DROP TABLE cities_test +POSTHOOK: type: DROPTABLE +POSTHOOK: Input: default@cities_test +POSTHOOK: Output: database:default +POSTHOOK: Output: default@cities_test +PREHOOK: query: DROP TABLE geography_test +PREHOOK: type: DROPTABLE +PREHOOK: Input: default@geography_test +PREHOOK: Output: database:default +PREHOOK: Output: default@geography_test +POSTHOOK: query: DROP TABLE geography_test +POSTHOOK: type: DROPTABLE +POSTHOOK: Input: default@geography_test +POSTHOOK: Output: database:default +POSTHOOK: Output: default@geography_test diff --git a/ql/src/test/results/clientpositive/llap/jdbc_case_sensitive_oracle.q.out b/ql/src/test/results/clientpositive/llap/jdbc_case_sensitive_oracle.q.out new file mode 100644 index 000000000000..f0182f2595d5 --- /dev/null +++ b/ql/src/test/results/clientpositive/llap/jdbc_case_sensitive_oracle.q.out @@ -0,0 +1,188 @@ +PREHOOK: query: CREATE EXTERNAL TABLE country_test (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" = "\"WorldData\"", + "hive.sql.dbcp.password" = "QTestPassword123", + "hive.sql.schema" = "\"WorldData\"", + "hive.sql.table" = "\"Country\"" +) +PREHOOK: type: CREATETABLE +PREHOOK: Output: database:default +PREHOOK: Output: default@country_test +POSTHOOK: query: CREATE EXTERNAL TABLE country_test (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" = "\"WorldData\"", + "hive.sql.dbcp.password" = "QTestPassword123", + "hive.sql.schema" = "\"WorldData\"", + "hive.sql.table" = "\"Country\"" +) +POSTHOOK: type: CREATETABLE +POSTHOOK: Output: database:default +POSTHOOK: Output: default@country_test +PREHOOK: query: SELECT * FROM country_test +PREHOOK: type: QUERY +PREHOOK: Input: default@country_test +#### A masked pattern was here #### +POSTHOOK: query: SELECT * FROM country_test +POSTHOOK: type: QUERY +POSTHOOK: Input: default@country_test +#### A masked pattern was here #### +1 India +2 USA +3 Japan +4 Germany +PREHOOK: query: CREATE EXTERNAL TABLE cities_test (id int, name varchar(20), regionid 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/XEPDB1", + "hive.sql.dbcp.username" = "\"WorldData\"", + "hive.sql.dbcp.password" = "QTestPassword123", + "hive.sql.schema" = "\"WorldData\"", + "hive.sql.table" = "\"Cities\"", + "hive.sql.partitionColumn" = "RegionID", + "hive.sql.numPartitions" = "2" +) +PREHOOK: type: CREATETABLE +PREHOOK: Output: database:default +PREHOOK: Output: default@cities_test +POSTHOOK: query: CREATE EXTERNAL TABLE cities_test (id int, name varchar(20), regionid 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/XEPDB1", + "hive.sql.dbcp.username" = "\"WorldData\"", + "hive.sql.dbcp.password" = "QTestPassword123", + "hive.sql.schema" = "\"WorldData\"", + "hive.sql.table" = "\"Cities\"", + "hive.sql.partitionColumn" = "RegionID", + "hive.sql.numPartitions" = "2" +) +POSTHOOK: type: CREATETABLE +POSTHOOK: Output: database:default +POSTHOOK: Output: default@cities_test +PREHOOK: query: SELECT * FROM cities_test where regionid >= 20 +PREHOOK: type: QUERY +PREHOOK: Input: default@cities_test +#### A masked pattern was here #### +POSTHOOK: query: SELECT * FROM cities_test where regionid >= 20 +POSTHOOK: type: QUERY +POSTHOOK: Input: default@cities_test +#### A masked pattern was here #### +2 New York 20 +3 Tokyo 30 +4 Berlin 40 +6 Kyoto 30 +PREHOOK: query: CREATE EXTERNAL TABLE geography_test (id int, description varchar(50)) +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" = "\"WorldData\"", + "hive.sql.dbcp.password" = "QTestPassword123", + "hive.sql.query" = "SELECT id, \"Description\" FROM \"WorldData\".\"Geography\"" +) +PREHOOK: type: CREATETABLE +PREHOOK: Output: database:default +PREHOOK: Output: default@geography_test +POSTHOOK: query: CREATE EXTERNAL TABLE geography_test (id int, description varchar(50)) +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" = "\"WorldData\"", + "hive.sql.dbcp.password" = "QTestPassword123", + "hive.sql.query" = "SELECT id, \"Description\" FROM \"WorldData\".\"Geography\"" +) +POSTHOOK: type: CREATETABLE +POSTHOOK: Output: database:default +POSTHOOK: Output: default@geography_test +PREHOOK: query: SELECT * FROM geography_test +PREHOOK: type: QUERY +PREHOOK: Input: default@geography_test +#### A masked pattern was here #### +POSTHOOK: query: SELECT * FROM geography_test +POSTHOOK: type: QUERY +POSTHOOK: Input: default@geography_test +#### A masked pattern was here #### +1 Asia +2 North America +3 Asia +4 Europe +PREHOOK: query: SELECT * FROM country_test +PREHOOK: type: QUERY +PREHOOK: Input: default@country_test +#### A masked pattern was here #### +POSTHOOK: query: SELECT * FROM country_test +POSTHOOK: type: QUERY +POSTHOOK: Input: default@country_test +#### A masked pattern was here #### +1 India +2 USA +3 Japan +4 Germany +PREHOOK: query: SELECT * FROM cities_test where regionid >= 20 +PREHOOK: type: QUERY +PREHOOK: Input: default@cities_test +#### A masked pattern was here #### +POSTHOOK: query: SELECT * FROM cities_test where regionid >= 20 +POSTHOOK: type: QUERY +POSTHOOK: Input: default@cities_test +#### A masked pattern was here #### +2 New York 20 +3 Tokyo 30 +4 Berlin 40 +6 Kyoto 30 +PREHOOK: query: SELECT * FROM geography_test +PREHOOK: type: QUERY +PREHOOK: Input: default@geography_test +#### A masked pattern was here #### +POSTHOOK: query: SELECT * FROM geography_test +POSTHOOK: type: QUERY +POSTHOOK: Input: default@geography_test +#### A masked pattern was here #### +1 Asia +2 North America +3 Asia +4 Europe +PREHOOK: query: DROP TABLE country_test +PREHOOK: type: DROPTABLE +PREHOOK: Input: default@country_test +PREHOOK: Output: database:default +PREHOOK: Output: default@country_test +POSTHOOK: query: DROP TABLE country_test +POSTHOOK: type: DROPTABLE +POSTHOOK: Input: default@country_test +POSTHOOK: Output: database:default +POSTHOOK: Output: default@country_test +PREHOOK: query: DROP TABLE cities_test +PREHOOK: type: DROPTABLE +PREHOOK: Input: default@cities_test +PREHOOK: Output: database:default +PREHOOK: Output: default@cities_test +POSTHOOK: query: DROP TABLE cities_test +POSTHOOK: type: DROPTABLE +POSTHOOK: Input: default@cities_test +POSTHOOK: Output: database:default +POSTHOOK: Output: default@cities_test +PREHOOK: query: DROP TABLE geography_test +PREHOOK: type: DROPTABLE +PREHOOK: Input: default@geography_test +PREHOOK: Output: database:default +PREHOOK: Output: default@geography_test +POSTHOOK: query: DROP TABLE geography_test +POSTHOOK: type: DROPTABLE +POSTHOOK: Input: default@geography_test +POSTHOOK: Output: database:default +POSTHOOK: Output: default@geography_test diff --git a/ql/src/test/results/clientpositive/llap/jdbc_case_sensitive_postgres.q.out b/ql/src/test/results/clientpositive/llap/jdbc_case_sensitive_postgres.q.out new file mode 100644 index 000000000000..8396f20cd0ca --- /dev/null +++ b/ql/src/test/results/clientpositive/llap/jdbc_case_sensitive_postgres.q.out @@ -0,0 +1,188 @@ +PREHOOK: query: CREATE EXTERNAL TABLE country_test (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/qdb", + "hive.sql.dbcp.username" = "qtestuser", + "hive.sql.dbcp.password" = "qtestpassword", + "hive.sql.schema" = "\"WorldData\"", + "hive.sql.table" = "\"Country\"" +) +PREHOOK: type: CREATETABLE +PREHOOK: Output: database:default +PREHOOK: Output: default@country_test +POSTHOOK: query: CREATE EXTERNAL TABLE country_test (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/qdb", + "hive.sql.dbcp.username" = "qtestuser", + "hive.sql.dbcp.password" = "qtestpassword", + "hive.sql.schema" = "\"WorldData\"", + "hive.sql.table" = "\"Country\"" +) +POSTHOOK: type: CREATETABLE +POSTHOOK: Output: database:default +POSTHOOK: Output: default@country_test +PREHOOK: query: SELECT * FROM country_test +PREHOOK: type: QUERY +PREHOOK: Input: default@country_test +#### A masked pattern was here #### +POSTHOOK: query: SELECT * FROM country_test +POSTHOOK: type: QUERY +POSTHOOK: Input: default@country_test +#### A masked pattern was here #### +1 India +2 USA +3 Japan +4 Germany +PREHOOK: query: CREATE EXTERNAL TABLE cities_test (id int, name varchar(20), regionid int) +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/qdb", + "hive.sql.dbcp.username" = "qtestuser", + "hive.sql.dbcp.password" = "qtestpassword", + "hive.sql.schema" = "\"WorldData\"", + "hive.sql.table" = "\"Cities\"", + "hive.sql.partitionColumn" = "RegionID", + "hive.sql.numPartitions" = "2" +) +PREHOOK: type: CREATETABLE +PREHOOK: Output: database:default +PREHOOK: Output: default@cities_test +POSTHOOK: query: CREATE EXTERNAL TABLE cities_test (id int, name varchar(20), regionid int) +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/qdb", + "hive.sql.dbcp.username" = "qtestuser", + "hive.sql.dbcp.password" = "qtestpassword", + "hive.sql.schema" = "\"WorldData\"", + "hive.sql.table" = "\"Cities\"", + "hive.sql.partitionColumn" = "RegionID", + "hive.sql.numPartitions" = "2" +) +POSTHOOK: type: CREATETABLE +POSTHOOK: Output: database:default +POSTHOOK: Output: default@cities_test +PREHOOK: query: SELECT * FROM cities_test where regionid >= 20 +PREHOOK: type: QUERY +PREHOOK: Input: default@cities_test +#### A masked pattern was here #### +POSTHOOK: query: SELECT * FROM cities_test where regionid >= 20 +POSTHOOK: type: QUERY +POSTHOOK: Input: default@cities_test +#### A masked pattern was here #### +2 New York 20 +3 Tokyo 30 +4 Berlin 40 +6 Kyoto 30 +PREHOOK: query: CREATE EXTERNAL TABLE geography_test (id int, description varchar(50)) +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/qdb", + "hive.sql.dbcp.username" = "qtestuser", + "hive.sql.dbcp.password" = "qtestpassword", + "hive.sql.query" = "SELECT id, \"Description\" FROM \"WorldData\".\"Geography\"" +) +PREHOOK: type: CREATETABLE +PREHOOK: Output: database:default +PREHOOK: Output: default@geography_test +POSTHOOK: query: CREATE EXTERNAL TABLE geography_test (id int, description varchar(50)) +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/qdb", + "hive.sql.dbcp.username" = "qtestuser", + "hive.sql.dbcp.password" = "qtestpassword", + "hive.sql.query" = "SELECT id, \"Description\" FROM \"WorldData\".\"Geography\"" +) +POSTHOOK: type: CREATETABLE +POSTHOOK: Output: database:default +POSTHOOK: Output: default@geography_test +PREHOOK: query: SELECT * FROM geography_test +PREHOOK: type: QUERY +PREHOOK: Input: default@geography_test +#### A masked pattern was here #### +POSTHOOK: query: SELECT * FROM geography_test +POSTHOOK: type: QUERY +POSTHOOK: Input: default@geography_test +#### A masked pattern was here #### +1 Asia +2 North America +3 Asia +4 Europe +PREHOOK: query: SELECT * FROM country_test +PREHOOK: type: QUERY +PREHOOK: Input: default@country_test +#### A masked pattern was here #### +POSTHOOK: query: SELECT * FROM country_test +POSTHOOK: type: QUERY +POSTHOOK: Input: default@country_test +#### A masked pattern was here #### +1 India +2 USA +3 Japan +4 Germany +PREHOOK: query: SELECT * FROM cities_test where regionid >= 20 +PREHOOK: type: QUERY +PREHOOK: Input: default@cities_test +#### A masked pattern was here #### +POSTHOOK: query: SELECT * FROM cities_test where regionid >= 20 +POSTHOOK: type: QUERY +POSTHOOK: Input: default@cities_test +#### A masked pattern was here #### +2 New York 20 +3 Tokyo 30 +4 Berlin 40 +6 Kyoto 30 +PREHOOK: query: SELECT * FROM geography_test +PREHOOK: type: QUERY +PREHOOK: Input: default@geography_test +#### A masked pattern was here #### +POSTHOOK: query: SELECT * FROM geography_test +POSTHOOK: type: QUERY +POSTHOOK: Input: default@geography_test +#### A masked pattern was here #### +1 Asia +2 North America +3 Asia +4 Europe +PREHOOK: query: DROP TABLE country_test +PREHOOK: type: DROPTABLE +PREHOOK: Input: default@country_test +PREHOOK: Output: database:default +PREHOOK: Output: default@country_test +POSTHOOK: query: DROP TABLE country_test +POSTHOOK: type: DROPTABLE +POSTHOOK: Input: default@country_test +POSTHOOK: Output: database:default +POSTHOOK: Output: default@country_test +PREHOOK: query: DROP TABLE cities_test +PREHOOK: type: DROPTABLE +PREHOOK: Input: default@cities_test +PREHOOK: Output: database:default +PREHOOK: Output: default@cities_test +POSTHOOK: query: DROP TABLE cities_test +POSTHOOK: type: DROPTABLE +POSTHOOK: Input: default@cities_test +POSTHOOK: Output: database:default +POSTHOOK: Output: default@cities_test +PREHOOK: query: DROP TABLE geography_test +PREHOOK: type: DROPTABLE +PREHOOK: Input: default@geography_test +PREHOOK: Output: database:default +PREHOOK: Output: default@geography_test +POSTHOOK: query: DROP TABLE geography_test +POSTHOOK: type: DROPTABLE +POSTHOOK: Input: default@geography_test +POSTHOOK: Output: database:default +POSTHOOK: Output: default@geography_test