Skip to content

Commit 15aeec7

Browse files
authored
Support UDT for BINARY (#3549)
--------- Signed-off-by: Heng Qian <[email protected]>
1 parent 3c1591a commit 15aeec7

File tree

8 files changed

+72
-45
lines changed

8 files changed

+72
-45
lines changed
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
/*
2+
* Copyright OpenSearch Contributors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
package org.opensearch.sql.calcite.type;
7+
8+
import org.apache.calcite.sql.type.SqlTypeName;
9+
import org.opensearch.sql.calcite.utils.OpenSearchTypeFactory;
10+
import org.opensearch.sql.calcite.utils.OpenSearchTypeFactory.ExprUDT;
11+
12+
public class ExprBinaryType extends ExprSqlType {
13+
public ExprBinaryType(OpenSearchTypeFactory typeFactory) {
14+
super(typeFactory, ExprUDT.EXPR_BINARY, SqlTypeName.VARCHAR);
15+
}
16+
}

core/src/main/java/org/opensearch/sql/calcite/utils/OpenSearchTypeFactory.java

Lines changed: 9 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
package org.opensearch.sql.calcite.utils;
77

88
import static org.opensearch.sql.data.type.ExprCoreType.ARRAY;
9+
import static org.opensearch.sql.data.type.ExprCoreType.BINARY;
910
import static org.opensearch.sql.data.type.ExprCoreType.BOOLEAN;
1011
import static org.opensearch.sql.data.type.ExprCoreType.BYTE;
1112
import static org.opensearch.sql.data.type.ExprCoreType.DATE;
@@ -41,6 +42,7 @@
4142
import org.apache.calcite.sql.type.SqlTypeName;
4243
import org.apache.calcite.sql.type.SqlTypeUtil;
4344
import org.opensearch.sql.calcite.type.AbstractExprRelDataType;
45+
import org.opensearch.sql.calcite.type.ExprBinaryType;
4446
import org.opensearch.sql.calcite.type.ExprDateType;
4547
import org.opensearch.sql.calcite.type.ExprIPType;
4648
import org.opensearch.sql.calcite.type.ExprTimeStampType;
@@ -67,6 +69,7 @@ public enum ExprUDT {
6769
EXPR_DATE(DATE),
6870
EXPR_TIME(TIME),
6971
EXPR_TIMESTAMP(TIMESTAMP),
72+
EXPR_BINARY(BINARY),
7073
EXPR_IP(IP);
7174

7275
// Associated `ExprCoreType`
@@ -120,6 +123,8 @@ public RelDataType createUDT(ExprUDT typeName) {
120123
yield new ExprTimeType(this);
121124
case EXPR_TIMESTAMP:
122125
yield new ExprTimeStampType(this);
126+
case EXPR_BINARY:
127+
yield new ExprBinaryType(this);
123128
case EXPR_IP:
124129
yield new ExprIPType(this);
125130
};
@@ -180,7 +185,7 @@ public static RelDataType convertExprTypeToRelDataType(ExprType fieldType, boole
180185
}
181186
} else {
182187
if (fieldType.legacyTypeName().equalsIgnoreCase("binary")) {
183-
return TYPE_FACTORY.createSqlType(SqlTypeName.BINARY, nullable);
188+
return TYPE_FACTORY.createUDT(ExprUDT.EXPR_BINARY, nullable);
184189
} else if (fieldType.legacyTypeName().equalsIgnoreCase("timestamp")) {
185190
return TYPE_FACTORY.createUDT(ExprUDT.EXPR_TIMESTAMP, nullable);
186191
} else if (fieldType.legacyTypeName().equalsIgnoreCase("date")) {
@@ -243,20 +248,9 @@ public static ExprType convertSqlTypeNameToExprType(SqlTypeName sqlTypeName) {
243248

244249
/** Get legacy name for a RelDataType. */
245250
public static String getLegacyTypeName(RelDataType relDataType, QueryType queryType) {
246-
if (relDataType instanceof AbstractExprRelDataType<?> udt) {
247-
return udt.getExprType().legacyTypeName();
248-
}
249-
switch (relDataType.getSqlTypeName()) {
250-
case BINARY:
251-
case VARBINARY:
252-
return "BINARY";
253-
case GEOMETRY:
254-
return "GEO_POINT";
255-
default:
256-
ExprType type = convertSqlTypeNameToExprType(relDataType.getSqlTypeName());
257-
return (queryType == PPL ? PPL_SPEC.typeName(type) : type.legacyTypeName())
258-
.toUpperCase(Locale.ROOT);
259-
}
251+
ExprType type = convertRelDataTypeToExprType(relDataType);
252+
return (queryType == PPL ? PPL_SPEC.typeName(type) : type.legacyTypeName())
253+
.toUpperCase(Locale.ROOT);
260254
}
261255

262256
/** Converts a Calcite data type to OpenSearch ExprCoreType. */

core/src/main/java/org/opensearch/sql/data/type/ExprCoreType.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@ public enum ExprCoreType implements ExprType {
5151
/** Geometry. Only support point now. */
5252
GEO_POINT(UNDEFINED),
5353

54+
BINARY(UNDEFINED),
55+
5456
/** Struct. */
5557
STRUCT(UNDEFINED),
5658

core/src/test/java/org/opensearch/sql/analysis/AnalyzerTest.java

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -161,12 +161,7 @@ public void filter_relation_with_invalid_qualifiedName_ExpressionEvaluationExcep
161161

162162
ExpressionEvaluationException exception =
163163
assertThrows(ExpressionEvaluationException.class, () -> analyze(typeMismatchPlan));
164-
assertEquals(
165-
"= function expected {[BYTE,BYTE],[SHORT,SHORT],[INTEGER,INTEGER],[LONG,LONG],"
166-
+ "[FLOAT,FLOAT],[DOUBLE,DOUBLE],[STRING,STRING],[BOOLEAN,BOOLEAN],[DATE,DATE],"
167-
+ "[TIME,TIME],[TIMESTAMP,TIMESTAMP],[INTERVAL,INTERVAL],[IP,IP],[GEO_POINT,GEO_POINT],"
168-
+ "[STRUCT,STRUCT],[ARRAY,ARRAY]}, but got [STRING,INTEGER]",
169-
exception.getMessage());
164+
assertEquals(getIncompatibleTypeErrMsg(STRING, INTEGER), exception.getMessage());
170165
}
171166

172167
@Test

core/src/test/java/org/opensearch/sql/analysis/AnalyzerTestBase.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import org.opensearch.sql.analysis.symbol.SymbolTable;
2727
import org.opensearch.sql.ast.tree.UnresolvedPlan;
2828
import org.opensearch.sql.config.TestConfig;
29+
import org.opensearch.sql.data.type.ExprCoreType;
2930
import org.opensearch.sql.data.type.ExprType;
3031
import org.opensearch.sql.datasource.DataSourceService;
3132
import org.opensearch.sql.datasource.RequestContext;
@@ -274,4 +275,14 @@ public Table applyArguments() {
274275
return table;
275276
}
276277
}
278+
279+
public static String getIncompatibleTypeErrMsg(ExprType lType, ExprType rType) {
280+
return String.format(
281+
"= function expected %s, but got [%s,%s]",
282+
ExprCoreType.coreTypes().stream()
283+
.map(type -> String.format("[%s,%s]", type.typeName(), type.typeName()))
284+
.collect(Collectors.joining(",", "{", "}")),
285+
lType,
286+
rType);
287+
}
277288
}

integ-test/src/test/java/org/opensearch/sql/calcite/remote/CalciteDataTypeIT.java

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55

66
package org.opensearch.sql.calcite.remote;
77

8-
import java.io.IOException;
98
import org.opensearch.sql.ppl.DataTypeIT;
109

1110
public class CalciteDataTypeIT extends DataTypeIT {
@@ -15,17 +14,4 @@ public void init() throws Exception {
1514
enableCalcite();
1615
disallowCalciteFallback();
1716
}
18-
19-
@Override
20-
public void test_nonnumeric_data_types() throws IOException {
21-
withFallbackEnabled(
22-
() -> {
23-
try {
24-
super.test_nonnumeric_data_types();
25-
} catch (IOException e) {
26-
throw new RuntimeException(e);
27-
}
28-
},
29-
"ignore this class since IP type is unsupported in calcite engine");
30-
}
3117
}

integ-test/src/test/java/org/opensearch/sql/ppl/DataTypeIT.java

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,12 @@
1414
import static org.opensearch.sql.util.MatcherUtils.rows;
1515
import static org.opensearch.sql.util.MatcherUtils.schema;
1616
import static org.opensearch.sql.util.MatcherUtils.verifyDataRows;
17+
import static org.opensearch.sql.util.MatcherUtils.verifyDataRowsInOrder;
1718
import static org.opensearch.sql.util.MatcherUtils.verifySchema;
19+
import static org.opensearch.sql.util.MatcherUtils.verifySchemaInOrder;
1820

1921
import java.io.IOException;
22+
import org.json.JSONArray;
2023
import org.json.JSONObject;
2124
import org.junit.Test;
2225

@@ -48,18 +51,33 @@ public void test_numeric_data_types() throws IOException {
4851
@Test
4952
public void test_nonnumeric_data_types() throws IOException {
5053
JSONObject result = executeQuery(String.format("source=%s", TEST_INDEX_DATATYPE_NONNUMERIC));
51-
verifySchema(
54+
verifySchemaInOrder(
5255
result,
53-
schema("boolean_value", "boolean"),
54-
schema("keyword_value", "string"),
5556
schema("text_value", "string"),
56-
schema("binary_value", "binary"),
57-
schema("date_value", "timestamp"),
5857
schema("date_nanos_value", "timestamp"),
58+
schema("date_value", "timestamp"),
59+
schema("boolean_value", "boolean"),
5960
schema("ip_value", "ip"),
60-
schema("object_value", "struct"),
6161
schema("nested_value", "array"),
62-
schema("geo_point_value", "geo_point"));
62+
schema("object_value", "struct"),
63+
schema("keyword_value", "string"),
64+
schema("geo_point_value", "geo_point"),
65+
schema("binary_value", "binary"));
66+
verifyDataRowsInOrder(
67+
result,
68+
rows(
69+
"text",
70+
"2019-03-24 01:34:46.123456789",
71+
"2020-10-13 13:00:00",
72+
true,
73+
"127.0.0.1",
74+
new JSONArray(
75+
"[{\"last\": \"Smith\", \"first\": \"John\"}, {\"last\": \"White\", \"first\":"
76+
+ " \"Alice\"}]"),
77+
new JSONObject("{\"last\": \"Dale\", \"first\": \"Dale\"}"),
78+
"keyword",
79+
new JSONObject("{\"lon\": 74, \"lat\": 40.71}"),
80+
"U29tZSBiaW5hcnkgYmxvYg=="));
6381
}
6482

6583
@Test

integ-test/src/test/java/org/opensearch/sql/ppl/WhereCommandIT.java

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,11 @@
1212
import static org.opensearch.sql.util.MatcherUtils.verifyDataRows;
1313

1414
import java.io.IOException;
15+
import java.util.stream.Collectors;
1516
import org.hamcrest.MatcherAssert;
1617
import org.json.JSONObject;
1718
import org.junit.jupiter.api.Test;
19+
import org.opensearch.sql.data.type.ExprCoreType;
1820

1921
public class WhereCommandIT extends PPLIntegTestCase {
2022

@@ -175,8 +177,11 @@ public void testInWithIncompatibleType() {
175177
}
176178

177179
protected String getIncompatibleTypeErrMsg() {
178-
return "function expected"
179-
+ " {[BYTE,BYTE],[SHORT,SHORT],[INTEGER,INTEGER],[LONG,LONG],[FLOAT,FLOAT],[DOUBLE,DOUBLE],[STRING,STRING],[BOOLEAN,BOOLEAN],[DATE,DATE],[TIME,TIME],[TIMESTAMP,TIMESTAMP],[INTERVAL,INTERVAL],[IP,IP],[GEO_POINT,GEO_POINT],[STRUCT,STRUCT],[ARRAY,ARRAY]},"
180-
+ " but got [LONG,STRING]";
180+
return String.format(
181+
"function expected %s, but got %s",
182+
ExprCoreType.coreTypes().stream()
183+
.map(type -> String.format("[%s,%s]", type.typeName(), type.typeName()))
184+
.collect(Collectors.joining(",", "{", "}")),
185+
"[LONG,STRING]");
181186
}
182187
}

0 commit comments

Comments
 (0)