1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-11-11 01:42:22 +03:00

Improved comments and other cleanup for the changes on this branch.

FossilOrigin-Name: bac953a80d1a541e7a12aef00c86c002133859237143ad670b39ea19799a8900
This commit is contained in:
drh
2023-07-26 11:43:39 +00:00
parent 9a184daad3
commit 7725370ff4
3 changed files with 93 additions and 95 deletions

View File

@@ -1,5 +1,5 @@
C Fix\sjsonForceRCStr()\sto\salso\sadd\sthe\sNULL\sterminator. C Improved\scomments\sand\sother\scleanup\sfor\sthe\schanges\son\sthis\sbranch.
D 2023-07-26T11:00:47.983 D 2023-07-26T11:43:39.965
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@@ -598,7 +598,7 @@ F src/hash.h 3340ab6e1d13e725571d7cee6d3e3135f0779a7d8e76a9ce0a85971fa3953c51
F src/hwtime.h f9c2dfb84dce7acf95ce6d289e46f5f9d3d1afd328e53da8f8e9008e3b3caae6 F src/hwtime.h f9c2dfb84dce7acf95ce6d289e46f5f9d3d1afd328e53da8f8e9008e3b3caae6
F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71 F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71
F src/insert.c 3f0a94082d978bbdd33c38fefea15346c6c6bffb70bc645a71dc0f1f87dd3276 F src/insert.c 3f0a94082d978bbdd33c38fefea15346c6c6bffb70bc645a71dc0f1f87dd3276
F src/json.c b3f20f01dc6e11071b0b5a8fda73a16c23fd7e65356ec715c0082e904f3fb284 F src/json.c 15ca3c2dfd5a525c225da5592f66d4ef6b789a83814f417be0a0af617071bc38
F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa
F src/loadext.c 176d6b2cb18a6ad73b133db17f6fc351c4d9a2d510deebdb76c22bde9cfd1465 F src/loadext.c 176d6b2cb18a6ad73b133db17f6fc351c4d9a2d510deebdb76c22bde9cfd1465
F src/main.c 512b1d45bc556edf4471a845afb7ba79e64bd5b832ab222dc195c469534cd002 F src/main.c 512b1d45bc556edf4471a845afb7ba79e64bd5b832ab222dc195c469534cd002
@@ -2044,8 +2044,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
P ef4e1664d159b98854d9aa580b0bb942f1726f32a190e2ea659c171131ddce9a P 134b01f37f8f741d7f7b7eda81384695d1cbe4c39751d87f08832d5c9afdcef2
R d6f55ea1e7a815bfa0f96bc129102acf R 9df4f7348f2973215055bf0d567d169d
U drh U drh
Z d5c0e742c545064eb8b7fe7e17a2bad7 Z b486171855fdc62c1515867c409e89e4
# Remove this line to create a well-formed Fossil manifest. # Remove this line to create a well-formed Fossil manifest.

View File

@@ -1 +1 @@
134b01f37f8f741d7f7b7eda81384695d1cbe4c39751d87f08832d5c9afdcef2 bac953a80d1a541e7a12aef00c86c002133859237143ad670b39ea19799a8900

View File

@@ -59,7 +59,7 @@ static const char jsonIsSpace[] = {
typedef struct JsonString JsonString; typedef struct JsonString JsonString;
typedef struct JsonNode JsonNode; typedef struct JsonNode JsonNode;
typedef struct JsonParse JsonParse; typedef struct JsonParse JsonParse;
typedef struct JsonTask JsonTask; typedef struct JsonCleanup JsonCleanup;
/* An instance of this object represents a JSON string /* An instance of this object represents a JSON string
** under construction. Really, this is a generic string accumulator ** under construction. Really, this is a generic string accumulator
@@ -75,11 +75,11 @@ struct JsonString {
char zSpace[100]; /* Initial static space */ char zSpace[100]; /* Initial static space */
}; };
/* A deferred cleanup task. A list of JsonTask objects might be /* A deferred cleanup task. A list of JsonCleanup objects might be
** run when the JsonParse object is destroyed. ** run when the JsonParse object is destroyed.
*/ */
struct JsonTask { struct JsonCleanup {
JsonTask *pJTNext; /* Next in a list */ JsonCleanup *pJCNext; /* Next in a list */
void (*xOp)(void*); /* Routine to run */ void (*xOp)(void*); /* Routine to run */
void *pArg; /* Argument to xOp() */ void *pArg; /* Argument to xOp() */
}; };
@@ -136,29 +136,50 @@ struct JsonNode {
}; };
/* A completely parsed JSON string /* A parsed and possibly edited JSON string. Lifecycle:
**
** 1. JSON comes in and is parsed into an array aNode[]. The original
** JSON text is stored in zJson. This object may or may not be the
** owner of the input JSON - the bOwnsJson variables determines which.
**
** 2. Zero or more changes are made (via json_remove() or json_replace()
** or similar) to the aNode[] array.
**
** 3. A new, edited and mimified JSON string is generated from aNode
** and stored in zAlt. The JsonParse object always owns zAlt.
**
** Step 1 always happens. Step 2 and 3 may or may not happen, depending
** on the operation.
**
** aNode[].u.zJContent entries typically point into zJson. Hence zJson
** must remain valid for the lifespan of the parse. For edits,
** aNode[].u.zJContent might point to malloced space other than zJson.
** Entries in pClup are responsible for freeing that extra malloced space.
**
** When walking the parse tree in aNode[], edits are ignored if useMod is
** false.
*/ */
struct JsonParse { struct JsonParse {
u32 nNode; /* Number of slots of aNode[] used */ u32 nNode; /* Number of slots of aNode[] used */
u32 nAlloc; /* Number of slots of aNode[] allocated */ u32 nAlloc; /* Number of slots of aNode[] allocated */
JsonNode *aNode; /* Array of nodes containing the parse */ JsonNode *aNode; /* Array of nodes containing the parse */
char *zJson; /* Original JSON string (before edits) */ char *zJson; /* Original JSON string (before edits) */
char *zAlt; /* Revised JSON after edits applied. Maybe NULL */ char *zAlt; /* Revised and/or mimified JSON */
u32 *aUp; /* Index of parent of each node */ u32 *aUp; /* Index of parent of each node */
JsonTask *pClean; /* Cleanup operations prior to freeing this object */ JsonCleanup *pClup;/* Cleanup operations prior to freeing this object */
u16 iDepth; /* Nesting depth */ u16 iDepth; /* Nesting depth */
u8 nErr; /* Number of errors seen */ u8 nErr; /* Number of errors seen */
u8 oom; /* Set to true if out of memory */ u8 oom; /* Set to true if out of memory */
u8 hasNonstd; /* True if input uses non-standard features like JSON5 */ u8 hasNonstd; /* True if input uses non-standard features like JSON5 */
u8 nJPRef; /* Number of references to this object */
u8 bOwnsJson; /* This object owns zJson and response for freeing it */ u8 bOwnsJson; /* This object owns zJson and response for freeing it */
u8 useMod; /* Actually use the edits contain inside aNode */ u8 useMod; /* Actually use the edits contain inside aNode */
u8 hasMod; /* aNode contains edits from the original zJson */ u8 hasMod; /* aNode contains edits from the original zJson */
u32 nJPRef; /* Number of references to this object */
int nJson; /* Length of the zJson string in bytes */ int nJson; /* Length of the zJson string in bytes */
int nAlt; /* Length of alternative JSON string zAlt, in bytes */ int nAlt; /* Length of alternative JSON string zAlt, in bytes */
u32 iErr; /* Error location in zJson[] */ u32 iErr; /* Error location in zJson[] */
u32 iSubst; /* Last known JSON_SUBST node */ u32 iSubst; /* Last JSON_SUBST entry in aNode[] */
u32 iHold; /* Replace cache line with the lowest iHold value */ u32 iHold; /* Age of this entry in the cache for LRU replacement */
}; };
/* /*
@@ -174,17 +195,6 @@ struct JsonParse {
** Utility routines for dealing with JsonString objects ** Utility routines for dealing with JsonString objects
**************************************************************************/ **************************************************************************/
#if 0
/*
** This is a destructor for JSON strings. We make it a separate function
** so that the sqlite3ValueIsOfClass() function can be used to unambiguously
** identify sqlite3_value objects that are known JSON strings.
*/
static void jsonStringClass(void *p){
sqlite3RCStrUnref((char*)p);
}
#endif
/* Set the JsonString object to an empty string /* Set the JsonString object to an empty string
*/ */
static void jsonZero(JsonString *p){ static void jsonZero(JsonString *p){
@@ -202,7 +212,6 @@ static void jsonInit(JsonString *p, sqlite3_context *pCtx){
jsonZero(p); jsonZero(p);
} }
/* Free all allocated memory and reset the JsonString object back to its /* Free all allocated memory and reset the JsonString object back to its
** initial state. ** initial state.
*/ */
@@ -211,8 +220,7 @@ static void jsonReset(JsonString *p){
jsonZero(p); jsonZero(p);
} }
/* Report an out-of-memory (OOM) condition
/* Report an out-of-memory (OOM) condition
*/ */
static void jsonOom(JsonString *p){ static void jsonOom(JsonString *p){
p->bErr = 1; p->bErr = 1;
@@ -316,7 +324,9 @@ static int jsonForceRCStr(JsonString *p){
p->nUsed--; p->nUsed--;
if( p->bStatic==0 ) return 1; if( p->bStatic==0 ) return 1;
p->nAlloc = 0; p->nAlloc = 0;
p->nUsed++;
jsonGrow(p, p->nUsed); jsonGrow(p, p->nUsed);
p->nUsed--;
return p->bStatic==0; return p->bStatic==0;
} }
@@ -392,7 +402,7 @@ static void jsonAppendNormalizedString(JsonString *p, const char *zIn, u32 N){
jsonAppendRawNZ(p, zIn, i); jsonAppendRawNZ(p, zIn, i);
zIn += i; zIn += i;
N -= i; N -= i;
if( N==0 ) break; if( N==0 ) break;
} }
assert( zIn[0]=='\\' ); assert( zIn[0]=='\\' );
switch( (u8)zIn[1] ){ switch( (u8)zIn[1] ){
@@ -501,7 +511,7 @@ static void jsonAppendNormalizedReal(JsonString *p, const char *zIn, u32 N){
/* /*
** Append a function parameter value to the JSON string under ** Append a function parameter value to the JSON string under
** construction. ** construction.
*/ */
static void jsonAppendValue( static void jsonAppendValue(
@@ -550,18 +560,11 @@ static void jsonAppendValue(
** The JSON string is reset. ** The JSON string is reset.
*/ */
static void jsonResult(JsonString *p){ static void jsonResult(JsonString *p){
if( p->bErr==0 ){ if( p->bErr==0 && jsonForceRCStr(p) ){
if( p->bStatic ){ sqlite3RCStrRef(p->zBuf);
sqlite3_result_text64(p->pCtx, p->zBuf, p->nUsed, SQLITE_TRANSIENT, sqlite3_result_text64(p->pCtx, p->zBuf, p->nUsed,
SQLITE_UTF8); (void(*)(void*))sqlite3RCStrUnref,
}else{ SQLITE_UTF8);
jsonAppendChar(p, 0);
p->nUsed--;
sqlite3RCStrRef(p->zBuf);
sqlite3_result_text64(p->pCtx, p->zBuf, p->nUsed,
(void(*)(void*))sqlite3RCStrUnref,
SQLITE_UTF8);
}
}else if( p->bErr==1 ){ }else if( p->bErr==1 ){
sqlite3_result_error_nomem(p->pCtx); sqlite3_result_error_nomem(p->pCtx);
} }
@@ -590,9 +593,9 @@ static u32 jsonNodeSize(JsonNode *pNode){
** delete the JsonParse object itself. ** delete the JsonParse object itself.
*/ */
static void jsonParseReset(JsonParse *pParse){ static void jsonParseReset(JsonParse *pParse){
while( pParse->pClean ){ while( pParse->pClup ){
JsonTask *pTask = pParse->pClean; JsonCleanup *pTask = pParse->pClup;
pParse->pClean = pTask->pJTNext; pParse->pClup = pTask->pJCNext;
pTask->xOp(pTask->pArg); pTask->xOp(pTask->pArg);
sqlite3_free(pTask); sqlite3_free(pTask);
} }
@@ -608,17 +611,13 @@ static void jsonParseReset(JsonParse *pParse){
pParse->aUp = 0; pParse->aUp = 0;
} }
if( pParse->zAlt ){ if( pParse->zAlt ){
char *z = pParse->zAlt; sqlite3RCStrUnref(pParse->zAlt);
pParse->zAlt = 0; pParse->zAlt = 0;
sqlite3RCStrUnref(z);
} }
if( pParse->bOwnsJson ){ if( pParse->bOwnsJson ){
/* Order operations so that if the destructor for pParse->zJson
** invokes jsonParseFree(), the recursion will terminate harmlessly */
char *z = pParse->zJson;
pParse->zJson = 0;
pParse->bOwnsJson = 0; pParse->bOwnsJson = 0;
sqlite3RCStrUnref(z); sqlite3RCStrUnref(pParse->zJson);
pParse->zJson = 0;
} }
} }
@@ -650,14 +649,14 @@ static int jsonParseAddCleanup(
void(*xOp)(void*), /* The cleanup task */ void(*xOp)(void*), /* The cleanup task */
void *pArg /* Argument to the cleanup */ void *pArg /* Argument to the cleanup */
){ ){
JsonTask *pTask = sqlite3_malloc64( sizeof(*pTask) ); JsonCleanup *pTask = sqlite3_malloc64( sizeof(*pTask) );
if( pTask==0 ){ if( pTask==0 ){
pParse->oom = 1; pParse->oom = 1;
xOp(pArg); xOp(pArg);
return SQLITE_ERROR; return SQLITE_ERROR;
} }
pTask->pJTNext = pParse->pClean; pTask->pJCNext = pParse->pClup;
pParse->pClean = pTask; pParse->pClup = pTask;
pTask->xOp = xOp; pTask->xOp = xOp;
pTask->pArg = pArg; pTask->pArg = pArg;
return SQLITE_OK; return SQLITE_OK;
@@ -870,8 +869,7 @@ static void jsonReturn(
int rc; int rc;
int bNeg = 0; int bNeg = 0;
const char *z; const char *z;
assert( pNode->eU==1 ); assert( pNode->eU==1 );
z = pNode->u.zJContent; z = pNode->u.zJContent;
if( z[0]=='-' ){ z++; bNeg = 1; } if( z[0]=='-' ){ z++; bNeg = 1; }
@@ -1458,23 +1456,23 @@ json_parse_restart:
cDelim = z[i]; cDelim = z[i];
for(j=i+1; 1; j++){ for(j=i+1; 1; j++){
static const char aOk[256] = { static const char aOk[256] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
}; };
if( aOk[(unsigned char)z[j]] ) continue; if( aOk[(unsigned char)z[j]] ) continue;
c = z[j]; c = z[j];
@@ -1740,18 +1738,18 @@ json_parse_restart:
/* /*
** Parse a complete JSON string. Return 0 on success or non-zero if there ** Parse a complete JSON string. Return 0 on success or non-zero if there
** are any errors. If an error occurs, free all memory associated with ** are any errors. If an error occurs, free all memory held by pParse,
** pParse. ** but not pParse itself.
** **
** pParse is uninitialized when this routine is called. ** pParse is uninitialized when this routine is called.
** **
** pParse->nJPRef set to 1. The caller becomes the owner of the ** pParse->nJPRef set to 1. The caller becomes the owner of the
** the JsonParse object. ** the JsonParse object.
** **
** pParse->bOwnsJson is to bTakeJson. If bTakeJson is 1, the newly initialized ** pParse->bOwnsJson is set to bTakeJson. If bTakeJson is 1, the newly
** JsonParse object will become the own the zJson input string. If bTakeJson ** initialized JsonParse object will become the owner of the zJson input
** is 0, then the caller is responsible for preserving zJson for the lifetime ** string. If bTakeJson is 0, then the caller is responsible for
** of the JsonParse object. ** preserving zJson for the lifetime of the JsonParse object.
*/ */
static int jsonParse( static int jsonParse(
JsonParse *pParse, /* Initialize and fill this JsonParse object */ JsonParse *pParse, /* Initialize and fill this JsonParse object */
@@ -2129,7 +2127,7 @@ static JsonNode *jsonLookupStep(
zPath += j + 1; zPath += j + 1;
j = 1; j = 1;
for(;;){ for(;;){
while( j<=pRoot->n while( j<=pRoot->n
&& (i>0 || ((pRoot[j].jnFlags & JNODE_REMOVE)!=0 && pParse->useMod)) && (i>0 || ((pRoot[j].jnFlags & JNODE_REMOVE)!=0 && pParse->useMod))
){ ){
if( (pRoot[j].jnFlags & JNODE_REMOVE)==0 || pParse->useMod==0 ) i--; if( (pRoot[j].jnFlags & JNODE_REMOVE)==0 || pParse->useMod==0 ) i--;
@@ -2255,7 +2253,7 @@ static void jsonWrongNumArgs(
char *zMsg = sqlite3_mprintf("json_%s() needs an odd number of arguments", char *zMsg = sqlite3_mprintf("json_%s() needs an odd number of arguments",
zFuncName); zFuncName);
sqlite3_result_error(pCtx, zMsg, -1); sqlite3_result_error(pCtx, zMsg, -1);
sqlite3_free(zMsg); sqlite3_free(zMsg);
} }
/* /*
@@ -2391,7 +2389,7 @@ static void jsonTest1Func(
/* /*
** Implementation of the json_QUOTE(VALUE) function. Return a JSON value ** Implementation of the json_QUOTE(VALUE) function. Return a JSON value
** corresponding to the SQL value input. Mostly this means putting ** corresponding to the SQL value input. Mostly this means putting
** double-quotes around strings and returning the unquoted string "null" ** double-quotes around strings and returning the unquoted string "null"
** when given a NULL input. ** when given a NULL input.
*/ */
@@ -2438,7 +2436,7 @@ static void jsonArrayFunc(
** json_array_length(JSON) ** json_array_length(JSON)
** json_array_length(JSON, PATH) ** json_array_length(JSON, PATH)
** **
** Return the number of elements in the top-level JSON array. ** Return the number of elements in the top-level JSON array.
** Return 0 if the input is not a well-formed JSON array. ** Return 0 if the input is not a well-formed JSON array.
*/ */
static void jsonArrayLengthFunc( static void jsonArrayLengthFunc(
@@ -2752,7 +2750,7 @@ static void jsonRemoveFunc(
if( argc<1 ) return; if( argc<1 ) return;
pParse = jsonParseCached(ctx, argv[0], ctx, argc>1); pParse = jsonParseCached(ctx, argv[0], ctx, argc>1);
if( pParse==0 ) return; if( pParse==0 ) return;
for(i=1; i<(u32)argc; i++){ for(i=1; i<(u32)argc; i++){
zPath = (const char*)sqlite3_value_text(argv[i]); zPath = (const char*)sqlite3_value_text(argv[i]);
if( zPath==0 ) goto remove_done; if( zPath==0 ) goto remove_done;
@@ -2854,7 +2852,7 @@ static void jsonReplaceNode(
} }
} }
} }
/* /*
** json_replace(JSON, PATH, VALUE, ...) ** json_replace(JSON, PATH, VALUE, ...)
** **
@@ -3269,7 +3267,7 @@ static int jsonEachConnect(
UNUSED_PARAMETER(argv); UNUSED_PARAMETER(argv);
UNUSED_PARAMETER(argc); UNUSED_PARAMETER(argc);
UNUSED_PARAMETER(pAux); UNUSED_PARAMETER(pAux);
rc = sqlite3_declare_vtab(db, rc = sqlite3_declare_vtab(db,
"CREATE TABLE x(key,value,type,atom,id,parent,fullkey,path," "CREATE TABLE x(key,value,type,atom,id,parent,fullkey,path,"
"json HIDDEN,root HIDDEN)"); "json HIDDEN,root HIDDEN)");
if( rc==SQLITE_OK ){ if( rc==SQLITE_OK ){
@@ -3481,7 +3479,7 @@ static int jsonEachColumn(
break; break;
} }
case JEACH_ID: { case JEACH_ID: {
sqlite3_result_int64(ctx, sqlite3_result_int64(ctx,
(sqlite3_int64)p->i + ((pThis->jnFlags & JNODE_LABEL)!=0)); (sqlite3_int64)p->i + ((pThis->jnFlags & JNODE_LABEL)!=0));
break; break;
} }
@@ -3581,8 +3579,8 @@ static int jsonEachBestIndex(
idxMask |= iMask; idxMask |= iMask;
} }
} }
if( pIdxInfo->nOrderBy>0 if( pIdxInfo->nOrderBy>0
&& pIdxInfo->aOrderBy[0].iColumn<0 && pIdxInfo->aOrderBy[0].iColumn<0
&& pIdxInfo->aOrderBy[0].desc==0 && pIdxInfo->aOrderBy[0].desc==0
){ ){
pIdxInfo->orderByConsumed = 1; pIdxInfo->orderByConsumed = 1;
@@ -3782,10 +3780,10 @@ void sqlite3RegisterJsonFunctions(void){
JFUNCTION(json_parse, 1, 0, jsonParseFunc), JFUNCTION(json_parse, 1, 0, jsonParseFunc),
JFUNCTION(json_test1, 1, 0, jsonTest1Func), JFUNCTION(json_test1, 1, 0, jsonTest1Func),
#endif #endif
WAGGREGATE(json_group_array, 1, 0, 0, WAGGREGATE(json_group_array, 1, 0, 0,
jsonArrayStep, jsonArrayFinal, jsonArrayValue, jsonGroupInverse, jsonArrayStep, jsonArrayFinal, jsonArrayValue, jsonGroupInverse,
SQLITE_SUBTYPE|SQLITE_UTF8|SQLITE_DETERMINISTIC), SQLITE_SUBTYPE|SQLITE_UTF8|SQLITE_DETERMINISTIC),
WAGGREGATE(json_group_object, 2, 0, 0, WAGGREGATE(json_group_object, 2, 0, 0,
jsonObjectStep, jsonObjectFinal, jsonObjectValue, jsonGroupInverse, jsonObjectStep, jsonObjectFinal, jsonObjectValue, jsonGroupInverse,
SQLITE_SUBTYPE|SQLITE_UTF8|SQLITE_DETERMINISTIC) SQLITE_SUBTYPE|SQLITE_UTF8|SQLITE_DETERMINISTIC)
}; };