This is an automated email from the ASF dual-hosted git repository.
jmclean pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/gravitino.git
The following commit(s) were added to refs/heads/main by this push:
new 4c886eb290 [#5755] Add List and Map types to table/columns in
Gravitino CLI (#6098)
4c886eb290 is described below
commit 4c886eb290bf1aec5a72734ad4a583a60717f7f8
Author: Vincent Chee Jia Hong <[email protected]>
AuthorDate: Sun Jan 5 22:06:11 2025 +0000
[#5755] Add List and Map types to table/columns in Gravitino CLI (#6098)
### What changes were proposed in this pull request?
- Supporting list and map types in Gravitino CLI operations.
### Why are the changes needed?
Fix: # (issue) https://github.com/apache/gravitino/issues/5755
### Does this PR introduce _any_ user-facing change?
No
### How was this patch tested?
Unit test to verify ParseType class can handle list and map input.
---
.../java/org/apache/gravitino/cli/ParseType.java | 39 +++++++++-
.../org/apache/gravitino/cli/TestParseType.java | 84 +++++++++++++++-------
2 files changed, 96 insertions(+), 27 deletions(-)
diff --git a/clients/cli/src/main/java/org/apache/gravitino/cli/ParseType.java
b/clients/cli/src/main/java/org/apache/gravitino/cli/ParseType.java
index e797d0552a..9442175ef8 100644
--- a/clients/cli/src/main/java/org/apache/gravitino/cli/ParseType.java
+++ b/clients/cli/src/main/java/org/apache/gravitino/cli/ParseType.java
@@ -22,6 +22,7 @@ package org.apache.gravitino.cli;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.gravitino.rel.types.Type;
+import org.apache.gravitino.rel.types.Types;
public class ParseType {
@@ -36,7 +37,7 @@ public class ParseType {
* @return a {@link org.apache.gravitino.cli.ParsedType} object representing
the parsed type name.
* @throws IllegalArgumentException if the data type format is unsupported
or malformed
*/
- public static ParsedType parse(String datatype) {
+ public static ParsedType parseBasicType(String datatype) {
Pattern pattern = Pattern.compile("^(\\w+)\\((\\d+)(?:,(\\d+))?\\)$");
Matcher matcher = pattern.matcher(datatype);
@@ -57,8 +58,8 @@ public class ParseType {
return null;
}
- public static Type toType(String datatype) {
- ParsedType parsed = parse(datatype);
+ private static Type toBasicType(String datatype) {
+ ParsedType parsed = parseBasicType(datatype);
if (parsed != null) {
if (parsed.getPrecision() != null && parsed.getScale() != null) {
@@ -70,4 +71,36 @@ public class ParseType {
return TypeConverter.convert(datatype);
}
+
+ private static Type toListType(String datatype) {
+ Pattern pattern = Pattern.compile("^list\\((.+)\\)$");
+ Matcher matcher = pattern.matcher(datatype);
+ if (matcher.matches()) {
+ Type elementType = toBasicType(matcher.group(1));
+ return Types.ListType.of(elementType, false);
+ }
+ throw new IllegalArgumentException("Malformed list type: " + datatype);
+ }
+
+ private static Type toMapType(String datatype) {
+ Pattern pattern = Pattern.compile("^map\\((.+),(.+)\\)$");
+ Matcher matcher = pattern.matcher(datatype);
+ if (matcher.matches()) {
+ Type keyType = toBasicType(matcher.group(1));
+ Type valueType = toBasicType(matcher.group(2));
+ return Types.MapType.of(keyType, valueType, false);
+ }
+ throw new IllegalArgumentException("Malformed map type: " + datatype);
+ }
+
+ public static Type toType(String datatype) {
+ if (datatype.startsWith("list")) {
+ return toListType(datatype);
+ } else if (datatype.startsWith("map")) {
+ return toMapType(datatype);
+ }
+
+ // fallback: if not complex type, parse as primitive type
+ return toBasicType(datatype);
+ }
}
diff --git
a/clients/cli/src/test/java/org/apache/gravitino/cli/TestParseType.java
b/clients/cli/src/test/java/org/apache/gravitino/cli/TestParseType.java
index c53d3c2bdc..6c9132dbf4 100644
--- a/clients/cli/src/test/java/org/apache/gravitino/cli/TestParseType.java
+++ b/clients/cli/src/test/java/org/apache/gravitino/cli/TestParseType.java
@@ -19,49 +19,85 @@
package org.apache.gravitino.cli;
+import static org.hamcrest.CoreMatchers.instanceOf;
+import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import org.apache.gravitino.rel.types.Type;
+import org.apache.gravitino.rel.types.Types;
import org.junit.jupiter.api.Test;
public class TestParseType {
@Test
- public void testParseVarcharWithLength() {
- ParsedType parsed = ParseType.parse("varchar(10)");
- assertNotNull(parsed);
- assertEquals("varchar", parsed.getTypeName());
- assertEquals(10, parsed.getLength());
- assertNull(parsed.getScale());
- assertNull(parsed.getPrecision());
+ public void testParseTypeVarcharWithLength() {
+ Type type = ParseType.toType("varchar(10)");
+ assertThat(type, instanceOf(Types.VarCharType.class));
+ assertEquals(10, ((Types.VarCharType) type).length());
}
@Test
- public void testParseDecimalWithPrecisionAndScale() {
- ParsedType parsed = ParseType.parse("decimal(10,5)");
- assertNotNull(parsed);
- assertEquals("decimal", parsed.getTypeName());
- assertEquals(10, parsed.getPrecision());
- assertEquals(5, parsed.getScale());
- assertNull(parsed.getLength());
+ public void testParseTypeDecimalWithPrecisionAndScale() {
+ Type type = ParseType.toType("decimal(10,5)");
+ assertThat(type, instanceOf(Types.DecimalType.class));
+ assertEquals(10, ((Types.DecimalType) type).precision());
+ assertEquals(5, ((Types.DecimalType) type).scale());
}
@Test
- public void testParseIntegerWithoutParameters() {
- ParsedType parsed = ParseType.parse("int()");
- assertNull(parsed); // Expect null because the format is unsupported
+ public void testParseTypeListValidInput() {
+ Type type = ParseType.toType("list(integer)");
+ assertThat(type, instanceOf(Types.ListType.class));
+ Type elementType = ((Types.ListType) type).elementType();
+ assertThat(elementType, instanceOf(Types.IntegerType.class));
}
@Test
- public void testParseOrdinaryInput() {
- assertNull(ParseType.parse("string"));
- assertNull(ParseType.parse("int"));
+ public void testParseTypeListMalformedInput() {
+ assertThrows(IllegalArgumentException.class, () ->
ParseType.toType("list()"));
+ assertThrows(IllegalArgumentException.class, () ->
ParseType.toType("list(10)"));
+ assertThrows(IllegalArgumentException.class, () ->
ParseType.toType("list(unknown)"));
+ assertThrows(IllegalArgumentException.class, () ->
ParseType.toType("list(integer,integer)"));
+ assertThrows(IllegalArgumentException.class, () ->
ParseType.toType("list(integer"));
}
@Test
- public void testParseMalformedInput() {
- assertNull(ParseType.parse("varchar(-10)"));
- assertNull(ParseType.parse("decimal(10,abc)"));
+ public void testParseTypeMapValidInput() {
+ Type type = ParseType.toType("map(string,integer)");
+ assertThat(type, instanceOf(Types.MapType.class));
+ Type keyType = ((Types.MapType) type).keyType();
+ Type valueType = ((Types.MapType) type).valueType();
+ assertThat(keyType, instanceOf(Types.StringType.class));
+ assertThat(valueType, instanceOf(Types.IntegerType.class));
+ }
+
+ @Test
+ public void testParseTypeMapMalformedInput() {
+ assertThrows(IllegalArgumentException.class, () ->
ParseType.toType("map()"));
+ assertThrows(IllegalArgumentException.class, () ->
ParseType.toType("map(10,10)"));
+ assertThrows(IllegalArgumentException.class, () ->
ParseType.toType("map(unknown,unknown)"));
+ assertThrows(IllegalArgumentException.class, () ->
ParseType.toType("map(string)"));
+ assertThrows(
+ IllegalArgumentException.class, () ->
ParseType.toType("map(string,integer,integer)"));
+ assertThrows(IllegalArgumentException.class, () ->
ParseType.toType("map(string,integer"));
+ }
+
+ @Test
+ public void testParseTypeIntegerWithoutParameters() {
+ assertThrows(IllegalArgumentException.class, () ->
ParseType.toType("int()"));
+ }
+
+ @Test
+ public void testParseTypeOrdinaryInput() {
+ assertNull(ParseType.parseBasicType("string"));
+ assertNull(ParseType.parseBasicType("int"));
+ }
+
+ @Test
+ public void testParseTypeMalformedInput() {
+ assertThrows(IllegalArgumentException.class, () ->
ParseType.toType("varchar(-10)"));
+ assertThrows(IllegalArgumentException.class, () ->
ParseType.toType("decimal(10,abc)"));
}
}