blob: 77857f5447ec04f96bcacf374da2379c4f79ea72 [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
dan2e8f5512015-09-17 17:21:09 +000036/*
37** Versions of isspace(), isalnum() and isdigit() to which it is safe
38** to pass signed char values.
39*/
dan2e8f5512015-09-17 17:21:09 +000040#define safe_isdigit(x) isdigit((unsigned char)(x))
41#define safe_isalnum(x) isalnum((unsigned char)(x))
42
drh95677942015-09-24 01:06:37 +000043/*
44** Growing our own isspace() routine this way is twice as fast as
45** the library isspace() function, resulting in a 7% overall performance
46** increase for the parser. (Ubuntu14.10 gcc 4.8.4 x64 with -Os).
47*/
48static const char jsonIsSpace[] = {
49 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0,
50 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
51 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
52 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
53 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
54 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
55 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
56 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
57 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
58 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
59 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
60 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
61 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
62 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
63 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
64 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
65};
66#define safe_isspace(x) (jsonIsSpace[(unsigned char)x])
67
drh5fa5c102015-08-12 16:49:40 +000068/* Unsigned integer types */
69typedef sqlite3_uint64 u64;
70typedef unsigned int u32;
71typedef unsigned char u8;
72
drh52216ad2015-08-18 02:28:03 +000073/* Objects */
drh505ad2c2015-08-21 17:33:11 +000074typedef struct JsonString JsonString;
drh52216ad2015-08-18 02:28:03 +000075typedef struct JsonNode JsonNode;
76typedef struct JsonParse JsonParse;
77
drh5634cc02015-08-17 11:28:03 +000078/* An instance of this object represents a JSON string
79** under construction. Really, this is a generic string accumulator
80** that can be and is used to create strings other than JSON.
drh5fa5c102015-08-12 16:49:40 +000081*/
drh505ad2c2015-08-21 17:33:11 +000082struct JsonString {
drh5fa5c102015-08-12 16:49:40 +000083 sqlite3_context *pCtx; /* Function context - put error messages here */
drh5634cc02015-08-17 11:28:03 +000084 char *zBuf; /* Append JSON content here */
drh5fa5c102015-08-12 16:49:40 +000085 u64 nAlloc; /* Bytes of storage available in zBuf[] */
86 u64 nUsed; /* Bytes of zBuf[] currently used */
87 u8 bStatic; /* True if zBuf is static space */
drhd0960592015-08-17 21:22:32 +000088 u8 bErr; /* True if an error has been encountered */
drh5fa5c102015-08-12 16:49:40 +000089 char zSpace[100]; /* Initial static space */
90};
91
drhe9c37f32015-08-15 21:25:36 +000092/* JSON type values
drhbd0621b2015-08-13 13:54:59 +000093*/
drhe9c37f32015-08-15 21:25:36 +000094#define JSON_NULL 0
95#define JSON_TRUE 1
96#define JSON_FALSE 2
97#define JSON_INT 3
98#define JSON_REAL 4
99#define JSON_STRING 5
100#define JSON_ARRAY 6
101#define JSON_OBJECT 7
102
drhf5ddb9c2015-09-11 00:06:41 +0000103/* The "subtype" set for JSON values */
104#define JSON_SUBTYPE 74 /* Ascii for "J" */
105
drh987eb1f2015-08-17 15:17:37 +0000106/*
107** Names of the various JSON types:
108*/
109static const char * const jsonType[] = {
110 "null", "true", "false", "integer", "real", "text", "array", "object"
111};
112
drh301eecc2015-08-17 20:14:19 +0000113/* Bit values for the JsonNode.jnFlag field
114*/
115#define JNODE_RAW 0x01 /* Content is raw, not JSON encoded */
116#define JNODE_ESCAPE 0x02 /* Content is text with \ escapes */
117#define JNODE_REMOVE 0x04 /* Do not output */
drhd0960592015-08-17 21:22:32 +0000118#define JNODE_REPLACE 0x08 /* Replace with JsonNode.iVal */
drh52216ad2015-08-18 02:28:03 +0000119#define JNODE_APPEND 0x10 /* More ARRAY/OBJECT entries at u.iAppend */
drhf5ddb9c2015-09-11 00:06:41 +0000120#define JNODE_LABEL 0x20 /* Is a label of an object */
drh301eecc2015-08-17 20:14:19 +0000121
drh987eb1f2015-08-17 15:17:37 +0000122
drhe9c37f32015-08-15 21:25:36 +0000123/* A single node of parsed JSON
124*/
drhe9c37f32015-08-15 21:25:36 +0000125struct JsonNode {
drh5634cc02015-08-17 11:28:03 +0000126 u8 eType; /* One of the JSON_ type values */
drh301eecc2015-08-17 20:14:19 +0000127 u8 jnFlags; /* JNODE flags */
drhd0960592015-08-17 21:22:32 +0000128 u8 iVal; /* Replacement value when JNODE_REPLACE */
drhe9c37f32015-08-15 21:25:36 +0000129 u32 n; /* Bytes of content, or number of sub-nodes */
drh52216ad2015-08-18 02:28:03 +0000130 union {
drh0042a972015-08-18 12:59:58 +0000131 const char *zJContent; /* Content for INT, REAL, and STRING */
132 u32 iAppend; /* More terms for ARRAY and OBJECT */
drh505ad2c2015-08-21 17:33:11 +0000133 u32 iKey; /* Key for ARRAY objects in json_tree() */
drh52216ad2015-08-18 02:28:03 +0000134 } u;
drhe9c37f32015-08-15 21:25:36 +0000135};
136
137/* A completely parsed JSON string
138*/
drhe9c37f32015-08-15 21:25:36 +0000139struct JsonParse {
140 u32 nNode; /* Number of slots of aNode[] used */
141 u32 nAlloc; /* Number of slots of aNode[] allocated */
142 JsonNode *aNode; /* Array of nodes containing the parse */
143 const char *zJson; /* Original JSON string */
drh505ad2c2015-08-21 17:33:11 +0000144 u32 *aUp; /* Index of parent of each node */
drhe9c37f32015-08-15 21:25:36 +0000145 u8 oom; /* Set to true if out of memory */
drha7714022015-08-29 00:54:49 +0000146 u8 nErr; /* Number of errors seen */
drhe9c37f32015-08-15 21:25:36 +0000147};
148
drh505ad2c2015-08-21 17:33:11 +0000149/**************************************************************************
150** Utility routines for dealing with JsonString objects
151**************************************************************************/
drh301eecc2015-08-17 20:14:19 +0000152
drh505ad2c2015-08-21 17:33:11 +0000153/* Set the JsonString object to an empty string
drh5fa5c102015-08-12 16:49:40 +0000154*/
drh505ad2c2015-08-21 17:33:11 +0000155static void jsonZero(JsonString *p){
drh5fa5c102015-08-12 16:49:40 +0000156 p->zBuf = p->zSpace;
157 p->nAlloc = sizeof(p->zSpace);
158 p->nUsed = 0;
159 p->bStatic = 1;
160}
161
drh505ad2c2015-08-21 17:33:11 +0000162/* Initialize the JsonString object
drh5fa5c102015-08-12 16:49:40 +0000163*/
drh505ad2c2015-08-21 17:33:11 +0000164static void jsonInit(JsonString *p, sqlite3_context *pCtx){
drh5fa5c102015-08-12 16:49:40 +0000165 p->pCtx = pCtx;
drhd0960592015-08-17 21:22:32 +0000166 p->bErr = 0;
drh5fa5c102015-08-12 16:49:40 +0000167 jsonZero(p);
168}
169
170
drh505ad2c2015-08-21 17:33:11 +0000171/* Free all allocated memory and reset the JsonString object back to its
drh5fa5c102015-08-12 16:49:40 +0000172** initial state.
173*/
drh505ad2c2015-08-21 17:33:11 +0000174static void jsonReset(JsonString *p){
drh5fa5c102015-08-12 16:49:40 +0000175 if( !p->bStatic ) sqlite3_free(p->zBuf);
176 jsonZero(p);
177}
178
179
180/* Report an out-of-memory (OOM) condition
181*/
drh505ad2c2015-08-21 17:33:11 +0000182static void jsonOom(JsonString *p){
drh3d1d2a92015-09-22 01:15:49 +0000183 p->bErr = 1;
184 sqlite3_result_error_nomem(p->pCtx);
185 jsonReset(p);
drh5fa5c102015-08-12 16:49:40 +0000186}
187
188/* Enlarge pJson->zBuf so that it can hold at least N more bytes.
189** Return zero on success. Return non-zero on an OOM error
190*/
drh505ad2c2015-08-21 17:33:11 +0000191static int jsonGrow(JsonString *p, u32 N){
drh301eecc2015-08-17 20:14:19 +0000192 u64 nTotal = N<p->nAlloc ? p->nAlloc*2 : p->nAlloc+N+10;
drh5fa5c102015-08-12 16:49:40 +0000193 char *zNew;
194 if( p->bStatic ){
drhd0960592015-08-17 21:22:32 +0000195 if( p->bErr ) return 1;
drh5fa5c102015-08-12 16:49:40 +0000196 zNew = sqlite3_malloc64(nTotal);
197 if( zNew==0 ){
198 jsonOom(p);
199 return SQLITE_NOMEM;
200 }
drh6fd5c1e2015-08-21 20:37:12 +0000201 memcpy(zNew, p->zBuf, (size_t)p->nUsed);
drh5fa5c102015-08-12 16:49:40 +0000202 p->zBuf = zNew;
203 p->bStatic = 0;
204 }else{
205 zNew = sqlite3_realloc64(p->zBuf, nTotal);
206 if( zNew==0 ){
207 jsonOom(p);
208 return SQLITE_NOMEM;
209 }
210 p->zBuf = zNew;
211 }
212 p->nAlloc = nTotal;
213 return SQLITE_OK;
214}
215
drh505ad2c2015-08-21 17:33:11 +0000216/* Append N bytes from zIn onto the end of the JsonString string.
drh5fa5c102015-08-12 16:49:40 +0000217*/
drh505ad2c2015-08-21 17:33:11 +0000218static void jsonAppendRaw(JsonString *p, const char *zIn, u32 N){
drh5fa5c102015-08-12 16:49:40 +0000219 if( (N+p->nUsed >= p->nAlloc) && jsonGrow(p,N)!=0 ) return;
220 memcpy(p->zBuf+p->nUsed, zIn, N);
221 p->nUsed += N;
222}
223
drh4af352d2015-08-21 20:02:48 +0000224/* Append formatted text (not to exceed N bytes) to the JsonString.
225*/
226static void jsonPrintf(int N, JsonString *p, const char *zFormat, ...){
227 va_list ap;
228 if( (p->nUsed + N >= p->nAlloc) && jsonGrow(p, N) ) return;
229 va_start(ap, zFormat);
230 sqlite3_vsnprintf(N, p->zBuf+p->nUsed, zFormat, ap);
231 va_end(ap);
232 p->nUsed += (int)strlen(p->zBuf+p->nUsed);
233}
234
drh5634cc02015-08-17 11:28:03 +0000235/* Append a single character
236*/
drh505ad2c2015-08-21 17:33:11 +0000237static void jsonAppendChar(JsonString *p, char c){
drh5634cc02015-08-17 11:28:03 +0000238 if( p->nUsed>=p->nAlloc && jsonGrow(p,1)!=0 ) return;
239 p->zBuf[p->nUsed++] = c;
240}
241
drh301eecc2015-08-17 20:14:19 +0000242/* Append a comma separator to the output buffer, if the previous
243** character is not '[' or '{'.
244*/
drh505ad2c2015-08-21 17:33:11 +0000245static void jsonAppendSeparator(JsonString *p){
drh301eecc2015-08-17 20:14:19 +0000246 char c;
247 if( p->nUsed==0 ) return;
248 c = p->zBuf[p->nUsed-1];
249 if( c!='[' && c!='{' ) jsonAppendChar(p, ',');
250}
251
drh505ad2c2015-08-21 17:33:11 +0000252/* Append the N-byte string in zIn to the end of the JsonString string
drh5fa5c102015-08-12 16:49:40 +0000253** under construction. Enclose the string in "..." and escape
254** any double-quotes or backslash characters contained within the
255** string.
256*/
drh505ad2c2015-08-21 17:33:11 +0000257static void jsonAppendString(JsonString *p, const char *zIn, u32 N){
drh5fa5c102015-08-12 16:49:40 +0000258 u32 i;
259 if( (N+p->nUsed+2 >= p->nAlloc) && jsonGrow(p,N+2)!=0 ) return;
260 p->zBuf[p->nUsed++] = '"';
261 for(i=0; i<N; i++){
262 char c = zIn[i];
263 if( c=='"' || c=='\\' ){
drh4977ccf2015-09-19 11:57:26 +0000264 if( (p->nUsed+N+3-i > p->nAlloc) && jsonGrow(p,N+3-i)!=0 ) return;
drh5fa5c102015-08-12 16:49:40 +0000265 p->zBuf[p->nUsed++] = '\\';
266 }
267 p->zBuf[p->nUsed++] = c;
268 }
269 p->zBuf[p->nUsed++] = '"';
drh4977ccf2015-09-19 11:57:26 +0000270 assert( p->nUsed<p->nAlloc );
drh5fa5c102015-08-12 16:49:40 +0000271}
272
drhd0960592015-08-17 21:22:32 +0000273/*
274** Append a function parameter value to the JSON string under
275** construction.
276*/
277static void jsonAppendValue(
drh505ad2c2015-08-21 17:33:11 +0000278 JsonString *p, /* Append to this JSON string */
drhf5ddb9c2015-09-11 00:06:41 +0000279 sqlite3_value *pValue /* Value to append */
drhd0960592015-08-17 21:22:32 +0000280){
281 switch( sqlite3_value_type(pValue) ){
282 case SQLITE_NULL: {
283 jsonAppendRaw(p, "null", 4);
284 break;
285 }
286 case SQLITE_INTEGER:
287 case SQLITE_FLOAT: {
288 const char *z = (const char*)sqlite3_value_text(pValue);
289 u32 n = (u32)sqlite3_value_bytes(pValue);
290 jsonAppendRaw(p, z, n);
291 break;
292 }
293 case SQLITE_TEXT: {
294 const char *z = (const char*)sqlite3_value_text(pValue);
295 u32 n = (u32)sqlite3_value_bytes(pValue);
drhf5ddb9c2015-09-11 00:06:41 +0000296 if( sqlite3_value_subtype(pValue)==JSON_SUBTYPE ){
drhecb5fed2015-08-28 03:33:50 +0000297 jsonAppendRaw(p, z, n);
298 }else{
299 jsonAppendString(p, z, n);
300 }
drhd0960592015-08-17 21:22:32 +0000301 break;
302 }
303 default: {
304 if( p->bErr==0 ){
305 sqlite3_result_error(p->pCtx, "JSON cannot hold BLOB values", -1);
306 p->bErr = 1;
307 jsonReset(p);
308 }
309 break;
310 }
311 }
312}
313
314
drhbd0621b2015-08-13 13:54:59 +0000315/* Make the JSON in p the result of the SQL function.
drh5fa5c102015-08-12 16:49:40 +0000316*/
drh505ad2c2015-08-21 17:33:11 +0000317static void jsonResult(JsonString *p){
drhd0960592015-08-17 21:22:32 +0000318 if( p->bErr==0 ){
drh5fa5c102015-08-12 16:49:40 +0000319 sqlite3_result_text64(p->pCtx, p->zBuf, p->nUsed,
320 p->bStatic ? SQLITE_TRANSIENT : sqlite3_free,
321 SQLITE_UTF8);
322 jsonZero(p);
323 }
324 assert( p->bStatic );
325}
326
drh505ad2c2015-08-21 17:33:11 +0000327/**************************************************************************
328** Utility routines for dealing with JsonNode and JsonParse objects
329**************************************************************************/
330
331/*
332** Return the number of consecutive JsonNode slots need to represent
333** the parsed JSON at pNode. The minimum answer is 1. For ARRAY and
334** OBJECT types, the number might be larger.
335**
336** Appended elements are not counted. The value returned is the number
337** by which the JsonNode counter should increment in order to go to the
338** next peer value.
339*/
340static u32 jsonNodeSize(JsonNode *pNode){
341 return pNode->eType>=JSON_ARRAY ? pNode->n+1 : 1;
342}
343
344/*
345** Reclaim all memory allocated by a JsonParse object. But do not
346** delete the JsonParse object itself.
347*/
348static void jsonParseReset(JsonParse *pParse){
349 sqlite3_free(pParse->aNode);
350 pParse->aNode = 0;
351 pParse->nNode = 0;
352 pParse->nAlloc = 0;
353 sqlite3_free(pParse->aUp);
354 pParse->aUp = 0;
355}
356
drh5634cc02015-08-17 11:28:03 +0000357/*
358** Convert the JsonNode pNode into a pure JSON string and
359** append to pOut. Subsubstructure is also included. Return
360** the number of JsonNode objects that are encoded.
drhbd0621b2015-08-13 13:54:59 +0000361*/
drh52216ad2015-08-18 02:28:03 +0000362static void jsonRenderNode(
drhd0960592015-08-17 21:22:32 +0000363 JsonNode *pNode, /* The node to render */
drh505ad2c2015-08-21 17:33:11 +0000364 JsonString *pOut, /* Write JSON here */
drhd0960592015-08-17 21:22:32 +0000365 sqlite3_value **aReplace /* Replacement values */
366){
drh5634cc02015-08-17 11:28:03 +0000367 switch( pNode->eType ){
drha8f39a92015-09-21 22:53:16 +0000368 default: {
369 assert( pNode->eType==JSON_NULL );
drh5634cc02015-08-17 11:28:03 +0000370 jsonAppendRaw(pOut, "null", 4);
371 break;
372 }
373 case JSON_TRUE: {
374 jsonAppendRaw(pOut, "true", 4);
375 break;
376 }
377 case JSON_FALSE: {
378 jsonAppendRaw(pOut, "false", 5);
379 break;
380 }
381 case JSON_STRING: {
drh301eecc2015-08-17 20:14:19 +0000382 if( pNode->jnFlags & JNODE_RAW ){
drh52216ad2015-08-18 02:28:03 +0000383 jsonAppendString(pOut, pNode->u.zJContent, pNode->n);
drh5634cc02015-08-17 11:28:03 +0000384 break;
385 }
386 /* Fall through into the next case */
387 }
388 case JSON_REAL:
389 case JSON_INT: {
drh52216ad2015-08-18 02:28:03 +0000390 jsonAppendRaw(pOut, pNode->u.zJContent, pNode->n);
drh5634cc02015-08-17 11:28:03 +0000391 break;
392 }
393 case JSON_ARRAY: {
drh52216ad2015-08-18 02:28:03 +0000394 u32 j = 1;
drh5634cc02015-08-17 11:28:03 +0000395 jsonAppendChar(pOut, '[');
drh52216ad2015-08-18 02:28:03 +0000396 for(;;){
397 while( j<=pNode->n ){
398 if( pNode[j].jnFlags & (JNODE_REMOVE|JNODE_REPLACE) ){
399 if( pNode[j].jnFlags & JNODE_REPLACE ){
400 jsonAppendSeparator(pOut);
drhf5ddb9c2015-09-11 00:06:41 +0000401 jsonAppendValue(pOut, aReplace[pNode[j].iVal]);
drh52216ad2015-08-18 02:28:03 +0000402 }
403 }else{
drhd0960592015-08-17 21:22:32 +0000404 jsonAppendSeparator(pOut);
drh52216ad2015-08-18 02:28:03 +0000405 jsonRenderNode(&pNode[j], pOut, aReplace);
drhd0960592015-08-17 21:22:32 +0000406 }
drh505ad2c2015-08-21 17:33:11 +0000407 j += jsonNodeSize(&pNode[j]);
drh301eecc2015-08-17 20:14:19 +0000408 }
drh52216ad2015-08-18 02:28:03 +0000409 if( (pNode->jnFlags & JNODE_APPEND)==0 ) break;
410 pNode = &pNode[pNode->u.iAppend];
411 j = 1;
drh5634cc02015-08-17 11:28:03 +0000412 }
413 jsonAppendChar(pOut, ']');
414 break;
415 }
416 case JSON_OBJECT: {
drh52216ad2015-08-18 02:28:03 +0000417 u32 j = 1;
drh5634cc02015-08-17 11:28:03 +0000418 jsonAppendChar(pOut, '{');
drh52216ad2015-08-18 02:28:03 +0000419 for(;;){
420 while( j<=pNode->n ){
421 if( (pNode[j+1].jnFlags & JNODE_REMOVE)==0 ){
422 jsonAppendSeparator(pOut);
423 jsonRenderNode(&pNode[j], pOut, aReplace);
424 jsonAppendChar(pOut, ':');
425 if( pNode[j+1].jnFlags & JNODE_REPLACE ){
drhf5ddb9c2015-09-11 00:06:41 +0000426 jsonAppendValue(pOut, aReplace[pNode[j+1].iVal]);
drh52216ad2015-08-18 02:28:03 +0000427 }else{
428 jsonRenderNode(&pNode[j+1], pOut, aReplace);
429 }
drhd0960592015-08-17 21:22:32 +0000430 }
drh505ad2c2015-08-21 17:33:11 +0000431 j += 1 + jsonNodeSize(&pNode[j+1]);
drh301eecc2015-08-17 20:14:19 +0000432 }
drh52216ad2015-08-18 02:28:03 +0000433 if( (pNode->jnFlags & JNODE_APPEND)==0 ) break;
434 pNode = &pNode[pNode->u.iAppend];
435 j = 1;
drh5634cc02015-08-17 11:28:03 +0000436 }
437 jsonAppendChar(pOut, '}');
438 break;
439 }
drhbd0621b2015-08-13 13:54:59 +0000440 }
drh5634cc02015-08-17 11:28:03 +0000441}
442
443/*
drhf2df7e72015-08-28 20:07:40 +0000444** Return a JsonNode and all its descendents as a JSON string.
445*/
446static void jsonReturnJson(
447 JsonNode *pNode, /* Node to return */
448 sqlite3_context *pCtx, /* Return value for this function */
449 sqlite3_value **aReplace /* Array of replacement values */
450){
451 JsonString s;
452 jsonInit(&s, pCtx);
453 jsonRenderNode(pNode, &s, aReplace);
454 jsonResult(&s);
drhf5ddb9c2015-09-11 00:06:41 +0000455 sqlite3_result_subtype(pCtx, JSON_SUBTYPE);
drhf2df7e72015-08-28 20:07:40 +0000456}
457
458/*
drh5634cc02015-08-17 11:28:03 +0000459** Make the JsonNode the return value of the function.
460*/
drhd0960592015-08-17 21:22:32 +0000461static void jsonReturn(
462 JsonNode *pNode, /* Node to return */
463 sqlite3_context *pCtx, /* Return value for this function */
464 sqlite3_value **aReplace /* Array of replacement values */
465){
drh5634cc02015-08-17 11:28:03 +0000466 switch( pNode->eType ){
drha8f39a92015-09-21 22:53:16 +0000467 default: {
468 assert( pNode->eType==JSON_NULL );
drh5634cc02015-08-17 11:28:03 +0000469 sqlite3_result_null(pCtx);
470 break;
471 }
472 case JSON_TRUE: {
473 sqlite3_result_int(pCtx, 1);
474 break;
475 }
476 case JSON_FALSE: {
477 sqlite3_result_int(pCtx, 0);
478 break;
479 }
drh987eb1f2015-08-17 15:17:37 +0000480 case JSON_REAL: {
drh52216ad2015-08-18 02:28:03 +0000481 double r = strtod(pNode->u.zJContent, 0);
drh987eb1f2015-08-17 15:17:37 +0000482 sqlite3_result_double(pCtx, r);
drh5634cc02015-08-17 11:28:03 +0000483 break;
484 }
drh987eb1f2015-08-17 15:17:37 +0000485 case JSON_INT: {
486 sqlite3_int64 i = 0;
drh52216ad2015-08-18 02:28:03 +0000487 const char *z = pNode->u.zJContent;
drh987eb1f2015-08-17 15:17:37 +0000488 if( z[0]=='-' ){ z++; }
489 while( z[0]>='0' && z[0]<='9' ){ i = i*10 + *(z++) - '0'; }
drh52216ad2015-08-18 02:28:03 +0000490 if( pNode->u.zJContent[0]=='-' ){ i = -i; }
drh987eb1f2015-08-17 15:17:37 +0000491 sqlite3_result_int64(pCtx, i);
492 break;
493 }
drh5634cc02015-08-17 11:28:03 +0000494 case JSON_STRING: {
drha8f39a92015-09-21 22:53:16 +0000495#if 0 /* Never happens because JNODE_RAW is only set by json_set(),
496 ** json_insert() and json_replace() and those routines do not
497 ** call jsonReturn() */
drh301eecc2015-08-17 20:14:19 +0000498 if( pNode->jnFlags & JNODE_RAW ){
drh52216ad2015-08-18 02:28:03 +0000499 sqlite3_result_text(pCtx, pNode->u.zJContent, pNode->n,
500 SQLITE_TRANSIENT);
drha8f39a92015-09-21 22:53:16 +0000501 }else
502#endif
503 assert( (pNode->jnFlags & JNODE_RAW)==0 );
504 if( (pNode->jnFlags & JNODE_ESCAPE)==0 ){
drh987eb1f2015-08-17 15:17:37 +0000505 /* JSON formatted without any backslash-escapes */
drh52216ad2015-08-18 02:28:03 +0000506 sqlite3_result_text(pCtx, pNode->u.zJContent+1, pNode->n-2,
drh987eb1f2015-08-17 15:17:37 +0000507 SQLITE_TRANSIENT);
drh5634cc02015-08-17 11:28:03 +0000508 }else{
509 /* Translate JSON formatted string into raw text */
drh987eb1f2015-08-17 15:17:37 +0000510 u32 i;
511 u32 n = pNode->n;
drh52216ad2015-08-18 02:28:03 +0000512 const char *z = pNode->u.zJContent;
drh987eb1f2015-08-17 15:17:37 +0000513 char *zOut;
514 u32 j;
515 zOut = sqlite3_malloc( n+1 );
516 if( zOut==0 ){
517 sqlite3_result_error_nomem(pCtx);
518 break;
519 }
520 for(i=1, j=0; i<n-1; i++){
521 char c = z[i];
drh80d87402015-08-24 12:42:41 +0000522 if( c!='\\' ){
drh987eb1f2015-08-17 15:17:37 +0000523 zOut[j++] = c;
524 }else{
525 c = z[++i];
drh80d87402015-08-24 12:42:41 +0000526 if( c=='u' ){
drh987eb1f2015-08-17 15:17:37 +0000527 u32 v = 0, k;
drh80d87402015-08-24 12:42:41 +0000528 for(k=0; k<4 && i<n-2; i++, k++){
drh8784eca2015-08-23 02:42:30 +0000529 c = z[i+1];
drh987eb1f2015-08-17 15:17:37 +0000530 if( c>='0' && c<='9' ) v = v*16 + c - '0';
531 else if( c>='A' && c<='F' ) v = v*16 + c - 'A' + 10;
532 else if( c>='a' && c<='f' ) v = v*16 + c - 'a' + 10;
533 else break;
drh987eb1f2015-08-17 15:17:37 +0000534 }
drh80d87402015-08-24 12:42:41 +0000535 if( v==0 ) break;
drh987eb1f2015-08-17 15:17:37 +0000536 if( v<=0x7f ){
mistachkin16a93122015-09-11 18:05:01 +0000537 zOut[j++] = (char)v;
drh987eb1f2015-08-17 15:17:37 +0000538 }else if( v<=0x7ff ){
mistachkin16a93122015-09-11 18:05:01 +0000539 zOut[j++] = (char)(0xc0 | (v>>6));
drh987eb1f2015-08-17 15:17:37 +0000540 zOut[j++] = 0x80 | (v&0x3f);
drh80d87402015-08-24 12:42:41 +0000541 }else{
mistachkin16a93122015-09-11 18:05:01 +0000542 zOut[j++] = (char)(0xe0 | (v>>12));
drh987eb1f2015-08-17 15:17:37 +0000543 zOut[j++] = 0x80 | ((v>>6)&0x3f);
544 zOut[j++] = 0x80 | (v&0x3f);
drh987eb1f2015-08-17 15:17:37 +0000545 }
546 }else{
547 if( c=='b' ){
548 c = '\b';
549 }else if( c=='f' ){
550 c = '\f';
551 }else if( c=='n' ){
552 c = '\n';
553 }else if( c=='r' ){
554 c = '\r';
555 }else if( c=='t' ){
556 c = '\t';
557 }
558 zOut[j++] = c;
559 }
560 }
561 }
562 zOut[j] = 0;
563 sqlite3_result_text(pCtx, zOut, j, sqlite3_free);
drh5634cc02015-08-17 11:28:03 +0000564 }
565 break;
566 }
567 case JSON_ARRAY:
568 case JSON_OBJECT: {
drhf2df7e72015-08-28 20:07:40 +0000569 jsonReturnJson(pNode, pCtx, aReplace);
drh5634cc02015-08-17 11:28:03 +0000570 break;
571 }
572 }
drhbd0621b2015-08-13 13:54:59 +0000573}
574
drh95677942015-09-24 01:06:37 +0000575/* Forward reference */
576static int jsonParseAddNode(JsonParse*,u32,u32,const char*);
577
578/*
579** A macro to hint to the compiler that a function should not be
580** inlined.
581*/
582#if defined(__GNUC__)
583# define JSON_NOINLINE __attribute__((noinline))
584#elif defined(_MSC_VER) && _MSC_VER>=1310
585# define JSON_NOINLINE __declspec(noinline)
586#else
587# define JSON_NOINLINE
588#endif
589
590
591static JSON_NOINLINE int jsonParseAddNodeExpand(
592 JsonParse *pParse, /* Append the node to this object */
593 u32 eType, /* Node type */
594 u32 n, /* Content size or sub-node count */
595 const char *zContent /* Content */
596){
597 u32 nNew;
598 JsonNode *pNew;
599 assert( pParse->nNode>=pParse->nAlloc );
600 if( pParse->oom ) return -1;
601 nNew = pParse->nAlloc*2 + 10;
602 pNew = sqlite3_realloc(pParse->aNode, sizeof(JsonNode)*nNew);
603 if( pNew==0 ){
604 pParse->oom = 1;
605 return -1;
606 }
607 pParse->nAlloc = nNew;
608 pParse->aNode = pNew;
609 assert( pParse->nNode<pParse->nAlloc );
610 return jsonParseAddNode(pParse, eType, n, zContent);
611}
612
drh5fa5c102015-08-12 16:49:40 +0000613/*
drhe9c37f32015-08-15 21:25:36 +0000614** Create a new JsonNode instance based on the arguments and append that
615** instance to the JsonParse. Return the index in pParse->aNode[] of the
616** new node, or -1 if a memory allocation fails.
617*/
618static int jsonParseAddNode(
619 JsonParse *pParse, /* Append the node to this object */
620 u32 eType, /* Node type */
621 u32 n, /* Content size or sub-node count */
622 const char *zContent /* Content */
623){
624 JsonNode *p;
625 if( pParse->nNode>=pParse->nAlloc ){
drh95677942015-09-24 01:06:37 +0000626 return jsonParseAddNodeExpand(pParse, eType, n, zContent);
drhe9c37f32015-08-15 21:25:36 +0000627 }
628 p = &pParse->aNode[pParse->nNode];
drh5634cc02015-08-17 11:28:03 +0000629 p->eType = (u8)eType;
drh301eecc2015-08-17 20:14:19 +0000630 p->jnFlags = 0;
drhd0960592015-08-17 21:22:32 +0000631 p->iVal = 0;
drhe9c37f32015-08-15 21:25:36 +0000632 p->n = n;
drh52216ad2015-08-18 02:28:03 +0000633 p->u.zJContent = zContent;
drhe9c37f32015-08-15 21:25:36 +0000634 return pParse->nNode++;
635}
636
637/*
638** Parse a single JSON value which begins at pParse->zJson[i]. Return the
639** index of the first character past the end of the value parsed.
640**
641** Return negative for a syntax error. Special cases: return -2 if the
642** first non-whitespace character is '}' and return -3 if the first
643** non-whitespace character is ']'.
644*/
645static int jsonParseValue(JsonParse *pParse, u32 i){
646 char c;
647 u32 j;
drhbc8f0922015-08-22 19:39:04 +0000648 int iThis;
drhe9c37f32015-08-15 21:25:36 +0000649 int x;
drh852944e2015-09-10 03:29:11 +0000650 JsonNode *pNode;
dan2e8f5512015-09-17 17:21:09 +0000651 while( safe_isspace(pParse->zJson[i]) ){ i++; }
drh8cb15cc2015-09-24 01:40:45 +0000652 if( (c = pParse->zJson[i])=='{' ){
drhe9c37f32015-08-15 21:25:36 +0000653 /* Parse object */
654 iThis = jsonParseAddNode(pParse, JSON_OBJECT, 0, 0);
drhbc8f0922015-08-22 19:39:04 +0000655 if( iThis<0 ) return -1;
drhe9c37f32015-08-15 21:25:36 +0000656 for(j=i+1;;j++){
dan2e8f5512015-09-17 17:21:09 +0000657 while( safe_isspace(pParse->zJson[j]) ){ j++; }
drhe9c37f32015-08-15 21:25:36 +0000658 x = jsonParseValue(pParse, j);
659 if( x<0 ){
drhf27cd1f2015-09-23 01:10:29 +0000660 if( x==(-2) && pParse->nNode==(u32)iThis+1 ) return j+1;
drhe9c37f32015-08-15 21:25:36 +0000661 return -1;
662 }
drhbe9474e2015-08-22 03:05:54 +0000663 if( pParse->oom ) return -1;
drh852944e2015-09-10 03:29:11 +0000664 pNode = &pParse->aNode[pParse->nNode-1];
665 if( pNode->eType!=JSON_STRING ) return -1;
666 pNode->jnFlags |= JNODE_LABEL;
drhe9c37f32015-08-15 21:25:36 +0000667 j = x;
dan2e8f5512015-09-17 17:21:09 +0000668 while( safe_isspace(pParse->zJson[j]) ){ j++; }
drhe9c37f32015-08-15 21:25:36 +0000669 if( pParse->zJson[j]!=':' ) return -1;
670 j++;
671 x = jsonParseValue(pParse, j);
672 if( x<0 ) return -1;
673 j = x;
dan2e8f5512015-09-17 17:21:09 +0000674 while( safe_isspace(pParse->zJson[j]) ){ j++; }
drhe9c37f32015-08-15 21:25:36 +0000675 c = pParse->zJson[j];
676 if( c==',' ) continue;
677 if( c!='}' ) return -1;
678 break;
679 }
drhbc8f0922015-08-22 19:39:04 +0000680 pParse->aNode[iThis].n = pParse->nNode - (u32)iThis - 1;
drhe9c37f32015-08-15 21:25:36 +0000681 return j+1;
682 }else if( c=='[' ){
683 /* Parse array */
684 iThis = jsonParseAddNode(pParse, JSON_ARRAY, 0, 0);
drhbc8f0922015-08-22 19:39:04 +0000685 if( iThis<0 ) return -1;
drhe9c37f32015-08-15 21:25:36 +0000686 for(j=i+1;;j++){
dan2e8f5512015-09-17 17:21:09 +0000687 while( safe_isspace(pParse->zJson[j]) ){ j++; }
drhe9c37f32015-08-15 21:25:36 +0000688 x = jsonParseValue(pParse, j);
689 if( x<0 ){
drhf27cd1f2015-09-23 01:10:29 +0000690 if( x==(-3) && pParse->nNode==(u32)iThis+1 ) return j+1;
drhe9c37f32015-08-15 21:25:36 +0000691 return -1;
692 }
693 j = x;
dan2e8f5512015-09-17 17:21:09 +0000694 while( safe_isspace(pParse->zJson[j]) ){ j++; }
drhe9c37f32015-08-15 21:25:36 +0000695 c = pParse->zJson[j];
696 if( c==',' ) continue;
697 if( c!=']' ) return -1;
698 break;
699 }
drhbc8f0922015-08-22 19:39:04 +0000700 pParse->aNode[iThis].n = pParse->nNode - (u32)iThis - 1;
drhe9c37f32015-08-15 21:25:36 +0000701 return j+1;
702 }else if( c=='"' ){
703 /* Parse string */
drh301eecc2015-08-17 20:14:19 +0000704 u8 jnFlags = 0;
drhe9c37f32015-08-15 21:25:36 +0000705 j = i+1;
706 for(;;){
707 c = pParse->zJson[j];
708 if( c==0 ) return -1;
709 if( c=='\\' ){
710 c = pParse->zJson[++j];
711 if( c==0 ) return -1;
drh301eecc2015-08-17 20:14:19 +0000712 jnFlags = JNODE_ESCAPE;
drhe9c37f32015-08-15 21:25:36 +0000713 }else if( c=='"' ){
714 break;
715 }
716 j++;
717 }
718 jsonParseAddNode(pParse, JSON_STRING, j+1-i, &pParse->zJson[i]);
drhbe9474e2015-08-22 03:05:54 +0000719 if( !pParse->oom ) pParse->aNode[pParse->nNode-1].jnFlags = jnFlags;
drhe9c37f32015-08-15 21:25:36 +0000720 return j+1;
721 }else if( c=='n'
722 && strncmp(pParse->zJson+i,"null",4)==0
dan2e8f5512015-09-17 17:21:09 +0000723 && !safe_isalnum(pParse->zJson[i+4]) ){
drhe9c37f32015-08-15 21:25:36 +0000724 jsonParseAddNode(pParse, JSON_NULL, 0, 0);
725 return i+4;
726 }else if( c=='t'
727 && strncmp(pParse->zJson+i,"true",4)==0
dan2e8f5512015-09-17 17:21:09 +0000728 && !safe_isalnum(pParse->zJson[i+4]) ){
drhe9c37f32015-08-15 21:25:36 +0000729 jsonParseAddNode(pParse, JSON_TRUE, 0, 0);
730 return i+4;
731 }else if( c=='f'
732 && strncmp(pParse->zJson+i,"false",5)==0
dan2e8f5512015-09-17 17:21:09 +0000733 && !safe_isalnum(pParse->zJson[i+5]) ){
drhe9c37f32015-08-15 21:25:36 +0000734 jsonParseAddNode(pParse, JSON_FALSE, 0, 0);
735 return i+5;
736 }else if( c=='-' || (c>='0' && c<='9') ){
737 /* Parse number */
738 u8 seenDP = 0;
739 u8 seenE = 0;
740 j = i+1;
741 for(;; j++){
742 c = pParse->zJson[j];
743 if( c>='0' && c<='9' ) continue;
744 if( c=='.' ){
745 if( pParse->zJson[j-1]=='-' ) return -1;
746 if( seenDP ) return -1;
747 seenDP = 1;
748 continue;
749 }
750 if( c=='e' || c=='E' ){
751 if( pParse->zJson[j-1]<'0' ) return -1;
752 if( seenE ) return -1;
753 seenDP = seenE = 1;
754 c = pParse->zJson[j+1];
drh8784eca2015-08-23 02:42:30 +0000755 if( c=='+' || c=='-' ){
756 j++;
757 c = pParse->zJson[j+1];
758 }
drhd1f00682015-08-29 16:02:37 +0000759 if( c<'0' || c>'9' ) return -1;
drhe9c37f32015-08-15 21:25:36 +0000760 continue;
761 }
762 break;
763 }
764 if( pParse->zJson[j-1]<'0' ) return -1;
765 jsonParseAddNode(pParse, seenDP ? JSON_REAL : JSON_INT,
766 j - i, &pParse->zJson[i]);
767 return j;
768 }else if( c=='}' ){
769 return -2; /* End of {...} */
770 }else if( c==']' ){
771 return -3; /* End of [...] */
drh8cb15cc2015-09-24 01:40:45 +0000772 }else if( c==0 ){
773 return 0; /* End of file */
drhe9c37f32015-08-15 21:25:36 +0000774 }else{
775 return -1; /* Syntax error */
776 }
777}
778
779/*
780** Parse a complete JSON string. Return 0 on success or non-zero if there
781** are any errors. If an error occurs, free all memory associated with
782** pParse.
783**
784** pParse is uninitialized when this routine is called.
785*/
drhbc8f0922015-08-22 19:39:04 +0000786static int jsonParse(
787 JsonParse *pParse, /* Initialize and fill this JsonParse object */
788 sqlite3_context *pCtx, /* Report errors here */
789 const char *zJson /* Input JSON text to be parsed */
790){
drhe9c37f32015-08-15 21:25:36 +0000791 int i;
drhe9c37f32015-08-15 21:25:36 +0000792 memset(pParse, 0, sizeof(*pParse));
drhc3722b22015-08-23 20:44:59 +0000793 if( zJson==0 ) return 1;
drhe9c37f32015-08-15 21:25:36 +0000794 pParse->zJson = zJson;
795 i = jsonParseValue(pParse, 0);
drhc3722b22015-08-23 20:44:59 +0000796 if( pParse->oom ) i = -1;
drhe9c37f32015-08-15 21:25:36 +0000797 if( i>0 ){
dan2e8f5512015-09-17 17:21:09 +0000798 while( safe_isspace(zJson[i]) ) i++;
drhe9c37f32015-08-15 21:25:36 +0000799 if( zJson[i] ) i = -1;
800 }
drhd1f00682015-08-29 16:02:37 +0000801 if( i<=0 ){
drhf2df7e72015-08-28 20:07:40 +0000802 if( pCtx!=0 ){
803 if( pParse->oom ){
804 sqlite3_result_error_nomem(pCtx);
805 }else{
806 sqlite3_result_error(pCtx, "malformed JSON", -1);
807 }
808 }
drh505ad2c2015-08-21 17:33:11 +0000809 jsonParseReset(pParse);
drhe9c37f32015-08-15 21:25:36 +0000810 return 1;
811 }
812 return 0;
813}
drh301eecc2015-08-17 20:14:19 +0000814
drh505ad2c2015-08-21 17:33:11 +0000815/* Mark node i of pParse as being a child of iParent. Call recursively
816** to fill in all the descendants of node i.
817*/
818static void jsonParseFillInParentage(JsonParse *pParse, u32 i, u32 iParent){
819 JsonNode *pNode = &pParse->aNode[i];
820 u32 j;
821 pParse->aUp[i] = iParent;
822 switch( pNode->eType ){
823 case JSON_ARRAY: {
824 for(j=1; j<=pNode->n; j += jsonNodeSize(pNode+j)){
825 jsonParseFillInParentage(pParse, i+j, i);
826 }
827 break;
828 }
829 case JSON_OBJECT: {
830 for(j=1; j<=pNode->n; j += jsonNodeSize(pNode+j+1)+1){
831 pParse->aUp[i+j] = i;
832 jsonParseFillInParentage(pParse, i+j+1, i);
833 }
834 break;
835 }
836 default: {
837 break;
838 }
839 }
840}
841
842/*
843** Compute the parentage of all nodes in a completed parse.
844*/
845static int jsonParseFindParents(JsonParse *pParse){
846 u32 *aUp;
847 assert( pParse->aUp==0 );
848 aUp = pParse->aUp = sqlite3_malloc( sizeof(u32)*pParse->nNode );
drhc3722b22015-08-23 20:44:59 +0000849 if( aUp==0 ){
850 pParse->oom = 1;
851 return SQLITE_NOMEM;
852 }
drh505ad2c2015-08-21 17:33:11 +0000853 jsonParseFillInParentage(pParse, 0, 0);
854 return SQLITE_OK;
855}
856
drh8cb0c832015-09-22 00:21:03 +0000857/*
858** Compare the OBJECT label at pNode against zKey,nKey. Return true on
859** a match.
860*/
861static int jsonLabelCompare(JsonNode *pNode, const char *zKey, int nKey){
862 if( pNode->jnFlags & JNODE_RAW ){
863 if( pNode->n!=nKey ) return 0;
864 return strncmp(pNode->u.zJContent, zKey, nKey)==0;
865 }else{
866 if( pNode->n!=nKey+2 ) return 0;
867 return strncmp(pNode->u.zJContent+1, zKey, nKey)==0;
868 }
869}
870
drh52216ad2015-08-18 02:28:03 +0000871/* forward declaration */
drha7714022015-08-29 00:54:49 +0000872static JsonNode *jsonLookupAppend(JsonParse*,const char*,int*,const char**);
drh52216ad2015-08-18 02:28:03 +0000873
drh987eb1f2015-08-17 15:17:37 +0000874/*
875** Search along zPath to find the node specified. Return a pointer
876** to that node, or NULL if zPath is malformed or if there is no such
877** node.
drh52216ad2015-08-18 02:28:03 +0000878**
879** If pApnd!=0, then try to append new nodes to complete zPath if it is
880** possible to do so and if no existing node corresponds to zPath. If
881** new nodes are appended *pApnd is set to 1.
drh987eb1f2015-08-17 15:17:37 +0000882*/
drha7714022015-08-29 00:54:49 +0000883static JsonNode *jsonLookupStep(
drh52216ad2015-08-18 02:28:03 +0000884 JsonParse *pParse, /* The JSON to search */
885 u32 iRoot, /* Begin the search at this node */
886 const char *zPath, /* The path to search */
drha7714022015-08-29 00:54:49 +0000887 int *pApnd, /* Append nodes to complete path if not NULL */
888 const char **pzErr /* Make *pzErr point to any syntax error in zPath */
drh52216ad2015-08-18 02:28:03 +0000889){
drhbc8f0922015-08-22 19:39:04 +0000890 u32 i, j, nKey;
drh6b43cc82015-08-19 23:02:49 +0000891 const char *zKey;
drh52216ad2015-08-18 02:28:03 +0000892 JsonNode *pRoot = &pParse->aNode[iRoot];
drh987eb1f2015-08-17 15:17:37 +0000893 if( zPath[0]==0 ) return pRoot;
894 if( zPath[0]=='.' ){
895 if( pRoot->eType!=JSON_OBJECT ) return 0;
896 zPath++;
drh6b43cc82015-08-19 23:02:49 +0000897 if( zPath[0]=='"' ){
898 zKey = zPath + 1;
899 for(i=1; zPath[i] && zPath[i]!='"'; i++){}
900 nKey = i-1;
drha8f39a92015-09-21 22:53:16 +0000901 if( zPath[i] ){
902 i++;
903 }else{
904 *pzErr = zPath;
905 return 0;
906 }
drh6b43cc82015-08-19 23:02:49 +0000907 }else{
908 zKey = zPath;
909 for(i=0; zPath[i] && zPath[i]!='.' && zPath[i]!='['; i++){}
910 nKey = i;
911 }
drha7714022015-08-29 00:54:49 +0000912 if( nKey==0 ){
913 *pzErr = zPath;
914 return 0;
915 }
drh987eb1f2015-08-17 15:17:37 +0000916 j = 1;
drh52216ad2015-08-18 02:28:03 +0000917 for(;;){
918 while( j<=pRoot->n ){
drh8cb0c832015-09-22 00:21:03 +0000919 if( jsonLabelCompare(pRoot+j, zKey, nKey) ){
drha7714022015-08-29 00:54:49 +0000920 return jsonLookupStep(pParse, iRoot+j+1, &zPath[i], pApnd, pzErr);
drh52216ad2015-08-18 02:28:03 +0000921 }
922 j++;
drh505ad2c2015-08-21 17:33:11 +0000923 j += jsonNodeSize(&pRoot[j]);
drh987eb1f2015-08-17 15:17:37 +0000924 }
drh52216ad2015-08-18 02:28:03 +0000925 if( (pRoot->jnFlags & JNODE_APPEND)==0 ) break;
926 iRoot += pRoot->u.iAppend;
927 pRoot = &pParse->aNode[iRoot];
928 j = 1;
929 }
930 if( pApnd ){
drhbc8f0922015-08-22 19:39:04 +0000931 u32 iStart, iLabel;
932 JsonNode *pNode;
933 iStart = jsonParseAddNode(pParse, JSON_OBJECT, 2, 0);
934 iLabel = jsonParseAddNode(pParse, JSON_STRING, i, zPath);
drh52216ad2015-08-18 02:28:03 +0000935 zPath += i;
drha7714022015-08-29 00:54:49 +0000936 pNode = jsonLookupAppend(pParse, zPath, pApnd, pzErr);
drhbc8f0922015-08-22 19:39:04 +0000937 if( pParse->oom ) return 0;
938 if( pNode ){
939 pRoot = &pParse->aNode[iRoot];
940 pRoot->u.iAppend = iStart - iRoot;
941 pRoot->jnFlags |= JNODE_APPEND;
942 pParse->aNode[iLabel].jnFlags |= JNODE_RAW;
943 }
944 return pNode;
drh987eb1f2015-08-17 15:17:37 +0000945 }
dan2e8f5512015-09-17 17:21:09 +0000946 }else if( zPath[0]=='[' && safe_isdigit(zPath[1]) ){
drh987eb1f2015-08-17 15:17:37 +0000947 if( pRoot->eType!=JSON_ARRAY ) return 0;
948 i = 0;
drh3d1d2a92015-09-22 01:15:49 +0000949 j = 1;
950 while( safe_isdigit(zPath[j]) ){
951 i = i*10 + zPath[j] - '0';
952 j++;
drh987eb1f2015-08-17 15:17:37 +0000953 }
drh3d1d2a92015-09-22 01:15:49 +0000954 if( zPath[j]!=']' ){
drha7714022015-08-29 00:54:49 +0000955 *pzErr = zPath;
956 return 0;
957 }
drh3d1d2a92015-09-22 01:15:49 +0000958 zPath += j + 1;
drh987eb1f2015-08-17 15:17:37 +0000959 j = 1;
drh52216ad2015-08-18 02:28:03 +0000960 for(;;){
drhbc8f0922015-08-22 19:39:04 +0000961 while( j<=pRoot->n && (i>0 || (pRoot[j].jnFlags & JNODE_REMOVE)!=0) ){
962 if( (pRoot[j].jnFlags & JNODE_REMOVE)==0 ) i--;
drh505ad2c2015-08-21 17:33:11 +0000963 j += jsonNodeSize(&pRoot[j]);
drh52216ad2015-08-18 02:28:03 +0000964 }
965 if( (pRoot->jnFlags & JNODE_APPEND)==0 ) break;
966 iRoot += pRoot->u.iAppend;
967 pRoot = &pParse->aNode[iRoot];
968 j = 1;
drh987eb1f2015-08-17 15:17:37 +0000969 }
970 if( j<=pRoot->n ){
drha7714022015-08-29 00:54:49 +0000971 return jsonLookupStep(pParse, iRoot+j, zPath, pApnd, pzErr);
drh52216ad2015-08-18 02:28:03 +0000972 }
973 if( i==0 && pApnd ){
drhbc8f0922015-08-22 19:39:04 +0000974 u32 iStart;
975 JsonNode *pNode;
976 iStart = jsonParseAddNode(pParse, JSON_ARRAY, 1, 0);
drha7714022015-08-29 00:54:49 +0000977 pNode = jsonLookupAppend(pParse, zPath, pApnd, pzErr);
drhbc8f0922015-08-22 19:39:04 +0000978 if( pParse->oom ) return 0;
979 if( pNode ){
980 pRoot = &pParse->aNode[iRoot];
981 pRoot->u.iAppend = iStart - iRoot;
982 pRoot->jnFlags |= JNODE_APPEND;
983 }
984 return pNode;
drh987eb1f2015-08-17 15:17:37 +0000985 }
drh3d1d2a92015-09-22 01:15:49 +0000986 }else{
drha7714022015-08-29 00:54:49 +0000987 *pzErr = zPath;
drh987eb1f2015-08-17 15:17:37 +0000988 }
989 return 0;
990}
991
drh52216ad2015-08-18 02:28:03 +0000992/*
drhbc8f0922015-08-22 19:39:04 +0000993** Append content to pParse that will complete zPath. Return a pointer
994** to the inserted node, or return NULL if the append fails.
drh52216ad2015-08-18 02:28:03 +0000995*/
996static JsonNode *jsonLookupAppend(
997 JsonParse *pParse, /* Append content to the JSON parse */
998 const char *zPath, /* Description of content to append */
drha7714022015-08-29 00:54:49 +0000999 int *pApnd, /* Set this flag to 1 */
1000 const char **pzErr /* Make this point to any syntax error */
drh52216ad2015-08-18 02:28:03 +00001001){
1002 *pApnd = 1;
1003 if( zPath[0]==0 ){
1004 jsonParseAddNode(pParse, JSON_NULL, 0, 0);
1005 return pParse->oom ? 0 : &pParse->aNode[pParse->nNode-1];
1006 }
1007 if( zPath[0]=='.' ){
1008 jsonParseAddNode(pParse, JSON_OBJECT, 0, 0);
1009 }else if( strncmp(zPath,"[0]",3)==0 ){
1010 jsonParseAddNode(pParse, JSON_ARRAY, 0, 0);
1011 }else{
1012 return 0;
1013 }
1014 if( pParse->oom ) return 0;
drha7714022015-08-29 00:54:49 +00001015 return jsonLookupStep(pParse, pParse->nNode-1, zPath, pApnd, pzErr);
drh52216ad2015-08-18 02:28:03 +00001016}
1017
drhbc8f0922015-08-22 19:39:04 +00001018/*
drha7714022015-08-29 00:54:49 +00001019** Return the text of a syntax error message on a JSON path. Space is
1020** obtained from sqlite3_malloc().
1021*/
1022static char *jsonPathSyntaxError(const char *zErr){
1023 return sqlite3_mprintf("JSON path error near '%q'", zErr);
1024}
1025
1026/*
1027** Do a node lookup using zPath. Return a pointer to the node on success.
1028** Return NULL if not found or if there is an error.
1029**
1030** On an error, write an error message into pCtx and increment the
1031** pParse->nErr counter.
1032**
1033** If pApnd!=NULL then try to append missing nodes and set *pApnd = 1 if
1034** nodes are appended.
drha7714022015-08-29 00:54:49 +00001035*/
1036static JsonNode *jsonLookup(
1037 JsonParse *pParse, /* The JSON to search */
1038 const char *zPath, /* The path to search */
1039 int *pApnd, /* Append nodes to complete path if not NULL */
drhf5ddb9c2015-09-11 00:06:41 +00001040 sqlite3_context *pCtx /* Report errors here, if not NULL */
drha7714022015-08-29 00:54:49 +00001041){
1042 const char *zErr = 0;
1043 JsonNode *pNode = 0;
drha8f39a92015-09-21 22:53:16 +00001044 char *zMsg;
drha7714022015-08-29 00:54:49 +00001045
1046 if( zPath==0 ) return 0;
1047 if( zPath[0]!='$' ){
1048 zErr = zPath;
1049 goto lookup_err;
1050 }
1051 zPath++;
drha7714022015-08-29 00:54:49 +00001052 pNode = jsonLookupStep(pParse, 0, zPath, pApnd, &zErr);
drha8f39a92015-09-21 22:53:16 +00001053 if( zErr==0 ) return pNode;
drha7714022015-08-29 00:54:49 +00001054
1055lookup_err:
1056 pParse->nErr++;
drha8f39a92015-09-21 22:53:16 +00001057 assert( zErr!=0 && pCtx!=0 );
1058 zMsg = jsonPathSyntaxError(zErr);
1059 if( zMsg ){
1060 sqlite3_result_error(pCtx, zMsg, -1);
1061 sqlite3_free(zMsg);
1062 }else{
1063 sqlite3_result_error_nomem(pCtx);
drha7714022015-08-29 00:54:49 +00001064 }
drha7714022015-08-29 00:54:49 +00001065 return 0;
1066}
1067
1068
1069/*
drhbc8f0922015-08-22 19:39:04 +00001070** Report the wrong number of arguments for json_insert(), json_replace()
1071** or json_set().
1072*/
1073static void jsonWrongNumArgs(
1074 sqlite3_context *pCtx,
1075 const char *zFuncName
1076){
1077 char *zMsg = sqlite3_mprintf("json_%s() needs an odd number of arguments",
1078 zFuncName);
1079 sqlite3_result_error(pCtx, zMsg, -1);
1080 sqlite3_free(zMsg);
1081}
drh52216ad2015-08-18 02:28:03 +00001082
drha7714022015-08-29 00:54:49 +00001083
drh987eb1f2015-08-17 15:17:37 +00001084/****************************************************************************
1085** SQL functions used for testing and debugging
1086****************************************************************************/
drhe9c37f32015-08-15 21:25:36 +00001087
drh301eecc2015-08-17 20:14:19 +00001088#ifdef SQLITE_DEBUG
drhe9c37f32015-08-15 21:25:36 +00001089/*
drh5634cc02015-08-17 11:28:03 +00001090** The json_parse(JSON) function returns a string which describes
drhe9c37f32015-08-15 21:25:36 +00001091** a parse of the JSON provided. Or it returns NULL if JSON is not
1092** well-formed.
1093*/
drh5634cc02015-08-17 11:28:03 +00001094static void jsonParseFunc(
drhbc8f0922015-08-22 19:39:04 +00001095 sqlite3_context *ctx,
drhe9c37f32015-08-15 21:25:36 +00001096 int argc,
1097 sqlite3_value **argv
1098){
drh505ad2c2015-08-21 17:33:11 +00001099 JsonString s; /* Output string - not real JSON */
1100 JsonParse x; /* The parse */
drhe9c37f32015-08-15 21:25:36 +00001101 u32 i;
drhe9c37f32015-08-15 21:25:36 +00001102
1103 assert( argc==1 );
drhbc8f0922015-08-22 19:39:04 +00001104 if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return;
drh8784eca2015-08-23 02:42:30 +00001105 jsonParseFindParents(&x);
drhbc8f0922015-08-22 19:39:04 +00001106 jsonInit(&s, ctx);
drhe9c37f32015-08-15 21:25:36 +00001107 for(i=0; i<x.nNode; i++){
drh852944e2015-09-10 03:29:11 +00001108 const char *zType;
1109 if( x.aNode[i].jnFlags & JNODE_LABEL ){
1110 assert( x.aNode[i].eType==JSON_STRING );
1111 zType = "label";
1112 }else{
1113 zType = jsonType[x.aNode[i].eType];
drhe9c37f32015-08-15 21:25:36 +00001114 }
drh852944e2015-09-10 03:29:11 +00001115 jsonPrintf(100, &s,"node %3u: %7s n=%-4d up=%-4d",
1116 i, zType, x.aNode[i].n, x.aUp[i]);
1117 if( x.aNode[i].u.zJContent!=0 ){
1118 jsonAppendRaw(&s, " ", 1);
1119 jsonAppendRaw(&s, x.aNode[i].u.zJContent, x.aNode[i].n);
1120 }
1121 jsonAppendRaw(&s, "\n", 1);
drhe9c37f32015-08-15 21:25:36 +00001122 }
drh505ad2c2015-08-21 17:33:11 +00001123 jsonParseReset(&x);
drhe9c37f32015-08-15 21:25:36 +00001124 jsonResult(&s);
1125}
1126
drh5634cc02015-08-17 11:28:03 +00001127/*
drhf5ddb9c2015-09-11 00:06:41 +00001128** The json_test1(JSON) function return true (1) if the input is JSON
1129** text generated by another json function. It returns (0) if the input
1130** is not known to be JSON.
drh5634cc02015-08-17 11:28:03 +00001131*/
1132static void jsonTest1Func(
drhbc8f0922015-08-22 19:39:04 +00001133 sqlite3_context *ctx,
drh5634cc02015-08-17 11:28:03 +00001134 int argc,
1135 sqlite3_value **argv
1136){
mistachkin16a93122015-09-11 18:05:01 +00001137 UNUSED_PARAM(argc);
drhf5ddb9c2015-09-11 00:06:41 +00001138 sqlite3_result_int(ctx, sqlite3_value_subtype(argv[0])==JSON_SUBTYPE);
drh5634cc02015-08-17 11:28:03 +00001139}
drh301eecc2015-08-17 20:14:19 +00001140#endif /* SQLITE_DEBUG */
drh5634cc02015-08-17 11:28:03 +00001141
drh987eb1f2015-08-17 15:17:37 +00001142/****************************************************************************
1143** SQL function implementations
1144****************************************************************************/
1145
1146/*
1147** Implementation of the json_array(VALUE,...) function. Return a JSON
1148** array that contains all values given in arguments. Or if any argument
1149** is a BLOB, throw an error.
1150*/
1151static void jsonArrayFunc(
drhbc8f0922015-08-22 19:39:04 +00001152 sqlite3_context *ctx,
drh987eb1f2015-08-17 15:17:37 +00001153 int argc,
1154 sqlite3_value **argv
1155){
1156 int i;
drh505ad2c2015-08-21 17:33:11 +00001157 JsonString jx;
drh987eb1f2015-08-17 15:17:37 +00001158
drhbc8f0922015-08-22 19:39:04 +00001159 jsonInit(&jx, ctx);
drhd0960592015-08-17 21:22:32 +00001160 jsonAppendChar(&jx, '[');
drh987eb1f2015-08-17 15:17:37 +00001161 for(i=0; i<argc; i++){
drhd0960592015-08-17 21:22:32 +00001162 jsonAppendSeparator(&jx);
drhf5ddb9c2015-09-11 00:06:41 +00001163 jsonAppendValue(&jx, argv[i]);
drh987eb1f2015-08-17 15:17:37 +00001164 }
drhd0960592015-08-17 21:22:32 +00001165 jsonAppendChar(&jx, ']');
drh987eb1f2015-08-17 15:17:37 +00001166 jsonResult(&jx);
drhf5ddb9c2015-09-11 00:06:41 +00001167 sqlite3_result_subtype(ctx, JSON_SUBTYPE);
drh987eb1f2015-08-17 15:17:37 +00001168}
1169
1170
1171/*
1172** json_array_length(JSON)
1173** json_array_length(JSON, PATH)
1174**
1175** Return the number of elements in the top-level JSON array.
1176** Return 0 if the input is not a well-formed JSON array.
1177*/
1178static void jsonArrayLengthFunc(
drhbc8f0922015-08-22 19:39:04 +00001179 sqlite3_context *ctx,
drh987eb1f2015-08-17 15:17:37 +00001180 int argc,
1181 sqlite3_value **argv
1182){
1183 JsonParse x; /* The parse */
1184 sqlite3_int64 n = 0;
1185 u32 i;
drha8f39a92015-09-21 22:53:16 +00001186 JsonNode *pNode;
drh987eb1f2015-08-17 15:17:37 +00001187
drhf2df7e72015-08-28 20:07:40 +00001188 if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return;
drha8f39a92015-09-21 22:53:16 +00001189 assert( x.nNode );
1190 if( argc==2 ){
1191 const char *zPath = (const char*)sqlite3_value_text(argv[1]);
1192 pNode = jsonLookup(&x, zPath, 0, ctx);
1193 }else{
1194 pNode = x.aNode;
1195 }
1196 if( pNode==0 ){
1197 x.nErr = 1;
1198 }else if( pNode->eType==JSON_ARRAY ){
1199 assert( (pNode->jnFlags & JNODE_APPEND)==0 );
1200 for(i=1; i<=pNode->n; n++){
1201 i += jsonNodeSize(&pNode[i]);
drh987eb1f2015-08-17 15:17:37 +00001202 }
drh987eb1f2015-08-17 15:17:37 +00001203 }
drha7714022015-08-29 00:54:49 +00001204 if( x.nErr==0 ) sqlite3_result_int64(ctx, n);
drhf6ec8d42015-08-28 03:48:04 +00001205 jsonParseReset(&x);
1206}
1207
1208/*
drh3ad93bb2015-08-29 19:41:45 +00001209** json_extract(JSON, PATH, ...)
drh987eb1f2015-08-17 15:17:37 +00001210**
drh3ad93bb2015-08-29 19:41:45 +00001211** Return the element described by PATH. Return NULL if there is no
1212** PATH element. If there are multiple PATHs, then return a JSON array
1213** with the result from each path. Throw an error if the JSON or any PATH
1214** is malformed.
drh987eb1f2015-08-17 15:17:37 +00001215*/
1216static void jsonExtractFunc(
drhbc8f0922015-08-22 19:39:04 +00001217 sqlite3_context *ctx,
drh987eb1f2015-08-17 15:17:37 +00001218 int argc,
1219 sqlite3_value **argv
1220){
1221 JsonParse x; /* The parse */
1222 JsonNode *pNode;
1223 const char *zPath;
drh3ad93bb2015-08-29 19:41:45 +00001224 JsonString jx;
1225 int i;
1226
1227 if( argc<2 ) return;
drhbc8f0922015-08-22 19:39:04 +00001228 if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return;
drh3ad93bb2015-08-29 19:41:45 +00001229 jsonInit(&jx, ctx);
1230 jsonAppendChar(&jx, '[');
1231 for(i=1; i<argc; i++){
1232 zPath = (const char*)sqlite3_value_text(argv[i]);
drhf5ddb9c2015-09-11 00:06:41 +00001233 pNode = jsonLookup(&x, zPath, 0, ctx);
drh3ad93bb2015-08-29 19:41:45 +00001234 if( x.nErr ) break;
1235 if( argc>2 ){
1236 jsonAppendSeparator(&jx);
1237 if( pNode ){
1238 jsonRenderNode(pNode, &jx, 0);
1239 }else{
1240 jsonAppendRaw(&jx, "null", 4);
1241 }
1242 }else if( pNode ){
1243 jsonReturn(pNode, ctx, 0);
1244 }
drh987eb1f2015-08-17 15:17:37 +00001245 }
drh3ad93bb2015-08-29 19:41:45 +00001246 if( argc>2 && i==argc ){
1247 jsonAppendChar(&jx, ']');
1248 jsonResult(&jx);
drhf5ddb9c2015-09-11 00:06:41 +00001249 sqlite3_result_subtype(ctx, JSON_SUBTYPE);
drh3ad93bb2015-08-29 19:41:45 +00001250 }
1251 jsonReset(&jx);
drh505ad2c2015-08-21 17:33:11 +00001252 jsonParseReset(&x);
drh987eb1f2015-08-17 15:17:37 +00001253}
1254
1255/*
1256** Implementation of the json_object(NAME,VALUE,...) function. Return a JSON
1257** object that contains all name/value given in arguments. Or if any name
1258** is not a string or if any value is a BLOB, throw an error.
1259*/
1260static void jsonObjectFunc(
drhbc8f0922015-08-22 19:39:04 +00001261 sqlite3_context *ctx,
drh987eb1f2015-08-17 15:17:37 +00001262 int argc,
1263 sqlite3_value **argv
1264){
1265 int i;
drh505ad2c2015-08-21 17:33:11 +00001266 JsonString jx;
drh987eb1f2015-08-17 15:17:37 +00001267 const char *z;
1268 u32 n;
1269
1270 if( argc&1 ){
drhbc8f0922015-08-22 19:39:04 +00001271 sqlite3_result_error(ctx, "json_object() requires an even number "
drh987eb1f2015-08-17 15:17:37 +00001272 "of arguments", -1);
1273 return;
1274 }
drhbc8f0922015-08-22 19:39:04 +00001275 jsonInit(&jx, ctx);
drhd0960592015-08-17 21:22:32 +00001276 jsonAppendChar(&jx, '{');
drh987eb1f2015-08-17 15:17:37 +00001277 for(i=0; i<argc; i+=2){
drh987eb1f2015-08-17 15:17:37 +00001278 if( sqlite3_value_type(argv[i])!=SQLITE_TEXT ){
drhbc8f0922015-08-22 19:39:04 +00001279 sqlite3_result_error(ctx, "json_object() labels must be TEXT", -1);
drhdc384952015-09-19 18:54:39 +00001280 jsonReset(&jx);
drh987eb1f2015-08-17 15:17:37 +00001281 return;
1282 }
drhd0960592015-08-17 21:22:32 +00001283 jsonAppendSeparator(&jx);
drh987eb1f2015-08-17 15:17:37 +00001284 z = (const char*)sqlite3_value_text(argv[i]);
1285 n = (u32)sqlite3_value_bytes(argv[i]);
1286 jsonAppendString(&jx, z, n);
drhd0960592015-08-17 21:22:32 +00001287 jsonAppendChar(&jx, ':');
drhf5ddb9c2015-09-11 00:06:41 +00001288 jsonAppendValue(&jx, argv[i+1]);
drh987eb1f2015-08-17 15:17:37 +00001289 }
drhd0960592015-08-17 21:22:32 +00001290 jsonAppendChar(&jx, '}');
drh987eb1f2015-08-17 15:17:37 +00001291 jsonResult(&jx);
drhf5ddb9c2015-09-11 00:06:41 +00001292 sqlite3_result_subtype(ctx, JSON_SUBTYPE);
drh987eb1f2015-08-17 15:17:37 +00001293}
1294
1295
1296/*
drh301eecc2015-08-17 20:14:19 +00001297** json_remove(JSON, PATH, ...)
1298**
drh3ad93bb2015-08-29 19:41:45 +00001299** Remove the named elements from JSON and return the result. malformed
1300** JSON or PATH arguments result in an error.
drh301eecc2015-08-17 20:14:19 +00001301*/
1302static void jsonRemoveFunc(
drhbc8f0922015-08-22 19:39:04 +00001303 sqlite3_context *ctx,
drh301eecc2015-08-17 20:14:19 +00001304 int argc,
1305 sqlite3_value **argv
1306){
1307 JsonParse x; /* The parse */
1308 JsonNode *pNode;
1309 const char *zPath;
1310 u32 i;
1311
1312 if( argc<1 ) return;
drhbc8f0922015-08-22 19:39:04 +00001313 if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return;
drha8f39a92015-09-21 22:53:16 +00001314 assert( x.nNode );
1315 for(i=1; i<(u32)argc; i++){
1316 zPath = (const char*)sqlite3_value_text(argv[i]);
1317 if( zPath==0 ) goto remove_done;
1318 pNode = jsonLookup(&x, zPath, 0, ctx);
1319 if( x.nErr ) goto remove_done;
1320 if( pNode ) pNode->jnFlags |= JNODE_REMOVE;
1321 }
1322 if( (x.aNode[0].jnFlags & JNODE_REMOVE)==0 ){
1323 jsonReturnJson(x.aNode, ctx, 0);
drhd0960592015-08-17 21:22:32 +00001324 }
drha7714022015-08-29 00:54:49 +00001325remove_done:
drh505ad2c2015-08-21 17:33:11 +00001326 jsonParseReset(&x);
drhd0960592015-08-17 21:22:32 +00001327}
1328
1329/*
1330** json_replace(JSON, PATH, VALUE, ...)
1331**
1332** Replace the value at PATH with VALUE. If PATH does not already exist,
drh3ad93bb2015-08-29 19:41:45 +00001333** this routine is a no-op. If JSON or PATH is malformed, throw an error.
drhd0960592015-08-17 21:22:32 +00001334*/
1335static void jsonReplaceFunc(
drhbc8f0922015-08-22 19:39:04 +00001336 sqlite3_context *ctx,
drhd0960592015-08-17 21:22:32 +00001337 int argc,
1338 sqlite3_value **argv
1339){
1340 JsonParse x; /* The parse */
1341 JsonNode *pNode;
1342 const char *zPath;
1343 u32 i;
1344
1345 if( argc<1 ) return;
1346 if( (argc&1)==0 ) {
drhbc8f0922015-08-22 19:39:04 +00001347 jsonWrongNumArgs(ctx, "replace");
drhd0960592015-08-17 21:22:32 +00001348 return;
1349 }
drhbc8f0922015-08-22 19:39:04 +00001350 if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return;
drha8f39a92015-09-21 22:53:16 +00001351 assert( x.nNode );
1352 for(i=1; i<(u32)argc; i+=2){
1353 zPath = (const char*)sqlite3_value_text(argv[i]);
1354 pNode = jsonLookup(&x, zPath, 0, ctx);
1355 if( x.nErr ) goto replace_err;
1356 if( pNode ){
1357 pNode->jnFlags |= (u8)JNODE_REPLACE;
1358 pNode->iVal = (u8)(i+1);
drhd0960592015-08-17 21:22:32 +00001359 }
drha8f39a92015-09-21 22:53:16 +00001360 }
1361 if( x.aNode[0].jnFlags & JNODE_REPLACE ){
1362 sqlite3_result_value(ctx, argv[x.aNode[0].iVal]);
1363 }else{
1364 jsonReturnJson(x.aNode, ctx, argv);
drh301eecc2015-08-17 20:14:19 +00001365 }
drha7714022015-08-29 00:54:49 +00001366replace_err:
drh505ad2c2015-08-21 17:33:11 +00001367 jsonParseReset(&x);
drh301eecc2015-08-17 20:14:19 +00001368}
drh505ad2c2015-08-21 17:33:11 +00001369
drh52216ad2015-08-18 02:28:03 +00001370/*
1371** json_set(JSON, PATH, VALUE, ...)
1372**
1373** Set the value at PATH to VALUE. Create the PATH if it does not already
1374** exist. Overwrite existing values that do exist.
drh3ad93bb2015-08-29 19:41:45 +00001375** If JSON or PATH is malformed, throw an error.
drh52216ad2015-08-18 02:28:03 +00001376**
1377** json_insert(JSON, PATH, VALUE, ...)
1378**
1379** Create PATH and initialize it to VALUE. If PATH already exists, this
drh3ad93bb2015-08-29 19:41:45 +00001380** routine is a no-op. If JSON or PATH is malformed, throw an error.
drh52216ad2015-08-18 02:28:03 +00001381*/
1382static void jsonSetFunc(
drhbc8f0922015-08-22 19:39:04 +00001383 sqlite3_context *ctx,
drh52216ad2015-08-18 02:28:03 +00001384 int argc,
1385 sqlite3_value **argv
1386){
1387 JsonParse x; /* The parse */
1388 JsonNode *pNode;
1389 const char *zPath;
1390 u32 i;
1391 int bApnd;
drhbc8f0922015-08-22 19:39:04 +00001392 int bIsSet = *(int*)sqlite3_user_data(ctx);
drh52216ad2015-08-18 02:28:03 +00001393
1394 if( argc<1 ) return;
1395 if( (argc&1)==0 ) {
drhbc8f0922015-08-22 19:39:04 +00001396 jsonWrongNumArgs(ctx, bIsSet ? "set" : "insert");
drh52216ad2015-08-18 02:28:03 +00001397 return;
1398 }
drhbc8f0922015-08-22 19:39:04 +00001399 if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return;
drha8f39a92015-09-21 22:53:16 +00001400 assert( x.nNode );
1401 for(i=1; i<(u32)argc; i+=2){
1402 zPath = (const char*)sqlite3_value_text(argv[i]);
1403 bApnd = 0;
1404 pNode = jsonLookup(&x, zPath, &bApnd, ctx);
1405 if( x.oom ){
1406 sqlite3_result_error_nomem(ctx);
1407 goto jsonSetDone;
1408 }else if( x.nErr ){
1409 goto jsonSetDone;
1410 }else if( pNode && (bApnd || bIsSet) ){
1411 pNode->jnFlags |= (u8)JNODE_REPLACE;
1412 pNode->iVal = (u8)(i+1);
drh52216ad2015-08-18 02:28:03 +00001413 }
drha8f39a92015-09-21 22:53:16 +00001414 }
1415 if( x.aNode[0].jnFlags & JNODE_REPLACE ){
1416 sqlite3_result_value(ctx, argv[x.aNode[0].iVal]);
1417 }else{
1418 jsonReturnJson(x.aNode, ctx, argv);
drh52216ad2015-08-18 02:28:03 +00001419 }
drhbc8f0922015-08-22 19:39:04 +00001420jsonSetDone:
drh505ad2c2015-08-21 17:33:11 +00001421 jsonParseReset(&x);
drh52216ad2015-08-18 02:28:03 +00001422}
drh301eecc2015-08-17 20:14:19 +00001423
1424/*
drh987eb1f2015-08-17 15:17:37 +00001425** json_type(JSON)
1426** json_type(JSON, PATH)
1427**
drh3ad93bb2015-08-29 19:41:45 +00001428** Return the top-level "type" of a JSON string. Throw an error if
1429** either the JSON or PATH inputs are not well-formed.
drh987eb1f2015-08-17 15:17:37 +00001430*/
1431static void jsonTypeFunc(
drhbc8f0922015-08-22 19:39:04 +00001432 sqlite3_context *ctx,
drh987eb1f2015-08-17 15:17:37 +00001433 int argc,
1434 sqlite3_value **argv
1435){
1436 JsonParse x; /* The parse */
1437 const char *zPath;
drha8f39a92015-09-21 22:53:16 +00001438 JsonNode *pNode;
drh987eb1f2015-08-17 15:17:37 +00001439
drhbc8f0922015-08-22 19:39:04 +00001440 if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return;
drha8f39a92015-09-21 22:53:16 +00001441 assert( x.nNode );
1442 if( argc==2 ){
1443 zPath = (const char*)sqlite3_value_text(argv[1]);
1444 pNode = jsonLookup(&x, zPath, 0, ctx);
1445 }else{
1446 pNode = x.aNode;
1447 }
1448 if( pNode ){
1449 sqlite3_result_text(ctx, jsonType[pNode->eType], -1, SQLITE_STATIC);
drh987eb1f2015-08-17 15:17:37 +00001450 }
drh505ad2c2015-08-21 17:33:11 +00001451 jsonParseReset(&x);
drh987eb1f2015-08-17 15:17:37 +00001452}
drh5634cc02015-08-17 11:28:03 +00001453
drhbc8f0922015-08-22 19:39:04 +00001454/*
1455** json_valid(JSON)
1456**
drh3ad93bb2015-08-29 19:41:45 +00001457** Return 1 if JSON is a well-formed JSON string according to RFC-7159.
1458** Return 0 otherwise.
drhbc8f0922015-08-22 19:39:04 +00001459*/
1460static void jsonValidFunc(
1461 sqlite3_context *ctx,
1462 int argc,
1463 sqlite3_value **argv
1464){
1465 JsonParse x; /* The parse */
1466 int rc = 0;
1467
mistachkin16a93122015-09-11 18:05:01 +00001468 UNUSED_PARAM(argc);
drha8f39a92015-09-21 22:53:16 +00001469 if( jsonParse(&x, 0, (const char*)sqlite3_value_text(argv[0]))==0 ){
drhbc8f0922015-08-22 19:39:04 +00001470 rc = 1;
1471 }
1472 jsonParseReset(&x);
1473 sqlite3_result_int(ctx, rc);
1474}
1475
drhd2975922015-08-29 17:22:33 +00001476#ifndef SQLITE_OMIT_VIRTUALTABLE
drhcb6c6c62015-08-19 22:47:17 +00001477/****************************************************************************
1478** The json_each virtual table
1479****************************************************************************/
1480typedef struct JsonEachCursor JsonEachCursor;
1481struct JsonEachCursor {
1482 sqlite3_vtab_cursor base; /* Base class - must be first */
drh505ad2c2015-08-21 17:33:11 +00001483 u32 iRowid; /* The rowid */
drh852944e2015-09-10 03:29:11 +00001484 u32 iBegin; /* The first node of the scan */
drh505ad2c2015-08-21 17:33:11 +00001485 u32 i; /* Index in sParse.aNode[] of current row */
1486 u32 iEnd; /* EOF when i equals or exceeds this value */
1487 u8 eType; /* Type of top-level element */
1488 u8 bRecursive; /* True for json_tree(). False for json_each() */
1489 char *zJson; /* Input JSON */
drh383de692015-09-10 17:20:57 +00001490 char *zRoot; /* Path by which to filter zJson */
drh505ad2c2015-08-21 17:33:11 +00001491 JsonParse sParse; /* Parse of the input JSON */
drhcb6c6c62015-08-19 22:47:17 +00001492};
1493
1494/* Constructor for the json_each virtual table */
1495static int jsonEachConnect(
1496 sqlite3 *db,
1497 void *pAux,
1498 int argc, const char *const*argv,
1499 sqlite3_vtab **ppVtab,
1500 char **pzErr
1501){
1502 sqlite3_vtab *pNew;
drh505ad2c2015-08-21 17:33:11 +00001503 int rc;
drhcb6c6c62015-08-19 22:47:17 +00001504
1505/* Column numbers */
drh4af352d2015-08-21 20:02:48 +00001506#define JEACH_KEY 0
1507#define JEACH_VALUE 1
1508#define JEACH_TYPE 2
1509#define JEACH_ATOM 3
1510#define JEACH_ID 4
1511#define JEACH_PARENT 5
1512#define JEACH_FULLKEY 6
drh383de692015-09-10 17:20:57 +00001513#define JEACH_PATH 7
1514#define JEACH_JSON 8
1515#define JEACH_ROOT 9
drhcb6c6c62015-08-19 22:47:17 +00001516
drh6fd5c1e2015-08-21 20:37:12 +00001517 UNUSED_PARAM(pzErr);
1518 UNUSED_PARAM(argv);
1519 UNUSED_PARAM(argc);
1520 UNUSED_PARAM(pAux);
drh505ad2c2015-08-21 17:33:11 +00001521 rc = sqlite3_declare_vtab(db,
drh383de692015-09-10 17:20:57 +00001522 "CREATE TABLE x(key,value,type,atom,id,parent,fullkey,path,"
1523 "json HIDDEN,root HIDDEN)");
drh505ad2c2015-08-21 17:33:11 +00001524 if( rc==SQLITE_OK ){
1525 pNew = *ppVtab = sqlite3_malloc( sizeof(*pNew) );
1526 if( pNew==0 ) return SQLITE_NOMEM;
1527 memset(pNew, 0, sizeof(*pNew));
1528 }
1529 return rc;
drhcb6c6c62015-08-19 22:47:17 +00001530}
1531
1532/* destructor for json_each virtual table */
1533static int jsonEachDisconnect(sqlite3_vtab *pVtab){
1534 sqlite3_free(pVtab);
1535 return SQLITE_OK;
1536}
1537
drh505ad2c2015-08-21 17:33:11 +00001538/* constructor for a JsonEachCursor object for json_each(). */
1539static int jsonEachOpenEach(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
drhcb6c6c62015-08-19 22:47:17 +00001540 JsonEachCursor *pCur;
drh6fd5c1e2015-08-21 20:37:12 +00001541
1542 UNUSED_PARAM(p);
drhcb6c6c62015-08-19 22:47:17 +00001543 pCur = sqlite3_malloc( sizeof(*pCur) );
1544 if( pCur==0 ) return SQLITE_NOMEM;
1545 memset(pCur, 0, sizeof(*pCur));
1546 *ppCursor = &pCur->base;
1547 return SQLITE_OK;
1548}
1549
drh505ad2c2015-08-21 17:33:11 +00001550/* constructor for a JsonEachCursor object for json_tree(). */
1551static int jsonEachOpenTree(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
1552 int rc = jsonEachOpenEach(p, ppCursor);
1553 if( rc==SQLITE_OK ){
1554 JsonEachCursor *pCur = (JsonEachCursor*)*ppCursor;
1555 pCur->bRecursive = 1;
1556 }
1557 return rc;
1558}
1559
drhcb6c6c62015-08-19 22:47:17 +00001560/* Reset a JsonEachCursor back to its original state. Free any memory
1561** held. */
1562static void jsonEachCursorReset(JsonEachCursor *p){
1563 sqlite3_free(p->zJson);
drh383de692015-09-10 17:20:57 +00001564 sqlite3_free(p->zRoot);
drh505ad2c2015-08-21 17:33:11 +00001565 jsonParseReset(&p->sParse);
drhcb6c6c62015-08-19 22:47:17 +00001566 p->iRowid = 0;
1567 p->i = 0;
1568 p->iEnd = 0;
1569 p->eType = 0;
drhcb6c6c62015-08-19 22:47:17 +00001570 p->zJson = 0;
drh383de692015-09-10 17:20:57 +00001571 p->zRoot = 0;
drhcb6c6c62015-08-19 22:47:17 +00001572}
1573
1574/* Destructor for a jsonEachCursor object */
1575static int jsonEachClose(sqlite3_vtab_cursor *cur){
1576 JsonEachCursor *p = (JsonEachCursor*)cur;
1577 jsonEachCursorReset(p);
1578 sqlite3_free(cur);
1579 return SQLITE_OK;
1580}
1581
1582/* Return TRUE if the jsonEachCursor object has been advanced off the end
1583** of the JSON object */
1584static int jsonEachEof(sqlite3_vtab_cursor *cur){
1585 JsonEachCursor *p = (JsonEachCursor*)cur;
1586 return p->i >= p->iEnd;
1587}
1588
drh505ad2c2015-08-21 17:33:11 +00001589/* Advance the cursor to the next element for json_tree() */
drh4af352d2015-08-21 20:02:48 +00001590static int jsonEachNext(sqlite3_vtab_cursor *cur){
drh505ad2c2015-08-21 17:33:11 +00001591 JsonEachCursor *p = (JsonEachCursor*)cur;
drh4af352d2015-08-21 20:02:48 +00001592 if( p->bRecursive ){
drh852944e2015-09-10 03:29:11 +00001593 if( p->sParse.aNode[p->i].jnFlags & JNODE_LABEL ) p->i++;
1594 p->i++;
drh4af352d2015-08-21 20:02:48 +00001595 p->iRowid++;
drh852944e2015-09-10 03:29:11 +00001596 if( p->i<p->iEnd ){
drh8784eca2015-08-23 02:42:30 +00001597 u32 iUp = p->sParse.aUp[p->i];
1598 JsonNode *pUp = &p->sParse.aNode[iUp];
drh4af352d2015-08-21 20:02:48 +00001599 p->eType = pUp->eType;
drh8784eca2015-08-23 02:42:30 +00001600 if( pUp->eType==JSON_ARRAY ){
1601 if( iUp==p->i-1 ){
1602 pUp->u.iKey = 0;
1603 }else{
1604 pUp->u.iKey++;
1605 }
drh4af352d2015-08-21 20:02:48 +00001606 }
1607 }
drh505ad2c2015-08-21 17:33:11 +00001608 }else{
drh4af352d2015-08-21 20:02:48 +00001609 switch( p->eType ){
1610 case JSON_ARRAY: {
1611 p->i += jsonNodeSize(&p->sParse.aNode[p->i]);
1612 p->iRowid++;
1613 break;
1614 }
1615 case JSON_OBJECT: {
1616 p->i += 1 + jsonNodeSize(&p->sParse.aNode[p->i+1]);
1617 p->iRowid++;
1618 break;
1619 }
1620 default: {
1621 p->i = p->iEnd;
1622 break;
1623 }
drh505ad2c2015-08-21 17:33:11 +00001624 }
1625 }
1626 return SQLITE_OK;
1627}
1628
drh4af352d2015-08-21 20:02:48 +00001629/* Append the name of the path for element i to pStr
1630*/
1631static void jsonEachComputePath(
1632 JsonEachCursor *p, /* The cursor */
1633 JsonString *pStr, /* Write the path here */
1634 u32 i /* Path to this element */
1635){
1636 JsonNode *pNode, *pUp;
1637 u32 iUp;
1638 if( i==0 ){
1639 jsonAppendChar(pStr, '$');
1640 return;
drhcb6c6c62015-08-19 22:47:17 +00001641 }
drh4af352d2015-08-21 20:02:48 +00001642 iUp = p->sParse.aUp[i];
1643 jsonEachComputePath(p, pStr, iUp);
1644 pNode = &p->sParse.aNode[i];
1645 pUp = &p->sParse.aNode[iUp];
1646 if( pUp->eType==JSON_ARRAY ){
1647 jsonPrintf(30, pStr, "[%d]", pUp->u.iKey);
1648 }else{
1649 assert( pUp->eType==JSON_OBJECT );
drh852944e2015-09-10 03:29:11 +00001650 if( (pNode->jnFlags & JNODE_LABEL)==0 ) pNode--;
drh4af352d2015-08-21 20:02:48 +00001651 assert( pNode->eType==JSON_STRING );
drh852944e2015-09-10 03:29:11 +00001652 assert( pNode->jnFlags & JNODE_LABEL );
drh4af352d2015-08-21 20:02:48 +00001653 jsonPrintf(pNode->n+1, pStr, ".%.*s", pNode->n-2, pNode->u.zJContent+1);
1654 }
drhcb6c6c62015-08-19 22:47:17 +00001655}
1656
1657/* Return the value of a column */
1658static int jsonEachColumn(
1659 sqlite3_vtab_cursor *cur, /* The cursor */
1660 sqlite3_context *ctx, /* First argument to sqlite3_result_...() */
1661 int i /* Which column to return */
1662){
1663 JsonEachCursor *p = (JsonEachCursor*)cur;
drh505ad2c2015-08-21 17:33:11 +00001664 JsonNode *pThis = &p->sParse.aNode[p->i];
drhcb6c6c62015-08-19 22:47:17 +00001665 switch( i ){
1666 case JEACH_KEY: {
drh8784eca2015-08-23 02:42:30 +00001667 if( p->i==0 ) break;
drhcb6c6c62015-08-19 22:47:17 +00001668 if( p->eType==JSON_OBJECT ){
drh505ad2c2015-08-21 17:33:11 +00001669 jsonReturn(pThis, ctx, 0);
1670 }else if( p->eType==JSON_ARRAY ){
1671 u32 iKey;
1672 if( p->bRecursive ){
1673 if( p->iRowid==0 ) break;
drh8784eca2015-08-23 02:42:30 +00001674 iKey = p->sParse.aNode[p->sParse.aUp[p->i]].u.iKey;
drh505ad2c2015-08-21 17:33:11 +00001675 }else{
1676 iKey = p->iRowid;
1677 }
drh6fd5c1e2015-08-21 20:37:12 +00001678 sqlite3_result_int64(ctx, (sqlite3_int64)iKey);
drhcb6c6c62015-08-19 22:47:17 +00001679 }
1680 break;
1681 }
1682 case JEACH_VALUE: {
drh852944e2015-09-10 03:29:11 +00001683 if( pThis->jnFlags & JNODE_LABEL ) pThis++;
drh505ad2c2015-08-21 17:33:11 +00001684 jsonReturn(pThis, ctx, 0);
1685 break;
1686 }
1687 case JEACH_TYPE: {
drh852944e2015-09-10 03:29:11 +00001688 if( pThis->jnFlags & JNODE_LABEL ) pThis++;
drh505ad2c2015-08-21 17:33:11 +00001689 sqlite3_result_text(ctx, jsonType[pThis->eType], -1, SQLITE_STATIC);
1690 break;
1691 }
1692 case JEACH_ATOM: {
drh852944e2015-09-10 03:29:11 +00001693 if( pThis->jnFlags & JNODE_LABEL ) pThis++;
drh505ad2c2015-08-21 17:33:11 +00001694 if( pThis->eType>=JSON_ARRAY ) break;
1695 jsonReturn(pThis, ctx, 0);
1696 break;
1697 }
1698 case JEACH_ID: {
drh852944e2015-09-10 03:29:11 +00001699 sqlite3_result_int64(ctx,
1700 (sqlite3_int64)p->i + ((pThis->jnFlags & JNODE_LABEL)!=0));
drh505ad2c2015-08-21 17:33:11 +00001701 break;
1702 }
1703 case JEACH_PARENT: {
drh852944e2015-09-10 03:29:11 +00001704 if( p->i>p->iBegin && p->bRecursive ){
drh6fd5c1e2015-08-21 20:37:12 +00001705 sqlite3_result_int64(ctx, (sqlite3_int64)p->sParse.aUp[p->i]);
drhcb6c6c62015-08-19 22:47:17 +00001706 }
1707 break;
1708 }
drh4af352d2015-08-21 20:02:48 +00001709 case JEACH_FULLKEY: {
1710 JsonString x;
1711 jsonInit(&x, ctx);
1712 if( p->bRecursive ){
1713 jsonEachComputePath(p, &x, p->i);
1714 }else{
drh383de692015-09-10 17:20:57 +00001715 if( p->zRoot ){
1716 jsonAppendRaw(&x, p->zRoot, (int)strlen(p->zRoot));
drh4af352d2015-08-21 20:02:48 +00001717 }else{
1718 jsonAppendChar(&x, '$');
1719 }
1720 if( p->eType==JSON_ARRAY ){
1721 jsonPrintf(30, &x, "[%d]", p->iRowid);
1722 }else{
1723 jsonPrintf(pThis->n, &x, ".%.*s", pThis->n-2, pThis->u.zJContent+1);
1724 }
1725 }
1726 jsonResult(&x);
1727 break;
1728 }
drhcb6c6c62015-08-19 22:47:17 +00001729 case JEACH_PATH: {
drh383de692015-09-10 17:20:57 +00001730 if( p->bRecursive ){
1731 JsonString x;
1732 jsonInit(&x, ctx);
1733 jsonEachComputePath(p, &x, p->sParse.aUp[p->i]);
1734 jsonResult(&x);
1735 break;
drh4af352d2015-08-21 20:02:48 +00001736 }
drh383de692015-09-10 17:20:57 +00001737 /* For json_each() path and root are the same so fall through
1738 ** into the root case */
1739 }
1740 case JEACH_ROOT: {
1741 const char *zRoot = p->zRoot;
1742 if( zRoot==0 ) zRoot = "$";
1743 sqlite3_result_text(ctx, zRoot, -1, SQLITE_STATIC);
drhcb6c6c62015-08-19 22:47:17 +00001744 break;
1745 }
drh3d1d2a92015-09-22 01:15:49 +00001746 case JEACH_JSON: {
drh505ad2c2015-08-21 17:33:11 +00001747 assert( i==JEACH_JSON );
drhcb6c6c62015-08-19 22:47:17 +00001748 sqlite3_result_text(ctx, p->sParse.zJson, -1, SQLITE_STATIC);
1749 break;
1750 }
1751 }
1752 return SQLITE_OK;
1753}
1754
1755/* Return the current rowid value */
1756static int jsonEachRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){
1757 JsonEachCursor *p = (JsonEachCursor*)cur;
1758 *pRowid = p->iRowid;
1759 return SQLITE_OK;
1760}
1761
1762/* The query strategy is to look for an equality constraint on the json
1763** column. Without such a constraint, the table cannot operate. idxNum is
drh383de692015-09-10 17:20:57 +00001764** 1 if the constraint is found, 3 if the constraint and zRoot are found,
drhcb6c6c62015-08-19 22:47:17 +00001765** and 0 otherwise.
1766*/
1767static int jsonEachBestIndex(
1768 sqlite3_vtab *tab,
1769 sqlite3_index_info *pIdxInfo
1770){
1771 int i;
1772 int jsonIdx = -1;
drh383de692015-09-10 17:20:57 +00001773 int rootIdx = -1;
drhcb6c6c62015-08-19 22:47:17 +00001774 const struct sqlite3_index_constraint *pConstraint;
drh6fd5c1e2015-08-21 20:37:12 +00001775
1776 UNUSED_PARAM(tab);
drhcb6c6c62015-08-19 22:47:17 +00001777 pConstraint = pIdxInfo->aConstraint;
1778 for(i=0; i<pIdxInfo->nConstraint; i++, pConstraint++){
1779 if( pConstraint->usable==0 ) continue;
1780 if( pConstraint->op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue;
1781 switch( pConstraint->iColumn ){
1782 case JEACH_JSON: jsonIdx = i; break;
drh383de692015-09-10 17:20:57 +00001783 case JEACH_ROOT: rootIdx = i; break;
drhcb6c6c62015-08-19 22:47:17 +00001784 default: /* no-op */ break;
1785 }
1786 }
1787 if( jsonIdx<0 ){
1788 pIdxInfo->idxNum = 0;
drh505ad2c2015-08-21 17:33:11 +00001789 pIdxInfo->estimatedCost = 1e99;
drhcb6c6c62015-08-19 22:47:17 +00001790 }else{
drh505ad2c2015-08-21 17:33:11 +00001791 pIdxInfo->estimatedCost = 1.0;
drhcb6c6c62015-08-19 22:47:17 +00001792 pIdxInfo->aConstraintUsage[jsonIdx].argvIndex = 1;
1793 pIdxInfo->aConstraintUsage[jsonIdx].omit = 1;
drh383de692015-09-10 17:20:57 +00001794 if( rootIdx<0 ){
drhcb6c6c62015-08-19 22:47:17 +00001795 pIdxInfo->idxNum = 1;
1796 }else{
drh383de692015-09-10 17:20:57 +00001797 pIdxInfo->aConstraintUsage[rootIdx].argvIndex = 2;
1798 pIdxInfo->aConstraintUsage[rootIdx].omit = 1;
drhcb6c6c62015-08-19 22:47:17 +00001799 pIdxInfo->idxNum = 3;
1800 }
1801 }
1802 return SQLITE_OK;
1803}
1804
1805/* Start a search on a new JSON string */
1806static int jsonEachFilter(
1807 sqlite3_vtab_cursor *cur,
1808 int idxNum, const char *idxStr,
1809 int argc, sqlite3_value **argv
1810){
1811 JsonEachCursor *p = (JsonEachCursor*)cur;
1812 const char *z;
mistachkin16a93122015-09-11 18:05:01 +00001813 const char *zRoot = 0;
drhcb6c6c62015-08-19 22:47:17 +00001814 sqlite3_int64 n;
1815
drh6fd5c1e2015-08-21 20:37:12 +00001816 UNUSED_PARAM(idxStr);
1817 UNUSED_PARAM(argc);
drhcb6c6c62015-08-19 22:47:17 +00001818 jsonEachCursorReset(p);
1819 if( idxNum==0 ) return SQLITE_OK;
1820 z = (const char*)sqlite3_value_text(argv[0]);
1821 if( z==0 ) return SQLITE_OK;
drhcb6c6c62015-08-19 22:47:17 +00001822 n = sqlite3_value_bytes(argv[0]);
drh6fd5c1e2015-08-21 20:37:12 +00001823 p->zJson = sqlite3_malloc64( n+1 );
drhcb6c6c62015-08-19 22:47:17 +00001824 if( p->zJson==0 ) return SQLITE_NOMEM;
drh6fd5c1e2015-08-21 20:37:12 +00001825 memcpy(p->zJson, z, (size_t)n+1);
drha7714022015-08-29 00:54:49 +00001826 if( jsonParse(&p->sParse, 0, p->zJson) ){
1827 int rc = SQLITE_NOMEM;
1828 if( p->sParse.oom==0 ){
1829 sqlite3_free(cur->pVtab->zErrMsg);
1830 cur->pVtab->zErrMsg = sqlite3_mprintf("malformed JSON");
1831 if( cur->pVtab->zErrMsg ) rc = SQLITE_ERROR;
1832 }
drhcb6c6c62015-08-19 22:47:17 +00001833 jsonEachCursorReset(p);
drha7714022015-08-29 00:54:49 +00001834 return rc;
1835 }else if( p->bRecursive && jsonParseFindParents(&p->sParse) ){
1836 jsonEachCursorReset(p);
1837 return SQLITE_NOMEM;
drhcb6c6c62015-08-19 22:47:17 +00001838 }else{
drh95677942015-09-24 01:06:37 +00001839 JsonNode *pNode = 0;
drhcb6c6c62015-08-19 22:47:17 +00001840 if( idxNum==3 ){
drha7714022015-08-29 00:54:49 +00001841 const char *zErr = 0;
drha8f39a92015-09-21 22:53:16 +00001842 zRoot = (const char*)sqlite3_value_text(argv[1]);
1843 if( zRoot==0 ) return SQLITE_OK;
drhcb6c6c62015-08-19 22:47:17 +00001844 n = sqlite3_value_bytes(argv[1]);
drh383de692015-09-10 17:20:57 +00001845 p->zRoot = sqlite3_malloc64( n+1 );
1846 if( p->zRoot==0 ) return SQLITE_NOMEM;
1847 memcpy(p->zRoot, zRoot, (size_t)n+1);
drha8f39a92015-09-21 22:53:16 +00001848 if( zRoot[0]!='$' ){
1849 zErr = zRoot;
1850 }else{
1851 pNode = jsonLookupStep(&p->sParse, 0, p->zRoot+1, 0, &zErr);
1852 }
1853 if( zErr ){
drha7714022015-08-29 00:54:49 +00001854 sqlite3_free(cur->pVtab->zErrMsg);
1855 cur->pVtab->zErrMsg = jsonPathSyntaxError(zErr);
drhcb6c6c62015-08-19 22:47:17 +00001856 jsonEachCursorReset(p);
drha7714022015-08-29 00:54:49 +00001857 return cur->pVtab->zErrMsg ? SQLITE_ERROR : SQLITE_NOMEM;
1858 }else if( pNode==0 ){
drhcb6c6c62015-08-19 22:47:17 +00001859 return SQLITE_OK;
1860 }
1861 }else{
1862 pNode = p->sParse.aNode;
1863 }
drh852944e2015-09-10 03:29:11 +00001864 p->iBegin = p->i = (int)(pNode - p->sParse.aNode);
drhcb6c6c62015-08-19 22:47:17 +00001865 p->eType = pNode->eType;
1866 if( p->eType>=JSON_ARRAY ){
drh8784eca2015-08-23 02:42:30 +00001867 pNode->u.iKey = 0;
drhc3722b22015-08-23 20:44:59 +00001868 p->iEnd = p->i + pNode->n + 1;
drh852944e2015-09-10 03:29:11 +00001869 if( p->bRecursive ){
drh3d1d2a92015-09-22 01:15:49 +00001870 p->eType = p->sParse.aNode[p->sParse.aUp[p->i]].eType;
drh852944e2015-09-10 03:29:11 +00001871 if( p->i>0 && (p->sParse.aNode[p->i-1].jnFlags & JNODE_LABEL)!=0 ){
1872 p->i--;
1873 }
1874 }else{
1875 p->i++;
1876 }
drhcb6c6c62015-08-19 22:47:17 +00001877 }else{
1878 p->iEnd = p->i+1;
1879 }
1880 }
drha8f39a92015-09-21 22:53:16 +00001881 return SQLITE_OK;
drhcb6c6c62015-08-19 22:47:17 +00001882}
1883
1884/* The methods of the json_each virtual table */
1885static sqlite3_module jsonEachModule = {
1886 0, /* iVersion */
1887 0, /* xCreate */
1888 jsonEachConnect, /* xConnect */
1889 jsonEachBestIndex, /* xBestIndex */
1890 jsonEachDisconnect, /* xDisconnect */
1891 0, /* xDestroy */
drh505ad2c2015-08-21 17:33:11 +00001892 jsonEachOpenEach, /* xOpen - open a cursor */
drhcb6c6c62015-08-19 22:47:17 +00001893 jsonEachClose, /* xClose - close a cursor */
1894 jsonEachFilter, /* xFilter - configure scan constraints */
drh4af352d2015-08-21 20:02:48 +00001895 jsonEachNext, /* xNext - advance a cursor */
drhcb6c6c62015-08-19 22:47:17 +00001896 jsonEachEof, /* xEof - check for end of scan */
1897 jsonEachColumn, /* xColumn - read data */
1898 jsonEachRowid, /* xRowid - read data */
1899 0, /* xUpdate */
1900 0, /* xBegin */
1901 0, /* xSync */
1902 0, /* xCommit */
1903 0, /* xRollback */
1904 0, /* xFindMethod */
1905 0, /* xRename */
drh6fd5c1e2015-08-21 20:37:12 +00001906 0, /* xSavepoint */
1907 0, /* xRelease */
1908 0 /* xRollbackTo */
drhcb6c6c62015-08-19 22:47:17 +00001909};
1910
drh505ad2c2015-08-21 17:33:11 +00001911/* The methods of the json_tree virtual table. */
1912static sqlite3_module jsonTreeModule = {
1913 0, /* iVersion */
1914 0, /* xCreate */
1915 jsonEachConnect, /* xConnect */
1916 jsonEachBestIndex, /* xBestIndex */
1917 jsonEachDisconnect, /* xDisconnect */
1918 0, /* xDestroy */
1919 jsonEachOpenTree, /* xOpen - open a cursor */
1920 jsonEachClose, /* xClose - close a cursor */
1921 jsonEachFilter, /* xFilter - configure scan constraints */
drh4af352d2015-08-21 20:02:48 +00001922 jsonEachNext, /* xNext - advance a cursor */
drh505ad2c2015-08-21 17:33:11 +00001923 jsonEachEof, /* xEof - check for end of scan */
1924 jsonEachColumn, /* xColumn - read data */
1925 jsonEachRowid, /* xRowid - read data */
1926 0, /* xUpdate */
1927 0, /* xBegin */
1928 0, /* xSync */
1929 0, /* xCommit */
1930 0, /* xRollback */
1931 0, /* xFindMethod */
1932 0, /* xRename */
drh6fd5c1e2015-08-21 20:37:12 +00001933 0, /* xSavepoint */
1934 0, /* xRelease */
1935 0 /* xRollbackTo */
drh505ad2c2015-08-21 17:33:11 +00001936};
drhd2975922015-08-29 17:22:33 +00001937#endif /* SQLITE_OMIT_VIRTUALTABLE */
drh505ad2c2015-08-21 17:33:11 +00001938
1939/****************************************************************************
drh2f20e132015-09-26 17:44:59 +00001940** The following routines are the only publically visible identifiers in this
1941** file. Call the following routines in order to register the various SQL
drh505ad2c2015-08-21 17:33:11 +00001942** functions and the virtual table implemented by this file.
1943****************************************************************************/
drhcb6c6c62015-08-19 22:47:17 +00001944
drh2f20e132015-09-26 17:44:59 +00001945int sqlite3Json1Init(sqlite3 *db){
drh5fa5c102015-08-12 16:49:40 +00001946 int rc = SQLITE_OK;
drh6fd5c1e2015-08-21 20:37:12 +00001947 unsigned int i;
drh5fa5c102015-08-12 16:49:40 +00001948 static const struct {
1949 const char *zName;
1950 int nArg;
drh52216ad2015-08-18 02:28:03 +00001951 int flag;
drh5fa5c102015-08-12 16:49:40 +00001952 void (*xFunc)(sqlite3_context*,int,sqlite3_value**);
1953 } aFunc[] = {
drhf5ddb9c2015-09-11 00:06:41 +00001954 { "json", 1, 0, jsonRemoveFunc },
drh52216ad2015-08-18 02:28:03 +00001955 { "json_array", -1, 0, jsonArrayFunc },
1956 { "json_array_length", 1, 0, jsonArrayLengthFunc },
1957 { "json_array_length", 2, 0, jsonArrayLengthFunc },
drh3ad93bb2015-08-29 19:41:45 +00001958 { "json_extract", -1, 0, jsonExtractFunc },
drh52216ad2015-08-18 02:28:03 +00001959 { "json_insert", -1, 0, jsonSetFunc },
1960 { "json_object", -1, 0, jsonObjectFunc },
1961 { "json_remove", -1, 0, jsonRemoveFunc },
1962 { "json_replace", -1, 0, jsonReplaceFunc },
1963 { "json_set", -1, 1, jsonSetFunc },
1964 { "json_type", 1, 0, jsonTypeFunc },
1965 { "json_type", 2, 0, jsonTypeFunc },
drhbc8f0922015-08-22 19:39:04 +00001966 { "json_valid", 1, 0, jsonValidFunc },
drh987eb1f2015-08-17 15:17:37 +00001967
drh301eecc2015-08-17 20:14:19 +00001968#if SQLITE_DEBUG
drh987eb1f2015-08-17 15:17:37 +00001969 /* DEBUG and TESTING functions */
drh52216ad2015-08-18 02:28:03 +00001970 { "json_parse", 1, 0, jsonParseFunc },
1971 { "json_test1", 1, 0, jsonTest1Func },
drh301eecc2015-08-17 20:14:19 +00001972#endif
drh5fa5c102015-08-12 16:49:40 +00001973 };
drhd2975922015-08-29 17:22:33 +00001974#ifndef SQLITE_OMIT_VIRTUALTABLE
drh505ad2c2015-08-21 17:33:11 +00001975 static const struct {
1976 const char *zName;
1977 sqlite3_module *pModule;
1978 } aMod[] = {
1979 { "json_each", &jsonEachModule },
1980 { "json_tree", &jsonTreeModule },
1981 };
drhd2975922015-08-29 17:22:33 +00001982#endif
drh5fa5c102015-08-12 16:49:40 +00001983 for(i=0; i<sizeof(aFunc)/sizeof(aFunc[0]) && rc==SQLITE_OK; i++){
1984 rc = sqlite3_create_function(db, aFunc[i].zName, aFunc[i].nArg,
drh52216ad2015-08-18 02:28:03 +00001985 SQLITE_UTF8 | SQLITE_DETERMINISTIC,
1986 (void*)&aFunc[i].flag,
drh5fa5c102015-08-12 16:49:40 +00001987 aFunc[i].xFunc, 0, 0);
1988 }
drhd2975922015-08-29 17:22:33 +00001989#ifndef SQLITE_OMIT_VIRTUALTABLE
drh505ad2c2015-08-21 17:33:11 +00001990 for(i=0; i<sizeof(aMod)/sizeof(aMod[0]) && rc==SQLITE_OK; i++){
1991 rc = sqlite3_create_module(db, aMod[i].zName, aMod[i].pModule, 0);
drhcb6c6c62015-08-19 22:47:17 +00001992 }
drhd2975922015-08-29 17:22:33 +00001993#endif
drh5fa5c102015-08-12 16:49:40 +00001994 return rc;
1995}
drh2f20e132015-09-26 17:44:59 +00001996
1997
1998#ifdef _WIN32
1999__declspec(dllexport)
2000#endif
2001int sqlite3_json_init(
2002 sqlite3 *db,
2003 char **pzErrMsg,
2004 const sqlite3_api_routines *pApi
2005){
2006 SQLITE_EXTENSION_INIT2(pApi);
2007 (void)pzErrMsg; /* Unused parameter */
2008 return sqlite3Json1Init(db);
2009}