Changeset: 8e3dc707bac7 for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=8e3dc707bac7
Modified Files:
        monetdb5/modules/atoms/json.c
        monetdb5/modules/atoms/json.h
        monetdb5/modules/atoms/json.mal
Branch: default
Log Message:

Add coercions to numbers
A JSON value, or [value] or {"tag":value}
are cast into an integer or double.
Failure to parse the numbers turns them into a nil.


diffs (146 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
@@ -354,11 +354,13 @@ JSONcompile(char *expr, pattern terms[])
                terms[t].first = INT_MAX;
                terms[t].last = INT_MAX;
                if ( *s == '$'){
-                       if( t )
+                       if( t  && terms[t-1].token != END_STEP)
                                throw(MAL,"json.compile","Root node must be 
first");
-                       terms[t].token = ROOT_STEP;
                        if ( !(*(s+1) == '.' || *(s+1) =='[' || *(s+1) == 0) )
                                throw(MAL,"json.compile","Root node must be 
first");
+                       s++;
+                       if( *s == 0)
+                               terms[t].token = ROOT_STEP;
                }
                if (*s == '.' && *(s + 1) == '.') {
                        terms[t].token = ANY_STEP;
@@ -558,10 +560,10 @@ JSONfilterInternal(json *ret, json *js, 
                s = JSONmatch(jt, 0, terms, ++tidx);
                result = JSONglue(result,s,',');
        }
-       if ( s) {
-               l = strlen(s);
-               if( s[l-1] == ',') 
-                       s[l-1]=0;
+       if ( result) {
+               l = strlen(result);
+               if( result[l-1] == ',') 
+                       result[l-1]=0;
        } else l= 3;
        s = GDKzalloc(l+3);
        snprintf(s,l+3,"[%s]", (result?result:""));
@@ -922,6 +924,7 @@ JSONjson2text(str *ret, json *js)
        l = strlen(s);
        if ( l) s[l-1]= 0;
        *ret = s;
+       JSONfree(jt);
        return MAL_SUCCEED;
 }
 
@@ -939,6 +942,71 @@ JSONjson2textSeparator(str *ret, json *j
        l = strlen(s);
        if ( l) s[l-1]= 0;
        *ret = s;
+       JSONfree(jt);
+       return MAL_SUCCEED;
+}
+
+str
+JSONjson2number(dbl *ret, json *js)
+{      
+       JSON *jt;
+       char *rest;
+
+       *ret = dbl_nil;
+       jt = JSONparse(*js,0);
+       switch( jt->elm[0].kind ){
+       case JSON_NUMBER:
+               *ret =  strtod(jt->elm[0].value, &rest);
+               if (rest && (size_t)(rest- jt->elm[0].value) != 
jt->elm[0].valuelen)
+                       *ret = dbl_nil;
+               break;
+       case JSON_ARRAY:
+               if ( jt->free == 2){
+                       *ret =  strtod(jt->elm[1].value, &rest);
+                       if (rest && (size_t)(rest- jt->elm[1].value) != 
jt->elm[1].valuelen)
+                               *ret = dbl_nil;
+               }
+               break;
+       case JSON_OBJECT:
+               if ( jt->free == 3){
+                       *ret =  strtod(jt->elm[2].value, &rest);
+                       if (rest && (size_t)(rest- jt->elm[2].value) != 
jt->elm[2].valuelen)
+                               *ret = dbl_nil;
+               }
+       }
+       JSONfree (jt);
+       return MAL_SUCCEED;
+}
+
+str
+JSONjson2integer(lng *ret, json *js)
+{      
+       JSON *jt;
+       char *rest;
+
+       *ret = lng_nil;
+       jt = JSONparse(*js,0);
+       switch( jt->elm[0].kind ){
+       case JSON_NUMBER:
+               *ret =  strtol(jt->elm[0].value, &rest,0);
+               if (rest && (size_t)(rest- jt->elm[0].value) != 
jt->elm[0].valuelen)
+                       *ret = lng_nil;
+               break;
+       case JSON_ARRAY:
+               if ( jt->free == 2){
+                       *ret =  strtol(jt->elm[1].value, &rest,0);
+                       if (rest && (size_t)(rest- jt->elm[1].value) != 
jt->elm[1].valuelen)
+                               *ret = lng_nil;
+               }
+               break;
+       case JSON_OBJECT:
+               if ( jt->free == 3){
+                       *ret =  strtol(jt->elm[2].value, &rest,0);
+                       if (rest && (size_t)(rest- jt->elm[2].value) != 
jt->elm[2].valuelen)
+                               *ret = lng_nil;
+               }
+       }
+       JSONfree (jt);
        return MAL_SUCCEED;
 }
 
diff --git a/monetdb5/modules/atoms/json.h b/monetdb5/modules/atoms/json.h
--- a/monetdb5/modules/atoms/json.h
+++ b/monetdb5/modules/atoms/json.h
@@ -75,6 +75,8 @@ json_export str JSONstr2json(json *ret, 
 json_export str JSONjson2str(str *ret, json *j);
 json_export str JSONjson2text(str *ret, json *arg);
 json_export str JSONjson2textSeparator(str *ret, json *arg, str *sep);
+json_export str JSONjson2number(dbl *ret, json *arg);
+json_export str JSONjson2integer(lng *ret, json *arg);
 
 json_export str JSONfilter( json *ret, json *js, str *expr);
 json_export str JSONfilterArray(json *ret, json *j, int *index);
diff --git a/monetdb5/modules/atoms/json.mal b/monetdb5/modules/atoms/json.mal
--- a/monetdb5/modules/atoms/json.mal
+++ b/monetdb5/modules/atoms/json.mal
@@ -47,7 +47,15 @@ comment "Convert JSON values to their pl
 
 command text(j:json,s:str):str
 address JSONjson2textSeparator
-comment "Convert JSON values to their plain string equivalent.";
+comment "Convert JSON values to their plain string equivalent, injecting a 
separator.";
+
+command number(j:json):dbl
+address JSONjson2number
+comment "Convert sinple JSON values to a double, return nil upon error.";
+
+command integer(j:json):lng
+address JSONjson2integer
+comment "Convert sinple JSON values to an integer, return nil upon error.";
 
 command dump(j:json):void
 address JSONdump;
_______________________________________________
checkin-list mailing list
checkin-list@monetdb.org
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to