Changeset: 3864bcbc6e5b for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/3864bcbc6e5b
Modified Files:
monetdb5/modules/atoms/json.c
monetdb5/modules/atoms/pg_jsonpath/jsonpath.h
monetdb5/modules/atoms/pg_jsonpath/jsonpath_exec.c
Branch: json-extend
Log Message:
use single dynamic allocator for JsonPathQuery
diffs (truncated from 645 to 300 lines):
diff --git a/monetdb5/modules/atoms/json.c b/monetdb5/modules/atoms/json.c
--- a/monetdb5/modules/atoms/json.c
+++ b/monetdb5/modules/atoms/json.c
@@ -1659,20 +1659,26 @@ JSONfilter(json *ret, const json *js, co
JsonPathParseResult* path = parsejsonpath(*expr, strlen(*expr),
escontext);
- yyjson_doc *doc = yyjson_read(*js, strlen(*js), 0);
+
+ yyjson_alc* alc = yyjson_alc_dyn_new(); // TODO initialize this with
gdk memory functions.
+ yyjson_read_err* read_error = NULL;
+ yyjson_doc *doc = yyjson_read_opts(*js, strlen(*js), 0, alc,
read_error);
yyjson_val *root = yyjson_doc_get_root(doc);
bool empty;
bool error;
List* vars = NULL;
const char *column_name = NULL;
// TODO pass the result as yyjson document
- yyjson_val *res = JsonPathQuery((Datum) root, path, JSW_UNCONDITIONAL,
&empty, &error, vars, column_name);
+ yyjson_val *res = JsonPathQuery((Datum) root, path, JSW_UNCONDITIONAL,
&empty, &error, vars, column_name, alc);
if (!res)
throw(MAL, "json.unfold", SQLSTATE(HY013) "JsonPathQuery
error");
- char* tmp_res = yyjson_val_write(res, 0, NULL); // TODO use different
allocation or doc write
+ size_t* len = NULL;
+ yyjson_write_err* write_error = NULL;
+ char* tmp_res = yyjson_val_write_opts(res, 0, alc, len, write_error);
// TODO use different allocation or doc write
+
*ret = GDKstrdup(tmp_res);
- free(tmp_res);
+ yyjson_alc_dyn_free(alc);
return MAL_SUCCEED;
// return JSONfilterInternal(ret, js, expr, 0);
}
diff --git a/monetdb5/modules/atoms/pg_jsonpath/jsonpath.h
b/monetdb5/modules/atoms/pg_jsonpath/jsonpath.h
--- a/monetdb5/modules/atoms/pg_jsonpath/jsonpath.h
+++ b/monetdb5/modules/atoms/pg_jsonpath/jsonpath.h
@@ -197,12 +197,12 @@ typedef struct JsonPathVariable
/* SQL/JSON query functions */
-extern bool JsonPathExists(Datum jb, JsonPath *jp, bool *error, List *vars);
+extern bool JsonPathExists(Datum jb, JsonPath *jp, bool *error, List *vars,
yyjson_alc* alc);
extern JsonbValue *JsonPathQuery(Datum jb, JsonPath *jp, JsonWrapper wrapper,
bool *empty, bool *error,
List *vars,
- const char *column_name);
+ const char *column_name,
yyjson_alc* alc);
extern JsonbValue *JsonPathValue(Datum jb, JsonPath *jp, bool *empty,
bool *error,
List *vars,
- const char
*column_name);
+ const char
*column_name, yyjson_alc* alc);
#endif
diff --git a/monetdb5/modules/atoms/pg_jsonpath/jsonpath_exec.c
b/monetdb5/modules/atoms/pg_jsonpath/jsonpath_exec.c
--- a/monetdb5/modules/atoms/pg_jsonpath/jsonpath_exec.c
+++ b/monetdb5/modules/atoms/pg_jsonpath/jsonpath_exec.c
@@ -59,7 +59,6 @@
#include "jsonpath.h"
#include "postgres_defines_internal.h"
-#define STACK_ALLOCATED_BUFFER_SIZE 1024 // figure out if good estimate or not
/*
* Represents "base object" and it's "id" for .keyvalue() evaluation.
@@ -72,7 +71,7 @@ typedef struct JsonBaseObjectInfo
} JsonBaseObjectInfo;
/* Callbacks for executeJsonPath() */
-typedef JsonbValue *(*JsonPathGetVarCallback) (void *vars, char *varName, int
varNameLen,
+typedef JsonbValue *(*JsonPathGetVarCallback) (void *vars , yyjson_alc* alc,
char *varName, int varNameLen,
JsonbValue **baseObject, int *baseObjectId);
typedef int (*JsonPathCountVarsCallback) (void *vars);
@@ -88,6 +87,8 @@ typedef struct JsonPathExecContext
JsonbValue *current; /* for @ evaluation */
JsonBaseObjectInfo baseObject; /* "base object" for .keyvalue()
*
evaluation */
+ yyjson_alc *alc;
+ yyjson_mut_doc *mutable_doc;
int lastGeneratedObjectId; /* "id" counter for
.keyvalue()
* evaluation */
int innermostArraySize; /* for LAST array index
evaluation */
@@ -182,7 +183,7 @@ static JsonPathExecResult executeJsonPat
JsonPathGetVarCallback getVar_,
JsonPathCountVarsCallback countVars,
Jsonb *json, bool throwErrors,
-
JsonValueList *result, bool useTz);
+
JsonValueList *result, bool useTz, yyjson_alc* alc);
static JsonPathExecResult executeItem(JsonPathExecContext *cxt,
JsonPathItem *jsp, JsonbValue *jb, JsonValueList *found);
static JsonPathExecResult executeItemOptUnwrapTarget(JsonPathExecContext *cxt,
@@ -228,18 +229,17 @@ static JsonPathExecResult executeKeyValu
JsonPathItem *jsp, JsonbValue *jb, JsonValueList *found);
static JsonPathExecResult appendBoolResult(JsonPathExecContext *cxt,
JsonPathItem *jsp, JsonValueList *found, JsonPathBool res);
-static JsonbValue *GetJsonPathVar(void *cxt, char *varName, int varNameLen,
+static JsonbValue *GetJsonPathVar(void *cxt , yyjson_alc* alc, char *varName,
int varNameLen,
JsonbValue
**baseObject, int *baseObjectId);
static int CountJsonPathVars(void *cxt);
static yyjson_mut_val*
-JsonItemFromDatum(Datum val, Oid typid, int32 typmod, yyjson_mut_doc* mut_doc);
+JsonItemFromDatum(Datum val, Oid typid, int32 typmod, yyjson_mut_doc*
mutable_doc);
static int JsonbArraySize(JsonbValue *jb);
static JsonPathBool executeComparison(JsonPathItem *cmp, JsonbValue *lv,
JsonbValue *rv, void *p);
static JsonPathBool compareItems(int32 op, JsonbValue *jb1, JsonbValue *jb2,
bool useTz);
static int compareNumeric(Numeric a, Numeric b);
-static JsonbValue *copyJsonbValue(JsonbValue *src);
static JsonPathExecResult getArrayIndex(JsonPathExecContext *cxt,
JsonPathItem *jsp, JsonbValue *jb, int32 *index);
static JsonBaseObjectInfo setBaseObject(JsonPathExecContext *cxt,
@@ -258,7 +258,7 @@ static JsonbValue *JsonValueListNext(con
static int JsonbType(JsonbValue *jb);
static bool isObjectOrArray(JsonbValue *jb);
static JsonbValue *getScalar(JsonbValue *scalar, enum jbvType type);
-static JsonbValue *wrapItemsInArray(const JsonValueList *items);
+static JsonbValue *wrapItemsInArray(yyjson_alc* alc, const JsonValueList
*items);
/********************Execute functions for JsonPath**************************/
@@ -288,7 +288,7 @@ static JsonPathExecResult
executeJsonPath(JsonPath *path, void *vars, JsonPathGetVarCallback getVar_,
JsonPathCountVarsCallback countVars,
Jsonb *json, bool throwErrors, JsonValueList
*result,
- bool useTz)
+ bool useTz, yyjson_alc* alc)
{
JsonPathExecContext cxt;
JsonPathExecResult res;
@@ -312,6 +312,8 @@ executeJsonPath(JsonPath *path, void *va
cxt.innermostArraySize = -1;
cxt.throwErrors = throwErrors;
cxt.useTz = useTz;
+ cxt.alc = alc;
+ cxt.mutable_doc = yyjson_mut_doc_new(alc);
if (jspStrictAbsenceOfErrors(&cxt) && !result)
{
@@ -370,7 +372,6 @@ executeItemOptUnwrapTarget(JsonPathExecC
case jpiString:
case jpiVariable:
{
- JsonbValue vbuf;
JsonbValue *v;
bool hasNext = (elem = jsp->next) ?
true: false;
@@ -384,32 +385,22 @@ executeItemOptUnwrapTarget(JsonPathExecC
break;
}
- v = hasNext ? &vbuf : palloc(sizeof(*v));
-
baseObject = cxt->baseObject;
- yyjson_alc alc;
- yyjson_alc* palc = NULL;
- char buf[STACK_ALLOCATED_BUFFER_SIZE];
- if (hasNext) {
- yyjson_alc_pool_init(&alc, buf, 1024);
- palc = &alc;
- }
- yyjson_mut_doc *mut_doc =
yyjson_mut_doc_new(palc);
yyjson_mut_val* mut_val = NULL;
switch (jsp->type)
{
case jpiNull:
- mut_val =
yyjson_mut_null(mut_doc);
+ mut_val =
yyjson_mut_null(cxt->mutable_doc);
break;
case jpiBool:
- mut_val =
yyjson_mut_bool(mut_doc, jspGetBool(jsp));
+ mut_val =
yyjson_mut_bool(cxt->mutable_doc, jspGetBool(jsp));
break;
case jpiNumeric:
- mut_val =
yyjson_mut_int(mut_doc, jspGetNumeric(jsp));
+ mut_val =
yyjson_mut_int(cxt->mutable_doc, jspGetNumeric(jsp));
break;
case jpiString:
- mut_val =
yyjson_mut_str(mut_doc, jspGetString(jsp, NULL)); //TODO use _set_ for
immutables
+ mut_val =
yyjson_mut_str(cxt->mutable_doc, jspGetString(jsp, NULL)); //TODO use _set_ for
immutables
break;
case jpiVariable:
{
@@ -423,7 +414,7 @@ executeItemOptUnwrapTarget(JsonPathExecC
varName =
jspGetString(jsp, &varNameLength);
if (cxt->vars == NULL ||
- (v =
cxt->getVar_(cxt->vars, varName, varNameLength,
+ (v =
cxt->getVar_(cxt->vars, cxt->alc , varName, varNameLength,
&baseObject, &baseObjectId)) == NULL)
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
@@ -433,15 +424,14 @@ executeItemOptUnwrapTarget(JsonPathExecC
if (baseObjectId > 0)
{
setBaseObject(cxt, baseObject, baseObjectId);
- // TODO:
yyjson_mem when using a stack allocator this might be to big
- mut_val =
yyjson_val_mut_copy(mut_doc, v);
+ mut_val =
yyjson_val_mut_copy(cxt->mutable_doc, v);
}
}
break;
default:
elog(ERROR, "unexpected
jsonpath item type");
}
- yyjson_doc* doc =
yyjson_mut_val_imut_copy(mut_val, palc);
+ yyjson_doc* doc =
yyjson_mut_val_imut_copy(mut_val, cxt->alc);
v = yyjson_doc_get_root(doc);
res = executeNextItem(cxt, jsp, elem,
@@ -693,10 +683,6 @@ executeItemOptUnwrapTarget(JsonPathExecC
{
res = executeNextItem(cxt, jsp, NULL,
v, found, false);
-
- /* free value if it was not added to
found list */
- if (jspHasNext(jsp) || !found)
- (void) v; // pfree(v); TODO
properly free v
}
else if (!jspIgnoreStructuralErrors(cxt))
{
@@ -755,9 +741,8 @@ executeItemOptUnwrapTarget(JsonPathExecC
case jpiType:
{
- yyjson_mut_doc *mut_doc =
yyjson_mut_doc_new(NULL);
- yyjson_mut_val * mut_jbv =
yyjson_mut_str(mut_doc, yyjson_get_type_desc(jb));
- yyjson_doc* doc =
yyjson_mut_val_imut_copy(mut_jbv, NULL);
+ yyjson_mut_val * mut_jbv =
yyjson_mut_str(cxt->mutable_doc, yyjson_get_type_desc(jb));
+ yyjson_doc* doc =
yyjson_mut_val_imut_copy(mut_jbv, cxt->alc);
yyjson_val* jbv = yyjson_doc_get_root(doc);
res = executeNextItem(cxt, jsp, NULL, jbv,
@@ -783,9 +768,8 @@ executeItemOptUnwrapTarget(JsonPathExecC
size = 1;
}
- yyjson_mut_doc *mut_doc =
yyjson_mut_doc_new(NULL);
- yyjson_mut_val * mut_jbv =
yyjson_mut_int(mut_doc, size);
- yyjson_doc* doc =
yyjson_mut_val_imut_copy(mut_jbv, NULL);
+ yyjson_mut_val * mut_jbv =
yyjson_mut_int(cxt->mutable_doc, size);
+ yyjson_doc* doc =
yyjson_mut_val_imut_copy(mut_jbv, cxt->alc);
yyjson_val* jbv = yyjson_doc_get_root(doc);
res = executeNextItem(cxt, jsp, NULL, jbv,
found, false);
@@ -812,10 +796,9 @@ executeItemOptUnwrapTarget(JsonPathExecC
(errcode(ERRCODE_NON_NUMERIC_SQL_JSON_ITEM),
errmsg("NaN or Infinity is not allowed for jsonpath item method
.%s()",
jspOperationName(jsp->type)))));
- // TODO: have a single mutable doc
hanging around for these kind of allocations
- yyjson_mut_doc *mut_doc =
yyjson_mut_doc_new(NULL);
- yyjson_mut_val * mut_jbv =
yyjson_mut_double(mut_doc, val);
- yyjson_doc* doc =
yyjson_mut_val_imut_copy(mut_jbv, NULL);
+
+ yyjson_mut_val * mut_jbv =
yyjson_mut_double(cxt->mutable_doc, val);
+ yyjson_doc* doc =
yyjson_mut_val_imut_copy(mut_jbv, cxt->alc);
jb = yyjson_doc_get_root(doc);
res = jperOk;
}
@@ -833,11 +816,9 @@ executeItemOptUnwrapTarget(JsonPathExecC
(errcode(ERRCODE_NON_NUMERIC_SQL_JSON_ITEM),
errmsg("NaN or Infinity is not allowed for jsonpath item method
.%s()",
jspOperationName(jsp->type)))));
-
- // TODO: have a single mutable doc
hanging around for these kind of allocations
- yyjson_mut_doc *mut_doc =
yyjson_mut_doc_new(NULL);
- yyjson_mut_val * mut_jbv =
yyjson_mut_double(mut_doc, val);
- yyjson_doc* doc =
yyjson_mut_val_imut_copy(mut_jbv, NULL);
+
+ yyjson_mut_val * mut_jbv =
yyjson_mut_double(cxt->mutable_doc, val);
+ yyjson_doc* doc =
yyjson_mut_val_imut_copy(mut_jbv, cxt->alc);
jb = yyjson_doc_get_root(doc);
res = jperOk;
}
@@ -886,17 +867,12 @@ executeItemOptUnwrapTarget(JsonPathExecC
last = cxt->innermostArraySize - 1;
(void) tmpjbv;
- yyjson_mut_doc *mut_doc =
yyjson_mut_doc_new(NULL);
- yyjson_mut_val * mut_jbv =
yyjson_mut_sint(mut_doc, last);
- yyjson_doc* doc =
yyjson_mut_val_imut_copy(mut_jbv, NULL);
+ yyjson_mut_val * mut_jbv =
yyjson_mut_sint(cxt->mutable_doc, last);
+ yyjson_doc* doc =
yyjson_mut_val_imut_copy(mut_jbv, cxt->alc);
lastjbv = yyjson_doc_get_root(doc);
res = executeNextItem(cxt, jsp, elem,
lastjbv, found, hasNext);
- if (hasNext) {
- yyjson_doc_free(doc);
- yyjson_mut_doc_free(mut_doc);
- }
}
break;
@@ -929,12 +905,8 @@ executeItemOptUnwrapTarget(JsonPathExecC
(errcode(ERRCODE_NON_NUMERIC_SQL_JSON_ITEM),
errmsg("jsonpath item method .%s() can only be applied to a string or numeric
value",
jspOperationName(jsp->type)))));
- yyjson_alc alc;
_______________________________________________
checkin-list mailing list -- [email protected]
To unsubscribe send an email to [email protected]