blob: 72ba33be0f457867d4ba6c329196b24bcc0c6572 [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 */
drhecb5fed2015-08-28 03:33:50 +000083#define JNODE_JSON 0x20 /* Treat REPLACE as JSON text */
drh301eecc2015-08-17 20:14:19 +000084
drh987eb1f2015-08-17 15:17:37 +000085
drhe9c37f32015-08-15 21:25:36 +000086/* A single node of parsed JSON
87*/
drhe9c37f32015-08-15 21:25:36 +000088struct JsonNode {
drh5634cc02015-08-17 11:28:03 +000089 u8 eType; /* One of the JSON_ type values */
drh301eecc2015-08-17 20:14:19 +000090 u8 jnFlags; /* JNODE flags */
drhd0960592015-08-17 21:22:32 +000091 u8 iVal; /* Replacement value when JNODE_REPLACE */
drhe9c37f32015-08-15 21:25:36 +000092 u32 n; /* Bytes of content, or number of sub-nodes */
drh52216ad2015-08-18 02:28:03 +000093 union {
drh0042a972015-08-18 12:59:58 +000094 const char *zJContent; /* Content for INT, REAL, and STRING */
95 u32 iAppend; /* More terms for ARRAY and OBJECT */
drh505ad2c2015-08-21 17:33:11 +000096 u32 iKey; /* Key for ARRAY objects in json_tree() */
drh52216ad2015-08-18 02:28:03 +000097 } u;
drhe9c37f32015-08-15 21:25:36 +000098};
99
100/* A completely parsed JSON string
101*/
drhe9c37f32015-08-15 21:25:36 +0000102struct JsonParse {
103 u32 nNode; /* Number of slots of aNode[] used */
104 u32 nAlloc; /* Number of slots of aNode[] allocated */
105 JsonNode *aNode; /* Array of nodes containing the parse */
106 const char *zJson; /* Original JSON string */
drh505ad2c2015-08-21 17:33:11 +0000107 u32 *aUp; /* Index of parent of each node */
drhe9c37f32015-08-15 21:25:36 +0000108 u8 oom; /* Set to true if out of memory */
109};
110
drh505ad2c2015-08-21 17:33:11 +0000111/**************************************************************************
112** Utility routines for dealing with JsonString objects
113**************************************************************************/
drh301eecc2015-08-17 20:14:19 +0000114
drh505ad2c2015-08-21 17:33:11 +0000115/* Set the JsonString object to an empty string
drh5fa5c102015-08-12 16:49:40 +0000116*/
drh505ad2c2015-08-21 17:33:11 +0000117static void jsonZero(JsonString *p){
drh5fa5c102015-08-12 16:49:40 +0000118 p->zBuf = p->zSpace;
119 p->nAlloc = sizeof(p->zSpace);
120 p->nUsed = 0;
121 p->bStatic = 1;
122}
123
drh505ad2c2015-08-21 17:33:11 +0000124/* Initialize the JsonString object
drh5fa5c102015-08-12 16:49:40 +0000125*/
drh505ad2c2015-08-21 17:33:11 +0000126static void jsonInit(JsonString *p, sqlite3_context *pCtx){
drh5fa5c102015-08-12 16:49:40 +0000127 p->pCtx = pCtx;
drhd0960592015-08-17 21:22:32 +0000128 p->bErr = 0;
drh5fa5c102015-08-12 16:49:40 +0000129 jsonZero(p);
130}
131
132
drh505ad2c2015-08-21 17:33:11 +0000133/* Free all allocated memory and reset the JsonString object back to its
drh5fa5c102015-08-12 16:49:40 +0000134** initial state.
135*/
drh505ad2c2015-08-21 17:33:11 +0000136static void jsonReset(JsonString *p){
drh5fa5c102015-08-12 16:49:40 +0000137 if( !p->bStatic ) sqlite3_free(p->zBuf);
138 jsonZero(p);
139}
140
141
142/* Report an out-of-memory (OOM) condition
143*/
drh505ad2c2015-08-21 17:33:11 +0000144static void jsonOom(JsonString *p){
drhd0960592015-08-17 21:22:32 +0000145 if( !p->bErr ){
146 p->bErr = 1;
147 sqlite3_result_error_nomem(p->pCtx);
148 jsonReset(p);
149 }
drh5fa5c102015-08-12 16:49:40 +0000150}
151
152/* Enlarge pJson->zBuf so that it can hold at least N more bytes.
153** Return zero on success. Return non-zero on an OOM error
154*/
drh505ad2c2015-08-21 17:33:11 +0000155static int jsonGrow(JsonString *p, u32 N){
drh301eecc2015-08-17 20:14:19 +0000156 u64 nTotal = N<p->nAlloc ? p->nAlloc*2 : p->nAlloc+N+10;
drh5fa5c102015-08-12 16:49:40 +0000157 char *zNew;
158 if( p->bStatic ){
drhd0960592015-08-17 21:22:32 +0000159 if( p->bErr ) return 1;
drh5fa5c102015-08-12 16:49:40 +0000160 zNew = sqlite3_malloc64(nTotal);
161 if( zNew==0 ){
162 jsonOom(p);
163 return SQLITE_NOMEM;
164 }
drh6fd5c1e2015-08-21 20:37:12 +0000165 memcpy(zNew, p->zBuf, (size_t)p->nUsed);
drh5fa5c102015-08-12 16:49:40 +0000166 p->zBuf = zNew;
167 p->bStatic = 0;
168 }else{
169 zNew = sqlite3_realloc64(p->zBuf, nTotal);
170 if( zNew==0 ){
171 jsonOom(p);
172 return SQLITE_NOMEM;
173 }
174 p->zBuf = zNew;
175 }
176 p->nAlloc = nTotal;
177 return SQLITE_OK;
178}
179
drh505ad2c2015-08-21 17:33:11 +0000180/* Append N bytes from zIn onto the end of the JsonString string.
drh5fa5c102015-08-12 16:49:40 +0000181*/
drh505ad2c2015-08-21 17:33:11 +0000182static void jsonAppendRaw(JsonString *p, const char *zIn, u32 N){
drh5fa5c102015-08-12 16:49:40 +0000183 if( (N+p->nUsed >= p->nAlloc) && jsonGrow(p,N)!=0 ) return;
184 memcpy(p->zBuf+p->nUsed, zIn, N);
185 p->nUsed += N;
186}
187
drh4af352d2015-08-21 20:02:48 +0000188/* Append formatted text (not to exceed N bytes) to the JsonString.
189*/
190static void jsonPrintf(int N, JsonString *p, const char *zFormat, ...){
191 va_list ap;
192 if( (p->nUsed + N >= p->nAlloc) && jsonGrow(p, N) ) return;
193 va_start(ap, zFormat);
194 sqlite3_vsnprintf(N, p->zBuf+p->nUsed, zFormat, ap);
195 va_end(ap);
196 p->nUsed += (int)strlen(p->zBuf+p->nUsed);
197}
198
drh5634cc02015-08-17 11:28:03 +0000199/* Append a single character
200*/
drh505ad2c2015-08-21 17:33:11 +0000201static void jsonAppendChar(JsonString *p, char c){
drh5634cc02015-08-17 11:28:03 +0000202 if( p->nUsed>=p->nAlloc && jsonGrow(p,1)!=0 ) return;
203 p->zBuf[p->nUsed++] = c;
204}
205
drh301eecc2015-08-17 20:14:19 +0000206/* Append a comma separator to the output buffer, if the previous
207** character is not '[' or '{'.
208*/
drh505ad2c2015-08-21 17:33:11 +0000209static void jsonAppendSeparator(JsonString *p){
drh301eecc2015-08-17 20:14:19 +0000210 char c;
211 if( p->nUsed==0 ) return;
212 c = p->zBuf[p->nUsed-1];
213 if( c!='[' && c!='{' ) jsonAppendChar(p, ',');
214}
215
drh505ad2c2015-08-21 17:33:11 +0000216/* Append the N-byte string in zIn to the end of the JsonString string
drh5fa5c102015-08-12 16:49:40 +0000217** under construction. Enclose the string in "..." and escape
218** any double-quotes or backslash characters contained within the
219** string.
220*/
drh505ad2c2015-08-21 17:33:11 +0000221static void jsonAppendString(JsonString *p, const char *zIn, u32 N){
drh5fa5c102015-08-12 16:49:40 +0000222 u32 i;
223 if( (N+p->nUsed+2 >= p->nAlloc) && jsonGrow(p,N+2)!=0 ) return;
224 p->zBuf[p->nUsed++] = '"';
225 for(i=0; i<N; i++){
226 char c = zIn[i];
227 if( c=='"' || c=='\\' ){
228 if( (p->nUsed+N+1-i > p->nAlloc) && jsonGrow(p,N+1-i)!=0 ) return;
229 p->zBuf[p->nUsed++] = '\\';
230 }
231 p->zBuf[p->nUsed++] = c;
232 }
233 p->zBuf[p->nUsed++] = '"';
234}
235
drhd0960592015-08-17 21:22:32 +0000236/*
237** Append a function parameter value to the JSON string under
238** construction.
239*/
240static void jsonAppendValue(
drh505ad2c2015-08-21 17:33:11 +0000241 JsonString *p, /* Append to this JSON string */
drhecb5fed2015-08-28 03:33:50 +0000242 sqlite3_value *pValue, /* Value to append */
243 u8 textIsJson /* Try to treat text values as JSON */
drhd0960592015-08-17 21:22:32 +0000244){
245 switch( sqlite3_value_type(pValue) ){
246 case SQLITE_NULL: {
247 jsonAppendRaw(p, "null", 4);
248 break;
249 }
250 case SQLITE_INTEGER:
251 case SQLITE_FLOAT: {
252 const char *z = (const char*)sqlite3_value_text(pValue);
253 u32 n = (u32)sqlite3_value_bytes(pValue);
254 jsonAppendRaw(p, z, n);
255 break;
256 }
257 case SQLITE_TEXT: {
258 const char *z = (const char*)sqlite3_value_text(pValue);
259 u32 n = (u32)sqlite3_value_bytes(pValue);
drhecb5fed2015-08-28 03:33:50 +0000260 if( textIsJson ){
261 jsonAppendRaw(p, z, n);
262 }else{
263 jsonAppendString(p, z, n);
264 }
drhd0960592015-08-17 21:22:32 +0000265 break;
266 }
267 default: {
268 if( p->bErr==0 ){
269 sqlite3_result_error(p->pCtx, "JSON cannot hold BLOB values", -1);
270 p->bErr = 1;
271 jsonReset(p);
272 }
273 break;
274 }
275 }
276}
277
278
drhbd0621b2015-08-13 13:54:59 +0000279/* Make the JSON in p the result of the SQL function.
drh5fa5c102015-08-12 16:49:40 +0000280*/
drh505ad2c2015-08-21 17:33:11 +0000281static void jsonResult(JsonString *p){
drhd0960592015-08-17 21:22:32 +0000282 if( p->bErr==0 ){
drh5fa5c102015-08-12 16:49:40 +0000283 sqlite3_result_text64(p->pCtx, p->zBuf, p->nUsed,
284 p->bStatic ? SQLITE_TRANSIENT : sqlite3_free,
285 SQLITE_UTF8);
286 jsonZero(p);
287 }
288 assert( p->bStatic );
289}
290
drh505ad2c2015-08-21 17:33:11 +0000291/**************************************************************************
292** Utility routines for dealing with JsonNode and JsonParse objects
293**************************************************************************/
294
295/*
296** Return the number of consecutive JsonNode slots need to represent
297** the parsed JSON at pNode. The minimum answer is 1. For ARRAY and
298** OBJECT types, the number might be larger.
299**
300** Appended elements are not counted. The value returned is the number
301** by which the JsonNode counter should increment in order to go to the
302** next peer value.
303*/
304static u32 jsonNodeSize(JsonNode *pNode){
305 return pNode->eType>=JSON_ARRAY ? pNode->n+1 : 1;
306}
307
308/*
309** Reclaim all memory allocated by a JsonParse object. But do not
310** delete the JsonParse object itself.
311*/
312static void jsonParseReset(JsonParse *pParse){
313 sqlite3_free(pParse->aNode);
314 pParse->aNode = 0;
315 pParse->nNode = 0;
316 pParse->nAlloc = 0;
317 sqlite3_free(pParse->aUp);
318 pParse->aUp = 0;
319}
320
drh5634cc02015-08-17 11:28:03 +0000321/*
322** Convert the JsonNode pNode into a pure JSON string and
323** append to pOut. Subsubstructure is also included. Return
324** the number of JsonNode objects that are encoded.
drhbd0621b2015-08-13 13:54:59 +0000325*/
drh52216ad2015-08-18 02:28:03 +0000326static void jsonRenderNode(
drhd0960592015-08-17 21:22:32 +0000327 JsonNode *pNode, /* The node to render */
drh505ad2c2015-08-21 17:33:11 +0000328 JsonString *pOut, /* Write JSON here */
drhd0960592015-08-17 21:22:32 +0000329 sqlite3_value **aReplace /* Replacement values */
330){
drh5634cc02015-08-17 11:28:03 +0000331 switch( pNode->eType ){
332 case JSON_NULL: {
333 jsonAppendRaw(pOut, "null", 4);
334 break;
335 }
336 case JSON_TRUE: {
337 jsonAppendRaw(pOut, "true", 4);
338 break;
339 }
340 case JSON_FALSE: {
341 jsonAppendRaw(pOut, "false", 5);
342 break;
343 }
344 case JSON_STRING: {
drh301eecc2015-08-17 20:14:19 +0000345 if( pNode->jnFlags & JNODE_RAW ){
drh52216ad2015-08-18 02:28:03 +0000346 jsonAppendString(pOut, pNode->u.zJContent, pNode->n);
drh5634cc02015-08-17 11:28:03 +0000347 break;
348 }
349 /* Fall through into the next case */
350 }
351 case JSON_REAL:
352 case JSON_INT: {
drh52216ad2015-08-18 02:28:03 +0000353 jsonAppendRaw(pOut, pNode->u.zJContent, pNode->n);
drh5634cc02015-08-17 11:28:03 +0000354 break;
355 }
356 case JSON_ARRAY: {
drh52216ad2015-08-18 02:28:03 +0000357 u32 j = 1;
drh5634cc02015-08-17 11:28:03 +0000358 jsonAppendChar(pOut, '[');
drh52216ad2015-08-18 02:28:03 +0000359 for(;;){
360 while( j<=pNode->n ){
361 if( pNode[j].jnFlags & (JNODE_REMOVE|JNODE_REPLACE) ){
362 if( pNode[j].jnFlags & JNODE_REPLACE ){
363 jsonAppendSeparator(pOut);
drhecb5fed2015-08-28 03:33:50 +0000364 jsonAppendValue(pOut, aReplace[pNode[j].iVal],
365 (pNode[j].jnFlags & JNODE_JSON)!=0);
drh52216ad2015-08-18 02:28:03 +0000366 }
367 }else{
drhd0960592015-08-17 21:22:32 +0000368 jsonAppendSeparator(pOut);
drh52216ad2015-08-18 02:28:03 +0000369 jsonRenderNode(&pNode[j], pOut, aReplace);
drhd0960592015-08-17 21:22:32 +0000370 }
drh505ad2c2015-08-21 17:33:11 +0000371 j += jsonNodeSize(&pNode[j]);
drh301eecc2015-08-17 20:14:19 +0000372 }
drh52216ad2015-08-18 02:28:03 +0000373 if( (pNode->jnFlags & JNODE_APPEND)==0 ) break;
374 pNode = &pNode[pNode->u.iAppend];
375 j = 1;
drh5634cc02015-08-17 11:28:03 +0000376 }
377 jsonAppendChar(pOut, ']');
378 break;
379 }
380 case JSON_OBJECT: {
drh52216ad2015-08-18 02:28:03 +0000381 u32 j = 1;
drh5634cc02015-08-17 11:28:03 +0000382 jsonAppendChar(pOut, '{');
drh52216ad2015-08-18 02:28:03 +0000383 for(;;){
384 while( j<=pNode->n ){
385 if( (pNode[j+1].jnFlags & JNODE_REMOVE)==0 ){
386 jsonAppendSeparator(pOut);
387 jsonRenderNode(&pNode[j], pOut, aReplace);
388 jsonAppendChar(pOut, ':');
389 if( pNode[j+1].jnFlags & JNODE_REPLACE ){
drhecb5fed2015-08-28 03:33:50 +0000390 jsonAppendValue(pOut, aReplace[pNode[j+1].iVal],
391 (pNode[j+1].jnFlags & JNODE_JSON)!=0);
drh52216ad2015-08-18 02:28:03 +0000392 }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];
drh80d87402015-08-24 12:42:41 +0000465 if( c!='\\' ){
drh987eb1f2015-08-17 15:17:37 +0000466 zOut[j++] = c;
467 }else{
468 c = z[++i];
drh80d87402015-08-24 12:42:41 +0000469 if( c=='u' ){
drh987eb1f2015-08-17 15:17:37 +0000470 u32 v = 0, k;
drh80d87402015-08-24 12:42:41 +0000471 for(k=0; k<4 && i<n-2; i++, k++){
drh8784eca2015-08-23 02:42:30 +0000472 c = z[i+1];
drh987eb1f2015-08-17 15:17:37 +0000473 if( c>='0' && c<='9' ) v = v*16 + c - '0';
474 else if( c>='A' && c<='F' ) v = v*16 + c - 'A' + 10;
475 else if( c>='a' && c<='f' ) v = v*16 + c - 'a' + 10;
476 else break;
drh987eb1f2015-08-17 15:17:37 +0000477 }
drh80d87402015-08-24 12:42:41 +0000478 if( v==0 ) break;
drh987eb1f2015-08-17 15:17:37 +0000479 if( v<=0x7f ){
480 zOut[j++] = v;
481 }else if( v<=0x7ff ){
482 zOut[j++] = 0xc0 | (v>>6);
483 zOut[j++] = 0x80 | (v&0x3f);
drh80d87402015-08-24 12:42:41 +0000484 }else{
drh987eb1f2015-08-17 15:17:37 +0000485 zOut[j++] = 0xe0 | (v>>12);
486 zOut[j++] = 0x80 | ((v>>6)&0x3f);
487 zOut[j++] = 0x80 | (v&0x3f);
drh987eb1f2015-08-17 15:17:37 +0000488 }
489 }else{
490 if( c=='b' ){
491 c = '\b';
492 }else if( c=='f' ){
493 c = '\f';
494 }else if( c=='n' ){
495 c = '\n';
496 }else if( c=='r' ){
497 c = '\r';
498 }else if( c=='t' ){
499 c = '\t';
500 }
501 zOut[j++] = c;
502 }
503 }
504 }
505 zOut[j] = 0;
506 sqlite3_result_text(pCtx, zOut, j, sqlite3_free);
drh5634cc02015-08-17 11:28:03 +0000507 }
508 break;
509 }
510 case JSON_ARRAY:
511 case JSON_OBJECT: {
drh505ad2c2015-08-21 17:33:11 +0000512 JsonString s;
drh5634cc02015-08-17 11:28:03 +0000513 jsonInit(&s, pCtx);
drhd0960592015-08-17 21:22:32 +0000514 jsonRenderNode(pNode, &s, aReplace);
drh5634cc02015-08-17 11:28:03 +0000515 jsonResult(&s);
516 break;
517 }
518 }
drhbd0621b2015-08-13 13:54:59 +0000519}
520
drh5fa5c102015-08-12 16:49:40 +0000521/*
drhe9c37f32015-08-15 21:25:36 +0000522** Create a new JsonNode instance based on the arguments and append that
523** instance to the JsonParse. Return the index in pParse->aNode[] of the
524** new node, or -1 if a memory allocation fails.
525*/
526static int jsonParseAddNode(
527 JsonParse *pParse, /* Append the node to this object */
528 u32 eType, /* Node type */
529 u32 n, /* Content size or sub-node count */
530 const char *zContent /* Content */
531){
532 JsonNode *p;
533 if( pParse->nNode>=pParse->nAlloc ){
534 u32 nNew;
535 JsonNode *pNew;
536 if( pParse->oom ) return -1;
537 nNew = pParse->nAlloc*2 + 10;
538 if( nNew<=pParse->nNode ){
539 pParse->oom = 1;
540 return -1;
541 }
542 pNew = sqlite3_realloc(pParse->aNode, sizeof(JsonNode)*nNew);
543 if( pNew==0 ){
544 pParse->oom = 1;
545 return -1;
546 }
547 pParse->nAlloc = nNew;
548 pParse->aNode = pNew;
549 }
550 p = &pParse->aNode[pParse->nNode];
drh5634cc02015-08-17 11:28:03 +0000551 p->eType = (u8)eType;
drh301eecc2015-08-17 20:14:19 +0000552 p->jnFlags = 0;
drhd0960592015-08-17 21:22:32 +0000553 p->iVal = 0;
drhe9c37f32015-08-15 21:25:36 +0000554 p->n = n;
drh52216ad2015-08-18 02:28:03 +0000555 p->u.zJContent = zContent;
drhe9c37f32015-08-15 21:25:36 +0000556 return pParse->nNode++;
557}
558
559/*
560** Parse a single JSON value which begins at pParse->zJson[i]. Return the
561** index of the first character past the end of the value parsed.
562**
563** Return negative for a syntax error. Special cases: return -2 if the
564** first non-whitespace character is '}' and return -3 if the first
565** non-whitespace character is ']'.
566*/
567static int jsonParseValue(JsonParse *pParse, u32 i){
568 char c;
569 u32 j;
drhbc8f0922015-08-22 19:39:04 +0000570 int iThis;
drhe9c37f32015-08-15 21:25:36 +0000571 int x;
572 while( isspace(pParse->zJson[i]) ){ i++; }
573 if( (c = pParse->zJson[i])==0 ) return 0;
574 if( c=='{' ){
575 /* Parse object */
576 iThis = jsonParseAddNode(pParse, JSON_OBJECT, 0, 0);
drhbc8f0922015-08-22 19:39:04 +0000577 if( iThis<0 ) return -1;
drhe9c37f32015-08-15 21:25:36 +0000578 for(j=i+1;;j++){
579 while( isspace(pParse->zJson[j]) ){ j++; }
580 x = jsonParseValue(pParse, j);
581 if( x<0 ){
drhbc8f0922015-08-22 19:39:04 +0000582 if( x==(-2) && pParse->nNode==(u32)iThis+1 ) return j+1;
drhe9c37f32015-08-15 21:25:36 +0000583 return -1;
584 }
drhbe9474e2015-08-22 03:05:54 +0000585 if( pParse->oom ) return -1;
drhe9c37f32015-08-15 21:25:36 +0000586 if( pParse->aNode[pParse->nNode-1].eType!=JSON_STRING ) return -1;
587 j = x;
588 while( isspace(pParse->zJson[j]) ){ j++; }
589 if( pParse->zJson[j]!=':' ) return -1;
590 j++;
591 x = jsonParseValue(pParse, j);
592 if( x<0 ) return -1;
593 j = x;
594 while( isspace(pParse->zJson[j]) ){ j++; }
595 c = pParse->zJson[j];
596 if( c==',' ) continue;
597 if( c!='}' ) return -1;
598 break;
599 }
drhbc8f0922015-08-22 19:39:04 +0000600 pParse->aNode[iThis].n = pParse->nNode - (u32)iThis - 1;
drhe9c37f32015-08-15 21:25:36 +0000601 return j+1;
602 }else if( c=='[' ){
603 /* Parse array */
604 iThis = jsonParseAddNode(pParse, JSON_ARRAY, 0, 0);
drhbc8f0922015-08-22 19:39:04 +0000605 if( iThis<0 ) return -1;
drhe9c37f32015-08-15 21:25:36 +0000606 for(j=i+1;;j++){
607 while( isspace(pParse->zJson[j]) ){ j++; }
608 x = jsonParseValue(pParse, j);
609 if( x<0 ){
drhbc8f0922015-08-22 19:39:04 +0000610 if( x==(-3) && pParse->nNode==(u32)iThis+1 ) return j+1;
drhe9c37f32015-08-15 21:25:36 +0000611 return -1;
612 }
613 j = x;
614 while( isspace(pParse->zJson[j]) ){ j++; }
615 c = pParse->zJson[j];
616 if( c==',' ) continue;
617 if( c!=']' ) return -1;
618 break;
619 }
drhbc8f0922015-08-22 19:39:04 +0000620 pParse->aNode[iThis].n = pParse->nNode - (u32)iThis - 1;
drhe9c37f32015-08-15 21:25:36 +0000621 return j+1;
622 }else if( c=='"' ){
623 /* Parse string */
drh301eecc2015-08-17 20:14:19 +0000624 u8 jnFlags = 0;
drhe9c37f32015-08-15 21:25:36 +0000625 j = i+1;
626 for(;;){
627 c = pParse->zJson[j];
628 if( c==0 ) return -1;
629 if( c=='\\' ){
630 c = pParse->zJson[++j];
631 if( c==0 ) return -1;
drh301eecc2015-08-17 20:14:19 +0000632 jnFlags = JNODE_ESCAPE;
drhe9c37f32015-08-15 21:25:36 +0000633 }else if( c=='"' ){
634 break;
635 }
636 j++;
637 }
638 jsonParseAddNode(pParse, JSON_STRING, j+1-i, &pParse->zJson[i]);
drhbe9474e2015-08-22 03:05:54 +0000639 if( !pParse->oom ) pParse->aNode[pParse->nNode-1].jnFlags = jnFlags;
drhe9c37f32015-08-15 21:25:36 +0000640 return j+1;
641 }else if( c=='n'
642 && strncmp(pParse->zJson+i,"null",4)==0
drhb2cd10e2015-08-15 21:29:14 +0000643 && !isalnum(pParse->zJson[i+4]) ){
drhe9c37f32015-08-15 21:25:36 +0000644 jsonParseAddNode(pParse, JSON_NULL, 0, 0);
645 return i+4;
646 }else if( c=='t'
647 && strncmp(pParse->zJson+i,"true",4)==0
drhb2cd10e2015-08-15 21:29:14 +0000648 && !isalnum(pParse->zJson[i+4]) ){
drhe9c37f32015-08-15 21:25:36 +0000649 jsonParseAddNode(pParse, JSON_TRUE, 0, 0);
650 return i+4;
651 }else if( c=='f'
652 && strncmp(pParse->zJson+i,"false",5)==0
drhb2cd10e2015-08-15 21:29:14 +0000653 && !isalnum(pParse->zJson[i+5]) ){
drhe9c37f32015-08-15 21:25:36 +0000654 jsonParseAddNode(pParse, JSON_FALSE, 0, 0);
655 return i+5;
656 }else if( c=='-' || (c>='0' && c<='9') ){
657 /* Parse number */
658 u8 seenDP = 0;
659 u8 seenE = 0;
660 j = i+1;
661 for(;; j++){
662 c = pParse->zJson[j];
663 if( c>='0' && c<='9' ) continue;
664 if( c=='.' ){
665 if( pParse->zJson[j-1]=='-' ) return -1;
666 if( seenDP ) return -1;
667 seenDP = 1;
668 continue;
669 }
670 if( c=='e' || c=='E' ){
671 if( pParse->zJson[j-1]<'0' ) return -1;
672 if( seenE ) return -1;
673 seenDP = seenE = 1;
674 c = pParse->zJson[j+1];
drh8784eca2015-08-23 02:42:30 +0000675 if( c=='+' || c=='-' ){
676 j++;
677 c = pParse->zJson[j+1];
678 }
679 if( c<'0' || c>'0' ) return -1;
drhe9c37f32015-08-15 21:25:36 +0000680 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*/
drhbc8f0922015-08-22 19:39:04 +0000704static int jsonParse(
705 JsonParse *pParse, /* Initialize and fill this JsonParse object */
706 sqlite3_context *pCtx, /* Report errors here */
707 const char *zJson /* Input JSON text to be parsed */
708){
drhe9c37f32015-08-15 21:25:36 +0000709 int i;
drhe9c37f32015-08-15 21:25:36 +0000710 memset(pParse, 0, sizeof(*pParse));
drhc3722b22015-08-23 20:44:59 +0000711 if( zJson==0 ) return 1;
drhe9c37f32015-08-15 21:25:36 +0000712 pParse->zJson = zJson;
713 i = jsonParseValue(pParse, 0);
drhc3722b22015-08-23 20:44:59 +0000714 if( pParse->oom ) i = -1;
drhe9c37f32015-08-15 21:25:36 +0000715 if( i>0 ){
716 while( isspace(zJson[i]) ) i++;
717 if( zJson[i] ) i = -1;
718 }
719 if( i<0 ){
drhbc8f0922015-08-22 19:39:04 +0000720 if( pParse->oom && pCtx!=0 ) sqlite3_result_error_nomem(pCtx);
drh505ad2c2015-08-21 17:33:11 +0000721 jsonParseReset(pParse);
drhe9c37f32015-08-15 21:25:36 +0000722 return 1;
723 }
724 return 0;
725}
drh301eecc2015-08-17 20:14:19 +0000726
drh505ad2c2015-08-21 17:33:11 +0000727/* Mark node i of pParse as being a child of iParent. Call recursively
728** to fill in all the descendants of node i.
729*/
730static void jsonParseFillInParentage(JsonParse *pParse, u32 i, u32 iParent){
731 JsonNode *pNode = &pParse->aNode[i];
732 u32 j;
733 pParse->aUp[i] = iParent;
734 switch( pNode->eType ){
735 case JSON_ARRAY: {
736 for(j=1; j<=pNode->n; j += jsonNodeSize(pNode+j)){
737 jsonParseFillInParentage(pParse, i+j, i);
738 }
739 break;
740 }
741 case JSON_OBJECT: {
742 for(j=1; j<=pNode->n; j += jsonNodeSize(pNode+j+1)+1){
743 pParse->aUp[i+j] = i;
744 jsonParseFillInParentage(pParse, i+j+1, i);
745 }
746 break;
747 }
748 default: {
749 break;
750 }
751 }
752}
753
754/*
755** Compute the parentage of all nodes in a completed parse.
756*/
757static int jsonParseFindParents(JsonParse *pParse){
758 u32 *aUp;
759 assert( pParse->aUp==0 );
760 aUp = pParse->aUp = sqlite3_malloc( sizeof(u32)*pParse->nNode );
drhc3722b22015-08-23 20:44:59 +0000761 if( aUp==0 ){
762 pParse->oom = 1;
763 return SQLITE_NOMEM;
764 }
drh505ad2c2015-08-21 17:33:11 +0000765 jsonParseFillInParentage(pParse, 0, 0);
766 return SQLITE_OK;
767}
768
drh52216ad2015-08-18 02:28:03 +0000769/* forward declaration */
770static JsonNode *jsonLookupAppend(JsonParse*,const char*,int*);
771
drh987eb1f2015-08-17 15:17:37 +0000772/*
773** Search along zPath to find the node specified. Return a pointer
774** to that node, or NULL if zPath is malformed or if there is no such
775** node.
drh52216ad2015-08-18 02:28:03 +0000776**
777** If pApnd!=0, then try to append new nodes to complete zPath if it is
778** possible to do so and if no existing node corresponds to zPath. If
779** new nodes are appended *pApnd is set to 1.
drh987eb1f2015-08-17 15:17:37 +0000780*/
drh52216ad2015-08-18 02:28:03 +0000781static JsonNode *jsonLookup(
782 JsonParse *pParse, /* The JSON to search */
783 u32 iRoot, /* Begin the search at this node */
784 const char *zPath, /* The path to search */
785 int *pApnd /* Append nodes to complete path if not NULL */
786){
drhbc8f0922015-08-22 19:39:04 +0000787 u32 i, j, nKey;
drh6b43cc82015-08-19 23:02:49 +0000788 const char *zKey;
drh52216ad2015-08-18 02:28:03 +0000789 JsonNode *pRoot = &pParse->aNode[iRoot];
drh987eb1f2015-08-17 15:17:37 +0000790 if( zPath[0]==0 ) return pRoot;
791 if( zPath[0]=='.' ){
792 if( pRoot->eType!=JSON_OBJECT ) return 0;
793 zPath++;
drh6b43cc82015-08-19 23:02:49 +0000794 if( zPath[0]=='"' ){
795 zKey = zPath + 1;
796 for(i=1; zPath[i] && zPath[i]!='"'; i++){}
797 nKey = i-1;
798 if( zPath[i] ) i++;
799 }else{
800 zKey = zPath;
801 for(i=0; zPath[i] && zPath[i]!='.' && zPath[i]!='['; i++){}
802 nKey = i;
803 }
804 if( nKey==0 ) return 0;
drh987eb1f2015-08-17 15:17:37 +0000805 j = 1;
drh52216ad2015-08-18 02:28:03 +0000806 for(;;){
807 while( j<=pRoot->n ){
drh6b43cc82015-08-19 23:02:49 +0000808 if( pRoot[j].n==nKey+2
809 && strncmp(&pRoot[j].u.zJContent[1],zKey,nKey)==0
drh52216ad2015-08-18 02:28:03 +0000810 ){
811 return jsonLookup(pParse, iRoot+j+1, &zPath[i], pApnd);
812 }
813 j++;
drh505ad2c2015-08-21 17:33:11 +0000814 j += jsonNodeSize(&pRoot[j]);
drh987eb1f2015-08-17 15:17:37 +0000815 }
drh52216ad2015-08-18 02:28:03 +0000816 if( (pRoot->jnFlags & JNODE_APPEND)==0 ) break;
817 iRoot += pRoot->u.iAppend;
818 pRoot = &pParse->aNode[iRoot];
819 j = 1;
820 }
821 if( pApnd ){
drhbc8f0922015-08-22 19:39:04 +0000822 u32 iStart, iLabel;
823 JsonNode *pNode;
824 iStart = jsonParseAddNode(pParse, JSON_OBJECT, 2, 0);
825 iLabel = jsonParseAddNode(pParse, JSON_STRING, i, zPath);
drh52216ad2015-08-18 02:28:03 +0000826 zPath += i;
drhbc8f0922015-08-22 19:39:04 +0000827 pNode = jsonLookupAppend(pParse, zPath, pApnd);
828 if( pParse->oom ) return 0;
829 if( pNode ){
830 pRoot = &pParse->aNode[iRoot];
831 pRoot->u.iAppend = iStart - iRoot;
832 pRoot->jnFlags |= JNODE_APPEND;
833 pParse->aNode[iLabel].jnFlags |= JNODE_RAW;
834 }
835 return pNode;
drh987eb1f2015-08-17 15:17:37 +0000836 }
837 }else if( zPath[0]=='[' && isdigit(zPath[1]) ){
838 if( pRoot->eType!=JSON_ARRAY ) return 0;
839 i = 0;
840 zPath++;
841 while( isdigit(zPath[0]) ){
drh8784eca2015-08-23 02:42:30 +0000842 i = i*10 + zPath[0] - '0';
drh987eb1f2015-08-17 15:17:37 +0000843 zPath++;
844 }
845 if( zPath[0]!=']' ) return 0;
846 zPath++;
847 j = 1;
drh52216ad2015-08-18 02:28:03 +0000848 for(;;){
drhbc8f0922015-08-22 19:39:04 +0000849 while( j<=pRoot->n && (i>0 || (pRoot[j].jnFlags & JNODE_REMOVE)!=0) ){
850 if( (pRoot[j].jnFlags & JNODE_REMOVE)==0 ) i--;
drh505ad2c2015-08-21 17:33:11 +0000851 j += jsonNodeSize(&pRoot[j]);
drh52216ad2015-08-18 02:28:03 +0000852 }
853 if( (pRoot->jnFlags & JNODE_APPEND)==0 ) break;
854 iRoot += pRoot->u.iAppend;
855 pRoot = &pParse->aNode[iRoot];
856 j = 1;
drh987eb1f2015-08-17 15:17:37 +0000857 }
858 if( j<=pRoot->n ){
drh52216ad2015-08-18 02:28:03 +0000859 return jsonLookup(pParse, iRoot+j, zPath, pApnd);
860 }
861 if( i==0 && pApnd ){
drhbc8f0922015-08-22 19:39:04 +0000862 u32 iStart;
863 JsonNode *pNode;
864 iStart = jsonParseAddNode(pParse, JSON_ARRAY, 1, 0);
865 pNode = jsonLookupAppend(pParse, zPath, pApnd);
866 if( pParse->oom ) return 0;
867 if( pNode ){
868 pRoot = &pParse->aNode[iRoot];
869 pRoot->u.iAppend = iStart - iRoot;
870 pRoot->jnFlags |= JNODE_APPEND;
871 }
872 return pNode;
drh987eb1f2015-08-17 15:17:37 +0000873 }
874 }
875 return 0;
876}
877
drh52216ad2015-08-18 02:28:03 +0000878/*
drhbc8f0922015-08-22 19:39:04 +0000879** Append content to pParse that will complete zPath. Return a pointer
880** to the inserted node, or return NULL if the append fails.
drh52216ad2015-08-18 02:28:03 +0000881*/
882static JsonNode *jsonLookupAppend(
883 JsonParse *pParse, /* Append content to the JSON parse */
884 const char *zPath, /* Description of content to append */
885 int *pApnd /* Set this flag to 1 */
886){
887 *pApnd = 1;
888 if( zPath[0]==0 ){
889 jsonParseAddNode(pParse, JSON_NULL, 0, 0);
890 return pParse->oom ? 0 : &pParse->aNode[pParse->nNode-1];
891 }
892 if( zPath[0]=='.' ){
893 jsonParseAddNode(pParse, JSON_OBJECT, 0, 0);
894 }else if( strncmp(zPath,"[0]",3)==0 ){
895 jsonParseAddNode(pParse, JSON_ARRAY, 0, 0);
896 }else{
897 return 0;
898 }
899 if( pParse->oom ) return 0;
900 return jsonLookup(pParse, pParse->nNode-1, zPath, pApnd);
901}
902
drhbc8f0922015-08-22 19:39:04 +0000903/*
904** Report the wrong number of arguments for json_insert(), json_replace()
905** or json_set().
906*/
907static void jsonWrongNumArgs(
908 sqlite3_context *pCtx,
909 const char *zFuncName
910){
911 char *zMsg = sqlite3_mprintf("json_%s() needs an odd number of arguments",
912 zFuncName);
913 sqlite3_result_error(pCtx, zMsg, -1);
914 sqlite3_free(zMsg);
915}
drh52216ad2015-08-18 02:28:03 +0000916
drh987eb1f2015-08-17 15:17:37 +0000917/****************************************************************************
918** SQL functions used for testing and debugging
919****************************************************************************/
drhe9c37f32015-08-15 21:25:36 +0000920
drh301eecc2015-08-17 20:14:19 +0000921#ifdef SQLITE_DEBUG
drhe9c37f32015-08-15 21:25:36 +0000922/*
drh5634cc02015-08-17 11:28:03 +0000923** The json_parse(JSON) function returns a string which describes
drhe9c37f32015-08-15 21:25:36 +0000924** a parse of the JSON provided. Or it returns NULL if JSON is not
925** well-formed.
926*/
drh5634cc02015-08-17 11:28:03 +0000927static void jsonParseFunc(
drhbc8f0922015-08-22 19:39:04 +0000928 sqlite3_context *ctx,
drhe9c37f32015-08-15 21:25:36 +0000929 int argc,
930 sqlite3_value **argv
931){
drh505ad2c2015-08-21 17:33:11 +0000932 JsonString s; /* Output string - not real JSON */
933 JsonParse x; /* The parse */
drhe9c37f32015-08-15 21:25:36 +0000934 u32 i;
drhe9c37f32015-08-15 21:25:36 +0000935
936 assert( argc==1 );
drhbc8f0922015-08-22 19:39:04 +0000937 if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return;
drh8784eca2015-08-23 02:42:30 +0000938 jsonParseFindParents(&x);
drhbc8f0922015-08-22 19:39:04 +0000939 jsonInit(&s, ctx);
drhe9c37f32015-08-15 21:25:36 +0000940 for(i=0; i<x.nNode; i++){
drh8784eca2015-08-23 02:42:30 +0000941 jsonPrintf(100, &s,"node %3u: %7s n=%-4d up=%d\n",
942 i, jsonType[x.aNode[i].eType], x.aNode[i].n, x.aUp[i]);
drh52216ad2015-08-18 02:28:03 +0000943 if( x.aNode[i].u.zJContent!=0 ){
drh301eecc2015-08-17 20:14:19 +0000944 jsonAppendRaw(&s, " text: ", 10);
drh52216ad2015-08-18 02:28:03 +0000945 jsonAppendRaw(&s, x.aNode[i].u.zJContent, x.aNode[i].n);
drhe9c37f32015-08-15 21:25:36 +0000946 jsonAppendRaw(&s, "\n", 1);
947 }
948 }
drh505ad2c2015-08-21 17:33:11 +0000949 jsonParseReset(&x);
drhe9c37f32015-08-15 21:25:36 +0000950 jsonResult(&s);
951}
952
drh5634cc02015-08-17 11:28:03 +0000953/*
954** The json_test1(JSON) function parses and rebuilds the JSON string.
955*/
956static void jsonTest1Func(
drhbc8f0922015-08-22 19:39:04 +0000957 sqlite3_context *ctx,
drh5634cc02015-08-17 11:28:03 +0000958 int argc,
959 sqlite3_value **argv
960){
961 JsonParse x; /* The parse */
drhbc8f0922015-08-22 19:39:04 +0000962 if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return;
963 jsonReturn(x.aNode, ctx, 0);
drh505ad2c2015-08-21 17:33:11 +0000964 jsonParseReset(&x);
drh5634cc02015-08-17 11:28:03 +0000965}
966
967/*
968** The json_nodecount(JSON) function returns the number of nodes in the
969** input JSON string.
970*/
971static void jsonNodeCountFunc(
drhbc8f0922015-08-22 19:39:04 +0000972 sqlite3_context *ctx,
drh5634cc02015-08-17 11:28:03 +0000973 int argc,
974 sqlite3_value **argv
975){
976 JsonParse x; /* The parse */
drhbc8f0922015-08-22 19:39:04 +0000977 if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return;
978 sqlite3_result_int64(ctx, (sqlite3_int64)x.nNode);
drh505ad2c2015-08-21 17:33:11 +0000979 jsonParseReset(&x);
drh5634cc02015-08-17 11:28:03 +0000980}
drh301eecc2015-08-17 20:14:19 +0000981#endif /* SQLITE_DEBUG */
drh5634cc02015-08-17 11:28:03 +0000982
drh987eb1f2015-08-17 15:17:37 +0000983/****************************************************************************
984** SQL function implementations
985****************************************************************************/
986
987/*
988** Implementation of the json_array(VALUE,...) function. Return a JSON
989** array that contains all values given in arguments. Or if any argument
990** is a BLOB, throw an error.
991*/
992static void jsonArrayFunc(
drhbc8f0922015-08-22 19:39:04 +0000993 sqlite3_context *ctx,
drh987eb1f2015-08-17 15:17:37 +0000994 int argc,
995 sqlite3_value **argv
996){
997 int i;
drh505ad2c2015-08-21 17:33:11 +0000998 JsonString jx;
drh987eb1f2015-08-17 15:17:37 +0000999
drhbc8f0922015-08-22 19:39:04 +00001000 jsonInit(&jx, ctx);
drhd0960592015-08-17 21:22:32 +00001001 jsonAppendChar(&jx, '[');
drh987eb1f2015-08-17 15:17:37 +00001002 for(i=0; i<argc; i++){
drhd0960592015-08-17 21:22:32 +00001003 jsonAppendSeparator(&jx);
drhecb5fed2015-08-28 03:33:50 +00001004 jsonAppendValue(&jx, argv[i], 0);
drh987eb1f2015-08-17 15:17:37 +00001005 }
drhd0960592015-08-17 21:22:32 +00001006 jsonAppendChar(&jx, ']');
drh987eb1f2015-08-17 15:17:37 +00001007 jsonResult(&jx);
1008}
1009
1010
1011/*
1012** json_array_length(JSON)
1013** json_array_length(JSON, PATH)
1014**
1015** Return the number of elements in the top-level JSON array.
1016** Return 0 if the input is not a well-formed JSON array.
1017*/
1018static void jsonArrayLengthFunc(
drhbc8f0922015-08-22 19:39:04 +00001019 sqlite3_context *ctx,
drh987eb1f2015-08-17 15:17:37 +00001020 int argc,
1021 sqlite3_value **argv
1022){
1023 JsonParse x; /* The parse */
1024 sqlite3_int64 n = 0;
1025 u32 i;
1026 const char *zPath;
1027
1028 if( argc==2 ){
1029 zPath = (const char*)sqlite3_value_text(argv[1]);
1030 if( zPath==0 ) return;
1031 if( zPath[0]!='$' ) return;
1032 zPath++;
1033 }else{
1034 zPath = 0;
1035 }
drhbc8f0922015-08-22 19:39:04 +00001036 if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0]))==0 ){
drh987eb1f2015-08-17 15:17:37 +00001037 if( x.nNode ){
1038 JsonNode *pNode = x.aNode;
drh52216ad2015-08-18 02:28:03 +00001039 if( zPath ) pNode = jsonLookup(&x, 0, zPath, 0);
drh987eb1f2015-08-17 15:17:37 +00001040 if( pNode->eType==JSON_ARRAY ){
drh52216ad2015-08-18 02:28:03 +00001041 assert( (pNode->jnFlags & JNODE_APPEND)==0 );
drh301eecc2015-08-17 20:14:19 +00001042 for(i=1; i<=pNode->n; n++){
drh505ad2c2015-08-21 17:33:11 +00001043 i += jsonNodeSize(&pNode[i]);
drh987eb1f2015-08-17 15:17:37 +00001044 }
1045 }
1046 }
drh505ad2c2015-08-21 17:33:11 +00001047 jsonParseReset(&x);
drh987eb1f2015-08-17 15:17:37 +00001048 }
drhbc8f0922015-08-22 19:39:04 +00001049 if( !x.oom ) sqlite3_result_int64(ctx, n);
drh987eb1f2015-08-17 15:17:37 +00001050}
1051
1052/*
drhf6ec8d42015-08-28 03:48:04 +00001053** json_check(JSON)
1054**
1055** Check the JSON argument to verify that it is well-formed. Return a
1056** compacted version of the argument (with white-space removed) if the
1057** argument is well-formed. Through an error if the argument is not
1058** correctly formatted JSON.
1059*/
1060static void jsonCheckFunc(
1061 sqlite3_context *ctx,
1062 int argc,
1063 sqlite3_value **argv
1064){
1065 JsonParse x; /* The parse */
1066 if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ){
1067 sqlite3_result_error(ctx, "malformed JSON", -1);
1068 return;
1069 }
1070 jsonReturn(x.aNode, ctx, argv);
1071 jsonParseReset(&x);
1072}
1073
1074/*
drh987eb1f2015-08-17 15:17:37 +00001075** json_extract(JSON, PATH)
1076**
1077** Return the element described by PATH. Return NULL if JSON is not
1078** valid JSON or if there is no PATH element or if PATH is malformed.
1079*/
1080static void jsonExtractFunc(
drhbc8f0922015-08-22 19:39:04 +00001081 sqlite3_context *ctx,
drh987eb1f2015-08-17 15:17:37 +00001082 int argc,
1083 sqlite3_value **argv
1084){
1085 JsonParse x; /* The parse */
1086 JsonNode *pNode;
1087 const char *zPath;
1088 assert( argc==2 );
1089 zPath = (const char*)sqlite3_value_text(argv[1]);
1090 if( zPath==0 ) return;
1091 if( zPath[0]!='$' ) return;
1092 zPath++;
drhbc8f0922015-08-22 19:39:04 +00001093 if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return;
drh52216ad2015-08-18 02:28:03 +00001094 pNode = jsonLookup(&x, 0, zPath, 0);
drh987eb1f2015-08-17 15:17:37 +00001095 if( pNode ){
drhbc8f0922015-08-22 19:39:04 +00001096 jsonReturn(pNode, ctx, 0);
drh987eb1f2015-08-17 15:17:37 +00001097 }
drh505ad2c2015-08-21 17:33:11 +00001098 jsonParseReset(&x);
drh987eb1f2015-08-17 15:17:37 +00001099}
1100
1101/*
1102** Implementation of the json_object(NAME,VALUE,...) function. Return a JSON
1103** object that contains all name/value given in arguments. Or if any name
1104** is not a string or if any value is a BLOB, throw an error.
1105*/
1106static void jsonObjectFunc(
drhbc8f0922015-08-22 19:39:04 +00001107 sqlite3_context *ctx,
drh987eb1f2015-08-17 15:17:37 +00001108 int argc,
1109 sqlite3_value **argv
1110){
1111 int i;
drh505ad2c2015-08-21 17:33:11 +00001112 JsonString jx;
drh987eb1f2015-08-17 15:17:37 +00001113 const char *z;
1114 u32 n;
1115
1116 if( argc&1 ){
drhbc8f0922015-08-22 19:39:04 +00001117 sqlite3_result_error(ctx, "json_object() requires an even number "
drh987eb1f2015-08-17 15:17:37 +00001118 "of arguments", -1);
1119 return;
1120 }
drhbc8f0922015-08-22 19:39:04 +00001121 jsonInit(&jx, ctx);
drhd0960592015-08-17 21:22:32 +00001122 jsonAppendChar(&jx, '{');
drh987eb1f2015-08-17 15:17:37 +00001123 for(i=0; i<argc; i+=2){
drh987eb1f2015-08-17 15:17:37 +00001124 if( sqlite3_value_type(argv[i])!=SQLITE_TEXT ){
drhbc8f0922015-08-22 19:39:04 +00001125 sqlite3_result_error(ctx, "json_object() labels must be TEXT", -1);
drh987eb1f2015-08-17 15:17:37 +00001126 jsonZero(&jx);
1127 return;
1128 }
drhd0960592015-08-17 21:22:32 +00001129 jsonAppendSeparator(&jx);
drh987eb1f2015-08-17 15:17:37 +00001130 z = (const char*)sqlite3_value_text(argv[i]);
1131 n = (u32)sqlite3_value_bytes(argv[i]);
1132 jsonAppendString(&jx, z, n);
drhd0960592015-08-17 21:22:32 +00001133 jsonAppendChar(&jx, ':');
drhecb5fed2015-08-28 03:33:50 +00001134 jsonAppendValue(&jx, argv[i+1], 0);
drh987eb1f2015-08-17 15:17:37 +00001135 }
drhd0960592015-08-17 21:22:32 +00001136 jsonAppendChar(&jx, '}');
drh987eb1f2015-08-17 15:17:37 +00001137 jsonResult(&jx);
1138}
1139
1140
1141/*
drh301eecc2015-08-17 20:14:19 +00001142** json_remove(JSON, PATH, ...)
1143**
1144** Remove the named elements from JSON and return the result. Ill-formed
1145** PATH arguments are silently ignored. If JSON is ill-formed, then NULL
1146** is returned.
1147*/
1148static void jsonRemoveFunc(
drhbc8f0922015-08-22 19:39:04 +00001149 sqlite3_context *ctx,
drh301eecc2015-08-17 20:14:19 +00001150 int argc,
1151 sqlite3_value **argv
1152){
1153 JsonParse x; /* The parse */
1154 JsonNode *pNode;
1155 const char *zPath;
1156 u32 i;
1157
1158 if( argc<1 ) return;
drhbc8f0922015-08-22 19:39:04 +00001159 if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return;
drh301eecc2015-08-17 20:14:19 +00001160 if( x.nNode ){
drh6fd5c1e2015-08-21 20:37:12 +00001161 for(i=1; i<(u32)argc; i++){
drh301eecc2015-08-17 20:14:19 +00001162 zPath = (const char*)sqlite3_value_text(argv[i]);
1163 if( zPath==0 ) continue;
1164 if( zPath[0]!='$' ) continue;
drh52216ad2015-08-18 02:28:03 +00001165 pNode = jsonLookup(&x, 0, &zPath[1], 0);
drh301eecc2015-08-17 20:14:19 +00001166 if( pNode ) pNode->jnFlags |= JNODE_REMOVE;
1167 }
1168 if( (x.aNode[0].jnFlags & JNODE_REMOVE)==0 ){
drhbc8f0922015-08-22 19:39:04 +00001169 jsonReturn(x.aNode, ctx, 0);
drhd0960592015-08-17 21:22:32 +00001170 }
1171 }
drh505ad2c2015-08-21 17:33:11 +00001172 jsonParseReset(&x);
drhd0960592015-08-17 21:22:32 +00001173}
1174
1175/*
1176** json_replace(JSON, PATH, VALUE, ...)
1177**
1178** Replace the value at PATH with VALUE. If PATH does not already exist,
1179** this routine is a no-op. If JSON is ill-formed, return NULL.
1180*/
1181static void jsonReplaceFunc(
drhbc8f0922015-08-22 19:39:04 +00001182 sqlite3_context *ctx,
drhd0960592015-08-17 21:22:32 +00001183 int argc,
1184 sqlite3_value **argv
1185){
1186 JsonParse x; /* The parse */
1187 JsonNode *pNode;
1188 const char *zPath;
1189 u32 i;
1190
1191 if( argc<1 ) return;
1192 if( (argc&1)==0 ) {
drhbc8f0922015-08-22 19:39:04 +00001193 jsonWrongNumArgs(ctx, "replace");
drhd0960592015-08-17 21:22:32 +00001194 return;
1195 }
drhbc8f0922015-08-22 19:39:04 +00001196 if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return;
drhd0960592015-08-17 21:22:32 +00001197 if( x.nNode ){
drh6fd5c1e2015-08-21 20:37:12 +00001198 for(i=1; i<(u32)argc; i+=2){
drhecb5fed2015-08-28 03:33:50 +00001199 u8 jnFlags = JNODE_REPLACE;
drhd0960592015-08-17 21:22:32 +00001200 zPath = (const char*)sqlite3_value_text(argv[i]);
1201 if( zPath==0 ) continue;
1202 if( zPath[0]!='$' ) continue;
drhecb5fed2015-08-28 03:33:50 +00001203 if( zPath[1]=='$' ){
1204 zPath++;
1205 jnFlags = JNODE_REPLACE|JNODE_JSON;
1206 }
drh52216ad2015-08-18 02:28:03 +00001207 pNode = jsonLookup(&x, 0, &zPath[1], 0);
drhd0960592015-08-17 21:22:32 +00001208 if( pNode ){
drhecb5fed2015-08-28 03:33:50 +00001209 pNode->jnFlags &= ~JNODE_JSON;
1210 pNode->jnFlags |= jnFlags;
drhd0960592015-08-17 21:22:32 +00001211 pNode->iVal = i+1;
1212 }
1213 }
1214 if( x.aNode[0].jnFlags & JNODE_REPLACE ){
drhbc8f0922015-08-22 19:39:04 +00001215 sqlite3_result_value(ctx, argv[x.aNode[0].iVal]);
drhd0960592015-08-17 21:22:32 +00001216 }else{
drhbc8f0922015-08-22 19:39:04 +00001217 jsonReturn(x.aNode, ctx, argv);
drh301eecc2015-08-17 20:14:19 +00001218 }
1219 }
drh505ad2c2015-08-21 17:33:11 +00001220 jsonParseReset(&x);
drh301eecc2015-08-17 20:14:19 +00001221}
drh505ad2c2015-08-21 17:33:11 +00001222
drh52216ad2015-08-18 02:28:03 +00001223/*
1224** json_set(JSON, PATH, VALUE, ...)
1225**
1226** Set the value at PATH to VALUE. Create the PATH if it does not already
1227** exist. Overwrite existing values that do exist.
1228** If JSON is ill-formed, return NULL.
1229**
1230** json_insert(JSON, PATH, VALUE, ...)
1231**
1232** Create PATH and initialize it to VALUE. If PATH already exists, this
1233** routine is a no-op. If JSON is ill-formed, return NULL.
1234*/
1235static void jsonSetFunc(
drhbc8f0922015-08-22 19:39:04 +00001236 sqlite3_context *ctx,
drh52216ad2015-08-18 02:28:03 +00001237 int argc,
1238 sqlite3_value **argv
1239){
1240 JsonParse x; /* The parse */
1241 JsonNode *pNode;
1242 const char *zPath;
1243 u32 i;
1244 int bApnd;
drhbc8f0922015-08-22 19:39:04 +00001245 int bIsSet = *(int*)sqlite3_user_data(ctx);
drh52216ad2015-08-18 02:28:03 +00001246
1247 if( argc<1 ) return;
1248 if( (argc&1)==0 ) {
drhbc8f0922015-08-22 19:39:04 +00001249 jsonWrongNumArgs(ctx, bIsSet ? "set" : "insert");
drh52216ad2015-08-18 02:28:03 +00001250 return;
1251 }
drhbc8f0922015-08-22 19:39:04 +00001252 if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return;
drh52216ad2015-08-18 02:28:03 +00001253 if( x.nNode ){
drh6fd5c1e2015-08-21 20:37:12 +00001254 for(i=1; i<(u32)argc; i+=2){
drhecb5fed2015-08-28 03:33:50 +00001255 u8 jnFlags = JNODE_REPLACE;
drh52216ad2015-08-18 02:28:03 +00001256 zPath = (const char*)sqlite3_value_text(argv[i]);
1257 if( zPath==0 ) continue;
1258 if( zPath[0]!='$' ) continue;
drhecb5fed2015-08-28 03:33:50 +00001259 if( zPath[1]=='$' ){
1260 zPath++;
1261 jnFlags = JNODE_REPLACE|JNODE_JSON;
1262 }
drh52216ad2015-08-18 02:28:03 +00001263 bApnd = 0;
1264 pNode = jsonLookup(&x, 0, &zPath[1], &bApnd);
drhbc8f0922015-08-22 19:39:04 +00001265 if( x.oom ){
1266 sqlite3_result_error_nomem(ctx);
1267 goto jsonSetDone;
1268 }else if( pNode && (bApnd || bIsSet) ){
drhecb5fed2015-08-28 03:33:50 +00001269 pNode->jnFlags &= ~JNODE_JSON;
1270 pNode->jnFlags |= jnFlags;
drh52216ad2015-08-18 02:28:03 +00001271 pNode->iVal = i+1;
1272 }
1273 }
1274 if( x.aNode[0].jnFlags & JNODE_REPLACE ){
drhbc8f0922015-08-22 19:39:04 +00001275 sqlite3_result_value(ctx, argv[x.aNode[0].iVal]);
drh52216ad2015-08-18 02:28:03 +00001276 }else{
drhbc8f0922015-08-22 19:39:04 +00001277 jsonReturn(x.aNode, ctx, argv);
drh52216ad2015-08-18 02:28:03 +00001278 }
1279 }
drhbc8f0922015-08-22 19:39:04 +00001280jsonSetDone:
drh505ad2c2015-08-21 17:33:11 +00001281 jsonParseReset(&x);
drh52216ad2015-08-18 02:28:03 +00001282}
drh301eecc2015-08-17 20:14:19 +00001283
1284/*
drh987eb1f2015-08-17 15:17:37 +00001285** json_type(JSON)
1286** json_type(JSON, PATH)
1287**
1288** Return the top-level "type" of a JSON string. Return NULL if the
1289** input is not a well-formed JSON string.
1290*/
1291static void jsonTypeFunc(
drhbc8f0922015-08-22 19:39:04 +00001292 sqlite3_context *ctx,
drh987eb1f2015-08-17 15:17:37 +00001293 int argc,
1294 sqlite3_value **argv
1295){
1296 JsonParse x; /* The parse */
1297 const char *zPath;
1298
1299 if( argc==2 ){
1300 zPath = (const char*)sqlite3_value_text(argv[1]);
1301 if( zPath==0 ) return;
1302 if( zPath[0]!='$' ) return;
1303 zPath++;
1304 }else{
1305 zPath = 0;
1306 }
drhbc8f0922015-08-22 19:39:04 +00001307 if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return;
drh987eb1f2015-08-17 15:17:37 +00001308 if( x.nNode ){
1309 JsonNode *pNode = x.aNode;
drh52216ad2015-08-18 02:28:03 +00001310 if( zPath ) pNode = jsonLookup(&x, 0, zPath, 0);
drhbc8f0922015-08-22 19:39:04 +00001311 if( pNode ){
1312 sqlite3_result_text(ctx, jsonType[pNode->eType], -1, SQLITE_STATIC);
1313 }
drh987eb1f2015-08-17 15:17:37 +00001314 }
drh505ad2c2015-08-21 17:33:11 +00001315 jsonParseReset(&x);
drh987eb1f2015-08-17 15:17:37 +00001316}
drh5634cc02015-08-17 11:28:03 +00001317
drhbc8f0922015-08-22 19:39:04 +00001318/*
1319** json_valid(JSON)
1320**
1321** Return 1 if JSON is a valid JSON string. Return 0 otherwise.
1322*/
1323static void jsonValidFunc(
1324 sqlite3_context *ctx,
1325 int argc,
1326 sqlite3_value **argv
1327){
1328 JsonParse x; /* The parse */
1329 int rc = 0;
1330
1331 if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0]))==0
1332 && x.nNode>0
1333 ){
1334 rc = 1;
1335 }
1336 jsonParseReset(&x);
1337 sqlite3_result_int(ctx, rc);
1338}
1339
drhcb6c6c62015-08-19 22:47:17 +00001340/****************************************************************************
1341** The json_each virtual table
1342****************************************************************************/
1343typedef struct JsonEachCursor JsonEachCursor;
1344struct JsonEachCursor {
1345 sqlite3_vtab_cursor base; /* Base class - must be first */
drh505ad2c2015-08-21 17:33:11 +00001346 u32 iRowid; /* The rowid */
1347 u32 i; /* Index in sParse.aNode[] of current row */
1348 u32 iEnd; /* EOF when i equals or exceeds this value */
1349 u8 eType; /* Type of top-level element */
1350 u8 bRecursive; /* True for json_tree(). False for json_each() */
1351 char *zJson; /* Input JSON */
1352 char *zPath; /* Path by which to filter zJson */
1353 JsonParse sParse; /* Parse of the input JSON */
drhcb6c6c62015-08-19 22:47:17 +00001354};
1355
1356/* Constructor for the json_each virtual table */
1357static int jsonEachConnect(
1358 sqlite3 *db,
1359 void *pAux,
1360 int argc, const char *const*argv,
1361 sqlite3_vtab **ppVtab,
1362 char **pzErr
1363){
1364 sqlite3_vtab *pNew;
drh505ad2c2015-08-21 17:33:11 +00001365 int rc;
drhcb6c6c62015-08-19 22:47:17 +00001366
1367/* Column numbers */
drh4af352d2015-08-21 20:02:48 +00001368#define JEACH_KEY 0
1369#define JEACH_VALUE 1
1370#define JEACH_TYPE 2
1371#define JEACH_ATOM 3
1372#define JEACH_ID 4
1373#define JEACH_PARENT 5
1374#define JEACH_FULLKEY 6
1375#define JEACH_JSON 7
1376#define JEACH_PATH 8
drhcb6c6c62015-08-19 22:47:17 +00001377
drh6fd5c1e2015-08-21 20:37:12 +00001378 UNUSED_PARAM(pzErr);
1379 UNUSED_PARAM(argv);
1380 UNUSED_PARAM(argc);
1381 UNUSED_PARAM(pAux);
drh505ad2c2015-08-21 17:33:11 +00001382 rc = sqlite3_declare_vtab(db,
drh4af352d2015-08-21 20:02:48 +00001383 "CREATE TABLE x(key,value,type,atom,id,parent,fullkey,"
1384 "json HIDDEN,path HIDDEN)");
drh505ad2c2015-08-21 17:33:11 +00001385 if( rc==SQLITE_OK ){
1386 pNew = *ppVtab = sqlite3_malloc( sizeof(*pNew) );
1387 if( pNew==0 ) return SQLITE_NOMEM;
1388 memset(pNew, 0, sizeof(*pNew));
1389 }
1390 return rc;
drhcb6c6c62015-08-19 22:47:17 +00001391}
1392
1393/* destructor for json_each virtual table */
1394static int jsonEachDisconnect(sqlite3_vtab *pVtab){
1395 sqlite3_free(pVtab);
1396 return SQLITE_OK;
1397}
1398
drh505ad2c2015-08-21 17:33:11 +00001399/* constructor for a JsonEachCursor object for json_each(). */
1400static int jsonEachOpenEach(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
drhcb6c6c62015-08-19 22:47:17 +00001401 JsonEachCursor *pCur;
drh6fd5c1e2015-08-21 20:37:12 +00001402
1403 UNUSED_PARAM(p);
drhcb6c6c62015-08-19 22:47:17 +00001404 pCur = sqlite3_malloc( sizeof(*pCur) );
1405 if( pCur==0 ) return SQLITE_NOMEM;
1406 memset(pCur, 0, sizeof(*pCur));
1407 *ppCursor = &pCur->base;
1408 return SQLITE_OK;
1409}
1410
drh505ad2c2015-08-21 17:33:11 +00001411/* constructor for a JsonEachCursor object for json_tree(). */
1412static int jsonEachOpenTree(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
1413 int rc = jsonEachOpenEach(p, ppCursor);
1414 if( rc==SQLITE_OK ){
1415 JsonEachCursor *pCur = (JsonEachCursor*)*ppCursor;
1416 pCur->bRecursive = 1;
1417 }
1418 return rc;
1419}
1420
drhcb6c6c62015-08-19 22:47:17 +00001421/* Reset a JsonEachCursor back to its original state. Free any memory
1422** held. */
1423static void jsonEachCursorReset(JsonEachCursor *p){
1424 sqlite3_free(p->zJson);
1425 sqlite3_free(p->zPath);
drh505ad2c2015-08-21 17:33:11 +00001426 jsonParseReset(&p->sParse);
drhcb6c6c62015-08-19 22:47:17 +00001427 p->iRowid = 0;
1428 p->i = 0;
1429 p->iEnd = 0;
1430 p->eType = 0;
drhcb6c6c62015-08-19 22:47:17 +00001431 p->zJson = 0;
1432 p->zPath = 0;
1433}
1434
1435/* Destructor for a jsonEachCursor object */
1436static int jsonEachClose(sqlite3_vtab_cursor *cur){
1437 JsonEachCursor *p = (JsonEachCursor*)cur;
1438 jsonEachCursorReset(p);
1439 sqlite3_free(cur);
1440 return SQLITE_OK;
1441}
1442
1443/* Return TRUE if the jsonEachCursor object has been advanced off the end
1444** of the JSON object */
1445static int jsonEachEof(sqlite3_vtab_cursor *cur){
1446 JsonEachCursor *p = (JsonEachCursor*)cur;
1447 return p->i >= p->iEnd;
1448}
1449
drh505ad2c2015-08-21 17:33:11 +00001450/* Advance the cursor to the next element for json_tree() */
drh4af352d2015-08-21 20:02:48 +00001451static int jsonEachNext(sqlite3_vtab_cursor *cur){
drh505ad2c2015-08-21 17:33:11 +00001452 JsonEachCursor *p = (JsonEachCursor*)cur;
drh4af352d2015-08-21 20:02:48 +00001453 if( p->bRecursive ){
1454 if( p->i==0 ){
1455 p->i = 1;
drh4af352d2015-08-21 20:02:48 +00001456 }else{
drh8784eca2015-08-23 02:42:30 +00001457 u32 iUp = p->sParse.aUp[p->i];
1458 JsonNode *pUp = &p->sParse.aNode[iUp];
drh4af352d2015-08-21 20:02:48 +00001459 p->i++;
drh8784eca2015-08-23 02:42:30 +00001460 if( pUp->eType==JSON_OBJECT && (pUp->n + iUp >= p->i) ) p->i++;
drh4af352d2015-08-21 20:02:48 +00001461 }
1462 p->iRowid++;
1463 if( p->i<p->sParse.nNode ){
drh8784eca2015-08-23 02:42:30 +00001464 u32 iUp = p->sParse.aUp[p->i];
1465 JsonNode *pUp = &p->sParse.aNode[iUp];
drh4af352d2015-08-21 20:02:48 +00001466 p->eType = pUp->eType;
drh8784eca2015-08-23 02:42:30 +00001467 if( pUp->eType==JSON_ARRAY ){
1468 if( iUp==p->i-1 ){
1469 pUp->u.iKey = 0;
1470 }else{
1471 pUp->u.iKey++;
1472 }
drh4af352d2015-08-21 20:02:48 +00001473 }
1474 }
drh505ad2c2015-08-21 17:33:11 +00001475 }else{
drh4af352d2015-08-21 20:02:48 +00001476 switch( p->eType ){
1477 case JSON_ARRAY: {
1478 p->i += jsonNodeSize(&p->sParse.aNode[p->i]);
1479 p->iRowid++;
1480 break;
1481 }
1482 case JSON_OBJECT: {
1483 p->i += 1 + jsonNodeSize(&p->sParse.aNode[p->i+1]);
1484 p->iRowid++;
1485 break;
1486 }
1487 default: {
1488 p->i = p->iEnd;
1489 break;
1490 }
drh505ad2c2015-08-21 17:33:11 +00001491 }
1492 }
1493 return SQLITE_OK;
1494}
1495
drh4af352d2015-08-21 20:02:48 +00001496/* Append the name of the path for element i to pStr
1497*/
1498static void jsonEachComputePath(
1499 JsonEachCursor *p, /* The cursor */
1500 JsonString *pStr, /* Write the path here */
1501 u32 i /* Path to this element */
1502){
1503 JsonNode *pNode, *pUp;
1504 u32 iUp;
1505 if( i==0 ){
1506 jsonAppendChar(pStr, '$');
1507 return;
drhcb6c6c62015-08-19 22:47:17 +00001508 }
drh4af352d2015-08-21 20:02:48 +00001509 iUp = p->sParse.aUp[i];
1510 jsonEachComputePath(p, pStr, iUp);
1511 pNode = &p->sParse.aNode[i];
1512 pUp = &p->sParse.aNode[iUp];
1513 if( pUp->eType==JSON_ARRAY ){
1514 jsonPrintf(30, pStr, "[%d]", pUp->u.iKey);
1515 }else{
1516 assert( pUp->eType==JSON_OBJECT );
1517 if( pNode->eType>=JSON_ARRAY ) pNode--;
1518 assert( pNode->eType==JSON_STRING );
1519 jsonPrintf(pNode->n+1, pStr, ".%.*s", pNode->n-2, pNode->u.zJContent+1);
1520 }
drhcb6c6c62015-08-19 22:47:17 +00001521}
1522
1523/* Return the value of a column */
1524static int jsonEachColumn(
1525 sqlite3_vtab_cursor *cur, /* The cursor */
1526 sqlite3_context *ctx, /* First argument to sqlite3_result_...() */
1527 int i /* Which column to return */
1528){
1529 JsonEachCursor *p = (JsonEachCursor*)cur;
drh505ad2c2015-08-21 17:33:11 +00001530 JsonNode *pThis = &p->sParse.aNode[p->i];
drhcb6c6c62015-08-19 22:47:17 +00001531 switch( i ){
1532 case JEACH_KEY: {
drh8784eca2015-08-23 02:42:30 +00001533 if( p->i==0 ) break;
drhcb6c6c62015-08-19 22:47:17 +00001534 if( p->eType==JSON_OBJECT ){
drh505ad2c2015-08-21 17:33:11 +00001535 jsonReturn(pThis, ctx, 0);
1536 }else if( p->eType==JSON_ARRAY ){
1537 u32 iKey;
1538 if( p->bRecursive ){
1539 if( p->iRowid==0 ) break;
drh8784eca2015-08-23 02:42:30 +00001540 iKey = p->sParse.aNode[p->sParse.aUp[p->i]].u.iKey;
drh505ad2c2015-08-21 17:33:11 +00001541 }else{
1542 iKey = p->iRowid;
1543 }
drh6fd5c1e2015-08-21 20:37:12 +00001544 sqlite3_result_int64(ctx, (sqlite3_int64)iKey);
drhcb6c6c62015-08-19 22:47:17 +00001545 }
1546 break;
1547 }
1548 case JEACH_VALUE: {
drh8784eca2015-08-23 02:42:30 +00001549 if( p->eType==JSON_OBJECT && p->i>0 ) pThis++;
drh505ad2c2015-08-21 17:33:11 +00001550 jsonReturn(pThis, ctx, 0);
1551 break;
1552 }
1553 case JEACH_TYPE: {
drh442a7c62015-08-24 02:32:04 +00001554 if( p->eType==JSON_OBJECT && p->i>0 ) pThis++;
drh505ad2c2015-08-21 17:33:11 +00001555 sqlite3_result_text(ctx, jsonType[pThis->eType], -1, SQLITE_STATIC);
1556 break;
1557 }
1558 case JEACH_ATOM: {
drh442a7c62015-08-24 02:32:04 +00001559 if( p->eType==JSON_OBJECT && p->i>0 ) pThis++;
drh505ad2c2015-08-21 17:33:11 +00001560 if( pThis->eType>=JSON_ARRAY ) break;
1561 jsonReturn(pThis, ctx, 0);
1562 break;
1563 }
1564 case JEACH_ID: {
drh6fd5c1e2015-08-21 20:37:12 +00001565 sqlite3_result_int64(ctx, (sqlite3_int64)p->i + (p->eType==JSON_OBJECT));
drh505ad2c2015-08-21 17:33:11 +00001566 break;
1567 }
1568 case JEACH_PARENT: {
1569 if( p->i>0 && p->bRecursive ){
drh6fd5c1e2015-08-21 20:37:12 +00001570 sqlite3_result_int64(ctx, (sqlite3_int64)p->sParse.aUp[p->i]);
drhcb6c6c62015-08-19 22:47:17 +00001571 }
1572 break;
1573 }
drh4af352d2015-08-21 20:02:48 +00001574 case JEACH_FULLKEY: {
1575 JsonString x;
1576 jsonInit(&x, ctx);
1577 if( p->bRecursive ){
1578 jsonEachComputePath(p, &x, p->i);
1579 }else{
1580 if( p->zPath ){
1581 jsonAppendRaw(&x, p->zPath, (int)strlen(p->zPath));
1582 }else{
1583 jsonAppendChar(&x, '$');
1584 }
1585 if( p->eType==JSON_ARRAY ){
1586 jsonPrintf(30, &x, "[%d]", p->iRowid);
1587 }else{
1588 jsonPrintf(pThis->n, &x, ".%.*s", pThis->n-2, pThis->u.zJContent+1);
1589 }
1590 }
1591 jsonResult(&x);
1592 break;
1593 }
drhcb6c6c62015-08-19 22:47:17 +00001594 case JEACH_PATH: {
1595 const char *zPath = p->zPath;
drh4af352d2015-08-21 20:02:48 +00001596 if( zPath==0 ){
1597 if( p->bRecursive ){
1598 JsonString x;
1599 jsonInit(&x, ctx);
1600 jsonEachComputePath(p, &x, p->sParse.aUp[p->i]);
1601 jsonResult(&x);
1602 break;
1603 }
1604 zPath = "$";
1605 }
drhcb6c6c62015-08-19 22:47:17 +00001606 sqlite3_result_text(ctx, zPath, -1, SQLITE_STATIC);
1607 break;
1608 }
1609 default: {
drh505ad2c2015-08-21 17:33:11 +00001610 assert( i==JEACH_JSON );
drhcb6c6c62015-08-19 22:47:17 +00001611 sqlite3_result_text(ctx, p->sParse.zJson, -1, SQLITE_STATIC);
1612 break;
1613 }
1614 }
1615 return SQLITE_OK;
1616}
1617
1618/* Return the current rowid value */
1619static int jsonEachRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){
1620 JsonEachCursor *p = (JsonEachCursor*)cur;
1621 *pRowid = p->iRowid;
1622 return SQLITE_OK;
1623}
1624
1625/* The query strategy is to look for an equality constraint on the json
1626** column. Without such a constraint, the table cannot operate. idxNum is
1627** 1 if the constraint is found, 3 if the constraint and zPath are found,
1628** and 0 otherwise.
1629*/
1630static int jsonEachBestIndex(
1631 sqlite3_vtab *tab,
1632 sqlite3_index_info *pIdxInfo
1633){
1634 int i;
1635 int jsonIdx = -1;
1636 int pathIdx = -1;
1637 const struct sqlite3_index_constraint *pConstraint;
drh6fd5c1e2015-08-21 20:37:12 +00001638
1639 UNUSED_PARAM(tab);
drhcb6c6c62015-08-19 22:47:17 +00001640 pConstraint = pIdxInfo->aConstraint;
1641 for(i=0; i<pIdxInfo->nConstraint; i++, pConstraint++){
1642 if( pConstraint->usable==0 ) continue;
1643 if( pConstraint->op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue;
1644 switch( pConstraint->iColumn ){
1645 case JEACH_JSON: jsonIdx = i; break;
1646 case JEACH_PATH: pathIdx = i; break;
1647 default: /* no-op */ break;
1648 }
1649 }
1650 if( jsonIdx<0 ){
1651 pIdxInfo->idxNum = 0;
drh505ad2c2015-08-21 17:33:11 +00001652 pIdxInfo->estimatedCost = 1e99;
drhcb6c6c62015-08-19 22:47:17 +00001653 }else{
drh505ad2c2015-08-21 17:33:11 +00001654 pIdxInfo->estimatedCost = 1.0;
drhcb6c6c62015-08-19 22:47:17 +00001655 pIdxInfo->aConstraintUsage[jsonIdx].argvIndex = 1;
1656 pIdxInfo->aConstraintUsage[jsonIdx].omit = 1;
1657 if( pathIdx<0 ){
1658 pIdxInfo->idxNum = 1;
1659 }else{
1660 pIdxInfo->aConstraintUsage[pathIdx].argvIndex = 2;
1661 pIdxInfo->aConstraintUsage[pathIdx].omit = 1;
1662 pIdxInfo->idxNum = 3;
1663 }
1664 }
1665 return SQLITE_OK;
1666}
1667
1668/* Start a search on a new JSON string */
1669static int jsonEachFilter(
1670 sqlite3_vtab_cursor *cur,
1671 int idxNum, const char *idxStr,
1672 int argc, sqlite3_value **argv
1673){
1674 JsonEachCursor *p = (JsonEachCursor*)cur;
1675 const char *z;
1676 const char *zPath;
1677 sqlite3_int64 n;
1678
drh6fd5c1e2015-08-21 20:37:12 +00001679 UNUSED_PARAM(idxStr);
1680 UNUSED_PARAM(argc);
drhcb6c6c62015-08-19 22:47:17 +00001681 jsonEachCursorReset(p);
1682 if( idxNum==0 ) return SQLITE_OK;
1683 z = (const char*)sqlite3_value_text(argv[0]);
1684 if( z==0 ) return SQLITE_OK;
1685 if( idxNum&2 ){
1686 zPath = (const char*)sqlite3_value_text(argv[1]);
1687 if( zPath==0 || zPath[0]!='$' ) return SQLITE_OK;
1688 }
1689 n = sqlite3_value_bytes(argv[0]);
drh6fd5c1e2015-08-21 20:37:12 +00001690 p->zJson = sqlite3_malloc64( n+1 );
drhcb6c6c62015-08-19 22:47:17 +00001691 if( p->zJson==0 ) return SQLITE_NOMEM;
drh6fd5c1e2015-08-21 20:37:12 +00001692 memcpy(p->zJson, z, (size_t)n+1);
drhbc8f0922015-08-22 19:39:04 +00001693 if( jsonParse(&p->sParse, 0, p->zJson)
drh505ad2c2015-08-21 17:33:11 +00001694 || (p->bRecursive && jsonParseFindParents(&p->sParse))
1695 ){
drhcb6c6c62015-08-19 22:47:17 +00001696 jsonEachCursorReset(p);
1697 }else{
1698 JsonNode *pNode;
1699 if( idxNum==3 ){
drh4af352d2015-08-21 20:02:48 +00001700 p->bRecursive = 0;
drhcb6c6c62015-08-19 22:47:17 +00001701 n = sqlite3_value_bytes(argv[1]);
drh6fd5c1e2015-08-21 20:37:12 +00001702 p->zPath = sqlite3_malloc64( n+1 );
drhcb6c6c62015-08-19 22:47:17 +00001703 if( p->zPath==0 ) return SQLITE_NOMEM;
drh6fd5c1e2015-08-21 20:37:12 +00001704 memcpy(p->zPath, zPath, (size_t)n+1);
drhcb6c6c62015-08-19 22:47:17 +00001705 pNode = jsonLookup(&p->sParse, 0, p->zPath+1, 0);
1706 if( pNode==0 ){
1707 jsonEachCursorReset(p);
1708 return SQLITE_OK;
1709 }
1710 }else{
1711 pNode = p->sParse.aNode;
1712 }
1713 p->i = (int)(pNode - p->sParse.aNode);
1714 p->eType = pNode->eType;
1715 if( p->eType>=JSON_ARRAY ){
drh8784eca2015-08-23 02:42:30 +00001716 pNode->u.iKey = 0;
drhc3722b22015-08-23 20:44:59 +00001717 p->iEnd = p->i + pNode->n + 1;
drh8784eca2015-08-23 02:42:30 +00001718 if( !p->bRecursive ) p->i++;
drhcb6c6c62015-08-19 22:47:17 +00001719 }else{
1720 p->iEnd = p->i+1;
1721 }
1722 }
drhbc8f0922015-08-22 19:39:04 +00001723 return p->sParse.oom ? SQLITE_NOMEM : SQLITE_OK;
drhcb6c6c62015-08-19 22:47:17 +00001724}
1725
1726/* The methods of the json_each virtual table */
1727static sqlite3_module jsonEachModule = {
1728 0, /* iVersion */
1729 0, /* xCreate */
1730 jsonEachConnect, /* xConnect */
1731 jsonEachBestIndex, /* xBestIndex */
1732 jsonEachDisconnect, /* xDisconnect */
1733 0, /* xDestroy */
drh505ad2c2015-08-21 17:33:11 +00001734 jsonEachOpenEach, /* xOpen - open a cursor */
drhcb6c6c62015-08-19 22:47:17 +00001735 jsonEachClose, /* xClose - close a cursor */
1736 jsonEachFilter, /* xFilter - configure scan constraints */
drh4af352d2015-08-21 20:02:48 +00001737 jsonEachNext, /* xNext - advance a cursor */
drhcb6c6c62015-08-19 22:47:17 +00001738 jsonEachEof, /* xEof - check for end of scan */
1739 jsonEachColumn, /* xColumn - read data */
1740 jsonEachRowid, /* xRowid - read data */
1741 0, /* xUpdate */
1742 0, /* xBegin */
1743 0, /* xSync */
1744 0, /* xCommit */
1745 0, /* xRollback */
1746 0, /* xFindMethod */
1747 0, /* xRename */
drh6fd5c1e2015-08-21 20:37:12 +00001748 0, /* xSavepoint */
1749 0, /* xRelease */
1750 0 /* xRollbackTo */
drhcb6c6c62015-08-19 22:47:17 +00001751};
1752
drh505ad2c2015-08-21 17:33:11 +00001753/* The methods of the json_tree virtual table. */
1754static sqlite3_module jsonTreeModule = {
1755 0, /* iVersion */
1756 0, /* xCreate */
1757 jsonEachConnect, /* xConnect */
1758 jsonEachBestIndex, /* xBestIndex */
1759 jsonEachDisconnect, /* xDisconnect */
1760 0, /* xDestroy */
1761 jsonEachOpenTree, /* xOpen - open a cursor */
1762 jsonEachClose, /* xClose - close a cursor */
1763 jsonEachFilter, /* xFilter - configure scan constraints */
drh4af352d2015-08-21 20:02:48 +00001764 jsonEachNext, /* xNext - advance a cursor */
drh505ad2c2015-08-21 17:33:11 +00001765 jsonEachEof, /* xEof - check for end of scan */
1766 jsonEachColumn, /* xColumn - read data */
1767 jsonEachRowid, /* xRowid - read data */
1768 0, /* xUpdate */
1769 0, /* xBegin */
1770 0, /* xSync */
1771 0, /* xCommit */
1772 0, /* xRollback */
1773 0, /* xFindMethod */
1774 0, /* xRename */
drh6fd5c1e2015-08-21 20:37:12 +00001775 0, /* xSavepoint */
1776 0, /* xRelease */
1777 0 /* xRollbackTo */
drh505ad2c2015-08-21 17:33:11 +00001778};
1779
1780/****************************************************************************
1781** The following routine is the only publically visible identifier in this
1782** file. Call the following routine in order to register the various SQL
1783** functions and the virtual table implemented by this file.
1784****************************************************************************/
drhcb6c6c62015-08-19 22:47:17 +00001785
drh5fa5c102015-08-12 16:49:40 +00001786#ifdef _WIN32
1787__declspec(dllexport)
1788#endif
1789int sqlite3_json_init(
1790 sqlite3 *db,
1791 char **pzErrMsg,
1792 const sqlite3_api_routines *pApi
1793){
1794 int rc = SQLITE_OK;
drh6fd5c1e2015-08-21 20:37:12 +00001795 unsigned int i;
drh5fa5c102015-08-12 16:49:40 +00001796 static const struct {
1797 const char *zName;
1798 int nArg;
drh52216ad2015-08-18 02:28:03 +00001799 int flag;
drh5fa5c102015-08-12 16:49:40 +00001800 void (*xFunc)(sqlite3_context*,int,sqlite3_value**);
1801 } aFunc[] = {
drh52216ad2015-08-18 02:28:03 +00001802 { "json_array", -1, 0, jsonArrayFunc },
1803 { "json_array_length", 1, 0, jsonArrayLengthFunc },
1804 { "json_array_length", 2, 0, jsonArrayLengthFunc },
drhf6ec8d42015-08-28 03:48:04 +00001805 { "json_check", 1, 0, jsonCheckFunc },
drh52216ad2015-08-18 02:28:03 +00001806 { "json_extract", 2, 0, jsonExtractFunc },
1807 { "json_insert", -1, 0, jsonSetFunc },
1808 { "json_object", -1, 0, jsonObjectFunc },
1809 { "json_remove", -1, 0, jsonRemoveFunc },
1810 { "json_replace", -1, 0, jsonReplaceFunc },
1811 { "json_set", -1, 1, jsonSetFunc },
1812 { "json_type", 1, 0, jsonTypeFunc },
1813 { "json_type", 2, 0, jsonTypeFunc },
drhbc8f0922015-08-22 19:39:04 +00001814 { "json_valid", 1, 0, jsonValidFunc },
drh987eb1f2015-08-17 15:17:37 +00001815
drh301eecc2015-08-17 20:14:19 +00001816#if SQLITE_DEBUG
drh987eb1f2015-08-17 15:17:37 +00001817 /* DEBUG and TESTING functions */
drh52216ad2015-08-18 02:28:03 +00001818 { "json_parse", 1, 0, jsonParseFunc },
1819 { "json_test1", 1, 0, jsonTest1Func },
1820 { "json_nodecount", 1, 0, jsonNodeCountFunc },
drh301eecc2015-08-17 20:14:19 +00001821#endif
drh5fa5c102015-08-12 16:49:40 +00001822 };
drh505ad2c2015-08-21 17:33:11 +00001823 static const struct {
1824 const char *zName;
1825 sqlite3_module *pModule;
1826 } aMod[] = {
1827 { "json_each", &jsonEachModule },
1828 { "json_tree", &jsonTreeModule },
1829 };
drh5fa5c102015-08-12 16:49:40 +00001830 SQLITE_EXTENSION_INIT2(pApi);
1831 (void)pzErrMsg; /* Unused parameter */
1832 for(i=0; i<sizeof(aFunc)/sizeof(aFunc[0]) && rc==SQLITE_OK; i++){
1833 rc = sqlite3_create_function(db, aFunc[i].zName, aFunc[i].nArg,
drh52216ad2015-08-18 02:28:03 +00001834 SQLITE_UTF8 | SQLITE_DETERMINISTIC,
1835 (void*)&aFunc[i].flag,
drh5fa5c102015-08-12 16:49:40 +00001836 aFunc[i].xFunc, 0, 0);
1837 }
drh505ad2c2015-08-21 17:33:11 +00001838 for(i=0; i<sizeof(aMod)/sizeof(aMod[0]) && rc==SQLITE_OK; i++){
1839 rc = sqlite3_create_module(db, aMod[i].zName, aMod[i].pModule, 0);
drhcb6c6c62015-08-19 22:47:17 +00001840 }
drh5fa5c102015-08-12 16:49:40 +00001841 return rc;
1842}