Skip to content

Commit

Permalink
Clean up merge conflicts
Browse files Browse the repository at this point in the history
Signed-off-by: Andrew Carbonetto <[email protected]>
  • Loading branch information
acarbonetto committed Jan 17, 2025
1 parent e8b6df3 commit ab9be75
Show file tree
Hide file tree
Showing 7 changed files with 59 additions and 39 deletions.
8 changes: 4 additions & 4 deletions core/src/main/java/org/opensearch/sql/expression/DSL.java
Original file line number Diff line number Diff line change
Expand Up @@ -687,6 +687,10 @@ public static FunctionExpression jsonValid(Expression... expressions) {
return compile(FunctionProperties.None, BuiltinFunctionName.JSON_VALID, expressions);
}

public static FunctionExpression stringToJson(Expression value) {
return compile(FunctionProperties.None, BuiltinFunctionName.JSON, value);
}

public static Aggregator avg(Expression... expressions) {
return aggregate(BuiltinFunctionName.AVG, expressions);
}
Expand Down Expand Up @@ -977,10 +981,6 @@ public static FunctionExpression utc_timestamp(
return compile(functionProperties, BuiltinFunctionName.UTC_TIMESTAMP, args);
}

public static FunctionExpression json_function(Expression value) {
return compile(FunctionProperties.None, BuiltinFunctionName.JSON, value);
}

@SuppressWarnings("unchecked")
private static <T extends FunctionImplementation> T compile(
FunctionProperties functionProperties, BuiltinFunctionName bfn, Expression... args) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,6 @@

package org.opensearch.sql.expression.json;

import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.experimental.UtilityClass;
import org.opensearch.sql.expression.function.BuiltinFunctionName;
import org.opensearch.sql.expression.function.BuiltinFunctionRepository;
import org.opensearch.sql.expression.function.DefaultFunctionResolver;

import static org.opensearch.sql.data.type.ExprCoreType.BOOLEAN;
import static org.opensearch.sql.data.type.ExprCoreType.STRING;
import static org.opensearch.sql.data.type.ExprCoreType.UNDEFINED;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,8 +92,9 @@ private static DefaultFunctionResolver castToByte() {
STRING),
impl(nullMissingHandling((v) -> new ExprByteValue(v.byteValue())), BYTE, DOUBLE),
impl(
nullMissingHandling((v) -> new ExprByteValue(v.booleanValue() ? 1 : 0)), BYTE, BOOLEAN),
impl(nullMissingHandling((v) -> v), BYTE, UNDEFINED));
nullMissingHandling((v) -> new ExprByteValue(v.booleanValue() ? 1 : 0)),
BYTE,
BOOLEAN));
}

private static DefaultFunctionResolver castToShort() {
Expand Down
20 changes: 18 additions & 2 deletions core/src/main/java/org/opensearch/sql/utils/JsonUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,11 @@
import java.util.List;
import java.util.Map;
import lombok.experimental.UtilityClass;
import org.opensearch.sql.data.model.ExprBooleanValue;
import org.opensearch.sql.data.model.ExprCollectionValue;
import org.opensearch.sql.data.model.ExprDoubleValue;
import org.opensearch.sql.data.model.ExprIntegerValue;
import org.opensearch.sql.data.model.ExprNullValue;
import org.opensearch.sql.data.model.ExprStringValue;
import org.opensearch.sql.data.model.ExprTupleValue;
import org.opensearch.sql.data.model.ExprValue;
Expand All @@ -27,7 +29,7 @@ public class JsonUtils {
* Checks if given JSON string can be parsed as valid JSON.
*
* @param jsonExprValue JSON string (e.g. "{\"hello\": \"world\"}").
* @return true if the string can be parsed as valid JSON, else false.
* @return true if the string can be parsed as valid JSON, else false (including null or missing).
*/
public static ExprValue isValidJson(ExprValue jsonExprValue) {
ObjectMapper objectMapper = new ObjectMapper();
Expand All @@ -44,7 +46,21 @@ public static ExprValue isValidJson(ExprValue jsonExprValue) {
}
}

/** Converts a JSON encoded string to an Expression object. */
/**
* Converts a JSON encoded string to a {@link ExprValue}. Expression type will be UNDEFINED.
*
* @param json JSON string (e.g. "{\"hello\": \"world\"}").
* @return ExprValue returns an expression that best represents the provided JSON-encoded string.
* <ol>
* <li>{@link ExprTupleValue} if the JSON is an object
* <li>{@link ExprCollectionValue} if the JSON is an array
* <li>{@link ExprDoubleValue} if the JSON is a floating-point number scalar
* <li>{@link ExprIntegerValue} if the JSON is an integral number scalar
* <li>{@link ExprStringValue} if the JSON is a string scalar
* <li>{@link ExprBooleanValue} if the JSON is a boolean scalar
* <li>{@link ExprNullValue} if the JSON is null, empty, or invalid
* </ol>
*/
public static ExprValue castJson(ExprValue json) {
ObjectMapper objectMapper = new ObjectMapper();
JsonNode jsonNode;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,8 @@ public void json_valid_returns_false() {
@Test
public void json_valid_throws_ExpressionEvaluationException() {
assertThrows(
ExpressionEvaluationException.class, () -> execute(ExprValueUtils.booleanValue(true)));

// caught by nullMissingHandling and returns null
assertEquals(LITERAL_NULL, execute(LITERAL_NULL));
ExpressionEvaluationException.class,
() -> DSL.jsonValid(DSL.literal((ExprValueUtils.booleanValue(true)))).valueOf());
}

@Test
Expand Down Expand Up @@ -115,12 +113,16 @@ void json_returnsJsonObject() {
ExprValue expectedTupleExpr = ExprTupleValue.fromExprValueMap(objectMap);

// exercise
exp = DSL.json_function(DSL.literal(objectJson));
exp = DSL.stringToJson(DSL.literal(objectJson));

// Verify
var value = exp.valueOf();
assertTrue(value instanceof ExprTupleValue);
assertEquals(expectedTupleExpr, value);

// also test the empty object case
assertEquals(
ExprTupleValue.fromExprValueMap(Map.of()), DSL.stringToJson(DSL.literal("{}")).valueOf());
}

@Test
Expand All @@ -141,35 +143,35 @@ void json_returnsJsonArray() {
LITERAL_NULL));

// exercise
exp = DSL.json_function(DSL.literal(arrayJson));
exp = DSL.stringToJson(DSL.literal(arrayJson));

// Verify
var value = exp.valueOf();
assertTrue(value instanceof ExprCollectionValue);
assertEquals(expectedArrayExpr, value);

// also test the empty-array case
assertEquals(new ExprCollectionValue(List.of()), DSL.stringToJson(DSL.literal("[]")).valueOf());
}

@Test
void json_returnsScalar() {
assertEquals(
new ExprStringValue("foobar"), DSL.json_function(DSL.literal("\"foobar\"")).valueOf());

assertEquals(new ExprIntegerValue(1234), DSL.json_function(DSL.literal("1234")).valueOf());
new ExprStringValue("foobar"), DSL.stringToJson(DSL.literal("\"foobar\"")).valueOf());

assertEquals(new ExprDoubleValue(12.34), DSL.json_function(DSL.literal("12.34")).valueOf());
assertEquals(new ExprIntegerValue(1234), DSL.stringToJson(DSL.literal("1234")).valueOf());

assertEquals(LITERAL_TRUE, DSL.json_function(DSL.literal("true")).valueOf());
assertEquals(new ExprDoubleValue(12.34), DSL.stringToJson(DSL.literal("12.34")).valueOf());

assertEquals(LITERAL_NULL, DSL.json_function(DSL.literal("null")).valueOf());
assertEquals(LITERAL_TRUE, DSL.stringToJson(DSL.literal("true")).valueOf());

assertEquals(LITERAL_NULL, DSL.json_function(DSL.literal(LITERAL_NULL)).valueOf());
assertEquals(LITERAL_NULL, DSL.stringToJson(DSL.literal("null")).valueOf());

assertEquals(LITERAL_MISSING, DSL.json_function(DSL.literal(LITERAL_MISSING)).valueOf());
assertEquals(LITERAL_NULL, DSL.stringToJson(DSL.literal(LITERAL_NULL)).valueOf());

assertEquals(LITERAL_NULL, DSL.json_function(DSL.literal("")).valueOf());
assertEquals(LITERAL_MISSING, DSL.stringToJson(DSL.literal(LITERAL_MISSING)).valueOf());

assertEquals(
ExprTupleValue.fromExprValueMap(Map.of()), DSL.json_function(DSL.literal("{}")).valueOf());
assertEquals(LITERAL_NULL, DSL.stringToJson(DSL.literal("")).valueOf());
}

@Test
Expand All @@ -181,7 +183,7 @@ void json_returnsSemanticCheckException() {
// missing bracket
assertThrows(SemanticCheckException.class, () -> DSL.castJson(DSL.literal("{{[}}")).valueOf());

// mnissing quote
// missing quote
assertThrows(
SemanticCheckException.class, () -> DSL.castJson(DSL.literal("\"missing quote")).valueOf());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -312,7 +312,7 @@ void castBooleanToDouble() {
void castUndefinedToDouble() {
Double value = 23.45e5;
// json cast is an UNDEFINED type expression
FunctionExpression expression = DSL.castDouble(DSL.castJson(DSL.literal(value)));
FunctionExpression expression = DSL.castDouble(DSL.castJson(DSL.literal(value.toString())));
assertEquals(DOUBLE, expression.type());
assertEquals(new ExprDoubleValue(value), expression.valueOf());
}
Expand Down Expand Up @@ -480,6 +480,10 @@ void castJson_returnsJsonObject() {
var value = exp.valueOf();
assertTrue(value instanceof ExprTupleValue);
assertEquals(expectedTupleExpr, value);

// also test the empty-object case
assertEquals(
ExprTupleValue.fromExprValueMap(Map.of()), DSL.castJson(DSL.literal("{}")).valueOf());
}

@Test
Expand All @@ -506,6 +510,9 @@ void castJson_returnsJsonArray() {
var value = exp.valueOf();
assertTrue(value instanceof ExprCollectionValue);
assertEquals(expectedArrayExpr, value);

// also test the empty-array case
assertEquals(new ExprCollectionValue(List.of()), DSL.castJson(DSL.literal("[]")).valueOf());
}

@Test
Expand All @@ -525,11 +532,6 @@ void castJson_returnsScalar() {

String empty = "";
assertEquals(LITERAL_NULL, DSL.castJson(DSL.literal(empty)).valueOf());

String emptyObject = "{}";
assertEquals(
ExprTupleValue.fromExprValueMap(Map.of()),
DSL.castJson(DSL.literal(emptyObject)).valueOf());
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,11 @@ public void test_json_valid() throws IOException {
rows("json object"),
rows("json array"),
rows("json scalar string"),
rows("json scalar int"),
rows("json scalar float"),
rows("json scalar double"),
rows("json scalar boolean true"),
rows("json scalar boolean false"),
rows("json empty string"));
}

Expand Down Expand Up @@ -102,7 +107,7 @@ public void test_json() throws IOException {
rows("json array", new JSONArray(List.of(1, 2, 3, 4))),
rows("json scalar string", "abc"),
rows("json scalar int", 1234),
rows("json scalar long", 42),
rows("json scalar float", 12.34),
rows("json scalar double", 2.99792458e8),
rows("json scalar boolean true", true),
rows("json scalar boolean false", false),
Expand Down

0 comments on commit ab9be75

Please sign in to comment.