blob: 274749726d3c6d68a086a014bc0959c1f34ffe41 [file] [log] [blame]
drh5fa5c102015-08-12 16:49:40 +00001/*
2** 2015-08-12
3**
4** The author disclaims copyright to this source code. In place of
5** a legal notice, here is a blessing:
6**
7** May you do good and not evil.
8** May you find forgiveness for yourself and forgive others.
9** May you share freely, never taking more than you give.
10**
11******************************************************************************
12**
13** This SQLite extension implements JSON functions. The interface is
14** modeled after MySQL JSON functions:
15**
16** https://dev.mysql.com/doc/refman/5.7/en/json.html
17**
drh5634cc02015-08-17 11:28:03 +000018** For the time being, all JSON is stored as pure text. (We might add
19** a JSONB type in the future which stores a binary encoding of JSON in
20** a BLOB, but there is no support for JSONB in the current implementation.)
drh5fa5c102015-08-12 16:49:40 +000021*/
22#include "sqlite3ext.h"
23SQLITE_EXTENSION_INIT1
24#include <assert.h>
25#include <string.h>
drhe9c37f32015-08-15 21:25:36 +000026#include <ctype.h>
drh987eb1f2015-08-17 15:17:37 +000027#include <stdlib.h>
drh5fa5c102015-08-12 16:49:40 +000028
29/* Unsigned integer types */
30typedef sqlite3_uint64 u64;
31typedef unsigned int u32;
32typedef unsigned char u8;
33
drh52216ad2015-08-18 02:28:03 +000034/* Objects */
35typedef struct Json Json;
36typedef struct JsonNode JsonNode;
37typedef struct JsonParse JsonParse;
38
drh5634cc02015-08-17 11:28:03 +000039/* An instance of this object represents a JSON string
40** under construction. Really, this is a generic string accumulator
41** that can be and is used to create strings other than JSON.
drh5fa5c102015-08-12 16:49:40 +000042*/
drh5fa5c102015-08-12 16:49:40 +000043struct Json {
44 sqlite3_context *pCtx; /* Function context - put error messages here */
drh5634cc02015-08-17 11:28:03 +000045 char *zBuf; /* Append JSON content here */
drh5fa5c102015-08-12 16:49:40 +000046 u64 nAlloc; /* Bytes of storage available in zBuf[] */
47 u64 nUsed; /* Bytes of zBuf[] currently used */
48 u8 bStatic; /* True if zBuf is static space */
drhd0960592015-08-17 21:22:32 +000049 u8 bErr; /* True if an error has been encountered */
drh5fa5c102015-08-12 16:49:40 +000050 char zSpace[100]; /* Initial static space */
51};
52
drhe9c37f32015-08-15 21:25:36 +000053/* JSON type values
drhbd0621b2015-08-13 13:54:59 +000054*/
drhe9c37f32015-08-15 21:25:36 +000055#define JSON_NULL 0
56#define JSON_TRUE 1
57#define JSON_FALSE 2
58#define JSON_INT 3
59#define JSON_REAL 4
60#define JSON_STRING 5
61#define JSON_ARRAY 6
62#define JSON_OBJECT 7
63
drh987eb1f2015-08-17 15:17:37 +000064/*
65** Names of the various JSON types:
66*/
67static const char * const jsonType[] = {
68 "null", "true", "false", "integer", "real", "text", "array", "object"
69};
70
drh301eecc2015-08-17 20:14:19 +000071/* Bit values for the JsonNode.jnFlag field
72*/
73#define JNODE_RAW 0x01 /* Content is raw, not JSON encoded */
74#define JNODE_ESCAPE 0x02 /* Content is text with \ escapes */
75#define JNODE_REMOVE 0x04 /* Do not output */
drhd0960592015-08-17 21:22:32 +000076#define JNODE_REPLACE 0x08 /* Replace with JsonNode.iVal */
drh52216ad2015-08-18 02:28:03 +000077#define JNODE_APPEND 0x10 /* More ARRAY/OBJECT entries at u.iAppend */
drh301eecc2015-08-17 20:14:19 +000078
drh987eb1f2015-08-17 15:17:37 +000079
drhe9c37f32015-08-15 21:25:36 +000080/* A single node of parsed JSON
81*/
drhe9c37f32015-08-15 21:25:36 +000082struct JsonNode {
drh5634cc02015-08-17 11:28:03 +000083 u8 eType; /* One of the JSON_ type values */
drh301eecc2015-08-17 20:14:19 +000084 u8 jnFlags; /* JNODE flags */
drhd0960592015-08-17 21:22:32 +000085 u8 iVal; /* Replacement value when JNODE_REPLACE */
drhe9c37f32015-08-15 21:25:36 +000086 u32 n; /* Bytes of content, or number of sub-nodes */
drh52216ad2015-08-18 02:28:03 +000087 union {
drh0042a972015-08-18 12:59:58 +000088 const char *zJContent; /* Content for INT, REAL, and STRING */
89 u32 iAppend; /* More terms for ARRAY and OBJECT */
drh52216ad2015-08-18 02:28:03 +000090 } u;
drhe9c37f32015-08-15 21:25:36 +000091};
92
93/* A completely parsed JSON string
94*/
drhe9c37f32015-08-15 21:25:36 +000095struct JsonParse {
96 u32 nNode; /* Number of slots of aNode[] used */
97 u32 nAlloc; /* Number of slots of aNode[] allocated */
98 JsonNode *aNode; /* Array of nodes containing the parse */
99 const char *zJson; /* Original JSON string */
100 u8 oom; /* Set to true if out of memory */
101};
102
drh301eecc2015-08-17 20:14:19 +0000103/*
104** Return the number of consecutive JsonNode slots need to represent
105** the parsed JSON at pNode. The minimum answer is 1. For ARRAY and
106** OBJECT types, the number might be larger.
drh52216ad2015-08-18 02:28:03 +0000107**
108** Appended elements are not counted. The value returned is the number
109** by which the JsonNode counter should increment in order to go to the
110** next peer value.
drh301eecc2015-08-17 20:14:19 +0000111*/
drhd0960592015-08-17 21:22:32 +0000112static u32 jsonSize(JsonNode *pNode){
drh301eecc2015-08-17 20:14:19 +0000113 return pNode->eType>=JSON_ARRAY ? pNode->n+1 : 1;
114}
115
drh5fa5c102015-08-12 16:49:40 +0000116/* Set the Json object to an empty string
117*/
118static void jsonZero(Json *p){
119 p->zBuf = p->zSpace;
120 p->nAlloc = sizeof(p->zSpace);
121 p->nUsed = 0;
122 p->bStatic = 1;
123}
124
125/* Initialize the Json object
126*/
127static void jsonInit(Json *p, sqlite3_context *pCtx){
128 p->pCtx = pCtx;
drhd0960592015-08-17 21:22:32 +0000129 p->bErr = 0;
drh5fa5c102015-08-12 16:49:40 +0000130 jsonZero(p);
131}
132
133
134/* Free all allocated memory and reset the Json object back to its
135** initial state.
136*/
137static void jsonReset(Json *p){
138 if( !p->bStatic ) sqlite3_free(p->zBuf);
139 jsonZero(p);
140}
141
142
143/* Report an out-of-memory (OOM) condition
144*/
145static void jsonOom(Json *p){
drhd0960592015-08-17 21:22:32 +0000146 if( !p->bErr ){
147 p->bErr = 1;
148 sqlite3_result_error_nomem(p->pCtx);
149 jsonReset(p);
150 }
drh5fa5c102015-08-12 16:49:40 +0000151}
152
153/* Enlarge pJson->zBuf so that it can hold at least N more bytes.
154** Return zero on success. Return non-zero on an OOM error
155*/
156static int jsonGrow(Json *p, u32 N){
drh301eecc2015-08-17 20:14:19 +0000157 u64 nTotal = N<p->nAlloc ? p->nAlloc*2 : p->nAlloc+N+10;
drh5fa5c102015-08-12 16:49:40 +0000158 char *zNew;
159 if( p->bStatic ){
drhd0960592015-08-17 21:22:32 +0000160 if( p->bErr ) return 1;
drh5fa5c102015-08-12 16:49:40 +0000161 zNew = sqlite3_malloc64(nTotal);
162 if( zNew==0 ){
163 jsonOom(p);
164 return SQLITE_NOMEM;
165 }
166 memcpy(zNew, p->zBuf, p->nUsed);
167 p->zBuf = zNew;
168 p->bStatic = 0;
169 }else{
170 zNew = sqlite3_realloc64(p->zBuf, nTotal);
171 if( zNew==0 ){
172 jsonOom(p);
173 return SQLITE_NOMEM;
174 }
175 p->zBuf = zNew;
176 }
177 p->nAlloc = nTotal;
178 return SQLITE_OK;
179}
180
181/* Append N bytes from zIn onto the end of the Json string.
182*/
183static void jsonAppendRaw(Json *p, const char *zIn, u32 N){
184 if( (N+p->nUsed >= p->nAlloc) && jsonGrow(p,N)!=0 ) return;
185 memcpy(p->zBuf+p->nUsed, zIn, N);
186 p->nUsed += N;
187}
188
drhd0960592015-08-17 21:22:32 +0000189#ifdef SQLITE_DEBUG
drhe9c37f32015-08-15 21:25:36 +0000190/* Append the zero-terminated string zIn
191*/
192static void jsonAppend(Json *p, const char *zIn){
193 jsonAppendRaw(p, zIn, (u32)strlen(zIn));
194}
drhd0960592015-08-17 21:22:32 +0000195#endif
drhe9c37f32015-08-15 21:25:36 +0000196
drh5634cc02015-08-17 11:28:03 +0000197/* Append a single character
198*/
199static void jsonAppendChar(Json *p, char c){
200 if( p->nUsed>=p->nAlloc && jsonGrow(p,1)!=0 ) return;
201 p->zBuf[p->nUsed++] = c;
202}
203
drh301eecc2015-08-17 20:14:19 +0000204/* Append a comma separator to the output buffer, if the previous
205** character is not '[' or '{'.
206*/
207static void jsonAppendSeparator(Json *p){
208 char c;
209 if( p->nUsed==0 ) return;
210 c = p->zBuf[p->nUsed-1];
211 if( c!='[' && c!='{' ) jsonAppendChar(p, ',');
212}
213
drh5fa5c102015-08-12 16:49:40 +0000214/* Append the N-byte string in zIn to the end of the Json string
215** under construction. Enclose the string in "..." and escape
216** any double-quotes or backslash characters contained within the
217** string.
218*/
219static void jsonAppendString(Json *p, const char *zIn, u32 N){
220 u32 i;
221 if( (N+p->nUsed+2 >= p->nAlloc) && jsonGrow(p,N+2)!=0 ) return;
222 p->zBuf[p->nUsed++] = '"';
223 for(i=0; i<N; i++){
224 char c = zIn[i];
225 if( c=='"' || c=='\\' ){
226 if( (p->nUsed+N+1-i > p->nAlloc) && jsonGrow(p,N+1-i)!=0 ) return;
227 p->zBuf[p->nUsed++] = '\\';
228 }
229 p->zBuf[p->nUsed++] = c;
230 }
231 p->zBuf[p->nUsed++] = '"';
232}
233
drhd0960592015-08-17 21:22:32 +0000234/*
235** Append a function parameter value to the JSON string under
236** construction.
237*/
238static void jsonAppendValue(
239 Json *p, /* Append to this JSON string */
240 sqlite3_value *pValue /* Value to append */
241){
242 switch( sqlite3_value_type(pValue) ){
243 case SQLITE_NULL: {
244 jsonAppendRaw(p, "null", 4);
245 break;
246 }
247 case SQLITE_INTEGER:
248 case SQLITE_FLOAT: {
249 const char *z = (const char*)sqlite3_value_text(pValue);
250 u32 n = (u32)sqlite3_value_bytes(pValue);
251 jsonAppendRaw(p, z, n);
252 break;
253 }
254 case SQLITE_TEXT: {
255 const char *z = (const char*)sqlite3_value_text(pValue);
256 u32 n = (u32)sqlite3_value_bytes(pValue);
257 jsonAppendString(p, z, n);
258 break;
259 }
260 default: {
261 if( p->bErr==0 ){
262 sqlite3_result_error(p->pCtx, "JSON cannot hold BLOB values", -1);
263 p->bErr = 1;
264 jsonReset(p);
265 }
266 break;
267 }
268 }
269}
270
271
drhbd0621b2015-08-13 13:54:59 +0000272/* Make the JSON in p the result of the SQL function.
drh5fa5c102015-08-12 16:49:40 +0000273*/
274static void jsonResult(Json *p){
drhd0960592015-08-17 21:22:32 +0000275 if( p->bErr==0 ){
drh5fa5c102015-08-12 16:49:40 +0000276 sqlite3_result_text64(p->pCtx, p->zBuf, p->nUsed,
277 p->bStatic ? SQLITE_TRANSIENT : sqlite3_free,
278 SQLITE_UTF8);
279 jsonZero(p);
280 }
281 assert( p->bStatic );
282}
283
drh5634cc02015-08-17 11:28:03 +0000284/*
285** Convert the JsonNode pNode into a pure JSON string and
286** append to pOut. Subsubstructure is also included. Return
287** the number of JsonNode objects that are encoded.
drhbd0621b2015-08-13 13:54:59 +0000288*/
drh52216ad2015-08-18 02:28:03 +0000289static void jsonRenderNode(
drhd0960592015-08-17 21:22:32 +0000290 JsonNode *pNode, /* The node to render */
291 Json *pOut, /* Write JSON here */
292 sqlite3_value **aReplace /* Replacement values */
293){
drh5634cc02015-08-17 11:28:03 +0000294 switch( pNode->eType ){
295 case JSON_NULL: {
296 jsonAppendRaw(pOut, "null", 4);
297 break;
298 }
299 case JSON_TRUE: {
300 jsonAppendRaw(pOut, "true", 4);
301 break;
302 }
303 case JSON_FALSE: {
304 jsonAppendRaw(pOut, "false", 5);
305 break;
306 }
307 case JSON_STRING: {
drh301eecc2015-08-17 20:14:19 +0000308 if( pNode->jnFlags & JNODE_RAW ){
drh52216ad2015-08-18 02:28:03 +0000309 jsonAppendString(pOut, pNode->u.zJContent, pNode->n);
drh5634cc02015-08-17 11:28:03 +0000310 break;
311 }
312 /* Fall through into the next case */
313 }
314 case JSON_REAL:
315 case JSON_INT: {
drh52216ad2015-08-18 02:28:03 +0000316 jsonAppendRaw(pOut, pNode->u.zJContent, pNode->n);
drh5634cc02015-08-17 11:28:03 +0000317 break;
318 }
319 case JSON_ARRAY: {
drh52216ad2015-08-18 02:28:03 +0000320 u32 j = 1;
drh5634cc02015-08-17 11:28:03 +0000321 jsonAppendChar(pOut, '[');
drh52216ad2015-08-18 02:28:03 +0000322 for(;;){
323 while( j<=pNode->n ){
324 if( pNode[j].jnFlags & (JNODE_REMOVE|JNODE_REPLACE) ){
325 if( pNode[j].jnFlags & JNODE_REPLACE ){
326 jsonAppendSeparator(pOut);
327 jsonAppendValue(pOut, aReplace[pNode[j].iVal]);
328 }
329 }else{
drhd0960592015-08-17 21:22:32 +0000330 jsonAppendSeparator(pOut);
drh52216ad2015-08-18 02:28:03 +0000331 jsonRenderNode(&pNode[j], pOut, aReplace);
drhd0960592015-08-17 21:22:32 +0000332 }
333 j += jsonSize(&pNode[j]);
drh301eecc2015-08-17 20:14:19 +0000334 }
drh52216ad2015-08-18 02:28:03 +0000335 if( (pNode->jnFlags & JNODE_APPEND)==0 ) break;
336 pNode = &pNode[pNode->u.iAppend];
337 j = 1;
drh5634cc02015-08-17 11:28:03 +0000338 }
339 jsonAppendChar(pOut, ']');
340 break;
341 }
342 case JSON_OBJECT: {
drh52216ad2015-08-18 02:28:03 +0000343 u32 j = 1;
drh5634cc02015-08-17 11:28:03 +0000344 jsonAppendChar(pOut, '{');
drh52216ad2015-08-18 02:28:03 +0000345 for(;;){
346 while( j<=pNode->n ){
347 if( (pNode[j+1].jnFlags & JNODE_REMOVE)==0 ){
348 jsonAppendSeparator(pOut);
349 jsonRenderNode(&pNode[j], pOut, aReplace);
350 jsonAppendChar(pOut, ':');
351 if( pNode[j+1].jnFlags & JNODE_REPLACE ){
352 jsonAppendValue(pOut, aReplace[pNode[j+1].iVal]);
353 }else{
354 jsonRenderNode(&pNode[j+1], pOut, aReplace);
355 }
drhd0960592015-08-17 21:22:32 +0000356 }
drh52216ad2015-08-18 02:28:03 +0000357 j += 1 + jsonSize(&pNode[j+1]);
drh301eecc2015-08-17 20:14:19 +0000358 }
drh52216ad2015-08-18 02:28:03 +0000359 if( (pNode->jnFlags & JNODE_APPEND)==0 ) break;
360 pNode = &pNode[pNode->u.iAppend];
361 j = 1;
drh5634cc02015-08-17 11:28:03 +0000362 }
363 jsonAppendChar(pOut, '}');
364 break;
365 }
drhbd0621b2015-08-13 13:54:59 +0000366 }
drh5634cc02015-08-17 11:28:03 +0000367}
368
369/*
370** Make the JsonNode the return value of the function.
371*/
drhd0960592015-08-17 21:22:32 +0000372static void jsonReturn(
373 JsonNode *pNode, /* Node to return */
374 sqlite3_context *pCtx, /* Return value for this function */
375 sqlite3_value **aReplace /* Array of replacement values */
376){
drh5634cc02015-08-17 11:28:03 +0000377 switch( pNode->eType ){
378 case JSON_NULL: {
379 sqlite3_result_null(pCtx);
380 break;
381 }
382 case JSON_TRUE: {
383 sqlite3_result_int(pCtx, 1);
384 break;
385 }
386 case JSON_FALSE: {
387 sqlite3_result_int(pCtx, 0);
388 break;
389 }
drh987eb1f2015-08-17 15:17:37 +0000390 case JSON_REAL: {
drh52216ad2015-08-18 02:28:03 +0000391 double r = strtod(pNode->u.zJContent, 0);
drh987eb1f2015-08-17 15:17:37 +0000392 sqlite3_result_double(pCtx, r);
drh5634cc02015-08-17 11:28:03 +0000393 break;
394 }
drh987eb1f2015-08-17 15:17:37 +0000395 case JSON_INT: {
396 sqlite3_int64 i = 0;
drh52216ad2015-08-18 02:28:03 +0000397 const char *z = pNode->u.zJContent;
drh987eb1f2015-08-17 15:17:37 +0000398 if( z[0]=='-' ){ z++; }
399 while( z[0]>='0' && z[0]<='9' ){ i = i*10 + *(z++) - '0'; }
drh52216ad2015-08-18 02:28:03 +0000400 if( pNode->u.zJContent[0]=='-' ){ i = -i; }
drh987eb1f2015-08-17 15:17:37 +0000401 sqlite3_result_int64(pCtx, i);
402 break;
403 }
drh5634cc02015-08-17 11:28:03 +0000404 case JSON_STRING: {
drh301eecc2015-08-17 20:14:19 +0000405 if( pNode->jnFlags & JNODE_RAW ){
drh52216ad2015-08-18 02:28:03 +0000406 sqlite3_result_text(pCtx, pNode->u.zJContent, pNode->n,
407 SQLITE_TRANSIENT);
drh301eecc2015-08-17 20:14:19 +0000408 }else if( (pNode->jnFlags & JNODE_ESCAPE)==0 ){
drh987eb1f2015-08-17 15:17:37 +0000409 /* JSON formatted without any backslash-escapes */
drh52216ad2015-08-18 02:28:03 +0000410 sqlite3_result_text(pCtx, pNode->u.zJContent+1, pNode->n-2,
drh987eb1f2015-08-17 15:17:37 +0000411 SQLITE_TRANSIENT);
drh5634cc02015-08-17 11:28:03 +0000412 }else{
413 /* Translate JSON formatted string into raw text */
drh987eb1f2015-08-17 15:17:37 +0000414 u32 i;
415 u32 n = pNode->n;
drh52216ad2015-08-18 02:28:03 +0000416 const char *z = pNode->u.zJContent;
drh987eb1f2015-08-17 15:17:37 +0000417 char *zOut;
418 u32 j;
419 zOut = sqlite3_malloc( n+1 );
420 if( zOut==0 ){
421 sqlite3_result_error_nomem(pCtx);
422 break;
423 }
424 for(i=1, j=0; i<n-1; i++){
425 char c = z[i];
426 if( c!='\\' && z[i+1] ){
427 zOut[j++] = c;
428 }else{
429 c = z[++i];
430 if( c=='u' && z[1] ){
431 u32 v = 0, k;
432 z++;
433 for(k=0; k<4 && z[k]; k++){
434 c = z[0];
435 if( c>='0' && c<='9' ) v = v*16 + c - '0';
436 else if( c>='A' && c<='F' ) v = v*16 + c - 'A' + 10;
437 else if( c>='a' && c<='f' ) v = v*16 + c - 'a' + 10;
438 else break;
439 z++;
440 }
441 if( v<=0x7f ){
442 zOut[j++] = v;
443 }else if( v<=0x7ff ){
444 zOut[j++] = 0xc0 | (v>>6);
445 zOut[j++] = 0x80 | (v&0x3f);
446 }else if( v<=0xffff ){
447 zOut[j++] = 0xe0 | (v>>12);
448 zOut[j++] = 0x80 | ((v>>6)&0x3f);
449 zOut[j++] = 0x80 | (v&0x3f);
450 }else if( v<=0x10ffff ){
451 zOut[j++] = 0xf0 | (v>>18);
452 zOut[j++] = 0x80 | ((v>>12)&0x3f);
453 zOut[j++] = 0x80 | ((v>>6)&0x3f);
454 zOut[j++] = 0x80 | (v&0x3f);
455 }
456 }else{
457 if( c=='b' ){
458 c = '\b';
459 }else if( c=='f' ){
460 c = '\f';
461 }else if( c=='n' ){
462 c = '\n';
463 }else if( c=='r' ){
464 c = '\r';
465 }else if( c=='t' ){
466 c = '\t';
467 }
468 zOut[j++] = c;
469 }
470 }
471 }
472 zOut[j] = 0;
473 sqlite3_result_text(pCtx, zOut, j, sqlite3_free);
drh5634cc02015-08-17 11:28:03 +0000474 }
475 break;
476 }
477 case JSON_ARRAY:
478 case JSON_OBJECT: {
479 Json s;
480 jsonInit(&s, pCtx);
drhd0960592015-08-17 21:22:32 +0000481 jsonRenderNode(pNode, &s, aReplace);
drh5634cc02015-08-17 11:28:03 +0000482 jsonResult(&s);
483 break;
484 }
485 }
drhbd0621b2015-08-13 13:54:59 +0000486}
487
drh5fa5c102015-08-12 16:49:40 +0000488/*
drhe9c37f32015-08-15 21:25:36 +0000489** Create a new JsonNode instance based on the arguments and append that
490** instance to the JsonParse. Return the index in pParse->aNode[] of the
491** new node, or -1 if a memory allocation fails.
492*/
493static int jsonParseAddNode(
494 JsonParse *pParse, /* Append the node to this object */
495 u32 eType, /* Node type */
496 u32 n, /* Content size or sub-node count */
497 const char *zContent /* Content */
498){
499 JsonNode *p;
500 if( pParse->nNode>=pParse->nAlloc ){
501 u32 nNew;
502 JsonNode *pNew;
503 if( pParse->oom ) return -1;
504 nNew = pParse->nAlloc*2 + 10;
505 if( nNew<=pParse->nNode ){
506 pParse->oom = 1;
507 return -1;
508 }
509 pNew = sqlite3_realloc(pParse->aNode, sizeof(JsonNode)*nNew);
510 if( pNew==0 ){
511 pParse->oom = 1;
512 return -1;
513 }
514 pParse->nAlloc = nNew;
515 pParse->aNode = pNew;
516 }
517 p = &pParse->aNode[pParse->nNode];
drh5634cc02015-08-17 11:28:03 +0000518 p->eType = (u8)eType;
drh301eecc2015-08-17 20:14:19 +0000519 p->jnFlags = 0;
drhd0960592015-08-17 21:22:32 +0000520 p->iVal = 0;
drhe9c37f32015-08-15 21:25:36 +0000521 p->n = n;
drh52216ad2015-08-18 02:28:03 +0000522 p->u.zJContent = zContent;
drhe9c37f32015-08-15 21:25:36 +0000523 return pParse->nNode++;
524}
525
526/*
527** Parse a single JSON value which begins at pParse->zJson[i]. Return the
528** index of the first character past the end of the value parsed.
529**
530** Return negative for a syntax error. Special cases: return -2 if the
531** first non-whitespace character is '}' and return -3 if the first
532** non-whitespace character is ']'.
533*/
534static int jsonParseValue(JsonParse *pParse, u32 i){
535 char c;
536 u32 j;
537 u32 iThis;
538 int x;
539 while( isspace(pParse->zJson[i]) ){ i++; }
540 if( (c = pParse->zJson[i])==0 ) return 0;
541 if( c=='{' ){
542 /* Parse object */
543 iThis = jsonParseAddNode(pParse, JSON_OBJECT, 0, 0);
544 if( iThis<0 ) return -1;
545 for(j=i+1;;j++){
546 while( isspace(pParse->zJson[j]) ){ j++; }
547 x = jsonParseValue(pParse, j);
548 if( x<0 ){
549 if( x==(-2) && pParse->nNode==iThis+1 ) return j+1;
550 return -1;
551 }
552 if( pParse->aNode[pParse->nNode-1].eType!=JSON_STRING ) return -1;
553 j = x;
554 while( isspace(pParse->zJson[j]) ){ j++; }
555 if( pParse->zJson[j]!=':' ) return -1;
556 j++;
557 x = jsonParseValue(pParse, j);
558 if( x<0 ) return -1;
559 j = x;
560 while( isspace(pParse->zJson[j]) ){ j++; }
561 c = pParse->zJson[j];
562 if( c==',' ) continue;
563 if( c!='}' ) return -1;
564 break;
565 }
566 pParse->aNode[iThis].n = pParse->nNode - iThis - 1;
567 return j+1;
568 }else if( c=='[' ){
569 /* Parse array */
570 iThis = jsonParseAddNode(pParse, JSON_ARRAY, 0, 0);
571 if( iThis<0 ) return -1;
572 for(j=i+1;;j++){
573 while( isspace(pParse->zJson[j]) ){ j++; }
574 x = jsonParseValue(pParse, j);
575 if( x<0 ){
576 if( x==(-3) && pParse->nNode==iThis+1 ) return j+1;
577 return -1;
578 }
579 j = x;
580 while( isspace(pParse->zJson[j]) ){ j++; }
581 c = pParse->zJson[j];
582 if( c==',' ) continue;
583 if( c!=']' ) return -1;
584 break;
585 }
586 pParse->aNode[iThis].n = pParse->nNode - iThis - 1;
587 return j+1;
588 }else if( c=='"' ){
589 /* Parse string */
drh301eecc2015-08-17 20:14:19 +0000590 u8 jnFlags = 0;
drhe9c37f32015-08-15 21:25:36 +0000591 j = i+1;
592 for(;;){
593 c = pParse->zJson[j];
594 if( c==0 ) return -1;
595 if( c=='\\' ){
596 c = pParse->zJson[++j];
597 if( c==0 ) return -1;
drh301eecc2015-08-17 20:14:19 +0000598 jnFlags = JNODE_ESCAPE;
drhe9c37f32015-08-15 21:25:36 +0000599 }else if( c=='"' ){
600 break;
601 }
602 j++;
603 }
604 jsonParseAddNode(pParse, JSON_STRING, j+1-i, &pParse->zJson[i]);
drh301eecc2015-08-17 20:14:19 +0000605 pParse->aNode[pParse->nNode-1].jnFlags = jnFlags;
drhe9c37f32015-08-15 21:25:36 +0000606 return j+1;
607 }else if( c=='n'
608 && strncmp(pParse->zJson+i,"null",4)==0
drhb2cd10e2015-08-15 21:29:14 +0000609 && !isalnum(pParse->zJson[i+4]) ){
drhe9c37f32015-08-15 21:25:36 +0000610 jsonParseAddNode(pParse, JSON_NULL, 0, 0);
611 return i+4;
612 }else if( c=='t'
613 && strncmp(pParse->zJson+i,"true",4)==0
drhb2cd10e2015-08-15 21:29:14 +0000614 && !isalnum(pParse->zJson[i+4]) ){
drhe9c37f32015-08-15 21:25:36 +0000615 jsonParseAddNode(pParse, JSON_TRUE, 0, 0);
616 return i+4;
617 }else if( c=='f'
618 && strncmp(pParse->zJson+i,"false",5)==0
drhb2cd10e2015-08-15 21:29:14 +0000619 && !isalnum(pParse->zJson[i+5]) ){
drhe9c37f32015-08-15 21:25:36 +0000620 jsonParseAddNode(pParse, JSON_FALSE, 0, 0);
621 return i+5;
622 }else if( c=='-' || (c>='0' && c<='9') ){
623 /* Parse number */
624 u8 seenDP = 0;
625 u8 seenE = 0;
626 j = i+1;
627 for(;; j++){
628 c = pParse->zJson[j];
629 if( c>='0' && c<='9' ) continue;
630 if( c=='.' ){
631 if( pParse->zJson[j-1]=='-' ) return -1;
632 if( seenDP ) return -1;
633 seenDP = 1;
634 continue;
635 }
636 if( c=='e' || c=='E' ){
637 if( pParse->zJson[j-1]<'0' ) return -1;
638 if( seenE ) return -1;
639 seenDP = seenE = 1;
640 c = pParse->zJson[j+1];
641 if( c=='+' || c=='-' ) j++;
642 continue;
643 }
644 break;
645 }
646 if( pParse->zJson[j-1]<'0' ) return -1;
647 jsonParseAddNode(pParse, seenDP ? JSON_REAL : JSON_INT,
648 j - i, &pParse->zJson[i]);
649 return j;
650 }else if( c=='}' ){
651 return -2; /* End of {...} */
652 }else if( c==']' ){
653 return -3; /* End of [...] */
654 }else{
655 return -1; /* Syntax error */
656 }
657}
658
659/*
660** Parse a complete JSON string. Return 0 on success or non-zero if there
661** are any errors. If an error occurs, free all memory associated with
662** pParse.
663**
664** pParse is uninitialized when this routine is called.
665*/
666static int jsonParse(JsonParse *pParse, const char *zJson){
667 int i;
668 if( zJson==0 ) return 1;
669 memset(pParse, 0, sizeof(*pParse));
670 pParse->zJson = zJson;
671 i = jsonParseValue(pParse, 0);
672 if( i>0 ){
673 while( isspace(zJson[i]) ) i++;
674 if( zJson[i] ) i = -1;
675 }
676 if( i<0 ){
677 sqlite3_free(pParse->aNode);
678 pParse->aNode = 0;
679 pParse->nNode = 0;
680 pParse->nAlloc = 0;
681 return 1;
682 }
683 return 0;
684}
drh301eecc2015-08-17 20:14:19 +0000685
drh52216ad2015-08-18 02:28:03 +0000686/* forward declaration */
687static JsonNode *jsonLookupAppend(JsonParse*,const char*,int*);
688
drh987eb1f2015-08-17 15:17:37 +0000689/*
690** Search along zPath to find the node specified. Return a pointer
691** to that node, or NULL if zPath is malformed or if there is no such
692** node.
drh52216ad2015-08-18 02:28:03 +0000693**
694** If pApnd!=0, then try to append new nodes to complete zPath if it is
695** possible to do so and if no existing node corresponds to zPath. If
696** new nodes are appended *pApnd is set to 1.
drh987eb1f2015-08-17 15:17:37 +0000697*/
drh52216ad2015-08-18 02:28:03 +0000698static JsonNode *jsonLookup(
699 JsonParse *pParse, /* The JSON to search */
700 u32 iRoot, /* Begin the search at this node */
701 const char *zPath, /* The path to search */
702 int *pApnd /* Append nodes to complete path if not NULL */
703){
704 u32 i, j, k;
705 JsonNode *pRoot = &pParse->aNode[iRoot];
drh987eb1f2015-08-17 15:17:37 +0000706 if( zPath[0]==0 ) return pRoot;
707 if( zPath[0]=='.' ){
708 if( pRoot->eType!=JSON_OBJECT ) return 0;
709 zPath++;
710 for(i=0; isalnum(zPath[i]); i++){}
711 if( i==0 ) return 0;
712 j = 1;
drh52216ad2015-08-18 02:28:03 +0000713 for(;;){
714 while( j<=pRoot->n ){
715 if( pRoot[j].n==i+2
716 && strncmp(&pRoot[j].u.zJContent[1],zPath,i)==0
717 ){
718 return jsonLookup(pParse, iRoot+j+1, &zPath[i], pApnd);
719 }
720 j++;
721 j += jsonSize(&pRoot[j]);
drh987eb1f2015-08-17 15:17:37 +0000722 }
drh52216ad2015-08-18 02:28:03 +0000723 if( (pRoot->jnFlags & JNODE_APPEND)==0 ) break;
724 iRoot += pRoot->u.iAppend;
725 pRoot = &pParse->aNode[iRoot];
726 j = 1;
727 }
728 if( pApnd ){
729 k = jsonParseAddNode(pParse, JSON_OBJECT, 2, 0);
730 pRoot->u.iAppend = k - iRoot;
731 pRoot->jnFlags |= JNODE_APPEND;
732 k = jsonParseAddNode(pParse, JSON_STRING, i, zPath);
733 if( !pParse->oom ) pParse->aNode[k].jnFlags |= JNODE_RAW;
734 zPath += i;
735 return jsonLookupAppend(pParse, zPath, pApnd);
drh987eb1f2015-08-17 15:17:37 +0000736 }
737 }else if( zPath[0]=='[' && isdigit(zPath[1]) ){
738 if( pRoot->eType!=JSON_ARRAY ) return 0;
739 i = 0;
740 zPath++;
741 while( isdigit(zPath[0]) ){
742 i = i + zPath[0] - '0';
743 zPath++;
744 }
745 if( zPath[0]!=']' ) return 0;
746 zPath++;
747 j = 1;
drh52216ad2015-08-18 02:28:03 +0000748 for(;;){
749 while( i>0 && j<=pRoot->n ){
750 j += jsonSize(&pRoot[j]);
751 i--;
752 }
753 if( (pRoot->jnFlags & JNODE_APPEND)==0 ) break;
754 iRoot += pRoot->u.iAppend;
755 pRoot = &pParse->aNode[iRoot];
756 j = 1;
drh987eb1f2015-08-17 15:17:37 +0000757 }
758 if( j<=pRoot->n ){
drh52216ad2015-08-18 02:28:03 +0000759 return jsonLookup(pParse, iRoot+j, zPath, pApnd);
760 }
761 if( i==0 && pApnd ){
762 k = jsonParseAddNode(pParse, JSON_ARRAY, 1, 0);
763 pRoot->u.iAppend = k - iRoot;
764 pRoot->jnFlags |= JNODE_APPEND;
765 return jsonLookupAppend(pParse, zPath, pApnd);
drh987eb1f2015-08-17 15:17:37 +0000766 }
767 }
768 return 0;
769}
770
drh52216ad2015-08-18 02:28:03 +0000771/*
772** Append content to pParse that will complete zPath.
773*/
774static JsonNode *jsonLookupAppend(
775 JsonParse *pParse, /* Append content to the JSON parse */
776 const char *zPath, /* Description of content to append */
777 int *pApnd /* Set this flag to 1 */
778){
779 *pApnd = 1;
780 if( zPath[0]==0 ){
781 jsonParseAddNode(pParse, JSON_NULL, 0, 0);
782 return pParse->oom ? 0 : &pParse->aNode[pParse->nNode-1];
783 }
784 if( zPath[0]=='.' ){
785 jsonParseAddNode(pParse, JSON_OBJECT, 0, 0);
786 }else if( strncmp(zPath,"[0]",3)==0 ){
787 jsonParseAddNode(pParse, JSON_ARRAY, 0, 0);
788 }else{
789 return 0;
790 }
791 if( pParse->oom ) return 0;
792 return jsonLookup(pParse, pParse->nNode-1, zPath, pApnd);
793}
794
795
drh987eb1f2015-08-17 15:17:37 +0000796/****************************************************************************
797** SQL functions used for testing and debugging
798****************************************************************************/
drhe9c37f32015-08-15 21:25:36 +0000799
drh301eecc2015-08-17 20:14:19 +0000800#ifdef SQLITE_DEBUG
drhe9c37f32015-08-15 21:25:36 +0000801/*
drh5634cc02015-08-17 11:28:03 +0000802** The json_parse(JSON) function returns a string which describes
drhe9c37f32015-08-15 21:25:36 +0000803** a parse of the JSON provided. Or it returns NULL if JSON is not
804** well-formed.
805*/
drh5634cc02015-08-17 11:28:03 +0000806static void jsonParseFunc(
drhe9c37f32015-08-15 21:25:36 +0000807 sqlite3_context *context,
808 int argc,
809 sqlite3_value **argv
810){
811 Json s; /* Output string - not real JSON */
812 JsonParse x; /* The parse */
813 u32 i;
drh301eecc2015-08-17 20:14:19 +0000814 char zBuf[100];
drhe9c37f32015-08-15 21:25:36 +0000815
816 assert( argc==1 );
817 if( jsonParse(&x, (const char*)sqlite3_value_text(argv[0])) ) return;
818 jsonInit(&s, context);
819 for(i=0; i<x.nNode; i++){
drh301eecc2015-08-17 20:14:19 +0000820 sqlite3_snprintf(sizeof(zBuf), zBuf, "node %3u: %7s n=%d\n",
821 i, jsonType[x.aNode[i].eType], x.aNode[i].n);
drhe9c37f32015-08-15 21:25:36 +0000822 jsonAppend(&s, zBuf);
drh52216ad2015-08-18 02:28:03 +0000823 if( x.aNode[i].u.zJContent!=0 ){
drh301eecc2015-08-17 20:14:19 +0000824 jsonAppendRaw(&s, " text: ", 10);
drh52216ad2015-08-18 02:28:03 +0000825 jsonAppendRaw(&s, x.aNode[i].u.zJContent, x.aNode[i].n);
drhe9c37f32015-08-15 21:25:36 +0000826 jsonAppendRaw(&s, "\n", 1);
827 }
828 }
829 sqlite3_free(x.aNode);
830 jsonResult(&s);
831}
832
drh5634cc02015-08-17 11:28:03 +0000833/*
834** The json_test1(JSON) function parses and rebuilds the JSON string.
835*/
836static void jsonTest1Func(
837 sqlite3_context *context,
838 int argc,
839 sqlite3_value **argv
840){
841 JsonParse x; /* The parse */
842 if( jsonParse(&x, (const char*)sqlite3_value_text(argv[0])) ) return;
drhd0960592015-08-17 21:22:32 +0000843 jsonReturn(x.aNode, context, 0);
drh5634cc02015-08-17 11:28:03 +0000844 sqlite3_free(x.aNode);
845}
846
847/*
848** The json_nodecount(JSON) function returns the number of nodes in the
849** input JSON string.
850*/
851static void jsonNodeCountFunc(
852 sqlite3_context *context,
853 int argc,
854 sqlite3_value **argv
855){
856 JsonParse x; /* The parse */
857 if( jsonParse(&x, (const char*)sqlite3_value_text(argv[0])) ) return;
858 sqlite3_result_int64(context, x.nNode);
859 sqlite3_free(x.aNode);
860}
drh301eecc2015-08-17 20:14:19 +0000861#endif /* SQLITE_DEBUG */
drh5634cc02015-08-17 11:28:03 +0000862
drh987eb1f2015-08-17 15:17:37 +0000863/****************************************************************************
864** SQL function implementations
865****************************************************************************/
866
867/*
868** Implementation of the json_array(VALUE,...) function. Return a JSON
869** array that contains all values given in arguments. Or if any argument
870** is a BLOB, throw an error.
871*/
872static void jsonArrayFunc(
873 sqlite3_context *context,
874 int argc,
875 sqlite3_value **argv
876){
877 int i;
878 Json jx;
drh987eb1f2015-08-17 15:17:37 +0000879
880 jsonInit(&jx, context);
drhd0960592015-08-17 21:22:32 +0000881 jsonAppendChar(&jx, '[');
drh987eb1f2015-08-17 15:17:37 +0000882 for(i=0; i<argc; i++){
drhd0960592015-08-17 21:22:32 +0000883 jsonAppendSeparator(&jx);
884 jsonAppendValue(&jx, argv[i]);
drh987eb1f2015-08-17 15:17:37 +0000885 }
drhd0960592015-08-17 21:22:32 +0000886 jsonAppendChar(&jx, ']');
drh987eb1f2015-08-17 15:17:37 +0000887 jsonResult(&jx);
888}
889
890
891/*
892** json_array_length(JSON)
893** json_array_length(JSON, PATH)
894**
895** Return the number of elements in the top-level JSON array.
896** Return 0 if the input is not a well-formed JSON array.
897*/
898static void jsonArrayLengthFunc(
899 sqlite3_context *context,
900 int argc,
901 sqlite3_value **argv
902){
903 JsonParse x; /* The parse */
904 sqlite3_int64 n = 0;
905 u32 i;
906 const char *zPath;
907
908 if( argc==2 ){
909 zPath = (const char*)sqlite3_value_text(argv[1]);
910 if( zPath==0 ) return;
911 if( zPath[0]!='$' ) return;
912 zPath++;
913 }else{
914 zPath = 0;
915 }
916 if( jsonParse(&x, (const char*)sqlite3_value_text(argv[0]))==0 ){
917 if( x.nNode ){
918 JsonNode *pNode = x.aNode;
drh52216ad2015-08-18 02:28:03 +0000919 if( zPath ) pNode = jsonLookup(&x, 0, zPath, 0);
drh987eb1f2015-08-17 15:17:37 +0000920 if( pNode->eType==JSON_ARRAY ){
drh52216ad2015-08-18 02:28:03 +0000921 assert( (pNode->jnFlags & JNODE_APPEND)==0 );
drh301eecc2015-08-17 20:14:19 +0000922 for(i=1; i<=pNode->n; n++){
drhd0960592015-08-17 21:22:32 +0000923 i += jsonSize(&pNode[i]);
drh987eb1f2015-08-17 15:17:37 +0000924 }
925 }
926 }
927 sqlite3_free(x.aNode);
928 }
929 sqlite3_result_int64(context, n);
930}
931
932/*
933** json_extract(JSON, PATH)
934**
935** Return the element described by PATH. Return NULL if JSON is not
936** valid JSON or if there is no PATH element or if PATH is malformed.
937*/
938static void jsonExtractFunc(
939 sqlite3_context *context,
940 int argc,
941 sqlite3_value **argv
942){
943 JsonParse x; /* The parse */
944 JsonNode *pNode;
945 const char *zPath;
946 assert( argc==2 );
947 zPath = (const char*)sqlite3_value_text(argv[1]);
948 if( zPath==0 ) return;
949 if( zPath[0]!='$' ) return;
950 zPath++;
951 if( jsonParse(&x, (const char*)sqlite3_value_text(argv[0])) ) return;
drh52216ad2015-08-18 02:28:03 +0000952 pNode = jsonLookup(&x, 0, zPath, 0);
drh987eb1f2015-08-17 15:17:37 +0000953 if( pNode ){
drhd0960592015-08-17 21:22:32 +0000954 jsonReturn(pNode, context, 0);
drh987eb1f2015-08-17 15:17:37 +0000955 }
956 sqlite3_free(x.aNode);
957}
958
959/*
960** Implementation of the json_object(NAME,VALUE,...) function. Return a JSON
961** object that contains all name/value given in arguments. Or if any name
962** is not a string or if any value is a BLOB, throw an error.
963*/
964static void jsonObjectFunc(
965 sqlite3_context *context,
966 int argc,
967 sqlite3_value **argv
968){
969 int i;
970 Json jx;
drh987eb1f2015-08-17 15:17:37 +0000971 const char *z;
972 u32 n;
973
974 if( argc&1 ){
975 sqlite3_result_error(context, "json_object() requires an even number "
976 "of arguments", -1);
977 return;
978 }
979 jsonInit(&jx, context);
drhd0960592015-08-17 21:22:32 +0000980 jsonAppendChar(&jx, '{');
drh987eb1f2015-08-17 15:17:37 +0000981 for(i=0; i<argc; i+=2){
drh987eb1f2015-08-17 15:17:37 +0000982 if( sqlite3_value_type(argv[i])!=SQLITE_TEXT ){
983 sqlite3_result_error(context, "json_object() labels must be TEXT", -1);
984 jsonZero(&jx);
985 return;
986 }
drhd0960592015-08-17 21:22:32 +0000987 jsonAppendSeparator(&jx);
drh987eb1f2015-08-17 15:17:37 +0000988 z = (const char*)sqlite3_value_text(argv[i]);
989 n = (u32)sqlite3_value_bytes(argv[i]);
990 jsonAppendString(&jx, z, n);
drhd0960592015-08-17 21:22:32 +0000991 jsonAppendChar(&jx, ':');
992 jsonAppendValue(&jx, argv[i+1]);
drh987eb1f2015-08-17 15:17:37 +0000993 }
drhd0960592015-08-17 21:22:32 +0000994 jsonAppendChar(&jx, '}');
drh987eb1f2015-08-17 15:17:37 +0000995 jsonResult(&jx);
996}
997
998
999/*
drh301eecc2015-08-17 20:14:19 +00001000** json_remove(JSON, PATH, ...)
1001**
1002** Remove the named elements from JSON and return the result. Ill-formed
1003** PATH arguments are silently ignored. If JSON is ill-formed, then NULL
1004** is returned.
1005*/
1006static void jsonRemoveFunc(
1007 sqlite3_context *context,
1008 int argc,
1009 sqlite3_value **argv
1010){
1011 JsonParse x; /* The parse */
1012 JsonNode *pNode;
1013 const char *zPath;
1014 u32 i;
1015
1016 if( argc<1 ) return;
1017 if( jsonParse(&x, (const char*)sqlite3_value_text(argv[0])) ) return;
1018 if( x.nNode ){
1019 for(i=1; i<argc; i++){
1020 zPath = (const char*)sqlite3_value_text(argv[i]);
1021 if( zPath==0 ) continue;
1022 if( zPath[0]!='$' ) continue;
drh52216ad2015-08-18 02:28:03 +00001023 pNode = jsonLookup(&x, 0, &zPath[1], 0);
drh301eecc2015-08-17 20:14:19 +00001024 if( pNode ) pNode->jnFlags |= JNODE_REMOVE;
1025 }
1026 if( (x.aNode[0].jnFlags & JNODE_REMOVE)==0 ){
drhd0960592015-08-17 21:22:32 +00001027 jsonReturn(x.aNode, context, 0);
1028 }
1029 }
1030 sqlite3_free(x.aNode);
1031}
1032
1033/*
1034** json_replace(JSON, PATH, VALUE, ...)
1035**
1036** Replace the value at PATH with VALUE. If PATH does not already exist,
1037** this routine is a no-op. If JSON is ill-formed, return NULL.
1038*/
1039static void jsonReplaceFunc(
1040 sqlite3_context *context,
1041 int argc,
1042 sqlite3_value **argv
1043){
1044 JsonParse x; /* The parse */
1045 JsonNode *pNode;
1046 const char *zPath;
1047 u32 i;
1048
1049 if( argc<1 ) return;
1050 if( (argc&1)==0 ) {
1051 sqlite3_result_error(context,
1052 "json_replace() needs an odd number of arguments", -1);
1053 return;
1054 }
1055 if( jsonParse(&x, (const char*)sqlite3_value_text(argv[0])) ) return;
1056 if( x.nNode ){
1057 for(i=1; i<argc; i+=2){
1058 zPath = (const char*)sqlite3_value_text(argv[i]);
1059 if( zPath==0 ) continue;
1060 if( zPath[0]!='$' ) continue;
drh52216ad2015-08-18 02:28:03 +00001061 pNode = jsonLookup(&x, 0, &zPath[1], 0);
drhd0960592015-08-17 21:22:32 +00001062 if( pNode ){
1063 pNode->jnFlags |= JNODE_REPLACE;
1064 pNode->iVal = i+1;
1065 }
1066 }
1067 if( x.aNode[0].jnFlags & JNODE_REPLACE ){
1068 sqlite3_result_value(context, argv[x.aNode[0].iVal]);
1069 }else{
1070 jsonReturn(x.aNode, context, argv);
drh301eecc2015-08-17 20:14:19 +00001071 }
1072 }
1073 sqlite3_free(x.aNode);
1074}
drh52216ad2015-08-18 02:28:03 +00001075/*
1076** json_set(JSON, PATH, VALUE, ...)
1077**
1078** Set the value at PATH to VALUE. Create the PATH if it does not already
1079** exist. Overwrite existing values that do exist.
1080** If JSON is ill-formed, return NULL.
1081**
1082** json_insert(JSON, PATH, VALUE, ...)
1083**
1084** Create PATH and initialize it to VALUE. If PATH already exists, this
1085** routine is a no-op. If JSON is ill-formed, return NULL.
1086*/
1087static void jsonSetFunc(
1088 sqlite3_context *context,
1089 int argc,
1090 sqlite3_value **argv
1091){
1092 JsonParse x; /* The parse */
1093 JsonNode *pNode;
1094 const char *zPath;
1095 u32 i;
1096 int bApnd;
1097 int bIsSet = *(int*)sqlite3_user_data(context);
1098
1099 if( argc<1 ) return;
1100 if( (argc&1)==0 ) {
1101 sqlite3_result_error(context,
1102 "json_set() needs an odd number of arguments", -1);
1103 return;
1104 }
1105 if( jsonParse(&x, (const char*)sqlite3_value_text(argv[0])) ) return;
1106 if( x.nNode ){
1107 for(i=1; i<argc; i+=2){
1108 zPath = (const char*)sqlite3_value_text(argv[i]);
1109 if( zPath==0 ) continue;
1110 if( zPath[0]!='$' ) continue;
1111 bApnd = 0;
1112 pNode = jsonLookup(&x, 0, &zPath[1], &bApnd);
1113 if( pNode && (bApnd || bIsSet) ){
1114 pNode->jnFlags |= JNODE_REPLACE;
1115 pNode->iVal = i+1;
1116 }
1117 }
1118 if( x.aNode[0].jnFlags & JNODE_REPLACE ){
1119 sqlite3_result_value(context, argv[x.aNode[0].iVal]);
1120 }else{
1121 jsonReturn(x.aNode, context, argv);
1122 }
1123 }
1124 sqlite3_free(x.aNode);
1125}
drh301eecc2015-08-17 20:14:19 +00001126
1127/*
drh987eb1f2015-08-17 15:17:37 +00001128** json_type(JSON)
1129** json_type(JSON, PATH)
1130**
1131** Return the top-level "type" of a JSON string. Return NULL if the
1132** input is not a well-formed JSON string.
1133*/
1134static void jsonTypeFunc(
1135 sqlite3_context *context,
1136 int argc,
1137 sqlite3_value **argv
1138){
1139 JsonParse x; /* The parse */
1140 const char *zPath;
1141
1142 if( argc==2 ){
1143 zPath = (const char*)sqlite3_value_text(argv[1]);
1144 if( zPath==0 ) return;
1145 if( zPath[0]!='$' ) return;
1146 zPath++;
1147 }else{
1148 zPath = 0;
1149 }
1150 if( jsonParse(&x, (const char*)sqlite3_value_text(argv[0])) ) return;
1151 if( x.nNode ){
1152 JsonNode *pNode = x.aNode;
drh52216ad2015-08-18 02:28:03 +00001153 if( zPath ) pNode = jsonLookup(&x, 0, zPath, 0);
drh987eb1f2015-08-17 15:17:37 +00001154 sqlite3_result_text(context, jsonType[pNode->eType], -1, SQLITE_STATIC);
1155 }
1156 sqlite3_free(x.aNode);
1157}
drh5634cc02015-08-17 11:28:03 +00001158
drh5fa5c102015-08-12 16:49:40 +00001159#ifdef _WIN32
1160__declspec(dllexport)
1161#endif
1162int sqlite3_json_init(
1163 sqlite3 *db,
1164 char **pzErrMsg,
1165 const sqlite3_api_routines *pApi
1166){
1167 int rc = SQLITE_OK;
1168 int i;
1169 static const struct {
1170 const char *zName;
1171 int nArg;
drh52216ad2015-08-18 02:28:03 +00001172 int flag;
drh5fa5c102015-08-12 16:49:40 +00001173 void (*xFunc)(sqlite3_context*,int,sqlite3_value**);
1174 } aFunc[] = {
drh52216ad2015-08-18 02:28:03 +00001175 { "json_array", -1, 0, jsonArrayFunc },
1176 { "json_array_length", 1, 0, jsonArrayLengthFunc },
1177 { "json_array_length", 2, 0, jsonArrayLengthFunc },
1178 { "json_extract", 2, 0, jsonExtractFunc },
1179 { "json_insert", -1, 0, jsonSetFunc },
1180 { "json_object", -1, 0, jsonObjectFunc },
1181 { "json_remove", -1, 0, jsonRemoveFunc },
1182 { "json_replace", -1, 0, jsonReplaceFunc },
1183 { "json_set", -1, 1, jsonSetFunc },
1184 { "json_type", 1, 0, jsonTypeFunc },
1185 { "json_type", 2, 0, jsonTypeFunc },
drh987eb1f2015-08-17 15:17:37 +00001186
drh301eecc2015-08-17 20:14:19 +00001187#if SQLITE_DEBUG
drh987eb1f2015-08-17 15:17:37 +00001188 /* DEBUG and TESTING functions */
drh52216ad2015-08-18 02:28:03 +00001189 { "json_parse", 1, 0, jsonParseFunc },
1190 { "json_test1", 1, 0, jsonTest1Func },
1191 { "json_nodecount", 1, 0, jsonNodeCountFunc },
drh301eecc2015-08-17 20:14:19 +00001192#endif
drh5fa5c102015-08-12 16:49:40 +00001193 };
1194 SQLITE_EXTENSION_INIT2(pApi);
1195 (void)pzErrMsg; /* Unused parameter */
1196 for(i=0; i<sizeof(aFunc)/sizeof(aFunc[0]) && rc==SQLITE_OK; i++){
1197 rc = sqlite3_create_function(db, aFunc[i].zName, aFunc[i].nArg,
drh52216ad2015-08-18 02:28:03 +00001198 SQLITE_UTF8 | SQLITE_DETERMINISTIC,
1199 (void*)&aFunc[i].flag,
drh5fa5c102015-08-12 16:49:40 +00001200 aFunc[i].xFunc, 0, 0);
1201 }
1202 return rc;
1203}