blob: 26cde6105636a89865aee58a444eb28fa17ab6a4 [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*/
24#include "sqlite3ext.h"
25SQLITE_EXTENSION_INIT1
26#include <assert.h>
27#include <string.h>
drhe9c37f32015-08-15 21:25:36 +000028#include <ctype.h>
drh987eb1f2015-08-17 15:17:37 +000029#include <stdlib.h>
drh5fa5c102015-08-12 16:49:40 +000030
31/* Unsigned integer types */
32typedef sqlite3_uint64 u64;
33typedef unsigned int u32;
34typedef unsigned char u8;
35
drh52216ad2015-08-18 02:28:03 +000036/* Objects */
drh505ad2c2015-08-21 17:33:11 +000037typedef struct JsonString JsonString;
drh52216ad2015-08-18 02:28:03 +000038typedef struct JsonNode JsonNode;
39typedef struct JsonParse JsonParse;
40
drh5634cc02015-08-17 11:28:03 +000041/* An instance of this object represents a JSON string
42** under construction. Really, this is a generic string accumulator
43** that can be and is used to create strings other than JSON.
drh5fa5c102015-08-12 16:49:40 +000044*/
drh505ad2c2015-08-21 17:33:11 +000045struct JsonString {
drh5fa5c102015-08-12 16:49:40 +000046 sqlite3_context *pCtx; /* Function context - put error messages here */
drh5634cc02015-08-17 11:28:03 +000047 char *zBuf; /* Append JSON content here */
drh5fa5c102015-08-12 16:49:40 +000048 u64 nAlloc; /* Bytes of storage available in zBuf[] */
49 u64 nUsed; /* Bytes of zBuf[] currently used */
50 u8 bStatic; /* True if zBuf is static space */
drhd0960592015-08-17 21:22:32 +000051 u8 bErr; /* True if an error has been encountered */
drh5fa5c102015-08-12 16:49:40 +000052 char zSpace[100]; /* Initial static space */
53};
54
drhe9c37f32015-08-15 21:25:36 +000055/* JSON type values
drhbd0621b2015-08-13 13:54:59 +000056*/
drhe9c37f32015-08-15 21:25:36 +000057#define JSON_NULL 0
58#define JSON_TRUE 1
59#define JSON_FALSE 2
60#define JSON_INT 3
61#define JSON_REAL 4
62#define JSON_STRING 5
63#define JSON_ARRAY 6
64#define JSON_OBJECT 7
65
drh987eb1f2015-08-17 15:17:37 +000066/*
67** Names of the various JSON types:
68*/
69static const char * const jsonType[] = {
70 "null", "true", "false", "integer", "real", "text", "array", "object"
71};
72
drh301eecc2015-08-17 20:14:19 +000073/* Bit values for the JsonNode.jnFlag field
74*/
75#define JNODE_RAW 0x01 /* Content is raw, not JSON encoded */
76#define JNODE_ESCAPE 0x02 /* Content is text with \ escapes */
77#define JNODE_REMOVE 0x04 /* Do not output */
drhd0960592015-08-17 21:22:32 +000078#define JNODE_REPLACE 0x08 /* Replace with JsonNode.iVal */
drh52216ad2015-08-18 02:28:03 +000079#define JNODE_APPEND 0x10 /* More ARRAY/OBJECT entries at u.iAppend */
drh301eecc2015-08-17 20:14:19 +000080
drh987eb1f2015-08-17 15:17:37 +000081
drhe9c37f32015-08-15 21:25:36 +000082/* A single node of parsed JSON
83*/
drhe9c37f32015-08-15 21:25:36 +000084struct JsonNode {
drh5634cc02015-08-17 11:28:03 +000085 u8 eType; /* One of the JSON_ type values */
drh301eecc2015-08-17 20:14:19 +000086 u8 jnFlags; /* JNODE flags */
drhd0960592015-08-17 21:22:32 +000087 u8 iVal; /* Replacement value when JNODE_REPLACE */
drhe9c37f32015-08-15 21:25:36 +000088 u32 n; /* Bytes of content, or number of sub-nodes */
drh52216ad2015-08-18 02:28:03 +000089 union {
drh0042a972015-08-18 12:59:58 +000090 const char *zJContent; /* Content for INT, REAL, and STRING */
91 u32 iAppend; /* More terms for ARRAY and OBJECT */
drh505ad2c2015-08-21 17:33:11 +000092 u32 iKey; /* Key for ARRAY objects in json_tree() */
drh52216ad2015-08-18 02:28:03 +000093 } u;
drhe9c37f32015-08-15 21:25:36 +000094};
95
96/* A completely parsed JSON string
97*/
drhe9c37f32015-08-15 21:25:36 +000098struct JsonParse {
99 u32 nNode; /* Number of slots of aNode[] used */
100 u32 nAlloc; /* Number of slots of aNode[] allocated */
101 JsonNode *aNode; /* Array of nodes containing the parse */
102 const char *zJson; /* Original JSON string */
drh505ad2c2015-08-21 17:33:11 +0000103 u32 *aUp; /* Index of parent of each node */
drhe9c37f32015-08-15 21:25:36 +0000104 u8 oom; /* Set to true if out of memory */
105};
106
drh505ad2c2015-08-21 17:33:11 +0000107/**************************************************************************
108** Utility routines for dealing with JsonString objects
109**************************************************************************/
drh301eecc2015-08-17 20:14:19 +0000110
drh505ad2c2015-08-21 17:33:11 +0000111/* Set the JsonString object to an empty string
drh5fa5c102015-08-12 16:49:40 +0000112*/
drh505ad2c2015-08-21 17:33:11 +0000113static void jsonZero(JsonString *p){
drh5fa5c102015-08-12 16:49:40 +0000114 p->zBuf = p->zSpace;
115 p->nAlloc = sizeof(p->zSpace);
116 p->nUsed = 0;
117 p->bStatic = 1;
118}
119
drh505ad2c2015-08-21 17:33:11 +0000120/* Initialize the JsonString object
drh5fa5c102015-08-12 16:49:40 +0000121*/
drh505ad2c2015-08-21 17:33:11 +0000122static void jsonInit(JsonString *p, sqlite3_context *pCtx){
drh5fa5c102015-08-12 16:49:40 +0000123 p->pCtx = pCtx;
drhd0960592015-08-17 21:22:32 +0000124 p->bErr = 0;
drh5fa5c102015-08-12 16:49:40 +0000125 jsonZero(p);
126}
127
128
drh505ad2c2015-08-21 17:33:11 +0000129/* Free all allocated memory and reset the JsonString object back to its
drh5fa5c102015-08-12 16:49:40 +0000130** initial state.
131*/
drh505ad2c2015-08-21 17:33:11 +0000132static void jsonReset(JsonString *p){
drh5fa5c102015-08-12 16:49:40 +0000133 if( !p->bStatic ) sqlite3_free(p->zBuf);
134 jsonZero(p);
135}
136
137
138/* Report an out-of-memory (OOM) condition
139*/
drh505ad2c2015-08-21 17:33:11 +0000140static void jsonOom(JsonString *p){
drhd0960592015-08-17 21:22:32 +0000141 if( !p->bErr ){
142 p->bErr = 1;
143 sqlite3_result_error_nomem(p->pCtx);
144 jsonReset(p);
145 }
drh5fa5c102015-08-12 16:49:40 +0000146}
147
148/* Enlarge pJson->zBuf so that it can hold at least N more bytes.
149** Return zero on success. Return non-zero on an OOM error
150*/
drh505ad2c2015-08-21 17:33:11 +0000151static int jsonGrow(JsonString *p, u32 N){
drh301eecc2015-08-17 20:14:19 +0000152 u64 nTotal = N<p->nAlloc ? p->nAlloc*2 : p->nAlloc+N+10;
drh5fa5c102015-08-12 16:49:40 +0000153 char *zNew;
154 if( p->bStatic ){
drhd0960592015-08-17 21:22:32 +0000155 if( p->bErr ) return 1;
drh5fa5c102015-08-12 16:49:40 +0000156 zNew = sqlite3_malloc64(nTotal);
157 if( zNew==0 ){
158 jsonOom(p);
159 return SQLITE_NOMEM;
160 }
161 memcpy(zNew, p->zBuf, p->nUsed);
162 p->zBuf = zNew;
163 p->bStatic = 0;
164 }else{
165 zNew = sqlite3_realloc64(p->zBuf, nTotal);
166 if( zNew==0 ){
167 jsonOom(p);
168 return SQLITE_NOMEM;
169 }
170 p->zBuf = zNew;
171 }
172 p->nAlloc = nTotal;
173 return SQLITE_OK;
174}
175
drh505ad2c2015-08-21 17:33:11 +0000176/* Append N bytes from zIn onto the end of the JsonString string.
drh5fa5c102015-08-12 16:49:40 +0000177*/
drh505ad2c2015-08-21 17:33:11 +0000178static void jsonAppendRaw(JsonString *p, const char *zIn, u32 N){
drh5fa5c102015-08-12 16:49:40 +0000179 if( (N+p->nUsed >= p->nAlloc) && jsonGrow(p,N)!=0 ) return;
180 memcpy(p->zBuf+p->nUsed, zIn, N);
181 p->nUsed += N;
182}
183
drhd0960592015-08-17 21:22:32 +0000184#ifdef SQLITE_DEBUG
drhe9c37f32015-08-15 21:25:36 +0000185/* Append the zero-terminated string zIn
186*/
drh505ad2c2015-08-21 17:33:11 +0000187static void jsonAppend(JsonString *p, const char *zIn){
drhe9c37f32015-08-15 21:25:36 +0000188 jsonAppendRaw(p, zIn, (u32)strlen(zIn));
189}
drhd0960592015-08-17 21:22:32 +0000190#endif
drhe9c37f32015-08-15 21:25:36 +0000191
drh5634cc02015-08-17 11:28:03 +0000192/* Append a single character
193*/
drh505ad2c2015-08-21 17:33:11 +0000194static void jsonAppendChar(JsonString *p, char c){
drh5634cc02015-08-17 11:28:03 +0000195 if( p->nUsed>=p->nAlloc && jsonGrow(p,1)!=0 ) return;
196 p->zBuf[p->nUsed++] = c;
197}
198
drh301eecc2015-08-17 20:14:19 +0000199/* Append a comma separator to the output buffer, if the previous
200** character is not '[' or '{'.
201*/
drh505ad2c2015-08-21 17:33:11 +0000202static void jsonAppendSeparator(JsonString *p){
drh301eecc2015-08-17 20:14:19 +0000203 char c;
204 if( p->nUsed==0 ) return;
205 c = p->zBuf[p->nUsed-1];
206 if( c!='[' && c!='{' ) jsonAppendChar(p, ',');
207}
208
drh505ad2c2015-08-21 17:33:11 +0000209/* Append the N-byte string in zIn to the end of the JsonString string
drh5fa5c102015-08-12 16:49:40 +0000210** under construction. Enclose the string in "..." and escape
211** any double-quotes or backslash characters contained within the
212** string.
213*/
drh505ad2c2015-08-21 17:33:11 +0000214static void jsonAppendString(JsonString *p, const char *zIn, u32 N){
drh5fa5c102015-08-12 16:49:40 +0000215 u32 i;
216 if( (N+p->nUsed+2 >= p->nAlloc) && jsonGrow(p,N+2)!=0 ) return;
217 p->zBuf[p->nUsed++] = '"';
218 for(i=0; i<N; i++){
219 char c = zIn[i];
220 if( c=='"' || c=='\\' ){
221 if( (p->nUsed+N+1-i > p->nAlloc) && jsonGrow(p,N+1-i)!=0 ) return;
222 p->zBuf[p->nUsed++] = '\\';
223 }
224 p->zBuf[p->nUsed++] = c;
225 }
226 p->zBuf[p->nUsed++] = '"';
227}
228
drhd0960592015-08-17 21:22:32 +0000229/*
230** Append a function parameter value to the JSON string under
231** construction.
232*/
233static void jsonAppendValue(
drh505ad2c2015-08-21 17:33:11 +0000234 JsonString *p, /* Append to this JSON string */
drhd0960592015-08-17 21:22:32 +0000235 sqlite3_value *pValue /* Value to append */
236){
237 switch( sqlite3_value_type(pValue) ){
238 case SQLITE_NULL: {
239 jsonAppendRaw(p, "null", 4);
240 break;
241 }
242 case SQLITE_INTEGER:
243 case SQLITE_FLOAT: {
244 const char *z = (const char*)sqlite3_value_text(pValue);
245 u32 n = (u32)sqlite3_value_bytes(pValue);
246 jsonAppendRaw(p, z, n);
247 break;
248 }
249 case SQLITE_TEXT: {
250 const char *z = (const char*)sqlite3_value_text(pValue);
251 u32 n = (u32)sqlite3_value_bytes(pValue);
252 jsonAppendString(p, z, n);
253 break;
254 }
255 default: {
256 if( p->bErr==0 ){
257 sqlite3_result_error(p->pCtx, "JSON cannot hold BLOB values", -1);
258 p->bErr = 1;
259 jsonReset(p);
260 }
261 break;
262 }
263 }
264}
265
266
drhbd0621b2015-08-13 13:54:59 +0000267/* Make the JSON in p the result of the SQL function.
drh5fa5c102015-08-12 16:49:40 +0000268*/
drh505ad2c2015-08-21 17:33:11 +0000269static void jsonResult(JsonString *p){
drhd0960592015-08-17 21:22:32 +0000270 if( p->bErr==0 ){
drh5fa5c102015-08-12 16:49:40 +0000271 sqlite3_result_text64(p->pCtx, p->zBuf, p->nUsed,
272 p->bStatic ? SQLITE_TRANSIENT : sqlite3_free,
273 SQLITE_UTF8);
274 jsonZero(p);
275 }
276 assert( p->bStatic );
277}
278
drh505ad2c2015-08-21 17:33:11 +0000279/**************************************************************************
280** Utility routines for dealing with JsonNode and JsonParse objects
281**************************************************************************/
282
283/*
284** Return the number of consecutive JsonNode slots need to represent
285** the parsed JSON at pNode. The minimum answer is 1. For ARRAY and
286** OBJECT types, the number might be larger.
287**
288** Appended elements are not counted. The value returned is the number
289** by which the JsonNode counter should increment in order to go to the
290** next peer value.
291*/
292static u32 jsonNodeSize(JsonNode *pNode){
293 return pNode->eType>=JSON_ARRAY ? pNode->n+1 : 1;
294}
295
296/*
297** Reclaim all memory allocated by a JsonParse object. But do not
298** delete the JsonParse object itself.
299*/
300static void jsonParseReset(JsonParse *pParse){
301 sqlite3_free(pParse->aNode);
302 pParse->aNode = 0;
303 pParse->nNode = 0;
304 pParse->nAlloc = 0;
305 sqlite3_free(pParse->aUp);
306 pParse->aUp = 0;
307}
308
drh5634cc02015-08-17 11:28:03 +0000309/*
310** Convert the JsonNode pNode into a pure JSON string and
311** append to pOut. Subsubstructure is also included. Return
312** the number of JsonNode objects that are encoded.
drhbd0621b2015-08-13 13:54:59 +0000313*/
drh52216ad2015-08-18 02:28:03 +0000314static void jsonRenderNode(
drhd0960592015-08-17 21:22:32 +0000315 JsonNode *pNode, /* The node to render */
drh505ad2c2015-08-21 17:33:11 +0000316 JsonString *pOut, /* Write JSON here */
drhd0960592015-08-17 21:22:32 +0000317 sqlite3_value **aReplace /* Replacement values */
318){
drh5634cc02015-08-17 11:28:03 +0000319 switch( pNode->eType ){
320 case JSON_NULL: {
321 jsonAppendRaw(pOut, "null", 4);
322 break;
323 }
324 case JSON_TRUE: {
325 jsonAppendRaw(pOut, "true", 4);
326 break;
327 }
328 case JSON_FALSE: {
329 jsonAppendRaw(pOut, "false", 5);
330 break;
331 }
332 case JSON_STRING: {
drh301eecc2015-08-17 20:14:19 +0000333 if( pNode->jnFlags & JNODE_RAW ){
drh52216ad2015-08-18 02:28:03 +0000334 jsonAppendString(pOut, pNode->u.zJContent, pNode->n);
drh5634cc02015-08-17 11:28:03 +0000335 break;
336 }
337 /* Fall through into the next case */
338 }
339 case JSON_REAL:
340 case JSON_INT: {
drh52216ad2015-08-18 02:28:03 +0000341 jsonAppendRaw(pOut, pNode->u.zJContent, pNode->n);
drh5634cc02015-08-17 11:28:03 +0000342 break;
343 }
344 case JSON_ARRAY: {
drh52216ad2015-08-18 02:28:03 +0000345 u32 j = 1;
drh5634cc02015-08-17 11:28:03 +0000346 jsonAppendChar(pOut, '[');
drh52216ad2015-08-18 02:28:03 +0000347 for(;;){
348 while( j<=pNode->n ){
349 if( pNode[j].jnFlags & (JNODE_REMOVE|JNODE_REPLACE) ){
350 if( pNode[j].jnFlags & JNODE_REPLACE ){
351 jsonAppendSeparator(pOut);
352 jsonAppendValue(pOut, aReplace[pNode[j].iVal]);
353 }
354 }else{
drhd0960592015-08-17 21:22:32 +0000355 jsonAppendSeparator(pOut);
drh52216ad2015-08-18 02:28:03 +0000356 jsonRenderNode(&pNode[j], pOut, aReplace);
drhd0960592015-08-17 21:22:32 +0000357 }
drh505ad2c2015-08-21 17:33:11 +0000358 j += jsonNodeSize(&pNode[j]);
drh301eecc2015-08-17 20:14:19 +0000359 }
drh52216ad2015-08-18 02:28:03 +0000360 if( (pNode->jnFlags & JNODE_APPEND)==0 ) break;
361 pNode = &pNode[pNode->u.iAppend];
362 j = 1;
drh5634cc02015-08-17 11:28:03 +0000363 }
364 jsonAppendChar(pOut, ']');
365 break;
366 }
367 case JSON_OBJECT: {
drh52216ad2015-08-18 02:28:03 +0000368 u32 j = 1;
drh5634cc02015-08-17 11:28:03 +0000369 jsonAppendChar(pOut, '{');
drh52216ad2015-08-18 02:28:03 +0000370 for(;;){
371 while( j<=pNode->n ){
372 if( (pNode[j+1].jnFlags & JNODE_REMOVE)==0 ){
373 jsonAppendSeparator(pOut);
374 jsonRenderNode(&pNode[j], pOut, aReplace);
375 jsonAppendChar(pOut, ':');
376 if( pNode[j+1].jnFlags & JNODE_REPLACE ){
377 jsonAppendValue(pOut, aReplace[pNode[j+1].iVal]);
378 }else{
379 jsonRenderNode(&pNode[j+1], pOut, aReplace);
380 }
drhd0960592015-08-17 21:22:32 +0000381 }
drh505ad2c2015-08-21 17:33:11 +0000382 j += 1 + jsonNodeSize(&pNode[j+1]);
drh301eecc2015-08-17 20:14:19 +0000383 }
drh52216ad2015-08-18 02:28:03 +0000384 if( (pNode->jnFlags & JNODE_APPEND)==0 ) break;
385 pNode = &pNode[pNode->u.iAppend];
386 j = 1;
drh5634cc02015-08-17 11:28:03 +0000387 }
388 jsonAppendChar(pOut, '}');
389 break;
390 }
drhbd0621b2015-08-13 13:54:59 +0000391 }
drh5634cc02015-08-17 11:28:03 +0000392}
393
394/*
395** Make the JsonNode the return value of the function.
396*/
drhd0960592015-08-17 21:22:32 +0000397static void jsonReturn(
398 JsonNode *pNode, /* Node to return */
399 sqlite3_context *pCtx, /* Return value for this function */
400 sqlite3_value **aReplace /* Array of replacement values */
401){
drh5634cc02015-08-17 11:28:03 +0000402 switch( pNode->eType ){
403 case JSON_NULL: {
404 sqlite3_result_null(pCtx);
405 break;
406 }
407 case JSON_TRUE: {
408 sqlite3_result_int(pCtx, 1);
409 break;
410 }
411 case JSON_FALSE: {
412 sqlite3_result_int(pCtx, 0);
413 break;
414 }
drh987eb1f2015-08-17 15:17:37 +0000415 case JSON_REAL: {
drh52216ad2015-08-18 02:28:03 +0000416 double r = strtod(pNode->u.zJContent, 0);
drh987eb1f2015-08-17 15:17:37 +0000417 sqlite3_result_double(pCtx, r);
drh5634cc02015-08-17 11:28:03 +0000418 break;
419 }
drh987eb1f2015-08-17 15:17:37 +0000420 case JSON_INT: {
421 sqlite3_int64 i = 0;
drh52216ad2015-08-18 02:28:03 +0000422 const char *z = pNode->u.zJContent;
drh987eb1f2015-08-17 15:17:37 +0000423 if( z[0]=='-' ){ z++; }
424 while( z[0]>='0' && z[0]<='9' ){ i = i*10 + *(z++) - '0'; }
drh52216ad2015-08-18 02:28:03 +0000425 if( pNode->u.zJContent[0]=='-' ){ i = -i; }
drh987eb1f2015-08-17 15:17:37 +0000426 sqlite3_result_int64(pCtx, i);
427 break;
428 }
drh5634cc02015-08-17 11:28:03 +0000429 case JSON_STRING: {
drh301eecc2015-08-17 20:14:19 +0000430 if( pNode->jnFlags & JNODE_RAW ){
drh52216ad2015-08-18 02:28:03 +0000431 sqlite3_result_text(pCtx, pNode->u.zJContent, pNode->n,
432 SQLITE_TRANSIENT);
drh301eecc2015-08-17 20:14:19 +0000433 }else if( (pNode->jnFlags & JNODE_ESCAPE)==0 ){
drh987eb1f2015-08-17 15:17:37 +0000434 /* JSON formatted without any backslash-escapes */
drh52216ad2015-08-18 02:28:03 +0000435 sqlite3_result_text(pCtx, pNode->u.zJContent+1, pNode->n-2,
drh987eb1f2015-08-17 15:17:37 +0000436 SQLITE_TRANSIENT);
drh5634cc02015-08-17 11:28:03 +0000437 }else{
438 /* Translate JSON formatted string into raw text */
drh987eb1f2015-08-17 15:17:37 +0000439 u32 i;
440 u32 n = pNode->n;
drh52216ad2015-08-18 02:28:03 +0000441 const char *z = pNode->u.zJContent;
drh987eb1f2015-08-17 15:17:37 +0000442 char *zOut;
443 u32 j;
444 zOut = sqlite3_malloc( n+1 );
445 if( zOut==0 ){
446 sqlite3_result_error_nomem(pCtx);
447 break;
448 }
449 for(i=1, j=0; i<n-1; i++){
450 char c = z[i];
451 if( c!='\\' && z[i+1] ){
452 zOut[j++] = c;
453 }else{
454 c = z[++i];
455 if( c=='u' && z[1] ){
456 u32 v = 0, k;
457 z++;
458 for(k=0; k<4 && z[k]; k++){
459 c = z[0];
460 if( c>='0' && c<='9' ) v = v*16 + c - '0';
461 else if( c>='A' && c<='F' ) v = v*16 + c - 'A' + 10;
462 else if( c>='a' && c<='f' ) v = v*16 + c - 'a' + 10;
463 else break;
464 z++;
465 }
466 if( v<=0x7f ){
467 zOut[j++] = v;
468 }else if( v<=0x7ff ){
469 zOut[j++] = 0xc0 | (v>>6);
470 zOut[j++] = 0x80 | (v&0x3f);
471 }else if( v<=0xffff ){
472 zOut[j++] = 0xe0 | (v>>12);
473 zOut[j++] = 0x80 | ((v>>6)&0x3f);
474 zOut[j++] = 0x80 | (v&0x3f);
475 }else if( v<=0x10ffff ){
476 zOut[j++] = 0xf0 | (v>>18);
477 zOut[j++] = 0x80 | ((v>>12)&0x3f);
478 zOut[j++] = 0x80 | ((v>>6)&0x3f);
479 zOut[j++] = 0x80 | (v&0x3f);
480 }
481 }else{
482 if( c=='b' ){
483 c = '\b';
484 }else if( c=='f' ){
485 c = '\f';
486 }else if( c=='n' ){
487 c = '\n';
488 }else if( c=='r' ){
489 c = '\r';
490 }else if( c=='t' ){
491 c = '\t';
492 }
493 zOut[j++] = c;
494 }
495 }
496 }
497 zOut[j] = 0;
498 sqlite3_result_text(pCtx, zOut, j, sqlite3_free);
drh5634cc02015-08-17 11:28:03 +0000499 }
500 break;
501 }
502 case JSON_ARRAY:
503 case JSON_OBJECT: {
drh505ad2c2015-08-21 17:33:11 +0000504 JsonString s;
drh5634cc02015-08-17 11:28:03 +0000505 jsonInit(&s, pCtx);
drhd0960592015-08-17 21:22:32 +0000506 jsonRenderNode(pNode, &s, aReplace);
drh5634cc02015-08-17 11:28:03 +0000507 jsonResult(&s);
508 break;
509 }
510 }
drhbd0621b2015-08-13 13:54:59 +0000511}
512
drh5fa5c102015-08-12 16:49:40 +0000513/*
drhe9c37f32015-08-15 21:25:36 +0000514** Create a new JsonNode instance based on the arguments and append that
515** instance to the JsonParse. Return the index in pParse->aNode[] of the
516** new node, or -1 if a memory allocation fails.
517*/
518static int jsonParseAddNode(
519 JsonParse *pParse, /* Append the node to this object */
520 u32 eType, /* Node type */
521 u32 n, /* Content size or sub-node count */
522 const char *zContent /* Content */
523){
524 JsonNode *p;
525 if( pParse->nNode>=pParse->nAlloc ){
526 u32 nNew;
527 JsonNode *pNew;
528 if( pParse->oom ) return -1;
529 nNew = pParse->nAlloc*2 + 10;
530 if( nNew<=pParse->nNode ){
531 pParse->oom = 1;
532 return -1;
533 }
534 pNew = sqlite3_realloc(pParse->aNode, sizeof(JsonNode)*nNew);
535 if( pNew==0 ){
536 pParse->oom = 1;
537 return -1;
538 }
539 pParse->nAlloc = nNew;
540 pParse->aNode = pNew;
541 }
542 p = &pParse->aNode[pParse->nNode];
drh5634cc02015-08-17 11:28:03 +0000543 p->eType = (u8)eType;
drh301eecc2015-08-17 20:14:19 +0000544 p->jnFlags = 0;
drhd0960592015-08-17 21:22:32 +0000545 p->iVal = 0;
drhe9c37f32015-08-15 21:25:36 +0000546 p->n = n;
drh52216ad2015-08-18 02:28:03 +0000547 p->u.zJContent = zContent;
drhe9c37f32015-08-15 21:25:36 +0000548 return pParse->nNode++;
549}
550
551/*
552** Parse a single JSON value which begins at pParse->zJson[i]. Return the
553** index of the first character past the end of the value parsed.
554**
555** Return negative for a syntax error. Special cases: return -2 if the
556** first non-whitespace character is '}' and return -3 if the first
557** non-whitespace character is ']'.
558*/
559static int jsonParseValue(JsonParse *pParse, u32 i){
560 char c;
561 u32 j;
562 u32 iThis;
563 int x;
564 while( isspace(pParse->zJson[i]) ){ i++; }
565 if( (c = pParse->zJson[i])==0 ) return 0;
566 if( c=='{' ){
567 /* Parse object */
568 iThis = jsonParseAddNode(pParse, JSON_OBJECT, 0, 0);
569 if( iThis<0 ) return -1;
570 for(j=i+1;;j++){
571 while( isspace(pParse->zJson[j]) ){ j++; }
572 x = jsonParseValue(pParse, j);
573 if( x<0 ){
574 if( x==(-2) && pParse->nNode==iThis+1 ) return j+1;
575 return -1;
576 }
577 if( pParse->aNode[pParse->nNode-1].eType!=JSON_STRING ) return -1;
578 j = x;
579 while( isspace(pParse->zJson[j]) ){ j++; }
580 if( pParse->zJson[j]!=':' ) return -1;
581 j++;
582 x = jsonParseValue(pParse, j);
583 if( x<0 ) return -1;
584 j = x;
585 while( isspace(pParse->zJson[j]) ){ j++; }
586 c = pParse->zJson[j];
587 if( c==',' ) continue;
588 if( c!='}' ) return -1;
589 break;
590 }
591 pParse->aNode[iThis].n = pParse->nNode - iThis - 1;
592 return j+1;
593 }else if( c=='[' ){
594 /* Parse array */
595 iThis = jsonParseAddNode(pParse, JSON_ARRAY, 0, 0);
596 if( iThis<0 ) return -1;
597 for(j=i+1;;j++){
598 while( isspace(pParse->zJson[j]) ){ j++; }
599 x = jsonParseValue(pParse, j);
600 if( x<0 ){
601 if( x==(-3) && pParse->nNode==iThis+1 ) return j+1;
602 return -1;
603 }
604 j = x;
605 while( isspace(pParse->zJson[j]) ){ j++; }
606 c = pParse->zJson[j];
607 if( c==',' ) continue;
608 if( c!=']' ) return -1;
609 break;
610 }
611 pParse->aNode[iThis].n = pParse->nNode - iThis - 1;
612 return j+1;
613 }else if( c=='"' ){
614 /* Parse string */
drh301eecc2015-08-17 20:14:19 +0000615 u8 jnFlags = 0;
drhe9c37f32015-08-15 21:25:36 +0000616 j = i+1;
617 for(;;){
618 c = pParse->zJson[j];
619 if( c==0 ) return -1;
620 if( c=='\\' ){
621 c = pParse->zJson[++j];
622 if( c==0 ) return -1;
drh301eecc2015-08-17 20:14:19 +0000623 jnFlags = JNODE_ESCAPE;
drhe9c37f32015-08-15 21:25:36 +0000624 }else if( c=='"' ){
625 break;
626 }
627 j++;
628 }
629 jsonParseAddNode(pParse, JSON_STRING, j+1-i, &pParse->zJson[i]);
drh301eecc2015-08-17 20:14:19 +0000630 pParse->aNode[pParse->nNode-1].jnFlags = jnFlags;
drhe9c37f32015-08-15 21:25:36 +0000631 return j+1;
632 }else if( c=='n'
633 && strncmp(pParse->zJson+i,"null",4)==0
drhb2cd10e2015-08-15 21:29:14 +0000634 && !isalnum(pParse->zJson[i+4]) ){
drhe9c37f32015-08-15 21:25:36 +0000635 jsonParseAddNode(pParse, JSON_NULL, 0, 0);
636 return i+4;
637 }else if( c=='t'
638 && strncmp(pParse->zJson+i,"true",4)==0
drhb2cd10e2015-08-15 21:29:14 +0000639 && !isalnum(pParse->zJson[i+4]) ){
drhe9c37f32015-08-15 21:25:36 +0000640 jsonParseAddNode(pParse, JSON_TRUE, 0, 0);
641 return i+4;
642 }else if( c=='f'
643 && strncmp(pParse->zJson+i,"false",5)==0
drhb2cd10e2015-08-15 21:29:14 +0000644 && !isalnum(pParse->zJson[i+5]) ){
drhe9c37f32015-08-15 21:25:36 +0000645 jsonParseAddNode(pParse, JSON_FALSE, 0, 0);
646 return i+5;
647 }else if( c=='-' || (c>='0' && c<='9') ){
648 /* Parse number */
649 u8 seenDP = 0;
650 u8 seenE = 0;
651 j = i+1;
652 for(;; j++){
653 c = pParse->zJson[j];
654 if( c>='0' && c<='9' ) continue;
655 if( c=='.' ){
656 if( pParse->zJson[j-1]=='-' ) return -1;
657 if( seenDP ) return -1;
658 seenDP = 1;
659 continue;
660 }
661 if( c=='e' || c=='E' ){
662 if( pParse->zJson[j-1]<'0' ) return -1;
663 if( seenE ) return -1;
664 seenDP = seenE = 1;
665 c = pParse->zJson[j+1];
666 if( c=='+' || c=='-' ) j++;
667 continue;
668 }
669 break;
670 }
671 if( pParse->zJson[j-1]<'0' ) return -1;
672 jsonParseAddNode(pParse, seenDP ? JSON_REAL : JSON_INT,
673 j - i, &pParse->zJson[i]);
674 return j;
675 }else if( c=='}' ){
676 return -2; /* End of {...} */
677 }else if( c==']' ){
678 return -3; /* End of [...] */
679 }else{
680 return -1; /* Syntax error */
681 }
682}
683
684/*
685** Parse a complete JSON string. Return 0 on success or non-zero if there
686** are any errors. If an error occurs, free all memory associated with
687** pParse.
688**
689** pParse is uninitialized when this routine is called.
690*/
691static int jsonParse(JsonParse *pParse, const char *zJson){
692 int i;
693 if( zJson==0 ) return 1;
694 memset(pParse, 0, sizeof(*pParse));
695 pParse->zJson = zJson;
696 i = jsonParseValue(pParse, 0);
697 if( i>0 ){
698 while( isspace(zJson[i]) ) i++;
699 if( zJson[i] ) i = -1;
700 }
701 if( i<0 ){
drh505ad2c2015-08-21 17:33:11 +0000702 jsonParseReset(pParse);
drhe9c37f32015-08-15 21:25:36 +0000703 return 1;
704 }
705 return 0;
706}
drh301eecc2015-08-17 20:14:19 +0000707
drh505ad2c2015-08-21 17:33:11 +0000708/* Mark node i of pParse as being a child of iParent. Call recursively
709** to fill in all the descendants of node i.
710*/
711static void jsonParseFillInParentage(JsonParse *pParse, u32 i, u32 iParent){
712 JsonNode *pNode = &pParse->aNode[i];
713 u32 j;
714 pParse->aUp[i] = iParent;
715 switch( pNode->eType ){
716 case JSON_ARRAY: {
717 for(j=1; j<=pNode->n; j += jsonNodeSize(pNode+j)){
718 jsonParseFillInParentage(pParse, i+j, i);
719 }
720 break;
721 }
722 case JSON_OBJECT: {
723 for(j=1; j<=pNode->n; j += jsonNodeSize(pNode+j+1)+1){
724 pParse->aUp[i+j] = i;
725 jsonParseFillInParentage(pParse, i+j+1, i);
726 }
727 break;
728 }
729 default: {
730 break;
731 }
732 }
733}
734
735/*
736** Compute the parentage of all nodes in a completed parse.
737*/
738static int jsonParseFindParents(JsonParse *pParse){
739 u32 *aUp;
740 assert( pParse->aUp==0 );
741 aUp = pParse->aUp = sqlite3_malloc( sizeof(u32)*pParse->nNode );
742 if( aUp==0 ) return SQLITE_NOMEM;
743 jsonParseFillInParentage(pParse, 0, 0);
744 return SQLITE_OK;
745}
746
drh52216ad2015-08-18 02:28:03 +0000747/* forward declaration */
748static JsonNode *jsonLookupAppend(JsonParse*,const char*,int*);
749
drh987eb1f2015-08-17 15:17:37 +0000750/*
751** Search along zPath to find the node specified. Return a pointer
752** to that node, or NULL if zPath is malformed or if there is no such
753** node.
drh52216ad2015-08-18 02:28:03 +0000754**
755** If pApnd!=0, then try to append new nodes to complete zPath if it is
756** possible to do so and if no existing node corresponds to zPath. If
757** new nodes are appended *pApnd is set to 1.
drh987eb1f2015-08-17 15:17:37 +0000758*/
drh52216ad2015-08-18 02:28:03 +0000759static JsonNode *jsonLookup(
760 JsonParse *pParse, /* The JSON to search */
761 u32 iRoot, /* Begin the search at this node */
762 const char *zPath, /* The path to search */
763 int *pApnd /* Append nodes to complete path if not NULL */
764){
drh6b43cc82015-08-19 23:02:49 +0000765 u32 i, j, k, nKey;
766 const char *zKey;
drh52216ad2015-08-18 02:28:03 +0000767 JsonNode *pRoot = &pParse->aNode[iRoot];
drh987eb1f2015-08-17 15:17:37 +0000768 if( zPath[0]==0 ) return pRoot;
769 if( zPath[0]=='.' ){
770 if( pRoot->eType!=JSON_OBJECT ) return 0;
771 zPath++;
drh6b43cc82015-08-19 23:02:49 +0000772 if( zPath[0]=='"' ){
773 zKey = zPath + 1;
774 for(i=1; zPath[i] && zPath[i]!='"'; i++){}
775 nKey = i-1;
776 if( zPath[i] ) i++;
777 }else{
778 zKey = zPath;
779 for(i=0; zPath[i] && zPath[i]!='.' && zPath[i]!='['; i++){}
780 nKey = i;
781 }
782 if( nKey==0 ) return 0;
drh987eb1f2015-08-17 15:17:37 +0000783 j = 1;
drh52216ad2015-08-18 02:28:03 +0000784 for(;;){
785 while( j<=pRoot->n ){
drh6b43cc82015-08-19 23:02:49 +0000786 if( pRoot[j].n==nKey+2
787 && strncmp(&pRoot[j].u.zJContent[1],zKey,nKey)==0
drh52216ad2015-08-18 02:28:03 +0000788 ){
789 return jsonLookup(pParse, iRoot+j+1, &zPath[i], pApnd);
790 }
791 j++;
drh505ad2c2015-08-21 17:33:11 +0000792 j += jsonNodeSize(&pRoot[j]);
drh987eb1f2015-08-17 15:17:37 +0000793 }
drh52216ad2015-08-18 02:28:03 +0000794 if( (pRoot->jnFlags & JNODE_APPEND)==0 ) break;
795 iRoot += pRoot->u.iAppend;
796 pRoot = &pParse->aNode[iRoot];
797 j = 1;
798 }
799 if( pApnd ){
800 k = jsonParseAddNode(pParse, JSON_OBJECT, 2, 0);
801 pRoot->u.iAppend = k - iRoot;
802 pRoot->jnFlags |= JNODE_APPEND;
803 k = jsonParseAddNode(pParse, JSON_STRING, i, zPath);
804 if( !pParse->oom ) pParse->aNode[k].jnFlags |= JNODE_RAW;
805 zPath += i;
806 return jsonLookupAppend(pParse, zPath, pApnd);
drh987eb1f2015-08-17 15:17:37 +0000807 }
808 }else if( zPath[0]=='[' && isdigit(zPath[1]) ){
809 if( pRoot->eType!=JSON_ARRAY ) return 0;
810 i = 0;
811 zPath++;
812 while( isdigit(zPath[0]) ){
813 i = i + zPath[0] - '0';
814 zPath++;
815 }
816 if( zPath[0]!=']' ) return 0;
817 zPath++;
818 j = 1;
drh52216ad2015-08-18 02:28:03 +0000819 for(;;){
820 while( i>0 && j<=pRoot->n ){
drh505ad2c2015-08-21 17:33:11 +0000821 j += jsonNodeSize(&pRoot[j]);
drh52216ad2015-08-18 02:28:03 +0000822 i--;
823 }
824 if( (pRoot->jnFlags & JNODE_APPEND)==0 ) break;
825 iRoot += pRoot->u.iAppend;
826 pRoot = &pParse->aNode[iRoot];
827 j = 1;
drh987eb1f2015-08-17 15:17:37 +0000828 }
829 if( j<=pRoot->n ){
drh52216ad2015-08-18 02:28:03 +0000830 return jsonLookup(pParse, iRoot+j, zPath, pApnd);
831 }
832 if( i==0 && pApnd ){
833 k = jsonParseAddNode(pParse, JSON_ARRAY, 1, 0);
834 pRoot->u.iAppend = k - iRoot;
835 pRoot->jnFlags |= JNODE_APPEND;
836 return jsonLookupAppend(pParse, zPath, pApnd);
drh987eb1f2015-08-17 15:17:37 +0000837 }
838 }
839 return 0;
840}
841
drh52216ad2015-08-18 02:28:03 +0000842/*
843** Append content to pParse that will complete zPath.
844*/
845static JsonNode *jsonLookupAppend(
846 JsonParse *pParse, /* Append content to the JSON parse */
847 const char *zPath, /* Description of content to append */
848 int *pApnd /* Set this flag to 1 */
849){
850 *pApnd = 1;
851 if( zPath[0]==0 ){
852 jsonParseAddNode(pParse, JSON_NULL, 0, 0);
853 return pParse->oom ? 0 : &pParse->aNode[pParse->nNode-1];
854 }
855 if( zPath[0]=='.' ){
856 jsonParseAddNode(pParse, JSON_OBJECT, 0, 0);
857 }else if( strncmp(zPath,"[0]",3)==0 ){
858 jsonParseAddNode(pParse, JSON_ARRAY, 0, 0);
859 }else{
860 return 0;
861 }
862 if( pParse->oom ) return 0;
863 return jsonLookup(pParse, pParse->nNode-1, zPath, pApnd);
864}
865
866
drh987eb1f2015-08-17 15:17:37 +0000867/****************************************************************************
868** SQL functions used for testing and debugging
869****************************************************************************/
drhe9c37f32015-08-15 21:25:36 +0000870
drh301eecc2015-08-17 20:14:19 +0000871#ifdef SQLITE_DEBUG
drhe9c37f32015-08-15 21:25:36 +0000872/*
drh5634cc02015-08-17 11:28:03 +0000873** The json_parse(JSON) function returns a string which describes
drhe9c37f32015-08-15 21:25:36 +0000874** a parse of the JSON provided. Or it returns NULL if JSON is not
875** well-formed.
876*/
drh5634cc02015-08-17 11:28:03 +0000877static void jsonParseFunc(
drhe9c37f32015-08-15 21:25:36 +0000878 sqlite3_context *context,
879 int argc,
880 sqlite3_value **argv
881){
drh505ad2c2015-08-21 17:33:11 +0000882 JsonString s; /* Output string - not real JSON */
883 JsonParse x; /* The parse */
drhe9c37f32015-08-15 21:25:36 +0000884 u32 i;
drh301eecc2015-08-17 20:14:19 +0000885 char zBuf[100];
drhe9c37f32015-08-15 21:25:36 +0000886
887 assert( argc==1 );
888 if( jsonParse(&x, (const char*)sqlite3_value_text(argv[0])) ) return;
889 jsonInit(&s, context);
890 for(i=0; i<x.nNode; i++){
drh301eecc2015-08-17 20:14:19 +0000891 sqlite3_snprintf(sizeof(zBuf), zBuf, "node %3u: %7s n=%d\n",
892 i, jsonType[x.aNode[i].eType], x.aNode[i].n);
drhe9c37f32015-08-15 21:25:36 +0000893 jsonAppend(&s, zBuf);
drh52216ad2015-08-18 02:28:03 +0000894 if( x.aNode[i].u.zJContent!=0 ){
drh301eecc2015-08-17 20:14:19 +0000895 jsonAppendRaw(&s, " text: ", 10);
drh52216ad2015-08-18 02:28:03 +0000896 jsonAppendRaw(&s, x.aNode[i].u.zJContent, x.aNode[i].n);
drhe9c37f32015-08-15 21:25:36 +0000897 jsonAppendRaw(&s, "\n", 1);
898 }
899 }
drh505ad2c2015-08-21 17:33:11 +0000900 jsonParseReset(&x);
drhe9c37f32015-08-15 21:25:36 +0000901 jsonResult(&s);
902}
903
drh5634cc02015-08-17 11:28:03 +0000904/*
905** The json_test1(JSON) function parses and rebuilds the JSON string.
906*/
907static void jsonTest1Func(
908 sqlite3_context *context,
909 int argc,
910 sqlite3_value **argv
911){
912 JsonParse x; /* The parse */
913 if( jsonParse(&x, (const char*)sqlite3_value_text(argv[0])) ) return;
drhd0960592015-08-17 21:22:32 +0000914 jsonReturn(x.aNode, context, 0);
drh505ad2c2015-08-21 17:33:11 +0000915 jsonParseReset(&x);
drh5634cc02015-08-17 11:28:03 +0000916}
917
918/*
919** The json_nodecount(JSON) function returns the number of nodes in the
920** input JSON string.
921*/
922static void jsonNodeCountFunc(
923 sqlite3_context *context,
924 int argc,
925 sqlite3_value **argv
926){
927 JsonParse x; /* The parse */
928 if( jsonParse(&x, (const char*)sqlite3_value_text(argv[0])) ) return;
929 sqlite3_result_int64(context, x.nNode);
drh505ad2c2015-08-21 17:33:11 +0000930 jsonParseReset(&x);
drh5634cc02015-08-17 11:28:03 +0000931}
drh301eecc2015-08-17 20:14:19 +0000932#endif /* SQLITE_DEBUG */
drh5634cc02015-08-17 11:28:03 +0000933
drh987eb1f2015-08-17 15:17:37 +0000934/****************************************************************************
935** SQL function implementations
936****************************************************************************/
937
938/*
939** Implementation of the json_array(VALUE,...) function. Return a JSON
940** array that contains all values given in arguments. Or if any argument
941** is a BLOB, throw an error.
942*/
943static void jsonArrayFunc(
944 sqlite3_context *context,
945 int argc,
946 sqlite3_value **argv
947){
948 int i;
drh505ad2c2015-08-21 17:33:11 +0000949 JsonString jx;
drh987eb1f2015-08-17 15:17:37 +0000950
951 jsonInit(&jx, context);
drhd0960592015-08-17 21:22:32 +0000952 jsonAppendChar(&jx, '[');
drh987eb1f2015-08-17 15:17:37 +0000953 for(i=0; i<argc; i++){
drhd0960592015-08-17 21:22:32 +0000954 jsonAppendSeparator(&jx);
955 jsonAppendValue(&jx, argv[i]);
drh987eb1f2015-08-17 15:17:37 +0000956 }
drhd0960592015-08-17 21:22:32 +0000957 jsonAppendChar(&jx, ']');
drh987eb1f2015-08-17 15:17:37 +0000958 jsonResult(&jx);
959}
960
961
962/*
963** json_array_length(JSON)
964** json_array_length(JSON, PATH)
965**
966** Return the number of elements in the top-level JSON array.
967** Return 0 if the input is not a well-formed JSON array.
968*/
969static void jsonArrayLengthFunc(
970 sqlite3_context *context,
971 int argc,
972 sqlite3_value **argv
973){
974 JsonParse x; /* The parse */
975 sqlite3_int64 n = 0;
976 u32 i;
977 const char *zPath;
978
979 if( argc==2 ){
980 zPath = (const char*)sqlite3_value_text(argv[1]);
981 if( zPath==0 ) return;
982 if( zPath[0]!='$' ) return;
983 zPath++;
984 }else{
985 zPath = 0;
986 }
987 if( jsonParse(&x, (const char*)sqlite3_value_text(argv[0]))==0 ){
988 if( x.nNode ){
989 JsonNode *pNode = x.aNode;
drh52216ad2015-08-18 02:28:03 +0000990 if( zPath ) pNode = jsonLookup(&x, 0, zPath, 0);
drh987eb1f2015-08-17 15:17:37 +0000991 if( pNode->eType==JSON_ARRAY ){
drh52216ad2015-08-18 02:28:03 +0000992 assert( (pNode->jnFlags & JNODE_APPEND)==0 );
drh301eecc2015-08-17 20:14:19 +0000993 for(i=1; i<=pNode->n; n++){
drh505ad2c2015-08-21 17:33:11 +0000994 i += jsonNodeSize(&pNode[i]);
drh987eb1f2015-08-17 15:17:37 +0000995 }
996 }
997 }
drh505ad2c2015-08-21 17:33:11 +0000998 jsonParseReset(&x);
drh987eb1f2015-08-17 15:17:37 +0000999 }
1000 sqlite3_result_int64(context, n);
1001}
1002
1003/*
1004** json_extract(JSON, PATH)
1005**
1006** Return the element described by PATH. Return NULL if JSON is not
1007** valid JSON or if there is no PATH element or if PATH is malformed.
1008*/
1009static void jsonExtractFunc(
1010 sqlite3_context *context,
1011 int argc,
1012 sqlite3_value **argv
1013){
1014 JsonParse x; /* The parse */
1015 JsonNode *pNode;
1016 const char *zPath;
1017 assert( argc==2 );
1018 zPath = (const char*)sqlite3_value_text(argv[1]);
1019 if( zPath==0 ) return;
1020 if( zPath[0]!='$' ) return;
1021 zPath++;
1022 if( jsonParse(&x, (const char*)sqlite3_value_text(argv[0])) ) return;
drh52216ad2015-08-18 02:28:03 +00001023 pNode = jsonLookup(&x, 0, zPath, 0);
drh987eb1f2015-08-17 15:17:37 +00001024 if( pNode ){
drhd0960592015-08-17 21:22:32 +00001025 jsonReturn(pNode, context, 0);
drh987eb1f2015-08-17 15:17:37 +00001026 }
drh505ad2c2015-08-21 17:33:11 +00001027 jsonParseReset(&x);
drh987eb1f2015-08-17 15:17:37 +00001028}
1029
1030/*
1031** Implementation of the json_object(NAME,VALUE,...) function. Return a JSON
1032** object that contains all name/value given in arguments. Or if any name
1033** is not a string or if any value is a BLOB, throw an error.
1034*/
1035static void jsonObjectFunc(
1036 sqlite3_context *context,
1037 int argc,
1038 sqlite3_value **argv
1039){
1040 int i;
drh505ad2c2015-08-21 17:33:11 +00001041 JsonString jx;
drh987eb1f2015-08-17 15:17:37 +00001042 const char *z;
1043 u32 n;
1044
1045 if( argc&1 ){
1046 sqlite3_result_error(context, "json_object() requires an even number "
1047 "of arguments", -1);
1048 return;
1049 }
1050 jsonInit(&jx, context);
drhd0960592015-08-17 21:22:32 +00001051 jsonAppendChar(&jx, '{');
drh987eb1f2015-08-17 15:17:37 +00001052 for(i=0; i<argc; i+=2){
drh987eb1f2015-08-17 15:17:37 +00001053 if( sqlite3_value_type(argv[i])!=SQLITE_TEXT ){
1054 sqlite3_result_error(context, "json_object() labels must be TEXT", -1);
1055 jsonZero(&jx);
1056 return;
1057 }
drhd0960592015-08-17 21:22:32 +00001058 jsonAppendSeparator(&jx);
drh987eb1f2015-08-17 15:17:37 +00001059 z = (const char*)sqlite3_value_text(argv[i]);
1060 n = (u32)sqlite3_value_bytes(argv[i]);
1061 jsonAppendString(&jx, z, n);
drhd0960592015-08-17 21:22:32 +00001062 jsonAppendChar(&jx, ':');
1063 jsonAppendValue(&jx, argv[i+1]);
drh987eb1f2015-08-17 15:17:37 +00001064 }
drhd0960592015-08-17 21:22:32 +00001065 jsonAppendChar(&jx, '}');
drh987eb1f2015-08-17 15:17:37 +00001066 jsonResult(&jx);
1067}
1068
1069
1070/*
drh301eecc2015-08-17 20:14:19 +00001071** json_remove(JSON, PATH, ...)
1072**
1073** Remove the named elements from JSON and return the result. Ill-formed
1074** PATH arguments are silently ignored. If JSON is ill-formed, then NULL
1075** is returned.
1076*/
1077static void jsonRemoveFunc(
1078 sqlite3_context *context,
1079 int argc,
1080 sqlite3_value **argv
1081){
1082 JsonParse x; /* The parse */
1083 JsonNode *pNode;
1084 const char *zPath;
1085 u32 i;
1086
1087 if( argc<1 ) return;
1088 if( jsonParse(&x, (const char*)sqlite3_value_text(argv[0])) ) return;
1089 if( x.nNode ){
1090 for(i=1; i<argc; i++){
1091 zPath = (const char*)sqlite3_value_text(argv[i]);
1092 if( zPath==0 ) continue;
1093 if( zPath[0]!='$' ) continue;
drh52216ad2015-08-18 02:28:03 +00001094 pNode = jsonLookup(&x, 0, &zPath[1], 0);
drh301eecc2015-08-17 20:14:19 +00001095 if( pNode ) pNode->jnFlags |= JNODE_REMOVE;
1096 }
1097 if( (x.aNode[0].jnFlags & JNODE_REMOVE)==0 ){
drhd0960592015-08-17 21:22:32 +00001098 jsonReturn(x.aNode, context, 0);
1099 }
1100 }
drh505ad2c2015-08-21 17:33:11 +00001101 jsonParseReset(&x);
drhd0960592015-08-17 21:22:32 +00001102}
1103
1104/*
1105** json_replace(JSON, PATH, VALUE, ...)
1106**
1107** Replace the value at PATH with VALUE. If PATH does not already exist,
1108** this routine is a no-op. If JSON is ill-formed, return NULL.
1109*/
1110static void jsonReplaceFunc(
1111 sqlite3_context *context,
1112 int argc,
1113 sqlite3_value **argv
1114){
1115 JsonParse x; /* The parse */
1116 JsonNode *pNode;
1117 const char *zPath;
1118 u32 i;
1119
1120 if( argc<1 ) return;
1121 if( (argc&1)==0 ) {
1122 sqlite3_result_error(context,
1123 "json_replace() needs an odd number of arguments", -1);
1124 return;
1125 }
1126 if( jsonParse(&x, (const char*)sqlite3_value_text(argv[0])) ) return;
1127 if( x.nNode ){
1128 for(i=1; i<argc; i+=2){
1129 zPath = (const char*)sqlite3_value_text(argv[i]);
1130 if( zPath==0 ) continue;
1131 if( zPath[0]!='$' ) continue;
drh52216ad2015-08-18 02:28:03 +00001132 pNode = jsonLookup(&x, 0, &zPath[1], 0);
drhd0960592015-08-17 21:22:32 +00001133 if( pNode ){
1134 pNode->jnFlags |= JNODE_REPLACE;
1135 pNode->iVal = i+1;
1136 }
1137 }
1138 if( x.aNode[0].jnFlags & JNODE_REPLACE ){
1139 sqlite3_result_value(context, argv[x.aNode[0].iVal]);
1140 }else{
1141 jsonReturn(x.aNode, context, argv);
drh301eecc2015-08-17 20:14:19 +00001142 }
1143 }
drh505ad2c2015-08-21 17:33:11 +00001144 jsonParseReset(&x);
drh301eecc2015-08-17 20:14:19 +00001145}
drh505ad2c2015-08-21 17:33:11 +00001146
drh52216ad2015-08-18 02:28:03 +00001147/*
1148** json_set(JSON, PATH, VALUE, ...)
1149**
1150** Set the value at PATH to VALUE. Create the PATH if it does not already
1151** exist. Overwrite existing values that do exist.
1152** If JSON is ill-formed, return NULL.
1153**
1154** json_insert(JSON, PATH, VALUE, ...)
1155**
1156** Create PATH and initialize it to VALUE. If PATH already exists, this
1157** routine is a no-op. If JSON is ill-formed, return NULL.
1158*/
1159static void jsonSetFunc(
1160 sqlite3_context *context,
1161 int argc,
1162 sqlite3_value **argv
1163){
1164 JsonParse x; /* The parse */
1165 JsonNode *pNode;
1166 const char *zPath;
1167 u32 i;
1168 int bApnd;
1169 int bIsSet = *(int*)sqlite3_user_data(context);
1170
1171 if( argc<1 ) return;
1172 if( (argc&1)==0 ) {
1173 sqlite3_result_error(context,
1174 "json_set() needs an odd number of arguments", -1);
1175 return;
1176 }
1177 if( jsonParse(&x, (const char*)sqlite3_value_text(argv[0])) ) return;
1178 if( x.nNode ){
1179 for(i=1; i<argc; i+=2){
1180 zPath = (const char*)sqlite3_value_text(argv[i]);
1181 if( zPath==0 ) continue;
1182 if( zPath[0]!='$' ) continue;
1183 bApnd = 0;
1184 pNode = jsonLookup(&x, 0, &zPath[1], &bApnd);
1185 if( pNode && (bApnd || bIsSet) ){
1186 pNode->jnFlags |= JNODE_REPLACE;
1187 pNode->iVal = i+1;
1188 }
1189 }
1190 if( x.aNode[0].jnFlags & JNODE_REPLACE ){
1191 sqlite3_result_value(context, argv[x.aNode[0].iVal]);
1192 }else{
1193 jsonReturn(x.aNode, context, argv);
1194 }
1195 }
drh505ad2c2015-08-21 17:33:11 +00001196 jsonParseReset(&x);
drh52216ad2015-08-18 02:28:03 +00001197}
drh301eecc2015-08-17 20:14:19 +00001198
1199/*
drh987eb1f2015-08-17 15:17:37 +00001200** json_type(JSON)
1201** json_type(JSON, PATH)
1202**
1203** Return the top-level "type" of a JSON string. Return NULL if the
1204** input is not a well-formed JSON string.
1205*/
1206static void jsonTypeFunc(
1207 sqlite3_context *context,
1208 int argc,
1209 sqlite3_value **argv
1210){
1211 JsonParse x; /* The parse */
1212 const char *zPath;
1213
1214 if( argc==2 ){
1215 zPath = (const char*)sqlite3_value_text(argv[1]);
1216 if( zPath==0 ) return;
1217 if( zPath[0]!='$' ) return;
1218 zPath++;
1219 }else{
1220 zPath = 0;
1221 }
1222 if( jsonParse(&x, (const char*)sqlite3_value_text(argv[0])) ) return;
1223 if( x.nNode ){
1224 JsonNode *pNode = x.aNode;
drh52216ad2015-08-18 02:28:03 +00001225 if( zPath ) pNode = jsonLookup(&x, 0, zPath, 0);
drh987eb1f2015-08-17 15:17:37 +00001226 sqlite3_result_text(context, jsonType[pNode->eType], -1, SQLITE_STATIC);
1227 }
drh505ad2c2015-08-21 17:33:11 +00001228 jsonParseReset(&x);
drh987eb1f2015-08-17 15:17:37 +00001229}
drh5634cc02015-08-17 11:28:03 +00001230
drhcb6c6c62015-08-19 22:47:17 +00001231/****************************************************************************
1232** The json_each virtual table
1233****************************************************************************/
1234typedef struct JsonEachCursor JsonEachCursor;
1235struct JsonEachCursor {
1236 sqlite3_vtab_cursor base; /* Base class - must be first */
drh505ad2c2015-08-21 17:33:11 +00001237 u32 iRowid; /* The rowid */
1238 u32 i; /* Index in sParse.aNode[] of current row */
1239 u32 iEnd; /* EOF when i equals or exceeds this value */
1240 u8 eType; /* Type of top-level element */
1241 u8 bRecursive; /* True for json_tree(). False for json_each() */
1242 char *zJson; /* Input JSON */
1243 char *zPath; /* Path by which to filter zJson */
1244 JsonParse sParse; /* Parse of the input JSON */
drhcb6c6c62015-08-19 22:47:17 +00001245};
1246
1247/* Constructor for the json_each virtual table */
1248static int jsonEachConnect(
1249 sqlite3 *db,
1250 void *pAux,
1251 int argc, const char *const*argv,
1252 sqlite3_vtab **ppVtab,
1253 char **pzErr
1254){
1255 sqlite3_vtab *pNew;
drh505ad2c2015-08-21 17:33:11 +00001256 int rc;
drhcb6c6c62015-08-19 22:47:17 +00001257
1258/* Column numbers */
1259#define JEACH_KEY 0
1260#define JEACH_VALUE 1
drh505ad2c2015-08-21 17:33:11 +00001261#define JEACH_TYPE 2
1262#define JEACH_ATOM 3
1263#define JEACH_ID 4
1264#define JEACH_PARENT 5
1265#define JEACH_JSON 6
1266#define JEACH_PATH 7
drhcb6c6c62015-08-19 22:47:17 +00001267
drh505ad2c2015-08-21 17:33:11 +00001268 rc = sqlite3_declare_vtab(db,
1269 "CREATE TABLE x(key,value,type,atom,id,parent,json hidden,path hidden)");
1270 if( rc==SQLITE_OK ){
1271 pNew = *ppVtab = sqlite3_malloc( sizeof(*pNew) );
1272 if( pNew==0 ) return SQLITE_NOMEM;
1273 memset(pNew, 0, sizeof(*pNew));
1274 }
1275 return rc;
drhcb6c6c62015-08-19 22:47:17 +00001276}
1277
1278/* destructor for json_each virtual table */
1279static int jsonEachDisconnect(sqlite3_vtab *pVtab){
1280 sqlite3_free(pVtab);
1281 return SQLITE_OK;
1282}
1283
drh505ad2c2015-08-21 17:33:11 +00001284/* constructor for a JsonEachCursor object for json_each(). */
1285static int jsonEachOpenEach(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
drhcb6c6c62015-08-19 22:47:17 +00001286 JsonEachCursor *pCur;
1287 pCur = sqlite3_malloc( sizeof(*pCur) );
1288 if( pCur==0 ) return SQLITE_NOMEM;
1289 memset(pCur, 0, sizeof(*pCur));
1290 *ppCursor = &pCur->base;
1291 return SQLITE_OK;
1292}
1293
drh505ad2c2015-08-21 17:33:11 +00001294/* constructor for a JsonEachCursor object for json_tree(). */
1295static int jsonEachOpenTree(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
1296 int rc = jsonEachOpenEach(p, ppCursor);
1297 if( rc==SQLITE_OK ){
1298 JsonEachCursor *pCur = (JsonEachCursor*)*ppCursor;
1299 pCur->bRecursive = 1;
1300 }
1301 return rc;
1302}
1303
drhcb6c6c62015-08-19 22:47:17 +00001304/* Reset a JsonEachCursor back to its original state. Free any memory
1305** held. */
1306static void jsonEachCursorReset(JsonEachCursor *p){
1307 sqlite3_free(p->zJson);
1308 sqlite3_free(p->zPath);
drh505ad2c2015-08-21 17:33:11 +00001309 jsonParseReset(&p->sParse);
drhcb6c6c62015-08-19 22:47:17 +00001310 p->iRowid = 0;
1311 p->i = 0;
1312 p->iEnd = 0;
1313 p->eType = 0;
drhcb6c6c62015-08-19 22:47:17 +00001314 p->zJson = 0;
1315 p->zPath = 0;
1316}
1317
1318/* Destructor for a jsonEachCursor object */
1319static int jsonEachClose(sqlite3_vtab_cursor *cur){
1320 JsonEachCursor *p = (JsonEachCursor*)cur;
1321 jsonEachCursorReset(p);
1322 sqlite3_free(cur);
1323 return SQLITE_OK;
1324}
1325
1326/* Return TRUE if the jsonEachCursor object has been advanced off the end
1327** of the JSON object */
1328static int jsonEachEof(sqlite3_vtab_cursor *cur){
1329 JsonEachCursor *p = (JsonEachCursor*)cur;
1330 return p->i >= p->iEnd;
1331}
1332
drh505ad2c2015-08-21 17:33:11 +00001333/* Advance the cursor to the next element for json_tree() */
1334static int jsonEachNextTree(sqlite3_vtab_cursor *cur){
1335 JsonEachCursor *p = (JsonEachCursor*)cur;
1336 if( p->i==0 ){
1337 p->i = 1;
1338 }else if( p->sParse.aNode[p->sParse.aUp[p->i]].eType==JSON_OBJECT ){
1339 p->i += 2;
1340 }else{
1341 p->i++;
1342 }
1343 p->iRowid++;
1344 if( p->i<p->sParse.nNode ){
1345 JsonNode *pUp = &p->sParse.aNode[p->sParse.aUp[p->i]];
1346 p->eType = pUp->eType;
1347 if( pUp->eType==JSON_ARRAY ) pUp->u.iKey++;
1348 if( p->sParse.aNode[p->i].eType==JSON_ARRAY ){
1349 p->sParse.aNode[p->i].u.iKey = 0;
1350 }
1351 }
1352 return SQLITE_OK;
1353}
1354
1355/* Advance the cursor to the next element for json_each() */
1356static int jsonEachNextEach(sqlite3_vtab_cursor *cur){
drhcb6c6c62015-08-19 22:47:17 +00001357 JsonEachCursor *p = (JsonEachCursor*)cur;
1358 switch( p->eType ){
1359 case JSON_ARRAY: {
drh505ad2c2015-08-21 17:33:11 +00001360 p->i += jsonNodeSize(&p->sParse.aNode[p->i]);
drhcb6c6c62015-08-19 22:47:17 +00001361 p->iRowid++;
1362 break;
1363 }
1364 case JSON_OBJECT: {
drh505ad2c2015-08-21 17:33:11 +00001365 p->i += 1 + jsonNodeSize(&p->sParse.aNode[p->i+1]);
drhcb6c6c62015-08-19 22:47:17 +00001366 p->iRowid++;
1367 break;
1368 }
1369 default: {
1370 p->i = p->iEnd;
1371 break;
1372 }
1373 }
1374 return SQLITE_OK;
1375}
1376
1377/* Return the value of a column */
1378static int jsonEachColumn(
1379 sqlite3_vtab_cursor *cur, /* The cursor */
1380 sqlite3_context *ctx, /* First argument to sqlite3_result_...() */
1381 int i /* Which column to return */
1382){
1383 JsonEachCursor *p = (JsonEachCursor*)cur;
drh505ad2c2015-08-21 17:33:11 +00001384 JsonNode *pThis = &p->sParse.aNode[p->i];
drhcb6c6c62015-08-19 22:47:17 +00001385 switch( i ){
1386 case JEACH_KEY: {
1387 if( p->eType==JSON_OBJECT ){
drh505ad2c2015-08-21 17:33:11 +00001388 jsonReturn(pThis, ctx, 0);
1389 }else if( p->eType==JSON_ARRAY ){
1390 u32 iKey;
1391 if( p->bRecursive ){
1392 if( p->iRowid==0 ) break;
1393 iKey = p->sParse.aNode[p->sParse.aUp[p->i]].u.iKey - 1;
1394 }else{
1395 iKey = p->iRowid;
1396 }
1397 sqlite3_result_int64(ctx, iKey);
drhcb6c6c62015-08-19 22:47:17 +00001398 }
1399 break;
1400 }
1401 case JEACH_VALUE: {
drh505ad2c2015-08-21 17:33:11 +00001402 if( p->eType==JSON_OBJECT ) pThis++;
1403 jsonReturn(pThis, ctx, 0);
1404 break;
1405 }
1406 case JEACH_TYPE: {
1407 if( p->eType==JSON_OBJECT ) pThis++;
1408 sqlite3_result_text(ctx, jsonType[pThis->eType], -1, SQLITE_STATIC);
1409 break;
1410 }
1411 case JEACH_ATOM: {
1412 if( p->eType==JSON_OBJECT ) pThis++;
1413 if( pThis->eType>=JSON_ARRAY ) break;
1414 jsonReturn(pThis, ctx, 0);
1415 break;
1416 }
1417 case JEACH_ID: {
1418 sqlite3_result_int64(ctx, p->i + (p->eType==JSON_OBJECT));
1419 break;
1420 }
1421 case JEACH_PARENT: {
1422 if( p->i>0 && p->bRecursive ){
1423 sqlite3_result_int64(ctx, p->sParse.aUp[p->i]);
drhcb6c6c62015-08-19 22:47:17 +00001424 }
1425 break;
1426 }
1427 case JEACH_PATH: {
1428 const char *zPath = p->zPath;
1429 if( zPath==0 ) zPath = "$";
1430 sqlite3_result_text(ctx, zPath, -1, SQLITE_STATIC);
1431 break;
1432 }
1433 default: {
drh505ad2c2015-08-21 17:33:11 +00001434 assert( i==JEACH_JSON );
drhcb6c6c62015-08-19 22:47:17 +00001435 sqlite3_result_text(ctx, p->sParse.zJson, -1, SQLITE_STATIC);
1436 break;
1437 }
1438 }
1439 return SQLITE_OK;
1440}
1441
1442/* Return the current rowid value */
1443static int jsonEachRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){
1444 JsonEachCursor *p = (JsonEachCursor*)cur;
1445 *pRowid = p->iRowid;
1446 return SQLITE_OK;
1447}
1448
1449/* The query strategy is to look for an equality constraint on the json
1450** column. Without such a constraint, the table cannot operate. idxNum is
1451** 1 if the constraint is found, 3 if the constraint and zPath are found,
1452** and 0 otherwise.
1453*/
1454static int jsonEachBestIndex(
1455 sqlite3_vtab *tab,
1456 sqlite3_index_info *pIdxInfo
1457){
1458 int i;
1459 int jsonIdx = -1;
1460 int pathIdx = -1;
1461 const struct sqlite3_index_constraint *pConstraint;
1462 pConstraint = pIdxInfo->aConstraint;
1463 for(i=0; i<pIdxInfo->nConstraint; i++, pConstraint++){
1464 if( pConstraint->usable==0 ) continue;
1465 if( pConstraint->op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue;
1466 switch( pConstraint->iColumn ){
1467 case JEACH_JSON: jsonIdx = i; break;
1468 case JEACH_PATH: pathIdx = i; break;
1469 default: /* no-op */ break;
1470 }
1471 }
1472 if( jsonIdx<0 ){
1473 pIdxInfo->idxNum = 0;
drh505ad2c2015-08-21 17:33:11 +00001474 pIdxInfo->estimatedCost = 1e99;
drhcb6c6c62015-08-19 22:47:17 +00001475 }else{
drh505ad2c2015-08-21 17:33:11 +00001476 pIdxInfo->estimatedCost = 1.0;
drhcb6c6c62015-08-19 22:47:17 +00001477 pIdxInfo->aConstraintUsage[jsonIdx].argvIndex = 1;
1478 pIdxInfo->aConstraintUsage[jsonIdx].omit = 1;
1479 if( pathIdx<0 ){
1480 pIdxInfo->idxNum = 1;
1481 }else{
1482 pIdxInfo->aConstraintUsage[pathIdx].argvIndex = 2;
1483 pIdxInfo->aConstraintUsage[pathIdx].omit = 1;
1484 pIdxInfo->idxNum = 3;
1485 }
1486 }
1487 return SQLITE_OK;
1488}
1489
1490/* Start a search on a new JSON string */
1491static int jsonEachFilter(
1492 sqlite3_vtab_cursor *cur,
1493 int idxNum, const char *idxStr,
1494 int argc, sqlite3_value **argv
1495){
1496 JsonEachCursor *p = (JsonEachCursor*)cur;
1497 const char *z;
1498 const char *zPath;
1499 sqlite3_int64 n;
1500
1501 jsonEachCursorReset(p);
1502 if( idxNum==0 ) return SQLITE_OK;
1503 z = (const char*)sqlite3_value_text(argv[0]);
1504 if( z==0 ) return SQLITE_OK;
1505 if( idxNum&2 ){
1506 zPath = (const char*)sqlite3_value_text(argv[1]);
1507 if( zPath==0 || zPath[0]!='$' ) return SQLITE_OK;
1508 }
1509 n = sqlite3_value_bytes(argv[0]);
1510 p->zJson = sqlite3_malloc( n+1 );
1511 if( p->zJson==0 ) return SQLITE_NOMEM;
1512 memcpy(p->zJson, z, n+1);
drh505ad2c2015-08-21 17:33:11 +00001513 if( jsonParse(&p->sParse, p->zJson)
1514 || (p->bRecursive && jsonParseFindParents(&p->sParse))
1515 ){
drhcb6c6c62015-08-19 22:47:17 +00001516 jsonEachCursorReset(p);
1517 }else{
1518 JsonNode *pNode;
1519 if( idxNum==3 ){
1520 n = sqlite3_value_bytes(argv[1]);
1521 p->zPath = sqlite3_malloc( n+1 );
1522 if( p->zPath==0 ) return SQLITE_NOMEM;
1523 memcpy(p->zPath, zPath, n+1);
1524 pNode = jsonLookup(&p->sParse, 0, p->zPath+1, 0);
1525 if( pNode==0 ){
1526 jsonEachCursorReset(p);
1527 return SQLITE_OK;
1528 }
1529 }else{
1530 pNode = p->sParse.aNode;
1531 }
1532 p->i = (int)(pNode - p->sParse.aNode);
1533 p->eType = pNode->eType;
1534 if( p->eType>=JSON_ARRAY ){
1535 p->i++;
1536 p->iEnd = p->i + pNode->n;
1537 }else{
1538 p->iEnd = p->i+1;
1539 }
1540 }
1541 return SQLITE_OK;
1542}
1543
1544/* The methods of the json_each virtual table */
1545static sqlite3_module jsonEachModule = {
1546 0, /* iVersion */
1547 0, /* xCreate */
1548 jsonEachConnect, /* xConnect */
1549 jsonEachBestIndex, /* xBestIndex */
1550 jsonEachDisconnect, /* xDisconnect */
1551 0, /* xDestroy */
drh505ad2c2015-08-21 17:33:11 +00001552 jsonEachOpenEach, /* xOpen - open a cursor */
drhcb6c6c62015-08-19 22:47:17 +00001553 jsonEachClose, /* xClose - close a cursor */
1554 jsonEachFilter, /* xFilter - configure scan constraints */
drh505ad2c2015-08-21 17:33:11 +00001555 jsonEachNextEach, /* xNext - advance a cursor */
drhcb6c6c62015-08-19 22:47:17 +00001556 jsonEachEof, /* xEof - check for end of scan */
1557 jsonEachColumn, /* xColumn - read data */
1558 jsonEachRowid, /* xRowid - read data */
1559 0, /* xUpdate */
1560 0, /* xBegin */
1561 0, /* xSync */
1562 0, /* xCommit */
1563 0, /* xRollback */
1564 0, /* xFindMethod */
1565 0, /* xRename */
1566};
1567
drh505ad2c2015-08-21 17:33:11 +00001568/* The methods of the json_tree virtual table. */
1569static sqlite3_module jsonTreeModule = {
1570 0, /* iVersion */
1571 0, /* xCreate */
1572 jsonEachConnect, /* xConnect */
1573 jsonEachBestIndex, /* xBestIndex */
1574 jsonEachDisconnect, /* xDisconnect */
1575 0, /* xDestroy */
1576 jsonEachOpenTree, /* xOpen - open a cursor */
1577 jsonEachClose, /* xClose - close a cursor */
1578 jsonEachFilter, /* xFilter - configure scan constraints */
1579 jsonEachNextTree, /* xNext - advance a cursor */
1580 jsonEachEof, /* xEof - check for end of scan */
1581 jsonEachColumn, /* xColumn - read data */
1582 jsonEachRowid, /* xRowid - read data */
1583 0, /* xUpdate */
1584 0, /* xBegin */
1585 0, /* xSync */
1586 0, /* xCommit */
1587 0, /* xRollback */
1588 0, /* xFindMethod */
1589 0, /* xRename */
1590};
1591
1592/****************************************************************************
1593** The following routine is the only publically visible identifier in this
1594** file. Call the following routine in order to register the various SQL
1595** functions and the virtual table implemented by this file.
1596****************************************************************************/
drhcb6c6c62015-08-19 22:47:17 +00001597
drh5fa5c102015-08-12 16:49:40 +00001598#ifdef _WIN32
1599__declspec(dllexport)
1600#endif
1601int sqlite3_json_init(
1602 sqlite3 *db,
1603 char **pzErrMsg,
1604 const sqlite3_api_routines *pApi
1605){
1606 int rc = SQLITE_OK;
1607 int i;
1608 static const struct {
1609 const char *zName;
1610 int nArg;
drh52216ad2015-08-18 02:28:03 +00001611 int flag;
drh5fa5c102015-08-12 16:49:40 +00001612 void (*xFunc)(sqlite3_context*,int,sqlite3_value**);
1613 } aFunc[] = {
drh52216ad2015-08-18 02:28:03 +00001614 { "json_array", -1, 0, jsonArrayFunc },
1615 { "json_array_length", 1, 0, jsonArrayLengthFunc },
1616 { "json_array_length", 2, 0, jsonArrayLengthFunc },
1617 { "json_extract", 2, 0, jsonExtractFunc },
1618 { "json_insert", -1, 0, jsonSetFunc },
1619 { "json_object", -1, 0, jsonObjectFunc },
1620 { "json_remove", -1, 0, jsonRemoveFunc },
1621 { "json_replace", -1, 0, jsonReplaceFunc },
1622 { "json_set", -1, 1, jsonSetFunc },
1623 { "json_type", 1, 0, jsonTypeFunc },
1624 { "json_type", 2, 0, jsonTypeFunc },
drh987eb1f2015-08-17 15:17:37 +00001625
drh301eecc2015-08-17 20:14:19 +00001626#if SQLITE_DEBUG
drh987eb1f2015-08-17 15:17:37 +00001627 /* DEBUG and TESTING functions */
drh52216ad2015-08-18 02:28:03 +00001628 { "json_parse", 1, 0, jsonParseFunc },
1629 { "json_test1", 1, 0, jsonTest1Func },
1630 { "json_nodecount", 1, 0, jsonNodeCountFunc },
drh301eecc2015-08-17 20:14:19 +00001631#endif
drh5fa5c102015-08-12 16:49:40 +00001632 };
drh505ad2c2015-08-21 17:33:11 +00001633 static const struct {
1634 const char *zName;
1635 sqlite3_module *pModule;
1636 } aMod[] = {
1637 { "json_each", &jsonEachModule },
1638 { "json_tree", &jsonTreeModule },
1639 };
drh5fa5c102015-08-12 16:49:40 +00001640 SQLITE_EXTENSION_INIT2(pApi);
1641 (void)pzErrMsg; /* Unused parameter */
1642 for(i=0; i<sizeof(aFunc)/sizeof(aFunc[0]) && rc==SQLITE_OK; i++){
1643 rc = sqlite3_create_function(db, aFunc[i].zName, aFunc[i].nArg,
drh52216ad2015-08-18 02:28:03 +00001644 SQLITE_UTF8 | SQLITE_DETERMINISTIC,
1645 (void*)&aFunc[i].flag,
drh5fa5c102015-08-12 16:49:40 +00001646 aFunc[i].xFunc, 0, 0);
1647 }
drh505ad2c2015-08-21 17:33:11 +00001648 for(i=0; i<sizeof(aMod)/sizeof(aMod[0]) && rc==SQLITE_OK; i++){
1649 rc = sqlite3_create_module(db, aMod[i].zName, aMod[i].pModule, 0);
drhcb6c6c62015-08-19 22:47:17 +00001650 }
drh5fa5c102015-08-12 16:49:40 +00001651 return rc;
1652}