/**
* 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.hive.jdbc;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.net.URI;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Types;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.Callable;
import java.util.concurrent.CancellationException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
import java.util.concurrent.RejectedExecutionException;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import org.apache.commons.lang.StringUtils;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.fs.permission.FsPermission;
import org.apache.hadoop.hive.conf.HiveConf;
import org.apache.hadoop.hive.conf.HiveConf.ConfVars;
import org.apache.hadoop.hive.metastore.ObjectStore;
import org.apache.hadoop.hive.ql.exec.FunctionRegistry;
import org.apache.hive.common.util.ReflectionUtil;
import org.apache.hive.jdbc.miniHS2.MiniHS2;
import org.datanucleus.ClassLoaderResolver;
import org.datanucleus.NucleusContext;
import org.datanucleus.api.jdo.JDOPersistenceManagerFactory;
import org.datanucleus.AbstractNucleusContext;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
public class TestJdbcWithMiniHS2 {
private static MiniHS2 miniHS2 = null;
private static String dataFileDir;
private static Path kvDataFilePath;
private static final String tmpDir = System.getProperty("test.tmp.dir");
private static final String testDbName = "testjdbcminihs2";
private static final String defaultDbName = "default";
private static final String tableName = "testjdbcminihs2tbl";
private static final String tableComment = "Simple table";
private static Connection conDefault = null;
private static Connection conTestDb = null;
private static String testUdfClassName =
"org.apache.hadoop.hive.contrib.udf.example.UDFExampleAdd";
@BeforeClass
public static void setupBeforeClass() throws Exception {
MiniHS2.cleanupLocalDir();
HiveConf conf = new HiveConf();
dataFileDir = conf.get("test.data.files").replace('\\', '/').replace("c:", "");
kvDataFilePath = new Path(dataFileDir, "kv1.txt");
try {
startMiniHS2(conf);
} catch (Exception e) {
System.out.println("Unable to start MiniHS2: " + e);
throw e;
}
// Open default connections which will be used throughout the tests
try {
openDefaultConnections();
} catch (Exception e) {
System.out.println("Unable to open default connections to MiniHS2: " + e);
throw e;
}
Statement stmt = conDefault.createStatement();
stmt.execute("drop database if exists " + testDbName + " cascade");
stmt.execute("create database " + testDbName);
stmt.close();
try {
openTestConnections();
} catch (Exception e) {
System.out.println("Unable to open default connections to MiniHS2: " + e);
throw e;
}
// tables in test db
createTestTables(conTestDb, testDbName);
}
private static Connection getConnection() throws Exception {
return getConnection(miniHS2.getJdbcURL(), System.getProperty("user.name"), "bar");
}
private static Connection getConnection(String dbName) throws Exception {
return getConnection(miniHS2.getJdbcURL(dbName), System.getProperty("user.name"), "bar");
}
private static Connection getConnection(String jdbcURL, String user, String pwd)
throws SQLException {
Connection conn = DriverManager.getConnection(jdbcURL, user, pwd);
assertNotNull(conn);
return conn;
}
private static void createTestTables(Connection conn, String dbName) throws SQLException {
Statement stmt = conn.createStatement();
Path dataFilePath = new Path(dataFileDir, "kv1.txt");
// We've already dropped testDbName in constructor & we also drop it in tearDownAfterClass
String prefix = dbName + ".";
String tableName = prefix + TestJdbcWithMiniHS2.tableName;
// create a table
stmt.execute("create table " + tableName
+ " (int_col int comment 'the int column', value string) comment '" + tableComment + "'");
// load data
stmt.execute("load data local inpath '" + dataFilePath.toString() + "' into table " + tableName);
stmt.close();
}
@AfterClass
public static void tearDownAfterClass() throws Exception {
// drop test db and its tables and views
Statement stmt = conDefault.createStatement();
stmt.execute("set hive.support.concurrency = false");
stmt.execute("drop database if exists " + testDbName + " cascade");
stmt.close();
if (conTestDb != null) {
conTestDb.close();
}
if (conDefault != null) {
conDefault.close();
}
stopMiniHS2();
cleanupMiniHS2();
}
private static void restoreMiniHS2AndConnections() throws Exception {
if (conTestDb != null) {
try {
conTestDb.close();
} catch (SQLException e) {
// Do nothing
}
}
if (conDefault != null) {
try {
conDefault.close();
} catch (SQLException e) {
// Do nothing
}
}
stopMiniHS2();
HiveConf conf = new HiveConf();
startMiniHS2(conf);
openDefaultConnections();
openTestConnections();
}
private static void startMiniHS2(HiveConf conf) throws Exception {
conf.setBoolVar(ConfVars.HIVE_SUPPORT_CONCURRENCY, false);
conf.setBoolVar(ConfVars.HIVE_SERVER2_LOGGING_OPERATION_ENABLED, false);
miniHS2 = new MiniHS2.Builder().withConf(conf).cleanupLocalDirOnStartup(false).build();
Map<String, String> confOverlay = new HashMap<String, String>();
miniHS2.start(confOverlay);
}
private static void stopMiniHS2() {
if ((miniHS2 != null) && (miniHS2.isStarted())) {
miniHS2.stop();
}
}
private static void cleanupMiniHS2() throws IOException {
if (miniHS2 != null) {
miniHS2.cleanup();
}
MiniHS2.cleanupLocalDir();
}
private static void openDefaultConnections() throws Exception {
conDefault = getConnection();
}
private static void openTestConnections() throws Exception {
conTestDb = getConnection(testDbName);
}
@Test
public void testConnection() throws Exception {
Statement stmt = conTestDb.createStatement();
ResultSet res = stmt.executeQuery("select * from " + tableName + " limit 5");
assertTrue(res.next());
res.close();
stmt.close();
}
@Test
public void testParallelCompilation() throws Exception {
Statement stmt = conTestDb.createStatement();
stmt.execute("set hive.driver.parallel.compilation=true");
stmt.execute("set hive.server2.async.exec.async.compile=true");
stmt.close();
startConcurrencyTest(conTestDb, tableName, 10);
Connection conn = getConnection(testDbName);
startConcurrencyTest(conn, tableName, 10);
conn.close();
}
@Test
public void testParallelCompilation2() throws Exception {
Statement stmt = conTestDb.createStatement();
stmt.execute("set hive.driver.parallel.compilation=false");
stmt.execute("set hive.server2.async.exec.async.compile=true");
stmt.close();
startConcurrencyTest(conTestDb, tableName, 10);
Connection conn = getConnection(testDbName);
startConcurrencyTest(conn, tableName, 10);
conn.close();
}
@Test
public void testConcurrentStatements() throws Exception {
startConcurrencyTest(conTestDb, tableName, 50);
}
private static void startConcurrencyTest(Connection conn, String tableName, int numTasks) {
// Start concurrent testing
int POOL_SIZE = 100;
int TASK_COUNT = numTasks;
SynchronousQueue<Runnable> executorQueue = new SynchronousQueue<Runnable>();
ExecutorService workers =
new ThreadPoolExecutor(1, POOL_SIZE, 20, TimeUnit.SECONDS, executorQueue);
List<Future<Boolean>> list = new ArrayList<Future<Boolean>>();
int i = 0;
while (i < TASK_COUNT) {
try {
Future<Boolean> future = workers.submit(new JDBCTask(conn, i, tableName));
list.add(future);
i++;
} catch (RejectedExecutionException ree) {
try {
TimeUnit.MILLISECONDS.sleep(100);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
for (Future<Boolean> future : list) {
try {
Boolean result = future.get(30, TimeUnit.SECONDS);
assertTrue(result);
} catch (ExecutionException ee) {
fail("Concurrent Statement failed: " + ee.getCause());
} catch (TimeoutException te) {
System.out.println("Task was timeout after 30 second: " + te);
} catch (CancellationException ce) {
System.out.println("Task was interrupted: " + ce);
} catch (InterruptedException ie) {
System.out.println("Thread was interrupted: " + ie);
}
}
workers.shutdown();
}
static class JDBCTask implements Callable<Boolean> {
private String showsql = "show tables";
private String querysql;
private int seq = 0;
Connection con = null;
Statement stmt = null;
ResultSet res = null;
JDBCTask(Connection con, int seq, String tblName) {
this.con = con;
this.seq = seq;
querysql = "SELECT count(value) FROM " + tblName;
}
public Boolean call() throws SQLException {
int mod = seq%10;
try {
if (mod < 2) {
String name = con.getMetaData().getDatabaseProductName();
} else if (mod < 5) {
stmt = con.createStatement();
res = stmt.executeQuery(querysql);
while (res.next()) {
res.getInt(1);
}
} else if (mod < 7) {
res = con.getMetaData().getSchemas();
if (res.next()) {
res.getString(1);
}
} else {
stmt = con.createStatement();
res = stmt.executeQuery(showsql);
if (res.next()) {
res.getString(1);
}
}
return new Boolean(true);
} finally {
try {
if (res != null) {
res.close();
res = null;
}
if (stmt != null) {
stmt.close();
stmt = null;
}
} catch (SQLException sqle1) {
}
}
}
}
/** This test is to connect to any database without using the command "Use <<DB>>"
* 1) connect to default database.
* 2) Create a new DB test_default.
* 3) Connect to test_default database.
* 4) Connect and create table under test_default_test.
* 5) Connect and display all tables.
* 6) Connect to default database and shouldn't find table test_default_test.
* 7) Connect and drop test_default_test.
* 8) drop test_default database.
*/
@Test
public void testURIDatabaseName() throws Exception{
String jdbcUri = miniHS2.getJdbcURL().substring(0, miniHS2.getJdbcURL().indexOf("default"));
Connection conn= getConnection(jdbcUri+"default", System.getProperty("user.name"),"bar");
String dbName="test_connection_non_default_db";
String tableInNonDefaultSchema="table_in_non_default_schema";
Statement stmt = conn.createStatement();
stmt.execute("create database if not exists "+dbName);
stmt.close();
conn.close();
conn = getConnection(jdbcUri+dbName,System.getProperty("user.name"),"bar");
stmt = conn .createStatement();
boolean expected = stmt.execute(" create table "+tableInNonDefaultSchema +" (x int)");
stmt.close();
conn .close();
conn = getConnection(jdbcUri+dbName,System.getProperty("user.name"),"bar");
stmt = conn .createStatement();
ResultSet res = stmt.executeQuery("show tables");
boolean testTableExists = false;
while (res.next()) {
assertNotNull("table name is null in result set", res.getString(1));
if (tableInNonDefaultSchema.equalsIgnoreCase(res.getString(1))) {
testTableExists = true;
}
}
assertTrue("table name "+tableInNonDefaultSchema
+ " found in SHOW TABLES result set", testTableExists);
stmt.close();
conn .close();
conn = getConnection(jdbcUri+"default",System.getProperty("user.name"),"bar");
stmt = conn .createStatement();
res = stmt.executeQuery("show tables");
testTableExists = false;
while (res.next()) {
assertNotNull("table name is null in result set", res.getString(1));
if (tableInNonDefaultSchema.equalsIgnoreCase(res.getString(1))) {
testTableExists = true;
}
}
assertFalse("table name "+tableInNonDefaultSchema
+ " NOT found in SHOW TABLES result set", testTableExists);
stmt.close();
conn .close();
conn = getConnection(jdbcUri+dbName,System.getProperty("user.name"),"bar");
stmt = conn .createStatement();
stmt.execute("set hive.support.concurrency = false");
res = stmt.executeQuery("show tables");
stmt.execute(" drop table if exists table_in_non_default_schema");
expected = stmt.execute("DROP DATABASE "+ dbName);
stmt.close();
conn.close();
conn = getConnection(jdbcUri+"default",System.getProperty("user.name"),"bar");
stmt = conn .createStatement();
res = stmt.executeQuery("show tables");
testTableExists = false;
while (res.next()) {
assertNotNull("table name is null in result set", res.getString(1));
if (tableInNonDefaultSchema.equalsIgnoreCase(res.getString(1))) {
testTableExists = true;
}
}
// test URI with no dbName
conn = getConnection(jdbcUri, System.getProperty("user.name"),"bar");
verifyCurrentDB("default", conn);
conn.close();
conn = getConnection(jdbcUri + ";", System.getProperty("user.name"),"bar");
verifyCurrentDB("default", conn);
conn.close();
conn = getConnection(jdbcUri + ";/foo=bar;foo1=bar1", System.getProperty("user.name"),"bar");
verifyCurrentDB("default", conn);
conn.close();
}
/**
* verify that the current db is the one expected. first create table as <db>.tab and then
* describe that table to check if <db> is the current database
* @param expectedDbName
* @param hs2Conn
* @throws Exception
*/
private void verifyCurrentDB(String expectedDbName, Connection hs2Conn) throws Exception {
String verifyTab = "miniHS2DbVerificationTable";
Statement stmt = hs2Conn.createStatement();
stmt.execute("DROP TABLE IF EXISTS " + expectedDbName + "." + verifyTab);
stmt.execute("CREATE TABLE " + expectedDbName + "." + verifyTab + "(id INT)");
stmt.execute("DESCRIBE " + verifyTab);
stmt.execute("DROP TABLE IF EXISTS " + expectedDbName + "." + verifyTab);
stmt.close();
}
@Test
public void testConnectionSchemaAPIs() throws Exception {
/**
* get/set Schema are new in JDK7 and not available in java.sql.Connection in JDK6. Hence the
* test uses HiveConnection object to call these methods so that test will run with older JDKs
*/
HiveConnection hiveConn = (HiveConnection) conDefault;
assertEquals(defaultDbName, hiveConn.getSchema());
Statement stmt = conDefault.createStatement();
stmt.execute("USE " + testDbName);
assertEquals(testDbName, hiveConn.getSchema());
stmt.execute("USE " + defaultDbName);
assertEquals(defaultDbName, hiveConn.getSchema());
hiveConn.setSchema(defaultDbName);
assertEquals(defaultDbName, hiveConn.getSchema());
hiveConn.setSchema(defaultDbName);
assertEquals(defaultDbName, hiveConn.getSchema());
assertTrue(hiveConn.getCatalog().isEmpty());
hiveConn.setCatalog("foo");
assertTrue(hiveConn.getCatalog().isEmpty());
}
/**
* This method tests whether while creating a new connection, the config
* variables specified in the JDBC URI are properly set for the connection.
* This is a test for HiveConnection#configureConnection.
*
* @throws Exception
*/
@Test
public void testNewConnectionConfiguration() throws Exception {
// Set some conf parameters
String hiveConf =
"hive.cli.print.header=true;hive.server2.async.exec.shutdown.timeout=20;"
+ "hive.server2.async.exec.threads=30;hive.server2.thrift.max.worker.threads=15";
// Set some conf vars
String hiveVar = "stab=salesTable;icol=customerID";
String jdbcUri = miniHS2.getJdbcURL() + "?" + hiveConf + "#" + hiveVar;
// Open a new connection with these conf & vars
Connection con1 = DriverManager.getConnection(jdbcUri);
// Execute "set" command and retrieve values for the conf & vars specified above
// Assert values retrieved
Statement stmt = con1.createStatement();
// Verify that the property has been properly set while creating the
// connection above
verifyConfProperty(stmt, "hive.cli.print.header", "true");
verifyConfProperty(stmt, "hive.server2.async.exec.shutdown.timeout", "20");
verifyConfProperty(stmt, "hive.server2.async.exec.threads", "30");
verifyConfProperty(stmt, "hive.server2.thrift.max.worker.threads", "15");
verifyConfProperty(stmt, "stab", "salesTable");
verifyConfProperty(stmt, "icol", "customerID");
stmt.close();
con1.close();
}
private void verifyConfProperty(Statement stmt, String property,
String expectedValue) throws Exception {
ResultSet res = stmt.executeQuery("set " + property);
while (res.next()) {
String resultValues[] = res.getString(1).split("=");
assertEquals(resultValues[1], expectedValue);
}
}
@Test
public void testMetadataQueriesWithSerializeThriftInTasks() throws Exception {
Statement stmt = conTestDb.createStatement();
setSerializeInTasksInConf(stmt);
ResultSet rs = stmt.executeQuery("show tables");
assertTrue(rs.next());
stmt.execute("describe " + tableName);
stmt.execute("explain select * from " + tableName);
// Note: by closing stmt object, we are also reverting any session specific config changes.
stmt.close();
}
@Test
public void testSelectThriftSerializeInTasks() throws Exception {
Statement stmt = conTestDb.createStatement();
setSerializeInTasksInConf(stmt);
stmt.execute("set hive.compute.query.using.stats=false");
stmt.execute("drop table if exists testSelectThriftOrders");
stmt.execute("drop table if exists testSelectThriftCustomers");
stmt.execute("create table testSelectThriftOrders (orderid int, orderdate string, customerid int)");
stmt.execute("create table testSelectThriftCustomers (customerid int, customername string, customercountry string)");
stmt.execute("insert into testSelectThriftOrders values (1, '2015-09-09', 123), "
+ "(2, '2015-10-10', 246), (3, '2015-11-11', 356)");
stmt.execute("insert into testSelectThriftCustomers values (123, 'David', 'America'), "
+ "(246, 'John', 'Canada'), (356, 'Mary', 'CostaRica')");
ResultSet countOrders = stmt.executeQuery("select count(*) from testSelectThriftOrders");
while (countOrders.next()) {
assertEquals(3, countOrders.getInt(1));
}
ResultSet maxOrders =
stmt.executeQuery("select max(customerid) from testSelectThriftCustomers");
while (maxOrders.next()) {
assertEquals(356, maxOrders.getInt(1));
}
stmt.execute("drop table testSelectThriftOrders");
stmt.execute("drop table testSelectThriftCustomers");
stmt.close();
}
@Test
public void testJoinThriftSerializeInTasks() throws Exception {
Statement stmt = conTestDb.createStatement();
setSerializeInTasksInConf(stmt);
stmt.execute("drop table if exists testThriftJoinOrders");
stmt.execute("drop table if exists testThriftJoinCustomers");
stmt.execute("create table testThriftJoinOrders (orderid int, orderdate string, customerid int)");
stmt.execute("create table testThriftJoinCustomers (customerid int, customername string, customercountry string)");
stmt.execute("insert into testThriftJoinOrders values (1, '2015-09-09', 123), (2, '2015-10-10', 246), "
+ "(3, '2015-11-11', 356)");
stmt.execute("insert into testThriftJoinCustomers values (123, 'David', 'America'), "
+ "(246, 'John', 'Canada'), (356, 'Mary', 'CostaRica')");
ResultSet joinResultSet =
stmt.executeQuery("select testThriftJoinOrders.orderid, testThriftJoinCustomers.customername "
+ "from testThriftJoinOrders inner join testThriftJoinCustomers where "
+ "testThriftJoinOrders.customerid=testThriftJoinCustomers.customerid");
Map<Integer, String> expectedResult = new HashMap<Integer, String>();
expectedResult.put(1, "David");
expectedResult.put(2, "John");
expectedResult.put(3, "Mary");
for (int i = 1; i < 4; i++) {
assertTrue(joinResultSet.next());
assertEquals(joinResultSet.getString(2), expectedResult.get(i));
}
stmt.execute("drop table testThriftJoinOrders");
stmt.execute("drop table testThriftJoinCustomers");
stmt.close();
}
@Test
public void testEmptyResultsetThriftSerializeInTasks() throws Exception {
Statement stmt = conTestDb.createStatement();
setSerializeInTasksInConf(stmt);
stmt.execute("drop table if exists testThriftSerializeShow1");
stmt.execute("drop table if exists testThriftSerializeShow2");
stmt.execute("create table testThriftSerializeShow1 (a int)");
stmt.execute("create table testThriftSerializeShow2 (b int)");
stmt.execute("insert into testThriftSerializeShow1 values (1)");
stmt.execute("insert into testThriftSerializeShow2 values (2)");
ResultSet rs = stmt.executeQuery("select * from testThriftSerializeShow1 inner join "
+ "testThriftSerializeShow2 where testThriftSerializeShow1.a=testThriftSerializeShow2.b");
assertTrue(!rs.next());
stmt.execute("drop table testThriftSerializeShow1");
stmt.execute("drop table testThriftSerializeShow2");
stmt.close();
}
@Test
public void testFloatCast2DoubleThriftSerializeInTasks() throws Exception {
Statement stmt = conTestDb.createStatement();
setSerializeInTasksInConf(stmt);
stmt.execute("drop table if exists testThriftSerializeShow1");
stmt.execute("drop table if exists testThriftSerializeShow2");
stmt.execute("create table testThriftSerializeShow1 (a float)");
stmt.execute("create table testThriftSerializeShow2 (b double)");
stmt.execute("insert into testThriftSerializeShow1 values (1.1), (2.2), (3.3)");
stmt.execute("insert into testThriftSerializeShow2 values (2.2), (3.3), (4.4)");
ResultSet rs =
stmt.executeQuery("select * from testThriftSerializeShow1 inner join "
+ "testThriftSerializeShow2 where testThriftSerializeShow1.a=testThriftSerializeShow2.b");
assertTrue(!rs.next());
stmt.execute("drop table testThriftSerializeShow1");
stmt.execute("drop table testThriftSerializeShow2");
stmt.close();
}
@Test
public void testEnableThriftSerializeInTasks() throws Exception {
Statement stmt = conTestDb.createStatement();
stmt.execute("drop table if exists testThriftSerializeShow1");
stmt.execute("drop table if exists testThriftSerializeShow2");
stmt.execute("create table testThriftSerializeShow1 (a int)");
stmt.execute("create table testThriftSerializeShow2 (b int)");
stmt.execute("insert into testThriftSerializeShow1 values (1)");
stmt.execute("insert into testThriftSerializeShow2 values (2)");
ResultSet rs =
stmt.executeQuery("select * from testThriftSerializeShow1 inner join "
+ "testThriftSerializeShow2 where testThriftSerializeShow1.a=testThriftSerializeShow2.b");
assertTrue(!rs.next());
unsetSerializeInTasksInConf(stmt);
rs =
stmt.executeQuery("select * from testThriftSerializeShow1 inner join "
+ "testThriftSerializeShow2 where testThriftSerializeShow1.a=testThriftSerializeShow2.b");
assertTrue(!rs.next());
setSerializeInTasksInConf(stmt);
rs =
stmt.executeQuery("select * from testThriftSerializeShow1 inner join "
+ "testThriftSerializeShow2 where testThriftSerializeShow1.a=testThriftSerializeShow2.b");
assertTrue(!rs.next());
stmt.execute("drop table testThriftSerializeShow1");
stmt.execute("drop table testThriftSerializeShow2");
stmt.close();
}
private void setSerializeInTasksInConf(Statement stmt) throws SQLException {
stmt.execute("set hive.server2.thrift.resultset.serialize.in.tasks=true");
stmt.execute("set hive.server2.thrift.resultset.max.fetch.size=1000");
}
private void unsetSerializeInTasksInConf(Statement stmt) throws SQLException {
stmt.execute("set hive.server2.thrift.resultset.serialize.in.tasks=false");
stmt.execute("set hive.server2.thrift.resultset.max.fetch.size");
}
/**
* Tests the creation of the 3 scratch dirs: hdfs, local, downloaded resources (which is also local).
* 1. Test with doAs=false: open a new JDBC session and verify the presence of directories/permissions
* 2. Test with doAs=true: open a new JDBC session and verify the presence of directories/permissions
* @throws Exception
*/
@Test
public void testSessionScratchDirs() throws Exception {
// Stop HiveServer2
stopMiniHS2();
HiveConf conf = new HiveConf();
String userName;
Path scratchDirPath;
// Set a custom prefix for hdfs scratch dir path
conf.set("hive.exec.scratchdir", tmpDir + "/hs2");
// Set a scratch dir permission
String fsPermissionStr = "700";
conf.set("hive.scratch.dir.permission", fsPermissionStr);
// Start an instance of HiveServer2 which uses miniMR
startMiniHS2(conf);
// 1. Test with doAs=false
String sessionConf="hive.server2.enable.doAs=false";
userName = System.getProperty("user.name");
Connection conn = getConnection(miniHS2.getJdbcURL(testDbName, sessionConf), userName, "password");
// FS
FileSystem fs = miniHS2.getLocalFS();
FsPermission expectedFSPermission = new FsPermission(HiveConf.getVar(conf,
HiveConf.ConfVars.SCRATCHDIRPERMISSION));
// Verify scratch dir paths and permission
// HDFS scratch dir
scratchDirPath = new Path(HiveConf.getVar(conf, HiveConf.ConfVars.SCRATCHDIR) + "/" + userName);
verifyScratchDir(conf, fs, scratchDirPath, expectedFSPermission, userName, false);
// Local scratch dir
scratchDirPath = new Path(HiveConf.getVar(conf, HiveConf.ConfVars.LOCALSCRATCHDIR));
verifyScratchDir(conf, fs, scratchDirPath, expectedFSPermission, userName, true);
// Downloaded resources dir
scratchDirPath = new Path(HiveConf.getVar(conf, HiveConf.ConfVars.DOWNLOADED_RESOURCES_DIR));
verifyScratchDir(conf, fs, scratchDirPath, expectedFSPermission, userName, true);
conn.close();
// 2. Test with doAs=true
sessionConf="hive.server2.enable.doAs=true";
// Test for user "neo"
userName = "neo";
conn = getConnection(miniHS2.getJdbcURL(testDbName, sessionConf), userName, "the-one");
// Verify scratch dir paths and permission
// HDFS scratch dir
scratchDirPath = new Path(HiveConf.getVar(conf, HiveConf.ConfVars.SCRATCHDIR) + "/" + userName);
verifyScratchDir(conf, fs, scratchDirPath, expectedFSPermission, userName, false);
// Local scratch dir
scratchDirPath = new Path(HiveConf.getVar(conf, HiveConf.ConfVars.LOCALSCRATCHDIR));
verifyScratchDir(conf, fs, scratchDirPath, expectedFSPermission, userName, true);
// Downloaded resources dir
scratchDirPath = new Path(HiveConf.getVar(conf, HiveConf.ConfVars.DOWNLOADED_RESOURCES_DIR));
verifyScratchDir(conf, fs, scratchDirPath, expectedFSPermission, userName, true);
conn.close();
// Restore original state
restoreMiniHS2AndConnections();
}
/**
* Test UDF whitelist
* - verify default value
* - verify udf allowed with default whitelist
* - verify udf allowed with specific whitelist
* - verify udf disallowed when not in whitelist
* @throws Exception
*/
@Test
public void testUdfWhiteBlackList() throws Exception {
HiveConf testConf = new HiveConf();
assertTrue(testConf.getVar(ConfVars.HIVE_SERVER2_BUILTIN_UDF_WHITELIST).isEmpty());
// verify that udf in default whitelist can be executed
Statement stmt = conDefault.createStatement();
stmt.executeQuery("SELECT substr('foobar', 4) ");
stmt.close();
// setup whitelist
stopMiniHS2();
Set<String> funcNames = FunctionRegistry.getFunctionNames();
funcNames.remove("reflect");
String funcNameStr = "";
for (String funcName : funcNames) {
funcNameStr += "," + funcName;
}
funcNameStr = funcNameStr.substring(1); // remove ',' at begining
testConf.setVar(ConfVars.HIVE_SERVER2_BUILTIN_UDF_WHITELIST, funcNameStr);
startMiniHS2(testConf);
Connection conn =
getConnection(miniHS2.getJdbcURL(testDbName), System.getProperty("user.name"), "bar");
stmt = conn.createStatement();
// verify that udf in whitelist can be executed
stmt.executeQuery("SELECT substr('foobar', 3) ");
// verify that udf not in whitelist fails
try {
stmt.executeQuery("SELECT reflect('java.lang.String', 'valueOf', 1) ");
fail("reflect() udf invocation should fail");
} catch (SQLException e) {
// expected
}
conn.close();
// Restore original state
restoreMiniHS2AndConnections();
}
/** Test UDF blacklist
* - verify default value
* - verify udfs allowed with default blacklist
* - verify udf disallowed when in blacklist
* @throws Exception
*/
@Test
public void testUdfBlackList() throws Exception {
HiveConf testConf = new HiveConf();
assertTrue(testConf.getVar(ConfVars.HIVE_SERVER2_BUILTIN_UDF_BLACKLIST).isEmpty());
Statement stmt = conDefault.createStatement();
// verify that udf in default whitelist can be executed
stmt.executeQuery("SELECT substr('foobar', 4) ");
stopMiniHS2();
testConf.setVar(ConfVars.HIVE_SERVER2_BUILTIN_UDF_BLACKLIST, "reflect");
startMiniHS2(testConf);
Connection conn =
getConnection(miniHS2.getJdbcURL(testDbName), System.getProperty("user.name"), "bar");
stmt = conn.createStatement();
try {
stmt.executeQuery("SELECT reflect('java.lang.String', 'valueOf', 1) ");
fail("reflect() udf invocation should fail");
} catch (SQLException e) {
// expected
}
conn.close();
// Restore original state
restoreMiniHS2AndConnections();
}
/** Test UDF blacklist overrides whitelist
* @throws Exception
*/
@Test
public void testUdfBlackListOverride() throws Exception {
stopMiniHS2();
// setup whitelist
HiveConf testConf = new HiveConf();
Set<String> funcNames = FunctionRegistry.getFunctionNames();
String funcNameStr = "";
for (String funcName : funcNames) {
funcNameStr += "," + funcName;
}
funcNameStr = funcNameStr.substring(1); // remove ',' at begining
testConf.setVar(ConfVars.HIVE_SERVER2_BUILTIN_UDF_WHITELIST, funcNameStr);
testConf.setVar(ConfVars.HIVE_SERVER2_BUILTIN_UDF_BLACKLIST, "reflect");
startMiniHS2(testConf);
Connection conn =
getConnection(miniHS2.getJdbcURL(testDbName), System.getProperty("user.name"), "bar");
Statement stmt = conn.createStatement();
// verify that udf in black list fails even though it's included in whitelist
try {
stmt.executeQuery("SELECT reflect('java.lang.String', 'valueOf', 1) ");
fail("reflect() udf invocation should fail");
} catch (SQLException e) {
// expected
}
conn.close();
// Restore original state
restoreMiniHS2AndConnections();
}
/**
* Tests the creation of the root hdfs scratch dir, which should be writable by all.
*
* @throws Exception
*/
@Test
public void testRootScratchDir() throws Exception {
// Stop HiveServer2
stopMiniHS2();
HiveConf conf = new HiveConf();
String userName;
Path scratchDirPath;
conf.set("hive.exec.scratchdir", tmpDir + "/hs2");
// Start an instance of HiveServer2 which uses miniMR
startMiniHS2(conf);
userName = System.getProperty("user.name");
Connection conn = getConnection(miniHS2.getJdbcURL(testDbName), userName, "password");
// FS
FileSystem fs = miniHS2.getLocalFS();
FsPermission expectedFSPermission = new FsPermission((short)00733);
// Verify scratch dir paths and permission
// HDFS scratch dir
scratchDirPath = new Path(HiveConf.getVar(conf, HiveConf.ConfVars.SCRATCHDIR));
verifyScratchDir(conf, fs, scratchDirPath, expectedFSPermission, userName, false);
conn.close();
// Test with multi-level scratch dir path
// Stop HiveServer2
stopMiniHS2();
conf.set("hive.exec.scratchdir", tmpDir + "/level1/level2/level3");
startMiniHS2(conf);
conn = getConnection(miniHS2.getJdbcURL(testDbName), userName, "password");
scratchDirPath = new Path(HiveConf.getVar(conf, HiveConf.ConfVars.SCRATCHDIR));
verifyScratchDir(conf, fs, scratchDirPath, expectedFSPermission, userName, false);
conn.close();
// Restore original state
restoreMiniHS2AndConnections();
}
private void verifyScratchDir(HiveConf conf, FileSystem fs, Path scratchDirPath,
FsPermission expectedFSPermission, String userName, boolean isLocal) throws Exception {
String dirType = isLocal ? "Local" : "DFS";
assertTrue("The expected " + dirType + " scratch dir does not exist for the user: " +
userName, fs.exists(scratchDirPath));
if (fs.exists(scratchDirPath) && !isLocal) {
assertEquals("DFS scratch dir permissions don't match", expectedFSPermission,
fs.getFileStatus(scratchDirPath).getPermission());
}
}
/**
* Test for http header size
* @throws Exception
*/
@Test
public void testHttpHeaderSize() throws Exception {
// Stop HiveServer2
stopMiniHS2();
HiveConf conf = new HiveConf();
conf.set("hive.server2.transport.mode", "http");
conf.setInt("hive.server2.thrift.http.request.header.size", 1024);
conf.setInt("hive.server2.thrift.http.response.header.size", 1024);
startMiniHS2(conf);
// Username is added to the request header
String userName = StringUtils.leftPad("*", 100);
Connection conn = null;
// This should go fine, since header should be less than the configured header size
try {
conn = getConnection(miniHS2.getJdbcURL(testDbName), userName, "password");
} catch (Exception e) {
fail("Not expecting exception: " + e);
} finally {
if (conn != null) {
conn.close();
}
}
// This should fail with given HTTP response code 413 in error message, since header is more
// than the configured the header size
userName = StringUtils.leftPad("*", 2000);
try {
conn = getConnection(miniHS2.getJdbcURL(testDbName), userName, "password");
} catch (Exception e) {
assertTrue("Header exception thrown", e != null);
assertTrue(e.getMessage().contains("HTTP Response code: 413"));
} finally {
if (conn != null) {
conn.close();
}
}
// Stop HiveServer2 to increase header size
stopMiniHS2();
conf.setInt("hive.server2.thrift.http.request.header.size", 3000);
conf.setInt("hive.server2.thrift.http.response.header.size", 3000);
startMiniHS2(conf);
// This should now go fine, since we increased the configured header size
try {
conn = getConnection(miniHS2.getJdbcURL(testDbName), userName, "password");
} catch (Exception e) {
fail("Not expecting exception: " + e);
} finally {
if (conn != null) {
conn.close();
}
}
// Restore original state
restoreMiniHS2AndConnections();
}
/**
* Test for jdbc driver retry on NoHttpResponseException
* @throws Exception
*/
@Test
public void testHttpRetryOnServerIdleTimeout() throws Exception {
// Stop HiveServer2
stopMiniHS2();
HiveConf conf = new HiveConf();
conf.set("hive.server2.transport.mode", "http");
// Set server's idle timeout to a very low value
conf.set("hive.server2.thrift.http.max.idle.time", "5");
startMiniHS2(conf);
String userName = System.getProperty("user.name");
Connection conn = getConnection(miniHS2.getJdbcURL(testDbName), userName, "password");
Statement stmt = conn.createStatement();
stmt.execute("select from_unixtime(unix_timestamp())");
// Sleep for longer than server's idletimeout and execute a query
TimeUnit.SECONDS.sleep(10);
try {
stmt.execute("select from_unixtime(unix_timestamp())");
} catch (Exception e) {
fail("Not expecting exception: " + e);
} finally {
if (conn != null) {
conn.close();
}
}
// Restore original state
restoreMiniHS2AndConnections();
}
/**
* Tests that DataNucleus' NucleusContext.classLoaderResolverMap clears cached class objects
* (& hence doesn't leak classloaders) on closing any session
*
* @throws Exception
*/
@Test
public void testAddJarDataNucleusUnCaching() throws Exception {
Path jarFilePath = getHiveContribJarPath();
// We need a new connection object as we'll check the cache size after connection close
Connection conn =
getConnection(miniHS2.getJdbcURL(testDbName), System.getProperty("user.name"), "password");
Statement stmt = conn.createStatement();
int mapSizeAfterClose;
// Add the jar file
stmt.execute("ADD JAR " + jarFilePath.toString());
// Create a temporary function using the jar
stmt.execute("CREATE TEMPORARY FUNCTION add_func AS '" + testUdfClassName + "'");
ResultSet res = stmt.executeQuery("DESCRIBE FUNCTION add_func");
checkForNotExist(res);
// Execute the UDF
stmt.execute("SELECT add_func(int_col, 1) from " + tableName + " limit 1");
// Close the connection
conn.close();
mapSizeAfterClose = getNucleusClassLoaderResolverMapSize();
System.out.println("classLoaderResolverMap size after connection close: " + mapSizeAfterClose);
// Cache size should be 0 now
Assert.assertTrue("Failed; NucleusContext classLoaderResolverMap size: " + mapSizeAfterClose,
mapSizeAfterClose == 0);
}
@SuppressWarnings("unchecked")
private int getNucleusClassLoaderResolverMapSize() {
Field classLoaderResolverMap;
Field pmf;
JDOPersistenceManagerFactory jdoPmf = null;
NucleusContext nc = null;
Map<String, ClassLoaderResolver> cMap;
try {
pmf = ObjectStore.class.getDeclaredField("pmf");
if (pmf != null) {
pmf.setAccessible(true);
jdoPmf = (JDOPersistenceManagerFactory) pmf.get(null);
if (jdoPmf != null) {
nc = jdoPmf.getNucleusContext();
}
}
} catch (Exception e) {
System.out.println(e);
}
if (nc != null) {
try {
classLoaderResolverMap = AbstractNucleusContext.class.getDeclaredField("classLoaderResolverMap");
if (classLoaderResolverMap != null) {
classLoaderResolverMap.setAccessible(true);
cMap = (Map<String, ClassLoaderResolver>) classLoaderResolverMap.get(nc);
if (cMap != null) {
return cMap.size();
}
}
} catch (Exception e) {
System.out.println(e);
}
}
return -1;
}
/**
* Tests ADD JAR uses Hives ReflectionUtil.CONSTRUCTOR_CACHE
*
* @throws Exception
*/
@Test
public void testAddJarConstructorUnCaching() throws Exception {
// This test assumes the hive-contrib JAR has been built as part of the Hive build.
// Also dependent on the UDFExampleAdd class within that JAR.
setReflectionUtilCache();
Path jarFilePath = getHiveContribJarPath();
long cacheBeforeAddJar, cacheAfterClose;
// Force the cache clear so we know its empty
invalidateReflectionUtlCache();
cacheBeforeAddJar = getReflectionUtilCacheSize();
System.out.println("CONSTRUCTOR_CACHE size before add jar: " + cacheBeforeAddJar);
System.out.println("CONSTRUCTOR_CACHE as map before add jar:" + getReflectionUtilCache().asMap());
Assert.assertTrue("FAILED: CONSTRUCTOR_CACHE size before add jar: " + cacheBeforeAddJar,
cacheBeforeAddJar == 0);
// Add the jar file
Statement stmt = conTestDb.createStatement();
stmt.execute("ADD JAR " + jarFilePath.toString());
// Create a temporary function using the jar
stmt.execute("CREATE TEMPORARY FUNCTION add_func AS '" + testUdfClassName + "'");
// Execute the UDF
ResultSet res = stmt.executeQuery("SELECT add_func(int_col, 1) from " + tableName + " limit 1");
assertTrue(res.next());
TimeUnit.SECONDS.sleep(7);
// Have to force a cleanup of all expired entries here because its possible that the
// expired entries will still be counted in Cache.size().
// Taken from:
// http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/cache/CacheBuilder.html
cleanUpReflectionUtlCache();
cacheAfterClose = getReflectionUtilCacheSize();
System.out.println("CONSTRUCTOR_CACHE size after connection close: " + cacheAfterClose);
Assert.assertTrue("FAILED: CONSTRUCTOR_CACHE size after connection close: " + cacheAfterClose,
cacheAfterClose == 0);
stmt.execute("DROP TEMPORARY FUNCTION IF EXISTS add_func");
stmt.close();
}
private void setReflectionUtilCache() {
Field constructorCacheField;
Cache<Class<?>, Constructor<?>> tmp;
try {
constructorCacheField = ReflectionUtil.class.getDeclaredField("CONSTRUCTOR_CACHE");
if (constructorCacheField != null) {
constructorCacheField.setAccessible(true);
Field modifiersField = Field.class.getDeclaredField("modifiers");
modifiersField.setAccessible(true);
modifiersField.setInt(constructorCacheField, constructorCacheField.getModifiers()
& ~Modifier.FINAL);
tmp =
CacheBuilder.newBuilder().expireAfterAccess(5, TimeUnit.SECONDS).concurrencyLevel(64)
.weakKeys().weakValues().build();
constructorCacheField.set(tmp.getClass(), tmp);
}
} catch (Exception e) {
System.out.println("Error when setting the CONSTRUCTOR_CACHE to expire: " + e);
}
}
private Cache getReflectionUtilCache() {
Field constructorCacheField;
try {
constructorCacheField = ReflectionUtil.class.getDeclaredField("CONSTRUCTOR_CACHE");
if (constructorCacheField != null) {
constructorCacheField.setAccessible(true);
return (Cache) constructorCacheField.get(null);
}
} catch (Exception e) {
System.out.println("Error when getting the CONSTRUCTOR_CACHE var: " + e);
}
return null;
}
private void invalidateReflectionUtlCache() {
try {
Cache constructorCache = getReflectionUtilCache();
if (constructorCache != null) {
constructorCache.invalidateAll();
}
} catch (Exception e) {
System.out.println("Error when trying to invalidate the cache: " + e);
}
}
private void cleanUpReflectionUtlCache() {
try {
Cache constructorCache = getReflectionUtilCache();
if (constructorCache != null) {
constructorCache.cleanUp();
}
} catch (Exception e) {
System.out.println("Error when trying to cleanUp the cache: " + e);
}
}
private long getReflectionUtilCacheSize() {
try {
Cache constructorCache = getReflectionUtilCache();
if (constructorCache != null) {
return constructorCache.size();
}
} catch (Exception e) {
System.out.println(e);
}
return -1;
}
@Test
public void testPermFunc() throws Exception {
// This test assumes the hive-contrib JAR has been built as part of the Hive build.
// Also dependent on the UDFExampleAdd class within that JAR.
Path jarFilePath = getHiveContribJarPath();
Statement stmt = conTestDb.createStatement();
ResultSet res;
// Add the jar file
stmt.execute("ADD JAR " + jarFilePath.toString());
// Register function
String queryStr =
"CREATE FUNCTION example_add AS '" + testUdfClassName + "' USING JAR '" + jarFilePath + "'";
stmt.execute(queryStr);
// Call describe
res = stmt.executeQuery("DESCRIBE FUNCTION " + testDbName + ".example_add");
checkForNotExist(res);
// Use UDF in query
res = stmt.executeQuery("SELECT example_add(1, 2) FROM " + tableName + " LIMIT 1");
assertTrue("query has results", res.next());
assertEquals(3, res.getInt(1));
assertFalse("no more results", res.next());
// A new connection should be able to call describe/use function without issue
Connection conn2 = getConnection(testDbName);
Statement stmt2 = conn2.createStatement();
stmt2.execute("USE " + testDbName);
res = stmt2.executeQuery("DESCRIBE FUNCTION " + testDbName + ".example_add");
checkForNotExist(res);
res =
stmt2.executeQuery("SELECT " + testDbName + ".example_add(1, 1) FROM " + tableName
+ " LIMIT 1");
assertTrue("query has results", res.next());
assertEquals(2, res.getInt(1));
assertFalse("no more results", res.next());
conn2.close();
stmt.execute("DROP FUNCTION IF EXISTS " + testDbName + ".example_add");
stmt.close();
}
private Path getHiveContribJarPath() {
String mvnRepo = System.getProperty("maven.local.repository");
String hiveVersion = System.getProperty("hive.version");
String jarFileName = "hive-contrib-" + hiveVersion + ".jar";
String[] pathParts = {
"org", "apache", "hive",
"hive-contrib", hiveVersion, jarFileName
};
// Create path to hive-contrib JAR on local filesystem
Path jarFilePath = new Path(mvnRepo);
for (String pathPart : pathParts) {
jarFilePath = new Path(jarFilePath, pathPart);
}
return jarFilePath;
}
@Test
public void testTempTable() throws Exception {
// Create temp table with current connection
String tempTableName = "tmp1";
Statement stmt = conTestDb.createStatement();
stmt.execute("CREATE TEMPORARY TABLE " + tempTableName + " (key string, value string)");
stmt.execute("load data local inpath '" + kvDataFilePath.toString() + "' into table "
+ tempTableName);
String resultVal = "val_238";
String queryStr = "SELECT * FROM " + tempTableName + " where value = '" + resultVal + "'";
ResultSet res = stmt.executeQuery(queryStr);
assertTrue(res.next());
assertEquals(resultVal, res.getString(2));
res.close();
stmt.close();
// Test getTables()
DatabaseMetaData md = conTestDb.getMetaData();
assertTrue(md.getConnection() == conTestDb);
ResultSet rs = md.getTables(null, null, tempTableName, null);
boolean foundTable = false;
while (rs.next()) {
String tableName = rs.getString(3);
if (tableName.equalsIgnoreCase(tempTableName)) {
assertFalse("Table not found yet", foundTable);
foundTable = true;
}
}
assertTrue("Found temp table", foundTable);
// Test getTables() with no table name pattern
rs = md.getTables(null, null, null, null);
foundTable = false;
while (rs.next()) {
String tableName = rs.getString(3);
if (tableName.equalsIgnoreCase(tempTableName)) {
assertFalse("Table not found yet", foundTable);
foundTable = true;
}
}
assertTrue("Found temp table", foundTable);
// Test getColumns()
rs = md.getColumns(null, null, tempTableName, null);
assertTrue("First row", rs.next());
assertTrue(rs.getString(3).equalsIgnoreCase(tempTableName));
assertTrue(rs.getString(4).equalsIgnoreCase("key"));
assertEquals(Types.VARCHAR, rs.getInt(5));
assertTrue("Second row", rs.next());
assertTrue(rs.getString(3).equalsIgnoreCase(tempTableName));
assertTrue(rs.getString(4).equalsIgnoreCase("value"));
assertEquals(Types.VARCHAR, rs.getInt(5));
// A second connection should not be able to see the table
Connection conn2 =
DriverManager.getConnection(miniHS2.getJdbcURL(testDbName),
System.getProperty("user.name"), "bar");
Statement stmt2 = conn2.createStatement();
stmt2.execute("USE " + testDbName);
boolean gotException = false;
try {
res = stmt2.executeQuery(queryStr);
} catch (SQLException err) {
// This is expected to fail.
assertTrue("Expecting table not found error, instead got: " + err,
err.getMessage().contains("Table not found"));
gotException = true;
}
assertTrue("Exception while querying non-existing temp table", gotException);
conn2.close();
}
private void checkForNotExist(ResultSet res) throws Exception {
int numRows = 0;
while (res.next()) {
numRows++;
String strVal = res.getString(1);
assertEquals("Should not find 'not exist'", -1, strVal.toLowerCase().indexOf("not exist"));
}
assertTrue("Rows returned from describe function", numRows > 0);
}
@Test
public void testReplDumpResultSet() throws Exception {
String tid =
TestJdbcWithMiniHS2.class.getCanonicalName().toLowerCase().replace('.', '_') + "_"
+ System.currentTimeMillis();
String testPathName = System.getProperty("test.warehouse.dir", "/tmp") + Path.SEPARATOR + tid;
Path testPath = new Path(testPathName);
FileSystem fs = testPath.getFileSystem(new HiveConf());
Statement stmt = conDefault.createStatement();
try {
stmt.execute("set hive.repl.rootdir = " + testPathName);
ResultSet rs = stmt.executeQuery("repl dump " + testDbName);
ResultSetMetaData rsMeta = rs.getMetaData();
assertEquals(2, rsMeta.getColumnCount());
int numRows = 0;
while (rs.next()) {
numRows++;
URI uri = new URI(rs.getString(1));
int notificationId = rs.getInt(2);
assertNotNull(uri);
assertEquals(testPath.toUri().getScheme(), uri.getScheme());
assertEquals(testPath.toUri().getAuthority(), uri.getAuthority());
// In test setup, we append '/next' to hive.repl.rootdir and use that as the dump location
assertEquals(testPath.toUri().getPath() + "/next", uri.getPath());
assertNotNull(notificationId);
}
assertEquals(1, numRows);
} finally {
// Clean up
fs.delete(testPath, true);
}
}
@Test
public void testFetchSize() throws Exception {
// Test setting fetch size below max
Connection fsConn = getConnection(miniHS2.getJdbcURL("default", "fetchSize=50", ""),
System.getProperty("user.name"), "bar");
Statement stmt = fsConn.createStatement();
stmt.execute("set hive.server2.thrift.resultset.serialize.in.tasks=true");
int fetchSize = stmt.getFetchSize();
assertEquals(50, fetchSize);
stmt.close();
fsConn.close();
// Test setting fetch size above max
fsConn = getConnection(
miniHS2.getJdbcURL(
"default",
"fetchSize=" + (miniHS2.getHiveConf().getIntVar(
HiveConf.ConfVars.HIVE_SERVER2_THRIFT_RESULTSET_MAX_FETCH_SIZE) + 1),
""),
System.getProperty("user.name"), "bar");
stmt = fsConn.createStatement();
stmt.execute("set hive.server2.thrift.resultset.serialize.in.tasks=true");
fetchSize = stmt.getFetchSize();
assertEquals(
miniHS2.getHiveConf().getIntVar(
HiveConf.ConfVars.HIVE_SERVER2_THRIFT_RESULTSET_MAX_FETCH_SIZE),
fetchSize);
stmt.close();
fsConn.close();
}
}