Skip to content

Commit

Permalink
Add comments
Browse files Browse the repository at this point in the history
  • Loading branch information
Florents-Tselai committed Sep 18, 2024
1 parent b8f3c1a commit d2b618b
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 23 deletions.
14 changes: 13 additions & 1 deletion sql/jsonb_apply--0.1.0.sql
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,20 @@ AS
'jsonb_apply_nofilter'
LANGUAGE C;

CREATE FUNCTION jsonb_apply(jsonb, regproc, variadic "any" default null) RETURNS jsonb
AS
'MODULE_PATHNAME',
'jsonb_apply_nofilter'
LANGUAGE C;

CREATE FUNCTION jsonb_filter_apply(jsonb, text[], text, variadic "any" default null) RETURNS jsonb
AS
'MODULE_PATHNAME',
'jsonb_filter_apply'
'jsonb_apply_withfilter'
LANGUAGE C;

CREATE FUNCTION jsonb_filter_apply(jsonb, text[], regproc, variadic "any" default null) RETURNS jsonb
AS
'MODULE_PATHNAME',
'jsonb_apply_withfilter'
LANGUAGE C;
58 changes: 36 additions & 22 deletions src/jsonb_apply.c
Original file line number Diff line number Diff line change
Expand Up @@ -225,51 +225,65 @@ jsonb_apply_worker(Jsonb *jb, text *funcdef,
PG_RETURN_JSONB_P(out);
}


/* Actual implementation for jsonb_apply(jsonb, text/regproc/regprocedure, variadic "any" default null) */
Datum jsonb_apply_internal(FunctionCallInfo fcinfo, bool withfilter) {
Jsonb *jb;
/* Input */
Jsonb *jb; /* That's always the first argument */
Datum funcdefDatum;
Oid funcdefOid;

bool variadic_null = false;
bool withvarargs;
int nvarargs;
Datum *varargs;
bool *varnulls;
Oid *vartypes;

text *funcdef;
bool with_filter = false;
Datum filter;
bool variadic_null = false;
int variadic_start;

if (withfilter) {
if (!withfilter) {
/* jsonb_apply(jsonb, text/regproc/regprocedure, args) */
jb = PG_GETARG_JSONB_P(0);
funcdefDatum = PG_GETARG_DATUM(1);
funcdefOid = PG_GETARG_OID(1);
Assert((funcdefDatum == TEXTOID) || (funcdefOid == REGPROCOID));
funcdef = PG_GETARG_TEXT_PP(1);
variadic_start = 2;
variadic_null = PG_NARGS() == 3 && PG_ARGISNULL(2);
} else {
/*
* jsonb_apply(jsonb, text[], text/regproc/regprocedure, args).
* We have a filter which is idx_arg=1,
* so we apply the filter first,
* and then like the if-block above but the rest of the indices are shifted by +1
*/
filter = PG_GETARG_DATUM(1);
/* We apply the filter before anything else */
jb = DatumGetJsonbP(DirectFunctionCall2(jsonb_extract_path, PG_GETARG_DATUM(0), filter));
funcdef = PG_GETARG_TEXT_PP(2);
variadic_null = PG_NARGS() == 4 && PG_ARGISNULL(3);

variadic_start = 3;
} else {
// filter = PG_GETARG_DATUM(1);
jb = PG_GETARG_JSONB_P(0);
funcdef = PG_GETARG_TEXT_PP(1);
variadic_null = PG_NARGS() == 3 && PG_ARGISNULL(2);
variadic_start = 2;
variadic_null = PG_NARGS() == 4 && PG_ARGISNULL(3);
}

/* A hack to trick the parser. true when call with (jsonb, text, null) */

Datum *varargs;
bool *varnulls;
Oid *vartypes;

/* build argument values to build the object */
int nvarargs = extract_variadic_args(fcinfo, variadic_start, true,
nvarargs = extract_variadic_args(fcinfo, variadic_start, true,
&varargs, &vartypes, &varnulls);

bool withvarargs = (nvarargs == -1 || variadic_null) ? false : true;
withvarargs = (nvarargs == -1 || variadic_null) ? false : true;

printf("withvarargs=%d\n", withvarargs);
PG_RETURN_DATUM(
jsonb_apply_worker(jb, funcdef, PG_NARGS(), withvarargs, nvarargs, varargs, varnulls, vartypes, fcinfo->
fncollation));
}

PG_FUNCTION_INFO_V1(jsonb_filter_apply);
PG_FUNCTION_INFO_V1(jsonb_apply_withfilter);

Datum
jsonb_filter_apply(PG_FUNCTION_ARGS) {
jsonb_apply_withfilter(PG_FUNCTION_ARGS) {
return jsonb_apply_internal(fcinfo, true);
}

Expand Down

0 comments on commit d2b618b

Please sign in to comment.