blob: a8b9ed539d506043c76aab17cecb5adcd4fdc2c1 [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 */
111};
112
drh505ad2c2015-08-21 17:33:11 +0000113/**************************************************************************
114** Utility routines for dealing with JsonString objects
115**************************************************************************/
drh301eecc2015-08-17 20:14:19 +0000116
drh505ad2c2015-08-21 17:33:11 +0000117/* Set the JsonString object to an empty string
drh5fa5c102015-08-12 16:49:40 +0000118*/
drh505ad2c2015-08-21 17:33:11 +0000119static void jsonZero(JsonString *p){
drh5fa5c102015-08-12 16:49:40 +0000120 p->zBuf = p->zSpace;
121 p->nAlloc = sizeof(p->zSpace);
122 p->nUsed = 0;
123 p->bStatic = 1;
124}
125
drh505ad2c2015-08-21 17:33:11 +0000126/* Initialize the JsonString object
drh5fa5c102015-08-12 16:49:40 +0000127*/
drh505ad2c2015-08-21 17:33:11 +0000128static void jsonInit(JsonString *p, sqlite3_context *pCtx){
drh5fa5c102015-08-12 16:49:40 +0000129 p->pCtx = pCtx;
drhd0960592015-08-17 21:22:32 +0000130 p->bErr = 0;
drh5fa5c102015-08-12 16:49:40 +0000131 jsonZero(p);
132}
133
134
drh505ad2c2015-08-21 17:33:11 +0000135/* Free all allocated memory and reset the JsonString object back to its
drh5fa5c102015-08-12 16:49:40 +0000136** initial state.
137*/
drh505ad2c2015-08-21 17:33:11 +0000138static void jsonReset(JsonString *p){
drh5fa5c102015-08-12 16:49:40 +0000139 if( !p->bStatic ) sqlite3_free(p->zBuf);
140 jsonZero(p);
141}
142
143
144/* Report an out-of-memory (OOM) condition
145*/
drh505ad2c2015-08-21 17:33:11 +0000146static void jsonOom(JsonString *p){
drhd0960592015-08-17 21:22:32 +0000147 if( !p->bErr ){
148 p->bErr = 1;
149 sqlite3_result_error_nomem(p->pCtx);
150 jsonReset(p);
151 }
drh5fa5c102015-08-12 16:49:40 +0000152}
153
154/* Enlarge pJson->zBuf so that it can hold at least N more bytes.
155** Return zero on success. Return non-zero on an OOM error
156*/
drh505ad2c2015-08-21 17:33:11 +0000157static int jsonGrow(JsonString *p, u32 N){
drh301eecc2015-08-17 20:14:19 +0000158 u64 nTotal = N<p->nAlloc ? p->nAlloc*2 : p->nAlloc+N+10;
drh5fa5c102015-08-12 16:49:40 +0000159 char *zNew;
160 if( p->bStatic ){
drhd0960592015-08-17 21:22:32 +0000161 if( p->bErr ) return 1;
drh5fa5c102015-08-12 16:49:40 +0000162 zNew = sqlite3_malloc64(nTotal);
163 if( zNew==0 ){
164 jsonOom(p);
165 return SQLITE_NOMEM;
166 }
drh6fd5c1e2015-08-21 20:37:12 +0000167 memcpy(zNew, p->zBuf, (size_t)p->nUsed);
drh5fa5c102015-08-12 16:49:40 +0000168 p->zBuf = zNew;
169 p->bStatic = 0;
170 }else{
171 zNew = sqlite3_realloc64(p->zBuf, nTotal);
172 if( zNew==0 ){
173 jsonOom(p);
174 return SQLITE_NOMEM;
175 }
176 p->zBuf = zNew;
177 }
178 p->nAlloc = nTotal;
179 return SQLITE_OK;
180}
181
drh505ad2c2015-08-21 17:33:11 +0000182/* Append N bytes from zIn onto the end of the JsonString string.
drh5fa5c102015-08-12 16:49:40 +0000183*/
drh505ad2c2015-08-21 17:33:11 +0000184static void jsonAppendRaw(JsonString *p, const char *zIn, u32 N){
drh5fa5c102015-08-12 16:49:40 +0000185 if( (N+p->nUsed >= p->nAlloc) && jsonGrow(p,N)!=0 ) return;
186 memcpy(p->zBuf+p->nUsed, zIn, N);
187 p->nUsed += N;
188}
189
drh4af352d2015-08-21 20:02:48 +0000190/* Append formatted text (not to exceed N bytes) to the JsonString.
191*/
192static void jsonPrintf(int N, JsonString *p, const char *zFormat, ...){
193 va_list ap;
194 if( (p->nUsed + N >= p->nAlloc) && jsonGrow(p, N) ) return;
195 va_start(ap, zFormat);
196 sqlite3_vsnprintf(N, p->zBuf+p->nUsed, zFormat, ap);
197 va_end(ap);
198 p->nUsed += (int)strlen(p->zBuf+p->nUsed);
199}
200
drh5634cc02015-08-17 11:28:03 +0000201/* Append a single character
202*/
drh505ad2c2015-08-21 17:33:11 +0000203static void jsonAppendChar(JsonString *p, char c){
drh5634cc02015-08-17 11:28:03 +0000204 if( p->nUsed>=p->nAlloc && jsonGrow(p,1)!=0 ) return;
205 p->zBuf[p->nUsed++] = c;
206}
207
drh301eecc2015-08-17 20:14:19 +0000208/* Append a comma separator to the output buffer, if the previous
209** character is not '[' or '{'.
210*/
drh505ad2c2015-08-21 17:33:11 +0000211static void jsonAppendSeparator(JsonString *p){
drh301eecc2015-08-17 20:14:19 +0000212 char c;
213 if( p->nUsed==0 ) return;
214 c = p->zBuf[p->nUsed-1];
215 if( c!='[' && c!='{' ) jsonAppendChar(p, ',');
216}
217
drh505ad2c2015-08-21 17:33:11 +0000218/* Append the N-byte string in zIn to the end of the JsonString string
drh5fa5c102015-08-12 16:49:40 +0000219** under construction. Enclose the string in "..." and escape
220** any double-quotes or backslash characters contained within the
221** string.
222*/
drh505ad2c2015-08-21 17:33:11 +0000223static void jsonAppendString(JsonString *p, const char *zIn, u32 N){
drh5fa5c102015-08-12 16:49:40 +0000224 u32 i;
225 if( (N+p->nUsed+2 >= p->nAlloc) && jsonGrow(p,N+2)!=0 ) return;
226 p->zBuf[p->nUsed++] = '"';
227 for(i=0; i<N; i++){
228 char c = zIn[i];
229 if( c=='"' || c=='\\' ){
230 if( (p->nUsed+N+1-i > p->nAlloc) && jsonGrow(p,N+1-i)!=0 ) return;
231 p->zBuf[p->nUsed++] = '\\';
232 }
233 p->zBuf[p->nUsed++] = c;
234 }
235 p->zBuf[p->nUsed++] = '"';
236}
237
drhd0960592015-08-17 21:22:32 +0000238/*
239** Append a function parameter value to the JSON string under
240** construction.
241*/
242static void jsonAppendValue(
drh505ad2c2015-08-21 17:33:11 +0000243 JsonString *p, /* Append to this JSON string */
drhecb5fed2015-08-28 03:33:50 +0000244 sqlite3_value *pValue, /* Value to append */
245 u8 textIsJson /* Try to treat text values as JSON */
drhd0960592015-08-17 21:22:32 +0000246){
247 switch( sqlite3_value_type(pValue) ){
248 case SQLITE_NULL: {
249 jsonAppendRaw(p, "null", 4);
250 break;
251 }
252 case SQLITE_INTEGER:
253 case SQLITE_FLOAT: {
254 const char *z = (const char*)sqlite3_value_text(pValue);
255 u32 n = (u32)sqlite3_value_bytes(pValue);
256 jsonAppendRaw(p, z, n);
257 break;
258 }
259 case SQLITE_TEXT: {
260 const char *z = (const char*)sqlite3_value_text(pValue);
261 u32 n = (u32)sqlite3_value_bytes(pValue);
drhecb5fed2015-08-28 03:33:50 +0000262 if( textIsJson ){
263 jsonAppendRaw(p, z, n);
264 }else{
265 jsonAppendString(p, z, n);
266 }
drhd0960592015-08-17 21:22:32 +0000267 break;
268 }
269 default: {
270 if( p->bErr==0 ){
271 sqlite3_result_error(p->pCtx, "JSON cannot hold BLOB values", -1);
272 p->bErr = 1;
273 jsonReset(p);
274 }
275 break;
276 }
277 }
278}
279
280
drhbd0621b2015-08-13 13:54:59 +0000281/* Make the JSON in p the result of the SQL function.
drh5fa5c102015-08-12 16:49:40 +0000282*/
drh505ad2c2015-08-21 17:33:11 +0000283static void jsonResult(JsonString *p){
drhd0960592015-08-17 21:22:32 +0000284 if( p->bErr==0 ){
drh5fa5c102015-08-12 16:49:40 +0000285 sqlite3_result_text64(p->pCtx, p->zBuf, p->nUsed,
286 p->bStatic ? SQLITE_TRANSIENT : sqlite3_free,
287 SQLITE_UTF8);
288 jsonZero(p);
289 }
290 assert( p->bStatic );
291}
292
drh505ad2c2015-08-21 17:33:11 +0000293/**************************************************************************
294** Utility routines for dealing with JsonNode and JsonParse objects
295**************************************************************************/
296
297/*
298** Return the number of consecutive JsonNode slots need to represent
299** the parsed JSON at pNode. The minimum answer is 1. For ARRAY and
300** OBJECT types, the number might be larger.
301**
302** Appended elements are not counted. The value returned is the number
303** by which the JsonNode counter should increment in order to go to the
304** next peer value.
305*/
306static u32 jsonNodeSize(JsonNode *pNode){
307 return pNode->eType>=JSON_ARRAY ? pNode->n+1 : 1;
308}
309
310/*
311** Reclaim all memory allocated by a JsonParse object. But do not
312** delete the JsonParse object itself.
313*/
314static void jsonParseReset(JsonParse *pParse){
315 sqlite3_free(pParse->aNode);
316 pParse->aNode = 0;
317 pParse->nNode = 0;
318 pParse->nAlloc = 0;
319 sqlite3_free(pParse->aUp);
320 pParse->aUp = 0;
321}
322
drh5634cc02015-08-17 11:28:03 +0000323/*
324** Convert the JsonNode pNode into a pure JSON string and
325** append to pOut. Subsubstructure is also included. Return
326** the number of JsonNode objects that are encoded.
drhbd0621b2015-08-13 13:54:59 +0000327*/
drh52216ad2015-08-18 02:28:03 +0000328static void jsonRenderNode(
drhd0960592015-08-17 21:22:32 +0000329 JsonNode *pNode, /* The node to render */
drh505ad2c2015-08-21 17:33:11 +0000330 JsonString *pOut, /* Write JSON here */
drhd0960592015-08-17 21:22:32 +0000331 sqlite3_value **aReplace /* Replacement values */
332){
drh5634cc02015-08-17 11:28:03 +0000333 switch( pNode->eType ){
334 case JSON_NULL: {
335 jsonAppendRaw(pOut, "null", 4);
336 break;
337 }
338 case JSON_TRUE: {
339 jsonAppendRaw(pOut, "true", 4);
340 break;
341 }
342 case JSON_FALSE: {
343 jsonAppendRaw(pOut, "false", 5);
344 break;
345 }
346 case JSON_STRING: {
drh301eecc2015-08-17 20:14:19 +0000347 if( pNode->jnFlags & JNODE_RAW ){
drh52216ad2015-08-18 02:28:03 +0000348 jsonAppendString(pOut, pNode->u.zJContent, pNode->n);
drh5634cc02015-08-17 11:28:03 +0000349 break;
350 }
351 /* Fall through into the next case */
352 }
353 case JSON_REAL:
354 case JSON_INT: {
drh52216ad2015-08-18 02:28:03 +0000355 jsonAppendRaw(pOut, pNode->u.zJContent, pNode->n);
drh5634cc02015-08-17 11:28:03 +0000356 break;
357 }
358 case JSON_ARRAY: {
drh52216ad2015-08-18 02:28:03 +0000359 u32 j = 1;
drh5634cc02015-08-17 11:28:03 +0000360 jsonAppendChar(pOut, '[');
drh52216ad2015-08-18 02:28:03 +0000361 for(;;){
362 while( j<=pNode->n ){
363 if( pNode[j].jnFlags & (JNODE_REMOVE|JNODE_REPLACE) ){
364 if( pNode[j].jnFlags & JNODE_REPLACE ){
365 jsonAppendSeparator(pOut);
drhecb5fed2015-08-28 03:33:50 +0000366 jsonAppendValue(pOut, aReplace[pNode[j].iVal],
367 (pNode[j].jnFlags & JNODE_JSON)!=0);
drh52216ad2015-08-18 02:28:03 +0000368 }
369 }else{
drhd0960592015-08-17 21:22:32 +0000370 jsonAppendSeparator(pOut);
drh52216ad2015-08-18 02:28:03 +0000371 jsonRenderNode(&pNode[j], pOut, aReplace);
drhd0960592015-08-17 21:22:32 +0000372 }
drh505ad2c2015-08-21 17:33:11 +0000373 j += jsonNodeSize(&pNode[j]);
drh301eecc2015-08-17 20:14:19 +0000374 }
drh52216ad2015-08-18 02:28:03 +0000375 if( (pNode->jnFlags & JNODE_APPEND)==0 ) break;
376 pNode = &pNode[pNode->u.iAppend];
377 j = 1;
drh5634cc02015-08-17 11:28:03 +0000378 }
379 jsonAppendChar(pOut, ']');
380 break;
381 }
382 case JSON_OBJECT: {
drh52216ad2015-08-18 02:28:03 +0000383 u32 j = 1;
drh5634cc02015-08-17 11:28:03 +0000384 jsonAppendChar(pOut, '{');
drh52216ad2015-08-18 02:28:03 +0000385 for(;;){
386 while( j<=pNode->n ){
387 if( (pNode[j+1].jnFlags & JNODE_REMOVE)==0 ){
388 jsonAppendSeparator(pOut);
389 jsonRenderNode(&pNode[j], pOut, aReplace);
390 jsonAppendChar(pOut, ':');
391 if( pNode[j+1].jnFlags & JNODE_REPLACE ){
drhecb5fed2015-08-28 03:33:50 +0000392 jsonAppendValue(pOut, aReplace[pNode[j+1].iVal],
393 (pNode[j+1].jnFlags & JNODE_JSON)!=0);
drh52216ad2015-08-18 02:28:03 +0000394 }else{
395 jsonRenderNode(&pNode[j+1], pOut, aReplace);
396 }
drhd0960592015-08-17 21:22:32 +0000397 }
drh505ad2c2015-08-21 17:33:11 +0000398 j += 1 + jsonNodeSize(&pNode[j+1]);
drh301eecc2015-08-17 20:14:19 +0000399 }
drh52216ad2015-08-18 02:28:03 +0000400 if( (pNode->jnFlags & JNODE_APPEND)==0 ) break;
401 pNode = &pNode[pNode->u.iAppend];
402 j = 1;
drh5634cc02015-08-17 11:28:03 +0000403 }
404 jsonAppendChar(pOut, '}');
405 break;
406 }
drhbd0621b2015-08-13 13:54:59 +0000407 }
drh5634cc02015-08-17 11:28:03 +0000408}
409
410/*
drhf2df7e72015-08-28 20:07:40 +0000411** Return a JsonNode and all its descendents as a JSON string.
412*/
413static void jsonReturnJson(
414 JsonNode *pNode, /* Node to return */
415 sqlite3_context *pCtx, /* Return value for this function */
416 sqlite3_value **aReplace /* Array of replacement values */
417){
418 JsonString s;
419 jsonInit(&s, pCtx);
420 jsonRenderNode(pNode, &s, aReplace);
421 jsonResult(&s);
422}
423
424/*
drh5634cc02015-08-17 11:28:03 +0000425** Make the JsonNode the return value of the function.
426*/
drhd0960592015-08-17 21:22:32 +0000427static void jsonReturn(
428 JsonNode *pNode, /* Node to return */
429 sqlite3_context *pCtx, /* Return value for this function */
430 sqlite3_value **aReplace /* Array of replacement values */
431){
drh5634cc02015-08-17 11:28:03 +0000432 switch( pNode->eType ){
433 case JSON_NULL: {
434 sqlite3_result_null(pCtx);
435 break;
436 }
437 case JSON_TRUE: {
438 sqlite3_result_int(pCtx, 1);
439 break;
440 }
441 case JSON_FALSE: {
442 sqlite3_result_int(pCtx, 0);
443 break;
444 }
drh987eb1f2015-08-17 15:17:37 +0000445 case JSON_REAL: {
drh52216ad2015-08-18 02:28:03 +0000446 double r = strtod(pNode->u.zJContent, 0);
drh987eb1f2015-08-17 15:17:37 +0000447 sqlite3_result_double(pCtx, r);
drh5634cc02015-08-17 11:28:03 +0000448 break;
449 }
drh987eb1f2015-08-17 15:17:37 +0000450 case JSON_INT: {
451 sqlite3_int64 i = 0;
drh52216ad2015-08-18 02:28:03 +0000452 const char *z = pNode->u.zJContent;
drh987eb1f2015-08-17 15:17:37 +0000453 if( z[0]=='-' ){ z++; }
454 while( z[0]>='0' && z[0]<='9' ){ i = i*10 + *(z++) - '0'; }
drh52216ad2015-08-18 02:28:03 +0000455 if( pNode->u.zJContent[0]=='-' ){ i = -i; }
drh987eb1f2015-08-17 15:17:37 +0000456 sqlite3_result_int64(pCtx, i);
457 break;
458 }
drh5634cc02015-08-17 11:28:03 +0000459 case JSON_STRING: {
drh301eecc2015-08-17 20:14:19 +0000460 if( pNode->jnFlags & JNODE_RAW ){
drh52216ad2015-08-18 02:28:03 +0000461 sqlite3_result_text(pCtx, pNode->u.zJContent, pNode->n,
462 SQLITE_TRANSIENT);
drh301eecc2015-08-17 20:14:19 +0000463 }else if( (pNode->jnFlags & JNODE_ESCAPE)==0 ){
drh987eb1f2015-08-17 15:17:37 +0000464 /* JSON formatted without any backslash-escapes */
drh52216ad2015-08-18 02:28:03 +0000465 sqlite3_result_text(pCtx, pNode->u.zJContent+1, pNode->n-2,
drh987eb1f2015-08-17 15:17:37 +0000466 SQLITE_TRANSIENT);
drh5634cc02015-08-17 11:28:03 +0000467 }else{
468 /* Translate JSON formatted string into raw text */
drh987eb1f2015-08-17 15:17:37 +0000469 u32 i;
470 u32 n = pNode->n;
drh52216ad2015-08-18 02:28:03 +0000471 const char *z = pNode->u.zJContent;
drh987eb1f2015-08-17 15:17:37 +0000472 char *zOut;
473 u32 j;
474 zOut = sqlite3_malloc( n+1 );
475 if( zOut==0 ){
476 sqlite3_result_error_nomem(pCtx);
477 break;
478 }
479 for(i=1, j=0; i<n-1; i++){
480 char c = z[i];
drh80d87402015-08-24 12:42:41 +0000481 if( c!='\\' ){
drh987eb1f2015-08-17 15:17:37 +0000482 zOut[j++] = c;
483 }else{
484 c = z[++i];
drh80d87402015-08-24 12:42:41 +0000485 if( c=='u' ){
drh987eb1f2015-08-17 15:17:37 +0000486 u32 v = 0, k;
drh80d87402015-08-24 12:42:41 +0000487 for(k=0; k<4 && i<n-2; i++, k++){
drh8784eca2015-08-23 02:42:30 +0000488 c = z[i+1];
drh987eb1f2015-08-17 15:17:37 +0000489 if( c>='0' && c<='9' ) v = v*16 + c - '0';
490 else if( c>='A' && c<='F' ) v = v*16 + c - 'A' + 10;
491 else if( c>='a' && c<='f' ) v = v*16 + c - 'a' + 10;
492 else break;
drh987eb1f2015-08-17 15:17:37 +0000493 }
drh80d87402015-08-24 12:42:41 +0000494 if( v==0 ) break;
drh987eb1f2015-08-17 15:17:37 +0000495 if( v<=0x7f ){
496 zOut[j++] = v;
497 }else if( v<=0x7ff ){
498 zOut[j++] = 0xc0 | (v>>6);
499 zOut[j++] = 0x80 | (v&0x3f);
drh80d87402015-08-24 12:42:41 +0000500 }else{
drh987eb1f2015-08-17 15:17:37 +0000501 zOut[j++] = 0xe0 | (v>>12);
502 zOut[j++] = 0x80 | ((v>>6)&0x3f);
503 zOut[j++] = 0x80 | (v&0x3f);
drh987eb1f2015-08-17 15:17:37 +0000504 }
505 }else{
506 if( c=='b' ){
507 c = '\b';
508 }else if( c=='f' ){
509 c = '\f';
510 }else if( c=='n' ){
511 c = '\n';
512 }else if( c=='r' ){
513 c = '\r';
514 }else if( c=='t' ){
515 c = '\t';
516 }
517 zOut[j++] = c;
518 }
519 }
520 }
521 zOut[j] = 0;
522 sqlite3_result_text(pCtx, zOut, j, sqlite3_free);
drh5634cc02015-08-17 11:28:03 +0000523 }
524 break;
525 }
526 case JSON_ARRAY:
527 case JSON_OBJECT: {
drhf2df7e72015-08-28 20:07:40 +0000528 jsonReturnJson(pNode, pCtx, aReplace);
drh5634cc02015-08-17 11:28:03 +0000529 break;
530 }
531 }
drhbd0621b2015-08-13 13:54:59 +0000532}
533
drh5fa5c102015-08-12 16:49:40 +0000534/*
drhe9c37f32015-08-15 21:25:36 +0000535** Create a new JsonNode instance based on the arguments and append that
536** instance to the JsonParse. Return the index in pParse->aNode[] of the
537** new node, or -1 if a memory allocation fails.
538*/
539static int jsonParseAddNode(
540 JsonParse *pParse, /* Append the node to this object */
541 u32 eType, /* Node type */
542 u32 n, /* Content size or sub-node count */
543 const char *zContent /* Content */
544){
545 JsonNode *p;
546 if( pParse->nNode>=pParse->nAlloc ){
547 u32 nNew;
548 JsonNode *pNew;
549 if( pParse->oom ) return -1;
550 nNew = pParse->nAlloc*2 + 10;
551 if( nNew<=pParse->nNode ){
552 pParse->oom = 1;
553 return -1;
554 }
555 pNew = sqlite3_realloc(pParse->aNode, sizeof(JsonNode)*nNew);
556 if( pNew==0 ){
557 pParse->oom = 1;
558 return -1;
559 }
560 pParse->nAlloc = nNew;
561 pParse->aNode = pNew;
562 }
563 p = &pParse->aNode[pParse->nNode];
drh5634cc02015-08-17 11:28:03 +0000564 p->eType = (u8)eType;
drh301eecc2015-08-17 20:14:19 +0000565 p->jnFlags = 0;
drhd0960592015-08-17 21:22:32 +0000566 p->iVal = 0;
drhe9c37f32015-08-15 21:25:36 +0000567 p->n = n;
drh52216ad2015-08-18 02:28:03 +0000568 p->u.zJContent = zContent;
drhe9c37f32015-08-15 21:25:36 +0000569 return pParse->nNode++;
570}
571
572/*
573** Parse a single JSON value which begins at pParse->zJson[i]. Return the
574** index of the first character past the end of the value parsed.
575**
576** Return negative for a syntax error. Special cases: return -2 if the
577** first non-whitespace character is '}' and return -3 if the first
578** non-whitespace character is ']'.
579*/
580static int jsonParseValue(JsonParse *pParse, u32 i){
581 char c;
582 u32 j;
drhbc8f0922015-08-22 19:39:04 +0000583 int iThis;
drhe9c37f32015-08-15 21:25:36 +0000584 int x;
585 while( isspace(pParse->zJson[i]) ){ i++; }
586 if( (c = pParse->zJson[i])==0 ) return 0;
587 if( c=='{' ){
588 /* Parse object */
589 iThis = jsonParseAddNode(pParse, JSON_OBJECT, 0, 0);
drhbc8f0922015-08-22 19:39:04 +0000590 if( iThis<0 ) return -1;
drhe9c37f32015-08-15 21:25:36 +0000591 for(j=i+1;;j++){
592 while( isspace(pParse->zJson[j]) ){ j++; }
593 x = jsonParseValue(pParse, j);
594 if( x<0 ){
drhbc8f0922015-08-22 19:39:04 +0000595 if( x==(-2) && pParse->nNode==(u32)iThis+1 ) return j+1;
drhe9c37f32015-08-15 21:25:36 +0000596 return -1;
597 }
drhbe9474e2015-08-22 03:05:54 +0000598 if( pParse->oom ) return -1;
drhe9c37f32015-08-15 21:25:36 +0000599 if( pParse->aNode[pParse->nNode-1].eType!=JSON_STRING ) return -1;
600 j = x;
601 while( isspace(pParse->zJson[j]) ){ j++; }
602 if( pParse->zJson[j]!=':' ) return -1;
603 j++;
604 x = jsonParseValue(pParse, j);
605 if( x<0 ) return -1;
606 j = x;
607 while( isspace(pParse->zJson[j]) ){ j++; }
608 c = pParse->zJson[j];
609 if( c==',' ) continue;
610 if( c!='}' ) return -1;
611 break;
612 }
drhbc8f0922015-08-22 19:39:04 +0000613 pParse->aNode[iThis].n = pParse->nNode - (u32)iThis - 1;
drhe9c37f32015-08-15 21:25:36 +0000614 return j+1;
615 }else if( c=='[' ){
616 /* Parse array */
617 iThis = jsonParseAddNode(pParse, JSON_ARRAY, 0, 0);
drhbc8f0922015-08-22 19:39:04 +0000618 if( iThis<0 ) return -1;
drhe9c37f32015-08-15 21:25:36 +0000619 for(j=i+1;;j++){
620 while( isspace(pParse->zJson[j]) ){ j++; }
621 x = jsonParseValue(pParse, j);
622 if( x<0 ){
drhbc8f0922015-08-22 19:39:04 +0000623 if( x==(-3) && pParse->nNode==(u32)iThis+1 ) return j+1;
drhe9c37f32015-08-15 21:25:36 +0000624 return -1;
625 }
626 j = x;
627 while( isspace(pParse->zJson[j]) ){ j++; }
628 c = pParse->zJson[j];
629 if( c==',' ) continue;
630 if( c!=']' ) return -1;
631 break;
632 }
drhbc8f0922015-08-22 19:39:04 +0000633 pParse->aNode[iThis].n = pParse->nNode - (u32)iThis - 1;
drhe9c37f32015-08-15 21:25:36 +0000634 return j+1;
635 }else if( c=='"' ){
636 /* Parse string */
drh301eecc2015-08-17 20:14:19 +0000637 u8 jnFlags = 0;
drhe9c37f32015-08-15 21:25:36 +0000638 j = i+1;
639 for(;;){
640 c = pParse->zJson[j];
641 if( c==0 ) return -1;
642 if( c=='\\' ){
643 c = pParse->zJson[++j];
644 if( c==0 ) return -1;
drh301eecc2015-08-17 20:14:19 +0000645 jnFlags = JNODE_ESCAPE;
drhe9c37f32015-08-15 21:25:36 +0000646 }else if( c=='"' ){
647 break;
648 }
649 j++;
650 }
651 jsonParseAddNode(pParse, JSON_STRING, j+1-i, &pParse->zJson[i]);
drhbe9474e2015-08-22 03:05:54 +0000652 if( !pParse->oom ) pParse->aNode[pParse->nNode-1].jnFlags = jnFlags;
drhe9c37f32015-08-15 21:25:36 +0000653 return j+1;
654 }else if( c=='n'
655 && strncmp(pParse->zJson+i,"null",4)==0
drhb2cd10e2015-08-15 21:29:14 +0000656 && !isalnum(pParse->zJson[i+4]) ){
drhe9c37f32015-08-15 21:25:36 +0000657 jsonParseAddNode(pParse, JSON_NULL, 0, 0);
658 return i+4;
659 }else if( c=='t'
660 && strncmp(pParse->zJson+i,"true",4)==0
drhb2cd10e2015-08-15 21:29:14 +0000661 && !isalnum(pParse->zJson[i+4]) ){
drhe9c37f32015-08-15 21:25:36 +0000662 jsonParseAddNode(pParse, JSON_TRUE, 0, 0);
663 return i+4;
664 }else if( c=='f'
665 && strncmp(pParse->zJson+i,"false",5)==0
drhb2cd10e2015-08-15 21:29:14 +0000666 && !isalnum(pParse->zJson[i+5]) ){
drhe9c37f32015-08-15 21:25:36 +0000667 jsonParseAddNode(pParse, JSON_FALSE, 0, 0);
668 return i+5;
669 }else if( c=='-' || (c>='0' && c<='9') ){
670 /* Parse number */
671 u8 seenDP = 0;
672 u8 seenE = 0;
673 j = i+1;
674 for(;; j++){
675 c = pParse->zJson[j];
676 if( c>='0' && c<='9' ) continue;
677 if( c=='.' ){
678 if( pParse->zJson[j-1]=='-' ) return -1;
679 if( seenDP ) return -1;
680 seenDP = 1;
681 continue;
682 }
683 if( c=='e' || c=='E' ){
684 if( pParse->zJson[j-1]<'0' ) return -1;
685 if( seenE ) return -1;
686 seenDP = seenE = 1;
687 c = pParse->zJson[j+1];
drh8784eca2015-08-23 02:42:30 +0000688 if( c=='+' || c=='-' ){
689 j++;
690 c = pParse->zJson[j+1];
691 }
692 if( c<'0' || c>'0' ) return -1;
drhe9c37f32015-08-15 21:25:36 +0000693 continue;
694 }
695 break;
696 }
697 if( pParse->zJson[j-1]<'0' ) return -1;
698 jsonParseAddNode(pParse, seenDP ? JSON_REAL : JSON_INT,
699 j - i, &pParse->zJson[i]);
700 return j;
701 }else if( c=='}' ){
702 return -2; /* End of {...} */
703 }else if( c==']' ){
704 return -3; /* End of [...] */
705 }else{
706 return -1; /* Syntax error */
707 }
708}
709
710/*
711** Parse a complete JSON string. Return 0 on success or non-zero if there
712** are any errors. If an error occurs, free all memory associated with
713** pParse.
714**
715** pParse is uninitialized when this routine is called.
716*/
drhbc8f0922015-08-22 19:39:04 +0000717static int jsonParse(
718 JsonParse *pParse, /* Initialize and fill this JsonParse object */
719 sqlite3_context *pCtx, /* Report errors here */
720 const char *zJson /* Input JSON text to be parsed */
721){
drhe9c37f32015-08-15 21:25:36 +0000722 int i;
drhe9c37f32015-08-15 21:25:36 +0000723 memset(pParse, 0, sizeof(*pParse));
drhc3722b22015-08-23 20:44:59 +0000724 if( zJson==0 ) return 1;
drhe9c37f32015-08-15 21:25:36 +0000725 pParse->zJson = zJson;
726 i = jsonParseValue(pParse, 0);
drhc3722b22015-08-23 20:44:59 +0000727 if( pParse->oom ) i = -1;
drhe9c37f32015-08-15 21:25:36 +0000728 if( i>0 ){
729 while( isspace(zJson[i]) ) i++;
730 if( zJson[i] ) i = -1;
731 }
732 if( i<0 ){
drhf2df7e72015-08-28 20:07:40 +0000733 if( pCtx!=0 ){
734 if( pParse->oom ){
735 sqlite3_result_error_nomem(pCtx);
736 }else{
737 sqlite3_result_error(pCtx, "malformed JSON", -1);
738 }
739 }
drh505ad2c2015-08-21 17:33:11 +0000740 jsonParseReset(pParse);
drhe9c37f32015-08-15 21:25:36 +0000741 return 1;
742 }
743 return 0;
744}
drh301eecc2015-08-17 20:14:19 +0000745
drh505ad2c2015-08-21 17:33:11 +0000746/* Mark node i of pParse as being a child of iParent. Call recursively
747** to fill in all the descendants of node i.
748*/
749static void jsonParseFillInParentage(JsonParse *pParse, u32 i, u32 iParent){
750 JsonNode *pNode = &pParse->aNode[i];
751 u32 j;
752 pParse->aUp[i] = iParent;
753 switch( pNode->eType ){
754 case JSON_ARRAY: {
755 for(j=1; j<=pNode->n; j += jsonNodeSize(pNode+j)){
756 jsonParseFillInParentage(pParse, i+j, i);
757 }
758 break;
759 }
760 case JSON_OBJECT: {
761 for(j=1; j<=pNode->n; j += jsonNodeSize(pNode+j+1)+1){
762 pParse->aUp[i+j] = i;
763 jsonParseFillInParentage(pParse, i+j+1, i);
764 }
765 break;
766 }
767 default: {
768 break;
769 }
770 }
771}
772
773/*
774** Compute the parentage of all nodes in a completed parse.
775*/
776static int jsonParseFindParents(JsonParse *pParse){
777 u32 *aUp;
778 assert( pParse->aUp==0 );
779 aUp = pParse->aUp = sqlite3_malloc( sizeof(u32)*pParse->nNode );
drhc3722b22015-08-23 20:44:59 +0000780 if( aUp==0 ){
781 pParse->oom = 1;
782 return SQLITE_NOMEM;
783 }
drh505ad2c2015-08-21 17:33:11 +0000784 jsonParseFillInParentage(pParse, 0, 0);
785 return SQLITE_OK;
786}
787
drh52216ad2015-08-18 02:28:03 +0000788/* forward declaration */
789static JsonNode *jsonLookupAppend(JsonParse*,const char*,int*);
790
drh987eb1f2015-08-17 15:17:37 +0000791/*
792** Search along zPath to find the node specified. Return a pointer
793** to that node, or NULL if zPath is malformed or if there is no such
794** node.
drh52216ad2015-08-18 02:28:03 +0000795**
796** If pApnd!=0, then try to append new nodes to complete zPath if it is
797** possible to do so and if no existing node corresponds to zPath. If
798** new nodes are appended *pApnd is set to 1.
drh987eb1f2015-08-17 15:17:37 +0000799*/
drh52216ad2015-08-18 02:28:03 +0000800static JsonNode *jsonLookup(
801 JsonParse *pParse, /* The JSON to search */
802 u32 iRoot, /* Begin the search at this node */
803 const char *zPath, /* The path to search */
804 int *pApnd /* Append nodes to complete path if not NULL */
805){
drhbc8f0922015-08-22 19:39:04 +0000806 u32 i, j, nKey;
drh6b43cc82015-08-19 23:02:49 +0000807 const char *zKey;
drh52216ad2015-08-18 02:28:03 +0000808 JsonNode *pRoot = &pParse->aNode[iRoot];
drh987eb1f2015-08-17 15:17:37 +0000809 if( zPath[0]==0 ) return pRoot;
810 if( zPath[0]=='.' ){
811 if( pRoot->eType!=JSON_OBJECT ) return 0;
812 zPath++;
drh6b43cc82015-08-19 23:02:49 +0000813 if( zPath[0]=='"' ){
814 zKey = zPath + 1;
815 for(i=1; zPath[i] && zPath[i]!='"'; i++){}
816 nKey = i-1;
817 if( zPath[i] ) i++;
818 }else{
819 zKey = zPath;
820 for(i=0; zPath[i] && zPath[i]!='.' && zPath[i]!='['; i++){}
821 nKey = i;
822 }
823 if( nKey==0 ) return 0;
drh987eb1f2015-08-17 15:17:37 +0000824 j = 1;
drh52216ad2015-08-18 02:28:03 +0000825 for(;;){
826 while( j<=pRoot->n ){
drh6b43cc82015-08-19 23:02:49 +0000827 if( pRoot[j].n==nKey+2
828 && strncmp(&pRoot[j].u.zJContent[1],zKey,nKey)==0
drh52216ad2015-08-18 02:28:03 +0000829 ){
830 return jsonLookup(pParse, iRoot+j+1, &zPath[i], pApnd);
831 }
832 j++;
drh505ad2c2015-08-21 17:33:11 +0000833 j += jsonNodeSize(&pRoot[j]);
drh987eb1f2015-08-17 15:17:37 +0000834 }
drh52216ad2015-08-18 02:28:03 +0000835 if( (pRoot->jnFlags & JNODE_APPEND)==0 ) break;
836 iRoot += pRoot->u.iAppend;
837 pRoot = &pParse->aNode[iRoot];
838 j = 1;
839 }
840 if( pApnd ){
drhbc8f0922015-08-22 19:39:04 +0000841 u32 iStart, iLabel;
842 JsonNode *pNode;
843 iStart = jsonParseAddNode(pParse, JSON_OBJECT, 2, 0);
844 iLabel = jsonParseAddNode(pParse, JSON_STRING, i, zPath);
drh52216ad2015-08-18 02:28:03 +0000845 zPath += i;
drhbc8f0922015-08-22 19:39:04 +0000846 pNode = jsonLookupAppend(pParse, zPath, pApnd);
847 if( pParse->oom ) return 0;
848 if( pNode ){
849 pRoot = &pParse->aNode[iRoot];
850 pRoot->u.iAppend = iStart - iRoot;
851 pRoot->jnFlags |= JNODE_APPEND;
852 pParse->aNode[iLabel].jnFlags |= JNODE_RAW;
853 }
854 return pNode;
drh987eb1f2015-08-17 15:17:37 +0000855 }
856 }else if( zPath[0]=='[' && isdigit(zPath[1]) ){
857 if( pRoot->eType!=JSON_ARRAY ) return 0;
858 i = 0;
859 zPath++;
860 while( isdigit(zPath[0]) ){
drh8784eca2015-08-23 02:42:30 +0000861 i = i*10 + zPath[0] - '0';
drh987eb1f2015-08-17 15:17:37 +0000862 zPath++;
863 }
864 if( zPath[0]!=']' ) return 0;
865 zPath++;
866 j = 1;
drh52216ad2015-08-18 02:28:03 +0000867 for(;;){
drhbc8f0922015-08-22 19:39:04 +0000868 while( j<=pRoot->n && (i>0 || (pRoot[j].jnFlags & JNODE_REMOVE)!=0) ){
869 if( (pRoot[j].jnFlags & JNODE_REMOVE)==0 ) i--;
drh505ad2c2015-08-21 17:33:11 +0000870 j += jsonNodeSize(&pRoot[j]);
drh52216ad2015-08-18 02:28:03 +0000871 }
872 if( (pRoot->jnFlags & JNODE_APPEND)==0 ) break;
873 iRoot += pRoot->u.iAppend;
874 pRoot = &pParse->aNode[iRoot];
875 j = 1;
drh987eb1f2015-08-17 15:17:37 +0000876 }
877 if( j<=pRoot->n ){
drh52216ad2015-08-18 02:28:03 +0000878 return jsonLookup(pParse, iRoot+j, zPath, pApnd);
879 }
880 if( i==0 && pApnd ){
drhbc8f0922015-08-22 19:39:04 +0000881 u32 iStart;
882 JsonNode *pNode;
883 iStart = jsonParseAddNode(pParse, JSON_ARRAY, 1, 0);
884 pNode = jsonLookupAppend(pParse, zPath, pApnd);
885 if( pParse->oom ) return 0;
886 if( pNode ){
887 pRoot = &pParse->aNode[iRoot];
888 pRoot->u.iAppend = iStart - iRoot;
889 pRoot->jnFlags |= JNODE_APPEND;
890 }
891 return pNode;
drh987eb1f2015-08-17 15:17:37 +0000892 }
893 }
894 return 0;
895}
896
drh52216ad2015-08-18 02:28:03 +0000897/*
drhbc8f0922015-08-22 19:39:04 +0000898** Append content to pParse that will complete zPath. Return a pointer
899** to the inserted node, or return NULL if the append fails.
drh52216ad2015-08-18 02:28:03 +0000900*/
901static JsonNode *jsonLookupAppend(
902 JsonParse *pParse, /* Append content to the JSON parse */
903 const char *zPath, /* Description of content to append */
904 int *pApnd /* Set this flag to 1 */
905){
906 *pApnd = 1;
907 if( zPath[0]==0 ){
908 jsonParseAddNode(pParse, JSON_NULL, 0, 0);
909 return pParse->oom ? 0 : &pParse->aNode[pParse->nNode-1];
910 }
911 if( zPath[0]=='.' ){
912 jsonParseAddNode(pParse, JSON_OBJECT, 0, 0);
913 }else if( strncmp(zPath,"[0]",3)==0 ){
914 jsonParseAddNode(pParse, JSON_ARRAY, 0, 0);
915 }else{
916 return 0;
917 }
918 if( pParse->oom ) return 0;
919 return jsonLookup(pParse, pParse->nNode-1, zPath, pApnd);
920}
921
drhbc8f0922015-08-22 19:39:04 +0000922/*
923** Report the wrong number of arguments for json_insert(), json_replace()
924** or json_set().
925*/
926static void jsonWrongNumArgs(
927 sqlite3_context *pCtx,
928 const char *zFuncName
929){
930 char *zMsg = sqlite3_mprintf("json_%s() needs an odd number of arguments",
931 zFuncName);
932 sqlite3_result_error(pCtx, zMsg, -1);
933 sqlite3_free(zMsg);
934}
drh52216ad2015-08-18 02:28:03 +0000935
drh987eb1f2015-08-17 15:17:37 +0000936/****************************************************************************
937** SQL functions used for testing and debugging
938****************************************************************************/
drhe9c37f32015-08-15 21:25:36 +0000939
drh301eecc2015-08-17 20:14:19 +0000940#ifdef SQLITE_DEBUG
drhe9c37f32015-08-15 21:25:36 +0000941/*
drh5634cc02015-08-17 11:28:03 +0000942** The json_parse(JSON) function returns a string which describes
drhe9c37f32015-08-15 21:25:36 +0000943** a parse of the JSON provided. Or it returns NULL if JSON is not
944** well-formed.
945*/
drh5634cc02015-08-17 11:28:03 +0000946static void jsonParseFunc(
drhbc8f0922015-08-22 19:39:04 +0000947 sqlite3_context *ctx,
drhe9c37f32015-08-15 21:25:36 +0000948 int argc,
949 sqlite3_value **argv
950){
drh505ad2c2015-08-21 17:33:11 +0000951 JsonString s; /* Output string - not real JSON */
952 JsonParse x; /* The parse */
drhe9c37f32015-08-15 21:25:36 +0000953 u32 i;
drhe9c37f32015-08-15 21:25:36 +0000954
955 assert( argc==1 );
drhbc8f0922015-08-22 19:39:04 +0000956 if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return;
drh8784eca2015-08-23 02:42:30 +0000957 jsonParseFindParents(&x);
drhbc8f0922015-08-22 19:39:04 +0000958 jsonInit(&s, ctx);
drhe9c37f32015-08-15 21:25:36 +0000959 for(i=0; i<x.nNode; i++){
drh8784eca2015-08-23 02:42:30 +0000960 jsonPrintf(100, &s,"node %3u: %7s n=%-4d up=%d\n",
961 i, jsonType[x.aNode[i].eType], x.aNode[i].n, x.aUp[i]);
drh52216ad2015-08-18 02:28:03 +0000962 if( x.aNode[i].u.zJContent!=0 ){
drh301eecc2015-08-17 20:14:19 +0000963 jsonAppendRaw(&s, " text: ", 10);
drh52216ad2015-08-18 02:28:03 +0000964 jsonAppendRaw(&s, x.aNode[i].u.zJContent, x.aNode[i].n);
drhe9c37f32015-08-15 21:25:36 +0000965 jsonAppendRaw(&s, "\n", 1);
966 }
967 }
drh505ad2c2015-08-21 17:33:11 +0000968 jsonParseReset(&x);
drhe9c37f32015-08-15 21:25:36 +0000969 jsonResult(&s);
970}
971
drh5634cc02015-08-17 11:28:03 +0000972/*
973** The json_test1(JSON) function parses and rebuilds the JSON string.
974*/
975static void jsonTest1Func(
drhbc8f0922015-08-22 19:39:04 +0000976 sqlite3_context *ctx,
drh5634cc02015-08-17 11:28:03 +0000977 int argc,
978 sqlite3_value **argv
979){
980 JsonParse x; /* The parse */
drhbc8f0922015-08-22 19:39:04 +0000981 if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return;
drhf2df7e72015-08-28 20:07:40 +0000982 jsonReturnJson(x.aNode, ctx, 0);
drh505ad2c2015-08-21 17:33:11 +0000983 jsonParseReset(&x);
drh5634cc02015-08-17 11:28:03 +0000984}
985
986/*
987** The json_nodecount(JSON) function returns the number of nodes in the
988** input JSON string.
989*/
990static void jsonNodeCountFunc(
drhbc8f0922015-08-22 19:39:04 +0000991 sqlite3_context *ctx,
drh5634cc02015-08-17 11:28:03 +0000992 int argc,
993 sqlite3_value **argv
994){
995 JsonParse x; /* The parse */
drhbc8f0922015-08-22 19:39:04 +0000996 if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return;
997 sqlite3_result_int64(ctx, (sqlite3_int64)x.nNode);
drh505ad2c2015-08-21 17:33:11 +0000998 jsonParseReset(&x);
drh5634cc02015-08-17 11:28:03 +0000999}
drh301eecc2015-08-17 20:14:19 +00001000#endif /* SQLITE_DEBUG */
drh5634cc02015-08-17 11:28:03 +00001001
drh987eb1f2015-08-17 15:17:37 +00001002/****************************************************************************
1003** SQL function implementations
1004****************************************************************************/
1005
1006/*
1007** Implementation of the json_array(VALUE,...) function. Return a JSON
1008** array that contains all values given in arguments. Or if any argument
1009** is a BLOB, throw an error.
1010*/
1011static void jsonArrayFunc(
drhbc8f0922015-08-22 19:39:04 +00001012 sqlite3_context *ctx,
drh987eb1f2015-08-17 15:17:37 +00001013 int argc,
1014 sqlite3_value **argv
1015){
1016 int i;
drh505ad2c2015-08-21 17:33:11 +00001017 JsonString jx;
drh987eb1f2015-08-17 15:17:37 +00001018
drhbc8f0922015-08-22 19:39:04 +00001019 jsonInit(&jx, ctx);
drhd0960592015-08-17 21:22:32 +00001020 jsonAppendChar(&jx, '[');
drh987eb1f2015-08-17 15:17:37 +00001021 for(i=0; i<argc; i++){
drhd0960592015-08-17 21:22:32 +00001022 jsonAppendSeparator(&jx);
drhecb5fed2015-08-28 03:33:50 +00001023 jsonAppendValue(&jx, argv[i], 0);
drh987eb1f2015-08-17 15:17:37 +00001024 }
drhd0960592015-08-17 21:22:32 +00001025 jsonAppendChar(&jx, ']');
drh987eb1f2015-08-17 15:17:37 +00001026 jsonResult(&jx);
1027}
1028
1029
1030/*
1031** json_array_length(JSON)
1032** json_array_length(JSON, PATH)
1033**
1034** Return the number of elements in the top-level JSON array.
1035** Return 0 if the input is not a well-formed JSON array.
1036*/
1037static void jsonArrayLengthFunc(
drhbc8f0922015-08-22 19:39:04 +00001038 sqlite3_context *ctx,
drh987eb1f2015-08-17 15:17:37 +00001039 int argc,
1040 sqlite3_value **argv
1041){
1042 JsonParse x; /* The parse */
1043 sqlite3_int64 n = 0;
1044 u32 i;
1045 const char *zPath;
1046
1047 if( argc==2 ){
1048 zPath = (const char*)sqlite3_value_text(argv[1]);
1049 if( zPath==0 ) return;
1050 if( zPath[0]!='$' ) return;
1051 zPath++;
1052 }else{
1053 zPath = 0;
1054 }
drhf2df7e72015-08-28 20:07:40 +00001055 if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return;
1056 if( x.nNode ){
1057 JsonNode *pNode = x.aNode;
1058 if( zPath ) pNode = jsonLookup(&x, 0, zPath, 0);
1059 if( pNode->eType==JSON_ARRAY ){
1060 assert( (pNode->jnFlags & JNODE_APPEND)==0 );
1061 for(i=1; i<=pNode->n; n++){
1062 i += jsonNodeSize(&pNode[i]);
drh987eb1f2015-08-17 15:17:37 +00001063 }
1064 }
drh987eb1f2015-08-17 15:17:37 +00001065 }
drhf6ec8d42015-08-28 03:48:04 +00001066 jsonParseReset(&x);
drhf2df7e72015-08-28 20:07:40 +00001067 sqlite3_result_int64(ctx, n);
drhf6ec8d42015-08-28 03:48:04 +00001068}
1069
1070/*
drh987eb1f2015-08-17 15:17:37 +00001071** json_extract(JSON, PATH)
1072**
1073** Return the element described by PATH. Return NULL if JSON is not
1074** valid JSON or if there is no PATH element or if PATH is malformed.
1075*/
1076static void jsonExtractFunc(
drhbc8f0922015-08-22 19:39:04 +00001077 sqlite3_context *ctx,
drh987eb1f2015-08-17 15:17:37 +00001078 int argc,
1079 sqlite3_value **argv
1080){
1081 JsonParse x; /* The parse */
1082 JsonNode *pNode;
1083 const char *zPath;
1084 assert( argc==2 );
1085 zPath = (const char*)sqlite3_value_text(argv[1]);
1086 if( zPath==0 ) return;
1087 if( zPath[0]!='$' ) return;
1088 zPath++;
drhbc8f0922015-08-22 19:39:04 +00001089 if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return;
drh52216ad2015-08-18 02:28:03 +00001090 pNode = jsonLookup(&x, 0, zPath, 0);
drh987eb1f2015-08-17 15:17:37 +00001091 if( pNode ){
drhbc8f0922015-08-22 19:39:04 +00001092 jsonReturn(pNode, ctx, 0);
drh987eb1f2015-08-17 15:17:37 +00001093 }
drh505ad2c2015-08-21 17:33:11 +00001094 jsonParseReset(&x);
drh987eb1f2015-08-17 15:17:37 +00001095}
1096
1097/*
1098** Implementation of the json_object(NAME,VALUE,...) function. Return a JSON
1099** object that contains all name/value given in arguments. Or if any name
1100** is not a string or if any value is a BLOB, throw an error.
1101*/
1102static void jsonObjectFunc(
drhbc8f0922015-08-22 19:39:04 +00001103 sqlite3_context *ctx,
drh987eb1f2015-08-17 15:17:37 +00001104 int argc,
1105 sqlite3_value **argv
1106){
1107 int i;
drh505ad2c2015-08-21 17:33:11 +00001108 JsonString jx;
drh987eb1f2015-08-17 15:17:37 +00001109 const char *z;
1110 u32 n;
1111
1112 if( argc&1 ){
drhbc8f0922015-08-22 19:39:04 +00001113 sqlite3_result_error(ctx, "json_object() requires an even number "
drh987eb1f2015-08-17 15:17:37 +00001114 "of arguments", -1);
1115 return;
1116 }
drhbc8f0922015-08-22 19:39:04 +00001117 jsonInit(&jx, ctx);
drhd0960592015-08-17 21:22:32 +00001118 jsonAppendChar(&jx, '{');
drh987eb1f2015-08-17 15:17:37 +00001119 for(i=0; i<argc; i+=2){
drh987eb1f2015-08-17 15:17:37 +00001120 if( sqlite3_value_type(argv[i])!=SQLITE_TEXT ){
drhbc8f0922015-08-22 19:39:04 +00001121 sqlite3_result_error(ctx, "json_object() labels must be TEXT", -1);
drh987eb1f2015-08-17 15:17:37 +00001122 jsonZero(&jx);
1123 return;
1124 }
drhd0960592015-08-17 21:22:32 +00001125 jsonAppendSeparator(&jx);
drh987eb1f2015-08-17 15:17:37 +00001126 z = (const char*)sqlite3_value_text(argv[i]);
1127 n = (u32)sqlite3_value_bytes(argv[i]);
1128 jsonAppendString(&jx, z, n);
drhd0960592015-08-17 21:22:32 +00001129 jsonAppendChar(&jx, ':');
drhecb5fed2015-08-28 03:33:50 +00001130 jsonAppendValue(&jx, argv[i+1], 0);
drh987eb1f2015-08-17 15:17:37 +00001131 }
drhd0960592015-08-17 21:22:32 +00001132 jsonAppendChar(&jx, '}');
drh987eb1f2015-08-17 15:17:37 +00001133 jsonResult(&jx);
1134}
1135
1136
1137/*
drh301eecc2015-08-17 20:14:19 +00001138** json_remove(JSON, PATH, ...)
1139**
1140** Remove the named elements from JSON and return the result. Ill-formed
1141** PATH arguments are silently ignored. If JSON is ill-formed, then NULL
1142** is returned.
1143*/
1144static void jsonRemoveFunc(
drhbc8f0922015-08-22 19:39:04 +00001145 sqlite3_context *ctx,
drh301eecc2015-08-17 20:14:19 +00001146 int argc,
1147 sqlite3_value **argv
1148){
1149 JsonParse x; /* The parse */
1150 JsonNode *pNode;
1151 const char *zPath;
1152 u32 i;
1153
1154 if( argc<1 ) return;
drhbc8f0922015-08-22 19:39:04 +00001155 if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return;
drh301eecc2015-08-17 20:14:19 +00001156 if( x.nNode ){
drh6fd5c1e2015-08-21 20:37:12 +00001157 for(i=1; i<(u32)argc; i++){
drh301eecc2015-08-17 20:14:19 +00001158 zPath = (const char*)sqlite3_value_text(argv[i]);
1159 if( zPath==0 ) continue;
1160 if( zPath[0]!='$' ) continue;
drh52216ad2015-08-18 02:28:03 +00001161 pNode = jsonLookup(&x, 0, &zPath[1], 0);
drh301eecc2015-08-17 20:14:19 +00001162 if( pNode ) pNode->jnFlags |= JNODE_REMOVE;
1163 }
1164 if( (x.aNode[0].jnFlags & JNODE_REMOVE)==0 ){
drhf2df7e72015-08-28 20:07:40 +00001165 jsonReturnJson(x.aNode, ctx, 0);
drhd0960592015-08-17 21:22:32 +00001166 }
1167 }
drh505ad2c2015-08-21 17:33:11 +00001168 jsonParseReset(&x);
drhd0960592015-08-17 21:22:32 +00001169}
1170
1171/*
1172** json_replace(JSON, PATH, VALUE, ...)
1173**
1174** Replace the value at PATH with VALUE. If PATH does not already exist,
1175** this routine is a no-op. If JSON is ill-formed, return NULL.
1176*/
1177static void jsonReplaceFunc(
drhbc8f0922015-08-22 19:39:04 +00001178 sqlite3_context *ctx,
drhd0960592015-08-17 21:22:32 +00001179 int argc,
1180 sqlite3_value **argv
1181){
1182 JsonParse x; /* The parse */
1183 JsonNode *pNode;
1184 const char *zPath;
1185 u32 i;
1186
1187 if( argc<1 ) return;
1188 if( (argc&1)==0 ) {
drhbc8f0922015-08-22 19:39:04 +00001189 jsonWrongNumArgs(ctx, "replace");
drhd0960592015-08-17 21:22:32 +00001190 return;
1191 }
drhbc8f0922015-08-22 19:39:04 +00001192 if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return;
drhd0960592015-08-17 21:22:32 +00001193 if( x.nNode ){
drh6fd5c1e2015-08-21 20:37:12 +00001194 for(i=1; i<(u32)argc; i+=2){
drhecb5fed2015-08-28 03:33:50 +00001195 u8 jnFlags = JNODE_REPLACE;
drhd0960592015-08-17 21:22:32 +00001196 zPath = (const char*)sqlite3_value_text(argv[i]);
1197 if( zPath==0 ) continue;
1198 if( zPath[0]!='$' ) continue;
drhecb5fed2015-08-28 03:33:50 +00001199 if( zPath[1]=='$' ){
1200 zPath++;
1201 jnFlags = JNODE_REPLACE|JNODE_JSON;
1202 }
drh52216ad2015-08-18 02:28:03 +00001203 pNode = jsonLookup(&x, 0, &zPath[1], 0);
drhd0960592015-08-17 21:22:32 +00001204 if( pNode ){
drhecb5fed2015-08-28 03:33:50 +00001205 pNode->jnFlags &= ~JNODE_JSON;
1206 pNode->jnFlags |= jnFlags;
drhd0960592015-08-17 21:22:32 +00001207 pNode->iVal = i+1;
1208 }
1209 }
1210 if( x.aNode[0].jnFlags & JNODE_REPLACE ){
drhbc8f0922015-08-22 19:39:04 +00001211 sqlite3_result_value(ctx, argv[x.aNode[0].iVal]);
drhd0960592015-08-17 21:22:32 +00001212 }else{
drhf2df7e72015-08-28 20:07:40 +00001213 jsonReturnJson(x.aNode, ctx, argv);
drh301eecc2015-08-17 20:14:19 +00001214 }
1215 }
drh505ad2c2015-08-21 17:33:11 +00001216 jsonParseReset(&x);
drh301eecc2015-08-17 20:14:19 +00001217}
drh505ad2c2015-08-21 17:33:11 +00001218
drh52216ad2015-08-18 02:28:03 +00001219/*
1220** json_set(JSON, PATH, VALUE, ...)
1221**
1222** Set the value at PATH to VALUE. Create the PATH if it does not already
1223** exist. Overwrite existing values that do exist.
1224** If JSON is ill-formed, return NULL.
1225**
1226** json_insert(JSON, PATH, VALUE, ...)
1227**
1228** Create PATH and initialize it to VALUE. If PATH already exists, this
1229** routine is a no-op. If JSON is ill-formed, return NULL.
1230*/
1231static void jsonSetFunc(
drhbc8f0922015-08-22 19:39:04 +00001232 sqlite3_context *ctx,
drh52216ad2015-08-18 02:28:03 +00001233 int argc,
1234 sqlite3_value **argv
1235){
1236 JsonParse x; /* The parse */
1237 JsonNode *pNode;
1238 const char *zPath;
1239 u32 i;
1240 int bApnd;
drhbc8f0922015-08-22 19:39:04 +00001241 int bIsSet = *(int*)sqlite3_user_data(ctx);
drh52216ad2015-08-18 02:28:03 +00001242
1243 if( argc<1 ) return;
1244 if( (argc&1)==0 ) {
drhbc8f0922015-08-22 19:39:04 +00001245 jsonWrongNumArgs(ctx, bIsSet ? "set" : "insert");
drh52216ad2015-08-18 02:28:03 +00001246 return;
1247 }
drhbc8f0922015-08-22 19:39:04 +00001248 if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return;
drh52216ad2015-08-18 02:28:03 +00001249 if( x.nNode ){
drh6fd5c1e2015-08-21 20:37:12 +00001250 for(i=1; i<(u32)argc; i+=2){
drhecb5fed2015-08-28 03:33:50 +00001251 u8 jnFlags = JNODE_REPLACE;
drh52216ad2015-08-18 02:28:03 +00001252 zPath = (const char*)sqlite3_value_text(argv[i]);
1253 if( zPath==0 ) continue;
1254 if( zPath[0]!='$' ) continue;
drhecb5fed2015-08-28 03:33:50 +00001255 if( zPath[1]=='$' ){
1256 zPath++;
1257 jnFlags = JNODE_REPLACE|JNODE_JSON;
1258 }
drh52216ad2015-08-18 02:28:03 +00001259 bApnd = 0;
1260 pNode = jsonLookup(&x, 0, &zPath[1], &bApnd);
drhbc8f0922015-08-22 19:39:04 +00001261 if( x.oom ){
1262 sqlite3_result_error_nomem(ctx);
1263 goto jsonSetDone;
1264 }else if( pNode && (bApnd || bIsSet) ){
drhecb5fed2015-08-28 03:33:50 +00001265 pNode->jnFlags &= ~JNODE_JSON;
1266 pNode->jnFlags |= jnFlags;
drh52216ad2015-08-18 02:28:03 +00001267 pNode->iVal = i+1;
1268 }
1269 }
1270 if( x.aNode[0].jnFlags & JNODE_REPLACE ){
drhbc8f0922015-08-22 19:39:04 +00001271 sqlite3_result_value(ctx, argv[x.aNode[0].iVal]);
drh52216ad2015-08-18 02:28:03 +00001272 }else{
drhf2df7e72015-08-28 20:07:40 +00001273 jsonReturnJson(x.aNode, ctx, argv);
drh52216ad2015-08-18 02:28:03 +00001274 }
1275 }
drhbc8f0922015-08-22 19:39:04 +00001276jsonSetDone:
drh505ad2c2015-08-21 17:33:11 +00001277 jsonParseReset(&x);
drh52216ad2015-08-18 02:28:03 +00001278}
drh301eecc2015-08-17 20:14:19 +00001279
1280/*
drh987eb1f2015-08-17 15:17:37 +00001281** json_type(JSON)
1282** json_type(JSON, PATH)
1283**
1284** Return the top-level "type" of a JSON string. Return NULL if the
1285** input is not a well-formed JSON string.
1286*/
1287static void jsonTypeFunc(
drhbc8f0922015-08-22 19:39:04 +00001288 sqlite3_context *ctx,
drh987eb1f2015-08-17 15:17:37 +00001289 int argc,
1290 sqlite3_value **argv
1291){
1292 JsonParse x; /* The parse */
1293 const char *zPath;
1294
1295 if( argc==2 ){
1296 zPath = (const char*)sqlite3_value_text(argv[1]);
1297 if( zPath==0 ) return;
1298 if( zPath[0]!='$' ) return;
1299 zPath++;
1300 }else{
1301 zPath = 0;
1302 }
drhbc8f0922015-08-22 19:39:04 +00001303 if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return;
drh987eb1f2015-08-17 15:17:37 +00001304 if( x.nNode ){
1305 JsonNode *pNode = x.aNode;
drh52216ad2015-08-18 02:28:03 +00001306 if( zPath ) pNode = jsonLookup(&x, 0, zPath, 0);
drhbc8f0922015-08-22 19:39:04 +00001307 if( pNode ){
1308 sqlite3_result_text(ctx, jsonType[pNode->eType], -1, SQLITE_STATIC);
1309 }
drh987eb1f2015-08-17 15:17:37 +00001310 }
drh505ad2c2015-08-21 17:33:11 +00001311 jsonParseReset(&x);
drh987eb1f2015-08-17 15:17:37 +00001312}
drh5634cc02015-08-17 11:28:03 +00001313
drhbc8f0922015-08-22 19:39:04 +00001314/*
1315** json_valid(JSON)
1316**
1317** Return 1 if JSON is a valid JSON string. Return 0 otherwise.
1318*/
1319static void jsonValidFunc(
1320 sqlite3_context *ctx,
1321 int argc,
1322 sqlite3_value **argv
1323){
1324 JsonParse x; /* The parse */
1325 int rc = 0;
1326
drhf2df7e72015-08-28 20:07:40 +00001327 if( jsonParse(&x, 0, (const char*)sqlite3_value_text(argv[0]))==0
drhbc8f0922015-08-22 19:39:04 +00001328 && x.nNode>0
1329 ){
1330 rc = 1;
1331 }
1332 jsonParseReset(&x);
1333 sqlite3_result_int(ctx, rc);
1334}
1335
drhcb6c6c62015-08-19 22:47:17 +00001336/****************************************************************************
1337** The json_each virtual table
1338****************************************************************************/
1339typedef struct JsonEachCursor JsonEachCursor;
1340struct JsonEachCursor {
1341 sqlite3_vtab_cursor base; /* Base class - must be first */
drh505ad2c2015-08-21 17:33:11 +00001342 u32 iRowid; /* The rowid */
1343 u32 i; /* Index in sParse.aNode[] of current row */
1344 u32 iEnd; /* EOF when i equals or exceeds this value */
1345 u8 eType; /* Type of top-level element */
1346 u8 bRecursive; /* True for json_tree(). False for json_each() */
1347 char *zJson; /* Input JSON */
1348 char *zPath; /* Path by which to filter zJson */
1349 JsonParse sParse; /* Parse of the input JSON */
drhcb6c6c62015-08-19 22:47:17 +00001350};
1351
1352/* Constructor for the json_each virtual table */
1353static int jsonEachConnect(
1354 sqlite3 *db,
1355 void *pAux,
1356 int argc, const char *const*argv,
1357 sqlite3_vtab **ppVtab,
1358 char **pzErr
1359){
1360 sqlite3_vtab *pNew;
drh505ad2c2015-08-21 17:33:11 +00001361 int rc;
drhcb6c6c62015-08-19 22:47:17 +00001362
1363/* Column numbers */
drh4af352d2015-08-21 20:02:48 +00001364#define JEACH_KEY 0
1365#define JEACH_VALUE 1
1366#define JEACH_TYPE 2
1367#define JEACH_ATOM 3
1368#define JEACH_ID 4
1369#define JEACH_PARENT 5
1370#define JEACH_FULLKEY 6
1371#define JEACH_JSON 7
1372#define JEACH_PATH 8
drhcb6c6c62015-08-19 22:47:17 +00001373
drh6fd5c1e2015-08-21 20:37:12 +00001374 UNUSED_PARAM(pzErr);
1375 UNUSED_PARAM(argv);
1376 UNUSED_PARAM(argc);
1377 UNUSED_PARAM(pAux);
drh505ad2c2015-08-21 17:33:11 +00001378 rc = sqlite3_declare_vtab(db,
drh4af352d2015-08-21 20:02:48 +00001379 "CREATE TABLE x(key,value,type,atom,id,parent,fullkey,"
1380 "json HIDDEN,path HIDDEN)");
drh505ad2c2015-08-21 17:33:11 +00001381 if( rc==SQLITE_OK ){
1382 pNew = *ppVtab = sqlite3_malloc( sizeof(*pNew) );
1383 if( pNew==0 ) return SQLITE_NOMEM;
1384 memset(pNew, 0, sizeof(*pNew));
1385 }
1386 return rc;
drhcb6c6c62015-08-19 22:47:17 +00001387}
1388
1389/* destructor for json_each virtual table */
1390static int jsonEachDisconnect(sqlite3_vtab *pVtab){
1391 sqlite3_free(pVtab);
1392 return SQLITE_OK;
1393}
1394
drh505ad2c2015-08-21 17:33:11 +00001395/* constructor for a JsonEachCursor object for json_each(). */
1396static int jsonEachOpenEach(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
drhcb6c6c62015-08-19 22:47:17 +00001397 JsonEachCursor *pCur;
drh6fd5c1e2015-08-21 20:37:12 +00001398
1399 UNUSED_PARAM(p);
drhcb6c6c62015-08-19 22:47:17 +00001400 pCur = sqlite3_malloc( sizeof(*pCur) );
1401 if( pCur==0 ) return SQLITE_NOMEM;
1402 memset(pCur, 0, sizeof(*pCur));
1403 *ppCursor = &pCur->base;
1404 return SQLITE_OK;
1405}
1406
drh505ad2c2015-08-21 17:33:11 +00001407/* constructor for a JsonEachCursor object for json_tree(). */
1408static int jsonEachOpenTree(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
1409 int rc = jsonEachOpenEach(p, ppCursor);
1410 if( rc==SQLITE_OK ){
1411 JsonEachCursor *pCur = (JsonEachCursor*)*ppCursor;
1412 pCur->bRecursive = 1;
1413 }
1414 return rc;
1415}
1416
drhcb6c6c62015-08-19 22:47:17 +00001417/* Reset a JsonEachCursor back to its original state. Free any memory
1418** held. */
1419static void jsonEachCursorReset(JsonEachCursor *p){
1420 sqlite3_free(p->zJson);
1421 sqlite3_free(p->zPath);
drh505ad2c2015-08-21 17:33:11 +00001422 jsonParseReset(&p->sParse);
drhcb6c6c62015-08-19 22:47:17 +00001423 p->iRowid = 0;
1424 p->i = 0;
1425 p->iEnd = 0;
1426 p->eType = 0;
drhcb6c6c62015-08-19 22:47:17 +00001427 p->zJson = 0;
1428 p->zPath = 0;
1429}
1430
1431/* Destructor for a jsonEachCursor object */
1432static int jsonEachClose(sqlite3_vtab_cursor *cur){
1433 JsonEachCursor *p = (JsonEachCursor*)cur;
1434 jsonEachCursorReset(p);
1435 sqlite3_free(cur);
1436 return SQLITE_OK;
1437}
1438
1439/* Return TRUE if the jsonEachCursor object has been advanced off the end
1440** of the JSON object */
1441static int jsonEachEof(sqlite3_vtab_cursor *cur){
1442 JsonEachCursor *p = (JsonEachCursor*)cur;
1443 return p->i >= p->iEnd;
1444}
1445
drh505ad2c2015-08-21 17:33:11 +00001446/* Advance the cursor to the next element for json_tree() */
drh4af352d2015-08-21 20:02:48 +00001447static int jsonEachNext(sqlite3_vtab_cursor *cur){
drh505ad2c2015-08-21 17:33:11 +00001448 JsonEachCursor *p = (JsonEachCursor*)cur;
drh4af352d2015-08-21 20:02:48 +00001449 if( p->bRecursive ){
1450 if( p->i==0 ){
1451 p->i = 1;
drh4af352d2015-08-21 20:02:48 +00001452 }else{
drh8784eca2015-08-23 02:42:30 +00001453 u32 iUp = p->sParse.aUp[p->i];
1454 JsonNode *pUp = &p->sParse.aNode[iUp];
drh4af352d2015-08-21 20:02:48 +00001455 p->i++;
drh8784eca2015-08-23 02:42:30 +00001456 if( pUp->eType==JSON_OBJECT && (pUp->n + iUp >= p->i) ) p->i++;
drh4af352d2015-08-21 20:02:48 +00001457 }
1458 p->iRowid++;
1459 if( p->i<p->sParse.nNode ){
drh8784eca2015-08-23 02:42:30 +00001460 u32 iUp = p->sParse.aUp[p->i];
1461 JsonNode *pUp = &p->sParse.aNode[iUp];
drh4af352d2015-08-21 20:02:48 +00001462 p->eType = pUp->eType;
drh8784eca2015-08-23 02:42:30 +00001463 if( pUp->eType==JSON_ARRAY ){
1464 if( iUp==p->i-1 ){
1465 pUp->u.iKey = 0;
1466 }else{
1467 pUp->u.iKey++;
1468 }
drh4af352d2015-08-21 20:02:48 +00001469 }
1470 }
drh505ad2c2015-08-21 17:33:11 +00001471 }else{
drh4af352d2015-08-21 20:02:48 +00001472 switch( p->eType ){
1473 case JSON_ARRAY: {
1474 p->i += jsonNodeSize(&p->sParse.aNode[p->i]);
1475 p->iRowid++;
1476 break;
1477 }
1478 case JSON_OBJECT: {
1479 p->i += 1 + jsonNodeSize(&p->sParse.aNode[p->i+1]);
1480 p->iRowid++;
1481 break;
1482 }
1483 default: {
1484 p->i = p->iEnd;
1485 break;
1486 }
drh505ad2c2015-08-21 17:33:11 +00001487 }
1488 }
1489 return SQLITE_OK;
1490}
1491
drh4af352d2015-08-21 20:02:48 +00001492/* Append the name of the path for element i to pStr
1493*/
1494static void jsonEachComputePath(
1495 JsonEachCursor *p, /* The cursor */
1496 JsonString *pStr, /* Write the path here */
1497 u32 i /* Path to this element */
1498){
1499 JsonNode *pNode, *pUp;
1500 u32 iUp;
1501 if( i==0 ){
1502 jsonAppendChar(pStr, '$');
1503 return;
drhcb6c6c62015-08-19 22:47:17 +00001504 }
drh4af352d2015-08-21 20:02:48 +00001505 iUp = p->sParse.aUp[i];
1506 jsonEachComputePath(p, pStr, iUp);
1507 pNode = &p->sParse.aNode[i];
1508 pUp = &p->sParse.aNode[iUp];
1509 if( pUp->eType==JSON_ARRAY ){
1510 jsonPrintf(30, pStr, "[%d]", pUp->u.iKey);
1511 }else{
1512 assert( pUp->eType==JSON_OBJECT );
1513 if( pNode->eType>=JSON_ARRAY ) pNode--;
1514 assert( pNode->eType==JSON_STRING );
1515 jsonPrintf(pNode->n+1, pStr, ".%.*s", pNode->n-2, pNode->u.zJContent+1);
1516 }
drhcb6c6c62015-08-19 22:47:17 +00001517}
1518
1519/* Return the value of a column */
1520static int jsonEachColumn(
1521 sqlite3_vtab_cursor *cur, /* The cursor */
1522 sqlite3_context *ctx, /* First argument to sqlite3_result_...() */
1523 int i /* Which column to return */
1524){
1525 JsonEachCursor *p = (JsonEachCursor*)cur;
drh505ad2c2015-08-21 17:33:11 +00001526 JsonNode *pThis = &p->sParse.aNode[p->i];
drhcb6c6c62015-08-19 22:47:17 +00001527 switch( i ){
1528 case JEACH_KEY: {
drh8784eca2015-08-23 02:42:30 +00001529 if( p->i==0 ) break;
drhcb6c6c62015-08-19 22:47:17 +00001530 if( p->eType==JSON_OBJECT ){
drh505ad2c2015-08-21 17:33:11 +00001531 jsonReturn(pThis, ctx, 0);
1532 }else if( p->eType==JSON_ARRAY ){
1533 u32 iKey;
1534 if( p->bRecursive ){
1535 if( p->iRowid==0 ) break;
drh8784eca2015-08-23 02:42:30 +00001536 iKey = p->sParse.aNode[p->sParse.aUp[p->i]].u.iKey;
drh505ad2c2015-08-21 17:33:11 +00001537 }else{
1538 iKey = p->iRowid;
1539 }
drh6fd5c1e2015-08-21 20:37:12 +00001540 sqlite3_result_int64(ctx, (sqlite3_int64)iKey);
drhcb6c6c62015-08-19 22:47:17 +00001541 }
1542 break;
1543 }
1544 case JEACH_VALUE: {
drh8784eca2015-08-23 02:42:30 +00001545 if( p->eType==JSON_OBJECT && p->i>0 ) pThis++;
drh505ad2c2015-08-21 17:33:11 +00001546 jsonReturn(pThis, ctx, 0);
1547 break;
1548 }
1549 case JEACH_TYPE: {
drh442a7c62015-08-24 02:32:04 +00001550 if( p->eType==JSON_OBJECT && p->i>0 ) pThis++;
drh505ad2c2015-08-21 17:33:11 +00001551 sqlite3_result_text(ctx, jsonType[pThis->eType], -1, SQLITE_STATIC);
1552 break;
1553 }
1554 case JEACH_ATOM: {
drh442a7c62015-08-24 02:32:04 +00001555 if( p->eType==JSON_OBJECT && p->i>0 ) pThis++;
drh505ad2c2015-08-21 17:33:11 +00001556 if( pThis->eType>=JSON_ARRAY ) break;
1557 jsonReturn(pThis, ctx, 0);
1558 break;
1559 }
1560 case JEACH_ID: {
drh6fd5c1e2015-08-21 20:37:12 +00001561 sqlite3_result_int64(ctx, (sqlite3_int64)p->i + (p->eType==JSON_OBJECT));
drh505ad2c2015-08-21 17:33:11 +00001562 break;
1563 }
1564 case JEACH_PARENT: {
1565 if( p->i>0 && p->bRecursive ){
drh6fd5c1e2015-08-21 20:37:12 +00001566 sqlite3_result_int64(ctx, (sqlite3_int64)p->sParse.aUp[p->i]);
drhcb6c6c62015-08-19 22:47:17 +00001567 }
1568 break;
1569 }
drh4af352d2015-08-21 20:02:48 +00001570 case JEACH_FULLKEY: {
1571 JsonString x;
1572 jsonInit(&x, ctx);
1573 if( p->bRecursive ){
1574 jsonEachComputePath(p, &x, p->i);
1575 }else{
1576 if( p->zPath ){
1577 jsonAppendRaw(&x, p->zPath, (int)strlen(p->zPath));
1578 }else{
1579 jsonAppendChar(&x, '$');
1580 }
1581 if( p->eType==JSON_ARRAY ){
1582 jsonPrintf(30, &x, "[%d]", p->iRowid);
1583 }else{
1584 jsonPrintf(pThis->n, &x, ".%.*s", pThis->n-2, pThis->u.zJContent+1);
1585 }
1586 }
1587 jsonResult(&x);
1588 break;
1589 }
drhcb6c6c62015-08-19 22:47:17 +00001590 case JEACH_PATH: {
1591 const char *zPath = p->zPath;
drh4af352d2015-08-21 20:02:48 +00001592 if( zPath==0 ){
1593 if( p->bRecursive ){
1594 JsonString x;
1595 jsonInit(&x, ctx);
1596 jsonEachComputePath(p, &x, p->sParse.aUp[p->i]);
1597 jsonResult(&x);
1598 break;
1599 }
1600 zPath = "$";
1601 }
drhcb6c6c62015-08-19 22:47:17 +00001602 sqlite3_result_text(ctx, zPath, -1, SQLITE_STATIC);
1603 break;
1604 }
1605 default: {
drh505ad2c2015-08-21 17:33:11 +00001606 assert( i==JEACH_JSON );
drhcb6c6c62015-08-19 22:47:17 +00001607 sqlite3_result_text(ctx, p->sParse.zJson, -1, SQLITE_STATIC);
1608 break;
1609 }
1610 }
1611 return SQLITE_OK;
1612}
1613
1614/* Return the current rowid value */
1615static int jsonEachRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){
1616 JsonEachCursor *p = (JsonEachCursor*)cur;
1617 *pRowid = p->iRowid;
1618 return SQLITE_OK;
1619}
1620
1621/* The query strategy is to look for an equality constraint on the json
1622** column. Without such a constraint, the table cannot operate. idxNum is
1623** 1 if the constraint is found, 3 if the constraint and zPath are found,
1624** and 0 otherwise.
1625*/
1626static int jsonEachBestIndex(
1627 sqlite3_vtab *tab,
1628 sqlite3_index_info *pIdxInfo
1629){
1630 int i;
1631 int jsonIdx = -1;
1632 int pathIdx = -1;
1633 const struct sqlite3_index_constraint *pConstraint;
drh6fd5c1e2015-08-21 20:37:12 +00001634
1635 UNUSED_PARAM(tab);
drhcb6c6c62015-08-19 22:47:17 +00001636 pConstraint = pIdxInfo->aConstraint;
1637 for(i=0; i<pIdxInfo->nConstraint; i++, pConstraint++){
1638 if( pConstraint->usable==0 ) continue;
1639 if( pConstraint->op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue;
1640 switch( pConstraint->iColumn ){
1641 case JEACH_JSON: jsonIdx = i; break;
1642 case JEACH_PATH: pathIdx = i; break;
1643 default: /* no-op */ break;
1644 }
1645 }
1646 if( jsonIdx<0 ){
1647 pIdxInfo->idxNum = 0;
drh505ad2c2015-08-21 17:33:11 +00001648 pIdxInfo->estimatedCost = 1e99;
drhcb6c6c62015-08-19 22:47:17 +00001649 }else{
drh505ad2c2015-08-21 17:33:11 +00001650 pIdxInfo->estimatedCost = 1.0;
drhcb6c6c62015-08-19 22:47:17 +00001651 pIdxInfo->aConstraintUsage[jsonIdx].argvIndex = 1;
1652 pIdxInfo->aConstraintUsage[jsonIdx].omit = 1;
1653 if( pathIdx<0 ){
1654 pIdxInfo->idxNum = 1;
1655 }else{
1656 pIdxInfo->aConstraintUsage[pathIdx].argvIndex = 2;
1657 pIdxInfo->aConstraintUsage[pathIdx].omit = 1;
1658 pIdxInfo->idxNum = 3;
1659 }
1660 }
1661 return SQLITE_OK;
1662}
1663
1664/* Start a search on a new JSON string */
1665static int jsonEachFilter(
1666 sqlite3_vtab_cursor *cur,
1667 int idxNum, const char *idxStr,
1668 int argc, sqlite3_value **argv
1669){
1670 JsonEachCursor *p = (JsonEachCursor*)cur;
1671 const char *z;
1672 const char *zPath;
1673 sqlite3_int64 n;
1674
drh6fd5c1e2015-08-21 20:37:12 +00001675 UNUSED_PARAM(idxStr);
1676 UNUSED_PARAM(argc);
drhcb6c6c62015-08-19 22:47:17 +00001677 jsonEachCursorReset(p);
1678 if( idxNum==0 ) return SQLITE_OK;
1679 z = (const char*)sqlite3_value_text(argv[0]);
1680 if( z==0 ) return SQLITE_OK;
1681 if( idxNum&2 ){
1682 zPath = (const char*)sqlite3_value_text(argv[1]);
1683 if( zPath==0 || zPath[0]!='$' ) return SQLITE_OK;
1684 }
1685 n = sqlite3_value_bytes(argv[0]);
drh6fd5c1e2015-08-21 20:37:12 +00001686 p->zJson = sqlite3_malloc64( n+1 );
drhcb6c6c62015-08-19 22:47:17 +00001687 if( p->zJson==0 ) return SQLITE_NOMEM;
drh6fd5c1e2015-08-21 20:37:12 +00001688 memcpy(p->zJson, z, (size_t)n+1);
drhbc8f0922015-08-22 19:39:04 +00001689 if( jsonParse(&p->sParse, 0, p->zJson)
drh505ad2c2015-08-21 17:33:11 +00001690 || (p->bRecursive && jsonParseFindParents(&p->sParse))
1691 ){
drhcb6c6c62015-08-19 22:47:17 +00001692 jsonEachCursorReset(p);
1693 }else{
1694 JsonNode *pNode;
1695 if( idxNum==3 ){
drh4af352d2015-08-21 20:02:48 +00001696 p->bRecursive = 0;
drhcb6c6c62015-08-19 22:47:17 +00001697 n = sqlite3_value_bytes(argv[1]);
drh6fd5c1e2015-08-21 20:37:12 +00001698 p->zPath = sqlite3_malloc64( n+1 );
drhcb6c6c62015-08-19 22:47:17 +00001699 if( p->zPath==0 ) return SQLITE_NOMEM;
drh6fd5c1e2015-08-21 20:37:12 +00001700 memcpy(p->zPath, zPath, (size_t)n+1);
drhcb6c6c62015-08-19 22:47:17 +00001701 pNode = jsonLookup(&p->sParse, 0, p->zPath+1, 0);
1702 if( pNode==0 ){
1703 jsonEachCursorReset(p);
1704 return SQLITE_OK;
1705 }
1706 }else{
1707 pNode = p->sParse.aNode;
1708 }
1709 p->i = (int)(pNode - p->sParse.aNode);
1710 p->eType = pNode->eType;
1711 if( p->eType>=JSON_ARRAY ){
drh8784eca2015-08-23 02:42:30 +00001712 pNode->u.iKey = 0;
drhc3722b22015-08-23 20:44:59 +00001713 p->iEnd = p->i + pNode->n + 1;
drh8784eca2015-08-23 02:42:30 +00001714 if( !p->bRecursive ) p->i++;
drhcb6c6c62015-08-19 22:47:17 +00001715 }else{
1716 p->iEnd = p->i+1;
1717 }
1718 }
drhbc8f0922015-08-22 19:39:04 +00001719 return p->sParse.oom ? SQLITE_NOMEM : SQLITE_OK;
drhcb6c6c62015-08-19 22:47:17 +00001720}
1721
1722/* The methods of the json_each virtual table */
1723static sqlite3_module jsonEachModule = {
1724 0, /* iVersion */
1725 0, /* xCreate */
1726 jsonEachConnect, /* xConnect */
1727 jsonEachBestIndex, /* xBestIndex */
1728 jsonEachDisconnect, /* xDisconnect */
1729 0, /* xDestroy */
drh505ad2c2015-08-21 17:33:11 +00001730 jsonEachOpenEach, /* xOpen - open a cursor */
drhcb6c6c62015-08-19 22:47:17 +00001731 jsonEachClose, /* xClose - close a cursor */
1732 jsonEachFilter, /* xFilter - configure scan constraints */
drh4af352d2015-08-21 20:02:48 +00001733 jsonEachNext, /* xNext - advance a cursor */
drhcb6c6c62015-08-19 22:47:17 +00001734 jsonEachEof, /* xEof - check for end of scan */
1735 jsonEachColumn, /* xColumn - read data */
1736 jsonEachRowid, /* xRowid - read data */
1737 0, /* xUpdate */
1738 0, /* xBegin */
1739 0, /* xSync */
1740 0, /* xCommit */
1741 0, /* xRollback */
1742 0, /* xFindMethod */
1743 0, /* xRename */
drh6fd5c1e2015-08-21 20:37:12 +00001744 0, /* xSavepoint */
1745 0, /* xRelease */
1746 0 /* xRollbackTo */
drhcb6c6c62015-08-19 22:47:17 +00001747};
1748
drh505ad2c2015-08-21 17:33:11 +00001749/* The methods of the json_tree virtual table. */
1750static sqlite3_module jsonTreeModule = {
1751 0, /* iVersion */
1752 0, /* xCreate */
1753 jsonEachConnect, /* xConnect */
1754 jsonEachBestIndex, /* xBestIndex */
1755 jsonEachDisconnect, /* xDisconnect */
1756 0, /* xDestroy */
1757 jsonEachOpenTree, /* xOpen - open a cursor */
1758 jsonEachClose, /* xClose - close a cursor */
1759 jsonEachFilter, /* xFilter - configure scan constraints */
drh4af352d2015-08-21 20:02:48 +00001760 jsonEachNext, /* xNext - advance a cursor */
drh505ad2c2015-08-21 17:33:11 +00001761 jsonEachEof, /* xEof - check for end of scan */
1762 jsonEachColumn, /* xColumn - read data */
1763 jsonEachRowid, /* xRowid - read data */
1764 0, /* xUpdate */
1765 0, /* xBegin */
1766 0, /* xSync */
1767 0, /* xCommit */
1768 0, /* xRollback */
1769 0, /* xFindMethod */
1770 0, /* xRename */
drh6fd5c1e2015-08-21 20:37:12 +00001771 0, /* xSavepoint */
1772 0, /* xRelease */
1773 0 /* xRollbackTo */
drh505ad2c2015-08-21 17:33:11 +00001774};
1775
1776/****************************************************************************
1777** The following routine is the only publically visible identifier in this
1778** file. Call the following routine in order to register the various SQL
1779** functions and the virtual table implemented by this file.
1780****************************************************************************/
drhcb6c6c62015-08-19 22:47:17 +00001781
drh5fa5c102015-08-12 16:49:40 +00001782#ifdef _WIN32
1783__declspec(dllexport)
1784#endif
1785int sqlite3_json_init(
1786 sqlite3 *db,
1787 char **pzErrMsg,
1788 const sqlite3_api_routines *pApi
1789){
1790 int rc = SQLITE_OK;
drh6fd5c1e2015-08-21 20:37:12 +00001791 unsigned int i;
drh5fa5c102015-08-12 16:49:40 +00001792 static const struct {
1793 const char *zName;
1794 int nArg;
drh52216ad2015-08-18 02:28:03 +00001795 int flag;
drh5fa5c102015-08-12 16:49:40 +00001796 void (*xFunc)(sqlite3_context*,int,sqlite3_value**);
1797 } aFunc[] = {
drh52216ad2015-08-18 02:28:03 +00001798 { "json_array", -1, 0, jsonArrayFunc },
1799 { "json_array_length", 1, 0, jsonArrayLengthFunc },
1800 { "json_array_length", 2, 0, jsonArrayLengthFunc },
1801 { "json_extract", 2, 0, jsonExtractFunc },
1802 { "json_insert", -1, 0, jsonSetFunc },
1803 { "json_object", -1, 0, jsonObjectFunc },
1804 { "json_remove", -1, 0, jsonRemoveFunc },
1805 { "json_replace", -1, 0, jsonReplaceFunc },
1806 { "json_set", -1, 1, jsonSetFunc },
1807 { "json_type", 1, 0, jsonTypeFunc },
1808 { "json_type", 2, 0, jsonTypeFunc },
drhbc8f0922015-08-22 19:39:04 +00001809 { "json_valid", 1, 0, jsonValidFunc },
drh987eb1f2015-08-17 15:17:37 +00001810
drh301eecc2015-08-17 20:14:19 +00001811#if SQLITE_DEBUG
drh987eb1f2015-08-17 15:17:37 +00001812 /* DEBUG and TESTING functions */
drh52216ad2015-08-18 02:28:03 +00001813 { "json_parse", 1, 0, jsonParseFunc },
1814 { "json_test1", 1, 0, jsonTest1Func },
1815 { "json_nodecount", 1, 0, jsonNodeCountFunc },
drh301eecc2015-08-17 20:14:19 +00001816#endif
drh5fa5c102015-08-12 16:49:40 +00001817 };
drh505ad2c2015-08-21 17:33:11 +00001818 static const struct {
1819 const char *zName;
1820 sqlite3_module *pModule;
1821 } aMod[] = {
1822 { "json_each", &jsonEachModule },
1823 { "json_tree", &jsonTreeModule },
1824 };
drh5fa5c102015-08-12 16:49:40 +00001825 SQLITE_EXTENSION_INIT2(pApi);
1826 (void)pzErrMsg; /* Unused parameter */
1827 for(i=0; i<sizeof(aFunc)/sizeof(aFunc[0]) && rc==SQLITE_OK; i++){
1828 rc = sqlite3_create_function(db, aFunc[i].zName, aFunc[i].nArg,
drh52216ad2015-08-18 02:28:03 +00001829 SQLITE_UTF8 | SQLITE_DETERMINISTIC,
1830 (void*)&aFunc[i].flag,
drh5fa5c102015-08-12 16:49:40 +00001831 aFunc[i].xFunc, 0, 0);
1832 }
drh505ad2c2015-08-21 17:33:11 +00001833 for(i=0; i<sizeof(aMod)/sizeof(aMod[0]) && rc==SQLITE_OK; i++){
1834 rc = sqlite3_create_module(db, aMod[i].zName, aMod[i].pModule, 0);
drhcb6c6c62015-08-19 22:47:17 +00001835 }
drh5fa5c102015-08-12 16:49:40 +00001836 return rc;
1837}