Skip to content

Commit

Permalink
Refinement of FOR JSON PATH & Nested Functionality (#205)
Browse files Browse the repository at this point in the history
Currently FOR JSON PATH is implemented in Babelfish using string manipulation. This change will implement FOR JSON PATH using PostgreSQL's JsonbValue and HTAB. The reason for this change is because the current implementation of FOR JSON PATH does not support the full functionality of the feature. Nested outputs determined by aliases in the SELECT statement are not supported. By implementing FOR JSON PATH using JsonbValue and HTAB, we provide an efficient solution that also supports nested json objects, while also setting the foundation for FOR JSON AUTO to be implemented.

BABELFISH_EXTENSIONS CHANGES:

Switched from String Manipulation implementation of FOR JSON PATH to an implementation using JsonbValue.
Wrapper function to add a value to JsonbValue and handle datatype checks.
Supporting functions to determine path to insert a JsonbValue object and key for HashTable.
Create json and insert into existing json functions that are used when dealing with nested json objects.
Implemented Nested Output tracking using PostgreSQL's HTAB library (HashTable)
Corrected the tests to showcase the new functionality of nested json objects
Added another set of tests to more thoroughly test the nested json object functionality.

POSTGRESQL_MODIFIED_FOR_BABELFISH CHANGES:

Created a public wrapper function in jsonb.h to call add_jsonb() from forjson.c

TEST CASES:

Added a test that checks the functionality and accuracy of the nested json feature. Includes cases with multiple layers, deeply nested layers, values in different stages of json layers, nested null outputs.
Organized version upgrade tests so previous versions use previous implementation of FOR JSON PATH and updated the schedule for each version.
Modified existing test cases to correctly showcase the nested functionality if the given test uses alias that cause nested json objects to be created.
Changed the expected outputs to include spaces as JsonbValue does when converted to a string.

Task: BABEL-3407

Signed-off-by: Kuzey Gok <[email protected]>
Co-authored-by: Jake Owen <[email protected]>
  • Loading branch information
northaxosky and Jake Owen authored Oct 17, 2023
1 parent 133adb5 commit 864c0d3
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 2 deletions.
12 changes: 11 additions & 1 deletion src/backend/utils/adt/jsonb.c
Original file line number Diff line number Diff line change
Expand Up @@ -598,6 +598,16 @@ JsonbToCStringWorker(StringInfo out, JsonbContainer *in, int estimated_len, bool
return out->data;
}

void
jsonb_get_value(Datum val, bool is_null, JsonbValue *json, Oid val_type)
{
JsonbInState state;
memset(&state, 0, sizeof(JsonbInState));

add_jsonb(val, is_null, &state, val_type, false);
*json = *(state.res);
}

static void
add_indent(StringInfo out, bool indent, int level)
{
Expand Down Expand Up @@ -2083,4 +2093,4 @@ jsonb_float8(PG_FUNCTION_ARGS)
PG_FREE_IF_COPY(in, 0);

PG_RETURN_DATUM(retValue);
}
}
3 changes: 2 additions & 1 deletion src/include/utils/jsonb.h
Original file line number Diff line number Diff line change
Expand Up @@ -415,4 +415,5 @@ extern Datum jsonb_set_element(Jsonb *jb, Datum *path, int path_len,
JsonbValue *newval);
extern Datum jsonb_get_element(Jsonb *jb, Datum *path, int npath,
bool *isnull, bool as_text);
#endif /* __JSONB_H__ */
extern void jsonb_get_value(Datum val, bool is_null, JsonbValue *json, Oid val_type);
#endif /* __JSONB_H__ */

0 comments on commit 864c0d3

Please sign in to comment.