blob: af20c691faa9049142fa0fcbc7ffd855e89184df [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*/
drhf2df7e72015-08-28 20:07:40 +000024#if !defined(_SQLITEINT_H_)
drh5fa5c102015-08-12 16:49:40 +000025#include "sqlite3ext.h"
drhf2df7e72015-08-28 20:07:40 +000026#endif
drh5fa5c102015-08-12 16:49:40 +000027SQLITE_EXTENSION_INIT1
28#include <assert.h>
29#include <string.h>
drhe9c37f32015-08-15 21:25:36 +000030#include <ctype.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
drh6fd5c1e2015-08-21 20:37:12 +000034#define UNUSED_PARAM(X) (void)(X)
35
drh5fa5c102015-08-12 16:49:40 +000036/* Unsigned integer types */
37typedef sqlite3_uint64 u64;
38typedef unsigned int u32;
39typedef unsigned char u8;
40
drh52216ad2015-08-18 02:28:03 +000041/* Objects */
drh505ad2c2015-08-21 17:33:11 +000042typedef struct JsonString JsonString;
drh52216ad2015-08-18 02:28:03 +000043typedef struct JsonNode JsonNode;
44typedef struct JsonParse JsonParse;
45
drh5634cc02015-08-17 11:28:03 +000046/* An instance of this object represents a JSON string
47** under construction. Really, this is a generic string accumulator
48** that can be and is used to create strings other than JSON.
drh5fa5c102015-08-12 16:49:40 +000049*/
drh505ad2c2015-08-21 17:33:11 +000050struct JsonString {
drh5fa5c102015-08-12 16:49:40 +000051 sqlite3_context *pCtx; /* Function context - put error messages here */
drh5634cc02015-08-17 11:28:03 +000052 char *zBuf; /* Append JSON content here */
drh5fa5c102015-08-12 16:49:40 +000053 u64 nAlloc; /* Bytes of storage available in zBuf[] */
54 u64 nUsed; /* Bytes of zBuf[] currently used */
55 u8 bStatic; /* True if zBuf is static space */
drhd0960592015-08-17 21:22:32 +000056 u8 bErr; /* True if an error has been encountered */
drh5fa5c102015-08-12 16:49:40 +000057 char zSpace[100]; /* Initial static space */
58};
59
drhe9c37f32015-08-15 21:25:36 +000060/* JSON type values
drhbd0621b2015-08-13 13:54:59 +000061*/
drhe9c37f32015-08-15 21:25:36 +000062#define JSON_NULL 0
63#define JSON_TRUE 1
64#define JSON_FALSE 2
65#define JSON_INT 3
66#define JSON_REAL 4
67#define JSON_STRING 5
68#define JSON_ARRAY 6
69#define JSON_OBJECT 7
70
drh987eb1f2015-08-17 15:17:37 +000071/*
72** Names of the various JSON types:
73*/
74static const char * const jsonType[] = {
75 "null", "true", "false", "integer", "real", "text", "array", "object"
76};
77
drh301eecc2015-08-17 20:14:19 +000078/* Bit values for the JsonNode.jnFlag field
79*/
80#define JNODE_RAW 0x01 /* Content is raw, not JSON encoded */
81#define JNODE_ESCAPE 0x02 /* Content is text with \ escapes */
82#define JNODE_REMOVE 0x04 /* Do not output */
drhd0960592015-08-17 21:22:32 +000083#define JNODE_REPLACE 0x08 /* Replace with JsonNode.iVal */
drh52216ad2015-08-18 02:28:03 +000084#define JNODE_APPEND 0x10 /* More ARRAY/OBJECT entries at u.iAppend */
drhecb5fed2015-08-28 03:33:50 +000085#define JNODE_JSON 0x20 /* Treat REPLACE as JSON text */
drh301eecc2015-08-17 20:14:19 +000086
drh987eb1f2015-08-17 15:17:37 +000087
drhe9c37f32015-08-15 21:25:36 +000088/* A single node of parsed JSON
89*/
drhe9c37f32015-08-15 21:25:36 +000090struct JsonNode {
drh5634cc02015-08-17 11:28:03 +000091 u8 eType; /* One of the JSON_ type values */
drh301eecc2015-08-17 20:14:19 +000092 u8 jnFlags; /* JNODE flags */
drhd0960592015-08-17 21:22:32 +000093 u8 iVal; /* Replacement value when JNODE_REPLACE */
drhe9c37f32015-08-15 21:25:36 +000094 u32 n; /* Bytes of content, or number of sub-nodes */
drh52216ad2015-08-18 02:28:03 +000095 union {
drh0042a972015-08-18 12:59:58 +000096 const char *zJContent; /* Content for INT, REAL, and STRING */
97 u32 iAppend; /* More terms for ARRAY and OBJECT */
drh505ad2c2015-08-21 17:33:11 +000098 u32 iKey; /* Key for ARRAY objects in json_tree() */
drh52216ad2015-08-18 02:28:03 +000099 } u;
drhe9c37f32015-08-15 21:25:36 +0000100};
101
102/* A completely parsed JSON string
103*/
drhe9c37f32015-08-15 21:25:36 +0000104struct JsonParse {
105 u32 nNode; /* Number of slots of aNode[] used */
106 u32 nAlloc; /* Number of slots of aNode[] allocated */
107 JsonNode *aNode; /* Array of nodes containing the parse */
108 const char *zJson; /* Original JSON string */
drh505ad2c2015-08-21 17:33:11 +0000109 u32 *aUp; /* Index of parent of each node */
drhe9c37f32015-08-15 21:25:36 +0000110 u8 oom; /* Set to true if out of memory */
drha7714022015-08-29 00:54:49 +0000111 u8 nErr; /* Number of errors seen */
drhe9c37f32015-08-15 21:25:36 +0000112};
113
drh505ad2c2015-08-21 17:33:11 +0000114/**************************************************************************
115** Utility routines for dealing with JsonString objects
116**************************************************************************/
drh301eecc2015-08-17 20:14:19 +0000117
drh505ad2c2015-08-21 17:33:11 +0000118/* Set the JsonString object to an empty string
drh5fa5c102015-08-12 16:49:40 +0000119*/
drh505ad2c2015-08-21 17:33:11 +0000120static void jsonZero(JsonString *p){
drh5fa5c102015-08-12 16:49:40 +0000121 p->zBuf = p->zSpace;
122 p->nAlloc = sizeof(p->zSpace);
123 p->nUsed = 0;
124 p->bStatic = 1;
125}
126
drh505ad2c2015-08-21 17:33:11 +0000127/* Initialize the JsonString object
drh5fa5c102015-08-12 16:49:40 +0000128*/
drh505ad2c2015-08-21 17:33:11 +0000129static void jsonInit(JsonString *p, sqlite3_context *pCtx){
drh5fa5c102015-08-12 16:49:40 +0000130 p->pCtx = pCtx;
drhd0960592015-08-17 21:22:32 +0000131 p->bErr = 0;
drh5fa5c102015-08-12 16:49:40 +0000132 jsonZero(p);
133}
134
135
drh505ad2c2015-08-21 17:33:11 +0000136/* Free all allocated memory and reset the JsonString object back to its
drh5fa5c102015-08-12 16:49:40 +0000137** initial state.
138*/
drh505ad2c2015-08-21 17:33:11 +0000139static void jsonReset(JsonString *p){
drh5fa5c102015-08-12 16:49:40 +0000140 if( !p->bStatic ) sqlite3_free(p->zBuf);
141 jsonZero(p);
142}
143
144
145/* Report an out-of-memory (OOM) condition
146*/
drh505ad2c2015-08-21 17:33:11 +0000147static void jsonOom(JsonString *p){
drhd0960592015-08-17 21:22:32 +0000148 if( !p->bErr ){
149 p->bErr = 1;
150 sqlite3_result_error_nomem(p->pCtx);
151 jsonReset(p);
152 }
drh5fa5c102015-08-12 16:49:40 +0000153}
154
155/* Enlarge pJson->zBuf so that it can hold at least N more bytes.
156** Return zero on success. Return non-zero on an OOM error
157*/
drh505ad2c2015-08-21 17:33:11 +0000158static int jsonGrow(JsonString *p, u32 N){
drh301eecc2015-08-17 20:14:19 +0000159 u64 nTotal = N<p->nAlloc ? p->nAlloc*2 : p->nAlloc+N+10;
drh5fa5c102015-08-12 16:49:40 +0000160 char *zNew;
161 if( p->bStatic ){
drhd0960592015-08-17 21:22:32 +0000162 if( p->bErr ) return 1;
drh5fa5c102015-08-12 16:49:40 +0000163 zNew = sqlite3_malloc64(nTotal);
164 if( zNew==0 ){
165 jsonOom(p);
166 return SQLITE_NOMEM;
167 }
drh6fd5c1e2015-08-21 20:37:12 +0000168 memcpy(zNew, p->zBuf, (size_t)p->nUsed);
drh5fa5c102015-08-12 16:49:40 +0000169 p->zBuf = zNew;
170 p->bStatic = 0;
171 }else{
172 zNew = sqlite3_realloc64(p->zBuf, nTotal);
173 if( zNew==0 ){
174 jsonOom(p);
175 return SQLITE_NOMEM;
176 }
177 p->zBuf = zNew;
178 }
179 p->nAlloc = nTotal;
180 return SQLITE_OK;
181}
182
drh505ad2c2015-08-21 17:33:11 +0000183/* Append N bytes from zIn onto the end of the JsonString string.
drh5fa5c102015-08-12 16:49:40 +0000184*/
drh505ad2c2015-08-21 17:33:11 +0000185static void jsonAppendRaw(JsonString *p, const char *zIn, u32 N){
drh5fa5c102015-08-12 16:49:40 +0000186 if( (N+p->nUsed >= p->nAlloc) && jsonGrow(p,N)!=0 ) return;
187 memcpy(p->zBuf+p->nUsed, zIn, N);
188 p->nUsed += N;
189}
190
drh4af352d2015-08-21 20:02:48 +0000191/* Append formatted text (not to exceed N bytes) to the JsonString.
192*/
193static void jsonPrintf(int N, JsonString *p, const char *zFormat, ...){
194 va_list ap;
195 if( (p->nUsed + N >= p->nAlloc) && jsonGrow(p, N) ) return;
196 va_start(ap, zFormat);
197 sqlite3_vsnprintf(N, p->zBuf+p->nUsed, zFormat, ap);
198 va_end(ap);
199 p->nUsed += (int)strlen(p->zBuf+p->nUsed);
200}
201
drh5634cc02015-08-17 11:28:03 +0000202/* Append a single character
203*/
drh505ad2c2015-08-21 17:33:11 +0000204static void jsonAppendChar(JsonString *p, char c){
drh5634cc02015-08-17 11:28:03 +0000205 if( p->nUsed>=p->nAlloc && jsonGrow(p,1)!=0 ) return;
206 p->zBuf[p->nUsed++] = c;
207}
208
drh301eecc2015-08-17 20:14:19 +0000209/* Append a comma separator to the output buffer, if the previous
210** character is not '[' or '{'.
211*/
drh505ad2c2015-08-21 17:33:11 +0000212static void jsonAppendSeparator(JsonString *p){
drh301eecc2015-08-17 20:14:19 +0000213 char c;
214 if( p->nUsed==0 ) return;
215 c = p->zBuf[p->nUsed-1];
216 if( c!='[' && c!='{' ) jsonAppendChar(p, ',');
217}
218
drh505ad2c2015-08-21 17:33:11 +0000219/* Append the N-byte string in zIn to the end of the JsonString string
drh5fa5c102015-08-12 16:49:40 +0000220** under construction. Enclose the string in "..." and escape
221** any double-quotes or backslash characters contained within the
222** string.
223*/
drh505ad2c2015-08-21 17:33:11 +0000224static void jsonAppendString(JsonString *p, const char *zIn, u32 N){
drh5fa5c102015-08-12 16:49:40 +0000225 u32 i;
226 if( (N+p->nUsed+2 >= p->nAlloc) && jsonGrow(p,N+2)!=0 ) return;
227 p->zBuf[p->nUsed++] = '"';
228 for(i=0; i<N; i++){
229 char c = zIn[i];
230 if( c=='"' || c=='\\' ){
231 if( (p->nUsed+N+1-i > p->nAlloc) && jsonGrow(p,N+1-i)!=0 ) return;
232 p->zBuf[p->nUsed++] = '\\';
233 }
234 p->zBuf[p->nUsed++] = c;
235 }
236 p->zBuf[p->nUsed++] = '"';
237}
238
drhd0960592015-08-17 21:22:32 +0000239/*
240** Append a function parameter value to the JSON string under
241** construction.
242*/
243static void jsonAppendValue(
drh505ad2c2015-08-21 17:33:11 +0000244 JsonString *p, /* Append to this JSON string */
drhecb5fed2015-08-28 03:33:50 +0000245 sqlite3_value *pValue, /* Value to append */
246 u8 textIsJson /* Try to treat text values as JSON */
drhd0960592015-08-17 21:22:32 +0000247){
248 switch( sqlite3_value_type(pValue) ){
249 case SQLITE_NULL: {
250 jsonAppendRaw(p, "null", 4);
251 break;
252 }
253 case SQLITE_INTEGER:
254 case SQLITE_FLOAT: {
255 const char *z = (const char*)sqlite3_value_text(pValue);
256 u32 n = (u32)sqlite3_value_bytes(pValue);
257 jsonAppendRaw(p, z, n);
258 break;
259 }
260 case SQLITE_TEXT: {
261 const char *z = (const char*)sqlite3_value_text(pValue);
262 u32 n = (u32)sqlite3_value_bytes(pValue);
drhecb5fed2015-08-28 03:33:50 +0000263 if( textIsJson ){
264 jsonAppendRaw(p, z, n);
265 }else{
266 jsonAppendString(p, z, n);
267 }
drhd0960592015-08-17 21:22:32 +0000268 break;
269 }
270 default: {
271 if( p->bErr==0 ){
272 sqlite3_result_error(p->pCtx, "JSON cannot hold BLOB values", -1);
273 p->bErr = 1;
274 jsonReset(p);
275 }
276 break;
277 }
278 }
279}
280
281
drhbd0621b2015-08-13 13:54:59 +0000282/* Make the JSON in p the result of the SQL function.
drh5fa5c102015-08-12 16:49:40 +0000283*/
drh505ad2c2015-08-21 17:33:11 +0000284static void jsonResult(JsonString *p){
drhd0960592015-08-17 21:22:32 +0000285 if( p->bErr==0 ){
drh5fa5c102015-08-12 16:49:40 +0000286 sqlite3_result_text64(p->pCtx, p->zBuf, p->nUsed,
287 p->bStatic ? SQLITE_TRANSIENT : sqlite3_free,
288 SQLITE_UTF8);
289 jsonZero(p);
290 }
291 assert( p->bStatic );
292}
293
drh505ad2c2015-08-21 17:33:11 +0000294/**************************************************************************
295** Utility routines for dealing with JsonNode and JsonParse objects
296**************************************************************************/
297
298/*
299** Return the number of consecutive JsonNode slots need to represent
300** the parsed JSON at pNode. The minimum answer is 1. For ARRAY and
301** OBJECT types, the number might be larger.
302**
303** Appended elements are not counted. The value returned is the number
304** by which the JsonNode counter should increment in order to go to the
305** next peer value.
306*/
307static u32 jsonNodeSize(JsonNode *pNode){
308 return pNode->eType>=JSON_ARRAY ? pNode->n+1 : 1;
309}
310
311/*
312** Reclaim all memory allocated by a JsonParse object. But do not
313** delete the JsonParse object itself.
314*/
315static void jsonParseReset(JsonParse *pParse){
316 sqlite3_free(pParse->aNode);
317 pParse->aNode = 0;
318 pParse->nNode = 0;
319 pParse->nAlloc = 0;
320 sqlite3_free(pParse->aUp);
321 pParse->aUp = 0;
322}
323
drh5634cc02015-08-17 11:28:03 +0000324/*
325** Convert the JsonNode pNode into a pure JSON string and
326** append to pOut. Subsubstructure is also included. Return
327** the number of JsonNode objects that are encoded.
drhbd0621b2015-08-13 13:54:59 +0000328*/
drh52216ad2015-08-18 02:28:03 +0000329static void jsonRenderNode(
drhd0960592015-08-17 21:22:32 +0000330 JsonNode *pNode, /* The node to render */
drh505ad2c2015-08-21 17:33:11 +0000331 JsonString *pOut, /* Write JSON here */
drhd0960592015-08-17 21:22:32 +0000332 sqlite3_value **aReplace /* Replacement values */
333){
drh5634cc02015-08-17 11:28:03 +0000334 switch( pNode->eType ){
335 case JSON_NULL: {
336 jsonAppendRaw(pOut, "null", 4);
337 break;
338 }
339 case JSON_TRUE: {
340 jsonAppendRaw(pOut, "true", 4);
341 break;
342 }
343 case JSON_FALSE: {
344 jsonAppendRaw(pOut, "false", 5);
345 break;
346 }
347 case JSON_STRING: {
drh301eecc2015-08-17 20:14:19 +0000348 if( pNode->jnFlags & JNODE_RAW ){
drh52216ad2015-08-18 02:28:03 +0000349 jsonAppendString(pOut, pNode->u.zJContent, pNode->n);
drh5634cc02015-08-17 11:28:03 +0000350 break;
351 }
352 /* Fall through into the next case */
353 }
354 case JSON_REAL:
355 case JSON_INT: {
drh52216ad2015-08-18 02:28:03 +0000356 jsonAppendRaw(pOut, pNode->u.zJContent, pNode->n);
drh5634cc02015-08-17 11:28:03 +0000357 break;
358 }
359 case JSON_ARRAY: {
drh52216ad2015-08-18 02:28:03 +0000360 u32 j = 1;
drh5634cc02015-08-17 11:28:03 +0000361 jsonAppendChar(pOut, '[');
drh52216ad2015-08-18 02:28:03 +0000362 for(;;){
363 while( j<=pNode->n ){
364 if( pNode[j].jnFlags & (JNODE_REMOVE|JNODE_REPLACE) ){
365 if( pNode[j].jnFlags & JNODE_REPLACE ){
366 jsonAppendSeparator(pOut);
drhecb5fed2015-08-28 03:33:50 +0000367 jsonAppendValue(pOut, aReplace[pNode[j].iVal],
368 (pNode[j].jnFlags & JNODE_JSON)!=0);
drh52216ad2015-08-18 02:28:03 +0000369 }
370 }else{
drhd0960592015-08-17 21:22:32 +0000371 jsonAppendSeparator(pOut);
drh52216ad2015-08-18 02:28:03 +0000372 jsonRenderNode(&pNode[j], pOut, aReplace);
drhd0960592015-08-17 21:22:32 +0000373 }
drh505ad2c2015-08-21 17:33:11 +0000374 j += jsonNodeSize(&pNode[j]);
drh301eecc2015-08-17 20:14:19 +0000375 }
drh52216ad2015-08-18 02:28:03 +0000376 if( (pNode->jnFlags & JNODE_APPEND)==0 ) break;
377 pNode = &pNode[pNode->u.iAppend];
378 j = 1;
drh5634cc02015-08-17 11:28:03 +0000379 }
380 jsonAppendChar(pOut, ']');
381 break;
382 }
383 case JSON_OBJECT: {
drh52216ad2015-08-18 02:28:03 +0000384 u32 j = 1;
drh5634cc02015-08-17 11:28:03 +0000385 jsonAppendChar(pOut, '{');
drh52216ad2015-08-18 02:28:03 +0000386 for(;;){
387 while( j<=pNode->n ){
388 if( (pNode[j+1].jnFlags & JNODE_REMOVE)==0 ){
389 jsonAppendSeparator(pOut);
390 jsonRenderNode(&pNode[j], pOut, aReplace);
391 jsonAppendChar(pOut, ':');
392 if( pNode[j+1].jnFlags & JNODE_REPLACE ){
drhecb5fed2015-08-28 03:33:50 +0000393 jsonAppendValue(pOut, aReplace[pNode[j+1].iVal],
394 (pNode[j+1].jnFlags & JNODE_JSON)!=0);
drh52216ad2015-08-18 02:28:03 +0000395 }else{
396 jsonRenderNode(&pNode[j+1], pOut, aReplace);
397 }
drhd0960592015-08-17 21:22:32 +0000398 }
drh505ad2c2015-08-21 17:33:11 +0000399 j += 1 + jsonNodeSize(&pNode[j+1]);
drh301eecc2015-08-17 20:14:19 +0000400 }
drh52216ad2015-08-18 02:28:03 +0000401 if( (pNode->jnFlags & JNODE_APPEND)==0 ) break;
402 pNode = &pNode[pNode->u.iAppend];
403 j = 1;
drh5634cc02015-08-17 11:28:03 +0000404 }
405 jsonAppendChar(pOut, '}');
406 break;
407 }
drhbd0621b2015-08-13 13:54:59 +0000408 }
drh5634cc02015-08-17 11:28:03 +0000409}
410
411/*
drhf2df7e72015-08-28 20:07:40 +0000412** Return a JsonNode and all its descendents as a JSON string.
413*/
414static void jsonReturnJson(
415 JsonNode *pNode, /* Node to return */
416 sqlite3_context *pCtx, /* Return value for this function */
417 sqlite3_value **aReplace /* Array of replacement values */
418){
419 JsonString s;
420 jsonInit(&s, pCtx);
421 jsonRenderNode(pNode, &s, aReplace);
422 jsonResult(&s);
423}
424
425/*
drh5634cc02015-08-17 11:28:03 +0000426** Make the JsonNode the return value of the function.
427*/
drhd0960592015-08-17 21:22:32 +0000428static void jsonReturn(
429 JsonNode *pNode, /* Node to return */
430 sqlite3_context *pCtx, /* Return value for this function */
431 sqlite3_value **aReplace /* Array of replacement values */
432){
drh5634cc02015-08-17 11:28:03 +0000433 switch( pNode->eType ){
434 case JSON_NULL: {
435 sqlite3_result_null(pCtx);
436 break;
437 }
438 case JSON_TRUE: {
439 sqlite3_result_int(pCtx, 1);
440 break;
441 }
442 case JSON_FALSE: {
443 sqlite3_result_int(pCtx, 0);
444 break;
445 }
drh987eb1f2015-08-17 15:17:37 +0000446 case JSON_REAL: {
drh52216ad2015-08-18 02:28:03 +0000447 double r = strtod(pNode->u.zJContent, 0);
drh987eb1f2015-08-17 15:17:37 +0000448 sqlite3_result_double(pCtx, r);
drh5634cc02015-08-17 11:28:03 +0000449 break;
450 }
drh987eb1f2015-08-17 15:17:37 +0000451 case JSON_INT: {
452 sqlite3_int64 i = 0;
drh52216ad2015-08-18 02:28:03 +0000453 const char *z = pNode->u.zJContent;
drh987eb1f2015-08-17 15:17:37 +0000454 if( z[0]=='-' ){ z++; }
455 while( z[0]>='0' && z[0]<='9' ){ i = i*10 + *(z++) - '0'; }
drh52216ad2015-08-18 02:28:03 +0000456 if( pNode->u.zJContent[0]=='-' ){ i = -i; }
drh987eb1f2015-08-17 15:17:37 +0000457 sqlite3_result_int64(pCtx, i);
458 break;
459 }
drh5634cc02015-08-17 11:28:03 +0000460 case JSON_STRING: {
drh301eecc2015-08-17 20:14:19 +0000461 if( pNode->jnFlags & JNODE_RAW ){
drh52216ad2015-08-18 02:28:03 +0000462 sqlite3_result_text(pCtx, pNode->u.zJContent, pNode->n,
463 SQLITE_TRANSIENT);
drh301eecc2015-08-17 20:14:19 +0000464 }else if( (pNode->jnFlags & JNODE_ESCAPE)==0 ){
drh987eb1f2015-08-17 15:17:37 +0000465 /* JSON formatted without any backslash-escapes */
drh52216ad2015-08-18 02:28:03 +0000466 sqlite3_result_text(pCtx, pNode->u.zJContent+1, pNode->n-2,
drh987eb1f2015-08-17 15:17:37 +0000467 SQLITE_TRANSIENT);
drh5634cc02015-08-17 11:28:03 +0000468 }else{
469 /* Translate JSON formatted string into raw text */
drh987eb1f2015-08-17 15:17:37 +0000470 u32 i;
471 u32 n = pNode->n;
drh52216ad2015-08-18 02:28:03 +0000472 const char *z = pNode->u.zJContent;
drh987eb1f2015-08-17 15:17:37 +0000473 char *zOut;
474 u32 j;
475 zOut = sqlite3_malloc( n+1 );
476 if( zOut==0 ){
477 sqlite3_result_error_nomem(pCtx);
478 break;
479 }
480 for(i=1, j=0; i<n-1; i++){
481 char c = z[i];
drh80d87402015-08-24 12:42:41 +0000482 if( c!='\\' ){
drh987eb1f2015-08-17 15:17:37 +0000483 zOut[j++] = c;
484 }else{
485 c = z[++i];
drh80d87402015-08-24 12:42:41 +0000486 if( c=='u' ){
drh987eb1f2015-08-17 15:17:37 +0000487 u32 v = 0, k;
drh80d87402015-08-24 12:42:41 +0000488 for(k=0; k<4 && i<n-2; i++, k++){
drh8784eca2015-08-23 02:42:30 +0000489 c = z[i+1];
drh987eb1f2015-08-17 15:17:37 +0000490 if( c>='0' && c<='9' ) v = v*16 + c - '0';
491 else if( c>='A' && c<='F' ) v = v*16 + c - 'A' + 10;
492 else if( c>='a' && c<='f' ) v = v*16 + c - 'a' + 10;
493 else break;
drh987eb1f2015-08-17 15:17:37 +0000494 }
drh80d87402015-08-24 12:42:41 +0000495 if( v==0 ) break;
drh987eb1f2015-08-17 15:17:37 +0000496 if( v<=0x7f ){
497 zOut[j++] = v;
498 }else if( v<=0x7ff ){
499 zOut[j++] = 0xc0 | (v>>6);
500 zOut[j++] = 0x80 | (v&0x3f);
drh80d87402015-08-24 12:42:41 +0000501 }else{
drh987eb1f2015-08-17 15:17:37 +0000502 zOut[j++] = 0xe0 | (v>>12);
503 zOut[j++] = 0x80 | ((v>>6)&0x3f);
504 zOut[j++] = 0x80 | (v&0x3f);
drh987eb1f2015-08-17 15:17:37 +0000505 }
506 }else{
507 if( c=='b' ){
508 c = '\b';
509 }else if( c=='f' ){
510 c = '\f';
511 }else if( c=='n' ){
512 c = '\n';
513 }else if( c=='r' ){
514 c = '\r';
515 }else if( c=='t' ){
516 c = '\t';
517 }
518 zOut[j++] = c;
519 }
520 }
521 }
522 zOut[j] = 0;
523 sqlite3_result_text(pCtx, zOut, j, sqlite3_free);
drh5634cc02015-08-17 11:28:03 +0000524 }
525 break;
526 }
527 case JSON_ARRAY:
528 case JSON_OBJECT: {
drhf2df7e72015-08-28 20:07:40 +0000529 jsonReturnJson(pNode, pCtx, aReplace);
drh5634cc02015-08-17 11:28:03 +0000530 break;
531 }
532 }
drhbd0621b2015-08-13 13:54:59 +0000533}
534
drh5fa5c102015-08-12 16:49:40 +0000535/*
drhe9c37f32015-08-15 21:25:36 +0000536** Create a new JsonNode instance based on the arguments and append that
537** instance to the JsonParse. Return the index in pParse->aNode[] of the
538** new node, or -1 if a memory allocation fails.
539*/
540static int jsonParseAddNode(
541 JsonParse *pParse, /* Append the node to this object */
542 u32 eType, /* Node type */
543 u32 n, /* Content size or sub-node count */
544 const char *zContent /* Content */
545){
546 JsonNode *p;
547 if( pParse->nNode>=pParse->nAlloc ){
548 u32 nNew;
549 JsonNode *pNew;
550 if( pParse->oom ) return -1;
551 nNew = pParse->nAlloc*2 + 10;
552 if( nNew<=pParse->nNode ){
553 pParse->oom = 1;
554 return -1;
555 }
556 pNew = sqlite3_realloc(pParse->aNode, sizeof(JsonNode)*nNew);
557 if( pNew==0 ){
558 pParse->oom = 1;
559 return -1;
560 }
561 pParse->nAlloc = nNew;
562 pParse->aNode = pNew;
563 }
564 p = &pParse->aNode[pParse->nNode];
drh5634cc02015-08-17 11:28:03 +0000565 p->eType = (u8)eType;
drh301eecc2015-08-17 20:14:19 +0000566 p->jnFlags = 0;
drhd0960592015-08-17 21:22:32 +0000567 p->iVal = 0;
drhe9c37f32015-08-15 21:25:36 +0000568 p->n = n;
drh52216ad2015-08-18 02:28:03 +0000569 p->u.zJContent = zContent;
drhe9c37f32015-08-15 21:25:36 +0000570 return pParse->nNode++;
571}
572
573/*
574** Parse a single JSON value which begins at pParse->zJson[i]. Return the
575** index of the first character past the end of the value parsed.
576**
577** Return negative for a syntax error. Special cases: return -2 if the
578** first non-whitespace character is '}' and return -3 if the first
579** non-whitespace character is ']'.
580*/
581static int jsonParseValue(JsonParse *pParse, u32 i){
582 char c;
583 u32 j;
drhbc8f0922015-08-22 19:39:04 +0000584 int iThis;
drhe9c37f32015-08-15 21:25:36 +0000585 int x;
586 while( isspace(pParse->zJson[i]) ){ i++; }
587 if( (c = pParse->zJson[i])==0 ) return 0;
588 if( c=='{' ){
589 /* Parse object */
590 iThis = jsonParseAddNode(pParse, JSON_OBJECT, 0, 0);
drhbc8f0922015-08-22 19:39:04 +0000591 if( iThis<0 ) return -1;
drhe9c37f32015-08-15 21:25:36 +0000592 for(j=i+1;;j++){
593 while( isspace(pParse->zJson[j]) ){ j++; }
594 x = jsonParseValue(pParse, j);
595 if( x<0 ){
drhbc8f0922015-08-22 19:39:04 +0000596 if( x==(-2) && pParse->nNode==(u32)iThis+1 ) return j+1;
drhe9c37f32015-08-15 21:25:36 +0000597 return -1;
598 }
drhbe9474e2015-08-22 03:05:54 +0000599 if( pParse->oom ) return -1;
drhe9c37f32015-08-15 21:25:36 +0000600 if( pParse->aNode[pParse->nNode-1].eType!=JSON_STRING ) return -1;
601 j = x;
602 while( isspace(pParse->zJson[j]) ){ j++; }
603 if( pParse->zJson[j]!=':' ) return -1;
604 j++;
605 x = jsonParseValue(pParse, j);
606 if( x<0 ) return -1;
607 j = x;
608 while( isspace(pParse->zJson[j]) ){ j++; }
609 c = pParse->zJson[j];
610 if( c==',' ) continue;
611 if( c!='}' ) return -1;
612 break;
613 }
drhbc8f0922015-08-22 19:39:04 +0000614 pParse->aNode[iThis].n = pParse->nNode - (u32)iThis - 1;
drhe9c37f32015-08-15 21:25:36 +0000615 return j+1;
616 }else if( c=='[' ){
617 /* Parse array */
618 iThis = jsonParseAddNode(pParse, JSON_ARRAY, 0, 0);
drhbc8f0922015-08-22 19:39:04 +0000619 if( iThis<0 ) return -1;
drhe9c37f32015-08-15 21:25:36 +0000620 for(j=i+1;;j++){
621 while( isspace(pParse->zJson[j]) ){ j++; }
622 x = jsonParseValue(pParse, j);
623 if( x<0 ){
drhbc8f0922015-08-22 19:39:04 +0000624 if( x==(-3) && pParse->nNode==(u32)iThis+1 ) return j+1;
drhe9c37f32015-08-15 21:25:36 +0000625 return -1;
626 }
627 j = x;
628 while( isspace(pParse->zJson[j]) ){ j++; }
629 c = pParse->zJson[j];
630 if( c==',' ) continue;
631 if( c!=']' ) return -1;
632 break;
633 }
drhbc8f0922015-08-22 19:39:04 +0000634 pParse->aNode[iThis].n = pParse->nNode - (u32)iThis - 1;
drhe9c37f32015-08-15 21:25:36 +0000635 return j+1;
636 }else if( c=='"' ){
637 /* Parse string */
drh301eecc2015-08-17 20:14:19 +0000638 u8 jnFlags = 0;
drhe9c37f32015-08-15 21:25:36 +0000639 j = i+1;
640 for(;;){
641 c = pParse->zJson[j];
642 if( c==0 ) return -1;
643 if( c=='\\' ){
644 c = pParse->zJson[++j];
645 if( c==0 ) return -1;
drh301eecc2015-08-17 20:14:19 +0000646 jnFlags = JNODE_ESCAPE;
drhe9c37f32015-08-15 21:25:36 +0000647 }else if( c=='"' ){
648 break;
649 }
650 j++;
651 }
652 jsonParseAddNode(pParse, JSON_STRING, j+1-i, &pParse->zJson[i]);
drhbe9474e2015-08-22 03:05:54 +0000653 if( !pParse->oom ) pParse->aNode[pParse->nNode-1].jnFlags = jnFlags;
drhe9c37f32015-08-15 21:25:36 +0000654 return j+1;
655 }else if( c=='n'
656 && strncmp(pParse->zJson+i,"null",4)==0
drhb2cd10e2015-08-15 21:29:14 +0000657 && !isalnum(pParse->zJson[i+4]) ){
drhe9c37f32015-08-15 21:25:36 +0000658 jsonParseAddNode(pParse, JSON_NULL, 0, 0);
659 return i+4;
660 }else if( c=='t'
661 && strncmp(pParse->zJson+i,"true",4)==0
drhb2cd10e2015-08-15 21:29:14 +0000662 && !isalnum(pParse->zJson[i+4]) ){
drhe9c37f32015-08-15 21:25:36 +0000663 jsonParseAddNode(pParse, JSON_TRUE, 0, 0);
664 return i+4;
665 }else if( c=='f'
666 && strncmp(pParse->zJson+i,"false",5)==0
drhb2cd10e2015-08-15 21:29:14 +0000667 && !isalnum(pParse->zJson[i+5]) ){
drhe9c37f32015-08-15 21:25:36 +0000668 jsonParseAddNode(pParse, JSON_FALSE, 0, 0);
669 return i+5;
670 }else if( c=='-' || (c>='0' && c<='9') ){
671 /* Parse number */
672 u8 seenDP = 0;
673 u8 seenE = 0;
674 j = i+1;
675 for(;; j++){
676 c = pParse->zJson[j];
677 if( c>='0' && c<='9' ) continue;
678 if( c=='.' ){
679 if( pParse->zJson[j-1]=='-' ) return -1;
680 if( seenDP ) return -1;
681 seenDP = 1;
682 continue;
683 }
684 if( c=='e' || c=='E' ){
685 if( pParse->zJson[j-1]<'0' ) return -1;
686 if( seenE ) return -1;
687 seenDP = seenE = 1;
688 c = pParse->zJson[j+1];
drh8784eca2015-08-23 02:42:30 +0000689 if( c=='+' || c=='-' ){
690 j++;
691 c = pParse->zJson[j+1];
692 }
drhd1f00682015-08-29 16:02:37 +0000693 if( c<'0' || c>'9' ) return -1;
drhe9c37f32015-08-15 21:25:36 +0000694 continue;
695 }
696 break;
697 }
698 if( pParse->zJson[j-1]<'0' ) return -1;
699 jsonParseAddNode(pParse, seenDP ? JSON_REAL : JSON_INT,
700 j - i, &pParse->zJson[i]);
701 return j;
702 }else if( c=='}' ){
703 return -2; /* End of {...} */
704 }else if( c==']' ){
705 return -3; /* End of [...] */
706 }else{
707 return -1; /* Syntax error */
708 }
709}
710
711/*
712** Parse a complete JSON string. Return 0 on success or non-zero if there
713** are any errors. If an error occurs, free all memory associated with
714** pParse.
715**
716** pParse is uninitialized when this routine is called.
717*/
drhbc8f0922015-08-22 19:39:04 +0000718static int jsonParse(
719 JsonParse *pParse, /* Initialize and fill this JsonParse object */
720 sqlite3_context *pCtx, /* Report errors here */
721 const char *zJson /* Input JSON text to be parsed */
722){
drhe9c37f32015-08-15 21:25:36 +0000723 int i;
drhe9c37f32015-08-15 21:25:36 +0000724 memset(pParse, 0, sizeof(*pParse));
drhc3722b22015-08-23 20:44:59 +0000725 if( zJson==0 ) return 1;
drhe9c37f32015-08-15 21:25:36 +0000726 pParse->zJson = zJson;
727 i = jsonParseValue(pParse, 0);
drhc3722b22015-08-23 20:44:59 +0000728 if( pParse->oom ) i = -1;
drhe9c37f32015-08-15 21:25:36 +0000729 if( i>0 ){
730 while( isspace(zJson[i]) ) i++;
731 if( zJson[i] ) i = -1;
732 }
drhd1f00682015-08-29 16:02:37 +0000733 if( i<=0 ){
drhf2df7e72015-08-28 20:07:40 +0000734 if( pCtx!=0 ){
735 if( pParse->oom ){
736 sqlite3_result_error_nomem(pCtx);
737 }else{
738 sqlite3_result_error(pCtx, "malformed JSON", -1);
739 }
740 }
drh505ad2c2015-08-21 17:33:11 +0000741 jsonParseReset(pParse);
drhe9c37f32015-08-15 21:25:36 +0000742 return 1;
743 }
744 return 0;
745}
drh301eecc2015-08-17 20:14:19 +0000746
drh505ad2c2015-08-21 17:33:11 +0000747/* Mark node i of pParse as being a child of iParent. Call recursively
748** to fill in all the descendants of node i.
749*/
750static void jsonParseFillInParentage(JsonParse *pParse, u32 i, u32 iParent){
751 JsonNode *pNode = &pParse->aNode[i];
752 u32 j;
753 pParse->aUp[i] = iParent;
754 switch( pNode->eType ){
755 case JSON_ARRAY: {
756 for(j=1; j<=pNode->n; j += jsonNodeSize(pNode+j)){
757 jsonParseFillInParentage(pParse, i+j, i);
758 }
759 break;
760 }
761 case JSON_OBJECT: {
762 for(j=1; j<=pNode->n; j += jsonNodeSize(pNode+j+1)+1){
763 pParse->aUp[i+j] = i;
764 jsonParseFillInParentage(pParse, i+j+1, i);
765 }
766 break;
767 }
768 default: {
769 break;
770 }
771 }
772}
773
774/*
775** Compute the parentage of all nodes in a completed parse.
776*/
777static int jsonParseFindParents(JsonParse *pParse){
778 u32 *aUp;
779 assert( pParse->aUp==0 );
780 aUp = pParse->aUp = sqlite3_malloc( sizeof(u32)*pParse->nNode );
drhc3722b22015-08-23 20:44:59 +0000781 if( aUp==0 ){
782 pParse->oom = 1;
783 return SQLITE_NOMEM;
784 }
drh505ad2c2015-08-21 17:33:11 +0000785 jsonParseFillInParentage(pParse, 0, 0);
786 return SQLITE_OK;
787}
788
drh52216ad2015-08-18 02:28:03 +0000789/* forward declaration */
drha7714022015-08-29 00:54:49 +0000790static JsonNode *jsonLookupAppend(JsonParse*,const char*,int*,const char**);
drh52216ad2015-08-18 02:28:03 +0000791
drh987eb1f2015-08-17 15:17:37 +0000792/*
793** Search along zPath to find the node specified. Return a pointer
794** to that node, or NULL if zPath is malformed or if there is no such
795** node.
drh52216ad2015-08-18 02:28:03 +0000796**
797** If pApnd!=0, then try to append new nodes to complete zPath if it is
798** possible to do so and if no existing node corresponds to zPath. If
799** new nodes are appended *pApnd is set to 1.
drh987eb1f2015-08-17 15:17:37 +0000800*/
drha7714022015-08-29 00:54:49 +0000801static JsonNode *jsonLookupStep(
drh52216ad2015-08-18 02:28:03 +0000802 JsonParse *pParse, /* The JSON to search */
803 u32 iRoot, /* Begin the search at this node */
804 const char *zPath, /* The path to search */
drha7714022015-08-29 00:54:49 +0000805 int *pApnd, /* Append nodes to complete path if not NULL */
806 const char **pzErr /* Make *pzErr point to any syntax error in zPath */
drh52216ad2015-08-18 02:28:03 +0000807){
drhbc8f0922015-08-22 19:39:04 +0000808 u32 i, j, nKey;
drh6b43cc82015-08-19 23:02:49 +0000809 const char *zKey;
drh52216ad2015-08-18 02:28:03 +0000810 JsonNode *pRoot = &pParse->aNode[iRoot];
drh987eb1f2015-08-17 15:17:37 +0000811 if( zPath[0]==0 ) return pRoot;
812 if( zPath[0]=='.' ){
813 if( pRoot->eType!=JSON_OBJECT ) return 0;
814 zPath++;
drh6b43cc82015-08-19 23:02:49 +0000815 if( zPath[0]=='"' ){
816 zKey = zPath + 1;
817 for(i=1; zPath[i] && zPath[i]!='"'; i++){}
818 nKey = i-1;
819 if( zPath[i] ) i++;
820 }else{
821 zKey = zPath;
822 for(i=0; zPath[i] && zPath[i]!='.' && zPath[i]!='['; i++){}
823 nKey = i;
824 }
drha7714022015-08-29 00:54:49 +0000825 if( nKey==0 ){
826 *pzErr = zPath;
827 return 0;
828 }
drh987eb1f2015-08-17 15:17:37 +0000829 j = 1;
drh52216ad2015-08-18 02:28:03 +0000830 for(;;){
831 while( j<=pRoot->n ){
drh6b43cc82015-08-19 23:02:49 +0000832 if( pRoot[j].n==nKey+2
833 && strncmp(&pRoot[j].u.zJContent[1],zKey,nKey)==0
drh52216ad2015-08-18 02:28:03 +0000834 ){
drha7714022015-08-29 00:54:49 +0000835 return jsonLookupStep(pParse, iRoot+j+1, &zPath[i], pApnd, pzErr);
drh52216ad2015-08-18 02:28:03 +0000836 }
837 j++;
drh505ad2c2015-08-21 17:33:11 +0000838 j += jsonNodeSize(&pRoot[j]);
drh987eb1f2015-08-17 15:17:37 +0000839 }
drh52216ad2015-08-18 02:28:03 +0000840 if( (pRoot->jnFlags & JNODE_APPEND)==0 ) break;
841 iRoot += pRoot->u.iAppend;
842 pRoot = &pParse->aNode[iRoot];
843 j = 1;
844 }
845 if( pApnd ){
drhbc8f0922015-08-22 19:39:04 +0000846 u32 iStart, iLabel;
847 JsonNode *pNode;
848 iStart = jsonParseAddNode(pParse, JSON_OBJECT, 2, 0);
849 iLabel = jsonParseAddNode(pParse, JSON_STRING, i, zPath);
drh52216ad2015-08-18 02:28:03 +0000850 zPath += i;
drha7714022015-08-29 00:54:49 +0000851 pNode = jsonLookupAppend(pParse, zPath, pApnd, pzErr);
drhbc8f0922015-08-22 19:39:04 +0000852 if( pParse->oom ) return 0;
853 if( pNode ){
854 pRoot = &pParse->aNode[iRoot];
855 pRoot->u.iAppend = iStart - iRoot;
856 pRoot->jnFlags |= JNODE_APPEND;
857 pParse->aNode[iLabel].jnFlags |= JNODE_RAW;
858 }
859 return pNode;
drh987eb1f2015-08-17 15:17:37 +0000860 }
861 }else if( zPath[0]=='[' && isdigit(zPath[1]) ){
862 if( pRoot->eType!=JSON_ARRAY ) return 0;
863 i = 0;
864 zPath++;
865 while( isdigit(zPath[0]) ){
drh8784eca2015-08-23 02:42:30 +0000866 i = i*10 + zPath[0] - '0';
drh987eb1f2015-08-17 15:17:37 +0000867 zPath++;
868 }
drha7714022015-08-29 00:54:49 +0000869 if( zPath[0]!=']' ){
870 *pzErr = zPath;
871 return 0;
872 }
drh987eb1f2015-08-17 15:17:37 +0000873 zPath++;
874 j = 1;
drh52216ad2015-08-18 02:28:03 +0000875 for(;;){
drhbc8f0922015-08-22 19:39:04 +0000876 while( j<=pRoot->n && (i>0 || (pRoot[j].jnFlags & JNODE_REMOVE)!=0) ){
877 if( (pRoot[j].jnFlags & JNODE_REMOVE)==0 ) i--;
drh505ad2c2015-08-21 17:33:11 +0000878 j += jsonNodeSize(&pRoot[j]);
drh52216ad2015-08-18 02:28:03 +0000879 }
880 if( (pRoot->jnFlags & JNODE_APPEND)==0 ) break;
881 iRoot += pRoot->u.iAppend;
882 pRoot = &pParse->aNode[iRoot];
883 j = 1;
drh987eb1f2015-08-17 15:17:37 +0000884 }
885 if( j<=pRoot->n ){
drha7714022015-08-29 00:54:49 +0000886 return jsonLookupStep(pParse, iRoot+j, zPath, pApnd, pzErr);
drh52216ad2015-08-18 02:28:03 +0000887 }
888 if( i==0 && pApnd ){
drhbc8f0922015-08-22 19:39:04 +0000889 u32 iStart;
890 JsonNode *pNode;
891 iStart = jsonParseAddNode(pParse, JSON_ARRAY, 1, 0);
drha7714022015-08-29 00:54:49 +0000892 pNode = jsonLookupAppend(pParse, zPath, pApnd, pzErr);
drhbc8f0922015-08-22 19:39:04 +0000893 if( pParse->oom ) return 0;
894 if( pNode ){
895 pRoot = &pParse->aNode[iRoot];
896 pRoot->u.iAppend = iStart - iRoot;
897 pRoot->jnFlags |= JNODE_APPEND;
898 }
899 return pNode;
drh987eb1f2015-08-17 15:17:37 +0000900 }
drha7714022015-08-29 00:54:49 +0000901 }else if( zPath[0]!=0 ){
902 *pzErr = zPath;
drh987eb1f2015-08-17 15:17:37 +0000903 }
904 return 0;
905}
906
drh52216ad2015-08-18 02:28:03 +0000907/*
drhbc8f0922015-08-22 19:39:04 +0000908** Append content to pParse that will complete zPath. Return a pointer
909** to the inserted node, or return NULL if the append fails.
drh52216ad2015-08-18 02:28:03 +0000910*/
911static JsonNode *jsonLookupAppend(
912 JsonParse *pParse, /* Append content to the JSON parse */
913 const char *zPath, /* Description of content to append */
drha7714022015-08-29 00:54:49 +0000914 int *pApnd, /* Set this flag to 1 */
915 const char **pzErr /* Make this point to any syntax error */
drh52216ad2015-08-18 02:28:03 +0000916){
917 *pApnd = 1;
918 if( zPath[0]==0 ){
919 jsonParseAddNode(pParse, JSON_NULL, 0, 0);
920 return pParse->oom ? 0 : &pParse->aNode[pParse->nNode-1];
921 }
922 if( zPath[0]=='.' ){
923 jsonParseAddNode(pParse, JSON_OBJECT, 0, 0);
924 }else if( strncmp(zPath,"[0]",3)==0 ){
925 jsonParseAddNode(pParse, JSON_ARRAY, 0, 0);
926 }else{
927 return 0;
928 }
929 if( pParse->oom ) return 0;
drha7714022015-08-29 00:54:49 +0000930 return jsonLookupStep(pParse, pParse->nNode-1, zPath, pApnd, pzErr);
drh52216ad2015-08-18 02:28:03 +0000931}
932
drhbc8f0922015-08-22 19:39:04 +0000933/*
drha7714022015-08-29 00:54:49 +0000934** Return the text of a syntax error message on a JSON path. Space is
935** obtained from sqlite3_malloc().
936*/
937static char *jsonPathSyntaxError(const char *zErr){
938 return sqlite3_mprintf("JSON path error near '%q'", zErr);
939}
940
941/*
942** Do a node lookup using zPath. Return a pointer to the node on success.
943** Return NULL if not found or if there is an error.
944**
945** On an error, write an error message into pCtx and increment the
946** pParse->nErr counter.
947**
948** If pApnd!=NULL then try to append missing nodes and set *pApnd = 1 if
949** nodes are appended.
950**
951** If the path starts with $$ then set *pFlags to JNODE_REPLACE|JNODE_JSON
952** as a single to the caller that the input text to be inserted should be
953** interpreted as JSON rather than as ordinary text.
954*/
955static JsonNode *jsonLookup(
956 JsonParse *pParse, /* The JSON to search */
957 const char *zPath, /* The path to search */
958 int *pApnd, /* Append nodes to complete path if not NULL */
959 sqlite3_context *pCtx, /* Report errors here, if not NULL */
960 u8 *pFlags /* Write JNODE_REPLACE or _REPLACE|_JSON here */
961){
962 const char *zErr = 0;
963 JsonNode *pNode = 0;
964 u8 fg = JNODE_REPLACE;
965
966 if( zPath==0 ) return 0;
967 if( zPath[0]!='$' ){
968 zErr = zPath;
969 goto lookup_err;
970 }
971 zPath++;
972 if( zPath[0]=='$' ){
973 if( pFlags==0 ){
974 zErr = zPath;
975 goto lookup_err;
976 }
977 zPath++;
978 fg = JNODE_REPLACE|JNODE_JSON;
979 }
980 if( pFlags ) *pFlags = fg;
981 pNode = jsonLookupStep(pParse, 0, zPath, pApnd, &zErr);
982 return pNode;
983
984lookup_err:
985 pParse->nErr++;
986 if( zErr!=0 && pCtx!=0 ){
987 char *z = jsonPathSyntaxError(zErr);
988 if( z ){
989 sqlite3_result_error(pCtx, z, -1);
990 sqlite3_free(z);
991 }else{
992 sqlite3_result_error_nomem(pCtx);
993 }
994 }
995 if( pFlags ) *pFlags = fg;
996 return 0;
997}
998
999
1000/*
drhbc8f0922015-08-22 19:39:04 +00001001** Report the wrong number of arguments for json_insert(), json_replace()
1002** or json_set().
1003*/
1004static void jsonWrongNumArgs(
1005 sqlite3_context *pCtx,
1006 const char *zFuncName
1007){
1008 char *zMsg = sqlite3_mprintf("json_%s() needs an odd number of arguments",
1009 zFuncName);
1010 sqlite3_result_error(pCtx, zMsg, -1);
1011 sqlite3_free(zMsg);
1012}
drh52216ad2015-08-18 02:28:03 +00001013
drha7714022015-08-29 00:54:49 +00001014
drh987eb1f2015-08-17 15:17:37 +00001015/****************************************************************************
1016** SQL functions used for testing and debugging
1017****************************************************************************/
drhe9c37f32015-08-15 21:25:36 +00001018
drh301eecc2015-08-17 20:14:19 +00001019#ifdef SQLITE_DEBUG
drhe9c37f32015-08-15 21:25:36 +00001020/*
drh5634cc02015-08-17 11:28:03 +00001021** The json_parse(JSON) function returns a string which describes
drhe9c37f32015-08-15 21:25:36 +00001022** a parse of the JSON provided. Or it returns NULL if JSON is not
1023** well-formed.
1024*/
drh5634cc02015-08-17 11:28:03 +00001025static void jsonParseFunc(
drhbc8f0922015-08-22 19:39:04 +00001026 sqlite3_context *ctx,
drhe9c37f32015-08-15 21:25:36 +00001027 int argc,
1028 sqlite3_value **argv
1029){
drh505ad2c2015-08-21 17:33:11 +00001030 JsonString s; /* Output string - not real JSON */
1031 JsonParse x; /* The parse */
drhe9c37f32015-08-15 21:25:36 +00001032 u32 i;
drhe9c37f32015-08-15 21:25:36 +00001033
1034 assert( argc==1 );
drhbc8f0922015-08-22 19:39:04 +00001035 if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return;
drh8784eca2015-08-23 02:42:30 +00001036 jsonParseFindParents(&x);
drhbc8f0922015-08-22 19:39:04 +00001037 jsonInit(&s, ctx);
drhe9c37f32015-08-15 21:25:36 +00001038 for(i=0; i<x.nNode; i++){
drh8784eca2015-08-23 02:42:30 +00001039 jsonPrintf(100, &s,"node %3u: %7s n=%-4d up=%d\n",
1040 i, jsonType[x.aNode[i].eType], x.aNode[i].n, x.aUp[i]);
drh52216ad2015-08-18 02:28:03 +00001041 if( x.aNode[i].u.zJContent!=0 ){
drh301eecc2015-08-17 20:14:19 +00001042 jsonAppendRaw(&s, " text: ", 10);
drh52216ad2015-08-18 02:28:03 +00001043 jsonAppendRaw(&s, x.aNode[i].u.zJContent, x.aNode[i].n);
drhe9c37f32015-08-15 21:25:36 +00001044 jsonAppendRaw(&s, "\n", 1);
1045 }
1046 }
drh505ad2c2015-08-21 17:33:11 +00001047 jsonParseReset(&x);
drhe9c37f32015-08-15 21:25:36 +00001048 jsonResult(&s);
1049}
1050
drh5634cc02015-08-17 11:28:03 +00001051/*
1052** The json_test1(JSON) function parses and rebuilds the JSON string.
1053*/
1054static void jsonTest1Func(
drhbc8f0922015-08-22 19:39:04 +00001055 sqlite3_context *ctx,
drh5634cc02015-08-17 11:28:03 +00001056 int argc,
1057 sqlite3_value **argv
1058){
1059 JsonParse x; /* The parse */
drhbc8f0922015-08-22 19:39:04 +00001060 if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return;
drhf2df7e72015-08-28 20:07:40 +00001061 jsonReturnJson(x.aNode, ctx, 0);
drh505ad2c2015-08-21 17:33:11 +00001062 jsonParseReset(&x);
drh5634cc02015-08-17 11:28:03 +00001063}
1064
1065/*
1066** The json_nodecount(JSON) function returns the number of nodes in the
1067** input JSON string.
1068*/
1069static void jsonNodeCountFunc(
drhbc8f0922015-08-22 19:39:04 +00001070 sqlite3_context *ctx,
drh5634cc02015-08-17 11:28:03 +00001071 int argc,
1072 sqlite3_value **argv
1073){
1074 JsonParse x; /* The parse */
drhbc8f0922015-08-22 19:39:04 +00001075 if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return;
1076 sqlite3_result_int64(ctx, (sqlite3_int64)x.nNode);
drh505ad2c2015-08-21 17:33:11 +00001077 jsonParseReset(&x);
drh5634cc02015-08-17 11:28:03 +00001078}
drh301eecc2015-08-17 20:14:19 +00001079#endif /* SQLITE_DEBUG */
drh5634cc02015-08-17 11:28:03 +00001080
drh987eb1f2015-08-17 15:17:37 +00001081/****************************************************************************
1082** SQL function implementations
1083****************************************************************************/
1084
1085/*
1086** Implementation of the json_array(VALUE,...) function. Return a JSON
1087** array that contains all values given in arguments. Or if any argument
1088** is a BLOB, throw an error.
1089*/
1090static void jsonArrayFunc(
drhbc8f0922015-08-22 19:39:04 +00001091 sqlite3_context *ctx,
drh987eb1f2015-08-17 15:17:37 +00001092 int argc,
1093 sqlite3_value **argv
1094){
1095 int i;
drh505ad2c2015-08-21 17:33:11 +00001096 JsonString jx;
drh987eb1f2015-08-17 15:17:37 +00001097
drhbc8f0922015-08-22 19:39:04 +00001098 jsonInit(&jx, ctx);
drhd0960592015-08-17 21:22:32 +00001099 jsonAppendChar(&jx, '[');
drh987eb1f2015-08-17 15:17:37 +00001100 for(i=0; i<argc; i++){
drhd0960592015-08-17 21:22:32 +00001101 jsonAppendSeparator(&jx);
drhecb5fed2015-08-28 03:33:50 +00001102 jsonAppendValue(&jx, argv[i], 0);
drh987eb1f2015-08-17 15:17:37 +00001103 }
drhd0960592015-08-17 21:22:32 +00001104 jsonAppendChar(&jx, ']');
drh987eb1f2015-08-17 15:17:37 +00001105 jsonResult(&jx);
1106}
1107
1108
1109/*
1110** json_array_length(JSON)
1111** json_array_length(JSON, PATH)
1112**
1113** Return the number of elements in the top-level JSON array.
1114** Return 0 if the input is not a well-formed JSON array.
1115*/
1116static void jsonArrayLengthFunc(
drhbc8f0922015-08-22 19:39:04 +00001117 sqlite3_context *ctx,
drh987eb1f2015-08-17 15:17:37 +00001118 int argc,
1119 sqlite3_value **argv
1120){
1121 JsonParse x; /* The parse */
1122 sqlite3_int64 n = 0;
1123 u32 i;
drh987eb1f2015-08-17 15:17:37 +00001124
drhf2df7e72015-08-28 20:07:40 +00001125 if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return;
1126 if( x.nNode ){
drha7714022015-08-29 00:54:49 +00001127 JsonNode *pNode;
1128 if( argc==2 ){
1129 const char *zPath = (const char*)sqlite3_value_text(argv[1]);
1130 pNode = jsonLookup(&x, zPath, 0, ctx, 0);
1131 }else{
1132 pNode = x.aNode;
1133 }
1134 if( pNode==0 ){
1135 x.nErr = 1;
1136 }else if( pNode->eType==JSON_ARRAY ){
drhf2df7e72015-08-28 20:07:40 +00001137 assert( (pNode->jnFlags & JNODE_APPEND)==0 );
1138 for(i=1; i<=pNode->n; n++){
1139 i += jsonNodeSize(&pNode[i]);
drh987eb1f2015-08-17 15:17:37 +00001140 }
1141 }
drh987eb1f2015-08-17 15:17:37 +00001142 }
drha7714022015-08-29 00:54:49 +00001143 if( x.nErr==0 ) sqlite3_result_int64(ctx, n);
drhf6ec8d42015-08-28 03:48:04 +00001144 jsonParseReset(&x);
1145}
1146
1147/*
drh987eb1f2015-08-17 15:17:37 +00001148** json_extract(JSON, PATH)
1149**
1150** Return the element described by PATH. Return NULL if JSON is not
1151** valid JSON or if there is no PATH element or if PATH is malformed.
1152*/
1153static void jsonExtractFunc(
drhbc8f0922015-08-22 19:39:04 +00001154 sqlite3_context *ctx,
drh987eb1f2015-08-17 15:17:37 +00001155 int argc,
1156 sqlite3_value **argv
1157){
1158 JsonParse x; /* The parse */
1159 JsonNode *pNode;
1160 const char *zPath;
1161 assert( argc==2 );
1162 zPath = (const char*)sqlite3_value_text(argv[1]);
drhbc8f0922015-08-22 19:39:04 +00001163 if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return;
drha7714022015-08-29 00:54:49 +00001164 pNode = jsonLookup(&x, zPath, 0, ctx, 0);
drh987eb1f2015-08-17 15:17:37 +00001165 if( pNode ){
drhbc8f0922015-08-22 19:39:04 +00001166 jsonReturn(pNode, ctx, 0);
drh987eb1f2015-08-17 15:17:37 +00001167 }
drh505ad2c2015-08-21 17:33:11 +00001168 jsonParseReset(&x);
drh987eb1f2015-08-17 15:17:37 +00001169}
1170
1171/*
1172** Implementation of the json_object(NAME,VALUE,...) function. Return a JSON
1173** object that contains all name/value given in arguments. Or if any name
1174** is not a string or if any value is a BLOB, throw an error.
1175*/
1176static void jsonObjectFunc(
drhbc8f0922015-08-22 19:39:04 +00001177 sqlite3_context *ctx,
drh987eb1f2015-08-17 15:17:37 +00001178 int argc,
1179 sqlite3_value **argv
1180){
1181 int i;
drh505ad2c2015-08-21 17:33:11 +00001182 JsonString jx;
drh987eb1f2015-08-17 15:17:37 +00001183 const char *z;
1184 u32 n;
1185
1186 if( argc&1 ){
drhbc8f0922015-08-22 19:39:04 +00001187 sqlite3_result_error(ctx, "json_object() requires an even number "
drh987eb1f2015-08-17 15:17:37 +00001188 "of arguments", -1);
1189 return;
1190 }
drhbc8f0922015-08-22 19:39:04 +00001191 jsonInit(&jx, ctx);
drhd0960592015-08-17 21:22:32 +00001192 jsonAppendChar(&jx, '{');
drh987eb1f2015-08-17 15:17:37 +00001193 for(i=0; i<argc; i+=2){
drh987eb1f2015-08-17 15:17:37 +00001194 if( sqlite3_value_type(argv[i])!=SQLITE_TEXT ){
drhbc8f0922015-08-22 19:39:04 +00001195 sqlite3_result_error(ctx, "json_object() labels must be TEXT", -1);
drh987eb1f2015-08-17 15:17:37 +00001196 jsonZero(&jx);
1197 return;
1198 }
drhd0960592015-08-17 21:22:32 +00001199 jsonAppendSeparator(&jx);
drh987eb1f2015-08-17 15:17:37 +00001200 z = (const char*)sqlite3_value_text(argv[i]);
1201 n = (u32)sqlite3_value_bytes(argv[i]);
1202 jsonAppendString(&jx, z, n);
drhd0960592015-08-17 21:22:32 +00001203 jsonAppendChar(&jx, ':');
drhecb5fed2015-08-28 03:33:50 +00001204 jsonAppendValue(&jx, argv[i+1], 0);
drh987eb1f2015-08-17 15:17:37 +00001205 }
drhd0960592015-08-17 21:22:32 +00001206 jsonAppendChar(&jx, '}');
drh987eb1f2015-08-17 15:17:37 +00001207 jsonResult(&jx);
1208}
1209
1210
1211/*
drh301eecc2015-08-17 20:14:19 +00001212** json_remove(JSON, PATH, ...)
1213**
1214** Remove the named elements from JSON and return the result. Ill-formed
1215** PATH arguments are silently ignored. If JSON is ill-formed, then NULL
1216** is returned.
1217*/
1218static void jsonRemoveFunc(
drhbc8f0922015-08-22 19:39:04 +00001219 sqlite3_context *ctx,
drh301eecc2015-08-17 20:14:19 +00001220 int argc,
1221 sqlite3_value **argv
1222){
1223 JsonParse x; /* The parse */
1224 JsonNode *pNode;
1225 const char *zPath;
1226 u32 i;
1227
1228 if( argc<1 ) return;
drhbc8f0922015-08-22 19:39:04 +00001229 if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return;
drh301eecc2015-08-17 20:14:19 +00001230 if( x.nNode ){
drh6fd5c1e2015-08-21 20:37:12 +00001231 for(i=1; i<(u32)argc; i++){
drh301eecc2015-08-17 20:14:19 +00001232 zPath = (const char*)sqlite3_value_text(argv[i]);
drha7714022015-08-29 00:54:49 +00001233 if( zPath==0 ) goto remove_done;
1234 pNode = jsonLookup(&x, zPath, 0, ctx, 0);
1235 if( x.nErr ) goto remove_done;
drh301eecc2015-08-17 20:14:19 +00001236 if( pNode ) pNode->jnFlags |= JNODE_REMOVE;
1237 }
1238 if( (x.aNode[0].jnFlags & JNODE_REMOVE)==0 ){
drhf2df7e72015-08-28 20:07:40 +00001239 jsonReturnJson(x.aNode, ctx, 0);
drhd0960592015-08-17 21:22:32 +00001240 }
1241 }
drha7714022015-08-29 00:54:49 +00001242remove_done:
drh505ad2c2015-08-21 17:33:11 +00001243 jsonParseReset(&x);
drhd0960592015-08-17 21:22:32 +00001244}
1245
1246/*
1247** json_replace(JSON, PATH, VALUE, ...)
1248**
1249** Replace the value at PATH with VALUE. If PATH does not already exist,
1250** this routine is a no-op. If JSON is ill-formed, return NULL.
1251*/
1252static void jsonReplaceFunc(
drhbc8f0922015-08-22 19:39:04 +00001253 sqlite3_context *ctx,
drhd0960592015-08-17 21:22:32 +00001254 int argc,
1255 sqlite3_value **argv
1256){
1257 JsonParse x; /* The parse */
1258 JsonNode *pNode;
1259 const char *zPath;
1260 u32 i;
1261
1262 if( argc<1 ) return;
1263 if( (argc&1)==0 ) {
drhbc8f0922015-08-22 19:39:04 +00001264 jsonWrongNumArgs(ctx, "replace");
drhd0960592015-08-17 21:22:32 +00001265 return;
1266 }
drhbc8f0922015-08-22 19:39:04 +00001267 if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return;
drhd0960592015-08-17 21:22:32 +00001268 if( x.nNode ){
drh6fd5c1e2015-08-21 20:37:12 +00001269 for(i=1; i<(u32)argc; i+=2){
drhecb5fed2015-08-28 03:33:50 +00001270 u8 jnFlags = JNODE_REPLACE;
drhd0960592015-08-17 21:22:32 +00001271 zPath = (const char*)sqlite3_value_text(argv[i]);
drha7714022015-08-29 00:54:49 +00001272 pNode = jsonLookup(&x, zPath, 0, ctx, &jnFlags);
1273 if( x.nErr ) goto replace_err;
drhd0960592015-08-17 21:22:32 +00001274 if( pNode ){
drhecb5fed2015-08-28 03:33:50 +00001275 pNode->jnFlags &= ~JNODE_JSON;
1276 pNode->jnFlags |= jnFlags;
drhd0960592015-08-17 21:22:32 +00001277 pNode->iVal = i+1;
1278 }
1279 }
1280 if( x.aNode[0].jnFlags & JNODE_REPLACE ){
drhbc8f0922015-08-22 19:39:04 +00001281 sqlite3_result_value(ctx, argv[x.aNode[0].iVal]);
drhd0960592015-08-17 21:22:32 +00001282 }else{
drhf2df7e72015-08-28 20:07:40 +00001283 jsonReturnJson(x.aNode, ctx, argv);
drh301eecc2015-08-17 20:14:19 +00001284 }
1285 }
drha7714022015-08-29 00:54:49 +00001286replace_err:
drh505ad2c2015-08-21 17:33:11 +00001287 jsonParseReset(&x);
drh301eecc2015-08-17 20:14:19 +00001288}
drh505ad2c2015-08-21 17:33:11 +00001289
drh52216ad2015-08-18 02:28:03 +00001290/*
1291** json_set(JSON, PATH, VALUE, ...)
1292**
1293** Set the value at PATH to VALUE. Create the PATH if it does not already
1294** exist. Overwrite existing values that do exist.
1295** If JSON is ill-formed, return NULL.
1296**
1297** json_insert(JSON, PATH, VALUE, ...)
1298**
1299** Create PATH and initialize it to VALUE. If PATH already exists, this
1300** routine is a no-op. If JSON is ill-formed, return NULL.
1301*/
1302static void jsonSetFunc(
drhbc8f0922015-08-22 19:39:04 +00001303 sqlite3_context *ctx,
drh52216ad2015-08-18 02:28:03 +00001304 int argc,
1305 sqlite3_value **argv
1306){
1307 JsonParse x; /* The parse */
1308 JsonNode *pNode;
1309 const char *zPath;
1310 u32 i;
1311 int bApnd;
drhbc8f0922015-08-22 19:39:04 +00001312 int bIsSet = *(int*)sqlite3_user_data(ctx);
drh52216ad2015-08-18 02:28:03 +00001313
1314 if( argc<1 ) return;
1315 if( (argc&1)==0 ) {
drhbc8f0922015-08-22 19:39:04 +00001316 jsonWrongNumArgs(ctx, bIsSet ? "set" : "insert");
drh52216ad2015-08-18 02:28:03 +00001317 return;
1318 }
drhbc8f0922015-08-22 19:39:04 +00001319 if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return;
drh52216ad2015-08-18 02:28:03 +00001320 if( x.nNode ){
drh6fd5c1e2015-08-21 20:37:12 +00001321 for(i=1; i<(u32)argc; i+=2){
drhecb5fed2015-08-28 03:33:50 +00001322 u8 jnFlags = JNODE_REPLACE;
drh52216ad2015-08-18 02:28:03 +00001323 zPath = (const char*)sqlite3_value_text(argv[i]);
drh52216ad2015-08-18 02:28:03 +00001324 bApnd = 0;
drha7714022015-08-29 00:54:49 +00001325 pNode = jsonLookup(&x, zPath, &bApnd, ctx, &jnFlags);
drhbc8f0922015-08-22 19:39:04 +00001326 if( x.oom ){
1327 sqlite3_result_error_nomem(ctx);
1328 goto jsonSetDone;
drha7714022015-08-29 00:54:49 +00001329 }else if( x.nErr ){
1330 goto jsonSetDone;
drhbc8f0922015-08-22 19:39:04 +00001331 }else if( pNode && (bApnd || bIsSet) ){
drhecb5fed2015-08-28 03:33:50 +00001332 pNode->jnFlags &= ~JNODE_JSON;
1333 pNode->jnFlags |= jnFlags;
drh52216ad2015-08-18 02:28:03 +00001334 pNode->iVal = i+1;
1335 }
1336 }
1337 if( x.aNode[0].jnFlags & JNODE_REPLACE ){
drhbc8f0922015-08-22 19:39:04 +00001338 sqlite3_result_value(ctx, argv[x.aNode[0].iVal]);
drh52216ad2015-08-18 02:28:03 +00001339 }else{
drhf2df7e72015-08-28 20:07:40 +00001340 jsonReturnJson(x.aNode, ctx, argv);
drh52216ad2015-08-18 02:28:03 +00001341 }
1342 }
drhbc8f0922015-08-22 19:39:04 +00001343jsonSetDone:
drh505ad2c2015-08-21 17:33:11 +00001344 jsonParseReset(&x);
drh52216ad2015-08-18 02:28:03 +00001345}
drh301eecc2015-08-17 20:14:19 +00001346
1347/*
drh987eb1f2015-08-17 15:17:37 +00001348** json_type(JSON)
1349** json_type(JSON, PATH)
1350**
1351** Return the top-level "type" of a JSON string. Return NULL if the
1352** input is not a well-formed JSON string.
1353*/
1354static void jsonTypeFunc(
drhbc8f0922015-08-22 19:39:04 +00001355 sqlite3_context *ctx,
drh987eb1f2015-08-17 15:17:37 +00001356 int argc,
1357 sqlite3_value **argv
1358){
1359 JsonParse x; /* The parse */
1360 const char *zPath;
1361
drhbc8f0922015-08-22 19:39:04 +00001362 if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return;
drh987eb1f2015-08-17 15:17:37 +00001363 if( x.nNode ){
drha7714022015-08-29 00:54:49 +00001364 JsonNode *pNode;
1365 if( argc==2 ){
1366 zPath = (const char*)sqlite3_value_text(argv[1]);
1367 pNode = jsonLookup(&x, zPath, 0, ctx, 0);
1368 }else{
1369 pNode = x.aNode;
1370 }
drhbc8f0922015-08-22 19:39:04 +00001371 if( pNode ){
1372 sqlite3_result_text(ctx, jsonType[pNode->eType], -1, SQLITE_STATIC);
1373 }
drh987eb1f2015-08-17 15:17:37 +00001374 }
drh505ad2c2015-08-21 17:33:11 +00001375 jsonParseReset(&x);
drh987eb1f2015-08-17 15:17:37 +00001376}
drh5634cc02015-08-17 11:28:03 +00001377
drhbc8f0922015-08-22 19:39:04 +00001378/*
1379** json_valid(JSON)
1380**
1381** Return 1 if JSON is a valid JSON string. Return 0 otherwise.
1382*/
1383static void jsonValidFunc(
1384 sqlite3_context *ctx,
1385 int argc,
1386 sqlite3_value **argv
1387){
1388 JsonParse x; /* The parse */
1389 int rc = 0;
1390
drhf2df7e72015-08-28 20:07:40 +00001391 if( jsonParse(&x, 0, (const char*)sqlite3_value_text(argv[0]))==0
drhbc8f0922015-08-22 19:39:04 +00001392 && x.nNode>0
1393 ){
1394 rc = 1;
1395 }
1396 jsonParseReset(&x);
1397 sqlite3_result_int(ctx, rc);
1398}
1399
drhcb6c6c62015-08-19 22:47:17 +00001400/****************************************************************************
1401** The json_each virtual table
1402****************************************************************************/
1403typedef struct JsonEachCursor JsonEachCursor;
1404struct JsonEachCursor {
1405 sqlite3_vtab_cursor base; /* Base class - must be first */
drh505ad2c2015-08-21 17:33:11 +00001406 u32 iRowid; /* The rowid */
1407 u32 i; /* Index in sParse.aNode[] of current row */
1408 u32 iEnd; /* EOF when i equals or exceeds this value */
1409 u8 eType; /* Type of top-level element */
1410 u8 bRecursive; /* True for json_tree(). False for json_each() */
1411 char *zJson; /* Input JSON */
1412 char *zPath; /* Path by which to filter zJson */
1413 JsonParse sParse; /* Parse of the input JSON */
drhcb6c6c62015-08-19 22:47:17 +00001414};
1415
1416/* Constructor for the json_each virtual table */
1417static int jsonEachConnect(
1418 sqlite3 *db,
1419 void *pAux,
1420 int argc, const char *const*argv,
1421 sqlite3_vtab **ppVtab,
1422 char **pzErr
1423){
1424 sqlite3_vtab *pNew;
drh505ad2c2015-08-21 17:33:11 +00001425 int rc;
drhcb6c6c62015-08-19 22:47:17 +00001426
1427/* Column numbers */
drh4af352d2015-08-21 20:02:48 +00001428#define JEACH_KEY 0
1429#define JEACH_VALUE 1
1430#define JEACH_TYPE 2
1431#define JEACH_ATOM 3
1432#define JEACH_ID 4
1433#define JEACH_PARENT 5
1434#define JEACH_FULLKEY 6
1435#define JEACH_JSON 7
1436#define JEACH_PATH 8
drhcb6c6c62015-08-19 22:47:17 +00001437
drh6fd5c1e2015-08-21 20:37:12 +00001438 UNUSED_PARAM(pzErr);
1439 UNUSED_PARAM(argv);
1440 UNUSED_PARAM(argc);
1441 UNUSED_PARAM(pAux);
drh505ad2c2015-08-21 17:33:11 +00001442 rc = sqlite3_declare_vtab(db,
drh4af352d2015-08-21 20:02:48 +00001443 "CREATE TABLE x(key,value,type,atom,id,parent,fullkey,"
1444 "json HIDDEN,path HIDDEN)");
drh505ad2c2015-08-21 17:33:11 +00001445 if( rc==SQLITE_OK ){
1446 pNew = *ppVtab = sqlite3_malloc( sizeof(*pNew) );
1447 if( pNew==0 ) return SQLITE_NOMEM;
1448 memset(pNew, 0, sizeof(*pNew));
1449 }
1450 return rc;
drhcb6c6c62015-08-19 22:47:17 +00001451}
1452
1453/* destructor for json_each virtual table */
1454static int jsonEachDisconnect(sqlite3_vtab *pVtab){
1455 sqlite3_free(pVtab);
1456 return SQLITE_OK;
1457}
1458
drh505ad2c2015-08-21 17:33:11 +00001459/* constructor for a JsonEachCursor object for json_each(). */
1460static int jsonEachOpenEach(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
drhcb6c6c62015-08-19 22:47:17 +00001461 JsonEachCursor *pCur;
drh6fd5c1e2015-08-21 20:37:12 +00001462
1463 UNUSED_PARAM(p);
drhcb6c6c62015-08-19 22:47:17 +00001464 pCur = sqlite3_malloc( sizeof(*pCur) );
1465 if( pCur==0 ) return SQLITE_NOMEM;
1466 memset(pCur, 0, sizeof(*pCur));
1467 *ppCursor = &pCur->base;
1468 return SQLITE_OK;
1469}
1470
drh505ad2c2015-08-21 17:33:11 +00001471/* constructor for a JsonEachCursor object for json_tree(). */
1472static int jsonEachOpenTree(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
1473 int rc = jsonEachOpenEach(p, ppCursor);
1474 if( rc==SQLITE_OK ){
1475 JsonEachCursor *pCur = (JsonEachCursor*)*ppCursor;
1476 pCur->bRecursive = 1;
1477 }
1478 return rc;
1479}
1480
drhcb6c6c62015-08-19 22:47:17 +00001481/* Reset a JsonEachCursor back to its original state. Free any memory
1482** held. */
1483static void jsonEachCursorReset(JsonEachCursor *p){
1484 sqlite3_free(p->zJson);
1485 sqlite3_free(p->zPath);
drh505ad2c2015-08-21 17:33:11 +00001486 jsonParseReset(&p->sParse);
drhcb6c6c62015-08-19 22:47:17 +00001487 p->iRowid = 0;
1488 p->i = 0;
1489 p->iEnd = 0;
1490 p->eType = 0;
drhcb6c6c62015-08-19 22:47:17 +00001491 p->zJson = 0;
1492 p->zPath = 0;
1493}
1494
1495/* Destructor for a jsonEachCursor object */
1496static int jsonEachClose(sqlite3_vtab_cursor *cur){
1497 JsonEachCursor *p = (JsonEachCursor*)cur;
1498 jsonEachCursorReset(p);
1499 sqlite3_free(cur);
1500 return SQLITE_OK;
1501}
1502
1503/* Return TRUE if the jsonEachCursor object has been advanced off the end
1504** of the JSON object */
1505static int jsonEachEof(sqlite3_vtab_cursor *cur){
1506 JsonEachCursor *p = (JsonEachCursor*)cur;
1507 return p->i >= p->iEnd;
1508}
1509
drh505ad2c2015-08-21 17:33:11 +00001510/* Advance the cursor to the next element for json_tree() */
drh4af352d2015-08-21 20:02:48 +00001511static int jsonEachNext(sqlite3_vtab_cursor *cur){
drh505ad2c2015-08-21 17:33:11 +00001512 JsonEachCursor *p = (JsonEachCursor*)cur;
drh4af352d2015-08-21 20:02:48 +00001513 if( p->bRecursive ){
1514 if( p->i==0 ){
1515 p->i = 1;
drh4af352d2015-08-21 20:02:48 +00001516 }else{
drh8784eca2015-08-23 02:42:30 +00001517 u32 iUp = p->sParse.aUp[p->i];
1518 JsonNode *pUp = &p->sParse.aNode[iUp];
drh4af352d2015-08-21 20:02:48 +00001519 p->i++;
drh8784eca2015-08-23 02:42:30 +00001520 if( pUp->eType==JSON_OBJECT && (pUp->n + iUp >= p->i) ) p->i++;
drh4af352d2015-08-21 20:02:48 +00001521 }
1522 p->iRowid++;
1523 if( p->i<p->sParse.nNode ){
drh8784eca2015-08-23 02:42:30 +00001524 u32 iUp = p->sParse.aUp[p->i];
1525 JsonNode *pUp = &p->sParse.aNode[iUp];
drh4af352d2015-08-21 20:02:48 +00001526 p->eType = pUp->eType;
drh8784eca2015-08-23 02:42:30 +00001527 if( pUp->eType==JSON_ARRAY ){
1528 if( iUp==p->i-1 ){
1529 pUp->u.iKey = 0;
1530 }else{
1531 pUp->u.iKey++;
1532 }
drh4af352d2015-08-21 20:02:48 +00001533 }
1534 }
drh505ad2c2015-08-21 17:33:11 +00001535 }else{
drh4af352d2015-08-21 20:02:48 +00001536 switch( p->eType ){
1537 case JSON_ARRAY: {
1538 p->i += jsonNodeSize(&p->sParse.aNode[p->i]);
1539 p->iRowid++;
1540 break;
1541 }
1542 case JSON_OBJECT: {
1543 p->i += 1 + jsonNodeSize(&p->sParse.aNode[p->i+1]);
1544 p->iRowid++;
1545 break;
1546 }
1547 default: {
1548 p->i = p->iEnd;
1549 break;
1550 }
drh505ad2c2015-08-21 17:33:11 +00001551 }
1552 }
1553 return SQLITE_OK;
1554}
1555
drh4af352d2015-08-21 20:02:48 +00001556/* Append the name of the path for element i to pStr
1557*/
1558static void jsonEachComputePath(
1559 JsonEachCursor *p, /* The cursor */
1560 JsonString *pStr, /* Write the path here */
1561 u32 i /* Path to this element */
1562){
1563 JsonNode *pNode, *pUp;
1564 u32 iUp;
1565 if( i==0 ){
1566 jsonAppendChar(pStr, '$');
1567 return;
drhcb6c6c62015-08-19 22:47:17 +00001568 }
drh4af352d2015-08-21 20:02:48 +00001569 iUp = p->sParse.aUp[i];
1570 jsonEachComputePath(p, pStr, iUp);
1571 pNode = &p->sParse.aNode[i];
1572 pUp = &p->sParse.aNode[iUp];
1573 if( pUp->eType==JSON_ARRAY ){
1574 jsonPrintf(30, pStr, "[%d]", pUp->u.iKey);
1575 }else{
1576 assert( pUp->eType==JSON_OBJECT );
1577 if( pNode->eType>=JSON_ARRAY ) pNode--;
1578 assert( pNode->eType==JSON_STRING );
1579 jsonPrintf(pNode->n+1, pStr, ".%.*s", pNode->n-2, pNode->u.zJContent+1);
1580 }
drhcb6c6c62015-08-19 22:47:17 +00001581}
1582
1583/* Return the value of a column */
1584static int jsonEachColumn(
1585 sqlite3_vtab_cursor *cur, /* The cursor */
1586 sqlite3_context *ctx, /* First argument to sqlite3_result_...() */
1587 int i /* Which column to return */
1588){
1589 JsonEachCursor *p = (JsonEachCursor*)cur;
drh505ad2c2015-08-21 17:33:11 +00001590 JsonNode *pThis = &p->sParse.aNode[p->i];
drhcb6c6c62015-08-19 22:47:17 +00001591 switch( i ){
1592 case JEACH_KEY: {
drh8784eca2015-08-23 02:42:30 +00001593 if( p->i==0 ) break;
drhcb6c6c62015-08-19 22:47:17 +00001594 if( p->eType==JSON_OBJECT ){
drh505ad2c2015-08-21 17:33:11 +00001595 jsonReturn(pThis, ctx, 0);
1596 }else if( p->eType==JSON_ARRAY ){
1597 u32 iKey;
1598 if( p->bRecursive ){
1599 if( p->iRowid==0 ) break;
drh8784eca2015-08-23 02:42:30 +00001600 iKey = p->sParse.aNode[p->sParse.aUp[p->i]].u.iKey;
drh505ad2c2015-08-21 17:33:11 +00001601 }else{
1602 iKey = p->iRowid;
1603 }
drh6fd5c1e2015-08-21 20:37:12 +00001604 sqlite3_result_int64(ctx, (sqlite3_int64)iKey);
drhcb6c6c62015-08-19 22:47:17 +00001605 }
1606 break;
1607 }
1608 case JEACH_VALUE: {
drh8784eca2015-08-23 02:42:30 +00001609 if( p->eType==JSON_OBJECT && p->i>0 ) pThis++;
drh505ad2c2015-08-21 17:33:11 +00001610 jsonReturn(pThis, ctx, 0);
1611 break;
1612 }
1613 case JEACH_TYPE: {
drh442a7c62015-08-24 02:32:04 +00001614 if( p->eType==JSON_OBJECT && p->i>0 ) pThis++;
drh505ad2c2015-08-21 17:33:11 +00001615 sqlite3_result_text(ctx, jsonType[pThis->eType], -1, SQLITE_STATIC);
1616 break;
1617 }
1618 case JEACH_ATOM: {
drh442a7c62015-08-24 02:32:04 +00001619 if( p->eType==JSON_OBJECT && p->i>0 ) pThis++;
drh505ad2c2015-08-21 17:33:11 +00001620 if( pThis->eType>=JSON_ARRAY ) break;
1621 jsonReturn(pThis, ctx, 0);
1622 break;
1623 }
1624 case JEACH_ID: {
drh6fd5c1e2015-08-21 20:37:12 +00001625 sqlite3_result_int64(ctx, (sqlite3_int64)p->i + (p->eType==JSON_OBJECT));
drh505ad2c2015-08-21 17:33:11 +00001626 break;
1627 }
1628 case JEACH_PARENT: {
1629 if( p->i>0 && p->bRecursive ){
drh6fd5c1e2015-08-21 20:37:12 +00001630 sqlite3_result_int64(ctx, (sqlite3_int64)p->sParse.aUp[p->i]);
drhcb6c6c62015-08-19 22:47:17 +00001631 }
1632 break;
1633 }
drh4af352d2015-08-21 20:02:48 +00001634 case JEACH_FULLKEY: {
1635 JsonString x;
1636 jsonInit(&x, ctx);
1637 if( p->bRecursive ){
1638 jsonEachComputePath(p, &x, p->i);
1639 }else{
1640 if( p->zPath ){
1641 jsonAppendRaw(&x, p->zPath, (int)strlen(p->zPath));
1642 }else{
1643 jsonAppendChar(&x, '$');
1644 }
1645 if( p->eType==JSON_ARRAY ){
1646 jsonPrintf(30, &x, "[%d]", p->iRowid);
1647 }else{
1648 jsonPrintf(pThis->n, &x, ".%.*s", pThis->n-2, pThis->u.zJContent+1);
1649 }
1650 }
1651 jsonResult(&x);
1652 break;
1653 }
drhcb6c6c62015-08-19 22:47:17 +00001654 case JEACH_PATH: {
1655 const char *zPath = p->zPath;
drh4af352d2015-08-21 20:02:48 +00001656 if( zPath==0 ){
1657 if( p->bRecursive ){
1658 JsonString x;
1659 jsonInit(&x, ctx);
1660 jsonEachComputePath(p, &x, p->sParse.aUp[p->i]);
1661 jsonResult(&x);
1662 break;
1663 }
1664 zPath = "$";
1665 }
drhcb6c6c62015-08-19 22:47:17 +00001666 sqlite3_result_text(ctx, zPath, -1, SQLITE_STATIC);
1667 break;
1668 }
1669 default: {
drh505ad2c2015-08-21 17:33:11 +00001670 assert( i==JEACH_JSON );
drhcb6c6c62015-08-19 22:47:17 +00001671 sqlite3_result_text(ctx, p->sParse.zJson, -1, SQLITE_STATIC);
1672 break;
1673 }
1674 }
1675 return SQLITE_OK;
1676}
1677
1678/* Return the current rowid value */
1679static int jsonEachRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){
1680 JsonEachCursor *p = (JsonEachCursor*)cur;
1681 *pRowid = p->iRowid;
1682 return SQLITE_OK;
1683}
1684
1685/* The query strategy is to look for an equality constraint on the json
1686** column. Without such a constraint, the table cannot operate. idxNum is
1687** 1 if the constraint is found, 3 if the constraint and zPath are found,
1688** and 0 otherwise.
1689*/
1690static int jsonEachBestIndex(
1691 sqlite3_vtab *tab,
1692 sqlite3_index_info *pIdxInfo
1693){
1694 int i;
1695 int jsonIdx = -1;
1696 int pathIdx = -1;
1697 const struct sqlite3_index_constraint *pConstraint;
drh6fd5c1e2015-08-21 20:37:12 +00001698
1699 UNUSED_PARAM(tab);
drhcb6c6c62015-08-19 22:47:17 +00001700 pConstraint = pIdxInfo->aConstraint;
1701 for(i=0; i<pIdxInfo->nConstraint; i++, pConstraint++){
1702 if( pConstraint->usable==0 ) continue;
1703 if( pConstraint->op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue;
1704 switch( pConstraint->iColumn ){
1705 case JEACH_JSON: jsonIdx = i; break;
1706 case JEACH_PATH: pathIdx = i; break;
1707 default: /* no-op */ break;
1708 }
1709 }
1710 if( jsonIdx<0 ){
1711 pIdxInfo->idxNum = 0;
drh505ad2c2015-08-21 17:33:11 +00001712 pIdxInfo->estimatedCost = 1e99;
drhcb6c6c62015-08-19 22:47:17 +00001713 }else{
drh505ad2c2015-08-21 17:33:11 +00001714 pIdxInfo->estimatedCost = 1.0;
drhcb6c6c62015-08-19 22:47:17 +00001715 pIdxInfo->aConstraintUsage[jsonIdx].argvIndex = 1;
1716 pIdxInfo->aConstraintUsage[jsonIdx].omit = 1;
1717 if( pathIdx<0 ){
1718 pIdxInfo->idxNum = 1;
1719 }else{
1720 pIdxInfo->aConstraintUsage[pathIdx].argvIndex = 2;
1721 pIdxInfo->aConstraintUsage[pathIdx].omit = 1;
1722 pIdxInfo->idxNum = 3;
1723 }
1724 }
1725 return SQLITE_OK;
1726}
1727
1728/* Start a search on a new JSON string */
1729static int jsonEachFilter(
1730 sqlite3_vtab_cursor *cur,
1731 int idxNum, const char *idxStr,
1732 int argc, sqlite3_value **argv
1733){
1734 JsonEachCursor *p = (JsonEachCursor*)cur;
1735 const char *z;
1736 const char *zPath;
1737 sqlite3_int64 n;
1738
drh6fd5c1e2015-08-21 20:37:12 +00001739 UNUSED_PARAM(idxStr);
1740 UNUSED_PARAM(argc);
drhcb6c6c62015-08-19 22:47:17 +00001741 jsonEachCursorReset(p);
1742 if( idxNum==0 ) return SQLITE_OK;
1743 z = (const char*)sqlite3_value_text(argv[0]);
1744 if( z==0 ) return SQLITE_OK;
1745 if( idxNum&2 ){
1746 zPath = (const char*)sqlite3_value_text(argv[1]);
drha7714022015-08-29 00:54:49 +00001747 if( zPath==0 ) return SQLITE_OK;
1748 if( zPath[0]!='$' ){
1749 sqlite3_free(cur->pVtab->zErrMsg);
1750 cur->pVtab->zErrMsg = jsonPathSyntaxError(zPath);
1751 return cur->pVtab->zErrMsg ? SQLITE_ERROR : SQLITE_NOMEM;
1752 }
drhcb6c6c62015-08-19 22:47:17 +00001753 }
1754 n = sqlite3_value_bytes(argv[0]);
drh6fd5c1e2015-08-21 20:37:12 +00001755 p->zJson = sqlite3_malloc64( n+1 );
drhcb6c6c62015-08-19 22:47:17 +00001756 if( p->zJson==0 ) return SQLITE_NOMEM;
drh6fd5c1e2015-08-21 20:37:12 +00001757 memcpy(p->zJson, z, (size_t)n+1);
drha7714022015-08-29 00:54:49 +00001758 if( jsonParse(&p->sParse, 0, p->zJson) ){
1759 int rc = SQLITE_NOMEM;
1760 if( p->sParse.oom==0 ){
1761 sqlite3_free(cur->pVtab->zErrMsg);
1762 cur->pVtab->zErrMsg = sqlite3_mprintf("malformed JSON");
1763 if( cur->pVtab->zErrMsg ) rc = SQLITE_ERROR;
1764 }
drhcb6c6c62015-08-19 22:47:17 +00001765 jsonEachCursorReset(p);
drha7714022015-08-29 00:54:49 +00001766 return rc;
1767 }else if( p->bRecursive && jsonParseFindParents(&p->sParse) ){
1768 jsonEachCursorReset(p);
1769 return SQLITE_NOMEM;
drhcb6c6c62015-08-19 22:47:17 +00001770 }else{
1771 JsonNode *pNode;
1772 if( idxNum==3 ){
drha7714022015-08-29 00:54:49 +00001773 const char *zErr = 0;
drh4af352d2015-08-21 20:02:48 +00001774 p->bRecursive = 0;
drhcb6c6c62015-08-19 22:47:17 +00001775 n = sqlite3_value_bytes(argv[1]);
drh6fd5c1e2015-08-21 20:37:12 +00001776 p->zPath = sqlite3_malloc64( n+1 );
drhcb6c6c62015-08-19 22:47:17 +00001777 if( p->zPath==0 ) return SQLITE_NOMEM;
drh6fd5c1e2015-08-21 20:37:12 +00001778 memcpy(p->zPath, zPath, (size_t)n+1);
drha7714022015-08-29 00:54:49 +00001779 pNode = jsonLookupStep(&p->sParse, 0, p->zPath+1, 0, &zErr);
1780 if( p->sParse.nErr ){
1781 sqlite3_free(cur->pVtab->zErrMsg);
1782 cur->pVtab->zErrMsg = jsonPathSyntaxError(zErr);
drhcb6c6c62015-08-19 22:47:17 +00001783 jsonEachCursorReset(p);
drha7714022015-08-29 00:54:49 +00001784 return cur->pVtab->zErrMsg ? SQLITE_ERROR : SQLITE_NOMEM;
1785 }else if( pNode==0 ){
drhcb6c6c62015-08-19 22:47:17 +00001786 return SQLITE_OK;
1787 }
1788 }else{
1789 pNode = p->sParse.aNode;
1790 }
1791 p->i = (int)(pNode - p->sParse.aNode);
1792 p->eType = pNode->eType;
1793 if( p->eType>=JSON_ARRAY ){
drh8784eca2015-08-23 02:42:30 +00001794 pNode->u.iKey = 0;
drhc3722b22015-08-23 20:44:59 +00001795 p->iEnd = p->i + pNode->n + 1;
drh8784eca2015-08-23 02:42:30 +00001796 if( !p->bRecursive ) p->i++;
drhcb6c6c62015-08-19 22:47:17 +00001797 }else{
1798 p->iEnd = p->i+1;
1799 }
1800 }
drhbc8f0922015-08-22 19:39:04 +00001801 return p->sParse.oom ? SQLITE_NOMEM : SQLITE_OK;
drhcb6c6c62015-08-19 22:47:17 +00001802}
1803
1804/* The methods of the json_each virtual table */
1805static sqlite3_module jsonEachModule = {
1806 0, /* iVersion */
1807 0, /* xCreate */
1808 jsonEachConnect, /* xConnect */
1809 jsonEachBestIndex, /* xBestIndex */
1810 jsonEachDisconnect, /* xDisconnect */
1811 0, /* xDestroy */
drh505ad2c2015-08-21 17:33:11 +00001812 jsonEachOpenEach, /* xOpen - open a cursor */
drhcb6c6c62015-08-19 22:47:17 +00001813 jsonEachClose, /* xClose - close a cursor */
1814 jsonEachFilter, /* xFilter - configure scan constraints */
drh4af352d2015-08-21 20:02:48 +00001815 jsonEachNext, /* xNext - advance a cursor */
drhcb6c6c62015-08-19 22:47:17 +00001816 jsonEachEof, /* xEof - check for end of scan */
1817 jsonEachColumn, /* xColumn - read data */
1818 jsonEachRowid, /* xRowid - read data */
1819 0, /* xUpdate */
1820 0, /* xBegin */
1821 0, /* xSync */
1822 0, /* xCommit */
1823 0, /* xRollback */
1824 0, /* xFindMethod */
1825 0, /* xRename */
drh6fd5c1e2015-08-21 20:37:12 +00001826 0, /* xSavepoint */
1827 0, /* xRelease */
1828 0 /* xRollbackTo */
drhcb6c6c62015-08-19 22:47:17 +00001829};
1830
drh505ad2c2015-08-21 17:33:11 +00001831/* The methods of the json_tree virtual table. */
1832static sqlite3_module jsonTreeModule = {
1833 0, /* iVersion */
1834 0, /* xCreate */
1835 jsonEachConnect, /* xConnect */
1836 jsonEachBestIndex, /* xBestIndex */
1837 jsonEachDisconnect, /* xDisconnect */
1838 0, /* xDestroy */
1839 jsonEachOpenTree, /* xOpen - open a cursor */
1840 jsonEachClose, /* xClose - close a cursor */
1841 jsonEachFilter, /* xFilter - configure scan constraints */
drh4af352d2015-08-21 20:02:48 +00001842 jsonEachNext, /* xNext - advance a cursor */
drh505ad2c2015-08-21 17:33:11 +00001843 jsonEachEof, /* xEof - check for end of scan */
1844 jsonEachColumn, /* xColumn - read data */
1845 jsonEachRowid, /* xRowid - read data */
1846 0, /* xUpdate */
1847 0, /* xBegin */
1848 0, /* xSync */
1849 0, /* xCommit */
1850 0, /* xRollback */
1851 0, /* xFindMethod */
1852 0, /* xRename */
drh6fd5c1e2015-08-21 20:37:12 +00001853 0, /* xSavepoint */
1854 0, /* xRelease */
1855 0 /* xRollbackTo */
drh505ad2c2015-08-21 17:33:11 +00001856};
1857
1858/****************************************************************************
1859** The following routine is the only publically visible identifier in this
1860** file. Call the following routine in order to register the various SQL
1861** functions and the virtual table implemented by this file.
1862****************************************************************************/
drhcb6c6c62015-08-19 22:47:17 +00001863
drh5fa5c102015-08-12 16:49:40 +00001864#ifdef _WIN32
1865__declspec(dllexport)
1866#endif
1867int sqlite3_json_init(
1868 sqlite3 *db,
1869 char **pzErrMsg,
1870 const sqlite3_api_routines *pApi
1871){
1872 int rc = SQLITE_OK;
drh6fd5c1e2015-08-21 20:37:12 +00001873 unsigned int i;
drh5fa5c102015-08-12 16:49:40 +00001874 static const struct {
1875 const char *zName;
1876 int nArg;
drh52216ad2015-08-18 02:28:03 +00001877 int flag;
drh5fa5c102015-08-12 16:49:40 +00001878 void (*xFunc)(sqlite3_context*,int,sqlite3_value**);
1879 } aFunc[] = {
drh52216ad2015-08-18 02:28:03 +00001880 { "json_array", -1, 0, jsonArrayFunc },
1881 { "json_array_length", 1, 0, jsonArrayLengthFunc },
1882 { "json_array_length", 2, 0, jsonArrayLengthFunc },
1883 { "json_extract", 2, 0, jsonExtractFunc },
1884 { "json_insert", -1, 0, jsonSetFunc },
1885 { "json_object", -1, 0, jsonObjectFunc },
1886 { "json_remove", -1, 0, jsonRemoveFunc },
1887 { "json_replace", -1, 0, jsonReplaceFunc },
1888 { "json_set", -1, 1, jsonSetFunc },
1889 { "json_type", 1, 0, jsonTypeFunc },
1890 { "json_type", 2, 0, jsonTypeFunc },
drhbc8f0922015-08-22 19:39:04 +00001891 { "json_valid", 1, 0, jsonValidFunc },
drh987eb1f2015-08-17 15:17:37 +00001892
drh301eecc2015-08-17 20:14:19 +00001893#if SQLITE_DEBUG
drh987eb1f2015-08-17 15:17:37 +00001894 /* DEBUG and TESTING functions */
drh52216ad2015-08-18 02:28:03 +00001895 { "json_parse", 1, 0, jsonParseFunc },
1896 { "json_test1", 1, 0, jsonTest1Func },
1897 { "json_nodecount", 1, 0, jsonNodeCountFunc },
drh301eecc2015-08-17 20:14:19 +00001898#endif
drh5fa5c102015-08-12 16:49:40 +00001899 };
drh505ad2c2015-08-21 17:33:11 +00001900 static const struct {
1901 const char *zName;
1902 sqlite3_module *pModule;
1903 } aMod[] = {
1904 { "json_each", &jsonEachModule },
1905 { "json_tree", &jsonTreeModule },
1906 };
drh5fa5c102015-08-12 16:49:40 +00001907 SQLITE_EXTENSION_INIT2(pApi);
1908 (void)pzErrMsg; /* Unused parameter */
1909 for(i=0; i<sizeof(aFunc)/sizeof(aFunc[0]) && rc==SQLITE_OK; i++){
1910 rc = sqlite3_create_function(db, aFunc[i].zName, aFunc[i].nArg,
drh52216ad2015-08-18 02:28:03 +00001911 SQLITE_UTF8 | SQLITE_DETERMINISTIC,
1912 (void*)&aFunc[i].flag,
drh5fa5c102015-08-12 16:49:40 +00001913 aFunc[i].xFunc, 0, 0);
1914 }
drh505ad2c2015-08-21 17:33:11 +00001915 for(i=0; i<sizeof(aMod)/sizeof(aMod[0]) && rc==SQLITE_OK; i++){
1916 rc = sqlite3_create_module(db, aMod[i].zName, aMod[i].pModule, 0);
drhcb6c6c62015-08-19 22:47:17 +00001917 }
drh5fa5c102015-08-12 16:49:40 +00001918 return rc;
1919}