blob: ea456bfeacb7617f22eb02e99d2505b9ee927181 [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 }
drhbe9474e2015-08-22 03:05:54 +0000590 if( pParse->oom ) return -1;
drhe9c37f32015-08-15 21:25:36 +0000591 if( pParse->aNode[pParse->nNode-1].eType!=JSON_STRING ) return -1;
592 j = x;
593 while( isspace(pParse->zJson[j]) ){ j++; }
594 if( pParse->zJson[j]!=':' ) return -1;
595 j++;
596 x = jsonParseValue(pParse, j);
597 if( x<0 ) return -1;
598 j = x;
599 while( isspace(pParse->zJson[j]) ){ j++; }
600 c = pParse->zJson[j];
601 if( c==',' ) continue;
602 if( c!='}' ) return -1;
603 break;
604 }
605 pParse->aNode[iThis].n = pParse->nNode - iThis - 1;
606 return j+1;
607 }else if( c=='[' ){
608 /* Parse array */
609 iThis = jsonParseAddNode(pParse, JSON_ARRAY, 0, 0);
drhe9c37f32015-08-15 21:25:36 +0000610 for(j=i+1;;j++){
611 while( isspace(pParse->zJson[j]) ){ j++; }
612 x = jsonParseValue(pParse, j);
613 if( x<0 ){
614 if( x==(-3) && pParse->nNode==iThis+1 ) return j+1;
615 return -1;
616 }
617 j = x;
618 while( isspace(pParse->zJson[j]) ){ j++; }
619 c = pParse->zJson[j];
620 if( c==',' ) continue;
621 if( c!=']' ) return -1;
622 break;
623 }
624 pParse->aNode[iThis].n = pParse->nNode - iThis - 1;
625 return j+1;
626 }else if( c=='"' ){
627 /* Parse string */
drh301eecc2015-08-17 20:14:19 +0000628 u8 jnFlags = 0;
drhe9c37f32015-08-15 21:25:36 +0000629 j = i+1;
630 for(;;){
631 c = pParse->zJson[j];
632 if( c==0 ) return -1;
633 if( c=='\\' ){
634 c = pParse->zJson[++j];
635 if( c==0 ) return -1;
drh301eecc2015-08-17 20:14:19 +0000636 jnFlags = JNODE_ESCAPE;
drhe9c37f32015-08-15 21:25:36 +0000637 }else if( c=='"' ){
638 break;
639 }
640 j++;
641 }
642 jsonParseAddNode(pParse, JSON_STRING, j+1-i, &pParse->zJson[i]);
drhbe9474e2015-08-22 03:05:54 +0000643 if( !pParse->oom ) pParse->aNode[pParse->nNode-1].jnFlags = jnFlags;
drhe9c37f32015-08-15 21:25:36 +0000644 return j+1;
645 }else if( c=='n'
646 && strncmp(pParse->zJson+i,"null",4)==0
drhb2cd10e2015-08-15 21:29:14 +0000647 && !isalnum(pParse->zJson[i+4]) ){
drhe9c37f32015-08-15 21:25:36 +0000648 jsonParseAddNode(pParse, JSON_NULL, 0, 0);
649 return i+4;
650 }else if( c=='t'
651 && strncmp(pParse->zJson+i,"true",4)==0
drhb2cd10e2015-08-15 21:29:14 +0000652 && !isalnum(pParse->zJson[i+4]) ){
drhe9c37f32015-08-15 21:25:36 +0000653 jsonParseAddNode(pParse, JSON_TRUE, 0, 0);
654 return i+4;
655 }else if( c=='f'
656 && strncmp(pParse->zJson+i,"false",5)==0
drhb2cd10e2015-08-15 21:29:14 +0000657 && !isalnum(pParse->zJson[i+5]) ){
drhe9c37f32015-08-15 21:25:36 +0000658 jsonParseAddNode(pParse, JSON_FALSE, 0, 0);
659 return i+5;
660 }else if( c=='-' || (c>='0' && c<='9') ){
661 /* Parse number */
662 u8 seenDP = 0;
663 u8 seenE = 0;
664 j = i+1;
665 for(;; j++){
666 c = pParse->zJson[j];
667 if( c>='0' && c<='9' ) continue;
668 if( c=='.' ){
669 if( pParse->zJson[j-1]=='-' ) return -1;
670 if( seenDP ) return -1;
671 seenDP = 1;
672 continue;
673 }
674 if( c=='e' || c=='E' ){
675 if( pParse->zJson[j-1]<'0' ) return -1;
676 if( seenE ) return -1;
677 seenDP = seenE = 1;
678 c = pParse->zJson[j+1];
679 if( c=='+' || c=='-' ) j++;
680 continue;
681 }
682 break;
683 }
684 if( pParse->zJson[j-1]<'0' ) return -1;
685 jsonParseAddNode(pParse, seenDP ? JSON_REAL : JSON_INT,
686 j - i, &pParse->zJson[i]);
687 return j;
688 }else if( c=='}' ){
689 return -2; /* End of {...} */
690 }else if( c==']' ){
691 return -3; /* End of [...] */
692 }else{
693 return -1; /* Syntax error */
694 }
695}
696
697/*
698** Parse a complete JSON string. Return 0 on success or non-zero if there
699** are any errors. If an error occurs, free all memory associated with
700** pParse.
701**
702** pParse is uninitialized when this routine is called.
703*/
704static int jsonParse(JsonParse *pParse, const char *zJson){
705 int i;
706 if( zJson==0 ) return 1;
707 memset(pParse, 0, sizeof(*pParse));
708 pParse->zJson = zJson;
709 i = jsonParseValue(pParse, 0);
710 if( i>0 ){
711 while( isspace(zJson[i]) ) i++;
712 if( zJson[i] ) i = -1;
713 }
714 if( i<0 ){
drh505ad2c2015-08-21 17:33:11 +0000715 jsonParseReset(pParse);
drhe9c37f32015-08-15 21:25:36 +0000716 return 1;
717 }
718 return 0;
719}
drh301eecc2015-08-17 20:14:19 +0000720
drh505ad2c2015-08-21 17:33:11 +0000721/* Mark node i of pParse as being a child of iParent. Call recursively
722** to fill in all the descendants of node i.
723*/
724static void jsonParseFillInParentage(JsonParse *pParse, u32 i, u32 iParent){
725 JsonNode *pNode = &pParse->aNode[i];
726 u32 j;
727 pParse->aUp[i] = iParent;
728 switch( pNode->eType ){
729 case JSON_ARRAY: {
730 for(j=1; j<=pNode->n; j += jsonNodeSize(pNode+j)){
731 jsonParseFillInParentage(pParse, i+j, i);
732 }
733 break;
734 }
735 case JSON_OBJECT: {
736 for(j=1; j<=pNode->n; j += jsonNodeSize(pNode+j+1)+1){
737 pParse->aUp[i+j] = i;
738 jsonParseFillInParentage(pParse, i+j+1, i);
739 }
740 break;
741 }
742 default: {
743 break;
744 }
745 }
746}
747
748/*
749** Compute the parentage of all nodes in a completed parse.
750*/
751static int jsonParseFindParents(JsonParse *pParse){
752 u32 *aUp;
753 assert( pParse->aUp==0 );
754 aUp = pParse->aUp = sqlite3_malloc( sizeof(u32)*pParse->nNode );
755 if( aUp==0 ) return SQLITE_NOMEM;
756 jsonParseFillInParentage(pParse, 0, 0);
757 return SQLITE_OK;
758}
759
drh52216ad2015-08-18 02:28:03 +0000760/* forward declaration */
761static JsonNode *jsonLookupAppend(JsonParse*,const char*,int*);
762
drh987eb1f2015-08-17 15:17:37 +0000763/*
764** Search along zPath to find the node specified. Return a pointer
765** to that node, or NULL if zPath is malformed or if there is no such
766** node.
drh52216ad2015-08-18 02:28:03 +0000767**
768** If pApnd!=0, then try to append new nodes to complete zPath if it is
769** possible to do so and if no existing node corresponds to zPath. If
770** new nodes are appended *pApnd is set to 1.
drh987eb1f2015-08-17 15:17:37 +0000771*/
drh52216ad2015-08-18 02:28:03 +0000772static JsonNode *jsonLookup(
773 JsonParse *pParse, /* The JSON to search */
774 u32 iRoot, /* Begin the search at this node */
775 const char *zPath, /* The path to search */
776 int *pApnd /* Append nodes to complete path if not NULL */
777){
drh6b43cc82015-08-19 23:02:49 +0000778 u32 i, j, k, nKey;
779 const char *zKey;
drh52216ad2015-08-18 02:28:03 +0000780 JsonNode *pRoot = &pParse->aNode[iRoot];
drh987eb1f2015-08-17 15:17:37 +0000781 if( zPath[0]==0 ) return pRoot;
782 if( zPath[0]=='.' ){
783 if( pRoot->eType!=JSON_OBJECT ) return 0;
784 zPath++;
drh6b43cc82015-08-19 23:02:49 +0000785 if( zPath[0]=='"' ){
786 zKey = zPath + 1;
787 for(i=1; zPath[i] && zPath[i]!='"'; i++){}
788 nKey = i-1;
789 if( zPath[i] ) i++;
790 }else{
791 zKey = zPath;
792 for(i=0; zPath[i] && zPath[i]!='.' && zPath[i]!='['; i++){}
793 nKey = i;
794 }
795 if( nKey==0 ) return 0;
drh987eb1f2015-08-17 15:17:37 +0000796 j = 1;
drh52216ad2015-08-18 02:28:03 +0000797 for(;;){
798 while( j<=pRoot->n ){
drh6b43cc82015-08-19 23:02:49 +0000799 if( pRoot[j].n==nKey+2
800 && strncmp(&pRoot[j].u.zJContent[1],zKey,nKey)==0
drh52216ad2015-08-18 02:28:03 +0000801 ){
802 return jsonLookup(pParse, iRoot+j+1, &zPath[i], pApnd);
803 }
804 j++;
drh505ad2c2015-08-21 17:33:11 +0000805 j += jsonNodeSize(&pRoot[j]);
drh987eb1f2015-08-17 15:17:37 +0000806 }
drh52216ad2015-08-18 02:28:03 +0000807 if( (pRoot->jnFlags & JNODE_APPEND)==0 ) break;
808 iRoot += pRoot->u.iAppend;
809 pRoot = &pParse->aNode[iRoot];
810 j = 1;
811 }
812 if( pApnd ){
813 k = jsonParseAddNode(pParse, JSON_OBJECT, 2, 0);
814 pRoot->u.iAppend = k - iRoot;
815 pRoot->jnFlags |= JNODE_APPEND;
816 k = jsonParseAddNode(pParse, JSON_STRING, i, zPath);
817 if( !pParse->oom ) pParse->aNode[k].jnFlags |= JNODE_RAW;
818 zPath += i;
819 return jsonLookupAppend(pParse, zPath, pApnd);
drh987eb1f2015-08-17 15:17:37 +0000820 }
821 }else if( zPath[0]=='[' && isdigit(zPath[1]) ){
822 if( pRoot->eType!=JSON_ARRAY ) return 0;
823 i = 0;
824 zPath++;
825 while( isdigit(zPath[0]) ){
826 i = i + zPath[0] - '0';
827 zPath++;
828 }
829 if( zPath[0]!=']' ) return 0;
830 zPath++;
831 j = 1;
drh52216ad2015-08-18 02:28:03 +0000832 for(;;){
833 while( i>0 && j<=pRoot->n ){
drh505ad2c2015-08-21 17:33:11 +0000834 j += jsonNodeSize(&pRoot[j]);
drh52216ad2015-08-18 02:28:03 +0000835 i--;
836 }
837 if( (pRoot->jnFlags & JNODE_APPEND)==0 ) break;
838 iRoot += pRoot->u.iAppend;
839 pRoot = &pParse->aNode[iRoot];
840 j = 1;
drh987eb1f2015-08-17 15:17:37 +0000841 }
842 if( j<=pRoot->n ){
drh52216ad2015-08-18 02:28:03 +0000843 return jsonLookup(pParse, iRoot+j, zPath, pApnd);
844 }
845 if( i==0 && pApnd ){
846 k = jsonParseAddNode(pParse, JSON_ARRAY, 1, 0);
847 pRoot->u.iAppend = k - iRoot;
848 pRoot->jnFlags |= JNODE_APPEND;
849 return jsonLookupAppend(pParse, zPath, pApnd);
drh987eb1f2015-08-17 15:17:37 +0000850 }
851 }
852 return 0;
853}
854
drh52216ad2015-08-18 02:28:03 +0000855/*
856** Append content to pParse that will complete zPath.
857*/
858static JsonNode *jsonLookupAppend(
859 JsonParse *pParse, /* Append content to the JSON parse */
860 const char *zPath, /* Description of content to append */
861 int *pApnd /* Set this flag to 1 */
862){
863 *pApnd = 1;
864 if( zPath[0]==0 ){
865 jsonParseAddNode(pParse, JSON_NULL, 0, 0);
866 return pParse->oom ? 0 : &pParse->aNode[pParse->nNode-1];
867 }
868 if( zPath[0]=='.' ){
869 jsonParseAddNode(pParse, JSON_OBJECT, 0, 0);
870 }else if( strncmp(zPath,"[0]",3)==0 ){
871 jsonParseAddNode(pParse, JSON_ARRAY, 0, 0);
872 }else{
873 return 0;
874 }
875 if( pParse->oom ) return 0;
876 return jsonLookup(pParse, pParse->nNode-1, zPath, pApnd);
877}
878
879
drh987eb1f2015-08-17 15:17:37 +0000880/****************************************************************************
881** SQL functions used for testing and debugging
882****************************************************************************/
drhe9c37f32015-08-15 21:25:36 +0000883
drh301eecc2015-08-17 20:14:19 +0000884#ifdef SQLITE_DEBUG
drhe9c37f32015-08-15 21:25:36 +0000885/*
drh5634cc02015-08-17 11:28:03 +0000886** The json_parse(JSON) function returns a string which describes
drhe9c37f32015-08-15 21:25:36 +0000887** a parse of the JSON provided. Or it returns NULL if JSON is not
888** well-formed.
889*/
drh5634cc02015-08-17 11:28:03 +0000890static void jsonParseFunc(
drhe9c37f32015-08-15 21:25:36 +0000891 sqlite3_context *context,
892 int argc,
893 sqlite3_value **argv
894){
drh505ad2c2015-08-21 17:33:11 +0000895 JsonString s; /* Output string - not real JSON */
896 JsonParse x; /* The parse */
drhe9c37f32015-08-15 21:25:36 +0000897 u32 i;
drh301eecc2015-08-17 20:14:19 +0000898 char zBuf[100];
drhe9c37f32015-08-15 21:25:36 +0000899
900 assert( argc==1 );
901 if( jsonParse(&x, (const char*)sqlite3_value_text(argv[0])) ) return;
902 jsonInit(&s, context);
903 for(i=0; i<x.nNode; i++){
drh301eecc2015-08-17 20:14:19 +0000904 sqlite3_snprintf(sizeof(zBuf), zBuf, "node %3u: %7s n=%d\n",
905 i, jsonType[x.aNode[i].eType], x.aNode[i].n);
drhe9c37f32015-08-15 21:25:36 +0000906 jsonAppend(&s, zBuf);
drh52216ad2015-08-18 02:28:03 +0000907 if( x.aNode[i].u.zJContent!=0 ){
drh301eecc2015-08-17 20:14:19 +0000908 jsonAppendRaw(&s, " text: ", 10);
drh52216ad2015-08-18 02:28:03 +0000909 jsonAppendRaw(&s, x.aNode[i].u.zJContent, x.aNode[i].n);
drhe9c37f32015-08-15 21:25:36 +0000910 jsonAppendRaw(&s, "\n", 1);
911 }
912 }
drh505ad2c2015-08-21 17:33:11 +0000913 jsonParseReset(&x);
drhe9c37f32015-08-15 21:25:36 +0000914 jsonResult(&s);
915}
916
drh5634cc02015-08-17 11:28:03 +0000917/*
918** The json_test1(JSON) function parses and rebuilds the JSON string.
919*/
920static void jsonTest1Func(
921 sqlite3_context *context,
922 int argc,
923 sqlite3_value **argv
924){
925 JsonParse x; /* The parse */
926 if( jsonParse(&x, (const char*)sqlite3_value_text(argv[0])) ) return;
drhd0960592015-08-17 21:22:32 +0000927 jsonReturn(x.aNode, context, 0);
drh505ad2c2015-08-21 17:33:11 +0000928 jsonParseReset(&x);
drh5634cc02015-08-17 11:28:03 +0000929}
930
931/*
932** The json_nodecount(JSON) function returns the number of nodes in the
933** input JSON string.
934*/
935static void jsonNodeCountFunc(
936 sqlite3_context *context,
937 int argc,
938 sqlite3_value **argv
939){
940 JsonParse x; /* The parse */
941 if( jsonParse(&x, (const char*)sqlite3_value_text(argv[0])) ) return;
drh6fd5c1e2015-08-21 20:37:12 +0000942 sqlite3_result_int64(context, (sqlite3_int64)x.nNode);
drh505ad2c2015-08-21 17:33:11 +0000943 jsonParseReset(&x);
drh5634cc02015-08-17 11:28:03 +0000944}
drh301eecc2015-08-17 20:14:19 +0000945#endif /* SQLITE_DEBUG */
drh5634cc02015-08-17 11:28:03 +0000946
drh987eb1f2015-08-17 15:17:37 +0000947/****************************************************************************
948** SQL function implementations
949****************************************************************************/
950
951/*
952** Implementation of the json_array(VALUE,...) function. Return a JSON
953** array that contains all values given in arguments. Or if any argument
954** is a BLOB, throw an error.
955*/
956static void jsonArrayFunc(
957 sqlite3_context *context,
958 int argc,
959 sqlite3_value **argv
960){
961 int i;
drh505ad2c2015-08-21 17:33:11 +0000962 JsonString jx;
drh987eb1f2015-08-17 15:17:37 +0000963
964 jsonInit(&jx, context);
drhd0960592015-08-17 21:22:32 +0000965 jsonAppendChar(&jx, '[');
drh987eb1f2015-08-17 15:17:37 +0000966 for(i=0; i<argc; i++){
drhd0960592015-08-17 21:22:32 +0000967 jsonAppendSeparator(&jx);
968 jsonAppendValue(&jx, argv[i]);
drh987eb1f2015-08-17 15:17:37 +0000969 }
drhd0960592015-08-17 21:22:32 +0000970 jsonAppendChar(&jx, ']');
drh987eb1f2015-08-17 15:17:37 +0000971 jsonResult(&jx);
972}
973
974
975/*
976** json_array_length(JSON)
977** json_array_length(JSON, PATH)
978**
979** Return the number of elements in the top-level JSON array.
980** Return 0 if the input is not a well-formed JSON array.
981*/
982static void jsonArrayLengthFunc(
983 sqlite3_context *context,
984 int argc,
985 sqlite3_value **argv
986){
987 JsonParse x; /* The parse */
988 sqlite3_int64 n = 0;
989 u32 i;
990 const char *zPath;
991
992 if( argc==2 ){
993 zPath = (const char*)sqlite3_value_text(argv[1]);
994 if( zPath==0 ) return;
995 if( zPath[0]!='$' ) return;
996 zPath++;
997 }else{
998 zPath = 0;
999 }
1000 if( jsonParse(&x, (const char*)sqlite3_value_text(argv[0]))==0 ){
1001 if( x.nNode ){
1002 JsonNode *pNode = x.aNode;
drh52216ad2015-08-18 02:28:03 +00001003 if( zPath ) pNode = jsonLookup(&x, 0, zPath, 0);
drh987eb1f2015-08-17 15:17:37 +00001004 if( pNode->eType==JSON_ARRAY ){
drh52216ad2015-08-18 02:28:03 +00001005 assert( (pNode->jnFlags & JNODE_APPEND)==0 );
drh301eecc2015-08-17 20:14:19 +00001006 for(i=1; i<=pNode->n; n++){
drh505ad2c2015-08-21 17:33:11 +00001007 i += jsonNodeSize(&pNode[i]);
drh987eb1f2015-08-17 15:17:37 +00001008 }
1009 }
1010 }
drh505ad2c2015-08-21 17:33:11 +00001011 jsonParseReset(&x);
drh987eb1f2015-08-17 15:17:37 +00001012 }
1013 sqlite3_result_int64(context, n);
1014}
1015
1016/*
1017** json_extract(JSON, PATH)
1018**
1019** Return the element described by PATH. Return NULL if JSON is not
1020** valid JSON or if there is no PATH element or if PATH is malformed.
1021*/
1022static void jsonExtractFunc(
1023 sqlite3_context *context,
1024 int argc,
1025 sqlite3_value **argv
1026){
1027 JsonParse x; /* The parse */
1028 JsonNode *pNode;
1029 const char *zPath;
1030 assert( argc==2 );
1031 zPath = (const char*)sqlite3_value_text(argv[1]);
1032 if( zPath==0 ) return;
1033 if( zPath[0]!='$' ) return;
1034 zPath++;
1035 if( jsonParse(&x, (const char*)sqlite3_value_text(argv[0])) ) return;
drh52216ad2015-08-18 02:28:03 +00001036 pNode = jsonLookup(&x, 0, zPath, 0);
drh987eb1f2015-08-17 15:17:37 +00001037 if( pNode ){
drhd0960592015-08-17 21:22:32 +00001038 jsonReturn(pNode, context, 0);
drh987eb1f2015-08-17 15:17:37 +00001039 }
drh505ad2c2015-08-21 17:33:11 +00001040 jsonParseReset(&x);
drh987eb1f2015-08-17 15:17:37 +00001041}
1042
1043/*
1044** Implementation of the json_object(NAME,VALUE,...) function. Return a JSON
1045** object that contains all name/value given in arguments. Or if any name
1046** is not a string or if any value is a BLOB, throw an error.
1047*/
1048static void jsonObjectFunc(
1049 sqlite3_context *context,
1050 int argc,
1051 sqlite3_value **argv
1052){
1053 int i;
drh505ad2c2015-08-21 17:33:11 +00001054 JsonString jx;
drh987eb1f2015-08-17 15:17:37 +00001055 const char *z;
1056 u32 n;
1057
1058 if( argc&1 ){
1059 sqlite3_result_error(context, "json_object() requires an even number "
1060 "of arguments", -1);
1061 return;
1062 }
1063 jsonInit(&jx, context);
drhd0960592015-08-17 21:22:32 +00001064 jsonAppendChar(&jx, '{');
drh987eb1f2015-08-17 15:17:37 +00001065 for(i=0; i<argc; i+=2){
drh987eb1f2015-08-17 15:17:37 +00001066 if( sqlite3_value_type(argv[i])!=SQLITE_TEXT ){
1067 sqlite3_result_error(context, "json_object() labels must be TEXT", -1);
1068 jsonZero(&jx);
1069 return;
1070 }
drhd0960592015-08-17 21:22:32 +00001071 jsonAppendSeparator(&jx);
drh987eb1f2015-08-17 15:17:37 +00001072 z = (const char*)sqlite3_value_text(argv[i]);
1073 n = (u32)sqlite3_value_bytes(argv[i]);
1074 jsonAppendString(&jx, z, n);
drhd0960592015-08-17 21:22:32 +00001075 jsonAppendChar(&jx, ':');
1076 jsonAppendValue(&jx, argv[i+1]);
drh987eb1f2015-08-17 15:17:37 +00001077 }
drhd0960592015-08-17 21:22:32 +00001078 jsonAppendChar(&jx, '}');
drh987eb1f2015-08-17 15:17:37 +00001079 jsonResult(&jx);
1080}
1081
1082
1083/*
drh301eecc2015-08-17 20:14:19 +00001084** json_remove(JSON, PATH, ...)
1085**
1086** Remove the named elements from JSON and return the result. Ill-formed
1087** PATH arguments are silently ignored. If JSON is ill-formed, then NULL
1088** is returned.
1089*/
1090static void jsonRemoveFunc(
1091 sqlite3_context *context,
1092 int argc,
1093 sqlite3_value **argv
1094){
1095 JsonParse x; /* The parse */
1096 JsonNode *pNode;
1097 const char *zPath;
1098 u32 i;
1099
1100 if( argc<1 ) return;
1101 if( jsonParse(&x, (const char*)sqlite3_value_text(argv[0])) ) return;
1102 if( x.nNode ){
drh6fd5c1e2015-08-21 20:37:12 +00001103 for(i=1; i<(u32)argc; i++){
drh301eecc2015-08-17 20:14:19 +00001104 zPath = (const char*)sqlite3_value_text(argv[i]);
1105 if( zPath==0 ) continue;
1106 if( zPath[0]!='$' ) continue;
drh52216ad2015-08-18 02:28:03 +00001107 pNode = jsonLookup(&x, 0, &zPath[1], 0);
drh301eecc2015-08-17 20:14:19 +00001108 if( pNode ) pNode->jnFlags |= JNODE_REMOVE;
1109 }
1110 if( (x.aNode[0].jnFlags & JNODE_REMOVE)==0 ){
drhd0960592015-08-17 21:22:32 +00001111 jsonReturn(x.aNode, context, 0);
1112 }
1113 }
drh505ad2c2015-08-21 17:33:11 +00001114 jsonParseReset(&x);
drhd0960592015-08-17 21:22:32 +00001115}
1116
1117/*
1118** json_replace(JSON, PATH, VALUE, ...)
1119**
1120** Replace the value at PATH with VALUE. If PATH does not already exist,
1121** this routine is a no-op. If JSON is ill-formed, return NULL.
1122*/
1123static void jsonReplaceFunc(
1124 sqlite3_context *context,
1125 int argc,
1126 sqlite3_value **argv
1127){
1128 JsonParse x; /* The parse */
1129 JsonNode *pNode;
1130 const char *zPath;
1131 u32 i;
1132
1133 if( argc<1 ) return;
1134 if( (argc&1)==0 ) {
1135 sqlite3_result_error(context,
1136 "json_replace() needs an odd number of arguments", -1);
1137 return;
1138 }
1139 if( jsonParse(&x, (const char*)sqlite3_value_text(argv[0])) ) return;
1140 if( x.nNode ){
drh6fd5c1e2015-08-21 20:37:12 +00001141 for(i=1; i<(u32)argc; i+=2){
drhd0960592015-08-17 21:22:32 +00001142 zPath = (const char*)sqlite3_value_text(argv[i]);
1143 if( zPath==0 ) continue;
1144 if( zPath[0]!='$' ) continue;
drh52216ad2015-08-18 02:28:03 +00001145 pNode = jsonLookup(&x, 0, &zPath[1], 0);
drhd0960592015-08-17 21:22:32 +00001146 if( pNode ){
1147 pNode->jnFlags |= JNODE_REPLACE;
1148 pNode->iVal = i+1;
1149 }
1150 }
1151 if( x.aNode[0].jnFlags & JNODE_REPLACE ){
1152 sqlite3_result_value(context, argv[x.aNode[0].iVal]);
1153 }else{
1154 jsonReturn(x.aNode, context, argv);
drh301eecc2015-08-17 20:14:19 +00001155 }
1156 }
drh505ad2c2015-08-21 17:33:11 +00001157 jsonParseReset(&x);
drh301eecc2015-08-17 20:14:19 +00001158}
drh505ad2c2015-08-21 17:33:11 +00001159
drh52216ad2015-08-18 02:28:03 +00001160/*
1161** json_set(JSON, PATH, VALUE, ...)
1162**
1163** Set the value at PATH to VALUE. Create the PATH if it does not already
1164** exist. Overwrite existing values that do exist.
1165** If JSON is ill-formed, return NULL.
1166**
1167** json_insert(JSON, PATH, VALUE, ...)
1168**
1169** Create PATH and initialize it to VALUE. If PATH already exists, this
1170** routine is a no-op. If JSON is ill-formed, return NULL.
1171*/
1172static void jsonSetFunc(
1173 sqlite3_context *context,
1174 int argc,
1175 sqlite3_value **argv
1176){
1177 JsonParse x; /* The parse */
1178 JsonNode *pNode;
1179 const char *zPath;
1180 u32 i;
1181 int bApnd;
1182 int bIsSet = *(int*)sqlite3_user_data(context);
1183
1184 if( argc<1 ) return;
1185 if( (argc&1)==0 ) {
1186 sqlite3_result_error(context,
1187 "json_set() needs an odd number of arguments", -1);
1188 return;
1189 }
1190 if( jsonParse(&x, (const char*)sqlite3_value_text(argv[0])) ) return;
1191 if( x.nNode ){
drh6fd5c1e2015-08-21 20:37:12 +00001192 for(i=1; i<(u32)argc; i+=2){
drh52216ad2015-08-18 02:28:03 +00001193 zPath = (const char*)sqlite3_value_text(argv[i]);
1194 if( zPath==0 ) continue;
1195 if( zPath[0]!='$' ) continue;
1196 bApnd = 0;
1197 pNode = jsonLookup(&x, 0, &zPath[1], &bApnd);
1198 if( pNode && (bApnd || bIsSet) ){
1199 pNode->jnFlags |= JNODE_REPLACE;
1200 pNode->iVal = i+1;
1201 }
1202 }
1203 if( x.aNode[0].jnFlags & JNODE_REPLACE ){
1204 sqlite3_result_value(context, argv[x.aNode[0].iVal]);
1205 }else{
1206 jsonReturn(x.aNode, context, argv);
1207 }
1208 }
drh505ad2c2015-08-21 17:33:11 +00001209 jsonParseReset(&x);
drh52216ad2015-08-18 02:28:03 +00001210}
drh301eecc2015-08-17 20:14:19 +00001211
1212/*
drh987eb1f2015-08-17 15:17:37 +00001213** json_type(JSON)
1214** json_type(JSON, PATH)
1215**
1216** Return the top-level "type" of a JSON string. Return NULL if the
1217** input is not a well-formed JSON string.
1218*/
1219static void jsonTypeFunc(
1220 sqlite3_context *context,
1221 int argc,
1222 sqlite3_value **argv
1223){
1224 JsonParse x; /* The parse */
1225 const char *zPath;
1226
1227 if( argc==2 ){
1228 zPath = (const char*)sqlite3_value_text(argv[1]);
1229 if( zPath==0 ) return;
1230 if( zPath[0]!='$' ) return;
1231 zPath++;
1232 }else{
1233 zPath = 0;
1234 }
1235 if( jsonParse(&x, (const char*)sqlite3_value_text(argv[0])) ) return;
1236 if( x.nNode ){
1237 JsonNode *pNode = x.aNode;
drh52216ad2015-08-18 02:28:03 +00001238 if( zPath ) pNode = jsonLookup(&x, 0, zPath, 0);
drh987eb1f2015-08-17 15:17:37 +00001239 sqlite3_result_text(context, jsonType[pNode->eType], -1, SQLITE_STATIC);
1240 }
drh505ad2c2015-08-21 17:33:11 +00001241 jsonParseReset(&x);
drh987eb1f2015-08-17 15:17:37 +00001242}
drh5634cc02015-08-17 11:28:03 +00001243
drhcb6c6c62015-08-19 22:47:17 +00001244/****************************************************************************
1245** The json_each virtual table
1246****************************************************************************/
1247typedef struct JsonEachCursor JsonEachCursor;
1248struct JsonEachCursor {
1249 sqlite3_vtab_cursor base; /* Base class - must be first */
drh505ad2c2015-08-21 17:33:11 +00001250 u32 iRowid; /* The rowid */
1251 u32 i; /* Index in sParse.aNode[] of current row */
1252 u32 iEnd; /* EOF when i equals or exceeds this value */
1253 u8 eType; /* Type of top-level element */
1254 u8 bRecursive; /* True for json_tree(). False for json_each() */
1255 char *zJson; /* Input JSON */
1256 char *zPath; /* Path by which to filter zJson */
1257 JsonParse sParse; /* Parse of the input JSON */
drhcb6c6c62015-08-19 22:47:17 +00001258};
1259
1260/* Constructor for the json_each virtual table */
1261static int jsonEachConnect(
1262 sqlite3 *db,
1263 void *pAux,
1264 int argc, const char *const*argv,
1265 sqlite3_vtab **ppVtab,
1266 char **pzErr
1267){
1268 sqlite3_vtab *pNew;
drh505ad2c2015-08-21 17:33:11 +00001269 int rc;
drhcb6c6c62015-08-19 22:47:17 +00001270
1271/* Column numbers */
drh4af352d2015-08-21 20:02:48 +00001272#define JEACH_KEY 0
1273#define JEACH_VALUE 1
1274#define JEACH_TYPE 2
1275#define JEACH_ATOM 3
1276#define JEACH_ID 4
1277#define JEACH_PARENT 5
1278#define JEACH_FULLKEY 6
1279#define JEACH_JSON 7
1280#define JEACH_PATH 8
drhcb6c6c62015-08-19 22:47:17 +00001281
drh6fd5c1e2015-08-21 20:37:12 +00001282 UNUSED_PARAM(pzErr);
1283 UNUSED_PARAM(argv);
1284 UNUSED_PARAM(argc);
1285 UNUSED_PARAM(pAux);
drh505ad2c2015-08-21 17:33:11 +00001286 rc = sqlite3_declare_vtab(db,
drh4af352d2015-08-21 20:02:48 +00001287 "CREATE TABLE x(key,value,type,atom,id,parent,fullkey,"
1288 "json HIDDEN,path HIDDEN)");
drh505ad2c2015-08-21 17:33:11 +00001289 if( rc==SQLITE_OK ){
1290 pNew = *ppVtab = sqlite3_malloc( sizeof(*pNew) );
1291 if( pNew==0 ) return SQLITE_NOMEM;
1292 memset(pNew, 0, sizeof(*pNew));
1293 }
1294 return rc;
drhcb6c6c62015-08-19 22:47:17 +00001295}
1296
1297/* destructor for json_each virtual table */
1298static int jsonEachDisconnect(sqlite3_vtab *pVtab){
1299 sqlite3_free(pVtab);
1300 return SQLITE_OK;
1301}
1302
drh505ad2c2015-08-21 17:33:11 +00001303/* constructor for a JsonEachCursor object for json_each(). */
1304static int jsonEachOpenEach(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
drhcb6c6c62015-08-19 22:47:17 +00001305 JsonEachCursor *pCur;
drh6fd5c1e2015-08-21 20:37:12 +00001306
1307 UNUSED_PARAM(p);
drhcb6c6c62015-08-19 22:47:17 +00001308 pCur = sqlite3_malloc( sizeof(*pCur) );
1309 if( pCur==0 ) return SQLITE_NOMEM;
1310 memset(pCur, 0, sizeof(*pCur));
1311 *ppCursor = &pCur->base;
1312 return SQLITE_OK;
1313}
1314
drh505ad2c2015-08-21 17:33:11 +00001315/* constructor for a JsonEachCursor object for json_tree(). */
1316static int jsonEachOpenTree(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
1317 int rc = jsonEachOpenEach(p, ppCursor);
1318 if( rc==SQLITE_OK ){
1319 JsonEachCursor *pCur = (JsonEachCursor*)*ppCursor;
1320 pCur->bRecursive = 1;
1321 }
1322 return rc;
1323}
1324
drhcb6c6c62015-08-19 22:47:17 +00001325/* Reset a JsonEachCursor back to its original state. Free any memory
1326** held. */
1327static void jsonEachCursorReset(JsonEachCursor *p){
1328 sqlite3_free(p->zJson);
1329 sqlite3_free(p->zPath);
drh505ad2c2015-08-21 17:33:11 +00001330 jsonParseReset(&p->sParse);
drhcb6c6c62015-08-19 22:47:17 +00001331 p->iRowid = 0;
1332 p->i = 0;
1333 p->iEnd = 0;
1334 p->eType = 0;
drhcb6c6c62015-08-19 22:47:17 +00001335 p->zJson = 0;
1336 p->zPath = 0;
1337}
1338
1339/* Destructor for a jsonEachCursor object */
1340static int jsonEachClose(sqlite3_vtab_cursor *cur){
1341 JsonEachCursor *p = (JsonEachCursor*)cur;
1342 jsonEachCursorReset(p);
1343 sqlite3_free(cur);
1344 return SQLITE_OK;
1345}
1346
1347/* Return TRUE if the jsonEachCursor object has been advanced off the end
1348** of the JSON object */
1349static int jsonEachEof(sqlite3_vtab_cursor *cur){
1350 JsonEachCursor *p = (JsonEachCursor*)cur;
1351 return p->i >= p->iEnd;
1352}
1353
drh505ad2c2015-08-21 17:33:11 +00001354/* Advance the cursor to the next element for json_tree() */
drh4af352d2015-08-21 20:02:48 +00001355static int jsonEachNext(sqlite3_vtab_cursor *cur){
drh505ad2c2015-08-21 17:33:11 +00001356 JsonEachCursor *p = (JsonEachCursor*)cur;
drh4af352d2015-08-21 20:02:48 +00001357 if( p->bRecursive ){
1358 if( p->i==0 ){
1359 p->i = 1;
1360 }else if( p->sParse.aNode[p->sParse.aUp[p->i]].eType==JSON_OBJECT ){
1361 p->i += 2;
1362 }else{
1363 p->i++;
1364 }
1365 p->iRowid++;
1366 if( p->i<p->sParse.nNode ){
1367 JsonNode *pUp = &p->sParse.aNode[p->sParse.aUp[p->i]];
1368 p->eType = pUp->eType;
1369 if( pUp->eType==JSON_ARRAY ) pUp->u.iKey++;
1370 if( p->sParse.aNode[p->i].eType==JSON_ARRAY ){
1371 p->sParse.aNode[p->i].u.iKey = 0;
1372 }
1373 }
drh505ad2c2015-08-21 17:33:11 +00001374 }else{
drh4af352d2015-08-21 20:02:48 +00001375 switch( p->eType ){
1376 case JSON_ARRAY: {
1377 p->i += jsonNodeSize(&p->sParse.aNode[p->i]);
1378 p->iRowid++;
1379 break;
1380 }
1381 case JSON_OBJECT: {
1382 p->i += 1 + jsonNodeSize(&p->sParse.aNode[p->i+1]);
1383 p->iRowid++;
1384 break;
1385 }
1386 default: {
1387 p->i = p->iEnd;
1388 break;
1389 }
drh505ad2c2015-08-21 17:33:11 +00001390 }
1391 }
1392 return SQLITE_OK;
1393}
1394
drh4af352d2015-08-21 20:02:48 +00001395/* Append the name of the path for element i to pStr
1396*/
1397static void jsonEachComputePath(
1398 JsonEachCursor *p, /* The cursor */
1399 JsonString *pStr, /* Write the path here */
1400 u32 i /* Path to this element */
1401){
1402 JsonNode *pNode, *pUp;
1403 u32 iUp;
1404 if( i==0 ){
1405 jsonAppendChar(pStr, '$');
1406 return;
drhcb6c6c62015-08-19 22:47:17 +00001407 }
drh4af352d2015-08-21 20:02:48 +00001408 iUp = p->sParse.aUp[i];
1409 jsonEachComputePath(p, pStr, iUp);
1410 pNode = &p->sParse.aNode[i];
1411 pUp = &p->sParse.aNode[iUp];
1412 if( pUp->eType==JSON_ARRAY ){
1413 jsonPrintf(30, pStr, "[%d]", pUp->u.iKey);
1414 }else{
1415 assert( pUp->eType==JSON_OBJECT );
1416 if( pNode->eType>=JSON_ARRAY ) pNode--;
1417 assert( pNode->eType==JSON_STRING );
1418 jsonPrintf(pNode->n+1, pStr, ".%.*s", pNode->n-2, pNode->u.zJContent+1);
1419 }
drhcb6c6c62015-08-19 22:47:17 +00001420}
1421
1422/* Return the value of a column */
1423static int jsonEachColumn(
1424 sqlite3_vtab_cursor *cur, /* The cursor */
1425 sqlite3_context *ctx, /* First argument to sqlite3_result_...() */
1426 int i /* Which column to return */
1427){
1428 JsonEachCursor *p = (JsonEachCursor*)cur;
drh505ad2c2015-08-21 17:33:11 +00001429 JsonNode *pThis = &p->sParse.aNode[p->i];
drhcb6c6c62015-08-19 22:47:17 +00001430 switch( i ){
1431 case JEACH_KEY: {
1432 if( p->eType==JSON_OBJECT ){
drh505ad2c2015-08-21 17:33:11 +00001433 jsonReturn(pThis, ctx, 0);
1434 }else if( p->eType==JSON_ARRAY ){
1435 u32 iKey;
1436 if( p->bRecursive ){
1437 if( p->iRowid==0 ) break;
1438 iKey = p->sParse.aNode[p->sParse.aUp[p->i]].u.iKey - 1;
1439 }else{
1440 iKey = p->iRowid;
1441 }
drh6fd5c1e2015-08-21 20:37:12 +00001442 sqlite3_result_int64(ctx, (sqlite3_int64)iKey);
drhcb6c6c62015-08-19 22:47:17 +00001443 }
1444 break;
1445 }
1446 case JEACH_VALUE: {
drh505ad2c2015-08-21 17:33:11 +00001447 if( p->eType==JSON_OBJECT ) pThis++;
1448 jsonReturn(pThis, ctx, 0);
1449 break;
1450 }
1451 case JEACH_TYPE: {
1452 if( p->eType==JSON_OBJECT ) pThis++;
1453 sqlite3_result_text(ctx, jsonType[pThis->eType], -1, SQLITE_STATIC);
1454 break;
1455 }
1456 case JEACH_ATOM: {
1457 if( p->eType==JSON_OBJECT ) pThis++;
1458 if( pThis->eType>=JSON_ARRAY ) break;
1459 jsonReturn(pThis, ctx, 0);
1460 break;
1461 }
1462 case JEACH_ID: {
drh6fd5c1e2015-08-21 20:37:12 +00001463 sqlite3_result_int64(ctx, (sqlite3_int64)p->i + (p->eType==JSON_OBJECT));
drh505ad2c2015-08-21 17:33:11 +00001464 break;
1465 }
1466 case JEACH_PARENT: {
1467 if( p->i>0 && p->bRecursive ){
drh6fd5c1e2015-08-21 20:37:12 +00001468 sqlite3_result_int64(ctx, (sqlite3_int64)p->sParse.aUp[p->i]);
drhcb6c6c62015-08-19 22:47:17 +00001469 }
1470 break;
1471 }
drh4af352d2015-08-21 20:02:48 +00001472 case JEACH_FULLKEY: {
1473 JsonString x;
1474 jsonInit(&x, ctx);
1475 if( p->bRecursive ){
1476 jsonEachComputePath(p, &x, p->i);
1477 }else{
1478 if( p->zPath ){
1479 jsonAppendRaw(&x, p->zPath, (int)strlen(p->zPath));
1480 }else{
1481 jsonAppendChar(&x, '$');
1482 }
1483 if( p->eType==JSON_ARRAY ){
1484 jsonPrintf(30, &x, "[%d]", p->iRowid);
1485 }else{
1486 jsonPrintf(pThis->n, &x, ".%.*s", pThis->n-2, pThis->u.zJContent+1);
1487 }
1488 }
1489 jsonResult(&x);
1490 break;
1491 }
drhcb6c6c62015-08-19 22:47:17 +00001492 case JEACH_PATH: {
1493 const char *zPath = p->zPath;
drh4af352d2015-08-21 20:02:48 +00001494 if( zPath==0 ){
1495 if( p->bRecursive ){
1496 JsonString x;
1497 jsonInit(&x, ctx);
1498 jsonEachComputePath(p, &x, p->sParse.aUp[p->i]);
1499 jsonResult(&x);
1500 break;
1501 }
1502 zPath = "$";
1503 }
drhcb6c6c62015-08-19 22:47:17 +00001504 sqlite3_result_text(ctx, zPath, -1, SQLITE_STATIC);
1505 break;
1506 }
1507 default: {
drh505ad2c2015-08-21 17:33:11 +00001508 assert( i==JEACH_JSON );
drhcb6c6c62015-08-19 22:47:17 +00001509 sqlite3_result_text(ctx, p->sParse.zJson, -1, SQLITE_STATIC);
1510 break;
1511 }
1512 }
1513 return SQLITE_OK;
1514}
1515
1516/* Return the current rowid value */
1517static int jsonEachRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){
1518 JsonEachCursor *p = (JsonEachCursor*)cur;
1519 *pRowid = p->iRowid;
1520 return SQLITE_OK;
1521}
1522
1523/* The query strategy is to look for an equality constraint on the json
1524** column. Without such a constraint, the table cannot operate. idxNum is
1525** 1 if the constraint is found, 3 if the constraint and zPath are found,
1526** and 0 otherwise.
1527*/
1528static int jsonEachBestIndex(
1529 sqlite3_vtab *tab,
1530 sqlite3_index_info *pIdxInfo
1531){
1532 int i;
1533 int jsonIdx = -1;
1534 int pathIdx = -1;
1535 const struct sqlite3_index_constraint *pConstraint;
drh6fd5c1e2015-08-21 20:37:12 +00001536
1537 UNUSED_PARAM(tab);
drhcb6c6c62015-08-19 22:47:17 +00001538 pConstraint = pIdxInfo->aConstraint;
1539 for(i=0; i<pIdxInfo->nConstraint; i++, pConstraint++){
1540 if( pConstraint->usable==0 ) continue;
1541 if( pConstraint->op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue;
1542 switch( pConstraint->iColumn ){
1543 case JEACH_JSON: jsonIdx = i; break;
1544 case JEACH_PATH: pathIdx = i; break;
1545 default: /* no-op */ break;
1546 }
1547 }
1548 if( jsonIdx<0 ){
1549 pIdxInfo->idxNum = 0;
drh505ad2c2015-08-21 17:33:11 +00001550 pIdxInfo->estimatedCost = 1e99;
drhcb6c6c62015-08-19 22:47:17 +00001551 }else{
drh505ad2c2015-08-21 17:33:11 +00001552 pIdxInfo->estimatedCost = 1.0;
drhcb6c6c62015-08-19 22:47:17 +00001553 pIdxInfo->aConstraintUsage[jsonIdx].argvIndex = 1;
1554 pIdxInfo->aConstraintUsage[jsonIdx].omit = 1;
1555 if( pathIdx<0 ){
1556 pIdxInfo->idxNum = 1;
1557 }else{
1558 pIdxInfo->aConstraintUsage[pathIdx].argvIndex = 2;
1559 pIdxInfo->aConstraintUsage[pathIdx].omit = 1;
1560 pIdxInfo->idxNum = 3;
1561 }
1562 }
1563 return SQLITE_OK;
1564}
1565
1566/* Start a search on a new JSON string */
1567static int jsonEachFilter(
1568 sqlite3_vtab_cursor *cur,
1569 int idxNum, const char *idxStr,
1570 int argc, sqlite3_value **argv
1571){
1572 JsonEachCursor *p = (JsonEachCursor*)cur;
1573 const char *z;
1574 const char *zPath;
1575 sqlite3_int64 n;
1576
drh6fd5c1e2015-08-21 20:37:12 +00001577 UNUSED_PARAM(idxStr);
1578 UNUSED_PARAM(argc);
drhcb6c6c62015-08-19 22:47:17 +00001579 jsonEachCursorReset(p);
1580 if( idxNum==0 ) return SQLITE_OK;
1581 z = (const char*)sqlite3_value_text(argv[0]);
1582 if( z==0 ) return SQLITE_OK;
1583 if( idxNum&2 ){
1584 zPath = (const char*)sqlite3_value_text(argv[1]);
1585 if( zPath==0 || zPath[0]!='$' ) return SQLITE_OK;
1586 }
1587 n = sqlite3_value_bytes(argv[0]);
drh6fd5c1e2015-08-21 20:37:12 +00001588 p->zJson = sqlite3_malloc64( n+1 );
drhcb6c6c62015-08-19 22:47:17 +00001589 if( p->zJson==0 ) return SQLITE_NOMEM;
drh6fd5c1e2015-08-21 20:37:12 +00001590 memcpy(p->zJson, z, (size_t)n+1);
drh505ad2c2015-08-21 17:33:11 +00001591 if( jsonParse(&p->sParse, p->zJson)
1592 || (p->bRecursive && jsonParseFindParents(&p->sParse))
1593 ){
drhcb6c6c62015-08-19 22:47:17 +00001594 jsonEachCursorReset(p);
1595 }else{
1596 JsonNode *pNode;
1597 if( idxNum==3 ){
drh4af352d2015-08-21 20:02:48 +00001598 p->bRecursive = 0;
drhcb6c6c62015-08-19 22:47:17 +00001599 n = sqlite3_value_bytes(argv[1]);
drh6fd5c1e2015-08-21 20:37:12 +00001600 p->zPath = sqlite3_malloc64( n+1 );
drhcb6c6c62015-08-19 22:47:17 +00001601 if( p->zPath==0 ) return SQLITE_NOMEM;
drh6fd5c1e2015-08-21 20:37:12 +00001602 memcpy(p->zPath, zPath, (size_t)n+1);
drhcb6c6c62015-08-19 22:47:17 +00001603 pNode = jsonLookup(&p->sParse, 0, p->zPath+1, 0);
1604 if( pNode==0 ){
1605 jsonEachCursorReset(p);
1606 return SQLITE_OK;
1607 }
1608 }else{
1609 pNode = p->sParse.aNode;
1610 }
1611 p->i = (int)(pNode - p->sParse.aNode);
1612 p->eType = pNode->eType;
1613 if( p->eType>=JSON_ARRAY ){
1614 p->i++;
1615 p->iEnd = p->i + pNode->n;
1616 }else{
1617 p->iEnd = p->i+1;
1618 }
1619 }
1620 return SQLITE_OK;
1621}
1622
1623/* The methods of the json_each virtual table */
1624static sqlite3_module jsonEachModule = {
1625 0, /* iVersion */
1626 0, /* xCreate */
1627 jsonEachConnect, /* xConnect */
1628 jsonEachBestIndex, /* xBestIndex */
1629 jsonEachDisconnect, /* xDisconnect */
1630 0, /* xDestroy */
drh505ad2c2015-08-21 17:33:11 +00001631 jsonEachOpenEach, /* xOpen - open a cursor */
drhcb6c6c62015-08-19 22:47:17 +00001632 jsonEachClose, /* xClose - close a cursor */
1633 jsonEachFilter, /* xFilter - configure scan constraints */
drh4af352d2015-08-21 20:02:48 +00001634 jsonEachNext, /* xNext - advance a cursor */
drhcb6c6c62015-08-19 22:47:17 +00001635 jsonEachEof, /* xEof - check for end of scan */
1636 jsonEachColumn, /* xColumn - read data */
1637 jsonEachRowid, /* xRowid - read data */
1638 0, /* xUpdate */
1639 0, /* xBegin */
1640 0, /* xSync */
1641 0, /* xCommit */
1642 0, /* xRollback */
1643 0, /* xFindMethod */
1644 0, /* xRename */
drh6fd5c1e2015-08-21 20:37:12 +00001645 0, /* xSavepoint */
1646 0, /* xRelease */
1647 0 /* xRollbackTo */
drhcb6c6c62015-08-19 22:47:17 +00001648};
1649
drh505ad2c2015-08-21 17:33:11 +00001650/* The methods of the json_tree virtual table. */
1651static sqlite3_module jsonTreeModule = {
1652 0, /* iVersion */
1653 0, /* xCreate */
1654 jsonEachConnect, /* xConnect */
1655 jsonEachBestIndex, /* xBestIndex */
1656 jsonEachDisconnect, /* xDisconnect */
1657 0, /* xDestroy */
1658 jsonEachOpenTree, /* xOpen - open a cursor */
1659 jsonEachClose, /* xClose - close a cursor */
1660 jsonEachFilter, /* xFilter - configure scan constraints */
drh4af352d2015-08-21 20:02:48 +00001661 jsonEachNext, /* xNext - advance a cursor */
drh505ad2c2015-08-21 17:33:11 +00001662 jsonEachEof, /* xEof - check for end of scan */
1663 jsonEachColumn, /* xColumn - read data */
1664 jsonEachRowid, /* xRowid - read data */
1665 0, /* xUpdate */
1666 0, /* xBegin */
1667 0, /* xSync */
1668 0, /* xCommit */
1669 0, /* xRollback */
1670 0, /* xFindMethod */
1671 0, /* xRename */
drh6fd5c1e2015-08-21 20:37:12 +00001672 0, /* xSavepoint */
1673 0, /* xRelease */
1674 0 /* xRollbackTo */
drh505ad2c2015-08-21 17:33:11 +00001675};
1676
1677/****************************************************************************
1678** The following routine is the only publically visible identifier in this
1679** file. Call the following routine in order to register the various SQL
1680** functions and the virtual table implemented by this file.
1681****************************************************************************/
drhcb6c6c62015-08-19 22:47:17 +00001682
drh5fa5c102015-08-12 16:49:40 +00001683#ifdef _WIN32
1684__declspec(dllexport)
1685#endif
1686int sqlite3_json_init(
1687 sqlite3 *db,
1688 char **pzErrMsg,
1689 const sqlite3_api_routines *pApi
1690){
1691 int rc = SQLITE_OK;
drh6fd5c1e2015-08-21 20:37:12 +00001692 unsigned int i;
drh5fa5c102015-08-12 16:49:40 +00001693 static const struct {
1694 const char *zName;
1695 int nArg;
drh52216ad2015-08-18 02:28:03 +00001696 int flag;
drh5fa5c102015-08-12 16:49:40 +00001697 void (*xFunc)(sqlite3_context*,int,sqlite3_value**);
1698 } aFunc[] = {
drh52216ad2015-08-18 02:28:03 +00001699 { "json_array", -1, 0, jsonArrayFunc },
1700 { "json_array_length", 1, 0, jsonArrayLengthFunc },
1701 { "json_array_length", 2, 0, jsonArrayLengthFunc },
1702 { "json_extract", 2, 0, jsonExtractFunc },
1703 { "json_insert", -1, 0, jsonSetFunc },
1704 { "json_object", -1, 0, jsonObjectFunc },
1705 { "json_remove", -1, 0, jsonRemoveFunc },
1706 { "json_replace", -1, 0, jsonReplaceFunc },
1707 { "json_set", -1, 1, jsonSetFunc },
1708 { "json_type", 1, 0, jsonTypeFunc },
1709 { "json_type", 2, 0, jsonTypeFunc },
drh987eb1f2015-08-17 15:17:37 +00001710
drh301eecc2015-08-17 20:14:19 +00001711#if SQLITE_DEBUG
drh987eb1f2015-08-17 15:17:37 +00001712 /* DEBUG and TESTING functions */
drh52216ad2015-08-18 02:28:03 +00001713 { "json_parse", 1, 0, jsonParseFunc },
1714 { "json_test1", 1, 0, jsonTest1Func },
1715 { "json_nodecount", 1, 0, jsonNodeCountFunc },
drh301eecc2015-08-17 20:14:19 +00001716#endif
drh5fa5c102015-08-12 16:49:40 +00001717 };
drh505ad2c2015-08-21 17:33:11 +00001718 static const struct {
1719 const char *zName;
1720 sqlite3_module *pModule;
1721 } aMod[] = {
1722 { "json_each", &jsonEachModule },
1723 { "json_tree", &jsonTreeModule },
1724 };
drh5fa5c102015-08-12 16:49:40 +00001725 SQLITE_EXTENSION_INIT2(pApi);
1726 (void)pzErrMsg; /* Unused parameter */
1727 for(i=0; i<sizeof(aFunc)/sizeof(aFunc[0]) && rc==SQLITE_OK; i++){
1728 rc = sqlite3_create_function(db, aFunc[i].zName, aFunc[i].nArg,
drh52216ad2015-08-18 02:28:03 +00001729 SQLITE_UTF8 | SQLITE_DETERMINISTIC,
1730 (void*)&aFunc[i].flag,
drh5fa5c102015-08-12 16:49:40 +00001731 aFunc[i].xFunc, 0, 0);
1732 }
drh505ad2c2015-08-21 17:33:11 +00001733 for(i=0; i<sizeof(aMod)/sizeof(aMod[0]) && rc==SQLITE_OK; i++){
1734 rc = sqlite3_create_module(db, aMod[i].zName, aMod[i].pModule, 0);
drhcb6c6c62015-08-19 22:47:17 +00001735 }
drh5fa5c102015-08-12 16:49:40 +00001736 return rc;
1737}