generated from amazon-archives/__template_Custom
-
Notifications
You must be signed in to change notification settings - Fork 181
Feature: PPL - json_set function #3271
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Closed
andy-k-improving
wants to merge
97
commits into
opensearch-project:main
from
Bit-Quill:ft-ak-json-set
Closed
Changes from all commits
Commits
Show all changes
97 commits
Select commit
Hold shift + click to select a range
70152eb
added implementation
14yapkc1 76c3995
added doctest, integ-tests, and unit tests
14yapkc1 ce2c551
addressed PR comments
kenrickyap ad1bde3
fixed unit tests
kenrickyap ccf47a2
addressed pr comments
kenrickyap acc76a0
addressed PR comments
kenrickyap 519c6f2
removed unused dependencies
kenrickyap 2e319fe
linting
kenrickyap ee0820d
addressed pr comment and rolling back disabled test case
kenrickyap d44fc5a
Merge branch 'main' into feature/json-valid
kenrickyap 3407d4a
removed disabled import
kenrickyap 7ef6cc9
Update docs/user/ppl/functions/json.rst
kenrickyap e5e90ac
Update integ-test/src/test/java/org/opensearch/sql/ppl/JsonFunctionIT…
kenrickyap 2187a5a
nit
kenrickyap 5e1e488
Merge branch 'feature/json-valid' of https://github.com/Bit-Quill/ope…
kenrickyap 3512b33
fixed integ test
kenrickyap 9fea606
change text type to keyword
kenrickyap fbc54bc
addressed PR comments
kenrickyap 31ad2a4
fix doc-test
kenrickyap 2b2a8f3
added null test
kenrickyap dc96563
Merge branch 'main' into feature/json-valid
acarbonetto 1913bfe
SQL: adding error case unit tests for json_valid
acarbonetto 67d979d
json_valid: null and missing should return false
acarbonetto aa6b723
PPL: Add json and cast to json functions
acarbonetto 4c99235
PPL: Update json cast for review
acarbonetto 9ccde7f
Fix testes
acarbonetto 4306bf3
spotless
acarbonetto 613137b
Fix tests
acarbonetto ab28872
SPOTLESS
acarbonetto 3ec16e0
Clean up for merge
acarbonetto 6dbf37b
added implementation
14yapkc1 b8c6d68
added doctest, integ-tests, and unit tests
14yapkc1 afb668c
addressed pr comments
kenrickyap 54ef183
addressed PR comments
kenrickyap d841394
removed unused dependencies
kenrickyap 25fb527
linting
kenrickyap 4a20d08
addressed pr comment and rolling back disabled test case
kenrickyap fdc4729
removed disabled import
kenrickyap 707a0b9
nit
kenrickyap 4f28211
Update integ-test/src/test/java/org/opensearch/sql/ppl/JsonFunctionIT…
kenrickyap 9ec6335
fixed integ test
kenrickyap 3324e66
SQL: adding error case unit tests for json_valid
acarbonetto 7123c35
json_valid: null and missing should return false
acarbonetto dbca991
PPL: Add json and cast to json functions
acarbonetto 7df87cb
PPL: Update json cast for review
acarbonetto cd45fcc
Fix testes
acarbonetto 6f5dc07
spotless
acarbonetto 0aae36e
Fix tests
acarbonetto b225f28
SPOTLESS
acarbonetto 78af4f8
Clean up for merge
acarbonetto b84282a
clean up unit tests
acarbonetto 1e23286
Add casting from undefined
acarbonetto 343f5a2
Add cast to scalar from undefined expression
acarbonetto e8b6df3
Add test for missing/null
acarbonetto ab9be75
Clean up merge conflicts
acarbonetto 788be9d
Fix jacoco coverage
acarbonetto a9721bf
Move to Switch by json type
acarbonetto daa95ff
Merge branch 'main' into feature/acarbo_json_cast_ppl
acarbonetto 018e462
functionality implemented
kenrickyap c6c6cc1
Remove conflicted files
acarbonetto a5652ea
Add doctext row
acarbonetto 2cd10a2
added integ-test and doc test
kenrickyap cd78ddd
fixed integ tests
kenrickyap afb385f
unit tests
kenrickyap 0e91b2e
Merge branch 'main' into feature/json-extract
kenrickyap 794db8a
finnished unit tests
kenrickyap 0f0b8d4
update doctest
kenrickyap f030057
addessed comments
kenrickyap 2b08007
added addition edge cases for unit tests
kenrickyap be52786
Merge branch 'feature/acarbo_json_cast_ppl' into feature/json-extract
kenrickyap 6bd2f40
Merge branch 'feature/acarbo_json_cast_ppl' into feature/json-extract
kenrickyap 0b9e9e4
Merge branch 'feature/json-extract' of https://github.com/Bit-Quill/o…
kenrickyap 6678be4
addressed PR comments
kenrickyap e57fa21
fix code coverage
14yapkc1 112be65
Update core/src/test/java/org/opensearch/sql/expression/json/JsonFunc…
kenrickyap 306ac97
address comments
kenrickyap 75e9cc3
fix build error
kenrickyap 77827bb
Merge branch 'main' into feature/json-extract
kenrickyap 80f44e2
add header
kenrickyap 0d1cc28
addressing PR comments
kenrickyap b6ae5ba
added multi path use case
kenrickyap adde88d
Merge branch 'main' into feature/json-extract
kenrickyap aa8b81e
linting
kenrickyap ec6ff5e
fixing doc tests
kenrickyap 95e996b
Update core/src/main/java/org/opensearch/sql/utils/JsonUtils.java
kenrickyap 527415e
Update jsonSet
andy-k-improving aefa9cb
Provide primitive support
andy-k-improving 3fabe17
Manual test
andy-k-improving 46183d9
IT tests
andy-k-improving afd7a31
IT test
andy-k-improving 6daca82
Code review
andy-k-improving b1cb3aa
Fix doc test
andy-k-improving 741322a
Update supported types
andy-k-improving 8d26f6b
Code comments
andy-k-improving c5b4da6
Update the test-case
andy-k-improving b44d1a1
Rebase
andy-k-improving 85c23f9
Code style
andy-k-improving File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -12,6 +12,14 @@ | |
| import com.fasterxml.jackson.core.JsonProcessingException; | ||
| import com.fasterxml.jackson.databind.JsonNode; | ||
| import com.fasterxml.jackson.databind.ObjectMapper; | ||
| import com.jayway.jsonpath.Configuration; | ||
| import com.jayway.jsonpath.DocumentContext; | ||
| import com.jayway.jsonpath.InvalidJsonException; | ||
| import com.jayway.jsonpath.InvalidPathException; | ||
| import com.jayway.jsonpath.JsonPath; | ||
| import com.jayway.jsonpath.Option; | ||
| import com.jayway.jsonpath.PathNotFoundException; | ||
| import java.util.ArrayList; | ||
| import java.util.LinkedHashMap; | ||
| import java.util.LinkedList; | ||
| import java.util.List; | ||
|
|
@@ -79,6 +87,58 @@ public static ExprValue castJson(ExprValue json) { | |
| return processJsonNode(jsonNode); | ||
| } | ||
|
|
||
| /** | ||
| * Extract value of JSON string at given JSON path. | ||
| * | ||
| * @param json JSON string (e.g. "{\"hello\": \"world\"}"). | ||
| * @param paths list of JSON path (e.g. "$.hello") | ||
| * @return ExprValue of value at given path of json string. | ||
| */ | ||
| public static ExprValue extractJson(ExprValue json, ExprValue... paths) { | ||
| List<ExprValue> resultList = new ArrayList<>(); | ||
|
|
||
| for (ExprValue path : paths) { | ||
| System.out.println("Processing path: " + path); | ||
| if (json.isNull() || json.isMissing()) { | ||
| return json; | ||
| } | ||
|
|
||
| String jsonString = json.stringValue(); | ||
| String jsonPath = path.stringValue(); | ||
|
|
||
| resultList.add(extractJsonPath(jsonString, jsonPath)); | ||
| } | ||
|
|
||
| if (resultList.size() == 1) { | ||
| return resultList.getFirst(); | ||
| } else { | ||
| return new ExprCollectionValue(resultList); | ||
| } | ||
| } | ||
|
|
||
| private static ExprValue extractJsonPath(String json, String path) { | ||
| if (json.isEmpty() || json.equals("null")) { | ||
| return LITERAL_NULL; | ||
| } | ||
|
|
||
| try { | ||
| Object results = JsonPath.parse(json).read(path); | ||
| return ExprValueUtils.fromObjectValue(results); | ||
| } catch (PathNotFoundException ignored) { | ||
| return LITERAL_NULL; | ||
| } catch (InvalidPathException invalidPathException) { | ||
| final String errorFormat = "JSON path '%s' is not valid. Error details: %s"; | ||
| throw new SemanticCheckException( | ||
| String.format(errorFormat, path, invalidPathException.getMessage()), | ||
| invalidPathException); | ||
| } catch (InvalidJsonException invalidJsonException) { | ||
| final String errorFormat = "JSON string '%s' is not valid. Error details: %s"; | ||
| throw new SemanticCheckException( | ||
| String.format(errorFormat, json, invalidJsonException.getMessage()), | ||
| invalidJsonException); | ||
| } | ||
| } | ||
|
|
||
| private static ExprValue processJsonNode(JsonNode jsonNode) { | ||
| switch (jsonNode.getNodeType()) { | ||
| case ARRAY: | ||
|
|
@@ -109,4 +169,60 @@ private static ExprValue processJsonNode(JsonNode jsonNode) { | |
| return LITERAL_NULL; | ||
| } | ||
| } | ||
|
|
||
| /** | ||
| * Perform an upsert operation against the incoming jsonString value with provided jsonPath and | ||
| * value. | ||
| * | ||
| * @param json jsonObject in String format. | ||
| * @param path upsert reference in the form of JsonPath. | ||
| * @param valueToInsert value to be added | ||
| * @return JsonString after the upsert operation. | ||
| */ | ||
| public static ExprValue setJson(ExprValue json, ExprValue path, ExprValue valueToInsert) { | ||
andy-k-improving marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| String jsonString = json.stringValue(); | ||
| String jsonPathString = path.stringValue(); | ||
| Object valueToInsertObj = valueToInsert.value(); | ||
| Configuration conf = | ||
| Configuration.defaultConfiguration().addOptions(Option.SUPPRESS_EXCEPTIONS); | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why suppress? |
||
| try { | ||
| JsonPath jsonPath = JsonPath.compile(jsonPathString); | ||
| DocumentContext docContext = JsonPath.using(conf).parse(jsonString); | ||
| Object readResult = docContext.read(jsonPath); | ||
| if (readResult == null) { | ||
| recursiveCreate(docContext, jsonPathString, valueToInsertObj); | ||
| } else { | ||
| docContext.set(jsonPathString, valueToInsertObj); | ||
| } | ||
| return new ExprStringValue(docContext.jsonString()); | ||
|
|
||
| } catch (InvalidPathException e) { | ||
| final String errorFormat = "JSON path '%s' is not valid. Error details: %s"; | ||
| throw new SemanticCheckException(String.format(errorFormat, path, e.getMessage()), e); | ||
|
|
||
| } catch (InvalidJsonException e) { | ||
| final String errorFormat = "JSON object '%s' is not valid. Error details: %s"; | ||
| throw new SemanticCheckException(String.format(errorFormat, json, e.getMessage()), e); | ||
| } | ||
| } | ||
|
|
||
| /** | ||
| * Helper method to handle recursive scenario. | ||
| * | ||
| * @param docContext incoming Json in Java object form. | ||
| * @param path path in String to perform insertion. | ||
| * @param value value to be inserted with given path. | ||
| */ | ||
| private static DocumentContext recursiveCreate( | ||
| DocumentContext docContext, String path, Object value) { | ||
| final int pos = path.lastIndexOf('.'); | ||
| final String parent = path.substring(0, pos); | ||
| final String current = path.substring(pos + 1); | ||
| // Attempt to read the current path as it is, trigger the recursive in case of deep insert. | ||
| if (docContext.read(parent) == null) { | ||
| recursiveCreate(docContext, parent, new LinkedHashMap<>()); | ||
| } | ||
| return docContext.put(parent, current, value); | ||
| } | ||
| } | ||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.