This is an automated email from the ASF dual-hosted git repository.
pdallig pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/zeppelin.git
The following commit(s) were added to refs/heads/master by this push:
new c9c3437a11 [ZEPPELIN-5970][ZEPPELIN-5971] bugs occur when
zeppelin.livy.tableWithUTFCharacters is enabled (#4675)
c9c3437a11 is described below
commit c9c3437a118bfdd472d474c22ae7393f21cf49b0
Author: levi0090 <[email protected]>
AuthorDate: Mon Nov 20 22:34:15 2023 +1300
[ZEPPELIN-5970][ZEPPELIN-5971] bugs occur when
zeppelin.livy.tableWithUTFCharacters is enabled (#4675)
* fix error occurs when non-select SQL statement is executed and
tableWithUTFCharacter is True
* fix error occurs when non-primitive type of data is within json response
such as array and tableWithUTFCharacter is True
* rename custom function
* fix bug and improve the performance to iterate over the entrySet.
* remove nit
---------
Co-authored-by: Philipp Dallig <[email protected]>
---
.../zeppelin/livy/LivySparkSQLInterpreter.java | 36 +++++++++++++++++++---
.../zeppelin/livy/LivySQLInterpreterTest.java | 14 ++++++++-
2 files changed, 44 insertions(+), 6 deletions(-)
diff --git
a/livy/src/main/java/org/apache/zeppelin/livy/LivySparkSQLInterpreter.java
b/livy/src/main/java/org/apache/zeppelin/livy/LivySparkSQLInterpreter.java
index 40aa36349a..aec8146499 100644
--- a/livy/src/main/java/org/apache/zeppelin/livy/LivySparkSQLInterpreter.java
+++ b/livy/src/main/java/org/apache/zeppelin/livy/LivySparkSQLInterpreter.java
@@ -18,7 +18,8 @@
package org.apache.zeppelin.livy;
import com.google.gson.Gson;
-import com.google.gson.reflect.TypeToken;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
import java.io.IOException;
import java.io.StringWriter;
@@ -180,15 +181,20 @@ public class LivySparkSQLInterpreter extends
BaseLivyInterpreter {
List<String> rows = new ArrayList<>();
String[] rowsOutput = output.split("(?<!\\\\)\\n");
+
+ if (rowsOutput.length < 2){
+ return Arrays.asList(rowsOutput);
+ }
+
String[] header = rowsOutput[1].split("\t");
List<String> cells = new ArrayList<>(Arrays.asList(header));
rows.add(StringUtils.join(cells, "\t"));
for (int i = 2; i < rowsOutput.length; i++) {
- Map<String, String> retMap = new Gson().fromJson(
- rowsOutput[i], new TypeToken<HashMap<String, String>>() {
- }.getType()
- );
+ // one-by-one serialization to handle the case when
+ // the value is non-primitive such as: {"lang": ["java", "NodeJS"]}.
+ Map<String, String> retMap = deserialize(rowsOutput[i]);
+
cells = new ArrayList<>();
for (String s : header) {
cells.add(retMap.getOrDefault(s, "null")
@@ -200,6 +206,26 @@ public class LivySparkSQLInterpreter extends
BaseLivyInterpreter {
return rows;
}
+ private Map<String, String> deserialize(String jsonString) {
+ Map<String, String> map = new HashMap<>();
+ Gson gson = new Gson();
+ JsonElement jsonElement = gson.fromJson(jsonString, JsonElement.class);
+ JsonObject jsonObject = jsonElement.getAsJsonObject();
+
+ for (Map.Entry<String, JsonElement> entry : jsonObject.entrySet()) {
+ String key = entry.getKey();
+ JsonElement value = entry.getValue();
+
+ if (value.isJsonPrimitive()) {
+ map.put(key, value.getAsString());
+ } else {
+ map.put(key, value.toString());
+ }
+
+ }
+ return map;
+ }
+
protected List<String> parseSQLOutput(String str) {
// the regex is referred to org.apache.spark.util.Utils#fullWidthRegex
// for spark every chinese character has two placeholder(one placeholder
is one char)
diff --git
a/livy/src/test/java/org/apache/zeppelin/livy/LivySQLInterpreterTest.java
b/livy/src/test/java/org/apache/zeppelin/livy/LivySQLInterpreterTest.java
index d9ba3f6921..6294473371 100644
--- a/livy/src/test/java/org/apache/zeppelin/livy/LivySQLInterpreterTest.java
+++ b/livy/src/test/java/org/apache/zeppelin/livy/LivySQLInterpreterTest.java
@@ -174,9 +174,14 @@ class LivySQLInterpreterTest {
@Test
void parseSQLJsonOutput() {
+
+ // Empty output
+ List<String> rows = sqlInterpreter.parseSQLJsonOutput("\n");
+ assertEquals(0, rows.size());
+
// Empty sql output
// id name
- List<String> rows = sqlInterpreter.parseSQLJsonOutput("\nid\tname\n");
+ rows = sqlInterpreter.parseSQLJsonOutput("\nid\tname\n");
assertEquals(1, rows.size());
assertEquals("id\tname", rows.get(0));
@@ -274,5 +279,12 @@ class LivySQLInterpreterTest {
assertEquals("1\t1a", rows.get(1));
assertEquals("2\tみんく", rows.get(2));
assertEquals("3\t3a", rows.get(3));
+
+
+ rows = sqlInterpreter.parseSQLJsonOutput("\nid\tarray\tname\n"
+ + "{\"id\":1,\"array\":[\"1a\",\"2a\"],\"name\":\"1b\"}\n");
+ assertEquals(2, rows.size());
+ assertEquals("id\tarray\tname", rows.get(0));
+ assertEquals("1\t[\"1a\",\"2a\"]\t1b", rows.get(1));
}
}