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

Reply via email to