This is an automated email from the ASF dual-hosted git repository.
dkuzmenko pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/hive.git
The following commit(s) were added to refs/heads/master by this push:
new cf0d4f171cd HIVE-27957: Better error message for STORED BY (Shohei
Okumiya, reviewed by Akshat Mathur, Attila Turoczy, Laszlo Bodor)
cf0d4f171cd is described below
commit cf0d4f171cd1147a3bdf3fd8d6c372e4e9758f3e
Author: okumin <[email protected]>
AuthorDate: Wed Apr 10 16:19:36 2024 +0900
HIVE-27957: Better error message for STORED BY (Shohei Okumiya, reviewed by
Akshat Mathur, Attila Turoczy, Laszlo Bodor)
Closes #4954
---
.../apache/hadoop/hive/ql/parse/StorageFormat.java | 52 +++++++++++++++++-----
.../create_table_stored_by_invalid1.q | 1 +
.../create_table_stored_by_invalid2.q | 1 +
.../create_table_stored_by_invalid3.q | 1 +
.../create_table_stored_by_invalid1.q.out | 1 +
.../create_table_stored_by_invalid2.q.out | 1 +
.../create_table_stored_by_invalid3.q.out | 1 +
7 files changed, 48 insertions(+), 10 deletions(-)
diff --git a/ql/src/java/org/apache/hadoop/hive/ql/parse/StorageFormat.java
b/ql/src/java/org/apache/hadoop/hive/ql/parse/StorageFormat.java
index 50f08ff1f4e..2472ad44ad0 100644
--- a/ql/src/java/org/apache/hadoop/hive/ql/parse/StorageFormat.java
+++ b/ql/src/java/org/apache/hadoop/hive/ql/parse/StorageFormat.java
@@ -19,9 +19,13 @@ package org.apache.hadoop.hive.ql.parse;
import static org.apache.hadoop.hive.ql.parse.ParseUtils.ensureClassExists;
+import java.util.Arrays;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
+import java.util.Objects;
+import java.util.stream.Collectors;
import org.apache.commons.lang3.StringUtils;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hive.conf.HiveConf;
@@ -48,9 +52,14 @@ public class StorageFormat {
public enum StorageHandlerTypes {
DEFAULT(),
- ICEBERG("\'org.apache.iceberg.mr.hive.HiveIcebergStorageHandler\'",
+ ICEBERG("'org.apache.iceberg.mr.hive.HiveIcebergStorageHandler'",
"org.apache.iceberg.mr.hive.HiveIcebergInputFormat",
"org.apache.iceberg.mr.hive.HiveIcebergOutputFormat");
+ private static final List<StorageHandlerTypes> NON_DEFAULT_TYPES = Arrays
+ .stream(values())
+ .filter(type -> type != StorageHandlerTypes.DEFAULT)
+ .collect(Collectors.toList());
+
private final String className;
private final String inputFormat;
private final String outputFormat;
@@ -133,7 +142,7 @@ public class StorageFormat {
BaseSemanticAnalyzer.readProps((ASTNode) grandChild.getChild(0),
serdeProps);
break;
default:
- storageHandler = processStorageHandler(grandChild.getText());
+ storageHandler = processStorageHandler(grandChild);
}
}
break;
@@ -157,17 +166,40 @@ public class StorageFormat {
return true;
}
- private String processStorageHandler(String name) throws SemanticException {
- for (StorageHandlerTypes type : StorageHandlerTypes.values()) {
- if (type.name().equalsIgnoreCase(name)) {
- name = type.className();
- inputFormat = type.inputFormat();
- outputFormat = type.outputFormat();
- break;
+ private String processStorageHandler(ASTNode node) throws SemanticException {
+ if (node.getType() == HiveParser.StringLiteral) {
+ // e.g. STORED BY 'org.apache.iceberg.mr.hive.HiveIcebergStorageHandler'
+ try {
+ return
ensureClassExists(BaseSemanticAnalyzer.unescapeSQLString(node.getText()));
+ } catch (SemanticException e) {
+ throw createUnsupportedStorageHandlerTypeError(node, e);
+ }
+ }
+ if (node.getType() == HiveParser.Identifier) {
+ // e.g. STORED BY ICEBERG
+ for (StorageHandlerTypes type : StorageHandlerTypes.NON_DEFAULT_TYPES) {
+ if (type.name().equalsIgnoreCase(node.getText())) {
+ Objects.requireNonNull(type.className());
+ inputFormat = type.inputFormat();
+ outputFormat = type.outputFormat();
+ return
ensureClassExists(BaseSemanticAnalyzer.unescapeSQLString(type.className()));
+ }
}
}
+ throw createUnsupportedStorageHandlerTypeError(node, null);
+ }
- return ensureClassExists(BaseSemanticAnalyzer.unescapeSQLString(name));
+ private static SemanticException
createUnsupportedStorageHandlerTypeError(ASTNode node, Throwable cause) {
+ final String supportedTypes = StorageHandlerTypes
+ .NON_DEFAULT_TYPES
+ .stream()
+ .map(Enum::toString)
+ .collect(Collectors.joining(", "));
+ return new SemanticException(String.format(
+ "The storage handler specified in the STORED BY clause is not
recognized: %s. Please use one of the supported "
+ + "types, which are %s, or provide the Fully Qualified Class Name
(FQCN) of a valid storage handler.",
+ node.getText(), supportedTypes
+ ), cause);
}
public void processStorageFormat(String name) throws SemanticException {
diff --git
a/ql/src/test/queries/clientnegative/create_table_stored_by_invalid1.q
b/ql/src/test/queries/clientnegative/create_table_stored_by_invalid1.q
new file mode 100644
index 00000000000..6d9af9f4209
--- /dev/null
+++ b/ql/src/test/queries/clientnegative/create_table_stored_by_invalid1.q
@@ -0,0 +1 @@
+CREATE TABLE test (a STRING) STORED BY DEFAULT;
diff --git
a/ql/src/test/queries/clientnegative/create_table_stored_by_invalid2.q
b/ql/src/test/queries/clientnegative/create_table_stored_by_invalid2.q
new file mode 100644
index 00000000000..bb42c0c3c9f
--- /dev/null
+++ b/ql/src/test/queries/clientnegative/create_table_stored_by_invalid2.q
@@ -0,0 +1 @@
+CREATE TABLE test (a STRING) STORED BY ORC;
diff --git
a/ql/src/test/queries/clientnegative/create_table_stored_by_invalid3.q
b/ql/src/test/queries/clientnegative/create_table_stored_by_invalid3.q
new file mode 100644
index 00000000000..e1ee4cefb1c
--- /dev/null
+++ b/ql/src/test/queries/clientnegative/create_table_stored_by_invalid3.q
@@ -0,0 +1 @@
+CREATE TABLE test (a STRING) STORED BY 'ICEBERG';
diff --git
a/ql/src/test/results/clientnegative/create_table_stored_by_invalid1.q.out
b/ql/src/test/results/clientnegative/create_table_stored_by_invalid1.q.out
new file mode 100644
index 00000000000..2271b4d3d79
--- /dev/null
+++ b/ql/src/test/results/clientnegative/create_table_stored_by_invalid1.q.out
@@ -0,0 +1 @@
+FAILED: SemanticException The storage handler specified in the STORED BY
clause is not recognized: DEFAULT. Please use one of the supported types, which
are ICEBERG, or provide the Fully Qualified Class Name (FQCN) of a valid
storage handler.
diff --git
a/ql/src/test/results/clientnegative/create_table_stored_by_invalid2.q.out
b/ql/src/test/results/clientnegative/create_table_stored_by_invalid2.q.out
new file mode 100644
index 00000000000..8176a6c0a9d
--- /dev/null
+++ b/ql/src/test/results/clientnegative/create_table_stored_by_invalid2.q.out
@@ -0,0 +1 @@
+FAILED: SemanticException The storage handler specified in the STORED BY
clause is not recognized: ORC. Please use one of the supported types, which are
ICEBERG, or provide the Fully Qualified Class Name (FQCN) of a valid storage
handler.
diff --git
a/ql/src/test/results/clientnegative/create_table_stored_by_invalid3.q.out
b/ql/src/test/results/clientnegative/create_table_stored_by_invalid3.q.out
new file mode 100644
index 00000000000..233012e9c21
--- /dev/null
+++ b/ql/src/test/results/clientnegative/create_table_stored_by_invalid3.q.out
@@ -0,0 +1 @@
+FAILED: SemanticException The storage handler specified in the STORED BY
clause is not recognized: 'ICEBERG'. Please use one of the supported types,
which are ICEBERG, or provide the Fully Qualified Class Name (FQCN) of a valid
storage handler.