Changeset: 9603470ae6ad for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=9603470ae6ad
Added Files:
        sql/test/json/Tests/pgexample.sql
Modified Files:
        monetdb5/modules/atoms/json_atom.c
        monetdb5/modules/atoms/json_atom.h
        monetdb5/modules/atoms/json_atom.mal
        sql/scripts/40_json.sql
        sql/test/json/Tests/All
        sql/test/json/Tests/books.stable.out
Branch: default
Log Message:

Add plain text generation.


diffs (206 lines):

diff --git a/monetdb5/modules/atoms/json_atom.c 
b/monetdb5/modules/atoms/json_atom.c
--- a/monetdb5/modules/atoms/json_atom.c
+++ b/monetdb5/modules/atoms/json_atom.c
@@ -1546,8 +1546,42 @@ JSONpathValidation(char *expr, pathterm 
        return MAL_SUCCEED;
 }
 
-str
-JSONpath(json *ret, json *js, str *expr)
+static void
+JSONtextInternal(char *result, char *valuebegin, char *valueend)
+{
+       char *s;
+       for ( s= valuebegin; *s && s != valueend; s++){
+               if ( *s =='[' || *s ==']' ||  *s == '{' || *s == '}' || *s == 
',')
+                       continue;
+               if ( *s == '"'){
+                       *result++ = ' ';
+                       for(s++; *s && *s != '"'; s++)
+                               if ( *s == '\\')
+                                       switch (*++s){
+                                       case '\\':
+                                               *result++ = '\\';break;
+                                       case 'r':
+                                               *result++ = '\r';break;
+                                       case 'f':
+                                               *result++ = '\f';break;
+                                       case 't':
+                                               *result++ = '\t';break;
+                                       case 'n':
+                                               *result++ = '\n';break;
+                                       default:
+                                               *result++ = *s;
+                                       }
+                               else
+                                       *result++ = *s;
+                       *result++ = ' ';
+               } else 
+                       *result++ = *s;
+       } 
+       *result = 0;
+}
+
+static str
+JSONpathInternal(json *ret, json *js, str *expr,int flag)
 {
        pathterm terms[MAXTERMS];
        str j, msg = MAL_SUCCEED;
@@ -1567,9 +1601,14 @@ JSONpath(json *ret, json *js, str *expr)
                result = (char *) GDKmalloc(BUFSIZ);
                if (result == NULL)
                        throw(MAL, "json.names", MAL_MALLOC_FAIL);
-               result[0] = '[';
-               result[1] = 0;
-               len = 1;
+               if ( !flag){
+                       result[0] = '[';
+                       result[1] = 0;
+                       len = 1;
+               } else {
+                       result[0] = 0;
+                       len = 0;
+               }
                lim = BUFSIZ;
                idx = INT_MIN;
 
@@ -1639,19 +1678,30 @@ JSONpath(json *ret, json *js, str *expr)
                                        l = valueend - valuebegin;
                                        if (len + l + 3 > lim)
                                                result = GDKrealloc(result, lim 
+= BUFSIZ);
-                                       strncpy(result + len, valuebegin, 
valueend - valuebegin);
-                                       len += l;
-                                       strncpy(result + len, ",", 2);
-                                       len++;
+                                       if ( !flag ){
+                                               strncpy(result + len, 
valuebegin, valueend - valuebegin);
+                                               len += l;
+                                               strncpy(result + len, ",", 2);
+                                               len++;
+                                       } else {
+                                               JSONtextInternal(result + len, 
valuebegin, valueend);
+                                               len += strlen(result+len);
+                                       }
                                }
                                skipblancs;
                        }
                }
-               if (result[1])
-                       result[len - 1] = ']';
-               else {
-                       result[1] = ']';
-                       result[2] = 0;
+               if (result[1]){
+                       if ( !flag )
+                               result[len - 1] = ']';
+                       else result[len] = 0;
+               }else {
+                       if ( flag )
+                               result[0] = 0;
+                       else {
+                               result[1] = ']';
+                               result[2] = 0;
+                       }
                }
                if (old)
                        GDKfree(old);
@@ -1665,3 +1715,13 @@ JSONpath(json *ret, json *js, str *expr)
        *ret = result;
        return msg;
 }
+str
+JSONpath(json *ret, json *js, str *expr)
+{
+       return JSONpathInternal(ret,js,expr,FALSE);
+}
+str
+JSONtext(json *ret, json *js, str *expr)
+{
+       return JSONpathInternal(ret,js,expr,TRUE);
+}
diff --git a/monetdb5/modules/atoms/json_atom.h 
b/monetdb5/modules/atoms/json_atom.h
--- a/monetdb5/modules/atoms/json_atom.h
+++ b/monetdb5/modules/atoms/json_atom.h
@@ -66,4 +66,5 @@ json_export str JSONprelude(int *ret);
 json_export str JSONrenderobject(Client cntxt, MalBlkPtr mb, MalStkPtr stk, 
InstrPtr pci);
 json_export str JSONrenderarray(Client cntxt, MalBlkPtr mb, MalStkPtr stk, 
InstrPtr pci);
 json_export str JSONpath( json *ret, json *js, str *expr);
+json_export str JSONtext( json *ret, json *js, str *expr);
 #endif /* JSON_H */
diff --git a/monetdb5/modules/atoms/json_atom.mal 
b/monetdb5/modules/atoms/json_atom.mal
--- a/monetdb5/modules/atoms/json_atom.mal
+++ b/monetdb5/modules/atoms/json_atom.mal
@@ -119,4 +119,9 @@ address JSONrenderarray;
 command path(js:json,e:str):json
 address JSONpath
 comment "Simple JSON path accessor";
+
+command text(js:json,e:str):str
+address JSONtext
+comment "Simple JSON path accessor, returning the concatenated string";
+
 json.prelude();
diff --git a/sql/scripts/40_json.sql b/sql/scripts/40_json.sql
--- a/sql/scripts/40_json.sql
+++ b/sql/scripts/40_json.sql
@@ -31,6 +31,10 @@ returns json external name json.filteral
 create function sys.json_path(js json, e string)
 returns json external name json.path;
 
+-- a simple path extractor as plain text
+create function sys.json_text(js json, e string)
+returns string external name json.text;
+
 -- test string for JSON compliancy
 create function sys.json_isvalid(js string)
 returns bool external name json.isvalid;
diff --git a/sql/test/json/Tests/All b/sql/test/json/Tests/All
--- a/sql/test/json/Tests/All
+++ b/sql/test/json/Tests/All
@@ -1,2 +1,3 @@
 parsing
 books
+pgexample
diff --git a/sql/test/json/Tests/books.stable.out 
b/sql/test/json/Tests/books.stable.out
--- a/sql/test/json/Tests/books.stable.out
+++ b/sql/test/json/Tests/books.stable.out
@@ -88,8 +88,8 @@ Ready.
 % sys.L # table_name
 % json_path_j # name
 % json # type
-% 12 # length
-[ "[19.95\n    ]"      ]
+% 7 # length
+[ "[19.95]"    ]
 #SELECT json_path(j,'store.book.author[1]') FROM books;
 % sys.L # table_name
 % json_path_j # name
diff --git a/sql/test/json/Tests/pgexample.sql 
b/sql/test/json/Tests/pgexample.sql
new file mode 100644
--- /dev/null
+++ b/sql/test/json/Tests/pgexample.sql
@@ -0,0 +1,24 @@
+-- 
http://michael.otacoo.com/postgresql-2/postgres-9-3-feature-highlight-json-operators/
+CREATE TABLE jsonTbl (a int, b json);
+
+INSERT INTO jsonTbl  VALUES (1, '{"f1":1,"f2":true,"f3":"Hi I''m 
\\"Daisy\\""}');
+INSERT INTO jsonTbl VALUES (2, '{"f1":{"f11":11,"f12":12},"f2":2}');
+INSERT INTO jsonTbl VALUES (3, '{"f1":[1,"Robert \\"M\\"",true],"f2":[2,"Kevin 
\\"K\\"",false]}');
+
+--The first operator is “->”, that can be used to fetch field values directly 
from JSON data. It can be used with a text value identifying the key of field.
+-- SELECT b->'f1' AS f1, b->'f3' AS f3 FROM jsonTbl WHERE a = 1;
+SELECT  json_path(b,'f1') AS f1, json_path(b,'f3') FROM jsonTbl WHERE a =1;
+
+--Multiple keys can also be used in chain to retrieve data or another JSON 
subset of data.
+-- SELECT b->'f1'->'f12' AS f12 FROM jsonTbl WHERE a = 2;
+ SELECT json_path(b,'f1.f12') AS f12 FROM jsonTbl WHERE a = 2;
+
+--When an integer is used as key, you can fetch data directly in a stored 
array, like that for example:
+-- SELECT b->'f1'->0 as f1_0 FROM jsonTbl WHERE a = 3;
+SELECT json_path(b,'f1[0]') as f1_0 FROM jsonTbl WHERE a = 3;
+
+--The second operator added is “->>”. Contrary to “->” that returns a JSON 
legal text, “->>” returns plain text.
+SELECT  json_path(b,'f3') AS f1, json_text(b,'f3') FROM jsonTbl WHERE a =1;
+SELECT json_path(b,'f1[0]') as f1_0 , json_text(b,'f1[0]')FROM jsonTbl WHERE a 
= 3;
+
+drop table jsonTbl;
_______________________________________________
checkin-list mailing list
[email protected]
http://mail.monetdb.org/mailman/listinfo/checkin-list

Reply via email to