diff --git itests/hive-unit/src/test/java/org/apache/hive/jdbc/TestJdbcDriver2.java itests/hive-unit/src/test/java/org/apache/hive/jdbc/TestJdbcDriver2.java index 192ee6b..a2eade1 100644 --- itests/hive-unit/src/test/java/org/apache/hive/jdbc/TestJdbcDriver2.java +++ itests/hive-unit/src/test/java/org/apache/hive/jdbc/TestJdbcDriver2.java @@ -60,7 +60,6 @@ import org.apache.hive.service.cli.operation.ClassicTableTypeMapping.ClassicTableTypes; import org.apache.hive.service.cli.operation.HiveTableTypeMapping; import org.apache.hive.service.cli.operation.TableTypeMappingFactory.TableTypeMappings; -import org.apache.hive.service.server.HiveServer2; import org.junit.After; import org.junit.Before; import org.junit.BeforeClass; @@ -105,7 +104,7 @@ public TestJdbcDriver2() { @BeforeClass public static void setUpBeforeClass() throws SQLException, ClassNotFoundException{ Class.forName(driverName); - Connection con1 = getConnection(); + Connection con1 = getConnection("default"); Statement stmt1 = con1.createStatement(); assertNotNull("Statement is null", stmt1); @@ -130,7 +129,7 @@ public static void setUpBeforeClass() throws SQLException, ClassNotFoundExceptio @Before public void setUp() throws Exception { - con = getConnection(); + con = getConnection("default"); Statement stmt = con.createStatement(); assertNotNull("Statement is null", stmt); @@ -214,14 +213,14 @@ public void setUp() throws Exception { +"' as select * from "+ tableName); } - private static Connection getConnection() throws SQLException { + private static Connection getConnection(String postfix) throws SQLException { Connection con1; if (standAloneServer) { // get connection - con1 = DriverManager.getConnection("jdbc:hive2://localhost:10000/default", + con1 = DriverManager.getConnection("jdbc:hive2://localhost:10000/" + postfix, "", ""); } else { - con1 = DriverManager.getConnection("jdbc:hive2://", "", ""); + con1 = DriverManager.getConnection("jdbc:hive2:///" + postfix, "", ""); } assertNotNull("Connection is null", con1); assertFalse("Connection should not be closed", con1.isClosed()); @@ -535,13 +534,26 @@ public void testExecutePreparedStatement() throws Exception { // execute() of Prepared statement ps.setString(1, val1); ps.execute(); - verifyConfValue(key, val1); + verifyConfValue(con, key, val1); // executeUpdate() of Prepared statement ps.clearParameters(); ps.setString(1, val2); ps.executeUpdate(); - verifyConfValue(key, val2); + verifyConfValue(con, key, val2); + } + + @Test + public void testSetOnConnection() throws Exception { + Connection connection = getConnection("test?conf1=conf2;conf3=conf4#var1=var2;var3=var4"); + try { + verifyConfValue(connection, "conf1", "conf2"); + verifyConfValue(connection, "conf3", "conf4"); + verifyConfValue(connection, "var1", "var2"); + verifyConfValue(connection, "var3", "var4"); + } catch (Exception e) { + connection.close(); + } } /** @@ -551,14 +563,17 @@ public void testExecutePreparedStatement() throws Exception { * @param expectedVal * @throws Exception */ - private void verifyConfValue(String key, String expectedVal) throws Exception { + private void verifyConfValue(Connection con, String key, String expectedVal) throws Exception { Statement stmt = con.createStatement(); ResultSet res = stmt.executeQuery("set " + key); assertTrue(res.next()); - String resultValues[] = res.getString(1).split("="); // "key = 'val'" - assertEquals("Result not in key = val format", 2, resultValues.length); - String result = resultValues[1].substring(1, resultValues[1].length() -1); // remove ' - assertEquals("Conf value should be set by execute()", expectedVal, result); + String value = res.getString(1); + String resultValues[] = value.split("="); // "key = 'val'" + assertEquals("Result not in key = val format: " + value, 2, resultValues.length); + if (resultValues[1].startsWith("'") && resultValues[1].endsWith("'")) { + resultValues[1] = resultValues[1].substring(1, resultValues[1].length() -1); // remove ' + } + assertEquals("Conf value should be set by execute()", expectedVal, resultValues[1]); } @Test diff --git jdbc/src/java/org/apache/hive/jdbc/HiveConnection.java jdbc/src/java/org/apache/hive/jdbc/HiveConnection.java index 8595677..cbcfec7 100644 --- jdbc/src/java/org/apache/hive/jdbc/HiveConnection.java +++ jdbc/src/java/org/apache/hive/jdbc/HiveConnection.java @@ -52,7 +52,6 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.apache.hadoop.hive.ql.session.SessionState; import org.apache.hadoop.hive.shims.ShimLoader; import org.apache.hive.service.auth.HiveAuthFactory; import org.apache.hive.service.auth.KerberosSaslHelper; @@ -190,9 +189,7 @@ public HiveConnection(String uri, Properties info) throws SQLException { supportedProtocols.add(TProtocolVersion.HIVE_CLI_SERVICE_PROTOCOL_V7); // open client session - openSession(connParams.getSessionVars()); - - configureConnection(connParams.getDbName()); + openSession(connParams); } private void openTransport() throws SQLException { @@ -400,16 +397,28 @@ private String getClientDelegationToken(Map jdbcConnConf) return tokenStr; } - private void openSession(Map sessVars) throws SQLException { + private void openSession(Utils.JdbcConnectionParams connParams) throws SQLException { TOpenSessionReq openReq = new TOpenSessionReq(); + Map openConf = new HashMap(); + // for remote JDBC client, try to set the conf var using 'set foo=bar' + for (Entry hiveConf : connParams.getHiveConfs().entrySet()) { + openConf.put("set:hiveconf:" + hiveConf.getKey(), hiveConf.getValue()); + } + // For remote JDBC client, try to set the hive var using 'set hivevar:key=value' + for (Entry hiveVar : connParams.getHiveVars().entrySet()) { + openConf.put("set:hivevar:" + hiveVar.getKey(), hiveVar.getValue()); + } + // switch the database + openConf.put("use:database", connParams.getDbName()); + // set the session configuration + Map sessVars = connParams.getSessionVars(); if (sessVars.containsKey(HiveAuthFactory.HS2_PROXY_USER)) { - Map openConf = new HashMap(); openConf.put(HiveAuthFactory.HS2_PROXY_USER, sessVars.get(HiveAuthFactory.HS2_PROXY_USER)); - openReq.setConfiguration(openConf); } + openReq.setConfiguration(openConf); try { TOpenSessionResp openResp = client.OpenSession(openReq); @@ -429,31 +438,6 @@ private void openSession(Map sessVars) throws SQLException { isClosed = false; } - private void configureConnection(String dbName) throws SQLException { - // set the hive variable in session state for local mode - if (isEmbeddedMode) { - if (!hiveVarMap.isEmpty()) { - SessionState.get().setHiveVariables(hiveVarMap); - } - } else { - // for remote JDBC client, try to set the conf var using 'set foo=bar' - Statement stmt = createStatement(); - for (Entry hiveConf : hiveConfMap.entrySet()) { - stmt.execute("set " + hiveConf.getKey() + "=" + hiveConf.getValue()); - } - - // For remote JDBC client, try to set the hive var using 'set hivevar:key=value' - for (Entry hiveVar : hiveVarMap.entrySet()) { - stmt.execute("set hivevar:" + hiveVar.getKey() + "=" + hiveVar.getValue()); - } - // if the client is setting a non-default db, then switch the database - if (!Utils.DEFAULT_DATABASE.equalsIgnoreCase(dbName)) { - stmt.execute("use " + dbName); - } - stmt.close(); - } - } - /** * @return username from sessConfMap */ diff --git jdbc/src/java/org/apache/hive/jdbc/Utils.java jdbc/src/java/org/apache/hive/jdbc/Utils.java index 87fec11..f0834bd 100644 --- jdbc/src/java/org/apache/hive/jdbc/Utils.java +++ jdbc/src/java/org/apache/hive/jdbc/Utils.java @@ -20,8 +20,7 @@ import java.net.URI; import java.sql.SQLException; -import java.sql.Types; -import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -51,9 +50,9 @@ private String host = null; private int port; private String dbName = DEFAULT_DATABASE; - private Map hiveConfs = new HashMap(); - private Map hiveVars = new HashMap(); - private Map sessionVars = new HashMap(); + private Map hiveConfs = new LinkedHashMap(); + private Map hiveVars = new LinkedHashMap(); + private Map sessionVars = new LinkedHashMap(); private boolean isEmbeddedMode = false; public JdbcConnectionParams() { diff --git ql/src/java/org/apache/hadoop/hive/ql/processors/SetProcessor.java ql/src/java/org/apache/hadoop/hive/ql/processors/SetProcessor.java index 92d5e75..9b24bfd 100644 --- ql/src/java/org/apache/hadoop/hive/ql/processors/SetProcessor.java +++ ql/src/java/org/apache/hadoop/hive/ql/processors/SetProcessor.java @@ -103,42 +103,39 @@ private void dumpOption(String s) { public void init() { } - private CommandProcessorResponse setVariable(String varname, String varvalue){ + public CommandProcessorResponse executeSetVariable(String varname, String varvalue) { + try { + return new CommandProcessorResponse(setVariable(varname, varvalue)); + } catch (Exception e) { + return new CommandProcessorResponse(1, e.getMessage(), "42000"); + } + } + + public static int setVariable(String varname, String varvalue) throws IllegalArgumentException { SessionState ss = SessionState.get(); if (varvalue.contains("\n")){ ss.err.println("Warning: Value had a \\n character in it."); } if (varname.startsWith(SetProcessor.ENV_PREFIX)){ ss.err.println("env:* variables can not be set."); - return new CommandProcessorResponse(1); + return 1; } else if (varname.startsWith(SetProcessor.SYSTEM_PREFIX)){ String propName = varname.substring(SetProcessor.SYSTEM_PREFIX.length()); System.getProperties().setProperty(propName, new VariableSubstitution().substitute(ss.getConf(),varvalue)); - return new CommandProcessorResponse(0); } else if (varname.startsWith(SetProcessor.HIVECONF_PREFIX)){ String propName = varname.substring(SetProcessor.HIVECONF_PREFIX.length()); - try { - setConf(varname, propName, varvalue, false); - return new CommandProcessorResponse(0); - } catch (IllegalArgumentException e) { - return new CommandProcessorResponse(1, e.getMessage(), "42000"); - } + setConf(varname, propName, varvalue, false); } else if (varname.startsWith(SetProcessor.HIVEVAR_PREFIX)) { String propName = varname.substring(SetProcessor.HIVEVAR_PREFIX.length()); ss.getHiveVariables().put(propName, new VariableSubstitution().substitute(ss.getConf(),varvalue)); - return new CommandProcessorResponse(0); } else { - try { - setConf(varname, varname, varvalue, true); - return new CommandProcessorResponse(0); - } catch (IllegalArgumentException e) { - return new CommandProcessorResponse(1, e.getMessage(), "42000"); - } + setConf(varname, varname, varvalue, true); } + return 0; } // returns non-null string for validation fail - private void setConf(String varname, String key, String varvalue, boolean register) + private static void setConf(String varname, String key, String varvalue, boolean register) throws IllegalArgumentException { HiveConf conf = SessionState.get().getConf(); String value = new VariableSubstitution().substitute(conf, varvalue); @@ -265,7 +262,7 @@ public CommandProcessorResponse run(String command) { ss.setIsSilent(getBoolean(part[1])); return new CommandProcessorResponse(0); } - return setVariable(part[0],part[1]); + return executeSetVariable(part[0],part[1]); } else { return getVariable(nwcmd); } diff --git service/src/java/org/apache/hive/service/cli/session/HiveSessionImpl.java service/src/java/org/apache/hive/service/cli/session/HiveSessionImpl.java index a9d5902..6a7ee7a 100644 --- service/src/java/org/apache/hive/service/cli/session/HiveSessionImpl.java +++ service/src/java/org/apache/hive/service/cli/session/HiveSessionImpl.java @@ -34,6 +34,7 @@ import org.apache.hadoop.hive.ql.exec.FetchFormatter; import org.apache.hadoop.hive.ql.exec.ListSinkOperator; import org.apache.hadoop.hive.ql.history.HiveHistory; +import org.apache.hadoop.hive.ql.processors.SetProcessor; import org.apache.hadoop.hive.ql.session.SessionState; import org.apache.hive.common.util.HiveVersionInfo; import org.apache.hive.service.auth.HiveAuthFactory; @@ -88,12 +89,6 @@ public HiveSessionImpl(TProtocolVersion protocol, String username, String passwo this.hiveConf = new HiveConf(serverhiveConf); this.ipAddress = ipAddress; - //set conf properties specified by user from client side - if (sessionConfMap != null) { - for (Map.Entry entry : sessionConfMap.entrySet()) { - hiveConf.verifyAndSet(entry.getKey(), entry.getValue()); - } - } // set an explicit session name to control the download directory name hiveConf.set(ConfVars.HIVESESSIONID.varname, sessionHandle.getHandleIdentifier().toString()); @@ -101,9 +96,28 @@ public HiveSessionImpl(TProtocolVersion protocol, String username, String passwo hiveConf.set(ListSinkOperator.OUTPUT_FORMATTER, FetchFormatter.ThriftFormatter.class.getName()); hiveConf.setInt(ListSinkOperator.OUTPUT_PROTOCOL, protocol.getValue()); + sessionState = new SessionState(hiveConf, username); sessionState.setIsHiveServerQuery(true); SessionState.start(sessionState); + + //set conf properties specified by user from client side + if (sessionConfMap != null) { + configureSession(sessionConfMap); + } + } + + private void configureSession(Map sessionConfMap) { + for (Map.Entry entry : sessionConfMap.entrySet()) { + String key = entry.getKey(); + if (key.startsWith("set:")) { + SetProcessor.setVariable(key.substring(4), entry.getValue()); + } else if (key.startsWith("use:")) { + SessionState.get().setCurrentDatabase(entry.getValue()); + } else { + hiveConf.verifyAndSet(key, entry.getValue()); + } + } } @Override