Changeset: ca6fdbb0a7ce for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/ca6fdbb0a7ce
Modified Files:
clients/Tests/MAL-signatures.stable.out
clients/Tests/MAL-signatures.stable.out.int128
Branch: default
Log Message:
Merged with Jul2021
diffs (truncated from 866 to 300 lines):
diff --git a/clients/Tests/MAL-signatures.stable.out
b/clients/Tests/MAL-signatures.stable.out
--- a/clients/Tests/MAL-signatures.stable.out
+++ b/clients/Tests/MAL-signatures.stable.out
@@ -7988,6 +7988,7 @@
[ "calc", "iszero", "pattern calc.iszero(X_0:int):bit ",
"CMDvarISZERO;", "Unary check for zero of V" ]
[ "calc", "iszero", "pattern calc.iszero(X_0:lng):bit ",
"CMDvarISZERO;", "Unary check for zero of V" ]
[ "calc", "iszero", "pattern calc.iszero(X_0:sht):bit ",
"CMDvarISZERO;", "Unary check for zero of V" ]
+[ "calc", "json", "command calc.json(X_0:json):json ", "JSON2json;",
"Convert JSON to JSON" ]
[ "calc", "json", "command calc.json(X_0:str):json ",
"JSONstr2json;", "Convert string to its JSON. Dealing with escape
characters" ]
[ "calc", "length", "command calc.length(X_0:str):int ",
"CMDstrlength;", "Length of STRING" ]
[ "calc", "lng", "pattern calc.lng(X_0:bit):lng ",
"CMDvarCONVERT;", "Cast VALUE to lng" ]
diff --git a/clients/Tests/MAL-signatures.stable.out.int128
b/clients/Tests/MAL-signatures.stable.out.int128
--- a/clients/Tests/MAL-signatures.stable.out.int128
+++ b/clients/Tests/MAL-signatures.stable.out.int128
@@ -11126,6 +11126,7 @@
[ "calc", "iszero", "pattern calc.iszero(X_0:int):bit ",
"CMDvarISZERO;", "Unary check for zero of V" ]
[ "calc", "iszero", "pattern calc.iszero(X_0:lng):bit ",
"CMDvarISZERO;", "Unary check for zero of V" ]
[ "calc", "iszero", "pattern calc.iszero(X_0:sht):bit ",
"CMDvarISZERO;", "Unary check for zero of V" ]
+[ "calc", "json", "command calc.json(X_0:json):json ", "JSON2json;",
"Convert JSON to JSON" ]
[ "calc", "json", "command calc.json(X_0:str):json ",
"JSONstr2json;", "Convert string to its JSON. Dealing with escape
characters" ]
[ "calc", "length", "command calc.length(X_0:str):int ",
"CMDstrlength;", "Length of STRING" ]
[ "calc", "lng", "pattern calc.lng(X_0:bit):lng ",
"CMDvarCONVERT;", "Cast VALUE to lng" ]
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
@@ -394,6 +394,13 @@ JSONjson2str(str *ret, json *j)
}
static str
+JSON2json(json *ret, const json *j)
+{
+ *ret = *j;
+ return MAL_SUCCEED;
+}
+
+static str
JSONstr2json(json *ret, str *j)
{
JSON *jt = JSONparse(*j);
@@ -645,7 +652,7 @@ JSONglue(str res, str r, char sep)
return n;
}
-/* return NULL on no match, return (str) -1 on (malloc) failure */
+/* return NULL on no match, return (str) -1 on (malloc) failure, (str) -2 on
stack overflow */
static str
JSONmatch(JSON *jt, int ji, pattern * terms, int ti)
{
@@ -653,6 +660,8 @@ JSONmatch(JSON *jt, int ji, pattern * te
int i;
int cnt;
+ if (THRhighwater())
+ return (str) -2;
if (ti >= MAXTERMS)
return res;
@@ -697,7 +706,7 @@ JSONmatch(JSON *jt, int ji, pattern * te
r = (str) -1;
} else
r = JSONmatch(jt, jt->elm[i].child,
terms, ti + 1);
- if (r == (str) -1) {
+ if (r == (str) -1 || r == (str) -2) {
GDKfree(res);
return r;
}
@@ -724,7 +733,7 @@ JSONmatch(JSON *jt, int ji, pattern * te
r = (str) -1;
} else
r = JSONmatch(jt,
jt->elm[i].child, terms, ti + 1);
- if (r == (str) -1) {
+ if (r == (str) -1 || r == (str) -2) {
GDKfree(res);
return r;
}
@@ -733,7 +742,7 @@ JSONmatch(JSON *jt, int ji, pattern * te
cnt++;
} else if (terms[ti].token == ANY_STEP &&
jt->elm[i].child) {
r = JSONmatch(jt, jt->elm[i].child, terms, ti);
- if (r == (str) -1) {
+ if (r == (str) -1 || r == (str) -2) {
GDKfree(res);
return r;
}
@@ -777,6 +786,10 @@ JSONfilterInternal(json *ret, json *js,
msg = createException(MAL,"JSONfilterInternal", SQLSTATE(HY013)
MAL_MALLOC_FAIL);
goto bailout;
}
+ if (s == (char *) -2) {
+ msg = createException(MAL, "JSONfilterInternal",
SQLSTATE(42000) "Expression too complex to parse");
+ goto bailout;
+ }
// process all other PATH expression
for (tidx++; tidx < MAXTERMS && terms[tidx].token; tidx++)
if (terms[tidx].token == END_STEP && tidx + 1 < MAXTERMS &&
terms[tidx + 1].token) {
@@ -785,6 +798,10 @@ JSONfilterInternal(json *ret, json *js,
msg = createException(MAL,"JSONfilterInternal",
SQLSTATE(HY013) MAL_MALLOC_FAIL);
goto bailout;
}
+ if (s == (char *) -2) {
+ msg = createException(MAL,
"JSONfilterInternal", SQLSTATE(42000) "Expression too complex to parse");
+ goto bailout;
+ }
result = JSONglue(result, s, ',');
}
if (result) {
@@ -991,7 +1008,7 @@ JSONtoken(JSON *jt, const char *j, const
if (jt->error)
return idx;
if (THRhighwater()) {
- jt->error = createException(MAL, "json.parser", "expression too
complex to parse");
+ jt->error = createException(MAL, "json.parser", SQLSTATE(42000)
"Expression too complex to parse");
return idx;
}
skipblancs(j);
@@ -1191,8 +1208,14 @@ static str
JSONlength(int *ret, json *j)
{
int i, cnt = 0;
- JSON *jt = JSONparse(*j);
+ JSON *jt;
+ if (strNil(*j)) {
+ *ret = int_nil;
+ return MAL_SUCCEED;
+ }
+
+ jt = JSONparse(*j);
CHECK_JSON(jt);
for (i = jt->elm[0].next; i; i = jt->elm[i].next)
cnt++;
@@ -1292,6 +1315,11 @@ JSONplaintext(char **r, size_t *l, size_
unsigned int u;
str msg = MAL_SUCCEED;
+ if (THRhighwater()) {
+ *r = *r - (*ilen - *l);
+ throw(MAL,"JSONplaintext", SQLSTATE(42000) "Expression too
complex to parse");
+ }
+
switch (jt->elm[idx].kind) {
case JSON_OBJECT:
for (i = jt->elm[idx].next; i; i = jt->elm[i].next)
@@ -1433,8 +1461,15 @@ JSONjson2textSeparator(str *ret, json *j
{
size_t l, ilen, sep_len;
str s, msg;
- JSON *jt = JSONparse(*js);
+ JSON *jt;
+ if (strNil(*js) || strNil(*sep)) {
+ if (!(*ret = GDKstrdup(str_nil)))
+ throw(MAL,"json2txt", SQLSTATE(HY013) MAL_MALLOC_FAIL);
+ return MAL_SUCCEED;
+ }
+
+ jt = JSONparse(*js);
CHECK_JSON(jt);
sep_len = strlen(*sep);
ilen = l = strlen(*js) + 1;
@@ -1531,14 +1566,17 @@ JSONjson2number(dbl *ret, json *js)
dbl val = 0;
dbl *val_ptr = &val;
str tmp;
- rethrow(__func__, tmp, JSONjson2numberInternal((void **)&val_ptr, js,
strtod_wrapper));
- if (val_ptr == NULL) {
+ if (strNil(*js)) {
*ret = dbl_nil;
+ return MAL_SUCCEED;
}
- else {
+
+ rethrow(__func__, tmp, JSONjson2numberInternal((void **)&val_ptr, js,
strtod_wrapper));
+ if (val_ptr == NULL)
+ *ret = dbl_nil;
+ else
*ret = val;
- }
return MAL_SUCCEED;
}
@@ -1550,13 +1588,16 @@ JSONjson2integer(lng *ret, json *js)
lng *val_ptr = &val;
str tmp;
- rethrow(__func__, tmp, JSONjson2numberInternal((void **)&val_ptr, js,
strtol_wrapper));
- if (val_ptr == NULL) {
+ if (strNil(*js)) {
*ret = lng_nil;
+ return MAL_SUCCEED;
}
- else {
+
+ rethrow(__func__, tmp, JSONjson2numberInternal((void **)&val_ptr, js,
strtol_wrapper));
+ if (val_ptr == NULL)
+ *ret = lng_nil;
+ else
*ret = val;
- }
return MAL_SUCCEED;
}
@@ -1729,6 +1770,12 @@ JSONkeyArray(json *ret, json *js)
int i;
JSON *jt;
+ if (strNil(*js)) {
+ if (!(*ret = GDKstrdup(str_nil)))
+ throw(MAL,"json.keyarray", SQLSTATE(HY013)
MAL_MALLOC_FAIL);
+ return MAL_SUCCEED;
+ }
+
jt = JSONparse(*js); // already validated
CHECK_JSON(jt);
@@ -1826,6 +1873,12 @@ JSONvalueArray(json *ret, json *js)
int i;
JSON *jt;
+ if (strNil(*js)) {
+ if (!(*ret = GDKstrdup(str_nil)))
+ throw(MAL,"json.valuearray", SQLSTATE(HY013)
MAL_MALLOC_FAIL);
+ return MAL_SUCCEED;
+ }
+
jt = JSONparse(*js); // already validated
CHECK_JSON(jt);
@@ -2331,86 +2384,112 @@ JSONfold(Client cntxt, MalBlkPtr mb, Mal
return JSONfoldKeyValue(ret, id, key, val);
}
+#define JSON_STR_CPY \
+ do { \
+ for (; *v; v++) { \
+ switch (*v) { \
+ case '"': \
+ case '\\': \
+ *dst++ = '\\'; \
+ /* fall through */ \
+ default: \
+ *dst++ = *v; \
+ break; \
+ case '\n': \
+ *dst++ = '\\'; \
+ *dst++ = 'n'; \
+ break; \
+ } \
+ } \
+ } while (0)
+
+#define JSON_AGGR_CHECK_NEXT_LENGTH(CALC) \
+ do { \
+ len = CALC; \
+ if (len >= maxlen - buflen) { \
+ maxlen = maxlen + len + BUFSIZ; \
+ buf2 = GDKrealloc(buf, maxlen); \
+ if (buf2 == NULL) { \
+ err = SQLSTATE(HY013) MAL_MALLOC_FAIL; \
+ goto bunins_failed; \
+ } \
+ buf = buf2; \
+ } \
+ } while (0)
+
static str
JSONgroupStr(str *ret, const bat *bid)
{
BAT *b;
BUN p, q;
- const char *t = NULL;
- size_t len, size = BUFSIZ, offset, cnt = 0;
- str buf = GDKmalloc(size);
+ size_t len, maxlen = BUFSIZ, buflen = 0;
+ char *buf = GDKmalloc(maxlen), *buf2;
BATiter bi;
const char *err = NULL;
- char temp[128] = "";
- const double *val = NULL;
+ dbl *restrict vals;
if (buf == NULL)
throw(MAL, "json.group", SQLSTATE(HY013) MAL_MALLOC_FAIL);
if ((b = BATdescriptor(*bid)) == NULL) {
GDKfree(buf);
- throw(MAL, "json.agg", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
+ throw(MAL, "json.group", SQLSTATE(HY002)
RUNTIME_OBJECT_MISSING);
}
assert(b->ttype == TYPE_str || b->ttype == TYPE_dbl);
- strcpy(buf, str_nil);
- offset = 0;
bi = bat_iterator(b);
- BATloop(b, p, q) {
- int n = 0, nil = 0;
+ vals = (dbl*) Tloc(b, 0);
+ switch (b->ttype) {
+ case TYPE_str:
+ for (p = 0, q = BATcount(b); p < q; p++) {
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list