blob: ca6021733c83497ec8892a240c66b5317659e890 [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
drhf5ddb9c2015-09-11 00:06:41 +000071/* The "subtype" set for JSON values */
72#define JSON_SUBTYPE 74 /* Ascii for "J" */
73
drh987eb1f2015-08-17 15:17:37 +000074/*
75** Names of the various JSON types:
76*/
77static const char * const jsonType[] = {
78 "null", "true", "false", "integer", "real", "text", "array", "object"
79};
80
drh301eecc2015-08-17 20:14:19 +000081/* Bit values for the JsonNode.jnFlag field
82*/
83#define JNODE_RAW 0x01 /* Content is raw, not JSON encoded */
84#define JNODE_ESCAPE 0x02 /* Content is text with \ escapes */
85#define JNODE_REMOVE 0x04 /* Do not output */
drhd0960592015-08-17 21:22:32 +000086#define JNODE_REPLACE 0x08 /* Replace with JsonNode.iVal */
drh52216ad2015-08-18 02:28:03 +000087#define JNODE_APPEND 0x10 /* More ARRAY/OBJECT entries at u.iAppend */
drhf5ddb9c2015-09-11 00:06:41 +000088#define JNODE_LABEL 0x20 /* Is a label of an object */
drh301eecc2015-08-17 20:14:19 +000089
drh987eb1f2015-08-17 15:17:37 +000090
drhe9c37f32015-08-15 21:25:36 +000091/* A single node of parsed JSON
92*/
drhe9c37f32015-08-15 21:25:36 +000093struct JsonNode {
drh5634cc02015-08-17 11:28:03 +000094 u8 eType; /* One of the JSON_ type values */
drh301eecc2015-08-17 20:14:19 +000095 u8 jnFlags; /* JNODE flags */
drhd0960592015-08-17 21:22:32 +000096 u8 iVal; /* Replacement value when JNODE_REPLACE */
drhe9c37f32015-08-15 21:25:36 +000097 u32 n; /* Bytes of content, or number of sub-nodes */
drh52216ad2015-08-18 02:28:03 +000098 union {
drh0042a972015-08-18 12:59:58 +000099 const char *zJContent; /* Content for INT, REAL, and STRING */
100 u32 iAppend; /* More terms for ARRAY and OBJECT */
drh505ad2c2015-08-21 17:33:11 +0000101 u32 iKey; /* Key for ARRAY objects in json_tree() */
drh52216ad2015-08-18 02:28:03 +0000102 } u;
drhe9c37f32015-08-15 21:25:36 +0000103};
104
105/* A completely parsed JSON string
106*/
drhe9c37f32015-08-15 21:25:36 +0000107struct JsonParse {
108 u32 nNode; /* Number of slots of aNode[] used */
109 u32 nAlloc; /* Number of slots of aNode[] allocated */
110 JsonNode *aNode; /* Array of nodes containing the parse */
111 const char *zJson; /* Original JSON string */
drh505ad2c2015-08-21 17:33:11 +0000112 u32 *aUp; /* Index of parent of each node */
drhe9c37f32015-08-15 21:25:36 +0000113 u8 oom; /* Set to true if out of memory */
drha7714022015-08-29 00:54:49 +0000114 u8 nErr; /* Number of errors seen */
drhe9c37f32015-08-15 21:25:36 +0000115};
116
drh505ad2c2015-08-21 17:33:11 +0000117/**************************************************************************
118** Utility routines for dealing with JsonString objects
119**************************************************************************/
drh301eecc2015-08-17 20:14:19 +0000120
drh505ad2c2015-08-21 17:33:11 +0000121/* Set the JsonString object to an empty string
drh5fa5c102015-08-12 16:49:40 +0000122*/
drh505ad2c2015-08-21 17:33:11 +0000123static void jsonZero(JsonString *p){
drh5fa5c102015-08-12 16:49:40 +0000124 p->zBuf = p->zSpace;
125 p->nAlloc = sizeof(p->zSpace);
126 p->nUsed = 0;
127 p->bStatic = 1;
128}
129
drh505ad2c2015-08-21 17:33:11 +0000130/* Initialize the JsonString object
drh5fa5c102015-08-12 16:49:40 +0000131*/
drh505ad2c2015-08-21 17:33:11 +0000132static void jsonInit(JsonString *p, sqlite3_context *pCtx){
drh5fa5c102015-08-12 16:49:40 +0000133 p->pCtx = pCtx;
drhd0960592015-08-17 21:22:32 +0000134 p->bErr = 0;
drh5fa5c102015-08-12 16:49:40 +0000135 jsonZero(p);
136}
137
138
drh505ad2c2015-08-21 17:33:11 +0000139/* Free all allocated memory and reset the JsonString object back to its
drh5fa5c102015-08-12 16:49:40 +0000140** initial state.
141*/
drh505ad2c2015-08-21 17:33:11 +0000142static void jsonReset(JsonString *p){
drh5fa5c102015-08-12 16:49:40 +0000143 if( !p->bStatic ) sqlite3_free(p->zBuf);
144 jsonZero(p);
145}
146
147
148/* Report an out-of-memory (OOM) condition
149*/
drh505ad2c2015-08-21 17:33:11 +0000150static void jsonOom(JsonString *p){
drhd0960592015-08-17 21:22:32 +0000151 if( !p->bErr ){
152 p->bErr = 1;
153 sqlite3_result_error_nomem(p->pCtx);
154 jsonReset(p);
155 }
drh5fa5c102015-08-12 16:49:40 +0000156}
157
158/* Enlarge pJson->zBuf so that it can hold at least N more bytes.
159** Return zero on success. Return non-zero on an OOM error
160*/
drh505ad2c2015-08-21 17:33:11 +0000161static int jsonGrow(JsonString *p, u32 N){
drh301eecc2015-08-17 20:14:19 +0000162 u64 nTotal = N<p->nAlloc ? p->nAlloc*2 : p->nAlloc+N+10;
drh5fa5c102015-08-12 16:49:40 +0000163 char *zNew;
164 if( p->bStatic ){
drhd0960592015-08-17 21:22:32 +0000165 if( p->bErr ) return 1;
drh5fa5c102015-08-12 16:49:40 +0000166 zNew = sqlite3_malloc64(nTotal);
167 if( zNew==0 ){
168 jsonOom(p);
169 return SQLITE_NOMEM;
170 }
drh6fd5c1e2015-08-21 20:37:12 +0000171 memcpy(zNew, p->zBuf, (size_t)p->nUsed);
drh5fa5c102015-08-12 16:49:40 +0000172 p->zBuf = zNew;
173 p->bStatic = 0;
174 }else{
175 zNew = sqlite3_realloc64(p->zBuf, nTotal);
176 if( zNew==0 ){
177 jsonOom(p);
178 return SQLITE_NOMEM;
179 }
180 p->zBuf = zNew;
181 }
182 p->nAlloc = nTotal;
183 return SQLITE_OK;
184}
185
drh505ad2c2015-08-21 17:33:11 +0000186/* Append N bytes from zIn onto the end of the JsonString string.
drh5fa5c102015-08-12 16:49:40 +0000187*/
drh505ad2c2015-08-21 17:33:11 +0000188static void jsonAppendRaw(JsonString *p, const char *zIn, u32 N){
drh5fa5c102015-08-12 16:49:40 +0000189 if( (N+p->nUsed >= p->nAlloc) && jsonGrow(p,N)!=0 ) return;
190 memcpy(p->zBuf+p->nUsed, zIn, N);
191 p->nUsed += N;
192}
193
drh4af352d2015-08-21 20:02:48 +0000194/* Append formatted text (not to exceed N bytes) to the JsonString.
195*/
196static void jsonPrintf(int N, JsonString *p, const char *zFormat, ...){
197 va_list ap;
198 if( (p->nUsed + N >= p->nAlloc) && jsonGrow(p, N) ) return;
199 va_start(ap, zFormat);
200 sqlite3_vsnprintf(N, p->zBuf+p->nUsed, zFormat, ap);
201 va_end(ap);
202 p->nUsed += (int)strlen(p->zBuf+p->nUsed);
203}
204
drh5634cc02015-08-17 11:28:03 +0000205/* Append a single character
206*/
drh505ad2c2015-08-21 17:33:11 +0000207static void jsonAppendChar(JsonString *p, char c){
drh5634cc02015-08-17 11:28:03 +0000208 if( p->nUsed>=p->nAlloc && jsonGrow(p,1)!=0 ) return;
209 p->zBuf[p->nUsed++] = c;
210}
211
drh301eecc2015-08-17 20:14:19 +0000212/* Append a comma separator to the output buffer, if the previous
213** character is not '[' or '{'.
214*/
drh505ad2c2015-08-21 17:33:11 +0000215static void jsonAppendSeparator(JsonString *p){
drh301eecc2015-08-17 20:14:19 +0000216 char c;
217 if( p->nUsed==0 ) return;
218 c = p->zBuf[p->nUsed-1];
219 if( c!='[' && c!='{' ) jsonAppendChar(p, ',');
220}
221
drh505ad2c2015-08-21 17:33:11 +0000222/* Append the N-byte string in zIn to the end of the JsonString string
drh5fa5c102015-08-12 16:49:40 +0000223** under construction. Enclose the string in "..." and escape
224** any double-quotes or backslash characters contained within the
225** string.
226*/
drh505ad2c2015-08-21 17:33:11 +0000227static void jsonAppendString(JsonString *p, const char *zIn, u32 N){
drh5fa5c102015-08-12 16:49:40 +0000228 u32 i;
229 if( (N+p->nUsed+2 >= p->nAlloc) && jsonGrow(p,N+2)!=0 ) return;
230 p->zBuf[p->nUsed++] = '"';
231 for(i=0; i<N; i++){
232 char c = zIn[i];
233 if( c=='"' || c=='\\' ){
234 if( (p->nUsed+N+1-i > p->nAlloc) && jsonGrow(p,N+1-i)!=0 ) return;
235 p->zBuf[p->nUsed++] = '\\';
236 }
237 p->zBuf[p->nUsed++] = c;
238 }
239 p->zBuf[p->nUsed++] = '"';
240}
241
drhd0960592015-08-17 21:22:32 +0000242/*
243** Append a function parameter value to the JSON string under
244** construction.
245*/
246static void jsonAppendValue(
drh505ad2c2015-08-21 17:33:11 +0000247 JsonString *p, /* Append to this JSON string */
drhf5ddb9c2015-09-11 00:06:41 +0000248 sqlite3_value *pValue /* Value to append */
drhd0960592015-08-17 21:22:32 +0000249){
250 switch( sqlite3_value_type(pValue) ){
251 case SQLITE_NULL: {
252 jsonAppendRaw(p, "null", 4);
253 break;
254 }
255 case SQLITE_INTEGER:
256 case SQLITE_FLOAT: {
257 const char *z = (const char*)sqlite3_value_text(pValue);
258 u32 n = (u32)sqlite3_value_bytes(pValue);
259 jsonAppendRaw(p, z, n);
260 break;
261 }
262 case SQLITE_TEXT: {
263 const char *z = (const char*)sqlite3_value_text(pValue);
264 u32 n = (u32)sqlite3_value_bytes(pValue);
drhf5ddb9c2015-09-11 00:06:41 +0000265 if( sqlite3_value_subtype(pValue)==JSON_SUBTYPE ){
drhecb5fed2015-08-28 03:33:50 +0000266 jsonAppendRaw(p, z, n);
267 }else{
268 jsonAppendString(p, z, n);
269 }
drhd0960592015-08-17 21:22:32 +0000270 break;
271 }
272 default: {
273 if( p->bErr==0 ){
274 sqlite3_result_error(p->pCtx, "JSON cannot hold BLOB values", -1);
275 p->bErr = 1;
276 jsonReset(p);
277 }
278 break;
279 }
280 }
281}
282
283
drhbd0621b2015-08-13 13:54:59 +0000284/* Make the JSON in p the result of the SQL function.
drh5fa5c102015-08-12 16:49:40 +0000285*/
drh505ad2c2015-08-21 17:33:11 +0000286static void jsonResult(JsonString *p){
drhd0960592015-08-17 21:22:32 +0000287 if( p->bErr==0 ){
drh5fa5c102015-08-12 16:49:40 +0000288 sqlite3_result_text64(p->pCtx, p->zBuf, p->nUsed,
289 p->bStatic ? SQLITE_TRANSIENT : sqlite3_free,
290 SQLITE_UTF8);
291 jsonZero(p);
292 }
293 assert( p->bStatic );
294}
295
drh505ad2c2015-08-21 17:33:11 +0000296/**************************************************************************
297** Utility routines for dealing with JsonNode and JsonParse objects
298**************************************************************************/
299
300/*
301** Return the number of consecutive JsonNode slots need to represent
302** the parsed JSON at pNode. The minimum answer is 1. For ARRAY and
303** OBJECT types, the number might be larger.
304**
305** Appended elements are not counted. The value returned is the number
306** by which the JsonNode counter should increment in order to go to the
307** next peer value.
308*/
309static u32 jsonNodeSize(JsonNode *pNode){
310 return pNode->eType>=JSON_ARRAY ? pNode->n+1 : 1;
311}
312
313/*
314** Reclaim all memory allocated by a JsonParse object. But do not
315** delete the JsonParse object itself.
316*/
317static void jsonParseReset(JsonParse *pParse){
318 sqlite3_free(pParse->aNode);
319 pParse->aNode = 0;
320 pParse->nNode = 0;
321 pParse->nAlloc = 0;
322 sqlite3_free(pParse->aUp);
323 pParse->aUp = 0;
324}
325
drh5634cc02015-08-17 11:28:03 +0000326/*
327** Convert the JsonNode pNode into a pure JSON string and
328** append to pOut. Subsubstructure is also included. Return
329** the number of JsonNode objects that are encoded.
drhbd0621b2015-08-13 13:54:59 +0000330*/
drh52216ad2015-08-18 02:28:03 +0000331static void jsonRenderNode(
drhd0960592015-08-17 21:22:32 +0000332 JsonNode *pNode, /* The node to render */
drh505ad2c2015-08-21 17:33:11 +0000333 JsonString *pOut, /* Write JSON here */
drhd0960592015-08-17 21:22:32 +0000334 sqlite3_value **aReplace /* Replacement values */
335){
drh5634cc02015-08-17 11:28:03 +0000336 switch( pNode->eType ){
337 case JSON_NULL: {
338 jsonAppendRaw(pOut, "null", 4);
339 break;
340 }
341 case JSON_TRUE: {
342 jsonAppendRaw(pOut, "true", 4);
343 break;
344 }
345 case JSON_FALSE: {
346 jsonAppendRaw(pOut, "false", 5);
347 break;
348 }
349 case JSON_STRING: {
drh301eecc2015-08-17 20:14:19 +0000350 if( pNode->jnFlags & JNODE_RAW ){
drh52216ad2015-08-18 02:28:03 +0000351 jsonAppendString(pOut, pNode->u.zJContent, pNode->n);
drh5634cc02015-08-17 11:28:03 +0000352 break;
353 }
354 /* Fall through into the next case */
355 }
356 case JSON_REAL:
357 case JSON_INT: {
drh52216ad2015-08-18 02:28:03 +0000358 jsonAppendRaw(pOut, pNode->u.zJContent, pNode->n);
drh5634cc02015-08-17 11:28:03 +0000359 break;
360 }
361 case JSON_ARRAY: {
drh52216ad2015-08-18 02:28:03 +0000362 u32 j = 1;
drh5634cc02015-08-17 11:28:03 +0000363 jsonAppendChar(pOut, '[');
drh52216ad2015-08-18 02:28:03 +0000364 for(;;){
365 while( j<=pNode->n ){
366 if( pNode[j].jnFlags & (JNODE_REMOVE|JNODE_REPLACE) ){
367 if( pNode[j].jnFlags & JNODE_REPLACE ){
368 jsonAppendSeparator(pOut);
drhf5ddb9c2015-09-11 00:06:41 +0000369 jsonAppendValue(pOut, aReplace[pNode[j].iVal]);
drh52216ad2015-08-18 02:28:03 +0000370 }
371 }else{
drhd0960592015-08-17 21:22:32 +0000372 jsonAppendSeparator(pOut);
drh52216ad2015-08-18 02:28:03 +0000373 jsonRenderNode(&pNode[j], pOut, aReplace);
drhd0960592015-08-17 21:22:32 +0000374 }
drh505ad2c2015-08-21 17:33:11 +0000375 j += jsonNodeSize(&pNode[j]);
drh301eecc2015-08-17 20:14:19 +0000376 }
drh52216ad2015-08-18 02:28:03 +0000377 if( (pNode->jnFlags & JNODE_APPEND)==0 ) break;
378 pNode = &pNode[pNode->u.iAppend];
379 j = 1;
drh5634cc02015-08-17 11:28:03 +0000380 }
381 jsonAppendChar(pOut, ']');
382 break;
383 }
384 case JSON_OBJECT: {
drh52216ad2015-08-18 02:28:03 +0000385 u32 j = 1;
drh5634cc02015-08-17 11:28:03 +0000386 jsonAppendChar(pOut, '{');
drh52216ad2015-08-18 02:28:03 +0000387 for(;;){
388 while( j<=pNode->n ){
389 if( (pNode[j+1].jnFlags & JNODE_REMOVE)==0 ){
390 jsonAppendSeparator(pOut);
391 jsonRenderNode(&pNode[j], pOut, aReplace);
392 jsonAppendChar(pOut, ':');
393 if( pNode[j+1].jnFlags & JNODE_REPLACE ){
drhf5ddb9c2015-09-11 00:06:41 +0000394 jsonAppendValue(pOut, aReplace[pNode[j+1].iVal]);
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);
drhf5ddb9c2015-09-11 00:06:41 +0000423 sqlite3_result_subtype(pCtx, JSON_SUBTYPE);
drhf2df7e72015-08-28 20:07:40 +0000424}
425
426/*
drh5634cc02015-08-17 11:28:03 +0000427** Make the JsonNode the return value of the function.
428*/
drhd0960592015-08-17 21:22:32 +0000429static void jsonReturn(
430 JsonNode *pNode, /* Node to return */
431 sqlite3_context *pCtx, /* Return value for this function */
432 sqlite3_value **aReplace /* Array of replacement values */
433){
drh5634cc02015-08-17 11:28:03 +0000434 switch( pNode->eType ){
435 case JSON_NULL: {
436 sqlite3_result_null(pCtx);
437 break;
438 }
439 case JSON_TRUE: {
440 sqlite3_result_int(pCtx, 1);
441 break;
442 }
443 case JSON_FALSE: {
444 sqlite3_result_int(pCtx, 0);
445 break;
446 }
drh987eb1f2015-08-17 15:17:37 +0000447 case JSON_REAL: {
drh52216ad2015-08-18 02:28:03 +0000448 double r = strtod(pNode->u.zJContent, 0);
drh987eb1f2015-08-17 15:17:37 +0000449 sqlite3_result_double(pCtx, r);
drh5634cc02015-08-17 11:28:03 +0000450 break;
451 }
drh987eb1f2015-08-17 15:17:37 +0000452 case JSON_INT: {
453 sqlite3_int64 i = 0;
drh52216ad2015-08-18 02:28:03 +0000454 const char *z = pNode->u.zJContent;
drh987eb1f2015-08-17 15:17:37 +0000455 if( z[0]=='-' ){ z++; }
456 while( z[0]>='0' && z[0]<='9' ){ i = i*10 + *(z++) - '0'; }
drh52216ad2015-08-18 02:28:03 +0000457 if( pNode->u.zJContent[0]=='-' ){ i = -i; }
drh987eb1f2015-08-17 15:17:37 +0000458 sqlite3_result_int64(pCtx, i);
459 break;
460 }
drh5634cc02015-08-17 11:28:03 +0000461 case JSON_STRING: {
drh301eecc2015-08-17 20:14:19 +0000462 if( pNode->jnFlags & JNODE_RAW ){
drh52216ad2015-08-18 02:28:03 +0000463 sqlite3_result_text(pCtx, pNode->u.zJContent, pNode->n,
464 SQLITE_TRANSIENT);
drh301eecc2015-08-17 20:14:19 +0000465 }else if( (pNode->jnFlags & JNODE_ESCAPE)==0 ){
drh987eb1f2015-08-17 15:17:37 +0000466 /* JSON formatted without any backslash-escapes */
drh52216ad2015-08-18 02:28:03 +0000467 sqlite3_result_text(pCtx, pNode->u.zJContent+1, pNode->n-2,
drh987eb1f2015-08-17 15:17:37 +0000468 SQLITE_TRANSIENT);
drh5634cc02015-08-17 11:28:03 +0000469 }else{
470 /* Translate JSON formatted string into raw text */
drh987eb1f2015-08-17 15:17:37 +0000471 u32 i;
472 u32 n = pNode->n;
drh52216ad2015-08-18 02:28:03 +0000473 const char *z = pNode->u.zJContent;
drh987eb1f2015-08-17 15:17:37 +0000474 char *zOut;
475 u32 j;
476 zOut = sqlite3_malloc( n+1 );
477 if( zOut==0 ){
478 sqlite3_result_error_nomem(pCtx);
479 break;
480 }
481 for(i=1, j=0; i<n-1; i++){
482 char c = z[i];
drh80d87402015-08-24 12:42:41 +0000483 if( c!='\\' ){
drh987eb1f2015-08-17 15:17:37 +0000484 zOut[j++] = c;
485 }else{
486 c = z[++i];
drh80d87402015-08-24 12:42:41 +0000487 if( c=='u' ){
drh987eb1f2015-08-17 15:17:37 +0000488 u32 v = 0, k;
drh80d87402015-08-24 12:42:41 +0000489 for(k=0; k<4 && i<n-2; i++, k++){
drh8784eca2015-08-23 02:42:30 +0000490 c = z[i+1];
drh987eb1f2015-08-17 15:17:37 +0000491 if( c>='0' && c<='9' ) v = v*16 + c - '0';
492 else if( c>='A' && c<='F' ) v = v*16 + c - 'A' + 10;
493 else if( c>='a' && c<='f' ) v = v*16 + c - 'a' + 10;
494 else break;
drh987eb1f2015-08-17 15:17:37 +0000495 }
drh80d87402015-08-24 12:42:41 +0000496 if( v==0 ) break;
drh987eb1f2015-08-17 15:17:37 +0000497 if( v<=0x7f ){
mistachkin16a93122015-09-11 18:05:01 +0000498 zOut[j++] = (char)v;
drh987eb1f2015-08-17 15:17:37 +0000499 }else if( v<=0x7ff ){
mistachkin16a93122015-09-11 18:05:01 +0000500 zOut[j++] = (char)(0xc0 | (v>>6));
drh987eb1f2015-08-17 15:17:37 +0000501 zOut[j++] = 0x80 | (v&0x3f);
drh80d87402015-08-24 12:42:41 +0000502 }else{
mistachkin16a93122015-09-11 18:05:01 +0000503 zOut[j++] = (char)(0xe0 | (v>>12));
drh987eb1f2015-08-17 15:17:37 +0000504 zOut[j++] = 0x80 | ((v>>6)&0x3f);
505 zOut[j++] = 0x80 | (v&0x3f);
drh987eb1f2015-08-17 15:17:37 +0000506 }
507 }else{
508 if( c=='b' ){
509 c = '\b';
510 }else if( c=='f' ){
511 c = '\f';
512 }else if( c=='n' ){
513 c = '\n';
514 }else if( c=='r' ){
515 c = '\r';
516 }else if( c=='t' ){
517 c = '\t';
518 }
519 zOut[j++] = c;
520 }
521 }
522 }
523 zOut[j] = 0;
524 sqlite3_result_text(pCtx, zOut, j, sqlite3_free);
drh5634cc02015-08-17 11:28:03 +0000525 }
526 break;
527 }
528 case JSON_ARRAY:
529 case JSON_OBJECT: {
drhf2df7e72015-08-28 20:07:40 +0000530 jsonReturnJson(pNode, pCtx, aReplace);
drh5634cc02015-08-17 11:28:03 +0000531 break;
532 }
533 }
drhbd0621b2015-08-13 13:54:59 +0000534}
535
drh5fa5c102015-08-12 16:49:40 +0000536/*
drhe9c37f32015-08-15 21:25:36 +0000537** Create a new JsonNode instance based on the arguments and append that
538** instance to the JsonParse. Return the index in pParse->aNode[] of the
539** new node, or -1 if a memory allocation fails.
540*/
541static int jsonParseAddNode(
542 JsonParse *pParse, /* Append the node to this object */
543 u32 eType, /* Node type */
544 u32 n, /* Content size or sub-node count */
545 const char *zContent /* Content */
546){
547 JsonNode *p;
548 if( pParse->nNode>=pParse->nAlloc ){
549 u32 nNew;
550 JsonNode *pNew;
551 if( pParse->oom ) return -1;
552 nNew = pParse->nAlloc*2 + 10;
553 if( nNew<=pParse->nNode ){
554 pParse->oom = 1;
555 return -1;
556 }
557 pNew = sqlite3_realloc(pParse->aNode, sizeof(JsonNode)*nNew);
558 if( pNew==0 ){
559 pParse->oom = 1;
560 return -1;
561 }
562 pParse->nAlloc = nNew;
563 pParse->aNode = pNew;
564 }
565 p = &pParse->aNode[pParse->nNode];
drh5634cc02015-08-17 11:28:03 +0000566 p->eType = (u8)eType;
drh301eecc2015-08-17 20:14:19 +0000567 p->jnFlags = 0;
drhd0960592015-08-17 21:22:32 +0000568 p->iVal = 0;
drhe9c37f32015-08-15 21:25:36 +0000569 p->n = n;
drh52216ad2015-08-18 02:28:03 +0000570 p->u.zJContent = zContent;
drhe9c37f32015-08-15 21:25:36 +0000571 return pParse->nNode++;
572}
573
574/*
575** Parse a single JSON value which begins at pParse->zJson[i]. Return the
576** index of the first character past the end of the value parsed.
577**
578** Return negative for a syntax error. Special cases: return -2 if the
579** first non-whitespace character is '}' and return -3 if the first
580** non-whitespace character is ']'.
581*/
582static int jsonParseValue(JsonParse *pParse, u32 i){
583 char c;
584 u32 j;
drhbc8f0922015-08-22 19:39:04 +0000585 int iThis;
drhe9c37f32015-08-15 21:25:36 +0000586 int x;
drh852944e2015-09-10 03:29:11 +0000587 JsonNode *pNode;
drhe9c37f32015-08-15 21:25:36 +0000588 while( isspace(pParse->zJson[i]) ){ i++; }
589 if( (c = pParse->zJson[i])==0 ) return 0;
590 if( c=='{' ){
591 /* Parse object */
592 iThis = jsonParseAddNode(pParse, JSON_OBJECT, 0, 0);
drhbc8f0922015-08-22 19:39:04 +0000593 if( iThis<0 ) return -1;
drhe9c37f32015-08-15 21:25:36 +0000594 for(j=i+1;;j++){
595 while( isspace(pParse->zJson[j]) ){ j++; }
596 x = jsonParseValue(pParse, j);
597 if( x<0 ){
drhbc8f0922015-08-22 19:39:04 +0000598 if( x==(-2) && pParse->nNode==(u32)iThis+1 ) return j+1;
drhe9c37f32015-08-15 21:25:36 +0000599 return -1;
600 }
drhbe9474e2015-08-22 03:05:54 +0000601 if( pParse->oom ) return -1;
drh852944e2015-09-10 03:29:11 +0000602 pNode = &pParse->aNode[pParse->nNode-1];
603 if( pNode->eType!=JSON_STRING ) return -1;
604 pNode->jnFlags |= JNODE_LABEL;
drhe9c37f32015-08-15 21:25:36 +0000605 j = x;
606 while( isspace(pParse->zJson[j]) ){ j++; }
607 if( pParse->zJson[j]!=':' ) return -1;
608 j++;
609 x = jsonParseValue(pParse, j);
610 if( x<0 ) return -1;
611 j = x;
612 while( isspace(pParse->zJson[j]) ){ j++; }
613 c = pParse->zJson[j];
614 if( c==',' ) continue;
615 if( c!='}' ) return -1;
616 break;
617 }
drhbc8f0922015-08-22 19:39:04 +0000618 pParse->aNode[iThis].n = pParse->nNode - (u32)iThis - 1;
drhe9c37f32015-08-15 21:25:36 +0000619 return j+1;
620 }else if( c=='[' ){
621 /* Parse array */
622 iThis = jsonParseAddNode(pParse, JSON_ARRAY, 0, 0);
drhbc8f0922015-08-22 19:39:04 +0000623 if( iThis<0 ) return -1;
drhe9c37f32015-08-15 21:25:36 +0000624 for(j=i+1;;j++){
625 while( isspace(pParse->zJson[j]) ){ j++; }
626 x = jsonParseValue(pParse, j);
627 if( x<0 ){
drhbc8f0922015-08-22 19:39:04 +0000628 if( x==(-3) && pParse->nNode==(u32)iThis+1 ) return j+1;
drhe9c37f32015-08-15 21:25:36 +0000629 return -1;
630 }
631 j = x;
632 while( isspace(pParse->zJson[j]) ){ j++; }
633 c = pParse->zJson[j];
634 if( c==',' ) continue;
635 if( c!=']' ) return -1;
636 break;
637 }
drhbc8f0922015-08-22 19:39:04 +0000638 pParse->aNode[iThis].n = pParse->nNode - (u32)iThis - 1;
drhe9c37f32015-08-15 21:25:36 +0000639 return j+1;
640 }else if( c=='"' ){
641 /* Parse string */
drh301eecc2015-08-17 20:14:19 +0000642 u8 jnFlags = 0;
drhe9c37f32015-08-15 21:25:36 +0000643 j = i+1;
644 for(;;){
645 c = pParse->zJson[j];
646 if( c==0 ) return -1;
647 if( c=='\\' ){
648 c = pParse->zJson[++j];
649 if( c==0 ) return -1;
drh301eecc2015-08-17 20:14:19 +0000650 jnFlags = JNODE_ESCAPE;
drhe9c37f32015-08-15 21:25:36 +0000651 }else if( c=='"' ){
652 break;
653 }
654 j++;
655 }
656 jsonParseAddNode(pParse, JSON_STRING, j+1-i, &pParse->zJson[i]);
drhbe9474e2015-08-22 03:05:54 +0000657 if( !pParse->oom ) pParse->aNode[pParse->nNode-1].jnFlags = jnFlags;
drhe9c37f32015-08-15 21:25:36 +0000658 return j+1;
659 }else if( c=='n'
660 && strncmp(pParse->zJson+i,"null",4)==0
drhb2cd10e2015-08-15 21:29:14 +0000661 && !isalnum(pParse->zJson[i+4]) ){
drhe9c37f32015-08-15 21:25:36 +0000662 jsonParseAddNode(pParse, JSON_NULL, 0, 0);
663 return i+4;
664 }else if( c=='t'
665 && strncmp(pParse->zJson+i,"true",4)==0
drhb2cd10e2015-08-15 21:29:14 +0000666 && !isalnum(pParse->zJson[i+4]) ){
drhe9c37f32015-08-15 21:25:36 +0000667 jsonParseAddNode(pParse, JSON_TRUE, 0, 0);
668 return i+4;
669 }else if( c=='f'
670 && strncmp(pParse->zJson+i,"false",5)==0
drhb2cd10e2015-08-15 21:29:14 +0000671 && !isalnum(pParse->zJson[i+5]) ){
drhe9c37f32015-08-15 21:25:36 +0000672 jsonParseAddNode(pParse, JSON_FALSE, 0, 0);
673 return i+5;
674 }else if( c=='-' || (c>='0' && c<='9') ){
675 /* Parse number */
676 u8 seenDP = 0;
677 u8 seenE = 0;
678 j = i+1;
679 for(;; j++){
680 c = pParse->zJson[j];
681 if( c>='0' && c<='9' ) continue;
682 if( c=='.' ){
683 if( pParse->zJson[j-1]=='-' ) return -1;
684 if( seenDP ) return -1;
685 seenDP = 1;
686 continue;
687 }
688 if( c=='e' || c=='E' ){
689 if( pParse->zJson[j-1]<'0' ) return -1;
690 if( seenE ) return -1;
691 seenDP = seenE = 1;
692 c = pParse->zJson[j+1];
drh8784eca2015-08-23 02:42:30 +0000693 if( c=='+' || c=='-' ){
694 j++;
695 c = pParse->zJson[j+1];
696 }
drhd1f00682015-08-29 16:02:37 +0000697 if( c<'0' || c>'9' ) return -1;
drhe9c37f32015-08-15 21:25:36 +0000698 continue;
699 }
700 break;
701 }
702 if( pParse->zJson[j-1]<'0' ) return -1;
703 jsonParseAddNode(pParse, seenDP ? JSON_REAL : JSON_INT,
704 j - i, &pParse->zJson[i]);
705 return j;
706 }else if( c=='}' ){
707 return -2; /* End of {...} */
708 }else if( c==']' ){
709 return -3; /* End of [...] */
710 }else{
711 return -1; /* Syntax error */
712 }
713}
714
715/*
716** Parse a complete JSON string. Return 0 on success or non-zero if there
717** are any errors. If an error occurs, free all memory associated with
718** pParse.
719**
720** pParse is uninitialized when this routine is called.
721*/
drhbc8f0922015-08-22 19:39:04 +0000722static int jsonParse(
723 JsonParse *pParse, /* Initialize and fill this JsonParse object */
724 sqlite3_context *pCtx, /* Report errors here */
725 const char *zJson /* Input JSON text to be parsed */
726){
drhe9c37f32015-08-15 21:25:36 +0000727 int i;
drhe9c37f32015-08-15 21:25:36 +0000728 memset(pParse, 0, sizeof(*pParse));
drhc3722b22015-08-23 20:44:59 +0000729 if( zJson==0 ) return 1;
drhe9c37f32015-08-15 21:25:36 +0000730 pParse->zJson = zJson;
731 i = jsonParseValue(pParse, 0);
drhc3722b22015-08-23 20:44:59 +0000732 if( pParse->oom ) i = -1;
drhe9c37f32015-08-15 21:25:36 +0000733 if( i>0 ){
734 while( isspace(zJson[i]) ) i++;
735 if( zJson[i] ) i = -1;
736 }
drhd1f00682015-08-29 16:02:37 +0000737 if( i<=0 ){
drhf2df7e72015-08-28 20:07:40 +0000738 if( pCtx!=0 ){
739 if( pParse->oom ){
740 sqlite3_result_error_nomem(pCtx);
741 }else{
742 sqlite3_result_error(pCtx, "malformed JSON", -1);
743 }
744 }
drh505ad2c2015-08-21 17:33:11 +0000745 jsonParseReset(pParse);
drhe9c37f32015-08-15 21:25:36 +0000746 return 1;
747 }
748 return 0;
749}
drh301eecc2015-08-17 20:14:19 +0000750
drh505ad2c2015-08-21 17:33:11 +0000751/* Mark node i of pParse as being a child of iParent. Call recursively
752** to fill in all the descendants of node i.
753*/
754static void jsonParseFillInParentage(JsonParse *pParse, u32 i, u32 iParent){
755 JsonNode *pNode = &pParse->aNode[i];
756 u32 j;
757 pParse->aUp[i] = iParent;
758 switch( pNode->eType ){
759 case JSON_ARRAY: {
760 for(j=1; j<=pNode->n; j += jsonNodeSize(pNode+j)){
761 jsonParseFillInParentage(pParse, i+j, i);
762 }
763 break;
764 }
765 case JSON_OBJECT: {
766 for(j=1; j<=pNode->n; j += jsonNodeSize(pNode+j+1)+1){
767 pParse->aUp[i+j] = i;
768 jsonParseFillInParentage(pParse, i+j+1, i);
769 }
770 break;
771 }
772 default: {
773 break;
774 }
775 }
776}
777
778/*
779** Compute the parentage of all nodes in a completed parse.
780*/
781static int jsonParseFindParents(JsonParse *pParse){
782 u32 *aUp;
783 assert( pParse->aUp==0 );
784 aUp = pParse->aUp = sqlite3_malloc( sizeof(u32)*pParse->nNode );
drhc3722b22015-08-23 20:44:59 +0000785 if( aUp==0 ){
786 pParse->oom = 1;
787 return SQLITE_NOMEM;
788 }
drh505ad2c2015-08-21 17:33:11 +0000789 jsonParseFillInParentage(pParse, 0, 0);
790 return SQLITE_OK;
791}
792
drh52216ad2015-08-18 02:28:03 +0000793/* forward declaration */
drha7714022015-08-29 00:54:49 +0000794static JsonNode *jsonLookupAppend(JsonParse*,const char*,int*,const char**);
drh52216ad2015-08-18 02:28:03 +0000795
drh987eb1f2015-08-17 15:17:37 +0000796/*
797** Search along zPath to find the node specified. Return a pointer
798** to that node, or NULL if zPath is malformed or if there is no such
799** node.
drh52216ad2015-08-18 02:28:03 +0000800**
801** If pApnd!=0, then try to append new nodes to complete zPath if it is
802** possible to do so and if no existing node corresponds to zPath. If
803** new nodes are appended *pApnd is set to 1.
drh987eb1f2015-08-17 15:17:37 +0000804*/
drha7714022015-08-29 00:54:49 +0000805static JsonNode *jsonLookupStep(
drh52216ad2015-08-18 02:28:03 +0000806 JsonParse *pParse, /* The JSON to search */
807 u32 iRoot, /* Begin the search at this node */
808 const char *zPath, /* The path to search */
drha7714022015-08-29 00:54:49 +0000809 int *pApnd, /* Append nodes to complete path if not NULL */
810 const char **pzErr /* Make *pzErr point to any syntax error in zPath */
drh52216ad2015-08-18 02:28:03 +0000811){
drhbc8f0922015-08-22 19:39:04 +0000812 u32 i, j, nKey;
drh6b43cc82015-08-19 23:02:49 +0000813 const char *zKey;
drh52216ad2015-08-18 02:28:03 +0000814 JsonNode *pRoot = &pParse->aNode[iRoot];
drh987eb1f2015-08-17 15:17:37 +0000815 if( zPath[0]==0 ) return pRoot;
816 if( zPath[0]=='.' ){
817 if( pRoot->eType!=JSON_OBJECT ) return 0;
818 zPath++;
drh6b43cc82015-08-19 23:02:49 +0000819 if( zPath[0]=='"' ){
820 zKey = zPath + 1;
821 for(i=1; zPath[i] && zPath[i]!='"'; i++){}
822 nKey = i-1;
823 if( zPath[i] ) i++;
824 }else{
825 zKey = zPath;
826 for(i=0; zPath[i] && zPath[i]!='.' && zPath[i]!='['; i++){}
827 nKey = i;
828 }
drha7714022015-08-29 00:54:49 +0000829 if( nKey==0 ){
830 *pzErr = zPath;
831 return 0;
832 }
drh987eb1f2015-08-17 15:17:37 +0000833 j = 1;
drh52216ad2015-08-18 02:28:03 +0000834 for(;;){
835 while( j<=pRoot->n ){
drh6b43cc82015-08-19 23:02:49 +0000836 if( pRoot[j].n==nKey+2
837 && strncmp(&pRoot[j].u.zJContent[1],zKey,nKey)==0
drh52216ad2015-08-18 02:28:03 +0000838 ){
drha7714022015-08-29 00:54:49 +0000839 return jsonLookupStep(pParse, iRoot+j+1, &zPath[i], pApnd, pzErr);
drh52216ad2015-08-18 02:28:03 +0000840 }
841 j++;
drh505ad2c2015-08-21 17:33:11 +0000842 j += jsonNodeSize(&pRoot[j]);
drh987eb1f2015-08-17 15:17:37 +0000843 }
drh52216ad2015-08-18 02:28:03 +0000844 if( (pRoot->jnFlags & JNODE_APPEND)==0 ) break;
845 iRoot += pRoot->u.iAppend;
846 pRoot = &pParse->aNode[iRoot];
847 j = 1;
848 }
849 if( pApnd ){
drhbc8f0922015-08-22 19:39:04 +0000850 u32 iStart, iLabel;
851 JsonNode *pNode;
852 iStart = jsonParseAddNode(pParse, JSON_OBJECT, 2, 0);
853 iLabel = jsonParseAddNode(pParse, JSON_STRING, i, zPath);
drh52216ad2015-08-18 02:28:03 +0000854 zPath += i;
drha7714022015-08-29 00:54:49 +0000855 pNode = jsonLookupAppend(pParse, zPath, pApnd, pzErr);
drhbc8f0922015-08-22 19:39:04 +0000856 if( pParse->oom ) return 0;
857 if( pNode ){
858 pRoot = &pParse->aNode[iRoot];
859 pRoot->u.iAppend = iStart - iRoot;
860 pRoot->jnFlags |= JNODE_APPEND;
861 pParse->aNode[iLabel].jnFlags |= JNODE_RAW;
862 }
863 return pNode;
drh987eb1f2015-08-17 15:17:37 +0000864 }
865 }else if( zPath[0]=='[' && isdigit(zPath[1]) ){
866 if( pRoot->eType!=JSON_ARRAY ) return 0;
867 i = 0;
868 zPath++;
869 while( isdigit(zPath[0]) ){
drh8784eca2015-08-23 02:42:30 +0000870 i = i*10 + zPath[0] - '0';
drh987eb1f2015-08-17 15:17:37 +0000871 zPath++;
872 }
drha7714022015-08-29 00:54:49 +0000873 if( zPath[0]!=']' ){
874 *pzErr = zPath;
875 return 0;
876 }
drh987eb1f2015-08-17 15:17:37 +0000877 zPath++;
878 j = 1;
drh52216ad2015-08-18 02:28:03 +0000879 for(;;){
drhbc8f0922015-08-22 19:39:04 +0000880 while( j<=pRoot->n && (i>0 || (pRoot[j].jnFlags & JNODE_REMOVE)!=0) ){
881 if( (pRoot[j].jnFlags & JNODE_REMOVE)==0 ) i--;
drh505ad2c2015-08-21 17:33:11 +0000882 j += jsonNodeSize(&pRoot[j]);
drh52216ad2015-08-18 02:28:03 +0000883 }
884 if( (pRoot->jnFlags & JNODE_APPEND)==0 ) break;
885 iRoot += pRoot->u.iAppend;
886 pRoot = &pParse->aNode[iRoot];
887 j = 1;
drh987eb1f2015-08-17 15:17:37 +0000888 }
889 if( j<=pRoot->n ){
drha7714022015-08-29 00:54:49 +0000890 return jsonLookupStep(pParse, iRoot+j, zPath, pApnd, pzErr);
drh52216ad2015-08-18 02:28:03 +0000891 }
892 if( i==0 && pApnd ){
drhbc8f0922015-08-22 19:39:04 +0000893 u32 iStart;
894 JsonNode *pNode;
895 iStart = jsonParseAddNode(pParse, JSON_ARRAY, 1, 0);
drha7714022015-08-29 00:54:49 +0000896 pNode = jsonLookupAppend(pParse, zPath, pApnd, pzErr);
drhbc8f0922015-08-22 19:39:04 +0000897 if( pParse->oom ) return 0;
898 if( pNode ){
899 pRoot = &pParse->aNode[iRoot];
900 pRoot->u.iAppend = iStart - iRoot;
901 pRoot->jnFlags |= JNODE_APPEND;
902 }
903 return pNode;
drh987eb1f2015-08-17 15:17:37 +0000904 }
drha7714022015-08-29 00:54:49 +0000905 }else if( zPath[0]!=0 ){
906 *pzErr = zPath;
drh987eb1f2015-08-17 15:17:37 +0000907 }
908 return 0;
909}
910
drh52216ad2015-08-18 02:28:03 +0000911/*
drhbc8f0922015-08-22 19:39:04 +0000912** Append content to pParse that will complete zPath. Return a pointer
913** to the inserted node, or return NULL if the append fails.
drh52216ad2015-08-18 02:28:03 +0000914*/
915static JsonNode *jsonLookupAppend(
916 JsonParse *pParse, /* Append content to the JSON parse */
917 const char *zPath, /* Description of content to append */
drha7714022015-08-29 00:54:49 +0000918 int *pApnd, /* Set this flag to 1 */
919 const char **pzErr /* Make this point to any syntax error */
drh52216ad2015-08-18 02:28:03 +0000920){
921 *pApnd = 1;
922 if( zPath[0]==0 ){
923 jsonParseAddNode(pParse, JSON_NULL, 0, 0);
924 return pParse->oom ? 0 : &pParse->aNode[pParse->nNode-1];
925 }
926 if( zPath[0]=='.' ){
927 jsonParseAddNode(pParse, JSON_OBJECT, 0, 0);
928 }else if( strncmp(zPath,"[0]",3)==0 ){
929 jsonParseAddNode(pParse, JSON_ARRAY, 0, 0);
930 }else{
931 return 0;
932 }
933 if( pParse->oom ) return 0;
drha7714022015-08-29 00:54:49 +0000934 return jsonLookupStep(pParse, pParse->nNode-1, zPath, pApnd, pzErr);
drh52216ad2015-08-18 02:28:03 +0000935}
936
drhbc8f0922015-08-22 19:39:04 +0000937/*
drha7714022015-08-29 00:54:49 +0000938** Return the text of a syntax error message on a JSON path. Space is
939** obtained from sqlite3_malloc().
940*/
941static char *jsonPathSyntaxError(const char *zErr){
942 return sqlite3_mprintf("JSON path error near '%q'", zErr);
943}
944
945/*
946** Do a node lookup using zPath. Return a pointer to the node on success.
947** Return NULL if not found or if there is an error.
948**
949** On an error, write an error message into pCtx and increment the
950** pParse->nErr counter.
951**
952** If pApnd!=NULL then try to append missing nodes and set *pApnd = 1 if
953** nodes are appended.
drha7714022015-08-29 00:54:49 +0000954*/
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 */
drhf5ddb9c2015-09-11 00:06:41 +0000959 sqlite3_context *pCtx /* Report errors here, if not NULL */
drha7714022015-08-29 00:54:49 +0000960){
961 const char *zErr = 0;
962 JsonNode *pNode = 0;
drha7714022015-08-29 00:54:49 +0000963
964 if( zPath==0 ) return 0;
965 if( zPath[0]!='$' ){
966 zErr = zPath;
967 goto lookup_err;
968 }
969 zPath++;
drha7714022015-08-29 00:54:49 +0000970 pNode = jsonLookupStep(pParse, 0, zPath, pApnd, &zErr);
971 return pNode;
972
973lookup_err:
974 pParse->nErr++;
975 if( zErr!=0 && pCtx!=0 ){
976 char *z = jsonPathSyntaxError(zErr);
977 if( z ){
978 sqlite3_result_error(pCtx, z, -1);
979 sqlite3_free(z);
980 }else{
981 sqlite3_result_error_nomem(pCtx);
982 }
983 }
drha7714022015-08-29 00:54:49 +0000984 return 0;
985}
986
987
988/*
drhbc8f0922015-08-22 19:39:04 +0000989** Report the wrong number of arguments for json_insert(), json_replace()
990** or json_set().
991*/
992static void jsonWrongNumArgs(
993 sqlite3_context *pCtx,
994 const char *zFuncName
995){
996 char *zMsg = sqlite3_mprintf("json_%s() needs an odd number of arguments",
997 zFuncName);
998 sqlite3_result_error(pCtx, zMsg, -1);
999 sqlite3_free(zMsg);
1000}
drh52216ad2015-08-18 02:28:03 +00001001
drha7714022015-08-29 00:54:49 +00001002
drh987eb1f2015-08-17 15:17:37 +00001003/****************************************************************************
1004** SQL functions used for testing and debugging
1005****************************************************************************/
drhe9c37f32015-08-15 21:25:36 +00001006
drh301eecc2015-08-17 20:14:19 +00001007#ifdef SQLITE_DEBUG
drhe9c37f32015-08-15 21:25:36 +00001008/*
drh5634cc02015-08-17 11:28:03 +00001009** The json_parse(JSON) function returns a string which describes
drhe9c37f32015-08-15 21:25:36 +00001010** a parse of the JSON provided. Or it returns NULL if JSON is not
1011** well-formed.
1012*/
drh5634cc02015-08-17 11:28:03 +00001013static void jsonParseFunc(
drhbc8f0922015-08-22 19:39:04 +00001014 sqlite3_context *ctx,
drhe9c37f32015-08-15 21:25:36 +00001015 int argc,
1016 sqlite3_value **argv
1017){
drh505ad2c2015-08-21 17:33:11 +00001018 JsonString s; /* Output string - not real JSON */
1019 JsonParse x; /* The parse */
drhe9c37f32015-08-15 21:25:36 +00001020 u32 i;
drhe9c37f32015-08-15 21:25:36 +00001021
1022 assert( argc==1 );
drhbc8f0922015-08-22 19:39:04 +00001023 if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return;
drh8784eca2015-08-23 02:42:30 +00001024 jsonParseFindParents(&x);
drhbc8f0922015-08-22 19:39:04 +00001025 jsonInit(&s, ctx);
drhe9c37f32015-08-15 21:25:36 +00001026 for(i=0; i<x.nNode; i++){
drh852944e2015-09-10 03:29:11 +00001027 const char *zType;
1028 if( x.aNode[i].jnFlags & JNODE_LABEL ){
1029 assert( x.aNode[i].eType==JSON_STRING );
1030 zType = "label";
1031 }else{
1032 zType = jsonType[x.aNode[i].eType];
drhe9c37f32015-08-15 21:25:36 +00001033 }
drh852944e2015-09-10 03:29:11 +00001034 jsonPrintf(100, &s,"node %3u: %7s n=%-4d up=%-4d",
1035 i, zType, x.aNode[i].n, x.aUp[i]);
1036 if( x.aNode[i].u.zJContent!=0 ){
1037 jsonAppendRaw(&s, " ", 1);
1038 jsonAppendRaw(&s, x.aNode[i].u.zJContent, x.aNode[i].n);
1039 }
1040 jsonAppendRaw(&s, "\n", 1);
drhe9c37f32015-08-15 21:25:36 +00001041 }
drh505ad2c2015-08-21 17:33:11 +00001042 jsonParseReset(&x);
drhe9c37f32015-08-15 21:25:36 +00001043 jsonResult(&s);
1044}
1045
drh5634cc02015-08-17 11:28:03 +00001046/*
drhf5ddb9c2015-09-11 00:06:41 +00001047** The json_test1(JSON) function return true (1) if the input is JSON
1048** text generated by another json function. It returns (0) if the input
1049** is not known to be JSON.
drh5634cc02015-08-17 11:28:03 +00001050*/
1051static void jsonTest1Func(
drhbc8f0922015-08-22 19:39:04 +00001052 sqlite3_context *ctx,
drh5634cc02015-08-17 11:28:03 +00001053 int argc,
1054 sqlite3_value **argv
1055){
mistachkin16a93122015-09-11 18:05:01 +00001056 UNUSED_PARAM(argc);
drhf5ddb9c2015-09-11 00:06:41 +00001057 sqlite3_result_int(ctx, sqlite3_value_subtype(argv[0])==JSON_SUBTYPE);
drh5634cc02015-08-17 11:28:03 +00001058}
drh301eecc2015-08-17 20:14:19 +00001059#endif /* SQLITE_DEBUG */
drh5634cc02015-08-17 11:28:03 +00001060
drh987eb1f2015-08-17 15:17:37 +00001061/****************************************************************************
1062** SQL function implementations
1063****************************************************************************/
1064
1065/*
1066** Implementation of the json_array(VALUE,...) function. Return a JSON
1067** array that contains all values given in arguments. Or if any argument
1068** is a BLOB, throw an error.
1069*/
1070static void jsonArrayFunc(
drhbc8f0922015-08-22 19:39:04 +00001071 sqlite3_context *ctx,
drh987eb1f2015-08-17 15:17:37 +00001072 int argc,
1073 sqlite3_value **argv
1074){
1075 int i;
drh505ad2c2015-08-21 17:33:11 +00001076 JsonString jx;
drh987eb1f2015-08-17 15:17:37 +00001077
drhbc8f0922015-08-22 19:39:04 +00001078 jsonInit(&jx, ctx);
drhd0960592015-08-17 21:22:32 +00001079 jsonAppendChar(&jx, '[');
drh987eb1f2015-08-17 15:17:37 +00001080 for(i=0; i<argc; i++){
drhd0960592015-08-17 21:22:32 +00001081 jsonAppendSeparator(&jx);
drhf5ddb9c2015-09-11 00:06:41 +00001082 jsonAppendValue(&jx, argv[i]);
drh987eb1f2015-08-17 15:17:37 +00001083 }
drhd0960592015-08-17 21:22:32 +00001084 jsonAppendChar(&jx, ']');
drh987eb1f2015-08-17 15:17:37 +00001085 jsonResult(&jx);
drhf5ddb9c2015-09-11 00:06:41 +00001086 sqlite3_result_subtype(ctx, JSON_SUBTYPE);
drh987eb1f2015-08-17 15:17:37 +00001087}
1088
1089
1090/*
1091** json_array_length(JSON)
1092** json_array_length(JSON, PATH)
1093**
1094** Return the number of elements in the top-level JSON array.
1095** Return 0 if the input is not a well-formed JSON array.
1096*/
1097static void jsonArrayLengthFunc(
drhbc8f0922015-08-22 19:39:04 +00001098 sqlite3_context *ctx,
drh987eb1f2015-08-17 15:17:37 +00001099 int argc,
1100 sqlite3_value **argv
1101){
1102 JsonParse x; /* The parse */
1103 sqlite3_int64 n = 0;
1104 u32 i;
drh987eb1f2015-08-17 15:17:37 +00001105
drhf2df7e72015-08-28 20:07:40 +00001106 if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return;
1107 if( x.nNode ){
drha7714022015-08-29 00:54:49 +00001108 JsonNode *pNode;
1109 if( argc==2 ){
1110 const char *zPath = (const char*)sqlite3_value_text(argv[1]);
drhf5ddb9c2015-09-11 00:06:41 +00001111 pNode = jsonLookup(&x, zPath, 0, ctx);
drha7714022015-08-29 00:54:49 +00001112 }else{
1113 pNode = x.aNode;
1114 }
1115 if( pNode==0 ){
1116 x.nErr = 1;
1117 }else if( pNode->eType==JSON_ARRAY ){
drhf2df7e72015-08-28 20:07:40 +00001118 assert( (pNode->jnFlags & JNODE_APPEND)==0 );
1119 for(i=1; i<=pNode->n; n++){
1120 i += jsonNodeSize(&pNode[i]);
drh987eb1f2015-08-17 15:17:37 +00001121 }
1122 }
drh987eb1f2015-08-17 15:17:37 +00001123 }
drha7714022015-08-29 00:54:49 +00001124 if( x.nErr==0 ) sqlite3_result_int64(ctx, n);
drhf6ec8d42015-08-28 03:48:04 +00001125 jsonParseReset(&x);
1126}
1127
1128/*
drh3ad93bb2015-08-29 19:41:45 +00001129** json_extract(JSON, PATH, ...)
drh987eb1f2015-08-17 15:17:37 +00001130**
drh3ad93bb2015-08-29 19:41:45 +00001131** Return the element described by PATH. Return NULL if there is no
1132** PATH element. If there are multiple PATHs, then return a JSON array
1133** with the result from each path. Throw an error if the JSON or any PATH
1134** is malformed.
drh987eb1f2015-08-17 15:17:37 +00001135*/
1136static void jsonExtractFunc(
drhbc8f0922015-08-22 19:39:04 +00001137 sqlite3_context *ctx,
drh987eb1f2015-08-17 15:17:37 +00001138 int argc,
1139 sqlite3_value **argv
1140){
1141 JsonParse x; /* The parse */
1142 JsonNode *pNode;
1143 const char *zPath;
drh3ad93bb2015-08-29 19:41:45 +00001144 JsonString jx;
1145 int i;
1146
1147 if( argc<2 ) return;
drhbc8f0922015-08-22 19:39:04 +00001148 if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return;
drh3ad93bb2015-08-29 19:41:45 +00001149 jsonInit(&jx, ctx);
1150 jsonAppendChar(&jx, '[');
1151 for(i=1; i<argc; i++){
1152 zPath = (const char*)sqlite3_value_text(argv[i]);
drhf5ddb9c2015-09-11 00:06:41 +00001153 pNode = jsonLookup(&x, zPath, 0, ctx);
drh3ad93bb2015-08-29 19:41:45 +00001154 if( x.nErr ) break;
1155 if( argc>2 ){
1156 jsonAppendSeparator(&jx);
1157 if( pNode ){
1158 jsonRenderNode(pNode, &jx, 0);
1159 }else{
1160 jsonAppendRaw(&jx, "null", 4);
1161 }
1162 }else if( pNode ){
1163 jsonReturn(pNode, ctx, 0);
1164 }
drh987eb1f2015-08-17 15:17:37 +00001165 }
drh3ad93bb2015-08-29 19:41:45 +00001166 if( argc>2 && i==argc ){
1167 jsonAppendChar(&jx, ']');
1168 jsonResult(&jx);
drhf5ddb9c2015-09-11 00:06:41 +00001169 sqlite3_result_subtype(ctx, JSON_SUBTYPE);
drh3ad93bb2015-08-29 19:41:45 +00001170 }
1171 jsonReset(&jx);
drh505ad2c2015-08-21 17:33:11 +00001172 jsonParseReset(&x);
drh987eb1f2015-08-17 15:17:37 +00001173}
1174
1175/*
1176** Implementation of the json_object(NAME,VALUE,...) function. Return a JSON
1177** object that contains all name/value given in arguments. Or if any name
1178** is not a string or if any value is a BLOB, throw an error.
1179*/
1180static void jsonObjectFunc(
drhbc8f0922015-08-22 19:39:04 +00001181 sqlite3_context *ctx,
drh987eb1f2015-08-17 15:17:37 +00001182 int argc,
1183 sqlite3_value **argv
1184){
1185 int i;
drh505ad2c2015-08-21 17:33:11 +00001186 JsonString jx;
drh987eb1f2015-08-17 15:17:37 +00001187 const char *z;
1188 u32 n;
1189
1190 if( argc&1 ){
drhbc8f0922015-08-22 19:39:04 +00001191 sqlite3_result_error(ctx, "json_object() requires an even number "
drh987eb1f2015-08-17 15:17:37 +00001192 "of arguments", -1);
1193 return;
1194 }
drhbc8f0922015-08-22 19:39:04 +00001195 jsonInit(&jx, ctx);
drhd0960592015-08-17 21:22:32 +00001196 jsonAppendChar(&jx, '{');
drh987eb1f2015-08-17 15:17:37 +00001197 for(i=0; i<argc; i+=2){
drh987eb1f2015-08-17 15:17:37 +00001198 if( sqlite3_value_type(argv[i])!=SQLITE_TEXT ){
drhbc8f0922015-08-22 19:39:04 +00001199 sqlite3_result_error(ctx, "json_object() labels must be TEXT", -1);
drh987eb1f2015-08-17 15:17:37 +00001200 jsonZero(&jx);
1201 return;
1202 }
drhd0960592015-08-17 21:22:32 +00001203 jsonAppendSeparator(&jx);
drh987eb1f2015-08-17 15:17:37 +00001204 z = (const char*)sqlite3_value_text(argv[i]);
1205 n = (u32)sqlite3_value_bytes(argv[i]);
1206 jsonAppendString(&jx, z, n);
drhd0960592015-08-17 21:22:32 +00001207 jsonAppendChar(&jx, ':');
drhf5ddb9c2015-09-11 00:06:41 +00001208 jsonAppendValue(&jx, argv[i+1]);
drh987eb1f2015-08-17 15:17:37 +00001209 }
drhd0960592015-08-17 21:22:32 +00001210 jsonAppendChar(&jx, '}');
drh987eb1f2015-08-17 15:17:37 +00001211 jsonResult(&jx);
drhf5ddb9c2015-09-11 00:06:41 +00001212 sqlite3_result_subtype(ctx, JSON_SUBTYPE);
drh987eb1f2015-08-17 15:17:37 +00001213}
1214
1215
1216/*
drh301eecc2015-08-17 20:14:19 +00001217** json_remove(JSON, PATH, ...)
1218**
drh3ad93bb2015-08-29 19:41:45 +00001219** Remove the named elements from JSON and return the result. malformed
1220** JSON or PATH arguments result in an error.
drh301eecc2015-08-17 20:14:19 +00001221*/
1222static void jsonRemoveFunc(
drhbc8f0922015-08-22 19:39:04 +00001223 sqlite3_context *ctx,
drh301eecc2015-08-17 20:14:19 +00001224 int argc,
1225 sqlite3_value **argv
1226){
1227 JsonParse x; /* The parse */
1228 JsonNode *pNode;
1229 const char *zPath;
1230 u32 i;
1231
1232 if( argc<1 ) return;
drhbc8f0922015-08-22 19:39:04 +00001233 if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return;
drh301eecc2015-08-17 20:14:19 +00001234 if( x.nNode ){
drh6fd5c1e2015-08-21 20:37:12 +00001235 for(i=1; i<(u32)argc; i++){
drh301eecc2015-08-17 20:14:19 +00001236 zPath = (const char*)sqlite3_value_text(argv[i]);
drha7714022015-08-29 00:54:49 +00001237 if( zPath==0 ) goto remove_done;
drhf5ddb9c2015-09-11 00:06:41 +00001238 pNode = jsonLookup(&x, zPath, 0, ctx);
drha7714022015-08-29 00:54:49 +00001239 if( x.nErr ) goto remove_done;
drh301eecc2015-08-17 20:14:19 +00001240 if( pNode ) pNode->jnFlags |= JNODE_REMOVE;
1241 }
1242 if( (x.aNode[0].jnFlags & JNODE_REMOVE)==0 ){
drhf2df7e72015-08-28 20:07:40 +00001243 jsonReturnJson(x.aNode, ctx, 0);
drhd0960592015-08-17 21:22:32 +00001244 }
1245 }
drha7714022015-08-29 00:54:49 +00001246remove_done:
drh505ad2c2015-08-21 17:33:11 +00001247 jsonParseReset(&x);
drhd0960592015-08-17 21:22:32 +00001248}
1249
1250/*
1251** json_replace(JSON, PATH, VALUE, ...)
1252**
1253** Replace the value at PATH with VALUE. If PATH does not already exist,
drh3ad93bb2015-08-29 19:41:45 +00001254** this routine is a no-op. If JSON or PATH is malformed, throw an error.
drhd0960592015-08-17 21:22:32 +00001255*/
1256static void jsonReplaceFunc(
drhbc8f0922015-08-22 19:39:04 +00001257 sqlite3_context *ctx,
drhd0960592015-08-17 21:22:32 +00001258 int argc,
1259 sqlite3_value **argv
1260){
1261 JsonParse x; /* The parse */
1262 JsonNode *pNode;
1263 const char *zPath;
1264 u32 i;
1265
1266 if( argc<1 ) return;
1267 if( (argc&1)==0 ) {
drhbc8f0922015-08-22 19:39:04 +00001268 jsonWrongNumArgs(ctx, "replace");
drhd0960592015-08-17 21:22:32 +00001269 return;
1270 }
drhbc8f0922015-08-22 19:39:04 +00001271 if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return;
drhd0960592015-08-17 21:22:32 +00001272 if( x.nNode ){
drh6fd5c1e2015-08-21 20:37:12 +00001273 for(i=1; i<(u32)argc; i+=2){
drhd0960592015-08-17 21:22:32 +00001274 zPath = (const char*)sqlite3_value_text(argv[i]);
drhf5ddb9c2015-09-11 00:06:41 +00001275 pNode = jsonLookup(&x, zPath, 0, ctx);
drha7714022015-08-29 00:54:49 +00001276 if( x.nErr ) goto replace_err;
drhd0960592015-08-17 21:22:32 +00001277 if( pNode ){
mistachkin16a93122015-09-11 18:05:01 +00001278 pNode->jnFlags |= (u8)JNODE_REPLACE;
1279 pNode->iVal = (u8)(i+1);
drhd0960592015-08-17 21:22:32 +00001280 }
1281 }
1282 if( x.aNode[0].jnFlags & JNODE_REPLACE ){
drhbc8f0922015-08-22 19:39:04 +00001283 sqlite3_result_value(ctx, argv[x.aNode[0].iVal]);
drhd0960592015-08-17 21:22:32 +00001284 }else{
drhf2df7e72015-08-28 20:07:40 +00001285 jsonReturnJson(x.aNode, ctx, argv);
drh301eecc2015-08-17 20:14:19 +00001286 }
1287 }
drha7714022015-08-29 00:54:49 +00001288replace_err:
drh505ad2c2015-08-21 17:33:11 +00001289 jsonParseReset(&x);
drh301eecc2015-08-17 20:14:19 +00001290}
drh505ad2c2015-08-21 17:33:11 +00001291
drh52216ad2015-08-18 02:28:03 +00001292/*
1293** json_set(JSON, PATH, VALUE, ...)
1294**
1295** Set the value at PATH to VALUE. Create the PATH if it does not already
1296** exist. Overwrite existing values that do exist.
drh3ad93bb2015-08-29 19:41:45 +00001297** If JSON or PATH is malformed, throw an error.
drh52216ad2015-08-18 02:28:03 +00001298**
1299** json_insert(JSON, PATH, VALUE, ...)
1300**
1301** Create PATH and initialize it to VALUE. If PATH already exists, this
drh3ad93bb2015-08-29 19:41:45 +00001302** routine is a no-op. If JSON or PATH is malformed, throw an error.
drh52216ad2015-08-18 02:28:03 +00001303*/
1304static void jsonSetFunc(
drhbc8f0922015-08-22 19:39:04 +00001305 sqlite3_context *ctx,
drh52216ad2015-08-18 02:28:03 +00001306 int argc,
1307 sqlite3_value **argv
1308){
1309 JsonParse x; /* The parse */
1310 JsonNode *pNode;
1311 const char *zPath;
1312 u32 i;
1313 int bApnd;
drhbc8f0922015-08-22 19:39:04 +00001314 int bIsSet = *(int*)sqlite3_user_data(ctx);
drh52216ad2015-08-18 02:28:03 +00001315
1316 if( argc<1 ) return;
1317 if( (argc&1)==0 ) {
drhbc8f0922015-08-22 19:39:04 +00001318 jsonWrongNumArgs(ctx, bIsSet ? "set" : "insert");
drh52216ad2015-08-18 02:28:03 +00001319 return;
1320 }
drhbc8f0922015-08-22 19:39:04 +00001321 if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return;
drh52216ad2015-08-18 02:28:03 +00001322 if( x.nNode ){
drh6fd5c1e2015-08-21 20:37:12 +00001323 for(i=1; i<(u32)argc; i+=2){
drh52216ad2015-08-18 02:28:03 +00001324 zPath = (const char*)sqlite3_value_text(argv[i]);
drh52216ad2015-08-18 02:28:03 +00001325 bApnd = 0;
drhf5ddb9c2015-09-11 00:06:41 +00001326 pNode = jsonLookup(&x, zPath, &bApnd, ctx);
drhbc8f0922015-08-22 19:39:04 +00001327 if( x.oom ){
1328 sqlite3_result_error_nomem(ctx);
1329 goto jsonSetDone;
drha7714022015-08-29 00:54:49 +00001330 }else if( x.nErr ){
1331 goto jsonSetDone;
drhbc8f0922015-08-22 19:39:04 +00001332 }else if( pNode && (bApnd || bIsSet) ){
mistachkin16a93122015-09-11 18:05:01 +00001333 pNode->jnFlags |= (u8)JNODE_REPLACE;
1334 pNode->iVal = (u8)(i+1);
drh52216ad2015-08-18 02:28:03 +00001335 }
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**
drh3ad93bb2015-08-29 19:41:45 +00001351** Return the top-level "type" of a JSON string. Throw an error if
1352** either the JSON or PATH inputs are not well-formed.
drh987eb1f2015-08-17 15:17:37 +00001353*/
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]);
drhf5ddb9c2015-09-11 00:06:41 +00001367 pNode = jsonLookup(&x, zPath, 0, ctx);
drha7714022015-08-29 00:54:49 +00001368 }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**
drh3ad93bb2015-08-29 19:41:45 +00001381** Return 1 if JSON is a well-formed JSON string according to RFC-7159.
1382** Return 0 otherwise.
drhbc8f0922015-08-22 19:39:04 +00001383*/
1384static void jsonValidFunc(
1385 sqlite3_context *ctx,
1386 int argc,
1387 sqlite3_value **argv
1388){
1389 JsonParse x; /* The parse */
1390 int rc = 0;
1391
mistachkin16a93122015-09-11 18:05:01 +00001392 UNUSED_PARAM(argc);
drhf2df7e72015-08-28 20:07:40 +00001393 if( jsonParse(&x, 0, (const char*)sqlite3_value_text(argv[0]))==0
drhbc8f0922015-08-22 19:39:04 +00001394 && x.nNode>0
1395 ){
1396 rc = 1;
1397 }
1398 jsonParseReset(&x);
1399 sqlite3_result_int(ctx, rc);
1400}
1401
drhd2975922015-08-29 17:22:33 +00001402#ifndef SQLITE_OMIT_VIRTUALTABLE
drhcb6c6c62015-08-19 22:47:17 +00001403/****************************************************************************
1404** The json_each virtual table
1405****************************************************************************/
1406typedef struct JsonEachCursor JsonEachCursor;
1407struct JsonEachCursor {
1408 sqlite3_vtab_cursor base; /* Base class - must be first */
drh505ad2c2015-08-21 17:33:11 +00001409 u32 iRowid; /* The rowid */
drh852944e2015-09-10 03:29:11 +00001410 u32 iBegin; /* The first node of the scan */
drh505ad2c2015-08-21 17:33:11 +00001411 u32 i; /* Index in sParse.aNode[] of current row */
1412 u32 iEnd; /* EOF when i equals or exceeds this value */
1413 u8 eType; /* Type of top-level element */
1414 u8 bRecursive; /* True for json_tree(). False for json_each() */
1415 char *zJson; /* Input JSON */
drh383de692015-09-10 17:20:57 +00001416 char *zRoot; /* Path by which to filter zJson */
drh505ad2c2015-08-21 17:33:11 +00001417 JsonParse sParse; /* Parse of the input JSON */
drhcb6c6c62015-08-19 22:47:17 +00001418};
1419
1420/* Constructor for the json_each virtual table */
1421static int jsonEachConnect(
1422 sqlite3 *db,
1423 void *pAux,
1424 int argc, const char *const*argv,
1425 sqlite3_vtab **ppVtab,
1426 char **pzErr
1427){
1428 sqlite3_vtab *pNew;
drh505ad2c2015-08-21 17:33:11 +00001429 int rc;
drhcb6c6c62015-08-19 22:47:17 +00001430
1431/* Column numbers */
drh4af352d2015-08-21 20:02:48 +00001432#define JEACH_KEY 0
1433#define JEACH_VALUE 1
1434#define JEACH_TYPE 2
1435#define JEACH_ATOM 3
1436#define JEACH_ID 4
1437#define JEACH_PARENT 5
1438#define JEACH_FULLKEY 6
drh383de692015-09-10 17:20:57 +00001439#define JEACH_PATH 7
1440#define JEACH_JSON 8
1441#define JEACH_ROOT 9
drhcb6c6c62015-08-19 22:47:17 +00001442
drh6fd5c1e2015-08-21 20:37:12 +00001443 UNUSED_PARAM(pzErr);
1444 UNUSED_PARAM(argv);
1445 UNUSED_PARAM(argc);
1446 UNUSED_PARAM(pAux);
drh505ad2c2015-08-21 17:33:11 +00001447 rc = sqlite3_declare_vtab(db,
drh383de692015-09-10 17:20:57 +00001448 "CREATE TABLE x(key,value,type,atom,id,parent,fullkey,path,"
1449 "json HIDDEN,root HIDDEN)");
drh505ad2c2015-08-21 17:33:11 +00001450 if( rc==SQLITE_OK ){
1451 pNew = *ppVtab = sqlite3_malloc( sizeof(*pNew) );
1452 if( pNew==0 ) return SQLITE_NOMEM;
1453 memset(pNew, 0, sizeof(*pNew));
1454 }
1455 return rc;
drhcb6c6c62015-08-19 22:47:17 +00001456}
1457
1458/* destructor for json_each virtual table */
1459static int jsonEachDisconnect(sqlite3_vtab *pVtab){
1460 sqlite3_free(pVtab);
1461 return SQLITE_OK;
1462}
1463
drh505ad2c2015-08-21 17:33:11 +00001464/* constructor for a JsonEachCursor object for json_each(). */
1465static int jsonEachOpenEach(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
drhcb6c6c62015-08-19 22:47:17 +00001466 JsonEachCursor *pCur;
drh6fd5c1e2015-08-21 20:37:12 +00001467
1468 UNUSED_PARAM(p);
drhcb6c6c62015-08-19 22:47:17 +00001469 pCur = sqlite3_malloc( sizeof(*pCur) );
1470 if( pCur==0 ) return SQLITE_NOMEM;
1471 memset(pCur, 0, sizeof(*pCur));
1472 *ppCursor = &pCur->base;
1473 return SQLITE_OK;
1474}
1475
drh505ad2c2015-08-21 17:33:11 +00001476/* constructor for a JsonEachCursor object for json_tree(). */
1477static int jsonEachOpenTree(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
1478 int rc = jsonEachOpenEach(p, ppCursor);
1479 if( rc==SQLITE_OK ){
1480 JsonEachCursor *pCur = (JsonEachCursor*)*ppCursor;
1481 pCur->bRecursive = 1;
1482 }
1483 return rc;
1484}
1485
drhcb6c6c62015-08-19 22:47:17 +00001486/* Reset a JsonEachCursor back to its original state. Free any memory
1487** held. */
1488static void jsonEachCursorReset(JsonEachCursor *p){
1489 sqlite3_free(p->zJson);
drh383de692015-09-10 17:20:57 +00001490 sqlite3_free(p->zRoot);
drh505ad2c2015-08-21 17:33:11 +00001491 jsonParseReset(&p->sParse);
drhcb6c6c62015-08-19 22:47:17 +00001492 p->iRowid = 0;
1493 p->i = 0;
1494 p->iEnd = 0;
1495 p->eType = 0;
drhcb6c6c62015-08-19 22:47:17 +00001496 p->zJson = 0;
drh383de692015-09-10 17:20:57 +00001497 p->zRoot = 0;
drhcb6c6c62015-08-19 22:47:17 +00001498}
1499
1500/* Destructor for a jsonEachCursor object */
1501static int jsonEachClose(sqlite3_vtab_cursor *cur){
1502 JsonEachCursor *p = (JsonEachCursor*)cur;
1503 jsonEachCursorReset(p);
1504 sqlite3_free(cur);
1505 return SQLITE_OK;
1506}
1507
1508/* Return TRUE if the jsonEachCursor object has been advanced off the end
1509** of the JSON object */
1510static int jsonEachEof(sqlite3_vtab_cursor *cur){
1511 JsonEachCursor *p = (JsonEachCursor*)cur;
1512 return p->i >= p->iEnd;
1513}
1514
drh505ad2c2015-08-21 17:33:11 +00001515/* Advance the cursor to the next element for json_tree() */
drh4af352d2015-08-21 20:02:48 +00001516static int jsonEachNext(sqlite3_vtab_cursor *cur){
drh505ad2c2015-08-21 17:33:11 +00001517 JsonEachCursor *p = (JsonEachCursor*)cur;
drh4af352d2015-08-21 20:02:48 +00001518 if( p->bRecursive ){
drh852944e2015-09-10 03:29:11 +00001519 if( p->sParse.aNode[p->i].jnFlags & JNODE_LABEL ) p->i++;
1520 p->i++;
drh4af352d2015-08-21 20:02:48 +00001521 p->iRowid++;
drh852944e2015-09-10 03:29:11 +00001522 if( p->i<p->iEnd ){
drh8784eca2015-08-23 02:42:30 +00001523 u32 iUp = p->sParse.aUp[p->i];
1524 JsonNode *pUp = &p->sParse.aNode[iUp];
drh4af352d2015-08-21 20:02:48 +00001525 p->eType = pUp->eType;
drh8784eca2015-08-23 02:42:30 +00001526 if( pUp->eType==JSON_ARRAY ){
1527 if( iUp==p->i-1 ){
1528 pUp->u.iKey = 0;
1529 }else{
1530 pUp->u.iKey++;
1531 }
drh4af352d2015-08-21 20:02:48 +00001532 }
1533 }
drh505ad2c2015-08-21 17:33:11 +00001534 }else{
drh4af352d2015-08-21 20:02:48 +00001535 switch( p->eType ){
1536 case JSON_ARRAY: {
1537 p->i += jsonNodeSize(&p->sParse.aNode[p->i]);
1538 p->iRowid++;
1539 break;
1540 }
1541 case JSON_OBJECT: {
1542 p->i += 1 + jsonNodeSize(&p->sParse.aNode[p->i+1]);
1543 p->iRowid++;
1544 break;
1545 }
1546 default: {
1547 p->i = p->iEnd;
1548 break;
1549 }
drh505ad2c2015-08-21 17:33:11 +00001550 }
1551 }
1552 return SQLITE_OK;
1553}
1554
drh4af352d2015-08-21 20:02:48 +00001555/* Append the name of the path for element i to pStr
1556*/
1557static void jsonEachComputePath(
1558 JsonEachCursor *p, /* The cursor */
1559 JsonString *pStr, /* Write the path here */
1560 u32 i /* Path to this element */
1561){
1562 JsonNode *pNode, *pUp;
1563 u32 iUp;
1564 if( i==0 ){
1565 jsonAppendChar(pStr, '$');
1566 return;
drhcb6c6c62015-08-19 22:47:17 +00001567 }
drh4af352d2015-08-21 20:02:48 +00001568 iUp = p->sParse.aUp[i];
1569 jsonEachComputePath(p, pStr, iUp);
1570 pNode = &p->sParse.aNode[i];
1571 pUp = &p->sParse.aNode[iUp];
1572 if( pUp->eType==JSON_ARRAY ){
1573 jsonPrintf(30, pStr, "[%d]", pUp->u.iKey);
1574 }else{
1575 assert( pUp->eType==JSON_OBJECT );
drh852944e2015-09-10 03:29:11 +00001576 if( (pNode->jnFlags & JNODE_LABEL)==0 ) pNode--;
drh4af352d2015-08-21 20:02:48 +00001577 assert( pNode->eType==JSON_STRING );
drh852944e2015-09-10 03:29:11 +00001578 assert( pNode->jnFlags & JNODE_LABEL );
drh4af352d2015-08-21 20:02:48 +00001579 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: {
drh852944e2015-09-10 03:29:11 +00001609 if( pThis->jnFlags & JNODE_LABEL ) pThis++;
drh505ad2c2015-08-21 17:33:11 +00001610 jsonReturn(pThis, ctx, 0);
1611 break;
1612 }
1613 case JEACH_TYPE: {
drh852944e2015-09-10 03:29:11 +00001614 if( pThis->jnFlags & JNODE_LABEL ) 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: {
drh852944e2015-09-10 03:29:11 +00001619 if( pThis->jnFlags & JNODE_LABEL ) 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: {
drh852944e2015-09-10 03:29:11 +00001625 sqlite3_result_int64(ctx,
1626 (sqlite3_int64)p->i + ((pThis->jnFlags & JNODE_LABEL)!=0));
drh505ad2c2015-08-21 17:33:11 +00001627 break;
1628 }
1629 case JEACH_PARENT: {
drh852944e2015-09-10 03:29:11 +00001630 if( p->i>p->iBegin && p->bRecursive ){
drh6fd5c1e2015-08-21 20:37:12 +00001631 sqlite3_result_int64(ctx, (sqlite3_int64)p->sParse.aUp[p->i]);
drhcb6c6c62015-08-19 22:47:17 +00001632 }
1633 break;
1634 }
drh4af352d2015-08-21 20:02:48 +00001635 case JEACH_FULLKEY: {
1636 JsonString x;
1637 jsonInit(&x, ctx);
1638 if( p->bRecursive ){
1639 jsonEachComputePath(p, &x, p->i);
1640 }else{
drh383de692015-09-10 17:20:57 +00001641 if( p->zRoot ){
1642 jsonAppendRaw(&x, p->zRoot, (int)strlen(p->zRoot));
drh4af352d2015-08-21 20:02:48 +00001643 }else{
1644 jsonAppendChar(&x, '$');
1645 }
1646 if( p->eType==JSON_ARRAY ){
1647 jsonPrintf(30, &x, "[%d]", p->iRowid);
1648 }else{
1649 jsonPrintf(pThis->n, &x, ".%.*s", pThis->n-2, pThis->u.zJContent+1);
1650 }
1651 }
1652 jsonResult(&x);
1653 break;
1654 }
drhcb6c6c62015-08-19 22:47:17 +00001655 case JEACH_PATH: {
drh383de692015-09-10 17:20:57 +00001656 if( p->bRecursive ){
1657 JsonString x;
1658 jsonInit(&x, ctx);
1659 jsonEachComputePath(p, &x, p->sParse.aUp[p->i]);
1660 jsonResult(&x);
1661 break;
drh4af352d2015-08-21 20:02:48 +00001662 }
drh383de692015-09-10 17:20:57 +00001663 /* For json_each() path and root are the same so fall through
1664 ** into the root case */
1665 }
1666 case JEACH_ROOT: {
1667 const char *zRoot = p->zRoot;
1668 if( zRoot==0 ) zRoot = "$";
1669 sqlite3_result_text(ctx, zRoot, -1, SQLITE_STATIC);
drhcb6c6c62015-08-19 22:47:17 +00001670 break;
1671 }
1672 default: {
drh505ad2c2015-08-21 17:33:11 +00001673 assert( i==JEACH_JSON );
drhcb6c6c62015-08-19 22:47:17 +00001674 sqlite3_result_text(ctx, p->sParse.zJson, -1, SQLITE_STATIC);
1675 break;
1676 }
1677 }
1678 return SQLITE_OK;
1679}
1680
1681/* Return the current rowid value */
1682static int jsonEachRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){
1683 JsonEachCursor *p = (JsonEachCursor*)cur;
1684 *pRowid = p->iRowid;
1685 return SQLITE_OK;
1686}
1687
1688/* The query strategy is to look for an equality constraint on the json
1689** column. Without such a constraint, the table cannot operate. idxNum is
drh383de692015-09-10 17:20:57 +00001690** 1 if the constraint is found, 3 if the constraint and zRoot are found,
drhcb6c6c62015-08-19 22:47:17 +00001691** and 0 otherwise.
1692*/
1693static int jsonEachBestIndex(
1694 sqlite3_vtab *tab,
1695 sqlite3_index_info *pIdxInfo
1696){
1697 int i;
1698 int jsonIdx = -1;
drh383de692015-09-10 17:20:57 +00001699 int rootIdx = -1;
drhcb6c6c62015-08-19 22:47:17 +00001700 const struct sqlite3_index_constraint *pConstraint;
drh6fd5c1e2015-08-21 20:37:12 +00001701
1702 UNUSED_PARAM(tab);
drhcb6c6c62015-08-19 22:47:17 +00001703 pConstraint = pIdxInfo->aConstraint;
1704 for(i=0; i<pIdxInfo->nConstraint; i++, pConstraint++){
1705 if( pConstraint->usable==0 ) continue;
1706 if( pConstraint->op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue;
1707 switch( pConstraint->iColumn ){
1708 case JEACH_JSON: jsonIdx = i; break;
drh383de692015-09-10 17:20:57 +00001709 case JEACH_ROOT: rootIdx = i; break;
drhcb6c6c62015-08-19 22:47:17 +00001710 default: /* no-op */ break;
1711 }
1712 }
1713 if( jsonIdx<0 ){
1714 pIdxInfo->idxNum = 0;
drh505ad2c2015-08-21 17:33:11 +00001715 pIdxInfo->estimatedCost = 1e99;
drhcb6c6c62015-08-19 22:47:17 +00001716 }else{
drh505ad2c2015-08-21 17:33:11 +00001717 pIdxInfo->estimatedCost = 1.0;
drhcb6c6c62015-08-19 22:47:17 +00001718 pIdxInfo->aConstraintUsage[jsonIdx].argvIndex = 1;
1719 pIdxInfo->aConstraintUsage[jsonIdx].omit = 1;
drh383de692015-09-10 17:20:57 +00001720 if( rootIdx<0 ){
drhcb6c6c62015-08-19 22:47:17 +00001721 pIdxInfo->idxNum = 1;
1722 }else{
drh383de692015-09-10 17:20:57 +00001723 pIdxInfo->aConstraintUsage[rootIdx].argvIndex = 2;
1724 pIdxInfo->aConstraintUsage[rootIdx].omit = 1;
drhcb6c6c62015-08-19 22:47:17 +00001725 pIdxInfo->idxNum = 3;
1726 }
1727 }
1728 return SQLITE_OK;
1729}
1730
1731/* Start a search on a new JSON string */
1732static int jsonEachFilter(
1733 sqlite3_vtab_cursor *cur,
1734 int idxNum, const char *idxStr,
1735 int argc, sqlite3_value **argv
1736){
1737 JsonEachCursor *p = (JsonEachCursor*)cur;
1738 const char *z;
mistachkin16a93122015-09-11 18:05:01 +00001739 const char *zRoot = 0;
drhcb6c6c62015-08-19 22:47:17 +00001740 sqlite3_int64 n;
1741
drh6fd5c1e2015-08-21 20:37:12 +00001742 UNUSED_PARAM(idxStr);
1743 UNUSED_PARAM(argc);
drhcb6c6c62015-08-19 22:47:17 +00001744 jsonEachCursorReset(p);
1745 if( idxNum==0 ) return SQLITE_OK;
1746 z = (const char*)sqlite3_value_text(argv[0]);
1747 if( z==0 ) return SQLITE_OK;
1748 if( idxNum&2 ){
drh383de692015-09-10 17:20:57 +00001749 zRoot = (const char*)sqlite3_value_text(argv[1]);
1750 if( zRoot==0 ) return SQLITE_OK;
1751 if( zRoot[0]!='$' ){
drha7714022015-08-29 00:54:49 +00001752 sqlite3_free(cur->pVtab->zErrMsg);
drh383de692015-09-10 17:20:57 +00001753 cur->pVtab->zErrMsg = jsonPathSyntaxError(zRoot);
drha7714022015-08-29 00:54:49 +00001754 return cur->pVtab->zErrMsg ? SQLITE_ERROR : SQLITE_NOMEM;
1755 }
drhcb6c6c62015-08-19 22:47:17 +00001756 }
1757 n = sqlite3_value_bytes(argv[0]);
drh6fd5c1e2015-08-21 20:37:12 +00001758 p->zJson = sqlite3_malloc64( n+1 );
drhcb6c6c62015-08-19 22:47:17 +00001759 if( p->zJson==0 ) return SQLITE_NOMEM;
drh6fd5c1e2015-08-21 20:37:12 +00001760 memcpy(p->zJson, z, (size_t)n+1);
drha7714022015-08-29 00:54:49 +00001761 if( jsonParse(&p->sParse, 0, p->zJson) ){
1762 int rc = SQLITE_NOMEM;
1763 if( p->sParse.oom==0 ){
1764 sqlite3_free(cur->pVtab->zErrMsg);
1765 cur->pVtab->zErrMsg = sqlite3_mprintf("malformed JSON");
1766 if( cur->pVtab->zErrMsg ) rc = SQLITE_ERROR;
1767 }
drhcb6c6c62015-08-19 22:47:17 +00001768 jsonEachCursorReset(p);
drha7714022015-08-29 00:54:49 +00001769 return rc;
1770 }else if( p->bRecursive && jsonParseFindParents(&p->sParse) ){
1771 jsonEachCursorReset(p);
1772 return SQLITE_NOMEM;
drhcb6c6c62015-08-19 22:47:17 +00001773 }else{
1774 JsonNode *pNode;
1775 if( idxNum==3 ){
drha7714022015-08-29 00:54:49 +00001776 const char *zErr = 0;
drhcb6c6c62015-08-19 22:47:17 +00001777 n = sqlite3_value_bytes(argv[1]);
drh383de692015-09-10 17:20:57 +00001778 p->zRoot = sqlite3_malloc64( n+1 );
1779 if( p->zRoot==0 ) return SQLITE_NOMEM;
1780 memcpy(p->zRoot, zRoot, (size_t)n+1);
1781 pNode = jsonLookupStep(&p->sParse, 0, p->zRoot+1, 0, &zErr);
drha7714022015-08-29 00:54:49 +00001782 if( p->sParse.nErr ){
1783 sqlite3_free(cur->pVtab->zErrMsg);
1784 cur->pVtab->zErrMsg = jsonPathSyntaxError(zErr);
drhcb6c6c62015-08-19 22:47:17 +00001785 jsonEachCursorReset(p);
drha7714022015-08-29 00:54:49 +00001786 return cur->pVtab->zErrMsg ? SQLITE_ERROR : SQLITE_NOMEM;
1787 }else if( pNode==0 ){
drhcb6c6c62015-08-19 22:47:17 +00001788 return SQLITE_OK;
1789 }
1790 }else{
1791 pNode = p->sParse.aNode;
1792 }
drh852944e2015-09-10 03:29:11 +00001793 p->iBegin = p->i = (int)(pNode - p->sParse.aNode);
drhcb6c6c62015-08-19 22:47:17 +00001794 p->eType = pNode->eType;
1795 if( p->eType>=JSON_ARRAY ){
drh8784eca2015-08-23 02:42:30 +00001796 pNode->u.iKey = 0;
drhc3722b22015-08-23 20:44:59 +00001797 p->iEnd = p->i + pNode->n + 1;
drh852944e2015-09-10 03:29:11 +00001798 if( p->bRecursive ){
1799 if( p->i>0 && (p->sParse.aNode[p->i-1].jnFlags & JNODE_LABEL)!=0 ){
1800 p->i--;
1801 }
1802 }else{
1803 p->i++;
1804 }
drhcb6c6c62015-08-19 22:47:17 +00001805 }else{
1806 p->iEnd = p->i+1;
1807 }
1808 }
drhbc8f0922015-08-22 19:39:04 +00001809 return p->sParse.oom ? SQLITE_NOMEM : SQLITE_OK;
drhcb6c6c62015-08-19 22:47:17 +00001810}
1811
1812/* The methods of the json_each virtual table */
1813static sqlite3_module jsonEachModule = {
1814 0, /* iVersion */
1815 0, /* xCreate */
1816 jsonEachConnect, /* xConnect */
1817 jsonEachBestIndex, /* xBestIndex */
1818 jsonEachDisconnect, /* xDisconnect */
1819 0, /* xDestroy */
drh505ad2c2015-08-21 17:33:11 +00001820 jsonEachOpenEach, /* xOpen - open a cursor */
drhcb6c6c62015-08-19 22:47:17 +00001821 jsonEachClose, /* xClose - close a cursor */
1822 jsonEachFilter, /* xFilter - configure scan constraints */
drh4af352d2015-08-21 20:02:48 +00001823 jsonEachNext, /* xNext - advance a cursor */
drhcb6c6c62015-08-19 22:47:17 +00001824 jsonEachEof, /* xEof - check for end of scan */
1825 jsonEachColumn, /* xColumn - read data */
1826 jsonEachRowid, /* xRowid - read data */
1827 0, /* xUpdate */
1828 0, /* xBegin */
1829 0, /* xSync */
1830 0, /* xCommit */
1831 0, /* xRollback */
1832 0, /* xFindMethod */
1833 0, /* xRename */
drh6fd5c1e2015-08-21 20:37:12 +00001834 0, /* xSavepoint */
1835 0, /* xRelease */
1836 0 /* xRollbackTo */
drhcb6c6c62015-08-19 22:47:17 +00001837};
1838
drh505ad2c2015-08-21 17:33:11 +00001839/* The methods of the json_tree virtual table. */
1840static sqlite3_module jsonTreeModule = {
1841 0, /* iVersion */
1842 0, /* xCreate */
1843 jsonEachConnect, /* xConnect */
1844 jsonEachBestIndex, /* xBestIndex */
1845 jsonEachDisconnect, /* xDisconnect */
1846 0, /* xDestroy */
1847 jsonEachOpenTree, /* xOpen - open a cursor */
1848 jsonEachClose, /* xClose - close a cursor */
1849 jsonEachFilter, /* xFilter - configure scan constraints */
drh4af352d2015-08-21 20:02:48 +00001850 jsonEachNext, /* xNext - advance a cursor */
drh505ad2c2015-08-21 17:33:11 +00001851 jsonEachEof, /* xEof - check for end of scan */
1852 jsonEachColumn, /* xColumn - read data */
1853 jsonEachRowid, /* xRowid - read data */
1854 0, /* xUpdate */
1855 0, /* xBegin */
1856 0, /* xSync */
1857 0, /* xCommit */
1858 0, /* xRollback */
1859 0, /* xFindMethod */
1860 0, /* xRename */
drh6fd5c1e2015-08-21 20:37:12 +00001861 0, /* xSavepoint */
1862 0, /* xRelease */
1863 0 /* xRollbackTo */
drh505ad2c2015-08-21 17:33:11 +00001864};
drhd2975922015-08-29 17:22:33 +00001865#endif /* SQLITE_OMIT_VIRTUALTABLE */
drh505ad2c2015-08-21 17:33:11 +00001866
1867/****************************************************************************
1868** The following routine is the only publically visible identifier in this
1869** file. Call the following routine in order to register the various SQL
1870** functions and the virtual table implemented by this file.
1871****************************************************************************/
drhcb6c6c62015-08-19 22:47:17 +00001872
drh5fa5c102015-08-12 16:49:40 +00001873#ifdef _WIN32
1874__declspec(dllexport)
1875#endif
1876int sqlite3_json_init(
1877 sqlite3 *db,
1878 char **pzErrMsg,
1879 const sqlite3_api_routines *pApi
1880){
1881 int rc = SQLITE_OK;
drh6fd5c1e2015-08-21 20:37:12 +00001882 unsigned int i;
drh5fa5c102015-08-12 16:49:40 +00001883 static const struct {
1884 const char *zName;
1885 int nArg;
drh52216ad2015-08-18 02:28:03 +00001886 int flag;
drh5fa5c102015-08-12 16:49:40 +00001887 void (*xFunc)(sqlite3_context*,int,sqlite3_value**);
1888 } aFunc[] = {
drhf5ddb9c2015-09-11 00:06:41 +00001889 { "json", 1, 0, jsonRemoveFunc },
drh52216ad2015-08-18 02:28:03 +00001890 { "json_array", -1, 0, jsonArrayFunc },
1891 { "json_array_length", 1, 0, jsonArrayLengthFunc },
1892 { "json_array_length", 2, 0, jsonArrayLengthFunc },
drh3ad93bb2015-08-29 19:41:45 +00001893 { "json_extract", -1, 0, jsonExtractFunc },
drh52216ad2015-08-18 02:28:03 +00001894 { "json_insert", -1, 0, jsonSetFunc },
1895 { "json_object", -1, 0, jsonObjectFunc },
1896 { "json_remove", -1, 0, jsonRemoveFunc },
1897 { "json_replace", -1, 0, jsonReplaceFunc },
1898 { "json_set", -1, 1, jsonSetFunc },
1899 { "json_type", 1, 0, jsonTypeFunc },
1900 { "json_type", 2, 0, jsonTypeFunc },
drhbc8f0922015-08-22 19:39:04 +00001901 { "json_valid", 1, 0, jsonValidFunc },
drh987eb1f2015-08-17 15:17:37 +00001902
drh301eecc2015-08-17 20:14:19 +00001903#if SQLITE_DEBUG
drh987eb1f2015-08-17 15:17:37 +00001904 /* DEBUG and TESTING functions */
drh52216ad2015-08-18 02:28:03 +00001905 { "json_parse", 1, 0, jsonParseFunc },
1906 { "json_test1", 1, 0, jsonTest1Func },
drh301eecc2015-08-17 20:14:19 +00001907#endif
drh5fa5c102015-08-12 16:49:40 +00001908 };
drhd2975922015-08-29 17:22:33 +00001909#ifndef SQLITE_OMIT_VIRTUALTABLE
drh505ad2c2015-08-21 17:33:11 +00001910 static const struct {
1911 const char *zName;
1912 sqlite3_module *pModule;
1913 } aMod[] = {
1914 { "json_each", &jsonEachModule },
1915 { "json_tree", &jsonTreeModule },
1916 };
drhd2975922015-08-29 17:22:33 +00001917#endif
drh5fa5c102015-08-12 16:49:40 +00001918 SQLITE_EXTENSION_INIT2(pApi);
1919 (void)pzErrMsg; /* Unused parameter */
1920 for(i=0; i<sizeof(aFunc)/sizeof(aFunc[0]) && rc==SQLITE_OK; i++){
1921 rc = sqlite3_create_function(db, aFunc[i].zName, aFunc[i].nArg,
drh52216ad2015-08-18 02:28:03 +00001922 SQLITE_UTF8 | SQLITE_DETERMINISTIC,
1923 (void*)&aFunc[i].flag,
drh5fa5c102015-08-12 16:49:40 +00001924 aFunc[i].xFunc, 0, 0);
1925 }
drhd2975922015-08-29 17:22:33 +00001926#ifndef SQLITE_OMIT_VIRTUALTABLE
drh505ad2c2015-08-21 17:33:11 +00001927 for(i=0; i<sizeof(aMod)/sizeof(aMod[0]) && rc==SQLITE_OK; i++){
1928 rc = sqlite3_create_module(db, aMod[i].zName, aMod[i].pModule, 0);
drhcb6c6c62015-08-19 22:47:17 +00001929 }
drhd2975922015-08-29 17:22:33 +00001930#endif
drh5fa5c102015-08-12 16:49:40 +00001931 return rc;
1932}