Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ private static boolean isScalarObject(Object obj) {

private static String doJsonize(Object candidate) {
if (candidate == null) {
return "null"; // Matches isScalarObject, but not toString-able.
return null;
} else if (isScalarObject(candidate)) {
return candidate.toString();
} else {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/

package org.opensearch.sql.expression.function.jsonUDF;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNull;

import org.junit.jupiter.api.Test;

public class JsonExtractFunctionImplTest {

@Test
public void testMissingPathReturnsNull() {
Object result = JsonExtractFunctionImpl.eval("{}", "name");
assertNull(result, "Missing path should return actual null, not string \"null\"");
}

@Test
public void testExplicitNullValueReturnsNull() {
Object result = JsonExtractFunctionImpl.eval("{\"name\": null}", "name");
assertNull(result, "Explicit JSON null value should return actual null, not string \"null\"");
}

@Test
public void testNoArgsReturnsNull() {
assertNull(JsonExtractFunctionImpl.eval());
}

@Test
public void testSingleArgReturnsNull() {
assertNull(JsonExtractFunctionImpl.eval("{}"));
}

@Test
public void testExtractStringValue() {
Object result = JsonExtractFunctionImpl.eval("{\"name\": \"John\"}", "name");
assertEquals("John", result);
}

@Test
public void testExtractNumericValue() {
Object result = JsonExtractFunctionImpl.eval("{\"age\": 30}", "age");
assertEquals("30", result);
}

@Test
public void testExtractNestedObject() {
Object result =
JsonExtractFunctionImpl.eval("{\"user\": {\"name\": \"John\"}}", "user");
assertEquals("{\"name\":\"John\"}", result);
}

@Test
public void testExtractArray() {
Object result = JsonExtractFunctionImpl.eval("{\"items\": [1, 2, 3]}", "items");
assertEquals("[1,2,3]", result);
}

@Test
public void testExtractBooleanValue() {
Object result = JsonExtractFunctionImpl.eval("{\"active\": true}", "active");
assertEquals("true", result);
}

@Test
public void testMultiPathWithMissingPath() {
Object result = JsonExtractFunctionImpl.eval("{\"name\": \"John\"}", "name", "age");
assertEquals("[\"John\",null]", result);
}

@Test
public void testMultiPathAllMissing() {
Object result = JsonExtractFunctionImpl.eval("{}", "name", "age");
assertEquals("[null,null]", result);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,36 @@ public void testJsonExtractWithMultiplyResult() throws IOException {
verifyDataRows(actual, rows("[[\"Bridge of Sighs\",\"Ponte della Paglia\"],8981.0]"));
}

@Test
public void testJsonExtractReturnsNullForMissingPathAndNullValue() throws IOException {
JSONObject actual =
executeQuery(
String.format(
"source=%s | head 1 | eval a = json_extract('{}', 'name'),"
+ " b = json_extract('{\\\"name\\\": null}', 'name')"
+ " | fields a, b | head 1",
TEST_INDEX_PEOPLE2));

verifySchema(actual, schema("a", "string"), schema("b", "string"));

verifyDataRows(actual, rows(null, null));
}

@Test
public void testJsonExtractMultiPathWithMissingPath() throws IOException {
JSONObject actual =
executeQuery(
String.format(
"source=%s | head 1 | eval a = json_extract('{\\\"name\\\": \\\"John\\\"}',"
+ " 'name', 'age')"
+ " | fields a | head 1",
TEST_INDEX_PEOPLE2));

verifySchema(actual, schema("a", "string"));

verifyDataRows(actual, rows("[\"John\",null]"));
}

@Test
public void testJsonKeys() throws IOException {
JSONObject actual =
Expand Down