blob: 66173482c4d4824e96015d05e11d8c3e836b07b6 [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
drhd0960592015-08-17 21:22:32 +0000198#ifdef SQLITE_DEBUG
drhe9c37f32015-08-15 21:25:36 +0000199/* Append the zero-terminated string zIn
200*/
drh505ad2c2015-08-21 17:33:11 +0000201static void jsonAppend(JsonString *p, const char *zIn){
drhe9c37f32015-08-15 21:25:36 +0000202 jsonAppendRaw(p, zIn, (u32)strlen(zIn));
203}
drhd0960592015-08-17 21:22:32 +0000204#endif
drhe9c37f32015-08-15 21:25:36 +0000205
drh5634cc02015-08-17 11:28:03 +0000206/* Append a single character
207*/
drh505ad2c2015-08-21 17:33:11 +0000208static void jsonAppendChar(JsonString *p, char c){
drh5634cc02015-08-17 11:28:03 +0000209 if( p->nUsed>=p->nAlloc && jsonGrow(p,1)!=0 ) return;
210 p->zBuf[p->nUsed++] = c;
211}
212
drh301eecc2015-08-17 20:14:19 +0000213/* Append a comma separator to the output buffer, if the previous
214** character is not '[' or '{'.
215*/
drh505ad2c2015-08-21 17:33:11 +0000216static void jsonAppendSeparator(JsonString *p){
drh301eecc2015-08-17 20:14:19 +0000217 char c;
218 if( p->nUsed==0 ) return;
219 c = p->zBuf[p->nUsed-1];
220 if( c!='[' && c!='{' ) jsonAppendChar(p, ',');
221}
222
drh505ad2c2015-08-21 17:33:11 +0000223/* Append the N-byte string in zIn to the end of the JsonString string
drh5fa5c102015-08-12 16:49:40 +0000224** under construction. Enclose the string in "..." and escape
225** any double-quotes or backslash characters contained within the
226** string.
227*/
drh505ad2c2015-08-21 17:33:11 +0000228static void jsonAppendString(JsonString *p, const char *zIn, u32 N){
drh5fa5c102015-08-12 16:49:40 +0000229 u32 i;
230 if( (N+p->nUsed+2 >= p->nAlloc) && jsonGrow(p,N+2)!=0 ) return;
231 p->zBuf[p->nUsed++] = '"';
232 for(i=0; i<N; i++){
233 char c = zIn[i];
234 if( c=='"' || c=='\\' ){
235 if( (p->nUsed+N+1-i > p->nAlloc) && jsonGrow(p,N+1-i)!=0 ) return;
236 p->zBuf[p->nUsed++] = '\\';
237 }
238 p->zBuf[p->nUsed++] = c;
239 }
240 p->zBuf[p->nUsed++] = '"';
241}
242
drhd0960592015-08-17 21:22:32 +0000243/*
244** Append a function parameter value to the JSON string under
245** construction.
246*/
247static void jsonAppendValue(
drh505ad2c2015-08-21 17:33:11 +0000248 JsonString *p, /* Append to this JSON string */
drhd0960592015-08-17 21:22:32 +0000249 sqlite3_value *pValue /* Value to append */
250){
251 switch( sqlite3_value_type(pValue) ){
252 case SQLITE_NULL: {
253 jsonAppendRaw(p, "null", 4);
254 break;
255 }
256 case SQLITE_INTEGER:
257 case SQLITE_FLOAT: {
258 const char *z = (const char*)sqlite3_value_text(pValue);
259 u32 n = (u32)sqlite3_value_bytes(pValue);
260 jsonAppendRaw(p, z, n);
261 break;
262 }
263 case SQLITE_TEXT: {
264 const char *z = (const char*)sqlite3_value_text(pValue);
265 u32 n = (u32)sqlite3_value_bytes(pValue);
266 jsonAppendString(p, z, n);
267 break;
268 }
269 default: {
270 if( p->bErr==0 ){
271 sqlite3_result_error(p->pCtx, "JSON cannot hold BLOB values", -1);
272 p->bErr = 1;
273 jsonReset(p);
274 }
275 break;
276 }
277 }
278}
279
280
drhbd0621b2015-08-13 13:54:59 +0000281/* Make the JSON in p the result of the SQL function.
drh5fa5c102015-08-12 16:49:40 +0000282*/
drh505ad2c2015-08-21 17:33:11 +0000283static void jsonResult(JsonString *p){
drhd0960592015-08-17 21:22:32 +0000284 if( p->bErr==0 ){
drh5fa5c102015-08-12 16:49:40 +0000285 sqlite3_result_text64(p->pCtx, p->zBuf, p->nUsed,
286 p->bStatic ? SQLITE_TRANSIENT : sqlite3_free,
287 SQLITE_UTF8);
288 jsonZero(p);
289 }
290 assert( p->bStatic );
291}
292
drh505ad2c2015-08-21 17:33:11 +0000293/**************************************************************************
294** Utility routines for dealing with JsonNode and JsonParse objects
295**************************************************************************/
296
297/*
298** Return the number of consecutive JsonNode slots need to represent
299** the parsed JSON at pNode. The minimum answer is 1. For ARRAY and
300** OBJECT types, the number might be larger.
301**
302** Appended elements are not counted. The value returned is the number
303** by which the JsonNode counter should increment in order to go to the
304** next peer value.
305*/
306static u32 jsonNodeSize(JsonNode *pNode){
307 return pNode->eType>=JSON_ARRAY ? pNode->n+1 : 1;
308}
309
310/*
311** Reclaim all memory allocated by a JsonParse object. But do not
312** delete the JsonParse object itself.
313*/
314static void jsonParseReset(JsonParse *pParse){
315 sqlite3_free(pParse->aNode);
316 pParse->aNode = 0;
317 pParse->nNode = 0;
318 pParse->nAlloc = 0;
319 sqlite3_free(pParse->aUp);
320 pParse->aUp = 0;
321}
322
drh5634cc02015-08-17 11:28:03 +0000323/*
324** Convert the JsonNode pNode into a pure JSON string and
325** append to pOut. Subsubstructure is also included. Return
326** the number of JsonNode objects that are encoded.
drhbd0621b2015-08-13 13:54:59 +0000327*/
drh52216ad2015-08-18 02:28:03 +0000328static void jsonRenderNode(
drhd0960592015-08-17 21:22:32 +0000329 JsonNode *pNode, /* The node to render */
drh505ad2c2015-08-21 17:33:11 +0000330 JsonString *pOut, /* Write JSON here */
drhd0960592015-08-17 21:22:32 +0000331 sqlite3_value **aReplace /* Replacement values */
332){
drh5634cc02015-08-17 11:28:03 +0000333 switch( pNode->eType ){
334 case JSON_NULL: {
335 jsonAppendRaw(pOut, "null", 4);
336 break;
337 }
338 case JSON_TRUE: {
339 jsonAppendRaw(pOut, "true", 4);
340 break;
341 }
342 case JSON_FALSE: {
343 jsonAppendRaw(pOut, "false", 5);
344 break;
345 }
346 case JSON_STRING: {
drh301eecc2015-08-17 20:14:19 +0000347 if( pNode->jnFlags & JNODE_RAW ){
drh52216ad2015-08-18 02:28:03 +0000348 jsonAppendString(pOut, pNode->u.zJContent, pNode->n);
drh5634cc02015-08-17 11:28:03 +0000349 break;
350 }
351 /* Fall through into the next case */
352 }
353 case JSON_REAL:
354 case JSON_INT: {
drh52216ad2015-08-18 02:28:03 +0000355 jsonAppendRaw(pOut, pNode->u.zJContent, pNode->n);
drh5634cc02015-08-17 11:28:03 +0000356 break;
357 }
358 case JSON_ARRAY: {
drh52216ad2015-08-18 02:28:03 +0000359 u32 j = 1;
drh5634cc02015-08-17 11:28:03 +0000360 jsonAppendChar(pOut, '[');
drh52216ad2015-08-18 02:28:03 +0000361 for(;;){
362 while( j<=pNode->n ){
363 if( pNode[j].jnFlags & (JNODE_REMOVE|JNODE_REPLACE) ){
364 if( pNode[j].jnFlags & JNODE_REPLACE ){
365 jsonAppendSeparator(pOut);
366 jsonAppendValue(pOut, aReplace[pNode[j].iVal]);
367 }
368 }else{
drhd0960592015-08-17 21:22:32 +0000369 jsonAppendSeparator(pOut);
drh52216ad2015-08-18 02:28:03 +0000370 jsonRenderNode(&pNode[j], pOut, aReplace);
drhd0960592015-08-17 21:22:32 +0000371 }
drh505ad2c2015-08-21 17:33:11 +0000372 j += jsonNodeSize(&pNode[j]);
drh301eecc2015-08-17 20:14:19 +0000373 }
drh52216ad2015-08-18 02:28:03 +0000374 if( (pNode->jnFlags & JNODE_APPEND)==0 ) break;
375 pNode = &pNode[pNode->u.iAppend];
376 j = 1;
drh5634cc02015-08-17 11:28:03 +0000377 }
378 jsonAppendChar(pOut, ']');
379 break;
380 }
381 case JSON_OBJECT: {
drh52216ad2015-08-18 02:28:03 +0000382 u32 j = 1;
drh5634cc02015-08-17 11:28:03 +0000383 jsonAppendChar(pOut, '{');
drh52216ad2015-08-18 02:28:03 +0000384 for(;;){
385 while( j<=pNode->n ){
386 if( (pNode[j+1].jnFlags & JNODE_REMOVE)==0 ){
387 jsonAppendSeparator(pOut);
388 jsonRenderNode(&pNode[j], pOut, aReplace);
389 jsonAppendChar(pOut, ':');
390 if( pNode[j+1].jnFlags & JNODE_REPLACE ){
391 jsonAppendValue(pOut, aReplace[pNode[j+1].iVal]);
392 }else{
393 jsonRenderNode(&pNode[j+1], pOut, aReplace);
394 }
drhd0960592015-08-17 21:22:32 +0000395 }
drh505ad2c2015-08-21 17:33:11 +0000396 j += 1 + jsonNodeSize(&pNode[j+1]);
drh301eecc2015-08-17 20:14:19 +0000397 }
drh52216ad2015-08-18 02:28:03 +0000398 if( (pNode->jnFlags & JNODE_APPEND)==0 ) break;
399 pNode = &pNode[pNode->u.iAppend];
400 j = 1;
drh5634cc02015-08-17 11:28:03 +0000401 }
402 jsonAppendChar(pOut, '}');
403 break;
404 }
drhbd0621b2015-08-13 13:54:59 +0000405 }
drh5634cc02015-08-17 11:28:03 +0000406}
407
408/*
409** Make the JsonNode the return value of the function.
410*/
drhd0960592015-08-17 21:22:32 +0000411static void jsonReturn(
412 JsonNode *pNode, /* Node to return */
413 sqlite3_context *pCtx, /* Return value for this function */
414 sqlite3_value **aReplace /* Array of replacement values */
415){
drh5634cc02015-08-17 11:28:03 +0000416 switch( pNode->eType ){
417 case JSON_NULL: {
418 sqlite3_result_null(pCtx);
419 break;
420 }
421 case JSON_TRUE: {
422 sqlite3_result_int(pCtx, 1);
423 break;
424 }
425 case JSON_FALSE: {
426 sqlite3_result_int(pCtx, 0);
427 break;
428 }
drh987eb1f2015-08-17 15:17:37 +0000429 case JSON_REAL: {
drh52216ad2015-08-18 02:28:03 +0000430 double r = strtod(pNode->u.zJContent, 0);
drh987eb1f2015-08-17 15:17:37 +0000431 sqlite3_result_double(pCtx, r);
drh5634cc02015-08-17 11:28:03 +0000432 break;
433 }
drh987eb1f2015-08-17 15:17:37 +0000434 case JSON_INT: {
435 sqlite3_int64 i = 0;
drh52216ad2015-08-18 02:28:03 +0000436 const char *z = pNode->u.zJContent;
drh987eb1f2015-08-17 15:17:37 +0000437 if( z[0]=='-' ){ z++; }
438 while( z[0]>='0' && z[0]<='9' ){ i = i*10 + *(z++) - '0'; }
drh52216ad2015-08-18 02:28:03 +0000439 if( pNode->u.zJContent[0]=='-' ){ i = -i; }
drh987eb1f2015-08-17 15:17:37 +0000440 sqlite3_result_int64(pCtx, i);
441 break;
442 }
drh5634cc02015-08-17 11:28:03 +0000443 case JSON_STRING: {
drh301eecc2015-08-17 20:14:19 +0000444 if( pNode->jnFlags & JNODE_RAW ){
drh52216ad2015-08-18 02:28:03 +0000445 sqlite3_result_text(pCtx, pNode->u.zJContent, pNode->n,
446 SQLITE_TRANSIENT);
drh301eecc2015-08-17 20:14:19 +0000447 }else if( (pNode->jnFlags & JNODE_ESCAPE)==0 ){
drh987eb1f2015-08-17 15:17:37 +0000448 /* JSON formatted without any backslash-escapes */
drh52216ad2015-08-18 02:28:03 +0000449 sqlite3_result_text(pCtx, pNode->u.zJContent+1, pNode->n-2,
drh987eb1f2015-08-17 15:17:37 +0000450 SQLITE_TRANSIENT);
drh5634cc02015-08-17 11:28:03 +0000451 }else{
452 /* Translate JSON formatted string into raw text */
drh987eb1f2015-08-17 15:17:37 +0000453 u32 i;
454 u32 n = pNode->n;
drh52216ad2015-08-18 02:28:03 +0000455 const char *z = pNode->u.zJContent;
drh987eb1f2015-08-17 15:17:37 +0000456 char *zOut;
457 u32 j;
458 zOut = sqlite3_malloc( n+1 );
459 if( zOut==0 ){
460 sqlite3_result_error_nomem(pCtx);
461 break;
462 }
463 for(i=1, j=0; i<n-1; i++){
464 char c = z[i];
465 if( c!='\\' && z[i+1] ){
466 zOut[j++] = c;
467 }else{
468 c = z[++i];
469 if( c=='u' && z[1] ){
470 u32 v = 0, k;
471 z++;
472 for(k=0; k<4 && z[k]; k++){
473 c = z[0];
474 if( c>='0' && c<='9' ) v = v*16 + c - '0';
475 else if( c>='A' && c<='F' ) v = v*16 + c - 'A' + 10;
476 else if( c>='a' && c<='f' ) v = v*16 + c - 'a' + 10;
477 else break;
478 z++;
479 }
480 if( v<=0x7f ){
481 zOut[j++] = v;
482 }else if( v<=0x7ff ){
483 zOut[j++] = 0xc0 | (v>>6);
484 zOut[j++] = 0x80 | (v&0x3f);
485 }else if( v<=0xffff ){
486 zOut[j++] = 0xe0 | (v>>12);
487 zOut[j++] = 0x80 | ((v>>6)&0x3f);
488 zOut[j++] = 0x80 | (v&0x3f);
489 }else if( v<=0x10ffff ){
490 zOut[j++] = 0xf0 | (v>>18);
491 zOut[j++] = 0x80 | ((v>>12)&0x3f);
492 zOut[j++] = 0x80 | ((v>>6)&0x3f);
493 zOut[j++] = 0x80 | (v&0x3f);
494 }
495 }else{
496 if( c=='b' ){
497 c = '\b';
498 }else if( c=='f' ){
499 c = '\f';
500 }else if( c=='n' ){
501 c = '\n';
502 }else if( c=='r' ){
503 c = '\r';
504 }else if( c=='t' ){
505 c = '\t';
506 }
507 zOut[j++] = c;
508 }
509 }
510 }
511 zOut[j] = 0;
512 sqlite3_result_text(pCtx, zOut, j, sqlite3_free);
drh5634cc02015-08-17 11:28:03 +0000513 }
514 break;
515 }
516 case JSON_ARRAY:
517 case JSON_OBJECT: {
drh505ad2c2015-08-21 17:33:11 +0000518 JsonString s;
drh5634cc02015-08-17 11:28:03 +0000519 jsonInit(&s, pCtx);
drhd0960592015-08-17 21:22:32 +0000520 jsonRenderNode(pNode, &s, aReplace);
drh5634cc02015-08-17 11:28:03 +0000521 jsonResult(&s);
522 break;
523 }
524 }
drhbd0621b2015-08-13 13:54:59 +0000525}
526
drh5fa5c102015-08-12 16:49:40 +0000527/*
drhe9c37f32015-08-15 21:25:36 +0000528** Create a new JsonNode instance based on the arguments and append that
529** instance to the JsonParse. Return the index in pParse->aNode[] of the
530** new node, or -1 if a memory allocation fails.
531*/
532static int jsonParseAddNode(
533 JsonParse *pParse, /* Append the node to this object */
534 u32 eType, /* Node type */
535 u32 n, /* Content size or sub-node count */
536 const char *zContent /* Content */
537){
538 JsonNode *p;
539 if( pParse->nNode>=pParse->nAlloc ){
540 u32 nNew;
541 JsonNode *pNew;
542 if( pParse->oom ) return -1;
543 nNew = pParse->nAlloc*2 + 10;
544 if( nNew<=pParse->nNode ){
545 pParse->oom = 1;
546 return -1;
547 }
548 pNew = sqlite3_realloc(pParse->aNode, sizeof(JsonNode)*nNew);
549 if( pNew==0 ){
550 pParse->oom = 1;
551 return -1;
552 }
553 pParse->nAlloc = nNew;
554 pParse->aNode = pNew;
555 }
556 p = &pParse->aNode[pParse->nNode];
drh5634cc02015-08-17 11:28:03 +0000557 p->eType = (u8)eType;
drh301eecc2015-08-17 20:14:19 +0000558 p->jnFlags = 0;
drhd0960592015-08-17 21:22:32 +0000559 p->iVal = 0;
drhe9c37f32015-08-15 21:25:36 +0000560 p->n = n;
drh52216ad2015-08-18 02:28:03 +0000561 p->u.zJContent = zContent;
drhe9c37f32015-08-15 21:25:36 +0000562 return pParse->nNode++;
563}
564
565/*
566** Parse a single JSON value which begins at pParse->zJson[i]. Return the
567** index of the first character past the end of the value parsed.
568**
569** Return negative for a syntax error. Special cases: return -2 if the
570** first non-whitespace character is '}' and return -3 if the first
571** non-whitespace character is ']'.
572*/
573static int jsonParseValue(JsonParse *pParse, u32 i){
574 char c;
575 u32 j;
576 u32 iThis;
577 int x;
578 while( isspace(pParse->zJson[i]) ){ i++; }
579 if( (c = pParse->zJson[i])==0 ) return 0;
580 if( c=='{' ){
581 /* Parse object */
582 iThis = jsonParseAddNode(pParse, JSON_OBJECT, 0, 0);
drhe9c37f32015-08-15 21:25:36 +0000583 for(j=i+1;;j++){
584 while( isspace(pParse->zJson[j]) ){ j++; }
585 x = jsonParseValue(pParse, j);
586 if( x<0 ){
587 if( x==(-2) && pParse->nNode==iThis+1 ) return j+1;
588 return -1;
589 }
590 if( pParse->aNode[pParse->nNode-1].eType!=JSON_STRING ) return -1;
591 j = x;
592 while( isspace(pParse->zJson[j]) ){ j++; }
593 if( pParse->zJson[j]!=':' ) return -1;
594 j++;
595 x = jsonParseValue(pParse, j);
596 if( x<0 ) return -1;
597 j = x;
598 while( isspace(pParse->zJson[j]) ){ j++; }
599 c = pParse->zJson[j];
600 if( c==',' ) continue;
601 if( c!='}' ) return -1;
602 break;
603 }
604 pParse->aNode[iThis].n = pParse->nNode - iThis - 1;
605 return j+1;
606 }else if( c=='[' ){
607 /* Parse array */
608 iThis = jsonParseAddNode(pParse, JSON_ARRAY, 0, 0);
drhe9c37f32015-08-15 21:25:36 +0000609 for(j=i+1;;j++){
610 while( isspace(pParse->zJson[j]) ){ j++; }
611 x = jsonParseValue(pParse, j);
612 if( x<0 ){
613 if( x==(-3) && pParse->nNode==iThis+1 ) return j+1;
614 return -1;
615 }
616 j = x;
617 while( isspace(pParse->zJson[j]) ){ j++; }
618 c = pParse->zJson[j];
619 if( c==',' ) continue;
620 if( c!=']' ) return -1;
621 break;
622 }
623 pParse->aNode[iThis].n = pParse->nNode - iThis - 1;
624 return j+1;
625 }else if( c=='"' ){
626 /* Parse string */
drh301eecc2015-08-17 20:14:19 +0000627 u8 jnFlags = 0;
drhe9c37f32015-08-15 21:25:36 +0000628 j = i+1;
629 for(;;){
630 c = pParse->zJson[j];
631 if( c==0 ) return -1;
632 if( c=='\\' ){
633 c = pParse->zJson[++j];
634 if( c==0 ) return -1;
drh301eecc2015-08-17 20:14:19 +0000635 jnFlags = JNODE_ESCAPE;
drhe9c37f32015-08-15 21:25:36 +0000636 }else if( c=='"' ){
637 break;
638 }
639 j++;
640 }
641 jsonParseAddNode(pParse, JSON_STRING, j+1-i, &pParse->zJson[i]);
drh301eecc2015-08-17 20:14:19 +0000642 pParse->aNode[pParse->nNode-1].jnFlags = jnFlags;
drhe9c37f32015-08-15 21:25:36 +0000643 return j+1;
644 }else if( c=='n'
645 && strncmp(pParse->zJson+i,"null",4)==0
drhb2cd10e2015-08-15 21:29:14 +0000646 && !isalnum(pParse->zJson[i+4]) ){
drhe9c37f32015-08-15 21:25:36 +0000647 jsonParseAddNode(pParse, JSON_NULL, 0, 0);
648 return i+4;
649 }else if( c=='t'
650 && strncmp(pParse->zJson+i,"true",4)==0
drhb2cd10e2015-08-15 21:29:14 +0000651 && !isalnum(pParse->zJson[i+4]) ){
drhe9c37f32015-08-15 21:25:36 +0000652 jsonParseAddNode(pParse, JSON_TRUE, 0, 0);
653 return i+4;
654 }else if( c=='f'
655 && strncmp(pParse->zJson+i,"false",5)==0
drhb2cd10e2015-08-15 21:29:14 +0000656 && !isalnum(pParse->zJson[i+5]) ){
drhe9c37f32015-08-15 21:25:36 +0000657 jsonParseAddNode(pParse, JSON_FALSE, 0, 0);
658 return i+5;
659 }else if( c=='-' || (c>='0' && c<='9') ){
660 /* Parse number */
661 u8 seenDP = 0;
662 u8 seenE = 0;
663 j = i+1;
664 for(;; j++){
665 c = pParse->zJson[j];
666 if( c>='0' && c<='9' ) continue;
667 if( c=='.' ){
668 if( pParse->zJson[j-1]=='-' ) return -1;
669 if( seenDP ) return -1;
670 seenDP = 1;
671 continue;
672 }
673 if( c=='e' || c=='E' ){
674 if( pParse->zJson[j-1]<'0' ) return -1;
675 if( seenE ) return -1;
676 seenDP = seenE = 1;
677 c = pParse->zJson[j+1];
678 if( c=='+' || c=='-' ) j++;
679 continue;
680 }
681 break;
682 }
683 if( pParse->zJson[j-1]<'0' ) return -1;
684 jsonParseAddNode(pParse, seenDP ? JSON_REAL : JSON_INT,
685 j - i, &pParse->zJson[i]);
686 return j;
687 }else if( c=='}' ){
688 return -2; /* End of {...} */
689 }else if( c==']' ){
690 return -3; /* End of [...] */
691 }else{
692 return -1; /* Syntax error */
693 }
694}
695
696/*
697** Parse a complete JSON string. Return 0 on success or non-zero if there
698** are any errors. If an error occurs, free all memory associated with
699** pParse.
700**
701** pParse is uninitialized when this routine is called.
702*/
703static int jsonParse(JsonParse *pParse, const char *zJson){
704 int i;
705 if( zJson==0 ) return 1;
706 memset(pParse, 0, sizeof(*pParse));
707 pParse->zJson = zJson;
708 i = jsonParseValue(pParse, 0);
709 if( i>0 ){
710 while( isspace(zJson[i]) ) i++;
711 if( zJson[i] ) i = -1;
712 }
713 if( i<0 ){
drh505ad2c2015-08-21 17:33:11 +0000714 jsonParseReset(pParse);
drhe9c37f32015-08-15 21:25:36 +0000715 return 1;
716 }
717 return 0;
718}
drh301eecc2015-08-17 20:14:19 +0000719
drh505ad2c2015-08-21 17:33:11 +0000720/* Mark node i of pParse as being a child of iParent. Call recursively
721** to fill in all the descendants of node i.
722*/
723static void jsonParseFillInParentage(JsonParse *pParse, u32 i, u32 iParent){
724 JsonNode *pNode = &pParse->aNode[i];
725 u32 j;
726 pParse->aUp[i] = iParent;
727 switch( pNode->eType ){
728 case JSON_ARRAY: {
729 for(j=1; j<=pNode->n; j += jsonNodeSize(pNode+j)){
730 jsonParseFillInParentage(pParse, i+j, i);
731 }
732 break;
733 }
734 case JSON_OBJECT: {
735 for(j=1; j<=pNode->n; j += jsonNodeSize(pNode+j+1)+1){
736 pParse->aUp[i+j] = i;
737 jsonParseFillInParentage(pParse, i+j+1, i);
738 }
739 break;
740 }
741 default: {
742 break;
743 }
744 }
745}
746
747/*
748** Compute the parentage of all nodes in a completed parse.
749*/
750static int jsonParseFindParents(JsonParse *pParse){
751 u32 *aUp;
752 assert( pParse->aUp==0 );
753 aUp = pParse->aUp = sqlite3_malloc( sizeof(u32)*pParse->nNode );
754 if( aUp==0 ) return SQLITE_NOMEM;
755 jsonParseFillInParentage(pParse, 0, 0);
756 return SQLITE_OK;
757}
758
drh52216ad2015-08-18 02:28:03 +0000759/* forward declaration */
760static JsonNode *jsonLookupAppend(JsonParse*,const char*,int*);
761
drh987eb1f2015-08-17 15:17:37 +0000762/*
763** Search along zPath to find the node specified. Return a pointer
764** to that node, or NULL if zPath is malformed or if there is no such
765** node.
drh52216ad2015-08-18 02:28:03 +0000766**
767** If pApnd!=0, then try to append new nodes to complete zPath if it is
768** possible to do so and if no existing node corresponds to zPath. If
769** new nodes are appended *pApnd is set to 1.
drh987eb1f2015-08-17 15:17:37 +0000770*/
drh52216ad2015-08-18 02:28:03 +0000771static JsonNode *jsonLookup(
772 JsonParse *pParse, /* The JSON to search */
773 u32 iRoot, /* Begin the search at this node */
774 const char *zPath, /* The path to search */
775 int *pApnd /* Append nodes to complete path if not NULL */
776){
drh6b43cc82015-08-19 23:02:49 +0000777 u32 i, j, k, nKey;
778 const char *zKey;
drh52216ad2015-08-18 02:28:03 +0000779 JsonNode *pRoot = &pParse->aNode[iRoot];
drh987eb1f2015-08-17 15:17:37 +0000780 if( zPath[0]==0 ) return pRoot;
781 if( zPath[0]=='.' ){
782 if( pRoot->eType!=JSON_OBJECT ) return 0;
783 zPath++;
drh6b43cc82015-08-19 23:02:49 +0000784 if( zPath[0]=='"' ){
785 zKey = zPath + 1;
786 for(i=1; zPath[i] && zPath[i]!='"'; i++){}
787 nKey = i-1;
788 if( zPath[i] ) i++;
789 }else{
790 zKey = zPath;
791 for(i=0; zPath[i] && zPath[i]!='.' && zPath[i]!='['; i++){}
792 nKey = i;
793 }
794 if( nKey==0 ) return 0;
drh987eb1f2015-08-17 15:17:37 +0000795 j = 1;
drh52216ad2015-08-18 02:28:03 +0000796 for(;;){
797 while( j<=pRoot->n ){
drh6b43cc82015-08-19 23:02:49 +0000798 if( pRoot[j].n==nKey+2
799 && strncmp(&pRoot[j].u.zJContent[1],zKey,nKey)==0
drh52216ad2015-08-18 02:28:03 +0000800 ){
801 return jsonLookup(pParse, iRoot+j+1, &zPath[i], pApnd);
802 }
803 j++;
drh505ad2c2015-08-21 17:33:11 +0000804 j += jsonNodeSize(&pRoot[j]);
drh987eb1f2015-08-17 15:17:37 +0000805 }
drh52216ad2015-08-18 02:28:03 +0000806 if( (pRoot->jnFlags & JNODE_APPEND)==0 ) break;
807 iRoot += pRoot->u.iAppend;
808 pRoot = &pParse->aNode[iRoot];
809 j = 1;
810 }
811 if( pApnd ){
812 k = jsonParseAddNode(pParse, JSON_OBJECT, 2, 0);
813 pRoot->u.iAppend = k - iRoot;
814 pRoot->jnFlags |= JNODE_APPEND;
815 k = jsonParseAddNode(pParse, JSON_STRING, i, zPath);
816 if( !pParse->oom ) pParse->aNode[k].jnFlags |= JNODE_RAW;
817 zPath += i;
818 return jsonLookupAppend(pParse, zPath, pApnd);
drh987eb1f2015-08-17 15:17:37 +0000819 }
820 }else if( zPath[0]=='[' && isdigit(zPath[1]) ){
821 if( pRoot->eType!=JSON_ARRAY ) return 0;
822 i = 0;
823 zPath++;
824 while( isdigit(zPath[0]) ){
825 i = i + zPath[0] - '0';
826 zPath++;
827 }
828 if( zPath[0]!=']' ) return 0;
829 zPath++;
830 j = 1;
drh52216ad2015-08-18 02:28:03 +0000831 for(;;){
832 while( i>0 && j<=pRoot->n ){
drh505ad2c2015-08-21 17:33:11 +0000833 j += jsonNodeSize(&pRoot[j]);
drh52216ad2015-08-18 02:28:03 +0000834 i--;
835 }
836 if( (pRoot->jnFlags & JNODE_APPEND)==0 ) break;
837 iRoot += pRoot->u.iAppend;
838 pRoot = &pParse->aNode[iRoot];
839 j = 1;
drh987eb1f2015-08-17 15:17:37 +0000840 }
841 if( j<=pRoot->n ){
drh52216ad2015-08-18 02:28:03 +0000842 return jsonLookup(pParse, iRoot+j, zPath, pApnd);
843 }
844 if( i==0 && pApnd ){
845 k = jsonParseAddNode(pParse, JSON_ARRAY, 1, 0);
846 pRoot->u.iAppend = k - iRoot;
847 pRoot->jnFlags |= JNODE_APPEND;
848 return jsonLookupAppend(pParse, zPath, pApnd);
drh987eb1f2015-08-17 15:17:37 +0000849 }
850 }
851 return 0;
852}
853
drh52216ad2015-08-18 02:28:03 +0000854/*
855** Append content to pParse that will complete zPath.
856*/
857static JsonNode *jsonLookupAppend(
858 JsonParse *pParse, /* Append content to the JSON parse */
859 const char *zPath, /* Description of content to append */
860 int *pApnd /* Set this flag to 1 */
861){
862 *pApnd = 1;
863 if( zPath[0]==0 ){
864 jsonParseAddNode(pParse, JSON_NULL, 0, 0);
865 return pParse->oom ? 0 : &pParse->aNode[pParse->nNode-1];
866 }
867 if( zPath[0]=='.' ){
868 jsonParseAddNode(pParse, JSON_OBJECT, 0, 0);
869 }else if( strncmp(zPath,"[0]",3)==0 ){
870 jsonParseAddNode(pParse, JSON_ARRAY, 0, 0);
871 }else{
872 return 0;
873 }
874 if( pParse->oom ) return 0;
875 return jsonLookup(pParse, pParse->nNode-1, zPath, pApnd);
876}
877
878
drh987eb1f2015-08-17 15:17:37 +0000879/****************************************************************************
880** SQL functions used for testing and debugging
881****************************************************************************/
drhe9c37f32015-08-15 21:25:36 +0000882
drh301eecc2015-08-17 20:14:19 +0000883#ifdef SQLITE_DEBUG
drhe9c37f32015-08-15 21:25:36 +0000884/*
drh5634cc02015-08-17 11:28:03 +0000885** The json_parse(JSON) function returns a string which describes
drhe9c37f32015-08-15 21:25:36 +0000886** a parse of the JSON provided. Or it returns NULL if JSON is not
887** well-formed.
888*/
drh5634cc02015-08-17 11:28:03 +0000889static void jsonParseFunc(
drhe9c37f32015-08-15 21:25:36 +0000890 sqlite3_context *context,
891 int argc,
892 sqlite3_value **argv
893){
drh505ad2c2015-08-21 17:33:11 +0000894 JsonString s; /* Output string - not real JSON */
895 JsonParse x; /* The parse */
drhe9c37f32015-08-15 21:25:36 +0000896 u32 i;
drh301eecc2015-08-17 20:14:19 +0000897 char zBuf[100];
drhe9c37f32015-08-15 21:25:36 +0000898
899 assert( argc==1 );
900 if( jsonParse(&x, (const char*)sqlite3_value_text(argv[0])) ) return;
901 jsonInit(&s, context);
902 for(i=0; i<x.nNode; i++){
drh301eecc2015-08-17 20:14:19 +0000903 sqlite3_snprintf(sizeof(zBuf), zBuf, "node %3u: %7s n=%d\n",
904 i, jsonType[x.aNode[i].eType], x.aNode[i].n);
drhe9c37f32015-08-15 21:25:36 +0000905 jsonAppend(&s, zBuf);
drh52216ad2015-08-18 02:28:03 +0000906 if( x.aNode[i].u.zJContent!=0 ){
drh301eecc2015-08-17 20:14:19 +0000907 jsonAppendRaw(&s, " text: ", 10);
drh52216ad2015-08-18 02:28:03 +0000908 jsonAppendRaw(&s, x.aNode[i].u.zJContent, x.aNode[i].n);
drhe9c37f32015-08-15 21:25:36 +0000909 jsonAppendRaw(&s, "\n", 1);
910 }
911 }
drh505ad2c2015-08-21 17:33:11 +0000912 jsonParseReset(&x);
drhe9c37f32015-08-15 21:25:36 +0000913 jsonResult(&s);
914}
915
drh5634cc02015-08-17 11:28:03 +0000916/*
917** The json_test1(JSON) function parses and rebuilds the JSON string.
918*/
919static void jsonTest1Func(
920 sqlite3_context *context,
921 int argc,
922 sqlite3_value **argv
923){
924 JsonParse x; /* The parse */
925 if( jsonParse(&x, (const char*)sqlite3_value_text(argv[0])) ) return;
drhd0960592015-08-17 21:22:32 +0000926 jsonReturn(x.aNode, context, 0);
drh505ad2c2015-08-21 17:33:11 +0000927 jsonParseReset(&x);
drh5634cc02015-08-17 11:28:03 +0000928}
929
930/*
931** The json_nodecount(JSON) function returns the number of nodes in the
932** input JSON string.
933*/
934static void jsonNodeCountFunc(
935 sqlite3_context *context,
936 int argc,
937 sqlite3_value **argv
938){
939 JsonParse x; /* The parse */
940 if( jsonParse(&x, (const char*)sqlite3_value_text(argv[0])) ) return;
drh6fd5c1e2015-08-21 20:37:12 +0000941 sqlite3_result_int64(context, (sqlite3_int64)x.nNode);
drh505ad2c2015-08-21 17:33:11 +0000942 jsonParseReset(&x);
drh5634cc02015-08-17 11:28:03 +0000943}
drh301eecc2015-08-17 20:14:19 +0000944#endif /* SQLITE_DEBUG */
drh5634cc02015-08-17 11:28:03 +0000945
drh987eb1f2015-08-17 15:17:37 +0000946/****************************************************************************
947** SQL function implementations
948****************************************************************************/
949
950/*
951** Implementation of the json_array(VALUE,...) function. Return a JSON
952** array that contains all values given in arguments. Or if any argument
953** is a BLOB, throw an error.
954*/
955static void jsonArrayFunc(
956 sqlite3_context *context,
957 int argc,
958 sqlite3_value **argv
959){
960 int i;
drh505ad2c2015-08-21 17:33:11 +0000961 JsonString jx;
drh987eb1f2015-08-17 15:17:37 +0000962
963 jsonInit(&jx, context);
drhd0960592015-08-17 21:22:32 +0000964 jsonAppendChar(&jx, '[');
drh987eb1f2015-08-17 15:17:37 +0000965 for(i=0; i<argc; i++){
drhd0960592015-08-17 21:22:32 +0000966 jsonAppendSeparator(&jx);
967 jsonAppendValue(&jx, argv[i]);
drh987eb1f2015-08-17 15:17:37 +0000968 }
drhd0960592015-08-17 21:22:32 +0000969 jsonAppendChar(&jx, ']');
drh987eb1f2015-08-17 15:17:37 +0000970 jsonResult(&jx);
971}
972
973
974/*
975** json_array_length(JSON)
976** json_array_length(JSON, PATH)
977**
978** Return the number of elements in the top-level JSON array.
979** Return 0 if the input is not a well-formed JSON array.
980*/
981static void jsonArrayLengthFunc(
982 sqlite3_context *context,
983 int argc,
984 sqlite3_value **argv
985){
986 JsonParse x; /* The parse */
987 sqlite3_int64 n = 0;
988 u32 i;
989 const char *zPath;
990
991 if( argc==2 ){
992 zPath = (const char*)sqlite3_value_text(argv[1]);
993 if( zPath==0 ) return;
994 if( zPath[0]!='$' ) return;
995 zPath++;
996 }else{
997 zPath = 0;
998 }
999 if( jsonParse(&x, (const char*)sqlite3_value_text(argv[0]))==0 ){
1000 if( x.nNode ){
1001 JsonNode *pNode = x.aNode;
drh52216ad2015-08-18 02:28:03 +00001002 if( zPath ) pNode = jsonLookup(&x, 0, zPath, 0);
drh987eb1f2015-08-17 15:17:37 +00001003 if( pNode->eType==JSON_ARRAY ){
drh52216ad2015-08-18 02:28:03 +00001004 assert( (pNode->jnFlags & JNODE_APPEND)==0 );
drh301eecc2015-08-17 20:14:19 +00001005 for(i=1; i<=pNode->n; n++){
drh505ad2c2015-08-21 17:33:11 +00001006 i += jsonNodeSize(&pNode[i]);
drh987eb1f2015-08-17 15:17:37 +00001007 }
1008 }
1009 }
drh505ad2c2015-08-21 17:33:11 +00001010 jsonParseReset(&x);
drh987eb1f2015-08-17 15:17:37 +00001011 }
1012 sqlite3_result_int64(context, n);
1013}
1014
1015/*
1016** json_extract(JSON, PATH)
1017**
1018** Return the element described by PATH. Return NULL if JSON is not
1019** valid JSON or if there is no PATH element or if PATH is malformed.
1020*/
1021static void jsonExtractFunc(
1022 sqlite3_context *context,
1023 int argc,
1024 sqlite3_value **argv
1025){
1026 JsonParse x; /* The parse */
1027 JsonNode *pNode;
1028 const char *zPath;
1029 assert( argc==2 );
1030 zPath = (const char*)sqlite3_value_text(argv[1]);
1031 if( zPath==0 ) return;
1032 if( zPath[0]!='$' ) return;
1033 zPath++;
1034 if( jsonParse(&x, (const char*)sqlite3_value_text(argv[0])) ) return;
drh52216ad2015-08-18 02:28:03 +00001035 pNode = jsonLookup(&x, 0, zPath, 0);
drh987eb1f2015-08-17 15:17:37 +00001036 if( pNode ){
drhd0960592015-08-17 21:22:32 +00001037 jsonReturn(pNode, context, 0);
drh987eb1f2015-08-17 15:17:37 +00001038 }
drh505ad2c2015-08-21 17:33:11 +00001039 jsonParseReset(&x);
drh987eb1f2015-08-17 15:17:37 +00001040}
1041
1042/*
1043** Implementation of the json_object(NAME,VALUE,...) function. Return a JSON
1044** object that contains all name/value given in arguments. Or if any name
1045** is not a string or if any value is a BLOB, throw an error.
1046*/
1047static void jsonObjectFunc(
1048 sqlite3_context *context,
1049 int argc,
1050 sqlite3_value **argv
1051){
1052 int i;
drh505ad2c2015-08-21 17:33:11 +00001053 JsonString jx;
drh987eb1f2015-08-17 15:17:37 +00001054 const char *z;
1055 u32 n;
1056
1057 if( argc&1 ){
1058 sqlite3_result_error(context, "json_object() requires an even number "
1059 "of arguments", -1);
1060 return;
1061 }
1062 jsonInit(&jx, context);
drhd0960592015-08-17 21:22:32 +00001063 jsonAppendChar(&jx, '{');
drh987eb1f2015-08-17 15:17:37 +00001064 for(i=0; i<argc; i+=2){
drh987eb1f2015-08-17 15:17:37 +00001065 if( sqlite3_value_type(argv[i])!=SQLITE_TEXT ){
1066 sqlite3_result_error(context, "json_object() labels must be TEXT", -1);
1067 jsonZero(&jx);
1068 return;
1069 }
drhd0960592015-08-17 21:22:32 +00001070 jsonAppendSeparator(&jx);
drh987eb1f2015-08-17 15:17:37 +00001071 z = (const char*)sqlite3_value_text(argv[i]);
1072 n = (u32)sqlite3_value_bytes(argv[i]);
1073 jsonAppendString(&jx, z, n);
drhd0960592015-08-17 21:22:32 +00001074 jsonAppendChar(&jx, ':');
1075 jsonAppendValue(&jx, argv[i+1]);
drh987eb1f2015-08-17 15:17:37 +00001076 }
drhd0960592015-08-17 21:22:32 +00001077 jsonAppendChar(&jx, '}');
drh987eb1f2015-08-17 15:17:37 +00001078 jsonResult(&jx);
1079}
1080
1081
1082/*
drh301eecc2015-08-17 20:14:19 +00001083** json_remove(JSON, PATH, ...)
1084**
1085** Remove the named elements from JSON and return the result. Ill-formed
1086** PATH arguments are silently ignored. If JSON is ill-formed, then NULL
1087** is returned.
1088*/
1089static void jsonRemoveFunc(
1090 sqlite3_context *context,
1091 int argc,
1092 sqlite3_value **argv
1093){
1094 JsonParse x; /* The parse */
1095 JsonNode *pNode;
1096 const char *zPath;
1097 u32 i;
1098
1099 if( argc<1 ) return;
1100 if( jsonParse(&x, (const char*)sqlite3_value_text(argv[0])) ) return;
1101 if( x.nNode ){
drh6fd5c1e2015-08-21 20:37:12 +00001102 for(i=1; i<(u32)argc; i++){
drh301eecc2015-08-17 20:14:19 +00001103 zPath = (const char*)sqlite3_value_text(argv[i]);
1104 if( zPath==0 ) continue;
1105 if( zPath[0]!='$' ) continue;
drh52216ad2015-08-18 02:28:03 +00001106 pNode = jsonLookup(&x, 0, &zPath[1], 0);
drh301eecc2015-08-17 20:14:19 +00001107 if( pNode ) pNode->jnFlags |= JNODE_REMOVE;
1108 }
1109 if( (x.aNode[0].jnFlags & JNODE_REMOVE)==0 ){
drhd0960592015-08-17 21:22:32 +00001110 jsonReturn(x.aNode, context, 0);
1111 }
1112 }
drh505ad2c2015-08-21 17:33:11 +00001113 jsonParseReset(&x);
drhd0960592015-08-17 21:22:32 +00001114}
1115
1116/*
1117** json_replace(JSON, PATH, VALUE, ...)
1118**
1119** Replace the value at PATH with VALUE. If PATH does not already exist,
1120** this routine is a no-op. If JSON is ill-formed, return NULL.
1121*/
1122static void jsonReplaceFunc(
1123 sqlite3_context *context,
1124 int argc,
1125 sqlite3_value **argv
1126){
1127 JsonParse x; /* The parse */
1128 JsonNode *pNode;
1129 const char *zPath;
1130 u32 i;
1131
1132 if( argc<1 ) return;
1133 if( (argc&1)==0 ) {
1134 sqlite3_result_error(context,
1135 "json_replace() needs an odd number of arguments", -1);
1136 return;
1137 }
1138 if( jsonParse(&x, (const char*)sqlite3_value_text(argv[0])) ) return;
1139 if( x.nNode ){
drh6fd5c1e2015-08-21 20:37:12 +00001140 for(i=1; i<(u32)argc; i+=2){
drhd0960592015-08-17 21:22:32 +00001141 zPath = (const char*)sqlite3_value_text(argv[i]);
1142 if( zPath==0 ) continue;
1143 if( zPath[0]!='$' ) continue;
drh52216ad2015-08-18 02:28:03 +00001144 pNode = jsonLookup(&x, 0, &zPath[1], 0);
drhd0960592015-08-17 21:22:32 +00001145 if( pNode ){
1146 pNode->jnFlags |= JNODE_REPLACE;
1147 pNode->iVal = i+1;
1148 }
1149 }
1150 if( x.aNode[0].jnFlags & JNODE_REPLACE ){
1151 sqlite3_result_value(context, argv[x.aNode[0].iVal]);
1152 }else{
1153 jsonReturn(x.aNode, context, argv);
drh301eecc2015-08-17 20:14:19 +00001154 }
1155 }
drh505ad2c2015-08-21 17:33:11 +00001156 jsonParseReset(&x);
drh301eecc2015-08-17 20:14:19 +00001157}
drh505ad2c2015-08-21 17:33:11 +00001158
drh52216ad2015-08-18 02:28:03 +00001159/*
1160** json_set(JSON, PATH, VALUE, ...)
1161**
1162** Set the value at PATH to VALUE. Create the PATH if it does not already
1163** exist. Overwrite existing values that do exist.
1164** If JSON is ill-formed, return NULL.
1165**
1166** json_insert(JSON, PATH, VALUE, ...)
1167**
1168** Create PATH and initialize it to VALUE. If PATH already exists, this
1169** routine is a no-op. If JSON is ill-formed, return NULL.
1170*/
1171static void jsonSetFunc(
1172 sqlite3_context *context,
1173 int argc,
1174 sqlite3_value **argv
1175){
1176 JsonParse x; /* The parse */
1177 JsonNode *pNode;
1178 const char *zPath;
1179 u32 i;
1180 int bApnd;
1181 int bIsSet = *(int*)sqlite3_user_data(context);
1182
1183 if( argc<1 ) return;
1184 if( (argc&1)==0 ) {
1185 sqlite3_result_error(context,
1186 "json_set() needs an odd number of arguments", -1);
1187 return;
1188 }
1189 if( jsonParse(&x, (const char*)sqlite3_value_text(argv[0])) ) return;
1190 if( x.nNode ){
drh6fd5c1e2015-08-21 20:37:12 +00001191 for(i=1; i<(u32)argc; i+=2){
drh52216ad2015-08-18 02:28:03 +00001192 zPath = (const char*)sqlite3_value_text(argv[i]);
1193 if( zPath==0 ) continue;
1194 if( zPath[0]!='$' ) continue;
1195 bApnd = 0;
1196 pNode = jsonLookup(&x, 0, &zPath[1], &bApnd);
1197 if( pNode && (bApnd || bIsSet) ){
1198 pNode->jnFlags |= JNODE_REPLACE;
1199 pNode->iVal = i+1;
1200 }
1201 }
1202 if( x.aNode[0].jnFlags & JNODE_REPLACE ){
1203 sqlite3_result_value(context, argv[x.aNode[0].iVal]);
1204 }else{
1205 jsonReturn(x.aNode, context, argv);
1206 }
1207 }
drh505ad2c2015-08-21 17:33:11 +00001208 jsonParseReset(&x);
drh52216ad2015-08-18 02:28:03 +00001209}
drh301eecc2015-08-17 20:14:19 +00001210
1211/*
drh987eb1f2015-08-17 15:17:37 +00001212** json_type(JSON)
1213** json_type(JSON, PATH)
1214**
1215** Return the top-level "type" of a JSON string. Return NULL if the
1216** input is not a well-formed JSON string.
1217*/
1218static void jsonTypeFunc(
1219 sqlite3_context *context,
1220 int argc,
1221 sqlite3_value **argv
1222){
1223 JsonParse x; /* The parse */
1224 const char *zPath;
1225
1226 if( argc==2 ){
1227 zPath = (const char*)sqlite3_value_text(argv[1]);
1228 if( zPath==0 ) return;
1229 if( zPath[0]!='$' ) return;
1230 zPath++;
1231 }else{
1232 zPath = 0;
1233 }
1234 if( jsonParse(&x, (const char*)sqlite3_value_text(argv[0])) ) return;
1235 if( x.nNode ){
1236 JsonNode *pNode = x.aNode;
drh52216ad2015-08-18 02:28:03 +00001237 if( zPath ) pNode = jsonLookup(&x, 0, zPath, 0);
drh987eb1f2015-08-17 15:17:37 +00001238 sqlite3_result_text(context, jsonType[pNode->eType], -1, SQLITE_STATIC);
1239 }
drh505ad2c2015-08-21 17:33:11 +00001240 jsonParseReset(&x);
drh987eb1f2015-08-17 15:17:37 +00001241}
drh5634cc02015-08-17 11:28:03 +00001242
drhcb6c6c62015-08-19 22:47:17 +00001243/****************************************************************************
1244** The json_each virtual table
1245****************************************************************************/
1246typedef struct JsonEachCursor JsonEachCursor;
1247struct JsonEachCursor {
1248 sqlite3_vtab_cursor base; /* Base class - must be first */
drh505ad2c2015-08-21 17:33:11 +00001249 u32 iRowid; /* The rowid */
1250 u32 i; /* Index in sParse.aNode[] of current row */
1251 u32 iEnd; /* EOF when i equals or exceeds this value */
1252 u8 eType; /* Type of top-level element */
1253 u8 bRecursive; /* True for json_tree(). False for json_each() */
1254 char *zJson; /* Input JSON */
1255 char *zPath; /* Path by which to filter zJson */
1256 JsonParse sParse; /* Parse of the input JSON */
drhcb6c6c62015-08-19 22:47:17 +00001257};
1258
1259/* Constructor for the json_each virtual table */
1260static int jsonEachConnect(
1261 sqlite3 *db,
1262 void *pAux,
1263 int argc, const char *const*argv,
1264 sqlite3_vtab **ppVtab,
1265 char **pzErr
1266){
1267 sqlite3_vtab *pNew;
drh505ad2c2015-08-21 17:33:11 +00001268 int rc;
drhcb6c6c62015-08-19 22:47:17 +00001269
1270/* Column numbers */
drh4af352d2015-08-21 20:02:48 +00001271#define JEACH_KEY 0
1272#define JEACH_VALUE 1
1273#define JEACH_TYPE 2
1274#define JEACH_ATOM 3
1275#define JEACH_ID 4
1276#define JEACH_PARENT 5
1277#define JEACH_FULLKEY 6
1278#define JEACH_JSON 7
1279#define JEACH_PATH 8
drhcb6c6c62015-08-19 22:47:17 +00001280
drh6fd5c1e2015-08-21 20:37:12 +00001281 UNUSED_PARAM(pzErr);
1282 UNUSED_PARAM(argv);
1283 UNUSED_PARAM(argc);
1284 UNUSED_PARAM(pAux);
drh505ad2c2015-08-21 17:33:11 +00001285 rc = sqlite3_declare_vtab(db,
drh4af352d2015-08-21 20:02:48 +00001286 "CREATE TABLE x(key,value,type,atom,id,parent,fullkey,"
1287 "json HIDDEN,path HIDDEN)");
drh505ad2c2015-08-21 17:33:11 +00001288 if( rc==SQLITE_OK ){
1289 pNew = *ppVtab = sqlite3_malloc( sizeof(*pNew) );
1290 if( pNew==0 ) return SQLITE_NOMEM;
1291 memset(pNew, 0, sizeof(*pNew));
1292 }
1293 return rc;
drhcb6c6c62015-08-19 22:47:17 +00001294}
1295
1296/* destructor for json_each virtual table */
1297static int jsonEachDisconnect(sqlite3_vtab *pVtab){
1298 sqlite3_free(pVtab);
1299 return SQLITE_OK;
1300}
1301
drh505ad2c2015-08-21 17:33:11 +00001302/* constructor for a JsonEachCursor object for json_each(). */
1303static int jsonEachOpenEach(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
drhcb6c6c62015-08-19 22:47:17 +00001304 JsonEachCursor *pCur;
drh6fd5c1e2015-08-21 20:37:12 +00001305
1306 UNUSED_PARAM(p);
drhcb6c6c62015-08-19 22:47:17 +00001307 pCur = sqlite3_malloc( sizeof(*pCur) );
1308 if( pCur==0 ) return SQLITE_NOMEM;
1309 memset(pCur, 0, sizeof(*pCur));
1310 *ppCursor = &pCur->base;
1311 return SQLITE_OK;
1312}
1313
drh505ad2c2015-08-21 17:33:11 +00001314/* constructor for a JsonEachCursor object for json_tree(). */
1315static int jsonEachOpenTree(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
1316 int rc = jsonEachOpenEach(p, ppCursor);
1317 if( rc==SQLITE_OK ){
1318 JsonEachCursor *pCur = (JsonEachCursor*)*ppCursor;
1319 pCur->bRecursive = 1;
1320 }
1321 return rc;
1322}
1323
drhcb6c6c62015-08-19 22:47:17 +00001324/* Reset a JsonEachCursor back to its original state. Free any memory
1325** held. */
1326static void jsonEachCursorReset(JsonEachCursor *p){
1327 sqlite3_free(p->zJson);
1328 sqlite3_free(p->zPath);
drh505ad2c2015-08-21 17:33:11 +00001329 jsonParseReset(&p->sParse);
drhcb6c6c62015-08-19 22:47:17 +00001330 p->iRowid = 0;
1331 p->i = 0;
1332 p->iEnd = 0;
1333 p->eType = 0;
drhcb6c6c62015-08-19 22:47:17 +00001334 p->zJson = 0;
1335 p->zPath = 0;
1336}
1337
1338/* Destructor for a jsonEachCursor object */
1339static int jsonEachClose(sqlite3_vtab_cursor *cur){
1340 JsonEachCursor *p = (JsonEachCursor*)cur;
1341 jsonEachCursorReset(p);
1342 sqlite3_free(cur);
1343 return SQLITE_OK;
1344}
1345
1346/* Return TRUE if the jsonEachCursor object has been advanced off the end
1347** of the JSON object */
1348static int jsonEachEof(sqlite3_vtab_cursor *cur){
1349 JsonEachCursor *p = (JsonEachCursor*)cur;
1350 return p->i >= p->iEnd;
1351}
1352
drh505ad2c2015-08-21 17:33:11 +00001353/* Advance the cursor to the next element for json_tree() */
drh4af352d2015-08-21 20:02:48 +00001354static int jsonEachNext(sqlite3_vtab_cursor *cur){
drh505ad2c2015-08-21 17:33:11 +00001355 JsonEachCursor *p = (JsonEachCursor*)cur;
drh4af352d2015-08-21 20:02:48 +00001356 if( p->bRecursive ){
1357 if( p->i==0 ){
1358 p->i = 1;
1359 }else if( p->sParse.aNode[p->sParse.aUp[p->i]].eType==JSON_OBJECT ){
1360 p->i += 2;
1361 }else{
1362 p->i++;
1363 }
1364 p->iRowid++;
1365 if( p->i<p->sParse.nNode ){
1366 JsonNode *pUp = &p->sParse.aNode[p->sParse.aUp[p->i]];
1367 p->eType = pUp->eType;
1368 if( pUp->eType==JSON_ARRAY ) pUp->u.iKey++;
1369 if( p->sParse.aNode[p->i].eType==JSON_ARRAY ){
1370 p->sParse.aNode[p->i].u.iKey = 0;
1371 }
1372 }
drh505ad2c2015-08-21 17:33:11 +00001373 }else{
drh4af352d2015-08-21 20:02:48 +00001374 switch( p->eType ){
1375 case JSON_ARRAY: {
1376 p->i += jsonNodeSize(&p->sParse.aNode[p->i]);
1377 p->iRowid++;
1378 break;
1379 }
1380 case JSON_OBJECT: {
1381 p->i += 1 + jsonNodeSize(&p->sParse.aNode[p->i+1]);
1382 p->iRowid++;
1383 break;
1384 }
1385 default: {
1386 p->i = p->iEnd;
1387 break;
1388 }
drh505ad2c2015-08-21 17:33:11 +00001389 }
1390 }
1391 return SQLITE_OK;
1392}
1393
drh4af352d2015-08-21 20:02:48 +00001394/* Append the name of the path for element i to pStr
1395*/
1396static void jsonEachComputePath(
1397 JsonEachCursor *p, /* The cursor */
1398 JsonString *pStr, /* Write the path here */
1399 u32 i /* Path to this element */
1400){
1401 JsonNode *pNode, *pUp;
1402 u32 iUp;
1403 if( i==0 ){
1404 jsonAppendChar(pStr, '$');
1405 return;
drhcb6c6c62015-08-19 22:47:17 +00001406 }
drh4af352d2015-08-21 20:02:48 +00001407 iUp = p->sParse.aUp[i];
1408 jsonEachComputePath(p, pStr, iUp);
1409 pNode = &p->sParse.aNode[i];
1410 pUp = &p->sParse.aNode[iUp];
1411 if( pUp->eType==JSON_ARRAY ){
1412 jsonPrintf(30, pStr, "[%d]", pUp->u.iKey);
1413 }else{
1414 assert( pUp->eType==JSON_OBJECT );
1415 if( pNode->eType>=JSON_ARRAY ) pNode--;
1416 assert( pNode->eType==JSON_STRING );
1417 jsonPrintf(pNode->n+1, pStr, ".%.*s", pNode->n-2, pNode->u.zJContent+1);
1418 }
drhcb6c6c62015-08-19 22:47:17 +00001419}
1420
1421/* Return the value of a column */
1422static int jsonEachColumn(
1423 sqlite3_vtab_cursor *cur, /* The cursor */
1424 sqlite3_context *ctx, /* First argument to sqlite3_result_...() */
1425 int i /* Which column to return */
1426){
1427 JsonEachCursor *p = (JsonEachCursor*)cur;
drh505ad2c2015-08-21 17:33:11 +00001428 JsonNode *pThis = &p->sParse.aNode[p->i];
drhcb6c6c62015-08-19 22:47:17 +00001429 switch( i ){
1430 case JEACH_KEY: {
1431 if( p->eType==JSON_OBJECT ){
drh505ad2c2015-08-21 17:33:11 +00001432 jsonReturn(pThis, ctx, 0);
1433 }else if( p->eType==JSON_ARRAY ){
1434 u32 iKey;
1435 if( p->bRecursive ){
1436 if( p->iRowid==0 ) break;
1437 iKey = p->sParse.aNode[p->sParse.aUp[p->i]].u.iKey - 1;
1438 }else{
1439 iKey = p->iRowid;
1440 }
drh6fd5c1e2015-08-21 20:37:12 +00001441 sqlite3_result_int64(ctx, (sqlite3_int64)iKey);
drhcb6c6c62015-08-19 22:47:17 +00001442 }
1443 break;
1444 }
1445 case JEACH_VALUE: {
drh505ad2c2015-08-21 17:33:11 +00001446 if( p->eType==JSON_OBJECT ) pThis++;
1447 jsonReturn(pThis, ctx, 0);
1448 break;
1449 }
1450 case JEACH_TYPE: {
1451 if( p->eType==JSON_OBJECT ) pThis++;
1452 sqlite3_result_text(ctx, jsonType[pThis->eType], -1, SQLITE_STATIC);
1453 break;
1454 }
1455 case JEACH_ATOM: {
1456 if( p->eType==JSON_OBJECT ) pThis++;
1457 if( pThis->eType>=JSON_ARRAY ) break;
1458 jsonReturn(pThis, ctx, 0);
1459 break;
1460 }
1461 case JEACH_ID: {
drh6fd5c1e2015-08-21 20:37:12 +00001462 sqlite3_result_int64(ctx, (sqlite3_int64)p->i + (p->eType==JSON_OBJECT));
drh505ad2c2015-08-21 17:33:11 +00001463 break;
1464 }
1465 case JEACH_PARENT: {
1466 if( p->i>0 && p->bRecursive ){
drh6fd5c1e2015-08-21 20:37:12 +00001467 sqlite3_result_int64(ctx, (sqlite3_int64)p->sParse.aUp[p->i]);
drhcb6c6c62015-08-19 22:47:17 +00001468 }
1469 break;
1470 }
drh4af352d2015-08-21 20:02:48 +00001471 case JEACH_FULLKEY: {
1472 JsonString x;
1473 jsonInit(&x, ctx);
1474 if( p->bRecursive ){
1475 jsonEachComputePath(p, &x, p->i);
1476 }else{
1477 if( p->zPath ){
1478 jsonAppendRaw(&x, p->zPath, (int)strlen(p->zPath));
1479 }else{
1480 jsonAppendChar(&x, '$');
1481 }
1482 if( p->eType==JSON_ARRAY ){
1483 jsonPrintf(30, &x, "[%d]", p->iRowid);
1484 }else{
1485 jsonPrintf(pThis->n, &x, ".%.*s", pThis->n-2, pThis->u.zJContent+1);
1486 }
1487 }
1488 jsonResult(&x);
1489 break;
1490 }
drhcb6c6c62015-08-19 22:47:17 +00001491 case JEACH_PATH: {
1492 const char *zPath = p->zPath;
drh4af352d2015-08-21 20:02:48 +00001493 if( zPath==0 ){
1494 if( p->bRecursive ){
1495 JsonString x;
1496 jsonInit(&x, ctx);
1497 jsonEachComputePath(p, &x, p->sParse.aUp[p->i]);
1498 jsonResult(&x);
1499 break;
1500 }
1501 zPath = "$";
1502 }
drhcb6c6c62015-08-19 22:47:17 +00001503 sqlite3_result_text(ctx, zPath, -1, SQLITE_STATIC);
1504 break;
1505 }
1506 default: {
drh505ad2c2015-08-21 17:33:11 +00001507 assert( i==JEACH_JSON );
drhcb6c6c62015-08-19 22:47:17 +00001508 sqlite3_result_text(ctx, p->sParse.zJson, -1, SQLITE_STATIC);
1509 break;
1510 }
1511 }
1512 return SQLITE_OK;
1513}
1514
1515/* Return the current rowid value */
1516static int jsonEachRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){
1517 JsonEachCursor *p = (JsonEachCursor*)cur;
1518 *pRowid = p->iRowid;
1519 return SQLITE_OK;
1520}
1521
1522/* The query strategy is to look for an equality constraint on the json
1523** column. Without such a constraint, the table cannot operate. idxNum is
1524** 1 if the constraint is found, 3 if the constraint and zPath are found,
1525** and 0 otherwise.
1526*/
1527static int jsonEachBestIndex(
1528 sqlite3_vtab *tab,
1529 sqlite3_index_info *pIdxInfo
1530){
1531 int i;
1532 int jsonIdx = -1;
1533 int pathIdx = -1;
1534 const struct sqlite3_index_constraint *pConstraint;
drh6fd5c1e2015-08-21 20:37:12 +00001535
1536 UNUSED_PARAM(tab);
drhcb6c6c62015-08-19 22:47:17 +00001537 pConstraint = pIdxInfo->aConstraint;
1538 for(i=0; i<pIdxInfo->nConstraint; i++, pConstraint++){
1539 if( pConstraint->usable==0 ) continue;
1540 if( pConstraint->op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue;
1541 switch( pConstraint->iColumn ){
1542 case JEACH_JSON: jsonIdx = i; break;
1543 case JEACH_PATH: pathIdx = i; break;
1544 default: /* no-op */ break;
1545 }
1546 }
1547 if( jsonIdx<0 ){
1548 pIdxInfo->idxNum = 0;
drh505ad2c2015-08-21 17:33:11 +00001549 pIdxInfo->estimatedCost = 1e99;
drhcb6c6c62015-08-19 22:47:17 +00001550 }else{
drh505ad2c2015-08-21 17:33:11 +00001551 pIdxInfo->estimatedCost = 1.0;
drhcb6c6c62015-08-19 22:47:17 +00001552 pIdxInfo->aConstraintUsage[jsonIdx].argvIndex = 1;
1553 pIdxInfo->aConstraintUsage[jsonIdx].omit = 1;
1554 if( pathIdx<0 ){
1555 pIdxInfo->idxNum = 1;
1556 }else{
1557 pIdxInfo->aConstraintUsage[pathIdx].argvIndex = 2;
1558 pIdxInfo->aConstraintUsage[pathIdx].omit = 1;
1559 pIdxInfo->idxNum = 3;
1560 }
1561 }
1562 return SQLITE_OK;
1563}
1564
1565/* Start a search on a new JSON string */
1566static int jsonEachFilter(
1567 sqlite3_vtab_cursor *cur,
1568 int idxNum, const char *idxStr,
1569 int argc, sqlite3_value **argv
1570){
1571 JsonEachCursor *p = (JsonEachCursor*)cur;
1572 const char *z;
1573 const char *zPath;
1574 sqlite3_int64 n;
1575
drh6fd5c1e2015-08-21 20:37:12 +00001576 UNUSED_PARAM(idxStr);
1577 UNUSED_PARAM(argc);
drhcb6c6c62015-08-19 22:47:17 +00001578 jsonEachCursorReset(p);
1579 if( idxNum==0 ) return SQLITE_OK;
1580 z = (const char*)sqlite3_value_text(argv[0]);
1581 if( z==0 ) return SQLITE_OK;
1582 if( idxNum&2 ){
1583 zPath = (const char*)sqlite3_value_text(argv[1]);
1584 if( zPath==0 || zPath[0]!='$' ) return SQLITE_OK;
1585 }
1586 n = sqlite3_value_bytes(argv[0]);
drh6fd5c1e2015-08-21 20:37:12 +00001587 p->zJson = sqlite3_malloc64( n+1 );
drhcb6c6c62015-08-19 22:47:17 +00001588 if( p->zJson==0 ) return SQLITE_NOMEM;
drh6fd5c1e2015-08-21 20:37:12 +00001589 memcpy(p->zJson, z, (size_t)n+1);
drh505ad2c2015-08-21 17:33:11 +00001590 if( jsonParse(&p->sParse, p->zJson)
1591 || (p->bRecursive && jsonParseFindParents(&p->sParse))
1592 ){
drhcb6c6c62015-08-19 22:47:17 +00001593 jsonEachCursorReset(p);
1594 }else{
1595 JsonNode *pNode;
1596 if( idxNum==3 ){
drh4af352d2015-08-21 20:02:48 +00001597 p->bRecursive = 0;
drhcb6c6c62015-08-19 22:47:17 +00001598 n = sqlite3_value_bytes(argv[1]);
drh6fd5c1e2015-08-21 20:37:12 +00001599 p->zPath = sqlite3_malloc64( n+1 );
drhcb6c6c62015-08-19 22:47:17 +00001600 if( p->zPath==0 ) return SQLITE_NOMEM;
drh6fd5c1e2015-08-21 20:37:12 +00001601 memcpy(p->zPath, zPath, (size_t)n+1);
drhcb6c6c62015-08-19 22:47:17 +00001602 pNode = jsonLookup(&p->sParse, 0, p->zPath+1, 0);
1603 if( pNode==0 ){
1604 jsonEachCursorReset(p);
1605 return SQLITE_OK;
1606 }
1607 }else{
1608 pNode = p->sParse.aNode;
1609 }
1610 p->i = (int)(pNode - p->sParse.aNode);
1611 p->eType = pNode->eType;
1612 if( p->eType>=JSON_ARRAY ){
1613 p->i++;
1614 p->iEnd = p->i + pNode->n;
1615 }else{
1616 p->iEnd = p->i+1;
1617 }
1618 }
1619 return SQLITE_OK;
1620}
1621
1622/* The methods of the json_each virtual table */
1623static sqlite3_module jsonEachModule = {
1624 0, /* iVersion */
1625 0, /* xCreate */
1626 jsonEachConnect, /* xConnect */
1627 jsonEachBestIndex, /* xBestIndex */
1628 jsonEachDisconnect, /* xDisconnect */
1629 0, /* xDestroy */
drh505ad2c2015-08-21 17:33:11 +00001630 jsonEachOpenEach, /* xOpen - open a cursor */
drhcb6c6c62015-08-19 22:47:17 +00001631 jsonEachClose, /* xClose - close a cursor */
1632 jsonEachFilter, /* xFilter - configure scan constraints */
drh4af352d2015-08-21 20:02:48 +00001633 jsonEachNext, /* xNext - advance a cursor */
drhcb6c6c62015-08-19 22:47:17 +00001634 jsonEachEof, /* xEof - check for end of scan */
1635 jsonEachColumn, /* xColumn - read data */
1636 jsonEachRowid, /* xRowid - read data */
1637 0, /* xUpdate */
1638 0, /* xBegin */
1639 0, /* xSync */
1640 0, /* xCommit */
1641 0, /* xRollback */
1642 0, /* xFindMethod */
1643 0, /* xRename */
drh6fd5c1e2015-08-21 20:37:12 +00001644 0, /* xSavepoint */
1645 0, /* xRelease */
1646 0 /* xRollbackTo */
drhcb6c6c62015-08-19 22:47:17 +00001647};
1648
drh505ad2c2015-08-21 17:33:11 +00001649/* The methods of the json_tree virtual table. */
1650static sqlite3_module jsonTreeModule = {
1651 0, /* iVersion */
1652 0, /* xCreate */
1653 jsonEachConnect, /* xConnect */
1654 jsonEachBestIndex, /* xBestIndex */
1655 jsonEachDisconnect, /* xDisconnect */
1656 0, /* xDestroy */
1657 jsonEachOpenTree, /* xOpen - open a cursor */
1658 jsonEachClose, /* xClose - close a cursor */
1659 jsonEachFilter, /* xFilter - configure scan constraints */
drh4af352d2015-08-21 20:02:48 +00001660 jsonEachNext, /* xNext - advance a cursor */
drh505ad2c2015-08-21 17:33:11 +00001661 jsonEachEof, /* xEof - check for end of scan */
1662 jsonEachColumn, /* xColumn - read data */
1663 jsonEachRowid, /* xRowid - read data */
1664 0, /* xUpdate */
1665 0, /* xBegin */
1666 0, /* xSync */
1667 0, /* xCommit */
1668 0, /* xRollback */
1669 0, /* xFindMethod */
1670 0, /* xRename */
drh6fd5c1e2015-08-21 20:37:12 +00001671 0, /* xSavepoint */
1672 0, /* xRelease */
1673 0 /* xRollbackTo */
drh505ad2c2015-08-21 17:33:11 +00001674};
1675
1676/****************************************************************************
1677** The following routine is the only publically visible identifier in this
1678** file. Call the following routine in order to register the various SQL
1679** functions and the virtual table implemented by this file.
1680****************************************************************************/
drhcb6c6c62015-08-19 22:47:17 +00001681
drh5fa5c102015-08-12 16:49:40 +00001682#ifdef _WIN32
1683__declspec(dllexport)
1684#endif
1685int sqlite3_json_init(
1686 sqlite3 *db,
1687 char **pzErrMsg,
1688 const sqlite3_api_routines *pApi
1689){
1690 int rc = SQLITE_OK;
drh6fd5c1e2015-08-21 20:37:12 +00001691 unsigned int i;
drh5fa5c102015-08-12 16:49:40 +00001692 static const struct {
1693 const char *zName;
1694 int nArg;
drh52216ad2015-08-18 02:28:03 +00001695 int flag;
drh5fa5c102015-08-12 16:49:40 +00001696 void (*xFunc)(sqlite3_context*,int,sqlite3_value**);
1697 } aFunc[] = {
drh52216ad2015-08-18 02:28:03 +00001698 { "json_array", -1, 0, jsonArrayFunc },
1699 { "json_array_length", 1, 0, jsonArrayLengthFunc },
1700 { "json_array_length", 2, 0, jsonArrayLengthFunc },
1701 { "json_extract", 2, 0, jsonExtractFunc },
1702 { "json_insert", -1, 0, jsonSetFunc },
1703 { "json_object", -1, 0, jsonObjectFunc },
1704 { "json_remove", -1, 0, jsonRemoveFunc },
1705 { "json_replace", -1, 0, jsonReplaceFunc },
1706 { "json_set", -1, 1, jsonSetFunc },
1707 { "json_type", 1, 0, jsonTypeFunc },
1708 { "json_type", 2, 0, jsonTypeFunc },
drh987eb1f2015-08-17 15:17:37 +00001709
drh301eecc2015-08-17 20:14:19 +00001710#if SQLITE_DEBUG
drh987eb1f2015-08-17 15:17:37 +00001711 /* DEBUG and TESTING functions */
drh52216ad2015-08-18 02:28:03 +00001712 { "json_parse", 1, 0, jsonParseFunc },
1713 { "json_test1", 1, 0, jsonTest1Func },
1714 { "json_nodecount", 1, 0, jsonNodeCountFunc },
drh301eecc2015-08-17 20:14:19 +00001715#endif
drh5fa5c102015-08-12 16:49:40 +00001716 };
drh505ad2c2015-08-21 17:33:11 +00001717 static const struct {
1718 const char *zName;
1719 sqlite3_module *pModule;
1720 } aMod[] = {
1721 { "json_each", &jsonEachModule },
1722 { "json_tree", &jsonTreeModule },
1723 };
drh5fa5c102015-08-12 16:49:40 +00001724 SQLITE_EXTENSION_INIT2(pApi);
1725 (void)pzErrMsg; /* Unused parameter */
1726 for(i=0; i<sizeof(aFunc)/sizeof(aFunc[0]) && rc==SQLITE_OK; i++){
1727 rc = sqlite3_create_function(db, aFunc[i].zName, aFunc[i].nArg,
drh52216ad2015-08-18 02:28:03 +00001728 SQLITE_UTF8 | SQLITE_DETERMINISTIC,
1729 (void*)&aFunc[i].flag,
drh5fa5c102015-08-12 16:49:40 +00001730 aFunc[i].xFunc, 0, 0);
1731 }
drh505ad2c2015-08-21 17:33:11 +00001732 for(i=0; i<sizeof(aMod)/sizeof(aMod[0]) && rc==SQLITE_OK; i++){
1733 rc = sqlite3_create_module(db, aMod[i].zName, aMod[i].pModule, 0);
drhcb6c6c62015-08-19 22:47:17 +00001734 }
drh5fa5c102015-08-12 16:49:40 +00001735 return rc;
1736}