1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-11-09 14:21:03 +03:00

Code and comment cleanup. Everything should work the same.

FossilOrigin-Name: c640754df0d3ffdad994745f0d0e10c8f19f424b87f6a6e6e269491a0350b950
This commit is contained in:
drh
2023-12-02 20:25:36 +00:00
parent 53c2160db0
commit c1e85742da
3 changed files with 125 additions and 90 deletions

View File

@@ -1,5 +1,5 @@
C Fix\sharmless\scompiler\swarnings.\s\sRefactor\ssome\sidentifier\snames\sfor\nclearer\spresentation.
D 2023-12-02T18:17:38.516
C Code\sand\scomment\scleanup.\s\sEverything\sshould\swork\sthe\ssame.
D 2023-12-02T20:25:36.578
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@@ -688,7 +688,7 @@ F src/hash.h 3340ab6e1d13e725571d7cee6d3e3135f0779a7d8e76a9ce0a85971fa3953c51
F src/hwtime.h f9c2dfb84dce7acf95ce6d289e46f5f9d3d1afd328e53da8f8e9008e3b3caae6
F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71
F src/insert.c 3f0a94082d978bbdd33c38fefea15346c6c6bffb70bc645a71dc0f1f87dd3276
F src/json.c b67328611c8ebc5aca49e2d73b1bad9962948aa5c952f3d96c44eb74ee3d0010
F src/json.c 5ad1a1be6199359b09bb4eca690789b77375e00f17c55697b6288f1b0fbbe8b0
F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa
F src/loadext.c 7432c944ff197046d67a1207790a1b13eec4548c85a9457eb0896bb3641dfb36
F src/main.c 1b89f3de98d1b59fec5bac1d66d6ece21f703821b8eaa0d53d9604c35309f6f9
@@ -2145,8 +2145,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
P 1304534001e9ef66c6b12752b69d790bfa3427cc803f87cc48ca22ae12df0fdf
R 1b492fad564bbccdff370d30a804d641
P 7e3941502789c5afaf19b08112f464abf5e3cba7f92fc9290af2a0f96127ad9a
R 9f984966a856d28c36c8f0d6d69732a4
U drh
Z f1274565e5b6e1f5da018a4ab14dfe40
Z ea3e13091dceb571341f1dccf0e97828
# Remove this line to create a well-formed Fossil manifest.

View File

@@ -1 +1 @@
7e3941502789c5afaf19b08112f464abf5e3cba7f92fc9290af2a0f96127ad9a
c640754df0d3ffdad994745f0d0e10c8f19f424b87f6a6e6e269491a0350b950

View File

@@ -133,12 +133,13 @@
#define JSONB_ARRAY 11 /* An array */
#define JSONB_OBJECT 12 /* An object */
/* Human-readable names for the JSONB values:
/* Human-readable names for the JSONB values. The index for each
** string must correspond to the JSONB_* integer above.
*/
static const char * const jsonbType[] = {
"null", "true", "false", "integer", "integer",
"real", "real", "text", "text", "text",
"text", "array", "object"
"text", "array", "object", "", "", "", ""
};
/*
@@ -168,7 +169,7 @@ static const char jsonIsSpace[] = {
#define jsonIsspace(x) (jsonIsSpace[(unsigned char)x])
/*
** Characters that are special to JSON. Control charaters,
** Characters that are special to JSON. Control characters,
** '"' and '\\'.
*/
static const char jsonIsOk[256] = {
@@ -204,7 +205,6 @@ typedef struct JsonCache JsonCache;
typedef struct JsonString JsonString;
typedef struct JsonParse JsonParse;
/*
** Magic number used for the JSON parse cache in sqlite3_get_auxdata()
*/
@@ -213,8 +213,14 @@ typedef struct JsonParse JsonParse;
/* A cache mapping JSON text into JSONB blobs.
**
** All content, both JSON text and the JSONB blobs, is stored as RCStr
** objects.
** Each cache entry is a JsonParse object with the following restrictions:
**
** * The bReadOnly flag must be set
**
** * The aBlob[] array must be owned by the JsonParse object. In other
** words, nBlobAlloc must be non-zero.
**
** * zJson must be an RCStr. In other words bJsonIsRCStr must be true.
*/
struct JsonCache {
sqlite3 *db; /* Database connection */
@@ -225,6 +231,10 @@ struct JsonCache {
/* An instance of this object represents a JSON string
** under construction. Really, this is a generic string accumulator
** that can be and is used to create strings other than JSON.
**
** If the generated string is longer than will fit into the zSpace[] buffer,
** then it will be an RCStr string. This aids with caching of large
** JSON strings.
*/
struct JsonString {
sqlite3_context *pCtx; /* Function context - put error messages here */
@@ -260,18 +270,17 @@ struct JsonString {
/* A parsed JSON value. Lifecycle:
**
** 1. JSON comes in and is parsed into a JSONB value in aBlob. The
** original text is stored in zJson.
** original text is stored in zJson. This step is skipped if the
** input is JSONB instead of text JSON.
**
** 2. The aBlob is searched using the JSON path notation, if needed.
** 2. The aBlob[] array is searched using the JSON path notation, if needed.
**
** 3. Zero or more changes are made to aBlob (via json_remove() or
** json_replace() or similar).
** 3. Zero or more changes are made to aBlob[] (via json_remove() or
** json_replace() or json_patch() or similar).
**
** 4. New JSON text is generated from the aBlob for output.
**
** Step 1 is omitted if the input is a BLOB in the JSONB format. Step 4
** is omitted if the output is JSONB or some other value that is not
** JSON text.
** 4. New JSON text is generated from the aBlob[] for output. This step
** is skipped the function is one of the jsonb_* functions that returns
** JSONB instead of text JSON.
*/
struct JsonParse {
u8 *aBlob; /* JSONB representation of JSON value */
@@ -326,7 +335,6 @@ static void jsonReturnParse(sqlite3_context*,JsonParse*);
static JsonParse *jsonParseFuncArg(sqlite3_context*,sqlite3_value*,u32);
static void jsonParseFree(JsonParse*);
/**************************************************************************
** Utility routines for dealing with JsonCache objects
**************************************************************************/
@@ -346,11 +354,11 @@ static void jsonCacheDeleteGeneric(void *p){
}
/*
** Insert a new entry into the cache. If the cache is full, expell
** Insert a new entry into the cache. If the cache is full, expel
** the least recently used entry. Return SQLITE_OK on success or a
** result code otherwise.
**
** Both the input JSON and JSONB must be RCStr objects.
** Cache entries are stored in age order, oldest first.
*/
static int jsonCacheInsert(
sqlite3_context *ctx, /* The SQL statement context holding the cache */
@@ -386,7 +394,14 @@ static int jsonCacheInsert(
/*
** Search for a cached translation the json text supplied by pArg. Return
** the JsonParse object if found.
** the JsonParse object if found. Return NULL if not found.
**
** When a match if found, the matching entry is moved to become the
** most-recently used entry if it isn't so already.
**
** The JsonParse object returned still belongs to the Cache and might
** be deleted at any moment. If the caller whants the JsonParse to
** linger, it needs to increment the nPJRef reference counter.
*/
static JsonParse *jsonCacheSearch(
sqlite3_context *ctx, /* The SQL statement context holding the cache */
@@ -419,6 +434,7 @@ static JsonParse *jsonCacheSearch(
}
if( i<p->nUsed ){
if( i<p->nUsed-1 ){
/* Make the matching entry the most recently used entry */
JsonParse *tmp = p->a[i];
memmove(&p->a[i], &p->a[i+1], (p->nUsed-i-1)*sizeof(tmp));
p->a[p->nUsed-1] = tmp;
@@ -561,7 +577,9 @@ static void jsonStringTerminate(JsonString *p){
}
}
/* Try to force the string to be a zero-terminated RCStr string.
/* Try to force the string to be a zero-terminated RCStr string. In other
** words, make sure it is not still using the internal zSpace[] static
** buffer.
**
** Return true on success. Return false if an OOM prevents this
** from happening.
@@ -591,9 +609,12 @@ static void jsonAppendSeparator(JsonString *p){
}
/* Append the N-byte string in zIn to the end of the JsonString string
** under construction. Enclose the string in "..." and escape
** any double-quotes or backslash characters contained within the
** under construction. Enclose the string in double-quotes ("...") and
** escape any double-quotes or backslash characters contained within the
** string.
**
** This routine is a high-runner. There is a measurable performance
** increase associated with unwinding the jsonIsOk[] loop.
*/
static void jsonAppendString(JsonString *p, const char *zIn, u32 N){
u32 k;
@@ -604,8 +625,8 @@ static void jsonAppendString(JsonString *p, const char *zIn, u32 N){
p->zBuf[p->nUsed++] = '"';
while( 1 /*exit-by-break*/ ){
k = 0;
while( k+1<N && jsonIsOk[z[k]] && jsonIsOk[z[k+1]] ){ k += 2; }
while( k<N && jsonIsOk[z[k]] ){ k++; }
while( k+1<N && jsonIsOk[z[k]] && jsonIsOk[z[k+1]] ){ k += 2; } /* <--, */
while( k<N && jsonIsOk[z[k]] ){ k++; } /* <-- loop unwound for speed */
if( k>=N ){
if( k>0 ){
memcpy(&p->zBuf[p->nUsed], z, k);
@@ -783,12 +804,8 @@ static void jsonParseReset(JsonParse *pParse){
}
/*
** Free a JsonParse object that was obtained from sqlite3_malloc().
**
** Note that destroying JsonParse might call sqlite3RCStrUnref() to
** destroy the zJson value. The RCStr object might recursively invoke
** JsonParse to destroy this pParse object again. Take care to ensure
** that this recursive destructor sequence terminates harmlessly.
** Decrement the reference count on the JsonParse object. When the
** count reaches zero, free the object.
*/
static void jsonParseFree(JsonParse *pParse){
if( pParse ){
@@ -1010,7 +1027,6 @@ static void jsonWrongNumArgs(
** Utility routines for dealing with the binary BLOB representation of JSON
****************************************************************************/
/*
** Expand pParse->aBlob so that it holds at least N bytes.
**
@@ -2068,7 +2084,8 @@ static u32 jsonbArrayCount(JsonParse *pParse, u32 iRoot){
}
/*
** Edit the size of the element at iRoot by the amount in pParse->delta.
** Edit the payload size of the element at iRoot by the amount in
** pParse->delta.
*/
static void jsonAfterEditSizeAdjust(JsonParse *pParse, u32 iRoot){
u32 sz = 0;
@@ -2126,6 +2143,55 @@ static void jsonBlobEdit(
#define JSON_LOOKUP_PATHERROR 0xfffffffd
#define JSON_LOOKUP_ISERROR(x) ((x)>=JSON_LOOKUP_PATHERROR)
/* Forward declaration */
static u32 jsonLookupStep(JsonParse*,u32,const char*,u32);
/* This helper routine for jsonLookupStep() populates pIns with
** binary data that is to be inserted into pParse.
**
** In the common case, pIns just points to pParse->aIns and pParse->nIns.
** But if the zPath of the original edit operation includes path elements
** that go deeper, additional substructure must be created.
**
** For example:
**
** json_insert('{}', '$.a.b.c', 123);
**
** The search stops at '$.a' But additional substructure must be
** created for the ".b.c" part of the patch so that the final result
** is: {"a":{"b":{"c"::123}}}. This routine populates pIns with
** the binary equivalent of {"b":{"c":123}} so that it can be inserted.
**
** The caller is responsible for resetting pIns when it has finished
** using the substructure.
*/
static u32 jsonCreateEditSubstructure(
JsonParse *pParse, /* The original JSONB that is being edited */
JsonParse *pIns, /* Populate this with the blob data to insert */
const char *zTail /* Tail of the path that determins substructure */
){
static const u8 emptyObject[] = { JSONB_ARRAY, JSONB_OBJECT };
int rc;
memset(pIns, 0, sizeof(*pIns));
if( zTail[0]==0 ){
/* No substructure. Just insert what is given in pParse. */
pIns->aBlob = pParse->aIns;
pIns->nBlob = pParse->nIns;
rc = 0;
}else{
/* Construct the binary substructure */
pIns->nBlob = 1;
pIns->aBlob = (u8*)&emptyObject[zTail[0]=='.'];
pIns->eEdit = pParse->eEdit;
pIns->nIns = pParse->nIns;
pIns->aIns = pParse->aIns;
rc = jsonLookupStep(pIns, 0, zTail, 0);
pParse->oom |= pIns->oom;
}
return rc; /* Error code only */
}
/*
** Search along zPath to find the Json element specified. Return an
** index into pParse->aBlob[] for the start of that element's value.
@@ -2135,6 +2201,13 @@ static void jsonBlobEdit(
** label, before returning.
**
** Return one of the JSON_LOOKUP error codes if problems are seen.
**
** This routine will also modify the blob. If pParse->eEdit is one of
** JEDIT_DEL, JEDIT_REPL, JEDIT_INS, or JEDIT_SET, then changes might be
** made to the selected value. If an edit is performed, then the return
** value does not necessarily point to the select element. If an edit
** is performed, the return value is only useful for detecting error
** conditions.
*/
static u32 jsonLookupStep(
JsonParse *pParse, /* The JSON to search */
@@ -2145,7 +2218,6 @@ static u32 jsonLookupStep(
u32 i, j, k, nKey, sz, n, iEnd, rc;
const char *zKey;
u8 x;
static const u8 emptyObject[] = { JSONB_ARRAY, JSONB_OBJECT };
if( zPath[0]==0 ){
if( pParse->eEdit && jsonBlobMakeEditable(pParse, pParse->nIns) ){
@@ -2224,26 +2296,12 @@ static u32 jsonLookupStep(
testcase( pParse->eEdit==JEDIT_SET );
memset(&ix, 0, sizeof(ix));
jsonBlobAppendNode(&ix,JSONB_TEXTRAW, nKey, 0);
memset(&v, 0, sizeof(v));
if( zPath[i]==0 ){
v.nBlob = pParse->nIns;
v.aBlob = pParse->aIns;
}else{
v.nBlob = 1;
v.aBlob = (u8*)&emptyObject[zPath[i]=='.'];
v.eEdit = pParse->eEdit;
v.nIns = pParse->nIns;
v.aIns = pParse->aIns;
rc = jsonLookupStep(&v, 0, &zPath[i], 0);
if( JSON_LOOKUP_ISERROR(rc) || v.oom ){
pParse->oom |= v.oom;
jsonParseReset(&v);
jsonParseReset(&ix);
return rc;
}
}
pParse->oom |= ix.oom;
if( jsonBlobMakeEditable(pParse, ix.nBlob+nKey+v.nBlob) ){
rc = jsonCreateEditSubstructure(pParse, &v, &zPath[i]);
if( !JSON_LOOKUP_ISERROR(rc)
&& jsonBlobMakeEditable(pParse, ix.nBlob+nKey+v.nBlob)
){
assert( !pParse->oom );
nIns = ix.nBlob + nKey + v.nBlob;
jsonBlobEdit(pParse, j, 0, 0, nIns);
if( !pParse->oom ){
@@ -2257,7 +2315,7 @@ static u32 jsonLookupStep(
}
jsonParseReset(&v);
jsonParseReset(&ix);
return j;
return rc;
}
}else if( zPath[0]=='[' ){
x = pParse->aBlob[iRoot] & 0x0f;
@@ -2309,29 +2367,16 @@ static u32 jsonLookupStep(
JsonParse v;
testcase( pParse->eEdit==JEDIT_INS );
testcase( pParse->eEdit==JEDIT_SET );
memset(&v, 0, sizeof(v));
if( zPath[i+1]==0 ){
v.aBlob = pParse->aIns;
v.nBlob = pParse->nIns;
}else{
v.nBlob = 1;
v.aBlob = (u8*)&emptyObject[zPath[i+1]=='.'];
v.eEdit = pParse->eEdit;
v.nIns = pParse->nIns;
v.aIns = pParse->aIns;
rc = jsonLookupStep(&v, 0, &zPath[i+1], 0);
if( JSON_LOOKUP_ISERROR(rc) || v.oom ){
pParse->oom |= v.oom;
jsonParseReset(&v);
return rc;
}
}
if( jsonBlobMakeEditable(pParse, v.nBlob) ){
rc = jsonCreateEditSubstructure(pParse, &v, &zPath[i+1]);
if( !JSON_LOOKUP_ISERROR(rc)
&& jsonBlobMakeEditable(pParse, v.nBlob)
){
assert( !pParse->oom );
jsonBlobEdit(pParse, j, 0, v.aBlob, v.nBlob);
}
jsonParseReset(&v);
if( pParse->delta ) jsonAfterEditSizeAdjust(pParse, iRoot);
return j;
return rc;
}
}else{
return JSON_LOOKUP_PATHERROR;
@@ -3169,17 +3214,7 @@ static void jsonArrayLengthFunc(
i = 0;
}
if( (p->aBlob[i] & 0x0f)==JSONB_ARRAY ){
u32 n, sz = 0, iEnd;
n = jsonbPayloadSize(p, i, &sz);
if( n==0 ) eErr = 2;
iEnd = i+n+sz;
i += n;
while( eErr==0 && i<iEnd ){
cnt++;
n = jsonbPayloadSize(p, i, &sz);
if( n==0 ) eErr = 2;
i += n+sz;
}
cnt = jsonbArrayCount(p, i);
}
if( eErr ){
if( eErr==2 ) sqlite3_result_error(ctx, "malformed JSON", -1);