19dbf96bdSdrh /*
29dbf96bdSdrh ** 2015-08-12
39dbf96bdSdrh **
49dbf96bdSdrh ** The author disclaims copyright to this source code. In place of
59dbf96bdSdrh ** a legal notice, here is a blessing:
69dbf96bdSdrh **
79dbf96bdSdrh ** May you do good and not evil.
89dbf96bdSdrh ** May you find forgiveness for yourself and forgive others.
99dbf96bdSdrh ** May you share freely, never taking more than you give.
109dbf96bdSdrh **
119dbf96bdSdrh ******************************************************************************
129dbf96bdSdrh **
139dbf96bdSdrh ** This SQLite JSON functions.
149dbf96bdSdrh **
159dbf96bdSdrh ** This file began as an extension in ext/misc/json1.c in 2015. That
169dbf96bdSdrh ** extension proved so useful that it has now been moved into the core.
179dbf96bdSdrh **
189dbf96bdSdrh ** For the time being, all JSON is stored as pure text. (We might add
199dbf96bdSdrh ** a JSONB type in the future which stores a binary encoding of JSON in
209dbf96bdSdrh ** a BLOB, but there is no support for JSONB in the current implementation.
219dbf96bdSdrh ** This implementation parses JSON text at 250 MB/s, so it is hard to see
229dbf96bdSdrh ** how JSONB might improve on that.)
239dbf96bdSdrh */
249dbf96bdSdrh #ifndef SQLITE_OMIT_JSON
259dbf96bdSdrh #include "sqliteInt.h"
269dbf96bdSdrh
279dbf96bdSdrh /*
289dbf96bdSdrh ** Growing our own isspace() routine this way is twice as fast as
299dbf96bdSdrh ** the library isspace() function, resulting in a 7% overall performance
309dbf96bdSdrh ** increase for the parser. (Ubuntu14.10 gcc 4.8.4 x64 with -Os).
319dbf96bdSdrh */
329dbf96bdSdrh static const char jsonIsSpace[] = {
339dbf96bdSdrh 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0,
349dbf96bdSdrh 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
359dbf96bdSdrh 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
369dbf96bdSdrh 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
379dbf96bdSdrh 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
389dbf96bdSdrh 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
399dbf96bdSdrh 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
409dbf96bdSdrh 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
419dbf96bdSdrh 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
429dbf96bdSdrh 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
439dbf96bdSdrh 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
449dbf96bdSdrh 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
459dbf96bdSdrh 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
469dbf96bdSdrh 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
479dbf96bdSdrh 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
489dbf96bdSdrh 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
499dbf96bdSdrh };
509dbf96bdSdrh #define fast_isspace(x) (jsonIsSpace[(unsigned char)x])
519dbf96bdSdrh
529dbf96bdSdrh #if !defined(SQLITE_DEBUG) && !defined(SQLITE_COVERAGE_TEST)
539dbf96bdSdrh # define VVA(X)
549dbf96bdSdrh #else
559dbf96bdSdrh # define VVA(X) X
569dbf96bdSdrh #endif
579dbf96bdSdrh
589dbf96bdSdrh /* Objects */
599dbf96bdSdrh typedef struct JsonString JsonString;
609dbf96bdSdrh typedef struct JsonNode JsonNode;
619dbf96bdSdrh typedef struct JsonParse JsonParse;
629dbf96bdSdrh
639dbf96bdSdrh /* An instance of this object represents a JSON string
649dbf96bdSdrh ** under construction. Really, this is a generic string accumulator
659dbf96bdSdrh ** that can be and is used to create strings other than JSON.
669dbf96bdSdrh */
679dbf96bdSdrh struct JsonString {
689dbf96bdSdrh sqlite3_context *pCtx; /* Function context - put error messages here */
699dbf96bdSdrh char *zBuf; /* Append JSON content here */
709dbf96bdSdrh u64 nAlloc; /* Bytes of storage available in zBuf[] */
719dbf96bdSdrh u64 nUsed; /* Bytes of zBuf[] currently used */
729dbf96bdSdrh u8 bStatic; /* True if zBuf is static space */
739dbf96bdSdrh u8 bErr; /* True if an error has been encountered */
749dbf96bdSdrh char zSpace[100]; /* Initial static space */
759dbf96bdSdrh };
769dbf96bdSdrh
779dbf96bdSdrh /* JSON type values
789dbf96bdSdrh */
799dbf96bdSdrh #define JSON_NULL 0
809dbf96bdSdrh #define JSON_TRUE 1
819dbf96bdSdrh #define JSON_FALSE 2
829dbf96bdSdrh #define JSON_INT 3
839dbf96bdSdrh #define JSON_REAL 4
849dbf96bdSdrh #define JSON_STRING 5
859dbf96bdSdrh #define JSON_ARRAY 6
869dbf96bdSdrh #define JSON_OBJECT 7
879dbf96bdSdrh
889dbf96bdSdrh /* The "subtype" set for JSON values */
899dbf96bdSdrh #define JSON_SUBTYPE 74 /* Ascii for "J" */
909dbf96bdSdrh
919dbf96bdSdrh /*
929dbf96bdSdrh ** Names of the various JSON types:
939dbf96bdSdrh */
949dbf96bdSdrh static const char * const jsonType[] = {
959dbf96bdSdrh "null", "true", "false", "integer", "real", "text", "array", "object"
969dbf96bdSdrh };
979dbf96bdSdrh
989dbf96bdSdrh /* Bit values for the JsonNode.jnFlag field
999dbf96bdSdrh */
1009dbf96bdSdrh #define JNODE_RAW 0x01 /* Content is raw, not JSON encoded */
1019dbf96bdSdrh #define JNODE_ESCAPE 0x02 /* Content is text with \ escapes */
1029dbf96bdSdrh #define JNODE_REMOVE 0x04 /* Do not output */
1039dbf96bdSdrh #define JNODE_REPLACE 0x08 /* Replace with JsonNode.u.iReplace */
1049dbf96bdSdrh #define JNODE_PATCH 0x10 /* Patch with JsonNode.u.pPatch */
1059dbf96bdSdrh #define JNODE_APPEND 0x20 /* More ARRAY/OBJECT entries at u.iAppend */
1069dbf96bdSdrh #define JNODE_LABEL 0x40 /* Is a label of an object */
1079dbf96bdSdrh
1089dbf96bdSdrh
1099dbf96bdSdrh /* A single node of parsed JSON
1109dbf96bdSdrh */
1119dbf96bdSdrh struct JsonNode {
1129dbf96bdSdrh u8 eType; /* One of the JSON_ type values */
1139dbf96bdSdrh u8 jnFlags; /* JNODE flags */
1149dbf96bdSdrh u8 eU; /* Which union element to use */
1159dbf96bdSdrh u32 n; /* Bytes of content, or number of sub-nodes */
1169dbf96bdSdrh union {
1179dbf96bdSdrh const char *zJContent; /* 1: Content for INT, REAL, and STRING */
1189dbf96bdSdrh u32 iAppend; /* 2: More terms for ARRAY and OBJECT */
1199dbf96bdSdrh u32 iKey; /* 3: Key for ARRAY objects in json_tree() */
1209dbf96bdSdrh u32 iReplace; /* 4: Replacement content for JNODE_REPLACE */
1219dbf96bdSdrh JsonNode *pPatch; /* 5: Node chain of patch for JNODE_PATCH */
1229dbf96bdSdrh } u;
1239dbf96bdSdrh };
1249dbf96bdSdrh
1259dbf96bdSdrh /* A completely parsed JSON string
1269dbf96bdSdrh */
1279dbf96bdSdrh struct JsonParse {
1289dbf96bdSdrh u32 nNode; /* Number of slots of aNode[] used */
1299dbf96bdSdrh u32 nAlloc; /* Number of slots of aNode[] allocated */
1309dbf96bdSdrh JsonNode *aNode; /* Array of nodes containing the parse */
1319dbf96bdSdrh const char *zJson; /* Original JSON string */
1329dbf96bdSdrh u32 *aUp; /* Index of parent of each node */
1339dbf96bdSdrh u8 oom; /* Set to true if out of memory */
1349dbf96bdSdrh u8 nErr; /* Number of errors seen */
1359dbf96bdSdrh u16 iDepth; /* Nesting depth */
1369dbf96bdSdrh int nJson; /* Length of the zJson string in bytes */
1379dbf96bdSdrh u32 iHold; /* Replace cache line with the lowest iHold value */
1389dbf96bdSdrh };
1399dbf96bdSdrh
1409dbf96bdSdrh /*
1419dbf96bdSdrh ** Maximum nesting depth of JSON for this implementation.
1429dbf96bdSdrh **
1439dbf96bdSdrh ** This limit is needed to avoid a stack overflow in the recursive
1449dbf96bdSdrh ** descent parser. A depth of 2000 is far deeper than any sane JSON
1459dbf96bdSdrh ** should go.
1469dbf96bdSdrh */
1479dbf96bdSdrh #define JSON_MAX_DEPTH 2000
1489dbf96bdSdrh
1499dbf96bdSdrh /**************************************************************************
1509dbf96bdSdrh ** Utility routines for dealing with JsonString objects
1519dbf96bdSdrh **************************************************************************/
1529dbf96bdSdrh
1539dbf96bdSdrh /* Set the JsonString object to an empty string
1549dbf96bdSdrh */
jsonZero(JsonString * p)1559dbf96bdSdrh static void jsonZero(JsonString *p){
1569dbf96bdSdrh p->zBuf = p->zSpace;
1579dbf96bdSdrh p->nAlloc = sizeof(p->zSpace);
1589dbf96bdSdrh p->nUsed = 0;
1599dbf96bdSdrh p->bStatic = 1;
1609dbf96bdSdrh }
1619dbf96bdSdrh
1629dbf96bdSdrh /* Initialize the JsonString object
1639dbf96bdSdrh */
jsonInit(JsonString * p,sqlite3_context * pCtx)1649dbf96bdSdrh static void jsonInit(JsonString *p, sqlite3_context *pCtx){
1659dbf96bdSdrh p->pCtx = pCtx;
1669dbf96bdSdrh p->bErr = 0;
1679dbf96bdSdrh jsonZero(p);
1689dbf96bdSdrh }
1699dbf96bdSdrh
1709dbf96bdSdrh
1719dbf96bdSdrh /* Free all allocated memory and reset the JsonString object back to its
1729dbf96bdSdrh ** initial state.
1739dbf96bdSdrh */
jsonReset(JsonString * p)1749dbf96bdSdrh static void jsonReset(JsonString *p){
1759dbf96bdSdrh if( !p->bStatic ) sqlite3_free(p->zBuf);
1769dbf96bdSdrh jsonZero(p);
1779dbf96bdSdrh }
1789dbf96bdSdrh
1799dbf96bdSdrh
1809dbf96bdSdrh /* Report an out-of-memory (OOM) condition
1819dbf96bdSdrh */
jsonOom(JsonString * p)1829dbf96bdSdrh static void jsonOom(JsonString *p){
1839dbf96bdSdrh p->bErr = 1;
1849dbf96bdSdrh sqlite3_result_error_nomem(p->pCtx);
1859dbf96bdSdrh jsonReset(p);
1869dbf96bdSdrh }
1879dbf96bdSdrh
1889dbf96bdSdrh /* Enlarge pJson->zBuf so that it can hold at least N more bytes.
1899dbf96bdSdrh ** Return zero on success. Return non-zero on an OOM error
1909dbf96bdSdrh */
jsonGrow(JsonString * p,u32 N)1919dbf96bdSdrh static int jsonGrow(JsonString *p, u32 N){
1929dbf96bdSdrh u64 nTotal = N<p->nAlloc ? p->nAlloc*2 : p->nAlloc+N+10;
1939dbf96bdSdrh char *zNew;
1949dbf96bdSdrh if( p->bStatic ){
1959dbf96bdSdrh if( p->bErr ) return 1;
1969dbf96bdSdrh zNew = sqlite3_malloc64(nTotal);
1979dbf96bdSdrh if( zNew==0 ){
1989dbf96bdSdrh jsonOom(p);
1999dbf96bdSdrh return SQLITE_NOMEM;
2009dbf96bdSdrh }
2019dbf96bdSdrh memcpy(zNew, p->zBuf, (size_t)p->nUsed);
2029dbf96bdSdrh p->zBuf = zNew;
2039dbf96bdSdrh p->bStatic = 0;
2049dbf96bdSdrh }else{
2059dbf96bdSdrh zNew = sqlite3_realloc64(p->zBuf, nTotal);
2069dbf96bdSdrh if( zNew==0 ){
2079dbf96bdSdrh jsonOom(p);
2089dbf96bdSdrh return SQLITE_NOMEM;
2099dbf96bdSdrh }
2109dbf96bdSdrh p->zBuf = zNew;
2119dbf96bdSdrh }
2129dbf96bdSdrh p->nAlloc = nTotal;
2139dbf96bdSdrh return SQLITE_OK;
2149dbf96bdSdrh }
2159dbf96bdSdrh
2169dbf96bdSdrh /* Append N bytes from zIn onto the end of the JsonString string.
2179dbf96bdSdrh */
jsonAppendRaw(JsonString * p,const char * zIn,u32 N)2189dbf96bdSdrh static void jsonAppendRaw(JsonString *p, const char *zIn, u32 N){
2199dbf96bdSdrh if( N==0 ) return;
2209dbf96bdSdrh if( (N+p->nUsed >= p->nAlloc) && jsonGrow(p,N)!=0 ) return;
2219dbf96bdSdrh memcpy(p->zBuf+p->nUsed, zIn, N);
2229dbf96bdSdrh p->nUsed += N;
2239dbf96bdSdrh }
2249dbf96bdSdrh
2259dbf96bdSdrh /* Append formatted text (not to exceed N bytes) to the JsonString.
2269dbf96bdSdrh */
jsonPrintf(int N,JsonString * p,const char * zFormat,...)2279dbf96bdSdrh static void jsonPrintf(int N, JsonString *p, const char *zFormat, ...){
2289dbf96bdSdrh va_list ap;
2299dbf96bdSdrh if( (p->nUsed + N >= p->nAlloc) && jsonGrow(p, N) ) return;
2309dbf96bdSdrh va_start(ap, zFormat);
2319dbf96bdSdrh sqlite3_vsnprintf(N, p->zBuf+p->nUsed, zFormat, ap);
2329dbf96bdSdrh va_end(ap);
2339dbf96bdSdrh p->nUsed += (int)strlen(p->zBuf+p->nUsed);
2349dbf96bdSdrh }
2359dbf96bdSdrh
2369dbf96bdSdrh /* Append a single character
2379dbf96bdSdrh */
jsonAppendChar(JsonString * p,char c)2389dbf96bdSdrh static void jsonAppendChar(JsonString *p, char c){
2399dbf96bdSdrh if( p->nUsed>=p->nAlloc && jsonGrow(p,1)!=0 ) return;
2409dbf96bdSdrh p->zBuf[p->nUsed++] = c;
2419dbf96bdSdrh }
2429dbf96bdSdrh
2439dbf96bdSdrh /* Append a comma separator to the output buffer, if the previous
2449dbf96bdSdrh ** character is not '[' or '{'.
2459dbf96bdSdrh */
jsonAppendSeparator(JsonString * p)2469dbf96bdSdrh static void jsonAppendSeparator(JsonString *p){
2479dbf96bdSdrh char c;
2489dbf96bdSdrh if( p->nUsed==0 ) return;
2499dbf96bdSdrh c = p->zBuf[p->nUsed-1];
2509dbf96bdSdrh if( c!='[' && c!='{' ) jsonAppendChar(p, ',');
2519dbf96bdSdrh }
2529dbf96bdSdrh
2539dbf96bdSdrh /* Append the N-byte string in zIn to the end of the JsonString string
2549dbf96bdSdrh ** under construction. Enclose the string in "..." and escape
2559dbf96bdSdrh ** any double-quotes or backslash characters contained within the
2569dbf96bdSdrh ** string.
2579dbf96bdSdrh */
jsonAppendString(JsonString * p,const char * zIn,u32 N)2589dbf96bdSdrh static void jsonAppendString(JsonString *p, const char *zIn, u32 N){
2599dbf96bdSdrh u32 i;
2609dbf96bdSdrh if( zIn==0 || ((N+p->nUsed+2 >= p->nAlloc) && jsonGrow(p,N+2)!=0) ) return;
2619dbf96bdSdrh p->zBuf[p->nUsed++] = '"';
2629dbf96bdSdrh for(i=0; i<N; i++){
2639dbf96bdSdrh unsigned char c = ((unsigned const char*)zIn)[i];
2649dbf96bdSdrh if( c=='"' || c=='\\' ){
2659dbf96bdSdrh json_simple_escape:
2669dbf96bdSdrh if( (p->nUsed+N+3-i > p->nAlloc) && jsonGrow(p,N+3-i)!=0 ) return;
2679dbf96bdSdrh p->zBuf[p->nUsed++] = '\\';
2689dbf96bdSdrh }else if( c<=0x1f ){
2699dbf96bdSdrh static const char aSpecial[] = {
2709dbf96bdSdrh 0, 0, 0, 0, 0, 0, 0, 0, 'b', 't', 'n', 0, 'f', 'r', 0, 0,
2719dbf96bdSdrh 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
2729dbf96bdSdrh };
2739dbf96bdSdrh assert( sizeof(aSpecial)==32 );
2749dbf96bdSdrh assert( aSpecial['\b']=='b' );
2759dbf96bdSdrh assert( aSpecial['\f']=='f' );
2769dbf96bdSdrh assert( aSpecial['\n']=='n' );
2779dbf96bdSdrh assert( aSpecial['\r']=='r' );
2789dbf96bdSdrh assert( aSpecial['\t']=='t' );
2799dbf96bdSdrh if( aSpecial[c] ){
2809dbf96bdSdrh c = aSpecial[c];
2819dbf96bdSdrh goto json_simple_escape;
2829dbf96bdSdrh }
2839dbf96bdSdrh if( (p->nUsed+N+7+i > p->nAlloc) && jsonGrow(p,N+7-i)!=0 ) return;
2849dbf96bdSdrh p->zBuf[p->nUsed++] = '\\';
2859dbf96bdSdrh p->zBuf[p->nUsed++] = 'u';
2869dbf96bdSdrh p->zBuf[p->nUsed++] = '0';
2879dbf96bdSdrh p->zBuf[p->nUsed++] = '0';
2889dbf96bdSdrh p->zBuf[p->nUsed++] = '0' + (c>>4);
2899dbf96bdSdrh c = "0123456789abcdef"[c&0xf];
2909dbf96bdSdrh }
2919dbf96bdSdrh p->zBuf[p->nUsed++] = c;
2929dbf96bdSdrh }
2939dbf96bdSdrh p->zBuf[p->nUsed++] = '"';
2949dbf96bdSdrh assert( p->nUsed<p->nAlloc );
2959dbf96bdSdrh }
2969dbf96bdSdrh
2979dbf96bdSdrh /*
2989dbf96bdSdrh ** Append a function parameter value to the JSON string under
2999dbf96bdSdrh ** construction.
3009dbf96bdSdrh */
jsonAppendValue(JsonString * p,sqlite3_value * pValue)3019dbf96bdSdrh static void jsonAppendValue(
3029dbf96bdSdrh JsonString *p, /* Append to this JSON string */
3039dbf96bdSdrh sqlite3_value *pValue /* Value to append */
3049dbf96bdSdrh ){
3059dbf96bdSdrh switch( sqlite3_value_type(pValue) ){
3069dbf96bdSdrh case SQLITE_NULL: {
3079dbf96bdSdrh jsonAppendRaw(p, "null", 4);
3089dbf96bdSdrh break;
3099dbf96bdSdrh }
3109dbf96bdSdrh case SQLITE_INTEGER:
3119dbf96bdSdrh case SQLITE_FLOAT: {
3129dbf96bdSdrh const char *z = (const char*)sqlite3_value_text(pValue);
3139dbf96bdSdrh u32 n = (u32)sqlite3_value_bytes(pValue);
3149dbf96bdSdrh jsonAppendRaw(p, z, n);
3159dbf96bdSdrh break;
3169dbf96bdSdrh }
3179dbf96bdSdrh case SQLITE_TEXT: {
3189dbf96bdSdrh const char *z = (const char*)sqlite3_value_text(pValue);
3199dbf96bdSdrh u32 n = (u32)sqlite3_value_bytes(pValue);
3209dbf96bdSdrh if( sqlite3_value_subtype(pValue)==JSON_SUBTYPE ){
3219dbf96bdSdrh jsonAppendRaw(p, z, n);
3229dbf96bdSdrh }else{
3239dbf96bdSdrh jsonAppendString(p, z, n);
3249dbf96bdSdrh }
3259dbf96bdSdrh break;
3269dbf96bdSdrh }
3279dbf96bdSdrh default: {
3289dbf96bdSdrh if( p->bErr==0 ){
3299dbf96bdSdrh sqlite3_result_error(p->pCtx, "JSON cannot hold BLOB values", -1);
3309dbf96bdSdrh p->bErr = 2;
3319dbf96bdSdrh jsonReset(p);
3329dbf96bdSdrh }
3339dbf96bdSdrh break;
3349dbf96bdSdrh }
3359dbf96bdSdrh }
3369dbf96bdSdrh }
3379dbf96bdSdrh
3389dbf96bdSdrh
3399dbf96bdSdrh /* Make the JSON in p the result of the SQL function.
3409dbf96bdSdrh */
jsonResult(JsonString * p)3419dbf96bdSdrh static void jsonResult(JsonString *p){
3429dbf96bdSdrh if( p->bErr==0 ){
3439dbf96bdSdrh sqlite3_result_text64(p->pCtx, p->zBuf, p->nUsed,
3449dbf96bdSdrh p->bStatic ? SQLITE_TRANSIENT : sqlite3_free,
3459dbf96bdSdrh SQLITE_UTF8);
3469dbf96bdSdrh jsonZero(p);
3479dbf96bdSdrh }
3489dbf96bdSdrh assert( p->bStatic );
3499dbf96bdSdrh }
3509dbf96bdSdrh
3519dbf96bdSdrh /**************************************************************************
3529dbf96bdSdrh ** Utility routines for dealing with JsonNode and JsonParse objects
3539dbf96bdSdrh **************************************************************************/
3549dbf96bdSdrh
3559dbf96bdSdrh /*
3569dbf96bdSdrh ** Return the number of consecutive JsonNode slots need to represent
3579dbf96bdSdrh ** the parsed JSON at pNode. The minimum answer is 1. For ARRAY and
3589dbf96bdSdrh ** OBJECT types, the number might be larger.
3599dbf96bdSdrh **
3609dbf96bdSdrh ** Appended elements are not counted. The value returned is the number
3619dbf96bdSdrh ** by which the JsonNode counter should increment in order to go to the
3629dbf96bdSdrh ** next peer value.
3639dbf96bdSdrh */
jsonNodeSize(JsonNode * pNode)3649dbf96bdSdrh static u32 jsonNodeSize(JsonNode *pNode){
3659dbf96bdSdrh return pNode->eType>=JSON_ARRAY ? pNode->n+1 : 1;
3669dbf96bdSdrh }
3679dbf96bdSdrh
3689dbf96bdSdrh /*
3699dbf96bdSdrh ** Reclaim all memory allocated by a JsonParse object. But do not
3709dbf96bdSdrh ** delete the JsonParse object itself.
3719dbf96bdSdrh */
jsonParseReset(JsonParse * pParse)3729dbf96bdSdrh static void jsonParseReset(JsonParse *pParse){
3739dbf96bdSdrh sqlite3_free(pParse->aNode);
3749dbf96bdSdrh pParse->aNode = 0;
3759dbf96bdSdrh pParse->nNode = 0;
3769dbf96bdSdrh pParse->nAlloc = 0;
3779dbf96bdSdrh sqlite3_free(pParse->aUp);
3789dbf96bdSdrh pParse->aUp = 0;
3799dbf96bdSdrh }
3809dbf96bdSdrh
3819dbf96bdSdrh /*
3829dbf96bdSdrh ** Free a JsonParse object that was obtained from sqlite3_malloc().
3839dbf96bdSdrh */
jsonParseFree(JsonParse * pParse)3849dbf96bdSdrh static void jsonParseFree(JsonParse *pParse){
3859dbf96bdSdrh jsonParseReset(pParse);
3869dbf96bdSdrh sqlite3_free(pParse);
3879dbf96bdSdrh }
3889dbf96bdSdrh
3899dbf96bdSdrh /*
3909dbf96bdSdrh ** Convert the JsonNode pNode into a pure JSON string and
3919dbf96bdSdrh ** append to pOut. Subsubstructure is also included. Return
3929dbf96bdSdrh ** the number of JsonNode objects that are encoded.
3939dbf96bdSdrh */
jsonRenderNode(JsonNode * pNode,JsonString * pOut,sqlite3_value ** aReplace)3949dbf96bdSdrh static void jsonRenderNode(
3959dbf96bdSdrh JsonNode *pNode, /* The node to render */
3969dbf96bdSdrh JsonString *pOut, /* Write JSON here */
3979dbf96bdSdrh sqlite3_value **aReplace /* Replacement values */
3989dbf96bdSdrh ){
3999dbf96bdSdrh assert( pNode!=0 );
4009dbf96bdSdrh if( pNode->jnFlags & (JNODE_REPLACE|JNODE_PATCH) ){
4019dbf96bdSdrh if( (pNode->jnFlags & JNODE_REPLACE)!=0 && ALWAYS(aReplace!=0) ){
4029dbf96bdSdrh assert( pNode->eU==4 );
4039dbf96bdSdrh jsonAppendValue(pOut, aReplace[pNode->u.iReplace]);
4049dbf96bdSdrh return;
4059dbf96bdSdrh }
4069dbf96bdSdrh assert( pNode->eU==5 );
4079dbf96bdSdrh pNode = pNode->u.pPatch;
4089dbf96bdSdrh }
4099dbf96bdSdrh switch( pNode->eType ){
4109dbf96bdSdrh default: {
4119dbf96bdSdrh assert( pNode->eType==JSON_NULL );
4129dbf96bdSdrh jsonAppendRaw(pOut, "null", 4);
4139dbf96bdSdrh break;
4149dbf96bdSdrh }
4159dbf96bdSdrh case JSON_TRUE: {
4169dbf96bdSdrh jsonAppendRaw(pOut, "true", 4);
4179dbf96bdSdrh break;
4189dbf96bdSdrh }
4199dbf96bdSdrh case JSON_FALSE: {
4209dbf96bdSdrh jsonAppendRaw(pOut, "false", 5);
4219dbf96bdSdrh break;
4229dbf96bdSdrh }
4239dbf96bdSdrh case JSON_STRING: {
4249dbf96bdSdrh if( pNode->jnFlags & JNODE_RAW ){
4259dbf96bdSdrh assert( pNode->eU==1 );
4269dbf96bdSdrh jsonAppendString(pOut, pNode->u.zJContent, pNode->n);
4279dbf96bdSdrh break;
4289dbf96bdSdrh }
4299dbf96bdSdrh /* no break */ deliberate_fall_through
4309dbf96bdSdrh }
4319dbf96bdSdrh case JSON_REAL:
4329dbf96bdSdrh case JSON_INT: {
4339dbf96bdSdrh assert( pNode->eU==1 );
4349dbf96bdSdrh jsonAppendRaw(pOut, pNode->u.zJContent, pNode->n);
4359dbf96bdSdrh break;
4369dbf96bdSdrh }
4379dbf96bdSdrh case JSON_ARRAY: {
4389dbf96bdSdrh u32 j = 1;
4399dbf96bdSdrh jsonAppendChar(pOut, '[');
4409dbf96bdSdrh for(;;){
4419dbf96bdSdrh while( j<=pNode->n ){
4429dbf96bdSdrh if( (pNode[j].jnFlags & JNODE_REMOVE)==0 ){
4439dbf96bdSdrh jsonAppendSeparator(pOut);
4449dbf96bdSdrh jsonRenderNode(&pNode[j], pOut, aReplace);
4459dbf96bdSdrh }
4469dbf96bdSdrh j += jsonNodeSize(&pNode[j]);
4479dbf96bdSdrh }
4489dbf96bdSdrh if( (pNode->jnFlags & JNODE_APPEND)==0 ) break;
4499dbf96bdSdrh assert( pNode->eU==2 );
4509dbf96bdSdrh pNode = &pNode[pNode->u.iAppend];
4519dbf96bdSdrh j = 1;
4529dbf96bdSdrh }
4539dbf96bdSdrh jsonAppendChar(pOut, ']');
4549dbf96bdSdrh break;
4559dbf96bdSdrh }
4569dbf96bdSdrh case JSON_OBJECT: {
4579dbf96bdSdrh u32 j = 1;
4589dbf96bdSdrh jsonAppendChar(pOut, '{');
4599dbf96bdSdrh for(;;){
4609dbf96bdSdrh while( j<=pNode->n ){
4619dbf96bdSdrh if( (pNode[j+1].jnFlags & JNODE_REMOVE)==0 ){
4629dbf96bdSdrh jsonAppendSeparator(pOut);
4639dbf96bdSdrh jsonRenderNode(&pNode[j], pOut, aReplace);
4649dbf96bdSdrh jsonAppendChar(pOut, ':');
4659dbf96bdSdrh jsonRenderNode(&pNode[j+1], pOut, aReplace);
4669dbf96bdSdrh }
4679dbf96bdSdrh j += 1 + jsonNodeSize(&pNode[j+1]);
4689dbf96bdSdrh }
4699dbf96bdSdrh if( (pNode->jnFlags & JNODE_APPEND)==0 ) break;
4709dbf96bdSdrh assert( pNode->eU==2 );
4719dbf96bdSdrh pNode = &pNode[pNode->u.iAppend];
4729dbf96bdSdrh j = 1;
4739dbf96bdSdrh }
4749dbf96bdSdrh jsonAppendChar(pOut, '}');
4759dbf96bdSdrh break;
4769dbf96bdSdrh }
4779dbf96bdSdrh }
4789dbf96bdSdrh }
4799dbf96bdSdrh
4809dbf96bdSdrh /*
4819dbf96bdSdrh ** Return a JsonNode and all its descendents as a JSON string.
4829dbf96bdSdrh */
jsonReturnJson(JsonNode * pNode,sqlite3_context * pCtx,sqlite3_value ** aReplace)4839dbf96bdSdrh static void jsonReturnJson(
4849dbf96bdSdrh JsonNode *pNode, /* Node to return */
4859dbf96bdSdrh sqlite3_context *pCtx, /* Return value for this function */
4869dbf96bdSdrh sqlite3_value **aReplace /* Array of replacement values */
4879dbf96bdSdrh ){
4889dbf96bdSdrh JsonString s;
4899dbf96bdSdrh jsonInit(&s, pCtx);
4909dbf96bdSdrh jsonRenderNode(pNode, &s, aReplace);
4919dbf96bdSdrh jsonResult(&s);
4929dbf96bdSdrh sqlite3_result_subtype(pCtx, JSON_SUBTYPE);
4939dbf96bdSdrh }
4949dbf96bdSdrh
4959dbf96bdSdrh /*
4969dbf96bdSdrh ** Translate a single byte of Hex into an integer.
4979dbf96bdSdrh ** This routine only works if h really is a valid hexadecimal
4989dbf96bdSdrh ** character: 0..9a..fA..F
4999dbf96bdSdrh */
jsonHexToInt(int h)5009dbf96bdSdrh static u8 jsonHexToInt(int h){
5019dbf96bdSdrh assert( (h>='0' && h<='9') || (h>='a' && h<='f') || (h>='A' && h<='F') );
5029dbf96bdSdrh #ifdef SQLITE_EBCDIC
5039dbf96bdSdrh h += 9*(1&~(h>>4));
5049dbf96bdSdrh #else
5059dbf96bdSdrh h += 9*(1&(h>>6));
5069dbf96bdSdrh #endif
5079dbf96bdSdrh return (u8)(h & 0xf);
5089dbf96bdSdrh }
5099dbf96bdSdrh
5109dbf96bdSdrh /*
5119dbf96bdSdrh ** Convert a 4-byte hex string into an integer
5129dbf96bdSdrh */
jsonHexToInt4(const char * z)5139dbf96bdSdrh static u32 jsonHexToInt4(const char *z){
5149dbf96bdSdrh u32 v;
5159dbf96bdSdrh assert( sqlite3Isxdigit(z[0]) );
5169dbf96bdSdrh assert( sqlite3Isxdigit(z[1]) );
5179dbf96bdSdrh assert( sqlite3Isxdigit(z[2]) );
5189dbf96bdSdrh assert( sqlite3Isxdigit(z[3]) );
5199dbf96bdSdrh v = (jsonHexToInt(z[0])<<12)
5209dbf96bdSdrh + (jsonHexToInt(z[1])<<8)
5219dbf96bdSdrh + (jsonHexToInt(z[2])<<4)
5229dbf96bdSdrh + jsonHexToInt(z[3]);
5239dbf96bdSdrh return v;
5249dbf96bdSdrh }
5259dbf96bdSdrh
5269dbf96bdSdrh /*
5279dbf96bdSdrh ** Make the JsonNode the return value of the function.
5289dbf96bdSdrh */
jsonReturn(JsonNode * pNode,sqlite3_context * pCtx,sqlite3_value ** aReplace)5299dbf96bdSdrh static void jsonReturn(
5309dbf96bdSdrh JsonNode *pNode, /* Node to return */
5319dbf96bdSdrh sqlite3_context *pCtx, /* Return value for this function */
5329dbf96bdSdrh sqlite3_value **aReplace /* Array of replacement values */
5339dbf96bdSdrh ){
5349dbf96bdSdrh switch( pNode->eType ){
5359dbf96bdSdrh default: {
5369dbf96bdSdrh assert( pNode->eType==JSON_NULL );
5379dbf96bdSdrh sqlite3_result_null(pCtx);
5389dbf96bdSdrh break;
5399dbf96bdSdrh }
5409dbf96bdSdrh case JSON_TRUE: {
5419dbf96bdSdrh sqlite3_result_int(pCtx, 1);
5429dbf96bdSdrh break;
5439dbf96bdSdrh }
5449dbf96bdSdrh case JSON_FALSE: {
5459dbf96bdSdrh sqlite3_result_int(pCtx, 0);
5469dbf96bdSdrh break;
5479dbf96bdSdrh }
5489dbf96bdSdrh case JSON_INT: {
5499dbf96bdSdrh sqlite3_int64 i = 0;
5509dbf96bdSdrh const char *z;
5519dbf96bdSdrh assert( pNode->eU==1 );
5529dbf96bdSdrh z = pNode->u.zJContent;
5539dbf96bdSdrh if( z[0]=='-' ){ z++; }
5549dbf96bdSdrh while( z[0]>='0' && z[0]<='9' ){
5559dbf96bdSdrh unsigned v = *(z++) - '0';
5569dbf96bdSdrh if( i>=LARGEST_INT64/10 ){
5579dbf96bdSdrh if( i>LARGEST_INT64/10 ) goto int_as_real;
5589dbf96bdSdrh if( z[0]>='0' && z[0]<='9' ) goto int_as_real;
5599dbf96bdSdrh if( v==9 ) goto int_as_real;
5609dbf96bdSdrh if( v==8 ){
5619dbf96bdSdrh if( pNode->u.zJContent[0]=='-' ){
5629dbf96bdSdrh sqlite3_result_int64(pCtx, SMALLEST_INT64);
5639dbf96bdSdrh goto int_done;
5649dbf96bdSdrh }else{
5659dbf96bdSdrh goto int_as_real;
5669dbf96bdSdrh }
5679dbf96bdSdrh }
5689dbf96bdSdrh }
5699dbf96bdSdrh i = i*10 + v;
5709dbf96bdSdrh }
5719dbf96bdSdrh if( pNode->u.zJContent[0]=='-' ){ i = -i; }
5729dbf96bdSdrh sqlite3_result_int64(pCtx, i);
5739dbf96bdSdrh int_done:
5749dbf96bdSdrh break;
5759dbf96bdSdrh int_as_real: ; /* no break */ deliberate_fall_through
5769dbf96bdSdrh }
5779dbf96bdSdrh case JSON_REAL: {
5789dbf96bdSdrh double r;
5799dbf96bdSdrh #ifdef SQLITE_AMALGAMATION
5809dbf96bdSdrh const char *z;
5819dbf96bdSdrh assert( pNode->eU==1 );
5829dbf96bdSdrh z = pNode->u.zJContent;
5839dbf96bdSdrh sqlite3AtoF(z, &r, sqlite3Strlen30(z), SQLITE_UTF8);
5849dbf96bdSdrh #else
5859dbf96bdSdrh assert( pNode->eU==1 );
5869dbf96bdSdrh r = strtod(pNode->u.zJContent, 0);
5879dbf96bdSdrh #endif
5889dbf96bdSdrh sqlite3_result_double(pCtx, r);
5899dbf96bdSdrh break;
5909dbf96bdSdrh }
5919dbf96bdSdrh case JSON_STRING: {
5929dbf96bdSdrh #if 0 /* Never happens because JNODE_RAW is only set by json_set(),
5939dbf96bdSdrh ** json_insert() and json_replace() and those routines do not
5949dbf96bdSdrh ** call jsonReturn() */
5959dbf96bdSdrh if( pNode->jnFlags & JNODE_RAW ){
5969dbf96bdSdrh assert( pNode->eU==1 );
5979dbf96bdSdrh sqlite3_result_text(pCtx, pNode->u.zJContent, pNode->n,
5989dbf96bdSdrh SQLITE_TRANSIENT);
5999dbf96bdSdrh }else
6009dbf96bdSdrh #endif
6019dbf96bdSdrh assert( (pNode->jnFlags & JNODE_RAW)==0 );
6029dbf96bdSdrh if( (pNode->jnFlags & JNODE_ESCAPE)==0 ){
6039dbf96bdSdrh /* JSON formatted without any backslash-escapes */
6049dbf96bdSdrh assert( pNode->eU==1 );
6059dbf96bdSdrh sqlite3_result_text(pCtx, pNode->u.zJContent+1, pNode->n-2,
6069dbf96bdSdrh SQLITE_TRANSIENT);
6079dbf96bdSdrh }else{
6089dbf96bdSdrh /* Translate JSON formatted string into raw text */
6099dbf96bdSdrh u32 i;
6109dbf96bdSdrh u32 n = pNode->n;
6119dbf96bdSdrh const char *z;
6129dbf96bdSdrh char *zOut;
6139dbf96bdSdrh u32 j;
6149dbf96bdSdrh assert( pNode->eU==1 );
6159dbf96bdSdrh z = pNode->u.zJContent;
6169dbf96bdSdrh zOut = sqlite3_malloc( n+1 );
6179dbf96bdSdrh if( zOut==0 ){
6189dbf96bdSdrh sqlite3_result_error_nomem(pCtx);
6199dbf96bdSdrh break;
6209dbf96bdSdrh }
6219dbf96bdSdrh for(i=1, j=0; i<n-1; i++){
6229dbf96bdSdrh char c = z[i];
6239dbf96bdSdrh if( c!='\\' ){
6249dbf96bdSdrh zOut[j++] = c;
6259dbf96bdSdrh }else{
6269dbf96bdSdrh c = z[++i];
6279dbf96bdSdrh if( c=='u' ){
6289dbf96bdSdrh u32 v = jsonHexToInt4(z+i+1);
6299dbf96bdSdrh i += 4;
6309dbf96bdSdrh if( v==0 ) break;
6319dbf96bdSdrh if( v<=0x7f ){
6329dbf96bdSdrh zOut[j++] = (char)v;
6339dbf96bdSdrh }else if( v<=0x7ff ){
6349dbf96bdSdrh zOut[j++] = (char)(0xc0 | (v>>6));
6359dbf96bdSdrh zOut[j++] = 0x80 | (v&0x3f);
6369dbf96bdSdrh }else{
6379dbf96bdSdrh u32 vlo;
6389dbf96bdSdrh if( (v&0xfc00)==0xd800
6399dbf96bdSdrh && i<n-6
6409dbf96bdSdrh && z[i+1]=='\\'
6419dbf96bdSdrh && z[i+2]=='u'
6429dbf96bdSdrh && ((vlo = jsonHexToInt4(z+i+3))&0xfc00)==0xdc00
6439dbf96bdSdrh ){
6449dbf96bdSdrh /* We have a surrogate pair */
6459dbf96bdSdrh v = ((v&0x3ff)<<10) + (vlo&0x3ff) + 0x10000;
6469dbf96bdSdrh i += 6;
6479dbf96bdSdrh zOut[j++] = 0xf0 | (v>>18);
6489dbf96bdSdrh zOut[j++] = 0x80 | ((v>>12)&0x3f);
6499dbf96bdSdrh zOut[j++] = 0x80 | ((v>>6)&0x3f);
6509dbf96bdSdrh zOut[j++] = 0x80 | (v&0x3f);
6519dbf96bdSdrh }else{
6529dbf96bdSdrh zOut[j++] = 0xe0 | (v>>12);
6539dbf96bdSdrh zOut[j++] = 0x80 | ((v>>6)&0x3f);
6549dbf96bdSdrh zOut[j++] = 0x80 | (v&0x3f);
6559dbf96bdSdrh }
6569dbf96bdSdrh }
6579dbf96bdSdrh }else{
6589dbf96bdSdrh if( c=='b' ){
6599dbf96bdSdrh c = '\b';
6609dbf96bdSdrh }else if( c=='f' ){
6619dbf96bdSdrh c = '\f';
6629dbf96bdSdrh }else if( c=='n' ){
6639dbf96bdSdrh c = '\n';
6649dbf96bdSdrh }else if( c=='r' ){
6659dbf96bdSdrh c = '\r';
6669dbf96bdSdrh }else if( c=='t' ){
6679dbf96bdSdrh c = '\t';
6689dbf96bdSdrh }
6699dbf96bdSdrh zOut[j++] = c;
6709dbf96bdSdrh }
6719dbf96bdSdrh }
6729dbf96bdSdrh }
6739dbf96bdSdrh zOut[j] = 0;
6749dbf96bdSdrh sqlite3_result_text(pCtx, zOut, j, sqlite3_free);
6759dbf96bdSdrh }
6769dbf96bdSdrh break;
6779dbf96bdSdrh }
6789dbf96bdSdrh case JSON_ARRAY:
6799dbf96bdSdrh case JSON_OBJECT: {
6809dbf96bdSdrh jsonReturnJson(pNode, pCtx, aReplace);
6819dbf96bdSdrh break;
6829dbf96bdSdrh }
6839dbf96bdSdrh }
6849dbf96bdSdrh }
6859dbf96bdSdrh
6869dbf96bdSdrh /* Forward reference */
6879dbf96bdSdrh static int jsonParseAddNode(JsonParse*,u32,u32,const char*);
6889dbf96bdSdrh
6899dbf96bdSdrh /*
6909dbf96bdSdrh ** A macro to hint to the compiler that a function should not be
6919dbf96bdSdrh ** inlined.
6929dbf96bdSdrh */
6939dbf96bdSdrh #if defined(__GNUC__)
6949dbf96bdSdrh # define JSON_NOINLINE __attribute__((noinline))
6959dbf96bdSdrh #elif defined(_MSC_VER) && _MSC_VER>=1310
6969dbf96bdSdrh # define JSON_NOINLINE __declspec(noinline)
6979dbf96bdSdrh #else
6989dbf96bdSdrh # define JSON_NOINLINE
6999dbf96bdSdrh #endif
7009dbf96bdSdrh
7019dbf96bdSdrh
jsonParseAddNodeExpand(JsonParse * pParse,u32 eType,u32 n,const char * zContent)7029dbf96bdSdrh static JSON_NOINLINE int jsonParseAddNodeExpand(
7039dbf96bdSdrh JsonParse *pParse, /* Append the node to this object */
7049dbf96bdSdrh u32 eType, /* Node type */
7059dbf96bdSdrh u32 n, /* Content size or sub-node count */
7069dbf96bdSdrh const char *zContent /* Content */
7079dbf96bdSdrh ){
7089dbf96bdSdrh u32 nNew;
7099dbf96bdSdrh JsonNode *pNew;
7109dbf96bdSdrh assert( pParse->nNode>=pParse->nAlloc );
7119dbf96bdSdrh if( pParse->oom ) return -1;
7129dbf96bdSdrh nNew = pParse->nAlloc*2 + 10;
7139dbf96bdSdrh pNew = sqlite3_realloc64(pParse->aNode, sizeof(JsonNode)*nNew);
7149dbf96bdSdrh if( pNew==0 ){
7159dbf96bdSdrh pParse->oom = 1;
7169dbf96bdSdrh return -1;
7179dbf96bdSdrh }
7189dbf96bdSdrh pParse->nAlloc = nNew;
7199dbf96bdSdrh pParse->aNode = pNew;
7209dbf96bdSdrh assert( pParse->nNode<pParse->nAlloc );
7219dbf96bdSdrh return jsonParseAddNode(pParse, eType, n, zContent);
7229dbf96bdSdrh }
7239dbf96bdSdrh
7249dbf96bdSdrh /*
7259dbf96bdSdrh ** Create a new JsonNode instance based on the arguments and append that
7269dbf96bdSdrh ** instance to the JsonParse. Return the index in pParse->aNode[] of the
7279dbf96bdSdrh ** new node, or -1 if a memory allocation fails.
7289dbf96bdSdrh */
jsonParseAddNode(JsonParse * pParse,u32 eType,u32 n,const char * zContent)7299dbf96bdSdrh static int jsonParseAddNode(
7309dbf96bdSdrh JsonParse *pParse, /* Append the node to this object */
7319dbf96bdSdrh u32 eType, /* Node type */
7329dbf96bdSdrh u32 n, /* Content size or sub-node count */
7339dbf96bdSdrh const char *zContent /* Content */
7349dbf96bdSdrh ){
7359dbf96bdSdrh JsonNode *p;
7369dbf96bdSdrh if( pParse->aNode==0 || pParse->nNode>=pParse->nAlloc ){
7379dbf96bdSdrh return jsonParseAddNodeExpand(pParse, eType, n, zContent);
7389dbf96bdSdrh }
7399dbf96bdSdrh p = &pParse->aNode[pParse->nNode];
7409dbf96bdSdrh p->eType = (u8)eType;
7419dbf96bdSdrh p->jnFlags = 0;
7429dbf96bdSdrh VVA( p->eU = zContent ? 1 : 0 );
7439dbf96bdSdrh p->n = n;
7449dbf96bdSdrh p->u.zJContent = zContent;
7459dbf96bdSdrh return pParse->nNode++;
7469dbf96bdSdrh }
7479dbf96bdSdrh
7489dbf96bdSdrh /*
7499dbf96bdSdrh ** Return true if z[] begins with 4 (or more) hexadecimal digits
7509dbf96bdSdrh */
jsonIs4Hex(const char * z)7519dbf96bdSdrh static int jsonIs4Hex(const char *z){
7529dbf96bdSdrh int i;
7539dbf96bdSdrh for(i=0; i<4; i++) if( !sqlite3Isxdigit(z[i]) ) return 0;
7549dbf96bdSdrh return 1;
7559dbf96bdSdrh }
7569dbf96bdSdrh
7579dbf96bdSdrh /*
7589dbf96bdSdrh ** Parse a single JSON value which begins at pParse->zJson[i]. Return the
7599dbf96bdSdrh ** index of the first character past the end of the value parsed.
7609dbf96bdSdrh **
7619dbf96bdSdrh ** Return negative for a syntax error. Special cases: return -2 if the
7629dbf96bdSdrh ** first non-whitespace character is '}' and return -3 if the first
7639dbf96bdSdrh ** non-whitespace character is ']'.
7649dbf96bdSdrh */
jsonParseValue(JsonParse * pParse,u32 i)7659dbf96bdSdrh static int jsonParseValue(JsonParse *pParse, u32 i){
7669dbf96bdSdrh char c;
7679dbf96bdSdrh u32 j;
7689dbf96bdSdrh int iThis;
7699dbf96bdSdrh int x;
7709dbf96bdSdrh JsonNode *pNode;
7719dbf96bdSdrh const char *z = pParse->zJson;
7729dbf96bdSdrh while( fast_isspace(z[i]) ){ i++; }
7739dbf96bdSdrh if( (c = z[i])=='{' ){
7749dbf96bdSdrh /* Parse object */
7759dbf96bdSdrh iThis = jsonParseAddNode(pParse, JSON_OBJECT, 0, 0);
7769dbf96bdSdrh if( iThis<0 ) return -1;
7779dbf96bdSdrh for(j=i+1;;j++){
7789dbf96bdSdrh while( fast_isspace(z[j]) ){ j++; }
7799dbf96bdSdrh if( ++pParse->iDepth > JSON_MAX_DEPTH ) return -1;
7809dbf96bdSdrh x = jsonParseValue(pParse, j);
7819dbf96bdSdrh if( x<0 ){
7829dbf96bdSdrh pParse->iDepth--;
7839dbf96bdSdrh if( x==(-2) && pParse->nNode==(u32)iThis+1 ) return j+1;
7849dbf96bdSdrh return -1;
7859dbf96bdSdrh }
7869dbf96bdSdrh if( pParse->oom ) return -1;
7879dbf96bdSdrh pNode = &pParse->aNode[pParse->nNode-1];
7889dbf96bdSdrh if( pNode->eType!=JSON_STRING ) return -1;
7899dbf96bdSdrh pNode->jnFlags |= JNODE_LABEL;
7909dbf96bdSdrh j = x;
7919dbf96bdSdrh while( fast_isspace(z[j]) ){ j++; }
7929dbf96bdSdrh if( z[j]!=':' ) return -1;
7939dbf96bdSdrh j++;
7949dbf96bdSdrh x = jsonParseValue(pParse, j);
7959dbf96bdSdrh pParse->iDepth--;
7969dbf96bdSdrh if( x<0 ) return -1;
7979dbf96bdSdrh j = x;
7989dbf96bdSdrh while( fast_isspace(z[j]) ){ j++; }
7999dbf96bdSdrh c = z[j];
8009dbf96bdSdrh if( c==',' ) continue;
8019dbf96bdSdrh if( c!='}' ) return -1;
8029dbf96bdSdrh break;
8039dbf96bdSdrh }
8049dbf96bdSdrh pParse->aNode[iThis].n = pParse->nNode - (u32)iThis - 1;
8059dbf96bdSdrh return j+1;
8069dbf96bdSdrh }else if( c=='[' ){
8079dbf96bdSdrh /* Parse array */
8089dbf96bdSdrh iThis = jsonParseAddNode(pParse, JSON_ARRAY, 0, 0);
8099dbf96bdSdrh if( iThis<0 ) return -1;
8109dbf96bdSdrh memset(&pParse->aNode[iThis].u, 0, sizeof(pParse->aNode[iThis].u));
8119dbf96bdSdrh for(j=i+1;;j++){
8129dbf96bdSdrh while( fast_isspace(z[j]) ){ j++; }
8139dbf96bdSdrh if( ++pParse->iDepth > JSON_MAX_DEPTH ) return -1;
8149dbf96bdSdrh x = jsonParseValue(pParse, j);
8159dbf96bdSdrh pParse->iDepth--;
8169dbf96bdSdrh if( x<0 ){
8179dbf96bdSdrh if( x==(-3) && pParse->nNode==(u32)iThis+1 ) return j+1;
8189dbf96bdSdrh return -1;
8199dbf96bdSdrh }
8209dbf96bdSdrh j = x;
8219dbf96bdSdrh while( fast_isspace(z[j]) ){ j++; }
8229dbf96bdSdrh c = z[j];
8239dbf96bdSdrh if( c==',' ) continue;
8249dbf96bdSdrh if( c!=']' ) return -1;
8259dbf96bdSdrh break;
8269dbf96bdSdrh }
8279dbf96bdSdrh pParse->aNode[iThis].n = pParse->nNode - (u32)iThis - 1;
8289dbf96bdSdrh return j+1;
8299dbf96bdSdrh }else if( c=='"' ){
8309dbf96bdSdrh /* Parse string */
8319dbf96bdSdrh u8 jnFlags = 0;
8329dbf96bdSdrh j = i+1;
8339dbf96bdSdrh for(;;){
8349dbf96bdSdrh c = z[j];
8359dbf96bdSdrh if( (c & ~0x1f)==0 ){
8369dbf96bdSdrh /* Control characters are not allowed in strings */
8379dbf96bdSdrh return -1;
8389dbf96bdSdrh }
8399dbf96bdSdrh if( c=='\\' ){
8409dbf96bdSdrh c = z[++j];
8419dbf96bdSdrh if( c=='"' || c=='\\' || c=='/' || c=='b' || c=='f'
8429dbf96bdSdrh || c=='n' || c=='r' || c=='t'
8439dbf96bdSdrh || (c=='u' && jsonIs4Hex(z+j+1)) ){
8449dbf96bdSdrh jnFlags = JNODE_ESCAPE;
8459dbf96bdSdrh }else{
8469dbf96bdSdrh return -1;
8479dbf96bdSdrh }
8489dbf96bdSdrh }else if( c=='"' ){
8499dbf96bdSdrh break;
8509dbf96bdSdrh }
8519dbf96bdSdrh j++;
8529dbf96bdSdrh }
8539dbf96bdSdrh jsonParseAddNode(pParse, JSON_STRING, j+1-i, &z[i]);
8549dbf96bdSdrh if( !pParse->oom ) pParse->aNode[pParse->nNode-1].jnFlags = jnFlags;
8559dbf96bdSdrh return j+1;
8569dbf96bdSdrh }else if( c=='n'
8579dbf96bdSdrh && strncmp(z+i,"null",4)==0
8589dbf96bdSdrh && !sqlite3Isalnum(z[i+4]) ){
8599dbf96bdSdrh jsonParseAddNode(pParse, JSON_NULL, 0, 0);
8609dbf96bdSdrh return i+4;
8619dbf96bdSdrh }else if( c=='t'
8629dbf96bdSdrh && strncmp(z+i,"true",4)==0
8639dbf96bdSdrh && !sqlite3Isalnum(z[i+4]) ){
8649dbf96bdSdrh jsonParseAddNode(pParse, JSON_TRUE, 0, 0);
8659dbf96bdSdrh return i+4;
8669dbf96bdSdrh }else if( c=='f'
8679dbf96bdSdrh && strncmp(z+i,"false",5)==0
8689dbf96bdSdrh && !sqlite3Isalnum(z[i+5]) ){
8699dbf96bdSdrh jsonParseAddNode(pParse, JSON_FALSE, 0, 0);
8709dbf96bdSdrh return i+5;
8719dbf96bdSdrh }else if( c=='-' || (c>='0' && c<='9') ){
8729dbf96bdSdrh /* Parse number */
8739dbf96bdSdrh u8 seenDP = 0;
8749dbf96bdSdrh u8 seenE = 0;
8759dbf96bdSdrh assert( '-' < '0' );
8769dbf96bdSdrh if( c<='0' ){
8779dbf96bdSdrh j = c=='-' ? i+1 : i;
8789dbf96bdSdrh if( z[j]=='0' && z[j+1]>='0' && z[j+1]<='9' ) return -1;
8799dbf96bdSdrh }
8809dbf96bdSdrh j = i+1;
8819dbf96bdSdrh for(;; j++){
8829dbf96bdSdrh c = z[j];
8839dbf96bdSdrh if( c>='0' && c<='9' ) continue;
8849dbf96bdSdrh if( c=='.' ){
8859dbf96bdSdrh if( z[j-1]=='-' ) return -1;
8869dbf96bdSdrh if( seenDP ) return -1;
8879dbf96bdSdrh seenDP = 1;
8889dbf96bdSdrh continue;
8899dbf96bdSdrh }
8909dbf96bdSdrh if( c=='e' || c=='E' ){
8919dbf96bdSdrh if( z[j-1]<'0' ) return -1;
8929dbf96bdSdrh if( seenE ) return -1;
8939dbf96bdSdrh seenDP = seenE = 1;
8949dbf96bdSdrh c = z[j+1];
8959dbf96bdSdrh if( c=='+' || c=='-' ){
8969dbf96bdSdrh j++;
8979dbf96bdSdrh c = z[j+1];
8989dbf96bdSdrh }
8999dbf96bdSdrh if( c<'0' || c>'9' ) return -1;
9009dbf96bdSdrh continue;
9019dbf96bdSdrh }
9029dbf96bdSdrh break;
9039dbf96bdSdrh }
9049dbf96bdSdrh if( z[j-1]<'0' ) return -1;
9059dbf96bdSdrh jsonParseAddNode(pParse, seenDP ? JSON_REAL : JSON_INT,
9069dbf96bdSdrh j - i, &z[i]);
9079dbf96bdSdrh return j;
9089dbf96bdSdrh }else if( c=='}' ){
9099dbf96bdSdrh return -2; /* End of {...} */
9109dbf96bdSdrh }else if( c==']' ){
9119dbf96bdSdrh return -3; /* End of [...] */
9129dbf96bdSdrh }else if( c==0 ){
9139dbf96bdSdrh return 0; /* End of file */
9149dbf96bdSdrh }else{
9159dbf96bdSdrh return -1; /* Syntax error */
9169dbf96bdSdrh }
9179dbf96bdSdrh }
9189dbf96bdSdrh
9199dbf96bdSdrh /*
9209dbf96bdSdrh ** Parse a complete JSON string. Return 0 on success or non-zero if there
9219dbf96bdSdrh ** are any errors. If an error occurs, free all memory associated with
9229dbf96bdSdrh ** pParse.
9239dbf96bdSdrh **
9249dbf96bdSdrh ** pParse is uninitialized when this routine is called.
9259dbf96bdSdrh */
jsonParse(JsonParse * pParse,sqlite3_context * pCtx,const char * zJson)9269dbf96bdSdrh static int jsonParse(
9279dbf96bdSdrh JsonParse *pParse, /* Initialize and fill this JsonParse object */
9289dbf96bdSdrh sqlite3_context *pCtx, /* Report errors here */
9299dbf96bdSdrh const char *zJson /* Input JSON text to be parsed */
9309dbf96bdSdrh ){
9319dbf96bdSdrh int i;
9329dbf96bdSdrh memset(pParse, 0, sizeof(*pParse));
9339dbf96bdSdrh if( zJson==0 ) return 1;
9349dbf96bdSdrh pParse->zJson = zJson;
9359dbf96bdSdrh i = jsonParseValue(pParse, 0);
9369dbf96bdSdrh if( pParse->oom ) i = -1;
9379dbf96bdSdrh if( i>0 ){
9389dbf96bdSdrh assert( pParse->iDepth==0 );
9399dbf96bdSdrh while( fast_isspace(zJson[i]) ) i++;
9409dbf96bdSdrh if( zJson[i] ) i = -1;
9419dbf96bdSdrh }
9429dbf96bdSdrh if( i<=0 ){
9439dbf96bdSdrh if( pCtx!=0 ){
9449dbf96bdSdrh if( pParse->oom ){
9459dbf96bdSdrh sqlite3_result_error_nomem(pCtx);
9469dbf96bdSdrh }else{
9479dbf96bdSdrh sqlite3_result_error(pCtx, "malformed JSON", -1);
9489dbf96bdSdrh }
9499dbf96bdSdrh }
9509dbf96bdSdrh jsonParseReset(pParse);
9519dbf96bdSdrh return 1;
9529dbf96bdSdrh }
9539dbf96bdSdrh return 0;
9549dbf96bdSdrh }
9559dbf96bdSdrh
9569dbf96bdSdrh /* Mark node i of pParse as being a child of iParent. Call recursively
9579dbf96bdSdrh ** to fill in all the descendants of node i.
9589dbf96bdSdrh */
jsonParseFillInParentage(JsonParse * pParse,u32 i,u32 iParent)9599dbf96bdSdrh static void jsonParseFillInParentage(JsonParse *pParse, u32 i, u32 iParent){
9609dbf96bdSdrh JsonNode *pNode = &pParse->aNode[i];
9619dbf96bdSdrh u32 j;
9629dbf96bdSdrh pParse->aUp[i] = iParent;
9639dbf96bdSdrh switch( pNode->eType ){
9649dbf96bdSdrh case JSON_ARRAY: {
9659dbf96bdSdrh for(j=1; j<=pNode->n; j += jsonNodeSize(pNode+j)){
9669dbf96bdSdrh jsonParseFillInParentage(pParse, i+j, i);
9679dbf96bdSdrh }
9689dbf96bdSdrh break;
9699dbf96bdSdrh }
9709dbf96bdSdrh case JSON_OBJECT: {
9719dbf96bdSdrh for(j=1; j<=pNode->n; j += jsonNodeSize(pNode+j+1)+1){
9729dbf96bdSdrh pParse->aUp[i+j] = i;
9739dbf96bdSdrh jsonParseFillInParentage(pParse, i+j+1, i);
9749dbf96bdSdrh }
9759dbf96bdSdrh break;
9769dbf96bdSdrh }
9779dbf96bdSdrh default: {
9789dbf96bdSdrh break;
9799dbf96bdSdrh }
9809dbf96bdSdrh }
9819dbf96bdSdrh }
9829dbf96bdSdrh
9839dbf96bdSdrh /*
9849dbf96bdSdrh ** Compute the parentage of all nodes in a completed parse.
9859dbf96bdSdrh */
jsonParseFindParents(JsonParse * pParse)9869dbf96bdSdrh static int jsonParseFindParents(JsonParse *pParse){
9879dbf96bdSdrh u32 *aUp;
9889dbf96bdSdrh assert( pParse->aUp==0 );
9899dbf96bdSdrh aUp = pParse->aUp = sqlite3_malloc64( sizeof(u32)*pParse->nNode );
9909dbf96bdSdrh if( aUp==0 ){
9919dbf96bdSdrh pParse->oom = 1;
9929dbf96bdSdrh return SQLITE_NOMEM;
9939dbf96bdSdrh }
9949dbf96bdSdrh jsonParseFillInParentage(pParse, 0, 0);
9959dbf96bdSdrh return SQLITE_OK;
9969dbf96bdSdrh }
9979dbf96bdSdrh
9989dbf96bdSdrh /*
9999dbf96bdSdrh ** Magic number used for the JSON parse cache in sqlite3_get_auxdata()
10009dbf96bdSdrh */
10019dbf96bdSdrh #define JSON_CACHE_ID (-429938) /* First cache entry */
10029dbf96bdSdrh #define JSON_CACHE_SZ 4 /* Max number of cache entries */
10039dbf96bdSdrh
10049dbf96bdSdrh /*
10059dbf96bdSdrh ** Obtain a complete parse of the JSON found in the first argument
10069dbf96bdSdrh ** of the argv array. Use the sqlite3_get_auxdata() cache for this
10079dbf96bdSdrh ** parse if it is available. If the cache is not available or if it
10089dbf96bdSdrh ** is no longer valid, parse the JSON again and return the new parse,
10099dbf96bdSdrh ** and also register the new parse so that it will be available for
10109dbf96bdSdrh ** future sqlite3_get_auxdata() calls.
10119dbf96bdSdrh */
jsonParseCached(sqlite3_context * pCtx,sqlite3_value ** argv,sqlite3_context * pErrCtx)10129dbf96bdSdrh static JsonParse *jsonParseCached(
10139dbf96bdSdrh sqlite3_context *pCtx,
10149dbf96bdSdrh sqlite3_value **argv,
10159dbf96bdSdrh sqlite3_context *pErrCtx
10169dbf96bdSdrh ){
10179dbf96bdSdrh const char *zJson = (const char*)sqlite3_value_text(argv[0]);
10189dbf96bdSdrh int nJson = sqlite3_value_bytes(argv[0]);
10199dbf96bdSdrh JsonParse *p;
10209dbf96bdSdrh JsonParse *pMatch = 0;
10219dbf96bdSdrh int iKey;
10229dbf96bdSdrh int iMinKey = 0;
10239dbf96bdSdrh u32 iMinHold = 0xffffffff;
10249dbf96bdSdrh u32 iMaxHold = 0;
10259dbf96bdSdrh if( zJson==0 ) return 0;
10269dbf96bdSdrh for(iKey=0; iKey<JSON_CACHE_SZ; iKey++){
10279dbf96bdSdrh p = (JsonParse*)sqlite3_get_auxdata(pCtx, JSON_CACHE_ID+iKey);
10289dbf96bdSdrh if( p==0 ){
10299dbf96bdSdrh iMinKey = iKey;
10309dbf96bdSdrh break;
10319dbf96bdSdrh }
10329dbf96bdSdrh if( pMatch==0
10339dbf96bdSdrh && p->nJson==nJson
10349dbf96bdSdrh && memcmp(p->zJson,zJson,nJson)==0
10359dbf96bdSdrh ){
10369dbf96bdSdrh p->nErr = 0;
10379dbf96bdSdrh pMatch = p;
10389dbf96bdSdrh }else if( p->iHold<iMinHold ){
10399dbf96bdSdrh iMinHold = p->iHold;
10409dbf96bdSdrh iMinKey = iKey;
10419dbf96bdSdrh }
10429dbf96bdSdrh if( p->iHold>iMaxHold ){
10439dbf96bdSdrh iMaxHold = p->iHold;
10449dbf96bdSdrh }
10459dbf96bdSdrh }
10469dbf96bdSdrh if( pMatch ){
10479dbf96bdSdrh pMatch->nErr = 0;
10489dbf96bdSdrh pMatch->iHold = iMaxHold+1;
10499dbf96bdSdrh return pMatch;
10509dbf96bdSdrh }
10519dbf96bdSdrh p = sqlite3_malloc64( sizeof(*p) + nJson + 1 );
10529dbf96bdSdrh if( p==0 ){
10539dbf96bdSdrh sqlite3_result_error_nomem(pCtx);
10549dbf96bdSdrh return 0;
10559dbf96bdSdrh }
10569dbf96bdSdrh memset(p, 0, sizeof(*p));
10579dbf96bdSdrh p->zJson = (char*)&p[1];
10589dbf96bdSdrh memcpy((char*)p->zJson, zJson, nJson+1);
10599dbf96bdSdrh if( jsonParse(p, pErrCtx, p->zJson) ){
10609dbf96bdSdrh sqlite3_free(p);
10619dbf96bdSdrh return 0;
10629dbf96bdSdrh }
10639dbf96bdSdrh p->nJson = nJson;
10649dbf96bdSdrh p->iHold = iMaxHold+1;
10659dbf96bdSdrh sqlite3_set_auxdata(pCtx, JSON_CACHE_ID+iMinKey, p,
10669dbf96bdSdrh (void(*)(void*))jsonParseFree);
10679dbf96bdSdrh return (JsonParse*)sqlite3_get_auxdata(pCtx, JSON_CACHE_ID+iMinKey);
10689dbf96bdSdrh }
10699dbf96bdSdrh
10709dbf96bdSdrh /*
10719dbf96bdSdrh ** Compare the OBJECT label at pNode against zKey,nKey. Return true on
10729dbf96bdSdrh ** a match.
10739dbf96bdSdrh */
jsonLabelCompare(JsonNode * pNode,const char * zKey,u32 nKey)10749dbf96bdSdrh static int jsonLabelCompare(JsonNode *pNode, const char *zKey, u32 nKey){
10759dbf96bdSdrh assert( pNode->eU==1 );
10769dbf96bdSdrh if( pNode->jnFlags & JNODE_RAW ){
10779dbf96bdSdrh if( pNode->n!=nKey ) return 0;
10789dbf96bdSdrh return strncmp(pNode->u.zJContent, zKey, nKey)==0;
10799dbf96bdSdrh }else{
10809dbf96bdSdrh if( pNode->n!=nKey+2 ) return 0;
10819dbf96bdSdrh return strncmp(pNode->u.zJContent+1, zKey, nKey)==0;
10829dbf96bdSdrh }
10839dbf96bdSdrh }
10849dbf96bdSdrh
10859dbf96bdSdrh /* forward declaration */
10869dbf96bdSdrh static JsonNode *jsonLookupAppend(JsonParse*,const char*,int*,const char**);
10879dbf96bdSdrh
10889dbf96bdSdrh /*
10899dbf96bdSdrh ** Search along zPath to find the node specified. Return a pointer
10909dbf96bdSdrh ** to that node, or NULL if zPath is malformed or if there is no such
10919dbf96bdSdrh ** node.
10929dbf96bdSdrh **
10939dbf96bdSdrh ** If pApnd!=0, then try to append new nodes to complete zPath if it is
10949dbf96bdSdrh ** possible to do so and if no existing node corresponds to zPath. If
10959dbf96bdSdrh ** new nodes are appended *pApnd is set to 1.
10969dbf96bdSdrh */
jsonLookupStep(JsonParse * pParse,u32 iRoot,const char * zPath,int * pApnd,const char ** pzErr)10979dbf96bdSdrh static JsonNode *jsonLookupStep(
10989dbf96bdSdrh JsonParse *pParse, /* The JSON to search */
10999dbf96bdSdrh u32 iRoot, /* Begin the search at this node */
11009dbf96bdSdrh const char *zPath, /* The path to search */
11019dbf96bdSdrh int *pApnd, /* Append nodes to complete path if not NULL */
11029dbf96bdSdrh const char **pzErr /* Make *pzErr point to any syntax error in zPath */
11039dbf96bdSdrh ){
11049dbf96bdSdrh u32 i, j, nKey;
11059dbf96bdSdrh const char *zKey;
11069dbf96bdSdrh JsonNode *pRoot = &pParse->aNode[iRoot];
11079dbf96bdSdrh if( zPath[0]==0 ) return pRoot;
11089dbf96bdSdrh if( pRoot->jnFlags & JNODE_REPLACE ) return 0;
11099dbf96bdSdrh if( zPath[0]=='.' ){
11109dbf96bdSdrh if( pRoot->eType!=JSON_OBJECT ) return 0;
11119dbf96bdSdrh zPath++;
11129dbf96bdSdrh if( zPath[0]=='"' ){
11139dbf96bdSdrh zKey = zPath + 1;
11149dbf96bdSdrh for(i=1; zPath[i] && zPath[i]!='"'; i++){}
11159dbf96bdSdrh nKey = i-1;
11169dbf96bdSdrh if( zPath[i] ){
11179dbf96bdSdrh i++;
11189dbf96bdSdrh }else{
11199dbf96bdSdrh *pzErr = zPath;
11209dbf96bdSdrh return 0;
11219dbf96bdSdrh }
1122b07fb4f1Sdrh testcase( nKey==0 );
11239dbf96bdSdrh }else{
11249dbf96bdSdrh zKey = zPath;
11259dbf96bdSdrh for(i=0; zPath[i] && zPath[i]!='.' && zPath[i]!='['; i++){}
11269dbf96bdSdrh nKey = i;
11279dbf96bdSdrh if( nKey==0 ){
11289dbf96bdSdrh *pzErr = zPath;
11299dbf96bdSdrh return 0;
11309dbf96bdSdrh }
1131b07fb4f1Sdrh }
11329dbf96bdSdrh j = 1;
11339dbf96bdSdrh for(;;){
11349dbf96bdSdrh while( j<=pRoot->n ){
11359dbf96bdSdrh if( jsonLabelCompare(pRoot+j, zKey, nKey) ){
11369dbf96bdSdrh return jsonLookupStep(pParse, iRoot+j+1, &zPath[i], pApnd, pzErr);
11379dbf96bdSdrh }
11389dbf96bdSdrh j++;
11399dbf96bdSdrh j += jsonNodeSize(&pRoot[j]);
11409dbf96bdSdrh }
11419dbf96bdSdrh if( (pRoot->jnFlags & JNODE_APPEND)==0 ) break;
11429dbf96bdSdrh assert( pRoot->eU==2 );
11439dbf96bdSdrh iRoot += pRoot->u.iAppend;
11449dbf96bdSdrh pRoot = &pParse->aNode[iRoot];
11459dbf96bdSdrh j = 1;
11469dbf96bdSdrh }
11479dbf96bdSdrh if( pApnd ){
11489dbf96bdSdrh u32 iStart, iLabel;
11499dbf96bdSdrh JsonNode *pNode;
11509dbf96bdSdrh iStart = jsonParseAddNode(pParse, JSON_OBJECT, 2, 0);
11519dbf96bdSdrh iLabel = jsonParseAddNode(pParse, JSON_STRING, nKey, zKey);
11529dbf96bdSdrh zPath += i;
11539dbf96bdSdrh pNode = jsonLookupAppend(pParse, zPath, pApnd, pzErr);
11549dbf96bdSdrh if( pParse->oom ) return 0;
11559dbf96bdSdrh if( pNode ){
11569dbf96bdSdrh pRoot = &pParse->aNode[iRoot];
11579dbf96bdSdrh assert( pRoot->eU==0 );
11589dbf96bdSdrh pRoot->u.iAppend = iStart - iRoot;
11599dbf96bdSdrh pRoot->jnFlags |= JNODE_APPEND;
11609dbf96bdSdrh VVA( pRoot->eU = 2 );
11619dbf96bdSdrh pParse->aNode[iLabel].jnFlags |= JNODE_RAW;
11629dbf96bdSdrh }
11639dbf96bdSdrh return pNode;
11649dbf96bdSdrh }
11659dbf96bdSdrh }else if( zPath[0]=='[' ){
11669dbf96bdSdrh i = 0;
11679dbf96bdSdrh j = 1;
11689dbf96bdSdrh while( sqlite3Isdigit(zPath[j]) ){
11699dbf96bdSdrh i = i*10 + zPath[j] - '0';
11709dbf96bdSdrh j++;
11719dbf96bdSdrh }
11729dbf96bdSdrh if( j<2 || zPath[j]!=']' ){
11739dbf96bdSdrh if( zPath[1]=='#' ){
11749dbf96bdSdrh JsonNode *pBase = pRoot;
11759dbf96bdSdrh int iBase = iRoot;
11769dbf96bdSdrh if( pRoot->eType!=JSON_ARRAY ) return 0;
11779dbf96bdSdrh for(;;){
11789dbf96bdSdrh while( j<=pBase->n ){
11799dbf96bdSdrh if( (pBase[j].jnFlags & JNODE_REMOVE)==0 ) i++;
11809dbf96bdSdrh j += jsonNodeSize(&pBase[j]);
11819dbf96bdSdrh }
11829dbf96bdSdrh if( (pBase->jnFlags & JNODE_APPEND)==0 ) break;
11839dbf96bdSdrh assert( pBase->eU==2 );
11849dbf96bdSdrh iBase += pBase->u.iAppend;
11859dbf96bdSdrh pBase = &pParse->aNode[iBase];
11869dbf96bdSdrh j = 1;
11879dbf96bdSdrh }
11889dbf96bdSdrh j = 2;
11899dbf96bdSdrh if( zPath[2]=='-' && sqlite3Isdigit(zPath[3]) ){
11909dbf96bdSdrh unsigned int x = 0;
11919dbf96bdSdrh j = 3;
11929dbf96bdSdrh do{
11939dbf96bdSdrh x = x*10 + zPath[j] - '0';
11949dbf96bdSdrh j++;
11959dbf96bdSdrh }while( sqlite3Isdigit(zPath[j]) );
11969dbf96bdSdrh if( x>i ) return 0;
11979dbf96bdSdrh i -= x;
11989dbf96bdSdrh }
11999dbf96bdSdrh if( zPath[j]!=']' ){
12009dbf96bdSdrh *pzErr = zPath;
12019dbf96bdSdrh return 0;
12029dbf96bdSdrh }
12039dbf96bdSdrh }else{
12049dbf96bdSdrh *pzErr = zPath;
12059dbf96bdSdrh return 0;
12069dbf96bdSdrh }
12079dbf96bdSdrh }
12089dbf96bdSdrh if( pRoot->eType!=JSON_ARRAY ) return 0;
12099dbf96bdSdrh zPath += j + 1;
12109dbf96bdSdrh j = 1;
12119dbf96bdSdrh for(;;){
12129dbf96bdSdrh while( j<=pRoot->n && (i>0 || (pRoot[j].jnFlags & JNODE_REMOVE)!=0) ){
12139dbf96bdSdrh if( (pRoot[j].jnFlags & JNODE_REMOVE)==0 ) i--;
12149dbf96bdSdrh j += jsonNodeSize(&pRoot[j]);
12159dbf96bdSdrh }
12169dbf96bdSdrh if( (pRoot->jnFlags & JNODE_APPEND)==0 ) break;
12179dbf96bdSdrh assert( pRoot->eU==2 );
12189dbf96bdSdrh iRoot += pRoot->u.iAppend;
12199dbf96bdSdrh pRoot = &pParse->aNode[iRoot];
12209dbf96bdSdrh j = 1;
12219dbf96bdSdrh }
12229dbf96bdSdrh if( j<=pRoot->n ){
12239dbf96bdSdrh return jsonLookupStep(pParse, iRoot+j, zPath, pApnd, pzErr);
12249dbf96bdSdrh }
12259dbf96bdSdrh if( i==0 && pApnd ){
12269dbf96bdSdrh u32 iStart;
12279dbf96bdSdrh JsonNode *pNode;
12289dbf96bdSdrh iStart = jsonParseAddNode(pParse, JSON_ARRAY, 1, 0);
12299dbf96bdSdrh pNode = jsonLookupAppend(pParse, zPath, pApnd, pzErr);
12309dbf96bdSdrh if( pParse->oom ) return 0;
12319dbf96bdSdrh if( pNode ){
12329dbf96bdSdrh pRoot = &pParse->aNode[iRoot];
12339dbf96bdSdrh assert( pRoot->eU==0 );
12349dbf96bdSdrh pRoot->u.iAppend = iStart - iRoot;
12359dbf96bdSdrh pRoot->jnFlags |= JNODE_APPEND;
12369dbf96bdSdrh VVA( pRoot->eU = 2 );
12379dbf96bdSdrh }
12389dbf96bdSdrh return pNode;
12399dbf96bdSdrh }
12409dbf96bdSdrh }else{
12419dbf96bdSdrh *pzErr = zPath;
12429dbf96bdSdrh }
12439dbf96bdSdrh return 0;
12449dbf96bdSdrh }
12459dbf96bdSdrh
12469dbf96bdSdrh /*
12479dbf96bdSdrh ** Append content to pParse that will complete zPath. Return a pointer
12489dbf96bdSdrh ** to the inserted node, or return NULL if the append fails.
12499dbf96bdSdrh */
jsonLookupAppend(JsonParse * pParse,const char * zPath,int * pApnd,const char ** pzErr)12509dbf96bdSdrh static JsonNode *jsonLookupAppend(
12519dbf96bdSdrh JsonParse *pParse, /* Append content to the JSON parse */
12529dbf96bdSdrh const char *zPath, /* Description of content to append */
12539dbf96bdSdrh int *pApnd, /* Set this flag to 1 */
12549dbf96bdSdrh const char **pzErr /* Make this point to any syntax error */
12559dbf96bdSdrh ){
12569dbf96bdSdrh *pApnd = 1;
12579dbf96bdSdrh if( zPath[0]==0 ){
12589dbf96bdSdrh jsonParseAddNode(pParse, JSON_NULL, 0, 0);
12599dbf96bdSdrh return pParse->oom ? 0 : &pParse->aNode[pParse->nNode-1];
12609dbf96bdSdrh }
12619dbf96bdSdrh if( zPath[0]=='.' ){
12629dbf96bdSdrh jsonParseAddNode(pParse, JSON_OBJECT, 0, 0);
12639dbf96bdSdrh }else if( strncmp(zPath,"[0]",3)==0 ){
12649dbf96bdSdrh jsonParseAddNode(pParse, JSON_ARRAY, 0, 0);
12659dbf96bdSdrh }else{
12669dbf96bdSdrh return 0;
12679dbf96bdSdrh }
12689dbf96bdSdrh if( pParse->oom ) return 0;
12699dbf96bdSdrh return jsonLookupStep(pParse, pParse->nNode-1, zPath, pApnd, pzErr);
12709dbf96bdSdrh }
12719dbf96bdSdrh
12729dbf96bdSdrh /*
12739dbf96bdSdrh ** Return the text of a syntax error message on a JSON path. Space is
12749dbf96bdSdrh ** obtained from sqlite3_malloc().
12759dbf96bdSdrh */
jsonPathSyntaxError(const char * zErr)12769dbf96bdSdrh static char *jsonPathSyntaxError(const char *zErr){
12779dbf96bdSdrh return sqlite3_mprintf("JSON path error near '%q'", zErr);
12789dbf96bdSdrh }
12799dbf96bdSdrh
12809dbf96bdSdrh /*
12819dbf96bdSdrh ** Do a node lookup using zPath. Return a pointer to the node on success.
12829dbf96bdSdrh ** Return NULL if not found or if there is an error.
12839dbf96bdSdrh **
12849dbf96bdSdrh ** On an error, write an error message into pCtx and increment the
12859dbf96bdSdrh ** pParse->nErr counter.
12869dbf96bdSdrh **
12879dbf96bdSdrh ** If pApnd!=NULL then try to append missing nodes and set *pApnd = 1 if
12889dbf96bdSdrh ** nodes are appended.
12899dbf96bdSdrh */
jsonLookup(JsonParse * pParse,const char * zPath,int * pApnd,sqlite3_context * pCtx)12909dbf96bdSdrh static JsonNode *jsonLookup(
12919dbf96bdSdrh JsonParse *pParse, /* The JSON to search */
12929dbf96bdSdrh const char *zPath, /* The path to search */
12939dbf96bdSdrh int *pApnd, /* Append nodes to complete path if not NULL */
12949dbf96bdSdrh sqlite3_context *pCtx /* Report errors here, if not NULL */
12959dbf96bdSdrh ){
12969dbf96bdSdrh const char *zErr = 0;
12979dbf96bdSdrh JsonNode *pNode = 0;
12989dbf96bdSdrh char *zMsg;
12999dbf96bdSdrh
13009dbf96bdSdrh if( zPath==0 ) return 0;
13019dbf96bdSdrh if( zPath[0]!='$' ){
13029dbf96bdSdrh zErr = zPath;
13039dbf96bdSdrh goto lookup_err;
13049dbf96bdSdrh }
13059dbf96bdSdrh zPath++;
13069dbf96bdSdrh pNode = jsonLookupStep(pParse, 0, zPath, pApnd, &zErr);
13079dbf96bdSdrh if( zErr==0 ) return pNode;
13089dbf96bdSdrh
13099dbf96bdSdrh lookup_err:
13109dbf96bdSdrh pParse->nErr++;
13119dbf96bdSdrh assert( zErr!=0 && pCtx!=0 );
13129dbf96bdSdrh zMsg = jsonPathSyntaxError(zErr);
13139dbf96bdSdrh if( zMsg ){
13149dbf96bdSdrh sqlite3_result_error(pCtx, zMsg, -1);
13159dbf96bdSdrh sqlite3_free(zMsg);
13169dbf96bdSdrh }else{
13179dbf96bdSdrh sqlite3_result_error_nomem(pCtx);
13189dbf96bdSdrh }
13199dbf96bdSdrh return 0;
13209dbf96bdSdrh }
13219dbf96bdSdrh
13229dbf96bdSdrh
13239dbf96bdSdrh /*
13249dbf96bdSdrh ** Report the wrong number of arguments for json_insert(), json_replace()
13259dbf96bdSdrh ** or json_set().
13269dbf96bdSdrh */
jsonWrongNumArgs(sqlite3_context * pCtx,const char * zFuncName)13279dbf96bdSdrh static void jsonWrongNumArgs(
13289dbf96bdSdrh sqlite3_context *pCtx,
13299dbf96bdSdrh const char *zFuncName
13309dbf96bdSdrh ){
13319dbf96bdSdrh char *zMsg = sqlite3_mprintf("json_%s() needs an odd number of arguments",
13329dbf96bdSdrh zFuncName);
13339dbf96bdSdrh sqlite3_result_error(pCtx, zMsg, -1);
13349dbf96bdSdrh sqlite3_free(zMsg);
13359dbf96bdSdrh }
13369dbf96bdSdrh
13379dbf96bdSdrh /*
13389dbf96bdSdrh ** Mark all NULL entries in the Object passed in as JNODE_REMOVE.
13399dbf96bdSdrh */
jsonRemoveAllNulls(JsonNode * pNode)13409dbf96bdSdrh static void jsonRemoveAllNulls(JsonNode *pNode){
13419dbf96bdSdrh int i, n;
13429dbf96bdSdrh assert( pNode->eType==JSON_OBJECT );
13439dbf96bdSdrh n = pNode->n;
13449dbf96bdSdrh for(i=2; i<=n; i += jsonNodeSize(&pNode[i])+1){
13459dbf96bdSdrh switch( pNode[i].eType ){
13469dbf96bdSdrh case JSON_NULL:
13479dbf96bdSdrh pNode[i].jnFlags |= JNODE_REMOVE;
13489dbf96bdSdrh break;
13499dbf96bdSdrh case JSON_OBJECT:
13509dbf96bdSdrh jsonRemoveAllNulls(&pNode[i]);
13519dbf96bdSdrh break;
13529dbf96bdSdrh }
13539dbf96bdSdrh }
13549dbf96bdSdrh }
13559dbf96bdSdrh
13569dbf96bdSdrh
13579dbf96bdSdrh /****************************************************************************
13589dbf96bdSdrh ** SQL functions used for testing and debugging
13599dbf96bdSdrh ****************************************************************************/
13609dbf96bdSdrh
13619dbf96bdSdrh #ifdef SQLITE_DEBUG
13629dbf96bdSdrh /*
13639dbf96bdSdrh ** The json_parse(JSON) function returns a string which describes
13649dbf96bdSdrh ** a parse of the JSON provided. Or it returns NULL if JSON is not
13659dbf96bdSdrh ** well-formed.
13669dbf96bdSdrh */
jsonParseFunc(sqlite3_context * ctx,int argc,sqlite3_value ** argv)13679dbf96bdSdrh static void jsonParseFunc(
13689dbf96bdSdrh sqlite3_context *ctx,
13699dbf96bdSdrh int argc,
13709dbf96bdSdrh sqlite3_value **argv
13719dbf96bdSdrh ){
13729dbf96bdSdrh JsonString s; /* Output string - not real JSON */
13739dbf96bdSdrh JsonParse x; /* The parse */
13749dbf96bdSdrh u32 i;
13759dbf96bdSdrh
13769dbf96bdSdrh assert( argc==1 );
13779dbf96bdSdrh if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return;
13789dbf96bdSdrh jsonParseFindParents(&x);
13799dbf96bdSdrh jsonInit(&s, ctx);
13809dbf96bdSdrh for(i=0; i<x.nNode; i++){
13819dbf96bdSdrh const char *zType;
13829dbf96bdSdrh if( x.aNode[i].jnFlags & JNODE_LABEL ){
13839dbf96bdSdrh assert( x.aNode[i].eType==JSON_STRING );
13849dbf96bdSdrh zType = "label";
13859dbf96bdSdrh }else{
13869dbf96bdSdrh zType = jsonType[x.aNode[i].eType];
13879dbf96bdSdrh }
13889dbf96bdSdrh jsonPrintf(100, &s,"node %3u: %7s n=%-4d up=%-4d",
13899dbf96bdSdrh i, zType, x.aNode[i].n, x.aUp[i]);
13909dbf96bdSdrh assert( x.aNode[i].eU==0 || x.aNode[i].eU==1 );
13919dbf96bdSdrh if( x.aNode[i].u.zJContent!=0 ){
13929dbf96bdSdrh assert( x.aNode[i].eU==1 );
13939dbf96bdSdrh jsonAppendRaw(&s, " ", 1);
13949dbf96bdSdrh jsonAppendRaw(&s, x.aNode[i].u.zJContent, x.aNode[i].n);
13959dbf96bdSdrh }else{
13969dbf96bdSdrh assert( x.aNode[i].eU==0 );
13979dbf96bdSdrh }
13989dbf96bdSdrh jsonAppendRaw(&s, "\n", 1);
13999dbf96bdSdrh }
14009dbf96bdSdrh jsonParseReset(&x);
14019dbf96bdSdrh jsonResult(&s);
14029dbf96bdSdrh }
14039dbf96bdSdrh
14049dbf96bdSdrh /*
14059dbf96bdSdrh ** The json_test1(JSON) function return true (1) if the input is JSON
14069dbf96bdSdrh ** text generated by another json function. It returns (0) if the input
14079dbf96bdSdrh ** is not known to be JSON.
14089dbf96bdSdrh */
jsonTest1Func(sqlite3_context * ctx,int argc,sqlite3_value ** argv)14099dbf96bdSdrh static void jsonTest1Func(
14109dbf96bdSdrh sqlite3_context *ctx,
14119dbf96bdSdrh int argc,
14129dbf96bdSdrh sqlite3_value **argv
14139dbf96bdSdrh ){
14149dbf96bdSdrh UNUSED_PARAMETER(argc);
14159dbf96bdSdrh sqlite3_result_int(ctx, sqlite3_value_subtype(argv[0])==JSON_SUBTYPE);
14169dbf96bdSdrh }
14179dbf96bdSdrh #endif /* SQLITE_DEBUG */
14189dbf96bdSdrh
14199dbf96bdSdrh /****************************************************************************
14209dbf96bdSdrh ** Scalar SQL function implementations
14219dbf96bdSdrh ****************************************************************************/
14229dbf96bdSdrh
14239dbf96bdSdrh /*
14249dbf96bdSdrh ** Implementation of the json_QUOTE(VALUE) function. Return a JSON value
14259dbf96bdSdrh ** corresponding to the SQL value input. Mostly this means putting
14269dbf96bdSdrh ** double-quotes around strings and returning the unquoted string "null"
14279dbf96bdSdrh ** when given a NULL input.
14289dbf96bdSdrh */
jsonQuoteFunc(sqlite3_context * ctx,int argc,sqlite3_value ** argv)14299dbf96bdSdrh static void jsonQuoteFunc(
14309dbf96bdSdrh sqlite3_context *ctx,
14319dbf96bdSdrh int argc,
14329dbf96bdSdrh sqlite3_value **argv
14339dbf96bdSdrh ){
14349dbf96bdSdrh JsonString jx;
14359dbf96bdSdrh UNUSED_PARAMETER(argc);
14369dbf96bdSdrh
14379dbf96bdSdrh jsonInit(&jx, ctx);
14389dbf96bdSdrh jsonAppendValue(&jx, argv[0]);
14399dbf96bdSdrh jsonResult(&jx);
14409dbf96bdSdrh sqlite3_result_subtype(ctx, JSON_SUBTYPE);
14419dbf96bdSdrh }
14429dbf96bdSdrh
14439dbf96bdSdrh /*
14449dbf96bdSdrh ** Implementation of the json_array(VALUE,...) function. Return a JSON
14459dbf96bdSdrh ** array that contains all values given in arguments. Or if any argument
14469dbf96bdSdrh ** is a BLOB, throw an error.
14479dbf96bdSdrh */
jsonArrayFunc(sqlite3_context * ctx,int argc,sqlite3_value ** argv)14489dbf96bdSdrh static void jsonArrayFunc(
14499dbf96bdSdrh sqlite3_context *ctx,
14509dbf96bdSdrh int argc,
14519dbf96bdSdrh sqlite3_value **argv
14529dbf96bdSdrh ){
14539dbf96bdSdrh int i;
14549dbf96bdSdrh JsonString jx;
14559dbf96bdSdrh
14569dbf96bdSdrh jsonInit(&jx, ctx);
14579dbf96bdSdrh jsonAppendChar(&jx, '[');
14589dbf96bdSdrh for(i=0; i<argc; i++){
14599dbf96bdSdrh jsonAppendSeparator(&jx);
14609dbf96bdSdrh jsonAppendValue(&jx, argv[i]);
14619dbf96bdSdrh }
14629dbf96bdSdrh jsonAppendChar(&jx, ']');
14639dbf96bdSdrh jsonResult(&jx);
14649dbf96bdSdrh sqlite3_result_subtype(ctx, JSON_SUBTYPE);
14659dbf96bdSdrh }
14669dbf96bdSdrh
14679dbf96bdSdrh
14689dbf96bdSdrh /*
14699dbf96bdSdrh ** json_array_length(JSON)
14709dbf96bdSdrh ** json_array_length(JSON, PATH)
14719dbf96bdSdrh **
14729dbf96bdSdrh ** Return the number of elements in the top-level JSON array.
14739dbf96bdSdrh ** Return 0 if the input is not a well-formed JSON array.
14749dbf96bdSdrh */
jsonArrayLengthFunc(sqlite3_context * ctx,int argc,sqlite3_value ** argv)14759dbf96bdSdrh static void jsonArrayLengthFunc(
14769dbf96bdSdrh sqlite3_context *ctx,
14779dbf96bdSdrh int argc,
14789dbf96bdSdrh sqlite3_value **argv
14799dbf96bdSdrh ){
14809dbf96bdSdrh JsonParse *p; /* The parse */
14819dbf96bdSdrh sqlite3_int64 n = 0;
14829dbf96bdSdrh u32 i;
14839dbf96bdSdrh JsonNode *pNode;
14849dbf96bdSdrh
14859dbf96bdSdrh p = jsonParseCached(ctx, argv, ctx);
14869dbf96bdSdrh if( p==0 ) return;
14879dbf96bdSdrh assert( p->nNode );
14889dbf96bdSdrh if( argc==2 ){
14899dbf96bdSdrh const char *zPath = (const char*)sqlite3_value_text(argv[1]);
14909dbf96bdSdrh pNode = jsonLookup(p, zPath, 0, ctx);
14919dbf96bdSdrh }else{
14929dbf96bdSdrh pNode = p->aNode;
14939dbf96bdSdrh }
14949dbf96bdSdrh if( pNode==0 ){
14959dbf96bdSdrh return;
14969dbf96bdSdrh }
14979dbf96bdSdrh if( pNode->eType==JSON_ARRAY ){
14989dbf96bdSdrh assert( (pNode->jnFlags & JNODE_APPEND)==0 );
14999dbf96bdSdrh for(i=1; i<=pNode->n; n++){
15009dbf96bdSdrh i += jsonNodeSize(&pNode[i]);
15019dbf96bdSdrh }
15029dbf96bdSdrh }
15039dbf96bdSdrh sqlite3_result_int64(ctx, n);
15049dbf96bdSdrh }
15059dbf96bdSdrh
15069dbf96bdSdrh /*
1507daefcd9eSdrh ** Bit values for the flags passed into jsonExtractFunc() or
1508daefcd9eSdrh ** jsonSetFunc() via the user-data value.
1509daefcd9eSdrh */
1510d83c90bdSdrh #define JSON_JSON 0x01 /* Result is always JSON */
1511d83c90bdSdrh #define JSON_SQL 0x02 /* Result is always SQL */
1512d83c90bdSdrh #define JSON_ABPATH 0x03 /* Allow abbreviated JSON path specs */
1513daefcd9eSdrh #define JSON_ISSET 0x04 /* json_set(), not json_insert() */
1514daefcd9eSdrh
1515daefcd9eSdrh /*
15169dbf96bdSdrh ** json_extract(JSON, PATH, ...)
1517daefcd9eSdrh ** "->"(JSON,PATH)
1518daefcd9eSdrh ** "->>"(JSON,PATH)
15199dbf96bdSdrh **
1520daefcd9eSdrh ** Return the element described by PATH. Return NULL if that PATH element
1521d83c90bdSdrh ** is not found.
1522daefcd9eSdrh **
1523d83c90bdSdrh ** If JSON_JSON is set or if more that one PATH argument is supplied then
1524d83c90bdSdrh ** always return a JSON representation of the result. If JSON_SQL is set,
1525d83c90bdSdrh ** then always return an SQL representation of the result. If neither flag
1526d83c90bdSdrh ** is present and argc==2, then return JSON for objects and arrays and SQL
1527d83c90bdSdrh ** for all other values.
1528daefcd9eSdrh **
1529d83c90bdSdrh ** When multiple PATH arguments are supplied, the result is a JSON array
1530d83c90bdSdrh ** containing the result of each PATH.
1531daefcd9eSdrh **
1532d83c90bdSdrh ** Abbreviated JSON path expressions are allows if JSON_ABPATH, for
1533d83c90bdSdrh ** compatibility with PG.
15349dbf96bdSdrh */
jsonExtractFunc(sqlite3_context * ctx,int argc,sqlite3_value ** argv)15359dbf96bdSdrh static void jsonExtractFunc(
15369dbf96bdSdrh sqlite3_context *ctx,
15379dbf96bdSdrh int argc,
15389dbf96bdSdrh sqlite3_value **argv
15399dbf96bdSdrh ){
15409dbf96bdSdrh JsonParse *p; /* The parse */
15419dbf96bdSdrh JsonNode *pNode;
15429dbf96bdSdrh const char *zPath;
1543daefcd9eSdrh int flags = SQLITE_PTR_TO_INT(sqlite3_user_data(ctx));
15449dbf96bdSdrh JsonString jx;
15459dbf96bdSdrh
15469dbf96bdSdrh if( argc<2 ) return;
1547d83c90bdSdrh p = jsonParseCached(ctx, argv, ctx);
1548d83c90bdSdrh if( p==0 ) return;
1549daefcd9eSdrh if( argc==2 ){
1550d83c90bdSdrh /* With a single PATH argument */
1551daefcd9eSdrh zPath = (const char*)sqlite3_value_text(argv[1]);
1552d83c90bdSdrh if( zPath==0 ) return;
1553aa97b57bSdrh if( flags & JSON_ABPATH ){
1554aa97b57bSdrh if( zPath[0]!='$' ){
1555daefcd9eSdrh /* The -> and ->> operators accept abbreviated PATH arguments. This
1556aa97b57bSdrh ** is mostly for compatibility with PostgreSQL, but also for
1557aa97b57bSdrh ** convenience.
1558daefcd9eSdrh **
1559daefcd9eSdrh ** NUMBER ==> $[NUMBER] // PG compatible
1560daefcd9eSdrh ** LABEL ==> $.LABEL // PG compatible
1561daefcd9eSdrh ** [NUMBER] ==> $[NUMBER] // Not PG. Purely for convenience
1562daefcd9eSdrh */
1563daefcd9eSdrh jsonInit(&jx, ctx);
1564daefcd9eSdrh if( sqlite3Isdigit(zPath[0]) ){
1565daefcd9eSdrh jsonAppendRaw(&jx, "$[", 2);
1566daefcd9eSdrh jsonAppendRaw(&jx, zPath, (int)strlen(zPath));
1567daefcd9eSdrh jsonAppendRaw(&jx, "]", 2);
1568daefcd9eSdrh }else{
1569daefcd9eSdrh jsonAppendRaw(&jx, "$.", 1 + (zPath[0]!='['));
1570daefcd9eSdrh jsonAppendRaw(&jx, zPath, (int)strlen(zPath));
1571daefcd9eSdrh jsonAppendChar(&jx, 0);
1572daefcd9eSdrh }
1573aa97b57bSdrh pNode = jx.bErr ? 0 : jsonLookup(p, jx.zBuf, 0, ctx);
1574aa97b57bSdrh jsonReset(&jx);
1575aa97b57bSdrh }else{
1576aa97b57bSdrh pNode = jsonLookup(p, zPath, 0, ctx);
1577aa97b57bSdrh }
1578aa97b57bSdrh if( pNode ){
1579aa97b57bSdrh if( flags & JSON_JSON ){
1580d83c90bdSdrh jsonReturnJson(pNode, ctx, 0);
1581d83c90bdSdrh }else{
1582d83c90bdSdrh jsonReturn(pNode, ctx, 0);
1583d83c90bdSdrh sqlite3_result_subtype(ctx, 0);
1584d83c90bdSdrh }
1585d83c90bdSdrh }
1586daefcd9eSdrh }else{
1587daefcd9eSdrh pNode = jsonLookup(p, zPath, 0, ctx);
1588d83c90bdSdrh if( p->nErr==0 && pNode ) jsonReturn(pNode, ctx, 0);
1589daefcd9eSdrh }
1590daefcd9eSdrh }else{
1591daefcd9eSdrh /* Two or more PATH arguments results in a JSON array with each
1592daefcd9eSdrh ** element of the array being the value selected by one of the PATHs */
1593daefcd9eSdrh int i;
15949dbf96bdSdrh jsonInit(&jx, ctx);
15959dbf96bdSdrh jsonAppendChar(&jx, '[');
15969dbf96bdSdrh for(i=1; i<argc; i++){
15979dbf96bdSdrh zPath = (const char*)sqlite3_value_text(argv[i]);
15989dbf96bdSdrh pNode = jsonLookup(p, zPath, 0, ctx);
15999dbf96bdSdrh if( p->nErr ) break;
16009dbf96bdSdrh jsonAppendSeparator(&jx);
16019dbf96bdSdrh if( pNode ){
16029dbf96bdSdrh jsonRenderNode(pNode, &jx, 0);
16039dbf96bdSdrh }else{
16049dbf96bdSdrh jsonAppendRaw(&jx, "null", 4);
16059dbf96bdSdrh }
16069dbf96bdSdrh }
1607daefcd9eSdrh if( i==argc ){
16089dbf96bdSdrh jsonAppendChar(&jx, ']');
16099dbf96bdSdrh jsonResult(&jx);
16109dbf96bdSdrh sqlite3_result_subtype(ctx, JSON_SUBTYPE);
16119dbf96bdSdrh }
16129dbf96bdSdrh jsonReset(&jx);
16139dbf96bdSdrh }
1614daefcd9eSdrh }
16159dbf96bdSdrh
16169dbf96bdSdrh /* This is the RFC 7396 MergePatch algorithm.
16179dbf96bdSdrh */
jsonMergePatch(JsonParse * pParse,u32 iTarget,JsonNode * pPatch)16189dbf96bdSdrh static JsonNode *jsonMergePatch(
16199dbf96bdSdrh JsonParse *pParse, /* The JSON parser that contains the TARGET */
16209dbf96bdSdrh u32 iTarget, /* Node of the TARGET in pParse */
16219dbf96bdSdrh JsonNode *pPatch /* The PATCH */
16229dbf96bdSdrh ){
16239dbf96bdSdrh u32 i, j;
16249dbf96bdSdrh u32 iRoot;
16259dbf96bdSdrh JsonNode *pTarget;
16269dbf96bdSdrh if( pPatch->eType!=JSON_OBJECT ){
16279dbf96bdSdrh return pPatch;
16289dbf96bdSdrh }
1629e684ac6fSdrh assert( iTarget<pParse->nNode );
16309dbf96bdSdrh pTarget = &pParse->aNode[iTarget];
16319dbf96bdSdrh assert( (pPatch->jnFlags & JNODE_APPEND)==0 );
16329dbf96bdSdrh if( pTarget->eType!=JSON_OBJECT ){
16339dbf96bdSdrh jsonRemoveAllNulls(pPatch);
16349dbf96bdSdrh return pPatch;
16359dbf96bdSdrh }
16369dbf96bdSdrh iRoot = iTarget;
16379dbf96bdSdrh for(i=1; i<pPatch->n; i += jsonNodeSize(&pPatch[i+1])+1){
16389dbf96bdSdrh u32 nKey;
16399dbf96bdSdrh const char *zKey;
16409dbf96bdSdrh assert( pPatch[i].eType==JSON_STRING );
16419dbf96bdSdrh assert( pPatch[i].jnFlags & JNODE_LABEL );
16429dbf96bdSdrh assert( pPatch[i].eU==1 );
16439dbf96bdSdrh nKey = pPatch[i].n;
16449dbf96bdSdrh zKey = pPatch[i].u.zJContent;
16459dbf96bdSdrh assert( (pPatch[i].jnFlags & JNODE_RAW)==0 );
16469dbf96bdSdrh for(j=1; j<pTarget->n; j += jsonNodeSize(&pTarget[j+1])+1 ){
16479dbf96bdSdrh assert( pTarget[j].eType==JSON_STRING );
16489dbf96bdSdrh assert( pTarget[j].jnFlags & JNODE_LABEL );
16499dbf96bdSdrh assert( (pPatch[i].jnFlags & JNODE_RAW)==0 );
16509dbf96bdSdrh if( pTarget[j].n==nKey && strncmp(pTarget[j].u.zJContent,zKey,nKey)==0 ){
16519dbf96bdSdrh if( pTarget[j+1].jnFlags & (JNODE_REMOVE|JNODE_PATCH) ) break;
16529dbf96bdSdrh if( pPatch[i+1].eType==JSON_NULL ){
16539dbf96bdSdrh pTarget[j+1].jnFlags |= JNODE_REMOVE;
16549dbf96bdSdrh }else{
16559dbf96bdSdrh JsonNode *pNew = jsonMergePatch(pParse, iTarget+j+1, &pPatch[i+1]);
16569dbf96bdSdrh if( pNew==0 ) return 0;
16579dbf96bdSdrh pTarget = &pParse->aNode[iTarget];
16589dbf96bdSdrh if( pNew!=&pTarget[j+1] ){
16599dbf96bdSdrh assert( pTarget[j+1].eU==0
16609dbf96bdSdrh || pTarget[j+1].eU==1
16619dbf96bdSdrh || pTarget[j+1].eU==2 );
16629dbf96bdSdrh testcase( pTarget[j+1].eU==1 );
16639dbf96bdSdrh testcase( pTarget[j+1].eU==2 );
16649dbf96bdSdrh VVA( pTarget[j+1].eU = 5 );
16659dbf96bdSdrh pTarget[j+1].u.pPatch = pNew;
16669dbf96bdSdrh pTarget[j+1].jnFlags |= JNODE_PATCH;
16679dbf96bdSdrh }
16689dbf96bdSdrh }
16699dbf96bdSdrh break;
16709dbf96bdSdrh }
16719dbf96bdSdrh }
16729dbf96bdSdrh if( j>=pTarget->n && pPatch[i+1].eType!=JSON_NULL ){
16739dbf96bdSdrh int iStart, iPatch;
16749dbf96bdSdrh iStart = jsonParseAddNode(pParse, JSON_OBJECT, 2, 0);
16759dbf96bdSdrh jsonParseAddNode(pParse, JSON_STRING, nKey, zKey);
16769dbf96bdSdrh iPatch = jsonParseAddNode(pParse, JSON_TRUE, 0, 0);
16779dbf96bdSdrh if( pParse->oom ) return 0;
16789dbf96bdSdrh jsonRemoveAllNulls(pPatch);
16799dbf96bdSdrh pTarget = &pParse->aNode[iTarget];
16809dbf96bdSdrh assert( pParse->aNode[iRoot].eU==0 || pParse->aNode[iRoot].eU==2 );
16819dbf96bdSdrh testcase( pParse->aNode[iRoot].eU==2 );
16829dbf96bdSdrh pParse->aNode[iRoot].jnFlags |= JNODE_APPEND;
16839dbf96bdSdrh VVA( pParse->aNode[iRoot].eU = 2 );
16849dbf96bdSdrh pParse->aNode[iRoot].u.iAppend = iStart - iRoot;
16859dbf96bdSdrh iRoot = iStart;
16869dbf96bdSdrh assert( pParse->aNode[iPatch].eU==0 );
16879dbf96bdSdrh VVA( pParse->aNode[iPatch].eU = 5 );
16889dbf96bdSdrh pParse->aNode[iPatch].jnFlags |= JNODE_PATCH;
16899dbf96bdSdrh pParse->aNode[iPatch].u.pPatch = &pPatch[i+1];
16909dbf96bdSdrh }
16919dbf96bdSdrh }
16929dbf96bdSdrh return pTarget;
16939dbf96bdSdrh }
16949dbf96bdSdrh
16959dbf96bdSdrh /*
16969dbf96bdSdrh ** Implementation of the json_mergepatch(JSON1,JSON2) function. Return a JSON
16979dbf96bdSdrh ** object that is the result of running the RFC 7396 MergePatch() algorithm
16989dbf96bdSdrh ** on the two arguments.
16999dbf96bdSdrh */
jsonPatchFunc(sqlite3_context * ctx,int argc,sqlite3_value ** argv)17009dbf96bdSdrh static void jsonPatchFunc(
17019dbf96bdSdrh sqlite3_context *ctx,
17029dbf96bdSdrh int argc,
17039dbf96bdSdrh sqlite3_value **argv
17049dbf96bdSdrh ){
17059dbf96bdSdrh JsonParse x; /* The JSON that is being patched */
17069dbf96bdSdrh JsonParse y; /* The patch */
17079dbf96bdSdrh JsonNode *pResult; /* The result of the merge */
17089dbf96bdSdrh
17099dbf96bdSdrh UNUSED_PARAMETER(argc);
17109dbf96bdSdrh if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return;
17119dbf96bdSdrh if( jsonParse(&y, ctx, (const char*)sqlite3_value_text(argv[1])) ){
17129dbf96bdSdrh jsonParseReset(&x);
17139dbf96bdSdrh return;
17149dbf96bdSdrh }
17159dbf96bdSdrh pResult = jsonMergePatch(&x, 0, y.aNode);
17169dbf96bdSdrh assert( pResult!=0 || x.oom );
17179dbf96bdSdrh if( pResult ){
17189dbf96bdSdrh jsonReturnJson(pResult, ctx, 0);
17199dbf96bdSdrh }else{
17209dbf96bdSdrh sqlite3_result_error_nomem(ctx);
17219dbf96bdSdrh }
17229dbf96bdSdrh jsonParseReset(&x);
17239dbf96bdSdrh jsonParseReset(&y);
17249dbf96bdSdrh }
17259dbf96bdSdrh
17269dbf96bdSdrh
17279dbf96bdSdrh /*
17289dbf96bdSdrh ** Implementation of the json_object(NAME,VALUE,...) function. Return a JSON
17299dbf96bdSdrh ** object that contains all name/value given in arguments. Or if any name
17309dbf96bdSdrh ** is not a string or if any value is a BLOB, throw an error.
17319dbf96bdSdrh */
jsonObjectFunc(sqlite3_context * ctx,int argc,sqlite3_value ** argv)17329dbf96bdSdrh static void jsonObjectFunc(
17339dbf96bdSdrh sqlite3_context *ctx,
17349dbf96bdSdrh int argc,
17359dbf96bdSdrh sqlite3_value **argv
17369dbf96bdSdrh ){
17379dbf96bdSdrh int i;
17389dbf96bdSdrh JsonString jx;
17399dbf96bdSdrh const char *z;
17409dbf96bdSdrh u32 n;
17419dbf96bdSdrh
17429dbf96bdSdrh if( argc&1 ){
17439dbf96bdSdrh sqlite3_result_error(ctx, "json_object() requires an even number "
17449dbf96bdSdrh "of arguments", -1);
17459dbf96bdSdrh return;
17469dbf96bdSdrh }
17479dbf96bdSdrh jsonInit(&jx, ctx);
17489dbf96bdSdrh jsonAppendChar(&jx, '{');
17499dbf96bdSdrh for(i=0; i<argc; i+=2){
17509dbf96bdSdrh if( sqlite3_value_type(argv[i])!=SQLITE_TEXT ){
17519dbf96bdSdrh sqlite3_result_error(ctx, "json_object() labels must be TEXT", -1);
17529dbf96bdSdrh jsonReset(&jx);
17539dbf96bdSdrh return;
17549dbf96bdSdrh }
17559dbf96bdSdrh jsonAppendSeparator(&jx);
17569dbf96bdSdrh z = (const char*)sqlite3_value_text(argv[i]);
17579dbf96bdSdrh n = (u32)sqlite3_value_bytes(argv[i]);
17589dbf96bdSdrh jsonAppendString(&jx, z, n);
17599dbf96bdSdrh jsonAppendChar(&jx, ':');
17609dbf96bdSdrh jsonAppendValue(&jx, argv[i+1]);
17619dbf96bdSdrh }
17629dbf96bdSdrh jsonAppendChar(&jx, '}');
17639dbf96bdSdrh jsonResult(&jx);
17649dbf96bdSdrh sqlite3_result_subtype(ctx, JSON_SUBTYPE);
17659dbf96bdSdrh }
17669dbf96bdSdrh
17679dbf96bdSdrh
17689dbf96bdSdrh /*
17699dbf96bdSdrh ** json_remove(JSON, PATH, ...)
17709dbf96bdSdrh **
17719dbf96bdSdrh ** Remove the named elements from JSON and return the result. malformed
17729dbf96bdSdrh ** JSON or PATH arguments result in an error.
17739dbf96bdSdrh */
jsonRemoveFunc(sqlite3_context * ctx,int argc,sqlite3_value ** argv)17749dbf96bdSdrh static void jsonRemoveFunc(
17759dbf96bdSdrh sqlite3_context *ctx,
17769dbf96bdSdrh int argc,
17779dbf96bdSdrh sqlite3_value **argv
17789dbf96bdSdrh ){
17799dbf96bdSdrh JsonParse x; /* The parse */
17809dbf96bdSdrh JsonNode *pNode;
17819dbf96bdSdrh const char *zPath;
17829dbf96bdSdrh u32 i;
17839dbf96bdSdrh
17849dbf96bdSdrh if( argc<1 ) return;
17859dbf96bdSdrh if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return;
17869dbf96bdSdrh assert( x.nNode );
17879dbf96bdSdrh for(i=1; i<(u32)argc; i++){
17889dbf96bdSdrh zPath = (const char*)sqlite3_value_text(argv[i]);
17899dbf96bdSdrh if( zPath==0 ) goto remove_done;
17909dbf96bdSdrh pNode = jsonLookup(&x, zPath, 0, ctx);
17919dbf96bdSdrh if( x.nErr ) goto remove_done;
17929dbf96bdSdrh if( pNode ) pNode->jnFlags |= JNODE_REMOVE;
17939dbf96bdSdrh }
17949dbf96bdSdrh if( (x.aNode[0].jnFlags & JNODE_REMOVE)==0 ){
17959dbf96bdSdrh jsonReturnJson(x.aNode, ctx, 0);
17969dbf96bdSdrh }
17979dbf96bdSdrh remove_done:
17989dbf96bdSdrh jsonParseReset(&x);
17999dbf96bdSdrh }
18009dbf96bdSdrh
18019dbf96bdSdrh /*
18029dbf96bdSdrh ** json_replace(JSON, PATH, VALUE, ...)
18039dbf96bdSdrh **
18049dbf96bdSdrh ** Replace the value at PATH with VALUE. If PATH does not already exist,
18059dbf96bdSdrh ** this routine is a no-op. If JSON or PATH is malformed, throw an error.
18069dbf96bdSdrh */
jsonReplaceFunc(sqlite3_context * ctx,int argc,sqlite3_value ** argv)18079dbf96bdSdrh static void jsonReplaceFunc(
18089dbf96bdSdrh sqlite3_context *ctx,
18099dbf96bdSdrh int argc,
18109dbf96bdSdrh sqlite3_value **argv
18119dbf96bdSdrh ){
18129dbf96bdSdrh JsonParse x; /* The parse */
18139dbf96bdSdrh JsonNode *pNode;
18149dbf96bdSdrh const char *zPath;
18159dbf96bdSdrh u32 i;
18169dbf96bdSdrh
18179dbf96bdSdrh if( argc<1 ) return;
18189dbf96bdSdrh if( (argc&1)==0 ) {
18199dbf96bdSdrh jsonWrongNumArgs(ctx, "replace");
18209dbf96bdSdrh return;
18219dbf96bdSdrh }
18229dbf96bdSdrh if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return;
18239dbf96bdSdrh assert( x.nNode );
18249dbf96bdSdrh for(i=1; i<(u32)argc; i+=2){
18259dbf96bdSdrh zPath = (const char*)sqlite3_value_text(argv[i]);
18269dbf96bdSdrh pNode = jsonLookup(&x, zPath, 0, ctx);
18279dbf96bdSdrh if( x.nErr ) goto replace_err;
18289dbf96bdSdrh if( pNode ){
18299dbf96bdSdrh assert( pNode->eU==0 || pNode->eU==1 || pNode->eU==4 );
18309dbf96bdSdrh testcase( pNode->eU!=0 && pNode->eU!=1 );
18319dbf96bdSdrh pNode->jnFlags |= (u8)JNODE_REPLACE;
18329dbf96bdSdrh VVA( pNode->eU = 4 );
18339dbf96bdSdrh pNode->u.iReplace = i + 1;
18349dbf96bdSdrh }
18359dbf96bdSdrh }
18369dbf96bdSdrh if( x.aNode[0].jnFlags & JNODE_REPLACE ){
18379dbf96bdSdrh assert( x.aNode[0].eU==4 );
18389dbf96bdSdrh sqlite3_result_value(ctx, argv[x.aNode[0].u.iReplace]);
18399dbf96bdSdrh }else{
18409dbf96bdSdrh jsonReturnJson(x.aNode, ctx, argv);
18419dbf96bdSdrh }
18429dbf96bdSdrh replace_err:
18439dbf96bdSdrh jsonParseReset(&x);
18449dbf96bdSdrh }
18459dbf96bdSdrh
1846daefcd9eSdrh
18479dbf96bdSdrh /*
18489dbf96bdSdrh ** json_set(JSON, PATH, VALUE, ...)
18499dbf96bdSdrh **
18509dbf96bdSdrh ** Set the value at PATH to VALUE. Create the PATH if it does not already
18519dbf96bdSdrh ** exist. Overwrite existing values that do exist.
18529dbf96bdSdrh ** If JSON or PATH is malformed, throw an error.
18539dbf96bdSdrh **
18549dbf96bdSdrh ** json_insert(JSON, PATH, VALUE, ...)
18559dbf96bdSdrh **
18569dbf96bdSdrh ** Create PATH and initialize it to VALUE. If PATH already exists, this
18579dbf96bdSdrh ** routine is a no-op. If JSON or PATH is malformed, throw an error.
18589dbf96bdSdrh */
jsonSetFunc(sqlite3_context * ctx,int argc,sqlite3_value ** argv)18599dbf96bdSdrh static void jsonSetFunc(
18609dbf96bdSdrh sqlite3_context *ctx,
18619dbf96bdSdrh int argc,
18629dbf96bdSdrh sqlite3_value **argv
18639dbf96bdSdrh ){
18649dbf96bdSdrh JsonParse x; /* The parse */
18659dbf96bdSdrh JsonNode *pNode;
18669dbf96bdSdrh const char *zPath;
18679dbf96bdSdrh u32 i;
18689dbf96bdSdrh int bApnd;
18699dbf96bdSdrh int bIsSet = sqlite3_user_data(ctx)!=0;
18709dbf96bdSdrh
18719dbf96bdSdrh if( argc<1 ) return;
18729dbf96bdSdrh if( (argc&1)==0 ) {
18739dbf96bdSdrh jsonWrongNumArgs(ctx, bIsSet ? "set" : "insert");
18749dbf96bdSdrh return;
18759dbf96bdSdrh }
18769dbf96bdSdrh if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return;
18779dbf96bdSdrh assert( x.nNode );
18789dbf96bdSdrh for(i=1; i<(u32)argc; i+=2){
18799dbf96bdSdrh zPath = (const char*)sqlite3_value_text(argv[i]);
18809dbf96bdSdrh bApnd = 0;
18819dbf96bdSdrh pNode = jsonLookup(&x, zPath, &bApnd, ctx);
18829dbf96bdSdrh if( x.oom ){
18839dbf96bdSdrh sqlite3_result_error_nomem(ctx);
18849dbf96bdSdrh goto jsonSetDone;
18859dbf96bdSdrh }else if( x.nErr ){
18869dbf96bdSdrh goto jsonSetDone;
18879dbf96bdSdrh }else if( pNode && (bApnd || bIsSet) ){
188814818366Sdrh testcase( pNode->eU!=0 && pNode->eU!=1 );
188914818366Sdrh assert( pNode->eU!=3 && pNode->eU!=5 );
18909dbf96bdSdrh VVA( pNode->eU = 4 );
18919dbf96bdSdrh pNode->jnFlags |= (u8)JNODE_REPLACE;
18929dbf96bdSdrh pNode->u.iReplace = i + 1;
18939dbf96bdSdrh }
18949dbf96bdSdrh }
18959dbf96bdSdrh if( x.aNode[0].jnFlags & JNODE_REPLACE ){
18969dbf96bdSdrh assert( x.aNode[0].eU==4 );
18979dbf96bdSdrh sqlite3_result_value(ctx, argv[x.aNode[0].u.iReplace]);
18989dbf96bdSdrh }else{
18999dbf96bdSdrh jsonReturnJson(x.aNode, ctx, argv);
19009dbf96bdSdrh }
19019dbf96bdSdrh jsonSetDone:
19029dbf96bdSdrh jsonParseReset(&x);
19039dbf96bdSdrh }
19049dbf96bdSdrh
19059dbf96bdSdrh /*
19069dbf96bdSdrh ** json_type(JSON)
19079dbf96bdSdrh ** json_type(JSON, PATH)
19089dbf96bdSdrh **
1909daefcd9eSdrh ** Return the top-level "type" of a JSON string. json_type() raises an
1910a6c596b1Sdrh ** error if either the JSON or PATH inputs are not well-formed.
19119dbf96bdSdrh */
jsonTypeFunc(sqlite3_context * ctx,int argc,sqlite3_value ** argv)19129dbf96bdSdrh static void jsonTypeFunc(
19139dbf96bdSdrh sqlite3_context *ctx,
19149dbf96bdSdrh int argc,
19159dbf96bdSdrh sqlite3_value **argv
19169dbf96bdSdrh ){
19179dbf96bdSdrh JsonParse *p; /* The parse */
19189dbf96bdSdrh const char *zPath;
19199dbf96bdSdrh JsonNode *pNode;
19209dbf96bdSdrh
1921a6c596b1Sdrh p = jsonParseCached(ctx, argv, ctx);
19229dbf96bdSdrh if( p==0 ) return;
19239dbf96bdSdrh if( argc==2 ){
19249dbf96bdSdrh zPath = (const char*)sqlite3_value_text(argv[1]);
19259dbf96bdSdrh pNode = jsonLookup(p, zPath, 0, ctx);
19269dbf96bdSdrh }else{
19279dbf96bdSdrh pNode = p->aNode;
19289dbf96bdSdrh }
19299dbf96bdSdrh if( pNode ){
19309dbf96bdSdrh sqlite3_result_text(ctx, jsonType[pNode->eType], -1, SQLITE_STATIC);
19319dbf96bdSdrh }
19329dbf96bdSdrh }
19339dbf96bdSdrh
19349dbf96bdSdrh /*
19359dbf96bdSdrh ** json_valid(JSON)
19369dbf96bdSdrh **
19379dbf96bdSdrh ** Return 1 if JSON is a well-formed JSON string according to RFC-7159.
19389dbf96bdSdrh ** Return 0 otherwise.
19399dbf96bdSdrh */
jsonValidFunc(sqlite3_context * ctx,int argc,sqlite3_value ** argv)19409dbf96bdSdrh static void jsonValidFunc(
19419dbf96bdSdrh sqlite3_context *ctx,
19429dbf96bdSdrh int argc,
19439dbf96bdSdrh sqlite3_value **argv
19449dbf96bdSdrh ){
19459dbf96bdSdrh JsonParse *p; /* The parse */
19469dbf96bdSdrh UNUSED_PARAMETER(argc);
19479dbf96bdSdrh p = jsonParseCached(ctx, argv, 0);
19489dbf96bdSdrh sqlite3_result_int(ctx, p!=0);
19499dbf96bdSdrh }
19509dbf96bdSdrh
19519dbf96bdSdrh
19529dbf96bdSdrh /****************************************************************************
19539dbf96bdSdrh ** Aggregate SQL function implementations
19549dbf96bdSdrh ****************************************************************************/
19559dbf96bdSdrh /*
19569dbf96bdSdrh ** json_group_array(VALUE)
19579dbf96bdSdrh **
19589dbf96bdSdrh ** Return a JSON array composed of all values in the aggregate.
19599dbf96bdSdrh */
jsonArrayStep(sqlite3_context * ctx,int argc,sqlite3_value ** argv)19609dbf96bdSdrh static void jsonArrayStep(
19619dbf96bdSdrh sqlite3_context *ctx,
19629dbf96bdSdrh int argc,
19639dbf96bdSdrh sqlite3_value **argv
19649dbf96bdSdrh ){
19659dbf96bdSdrh JsonString *pStr;
19669dbf96bdSdrh UNUSED_PARAMETER(argc);
19679dbf96bdSdrh pStr = (JsonString*)sqlite3_aggregate_context(ctx, sizeof(*pStr));
19689dbf96bdSdrh if( pStr ){
19699dbf96bdSdrh if( pStr->zBuf==0 ){
19709dbf96bdSdrh jsonInit(pStr, ctx);
19719dbf96bdSdrh jsonAppendChar(pStr, '[');
19729dbf96bdSdrh }else if( pStr->nUsed>1 ){
19739dbf96bdSdrh jsonAppendChar(pStr, ',');
19749dbf96bdSdrh }
19759dbf96bdSdrh pStr->pCtx = ctx;
19769dbf96bdSdrh jsonAppendValue(pStr, argv[0]);
19779dbf96bdSdrh }
19789dbf96bdSdrh }
jsonArrayCompute(sqlite3_context * ctx,int isFinal)19799dbf96bdSdrh static void jsonArrayCompute(sqlite3_context *ctx, int isFinal){
19809dbf96bdSdrh JsonString *pStr;
19819dbf96bdSdrh pStr = (JsonString*)sqlite3_aggregate_context(ctx, 0);
19829dbf96bdSdrh if( pStr ){
19839dbf96bdSdrh pStr->pCtx = ctx;
19849dbf96bdSdrh jsonAppendChar(pStr, ']');
19859dbf96bdSdrh if( pStr->bErr ){
19869dbf96bdSdrh if( pStr->bErr==1 ) sqlite3_result_error_nomem(ctx);
19879dbf96bdSdrh assert( pStr->bStatic );
19889dbf96bdSdrh }else if( isFinal ){
19899dbf96bdSdrh sqlite3_result_text(ctx, pStr->zBuf, (int)pStr->nUsed,
19909dbf96bdSdrh pStr->bStatic ? SQLITE_TRANSIENT : sqlite3_free);
19919dbf96bdSdrh pStr->bStatic = 1;
19929dbf96bdSdrh }else{
19939dbf96bdSdrh sqlite3_result_text(ctx, pStr->zBuf, (int)pStr->nUsed, SQLITE_TRANSIENT);
19949dbf96bdSdrh pStr->nUsed--;
19959dbf96bdSdrh }
19969dbf96bdSdrh }else{
19979dbf96bdSdrh sqlite3_result_text(ctx, "[]", 2, SQLITE_STATIC);
19989dbf96bdSdrh }
19999dbf96bdSdrh sqlite3_result_subtype(ctx, JSON_SUBTYPE);
20009dbf96bdSdrh }
jsonArrayValue(sqlite3_context * ctx)20019dbf96bdSdrh static void jsonArrayValue(sqlite3_context *ctx){
20029dbf96bdSdrh jsonArrayCompute(ctx, 0);
20039dbf96bdSdrh }
jsonArrayFinal(sqlite3_context * ctx)20049dbf96bdSdrh static void jsonArrayFinal(sqlite3_context *ctx){
20059dbf96bdSdrh jsonArrayCompute(ctx, 1);
20069dbf96bdSdrh }
20079dbf96bdSdrh
20089dbf96bdSdrh #ifndef SQLITE_OMIT_WINDOWFUNC
20099dbf96bdSdrh /*
20109dbf96bdSdrh ** This method works for both json_group_array() and json_group_object().
20119dbf96bdSdrh ** It works by removing the first element of the group by searching forward
20129dbf96bdSdrh ** to the first comma (",") that is not within a string and deleting all
20139dbf96bdSdrh ** text through that comma.
20149dbf96bdSdrh */
jsonGroupInverse(sqlite3_context * ctx,int argc,sqlite3_value ** argv)20159dbf96bdSdrh static void jsonGroupInverse(
20169dbf96bdSdrh sqlite3_context *ctx,
20179dbf96bdSdrh int argc,
20189dbf96bdSdrh sqlite3_value **argv
20199dbf96bdSdrh ){
20209dbf96bdSdrh unsigned int i;
20219dbf96bdSdrh int inStr = 0;
20229dbf96bdSdrh int nNest = 0;
20239dbf96bdSdrh char *z;
20249dbf96bdSdrh char c;
20259dbf96bdSdrh JsonString *pStr;
20269dbf96bdSdrh UNUSED_PARAMETER(argc);
20279dbf96bdSdrh UNUSED_PARAMETER(argv);
20289dbf96bdSdrh pStr = (JsonString*)sqlite3_aggregate_context(ctx, 0);
20299dbf96bdSdrh #ifdef NEVER
20309dbf96bdSdrh /* pStr is always non-NULL since jsonArrayStep() or jsonObjectStep() will
20319dbf96bdSdrh ** always have been called to initalize it */
20329dbf96bdSdrh if( NEVER(!pStr) ) return;
20339dbf96bdSdrh #endif
20349dbf96bdSdrh z = pStr->zBuf;
20359dbf96bdSdrh for(i=1; i<pStr->nUsed && ((c = z[i])!=',' || inStr || nNest); i++){
20369dbf96bdSdrh if( c=='"' ){
20379dbf96bdSdrh inStr = !inStr;
20389dbf96bdSdrh }else if( c=='\\' ){
20399dbf96bdSdrh i++;
20409dbf96bdSdrh }else if( !inStr ){
20419dbf96bdSdrh if( c=='{' || c=='[' ) nNest++;
20429dbf96bdSdrh if( c=='}' || c==']' ) nNest--;
20439dbf96bdSdrh }
20449dbf96bdSdrh }
20459dbf96bdSdrh if( i<pStr->nUsed ){
20469dbf96bdSdrh pStr->nUsed -= i;
20479dbf96bdSdrh memmove(&z[1], &z[i+1], (size_t)pStr->nUsed-1);
20489dbf96bdSdrh z[pStr->nUsed] = 0;
20499dbf96bdSdrh }else{
20509dbf96bdSdrh pStr->nUsed = 1;
20519dbf96bdSdrh }
20529dbf96bdSdrh }
20539dbf96bdSdrh #else
20549dbf96bdSdrh # define jsonGroupInverse 0
20559dbf96bdSdrh #endif
20569dbf96bdSdrh
20579dbf96bdSdrh
20589dbf96bdSdrh /*
20599dbf96bdSdrh ** json_group_obj(NAME,VALUE)
20609dbf96bdSdrh **
20619dbf96bdSdrh ** Return a JSON object composed of all names and values in the aggregate.
20629dbf96bdSdrh */
jsonObjectStep(sqlite3_context * ctx,int argc,sqlite3_value ** argv)20639dbf96bdSdrh static void jsonObjectStep(
20649dbf96bdSdrh sqlite3_context *ctx,
20659dbf96bdSdrh int argc,
20669dbf96bdSdrh sqlite3_value **argv
20679dbf96bdSdrh ){
20689dbf96bdSdrh JsonString *pStr;
20699dbf96bdSdrh const char *z;
20709dbf96bdSdrh u32 n;
20719dbf96bdSdrh UNUSED_PARAMETER(argc);
20729dbf96bdSdrh pStr = (JsonString*)sqlite3_aggregate_context(ctx, sizeof(*pStr));
20739dbf96bdSdrh if( pStr ){
20749dbf96bdSdrh if( pStr->zBuf==0 ){
20759dbf96bdSdrh jsonInit(pStr, ctx);
20769dbf96bdSdrh jsonAppendChar(pStr, '{');
20779dbf96bdSdrh }else if( pStr->nUsed>1 ){
20789dbf96bdSdrh jsonAppendChar(pStr, ',');
20799dbf96bdSdrh }
20809dbf96bdSdrh pStr->pCtx = ctx;
20819dbf96bdSdrh z = (const char*)sqlite3_value_text(argv[0]);
20829dbf96bdSdrh n = (u32)sqlite3_value_bytes(argv[0]);
20839dbf96bdSdrh jsonAppendString(pStr, z, n);
20849dbf96bdSdrh jsonAppendChar(pStr, ':');
20859dbf96bdSdrh jsonAppendValue(pStr, argv[1]);
20869dbf96bdSdrh }
20879dbf96bdSdrh }
jsonObjectCompute(sqlite3_context * ctx,int isFinal)20889dbf96bdSdrh static void jsonObjectCompute(sqlite3_context *ctx, int isFinal){
20899dbf96bdSdrh JsonString *pStr;
20909dbf96bdSdrh pStr = (JsonString*)sqlite3_aggregate_context(ctx, 0);
20919dbf96bdSdrh if( pStr ){
20929dbf96bdSdrh jsonAppendChar(pStr, '}');
20939dbf96bdSdrh if( pStr->bErr ){
20949dbf96bdSdrh if( pStr->bErr==1 ) sqlite3_result_error_nomem(ctx);
20959dbf96bdSdrh assert( pStr->bStatic );
20969dbf96bdSdrh }else if( isFinal ){
20979dbf96bdSdrh sqlite3_result_text(ctx, pStr->zBuf, (int)pStr->nUsed,
20989dbf96bdSdrh pStr->bStatic ? SQLITE_TRANSIENT : sqlite3_free);
20999dbf96bdSdrh pStr->bStatic = 1;
21009dbf96bdSdrh }else{
21019dbf96bdSdrh sqlite3_result_text(ctx, pStr->zBuf, (int)pStr->nUsed, SQLITE_TRANSIENT);
21029dbf96bdSdrh pStr->nUsed--;
21039dbf96bdSdrh }
21049dbf96bdSdrh }else{
21059dbf96bdSdrh sqlite3_result_text(ctx, "{}", 2, SQLITE_STATIC);
21069dbf96bdSdrh }
21079dbf96bdSdrh sqlite3_result_subtype(ctx, JSON_SUBTYPE);
21089dbf96bdSdrh }
jsonObjectValue(sqlite3_context * ctx)21099dbf96bdSdrh static void jsonObjectValue(sqlite3_context *ctx){
21109dbf96bdSdrh jsonObjectCompute(ctx, 0);
21119dbf96bdSdrh }
jsonObjectFinal(sqlite3_context * ctx)21129dbf96bdSdrh static void jsonObjectFinal(sqlite3_context *ctx){
21139dbf96bdSdrh jsonObjectCompute(ctx, 1);
21149dbf96bdSdrh }
21159dbf96bdSdrh
21169dbf96bdSdrh
21179dbf96bdSdrh
21189dbf96bdSdrh #ifndef SQLITE_OMIT_VIRTUALTABLE
21199dbf96bdSdrh /****************************************************************************
21209dbf96bdSdrh ** The json_each virtual table
21219dbf96bdSdrh ****************************************************************************/
21229dbf96bdSdrh typedef struct JsonEachCursor JsonEachCursor;
21239dbf96bdSdrh struct JsonEachCursor {
21249dbf96bdSdrh sqlite3_vtab_cursor base; /* Base class - must be first */
21259dbf96bdSdrh u32 iRowid; /* The rowid */
21269dbf96bdSdrh u32 iBegin; /* The first node of the scan */
21279dbf96bdSdrh u32 i; /* Index in sParse.aNode[] of current row */
21289dbf96bdSdrh u32 iEnd; /* EOF when i equals or exceeds this value */
21299dbf96bdSdrh u8 eType; /* Type of top-level element */
21309dbf96bdSdrh u8 bRecursive; /* True for json_tree(). False for json_each() */
21319dbf96bdSdrh char *zJson; /* Input JSON */
21329dbf96bdSdrh char *zRoot; /* Path by which to filter zJson */
21339dbf96bdSdrh JsonParse sParse; /* Parse of the input JSON */
21349dbf96bdSdrh };
21359dbf96bdSdrh
21369dbf96bdSdrh /* Constructor for the json_each virtual table */
jsonEachConnect(sqlite3 * db,void * pAux,int argc,const char * const * argv,sqlite3_vtab ** ppVtab,char ** pzErr)21379dbf96bdSdrh static int jsonEachConnect(
21389dbf96bdSdrh sqlite3 *db,
21399dbf96bdSdrh void *pAux,
21409dbf96bdSdrh int argc, const char *const*argv,
21419dbf96bdSdrh sqlite3_vtab **ppVtab,
21429dbf96bdSdrh char **pzErr
21439dbf96bdSdrh ){
21449dbf96bdSdrh sqlite3_vtab *pNew;
21459dbf96bdSdrh int rc;
21469dbf96bdSdrh
21479dbf96bdSdrh /* Column numbers */
21489dbf96bdSdrh #define JEACH_KEY 0
21499dbf96bdSdrh #define JEACH_VALUE 1
21509dbf96bdSdrh #define JEACH_TYPE 2
21519dbf96bdSdrh #define JEACH_ATOM 3
21529dbf96bdSdrh #define JEACH_ID 4
21539dbf96bdSdrh #define JEACH_PARENT 5
21549dbf96bdSdrh #define JEACH_FULLKEY 6
21559dbf96bdSdrh #define JEACH_PATH 7
21569dbf96bdSdrh /* The xBestIndex method assumes that the JSON and ROOT columns are
21579dbf96bdSdrh ** the last two columns in the table. Should this ever changes, be
21589dbf96bdSdrh ** sure to update the xBestIndex method. */
21599dbf96bdSdrh #define JEACH_JSON 8
21609dbf96bdSdrh #define JEACH_ROOT 9
21619dbf96bdSdrh
21629dbf96bdSdrh UNUSED_PARAMETER(pzErr);
21639dbf96bdSdrh UNUSED_PARAMETER(argv);
21649dbf96bdSdrh UNUSED_PARAMETER(argc);
21659dbf96bdSdrh UNUSED_PARAMETER(pAux);
21669dbf96bdSdrh rc = sqlite3_declare_vtab(db,
21679dbf96bdSdrh "CREATE TABLE x(key,value,type,atom,id,parent,fullkey,path,"
21689dbf96bdSdrh "json HIDDEN,root HIDDEN)");
21699dbf96bdSdrh if( rc==SQLITE_OK ){
21709dbf96bdSdrh pNew = *ppVtab = sqlite3_malloc( sizeof(*pNew) );
21719dbf96bdSdrh if( pNew==0 ) return SQLITE_NOMEM;
21729dbf96bdSdrh memset(pNew, 0, sizeof(*pNew));
21739dbf96bdSdrh sqlite3_vtab_config(db, SQLITE_VTAB_INNOCUOUS);
21749dbf96bdSdrh }
21759dbf96bdSdrh return rc;
21769dbf96bdSdrh }
21779dbf96bdSdrh
21789dbf96bdSdrh /* destructor for json_each virtual table */
jsonEachDisconnect(sqlite3_vtab * pVtab)21799dbf96bdSdrh static int jsonEachDisconnect(sqlite3_vtab *pVtab){
21809dbf96bdSdrh sqlite3_free(pVtab);
21819dbf96bdSdrh return SQLITE_OK;
21829dbf96bdSdrh }
21839dbf96bdSdrh
21849dbf96bdSdrh /* constructor for a JsonEachCursor object for json_each(). */
jsonEachOpenEach(sqlite3_vtab * p,sqlite3_vtab_cursor ** ppCursor)21859dbf96bdSdrh static int jsonEachOpenEach(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
21869dbf96bdSdrh JsonEachCursor *pCur;
21879dbf96bdSdrh
21889dbf96bdSdrh UNUSED_PARAMETER(p);
21899dbf96bdSdrh pCur = sqlite3_malloc( sizeof(*pCur) );
21909dbf96bdSdrh if( pCur==0 ) return SQLITE_NOMEM;
21919dbf96bdSdrh memset(pCur, 0, sizeof(*pCur));
21929dbf96bdSdrh *ppCursor = &pCur->base;
21939dbf96bdSdrh return SQLITE_OK;
21949dbf96bdSdrh }
21959dbf96bdSdrh
21969dbf96bdSdrh /* constructor for a JsonEachCursor object for json_tree(). */
jsonEachOpenTree(sqlite3_vtab * p,sqlite3_vtab_cursor ** ppCursor)21979dbf96bdSdrh static int jsonEachOpenTree(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
21989dbf96bdSdrh int rc = jsonEachOpenEach(p, ppCursor);
21999dbf96bdSdrh if( rc==SQLITE_OK ){
22009dbf96bdSdrh JsonEachCursor *pCur = (JsonEachCursor*)*ppCursor;
22019dbf96bdSdrh pCur->bRecursive = 1;
22029dbf96bdSdrh }
22039dbf96bdSdrh return rc;
22049dbf96bdSdrh }
22059dbf96bdSdrh
22069dbf96bdSdrh /* Reset a JsonEachCursor back to its original state. Free any memory
22079dbf96bdSdrh ** held. */
jsonEachCursorReset(JsonEachCursor * p)22089dbf96bdSdrh static void jsonEachCursorReset(JsonEachCursor *p){
22099dbf96bdSdrh sqlite3_free(p->zJson);
22109dbf96bdSdrh sqlite3_free(p->zRoot);
22119dbf96bdSdrh jsonParseReset(&p->sParse);
22129dbf96bdSdrh p->iRowid = 0;
22139dbf96bdSdrh p->i = 0;
22149dbf96bdSdrh p->iEnd = 0;
22159dbf96bdSdrh p->eType = 0;
22169dbf96bdSdrh p->zJson = 0;
22179dbf96bdSdrh p->zRoot = 0;
22189dbf96bdSdrh }
22199dbf96bdSdrh
22209dbf96bdSdrh /* Destructor for a jsonEachCursor object */
jsonEachClose(sqlite3_vtab_cursor * cur)22219dbf96bdSdrh static int jsonEachClose(sqlite3_vtab_cursor *cur){
22229dbf96bdSdrh JsonEachCursor *p = (JsonEachCursor*)cur;
22239dbf96bdSdrh jsonEachCursorReset(p);
22249dbf96bdSdrh sqlite3_free(cur);
22259dbf96bdSdrh return SQLITE_OK;
22269dbf96bdSdrh }
22279dbf96bdSdrh
22289dbf96bdSdrh /* Return TRUE if the jsonEachCursor object has been advanced off the end
22299dbf96bdSdrh ** of the JSON object */
jsonEachEof(sqlite3_vtab_cursor * cur)22309dbf96bdSdrh static int jsonEachEof(sqlite3_vtab_cursor *cur){
22319dbf96bdSdrh JsonEachCursor *p = (JsonEachCursor*)cur;
22329dbf96bdSdrh return p->i >= p->iEnd;
22339dbf96bdSdrh }
22349dbf96bdSdrh
22359dbf96bdSdrh /* Advance the cursor to the next element for json_tree() */
jsonEachNext(sqlite3_vtab_cursor * cur)22369dbf96bdSdrh static int jsonEachNext(sqlite3_vtab_cursor *cur){
22379dbf96bdSdrh JsonEachCursor *p = (JsonEachCursor*)cur;
22389dbf96bdSdrh if( p->bRecursive ){
22399dbf96bdSdrh if( p->sParse.aNode[p->i].jnFlags & JNODE_LABEL ) p->i++;
22409dbf96bdSdrh p->i++;
22419dbf96bdSdrh p->iRowid++;
22429dbf96bdSdrh if( p->i<p->iEnd ){
22439dbf96bdSdrh u32 iUp = p->sParse.aUp[p->i];
22449dbf96bdSdrh JsonNode *pUp = &p->sParse.aNode[iUp];
22459dbf96bdSdrh p->eType = pUp->eType;
22469dbf96bdSdrh if( pUp->eType==JSON_ARRAY ){
22479dbf96bdSdrh assert( pUp->eU==0 || pUp->eU==3 );
22489dbf96bdSdrh testcase( pUp->eU==3 );
22499dbf96bdSdrh VVA( pUp->eU = 3 );
22509dbf96bdSdrh if( iUp==p->i-1 ){
22519dbf96bdSdrh pUp->u.iKey = 0;
22529dbf96bdSdrh }else{
22539dbf96bdSdrh pUp->u.iKey++;
22549dbf96bdSdrh }
22559dbf96bdSdrh }
22569dbf96bdSdrh }
22579dbf96bdSdrh }else{
22589dbf96bdSdrh switch( p->eType ){
22599dbf96bdSdrh case JSON_ARRAY: {
22609dbf96bdSdrh p->i += jsonNodeSize(&p->sParse.aNode[p->i]);
22619dbf96bdSdrh p->iRowid++;
22629dbf96bdSdrh break;
22639dbf96bdSdrh }
22649dbf96bdSdrh case JSON_OBJECT: {
22659dbf96bdSdrh p->i += 1 + jsonNodeSize(&p->sParse.aNode[p->i+1]);
22669dbf96bdSdrh p->iRowid++;
22679dbf96bdSdrh break;
22689dbf96bdSdrh }
22699dbf96bdSdrh default: {
22709dbf96bdSdrh p->i = p->iEnd;
22719dbf96bdSdrh break;
22729dbf96bdSdrh }
22739dbf96bdSdrh }
22749dbf96bdSdrh }
22759dbf96bdSdrh return SQLITE_OK;
22769dbf96bdSdrh }
22779dbf96bdSdrh
2278*0de10ac1Sdrh /* Append an object label to the JSON Path being constructed
2279*0de10ac1Sdrh ** in pStr.
2280*0de10ac1Sdrh */
jsonAppendObjectPathElement(JsonString * pStr,JsonNode * pNode)2281*0de10ac1Sdrh static void jsonAppendObjectPathElement(
2282*0de10ac1Sdrh JsonString *pStr,
2283*0de10ac1Sdrh JsonNode *pNode
2284*0de10ac1Sdrh ){
2285*0de10ac1Sdrh int jj, nn;
2286*0de10ac1Sdrh const char *z;
2287*0de10ac1Sdrh assert( pNode->eType==JSON_STRING );
2288*0de10ac1Sdrh assert( pNode->jnFlags & JNODE_LABEL );
2289*0de10ac1Sdrh assert( pNode->eU==1 );
2290*0de10ac1Sdrh z = pNode->u.zJContent;
2291*0de10ac1Sdrh nn = pNode->n;
2292*0de10ac1Sdrh assert( nn>=2 );
2293*0de10ac1Sdrh assert( z[0]=='"' );
2294*0de10ac1Sdrh assert( z[nn-1]=='"' );
2295*0de10ac1Sdrh if( nn>2 && sqlite3Isalpha(z[1]) ){
2296*0de10ac1Sdrh for(jj=2; jj<nn-1 && sqlite3Isalnum(z[jj]); jj++){}
2297*0de10ac1Sdrh if( jj==nn-1 ){
2298*0de10ac1Sdrh z++;
2299*0de10ac1Sdrh nn -= 2;
2300*0de10ac1Sdrh }
2301*0de10ac1Sdrh }
2302*0de10ac1Sdrh jsonPrintf(nn+2, pStr, ".%.*s", nn, z);
2303*0de10ac1Sdrh }
2304*0de10ac1Sdrh
23059dbf96bdSdrh /* Append the name of the path for element i to pStr
23069dbf96bdSdrh */
jsonEachComputePath(JsonEachCursor * p,JsonString * pStr,u32 i)23079dbf96bdSdrh static void jsonEachComputePath(
23089dbf96bdSdrh JsonEachCursor *p, /* The cursor */
23099dbf96bdSdrh JsonString *pStr, /* Write the path here */
23109dbf96bdSdrh u32 i /* Path to this element */
23119dbf96bdSdrh ){
23129dbf96bdSdrh JsonNode *pNode, *pUp;
23139dbf96bdSdrh u32 iUp;
23149dbf96bdSdrh if( i==0 ){
23159dbf96bdSdrh jsonAppendChar(pStr, '$');
23169dbf96bdSdrh return;
23179dbf96bdSdrh }
23189dbf96bdSdrh iUp = p->sParse.aUp[i];
23199dbf96bdSdrh jsonEachComputePath(p, pStr, iUp);
23209dbf96bdSdrh pNode = &p->sParse.aNode[i];
23219dbf96bdSdrh pUp = &p->sParse.aNode[iUp];
23229dbf96bdSdrh if( pUp->eType==JSON_ARRAY ){
23239dbf96bdSdrh assert( pUp->eU==3 || (pUp->eU==0 && pUp->u.iKey==0) );
23249dbf96bdSdrh testcase( pUp->eU==0 );
23259dbf96bdSdrh jsonPrintf(30, pStr, "[%d]", pUp->u.iKey);
23269dbf96bdSdrh }else{
23279dbf96bdSdrh assert( pUp->eType==JSON_OBJECT );
23289dbf96bdSdrh if( (pNode->jnFlags & JNODE_LABEL)==0 ) pNode--;
2329*0de10ac1Sdrh jsonAppendObjectPathElement(pStr, pNode);
23309dbf96bdSdrh }
23319dbf96bdSdrh }
23329dbf96bdSdrh
23339dbf96bdSdrh /* Return the value of a column */
jsonEachColumn(sqlite3_vtab_cursor * cur,sqlite3_context * ctx,int i)23349dbf96bdSdrh static int jsonEachColumn(
23359dbf96bdSdrh sqlite3_vtab_cursor *cur, /* The cursor */
23369dbf96bdSdrh sqlite3_context *ctx, /* First argument to sqlite3_result_...() */
23379dbf96bdSdrh int i /* Which column to return */
23389dbf96bdSdrh ){
23399dbf96bdSdrh JsonEachCursor *p = (JsonEachCursor*)cur;
23409dbf96bdSdrh JsonNode *pThis = &p->sParse.aNode[p->i];
23419dbf96bdSdrh switch( i ){
23429dbf96bdSdrh case JEACH_KEY: {
23439dbf96bdSdrh if( p->i==0 ) break;
23449dbf96bdSdrh if( p->eType==JSON_OBJECT ){
23459dbf96bdSdrh jsonReturn(pThis, ctx, 0);
23469dbf96bdSdrh }else if( p->eType==JSON_ARRAY ){
23479dbf96bdSdrh u32 iKey;
23489dbf96bdSdrh if( p->bRecursive ){
23499dbf96bdSdrh if( p->iRowid==0 ) break;
23509dbf96bdSdrh assert( p->sParse.aNode[p->sParse.aUp[p->i]].eU==3 );
23519dbf96bdSdrh iKey = p->sParse.aNode[p->sParse.aUp[p->i]].u.iKey;
23529dbf96bdSdrh }else{
23539dbf96bdSdrh iKey = p->iRowid;
23549dbf96bdSdrh }
23559dbf96bdSdrh sqlite3_result_int64(ctx, (sqlite3_int64)iKey);
23569dbf96bdSdrh }
23579dbf96bdSdrh break;
23589dbf96bdSdrh }
23599dbf96bdSdrh case JEACH_VALUE: {
23609dbf96bdSdrh if( pThis->jnFlags & JNODE_LABEL ) pThis++;
23619dbf96bdSdrh jsonReturn(pThis, ctx, 0);
23629dbf96bdSdrh break;
23639dbf96bdSdrh }
23649dbf96bdSdrh case JEACH_TYPE: {
23659dbf96bdSdrh if( pThis->jnFlags & JNODE_LABEL ) pThis++;
23669dbf96bdSdrh sqlite3_result_text(ctx, jsonType[pThis->eType], -1, SQLITE_STATIC);
23679dbf96bdSdrh break;
23689dbf96bdSdrh }
23699dbf96bdSdrh case JEACH_ATOM: {
23709dbf96bdSdrh if( pThis->jnFlags & JNODE_LABEL ) pThis++;
23719dbf96bdSdrh if( pThis->eType>=JSON_ARRAY ) break;
23729dbf96bdSdrh jsonReturn(pThis, ctx, 0);
23739dbf96bdSdrh break;
23749dbf96bdSdrh }
23759dbf96bdSdrh case JEACH_ID: {
23769dbf96bdSdrh sqlite3_result_int64(ctx,
23779dbf96bdSdrh (sqlite3_int64)p->i + ((pThis->jnFlags & JNODE_LABEL)!=0));
23789dbf96bdSdrh break;
23799dbf96bdSdrh }
23809dbf96bdSdrh case JEACH_PARENT: {
23819dbf96bdSdrh if( p->i>p->iBegin && p->bRecursive ){
23829dbf96bdSdrh sqlite3_result_int64(ctx, (sqlite3_int64)p->sParse.aUp[p->i]);
23839dbf96bdSdrh }
23849dbf96bdSdrh break;
23859dbf96bdSdrh }
23869dbf96bdSdrh case JEACH_FULLKEY: {
23879dbf96bdSdrh JsonString x;
23889dbf96bdSdrh jsonInit(&x, ctx);
23899dbf96bdSdrh if( p->bRecursive ){
23909dbf96bdSdrh jsonEachComputePath(p, &x, p->i);
23919dbf96bdSdrh }else{
23929dbf96bdSdrh if( p->zRoot ){
23939dbf96bdSdrh jsonAppendRaw(&x, p->zRoot, (int)strlen(p->zRoot));
23949dbf96bdSdrh }else{
23959dbf96bdSdrh jsonAppendChar(&x, '$');
23969dbf96bdSdrh }
23979dbf96bdSdrh if( p->eType==JSON_ARRAY ){
23989dbf96bdSdrh jsonPrintf(30, &x, "[%d]", p->iRowid);
23999dbf96bdSdrh }else if( p->eType==JSON_OBJECT ){
2400*0de10ac1Sdrh jsonAppendObjectPathElement(&x, pThis);
24019dbf96bdSdrh }
24029dbf96bdSdrh }
24039dbf96bdSdrh jsonResult(&x);
24049dbf96bdSdrh break;
24059dbf96bdSdrh }
24069dbf96bdSdrh case JEACH_PATH: {
24079dbf96bdSdrh if( p->bRecursive ){
24089dbf96bdSdrh JsonString x;
24099dbf96bdSdrh jsonInit(&x, ctx);
24109dbf96bdSdrh jsonEachComputePath(p, &x, p->sParse.aUp[p->i]);
24119dbf96bdSdrh jsonResult(&x);
24129dbf96bdSdrh break;
24139dbf96bdSdrh }
24149dbf96bdSdrh /* For json_each() path and root are the same so fall through
24159dbf96bdSdrh ** into the root case */
24169dbf96bdSdrh /* no break */ deliberate_fall_through
24179dbf96bdSdrh }
24189dbf96bdSdrh default: {
24199dbf96bdSdrh const char *zRoot = p->zRoot;
24209dbf96bdSdrh if( zRoot==0 ) zRoot = "$";
24219dbf96bdSdrh sqlite3_result_text(ctx, zRoot, -1, SQLITE_STATIC);
24229dbf96bdSdrh break;
24239dbf96bdSdrh }
24249dbf96bdSdrh case JEACH_JSON: {
24259dbf96bdSdrh assert( i==JEACH_JSON );
24269dbf96bdSdrh sqlite3_result_text(ctx, p->sParse.zJson, -1, SQLITE_STATIC);
24279dbf96bdSdrh break;
24289dbf96bdSdrh }
24299dbf96bdSdrh }
24309dbf96bdSdrh return SQLITE_OK;
24319dbf96bdSdrh }
24329dbf96bdSdrh
24339dbf96bdSdrh /* Return the current rowid value */
jsonEachRowid(sqlite3_vtab_cursor * cur,sqlite_int64 * pRowid)24349dbf96bdSdrh static int jsonEachRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){
24359dbf96bdSdrh JsonEachCursor *p = (JsonEachCursor*)cur;
24369dbf96bdSdrh *pRowid = p->iRowid;
24379dbf96bdSdrh return SQLITE_OK;
24389dbf96bdSdrh }
24399dbf96bdSdrh
24409dbf96bdSdrh /* The query strategy is to look for an equality constraint on the json
24419dbf96bdSdrh ** column. Without such a constraint, the table cannot operate. idxNum is
24429dbf96bdSdrh ** 1 if the constraint is found, 3 if the constraint and zRoot are found,
24439dbf96bdSdrh ** and 0 otherwise.
24449dbf96bdSdrh */
jsonEachBestIndex(sqlite3_vtab * tab,sqlite3_index_info * pIdxInfo)24459dbf96bdSdrh static int jsonEachBestIndex(
24469dbf96bdSdrh sqlite3_vtab *tab,
24479dbf96bdSdrh sqlite3_index_info *pIdxInfo
24489dbf96bdSdrh ){
24499dbf96bdSdrh int i; /* Loop counter or computed array index */
24509dbf96bdSdrh int aIdx[2]; /* Index of constraints for JSON and ROOT */
24519dbf96bdSdrh int unusableMask = 0; /* Mask of unusable JSON and ROOT constraints */
24529dbf96bdSdrh int idxMask = 0; /* Mask of usable == constraints JSON and ROOT */
24539dbf96bdSdrh const struct sqlite3_index_constraint *pConstraint;
24549dbf96bdSdrh
24559dbf96bdSdrh /* This implementation assumes that JSON and ROOT are the last two
24569dbf96bdSdrh ** columns in the table */
24579dbf96bdSdrh assert( JEACH_ROOT == JEACH_JSON+1 );
24589dbf96bdSdrh UNUSED_PARAMETER(tab);
24599dbf96bdSdrh aIdx[0] = aIdx[1] = -1;
24609dbf96bdSdrh pConstraint = pIdxInfo->aConstraint;
24619dbf96bdSdrh for(i=0; i<pIdxInfo->nConstraint; i++, pConstraint++){
24629dbf96bdSdrh int iCol;
24639dbf96bdSdrh int iMask;
24649dbf96bdSdrh if( pConstraint->iColumn < JEACH_JSON ) continue;
24659dbf96bdSdrh iCol = pConstraint->iColumn - JEACH_JSON;
24669dbf96bdSdrh assert( iCol==0 || iCol==1 );
24679dbf96bdSdrh testcase( iCol==0 );
24689dbf96bdSdrh iMask = 1 << iCol;
24699dbf96bdSdrh if( pConstraint->usable==0 ){
24709dbf96bdSdrh unusableMask |= iMask;
24719dbf96bdSdrh }else if( pConstraint->op==SQLITE_INDEX_CONSTRAINT_EQ ){
24729dbf96bdSdrh aIdx[iCol] = i;
24739dbf96bdSdrh idxMask |= iMask;
24749dbf96bdSdrh }
24759dbf96bdSdrh }
24769dbf96bdSdrh if( (unusableMask & ~idxMask)!=0 ){
24779dbf96bdSdrh /* If there are any unusable constraints on JSON or ROOT, then reject
24789dbf96bdSdrh ** this entire plan */
24799dbf96bdSdrh return SQLITE_CONSTRAINT;
24809dbf96bdSdrh }
24819dbf96bdSdrh if( aIdx[0]<0 ){
24829dbf96bdSdrh /* No JSON input. Leave estimatedCost at the huge value that it was
24839dbf96bdSdrh ** initialized to to discourage the query planner from selecting this
24849dbf96bdSdrh ** plan. */
24859dbf96bdSdrh pIdxInfo->idxNum = 0;
24869dbf96bdSdrh }else{
24879dbf96bdSdrh pIdxInfo->estimatedCost = 1.0;
24889dbf96bdSdrh i = aIdx[0];
24899dbf96bdSdrh pIdxInfo->aConstraintUsage[i].argvIndex = 1;
24909dbf96bdSdrh pIdxInfo->aConstraintUsage[i].omit = 1;
24919dbf96bdSdrh if( aIdx[1]<0 ){
24929dbf96bdSdrh pIdxInfo->idxNum = 1; /* Only JSON supplied. Plan 1 */
24939dbf96bdSdrh }else{
24949dbf96bdSdrh i = aIdx[1];
24959dbf96bdSdrh pIdxInfo->aConstraintUsage[i].argvIndex = 2;
24969dbf96bdSdrh pIdxInfo->aConstraintUsage[i].omit = 1;
24979dbf96bdSdrh pIdxInfo->idxNum = 3; /* Both JSON and ROOT are supplied. Plan 3 */
24989dbf96bdSdrh }
24999dbf96bdSdrh }
25009dbf96bdSdrh return SQLITE_OK;
25019dbf96bdSdrh }
25029dbf96bdSdrh
25039dbf96bdSdrh /* Start a search on a new JSON string */
jsonEachFilter(sqlite3_vtab_cursor * cur,int idxNum,const char * idxStr,int argc,sqlite3_value ** argv)25049dbf96bdSdrh static int jsonEachFilter(
25059dbf96bdSdrh sqlite3_vtab_cursor *cur,
25069dbf96bdSdrh int idxNum, const char *idxStr,
25079dbf96bdSdrh int argc, sqlite3_value **argv
25089dbf96bdSdrh ){
25099dbf96bdSdrh JsonEachCursor *p = (JsonEachCursor*)cur;
25109dbf96bdSdrh const char *z;
25119dbf96bdSdrh const char *zRoot = 0;
25129dbf96bdSdrh sqlite3_int64 n;
25139dbf96bdSdrh
25149dbf96bdSdrh UNUSED_PARAMETER(idxStr);
25159dbf96bdSdrh UNUSED_PARAMETER(argc);
25169dbf96bdSdrh jsonEachCursorReset(p);
25179dbf96bdSdrh if( idxNum==0 ) return SQLITE_OK;
25189dbf96bdSdrh z = (const char*)sqlite3_value_text(argv[0]);
25199dbf96bdSdrh if( z==0 ) return SQLITE_OK;
25209dbf96bdSdrh n = sqlite3_value_bytes(argv[0]);
25219dbf96bdSdrh p->zJson = sqlite3_malloc64( n+1 );
25229dbf96bdSdrh if( p->zJson==0 ) return SQLITE_NOMEM;
25239dbf96bdSdrh memcpy(p->zJson, z, (size_t)n+1);
25249dbf96bdSdrh if( jsonParse(&p->sParse, 0, p->zJson) ){
25259dbf96bdSdrh int rc = SQLITE_NOMEM;
25269dbf96bdSdrh if( p->sParse.oom==0 ){
25279dbf96bdSdrh sqlite3_free(cur->pVtab->zErrMsg);
25289dbf96bdSdrh cur->pVtab->zErrMsg = sqlite3_mprintf("malformed JSON");
25299dbf96bdSdrh if( cur->pVtab->zErrMsg ) rc = SQLITE_ERROR;
25309dbf96bdSdrh }
25319dbf96bdSdrh jsonEachCursorReset(p);
25329dbf96bdSdrh return rc;
25339dbf96bdSdrh }else if( p->bRecursive && jsonParseFindParents(&p->sParse) ){
25349dbf96bdSdrh jsonEachCursorReset(p);
25359dbf96bdSdrh return SQLITE_NOMEM;
25369dbf96bdSdrh }else{
25379dbf96bdSdrh JsonNode *pNode = 0;
25389dbf96bdSdrh if( idxNum==3 ){
25399dbf96bdSdrh const char *zErr = 0;
25409dbf96bdSdrh zRoot = (const char*)sqlite3_value_text(argv[1]);
25419dbf96bdSdrh if( zRoot==0 ) return SQLITE_OK;
25429dbf96bdSdrh n = sqlite3_value_bytes(argv[1]);
25439dbf96bdSdrh p->zRoot = sqlite3_malloc64( n+1 );
25449dbf96bdSdrh if( p->zRoot==0 ) return SQLITE_NOMEM;
25459dbf96bdSdrh memcpy(p->zRoot, zRoot, (size_t)n+1);
25469dbf96bdSdrh if( zRoot[0]!='$' ){
25479dbf96bdSdrh zErr = zRoot;
25489dbf96bdSdrh }else{
25499dbf96bdSdrh pNode = jsonLookupStep(&p->sParse, 0, p->zRoot+1, 0, &zErr);
25509dbf96bdSdrh }
25519dbf96bdSdrh if( zErr ){
25529dbf96bdSdrh sqlite3_free(cur->pVtab->zErrMsg);
25539dbf96bdSdrh cur->pVtab->zErrMsg = jsonPathSyntaxError(zErr);
25549dbf96bdSdrh jsonEachCursorReset(p);
25559dbf96bdSdrh return cur->pVtab->zErrMsg ? SQLITE_ERROR : SQLITE_NOMEM;
25569dbf96bdSdrh }else if( pNode==0 ){
25579dbf96bdSdrh return SQLITE_OK;
25589dbf96bdSdrh }
25599dbf96bdSdrh }else{
25609dbf96bdSdrh pNode = p->sParse.aNode;
25619dbf96bdSdrh }
25629dbf96bdSdrh p->iBegin = p->i = (int)(pNode - p->sParse.aNode);
25639dbf96bdSdrh p->eType = pNode->eType;
25649dbf96bdSdrh if( p->eType>=JSON_ARRAY ){
25659dbf96bdSdrh assert( pNode->eU==0 );
25669dbf96bdSdrh VVA( pNode->eU = 3 );
25679dbf96bdSdrh pNode->u.iKey = 0;
25689dbf96bdSdrh p->iEnd = p->i + pNode->n + 1;
25699dbf96bdSdrh if( p->bRecursive ){
25709dbf96bdSdrh p->eType = p->sParse.aNode[p->sParse.aUp[p->i]].eType;
25719dbf96bdSdrh if( p->i>0 && (p->sParse.aNode[p->i-1].jnFlags & JNODE_LABEL)!=0 ){
25729dbf96bdSdrh p->i--;
25739dbf96bdSdrh }
25749dbf96bdSdrh }else{
25759dbf96bdSdrh p->i++;
25769dbf96bdSdrh }
25779dbf96bdSdrh }else{
25789dbf96bdSdrh p->iEnd = p->i+1;
25799dbf96bdSdrh }
25809dbf96bdSdrh }
25819dbf96bdSdrh return SQLITE_OK;
25829dbf96bdSdrh }
25839dbf96bdSdrh
25849dbf96bdSdrh /* The methods of the json_each virtual table */
25859dbf96bdSdrh static sqlite3_module jsonEachModule = {
25869dbf96bdSdrh 0, /* iVersion */
25879dbf96bdSdrh 0, /* xCreate */
25889dbf96bdSdrh jsonEachConnect, /* xConnect */
25899dbf96bdSdrh jsonEachBestIndex, /* xBestIndex */
25909dbf96bdSdrh jsonEachDisconnect, /* xDisconnect */
25919dbf96bdSdrh 0, /* xDestroy */
25929dbf96bdSdrh jsonEachOpenEach, /* xOpen - open a cursor */
25939dbf96bdSdrh jsonEachClose, /* xClose - close a cursor */
25949dbf96bdSdrh jsonEachFilter, /* xFilter - configure scan constraints */
25959dbf96bdSdrh jsonEachNext, /* xNext - advance a cursor */
25969dbf96bdSdrh jsonEachEof, /* xEof - check for end of scan */
25979dbf96bdSdrh jsonEachColumn, /* xColumn - read data */
25989dbf96bdSdrh jsonEachRowid, /* xRowid - read data */
25999dbf96bdSdrh 0, /* xUpdate */
26009dbf96bdSdrh 0, /* xBegin */
26019dbf96bdSdrh 0, /* xSync */
26029dbf96bdSdrh 0, /* xCommit */
26039dbf96bdSdrh 0, /* xRollback */
26049dbf96bdSdrh 0, /* xFindMethod */
26059dbf96bdSdrh 0, /* xRename */
26069dbf96bdSdrh 0, /* xSavepoint */
26079dbf96bdSdrh 0, /* xRelease */
26089dbf96bdSdrh 0, /* xRollbackTo */
26099dbf96bdSdrh 0 /* xShadowName */
26109dbf96bdSdrh };
26119dbf96bdSdrh
26129dbf96bdSdrh /* The methods of the json_tree virtual table. */
26139dbf96bdSdrh static sqlite3_module jsonTreeModule = {
26149dbf96bdSdrh 0, /* iVersion */
26159dbf96bdSdrh 0, /* xCreate */
26169dbf96bdSdrh jsonEachConnect, /* xConnect */
26179dbf96bdSdrh jsonEachBestIndex, /* xBestIndex */
26189dbf96bdSdrh jsonEachDisconnect, /* xDisconnect */
26199dbf96bdSdrh 0, /* xDestroy */
26209dbf96bdSdrh jsonEachOpenTree, /* xOpen - open a cursor */
26219dbf96bdSdrh jsonEachClose, /* xClose - close a cursor */
26229dbf96bdSdrh jsonEachFilter, /* xFilter - configure scan constraints */
26239dbf96bdSdrh jsonEachNext, /* xNext - advance a cursor */
26249dbf96bdSdrh jsonEachEof, /* xEof - check for end of scan */
26259dbf96bdSdrh jsonEachColumn, /* xColumn - read data */
26269dbf96bdSdrh jsonEachRowid, /* xRowid - read data */
26279dbf96bdSdrh 0, /* xUpdate */
26289dbf96bdSdrh 0, /* xBegin */
26299dbf96bdSdrh 0, /* xSync */
26309dbf96bdSdrh 0, /* xCommit */
26319dbf96bdSdrh 0, /* xRollback */
26329dbf96bdSdrh 0, /* xFindMethod */
26339dbf96bdSdrh 0, /* xRename */
26349dbf96bdSdrh 0, /* xSavepoint */
26359dbf96bdSdrh 0, /* xRelease */
26369dbf96bdSdrh 0, /* xRollbackTo */
26379dbf96bdSdrh 0 /* xShadowName */
26389dbf96bdSdrh };
26399dbf96bdSdrh #endif /* SQLITE_OMIT_VIRTUALTABLE */
26409dbf96bdSdrh #endif /* !defined(SQLITE_OMIT_JSON) */
26419dbf96bdSdrh
26429dbf96bdSdrh /*
26439dbf96bdSdrh ** Register JSON functions.
26449dbf96bdSdrh */
sqlite3RegisterJsonFunctions(void)26459dbf96bdSdrh void sqlite3RegisterJsonFunctions(void){
26469dbf96bdSdrh #ifndef SQLITE_OMIT_JSON
26479dbf96bdSdrh static FuncDef aJsonFunc[] = {
26489dbf96bdSdrh JFUNCTION(json, 1, 0, jsonRemoveFunc),
26499dbf96bdSdrh JFUNCTION(json_array, -1, 0, jsonArrayFunc),
26509dbf96bdSdrh JFUNCTION(json_array_length, 1, 0, jsonArrayLengthFunc),
26519dbf96bdSdrh JFUNCTION(json_array_length, 2, 0, jsonArrayLengthFunc),
26529dbf96bdSdrh JFUNCTION(json_extract, -1, 0, jsonExtractFunc),
2653d83c90bdSdrh JFUNCTION(->, 2, JSON_JSON, jsonExtractFunc),
2654d83c90bdSdrh JFUNCTION(->>, 2, JSON_SQL, jsonExtractFunc),
26559dbf96bdSdrh JFUNCTION(json_insert, -1, 0, jsonSetFunc),
26569dbf96bdSdrh JFUNCTION(json_object, -1, 0, jsonObjectFunc),
26579dbf96bdSdrh JFUNCTION(json_patch, 2, 0, jsonPatchFunc),
26589dbf96bdSdrh JFUNCTION(json_quote, 1, 0, jsonQuoteFunc),
26599dbf96bdSdrh JFUNCTION(json_remove, -1, 0, jsonRemoveFunc),
26609dbf96bdSdrh JFUNCTION(json_replace, -1, 0, jsonReplaceFunc),
2661daefcd9eSdrh JFUNCTION(json_set, -1, JSON_ISSET, jsonSetFunc),
26629dbf96bdSdrh JFUNCTION(json_type, 1, 0, jsonTypeFunc),
26639dbf96bdSdrh JFUNCTION(json_type, 2, 0, jsonTypeFunc),
26649dbf96bdSdrh JFUNCTION(json_valid, 1, 0, jsonValidFunc),
26659dbf96bdSdrh #if SQLITE_DEBUG
26669dbf96bdSdrh JFUNCTION(json_parse, 1, 0, jsonParseFunc),
26679dbf96bdSdrh JFUNCTION(json_test1, 1, 0, jsonTest1Func),
26689dbf96bdSdrh #endif
26699dbf96bdSdrh WAGGREGATE(json_group_array, 1, 0, 0,
26709dbf96bdSdrh jsonArrayStep, jsonArrayFinal, jsonArrayValue, jsonGroupInverse,
26719dbf96bdSdrh SQLITE_SUBTYPE|SQLITE_UTF8|SQLITE_DETERMINISTIC|SQLITE_INNOCUOUS),
26729dbf96bdSdrh WAGGREGATE(json_group_object, 2, 0, 0,
26739dbf96bdSdrh jsonObjectStep, jsonObjectFinal, jsonObjectValue, jsonGroupInverse,
26749dbf96bdSdrh SQLITE_SUBTYPE|SQLITE_UTF8|SQLITE_DETERMINISTIC|SQLITE_INNOCUOUS)
26759dbf96bdSdrh };
26769dbf96bdSdrh sqlite3InsertBuiltinFuncs(aJsonFunc, ArraySize(aJsonFunc));
26779dbf96bdSdrh #endif
26789dbf96bdSdrh }
26799dbf96bdSdrh
26809dbf96bdSdrh #if !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_OMIT_JSON)
26819dbf96bdSdrh /*
26829dbf96bdSdrh ** Register the JSON table-valued functions
26839dbf96bdSdrh */
sqlite3JsonTableFunctions(sqlite3 * db)26849dbf96bdSdrh int sqlite3JsonTableFunctions(sqlite3 *db){
26859dbf96bdSdrh int rc = SQLITE_OK;
26869dbf96bdSdrh static const struct {
26879dbf96bdSdrh const char *zName;
26889dbf96bdSdrh sqlite3_module *pModule;
26899dbf96bdSdrh } aMod[] = {
26909dbf96bdSdrh { "json_each", &jsonEachModule },
26919dbf96bdSdrh { "json_tree", &jsonTreeModule },
26929dbf96bdSdrh };
269369b0ce33Sdrh unsigned int i;
26949dbf96bdSdrh for(i=0; i<sizeof(aMod)/sizeof(aMod[0]) && rc==SQLITE_OK; i++){
26959dbf96bdSdrh rc = sqlite3_create_module(db, aMod[i].zName, aMod[i].pModule, 0);
26969dbf96bdSdrh }
26979dbf96bdSdrh return rc;
26989dbf96bdSdrh }
26999dbf96bdSdrh #endif /* !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_OMIT_JSON) */
2700