blob: 0adf710ef0d9b4af52e931c1a5d161a4ee9c851d [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*/
drh50065652015-10-08 19:29:18 +000024#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_JSON1)
drh666d34c2017-01-25 13:54:27 +000025#if !defined(SQLITEINT_H)
drh5fa5c102015-08-12 16:49:40 +000026#include "sqlite3ext.h"
drhf2df7e72015-08-28 20:07:40 +000027#endif
drh5fa5c102015-08-12 16:49:40 +000028SQLITE_EXTENSION_INIT1
29#include <assert.h>
30#include <string.h>
drh987eb1f2015-08-17 15:17:37 +000031#include <stdlib.h>
drh4af352d2015-08-21 20:02:48 +000032#include <stdarg.h>
drh5fa5c102015-08-12 16:49:40 +000033
drhdf3a9072016-02-11 15:37:18 +000034/* Mark a function parameter as unused, to suppress nuisance compiler
35** warnings. */
36#ifndef UNUSED_PARAM
37# define UNUSED_PARAM(X) (void)(X)
38#endif
drh6fd5c1e2015-08-21 20:37:12 +000039
drh8deb4b82015-10-09 18:21:43 +000040#ifndef LARGEST_INT64
41# define LARGEST_INT64 (0xffffffff|(((sqlite3_int64)0x7fffffff)<<32))
42# define SMALLEST_INT64 (((sqlite3_int64)-1) - LARGEST_INT64)
43#endif
44
drh08b92082020-08-10 14:18:00 +000045#ifndef deliberate_fall_through
46# define deliberate_fall_through
47#endif
48
dan2e8f5512015-09-17 17:21:09 +000049/*
50** Versions of isspace(), isalnum() and isdigit() to which it is safe
51** to pass signed char values.
52*/
drh49472652015-10-16 15:35:39 +000053#ifdef sqlite3Isdigit
54 /* Use the SQLite core versions if this routine is part of the
55 ** SQLite amalgamation */
drhad875e72016-11-07 13:37:28 +000056# define safe_isdigit(x) sqlite3Isdigit(x)
57# define safe_isalnum(x) sqlite3Isalnum(x)
58# define safe_isxdigit(x) sqlite3Isxdigit(x)
drh49472652015-10-16 15:35:39 +000059#else
60 /* Use the standard library for separate compilation */
61#include <ctype.h> /* amalgamator: keep */
drhad875e72016-11-07 13:37:28 +000062# define safe_isdigit(x) isdigit((unsigned char)(x))
63# define safe_isalnum(x) isalnum((unsigned char)(x))
64# define safe_isxdigit(x) isxdigit((unsigned char)(x))
drh49472652015-10-16 15:35:39 +000065#endif
dan2e8f5512015-09-17 17:21:09 +000066
drh95677942015-09-24 01:06:37 +000067/*
68** Growing our own isspace() routine this way is twice as fast as
69** the library isspace() function, resulting in a 7% overall performance
70** increase for the parser. (Ubuntu14.10 gcc 4.8.4 x64 with -Os).
71*/
72static const char jsonIsSpace[] = {
drhb9e8f592015-10-16 15:16:06 +000073 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0,
drh95677942015-09-24 01:06:37 +000074 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
75 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
76 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
77 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
78 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
79 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
80 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
81 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
82 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
83 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
84 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
85 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
86 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
87 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
88 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
89};
90#define safe_isspace(x) (jsonIsSpace[(unsigned char)x])
91
drh9a4718f2015-10-10 14:00:37 +000092#ifndef SQLITE_AMALGAMATION
93 /* Unsigned integer types. These are already defined in the sqliteInt.h,
94 ** but the definitions need to be repeated for separate compilation. */
95 typedef sqlite3_uint64 u64;
96 typedef unsigned int u32;
drhff6d50e2017-04-11 18:55:05 +000097 typedef unsigned short int u16;
drh9a4718f2015-10-10 14:00:37 +000098 typedef unsigned char u8;
drh6a726fa2021-10-05 15:30:52 +000099# if defined(SQLITE_COVERAGE_TEST) || defined(SQLITE_MUTATION_TEST)
100# define SQLITE_OMIT_AUXILIARY_SAFETY_CHECKS 1
101# endif
102# if defined(SQLITE_OMIT_AUXILIARY_SAFETY_CHECKS)
103# define ALWAYS(X) (1)
104# define NEVER(X) (0)
105# elif !defined(NDEBUG)
106# define ALWAYS(X) ((X)?1:(assert(0),0))
107# define NEVER(X) ((X)?(assert(0),1):0)
108# else
109# define ALWAYS(X) (X)
110# define NEVER(X) (X)
111# endif
drh285f2ef2021-10-15 16:15:04 +0000112# define testcase(X)
drh9a4718f2015-10-10 14:00:37 +0000113#endif
drh16fc5e62021-11-01 12:53:01 +0000114#if !defined(SQLITE_DEBUG) && !defined(SQLITE_COVERAGE_TEST)
drh285f2ef2021-10-15 16:15:04 +0000115# define VVA(X)
116#else
117# define VVA(X) X
118#endif
119
120/*
121** Some of the testcase() macros in this file are problematic for gcov
122** in that they generate false-miss errors randomly. This is a gcov problem,
123** not a problem in this case. But to work around it, we disable the
124** problematic test cases for production builds.
125*/
126#define json_testcase(X)
drh5fa5c102015-08-12 16:49:40 +0000127
drh52216ad2015-08-18 02:28:03 +0000128/* Objects */
drh505ad2c2015-08-21 17:33:11 +0000129typedef struct JsonString JsonString;
drh52216ad2015-08-18 02:28:03 +0000130typedef struct JsonNode JsonNode;
131typedef struct JsonParse JsonParse;
132
drh5634cc02015-08-17 11:28:03 +0000133/* An instance of this object represents a JSON string
134** under construction. Really, this is a generic string accumulator
135** that can be and is used to create strings other than JSON.
drh5fa5c102015-08-12 16:49:40 +0000136*/
drh505ad2c2015-08-21 17:33:11 +0000137struct JsonString {
drh5fa5c102015-08-12 16:49:40 +0000138 sqlite3_context *pCtx; /* Function context - put error messages here */
drh5634cc02015-08-17 11:28:03 +0000139 char *zBuf; /* Append JSON content here */
drh5fa5c102015-08-12 16:49:40 +0000140 u64 nAlloc; /* Bytes of storage available in zBuf[] */
141 u64 nUsed; /* Bytes of zBuf[] currently used */
142 u8 bStatic; /* True if zBuf is static space */
drhd0960592015-08-17 21:22:32 +0000143 u8 bErr; /* True if an error has been encountered */
drh5fa5c102015-08-12 16:49:40 +0000144 char zSpace[100]; /* Initial static space */
145};
146
drhe9c37f32015-08-15 21:25:36 +0000147/* JSON type values
drhbd0621b2015-08-13 13:54:59 +0000148*/
drhe9c37f32015-08-15 21:25:36 +0000149#define JSON_NULL 0
150#define JSON_TRUE 1
151#define JSON_FALSE 2
152#define JSON_INT 3
153#define JSON_REAL 4
154#define JSON_STRING 5
155#define JSON_ARRAY 6
156#define JSON_OBJECT 7
157
drhf5ddb9c2015-09-11 00:06:41 +0000158/* The "subtype" set for JSON values */
159#define JSON_SUBTYPE 74 /* Ascii for "J" */
160
drh987eb1f2015-08-17 15:17:37 +0000161/*
162** Names of the various JSON types:
163*/
164static const char * const jsonType[] = {
165 "null", "true", "false", "integer", "real", "text", "array", "object"
166};
167
drh301eecc2015-08-17 20:14:19 +0000168/* Bit values for the JsonNode.jnFlag field
169*/
170#define JNODE_RAW 0x01 /* Content is raw, not JSON encoded */
171#define JNODE_ESCAPE 0x02 /* Content is text with \ escapes */
172#define JNODE_REMOVE 0x04 /* Do not output */
drh633647a2017-03-22 21:24:31 +0000173#define JNODE_REPLACE 0x08 /* Replace with JsonNode.u.iReplace */
174#define JNODE_PATCH 0x10 /* Patch with JsonNode.u.pPatch */
175#define JNODE_APPEND 0x20 /* More ARRAY/OBJECT entries at u.iAppend */
176#define JNODE_LABEL 0x40 /* Is a label of an object */
drh301eecc2015-08-17 20:14:19 +0000177
drh987eb1f2015-08-17 15:17:37 +0000178
drhe9c37f32015-08-15 21:25:36 +0000179/* A single node of parsed JSON
180*/
drhe9c37f32015-08-15 21:25:36 +0000181struct JsonNode {
drh5634cc02015-08-17 11:28:03 +0000182 u8 eType; /* One of the JSON_ type values */
drh301eecc2015-08-17 20:14:19 +0000183 u8 jnFlags; /* JNODE flags */
drh285f2ef2021-10-15 16:15:04 +0000184 u8 eU; /* Which union element to use */
drhe9c37f32015-08-15 21:25:36 +0000185 u32 n; /* Bytes of content, or number of sub-nodes */
drh52216ad2015-08-18 02:28:03 +0000186 union {
drh285f2ef2021-10-15 16:15:04 +0000187 const char *zJContent; /* 1: Content for INT, REAL, and STRING */
188 u32 iAppend; /* 2: More terms for ARRAY and OBJECT */
189 u32 iKey; /* 3: Key for ARRAY objects in json_tree() */
190 u32 iReplace; /* 4: Replacement content for JNODE_REPLACE */
191 JsonNode *pPatch; /* 5: Node chain of patch for JNODE_PATCH */
drh52216ad2015-08-18 02:28:03 +0000192 } u;
drhe9c37f32015-08-15 21:25:36 +0000193};
194
195/* A completely parsed JSON string
196*/
drhe9c37f32015-08-15 21:25:36 +0000197struct JsonParse {
198 u32 nNode; /* Number of slots of aNode[] used */
199 u32 nAlloc; /* Number of slots of aNode[] allocated */
200 JsonNode *aNode; /* Array of nodes containing the parse */
201 const char *zJson; /* Original JSON string */
drh505ad2c2015-08-21 17:33:11 +0000202 u32 *aUp; /* Index of parent of each node */
drhe9c37f32015-08-15 21:25:36 +0000203 u8 oom; /* Set to true if out of memory */
drha7714022015-08-29 00:54:49 +0000204 u8 nErr; /* Number of errors seen */
drhff6d50e2017-04-11 18:55:05 +0000205 u16 iDepth; /* Nesting depth */
drh3fb153c2017-05-11 16:49:59 +0000206 int nJson; /* Length of the zJson string in bytes */
drhe35fc302018-08-30 01:52:10 +0000207 u32 iHold; /* Replace cache line with the lowest iHold value */
drhe9c37f32015-08-15 21:25:36 +0000208};
209
drhff6d50e2017-04-11 18:55:05 +0000210/*
211** Maximum nesting depth of JSON for this implementation.
212**
213** This limit is needed to avoid a stack overflow in the recursive
214** descent parser. A depth of 2000 is far deeper than any sane JSON
215** should go.
216*/
217#define JSON_MAX_DEPTH 2000
218
drh505ad2c2015-08-21 17:33:11 +0000219/**************************************************************************
220** Utility routines for dealing with JsonString objects
221**************************************************************************/
drh301eecc2015-08-17 20:14:19 +0000222
drh505ad2c2015-08-21 17:33:11 +0000223/* Set the JsonString object to an empty string
drh5fa5c102015-08-12 16:49:40 +0000224*/
drh505ad2c2015-08-21 17:33:11 +0000225static void jsonZero(JsonString *p){
drh5fa5c102015-08-12 16:49:40 +0000226 p->zBuf = p->zSpace;
227 p->nAlloc = sizeof(p->zSpace);
228 p->nUsed = 0;
229 p->bStatic = 1;
230}
231
drh505ad2c2015-08-21 17:33:11 +0000232/* Initialize the JsonString object
drh5fa5c102015-08-12 16:49:40 +0000233*/
drh505ad2c2015-08-21 17:33:11 +0000234static void jsonInit(JsonString *p, sqlite3_context *pCtx){
drh5fa5c102015-08-12 16:49:40 +0000235 p->pCtx = pCtx;
drhd0960592015-08-17 21:22:32 +0000236 p->bErr = 0;
drh5fa5c102015-08-12 16:49:40 +0000237 jsonZero(p);
238}
239
240
drh505ad2c2015-08-21 17:33:11 +0000241/* Free all allocated memory and reset the JsonString object back to its
drh5fa5c102015-08-12 16:49:40 +0000242** initial state.
243*/
drh505ad2c2015-08-21 17:33:11 +0000244static void jsonReset(JsonString *p){
drh5fa5c102015-08-12 16:49:40 +0000245 if( !p->bStatic ) sqlite3_free(p->zBuf);
246 jsonZero(p);
247}
248
249
250/* Report an out-of-memory (OOM) condition
251*/
drh505ad2c2015-08-21 17:33:11 +0000252static void jsonOom(JsonString *p){
drh3d1d2a92015-09-22 01:15:49 +0000253 p->bErr = 1;
254 sqlite3_result_error_nomem(p->pCtx);
255 jsonReset(p);
drh5fa5c102015-08-12 16:49:40 +0000256}
257
258/* Enlarge pJson->zBuf so that it can hold at least N more bytes.
259** Return zero on success. Return non-zero on an OOM error
260*/
drh505ad2c2015-08-21 17:33:11 +0000261static int jsonGrow(JsonString *p, u32 N){
drh301eecc2015-08-17 20:14:19 +0000262 u64 nTotal = N<p->nAlloc ? p->nAlloc*2 : p->nAlloc+N+10;
drh5fa5c102015-08-12 16:49:40 +0000263 char *zNew;
264 if( p->bStatic ){
drhd0960592015-08-17 21:22:32 +0000265 if( p->bErr ) return 1;
drh5fa5c102015-08-12 16:49:40 +0000266 zNew = sqlite3_malloc64(nTotal);
267 if( zNew==0 ){
268 jsonOom(p);
269 return SQLITE_NOMEM;
270 }
drh6fd5c1e2015-08-21 20:37:12 +0000271 memcpy(zNew, p->zBuf, (size_t)p->nUsed);
drh5fa5c102015-08-12 16:49:40 +0000272 p->zBuf = zNew;
273 p->bStatic = 0;
274 }else{
275 zNew = sqlite3_realloc64(p->zBuf, nTotal);
276 if( zNew==0 ){
277 jsonOom(p);
278 return SQLITE_NOMEM;
279 }
280 p->zBuf = zNew;
281 }
282 p->nAlloc = nTotal;
283 return SQLITE_OK;
284}
285
drh505ad2c2015-08-21 17:33:11 +0000286/* Append N bytes from zIn onto the end of the JsonString string.
drh5fa5c102015-08-12 16:49:40 +0000287*/
drh505ad2c2015-08-21 17:33:11 +0000288static void jsonAppendRaw(JsonString *p, const char *zIn, u32 N){
drhc795e3d2020-05-17 13:47:28 +0000289 if( N==0 ) return;
drh5fa5c102015-08-12 16:49:40 +0000290 if( (N+p->nUsed >= p->nAlloc) && jsonGrow(p,N)!=0 ) return;
291 memcpy(p->zBuf+p->nUsed, zIn, N);
292 p->nUsed += N;
293}
294
drh4af352d2015-08-21 20:02:48 +0000295/* Append formatted text (not to exceed N bytes) to the JsonString.
296*/
297static void jsonPrintf(int N, JsonString *p, const char *zFormat, ...){
298 va_list ap;
299 if( (p->nUsed + N >= p->nAlloc) && jsonGrow(p, N) ) return;
300 va_start(ap, zFormat);
301 sqlite3_vsnprintf(N, p->zBuf+p->nUsed, zFormat, ap);
302 va_end(ap);
303 p->nUsed += (int)strlen(p->zBuf+p->nUsed);
304}
305
drh5634cc02015-08-17 11:28:03 +0000306/* Append a single character
307*/
drh505ad2c2015-08-21 17:33:11 +0000308static void jsonAppendChar(JsonString *p, char c){
drh5634cc02015-08-17 11:28:03 +0000309 if( p->nUsed>=p->nAlloc && jsonGrow(p,1)!=0 ) return;
310 p->zBuf[p->nUsed++] = c;
311}
312
drh301eecc2015-08-17 20:14:19 +0000313/* Append a comma separator to the output buffer, if the previous
314** character is not '[' or '{'.
315*/
drh505ad2c2015-08-21 17:33:11 +0000316static void jsonAppendSeparator(JsonString *p){
drh301eecc2015-08-17 20:14:19 +0000317 char c;
318 if( p->nUsed==0 ) return;
319 c = p->zBuf[p->nUsed-1];
320 if( c!='[' && c!='{' ) jsonAppendChar(p, ',');
321}
322
drh505ad2c2015-08-21 17:33:11 +0000323/* Append the N-byte string in zIn to the end of the JsonString string
drh5fa5c102015-08-12 16:49:40 +0000324** under construction. Enclose the string in "..." and escape
325** any double-quotes or backslash characters contained within the
326** string.
327*/
drh505ad2c2015-08-21 17:33:11 +0000328static void jsonAppendString(JsonString *p, const char *zIn, u32 N){
drh5fa5c102015-08-12 16:49:40 +0000329 u32 i;
drh76baad92021-04-30 16:12:40 +0000330 if( zIn==0 || ((N+p->nUsed+2 >= p->nAlloc) && jsonGrow(p,N+2)!=0) ) return;
drh5fa5c102015-08-12 16:49:40 +0000331 p->zBuf[p->nUsed++] = '"';
332 for(i=0; i<N; i++){
drh3b7f9a62016-02-04 10:28:57 +0000333 unsigned char c = ((unsigned const char*)zIn)[i];
drh5fa5c102015-08-12 16:49:40 +0000334 if( c=='"' || c=='\\' ){
drh3b7f9a62016-02-04 10:28:57 +0000335 json_simple_escape:
drh4977ccf2015-09-19 11:57:26 +0000336 if( (p->nUsed+N+3-i > p->nAlloc) && jsonGrow(p,N+3-i)!=0 ) return;
drh5fa5c102015-08-12 16:49:40 +0000337 p->zBuf[p->nUsed++] = '\\';
drh3b7f9a62016-02-04 10:28:57 +0000338 }else if( c<=0x1f ){
339 static const char aSpecial[] = {
340 0, 0, 0, 0, 0, 0, 0, 0, 'b', 't', 'n', 0, 'f', 'r', 0, 0,
341 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
342 };
343 assert( sizeof(aSpecial)==32 );
344 assert( aSpecial['\b']=='b' );
345 assert( aSpecial['\f']=='f' );
346 assert( aSpecial['\n']=='n' );
347 assert( aSpecial['\r']=='r' );
348 assert( aSpecial['\t']=='t' );
349 if( aSpecial[c] ){
350 c = aSpecial[c];
351 goto json_simple_escape;
352 }
353 if( (p->nUsed+N+7+i > p->nAlloc) && jsonGrow(p,N+7-i)!=0 ) return;
354 p->zBuf[p->nUsed++] = '\\';
355 p->zBuf[p->nUsed++] = 'u';
356 p->zBuf[p->nUsed++] = '0';
357 p->zBuf[p->nUsed++] = '0';
358 p->zBuf[p->nUsed++] = '0' + (c>>4);
359 c = "0123456789abcdef"[c&0xf];
drh5fa5c102015-08-12 16:49:40 +0000360 }
361 p->zBuf[p->nUsed++] = c;
362 }
363 p->zBuf[p->nUsed++] = '"';
drh4977ccf2015-09-19 11:57:26 +0000364 assert( p->nUsed<p->nAlloc );
drh5fa5c102015-08-12 16:49:40 +0000365}
366
drhd0960592015-08-17 21:22:32 +0000367/*
368** Append a function parameter value to the JSON string under
369** construction.
370*/
371static void jsonAppendValue(
drh505ad2c2015-08-21 17:33:11 +0000372 JsonString *p, /* Append to this JSON string */
drhf5ddb9c2015-09-11 00:06:41 +0000373 sqlite3_value *pValue /* Value to append */
drhd0960592015-08-17 21:22:32 +0000374){
375 switch( sqlite3_value_type(pValue) ){
376 case SQLITE_NULL: {
377 jsonAppendRaw(p, "null", 4);
378 break;
379 }
380 case SQLITE_INTEGER:
381 case SQLITE_FLOAT: {
382 const char *z = (const char*)sqlite3_value_text(pValue);
383 u32 n = (u32)sqlite3_value_bytes(pValue);
384 jsonAppendRaw(p, z, n);
385 break;
386 }
387 case SQLITE_TEXT: {
388 const char *z = (const char*)sqlite3_value_text(pValue);
389 u32 n = (u32)sqlite3_value_bytes(pValue);
drhf5ddb9c2015-09-11 00:06:41 +0000390 if( sqlite3_value_subtype(pValue)==JSON_SUBTYPE ){
drhecb5fed2015-08-28 03:33:50 +0000391 jsonAppendRaw(p, z, n);
392 }else{
393 jsonAppendString(p, z, n);
394 }
drhd0960592015-08-17 21:22:32 +0000395 break;
396 }
397 default: {
398 if( p->bErr==0 ){
399 sqlite3_result_error(p->pCtx, "JSON cannot hold BLOB values", -1);
drh4a642b62016-02-05 01:55:27 +0000400 p->bErr = 2;
drhd0960592015-08-17 21:22:32 +0000401 jsonReset(p);
402 }
403 break;
404 }
405 }
406}
407
408
drhbd0621b2015-08-13 13:54:59 +0000409/* Make the JSON in p the result of the SQL function.
drh5fa5c102015-08-12 16:49:40 +0000410*/
drh505ad2c2015-08-21 17:33:11 +0000411static void jsonResult(JsonString *p){
drhd0960592015-08-17 21:22:32 +0000412 if( p->bErr==0 ){
drh5fa5c102015-08-12 16:49:40 +0000413 sqlite3_result_text64(p->pCtx, p->zBuf, p->nUsed,
414 p->bStatic ? SQLITE_TRANSIENT : sqlite3_free,
415 SQLITE_UTF8);
416 jsonZero(p);
417 }
418 assert( p->bStatic );
419}
420
drh505ad2c2015-08-21 17:33:11 +0000421/**************************************************************************
422** Utility routines for dealing with JsonNode and JsonParse objects
423**************************************************************************/
424
425/*
426** Return the number of consecutive JsonNode slots need to represent
427** the parsed JSON at pNode. The minimum answer is 1. For ARRAY and
428** OBJECT types, the number might be larger.
429**
430** Appended elements are not counted. The value returned is the number
431** by which the JsonNode counter should increment in order to go to the
432** next peer value.
433*/
434static u32 jsonNodeSize(JsonNode *pNode){
435 return pNode->eType>=JSON_ARRAY ? pNode->n+1 : 1;
436}
437
438/*
439** Reclaim all memory allocated by a JsonParse object. But do not
440** delete the JsonParse object itself.
441*/
442static void jsonParseReset(JsonParse *pParse){
443 sqlite3_free(pParse->aNode);
444 pParse->aNode = 0;
445 pParse->nNode = 0;
446 pParse->nAlloc = 0;
447 sqlite3_free(pParse->aUp);
448 pParse->aUp = 0;
449}
450
drh5634cc02015-08-17 11:28:03 +0000451/*
drh3fb153c2017-05-11 16:49:59 +0000452** Free a JsonParse object that was obtained from sqlite3_malloc().
453*/
454static void jsonParseFree(JsonParse *pParse){
455 jsonParseReset(pParse);
456 sqlite3_free(pParse);
457}
458
459/*
drh5634cc02015-08-17 11:28:03 +0000460** Convert the JsonNode pNode into a pure JSON string and
461** append to pOut. Subsubstructure is also included. Return
462** the number of JsonNode objects that are encoded.
drhbd0621b2015-08-13 13:54:59 +0000463*/
drh52216ad2015-08-18 02:28:03 +0000464static void jsonRenderNode(
drhd0960592015-08-17 21:22:32 +0000465 JsonNode *pNode, /* The node to render */
drh505ad2c2015-08-21 17:33:11 +0000466 JsonString *pOut, /* Write JSON here */
drhd0960592015-08-17 21:22:32 +0000467 sqlite3_value **aReplace /* Replacement values */
468){
drh7d4c94b2021-10-04 22:34:38 +0000469 assert( pNode!=0 );
drh633647a2017-03-22 21:24:31 +0000470 if( pNode->jnFlags & (JNODE_REPLACE|JNODE_PATCH) ){
drh7d4c94b2021-10-04 22:34:38 +0000471 if( (pNode->jnFlags & JNODE_REPLACE)!=0 && ALWAYS(aReplace!=0) ){
drh285f2ef2021-10-15 16:15:04 +0000472 assert( pNode->eU==4 );
drh633647a2017-03-22 21:24:31 +0000473 jsonAppendValue(pOut, aReplace[pNode->u.iReplace]);
474 return;
475 }
drh285f2ef2021-10-15 16:15:04 +0000476 assert( pNode->eU==5 );
drh633647a2017-03-22 21:24:31 +0000477 pNode = pNode->u.pPatch;
478 }
drh5634cc02015-08-17 11:28:03 +0000479 switch( pNode->eType ){
drha8f39a92015-09-21 22:53:16 +0000480 default: {
481 assert( pNode->eType==JSON_NULL );
drh5634cc02015-08-17 11:28:03 +0000482 jsonAppendRaw(pOut, "null", 4);
483 break;
484 }
485 case JSON_TRUE: {
486 jsonAppendRaw(pOut, "true", 4);
487 break;
488 }
489 case JSON_FALSE: {
490 jsonAppendRaw(pOut, "false", 5);
491 break;
492 }
493 case JSON_STRING: {
drh301eecc2015-08-17 20:14:19 +0000494 if( pNode->jnFlags & JNODE_RAW ){
drh285f2ef2021-10-15 16:15:04 +0000495 assert( pNode->eU==1 );
drh52216ad2015-08-18 02:28:03 +0000496 jsonAppendString(pOut, pNode->u.zJContent, pNode->n);
drh5634cc02015-08-17 11:28:03 +0000497 break;
498 }
drh08b92082020-08-10 14:18:00 +0000499 /* no break */ deliberate_fall_through
drh5634cc02015-08-17 11:28:03 +0000500 }
501 case JSON_REAL:
502 case JSON_INT: {
drh285f2ef2021-10-15 16:15:04 +0000503 assert( pNode->eU==1 );
drh52216ad2015-08-18 02:28:03 +0000504 jsonAppendRaw(pOut, pNode->u.zJContent, pNode->n);
drh5634cc02015-08-17 11:28:03 +0000505 break;
506 }
507 case JSON_ARRAY: {
drh52216ad2015-08-18 02:28:03 +0000508 u32 j = 1;
drh5634cc02015-08-17 11:28:03 +0000509 jsonAppendChar(pOut, '[');
drh52216ad2015-08-18 02:28:03 +0000510 for(;;){
511 while( j<=pNode->n ){
drh633647a2017-03-22 21:24:31 +0000512 if( (pNode[j].jnFlags & JNODE_REMOVE)==0 ){
drhd0960592015-08-17 21:22:32 +0000513 jsonAppendSeparator(pOut);
drh52216ad2015-08-18 02:28:03 +0000514 jsonRenderNode(&pNode[j], pOut, aReplace);
drhd0960592015-08-17 21:22:32 +0000515 }
drh505ad2c2015-08-21 17:33:11 +0000516 j += jsonNodeSize(&pNode[j]);
drh301eecc2015-08-17 20:14:19 +0000517 }
drh52216ad2015-08-18 02:28:03 +0000518 if( (pNode->jnFlags & JNODE_APPEND)==0 ) break;
drh285f2ef2021-10-15 16:15:04 +0000519 assert( pNode->eU==2 );
drh52216ad2015-08-18 02:28:03 +0000520 pNode = &pNode[pNode->u.iAppend];
521 j = 1;
drh5634cc02015-08-17 11:28:03 +0000522 }
523 jsonAppendChar(pOut, ']');
524 break;
525 }
526 case JSON_OBJECT: {
drh52216ad2015-08-18 02:28:03 +0000527 u32 j = 1;
drh5634cc02015-08-17 11:28:03 +0000528 jsonAppendChar(pOut, '{');
drh52216ad2015-08-18 02:28:03 +0000529 for(;;){
530 while( j<=pNode->n ){
531 if( (pNode[j+1].jnFlags & JNODE_REMOVE)==0 ){
532 jsonAppendSeparator(pOut);
533 jsonRenderNode(&pNode[j], pOut, aReplace);
534 jsonAppendChar(pOut, ':');
drh633647a2017-03-22 21:24:31 +0000535 jsonRenderNode(&pNode[j+1], pOut, aReplace);
drhd0960592015-08-17 21:22:32 +0000536 }
drh505ad2c2015-08-21 17:33:11 +0000537 j += 1 + jsonNodeSize(&pNode[j+1]);
drh301eecc2015-08-17 20:14:19 +0000538 }
drh52216ad2015-08-18 02:28:03 +0000539 if( (pNode->jnFlags & JNODE_APPEND)==0 ) break;
drh285f2ef2021-10-15 16:15:04 +0000540 assert( pNode->eU==2 );
drh52216ad2015-08-18 02:28:03 +0000541 pNode = &pNode[pNode->u.iAppend];
542 j = 1;
drh5634cc02015-08-17 11:28:03 +0000543 }
544 jsonAppendChar(pOut, '}');
545 break;
546 }
drhbd0621b2015-08-13 13:54:59 +0000547 }
drh5634cc02015-08-17 11:28:03 +0000548}
549
550/*
drhf2df7e72015-08-28 20:07:40 +0000551** Return a JsonNode and all its descendents as a JSON string.
552*/
553static void jsonReturnJson(
554 JsonNode *pNode, /* Node to return */
555 sqlite3_context *pCtx, /* Return value for this function */
556 sqlite3_value **aReplace /* Array of replacement values */
557){
558 JsonString s;
559 jsonInit(&s, pCtx);
560 jsonRenderNode(pNode, &s, aReplace);
561 jsonResult(&s);
drhf5ddb9c2015-09-11 00:06:41 +0000562 sqlite3_result_subtype(pCtx, JSON_SUBTYPE);
drhf2df7e72015-08-28 20:07:40 +0000563}
564
565/*
drh48eb03b2019-11-10 11:09:06 +0000566** Translate a single byte of Hex into an integer.
567** This routine only works if h really is a valid hexadecimal
568** character: 0..9a..fA..F
569*/
570static u8 jsonHexToInt(int h){
571 assert( (h>='0' && h<='9') || (h>='a' && h<='f') || (h>='A' && h<='F') );
572#ifdef SQLITE_EBCDIC
573 h += 9*(1&~(h>>4));
574#else
575 h += 9*(1&(h>>6));
576#endif
577 return (u8)(h & 0xf);
578}
579
580/*
581** Convert a 4-byte hex string into an integer
582*/
583static u32 jsonHexToInt4(const char *z){
584 u32 v;
585 assert( safe_isxdigit(z[0]) );
586 assert( safe_isxdigit(z[1]) );
587 assert( safe_isxdigit(z[2]) );
588 assert( safe_isxdigit(z[3]) );
589 v = (jsonHexToInt(z[0])<<12)
590 + (jsonHexToInt(z[1])<<8)
591 + (jsonHexToInt(z[2])<<4)
592 + jsonHexToInt(z[3]);
593 return v;
594}
595
596/*
drh5634cc02015-08-17 11:28:03 +0000597** Make the JsonNode the return value of the function.
598*/
drhd0960592015-08-17 21:22:32 +0000599static void jsonReturn(
600 JsonNode *pNode, /* Node to return */
601 sqlite3_context *pCtx, /* Return value for this function */
602 sqlite3_value **aReplace /* Array of replacement values */
603){
drh5634cc02015-08-17 11:28:03 +0000604 switch( pNode->eType ){
drha8f39a92015-09-21 22:53:16 +0000605 default: {
606 assert( pNode->eType==JSON_NULL );
drh5634cc02015-08-17 11:28:03 +0000607 sqlite3_result_null(pCtx);
608 break;
609 }
610 case JSON_TRUE: {
611 sqlite3_result_int(pCtx, 1);
612 break;
613 }
614 case JSON_FALSE: {
615 sqlite3_result_int(pCtx, 0);
616 break;
617 }
drh987eb1f2015-08-17 15:17:37 +0000618 case JSON_INT: {
619 sqlite3_int64 i = 0;
drh285f2ef2021-10-15 16:15:04 +0000620 const char *z;
621 assert( pNode->eU==1 );
622 z = pNode->u.zJContent;
drh987eb1f2015-08-17 15:17:37 +0000623 if( z[0]=='-' ){ z++; }
drh8deb4b82015-10-09 18:21:43 +0000624 while( z[0]>='0' && z[0]<='9' ){
625 unsigned v = *(z++) - '0';
626 if( i>=LARGEST_INT64/10 ){
drha0882fa2015-10-09 20:40:44 +0000627 if( i>LARGEST_INT64/10 ) goto int_as_real;
drh8deb4b82015-10-09 18:21:43 +0000628 if( z[0]>='0' && z[0]<='9' ) goto int_as_real;
629 if( v==9 ) goto int_as_real;
630 if( v==8 ){
631 if( pNode->u.zJContent[0]=='-' ){
632 sqlite3_result_int64(pCtx, SMALLEST_INT64);
633 goto int_done;
634 }else{
635 goto int_as_real;
636 }
637 }
638 }
639 i = i*10 + v;
640 }
drh52216ad2015-08-18 02:28:03 +0000641 if( pNode->u.zJContent[0]=='-' ){ i = -i; }
drh987eb1f2015-08-17 15:17:37 +0000642 sqlite3_result_int64(pCtx, i);
drh8deb4b82015-10-09 18:21:43 +0000643 int_done:
644 break;
drhe85e1da2021-10-01 21:01:07 +0000645 int_as_real: ; /* no break */ deliberate_fall_through
drh8deb4b82015-10-09 18:21:43 +0000646 }
647 case JSON_REAL: {
drh49472652015-10-16 15:35:39 +0000648 double r;
649#ifdef SQLITE_AMALGAMATION
drh285f2ef2021-10-15 16:15:04 +0000650 const char *z;
651 assert( pNode->eU==1 );
652 z = pNode->u.zJContent;
drh49472652015-10-16 15:35:39 +0000653 sqlite3AtoF(z, &r, sqlite3Strlen30(z), SQLITE_UTF8);
654#else
drh285f2ef2021-10-15 16:15:04 +0000655 assert( pNode->eU==1 );
drh49472652015-10-16 15:35:39 +0000656 r = strtod(pNode->u.zJContent, 0);
657#endif
drh8deb4b82015-10-09 18:21:43 +0000658 sqlite3_result_double(pCtx, r);
drh987eb1f2015-08-17 15:17:37 +0000659 break;
660 }
drh5634cc02015-08-17 11:28:03 +0000661 case JSON_STRING: {
drha8f39a92015-09-21 22:53:16 +0000662#if 0 /* Never happens because JNODE_RAW is only set by json_set(),
663 ** json_insert() and json_replace() and those routines do not
664 ** call jsonReturn() */
drh301eecc2015-08-17 20:14:19 +0000665 if( pNode->jnFlags & JNODE_RAW ){
drh285f2ef2021-10-15 16:15:04 +0000666 assert( pNode->eU==1 );
drh52216ad2015-08-18 02:28:03 +0000667 sqlite3_result_text(pCtx, pNode->u.zJContent, pNode->n,
668 SQLITE_TRANSIENT);
drha8f39a92015-09-21 22:53:16 +0000669 }else
670#endif
671 assert( (pNode->jnFlags & JNODE_RAW)==0 );
672 if( (pNode->jnFlags & JNODE_ESCAPE)==0 ){
drh987eb1f2015-08-17 15:17:37 +0000673 /* JSON formatted without any backslash-escapes */
drh285f2ef2021-10-15 16:15:04 +0000674 assert( pNode->eU==1 );
drh52216ad2015-08-18 02:28:03 +0000675 sqlite3_result_text(pCtx, pNode->u.zJContent+1, pNode->n-2,
drh987eb1f2015-08-17 15:17:37 +0000676 SQLITE_TRANSIENT);
drh5634cc02015-08-17 11:28:03 +0000677 }else{
678 /* Translate JSON formatted string into raw text */
drh987eb1f2015-08-17 15:17:37 +0000679 u32 i;
680 u32 n = pNode->n;
drh285f2ef2021-10-15 16:15:04 +0000681 const char *z;
drh987eb1f2015-08-17 15:17:37 +0000682 char *zOut;
683 u32 j;
drh285f2ef2021-10-15 16:15:04 +0000684 assert( pNode->eU==1 );
685 z = pNode->u.zJContent;
drh987eb1f2015-08-17 15:17:37 +0000686 zOut = sqlite3_malloc( n+1 );
687 if( zOut==0 ){
688 sqlite3_result_error_nomem(pCtx);
689 break;
690 }
691 for(i=1, j=0; i<n-1; i++){
692 char c = z[i];
drh80d87402015-08-24 12:42:41 +0000693 if( c!='\\' ){
drh987eb1f2015-08-17 15:17:37 +0000694 zOut[j++] = c;
695 }else{
696 c = z[++i];
drh80d87402015-08-24 12:42:41 +0000697 if( c=='u' ){
drh48eb03b2019-11-10 11:09:06 +0000698 u32 v = jsonHexToInt4(z+i+1);
699 i += 4;
drh80d87402015-08-24 12:42:41 +0000700 if( v==0 ) break;
drh987eb1f2015-08-17 15:17:37 +0000701 if( v<=0x7f ){
mistachkin16a93122015-09-11 18:05:01 +0000702 zOut[j++] = (char)v;
drh987eb1f2015-08-17 15:17:37 +0000703 }else if( v<=0x7ff ){
mistachkin16a93122015-09-11 18:05:01 +0000704 zOut[j++] = (char)(0xc0 | (v>>6));
drh987eb1f2015-08-17 15:17:37 +0000705 zOut[j++] = 0x80 | (v&0x3f);
drh80d87402015-08-24 12:42:41 +0000706 }else{
drh48eb03b2019-11-10 11:09:06 +0000707 u32 vlo;
708 if( (v&0xfc00)==0xd800
709 && i<n-6
710 && z[i+1]=='\\'
711 && z[i+2]=='u'
712 && ((vlo = jsonHexToInt4(z+i+3))&0xfc00)==0xdc00
713 ){
714 /* We have a surrogate pair */
715 v = ((v&0x3ff)<<10) + (vlo&0x3ff) + 0x10000;
716 i += 6;
717 zOut[j++] = 0xf0 | (v>>18);
718 zOut[j++] = 0x80 | ((v>>12)&0x3f);
719 zOut[j++] = 0x80 | ((v>>6)&0x3f);
720 zOut[j++] = 0x80 | (v&0x3f);
721 }else{
722 zOut[j++] = 0xe0 | (v>>12);
723 zOut[j++] = 0x80 | ((v>>6)&0x3f);
724 zOut[j++] = 0x80 | (v&0x3f);
725 }
drh987eb1f2015-08-17 15:17:37 +0000726 }
727 }else{
728 if( c=='b' ){
729 c = '\b';
730 }else if( c=='f' ){
731 c = '\f';
732 }else if( c=='n' ){
733 c = '\n';
734 }else if( c=='r' ){
735 c = '\r';
736 }else if( c=='t' ){
737 c = '\t';
738 }
739 zOut[j++] = c;
740 }
741 }
742 }
743 zOut[j] = 0;
744 sqlite3_result_text(pCtx, zOut, j, sqlite3_free);
drh5634cc02015-08-17 11:28:03 +0000745 }
746 break;
747 }
748 case JSON_ARRAY:
749 case JSON_OBJECT: {
drhf2df7e72015-08-28 20:07:40 +0000750 jsonReturnJson(pNode, pCtx, aReplace);
drh5634cc02015-08-17 11:28:03 +0000751 break;
752 }
753 }
drhbd0621b2015-08-13 13:54:59 +0000754}
755
drh95677942015-09-24 01:06:37 +0000756/* Forward reference */
757static int jsonParseAddNode(JsonParse*,u32,u32,const char*);
758
759/*
760** A macro to hint to the compiler that a function should not be
761** inlined.
762*/
763#if defined(__GNUC__)
764# define JSON_NOINLINE __attribute__((noinline))
765#elif defined(_MSC_VER) && _MSC_VER>=1310
766# define JSON_NOINLINE __declspec(noinline)
767#else
768# define JSON_NOINLINE
769#endif
770
771
772static JSON_NOINLINE int jsonParseAddNodeExpand(
773 JsonParse *pParse, /* Append the node to this object */
774 u32 eType, /* Node type */
775 u32 n, /* Content size or sub-node count */
776 const char *zContent /* Content */
777){
778 u32 nNew;
779 JsonNode *pNew;
780 assert( pParse->nNode>=pParse->nAlloc );
781 if( pParse->oom ) return -1;
782 nNew = pParse->nAlloc*2 + 10;
drh2d77d802019-01-08 20:02:48 +0000783 pNew = sqlite3_realloc64(pParse->aNode, sizeof(JsonNode)*nNew);
drh95677942015-09-24 01:06:37 +0000784 if( pNew==0 ){
785 pParse->oom = 1;
786 return -1;
787 }
788 pParse->nAlloc = nNew;
789 pParse->aNode = pNew;
790 assert( pParse->nNode<pParse->nAlloc );
791 return jsonParseAddNode(pParse, eType, n, zContent);
792}
793
drh5fa5c102015-08-12 16:49:40 +0000794/*
drhe9c37f32015-08-15 21:25:36 +0000795** Create a new JsonNode instance based on the arguments and append that
796** instance to the JsonParse. Return the index in pParse->aNode[] of the
797** new node, or -1 if a memory allocation fails.
798*/
799static int jsonParseAddNode(
800 JsonParse *pParse, /* Append the node to this object */
801 u32 eType, /* Node type */
802 u32 n, /* Content size or sub-node count */
803 const char *zContent /* Content */
804){
805 JsonNode *p;
drhaa6fe5b2021-10-04 13:18:44 +0000806 if( pParse->aNode==0 || pParse->nNode>=pParse->nAlloc ){
drh95677942015-09-24 01:06:37 +0000807 return jsonParseAddNodeExpand(pParse, eType, n, zContent);
drhe9c37f32015-08-15 21:25:36 +0000808 }
809 p = &pParse->aNode[pParse->nNode];
drh5634cc02015-08-17 11:28:03 +0000810 p->eType = (u8)eType;
drh301eecc2015-08-17 20:14:19 +0000811 p->jnFlags = 0;
drh285f2ef2021-10-15 16:15:04 +0000812 VVA( p->eU = zContent ? 1 : 0 );
drhe9c37f32015-08-15 21:25:36 +0000813 p->n = n;
drh52216ad2015-08-18 02:28:03 +0000814 p->u.zJContent = zContent;
drhe9c37f32015-08-15 21:25:36 +0000815 return pParse->nNode++;
816}
817
818/*
drhad875e72016-11-07 13:37:28 +0000819** Return true if z[] begins with 4 (or more) hexadecimal digits
820*/
821static int jsonIs4Hex(const char *z){
822 int i;
823 for(i=0; i<4; i++) if( !safe_isxdigit(z[i]) ) return 0;
824 return 1;
825}
826
827/*
drhe9c37f32015-08-15 21:25:36 +0000828** Parse a single JSON value which begins at pParse->zJson[i]. Return the
829** index of the first character past the end of the value parsed.
830**
831** Return negative for a syntax error. Special cases: return -2 if the
832** first non-whitespace character is '}' and return -3 if the first
833** non-whitespace character is ']'.
834*/
835static int jsonParseValue(JsonParse *pParse, u32 i){
836 char c;
837 u32 j;
drhbc8f0922015-08-22 19:39:04 +0000838 int iThis;
drhe9c37f32015-08-15 21:25:36 +0000839 int x;
drh852944e2015-09-10 03:29:11 +0000840 JsonNode *pNode;
drh9fa866a2017-04-08 18:18:22 +0000841 const char *z = pParse->zJson;
842 while( safe_isspace(z[i]) ){ i++; }
843 if( (c = z[i])=='{' ){
drhe9c37f32015-08-15 21:25:36 +0000844 /* Parse object */
845 iThis = jsonParseAddNode(pParse, JSON_OBJECT, 0, 0);
drhbc8f0922015-08-22 19:39:04 +0000846 if( iThis<0 ) return -1;
drhe9c37f32015-08-15 21:25:36 +0000847 for(j=i+1;;j++){
drh9fa866a2017-04-08 18:18:22 +0000848 while( safe_isspace(z[j]) ){ j++; }
drhff6d50e2017-04-11 18:55:05 +0000849 if( ++pParse->iDepth > JSON_MAX_DEPTH ) return -1;
drhe9c37f32015-08-15 21:25:36 +0000850 x = jsonParseValue(pParse, j);
851 if( x<0 ){
drhff6d50e2017-04-11 18:55:05 +0000852 pParse->iDepth--;
drhf27cd1f2015-09-23 01:10:29 +0000853 if( x==(-2) && pParse->nNode==(u32)iThis+1 ) return j+1;
drhe9c37f32015-08-15 21:25:36 +0000854 return -1;
855 }
drhbe9474e2015-08-22 03:05:54 +0000856 if( pParse->oom ) return -1;
drh852944e2015-09-10 03:29:11 +0000857 pNode = &pParse->aNode[pParse->nNode-1];
858 if( pNode->eType!=JSON_STRING ) return -1;
859 pNode->jnFlags |= JNODE_LABEL;
drhe9c37f32015-08-15 21:25:36 +0000860 j = x;
drh9fa866a2017-04-08 18:18:22 +0000861 while( safe_isspace(z[j]) ){ j++; }
862 if( z[j]!=':' ) return -1;
drhe9c37f32015-08-15 21:25:36 +0000863 j++;
864 x = jsonParseValue(pParse, j);
drhff6d50e2017-04-11 18:55:05 +0000865 pParse->iDepth--;
drhe9c37f32015-08-15 21:25:36 +0000866 if( x<0 ) return -1;
867 j = x;
drh9fa866a2017-04-08 18:18:22 +0000868 while( safe_isspace(z[j]) ){ j++; }
869 c = z[j];
drhe9c37f32015-08-15 21:25:36 +0000870 if( c==',' ) continue;
871 if( c!='}' ) return -1;
872 break;
873 }
drhbc8f0922015-08-22 19:39:04 +0000874 pParse->aNode[iThis].n = pParse->nNode - (u32)iThis - 1;
drhe9c37f32015-08-15 21:25:36 +0000875 return j+1;
876 }else if( c=='[' ){
877 /* Parse array */
878 iThis = jsonParseAddNode(pParse, JSON_ARRAY, 0, 0);
drhbc8f0922015-08-22 19:39:04 +0000879 if( iThis<0 ) return -1;
drh285f2ef2021-10-15 16:15:04 +0000880 memset(&pParse->aNode[iThis].u, 0, sizeof(pParse->aNode[iThis].u));
drhe9c37f32015-08-15 21:25:36 +0000881 for(j=i+1;;j++){
drh9fa866a2017-04-08 18:18:22 +0000882 while( safe_isspace(z[j]) ){ j++; }
drhff6d50e2017-04-11 18:55:05 +0000883 if( ++pParse->iDepth > JSON_MAX_DEPTH ) return -1;
drhe9c37f32015-08-15 21:25:36 +0000884 x = jsonParseValue(pParse, j);
drhff6d50e2017-04-11 18:55:05 +0000885 pParse->iDepth--;
drhe9c37f32015-08-15 21:25:36 +0000886 if( x<0 ){
drhf27cd1f2015-09-23 01:10:29 +0000887 if( x==(-3) && pParse->nNode==(u32)iThis+1 ) return j+1;
drhe9c37f32015-08-15 21:25:36 +0000888 return -1;
889 }
890 j = x;
drh9fa866a2017-04-08 18:18:22 +0000891 while( safe_isspace(z[j]) ){ j++; }
892 c = z[j];
drhe9c37f32015-08-15 21:25:36 +0000893 if( c==',' ) continue;
894 if( c!=']' ) return -1;
895 break;
896 }
drhbc8f0922015-08-22 19:39:04 +0000897 pParse->aNode[iThis].n = pParse->nNode - (u32)iThis - 1;
drhe9c37f32015-08-15 21:25:36 +0000898 return j+1;
899 }else if( c=='"' ){
900 /* Parse string */
drh301eecc2015-08-17 20:14:19 +0000901 u8 jnFlags = 0;
drhe9c37f32015-08-15 21:25:36 +0000902 j = i+1;
903 for(;;){
drh9fa866a2017-04-08 18:18:22 +0000904 c = z[j];
drh86715382017-04-13 00:12:32 +0000905 if( (c & ~0x1f)==0 ){
906 /* Control characters are not allowed in strings */
907 return -1;
908 }
drhe9c37f32015-08-15 21:25:36 +0000909 if( c=='\\' ){
drh9fa866a2017-04-08 18:18:22 +0000910 c = z[++j];
drhad875e72016-11-07 13:37:28 +0000911 if( c=='"' || c=='\\' || c=='/' || c=='b' || c=='f'
912 || c=='n' || c=='r' || c=='t'
drh9fa866a2017-04-08 18:18:22 +0000913 || (c=='u' && jsonIs4Hex(z+j+1)) ){
drhad875e72016-11-07 13:37:28 +0000914 jnFlags = JNODE_ESCAPE;
915 }else{
916 return -1;
917 }
drhe9c37f32015-08-15 21:25:36 +0000918 }else if( c=='"' ){
919 break;
920 }
921 j++;
922 }
drh9fa866a2017-04-08 18:18:22 +0000923 jsonParseAddNode(pParse, JSON_STRING, j+1-i, &z[i]);
drhbe9474e2015-08-22 03:05:54 +0000924 if( !pParse->oom ) pParse->aNode[pParse->nNode-1].jnFlags = jnFlags;
drhe9c37f32015-08-15 21:25:36 +0000925 return j+1;
926 }else if( c=='n'
drh9fa866a2017-04-08 18:18:22 +0000927 && strncmp(z+i,"null",4)==0
928 && !safe_isalnum(z[i+4]) ){
drhe9c37f32015-08-15 21:25:36 +0000929 jsonParseAddNode(pParse, JSON_NULL, 0, 0);
930 return i+4;
931 }else if( c=='t'
drh9fa866a2017-04-08 18:18:22 +0000932 && strncmp(z+i,"true",4)==0
933 && !safe_isalnum(z[i+4]) ){
drhe9c37f32015-08-15 21:25:36 +0000934 jsonParseAddNode(pParse, JSON_TRUE, 0, 0);
935 return i+4;
936 }else if( c=='f'
drh9fa866a2017-04-08 18:18:22 +0000937 && strncmp(z+i,"false",5)==0
938 && !safe_isalnum(z[i+5]) ){
drhe9c37f32015-08-15 21:25:36 +0000939 jsonParseAddNode(pParse, JSON_FALSE, 0, 0);
940 return i+5;
941 }else if( c=='-' || (c>='0' && c<='9') ){
942 /* Parse number */
943 u8 seenDP = 0;
944 u8 seenE = 0;
drh9fa866a2017-04-08 18:18:22 +0000945 assert( '-' < '0' );
946 if( c<='0' ){
947 j = c=='-' ? i+1 : i;
948 if( z[j]=='0' && z[j+1]>='0' && z[j+1]<='9' ) return -1;
949 }
drhe9c37f32015-08-15 21:25:36 +0000950 j = i+1;
951 for(;; j++){
drh9fa866a2017-04-08 18:18:22 +0000952 c = z[j];
drhe9c37f32015-08-15 21:25:36 +0000953 if( c>='0' && c<='9' ) continue;
954 if( c=='.' ){
drh9fa866a2017-04-08 18:18:22 +0000955 if( z[j-1]=='-' ) return -1;
drhe9c37f32015-08-15 21:25:36 +0000956 if( seenDP ) return -1;
957 seenDP = 1;
958 continue;
959 }
960 if( c=='e' || c=='E' ){
drh9fa866a2017-04-08 18:18:22 +0000961 if( z[j-1]<'0' ) return -1;
drhe9c37f32015-08-15 21:25:36 +0000962 if( seenE ) return -1;
963 seenDP = seenE = 1;
drh9fa866a2017-04-08 18:18:22 +0000964 c = z[j+1];
drh8784eca2015-08-23 02:42:30 +0000965 if( c=='+' || c=='-' ){
966 j++;
drh9fa866a2017-04-08 18:18:22 +0000967 c = z[j+1];
drh8784eca2015-08-23 02:42:30 +0000968 }
drhd1f00682015-08-29 16:02:37 +0000969 if( c<'0' || c>'9' ) return -1;
drhe9c37f32015-08-15 21:25:36 +0000970 continue;
971 }
972 break;
973 }
drh9fa866a2017-04-08 18:18:22 +0000974 if( z[j-1]<'0' ) return -1;
drhe9c37f32015-08-15 21:25:36 +0000975 jsonParseAddNode(pParse, seenDP ? JSON_REAL : JSON_INT,
drh9fa866a2017-04-08 18:18:22 +0000976 j - i, &z[i]);
drhe9c37f32015-08-15 21:25:36 +0000977 return j;
978 }else if( c=='}' ){
979 return -2; /* End of {...} */
980 }else if( c==']' ){
981 return -3; /* End of [...] */
drh8cb15cc2015-09-24 01:40:45 +0000982 }else if( c==0 ){
983 return 0; /* End of file */
drhe9c37f32015-08-15 21:25:36 +0000984 }else{
985 return -1; /* Syntax error */
986 }
987}
988
989/*
990** Parse a complete JSON string. Return 0 on success or non-zero if there
991** are any errors. If an error occurs, free all memory associated with
992** pParse.
993**
994** pParse is uninitialized when this routine is called.
995*/
drhbc8f0922015-08-22 19:39:04 +0000996static int jsonParse(
997 JsonParse *pParse, /* Initialize and fill this JsonParse object */
998 sqlite3_context *pCtx, /* Report errors here */
999 const char *zJson /* Input JSON text to be parsed */
1000){
drhe9c37f32015-08-15 21:25:36 +00001001 int i;
drhe9c37f32015-08-15 21:25:36 +00001002 memset(pParse, 0, sizeof(*pParse));
drhc3722b22015-08-23 20:44:59 +00001003 if( zJson==0 ) return 1;
drhe9c37f32015-08-15 21:25:36 +00001004 pParse->zJson = zJson;
1005 i = jsonParseValue(pParse, 0);
drhc3722b22015-08-23 20:44:59 +00001006 if( pParse->oom ) i = -1;
drhe9c37f32015-08-15 21:25:36 +00001007 if( i>0 ){
drhff6d50e2017-04-11 18:55:05 +00001008 assert( pParse->iDepth==0 );
dan2e8f5512015-09-17 17:21:09 +00001009 while( safe_isspace(zJson[i]) ) i++;
drhe9c37f32015-08-15 21:25:36 +00001010 if( zJson[i] ) i = -1;
1011 }
drhd1f00682015-08-29 16:02:37 +00001012 if( i<=0 ){
drhf2df7e72015-08-28 20:07:40 +00001013 if( pCtx!=0 ){
1014 if( pParse->oom ){
1015 sqlite3_result_error_nomem(pCtx);
1016 }else{
1017 sqlite3_result_error(pCtx, "malformed JSON", -1);
1018 }
1019 }
drh505ad2c2015-08-21 17:33:11 +00001020 jsonParseReset(pParse);
drhe9c37f32015-08-15 21:25:36 +00001021 return 1;
1022 }
1023 return 0;
1024}
drh301eecc2015-08-17 20:14:19 +00001025
drh505ad2c2015-08-21 17:33:11 +00001026/* Mark node i of pParse as being a child of iParent. Call recursively
1027** to fill in all the descendants of node i.
1028*/
1029static void jsonParseFillInParentage(JsonParse *pParse, u32 i, u32 iParent){
1030 JsonNode *pNode = &pParse->aNode[i];
1031 u32 j;
1032 pParse->aUp[i] = iParent;
1033 switch( pNode->eType ){
1034 case JSON_ARRAY: {
1035 for(j=1; j<=pNode->n; j += jsonNodeSize(pNode+j)){
1036 jsonParseFillInParentage(pParse, i+j, i);
1037 }
1038 break;
1039 }
1040 case JSON_OBJECT: {
1041 for(j=1; j<=pNode->n; j += jsonNodeSize(pNode+j+1)+1){
1042 pParse->aUp[i+j] = i;
1043 jsonParseFillInParentage(pParse, i+j+1, i);
1044 }
1045 break;
1046 }
1047 default: {
1048 break;
1049 }
1050 }
1051}
1052
1053/*
1054** Compute the parentage of all nodes in a completed parse.
1055*/
1056static int jsonParseFindParents(JsonParse *pParse){
1057 u32 *aUp;
1058 assert( pParse->aUp==0 );
drh2d77d802019-01-08 20:02:48 +00001059 aUp = pParse->aUp = sqlite3_malloc64( sizeof(u32)*pParse->nNode );
drhc3722b22015-08-23 20:44:59 +00001060 if( aUp==0 ){
1061 pParse->oom = 1;
1062 return SQLITE_NOMEM;
1063 }
drh505ad2c2015-08-21 17:33:11 +00001064 jsonParseFillInParentage(pParse, 0, 0);
1065 return SQLITE_OK;
1066}
1067
drh8cb0c832015-09-22 00:21:03 +00001068/*
drh3fb153c2017-05-11 16:49:59 +00001069** Magic number used for the JSON parse cache in sqlite3_get_auxdata()
1070*/
drhe35fc302018-08-30 01:52:10 +00001071#define JSON_CACHE_ID (-429938) /* First cache entry */
1072#define JSON_CACHE_SZ 4 /* Max number of cache entries */
drh3fb153c2017-05-11 16:49:59 +00001073
1074/*
1075** Obtain a complete parse of the JSON found in the first argument
1076** of the argv array. Use the sqlite3_get_auxdata() cache for this
1077** parse if it is available. If the cache is not available or if it
1078** is no longer valid, parse the JSON again and return the new parse,
1079** and also register the new parse so that it will be available for
1080** future sqlite3_get_auxdata() calls.
1081*/
1082static JsonParse *jsonParseCached(
1083 sqlite3_context *pCtx,
drhe35fc302018-08-30 01:52:10 +00001084 sqlite3_value **argv,
1085 sqlite3_context *pErrCtx
drh3fb153c2017-05-11 16:49:59 +00001086){
1087 const char *zJson = (const char*)sqlite3_value_text(argv[0]);
1088 int nJson = sqlite3_value_bytes(argv[0]);
1089 JsonParse *p;
drhe35fc302018-08-30 01:52:10 +00001090 JsonParse *pMatch = 0;
1091 int iKey;
1092 int iMinKey = 0;
1093 u32 iMinHold = 0xffffffff;
1094 u32 iMaxHold = 0;
drh3fb153c2017-05-11 16:49:59 +00001095 if( zJson==0 ) return 0;
drhe35fc302018-08-30 01:52:10 +00001096 for(iKey=0; iKey<JSON_CACHE_SZ; iKey++){
1097 p = (JsonParse*)sqlite3_get_auxdata(pCtx, JSON_CACHE_ID+iKey);
1098 if( p==0 ){
1099 iMinKey = iKey;
1100 break;
1101 }
1102 if( pMatch==0
1103 && p->nJson==nJson
1104 && memcmp(p->zJson,zJson,nJson)==0
1105 ){
1106 p->nErr = 0;
1107 pMatch = p;
1108 }else if( p->iHold<iMinHold ){
1109 iMinHold = p->iHold;
1110 iMinKey = iKey;
1111 }
1112 if( p->iHold>iMaxHold ){
1113 iMaxHold = p->iHold;
1114 }
1115 }
1116 if( pMatch ){
1117 pMatch->nErr = 0;
1118 pMatch->iHold = iMaxHold+1;
1119 return pMatch;
drh3fb153c2017-05-11 16:49:59 +00001120 }
drh2d77d802019-01-08 20:02:48 +00001121 p = sqlite3_malloc64( sizeof(*p) + nJson + 1 );
drh3fb153c2017-05-11 16:49:59 +00001122 if( p==0 ){
1123 sqlite3_result_error_nomem(pCtx);
1124 return 0;
1125 }
1126 memset(p, 0, sizeof(*p));
1127 p->zJson = (char*)&p[1];
1128 memcpy((char*)p->zJson, zJson, nJson+1);
drhe35fc302018-08-30 01:52:10 +00001129 if( jsonParse(p, pErrCtx, p->zJson) ){
drh3fb153c2017-05-11 16:49:59 +00001130 sqlite3_free(p);
1131 return 0;
1132 }
1133 p->nJson = nJson;
drhe35fc302018-08-30 01:52:10 +00001134 p->iHold = iMaxHold+1;
1135 sqlite3_set_auxdata(pCtx, JSON_CACHE_ID+iMinKey, p,
1136 (void(*)(void*))jsonParseFree);
1137 return (JsonParse*)sqlite3_get_auxdata(pCtx, JSON_CACHE_ID+iMinKey);
drh3fb153c2017-05-11 16:49:59 +00001138}
1139
1140/*
drh8cb0c832015-09-22 00:21:03 +00001141** Compare the OBJECT label at pNode against zKey,nKey. Return true on
1142** a match.
1143*/
mistachkinf2c26ed2015-10-12 22:20:29 +00001144static int jsonLabelCompare(JsonNode *pNode, const char *zKey, u32 nKey){
drh285f2ef2021-10-15 16:15:04 +00001145 assert( pNode->eU==1 );
drh8cb0c832015-09-22 00:21:03 +00001146 if( pNode->jnFlags & JNODE_RAW ){
1147 if( pNode->n!=nKey ) return 0;
1148 return strncmp(pNode->u.zJContent, zKey, nKey)==0;
1149 }else{
1150 if( pNode->n!=nKey+2 ) return 0;
1151 return strncmp(pNode->u.zJContent+1, zKey, nKey)==0;
1152 }
1153}
1154
drh52216ad2015-08-18 02:28:03 +00001155/* forward declaration */
drha7714022015-08-29 00:54:49 +00001156static JsonNode *jsonLookupAppend(JsonParse*,const char*,int*,const char**);
drh52216ad2015-08-18 02:28:03 +00001157
drh987eb1f2015-08-17 15:17:37 +00001158/*
1159** Search along zPath to find the node specified. Return a pointer
1160** to that node, or NULL if zPath is malformed or if there is no such
1161** node.
drh52216ad2015-08-18 02:28:03 +00001162**
1163** If pApnd!=0, then try to append new nodes to complete zPath if it is
1164** possible to do so and if no existing node corresponds to zPath. If
1165** new nodes are appended *pApnd is set to 1.
drh987eb1f2015-08-17 15:17:37 +00001166*/
drha7714022015-08-29 00:54:49 +00001167static JsonNode *jsonLookupStep(
drh52216ad2015-08-18 02:28:03 +00001168 JsonParse *pParse, /* The JSON to search */
1169 u32 iRoot, /* Begin the search at this node */
1170 const char *zPath, /* The path to search */
drha7714022015-08-29 00:54:49 +00001171 int *pApnd, /* Append nodes to complete path if not NULL */
1172 const char **pzErr /* Make *pzErr point to any syntax error in zPath */
drh52216ad2015-08-18 02:28:03 +00001173){
drhbc8f0922015-08-22 19:39:04 +00001174 u32 i, j, nKey;
drh6b43cc82015-08-19 23:02:49 +00001175 const char *zKey;
drh52216ad2015-08-18 02:28:03 +00001176 JsonNode *pRoot = &pParse->aNode[iRoot];
drh987eb1f2015-08-17 15:17:37 +00001177 if( zPath[0]==0 ) return pRoot;
drh7e35e812019-07-31 12:13:58 +00001178 if( pRoot->jnFlags & JNODE_REPLACE ) return 0;
drh987eb1f2015-08-17 15:17:37 +00001179 if( zPath[0]=='.' ){
1180 if( pRoot->eType!=JSON_OBJECT ) return 0;
1181 zPath++;
drh6b43cc82015-08-19 23:02:49 +00001182 if( zPath[0]=='"' ){
1183 zKey = zPath + 1;
1184 for(i=1; zPath[i] && zPath[i]!='"'; i++){}
1185 nKey = i-1;
drha8f39a92015-09-21 22:53:16 +00001186 if( zPath[i] ){
1187 i++;
1188 }else{
1189 *pzErr = zPath;
1190 return 0;
1191 }
drh6b43cc82015-08-19 23:02:49 +00001192 }else{
1193 zKey = zPath;
1194 for(i=0; zPath[i] && zPath[i]!='.' && zPath[i]!='['; i++){}
1195 nKey = i;
1196 }
drha7714022015-08-29 00:54:49 +00001197 if( nKey==0 ){
1198 *pzErr = zPath;
1199 return 0;
1200 }
drh987eb1f2015-08-17 15:17:37 +00001201 j = 1;
drh52216ad2015-08-18 02:28:03 +00001202 for(;;){
1203 while( j<=pRoot->n ){
drh8cb0c832015-09-22 00:21:03 +00001204 if( jsonLabelCompare(pRoot+j, zKey, nKey) ){
drha7714022015-08-29 00:54:49 +00001205 return jsonLookupStep(pParse, iRoot+j+1, &zPath[i], pApnd, pzErr);
drh52216ad2015-08-18 02:28:03 +00001206 }
1207 j++;
drh505ad2c2015-08-21 17:33:11 +00001208 j += jsonNodeSize(&pRoot[j]);
drh987eb1f2015-08-17 15:17:37 +00001209 }
drh52216ad2015-08-18 02:28:03 +00001210 if( (pRoot->jnFlags & JNODE_APPEND)==0 ) break;
drh285f2ef2021-10-15 16:15:04 +00001211 assert( pRoot->eU==2 );
drh52216ad2015-08-18 02:28:03 +00001212 iRoot += pRoot->u.iAppend;
1213 pRoot = &pParse->aNode[iRoot];
1214 j = 1;
1215 }
1216 if( pApnd ){
drhbc8f0922015-08-22 19:39:04 +00001217 u32 iStart, iLabel;
1218 JsonNode *pNode;
1219 iStart = jsonParseAddNode(pParse, JSON_OBJECT, 2, 0);
danfe9a8322019-06-17 14:50:33 +00001220 iLabel = jsonParseAddNode(pParse, JSON_STRING, nKey, zKey);
drh52216ad2015-08-18 02:28:03 +00001221 zPath += i;
drha7714022015-08-29 00:54:49 +00001222 pNode = jsonLookupAppend(pParse, zPath, pApnd, pzErr);
drhbc8f0922015-08-22 19:39:04 +00001223 if( pParse->oom ) return 0;
1224 if( pNode ){
1225 pRoot = &pParse->aNode[iRoot];
drh285f2ef2021-10-15 16:15:04 +00001226 assert( pRoot->eU==0 );
drhbc8f0922015-08-22 19:39:04 +00001227 pRoot->u.iAppend = iStart - iRoot;
1228 pRoot->jnFlags |= JNODE_APPEND;
drh285f2ef2021-10-15 16:15:04 +00001229 VVA( pRoot->eU = 2 );
drhbc8f0922015-08-22 19:39:04 +00001230 pParse->aNode[iLabel].jnFlags |= JNODE_RAW;
1231 }
1232 return pNode;
drh987eb1f2015-08-17 15:17:37 +00001233 }
drh52818642019-11-22 17:37:56 +00001234 }else if( zPath[0]=='[' ){
drh987eb1f2015-08-17 15:17:37 +00001235 i = 0;
drh3d1d2a92015-09-22 01:15:49 +00001236 j = 1;
1237 while( safe_isdigit(zPath[j]) ){
1238 i = i*10 + zPath[j] - '0';
1239 j++;
drh987eb1f2015-08-17 15:17:37 +00001240 }
drh52818642019-11-22 17:37:56 +00001241 if( j<2 || zPath[j]!=']' ){
1242 if( zPath[1]=='#' ){
1243 JsonNode *pBase = pRoot;
1244 int iBase = iRoot;
1245 if( pRoot->eType!=JSON_ARRAY ) return 0;
1246 for(;;){
1247 while( j<=pBase->n ){
1248 if( (pBase[j].jnFlags & JNODE_REMOVE)==0 ) i++;
1249 j += jsonNodeSize(&pBase[j]);
1250 }
1251 if( (pBase->jnFlags & JNODE_APPEND)==0 ) break;
drh285f2ef2021-10-15 16:15:04 +00001252 assert( pBase->eU==2 );
drh52818642019-11-22 17:37:56 +00001253 iBase += pBase->u.iAppend;
1254 pBase = &pParse->aNode[iBase];
1255 j = 1;
1256 }
1257 j = 2;
1258 if( zPath[2]=='-' && safe_isdigit(zPath[3]) ){
1259 unsigned int x = 0;
1260 j = 3;
1261 do{
1262 x = x*10 + zPath[j] - '0';
1263 j++;
1264 }while( safe_isdigit(zPath[j]) );
1265 if( x>i ) return 0;
1266 i -= x;
1267 }
1268 if( zPath[j]!=']' ){
1269 *pzErr = zPath;
1270 return 0;
1271 }
1272 }else{
1273 *pzErr = zPath;
1274 return 0;
1275 }
drha7714022015-08-29 00:54:49 +00001276 }
drh52818642019-11-22 17:37:56 +00001277 if( pRoot->eType!=JSON_ARRAY ) return 0;
drh3d1d2a92015-09-22 01:15:49 +00001278 zPath += j + 1;
drh987eb1f2015-08-17 15:17:37 +00001279 j = 1;
drh52216ad2015-08-18 02:28:03 +00001280 for(;;){
drhbc8f0922015-08-22 19:39:04 +00001281 while( j<=pRoot->n && (i>0 || (pRoot[j].jnFlags & JNODE_REMOVE)!=0) ){
1282 if( (pRoot[j].jnFlags & JNODE_REMOVE)==0 ) i--;
drh505ad2c2015-08-21 17:33:11 +00001283 j += jsonNodeSize(&pRoot[j]);
drh52216ad2015-08-18 02:28:03 +00001284 }
1285 if( (pRoot->jnFlags & JNODE_APPEND)==0 ) break;
drh285f2ef2021-10-15 16:15:04 +00001286 assert( pRoot->eU==2 );
drh52216ad2015-08-18 02:28:03 +00001287 iRoot += pRoot->u.iAppend;
1288 pRoot = &pParse->aNode[iRoot];
1289 j = 1;
drh987eb1f2015-08-17 15:17:37 +00001290 }
1291 if( j<=pRoot->n ){
drha7714022015-08-29 00:54:49 +00001292 return jsonLookupStep(pParse, iRoot+j, zPath, pApnd, pzErr);
drh52216ad2015-08-18 02:28:03 +00001293 }
1294 if( i==0 && pApnd ){
drhbc8f0922015-08-22 19:39:04 +00001295 u32 iStart;
1296 JsonNode *pNode;
1297 iStart = jsonParseAddNode(pParse, JSON_ARRAY, 1, 0);
drha7714022015-08-29 00:54:49 +00001298 pNode = jsonLookupAppend(pParse, zPath, pApnd, pzErr);
drhbc8f0922015-08-22 19:39:04 +00001299 if( pParse->oom ) return 0;
1300 if( pNode ){
1301 pRoot = &pParse->aNode[iRoot];
drh285f2ef2021-10-15 16:15:04 +00001302 assert( pRoot->eU==0 );
drhbc8f0922015-08-22 19:39:04 +00001303 pRoot->u.iAppend = iStart - iRoot;
1304 pRoot->jnFlags |= JNODE_APPEND;
drh285f2ef2021-10-15 16:15:04 +00001305 VVA( pRoot->eU = 2 );
drhbc8f0922015-08-22 19:39:04 +00001306 }
1307 return pNode;
drh987eb1f2015-08-17 15:17:37 +00001308 }
drh3d1d2a92015-09-22 01:15:49 +00001309 }else{
drha7714022015-08-29 00:54:49 +00001310 *pzErr = zPath;
drh987eb1f2015-08-17 15:17:37 +00001311 }
1312 return 0;
1313}
1314
drh52216ad2015-08-18 02:28:03 +00001315/*
drhbc8f0922015-08-22 19:39:04 +00001316** Append content to pParse that will complete zPath. Return a pointer
1317** to the inserted node, or return NULL if the append fails.
drh52216ad2015-08-18 02:28:03 +00001318*/
1319static JsonNode *jsonLookupAppend(
1320 JsonParse *pParse, /* Append content to the JSON parse */
1321 const char *zPath, /* Description of content to append */
drha7714022015-08-29 00:54:49 +00001322 int *pApnd, /* Set this flag to 1 */
1323 const char **pzErr /* Make this point to any syntax error */
drh52216ad2015-08-18 02:28:03 +00001324){
1325 *pApnd = 1;
1326 if( zPath[0]==0 ){
1327 jsonParseAddNode(pParse, JSON_NULL, 0, 0);
1328 return pParse->oom ? 0 : &pParse->aNode[pParse->nNode-1];
1329 }
1330 if( zPath[0]=='.' ){
1331 jsonParseAddNode(pParse, JSON_OBJECT, 0, 0);
1332 }else if( strncmp(zPath,"[0]",3)==0 ){
1333 jsonParseAddNode(pParse, JSON_ARRAY, 0, 0);
1334 }else{
1335 return 0;
1336 }
1337 if( pParse->oom ) return 0;
drha7714022015-08-29 00:54:49 +00001338 return jsonLookupStep(pParse, pParse->nNode-1, zPath, pApnd, pzErr);
drh52216ad2015-08-18 02:28:03 +00001339}
1340
drhbc8f0922015-08-22 19:39:04 +00001341/*
drha7714022015-08-29 00:54:49 +00001342** Return the text of a syntax error message on a JSON path. Space is
1343** obtained from sqlite3_malloc().
1344*/
1345static char *jsonPathSyntaxError(const char *zErr){
1346 return sqlite3_mprintf("JSON path error near '%q'", zErr);
1347}
1348
1349/*
1350** Do a node lookup using zPath. Return a pointer to the node on success.
1351** Return NULL if not found or if there is an error.
1352**
1353** On an error, write an error message into pCtx and increment the
1354** pParse->nErr counter.
1355**
1356** If pApnd!=NULL then try to append missing nodes and set *pApnd = 1 if
1357** nodes are appended.
drha7714022015-08-29 00:54:49 +00001358*/
1359static JsonNode *jsonLookup(
1360 JsonParse *pParse, /* The JSON to search */
1361 const char *zPath, /* The path to search */
1362 int *pApnd, /* Append nodes to complete path if not NULL */
drhf5ddb9c2015-09-11 00:06:41 +00001363 sqlite3_context *pCtx /* Report errors here, if not NULL */
drha7714022015-08-29 00:54:49 +00001364){
1365 const char *zErr = 0;
1366 JsonNode *pNode = 0;
drha8f39a92015-09-21 22:53:16 +00001367 char *zMsg;
drha7714022015-08-29 00:54:49 +00001368
1369 if( zPath==0 ) return 0;
1370 if( zPath[0]!='$' ){
1371 zErr = zPath;
1372 goto lookup_err;
1373 }
1374 zPath++;
drha7714022015-08-29 00:54:49 +00001375 pNode = jsonLookupStep(pParse, 0, zPath, pApnd, &zErr);
drha8f39a92015-09-21 22:53:16 +00001376 if( zErr==0 ) return pNode;
drha7714022015-08-29 00:54:49 +00001377
1378lookup_err:
1379 pParse->nErr++;
drha8f39a92015-09-21 22:53:16 +00001380 assert( zErr!=0 && pCtx!=0 );
1381 zMsg = jsonPathSyntaxError(zErr);
1382 if( zMsg ){
1383 sqlite3_result_error(pCtx, zMsg, -1);
1384 sqlite3_free(zMsg);
1385 }else{
1386 sqlite3_result_error_nomem(pCtx);
drha7714022015-08-29 00:54:49 +00001387 }
drha7714022015-08-29 00:54:49 +00001388 return 0;
1389}
1390
1391
1392/*
drhbc8f0922015-08-22 19:39:04 +00001393** Report the wrong number of arguments for json_insert(), json_replace()
1394** or json_set().
1395*/
1396static void jsonWrongNumArgs(
1397 sqlite3_context *pCtx,
1398 const char *zFuncName
1399){
1400 char *zMsg = sqlite3_mprintf("json_%s() needs an odd number of arguments",
1401 zFuncName);
1402 sqlite3_result_error(pCtx, zMsg, -1);
1403 sqlite3_free(zMsg);
1404}
drh52216ad2015-08-18 02:28:03 +00001405
drh29c99692017-03-24 12:35:17 +00001406/*
1407** Mark all NULL entries in the Object passed in as JNODE_REMOVE.
1408*/
1409static void jsonRemoveAllNulls(JsonNode *pNode){
1410 int i, n;
1411 assert( pNode->eType==JSON_OBJECT );
1412 n = pNode->n;
1413 for(i=2; i<=n; i += jsonNodeSize(&pNode[i])+1){
1414 switch( pNode[i].eType ){
1415 case JSON_NULL:
1416 pNode[i].jnFlags |= JNODE_REMOVE;
1417 break;
1418 case JSON_OBJECT:
1419 jsonRemoveAllNulls(&pNode[i]);
1420 break;
1421 }
1422 }
1423}
1424
drha7714022015-08-29 00:54:49 +00001425
drh987eb1f2015-08-17 15:17:37 +00001426/****************************************************************************
1427** SQL functions used for testing and debugging
1428****************************************************************************/
drhe9c37f32015-08-15 21:25:36 +00001429
drh301eecc2015-08-17 20:14:19 +00001430#ifdef SQLITE_DEBUG
drhe9c37f32015-08-15 21:25:36 +00001431/*
drh5634cc02015-08-17 11:28:03 +00001432** The json_parse(JSON) function returns a string which describes
drhe9c37f32015-08-15 21:25:36 +00001433** a parse of the JSON provided. Or it returns NULL if JSON is not
1434** well-formed.
1435*/
drh5634cc02015-08-17 11:28:03 +00001436static void jsonParseFunc(
drhbc8f0922015-08-22 19:39:04 +00001437 sqlite3_context *ctx,
drhe9c37f32015-08-15 21:25:36 +00001438 int argc,
1439 sqlite3_value **argv
1440){
drh505ad2c2015-08-21 17:33:11 +00001441 JsonString s; /* Output string - not real JSON */
1442 JsonParse x; /* The parse */
drhe9c37f32015-08-15 21:25:36 +00001443 u32 i;
drhe9c37f32015-08-15 21:25:36 +00001444
1445 assert( argc==1 );
drhbc8f0922015-08-22 19:39:04 +00001446 if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return;
drh8784eca2015-08-23 02:42:30 +00001447 jsonParseFindParents(&x);
drhbc8f0922015-08-22 19:39:04 +00001448 jsonInit(&s, ctx);
drhe9c37f32015-08-15 21:25:36 +00001449 for(i=0; i<x.nNode; i++){
drh852944e2015-09-10 03:29:11 +00001450 const char *zType;
1451 if( x.aNode[i].jnFlags & JNODE_LABEL ){
1452 assert( x.aNode[i].eType==JSON_STRING );
1453 zType = "label";
1454 }else{
1455 zType = jsonType[x.aNode[i].eType];
drhe9c37f32015-08-15 21:25:36 +00001456 }
drh852944e2015-09-10 03:29:11 +00001457 jsonPrintf(100, &s,"node %3u: %7s n=%-4d up=%-4d",
1458 i, zType, x.aNode[i].n, x.aUp[i]);
drh285f2ef2021-10-15 16:15:04 +00001459 assert( x.aNode[i].eU==0 || x.aNode[i].eU==1 );
drh852944e2015-09-10 03:29:11 +00001460 if( x.aNode[i].u.zJContent!=0 ){
drh285f2ef2021-10-15 16:15:04 +00001461 assert( x.aNode[i].eU==1 );
drh852944e2015-09-10 03:29:11 +00001462 jsonAppendRaw(&s, " ", 1);
1463 jsonAppendRaw(&s, x.aNode[i].u.zJContent, x.aNode[i].n);
drh285f2ef2021-10-15 16:15:04 +00001464 }else{
1465 assert( x.aNode[i].eU==0 );
drh852944e2015-09-10 03:29:11 +00001466 }
1467 jsonAppendRaw(&s, "\n", 1);
drhe9c37f32015-08-15 21:25:36 +00001468 }
drh505ad2c2015-08-21 17:33:11 +00001469 jsonParseReset(&x);
drhe9c37f32015-08-15 21:25:36 +00001470 jsonResult(&s);
1471}
1472
drh5634cc02015-08-17 11:28:03 +00001473/*
drhf5ddb9c2015-09-11 00:06:41 +00001474** The json_test1(JSON) function return true (1) if the input is JSON
1475** text generated by another json function. It returns (0) if the input
1476** is not known to be JSON.
drh5634cc02015-08-17 11:28:03 +00001477*/
1478static void jsonTest1Func(
drhbc8f0922015-08-22 19:39:04 +00001479 sqlite3_context *ctx,
drh5634cc02015-08-17 11:28:03 +00001480 int argc,
1481 sqlite3_value **argv
1482){
mistachkin16a93122015-09-11 18:05:01 +00001483 UNUSED_PARAM(argc);
drhf5ddb9c2015-09-11 00:06:41 +00001484 sqlite3_result_int(ctx, sqlite3_value_subtype(argv[0])==JSON_SUBTYPE);
drh5634cc02015-08-17 11:28:03 +00001485}
drh301eecc2015-08-17 20:14:19 +00001486#endif /* SQLITE_DEBUG */
drh5634cc02015-08-17 11:28:03 +00001487
drh987eb1f2015-08-17 15:17:37 +00001488/****************************************************************************
drhff135ae2015-12-30 01:07:02 +00001489** Scalar SQL function implementations
drh987eb1f2015-08-17 15:17:37 +00001490****************************************************************************/
1491
1492/*
drh2ad96f52016-06-17 13:01:51 +00001493** Implementation of the json_QUOTE(VALUE) function. Return a JSON value
1494** corresponding to the SQL value input. Mostly this means putting
1495** double-quotes around strings and returning the unquoted string "null"
1496** when given a NULL input.
1497*/
1498static void jsonQuoteFunc(
1499 sqlite3_context *ctx,
1500 int argc,
1501 sqlite3_value **argv
1502){
1503 JsonString jx;
drhb0df5402016-08-01 17:06:44 +00001504 UNUSED_PARAM(argc);
drh2ad96f52016-06-17 13:01:51 +00001505
1506 jsonInit(&jx, ctx);
1507 jsonAppendValue(&jx, argv[0]);
1508 jsonResult(&jx);
1509 sqlite3_result_subtype(ctx, JSON_SUBTYPE);
1510}
1511
1512/*
drh987eb1f2015-08-17 15:17:37 +00001513** Implementation of the json_array(VALUE,...) function. Return a JSON
1514** array that contains all values given in arguments. Or if any argument
1515** is a BLOB, throw an error.
1516*/
1517static void jsonArrayFunc(
drhbc8f0922015-08-22 19:39:04 +00001518 sqlite3_context *ctx,
drh987eb1f2015-08-17 15:17:37 +00001519 int argc,
1520 sqlite3_value **argv
1521){
1522 int i;
drh505ad2c2015-08-21 17:33:11 +00001523 JsonString jx;
drh987eb1f2015-08-17 15:17:37 +00001524
drhbc8f0922015-08-22 19:39:04 +00001525 jsonInit(&jx, ctx);
drhd0960592015-08-17 21:22:32 +00001526 jsonAppendChar(&jx, '[');
drh987eb1f2015-08-17 15:17:37 +00001527 for(i=0; i<argc; i++){
drhd0960592015-08-17 21:22:32 +00001528 jsonAppendSeparator(&jx);
drhf5ddb9c2015-09-11 00:06:41 +00001529 jsonAppendValue(&jx, argv[i]);
drh987eb1f2015-08-17 15:17:37 +00001530 }
drhd0960592015-08-17 21:22:32 +00001531 jsonAppendChar(&jx, ']');
drh987eb1f2015-08-17 15:17:37 +00001532 jsonResult(&jx);
drhf5ddb9c2015-09-11 00:06:41 +00001533 sqlite3_result_subtype(ctx, JSON_SUBTYPE);
drh987eb1f2015-08-17 15:17:37 +00001534}
1535
1536
1537/*
1538** json_array_length(JSON)
1539** json_array_length(JSON, PATH)
1540**
1541** Return the number of elements in the top-level JSON array.
1542** Return 0 if the input is not a well-formed JSON array.
1543*/
1544static void jsonArrayLengthFunc(
drhbc8f0922015-08-22 19:39:04 +00001545 sqlite3_context *ctx,
drh987eb1f2015-08-17 15:17:37 +00001546 int argc,
1547 sqlite3_value **argv
1548){
drh3fb153c2017-05-11 16:49:59 +00001549 JsonParse *p; /* The parse */
drh987eb1f2015-08-17 15:17:37 +00001550 sqlite3_int64 n = 0;
1551 u32 i;
drha8f39a92015-09-21 22:53:16 +00001552 JsonNode *pNode;
drh987eb1f2015-08-17 15:17:37 +00001553
drhe35fc302018-08-30 01:52:10 +00001554 p = jsonParseCached(ctx, argv, ctx);
drh3fb153c2017-05-11 16:49:59 +00001555 if( p==0 ) return;
1556 assert( p->nNode );
drha8f39a92015-09-21 22:53:16 +00001557 if( argc==2 ){
1558 const char *zPath = (const char*)sqlite3_value_text(argv[1]);
drh3fb153c2017-05-11 16:49:59 +00001559 pNode = jsonLookup(p, zPath, 0, ctx);
drha8f39a92015-09-21 22:53:16 +00001560 }else{
drh3fb153c2017-05-11 16:49:59 +00001561 pNode = p->aNode;
drha8f39a92015-09-21 22:53:16 +00001562 }
1563 if( pNode==0 ){
drh3fb153c2017-05-11 16:49:59 +00001564 return;
1565 }
1566 if( pNode->eType==JSON_ARRAY ){
drha8f39a92015-09-21 22:53:16 +00001567 assert( (pNode->jnFlags & JNODE_APPEND)==0 );
1568 for(i=1; i<=pNode->n; n++){
1569 i += jsonNodeSize(&pNode[i]);
drh987eb1f2015-08-17 15:17:37 +00001570 }
drh987eb1f2015-08-17 15:17:37 +00001571 }
drh3fb153c2017-05-11 16:49:59 +00001572 sqlite3_result_int64(ctx, n);
drhf6ec8d42015-08-28 03:48:04 +00001573}
1574
1575/*
drh3ad93bb2015-08-29 19:41:45 +00001576** json_extract(JSON, PATH, ...)
drh987eb1f2015-08-17 15:17:37 +00001577**
drh3ad93bb2015-08-29 19:41:45 +00001578** Return the element described by PATH. Return NULL if there is no
1579** PATH element. If there are multiple PATHs, then return a JSON array
1580** with the result from each path. Throw an error if the JSON or any PATH
1581** is malformed.
drh987eb1f2015-08-17 15:17:37 +00001582*/
1583static void jsonExtractFunc(
drhbc8f0922015-08-22 19:39:04 +00001584 sqlite3_context *ctx,
drh987eb1f2015-08-17 15:17:37 +00001585 int argc,
1586 sqlite3_value **argv
1587){
drh3fb153c2017-05-11 16:49:59 +00001588 JsonParse *p; /* The parse */
drh987eb1f2015-08-17 15:17:37 +00001589 JsonNode *pNode;
1590 const char *zPath;
drh3ad93bb2015-08-29 19:41:45 +00001591 JsonString jx;
1592 int i;
1593
1594 if( argc<2 ) return;
drhe35fc302018-08-30 01:52:10 +00001595 p = jsonParseCached(ctx, argv, ctx);
drh3fb153c2017-05-11 16:49:59 +00001596 if( p==0 ) return;
drh3ad93bb2015-08-29 19:41:45 +00001597 jsonInit(&jx, ctx);
1598 jsonAppendChar(&jx, '[');
1599 for(i=1; i<argc; i++){
1600 zPath = (const char*)sqlite3_value_text(argv[i]);
drh3fb153c2017-05-11 16:49:59 +00001601 pNode = jsonLookup(p, zPath, 0, ctx);
1602 if( p->nErr ) break;
drh3ad93bb2015-08-29 19:41:45 +00001603 if( argc>2 ){
1604 jsonAppendSeparator(&jx);
1605 if( pNode ){
1606 jsonRenderNode(pNode, &jx, 0);
1607 }else{
1608 jsonAppendRaw(&jx, "null", 4);
1609 }
1610 }else if( pNode ){
1611 jsonReturn(pNode, ctx, 0);
1612 }
drh987eb1f2015-08-17 15:17:37 +00001613 }
drh3ad93bb2015-08-29 19:41:45 +00001614 if( argc>2 && i==argc ){
1615 jsonAppendChar(&jx, ']');
1616 jsonResult(&jx);
drhf5ddb9c2015-09-11 00:06:41 +00001617 sqlite3_result_subtype(ctx, JSON_SUBTYPE);
drh3ad93bb2015-08-29 19:41:45 +00001618 }
1619 jsonReset(&jx);
drh987eb1f2015-08-17 15:17:37 +00001620}
1621
drh633647a2017-03-22 21:24:31 +00001622/* This is the RFC 7396 MergePatch algorithm.
1623*/
1624static JsonNode *jsonMergePatch(
1625 JsonParse *pParse, /* The JSON parser that contains the TARGET */
mistachkinb1ed7172017-04-14 14:50:34 +00001626 u32 iTarget, /* Node of the TARGET in pParse */
drh633647a2017-03-22 21:24:31 +00001627 JsonNode *pPatch /* The PATCH */
1628){
drh0002d242017-03-23 00:46:15 +00001629 u32 i, j;
1630 u32 iRoot;
drh633647a2017-03-22 21:24:31 +00001631 JsonNode *pTarget;
1632 if( pPatch->eType!=JSON_OBJECT ){
1633 return pPatch;
1634 }
1635 assert( iTarget>=0 && iTarget<pParse->nNode );
1636 pTarget = &pParse->aNode[iTarget];
1637 assert( (pPatch->jnFlags & JNODE_APPEND)==0 );
1638 if( pTarget->eType!=JSON_OBJECT ){
drh29c99692017-03-24 12:35:17 +00001639 jsonRemoveAllNulls(pPatch);
drh633647a2017-03-22 21:24:31 +00001640 return pPatch;
1641 }
drhbb7aa2d2017-03-23 00:13:52 +00001642 iRoot = iTarget;
drh633647a2017-03-22 21:24:31 +00001643 for(i=1; i<pPatch->n; i += jsonNodeSize(&pPatch[i+1])+1){
drhba7cce32017-03-24 19:45:05 +00001644 u32 nKey;
drh633647a2017-03-22 21:24:31 +00001645 const char *zKey;
1646 assert( pPatch[i].eType==JSON_STRING );
1647 assert( pPatch[i].jnFlags & JNODE_LABEL );
drh285f2ef2021-10-15 16:15:04 +00001648 assert( pPatch[i].eU==1 );
drh633647a2017-03-22 21:24:31 +00001649 nKey = pPatch[i].n;
1650 zKey = pPatch[i].u.zJContent;
drhbb7aa2d2017-03-23 00:13:52 +00001651 assert( (pPatch[i].jnFlags & JNODE_RAW)==0 );
drh633647a2017-03-22 21:24:31 +00001652 for(j=1; j<pTarget->n; j += jsonNodeSize(&pTarget[j+1])+1 ){
1653 assert( pTarget[j].eType==JSON_STRING );
1654 assert( pTarget[j].jnFlags & JNODE_LABEL );
drhbb7aa2d2017-03-23 00:13:52 +00001655 assert( (pPatch[i].jnFlags & JNODE_RAW)==0 );
drh1fe162f2017-03-23 12:56:44 +00001656 if( pTarget[j].n==nKey && strncmp(pTarget[j].u.zJContent,zKey,nKey)==0 ){
1657 if( pTarget[j+1].jnFlags & (JNODE_REMOVE|JNODE_PATCH) ) break;
drh633647a2017-03-22 21:24:31 +00001658 if( pPatch[i+1].eType==JSON_NULL ){
1659 pTarget[j+1].jnFlags |= JNODE_REMOVE;
1660 }else{
drhbb7aa2d2017-03-23 00:13:52 +00001661 JsonNode *pNew = jsonMergePatch(pParse, iTarget+j+1, &pPatch[i+1]);
drh633647a2017-03-22 21:24:31 +00001662 if( pNew==0 ) return 0;
1663 pTarget = &pParse->aNode[iTarget];
1664 if( pNew!=&pTarget[j+1] ){
drh285f2ef2021-10-15 16:15:04 +00001665 assert( pTarget[j+1].eU==0 || pTarget[j+1].eU==1 );
1666 testcase( pTarget[j+1].eU==1 );
1667 VVA( pTarget[j+1].eU = 5 );
drh633647a2017-03-22 21:24:31 +00001668 pTarget[j+1].u.pPatch = pNew;
1669 pTarget[j+1].jnFlags |= JNODE_PATCH;
1670 }
1671 }
1672 break;
1673 }
1674 }
drhbb7aa2d2017-03-23 00:13:52 +00001675 if( j>=pTarget->n && pPatch[i+1].eType!=JSON_NULL ){
drh633647a2017-03-22 21:24:31 +00001676 int iStart, iPatch;
1677 iStart = jsonParseAddNode(pParse, JSON_OBJECT, 2, 0);
1678 jsonParseAddNode(pParse, JSON_STRING, nKey, zKey);
1679 iPatch = jsonParseAddNode(pParse, JSON_TRUE, 0, 0);
1680 if( pParse->oom ) return 0;
drh29c99692017-03-24 12:35:17 +00001681 jsonRemoveAllNulls(pPatch);
drh633647a2017-03-22 21:24:31 +00001682 pTarget = &pParse->aNode[iTarget];
drh8b554e22021-10-20 20:22:37 +00001683 assert( pParse->aNode[iRoot].eU==0 || pParse->aNode[iRoot].eU==2 );
1684 testcase( pParse->aNode[iRoot].eU==2 );
drhbb7aa2d2017-03-23 00:13:52 +00001685 pParse->aNode[iRoot].jnFlags |= JNODE_APPEND;
drh285f2ef2021-10-15 16:15:04 +00001686 VVA( pParse->aNode[iRoot].eU = 2 );
drhbb7aa2d2017-03-23 00:13:52 +00001687 pParse->aNode[iRoot].u.iAppend = iStart - iRoot;
1688 iRoot = iStart;
drh285f2ef2021-10-15 16:15:04 +00001689 assert( pParse->aNode[iPatch].eU==0 );
1690 VVA( pParse->aNode[iPatch].eU = 5 );
drh633647a2017-03-22 21:24:31 +00001691 pParse->aNode[iPatch].jnFlags |= JNODE_PATCH;
1692 pParse->aNode[iPatch].u.pPatch = &pPatch[i+1];
1693 }
1694 }
1695 return pTarget;
1696}
1697
1698/*
1699** Implementation of the json_mergepatch(JSON1,JSON2) function. Return a JSON
1700** object that is the result of running the RFC 7396 MergePatch() algorithm
1701** on the two arguments.
1702*/
drh37f03df2017-03-23 20:33:49 +00001703static void jsonPatchFunc(
drh633647a2017-03-22 21:24:31 +00001704 sqlite3_context *ctx,
1705 int argc,
1706 sqlite3_value **argv
1707){
1708 JsonParse x; /* The JSON that is being patched */
1709 JsonParse y; /* The patch */
drhbb7aa2d2017-03-23 00:13:52 +00001710 JsonNode *pResult; /* The result of the merge */
drh633647a2017-03-22 21:24:31 +00001711
drh2fb79e92017-03-25 12:08:11 +00001712 UNUSED_PARAM(argc);
drh633647a2017-03-22 21:24:31 +00001713 if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return;
1714 if( jsonParse(&y, ctx, (const char*)sqlite3_value_text(argv[1])) ){
1715 jsonParseReset(&x);
1716 return;
1717 }
drhbb7aa2d2017-03-23 00:13:52 +00001718 pResult = jsonMergePatch(&x, 0, y.aNode);
1719 assert( pResult!=0 || x.oom );
1720 if( pResult ){
1721 jsonReturnJson(pResult, ctx, 0);
1722 }else{
1723 sqlite3_result_error_nomem(ctx);
1724 }
drh633647a2017-03-22 21:24:31 +00001725 jsonParseReset(&x);
1726 jsonParseReset(&y);
1727}
1728
1729
drh987eb1f2015-08-17 15:17:37 +00001730/*
1731** Implementation of the json_object(NAME,VALUE,...) function. Return a JSON
1732** object that contains all name/value given in arguments. Or if any name
1733** is not a string or if any value is a BLOB, throw an error.
1734*/
1735static void jsonObjectFunc(
drhbc8f0922015-08-22 19:39:04 +00001736 sqlite3_context *ctx,
drh987eb1f2015-08-17 15:17:37 +00001737 int argc,
1738 sqlite3_value **argv
1739){
1740 int i;
drh505ad2c2015-08-21 17:33:11 +00001741 JsonString jx;
drh987eb1f2015-08-17 15:17:37 +00001742 const char *z;
1743 u32 n;
1744
1745 if( argc&1 ){
drhbc8f0922015-08-22 19:39:04 +00001746 sqlite3_result_error(ctx, "json_object() requires an even number "
drh987eb1f2015-08-17 15:17:37 +00001747 "of arguments", -1);
1748 return;
1749 }
drhbc8f0922015-08-22 19:39:04 +00001750 jsonInit(&jx, ctx);
drhd0960592015-08-17 21:22:32 +00001751 jsonAppendChar(&jx, '{');
drh987eb1f2015-08-17 15:17:37 +00001752 for(i=0; i<argc; i+=2){
drh987eb1f2015-08-17 15:17:37 +00001753 if( sqlite3_value_type(argv[i])!=SQLITE_TEXT ){
drhbc8f0922015-08-22 19:39:04 +00001754 sqlite3_result_error(ctx, "json_object() labels must be TEXT", -1);
drhdc384952015-09-19 18:54:39 +00001755 jsonReset(&jx);
drh987eb1f2015-08-17 15:17:37 +00001756 return;
1757 }
drhd0960592015-08-17 21:22:32 +00001758 jsonAppendSeparator(&jx);
drh987eb1f2015-08-17 15:17:37 +00001759 z = (const char*)sqlite3_value_text(argv[i]);
1760 n = (u32)sqlite3_value_bytes(argv[i]);
1761 jsonAppendString(&jx, z, n);
drhd0960592015-08-17 21:22:32 +00001762 jsonAppendChar(&jx, ':');
drhf5ddb9c2015-09-11 00:06:41 +00001763 jsonAppendValue(&jx, argv[i+1]);
drh987eb1f2015-08-17 15:17:37 +00001764 }
drhd0960592015-08-17 21:22:32 +00001765 jsonAppendChar(&jx, '}');
drh987eb1f2015-08-17 15:17:37 +00001766 jsonResult(&jx);
drhf5ddb9c2015-09-11 00:06:41 +00001767 sqlite3_result_subtype(ctx, JSON_SUBTYPE);
drh987eb1f2015-08-17 15:17:37 +00001768}
1769
1770
1771/*
drh301eecc2015-08-17 20:14:19 +00001772** json_remove(JSON, PATH, ...)
1773**
drh3ad93bb2015-08-29 19:41:45 +00001774** Remove the named elements from JSON and return the result. malformed
1775** JSON or PATH arguments result in an error.
drh301eecc2015-08-17 20:14:19 +00001776*/
1777static void jsonRemoveFunc(
drhbc8f0922015-08-22 19:39:04 +00001778 sqlite3_context *ctx,
drh301eecc2015-08-17 20:14:19 +00001779 int argc,
1780 sqlite3_value **argv
1781){
1782 JsonParse x; /* The parse */
1783 JsonNode *pNode;
1784 const char *zPath;
1785 u32 i;
1786
1787 if( argc<1 ) return;
drhbc8f0922015-08-22 19:39:04 +00001788 if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return;
drha8f39a92015-09-21 22:53:16 +00001789 assert( x.nNode );
1790 for(i=1; i<(u32)argc; i++){
1791 zPath = (const char*)sqlite3_value_text(argv[i]);
1792 if( zPath==0 ) goto remove_done;
1793 pNode = jsonLookup(&x, zPath, 0, ctx);
1794 if( x.nErr ) goto remove_done;
1795 if( pNode ) pNode->jnFlags |= JNODE_REMOVE;
1796 }
1797 if( (x.aNode[0].jnFlags & JNODE_REMOVE)==0 ){
1798 jsonReturnJson(x.aNode, ctx, 0);
drhd0960592015-08-17 21:22:32 +00001799 }
drha7714022015-08-29 00:54:49 +00001800remove_done:
drh505ad2c2015-08-21 17:33:11 +00001801 jsonParseReset(&x);
drhd0960592015-08-17 21:22:32 +00001802}
1803
1804/*
1805** json_replace(JSON, PATH, VALUE, ...)
1806**
1807** Replace the value at PATH with VALUE. If PATH does not already exist,
drh3ad93bb2015-08-29 19:41:45 +00001808** this routine is a no-op. If JSON or PATH is malformed, throw an error.
drhd0960592015-08-17 21:22:32 +00001809*/
1810static void jsonReplaceFunc(
drhbc8f0922015-08-22 19:39:04 +00001811 sqlite3_context *ctx,
drhd0960592015-08-17 21:22:32 +00001812 int argc,
1813 sqlite3_value **argv
1814){
1815 JsonParse x; /* The parse */
1816 JsonNode *pNode;
1817 const char *zPath;
1818 u32 i;
1819
1820 if( argc<1 ) return;
1821 if( (argc&1)==0 ) {
drhbc8f0922015-08-22 19:39:04 +00001822 jsonWrongNumArgs(ctx, "replace");
drhd0960592015-08-17 21:22:32 +00001823 return;
1824 }
drhbc8f0922015-08-22 19:39:04 +00001825 if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return;
drha8f39a92015-09-21 22:53:16 +00001826 assert( x.nNode );
1827 for(i=1; i<(u32)argc; i+=2){
1828 zPath = (const char*)sqlite3_value_text(argv[i]);
1829 pNode = jsonLookup(&x, zPath, 0, ctx);
1830 if( x.nErr ) goto replace_err;
1831 if( pNode ){
drh285f2ef2021-10-15 16:15:04 +00001832 assert( pNode->eU==0 || pNode->eU==1 || pNode->eU==4 );
1833 json_testcase( pNode->eU!=0 && pNode->eU!=1 );
drha8f39a92015-09-21 22:53:16 +00001834 pNode->jnFlags |= (u8)JNODE_REPLACE;
drh285f2ef2021-10-15 16:15:04 +00001835 VVA( pNode->eU = 4 );
drh633647a2017-03-22 21:24:31 +00001836 pNode->u.iReplace = i + 1;
drhd0960592015-08-17 21:22:32 +00001837 }
drha8f39a92015-09-21 22:53:16 +00001838 }
1839 if( x.aNode[0].jnFlags & JNODE_REPLACE ){
drh285f2ef2021-10-15 16:15:04 +00001840 assert( x.aNode[0].eU==4 );
drh633647a2017-03-22 21:24:31 +00001841 sqlite3_result_value(ctx, argv[x.aNode[0].u.iReplace]);
drha8f39a92015-09-21 22:53:16 +00001842 }else{
1843 jsonReturnJson(x.aNode, ctx, argv);
drh301eecc2015-08-17 20:14:19 +00001844 }
drha7714022015-08-29 00:54:49 +00001845replace_err:
drh505ad2c2015-08-21 17:33:11 +00001846 jsonParseReset(&x);
drh301eecc2015-08-17 20:14:19 +00001847}
drh505ad2c2015-08-21 17:33:11 +00001848
drh52216ad2015-08-18 02:28:03 +00001849/*
1850** json_set(JSON, PATH, VALUE, ...)
1851**
1852** Set the value at PATH to VALUE. Create the PATH if it does not already
1853** exist. Overwrite existing values that do exist.
drh3ad93bb2015-08-29 19:41:45 +00001854** If JSON or PATH is malformed, throw an error.
drh52216ad2015-08-18 02:28:03 +00001855**
1856** json_insert(JSON, PATH, VALUE, ...)
1857**
1858** Create PATH and initialize it to VALUE. If PATH already exists, this
drh3ad93bb2015-08-29 19:41:45 +00001859** routine is a no-op. If JSON or PATH is malformed, throw an error.
drh52216ad2015-08-18 02:28:03 +00001860*/
1861static void jsonSetFunc(
drhbc8f0922015-08-22 19:39:04 +00001862 sqlite3_context *ctx,
drh52216ad2015-08-18 02:28:03 +00001863 int argc,
1864 sqlite3_value **argv
1865){
1866 JsonParse x; /* The parse */
1867 JsonNode *pNode;
1868 const char *zPath;
1869 u32 i;
1870 int bApnd;
drhbc8f0922015-08-22 19:39:04 +00001871 int bIsSet = *(int*)sqlite3_user_data(ctx);
drh52216ad2015-08-18 02:28:03 +00001872
1873 if( argc<1 ) return;
1874 if( (argc&1)==0 ) {
drhbc8f0922015-08-22 19:39:04 +00001875 jsonWrongNumArgs(ctx, bIsSet ? "set" : "insert");
drh52216ad2015-08-18 02:28:03 +00001876 return;
1877 }
drhbc8f0922015-08-22 19:39:04 +00001878 if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return;
drha8f39a92015-09-21 22:53:16 +00001879 assert( x.nNode );
1880 for(i=1; i<(u32)argc; i+=2){
1881 zPath = (const char*)sqlite3_value_text(argv[i]);
1882 bApnd = 0;
1883 pNode = jsonLookup(&x, zPath, &bApnd, ctx);
1884 if( x.oom ){
1885 sqlite3_result_error_nomem(ctx);
1886 goto jsonSetDone;
1887 }else if( x.nErr ){
1888 goto jsonSetDone;
1889 }else if( pNode && (bApnd || bIsSet) ){
drh285f2ef2021-10-15 16:15:04 +00001890 json_testcase( pNode->eU!=0 && pNode->eU!=1 && pNode->eU!=4 );
1891 assert( pNode->eU!=3 || pNode->eU!=5 );
1892 VVA( pNode->eU = 4 );
drha8f39a92015-09-21 22:53:16 +00001893 pNode->jnFlags |= (u8)JNODE_REPLACE;
drh633647a2017-03-22 21:24:31 +00001894 pNode->u.iReplace = i + 1;
drh52216ad2015-08-18 02:28:03 +00001895 }
drha8f39a92015-09-21 22:53:16 +00001896 }
1897 if( x.aNode[0].jnFlags & JNODE_REPLACE ){
drh285f2ef2021-10-15 16:15:04 +00001898 assert( x.aNode[0].eU==4 );
drh633647a2017-03-22 21:24:31 +00001899 sqlite3_result_value(ctx, argv[x.aNode[0].u.iReplace]);
drha8f39a92015-09-21 22:53:16 +00001900 }else{
1901 jsonReturnJson(x.aNode, ctx, argv);
drh52216ad2015-08-18 02:28:03 +00001902 }
drhbc8f0922015-08-22 19:39:04 +00001903jsonSetDone:
drh505ad2c2015-08-21 17:33:11 +00001904 jsonParseReset(&x);
drh52216ad2015-08-18 02:28:03 +00001905}
drh301eecc2015-08-17 20:14:19 +00001906
1907/*
drh987eb1f2015-08-17 15:17:37 +00001908** json_type(JSON)
1909** json_type(JSON, PATH)
1910**
drh3ad93bb2015-08-29 19:41:45 +00001911** Return the top-level "type" of a JSON string. Throw an error if
1912** either the JSON or PATH inputs are not well-formed.
drh987eb1f2015-08-17 15:17:37 +00001913*/
1914static void jsonTypeFunc(
drhbc8f0922015-08-22 19:39:04 +00001915 sqlite3_context *ctx,
drh987eb1f2015-08-17 15:17:37 +00001916 int argc,
1917 sqlite3_value **argv
1918){
drhe35fc302018-08-30 01:52:10 +00001919 JsonParse *p; /* The parse */
drh987eb1f2015-08-17 15:17:37 +00001920 const char *zPath;
drha8f39a92015-09-21 22:53:16 +00001921 JsonNode *pNode;
drh987eb1f2015-08-17 15:17:37 +00001922
drhe35fc302018-08-30 01:52:10 +00001923 p = jsonParseCached(ctx, argv, ctx);
1924 if( p==0 ) return;
drha8f39a92015-09-21 22:53:16 +00001925 if( argc==2 ){
1926 zPath = (const char*)sqlite3_value_text(argv[1]);
drhe35fc302018-08-30 01:52:10 +00001927 pNode = jsonLookup(p, zPath, 0, ctx);
drha8f39a92015-09-21 22:53:16 +00001928 }else{
drhe35fc302018-08-30 01:52:10 +00001929 pNode = p->aNode;
drha8f39a92015-09-21 22:53:16 +00001930 }
1931 if( pNode ){
1932 sqlite3_result_text(ctx, jsonType[pNode->eType], -1, SQLITE_STATIC);
drh987eb1f2015-08-17 15:17:37 +00001933 }
drh987eb1f2015-08-17 15:17:37 +00001934}
drh5634cc02015-08-17 11:28:03 +00001935
drhbc8f0922015-08-22 19:39:04 +00001936/*
1937** json_valid(JSON)
1938**
drh3ad93bb2015-08-29 19:41:45 +00001939** Return 1 if JSON is a well-formed JSON string according to RFC-7159.
1940** Return 0 otherwise.
drhbc8f0922015-08-22 19:39:04 +00001941*/
1942static void jsonValidFunc(
1943 sqlite3_context *ctx,
1944 int argc,
1945 sqlite3_value **argv
1946){
drhe35fc302018-08-30 01:52:10 +00001947 JsonParse *p; /* The parse */
mistachkin16a93122015-09-11 18:05:01 +00001948 UNUSED_PARAM(argc);
drhe35fc302018-08-30 01:52:10 +00001949 p = jsonParseCached(ctx, argv, 0);
1950 sqlite3_result_int(ctx, p!=0);
drhbc8f0922015-08-22 19:39:04 +00001951}
1952
drhff135ae2015-12-30 01:07:02 +00001953
1954/****************************************************************************
1955** Aggregate SQL function implementations
1956****************************************************************************/
1957/*
1958** json_group_array(VALUE)
1959**
1960** Return a JSON array composed of all values in the aggregate.
1961*/
1962static void jsonArrayStep(
1963 sqlite3_context *ctx,
1964 int argc,
1965 sqlite3_value **argv
1966){
1967 JsonString *pStr;
drhdf3a9072016-02-11 15:37:18 +00001968 UNUSED_PARAM(argc);
drhff135ae2015-12-30 01:07:02 +00001969 pStr = (JsonString*)sqlite3_aggregate_context(ctx, sizeof(*pStr));
1970 if( pStr ){
1971 if( pStr->zBuf==0 ){
1972 jsonInit(pStr, ctx);
1973 jsonAppendChar(pStr, '[');
drhfab5b072019-09-14 00:21:34 +00001974 }else if( pStr->nUsed>1 ){
drhff135ae2015-12-30 01:07:02 +00001975 jsonAppendChar(pStr, ',');
drhff135ae2015-12-30 01:07:02 +00001976 }
dan8505d732021-04-14 12:11:39 +00001977 pStr->pCtx = ctx;
drhff135ae2015-12-30 01:07:02 +00001978 jsonAppendValue(pStr, argv[0]);
1979 }
1980}
drh8be47a72018-07-05 20:05:29 +00001981static void jsonArrayCompute(sqlite3_context *ctx, int isFinal){
drhff135ae2015-12-30 01:07:02 +00001982 JsonString *pStr;
1983 pStr = (JsonString*)sqlite3_aggregate_context(ctx, 0);
1984 if( pStr ){
1985 pStr->pCtx = ctx;
1986 jsonAppendChar(pStr, ']');
1987 if( pStr->bErr ){
drh4a642b62016-02-05 01:55:27 +00001988 if( pStr->bErr==1 ) sqlite3_result_error_nomem(ctx);
drh23079262016-01-01 00:15:59 +00001989 assert( pStr->bStatic );
drh8be47a72018-07-05 20:05:29 +00001990 }else if( isFinal ){
mistachkined008ec2018-09-12 01:05:26 +00001991 sqlite3_result_text(ctx, pStr->zBuf, (int)pStr->nUsed,
drhff135ae2015-12-30 01:07:02 +00001992 pStr->bStatic ? SQLITE_TRANSIENT : sqlite3_free);
1993 pStr->bStatic = 1;
drh8be47a72018-07-05 20:05:29 +00001994 }else{
mistachkined008ec2018-09-12 01:05:26 +00001995 sqlite3_result_text(ctx, pStr->zBuf, (int)pStr->nUsed, SQLITE_TRANSIENT);
drh8be47a72018-07-05 20:05:29 +00001996 pStr->nUsed--;
drhff135ae2015-12-30 01:07:02 +00001997 }
1998 }else{
1999 sqlite3_result_text(ctx, "[]", 2, SQLITE_STATIC);
2000 }
2001 sqlite3_result_subtype(ctx, JSON_SUBTYPE);
2002}
drh8be47a72018-07-05 20:05:29 +00002003static void jsonArrayValue(sqlite3_context *ctx){
2004 jsonArrayCompute(ctx, 0);
2005}
2006static void jsonArrayFinal(sqlite3_context *ctx){
2007 jsonArrayCompute(ctx, 1);
2008}
2009
2010#ifndef SQLITE_OMIT_WINDOWFUNC
2011/*
2012** This method works for both json_group_array() and json_group_object().
2013** It works by removing the first element of the group by searching forward
2014** to the first comma (",") that is not within a string and deleting all
2015** text through that comma.
2016*/
2017static void jsonGroupInverse(
2018 sqlite3_context *ctx,
2019 int argc,
2020 sqlite3_value **argv
2021){
drhe39f3882019-09-21 17:31:03 +00002022 unsigned int i;
drh8be47a72018-07-05 20:05:29 +00002023 int inStr = 0;
drhfab5b072019-09-14 00:21:34 +00002024 int nNest = 0;
drh8be47a72018-07-05 20:05:29 +00002025 char *z;
drhfab5b072019-09-14 00:21:34 +00002026 char c;
drh8be47a72018-07-05 20:05:29 +00002027 JsonString *pStr;
drhc7bf5712018-07-09 22:49:01 +00002028 UNUSED_PARAM(argc);
2029 UNUSED_PARAM(argv);
drh8be47a72018-07-05 20:05:29 +00002030 pStr = (JsonString*)sqlite3_aggregate_context(ctx, 0);
drh491d4c82018-07-07 20:23:46 +00002031#ifdef NEVER
drhfd4b7282018-07-07 19:47:21 +00002032 /* pStr is always non-NULL since jsonArrayStep() or jsonObjectStep() will
2033 ** always have been called to initalize it */
2034 if( NEVER(!pStr) ) return;
drh491d4c82018-07-07 20:23:46 +00002035#endif
drh8be47a72018-07-05 20:05:29 +00002036 z = pStr->zBuf;
drh0e5cd342021-04-13 01:12:32 +00002037 for(i=1; i<pStr->nUsed && ((c = z[i])!=',' || inStr || nNest); i++){
drhfab5b072019-09-14 00:21:34 +00002038 if( c=='"' ){
drh8be47a72018-07-05 20:05:29 +00002039 inStr = !inStr;
drhfab5b072019-09-14 00:21:34 +00002040 }else if( c=='\\' ){
drh8be47a72018-07-05 20:05:29 +00002041 i++;
drhfab5b072019-09-14 00:21:34 +00002042 }else if( !inStr ){
2043 if( c=='{' || c=='[' ) nNest++;
2044 if( c=='}' || c==']' ) nNest--;
drh8be47a72018-07-05 20:05:29 +00002045 }
2046 }
drh0e5cd342021-04-13 01:12:32 +00002047 if( i<pStr->nUsed ){
2048 pStr->nUsed -= i;
2049 memmove(&z[1], &z[i+1], (size_t)pStr->nUsed-1);
2050 z[pStr->nUsed] = 0;
2051 }else{
2052 pStr->nUsed = 1;
2053 }
drh8be47a72018-07-05 20:05:29 +00002054}
2055#else
2056# define jsonGroupInverse 0
2057#endif
2058
drhff135ae2015-12-30 01:07:02 +00002059
2060/*
2061** json_group_obj(NAME,VALUE)
2062**
2063** Return a JSON object composed of all names and values in the aggregate.
2064*/
2065static void jsonObjectStep(
2066 sqlite3_context *ctx,
2067 int argc,
2068 sqlite3_value **argv
2069){
2070 JsonString *pStr;
2071 const char *z;
2072 u32 n;
drhdf3a9072016-02-11 15:37:18 +00002073 UNUSED_PARAM(argc);
drhff135ae2015-12-30 01:07:02 +00002074 pStr = (JsonString*)sqlite3_aggregate_context(ctx, sizeof(*pStr));
2075 if( pStr ){
2076 if( pStr->zBuf==0 ){
2077 jsonInit(pStr, ctx);
2078 jsonAppendChar(pStr, '{');
drhfab5b072019-09-14 00:21:34 +00002079 }else if( pStr->nUsed>1 ){
drhff135ae2015-12-30 01:07:02 +00002080 jsonAppendChar(pStr, ',');
drhff135ae2015-12-30 01:07:02 +00002081 }
drhd2f55772021-05-28 12:15:19 +00002082 pStr->pCtx = ctx;
drhff135ae2015-12-30 01:07:02 +00002083 z = (const char*)sqlite3_value_text(argv[0]);
2084 n = (u32)sqlite3_value_bytes(argv[0]);
2085 jsonAppendString(pStr, z, n);
2086 jsonAppendChar(pStr, ':');
2087 jsonAppendValue(pStr, argv[1]);
2088 }
2089}
drh8be47a72018-07-05 20:05:29 +00002090static void jsonObjectCompute(sqlite3_context *ctx, int isFinal){
drhff135ae2015-12-30 01:07:02 +00002091 JsonString *pStr;
2092 pStr = (JsonString*)sqlite3_aggregate_context(ctx, 0);
2093 if( pStr ){
2094 jsonAppendChar(pStr, '}');
2095 if( pStr->bErr ){
drh6850a632016-11-07 18:18:08 +00002096 if( pStr->bErr==1 ) sqlite3_result_error_nomem(ctx);
drh23079262016-01-01 00:15:59 +00002097 assert( pStr->bStatic );
drh8be47a72018-07-05 20:05:29 +00002098 }else if( isFinal ){
mistachkined008ec2018-09-12 01:05:26 +00002099 sqlite3_result_text(ctx, pStr->zBuf, (int)pStr->nUsed,
drhff135ae2015-12-30 01:07:02 +00002100 pStr->bStatic ? SQLITE_TRANSIENT : sqlite3_free);
2101 pStr->bStatic = 1;
drh8be47a72018-07-05 20:05:29 +00002102 }else{
mistachkined008ec2018-09-12 01:05:26 +00002103 sqlite3_result_text(ctx, pStr->zBuf, (int)pStr->nUsed, SQLITE_TRANSIENT);
drh8be47a72018-07-05 20:05:29 +00002104 pStr->nUsed--;
drhff135ae2015-12-30 01:07:02 +00002105 }
2106 }else{
2107 sqlite3_result_text(ctx, "{}", 2, SQLITE_STATIC);
2108 }
2109 sqlite3_result_subtype(ctx, JSON_SUBTYPE);
2110}
drh8be47a72018-07-05 20:05:29 +00002111static void jsonObjectValue(sqlite3_context *ctx){
2112 jsonObjectCompute(ctx, 0);
2113}
2114static void jsonObjectFinal(sqlite3_context *ctx){
2115 jsonObjectCompute(ctx, 1);
2116}
2117
drhff135ae2015-12-30 01:07:02 +00002118
2119
drhd2975922015-08-29 17:22:33 +00002120#ifndef SQLITE_OMIT_VIRTUALTABLE
drhcb6c6c62015-08-19 22:47:17 +00002121/****************************************************************************
2122** The json_each virtual table
2123****************************************************************************/
2124typedef struct JsonEachCursor JsonEachCursor;
2125struct JsonEachCursor {
2126 sqlite3_vtab_cursor base; /* Base class - must be first */
drh505ad2c2015-08-21 17:33:11 +00002127 u32 iRowid; /* The rowid */
drh852944e2015-09-10 03:29:11 +00002128 u32 iBegin; /* The first node of the scan */
drh505ad2c2015-08-21 17:33:11 +00002129 u32 i; /* Index in sParse.aNode[] of current row */
2130 u32 iEnd; /* EOF when i equals or exceeds this value */
2131 u8 eType; /* Type of top-level element */
2132 u8 bRecursive; /* True for json_tree(). False for json_each() */
2133 char *zJson; /* Input JSON */
drh383de692015-09-10 17:20:57 +00002134 char *zRoot; /* Path by which to filter zJson */
drh505ad2c2015-08-21 17:33:11 +00002135 JsonParse sParse; /* Parse of the input JSON */
drhcb6c6c62015-08-19 22:47:17 +00002136};
2137
2138/* Constructor for the json_each virtual table */
2139static int jsonEachConnect(
2140 sqlite3 *db,
2141 void *pAux,
2142 int argc, const char *const*argv,
2143 sqlite3_vtab **ppVtab,
2144 char **pzErr
2145){
2146 sqlite3_vtab *pNew;
drh505ad2c2015-08-21 17:33:11 +00002147 int rc;
drhcb6c6c62015-08-19 22:47:17 +00002148
2149/* Column numbers */
drh4af352d2015-08-21 20:02:48 +00002150#define JEACH_KEY 0
2151#define JEACH_VALUE 1
2152#define JEACH_TYPE 2
2153#define JEACH_ATOM 3
2154#define JEACH_ID 4
2155#define JEACH_PARENT 5
2156#define JEACH_FULLKEY 6
drh383de692015-09-10 17:20:57 +00002157#define JEACH_PATH 7
drh43579192018-11-16 16:04:50 +00002158/* The xBestIndex method assumes that the JSON and ROOT columns are
2159** the last two columns in the table. Should this ever changes, be
2160** sure to update the xBestIndex method. */
drh383de692015-09-10 17:20:57 +00002161#define JEACH_JSON 8
2162#define JEACH_ROOT 9
drhcb6c6c62015-08-19 22:47:17 +00002163
drh6fd5c1e2015-08-21 20:37:12 +00002164 UNUSED_PARAM(pzErr);
2165 UNUSED_PARAM(argv);
2166 UNUSED_PARAM(argc);
2167 UNUSED_PARAM(pAux);
drh505ad2c2015-08-21 17:33:11 +00002168 rc = sqlite3_declare_vtab(db,
drh383de692015-09-10 17:20:57 +00002169 "CREATE TABLE x(key,value,type,atom,id,parent,fullkey,path,"
2170 "json HIDDEN,root HIDDEN)");
drh505ad2c2015-08-21 17:33:11 +00002171 if( rc==SQLITE_OK ){
2172 pNew = *ppVtab = sqlite3_malloc( sizeof(*pNew) );
2173 if( pNew==0 ) return SQLITE_NOMEM;
2174 memset(pNew, 0, sizeof(*pNew));
drh2b1c2aa2020-01-07 19:45:40 +00002175 sqlite3_vtab_config(db, SQLITE_VTAB_INNOCUOUS);
drh505ad2c2015-08-21 17:33:11 +00002176 }
2177 return rc;
drhcb6c6c62015-08-19 22:47:17 +00002178}
2179
2180/* destructor for json_each virtual table */
2181static int jsonEachDisconnect(sqlite3_vtab *pVtab){
2182 sqlite3_free(pVtab);
2183 return SQLITE_OK;
2184}
2185
drh505ad2c2015-08-21 17:33:11 +00002186/* constructor for a JsonEachCursor object for json_each(). */
2187static int jsonEachOpenEach(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
drhcb6c6c62015-08-19 22:47:17 +00002188 JsonEachCursor *pCur;
drh6fd5c1e2015-08-21 20:37:12 +00002189
2190 UNUSED_PARAM(p);
drhcb6c6c62015-08-19 22:47:17 +00002191 pCur = sqlite3_malloc( sizeof(*pCur) );
2192 if( pCur==0 ) return SQLITE_NOMEM;
2193 memset(pCur, 0, sizeof(*pCur));
2194 *ppCursor = &pCur->base;
2195 return SQLITE_OK;
2196}
2197
drh505ad2c2015-08-21 17:33:11 +00002198/* constructor for a JsonEachCursor object for json_tree(). */
2199static int jsonEachOpenTree(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
2200 int rc = jsonEachOpenEach(p, ppCursor);
2201 if( rc==SQLITE_OK ){
2202 JsonEachCursor *pCur = (JsonEachCursor*)*ppCursor;
2203 pCur->bRecursive = 1;
2204 }
2205 return rc;
2206}
2207
drhcb6c6c62015-08-19 22:47:17 +00002208/* Reset a JsonEachCursor back to its original state. Free any memory
2209** held. */
2210static void jsonEachCursorReset(JsonEachCursor *p){
2211 sqlite3_free(p->zJson);
drh383de692015-09-10 17:20:57 +00002212 sqlite3_free(p->zRoot);
drh505ad2c2015-08-21 17:33:11 +00002213 jsonParseReset(&p->sParse);
drhcb6c6c62015-08-19 22:47:17 +00002214 p->iRowid = 0;
2215 p->i = 0;
2216 p->iEnd = 0;
2217 p->eType = 0;
drhcb6c6c62015-08-19 22:47:17 +00002218 p->zJson = 0;
drh383de692015-09-10 17:20:57 +00002219 p->zRoot = 0;
drhcb6c6c62015-08-19 22:47:17 +00002220}
2221
2222/* Destructor for a jsonEachCursor object */
2223static int jsonEachClose(sqlite3_vtab_cursor *cur){
2224 JsonEachCursor *p = (JsonEachCursor*)cur;
2225 jsonEachCursorReset(p);
2226 sqlite3_free(cur);
2227 return SQLITE_OK;
2228}
2229
2230/* Return TRUE if the jsonEachCursor object has been advanced off the end
2231** of the JSON object */
2232static int jsonEachEof(sqlite3_vtab_cursor *cur){
2233 JsonEachCursor *p = (JsonEachCursor*)cur;
2234 return p->i >= p->iEnd;
2235}
2236
drh505ad2c2015-08-21 17:33:11 +00002237/* Advance the cursor to the next element for json_tree() */
drh4af352d2015-08-21 20:02:48 +00002238static int jsonEachNext(sqlite3_vtab_cursor *cur){
drh505ad2c2015-08-21 17:33:11 +00002239 JsonEachCursor *p = (JsonEachCursor*)cur;
drh4af352d2015-08-21 20:02:48 +00002240 if( p->bRecursive ){
drh852944e2015-09-10 03:29:11 +00002241 if( p->sParse.aNode[p->i].jnFlags & JNODE_LABEL ) p->i++;
2242 p->i++;
drh4af352d2015-08-21 20:02:48 +00002243 p->iRowid++;
drh852944e2015-09-10 03:29:11 +00002244 if( p->i<p->iEnd ){
drh8784eca2015-08-23 02:42:30 +00002245 u32 iUp = p->sParse.aUp[p->i];
2246 JsonNode *pUp = &p->sParse.aNode[iUp];
drh4af352d2015-08-21 20:02:48 +00002247 p->eType = pUp->eType;
drh8784eca2015-08-23 02:42:30 +00002248 if( pUp->eType==JSON_ARRAY ){
drh285f2ef2021-10-15 16:15:04 +00002249 assert( pUp->eU==0 || pUp->eU==3 );
2250 json_testcase( pUp->eU==3 );
2251 VVA( pUp->eU = 3 );
drh8784eca2015-08-23 02:42:30 +00002252 if( iUp==p->i-1 ){
2253 pUp->u.iKey = 0;
2254 }else{
2255 pUp->u.iKey++;
2256 }
drh4af352d2015-08-21 20:02:48 +00002257 }
2258 }
drh505ad2c2015-08-21 17:33:11 +00002259 }else{
drh4af352d2015-08-21 20:02:48 +00002260 switch( p->eType ){
2261 case JSON_ARRAY: {
2262 p->i += jsonNodeSize(&p->sParse.aNode[p->i]);
2263 p->iRowid++;
2264 break;
2265 }
2266 case JSON_OBJECT: {
2267 p->i += 1 + jsonNodeSize(&p->sParse.aNode[p->i+1]);
2268 p->iRowid++;
2269 break;
2270 }
2271 default: {
2272 p->i = p->iEnd;
2273 break;
2274 }
drh505ad2c2015-08-21 17:33:11 +00002275 }
2276 }
2277 return SQLITE_OK;
2278}
2279
drh4af352d2015-08-21 20:02:48 +00002280/* Append the name of the path for element i to pStr
2281*/
2282static void jsonEachComputePath(
2283 JsonEachCursor *p, /* The cursor */
2284 JsonString *pStr, /* Write the path here */
2285 u32 i /* Path to this element */
2286){
2287 JsonNode *pNode, *pUp;
2288 u32 iUp;
2289 if( i==0 ){
2290 jsonAppendChar(pStr, '$');
2291 return;
drhcb6c6c62015-08-19 22:47:17 +00002292 }
drh4af352d2015-08-21 20:02:48 +00002293 iUp = p->sParse.aUp[i];
2294 jsonEachComputePath(p, pStr, iUp);
2295 pNode = &p->sParse.aNode[i];
2296 pUp = &p->sParse.aNode[iUp];
2297 if( pUp->eType==JSON_ARRAY ){
drh285f2ef2021-10-15 16:15:04 +00002298 assert( pUp->eU==3 || (pUp->eU==0 && pUp->u.iKey==0) );
2299 testcase( pUp->eU==0 );
drh4af352d2015-08-21 20:02:48 +00002300 jsonPrintf(30, pStr, "[%d]", pUp->u.iKey);
2301 }else{
2302 assert( pUp->eType==JSON_OBJECT );
drh852944e2015-09-10 03:29:11 +00002303 if( (pNode->jnFlags & JNODE_LABEL)==0 ) pNode--;
drh4af352d2015-08-21 20:02:48 +00002304 assert( pNode->eType==JSON_STRING );
drh852944e2015-09-10 03:29:11 +00002305 assert( pNode->jnFlags & JNODE_LABEL );
drh285f2ef2021-10-15 16:15:04 +00002306 assert( pNode->eU==1 );
drh4af352d2015-08-21 20:02:48 +00002307 jsonPrintf(pNode->n+1, pStr, ".%.*s", pNode->n-2, pNode->u.zJContent+1);
2308 }
drhcb6c6c62015-08-19 22:47:17 +00002309}
2310
2311/* Return the value of a column */
2312static int jsonEachColumn(
2313 sqlite3_vtab_cursor *cur, /* The cursor */
2314 sqlite3_context *ctx, /* First argument to sqlite3_result_...() */
2315 int i /* Which column to return */
2316){
2317 JsonEachCursor *p = (JsonEachCursor*)cur;
drh505ad2c2015-08-21 17:33:11 +00002318 JsonNode *pThis = &p->sParse.aNode[p->i];
drhcb6c6c62015-08-19 22:47:17 +00002319 switch( i ){
2320 case JEACH_KEY: {
drh8784eca2015-08-23 02:42:30 +00002321 if( p->i==0 ) break;
drhcb6c6c62015-08-19 22:47:17 +00002322 if( p->eType==JSON_OBJECT ){
drh505ad2c2015-08-21 17:33:11 +00002323 jsonReturn(pThis, ctx, 0);
2324 }else if( p->eType==JSON_ARRAY ){
2325 u32 iKey;
2326 if( p->bRecursive ){
2327 if( p->iRowid==0 ) break;
drh285f2ef2021-10-15 16:15:04 +00002328 assert( p->sParse.aNode[p->sParse.aUp[p->i]].eU==3 );
drh8784eca2015-08-23 02:42:30 +00002329 iKey = p->sParse.aNode[p->sParse.aUp[p->i]].u.iKey;
drh505ad2c2015-08-21 17:33:11 +00002330 }else{
2331 iKey = p->iRowid;
2332 }
drh6fd5c1e2015-08-21 20:37:12 +00002333 sqlite3_result_int64(ctx, (sqlite3_int64)iKey);
drhcb6c6c62015-08-19 22:47:17 +00002334 }
2335 break;
2336 }
2337 case JEACH_VALUE: {
drh852944e2015-09-10 03:29:11 +00002338 if( pThis->jnFlags & JNODE_LABEL ) pThis++;
drh505ad2c2015-08-21 17:33:11 +00002339 jsonReturn(pThis, ctx, 0);
2340 break;
2341 }
2342 case JEACH_TYPE: {
drh852944e2015-09-10 03:29:11 +00002343 if( pThis->jnFlags & JNODE_LABEL ) pThis++;
drh505ad2c2015-08-21 17:33:11 +00002344 sqlite3_result_text(ctx, jsonType[pThis->eType], -1, SQLITE_STATIC);
2345 break;
2346 }
2347 case JEACH_ATOM: {
drh852944e2015-09-10 03:29:11 +00002348 if( pThis->jnFlags & JNODE_LABEL ) pThis++;
drh505ad2c2015-08-21 17:33:11 +00002349 if( pThis->eType>=JSON_ARRAY ) break;
2350 jsonReturn(pThis, ctx, 0);
2351 break;
2352 }
2353 case JEACH_ID: {
drh852944e2015-09-10 03:29:11 +00002354 sqlite3_result_int64(ctx,
2355 (sqlite3_int64)p->i + ((pThis->jnFlags & JNODE_LABEL)!=0));
drh505ad2c2015-08-21 17:33:11 +00002356 break;
2357 }
2358 case JEACH_PARENT: {
drh852944e2015-09-10 03:29:11 +00002359 if( p->i>p->iBegin && p->bRecursive ){
drh6fd5c1e2015-08-21 20:37:12 +00002360 sqlite3_result_int64(ctx, (sqlite3_int64)p->sParse.aUp[p->i]);
drhcb6c6c62015-08-19 22:47:17 +00002361 }
2362 break;
2363 }
drh4af352d2015-08-21 20:02:48 +00002364 case JEACH_FULLKEY: {
2365 JsonString x;
2366 jsonInit(&x, ctx);
2367 if( p->bRecursive ){
2368 jsonEachComputePath(p, &x, p->i);
2369 }else{
drh383de692015-09-10 17:20:57 +00002370 if( p->zRoot ){
2371 jsonAppendRaw(&x, p->zRoot, (int)strlen(p->zRoot));
drh4af352d2015-08-21 20:02:48 +00002372 }else{
2373 jsonAppendChar(&x, '$');
2374 }
2375 if( p->eType==JSON_ARRAY ){
2376 jsonPrintf(30, &x, "[%d]", p->iRowid);
drhdd7460f2018-05-16 12:19:11 +00002377 }else if( p->eType==JSON_OBJECT ){
drh285f2ef2021-10-15 16:15:04 +00002378 assert( pThis->eU==1 );
drh4af352d2015-08-21 20:02:48 +00002379 jsonPrintf(pThis->n, &x, ".%.*s", pThis->n-2, pThis->u.zJContent+1);
2380 }
2381 }
2382 jsonResult(&x);
2383 break;
2384 }
drhcb6c6c62015-08-19 22:47:17 +00002385 case JEACH_PATH: {
drh383de692015-09-10 17:20:57 +00002386 if( p->bRecursive ){
2387 JsonString x;
2388 jsonInit(&x, ctx);
2389 jsonEachComputePath(p, &x, p->sParse.aUp[p->i]);
2390 jsonResult(&x);
2391 break;
drh4af352d2015-08-21 20:02:48 +00002392 }
drh383de692015-09-10 17:20:57 +00002393 /* For json_each() path and root are the same so fall through
2394 ** into the root case */
drh08b92082020-08-10 14:18:00 +00002395 /* no break */ deliberate_fall_through
drh383de692015-09-10 17:20:57 +00002396 }
drh6850a632016-11-07 18:18:08 +00002397 default: {
drh383de692015-09-10 17:20:57 +00002398 const char *zRoot = p->zRoot;
drh6850a632016-11-07 18:18:08 +00002399 if( zRoot==0 ) zRoot = "$";
drh383de692015-09-10 17:20:57 +00002400 sqlite3_result_text(ctx, zRoot, -1, SQLITE_STATIC);
drhcb6c6c62015-08-19 22:47:17 +00002401 break;
2402 }
drh3d1d2a92015-09-22 01:15:49 +00002403 case JEACH_JSON: {
drh505ad2c2015-08-21 17:33:11 +00002404 assert( i==JEACH_JSON );
drhcb6c6c62015-08-19 22:47:17 +00002405 sqlite3_result_text(ctx, p->sParse.zJson, -1, SQLITE_STATIC);
2406 break;
2407 }
2408 }
2409 return SQLITE_OK;
2410}
2411
2412/* Return the current rowid value */
2413static int jsonEachRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){
2414 JsonEachCursor *p = (JsonEachCursor*)cur;
2415 *pRowid = p->iRowid;
2416 return SQLITE_OK;
2417}
2418
2419/* The query strategy is to look for an equality constraint on the json
2420** column. Without such a constraint, the table cannot operate. idxNum is
drh383de692015-09-10 17:20:57 +00002421** 1 if the constraint is found, 3 if the constraint and zRoot are found,
drhcb6c6c62015-08-19 22:47:17 +00002422** and 0 otherwise.
2423*/
2424static int jsonEachBestIndex(
2425 sqlite3_vtab *tab,
2426 sqlite3_index_info *pIdxInfo
2427){
drh43579192018-11-16 16:04:50 +00002428 int i; /* Loop counter or computed array index */
2429 int aIdx[2]; /* Index of constraints for JSON and ROOT */
2430 int unusableMask = 0; /* Mask of unusable JSON and ROOT constraints */
2431 int idxMask = 0; /* Mask of usable == constraints JSON and ROOT */
drhcb6c6c62015-08-19 22:47:17 +00002432 const struct sqlite3_index_constraint *pConstraint;
drh6fd5c1e2015-08-21 20:37:12 +00002433
drh43579192018-11-16 16:04:50 +00002434 /* This implementation assumes that JSON and ROOT are the last two
2435 ** columns in the table */
2436 assert( JEACH_ROOT == JEACH_JSON+1 );
drh6fd5c1e2015-08-21 20:37:12 +00002437 UNUSED_PARAM(tab);
drh43579192018-11-16 16:04:50 +00002438 aIdx[0] = aIdx[1] = -1;
drhcb6c6c62015-08-19 22:47:17 +00002439 pConstraint = pIdxInfo->aConstraint;
2440 for(i=0; i<pIdxInfo->nConstraint; i++, pConstraint++){
drh43579192018-11-16 16:04:50 +00002441 int iCol;
2442 int iMask;
2443 if( pConstraint->iColumn < JEACH_JSON ) continue;
2444 iCol = pConstraint->iColumn - JEACH_JSON;
2445 assert( iCol==0 || iCol==1 );
drh285f2ef2021-10-15 16:15:04 +00002446 testcase( iCol==0 );
drh43579192018-11-16 16:04:50 +00002447 iMask = 1 << iCol;
2448 if( pConstraint->usable==0 ){
2449 unusableMask |= iMask;
2450 }else if( pConstraint->op==SQLITE_INDEX_CONSTRAINT_EQ ){
2451 aIdx[iCol] = i;
2452 idxMask |= iMask;
drhcb6c6c62015-08-19 22:47:17 +00002453 }
2454 }
drh43579192018-11-16 16:04:50 +00002455 if( (unusableMask & ~idxMask)!=0 ){
2456 /* If there are any unusable constraints on JSON or ROOT, then reject
2457 ** this entire plan */
2458 return SQLITE_CONSTRAINT;
2459 }
2460 if( aIdx[0]<0 ){
2461 /* No JSON input. Leave estimatedCost at the huge value that it was
2462 ** initialized to to discourage the query planner from selecting this
2463 ** plan. */
drhcb6c6c62015-08-19 22:47:17 +00002464 pIdxInfo->idxNum = 0;
drhcb6c6c62015-08-19 22:47:17 +00002465 }else{
drh505ad2c2015-08-21 17:33:11 +00002466 pIdxInfo->estimatedCost = 1.0;
drh43579192018-11-16 16:04:50 +00002467 i = aIdx[0];
2468 pIdxInfo->aConstraintUsage[i].argvIndex = 1;
2469 pIdxInfo->aConstraintUsage[i].omit = 1;
2470 if( aIdx[1]<0 ){
2471 pIdxInfo->idxNum = 1; /* Only JSON supplied. Plan 1 */
drhcb6c6c62015-08-19 22:47:17 +00002472 }else{
drh43579192018-11-16 16:04:50 +00002473 i = aIdx[1];
2474 pIdxInfo->aConstraintUsage[i].argvIndex = 2;
2475 pIdxInfo->aConstraintUsage[i].omit = 1;
2476 pIdxInfo->idxNum = 3; /* Both JSON and ROOT are supplied. Plan 3 */
drhcb6c6c62015-08-19 22:47:17 +00002477 }
2478 }
2479 return SQLITE_OK;
2480}
2481
2482/* Start a search on a new JSON string */
2483static int jsonEachFilter(
2484 sqlite3_vtab_cursor *cur,
2485 int idxNum, const char *idxStr,
2486 int argc, sqlite3_value **argv
2487){
2488 JsonEachCursor *p = (JsonEachCursor*)cur;
2489 const char *z;
mistachkin16a93122015-09-11 18:05:01 +00002490 const char *zRoot = 0;
drhcb6c6c62015-08-19 22:47:17 +00002491 sqlite3_int64 n;
2492
drh6fd5c1e2015-08-21 20:37:12 +00002493 UNUSED_PARAM(idxStr);
2494 UNUSED_PARAM(argc);
drhcb6c6c62015-08-19 22:47:17 +00002495 jsonEachCursorReset(p);
2496 if( idxNum==0 ) return SQLITE_OK;
2497 z = (const char*)sqlite3_value_text(argv[0]);
2498 if( z==0 ) return SQLITE_OK;
drhcb6c6c62015-08-19 22:47:17 +00002499 n = sqlite3_value_bytes(argv[0]);
drh6fd5c1e2015-08-21 20:37:12 +00002500 p->zJson = sqlite3_malloc64( n+1 );
drhcb6c6c62015-08-19 22:47:17 +00002501 if( p->zJson==0 ) return SQLITE_NOMEM;
drh6fd5c1e2015-08-21 20:37:12 +00002502 memcpy(p->zJson, z, (size_t)n+1);
drha7714022015-08-29 00:54:49 +00002503 if( jsonParse(&p->sParse, 0, p->zJson) ){
2504 int rc = SQLITE_NOMEM;
2505 if( p->sParse.oom==0 ){
2506 sqlite3_free(cur->pVtab->zErrMsg);
2507 cur->pVtab->zErrMsg = sqlite3_mprintf("malformed JSON");
2508 if( cur->pVtab->zErrMsg ) rc = SQLITE_ERROR;
2509 }
drhcb6c6c62015-08-19 22:47:17 +00002510 jsonEachCursorReset(p);
drha7714022015-08-29 00:54:49 +00002511 return rc;
2512 }else if( p->bRecursive && jsonParseFindParents(&p->sParse) ){
2513 jsonEachCursorReset(p);
2514 return SQLITE_NOMEM;
drhcb6c6c62015-08-19 22:47:17 +00002515 }else{
drh95677942015-09-24 01:06:37 +00002516 JsonNode *pNode = 0;
drhcb6c6c62015-08-19 22:47:17 +00002517 if( idxNum==3 ){
drha7714022015-08-29 00:54:49 +00002518 const char *zErr = 0;
drha8f39a92015-09-21 22:53:16 +00002519 zRoot = (const char*)sqlite3_value_text(argv[1]);
2520 if( zRoot==0 ) return SQLITE_OK;
drhcb6c6c62015-08-19 22:47:17 +00002521 n = sqlite3_value_bytes(argv[1]);
drh383de692015-09-10 17:20:57 +00002522 p->zRoot = sqlite3_malloc64( n+1 );
2523 if( p->zRoot==0 ) return SQLITE_NOMEM;
2524 memcpy(p->zRoot, zRoot, (size_t)n+1);
drha8f39a92015-09-21 22:53:16 +00002525 if( zRoot[0]!='$' ){
2526 zErr = zRoot;
2527 }else{
2528 pNode = jsonLookupStep(&p->sParse, 0, p->zRoot+1, 0, &zErr);
2529 }
2530 if( zErr ){
drha7714022015-08-29 00:54:49 +00002531 sqlite3_free(cur->pVtab->zErrMsg);
2532 cur->pVtab->zErrMsg = jsonPathSyntaxError(zErr);
drhcb6c6c62015-08-19 22:47:17 +00002533 jsonEachCursorReset(p);
drha7714022015-08-29 00:54:49 +00002534 return cur->pVtab->zErrMsg ? SQLITE_ERROR : SQLITE_NOMEM;
2535 }else if( pNode==0 ){
drhcb6c6c62015-08-19 22:47:17 +00002536 return SQLITE_OK;
2537 }
2538 }else{
2539 pNode = p->sParse.aNode;
2540 }
drh852944e2015-09-10 03:29:11 +00002541 p->iBegin = p->i = (int)(pNode - p->sParse.aNode);
drhcb6c6c62015-08-19 22:47:17 +00002542 p->eType = pNode->eType;
2543 if( p->eType>=JSON_ARRAY ){
drh285f2ef2021-10-15 16:15:04 +00002544 assert( pNode->eU==0 );
2545 VVA( pNode->eU = 3 );
drh8784eca2015-08-23 02:42:30 +00002546 pNode->u.iKey = 0;
drhc3722b22015-08-23 20:44:59 +00002547 p->iEnd = p->i + pNode->n + 1;
drh852944e2015-09-10 03:29:11 +00002548 if( p->bRecursive ){
drh3d1d2a92015-09-22 01:15:49 +00002549 p->eType = p->sParse.aNode[p->sParse.aUp[p->i]].eType;
drh852944e2015-09-10 03:29:11 +00002550 if( p->i>0 && (p->sParse.aNode[p->i-1].jnFlags & JNODE_LABEL)!=0 ){
2551 p->i--;
2552 }
2553 }else{
2554 p->i++;
2555 }
drhcb6c6c62015-08-19 22:47:17 +00002556 }else{
2557 p->iEnd = p->i+1;
2558 }
2559 }
drha8f39a92015-09-21 22:53:16 +00002560 return SQLITE_OK;
drhcb6c6c62015-08-19 22:47:17 +00002561}
2562
2563/* The methods of the json_each virtual table */
2564static sqlite3_module jsonEachModule = {
2565 0, /* iVersion */
2566 0, /* xCreate */
2567 jsonEachConnect, /* xConnect */
2568 jsonEachBestIndex, /* xBestIndex */
2569 jsonEachDisconnect, /* xDisconnect */
2570 0, /* xDestroy */
drh505ad2c2015-08-21 17:33:11 +00002571 jsonEachOpenEach, /* xOpen - open a cursor */
drhcb6c6c62015-08-19 22:47:17 +00002572 jsonEachClose, /* xClose - close a cursor */
2573 jsonEachFilter, /* xFilter - configure scan constraints */
drh4af352d2015-08-21 20:02:48 +00002574 jsonEachNext, /* xNext - advance a cursor */
drhcb6c6c62015-08-19 22:47:17 +00002575 jsonEachEof, /* xEof - check for end of scan */
2576 jsonEachColumn, /* xColumn - read data */
2577 jsonEachRowid, /* xRowid - read data */
2578 0, /* xUpdate */
2579 0, /* xBegin */
2580 0, /* xSync */
2581 0, /* xCommit */
2582 0, /* xRollback */
2583 0, /* xFindMethod */
2584 0, /* xRename */
drh6fd5c1e2015-08-21 20:37:12 +00002585 0, /* xSavepoint */
2586 0, /* xRelease */
drh84c501b2018-11-05 23:01:45 +00002587 0, /* xRollbackTo */
2588 0 /* xShadowName */
drhcb6c6c62015-08-19 22:47:17 +00002589};
2590
drh505ad2c2015-08-21 17:33:11 +00002591/* The methods of the json_tree virtual table. */
2592static sqlite3_module jsonTreeModule = {
2593 0, /* iVersion */
2594 0, /* xCreate */
2595 jsonEachConnect, /* xConnect */
2596 jsonEachBestIndex, /* xBestIndex */
2597 jsonEachDisconnect, /* xDisconnect */
2598 0, /* xDestroy */
2599 jsonEachOpenTree, /* xOpen - open a cursor */
2600 jsonEachClose, /* xClose - close a cursor */
2601 jsonEachFilter, /* xFilter - configure scan constraints */
drh4af352d2015-08-21 20:02:48 +00002602 jsonEachNext, /* xNext - advance a cursor */
drh505ad2c2015-08-21 17:33:11 +00002603 jsonEachEof, /* xEof - check for end of scan */
2604 jsonEachColumn, /* xColumn - read data */
2605 jsonEachRowid, /* xRowid - read data */
2606 0, /* xUpdate */
2607 0, /* xBegin */
2608 0, /* xSync */
2609 0, /* xCommit */
2610 0, /* xRollback */
2611 0, /* xFindMethod */
2612 0, /* xRename */
drh6fd5c1e2015-08-21 20:37:12 +00002613 0, /* xSavepoint */
2614 0, /* xRelease */
drh84c501b2018-11-05 23:01:45 +00002615 0, /* xRollbackTo */
2616 0 /* xShadowName */
drh505ad2c2015-08-21 17:33:11 +00002617};
drhd2975922015-08-29 17:22:33 +00002618#endif /* SQLITE_OMIT_VIRTUALTABLE */
drh505ad2c2015-08-21 17:33:11 +00002619
2620/****************************************************************************
drh2f20e132015-09-26 17:44:59 +00002621** The following routines are the only publically visible identifiers in this
2622** file. Call the following routines in order to register the various SQL
drh505ad2c2015-08-21 17:33:11 +00002623** functions and the virtual table implemented by this file.
2624****************************************************************************/
drhcb6c6c62015-08-19 22:47:17 +00002625
drh2f20e132015-09-26 17:44:59 +00002626int sqlite3Json1Init(sqlite3 *db){
drh5fa5c102015-08-12 16:49:40 +00002627 int rc = SQLITE_OK;
drh6fd5c1e2015-08-21 20:37:12 +00002628 unsigned int i;
drh5fa5c102015-08-12 16:49:40 +00002629 static const struct {
2630 const char *zName;
2631 int nArg;
drh52216ad2015-08-18 02:28:03 +00002632 int flag;
drh5fa5c102015-08-12 16:49:40 +00002633 void (*xFunc)(sqlite3_context*,int,sqlite3_value**);
2634 } aFunc[] = {
drhf5ddb9c2015-09-11 00:06:41 +00002635 { "json", 1, 0, jsonRemoveFunc },
drh52216ad2015-08-18 02:28:03 +00002636 { "json_array", -1, 0, jsonArrayFunc },
2637 { "json_array_length", 1, 0, jsonArrayLengthFunc },
2638 { "json_array_length", 2, 0, jsonArrayLengthFunc },
drh3ad93bb2015-08-29 19:41:45 +00002639 { "json_extract", -1, 0, jsonExtractFunc },
drh52216ad2015-08-18 02:28:03 +00002640 { "json_insert", -1, 0, jsonSetFunc },
2641 { "json_object", -1, 0, jsonObjectFunc },
drh37f03df2017-03-23 20:33:49 +00002642 { "json_patch", 2, 0, jsonPatchFunc },
drh2ad96f52016-06-17 13:01:51 +00002643 { "json_quote", 1, 0, jsonQuoteFunc },
drh52216ad2015-08-18 02:28:03 +00002644 { "json_remove", -1, 0, jsonRemoveFunc },
2645 { "json_replace", -1, 0, jsonReplaceFunc },
2646 { "json_set", -1, 1, jsonSetFunc },
2647 { "json_type", 1, 0, jsonTypeFunc },
2648 { "json_type", 2, 0, jsonTypeFunc },
drhbc8f0922015-08-22 19:39:04 +00002649 { "json_valid", 1, 0, jsonValidFunc },
drh987eb1f2015-08-17 15:17:37 +00002650
drh301eecc2015-08-17 20:14:19 +00002651#if SQLITE_DEBUG
drh987eb1f2015-08-17 15:17:37 +00002652 /* DEBUG and TESTING functions */
drh52216ad2015-08-18 02:28:03 +00002653 { "json_parse", 1, 0, jsonParseFunc },
2654 { "json_test1", 1, 0, jsonTest1Func },
drh301eecc2015-08-17 20:14:19 +00002655#endif
drh5fa5c102015-08-12 16:49:40 +00002656 };
drhff135ae2015-12-30 01:07:02 +00002657 static const struct {
2658 const char *zName;
2659 int nArg;
2660 void (*xStep)(sqlite3_context*,int,sqlite3_value**);
2661 void (*xFinal)(sqlite3_context*);
drh8be47a72018-07-05 20:05:29 +00002662 void (*xValue)(sqlite3_context*);
drhff135ae2015-12-30 01:07:02 +00002663 } aAgg[] = {
drh8be47a72018-07-05 20:05:29 +00002664 { "json_group_array", 1,
2665 jsonArrayStep, jsonArrayFinal, jsonArrayValue },
2666 { "json_group_object", 2,
2667 jsonObjectStep, jsonObjectFinal, jsonObjectValue },
drhff135ae2015-12-30 01:07:02 +00002668 };
drhd2975922015-08-29 17:22:33 +00002669#ifndef SQLITE_OMIT_VIRTUALTABLE
drh505ad2c2015-08-21 17:33:11 +00002670 static const struct {
2671 const char *zName;
2672 sqlite3_module *pModule;
2673 } aMod[] = {
2674 { "json_each", &jsonEachModule },
2675 { "json_tree", &jsonTreeModule },
2676 };
drhd2975922015-08-29 17:22:33 +00002677#endif
drh79d5bc82020-01-04 01:43:02 +00002678 static const int enc =
2679 SQLITE_UTF8 |
2680 SQLITE_DETERMINISTIC |
2681 SQLITE_INNOCUOUS;
drh5fa5c102015-08-12 16:49:40 +00002682 for(i=0; i<sizeof(aFunc)/sizeof(aFunc[0]) && rc==SQLITE_OK; i++){
drh79d5bc82020-01-04 01:43:02 +00002683 rc = sqlite3_create_function(db, aFunc[i].zName, aFunc[i].nArg, enc,
dan01a3b6b2019-09-13 17:05:48 +00002684 (void*)&aFunc[i].flag,
2685 aFunc[i].xFunc, 0, 0);
drh5fa5c102015-08-12 16:49:40 +00002686 }
mistachkin5a193dd2018-07-24 13:57:44 +00002687#ifndef SQLITE_OMIT_WINDOWFUNC
drhff135ae2015-12-30 01:07:02 +00002688 for(i=0; i<sizeof(aAgg)/sizeof(aAgg[0]) && rc==SQLITE_OK; i++){
drh8be47a72018-07-05 20:05:29 +00002689 rc = sqlite3_create_window_function(db, aAgg[i].zName, aAgg[i].nArg,
drh79d5bc82020-01-04 01:43:02 +00002690 SQLITE_SUBTYPE | enc, 0,
drh8be47a72018-07-05 20:05:29 +00002691 aAgg[i].xStep, aAgg[i].xFinal,
2692 aAgg[i].xValue, jsonGroupInverse, 0);
drhff135ae2015-12-30 01:07:02 +00002693 }
mistachkin5a193dd2018-07-24 13:57:44 +00002694#endif
drhd2975922015-08-29 17:22:33 +00002695#ifndef SQLITE_OMIT_VIRTUALTABLE
drh505ad2c2015-08-21 17:33:11 +00002696 for(i=0; i<sizeof(aMod)/sizeof(aMod[0]) && rc==SQLITE_OK; i++){
2697 rc = sqlite3_create_module(db, aMod[i].zName, aMod[i].pModule, 0);
drhcb6c6c62015-08-19 22:47:17 +00002698 }
drhd2975922015-08-29 17:22:33 +00002699#endif
drh5fa5c102015-08-12 16:49:40 +00002700 return rc;
2701}
drh2f20e132015-09-26 17:44:59 +00002702
2703
dan8d32e802015-10-14 18:45:42 +00002704#ifndef SQLITE_CORE
drh2f20e132015-09-26 17:44:59 +00002705#ifdef _WIN32
2706__declspec(dllexport)
2707#endif
2708int sqlite3_json_init(
2709 sqlite3 *db,
2710 char **pzErrMsg,
2711 const sqlite3_api_routines *pApi
2712){
2713 SQLITE_EXTENSION_INIT2(pApi);
2714 (void)pzErrMsg; /* Unused parameter */
2715 return sqlite3Json1Init(db);
2716}
dan8d32e802015-10-14 18:45:42 +00002717#endif
drh50065652015-10-08 19:29:18 +00002718#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_JSON1) */