This is an automated email from the ASF dual-hosted git repository.
chengpan pushed a commit to branch branch-1.7
in repository https://gitbox.apache.org/repos/asf/kyuubi.git
The following commit(s) were added to refs/heads/branch-1.7 by this push:
new 36ddb0db1 [KYUUBI #4965] [BEELINE] Support `--python-mode` option and
remove comments for non-python mode
36ddb0db1 is described below
commit 36ddb0db15c17275295ed58ee61a409f720205cc
Author: fwang12 <[email protected]>
AuthorDate: Fri Jun 16 17:34:24 2023 +0800
[KYUUBI #4965] [BEELINE] Support `--python-mode` option and remove comments
for non-python mode
Close #4803
The beeline has regression because of
https://github.com/apache/kyuubi/commit/70590f71ef32f5d3903acd75e72b78e5420b384c#diff-993fdbefe9fe3d1c91fcedba99362a8c8d9b94793ec16cbfbc989e750367ea89
- [x] Add some test cases that check the changes thoroughly including
negative and positive cases if possible
- [ ] Add screenshots for manual tests if appropriate
- [x] [Run
test](https://kyuubi.readthedocs.io/en/master/develop_tools/testing.html#running-tests)
locally before make a pull request
Closes #4965 from turboFei/revert_beeline_python_change.
Closes #4965
856d92391 [fwang12] trim for non python mdoe
f8464606b [fwang12] Revert "[KYUUBI #4619] Fix beeline with -e When there
are other SQL statements before the source statement, the source statement
cannot be executed normally"
e5e3c31b3 [fwang12] revert trim
bec09c254 [fwang12] migration guide
585da6fc1 [fwang12] fix'
f3fcfe97e [fwang12] save
8cb8cb9d0 [fwang12] save
e1539775a [fwang12] comments
814c970a2 [fwang12] save
b1baa773b [fwang12] save
3337ca8fa [fwang12] options
Authored-by: fwang12 <[email protected]>
Signed-off-by: fwang12 <[email protected]>
---
docs/deployment/migration-guide.md | 4 ++
.../org/apache/hive/beeline/KyuubiBeeLine.java | 36 +++++++++--
.../org/apache/hive/beeline/KyuubiCommands.java | 24 +++++--
.../org/apache/hive/beeline/KyuubiBeeLineTest.java | 73 ++++++++++++++++++++++
.../apache/hive/beeline/KyuubiCommandsTest.java | 18 ++++++
5 files changed, 144 insertions(+), 11 deletions(-)
diff --git a/docs/deployment/migration-guide.md
b/docs/deployment/migration-guide.md
index fc916048c..3240fdce9 100644
--- a/docs/deployment/migration-guide.md
+++ b/docs/deployment/migration-guide.md
@@ -17,6 +17,10 @@
# Kyuubi Migration Guide
+## Upgrading from Kyuubi 1.7.1 to 1.7.2
+
+* Since Kyuubi 1.7.2, for Kyuubi BeeLine, please use `--python-mode` option to
run python code or script.
+
## Upgrading from Kyuubi 1.7.0 to 1.7.1
* Since Kyuubi 1.7.1, `protocolVersion` is removed from the request parameters
of the REST API `Open(create) a session`. All removed or unknown parameters
will be silently ignored and affects nothing.
diff --git
a/kyuubi-hive-beeline/src/main/java/org/apache/hive/beeline/KyuubiBeeLine.java
b/kyuubi-hive-beeline/src/main/java/org/apache/hive/beeline/KyuubiBeeLine.java
index 3908a44f1..f5336816c 100644
---
a/kyuubi-hive-beeline/src/main/java/org/apache/hive/beeline/KyuubiBeeLine.java
+++
b/kyuubi-hive-beeline/src/main/java/org/apache/hive/beeline/KyuubiBeeLine.java
@@ -22,10 +22,7 @@ import java.io.InputStream;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.sql.Driver;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.List;
+import java.util.*;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
@@ -41,6 +38,9 @@ public class KyuubiBeeLine extends BeeLine {
private static final int ERRNO_ARGS = 1;
private static final int ERRNO_OTHER = 2;
+ private static final String PYTHON_MODE_PREFIX = "--python-mode";
+ private boolean pythonMode = false;
+
public KyuubiBeeLine() {
this(true);
}
@@ -68,6 +68,22 @@ public class KyuubiBeeLine extends BeeLine {
}
}
+ @Override
+ void usage() {
+ super.usage();
+ output("Usage: java \" + KyuubiBeeLine.class.getCanonicalName()");
+ output(" --python-mode Execute python code/script.");
+ }
+
+ public boolean isPythonMode() {
+ return pythonMode;
+ }
+
+ // Visible for testing
+ public void setPythonMode(boolean pythonMode) {
+ this.pythonMode = pythonMode;
+ }
+
/** Starts the program. */
public static void main(String[] args) throws IOException {
mainWithInputRedirection(args, null);
@@ -127,7 +143,17 @@ public class KyuubiBeeLine extends BeeLine {
optionsField.setAccessible(true);
Options options = (Options) optionsField.get(this);
- beelineParser = new BeelineParser();
+ beelineParser =
+ new BeelineParser() {
+ @Override
+ protected void processOption(String arg, ListIterator iter) throws
ParseException {
+ if (PYTHON_MODE_PREFIX.equals(arg)) {
+ pythonMode = true;
+ } else {
+ super.processOption(arg, iter);
+ }
+ }
+ };
cl = beelineParser.parse(options, args);
Method connectUsingArgsMethod =
diff --git
a/kyuubi-hive-beeline/src/main/java/org/apache/hive/beeline/KyuubiCommands.java
b/kyuubi-hive-beeline/src/main/java/org/apache/hive/beeline/KyuubiCommands.java
index 6580d2490..56ec1de6d 100644
---
a/kyuubi-hive-beeline/src/main/java/org/apache/hive/beeline/KyuubiCommands.java
+++
b/kyuubi-hive-beeline/src/main/java/org/apache/hive/beeline/KyuubiCommands.java
@@ -24,6 +24,7 @@ import java.io.*;
import java.sql.*;
import java.util.*;
import org.apache.hive.beeline.logs.KyuubiBeelineInPlaceUpdateStream;
+import org.apache.hive.common.util.HiveStringUtils;
import org.apache.kyuubi.jdbc.hive.KyuubiStatement;
import org.apache.kyuubi.jdbc.hive.Utils;
import org.apache.kyuubi.jdbc.hive.logs.InPlaceUpdateStream;
@@ -44,9 +45,14 @@ public class KyuubiCommands extends Commands {
return execute(line, false, false);
}
+ /** For python mode, keep it as it is. */
+ private String trimForNonPythonMode(String line) {
+ return beeLine.isPythonMode() ? line : line.trim();
+ }
+
/** Extract and clean up the first command in the input. */
private String getFirstCmd(String cmd, int length) {
- return cmd.substring(length).trim();
+ return trimForNonPythonMode(cmd.substring(length));
}
private String[] tokenizeCmd(String cmd) {
@@ -54,14 +60,12 @@ public class KyuubiCommands extends Commands {
}
private boolean isSourceCMD(String cmd) {
- cmd = cmd.trim();
if (cmd == null || cmd.isEmpty()) return false;
String[] tokens = tokenizeCmd(cmd);
return tokens[0].equalsIgnoreCase("source");
}
private boolean sourceFile(String cmd) {
- cmd = cmd.trim();
String[] tokens = tokenizeCmd(cmd);
String cmd_1 = getFirstCmd(cmd, tokens[0].length());
@@ -98,7 +102,7 @@ public class KyuubiCommands extends Commands {
}
String[] cmds = lines.split(beeLine.getOpts().getDelimiter());
for (String c : cmds) {
- c = c.trim();
+ c = trimForNonPythonMode(c);
if (!executeInternal(c, false)) {
return false;
}
@@ -262,9 +266,10 @@ public class KyuubiCommands extends Commands {
beeLine.handleException(e);
}
+ line = trimForNonPythonMode(line);
List<String> cmdList = getCmdList(line, entireLineAsCommand);
for (int i = 0; i < cmdList.size(); i++) {
- String sql = cmdList.get(i);
+ String sql = trimForNonPythonMode(cmdList.get(i));
if (sql.length() != 0) {
if (!executeInternal(sql, call)) {
return false;
@@ -522,6 +527,9 @@ public class KyuubiCommands extends Commands {
? null
: jline.console.ConsoleReader.NULL_MASK;
+ if (!beeLine.isPythonMode()) {
+ line = HiveStringUtils.removeComments(line, startQuote);
+ }
while (isMultiLine(line) && beeLine.getOpts().isAllowMultiLineCommand()) {
StringBuilder prompt = new StringBuilder(beeLine.getPrompt());
if (!beeLine.getOpts().isSilent()) {
@@ -547,6 +555,9 @@ public class KyuubiCommands extends Commands {
if (extra == null) { // it happens when using -f and the line of cmds
does not end with ;
break;
}
+ if (!beeLine.isPythonMode()) {
+ extra = HiveStringUtils.removeComments(extra, startQuote);
+ }
if (!extra.isEmpty()) {
line += "\n" + extra;
}
@@ -558,12 +569,13 @@ public class KyuubiCommands extends Commands {
// console. Used in handleMultiLineCmd method assumes line would never be
null when this method is
// called
private boolean isMultiLine(String line) {
+ line = trimForNonPythonMode(line);
if (line.endsWith(beeLine.getOpts().getDelimiter()) ||
beeLine.isComment(line)) {
return false;
}
// handles the case like line = show tables; --test comment
List<String> cmds = getCmdList(line, false);
- return cmds.isEmpty() || !cmds.get(cmds.size() - 1).startsWith("--");
+ return cmds.isEmpty() || !trimForNonPythonMode(cmds.get(cmds.size() -
1)).startsWith("--");
}
static class KyuubiLogRunnable implements Runnable {
diff --git
a/kyuubi-hive-beeline/src/test/java/org/apache/hive/beeline/KyuubiBeeLineTest.java
b/kyuubi-hive-beeline/src/test/java/org/apache/hive/beeline/KyuubiBeeLineTest.java
index 96b76373d..9119492b8 100644
---
a/kyuubi-hive-beeline/src/test/java/org/apache/hive/beeline/KyuubiBeeLineTest.java
+++
b/kyuubi-hive-beeline/src/test/java/org/apache/hive/beeline/KyuubiBeeLineTest.java
@@ -19,7 +19,12 @@
package org.apache.hive.beeline;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.lang.reflect.Field;
import org.junit.Test;
public class KyuubiBeeLineTest {
@@ -47,4 +52,72 @@ public class KyuubiBeeLineTest {
int result3 = kyuubiBeeLine.initArgs(args3);
assertEquals(1, result3);
}
+
+ @Test
+ public void testKyuubiBeeLineCmdUsage() throws ReflectiveOperationException {
+ BufferPrintStream printStream = new BufferPrintStream();
+
+ KyuubiBeeLine kyuubiBeeLine = new KyuubiBeeLine();
+ Field outputStreamField = BeeLine.class.getDeclaredField("outputStream");
+ outputStreamField.setAccessible(true);
+ outputStreamField.set(kyuubiBeeLine, printStream);
+ String[] args1 = {"-h"};
+ kyuubiBeeLine.initArgs(args1);
+ String output = printStream.getOutput();
+ assert output.contains("--python-mode Execute python
code/script.");
+ }
+
+ @Test
+ public void testKyuubiBeeLinePythonMode() {
+ KyuubiBeeLine kyuubiBeeLine = new KyuubiBeeLine();
+ String[] args1 = {"-u", "badUrl", "--python-mode"};
+ kyuubiBeeLine.initArgs(args1);
+ assertTrue(kyuubiBeeLine.isPythonMode());
+ kyuubiBeeLine.setPythonMode(false);
+
+ String[] args2 = {"--python-mode", "-f", "test.sql"};
+ kyuubiBeeLine.initArgs(args2);
+ assertTrue(kyuubiBeeLine.isPythonMode());
+ assert kyuubiBeeLine.getOpts().getScriptFile().equals("test.sql");
+ kyuubiBeeLine.setPythonMode(false);
+
+ String[] args3 = {"-u", "badUrl"};
+ kyuubiBeeLine.initArgs(args3);
+ assertTrue(!kyuubiBeeLine.isPythonMode());
+ kyuubiBeeLine.setPythonMode(false);
+ }
+
+ static class BufferPrintStream extends PrintStream {
+ public StringBuilder stringBuilder = new StringBuilder();
+
+ static OutputStream noOpOutputStream =
+ new OutputStream() {
+ @Override
+ public void write(int b) throws IOException {
+ // do nothing
+ }
+ };
+
+ public BufferPrintStream() {
+ super(noOpOutputStream);
+ }
+
+ public BufferPrintStream(OutputStream outputStream) {
+ super(noOpOutputStream);
+ }
+
+ @Override
+ public void println(String x) {
+ stringBuilder.append(x).append("\n");
+ }
+
+ @Override
+ public void print(String x) {
+ stringBuilder.append(x);
+ }
+
+ public String getOutput() {
+ return stringBuilder.toString();
+ }
+ }
}
diff --git
a/kyuubi-hive-beeline/src/test/java/org/apache/hive/beeline/KyuubiCommandsTest.java
b/kyuubi-hive-beeline/src/test/java/org/apache/hive/beeline/KyuubiCommandsTest.java
index ecb8d65f5..8cde13d45 100644
---
a/kyuubi-hive-beeline/src/test/java/org/apache/hive/beeline/KyuubiCommandsTest.java
+++
b/kyuubi-hive-beeline/src/test/java/org/apache/hive/beeline/KyuubiCommandsTest.java
@@ -34,6 +34,7 @@ public class KyuubiCommandsTest {
Mockito.when(reader.readLine()).thenReturn(pythonSnippets);
KyuubiBeeLine beeline = new KyuubiBeeLine();
+ beeline.setPythonMode(true);
beeline.setConsoleReader(reader);
KyuubiCommands commands = new KyuubiCommands(beeline);
String line = commands.handleMultiLineCmd(pythonSnippets);
@@ -42,4 +43,21 @@ public class KyuubiCommandsTest {
assertEquals(cmdList.size(), 1);
assertEquals(cmdList.get(0), pythonSnippets);
}
+
+ @Test
+ public void testHandleMultiLineCmd() throws IOException {
+ ConsoleReader reader = Mockito.mock(ConsoleReader.class);
+ String snippets = "select 1;--comments1\nselect 2;--comments2";
+ Mockito.when(reader.readLine()).thenReturn(snippets);
+
+ KyuubiBeeLine beeline = new KyuubiBeeLine();
+ beeline.setConsoleReader(reader);
+ beeline.setPythonMode(false);
+ KyuubiCommands commands = new KyuubiCommands(beeline);
+ String line = commands.handleMultiLineCmd(snippets);
+ List<String> cmdList = commands.getCmdList(line, false);
+ assertEquals(cmdList.size(), 2);
+ assertEquals(cmdList.get(0), "select 1");
+ assertEquals(cmdList.get(1), "\nselect 2");
+ }
}