You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hive.apache.org by xu...@apache.org on 2014/03/30 17:17:56 UTC
svn commit: r1583152 - in /hive/trunk/beeline/src:
java/org/apache/hive/beeline/BeeLine.java
test/org/apache/hive/beeline/TestBeelineArgParsing.java
Author: xuefu
Date: Sun Mar 30 15:17:55 2014
New Revision: 1583152
URL: http://svn.apache.org/r1583152
Log:
Beeline throws ArrayIndexOutOfBoundsException for mismatched arguments (Szehon via Xuefu)
Added:
hive/trunk/beeline/src/test/org/apache/hive/beeline/TestBeelineArgParsing.java
Modified:
hive/trunk/beeline/src/java/org/apache/hive/beeline/BeeLine.java
Modified: hive/trunk/beeline/src/java/org/apache/hive/beeline/BeeLine.java
URL: http://svn.apache.org/viewvc/hive/trunk/beeline/src/java/org/apache/hive/beeline/BeeLine.java?rev=1583152&r1=1583151&r2=1583152&view=diff
==============================================================================
--- hive/trunk/beeline/src/java/org/apache/hive/beeline/BeeLine.java (original)
+++ hive/trunk/beeline/src/java/org/apache/hive/beeline/BeeLine.java Sun Mar 30 15:17:55 2014
@@ -58,7 +58,9 @@ import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
+import java.util.ListIterator;
import java.util.Map;
+import java.util.Properties;
import java.util.ResourceBundle;
import java.util.Set;
import java.util.SortedSet;
@@ -76,6 +78,12 @@ import jline.ConsoleReader;
import jline.FileNameCompletor;
import jline.SimpleCompletor;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.GnuParser;
+import org.apache.commons.cli.OptionBuilder;
+import org.apache.commons.cli.Options;
+import org.apache.commons.cli.ParseException;
+
/**
* A console SQL shell with command completion.
@@ -115,6 +123,8 @@ public class BeeLine {
private List<String> batch = null;
private final Reflector reflector;
+ private static final Options options = new Options();
+
public static final String BEELINE_DEFAULT_JDBC_DRIVER = "org.apache.hive.jdbc.HiveDriver";
public static final String BEELINE_DEFAULT_JDBC_URL = "jdbc:hive2://";
@@ -245,6 +255,81 @@ public class BeeLine {
}
}
+ static {
+ // -d <driver class>
+ options.addOption(OptionBuilder
+ .hasArg()
+ .withArgName("driver class")
+ .withDescription("the driver class to use")
+ .create('d'));
+
+ // -u <database url>
+ options.addOption(OptionBuilder
+ .hasArg()
+ .withArgName("database url")
+ .withDescription("the JDBC URL to connect to")
+ .create('u'));
+
+ // -n <username>
+ options.addOption(OptionBuilder
+ .hasArg()
+ .withArgName("username")
+ .withDescription("the username to connect as")
+ .create('n'));
+
+ // -p <password>
+ options.addOption(OptionBuilder
+ .hasArg()
+ .withArgName("password")
+ .withDescription("the password to connect as")
+ .create('p'));
+
+ // -a <authType>
+ options.addOption(OptionBuilder
+ .hasArg()
+ .withArgName("authType")
+ .withDescription("the authentication type")
+ .create('a'));
+
+ // -e <query>
+ options.addOption(OptionBuilder
+ .hasArgs()
+ .withArgName("query")
+ .withDescription("query that should be executed")
+ .create('e'));
+
+ // -f <file>
+ options.addOption(OptionBuilder
+ .hasArg()
+ .withArgName("file")
+ .withDescription("script file that should be executed")
+ .create('f'));
+
+ // -help
+ options.addOption(OptionBuilder
+ .withLongOpt("help")
+ .withDescription("display this message")
+ .create('h'));
+
+ // Substitution option --hivevar
+ options.addOption(OptionBuilder
+ .withValueSeparator()
+ .hasArgs(2)
+ .withArgName("key=value")
+ .withLongOpt("hivevar")
+ .withDescription("hive variable name and value")
+ .create());
+
+ //hive conf option --hiveconf
+ options.addOption(OptionBuilder
+ .withValueSeparator()
+ .hasArgs(2)
+ .withArgName("property=value")
+ .withLongOpt("hiveconf")
+ .withDescription("Use value for given property")
+ .create());
+ }
+
static Manifest getManifest() throws IOException {
URL base = BeeLine.class.getResource("/META-INF/MANIFEST.MF");
@@ -498,79 +583,72 @@ public class BeeLine {
}
- boolean initArgs(String[] args) {
- List<String> commands = new LinkedList<String>();
- List<String> files = new LinkedList<String>();
- String driver = null, user = null, pass = null, url = null, cmd = null;
- String auth = null;
+ public class BeelineParser extends GnuParser {
- for (int i = 0; i < args.length; i++) {
- if (args[i].equals("--help") || args[i].equals("-h")) {
- // Return false here, so usage will be printed.
- return false;
- }
-
- // Parse hive variables
- if (args[i].equals(HIVE_VAR_PREFIX)) {
- String[] parts = split(args[++i], "=");
- if (parts.length != 2) {
- return false;
+ @Override
+ protected void processOption(final String arg, final ListIterator iter) throws ParseException {
+ if ((arg.startsWith("--")) && !(arg.equals(HIVE_VAR_PREFIX) || (arg.equals(HIVE_CONF_PREFIX)) || (arg.equals("--help")))) {
+ String stripped = arg.substring(2, arg.length());
+ String[] parts = split(stripped, "=");
+ debug(loc("setting-prop", Arrays.asList(parts)));
+ if (parts.length >= 2) {
+ getOpts().set(parts[0], parts[1], true);
+ } else {
+ getOpts().set(parts[0], "true", true);
}
- getOpts().getHiveVariables().put(parts[0], parts[1]);
- continue;
+ } else {
+ super.processOption(arg, iter);
}
+ }
- // Parse hive conf variables
- if (args[i].equals(HIVE_CONF_PREFIX)) {
- String[] parts = split(args[++i], "=");
- if (parts.length != 2) {
- return false;
- }
- getOpts().getHiveConfVariables().put(parts[0], parts[1]);
- continue;
- }
+ }
- // -- arguments are treated as properties
- if (args[i].startsWith("--")) {
- String[] parts = split(args[i].substring(2), "=");
- debug(loc("setting-prop", Arrays.asList(parts)));
- if (parts.length > 0) {
- boolean ret;
+ boolean initArgs(String[] args) {
+ List<String> commands = new LinkedList<String>();
+ List<String> files = new LinkedList<String>();
- if (parts.length >= 2) {
- ret = getOpts().set(parts[0], parts[1], true);
- } else {
- ret = getOpts().set(parts[0], "true", true);
- }
+ CommandLine cl;
+ BeelineParser beelineParser;
- if (!ret) {
- return false;
- }
+ try {
+ beelineParser = new BeelineParser();
+ cl = beelineParser.parse(options, args);
+ } catch (ParseException e1) {
+ output(e1.getMessage());
+ return false;
+ }
- }
- continue;
- }
+ String driver = null, user = null, pass = null, url = null, cmd = null;
+ String auth = null;
- if (args[i].equals("-d")) {
- driver = args[i++ + 1];
- } else if (args[i].equals("-n")) {
- user = args[i++ + 1];
- } else if (args[i].equals("-a")) {
- auth = args[i++ + 1];
- getOpts().setAuthType(auth);
- } else if (args[i].equals("-p")) {
- pass = args[i++ + 1];
- } else if (args[i].equals("-u")) {
- url = args[i++ + 1];
- } else if (args[i].equals("-e")) {
- commands.add(args[i++ + 1]);
- } else if (args[i].equals("-f")) {
- getOpts().setScriptFile(args[i++ + 1]);
- } else {
- return error(loc("unrecognized-argument", args[i]));
- }
+
+ if (cl.hasOption("help")) {
+ // Return false here, so usage will be printed.
+ return false;
}
+ Properties hiveVars = cl.getOptionProperties("hivevar");
+ for (String key : hiveVars.stringPropertyNames()) {
+ getOpts().getHiveVariables().put(key, hiveVars.getProperty(key));
+ }
+
+ Properties hiveConfs = cl.getOptionProperties("hiveconf");
+ for (String key : hiveConfs.stringPropertyNames()) {
+ getOpts().getHiveConfVariables().put(key, hiveConfs.getProperty(key));
+ }
+
+ driver = cl.getOptionValue("d");
+ auth = cl.getOptionValue("a");
+ user = cl.getOptionValue("n");
+ getOpts().setAuthType(auth);
+ pass = cl.getOptionValue("p");
+ url = cl.getOptionValue("u");
+ getOpts().setScriptFile(cl.getOptionValue("f"));
+ if (cl.getOptionValues('e') != null) {
+ commands = Arrays.asList(cl.getOptionValues('e'));
+ }
+
+
// TODO: temporary disable this for easier debugging
/*
if (url == null) {
Added: hive/trunk/beeline/src/test/org/apache/hive/beeline/TestBeelineArgParsing.java
URL: http://svn.apache.org/viewvc/hive/trunk/beeline/src/test/org/apache/hive/beeline/TestBeelineArgParsing.java?rev=1583152&view=auto
==============================================================================
--- hive/trunk/beeline/src/test/org/apache/hive/beeline/TestBeelineArgParsing.java (added)
+++ hive/trunk/beeline/src/test/org/apache/hive/beeline/TestBeelineArgParsing.java Sun Mar 30 15:17:55 2014
@@ -0,0 +1,148 @@
+/**
+ * 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.beeline;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import junit.framework.Assert;
+
+import org.junit.Test;
+
+/**
+ * Unit test for Beeline arg parser.
+ */
+public class TestBeelineArgParsing {
+
+ public class TestBeeline extends BeeLine {
+
+ String connectArgs = null;
+ List<String> properties = new ArrayList<String>();
+ List<String> queries = new ArrayList<String>();
+
+ @Override
+ boolean dispatch(String command) {
+ String connectCommand = "!connect";
+ String propertyCommand = "!property";
+ if (command.startsWith(connectCommand)) {
+ this.connectArgs = command.substring(connectCommand.length() + 1, command.length());
+ } else if (command.startsWith(propertyCommand)) {
+ this.properties.add(command.substring(propertyCommand.length() + 1, command.length()));
+ } else {
+ this.queries.add(command);
+ }
+ return true;
+ }
+ }
+
+ @Test
+ public void testSimpleArgs() throws Exception {
+ TestBeeline bl = new TestBeeline();
+ String args[] = new String[] {"-u", "url", "-n", "name",
+ "-p", "password", "-d", "driver", "-a", "authType"};
+ Assert.assertTrue(bl.initArgs(args));
+ Assert.assertTrue(bl.connectArgs.equals("url name password driver"));
+ Assert.assertTrue(bl.getOpts().getAuthType().equals("authType"));
+ }
+
+ /**
+ * The first flag is taken by the parser.
+ */
+ @Test
+ public void testDuplicateArgs() throws Exception {
+ TestBeeline bl = new TestBeeline();
+ String args[] = new String[] {"-u", "url", "-u", "url2", "-n", "name",
+ "-p", "password", "-d", "driver"};
+ Assert.assertTrue(bl.initArgs(args));
+ Assert.assertTrue(bl.connectArgs.equals("url name password driver"));
+ }
+
+ @Test
+ public void testQueryScripts() throws Exception {
+ TestBeeline bl = new TestBeeline();
+ String args[] = new String[] {"-u", "url", "-n", "name",
+ "-p", "password", "-d", "driver", "-e", "select1", "-e", "select2"};
+ Assert.assertTrue(bl.initArgs(args));
+ Assert.assertTrue(bl.connectArgs.equals("url name password driver"));
+ Assert.assertTrue(bl.queries.contains("select1"));
+ Assert.assertTrue(bl.queries.contains("select2"));
+ }
+
+ /**
+ * Test setting hive conf and hive vars with --hiveconf and --hivevar
+ */
+ @Test
+ public void testHiveConfAndVars() throws Exception {
+ TestBeeline bl = new TestBeeline();
+ String args[] = new String[] {"-u", "url", "-n", "name",
+ "-p", "password", "-d", "driver", "--hiveconf", "a=avalue", "--hiveconf", "b=bvalue",
+ "--hivevar", "c=cvalue", "--hivevar", "d=dvalue"};
+ Assert.assertTrue(bl.initArgs(args));
+ Assert.assertTrue(bl.connectArgs.equals("url name password driver"));
+ Assert.assertTrue(bl.getOpts().getHiveConfVariables().get("a").equals("avalue"));
+ Assert.assertTrue(bl.getOpts().getHiveConfVariables().get("b").equals("bvalue"));
+ Assert.assertTrue(bl.getOpts().getHiveVariables().get("c").equals("cvalue"));
+ Assert.assertTrue(bl.getOpts().getHiveVariables().get("d").equals("dvalue"));
+ }
+
+ @Test
+ public void testBeelineOpts() throws Exception {
+ TestBeeline bl = new TestBeeline();
+ String args[] = new String[] {"-u", "url", "-n", "name",
+ "-p", "password", "-d", "driver", "--autoCommit=true", "--verbose"};
+ Assert.assertTrue(bl.initArgs(args));
+ Assert.assertTrue(bl.connectArgs.equals("url name password driver"));
+ Assert.assertTrue(bl.getOpts().getAutoCommit());
+ Assert.assertTrue(bl.getOpts().getVerbose());
+ }
+
+ /**
+ * Test setting script file with -f option.
+ */
+ @Test
+ public void testScriptFile() throws Exception {
+ TestBeeline bl = new TestBeeline();
+ String args[] = new String[] {"-u", "url", "-n", "name",
+ "-p", "password", "-d", "driver", "-f", "myscript"};
+ Assert.assertTrue(bl.initArgs(args));
+ Assert.assertTrue(bl.connectArgs.equals("url name password driver"));
+ Assert.assertTrue(bl.getOpts().getScriptFile().equals("myscript"));
+ }
+
+ /**
+ * Displays the usage.
+ */
+ @Test
+ public void testHelp() throws Exception {
+ TestBeeline bl = new TestBeeline();
+ String args[] = new String[] {"--help"};
+ Assert.assertFalse(bl.initArgs(args));
+ }
+
+ /**
+ * Displays the usage.
+ */
+ @Test
+ public void testUnmatchedArgs() throws Exception {
+ TestBeeline bl = new TestBeeline();
+ String args[] = new String[] {"-u", "url", "-n"};
+ Assert.assertFalse(bl.initArgs(args));
+ }
+
+}