blob: cd4531bccbd47a070d4eb292ef216d1f7263ec48 [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
drhcb6c6c62015-08-19 22:47:17 +000020** a BLOB, but there is no support for JSONB in the current implementation.
21** This implementation parses JSON text at 250 MB/s, so it is hard to see
22** how JSONB might improve on that.)
drh5fa5c102015-08-12 16:49:40 +000023*/
24#include "sqlite3ext.h"
25SQLITE_EXTENSION_INIT1
26#include <assert.h>
27#include <string.h>
drhe9c37f32015-08-15 21:25:36 +000028#include <ctype.h>
drh987eb1f2015-08-17 15:17:37 +000029#include <stdlib.h>
drh4af352d2015-08-21 20:02:48 +000030#include <stdarg.h>
drh5fa5c102015-08-12 16:49:40 +000031
drh6fd5c1e2015-08-21 20:37:12 +000032#define UNUSED_PARAM(X) (void)(X)
33
drh5fa5c102015-08-12 16:49:40 +000034/* Unsigned integer types */
35typedef sqlite3_uint64 u64;
36typedef unsigned int u32;
37typedef unsigned char u8;
38
drh52216ad2015-08-18 02:28:03 +000039/* Objects */
drh505ad2c2015-08-21 17:33:11 +000040typedef struct JsonString JsonString;
drh52216ad2015-08-18 02:28:03 +000041typedef struct JsonNode JsonNode;
42typedef struct JsonParse JsonParse;
43
drh5634cc02015-08-17 11:28:03 +000044/* An instance of this object represents a JSON string
45** under construction. Really, this is a generic string accumulator
46** that can be and is used to create strings other than JSON.
drh5fa5c102015-08-12 16:49:40 +000047*/
drh505ad2c2015-08-21 17:33:11 +000048struct JsonString {
drh5fa5c102015-08-12 16:49:40 +000049 sqlite3_context *pCtx; /* Function context - put error messages here */
drh5634cc02015-08-17 11:28:03 +000050 char *zBuf; /* Append JSON content here */
drh5fa5c102015-08-12 16:49:40 +000051 u64 nAlloc; /* Bytes of storage available in zBuf[] */
52 u64 nUsed; /* Bytes of zBuf[] currently used */
53 u8 bStatic; /* True if zBuf is static space */
drhd0960592015-08-17 21:22:32 +000054 u8 bErr; /* True if an error has been encountered */
drh5fa5c102015-08-12 16:49:40 +000055 char zSpace[100]; /* Initial static space */
56};
57
drhe9c37f32015-08-15 21:25:36 +000058/* JSON type values
drhbd0621b2015-08-13 13:54:59 +000059*/
drhe9c37f32015-08-15 21:25:36 +000060#define JSON_NULL 0
61#define JSON_TRUE 1
62#define JSON_FALSE 2
63#define JSON_INT 3
64#define JSON_REAL 4
65#define JSON_STRING 5
66#define JSON_ARRAY 6
67#define JSON_OBJECT 7
68
drh987eb1f2015-08-17 15:17:37 +000069/*
70** Names of the various JSON types:
71*/
72static const char * const jsonType[] = {
73 "null", "true", "false", "integer", "real", "text", "array", "object"
74};
75
drh301eecc2015-08-17 20:14:19 +000076/* Bit values for the JsonNode.jnFlag field
77*/
78#define JNODE_RAW 0x01 /* Content is raw, not JSON encoded */
79#define JNODE_ESCAPE 0x02 /* Content is text with \ escapes */
80#define JNODE_REMOVE 0x04 /* Do not output */
drhd0960592015-08-17 21:22:32 +000081#define JNODE_REPLACE 0x08 /* Replace with JsonNode.iVal */
drh52216ad2015-08-18 02:28:03 +000082#define JNODE_APPEND 0x10 /* More ARRAY/OBJECT entries at u.iAppend */
drh301eecc2015-08-17 20:14:19 +000083
drh987eb1f2015-08-17 15:17:37 +000084
drhe9c37f32015-08-15 21:25:36 +000085/* A single node of parsed JSON
86*/
drhe9c37f32015-08-15 21:25:36 +000087struct JsonNode {
drh5634cc02015-08-17 11:28:03 +000088 u8 eType; /* One of the JSON_ type values */
drh301eecc2015-08-17 20:14:19 +000089 u8 jnFlags; /* JNODE flags */
drhd0960592015-08-17 21:22:32 +000090 u8 iVal; /* Replacement value when JNODE_REPLACE */
drhe9c37f32015-08-15 21:25:36 +000091 u32 n; /* Bytes of content, or number of sub-nodes */
drh52216ad2015-08-18 02:28:03 +000092 union {
drh0042a972015-08-18 12:59:58 +000093 const char *zJContent; /* Content for INT, REAL, and STRING */
94 u32 iAppend; /* More terms for ARRAY and OBJECT */
drh505ad2c2015-08-21 17:33:11 +000095 u32 iKey; /* Key for ARRAY objects in json_tree() */
drh52216ad2015-08-18 02:28:03 +000096 } u;
drhe9c37f32015-08-15 21:25:36 +000097};
98
99/* A completely parsed JSON string
100*/
drhe9c37f32015-08-15 21:25:36 +0000101struct JsonParse {
102 u32 nNode; /* Number of slots of aNode[] used */
103 u32 nAlloc; /* Number of slots of aNode[] allocated */
104 JsonNode *aNode; /* Array of nodes containing the parse */
105 const char *zJson; /* Original JSON string */
drh505ad2c2015-08-21 17:33:11 +0000106 u32 *aUp; /* Index of parent of each node */
drhe9c37f32015-08-15 21:25:36 +0000107 u8 oom; /* Set to true if out of memory */
108};
109
drh505ad2c2015-08-21 17:33:11 +0000110/**************************************************************************
111** Utility routines for dealing with JsonString objects
112**************************************************************************/
drh301eecc2015-08-17 20:14:19 +0000113
drh505ad2c2015-08-21 17:33:11 +0000114/* Set the JsonString object to an empty string
drh5fa5c102015-08-12 16:49:40 +0000115*/
drh505ad2c2015-08-21 17:33:11 +0000116static void jsonZero(JsonString *p){
drh5fa5c102015-08-12 16:49:40 +0000117 p->zBuf = p->zSpace;
118 p->nAlloc = sizeof(p->zSpace);
119 p->nUsed = 0;
120 p->bStatic = 1;
121}
122
drh505ad2c2015-08-21 17:33:11 +0000123/* Initialize the JsonString object
drh5fa5c102015-08-12 16:49:40 +0000124*/
drh505ad2c2015-08-21 17:33:11 +0000125static void jsonInit(JsonString *p, sqlite3_context *pCtx){
drh5fa5c102015-08-12 16:49:40 +0000126 p->pCtx = pCtx;
drhd0960592015-08-17 21:22:32 +0000127 p->bErr = 0;
drh5fa5c102015-08-12 16:49:40 +0000128 jsonZero(p);
129}
130
131
drh505ad2c2015-08-21 17:33:11 +0000132/* Free all allocated memory and reset the JsonString object back to its
drh5fa5c102015-08-12 16:49:40 +0000133** initial state.
134*/
drh505ad2c2015-08-21 17:33:11 +0000135static void jsonReset(JsonString *p){
drh5fa5c102015-08-12 16:49:40 +0000136 if( !p->bStatic ) sqlite3_free(p->zBuf);
137 jsonZero(p);
138}
139
140
141/* Report an out-of-memory (OOM) condition
142*/
drh505ad2c2015-08-21 17:33:11 +0000143static void jsonOom(JsonString *p){
drhd0960592015-08-17 21:22:32 +0000144 if( !p->bErr ){
145 p->bErr = 1;
146 sqlite3_result_error_nomem(p->pCtx);
147 jsonReset(p);
148 }
drh5fa5c102015-08-12 16:49:40 +0000149}
150
151/* Enlarge pJson->zBuf so that it can hold at least N more bytes.
152** Return zero on success. Return non-zero on an OOM error
153*/
drh505ad2c2015-08-21 17:33:11 +0000154static int jsonGrow(JsonString *p, u32 N){
drh301eecc2015-08-17 20:14:19 +0000155 u64 nTotal = N<p->nAlloc ? p->nAlloc*2 : p->nAlloc+N+10;
drh5fa5c102015-08-12 16:49:40 +0000156 char *zNew;
157 if( p->bStatic ){
drhd0960592015-08-17 21:22:32 +0000158 if( p->bErr ) return 1;
drh5fa5c102015-08-12 16:49:40 +0000159 zNew = sqlite3_malloc64(nTotal);
160 if( zNew==0 ){
161 jsonOom(p);
162 return SQLITE_NOMEM;
163 }
drh6fd5c1e2015-08-21 20:37:12 +0000164 memcpy(zNew, p->zBuf, (size_t)p->nUsed);
drh5fa5c102015-08-12 16:49:40 +0000165 p->zBuf = zNew;
166 p->bStatic = 0;
167 }else{
168 zNew = sqlite3_realloc64(p->zBuf, nTotal);
169 if( zNew==0 ){
170 jsonOom(p);
171 return SQLITE_NOMEM;
172 }
173 p->zBuf = zNew;
174 }
175 p->nAlloc = nTotal;
176 return SQLITE_OK;
177}
178
drh505ad2c2015-08-21 17:33:11 +0000179/* Append N bytes from zIn onto the end of the JsonString string.
drh5fa5c102015-08-12 16:49:40 +0000180*/
drh505ad2c2015-08-21 17:33:11 +0000181static void jsonAppendRaw(JsonString *p, const char *zIn, u32 N){
drh5fa5c102015-08-12 16:49:40 +0000182 if( (N+p->nUsed >= p->nAlloc) && jsonGrow(p,N)!=0 ) return;
183 memcpy(p->zBuf+p->nUsed, zIn, N);
184 p->nUsed += N;
185}
186
drh4af352d2015-08-21 20:02:48 +0000187/* Append formatted text (not to exceed N bytes) to the JsonString.
188*/
189static void jsonPrintf(int N, JsonString *p, const char *zFormat, ...){
190 va_list ap;
191 if( (p->nUsed + N >= p->nAlloc) && jsonGrow(p, N) ) return;
192 va_start(ap, zFormat);
193 sqlite3_vsnprintf(N, p->zBuf+p->nUsed, zFormat, ap);
194 va_end(ap);
195 p->nUsed += (int)strlen(p->zBuf+p->nUsed);
196}
197
drh5634cc02015-08-17 11:28:03 +0000198/* Append a single character
199*/
drh505ad2c2015-08-21 17:33:11 +0000200static void jsonAppendChar(JsonString *p, char c){
drh5634cc02015-08-17 11:28:03 +0000201 if( p->nUsed>=p->nAlloc && jsonGrow(p,1)!=0 ) return;
202 p->zBuf[p->nUsed++] = c;
203}
204
drh301eecc2015-08-17 20:14:19 +0000205/* Append a comma separator to the output buffer, if the previous
206** character is not '[' or '{'.
207*/
drh505ad2c2015-08-21 17:33:11 +0000208static void jsonAppendSeparator(JsonString *p){
drh301eecc2015-08-17 20:14:19 +0000209 char c;
210 if( p->nUsed==0 ) return;
211 c = p->zBuf[p->nUsed-1];
212 if( c!='[' && c!='{' ) jsonAppendChar(p, ',');
213}
214
drh505ad2c2015-08-21 17:33:11 +0000215/* Append the N-byte string in zIn to the end of the JsonString string
drh5fa5c102015-08-12 16:49:40 +0000216** under construction. Enclose the string in "..." and escape
217** any double-quotes or backslash characters contained within the
218** string.
219*/
drh505ad2c2015-08-21 17:33:11 +0000220static void jsonAppendString(JsonString *p, const char *zIn, u32 N){
drh5fa5c102015-08-12 16:49:40 +0000221 u32 i;
222 if( (N+p->nUsed+2 >= p->nAlloc) && jsonGrow(p,N+2)!=0 ) return;
223 p->zBuf[p->nUsed++] = '"';
224 for(i=0; i<N; i++){
225 char c = zIn[i];
226 if( c=='"' || c=='\\' ){
227 if( (p->nUsed+N+1-i > p->nAlloc) && jsonGrow(p,N+1-i)!=0 ) return;
228 p->zBuf[p->nUsed++] = '\\';
229 }
230 p->zBuf[p->nUsed++] = c;
231 }
232 p->zBuf[p->nUsed++] = '"';
233}
234
drhd0960592015-08-17 21:22:32 +0000235/*
236** Append a function parameter value to the JSON string under
237** construction.
238*/
239static void jsonAppendValue(
drh505ad2c2015-08-21 17:33:11 +0000240 JsonString *p, /* Append to this JSON string */
drhd0960592015-08-17 21:22:32 +0000241 sqlite3_value *pValue /* Value to append */
242){
243 switch( sqlite3_value_type(pValue) ){
244 case SQLITE_NULL: {
245 jsonAppendRaw(p, "null", 4);
246 break;
247 }
248 case SQLITE_INTEGER:
249 case SQLITE_FLOAT: {
250 const char *z = (const char*)sqlite3_value_text(pValue);
251 u32 n = (u32)sqlite3_value_bytes(pValue);
252 jsonAppendRaw(p, z, n);
253 break;
254 }
255 case SQLITE_TEXT: {
256 const char *z = (const char*)sqlite3_value_text(pValue);
257 u32 n = (u32)sqlite3_value_bytes(pValue);
258 jsonAppendString(p, z, n);
259 break;
260 }
261 default: {
262 if( p->bErr==0 ){
263 sqlite3_result_error(p->pCtx, "JSON cannot hold BLOB values", -1);
264 p->bErr = 1;
265 jsonReset(p);
266 }
267 break;
268 }
269 }
270}
271
272
drhbd0621b2015-08-13 13:54:59 +0000273/* Make the JSON in p the result of the SQL function.
drh5fa5c102015-08-12 16:49:40 +0000274*/
drh505ad2c2015-08-21 17:33:11 +0000275static void jsonResult(JsonString *p){
drhd0960592015-08-17 21:22:32 +0000276 if( p->bErr==0 ){
drh5fa5c102015-08-12 16:49:40 +0000277 sqlite3_result_text64(p->pCtx, p->zBuf, p->nUsed,
278 p->bStatic ? SQLITE_TRANSIENT : sqlite3_free,
279 SQLITE_UTF8);
280 jsonZero(p);
281 }
282 assert( p->bStatic );
283}
284
drh505ad2c2015-08-21 17:33:11 +0000285/**************************************************************************
286** Utility routines for dealing with JsonNode and JsonParse objects
287**************************************************************************/
288
289/*
290** Return the number of consecutive JsonNode slots need to represent
291** the parsed JSON at pNode. The minimum answer is 1. For ARRAY and
292** OBJECT types, the number might be larger.
293**
294** Appended elements are not counted. The value returned is the number
295** by which the JsonNode counter should increment in order to go to the
296** next peer value.
297*/
298static u32 jsonNodeSize(JsonNode *pNode){
299 return pNode->eType>=JSON_ARRAY ? pNode->n+1 : 1;
300}
301
302/*
303** Reclaim all memory allocated by a JsonParse object. But do not
304** delete the JsonParse object itself.
305*/
306static void jsonParseReset(JsonParse *pParse){
307 sqlite3_free(pParse->aNode);
308 pParse->aNode = 0;
309 pParse->nNode = 0;
310 pParse->nAlloc = 0;
311 sqlite3_free(pParse->aUp);
312 pParse->aUp = 0;
313}
314
drh5634cc02015-08-17 11:28:03 +0000315/*
316** Convert the JsonNode pNode into a pure JSON string and
317** append to pOut. Subsubstructure is also included. Return
318** the number of JsonNode objects that are encoded.
drhbd0621b2015-08-13 13:54:59 +0000319*/
drh52216ad2015-08-18 02:28:03 +0000320static void jsonRenderNode(
drhd0960592015-08-17 21:22:32 +0000321 JsonNode *pNode, /* The node to render */
drh505ad2c2015-08-21 17:33:11 +0000322 JsonString *pOut, /* Write JSON here */
drhd0960592015-08-17 21:22:32 +0000323 sqlite3_value **aReplace /* Replacement values */
324){
drh5634cc02015-08-17 11:28:03 +0000325 switch( pNode->eType ){
326 case JSON_NULL: {
327 jsonAppendRaw(pOut, "null", 4);
328 break;
329 }
330 case JSON_TRUE: {
331 jsonAppendRaw(pOut, "true", 4);
332 break;
333 }
334 case JSON_FALSE: {
335 jsonAppendRaw(pOut, "false", 5);
336 break;
337 }
338 case JSON_STRING: {
drh301eecc2015-08-17 20:14:19 +0000339 if( pNode->jnFlags & JNODE_RAW ){
drh52216ad2015-08-18 02:28:03 +0000340 jsonAppendString(pOut, pNode->u.zJContent, pNode->n);
drh5634cc02015-08-17 11:28:03 +0000341 break;
342 }
343 /* Fall through into the next case */
344 }
345 case JSON_REAL:
346 case JSON_INT: {
drh52216ad2015-08-18 02:28:03 +0000347 jsonAppendRaw(pOut, pNode->u.zJContent, pNode->n);
drh5634cc02015-08-17 11:28:03 +0000348 break;
349 }
350 case JSON_ARRAY: {
drh52216ad2015-08-18 02:28:03 +0000351 u32 j = 1;
drh5634cc02015-08-17 11:28:03 +0000352 jsonAppendChar(pOut, '[');
drh52216ad2015-08-18 02:28:03 +0000353 for(;;){
354 while( j<=pNode->n ){
355 if( pNode[j].jnFlags & (JNODE_REMOVE|JNODE_REPLACE) ){
356 if( pNode[j].jnFlags & JNODE_REPLACE ){
357 jsonAppendSeparator(pOut);
358 jsonAppendValue(pOut, aReplace[pNode[j].iVal]);
359 }
360 }else{
drhd0960592015-08-17 21:22:32 +0000361 jsonAppendSeparator(pOut);
drh52216ad2015-08-18 02:28:03 +0000362 jsonRenderNode(&pNode[j], pOut, aReplace);
drhd0960592015-08-17 21:22:32 +0000363 }
drh505ad2c2015-08-21 17:33:11 +0000364 j += jsonNodeSize(&pNode[j]);
drh301eecc2015-08-17 20:14:19 +0000365 }
drh52216ad2015-08-18 02:28:03 +0000366 if( (pNode->jnFlags & JNODE_APPEND)==0 ) break;
367 pNode = &pNode[pNode->u.iAppend];
368 j = 1;
drh5634cc02015-08-17 11:28:03 +0000369 }
370 jsonAppendChar(pOut, ']');
371 break;
372 }
373 case JSON_OBJECT: {
drh52216ad2015-08-18 02:28:03 +0000374 u32 j = 1;
drh5634cc02015-08-17 11:28:03 +0000375 jsonAppendChar(pOut, '{');
drh52216ad2015-08-18 02:28:03 +0000376 for(;;){
377 while( j<=pNode->n ){
378 if( (pNode[j+1].jnFlags & JNODE_REMOVE)==0 ){
379 jsonAppendSeparator(pOut);
380 jsonRenderNode(&pNode[j], pOut, aReplace);
381 jsonAppendChar(pOut, ':');
382 if( pNode[j+1].jnFlags & JNODE_REPLACE ){
383 jsonAppendValue(pOut, aReplace[pNode[j+1].iVal]);
384 }else{
385 jsonRenderNode(&pNode[j+1], pOut, aReplace);
386 }
drhd0960592015-08-17 21:22:32 +0000387 }
drh505ad2c2015-08-21 17:33:11 +0000388 j += 1 + jsonNodeSize(&pNode[j+1]);
drh301eecc2015-08-17 20:14:19 +0000389 }
drh52216ad2015-08-18 02:28:03 +0000390 if( (pNode->jnFlags & JNODE_APPEND)==0 ) break;
391 pNode = &pNode[pNode->u.iAppend];
392 j = 1;
drh5634cc02015-08-17 11:28:03 +0000393 }
394 jsonAppendChar(pOut, '}');
395 break;
396 }
drhbd0621b2015-08-13 13:54:59 +0000397 }
drh5634cc02015-08-17 11:28:03 +0000398}
399
400/*
401** Make the JsonNode the return value of the function.
402*/
drhd0960592015-08-17 21:22:32 +0000403static void jsonReturn(
404 JsonNode *pNode, /* Node to return */
405 sqlite3_context *pCtx, /* Return value for this function */
406 sqlite3_value **aReplace /* Array of replacement values */
407){
drh5634cc02015-08-17 11:28:03 +0000408 switch( pNode->eType ){
409 case JSON_NULL: {
410 sqlite3_result_null(pCtx);
411 break;
412 }
413 case JSON_TRUE: {
414 sqlite3_result_int(pCtx, 1);
415 break;
416 }
417 case JSON_FALSE: {
418 sqlite3_result_int(pCtx, 0);
419 break;
420 }
drh987eb1f2015-08-17 15:17:37 +0000421 case JSON_REAL: {
drh52216ad2015-08-18 02:28:03 +0000422 double r = strtod(pNode->u.zJContent, 0);
drh987eb1f2015-08-17 15:17:37 +0000423 sqlite3_result_double(pCtx, r);
drh5634cc02015-08-17 11:28:03 +0000424 break;
425 }
drh987eb1f2015-08-17 15:17:37 +0000426 case JSON_INT: {
427 sqlite3_int64 i = 0;
drh52216ad2015-08-18 02:28:03 +0000428 const char *z = pNode->u.zJContent;
drh987eb1f2015-08-17 15:17:37 +0000429 if( z[0]=='-' ){ z++; }
430 while( z[0]>='0' && z[0]<='9' ){ i = i*10 + *(z++) - '0'; }
drh52216ad2015-08-18 02:28:03 +0000431 if( pNode->u.zJContent[0]=='-' ){ i = -i; }
drh987eb1f2015-08-17 15:17:37 +0000432 sqlite3_result_int64(pCtx, i);
433 break;
434 }
drh5634cc02015-08-17 11:28:03 +0000435 case JSON_STRING: {
drh301eecc2015-08-17 20:14:19 +0000436 if( pNode->jnFlags & JNODE_RAW ){
drh52216ad2015-08-18 02:28:03 +0000437 sqlite3_result_text(pCtx, pNode->u.zJContent, pNode->n,
438 SQLITE_TRANSIENT);
drh301eecc2015-08-17 20:14:19 +0000439 }else if( (pNode->jnFlags & JNODE_ESCAPE)==0 ){
drh987eb1f2015-08-17 15:17:37 +0000440 /* JSON formatted without any backslash-escapes */
drh52216ad2015-08-18 02:28:03 +0000441 sqlite3_result_text(pCtx, pNode->u.zJContent+1, pNode->n-2,
drh987eb1f2015-08-17 15:17:37 +0000442 SQLITE_TRANSIENT);
drh5634cc02015-08-17 11:28:03 +0000443 }else{
444 /* Translate JSON formatted string into raw text */
drh987eb1f2015-08-17 15:17:37 +0000445 u32 i;
446 u32 n = pNode->n;
drh52216ad2015-08-18 02:28:03 +0000447 const char *z = pNode->u.zJContent;
drh987eb1f2015-08-17 15:17:37 +0000448 char *zOut;
449 u32 j;
450 zOut = sqlite3_malloc( n+1 );
451 if( zOut==0 ){
452 sqlite3_result_error_nomem(pCtx);
453 break;
454 }
455 for(i=1, j=0; i<n-1; i++){
456 char c = z[i];
drh80d87402015-08-24 12:42:41 +0000457 if( c!='\\' ){
drh987eb1f2015-08-17 15:17:37 +0000458 zOut[j++] = c;
459 }else{
460 c = z[++i];
drh80d87402015-08-24 12:42:41 +0000461 if( c=='u' ){
drh987eb1f2015-08-17 15:17:37 +0000462 u32 v = 0, k;
drh80d87402015-08-24 12:42:41 +0000463 for(k=0; k<4 && i<n-2; i++, k++){
drh8784eca2015-08-23 02:42:30 +0000464 c = z[i+1];
drh987eb1f2015-08-17 15:17:37 +0000465 if( c>='0' && c<='9' ) v = v*16 + c - '0';
466 else if( c>='A' && c<='F' ) v = v*16 + c - 'A' + 10;
467 else if( c>='a' && c<='f' ) v = v*16 + c - 'a' + 10;
468 else break;
drh987eb1f2015-08-17 15:17:37 +0000469 }
drh80d87402015-08-24 12:42:41 +0000470 if( v==0 ) break;
drh987eb1f2015-08-17 15:17:37 +0000471 if( v<=0x7f ){
472 zOut[j++] = v;
473 }else if( v<=0x7ff ){
474 zOut[j++] = 0xc0 | (v>>6);
475 zOut[j++] = 0x80 | (v&0x3f);
drh80d87402015-08-24 12:42:41 +0000476 }else{
drh987eb1f2015-08-17 15:17:37 +0000477 zOut[j++] = 0xe0 | (v>>12);
478 zOut[j++] = 0x80 | ((v>>6)&0x3f);
479 zOut[j++] = 0x80 | (v&0x3f);
drh987eb1f2015-08-17 15:17:37 +0000480 }
481 }else{
482 if( c=='b' ){
483 c = '\b';
484 }else if( c=='f' ){
485 c = '\f';
486 }else if( c=='n' ){
487 c = '\n';
488 }else if( c=='r' ){
489 c = '\r';
490 }else if( c=='t' ){
491 c = '\t';
492 }
493 zOut[j++] = c;
494 }
495 }
496 }
497 zOut[j] = 0;
498 sqlite3_result_text(pCtx, zOut, j, sqlite3_free);
drh5634cc02015-08-17 11:28:03 +0000499 }
500 break;
501 }
502 case JSON_ARRAY:
503 case JSON_OBJECT: {
drh505ad2c2015-08-21 17:33:11 +0000504 JsonString s;
drh5634cc02015-08-17 11:28:03 +0000505 jsonInit(&s, pCtx);
drhd0960592015-08-17 21:22:32 +0000506 jsonRenderNode(pNode, &s, aReplace);
drh5634cc02015-08-17 11:28:03 +0000507 jsonResult(&s);
508 break;
509 }
510 }
drhbd0621b2015-08-13 13:54:59 +0000511}
512
drh5fa5c102015-08-12 16:49:40 +0000513/*
drhe9c37f32015-08-15 21:25:36 +0000514** Create a new JsonNode instance based on the arguments and append that
515** instance to the JsonParse. Return the index in pParse->aNode[] of the
516** new node, or -1 if a memory allocation fails.
517*/
518static int jsonParseAddNode(
519 JsonParse *pParse, /* Append the node to this object */
520 u32 eType, /* Node type */
521 u32 n, /* Content size or sub-node count */
522 const char *zContent /* Content */
523){
524 JsonNode *p;
525 if( pParse->nNode>=pParse->nAlloc ){
526 u32 nNew;
527 JsonNode *pNew;
528 if( pParse->oom ) return -1;
529 nNew = pParse->nAlloc*2 + 10;
530 if( nNew<=pParse->nNode ){
531 pParse->oom = 1;
532 return -1;
533 }
534 pNew = sqlite3_realloc(pParse->aNode, sizeof(JsonNode)*nNew);
535 if( pNew==0 ){
536 pParse->oom = 1;
537 return -1;
538 }
539 pParse->nAlloc = nNew;
540 pParse->aNode = pNew;
541 }
542 p = &pParse->aNode[pParse->nNode];
drh5634cc02015-08-17 11:28:03 +0000543 p->eType = (u8)eType;
drh301eecc2015-08-17 20:14:19 +0000544 p->jnFlags = 0;
drhd0960592015-08-17 21:22:32 +0000545 p->iVal = 0;
drhe9c37f32015-08-15 21:25:36 +0000546 p->n = n;
drh52216ad2015-08-18 02:28:03 +0000547 p->u.zJContent = zContent;
drhe9c37f32015-08-15 21:25:36 +0000548 return pParse->nNode++;
549}
550
551/*
552** Parse a single JSON value which begins at pParse->zJson[i]. Return the
553** index of the first character past the end of the value parsed.
554**
555** Return negative for a syntax error. Special cases: return -2 if the
556** first non-whitespace character is '}' and return -3 if the first
557** non-whitespace character is ']'.
558*/
559static int jsonParseValue(JsonParse *pParse, u32 i){
560 char c;
561 u32 j;
drhbc8f0922015-08-22 19:39:04 +0000562 int iThis;
drhe9c37f32015-08-15 21:25:36 +0000563 int x;
564 while( isspace(pParse->zJson[i]) ){ i++; }
565 if( (c = pParse->zJson[i])==0 ) return 0;
566 if( c=='{' ){
567 /* Parse object */
568 iThis = jsonParseAddNode(pParse, JSON_OBJECT, 0, 0);
drhbc8f0922015-08-22 19:39:04 +0000569 if( iThis<0 ) return -1;
drhe9c37f32015-08-15 21:25:36 +0000570 for(j=i+1;;j++){
571 while( isspace(pParse->zJson[j]) ){ j++; }
572 x = jsonParseValue(pParse, j);
573 if( x<0 ){
drhbc8f0922015-08-22 19:39:04 +0000574 if( x==(-2) && pParse->nNode==(u32)iThis+1 ) return j+1;
drhe9c37f32015-08-15 21:25:36 +0000575 return -1;
576 }
drhbe9474e2015-08-22 03:05:54 +0000577 if( pParse->oom ) return -1;
drhe9c37f32015-08-15 21:25:36 +0000578 if( pParse->aNode[pParse->nNode-1].eType!=JSON_STRING ) return -1;
579 j = x;
580 while( isspace(pParse->zJson[j]) ){ j++; }
581 if( pParse->zJson[j]!=':' ) return -1;
582 j++;
583 x = jsonParseValue(pParse, j);
584 if( x<0 ) return -1;
585 j = x;
586 while( isspace(pParse->zJson[j]) ){ j++; }
587 c = pParse->zJson[j];
588 if( c==',' ) continue;
589 if( c!='}' ) return -1;
590 break;
591 }
drhbc8f0922015-08-22 19:39:04 +0000592 pParse->aNode[iThis].n = pParse->nNode - (u32)iThis - 1;
drhe9c37f32015-08-15 21:25:36 +0000593 return j+1;
594 }else if( c=='[' ){
595 /* Parse array */
596 iThis = jsonParseAddNode(pParse, JSON_ARRAY, 0, 0);
drhbc8f0922015-08-22 19:39:04 +0000597 if( iThis<0 ) return -1;
drhe9c37f32015-08-15 21:25:36 +0000598 for(j=i+1;;j++){
599 while( isspace(pParse->zJson[j]) ){ j++; }
600 x = jsonParseValue(pParse, j);
601 if( x<0 ){
drhbc8f0922015-08-22 19:39:04 +0000602 if( x==(-3) && pParse->nNode==(u32)iThis+1 ) return j+1;
drhe9c37f32015-08-15 21:25:36 +0000603 return -1;
604 }
605 j = x;
606 while( isspace(pParse->zJson[j]) ){ j++; }
607 c = pParse->zJson[j];
608 if( c==',' ) continue;
609 if( c!=']' ) return -1;
610 break;
611 }
drhbc8f0922015-08-22 19:39:04 +0000612 pParse->aNode[iThis].n = pParse->nNode - (u32)iThis - 1;
drhe9c37f32015-08-15 21:25:36 +0000613 return j+1;
614 }else if( c=='"' ){
615 /* Parse string */
drh301eecc2015-08-17 20:14:19 +0000616 u8 jnFlags = 0;
drhe9c37f32015-08-15 21:25:36 +0000617 j = i+1;
618 for(;;){
619 c = pParse->zJson[j];
620 if( c==0 ) return -1;
621 if( c=='\\' ){
622 c = pParse->zJson[++j];
623 if( c==0 ) return -1;
drh301eecc2015-08-17 20:14:19 +0000624 jnFlags = JNODE_ESCAPE;
drhe9c37f32015-08-15 21:25:36 +0000625 }else if( c=='"' ){
626 break;
627 }
628 j++;
629 }
630 jsonParseAddNode(pParse, JSON_STRING, j+1-i, &pParse->zJson[i]);
drhbe9474e2015-08-22 03:05:54 +0000631 if( !pParse->oom ) pParse->aNode[pParse->nNode-1].jnFlags = jnFlags;
drhe9c37f32015-08-15 21:25:36 +0000632 return j+1;
633 }else if( c=='n'
634 && strncmp(pParse->zJson+i,"null",4)==0
drhb2cd10e2015-08-15 21:29:14 +0000635 && !isalnum(pParse->zJson[i+4]) ){
drhe9c37f32015-08-15 21:25:36 +0000636 jsonParseAddNode(pParse, JSON_NULL, 0, 0);
637 return i+4;
638 }else if( c=='t'
639 && strncmp(pParse->zJson+i,"true",4)==0
drhb2cd10e2015-08-15 21:29:14 +0000640 && !isalnum(pParse->zJson[i+4]) ){
drhe9c37f32015-08-15 21:25:36 +0000641 jsonParseAddNode(pParse, JSON_TRUE, 0, 0);
642 return i+4;
643 }else if( c=='f'
644 && strncmp(pParse->zJson+i,"false",5)==0
drhb2cd10e2015-08-15 21:29:14 +0000645 && !isalnum(pParse->zJson[i+5]) ){
drhe9c37f32015-08-15 21:25:36 +0000646 jsonParseAddNode(pParse, JSON_FALSE, 0, 0);
647 return i+5;
648 }else if( c=='-' || (c>='0' && c<='9') ){
649 /* Parse number */
650 u8 seenDP = 0;
651 u8 seenE = 0;
652 j = i+1;
653 for(;; j++){
654 c = pParse->zJson[j];
655 if( c>='0' && c<='9' ) continue;
656 if( c=='.' ){
657 if( pParse->zJson[j-1]=='-' ) return -1;
658 if( seenDP ) return -1;
659 seenDP = 1;
660 continue;
661 }
662 if( c=='e' || c=='E' ){
663 if( pParse->zJson[j-1]<'0' ) return -1;
664 if( seenE ) return -1;
665 seenDP = seenE = 1;
666 c = pParse->zJson[j+1];
drh8784eca2015-08-23 02:42:30 +0000667 if( c=='+' || c=='-' ){
668 j++;
669 c = pParse->zJson[j+1];
670 }
671 if( c<'0' || c>'0' ) return -1;
drhe9c37f32015-08-15 21:25:36 +0000672 continue;
673 }
674 break;
675 }
676 if( pParse->zJson[j-1]<'0' ) return -1;
677 jsonParseAddNode(pParse, seenDP ? JSON_REAL : JSON_INT,
678 j - i, &pParse->zJson[i]);
679 return j;
680 }else if( c=='}' ){
681 return -2; /* End of {...} */
682 }else if( c==']' ){
683 return -3; /* End of [...] */
684 }else{
685 return -1; /* Syntax error */
686 }
687}
688
689/*
690** Parse a complete JSON string. Return 0 on success or non-zero if there
691** are any errors. If an error occurs, free all memory associated with
692** pParse.
693**
694** pParse is uninitialized when this routine is called.
695*/
drhbc8f0922015-08-22 19:39:04 +0000696static int jsonParse(
697 JsonParse *pParse, /* Initialize and fill this JsonParse object */
698 sqlite3_context *pCtx, /* Report errors here */
699 const char *zJson /* Input JSON text to be parsed */
700){
drhe9c37f32015-08-15 21:25:36 +0000701 int i;
drhe9c37f32015-08-15 21:25:36 +0000702 memset(pParse, 0, sizeof(*pParse));
drhc3722b22015-08-23 20:44:59 +0000703 if( zJson==0 ) return 1;
drhe9c37f32015-08-15 21:25:36 +0000704 pParse->zJson = zJson;
705 i = jsonParseValue(pParse, 0);
drhc3722b22015-08-23 20:44:59 +0000706 if( pParse->oom ) i = -1;
drhe9c37f32015-08-15 21:25:36 +0000707 if( i>0 ){
708 while( isspace(zJson[i]) ) i++;
709 if( zJson[i] ) i = -1;
710 }
711 if( i<0 ){
drhbc8f0922015-08-22 19:39:04 +0000712 if( pParse->oom && pCtx!=0 ) sqlite3_result_error_nomem(pCtx);
drh505ad2c2015-08-21 17:33:11 +0000713 jsonParseReset(pParse);
drhe9c37f32015-08-15 21:25:36 +0000714 return 1;
715 }
716 return 0;
717}
drh301eecc2015-08-17 20:14:19 +0000718
drh505ad2c2015-08-21 17:33:11 +0000719/* Mark node i of pParse as being a child of iParent. Call recursively
720** to fill in all the descendants of node i.
721*/
722static void jsonParseFillInParentage(JsonParse *pParse, u32 i, u32 iParent){
723 JsonNode *pNode = &pParse->aNode[i];
724 u32 j;
725 pParse->aUp[i] = iParent;
726 switch( pNode->eType ){
727 case JSON_ARRAY: {
728 for(j=1; j<=pNode->n; j += jsonNodeSize(pNode+j)){
729 jsonParseFillInParentage(pParse, i+j, i);
730 }
731 break;
732 }
733 case JSON_OBJECT: {
734 for(j=1; j<=pNode->n; j += jsonNodeSize(pNode+j+1)+1){
735 pParse->aUp[i+j] = i;
736 jsonParseFillInParentage(pParse, i+j+1, i);
737 }
738 break;
739 }
740 default: {
741 break;
742 }
743 }
744}
745
746/*
747** Compute the parentage of all nodes in a completed parse.
748*/
749static int jsonParseFindParents(JsonParse *pParse){
750 u32 *aUp;
751 assert( pParse->aUp==0 );
752 aUp = pParse->aUp = sqlite3_malloc( sizeof(u32)*pParse->nNode );
drhc3722b22015-08-23 20:44:59 +0000753 if( aUp==0 ){
754 pParse->oom = 1;
755 return SQLITE_NOMEM;
756 }
drh505ad2c2015-08-21 17:33:11 +0000757 jsonParseFillInParentage(pParse, 0, 0);
758 return SQLITE_OK;
759}
760
drh52216ad2015-08-18 02:28:03 +0000761/* forward declaration */
762static JsonNode *jsonLookupAppend(JsonParse*,const char*,int*);
763
drh987eb1f2015-08-17 15:17:37 +0000764/*
765** Search along zPath to find the node specified. Return a pointer
766** to that node, or NULL if zPath is malformed or if there is no such
767** node.
drh52216ad2015-08-18 02:28:03 +0000768**
769** If pApnd!=0, then try to append new nodes to complete zPath if it is
770** possible to do so and if no existing node corresponds to zPath. If
771** new nodes are appended *pApnd is set to 1.
drh987eb1f2015-08-17 15:17:37 +0000772*/
drh52216ad2015-08-18 02:28:03 +0000773static JsonNode *jsonLookup(
774 JsonParse *pParse, /* The JSON to search */
775 u32 iRoot, /* Begin the search at this node */
776 const char *zPath, /* The path to search */
777 int *pApnd /* Append nodes to complete path if not NULL */
778){
drhbc8f0922015-08-22 19:39:04 +0000779 u32 i, j, nKey;
drh6b43cc82015-08-19 23:02:49 +0000780 const char *zKey;
drh52216ad2015-08-18 02:28:03 +0000781 JsonNode *pRoot = &pParse->aNode[iRoot];
drh987eb1f2015-08-17 15:17:37 +0000782 if( zPath[0]==0 ) return pRoot;
783 if( zPath[0]=='.' ){
784 if( pRoot->eType!=JSON_OBJECT ) return 0;
785 zPath++;
drh6b43cc82015-08-19 23:02:49 +0000786 if( zPath[0]=='"' ){
787 zKey = zPath + 1;
788 for(i=1; zPath[i] && zPath[i]!='"'; i++){}
789 nKey = i-1;
790 if( zPath[i] ) i++;
791 }else{
792 zKey = zPath;
793 for(i=0; zPath[i] && zPath[i]!='.' && zPath[i]!='['; i++){}
794 nKey = i;
795 }
796 if( nKey==0 ) return 0;
drh987eb1f2015-08-17 15:17:37 +0000797 j = 1;
drh52216ad2015-08-18 02:28:03 +0000798 for(;;){
799 while( j<=pRoot->n ){
drh6b43cc82015-08-19 23:02:49 +0000800 if( pRoot[j].n==nKey+2
801 && strncmp(&pRoot[j].u.zJContent[1],zKey,nKey)==0
drh52216ad2015-08-18 02:28:03 +0000802 ){
803 return jsonLookup(pParse, iRoot+j+1, &zPath[i], pApnd);
804 }
805 j++;
drh505ad2c2015-08-21 17:33:11 +0000806 j += jsonNodeSize(&pRoot[j]);
drh987eb1f2015-08-17 15:17:37 +0000807 }
drh52216ad2015-08-18 02:28:03 +0000808 if( (pRoot->jnFlags & JNODE_APPEND)==0 ) break;
809 iRoot += pRoot->u.iAppend;
810 pRoot = &pParse->aNode[iRoot];
811 j = 1;
812 }
813 if( pApnd ){
drhbc8f0922015-08-22 19:39:04 +0000814 u32 iStart, iLabel;
815 JsonNode *pNode;
816 iStart = jsonParseAddNode(pParse, JSON_OBJECT, 2, 0);
817 iLabel = jsonParseAddNode(pParse, JSON_STRING, i, zPath);
drh52216ad2015-08-18 02:28:03 +0000818 zPath += i;
drhbc8f0922015-08-22 19:39:04 +0000819 pNode = jsonLookupAppend(pParse, zPath, pApnd);
820 if( pParse->oom ) return 0;
821 if( pNode ){
822 pRoot = &pParse->aNode[iRoot];
823 pRoot->u.iAppend = iStart - iRoot;
824 pRoot->jnFlags |= JNODE_APPEND;
825 pParse->aNode[iLabel].jnFlags |= JNODE_RAW;
826 }
827 return pNode;
drh987eb1f2015-08-17 15:17:37 +0000828 }
829 }else if( zPath[0]=='[' && isdigit(zPath[1]) ){
830 if( pRoot->eType!=JSON_ARRAY ) return 0;
831 i = 0;
832 zPath++;
833 while( isdigit(zPath[0]) ){
drh8784eca2015-08-23 02:42:30 +0000834 i = i*10 + zPath[0] - '0';
drh987eb1f2015-08-17 15:17:37 +0000835 zPath++;
836 }
837 if( zPath[0]!=']' ) return 0;
838 zPath++;
839 j = 1;
drh52216ad2015-08-18 02:28:03 +0000840 for(;;){
drhbc8f0922015-08-22 19:39:04 +0000841 while( j<=pRoot->n && (i>0 || (pRoot[j].jnFlags & JNODE_REMOVE)!=0) ){
842 if( (pRoot[j].jnFlags & JNODE_REMOVE)==0 ) i--;
drh505ad2c2015-08-21 17:33:11 +0000843 j += jsonNodeSize(&pRoot[j]);
drh52216ad2015-08-18 02:28:03 +0000844 }
845 if( (pRoot->jnFlags & JNODE_APPEND)==0 ) break;
846 iRoot += pRoot->u.iAppend;
847 pRoot = &pParse->aNode[iRoot];
848 j = 1;
drh987eb1f2015-08-17 15:17:37 +0000849 }
850 if( j<=pRoot->n ){
drh52216ad2015-08-18 02:28:03 +0000851 return jsonLookup(pParse, iRoot+j, zPath, pApnd);
852 }
853 if( i==0 && pApnd ){
drhbc8f0922015-08-22 19:39:04 +0000854 u32 iStart;
855 JsonNode *pNode;
856 iStart = jsonParseAddNode(pParse, JSON_ARRAY, 1, 0);
857 pNode = jsonLookupAppend(pParse, zPath, pApnd);
858 if( pParse->oom ) return 0;
859 if( pNode ){
860 pRoot = &pParse->aNode[iRoot];
861 pRoot->u.iAppend = iStart - iRoot;
862 pRoot->jnFlags |= JNODE_APPEND;
863 }
864 return pNode;
drh987eb1f2015-08-17 15:17:37 +0000865 }
866 }
867 return 0;
868}
869
drh52216ad2015-08-18 02:28:03 +0000870/*
drhbc8f0922015-08-22 19:39:04 +0000871** Append content to pParse that will complete zPath. Return a pointer
872** to the inserted node, or return NULL if the append fails.
drh52216ad2015-08-18 02:28:03 +0000873*/
874static JsonNode *jsonLookupAppend(
875 JsonParse *pParse, /* Append content to the JSON parse */
876 const char *zPath, /* Description of content to append */
877 int *pApnd /* Set this flag to 1 */
878){
879 *pApnd = 1;
880 if( zPath[0]==0 ){
881 jsonParseAddNode(pParse, JSON_NULL, 0, 0);
882 return pParse->oom ? 0 : &pParse->aNode[pParse->nNode-1];
883 }
884 if( zPath[0]=='.' ){
885 jsonParseAddNode(pParse, JSON_OBJECT, 0, 0);
886 }else if( strncmp(zPath,"[0]",3)==0 ){
887 jsonParseAddNode(pParse, JSON_ARRAY, 0, 0);
888 }else{
889 return 0;
890 }
891 if( pParse->oom ) return 0;
892 return jsonLookup(pParse, pParse->nNode-1, zPath, pApnd);
893}
894
drhbc8f0922015-08-22 19:39:04 +0000895/*
896** Report the wrong number of arguments for json_insert(), json_replace()
897** or json_set().
898*/
899static void jsonWrongNumArgs(
900 sqlite3_context *pCtx,
901 const char *zFuncName
902){
903 char *zMsg = sqlite3_mprintf("json_%s() needs an odd number of arguments",
904 zFuncName);
905 sqlite3_result_error(pCtx, zMsg, -1);
906 sqlite3_free(zMsg);
907}
drh52216ad2015-08-18 02:28:03 +0000908
drh987eb1f2015-08-17 15:17:37 +0000909/****************************************************************************
910** SQL functions used for testing and debugging
911****************************************************************************/
drhe9c37f32015-08-15 21:25:36 +0000912
drh301eecc2015-08-17 20:14:19 +0000913#ifdef SQLITE_DEBUG
drhe9c37f32015-08-15 21:25:36 +0000914/*
drh5634cc02015-08-17 11:28:03 +0000915** The json_parse(JSON) function returns a string which describes
drhe9c37f32015-08-15 21:25:36 +0000916** a parse of the JSON provided. Or it returns NULL if JSON is not
917** well-formed.
918*/
drh5634cc02015-08-17 11:28:03 +0000919static void jsonParseFunc(
drhbc8f0922015-08-22 19:39:04 +0000920 sqlite3_context *ctx,
drhe9c37f32015-08-15 21:25:36 +0000921 int argc,
922 sqlite3_value **argv
923){
drh505ad2c2015-08-21 17:33:11 +0000924 JsonString s; /* Output string - not real JSON */
925 JsonParse x; /* The parse */
drhe9c37f32015-08-15 21:25:36 +0000926 u32 i;
drhe9c37f32015-08-15 21:25:36 +0000927
928 assert( argc==1 );
drhbc8f0922015-08-22 19:39:04 +0000929 if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return;
drh8784eca2015-08-23 02:42:30 +0000930 jsonParseFindParents(&x);
drhbc8f0922015-08-22 19:39:04 +0000931 jsonInit(&s, ctx);
drhe9c37f32015-08-15 21:25:36 +0000932 for(i=0; i<x.nNode; i++){
drh8784eca2015-08-23 02:42:30 +0000933 jsonPrintf(100, &s,"node %3u: %7s n=%-4d up=%d\n",
934 i, jsonType[x.aNode[i].eType], x.aNode[i].n, x.aUp[i]);
drh52216ad2015-08-18 02:28:03 +0000935 if( x.aNode[i].u.zJContent!=0 ){
drh301eecc2015-08-17 20:14:19 +0000936 jsonAppendRaw(&s, " text: ", 10);
drh52216ad2015-08-18 02:28:03 +0000937 jsonAppendRaw(&s, x.aNode[i].u.zJContent, x.aNode[i].n);
drhe9c37f32015-08-15 21:25:36 +0000938 jsonAppendRaw(&s, "\n", 1);
939 }
940 }
drh505ad2c2015-08-21 17:33:11 +0000941 jsonParseReset(&x);
drhe9c37f32015-08-15 21:25:36 +0000942 jsonResult(&s);
943}
944
drh5634cc02015-08-17 11:28:03 +0000945/*
946** The json_test1(JSON) function parses and rebuilds the JSON string.
947*/
948static void jsonTest1Func(
drhbc8f0922015-08-22 19:39:04 +0000949 sqlite3_context *ctx,
drh5634cc02015-08-17 11:28:03 +0000950 int argc,
951 sqlite3_value **argv
952){
953 JsonParse x; /* The parse */
drhbc8f0922015-08-22 19:39:04 +0000954 if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return;
955 jsonReturn(x.aNode, ctx, 0);
drh505ad2c2015-08-21 17:33:11 +0000956 jsonParseReset(&x);
drh5634cc02015-08-17 11:28:03 +0000957}
958
959/*
960** The json_nodecount(JSON) function returns the number of nodes in the
961** input JSON string.
962*/
963static void jsonNodeCountFunc(
drhbc8f0922015-08-22 19:39:04 +0000964 sqlite3_context *ctx,
drh5634cc02015-08-17 11:28:03 +0000965 int argc,
966 sqlite3_value **argv
967){
968 JsonParse x; /* The parse */
drhbc8f0922015-08-22 19:39:04 +0000969 if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return;
970 sqlite3_result_int64(ctx, (sqlite3_int64)x.nNode);
drh505ad2c2015-08-21 17:33:11 +0000971 jsonParseReset(&x);
drh5634cc02015-08-17 11:28:03 +0000972}
drh301eecc2015-08-17 20:14:19 +0000973#endif /* SQLITE_DEBUG */
drh5634cc02015-08-17 11:28:03 +0000974
drh987eb1f2015-08-17 15:17:37 +0000975/****************************************************************************
976** SQL function implementations
977****************************************************************************/
978
979/*
980** Implementation of the json_array(VALUE,...) function. Return a JSON
981** array that contains all values given in arguments. Or if any argument
982** is a BLOB, throw an error.
983*/
984static void jsonArrayFunc(
drhbc8f0922015-08-22 19:39:04 +0000985 sqlite3_context *ctx,
drh987eb1f2015-08-17 15:17:37 +0000986 int argc,
987 sqlite3_value **argv
988){
989 int i;
drh505ad2c2015-08-21 17:33:11 +0000990 JsonString jx;
drh987eb1f2015-08-17 15:17:37 +0000991
drhbc8f0922015-08-22 19:39:04 +0000992 jsonInit(&jx, ctx);
drhd0960592015-08-17 21:22:32 +0000993 jsonAppendChar(&jx, '[');
drh987eb1f2015-08-17 15:17:37 +0000994 for(i=0; i<argc; i++){
drhd0960592015-08-17 21:22:32 +0000995 jsonAppendSeparator(&jx);
996 jsonAppendValue(&jx, argv[i]);
drh987eb1f2015-08-17 15:17:37 +0000997 }
drhd0960592015-08-17 21:22:32 +0000998 jsonAppendChar(&jx, ']');
drh987eb1f2015-08-17 15:17:37 +0000999 jsonResult(&jx);
1000}
1001
1002
1003/*
1004** json_array_length(JSON)
1005** json_array_length(JSON, PATH)
1006**
1007** Return the number of elements in the top-level JSON array.
1008** Return 0 if the input is not a well-formed JSON array.
1009*/
1010static void jsonArrayLengthFunc(
drhbc8f0922015-08-22 19:39:04 +00001011 sqlite3_context *ctx,
drh987eb1f2015-08-17 15:17:37 +00001012 int argc,
1013 sqlite3_value **argv
1014){
1015 JsonParse x; /* The parse */
1016 sqlite3_int64 n = 0;
1017 u32 i;
1018 const char *zPath;
1019
1020 if( argc==2 ){
1021 zPath = (const char*)sqlite3_value_text(argv[1]);
1022 if( zPath==0 ) return;
1023 if( zPath[0]!='$' ) return;
1024 zPath++;
1025 }else{
1026 zPath = 0;
1027 }
drhbc8f0922015-08-22 19:39:04 +00001028 if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0]))==0 ){
drh987eb1f2015-08-17 15:17:37 +00001029 if( x.nNode ){
1030 JsonNode *pNode = x.aNode;
drh52216ad2015-08-18 02:28:03 +00001031 if( zPath ) pNode = jsonLookup(&x, 0, zPath, 0);
drh987eb1f2015-08-17 15:17:37 +00001032 if( pNode->eType==JSON_ARRAY ){
drh52216ad2015-08-18 02:28:03 +00001033 assert( (pNode->jnFlags & JNODE_APPEND)==0 );
drh301eecc2015-08-17 20:14:19 +00001034 for(i=1; i<=pNode->n; n++){
drh505ad2c2015-08-21 17:33:11 +00001035 i += jsonNodeSize(&pNode[i]);
drh987eb1f2015-08-17 15:17:37 +00001036 }
1037 }
1038 }
drh505ad2c2015-08-21 17:33:11 +00001039 jsonParseReset(&x);
drh987eb1f2015-08-17 15:17:37 +00001040 }
drhbc8f0922015-08-22 19:39:04 +00001041 if( !x.oom ) sqlite3_result_int64(ctx, n);
drh987eb1f2015-08-17 15:17:37 +00001042}
1043
1044/*
1045** json_extract(JSON, PATH)
1046**
1047** Return the element described by PATH. Return NULL if JSON is not
1048** valid JSON or if there is no PATH element or if PATH is malformed.
1049*/
1050static void jsonExtractFunc(
drhbc8f0922015-08-22 19:39:04 +00001051 sqlite3_context *ctx,
drh987eb1f2015-08-17 15:17:37 +00001052 int argc,
1053 sqlite3_value **argv
1054){
1055 JsonParse x; /* The parse */
1056 JsonNode *pNode;
1057 const char *zPath;
1058 assert( argc==2 );
1059 zPath = (const char*)sqlite3_value_text(argv[1]);
1060 if( zPath==0 ) return;
1061 if( zPath[0]!='$' ) return;
1062 zPath++;
drhbc8f0922015-08-22 19:39:04 +00001063 if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return;
drh52216ad2015-08-18 02:28:03 +00001064 pNode = jsonLookup(&x, 0, zPath, 0);
drh987eb1f2015-08-17 15:17:37 +00001065 if( pNode ){
drhbc8f0922015-08-22 19:39:04 +00001066 jsonReturn(pNode, ctx, 0);
drh987eb1f2015-08-17 15:17:37 +00001067 }
drh505ad2c2015-08-21 17:33:11 +00001068 jsonParseReset(&x);
drh987eb1f2015-08-17 15:17:37 +00001069}
1070
1071/*
1072** Implementation of the json_object(NAME,VALUE,...) function. Return a JSON
1073** object that contains all name/value given in arguments. Or if any name
1074** is not a string or if any value is a BLOB, throw an error.
1075*/
1076static void jsonObjectFunc(
drhbc8f0922015-08-22 19:39:04 +00001077 sqlite3_context *ctx,
drh987eb1f2015-08-17 15:17:37 +00001078 int argc,
1079 sqlite3_value **argv
1080){
1081 int i;
drh505ad2c2015-08-21 17:33:11 +00001082 JsonString jx;
drh987eb1f2015-08-17 15:17:37 +00001083 const char *z;
1084 u32 n;
1085
1086 if( argc&1 ){
drhbc8f0922015-08-22 19:39:04 +00001087 sqlite3_result_error(ctx, "json_object() requires an even number "
drh987eb1f2015-08-17 15:17:37 +00001088 "of arguments", -1);
1089 return;
1090 }
drhbc8f0922015-08-22 19:39:04 +00001091 jsonInit(&jx, ctx);
drhd0960592015-08-17 21:22:32 +00001092 jsonAppendChar(&jx, '{');
drh987eb1f2015-08-17 15:17:37 +00001093 for(i=0; i<argc; i+=2){
drh987eb1f2015-08-17 15:17:37 +00001094 if( sqlite3_value_type(argv[i])!=SQLITE_TEXT ){
drhbc8f0922015-08-22 19:39:04 +00001095 sqlite3_result_error(ctx, "json_object() labels must be TEXT", -1);
drh987eb1f2015-08-17 15:17:37 +00001096 jsonZero(&jx);
1097 return;
1098 }
drhd0960592015-08-17 21:22:32 +00001099 jsonAppendSeparator(&jx);
drh987eb1f2015-08-17 15:17:37 +00001100 z = (const char*)sqlite3_value_text(argv[i]);
1101 n = (u32)sqlite3_value_bytes(argv[i]);
1102 jsonAppendString(&jx, z, n);
drhd0960592015-08-17 21:22:32 +00001103 jsonAppendChar(&jx, ':');
1104 jsonAppendValue(&jx, argv[i+1]);
drh987eb1f2015-08-17 15:17:37 +00001105 }
drhd0960592015-08-17 21:22:32 +00001106 jsonAppendChar(&jx, '}');
drh987eb1f2015-08-17 15:17:37 +00001107 jsonResult(&jx);
1108}
1109
1110
1111/*
drh301eecc2015-08-17 20:14:19 +00001112** json_remove(JSON, PATH, ...)
1113**
1114** Remove the named elements from JSON and return the result. Ill-formed
1115** PATH arguments are silently ignored. If JSON is ill-formed, then NULL
1116** is returned.
1117*/
1118static void jsonRemoveFunc(
drhbc8f0922015-08-22 19:39:04 +00001119 sqlite3_context *ctx,
drh301eecc2015-08-17 20:14:19 +00001120 int argc,
1121 sqlite3_value **argv
1122){
1123 JsonParse x; /* The parse */
1124 JsonNode *pNode;
1125 const char *zPath;
1126 u32 i;
1127
1128 if( argc<1 ) return;
drhbc8f0922015-08-22 19:39:04 +00001129 if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return;
drh301eecc2015-08-17 20:14:19 +00001130 if( x.nNode ){
drh6fd5c1e2015-08-21 20:37:12 +00001131 for(i=1; i<(u32)argc; i++){
drh301eecc2015-08-17 20:14:19 +00001132 zPath = (const char*)sqlite3_value_text(argv[i]);
1133 if( zPath==0 ) continue;
1134 if( zPath[0]!='$' ) continue;
drh52216ad2015-08-18 02:28:03 +00001135 pNode = jsonLookup(&x, 0, &zPath[1], 0);
drh301eecc2015-08-17 20:14:19 +00001136 if( pNode ) pNode->jnFlags |= JNODE_REMOVE;
1137 }
1138 if( (x.aNode[0].jnFlags & JNODE_REMOVE)==0 ){
drhbc8f0922015-08-22 19:39:04 +00001139 jsonReturn(x.aNode, ctx, 0);
drhd0960592015-08-17 21:22:32 +00001140 }
1141 }
drh505ad2c2015-08-21 17:33:11 +00001142 jsonParseReset(&x);
drhd0960592015-08-17 21:22:32 +00001143}
1144
1145/*
1146** json_replace(JSON, PATH, VALUE, ...)
1147**
1148** Replace the value at PATH with VALUE. If PATH does not already exist,
1149** this routine is a no-op. If JSON is ill-formed, return NULL.
1150*/
1151static void jsonReplaceFunc(
drhbc8f0922015-08-22 19:39:04 +00001152 sqlite3_context *ctx,
drhd0960592015-08-17 21:22:32 +00001153 int argc,
1154 sqlite3_value **argv
1155){
1156 JsonParse x; /* The parse */
1157 JsonNode *pNode;
1158 const char *zPath;
1159 u32 i;
1160
1161 if( argc<1 ) return;
1162 if( (argc&1)==0 ) {
drhbc8f0922015-08-22 19:39:04 +00001163 jsonWrongNumArgs(ctx, "replace");
drhd0960592015-08-17 21:22:32 +00001164 return;
1165 }
drhbc8f0922015-08-22 19:39:04 +00001166 if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return;
drhd0960592015-08-17 21:22:32 +00001167 if( x.nNode ){
drh6fd5c1e2015-08-21 20:37:12 +00001168 for(i=1; i<(u32)argc; i+=2){
drhd0960592015-08-17 21:22:32 +00001169 zPath = (const char*)sqlite3_value_text(argv[i]);
1170 if( zPath==0 ) continue;
1171 if( zPath[0]!='$' ) continue;
drh52216ad2015-08-18 02:28:03 +00001172 pNode = jsonLookup(&x, 0, &zPath[1], 0);
drhd0960592015-08-17 21:22:32 +00001173 if( pNode ){
1174 pNode->jnFlags |= JNODE_REPLACE;
1175 pNode->iVal = i+1;
1176 }
1177 }
1178 if( x.aNode[0].jnFlags & JNODE_REPLACE ){
drhbc8f0922015-08-22 19:39:04 +00001179 sqlite3_result_value(ctx, argv[x.aNode[0].iVal]);
drhd0960592015-08-17 21:22:32 +00001180 }else{
drhbc8f0922015-08-22 19:39:04 +00001181 jsonReturn(x.aNode, ctx, argv);
drh301eecc2015-08-17 20:14:19 +00001182 }
1183 }
drh505ad2c2015-08-21 17:33:11 +00001184 jsonParseReset(&x);
drh301eecc2015-08-17 20:14:19 +00001185}
drh505ad2c2015-08-21 17:33:11 +00001186
drh52216ad2015-08-18 02:28:03 +00001187/*
1188** json_set(JSON, PATH, VALUE, ...)
1189**
1190** Set the value at PATH to VALUE. Create the PATH if it does not already
1191** exist. Overwrite existing values that do exist.
1192** If JSON is ill-formed, return NULL.
1193**
1194** json_insert(JSON, PATH, VALUE, ...)
1195**
1196** Create PATH and initialize it to VALUE. If PATH already exists, this
1197** routine is a no-op. If JSON is ill-formed, return NULL.
1198*/
1199static void jsonSetFunc(
drhbc8f0922015-08-22 19:39:04 +00001200 sqlite3_context *ctx,
drh52216ad2015-08-18 02:28:03 +00001201 int argc,
1202 sqlite3_value **argv
1203){
1204 JsonParse x; /* The parse */
1205 JsonNode *pNode;
1206 const char *zPath;
1207 u32 i;
1208 int bApnd;
drhbc8f0922015-08-22 19:39:04 +00001209 int bIsSet = *(int*)sqlite3_user_data(ctx);
drh52216ad2015-08-18 02:28:03 +00001210
1211 if( argc<1 ) return;
1212 if( (argc&1)==0 ) {
drhbc8f0922015-08-22 19:39:04 +00001213 jsonWrongNumArgs(ctx, bIsSet ? "set" : "insert");
drh52216ad2015-08-18 02:28:03 +00001214 return;
1215 }
drhbc8f0922015-08-22 19:39:04 +00001216 if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return;
drh52216ad2015-08-18 02:28:03 +00001217 if( x.nNode ){
drh6fd5c1e2015-08-21 20:37:12 +00001218 for(i=1; i<(u32)argc; i+=2){
drh52216ad2015-08-18 02:28:03 +00001219 zPath = (const char*)sqlite3_value_text(argv[i]);
1220 if( zPath==0 ) continue;
1221 if( zPath[0]!='$' ) continue;
1222 bApnd = 0;
1223 pNode = jsonLookup(&x, 0, &zPath[1], &bApnd);
drhbc8f0922015-08-22 19:39:04 +00001224 if( x.oom ){
1225 sqlite3_result_error_nomem(ctx);
1226 goto jsonSetDone;
1227 }else if( pNode && (bApnd || bIsSet) ){
drh52216ad2015-08-18 02:28:03 +00001228 pNode->jnFlags |= JNODE_REPLACE;
1229 pNode->iVal = i+1;
1230 }
1231 }
1232 if( x.aNode[0].jnFlags & JNODE_REPLACE ){
drhbc8f0922015-08-22 19:39:04 +00001233 sqlite3_result_value(ctx, argv[x.aNode[0].iVal]);
drh52216ad2015-08-18 02:28:03 +00001234 }else{
drhbc8f0922015-08-22 19:39:04 +00001235 jsonReturn(x.aNode, ctx, argv);
drh52216ad2015-08-18 02:28:03 +00001236 }
1237 }
drhbc8f0922015-08-22 19:39:04 +00001238jsonSetDone:
drh505ad2c2015-08-21 17:33:11 +00001239 jsonParseReset(&x);
drh52216ad2015-08-18 02:28:03 +00001240}
drh301eecc2015-08-17 20:14:19 +00001241
1242/*
drh987eb1f2015-08-17 15:17:37 +00001243** json_type(JSON)
1244** json_type(JSON, PATH)
1245**
1246** Return the top-level "type" of a JSON string. Return NULL if the
1247** input is not a well-formed JSON string.
1248*/
1249static void jsonTypeFunc(
drhbc8f0922015-08-22 19:39:04 +00001250 sqlite3_context *ctx,
drh987eb1f2015-08-17 15:17:37 +00001251 int argc,
1252 sqlite3_value **argv
1253){
1254 JsonParse x; /* The parse */
1255 const char *zPath;
1256
1257 if( argc==2 ){
1258 zPath = (const char*)sqlite3_value_text(argv[1]);
1259 if( zPath==0 ) return;
1260 if( zPath[0]!='$' ) return;
1261 zPath++;
1262 }else{
1263 zPath = 0;
1264 }
drhbc8f0922015-08-22 19:39:04 +00001265 if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return;
drh987eb1f2015-08-17 15:17:37 +00001266 if( x.nNode ){
1267 JsonNode *pNode = x.aNode;
drh52216ad2015-08-18 02:28:03 +00001268 if( zPath ) pNode = jsonLookup(&x, 0, zPath, 0);
drhbc8f0922015-08-22 19:39:04 +00001269 if( pNode ){
1270 sqlite3_result_text(ctx, jsonType[pNode->eType], -1, SQLITE_STATIC);
1271 }
drh987eb1f2015-08-17 15:17:37 +00001272 }
drh505ad2c2015-08-21 17:33:11 +00001273 jsonParseReset(&x);
drh987eb1f2015-08-17 15:17:37 +00001274}
drh5634cc02015-08-17 11:28:03 +00001275
drhbc8f0922015-08-22 19:39:04 +00001276/*
1277** json_valid(JSON)
1278**
1279** Return 1 if JSON is a valid JSON string. Return 0 otherwise.
1280*/
1281static void jsonValidFunc(
1282 sqlite3_context *ctx,
1283 int argc,
1284 sqlite3_value **argv
1285){
1286 JsonParse x; /* The parse */
1287 int rc = 0;
1288
1289 if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0]))==0
1290 && x.nNode>0
1291 ){
1292 rc = 1;
1293 }
1294 jsonParseReset(&x);
1295 sqlite3_result_int(ctx, rc);
1296}
1297
drhcb6c6c62015-08-19 22:47:17 +00001298/****************************************************************************
1299** The json_each virtual table
1300****************************************************************************/
1301typedef struct JsonEachCursor JsonEachCursor;
1302struct JsonEachCursor {
1303 sqlite3_vtab_cursor base; /* Base class - must be first */
drh505ad2c2015-08-21 17:33:11 +00001304 u32 iRowid; /* The rowid */
1305 u32 i; /* Index in sParse.aNode[] of current row */
1306 u32 iEnd; /* EOF when i equals or exceeds this value */
1307 u8 eType; /* Type of top-level element */
1308 u8 bRecursive; /* True for json_tree(). False for json_each() */
1309 char *zJson; /* Input JSON */
1310 char *zPath; /* Path by which to filter zJson */
1311 JsonParse sParse; /* Parse of the input JSON */
drhcb6c6c62015-08-19 22:47:17 +00001312};
1313
1314/* Constructor for the json_each virtual table */
1315static int jsonEachConnect(
1316 sqlite3 *db,
1317 void *pAux,
1318 int argc, const char *const*argv,
1319 sqlite3_vtab **ppVtab,
1320 char **pzErr
1321){
1322 sqlite3_vtab *pNew;
drh505ad2c2015-08-21 17:33:11 +00001323 int rc;
drhcb6c6c62015-08-19 22:47:17 +00001324
1325/* Column numbers */
drh4af352d2015-08-21 20:02:48 +00001326#define JEACH_KEY 0
1327#define JEACH_VALUE 1
1328#define JEACH_TYPE 2
1329#define JEACH_ATOM 3
1330#define JEACH_ID 4
1331#define JEACH_PARENT 5
1332#define JEACH_FULLKEY 6
1333#define JEACH_JSON 7
1334#define JEACH_PATH 8
drhcb6c6c62015-08-19 22:47:17 +00001335
drh6fd5c1e2015-08-21 20:37:12 +00001336 UNUSED_PARAM(pzErr);
1337 UNUSED_PARAM(argv);
1338 UNUSED_PARAM(argc);
1339 UNUSED_PARAM(pAux);
drh505ad2c2015-08-21 17:33:11 +00001340 rc = sqlite3_declare_vtab(db,
drh4af352d2015-08-21 20:02:48 +00001341 "CREATE TABLE x(key,value,type,atom,id,parent,fullkey,"
1342 "json HIDDEN,path HIDDEN)");
drh505ad2c2015-08-21 17:33:11 +00001343 if( rc==SQLITE_OK ){
1344 pNew = *ppVtab = sqlite3_malloc( sizeof(*pNew) );
1345 if( pNew==0 ) return SQLITE_NOMEM;
1346 memset(pNew, 0, sizeof(*pNew));
1347 }
1348 return rc;
drhcb6c6c62015-08-19 22:47:17 +00001349}
1350
1351/* destructor for json_each virtual table */
1352static int jsonEachDisconnect(sqlite3_vtab *pVtab){
1353 sqlite3_free(pVtab);
1354 return SQLITE_OK;
1355}
1356
drh505ad2c2015-08-21 17:33:11 +00001357/* constructor for a JsonEachCursor object for json_each(). */
1358static int jsonEachOpenEach(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
drhcb6c6c62015-08-19 22:47:17 +00001359 JsonEachCursor *pCur;
drh6fd5c1e2015-08-21 20:37:12 +00001360
1361 UNUSED_PARAM(p);
drhcb6c6c62015-08-19 22:47:17 +00001362 pCur = sqlite3_malloc( sizeof(*pCur) );
1363 if( pCur==0 ) return SQLITE_NOMEM;
1364 memset(pCur, 0, sizeof(*pCur));
1365 *ppCursor = &pCur->base;
1366 return SQLITE_OK;
1367}
1368
drh505ad2c2015-08-21 17:33:11 +00001369/* constructor for a JsonEachCursor object for json_tree(). */
1370static int jsonEachOpenTree(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
1371 int rc = jsonEachOpenEach(p, ppCursor);
1372 if( rc==SQLITE_OK ){
1373 JsonEachCursor *pCur = (JsonEachCursor*)*ppCursor;
1374 pCur->bRecursive = 1;
1375 }
1376 return rc;
1377}
1378
drhcb6c6c62015-08-19 22:47:17 +00001379/* Reset a JsonEachCursor back to its original state. Free any memory
1380** held. */
1381static void jsonEachCursorReset(JsonEachCursor *p){
1382 sqlite3_free(p->zJson);
1383 sqlite3_free(p->zPath);
drh505ad2c2015-08-21 17:33:11 +00001384 jsonParseReset(&p->sParse);
drhcb6c6c62015-08-19 22:47:17 +00001385 p->iRowid = 0;
1386 p->i = 0;
1387 p->iEnd = 0;
1388 p->eType = 0;
drhcb6c6c62015-08-19 22:47:17 +00001389 p->zJson = 0;
1390 p->zPath = 0;
1391}
1392
1393/* Destructor for a jsonEachCursor object */
1394static int jsonEachClose(sqlite3_vtab_cursor *cur){
1395 JsonEachCursor *p = (JsonEachCursor*)cur;
1396 jsonEachCursorReset(p);
1397 sqlite3_free(cur);
1398 return SQLITE_OK;
1399}
1400
1401/* Return TRUE if the jsonEachCursor object has been advanced off the end
1402** of the JSON object */
1403static int jsonEachEof(sqlite3_vtab_cursor *cur){
1404 JsonEachCursor *p = (JsonEachCursor*)cur;
1405 return p->i >= p->iEnd;
1406}
1407
drh505ad2c2015-08-21 17:33:11 +00001408/* Advance the cursor to the next element for json_tree() */
drh4af352d2015-08-21 20:02:48 +00001409static int jsonEachNext(sqlite3_vtab_cursor *cur){
drh505ad2c2015-08-21 17:33:11 +00001410 JsonEachCursor *p = (JsonEachCursor*)cur;
drh4af352d2015-08-21 20:02:48 +00001411 if( p->bRecursive ){
1412 if( p->i==0 ){
1413 p->i = 1;
drh4af352d2015-08-21 20:02:48 +00001414 }else{
drh8784eca2015-08-23 02:42:30 +00001415 u32 iUp = p->sParse.aUp[p->i];
1416 JsonNode *pUp = &p->sParse.aNode[iUp];
drh4af352d2015-08-21 20:02:48 +00001417 p->i++;
drh8784eca2015-08-23 02:42:30 +00001418 if( pUp->eType==JSON_OBJECT && (pUp->n + iUp >= p->i) ) p->i++;
drh4af352d2015-08-21 20:02:48 +00001419 }
1420 p->iRowid++;
1421 if( p->i<p->sParse.nNode ){
drh8784eca2015-08-23 02:42:30 +00001422 u32 iUp = p->sParse.aUp[p->i];
1423 JsonNode *pUp = &p->sParse.aNode[iUp];
drh4af352d2015-08-21 20:02:48 +00001424 p->eType = pUp->eType;
drh8784eca2015-08-23 02:42:30 +00001425 if( pUp->eType==JSON_ARRAY ){
1426 if( iUp==p->i-1 ){
1427 pUp->u.iKey = 0;
1428 }else{
1429 pUp->u.iKey++;
1430 }
drh4af352d2015-08-21 20:02:48 +00001431 }
1432 }
drh505ad2c2015-08-21 17:33:11 +00001433 }else{
drh4af352d2015-08-21 20:02:48 +00001434 switch( p->eType ){
1435 case JSON_ARRAY: {
1436 p->i += jsonNodeSize(&p->sParse.aNode[p->i]);
1437 p->iRowid++;
1438 break;
1439 }
1440 case JSON_OBJECT: {
1441 p->i += 1 + jsonNodeSize(&p->sParse.aNode[p->i+1]);
1442 p->iRowid++;
1443 break;
1444 }
1445 default: {
1446 p->i = p->iEnd;
1447 break;
1448 }
drh505ad2c2015-08-21 17:33:11 +00001449 }
1450 }
1451 return SQLITE_OK;
1452}
1453
drh4af352d2015-08-21 20:02:48 +00001454/* Append the name of the path for element i to pStr
1455*/
1456static void jsonEachComputePath(
1457 JsonEachCursor *p, /* The cursor */
1458 JsonString *pStr, /* Write the path here */
1459 u32 i /* Path to this element */
1460){
1461 JsonNode *pNode, *pUp;
1462 u32 iUp;
1463 if( i==0 ){
1464 jsonAppendChar(pStr, '$');
1465 return;
drhcb6c6c62015-08-19 22:47:17 +00001466 }
drh4af352d2015-08-21 20:02:48 +00001467 iUp = p->sParse.aUp[i];
1468 jsonEachComputePath(p, pStr, iUp);
1469 pNode = &p->sParse.aNode[i];
1470 pUp = &p->sParse.aNode[iUp];
1471 if( pUp->eType==JSON_ARRAY ){
1472 jsonPrintf(30, pStr, "[%d]", pUp->u.iKey);
1473 }else{
1474 assert( pUp->eType==JSON_OBJECT );
1475 if( pNode->eType>=JSON_ARRAY ) pNode--;
1476 assert( pNode->eType==JSON_STRING );
1477 jsonPrintf(pNode->n+1, pStr, ".%.*s", pNode->n-2, pNode->u.zJContent+1);
1478 }
drhcb6c6c62015-08-19 22:47:17 +00001479}
1480
1481/* Return the value of a column */
1482static int jsonEachColumn(
1483 sqlite3_vtab_cursor *cur, /* The cursor */
1484 sqlite3_context *ctx, /* First argument to sqlite3_result_...() */
1485 int i /* Which column to return */
1486){
1487 JsonEachCursor *p = (JsonEachCursor*)cur;
drh505ad2c2015-08-21 17:33:11 +00001488 JsonNode *pThis = &p->sParse.aNode[p->i];
drhcb6c6c62015-08-19 22:47:17 +00001489 switch( i ){
1490 case JEACH_KEY: {
drh8784eca2015-08-23 02:42:30 +00001491 if( p->i==0 ) break;
drhcb6c6c62015-08-19 22:47:17 +00001492 if( p->eType==JSON_OBJECT ){
drh505ad2c2015-08-21 17:33:11 +00001493 jsonReturn(pThis, ctx, 0);
1494 }else if( p->eType==JSON_ARRAY ){
1495 u32 iKey;
1496 if( p->bRecursive ){
1497 if( p->iRowid==0 ) break;
drh8784eca2015-08-23 02:42:30 +00001498 iKey = p->sParse.aNode[p->sParse.aUp[p->i]].u.iKey;
drh505ad2c2015-08-21 17:33:11 +00001499 }else{
1500 iKey = p->iRowid;
1501 }
drh6fd5c1e2015-08-21 20:37:12 +00001502 sqlite3_result_int64(ctx, (sqlite3_int64)iKey);
drhcb6c6c62015-08-19 22:47:17 +00001503 }
1504 break;
1505 }
1506 case JEACH_VALUE: {
drh8784eca2015-08-23 02:42:30 +00001507 if( p->eType==JSON_OBJECT && p->i>0 ) pThis++;
drh505ad2c2015-08-21 17:33:11 +00001508 jsonReturn(pThis, ctx, 0);
1509 break;
1510 }
1511 case JEACH_TYPE: {
drh442a7c62015-08-24 02:32:04 +00001512 if( p->eType==JSON_OBJECT && p->i>0 ) pThis++;
drh505ad2c2015-08-21 17:33:11 +00001513 sqlite3_result_text(ctx, jsonType[pThis->eType], -1, SQLITE_STATIC);
1514 break;
1515 }
1516 case JEACH_ATOM: {
drh442a7c62015-08-24 02:32:04 +00001517 if( p->eType==JSON_OBJECT && p->i>0 ) pThis++;
drh505ad2c2015-08-21 17:33:11 +00001518 if( pThis->eType>=JSON_ARRAY ) break;
1519 jsonReturn(pThis, ctx, 0);
1520 break;
1521 }
1522 case JEACH_ID: {
drh6fd5c1e2015-08-21 20:37:12 +00001523 sqlite3_result_int64(ctx, (sqlite3_int64)p->i + (p->eType==JSON_OBJECT));
drh505ad2c2015-08-21 17:33:11 +00001524 break;
1525 }
1526 case JEACH_PARENT: {
1527 if( p->i>0 && p->bRecursive ){
drh6fd5c1e2015-08-21 20:37:12 +00001528 sqlite3_result_int64(ctx, (sqlite3_int64)p->sParse.aUp[p->i]);
drhcb6c6c62015-08-19 22:47:17 +00001529 }
1530 break;
1531 }
drh4af352d2015-08-21 20:02:48 +00001532 case JEACH_FULLKEY: {
1533 JsonString x;
1534 jsonInit(&x, ctx);
1535 if( p->bRecursive ){
1536 jsonEachComputePath(p, &x, p->i);
1537 }else{
1538 if( p->zPath ){
1539 jsonAppendRaw(&x, p->zPath, (int)strlen(p->zPath));
1540 }else{
1541 jsonAppendChar(&x, '$');
1542 }
1543 if( p->eType==JSON_ARRAY ){
1544 jsonPrintf(30, &x, "[%d]", p->iRowid);
1545 }else{
1546 jsonPrintf(pThis->n, &x, ".%.*s", pThis->n-2, pThis->u.zJContent+1);
1547 }
1548 }
1549 jsonResult(&x);
1550 break;
1551 }
drhcb6c6c62015-08-19 22:47:17 +00001552 case JEACH_PATH: {
1553 const char *zPath = p->zPath;
drh4af352d2015-08-21 20:02:48 +00001554 if( zPath==0 ){
1555 if( p->bRecursive ){
1556 JsonString x;
1557 jsonInit(&x, ctx);
1558 jsonEachComputePath(p, &x, p->sParse.aUp[p->i]);
1559 jsonResult(&x);
1560 break;
1561 }
1562 zPath = "$";
1563 }
drhcb6c6c62015-08-19 22:47:17 +00001564 sqlite3_result_text(ctx, zPath, -1, SQLITE_STATIC);
1565 break;
1566 }
1567 default: {
drh505ad2c2015-08-21 17:33:11 +00001568 assert( i==JEACH_JSON );
drhcb6c6c62015-08-19 22:47:17 +00001569 sqlite3_result_text(ctx, p->sParse.zJson, -1, SQLITE_STATIC);
1570 break;
1571 }
1572 }
1573 return SQLITE_OK;
1574}
1575
1576/* Return the current rowid value */
1577static int jsonEachRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){
1578 JsonEachCursor *p = (JsonEachCursor*)cur;
1579 *pRowid = p->iRowid;
1580 return SQLITE_OK;
1581}
1582
1583/* The query strategy is to look for an equality constraint on the json
1584** column. Without such a constraint, the table cannot operate. idxNum is
1585** 1 if the constraint is found, 3 if the constraint and zPath are found,
1586** and 0 otherwise.
1587*/
1588static int jsonEachBestIndex(
1589 sqlite3_vtab *tab,
1590 sqlite3_index_info *pIdxInfo
1591){
1592 int i;
1593 int jsonIdx = -1;
1594 int pathIdx = -1;
1595 const struct sqlite3_index_constraint *pConstraint;
drh6fd5c1e2015-08-21 20:37:12 +00001596
1597 UNUSED_PARAM(tab);
drhcb6c6c62015-08-19 22:47:17 +00001598 pConstraint = pIdxInfo->aConstraint;
1599 for(i=0; i<pIdxInfo->nConstraint; i++, pConstraint++){
1600 if( pConstraint->usable==0 ) continue;
1601 if( pConstraint->op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue;
1602 switch( pConstraint->iColumn ){
1603 case JEACH_JSON: jsonIdx = i; break;
1604 case JEACH_PATH: pathIdx = i; break;
1605 default: /* no-op */ break;
1606 }
1607 }
1608 if( jsonIdx<0 ){
1609 pIdxInfo->idxNum = 0;
drh505ad2c2015-08-21 17:33:11 +00001610 pIdxInfo->estimatedCost = 1e99;
drhcb6c6c62015-08-19 22:47:17 +00001611 }else{
drh505ad2c2015-08-21 17:33:11 +00001612 pIdxInfo->estimatedCost = 1.0;
drhcb6c6c62015-08-19 22:47:17 +00001613 pIdxInfo->aConstraintUsage[jsonIdx].argvIndex = 1;
1614 pIdxInfo->aConstraintUsage[jsonIdx].omit = 1;
1615 if( pathIdx<0 ){
1616 pIdxInfo->idxNum = 1;
1617 }else{
1618 pIdxInfo->aConstraintUsage[pathIdx].argvIndex = 2;
1619 pIdxInfo->aConstraintUsage[pathIdx].omit = 1;
1620 pIdxInfo->idxNum = 3;
1621 }
1622 }
1623 return SQLITE_OK;
1624}
1625
1626/* Start a search on a new JSON string */
1627static int jsonEachFilter(
1628 sqlite3_vtab_cursor *cur,
1629 int idxNum, const char *idxStr,
1630 int argc, sqlite3_value **argv
1631){
1632 JsonEachCursor *p = (JsonEachCursor*)cur;
1633 const char *z;
1634 const char *zPath;
1635 sqlite3_int64 n;
1636
drh6fd5c1e2015-08-21 20:37:12 +00001637 UNUSED_PARAM(idxStr);
1638 UNUSED_PARAM(argc);
drhcb6c6c62015-08-19 22:47:17 +00001639 jsonEachCursorReset(p);
1640 if( idxNum==0 ) return SQLITE_OK;
1641 z = (const char*)sqlite3_value_text(argv[0]);
1642 if( z==0 ) return SQLITE_OK;
1643 if( idxNum&2 ){
1644 zPath = (const char*)sqlite3_value_text(argv[1]);
1645 if( zPath==0 || zPath[0]!='$' ) return SQLITE_OK;
1646 }
1647 n = sqlite3_value_bytes(argv[0]);
drh6fd5c1e2015-08-21 20:37:12 +00001648 p->zJson = sqlite3_malloc64( n+1 );
drhcb6c6c62015-08-19 22:47:17 +00001649 if( p->zJson==0 ) return SQLITE_NOMEM;
drh6fd5c1e2015-08-21 20:37:12 +00001650 memcpy(p->zJson, z, (size_t)n+1);
drhbc8f0922015-08-22 19:39:04 +00001651 if( jsonParse(&p->sParse, 0, p->zJson)
drh505ad2c2015-08-21 17:33:11 +00001652 || (p->bRecursive && jsonParseFindParents(&p->sParse))
1653 ){
drhcb6c6c62015-08-19 22:47:17 +00001654 jsonEachCursorReset(p);
1655 }else{
1656 JsonNode *pNode;
1657 if( idxNum==3 ){
drh4af352d2015-08-21 20:02:48 +00001658 p->bRecursive = 0;
drhcb6c6c62015-08-19 22:47:17 +00001659 n = sqlite3_value_bytes(argv[1]);
drh6fd5c1e2015-08-21 20:37:12 +00001660 p->zPath = sqlite3_malloc64( n+1 );
drhcb6c6c62015-08-19 22:47:17 +00001661 if( p->zPath==0 ) return SQLITE_NOMEM;
drh6fd5c1e2015-08-21 20:37:12 +00001662 memcpy(p->zPath, zPath, (size_t)n+1);
drhcb6c6c62015-08-19 22:47:17 +00001663 pNode = jsonLookup(&p->sParse, 0, p->zPath+1, 0);
1664 if( pNode==0 ){
1665 jsonEachCursorReset(p);
1666 return SQLITE_OK;
1667 }
1668 }else{
1669 pNode = p->sParse.aNode;
1670 }
1671 p->i = (int)(pNode - p->sParse.aNode);
1672 p->eType = pNode->eType;
1673 if( p->eType>=JSON_ARRAY ){
drh8784eca2015-08-23 02:42:30 +00001674 pNode->u.iKey = 0;
drhc3722b22015-08-23 20:44:59 +00001675 p->iEnd = p->i + pNode->n + 1;
drh8784eca2015-08-23 02:42:30 +00001676 if( !p->bRecursive ) p->i++;
drhcb6c6c62015-08-19 22:47:17 +00001677 }else{
1678 p->iEnd = p->i+1;
1679 }
1680 }
drhbc8f0922015-08-22 19:39:04 +00001681 return p->sParse.oom ? SQLITE_NOMEM : SQLITE_OK;
drhcb6c6c62015-08-19 22:47:17 +00001682}
1683
1684/* The methods of the json_each virtual table */
1685static sqlite3_module jsonEachModule = {
1686 0, /* iVersion */
1687 0, /* xCreate */
1688 jsonEachConnect, /* xConnect */
1689 jsonEachBestIndex, /* xBestIndex */
1690 jsonEachDisconnect, /* xDisconnect */
1691 0, /* xDestroy */
drh505ad2c2015-08-21 17:33:11 +00001692 jsonEachOpenEach, /* xOpen - open a cursor */
drhcb6c6c62015-08-19 22:47:17 +00001693 jsonEachClose, /* xClose - close a cursor */
1694 jsonEachFilter, /* xFilter - configure scan constraints */
drh4af352d2015-08-21 20:02:48 +00001695 jsonEachNext, /* xNext - advance a cursor */
drhcb6c6c62015-08-19 22:47:17 +00001696 jsonEachEof, /* xEof - check for end of scan */
1697 jsonEachColumn, /* xColumn - read data */
1698 jsonEachRowid, /* xRowid - read data */
1699 0, /* xUpdate */
1700 0, /* xBegin */
1701 0, /* xSync */
1702 0, /* xCommit */
1703 0, /* xRollback */
1704 0, /* xFindMethod */
1705 0, /* xRename */
drh6fd5c1e2015-08-21 20:37:12 +00001706 0, /* xSavepoint */
1707 0, /* xRelease */
1708 0 /* xRollbackTo */
drhcb6c6c62015-08-19 22:47:17 +00001709};
1710
drh505ad2c2015-08-21 17:33:11 +00001711/* The methods of the json_tree virtual table. */
1712static sqlite3_module jsonTreeModule = {
1713 0, /* iVersion */
1714 0, /* xCreate */
1715 jsonEachConnect, /* xConnect */
1716 jsonEachBestIndex, /* xBestIndex */
1717 jsonEachDisconnect, /* xDisconnect */
1718 0, /* xDestroy */
1719 jsonEachOpenTree, /* xOpen - open a cursor */
1720 jsonEachClose, /* xClose - close a cursor */
1721 jsonEachFilter, /* xFilter - configure scan constraints */
drh4af352d2015-08-21 20:02:48 +00001722 jsonEachNext, /* xNext - advance a cursor */
drh505ad2c2015-08-21 17:33:11 +00001723 jsonEachEof, /* xEof - check for end of scan */
1724 jsonEachColumn, /* xColumn - read data */
1725 jsonEachRowid, /* xRowid - read data */
1726 0, /* xUpdate */
1727 0, /* xBegin */
1728 0, /* xSync */
1729 0, /* xCommit */
1730 0, /* xRollback */
1731 0, /* xFindMethod */
1732 0, /* xRename */
drh6fd5c1e2015-08-21 20:37:12 +00001733 0, /* xSavepoint */
1734 0, /* xRelease */
1735 0 /* xRollbackTo */
drh505ad2c2015-08-21 17:33:11 +00001736};
1737
1738/****************************************************************************
1739** The following routine is the only publically visible identifier in this
1740** file. Call the following routine in order to register the various SQL
1741** functions and the virtual table implemented by this file.
1742****************************************************************************/
drhcb6c6c62015-08-19 22:47:17 +00001743
drh5fa5c102015-08-12 16:49:40 +00001744#ifdef _WIN32
1745__declspec(dllexport)
1746#endif
1747int sqlite3_json_init(
1748 sqlite3 *db,
1749 char **pzErrMsg,
1750 const sqlite3_api_routines *pApi
1751){
1752 int rc = SQLITE_OK;
drh6fd5c1e2015-08-21 20:37:12 +00001753 unsigned int i;
drh5fa5c102015-08-12 16:49:40 +00001754 static const struct {
1755 const char *zName;
1756 int nArg;
drh52216ad2015-08-18 02:28:03 +00001757 int flag;
drh5fa5c102015-08-12 16:49:40 +00001758 void (*xFunc)(sqlite3_context*,int,sqlite3_value**);
1759 } aFunc[] = {
drh52216ad2015-08-18 02:28:03 +00001760 { "json_array", -1, 0, jsonArrayFunc },
1761 { "json_array_length", 1, 0, jsonArrayLengthFunc },
1762 { "json_array_length", 2, 0, jsonArrayLengthFunc },
1763 { "json_extract", 2, 0, jsonExtractFunc },
1764 { "json_insert", -1, 0, jsonSetFunc },
1765 { "json_object", -1, 0, jsonObjectFunc },
1766 { "json_remove", -1, 0, jsonRemoveFunc },
1767 { "json_replace", -1, 0, jsonReplaceFunc },
1768 { "json_set", -1, 1, jsonSetFunc },
1769 { "json_type", 1, 0, jsonTypeFunc },
1770 { "json_type", 2, 0, jsonTypeFunc },
drhbc8f0922015-08-22 19:39:04 +00001771 { "json_valid", 1, 0, jsonValidFunc },
drh987eb1f2015-08-17 15:17:37 +00001772
drh301eecc2015-08-17 20:14:19 +00001773#if SQLITE_DEBUG
drh987eb1f2015-08-17 15:17:37 +00001774 /* DEBUG and TESTING functions */
drh52216ad2015-08-18 02:28:03 +00001775 { "json_parse", 1, 0, jsonParseFunc },
1776 { "json_test1", 1, 0, jsonTest1Func },
1777 { "json_nodecount", 1, 0, jsonNodeCountFunc },
drh301eecc2015-08-17 20:14:19 +00001778#endif
drh5fa5c102015-08-12 16:49:40 +00001779 };
drh505ad2c2015-08-21 17:33:11 +00001780 static const struct {
1781 const char *zName;
1782 sqlite3_module *pModule;
1783 } aMod[] = {
1784 { "json_each", &jsonEachModule },
1785 { "json_tree", &jsonTreeModule },
1786 };
drh5fa5c102015-08-12 16:49:40 +00001787 SQLITE_EXTENSION_INIT2(pApi);
1788 (void)pzErrMsg; /* Unused parameter */
1789 for(i=0; i<sizeof(aFunc)/sizeof(aFunc[0]) && rc==SQLITE_OK; i++){
1790 rc = sqlite3_create_function(db, aFunc[i].zName, aFunc[i].nArg,
drh52216ad2015-08-18 02:28:03 +00001791 SQLITE_UTF8 | SQLITE_DETERMINISTIC,
1792 (void*)&aFunc[i].flag,
drh5fa5c102015-08-12 16:49:40 +00001793 aFunc[i].xFunc, 0, 0);
1794 }
drh505ad2c2015-08-21 17:33:11 +00001795 for(i=0; i<sizeof(aMod)/sizeof(aMod[0]) && rc==SQLITE_OK; i++){
1796 rc = sqlite3_create_module(db, aMod[i].zName, aMod[i].pModule, 0);
drhcb6c6c62015-08-19 22:47:17 +00001797 }
drh5fa5c102015-08-12 16:49:40 +00001798 return rc;
1799}