Changeset: 298c7bbaeb20 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/298c7bbaeb20
Modified Files:
monetdb5/modules/atoms/pg_jsonpath/jsonpath_exec.c
monetdb5/modules/atoms/pg_jsonpath/jsonpath_gram.y
monetdb5/modules/atoms/pg_jsonpath/postgres_defines.h
monetdb5/modules/atoms/pg_jsonpath/postgres_defines_internal.h
Branch: json-extend
Log Message:
Handle Numeric
diffs (truncated from 661 to 300 lines):
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
@@ -396,7 +396,11 @@ executeItemOptUnwrapTarget(JsonPathExecC
mut_val =
yyjson_mut_bool(cxt->mutable_doc, jspGetBool(jsp));
break;
case jpiNumeric:
- mut_val =
yyjson_mut_int(cxt->mutable_doc, jspGetNumeric(jsp));
+ Numeric num =
jspGetNumeric(jsp);
+ if (num.type ==
YYJSON_SUBTYPE_REAL)
+ mut_val =
yyjson_mut_real(cxt->mutable_doc, num.dnum);
+ else
+ mut_val =
yyjson_mut_int(cxt->mutable_doc, num.lnum);
break;
case jpiString:
mut_val =
yyjson_mut_str(cxt->mutable_doc, jspGetString(jsp, NULL)); //TODO use _set_ for
immutables
@@ -784,9 +788,16 @@ executeItemOptUnwrapTarget(JsonPathExecC
false);
if (JsonbType(jb) == jbvNumeric)
{
- // TODO requires a Numeric type that
can handle decimals
- lng nval = yyjson_get_int(jb);
- double val = (double) nval;
+ double val;
+
+ if (yyjson_get_subtype(jb) ==
YYJSON_SUBTYPE_SINT) {
+ lng lval = yyjson_get_int(jb);
+ val = (double) lval;
+ }
+ else {
+ assert (yyjson_get_subtype(jb)
== YYJSON_SUBTYPE_REAL);
+ val = yyjson_get_real(jb);
+ }
// TODO errors
if (isinf(val) || isnan(val))
RETURN_ERROR(ereport(ERROR,
@@ -878,26 +889,44 @@ executeItemOptUnwrapTarget(JsonPathExecC
case jpiBigint:
{
- Datum datum;
-
if (unwrap && JsonbType(jb) == jbvArray)
return
executeItemUnwrapTargetArray(cxt, jsp, jb, found,
false);
+ lng datum;
if (JsonbType(jb) == jbvNumeric)
{
- int64 val;
-
- val = yyjson_get_int(jb);
- datum = Int64GetDatum(val);
+ if (yyjson_get_subtype(jb) ==
YYJSON_SUBTYPE_SINT) {
+ datum = yyjson_get_int(jb);
+ }
+ else {
+ assert (yyjson_get_subtype(jb)
== YYJSON_SUBTYPE_REAL);
+ datum = (lng)
yyjson_get_real(jb);
+ }
res = jperOk;
}
else if (JsonbType(jb) == jbvString)
{
- const char *tmp = yyjson_get_str(jb);
- size_t len = sizeof(lng);
- lng* pdatum = (lng*) &datum;
- /*TODO error handling*/(void)
lngFromStr(tmp, &len, &pdatum, true);
+ const char* src = yyjson_get_str(jb);
+ size_t llen = sizeof(lng);
+ lng lval;
+ lng* plval = &lval;
+
+ size_t dlen = sizeof(dbl);
+ dbl dval;
+ dbl* pdval = &dval;
+
+ if (lngFromStr(src, &llen, &plval,
false) > 0) {
+ datum = lval;
+ }
+ else if (dblFromStr(src, &dlen, &pdval,
false) > 0) {
+ datum = (lng) dval;
+ }
+ else {
+ snprintf(cxt->_errmsg, 1024,
"string %s does not represent valid number", src);
+ return jperError;
+ }
+ res = jperOk;
}
if (res == jperNotFound)
@@ -905,7 +934,7 @@ 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_mut_val * mut_jbv =
yyjson_mut_int(cxt->mutable_doc, (lng) datum);
+ yyjson_mut_val * mut_jbv =
yyjson_mut_int(cxt->mutable_doc, datum);
yyjson_doc* doc =
yyjson_mut_val_imut_copy(mut_jbv, cxt->alc);
jb = yyjson_doc_get_root(doc);
res = executeNextItem(cxt, jsp, NULL, jb,
found, true);
@@ -928,7 +957,13 @@ executeItemOptUnwrapTarget(JsonPathExecC
}
else if (JsonbType(jb) == jbvNumeric)
{
- bval = yyjson_get_int(jb)?1:0;
+ if (yyjson_get_subtype(jb) ==
YYJSON_SUBTYPE_SINT) {
+ bval = yyjson_get_int(jb)?1:0;
+ }
+ else {
+ assert (yyjson_get_subtype(jb)
== YYJSON_SUBTYPE_REAL);
+ bval = yyjson_get_real(jb)?1:0;
+ }
res = jperOk;
}
@@ -957,7 +992,7 @@ executeItemOptUnwrapTarget(JsonPathExecC
case jpiDecimal:
case jpiNumber:
{
- Numeric num;
+ dbl num;
char *numstr = NULL;
if (unwrap && JsonbType(jb) == jbvArray)
@@ -966,18 +1001,22 @@ executeItemOptUnwrapTarget(JsonPathExecC
if (JsonbType(jb) == jbvNumeric)
{
- num = yyjson_get_int(jb);
- // TODO check if num is nan or inf
- size_t len = 0;
- (void) lngToStr(&numstr, &len, &num,
true);
+ if (yyjson_get_subtype(jb) ==
YYJSON_SUBTYPE_SINT) {
+ num = (dbl) yyjson_get_int(jb);
+ }
+ else {
+ assert (yyjson_get_subtype(jb)
== YYJSON_SUBTYPE_REAL);
+ num = yyjson_get_real(jb);
+ }
res = jperOk;
}
else if (JsonbType(jb) == jbvString)
{
numstr = (char*) yyjson_get_str(jb);
size_t len = sizeof(lng);
- lng* pnum = #
- (void) lngFromStr(numstr, &len, &pnum,
true);
+ dbl* pnum = #
+ if (dblFromStr(numstr, &len, &pnum,
true) < 0)
+ res = jperNotFound;
res = jperOk;
}
@@ -987,9 +1026,7 @@ executeItemOptUnwrapTarget(JsonPathExecC
errmsg("jsonpath item method .%s() can only be applied to a string or numeric
value",
jspOperationName(jsp->type)))));
- // TODO get Numeric type with
decimal(precision, scale) function to work and import it here
-
- yyjson_mut_val * mut_jbv =
yyjson_mut_int(cxt->mutable_doc, num);
+ yyjson_mut_val * mut_jbv =
yyjson_mut_real(cxt->mutable_doc, num);
yyjson_doc* doc =
yyjson_mut_val_imut_copy(mut_jbv, cxt->alc);
jb = yyjson_doc_get_root(doc);
@@ -999,7 +1036,7 @@ executeItemOptUnwrapTarget(JsonPathExecC
case jpiInteger:
{
- Datum datum;
+ lng datum;
if (unwrap && JsonbType(jb) == jbvArray)
return
executeItemUnwrapTargetArray(cxt, jsp, jb, found,
@@ -1007,16 +1044,21 @@ executeItemOptUnwrapTarget(JsonPathExecC
if (JsonbType(jb) == jbvNumeric)
{
- // TODO check for overflows
- datum = (Datum) yyjson_get_int(jb);
+ if (yyjson_get_subtype(jb) ==
YYJSON_SUBTYPE_SINT) {
+ datum = yyjson_get_int(jb);
+ }
+ else {
+ assert (yyjson_get_subtype(jb)
== YYJSON_SUBTYPE_REAL);
+ datum = (lng)
yyjson_get_real(jb);
+ }
res = jperOk;
}
else if (JsonbType(jb) == jbvString)
{
const char* tmp = yyjson_get_str(jb);
- size_t len = sizeof(int);
- int* pdatum = (int*) &datum;
- (void) intFromStr(tmp, &len, (int**)
&pdatum, true); // TODO check for errors
+ size_t len = sizeof(lng);
+ lng* pdatum = &datum;
+ (void) lngFromStr(tmp, &len, &pdatum,
true);
res = jperOk;
}
@@ -1025,8 +1067,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)))));
- // TODO must be Numeric
- yyjson_mut_val * mut_jbv =
yyjson_mut_int(cxt->mutable_doc, (int) datum);
+
+ yyjson_mut_val * mut_jbv =
yyjson_mut_int(cxt->mutable_doc, datum);
yyjson_doc* doc =
yyjson_mut_val_imut_copy(mut_jbv, cxt->alc);
jb = yyjson_doc_get_root(doc);
@@ -1050,8 +1092,15 @@ executeItemOptUnwrapTarget(JsonPathExecC
break;
case jbvNumeric:
size_t len = 0;
- Numeric val =
yyjson_get_int(jb);
- (void) lngToStr(&tmp, &len,
&val, true);
+ if (yyjson_get_subtype(jb) ==
YYJSON_SUBTYPE_SINT) {
+ lng val =
yyjson_get_int(jb);
+ (void) lngToStr(&tmp,
&len, &val, true);
+ }
+ else {
+ assert
(yyjson_get_subtype(jb) == YYJSON_SUBTYPE_REAL);
+ dbl val =
yyjson_get_real(jb);
+ (void) dblToStr(&tmp,
&len, &val, true);
+ }
cleanup_tmp = true;
break;
case jbvBool:
@@ -1519,6 +1568,42 @@ executePredicate(JsonPathExecContext *cx
return jpbFalse;
}
+static inline
+Numeric yyjson2Numeric(JsonbValue* val) {
+ Numeric num = {.type=yyjson_get_subtype(val)};
+
+ switch (num.type) {
+ case YYJSON_SUBTYPE_SINT:
+ num.lnum = yyjson_get_int(val);
+ break;
+ case YYJSON_SUBTYPE_REAL:
+ num.dnum = yyjson_get_real(val);
+ break;
+ default:
+ assert(0);
+ }
+ return num;
+}
+
+static inline // TODO: replace Numeric with yyjson where possible
+JsonbValue* Numeric2yyjson(JsonPathExecContext *cxt, Numeric num) {
+ yyjson_mut_val* mut_jbv;
+
+ switch (num.type) {
+ case YYJSON_SUBTYPE_SINT:
+ mut_jbv = yyjson_mut_int(cxt->mutable_doc, num.lnum);
+ break;
+ case YYJSON_SUBTYPE_REAL:
+ mut_jbv = yyjson_mut_real(cxt->mutable_doc, num.dnum);
+ break;
+ default:
+ assert(0);
+ }
+
+ yyjson_doc* doc = yyjson_mut_val_imut_copy(mut_jbv, cxt->alc);
+ return yyjson_doc_get_root(doc);
+}
+
/*
* Execute binary arithmetic expression on singleton numeric operands.
* Array operands are automatically unwrapped in lax mode.
@@ -1568,12 +1653,13 @@ executeBinaryArithmExpr(JsonPathExecCont
if (jspThrowErrors(cxt))
{
- res = func(yyjson_get_int(lval), yyjson_get_int(rval), NULL);
+ res = func(yyjson2Numeric(lval), yyjson2Numeric(rval), NULL);
+ // TODO: throw error
}
else
{
bool error = false;
- res = func(yyjson_get_int(lval), yyjson_get_int(rval), &error);
+ res = func(yyjson2Numeric(lval), yyjson2Numeric(rval), &error);
if (error)
return jperError;
@@ -1582,9 +1668,7 @@ executeBinaryArithmExpr(JsonPathExecCont
if (!(elem = jsp->next) && !found)
return jperOk; // TODO: weird why do func if not using the
result perhaps check when found is empty
- yyjson_mut_val * mut_jbv = yyjson_mut_int(cxt->mutable_doc, res);
- yyjson_doc* doc = yyjson_mut_val_imut_copy(mut_jbv, cxt->alc);
- lval = yyjson_doc_get_root(doc);
+ lval = Numeric2yyjson(cxt, res);
return executeNextItem(cxt, jsp, elem, lval, found, false);
}
@@ -1636,8 +1720,8 @@ executeUnaryArithmExpr(JsonPathExecConte
_______________________________________________
checkin-list mailing list -- [email protected]
To unsubscribe send an email to [email protected]