Skip to content

PPL: Add json function and cast(x as json) function #3243

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

Merged

Conversation

acarbonetto
Copy link
Collaborator

@acarbonetto acarbonetto commented Jan 13, 2025

Description

For OpenSearch-PPL, adds the json() and cast(expression as json) functions. Both of these functions can be used to convert a json-encoded string into an expression object. These functions return any expression type that is valid json (object, array, or scalar). Unfortunately, because the return type is unknown, the expression's return type is UNDEFINED.

The user can use cast to convert the types where necessary for scalar types. For example:

// converts json-encoded integer to an int expression
cast(json(json_string) as int) 

The following casts are available to convert json-encoded scalars: int, long, double, float, boolean.

JSON
----------

Description
>>>>>>>>>>>

Usage: `json(value)` Evaluates whether a string can be parsed as a json-encoded string and casted as an expression. Returns the JSON value if valid, null otherwise.

Argument type: STRING

Return type: BOOLEAN/DOUBLE/INTEGER/NULL/STRUCT/ARRAY

Example::

    > source=json_test | where json_valid(json_string) | eval json=json(json_string) | fields test_name, json_string, json
    fetched rows / total rows = 4/4
    +---------------------+------------------------------+---------------+
    | test_name           | json_string                  | json          |
    |---------------------|------------------------------|---------------|
    | json object         | {"a":"1","b":"2"}            | {a:"1",b:"2"} |
    | json array          | [1, 2, 3, 4]                 | [1,2,3,4]     |
    | json scalar string  | "abc"                        | "abc"         |
    | json empty string   |                              | null          |
    +---------------------+------------------------------+---------------+

Related Issues

Resolves #3209

Check List

  • New functionality includes testing.
  • New functionality has been documented.
  • New functionality has javadoc added.
  • New functionality has a user manual doc added.
  • API changes companion pull request created.
  • Commits are signed per the DCO using --signoff.
  • Public documentation issue/PR created.

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.
For more information on following Developer Certificate of Origin and signing off your commits, please check here.

14yapkc1 and others added 5 commits January 16, 2025 15:55
Copy link
Contributor

@kenrickyap kenrickyap left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM minor nits

Signed-off-by: Andrew Carbonetto <[email protected]>
Signed-off-by: Andrew Carbonetto <[email protected]>
@kenrickyap kenrickyap mentioned this pull request Jan 23, 2025
7 tasks
@@ -1,14 +1,24 @@
{"index":{"_id":"0"}}
{"test_name":"json nested object", "json_string":"{\"a\":\"1\",\"b\":{\"c\":\"2\",\"d\":\"3\"}}"}
{"test_name":"json nested object", "json_string":"{\"a\":\"1\", \"b\": {\"c\": \"3\"}, \"d\": [1, 2, 3]}"}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can u also add a use case for inner json obj that has an array ?
{"a":{"b":{"c":[....]}}}

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"d" is mapped to an array. Do you want an object within in an array?

Copy link
Member

@YANG-DB YANG-DB left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMO looking good - added some minor comments...

Signed-off-by: Andrew Carbonetto <[email protected]>
Signed-off-by: Andrew Carbonetto <[email protected]>
@acarbonetto
Copy link
Collaborator Author

IMO looking good - added some minor comments...

Tests added. Thank you for looking.

@YANG-DB
Copy link
Member

YANG-DB commented Jan 30, 2025

@acarbonetto can u plz resolve the conflicts ?
thanks

YANG-DB
YANG-DB previously approved these changes Feb 3, 2025
jsonNode = objectMapper.readTree(json.stringValue());
} catch (JsonProcessingException e) {
final String errorFormat = "JSON string '%s' is not valid. Error details: %s";
throw new SemanticCheckException(String.format(errorFormat, json, e.getMessage()), e);
Copy link
Member

@LantaoJin LantaoJin Feb 11, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

minor: SemanticCheckExcpetion is not a proper exception to throw here. Maybe change it to ExpressionEvaluationException (add a two-parameters construction)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you Lantao. I will address shortly.

Copy link
Member

@LantaoJin LantaoJin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM except a minor comment

@LantaoJin
Copy link
Member

Merging to main. Thanks for contribution. @acarbonetto please address this minor comment #3243 (comment) in your followup PR.

@LantaoJin LantaoJin merged commit 5aa86d7 into opensearch-project:main Feb 11, 2025
15 checks passed
@acarbonetto acarbonetto deleted the feature/acarbo_json_cast_ppl branch February 11, 2025 18:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[FEATURE] Add json function to cast string to json object
5 participants