mirror of
https://github.com/sqlite/sqlite.git
synced 2025-08-05 15:55:57 +03:00
Add support for JSON5.
FossilOrigin-Name: f8c3ed23a6931b1da3b93b3274b132387078112a5c8e8d06b5312c47987d3937
This commit is contained in:
202
ext/misc/randomjson.c
Normal file
202
ext/misc/randomjson.c
Normal file
@@ -0,0 +1,202 @@
|
|||||||
|
/*
|
||||||
|
** 2023-04-28
|
||||||
|
**
|
||||||
|
** The author disclaims copyright to this source code. In place of
|
||||||
|
** a legal notice, here is a blessing:
|
||||||
|
**
|
||||||
|
** May you do good and not evil.
|
||||||
|
** May you find forgiveness for yourself and forgive others.
|
||||||
|
** May you share freely, never taking more than you give.
|
||||||
|
**
|
||||||
|
******************************************************************************
|
||||||
|
**
|
||||||
|
** This SQLite extension implements a the random_json(SEED) and
|
||||||
|
** random_json5(SEED) functions. Given a numeric SEED value, these
|
||||||
|
** routines generate pseudo-random JSON or JSON5, respectively. The
|
||||||
|
** same value is always generated for the same seed.
|
||||||
|
**
|
||||||
|
** These SQL functions are intended for testing. They do not have any
|
||||||
|
** practical real-world use, that we know of.
|
||||||
|
**
|
||||||
|
** COMPILE:
|
||||||
|
**
|
||||||
|
** gcc --shared -fPIC -o randomjson.so -I. ext/misc/randomjson.c
|
||||||
|
**
|
||||||
|
** USING FROM THE CLI:
|
||||||
|
**
|
||||||
|
** .load ./randomjson
|
||||||
|
** SELECT random_json(1);
|
||||||
|
*/
|
||||||
|
#include "sqlite3ext.h"
|
||||||
|
SQLITE_EXTENSION_INIT1
|
||||||
|
#include <assert.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
/* Pseudo-random number generator */
|
||||||
|
typedef struct Prng {
|
||||||
|
unsigned int x, y;
|
||||||
|
} Prng;
|
||||||
|
|
||||||
|
/* Reseed the PRNG */
|
||||||
|
static void prngSeed(Prng *p, unsigned int iSeed){
|
||||||
|
p->x = iSeed | 1;
|
||||||
|
p->y = iSeed;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Extract a random number */
|
||||||
|
static unsigned int prngInt(Prng *p){
|
||||||
|
p->x = (p->x>>1) ^ ((1+~(p->x&1)) & 0xd0000001);
|
||||||
|
p->y = p->y*1103515245 + 12345;
|
||||||
|
return p->x ^ p->y;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char *azJsonAtoms[] = {
|
||||||
|
/* JSON /* JSON-5 */
|
||||||
|
"0", "0",
|
||||||
|
"1", "1",
|
||||||
|
"-1", "-1",
|
||||||
|
"2", "+2",
|
||||||
|
"3", "3",
|
||||||
|
"2.5", "2.5",
|
||||||
|
"0.75", ".75",
|
||||||
|
"-4.0e2", "-4.e2",
|
||||||
|
"5.0e-3", "+5e-3",
|
||||||
|
"0", "0x0",
|
||||||
|
"512", "0x200",
|
||||||
|
"256", "+0x100",
|
||||||
|
"-2748", "-0xabc",
|
||||||
|
"true", "true",
|
||||||
|
"false", "false",
|
||||||
|
"null", "null",
|
||||||
|
"9.0e999", "Infinity",
|
||||||
|
"-9.0e999", "-Infinity",
|
||||||
|
"9.0e999", "+Infinity",
|
||||||
|
"null", "NaN",
|
||||||
|
"-0.0005123", "-0.0005123",
|
||||||
|
"4.35e-3", "+4.35e-3",
|
||||||
|
"\"gem\\\"hay\"", "\"gem\\\"hay\"",
|
||||||
|
"\"icy'joy\"", "'icy\\'joy\'",
|
||||||
|
"\"keylog\"", "\"key\\\nlog\"",
|
||||||
|
"\"mix\\\\\\tnet\"", "\"mix\\\\\\tnet\"",
|
||||||
|
"{}", "{}",
|
||||||
|
"[]", "[]",
|
||||||
|
"[]", "[/*empty*/]",
|
||||||
|
"{}", "{//empty\n}",
|
||||||
|
"\"ask\"", "\"ask\"",
|
||||||
|
"\"bag\"", "\"bag\"",
|
||||||
|
"\"can\"", "\"can\"",
|
||||||
|
"\"day\"", "\"day\"",
|
||||||
|
"\"end\"", "'end'",
|
||||||
|
"\"fly\"", "\"fly\"",
|
||||||
|
"\"\"", "\"\"",
|
||||||
|
};
|
||||||
|
static const char *azJsonTemplate[] = {
|
||||||
|
/* JSON JSON-5 */
|
||||||
|
"{\"a\":%,\"b\":%,\"c\":%}", "{a:%,b:%,c:%}",
|
||||||
|
"{\"a\":%,\"b\":%,\"c\":%,\"d\":%,\"e\":%}", "{a:%,b:%,c:%,d:%,e:%}",
|
||||||
|
"{\"a\":%,\"b\":%,\"c\":%,\"d\":%,\"\":%}", "{a:%,b:%,c:%,d:%,\"\":%}",
|
||||||
|
"{\"d\":%}", "{d:%}",
|
||||||
|
"{\"eeee\":%, \"ffff\":%}", "{eeee:% /*and*/, ffff:%}",
|
||||||
|
"{\"$g\":%,\"_h_\":%}", "{$g:%,_h_:%,}",
|
||||||
|
"{\"x\":%,\n \"y\":%}", "{\"x\":%,\n \"y\":%}",
|
||||||
|
"{\"a b c d\":%,\"e\":%,\"f\":%,\"x\":%,\"y\":%}",
|
||||||
|
"{\"a b c d\":%,e:%,f:%,x:%,y:%}",
|
||||||
|
"{\"Z\":%}", "{Z:%,}",
|
||||||
|
"[%]", "[%,]",
|
||||||
|
"[%,%]", "[%,%]",
|
||||||
|
"[%,%,%]", "[%,%,%,]",
|
||||||
|
"[%,%,%,%]", "[%,%,%,%]",
|
||||||
|
"[%,%,%,%,%]", "[%,%,%,%,%]",
|
||||||
|
};
|
||||||
|
|
||||||
|
#define count(X) (sizeof(X)/sizeof(X[0]))
|
||||||
|
|
||||||
|
#define STRSZ 10000
|
||||||
|
|
||||||
|
static void jsonExpand(
|
||||||
|
const char *zSrc,
|
||||||
|
char *zDest,
|
||||||
|
Prng *p,
|
||||||
|
int eType, /* 0 for JSON, 1 for JSON5 */
|
||||||
|
unsigned int r /* Growth probability 0..1000. 0 means no growth */
|
||||||
|
){
|
||||||
|
unsigned int i, j, k;
|
||||||
|
const char *z;
|
||||||
|
size_t n;
|
||||||
|
|
||||||
|
j = 0;
|
||||||
|
if( zSrc==0 ){
|
||||||
|
k = prngInt(p)%(count(azJsonTemplate)/2);
|
||||||
|
k = k*2 + eType;
|
||||||
|
zSrc = azJsonTemplate[k];
|
||||||
|
}
|
||||||
|
if( strlen(zSrc)>=STRSZ/10 ) r = 0;
|
||||||
|
for(i=0; zSrc[i]; i++){
|
||||||
|
if( zSrc[i]!='%' ){
|
||||||
|
if( j<STRSZ ) zDest[j++] = zSrc[i];
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if( r==0 || (r<1000 && (prngInt(p)%1000)<=r) ){
|
||||||
|
/* Fill in without values without any new % */
|
||||||
|
k = prngInt(p)%(count(azJsonAtoms)/2);
|
||||||
|
k = k*2 + eType;
|
||||||
|
z = azJsonAtoms[k];
|
||||||
|
}else{
|
||||||
|
/* Add new % terms */
|
||||||
|
k = prngInt(p)%(count(azJsonTemplate)/2);
|
||||||
|
k = k*2 + eType;
|
||||||
|
z = azJsonTemplate[k];
|
||||||
|
}
|
||||||
|
n = strlen(z);
|
||||||
|
if( j+n<STRSZ ){
|
||||||
|
memcpy(&zDest[j], z, n);
|
||||||
|
j += n;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
zDest[STRSZ-1] = 0;
|
||||||
|
if( j<STRSZ ) zDest[j] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void randJsonFunc(
|
||||||
|
sqlite3_context *context,
|
||||||
|
int argc,
|
||||||
|
sqlite3_value **argv
|
||||||
|
){
|
||||||
|
unsigned int iSeed;
|
||||||
|
int eType = *(int*)sqlite3_user_data(context);
|
||||||
|
Prng prng;
|
||||||
|
char z1[STRSZ+1], z2[STRSZ+1];
|
||||||
|
|
||||||
|
iSeed = (unsigned int)sqlite3_value_int(argv[0]);
|
||||||
|
prngSeed(&prng, iSeed);
|
||||||
|
jsonExpand(0, z2, &prng, eType, 1000);
|
||||||
|
jsonExpand(z2, z1, &prng, eType, 1000);
|
||||||
|
jsonExpand(z1, z2, &prng, eType, 100);
|
||||||
|
jsonExpand(z2, z1, &prng, eType, 0);
|
||||||
|
sqlite3_result_text(context, z1, -1, SQLITE_TRANSIENT);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
__declspec(dllexport)
|
||||||
|
#endif
|
||||||
|
int sqlite3_randomjson_init(
|
||||||
|
sqlite3 *db,
|
||||||
|
char **pzErrMsg,
|
||||||
|
const sqlite3_api_routines *pApi
|
||||||
|
){
|
||||||
|
static int cOne = 1;
|
||||||
|
static int cZero = 0;
|
||||||
|
int rc = SQLITE_OK;
|
||||||
|
SQLITE_EXTENSION_INIT2(pApi);
|
||||||
|
(void)pzErrMsg; /* Unused parameter */
|
||||||
|
rc = sqlite3_create_function(db, "random_json", 1,
|
||||||
|
SQLITE_UTF8|SQLITE_INNOCUOUS|SQLITE_DETERMINISTIC,
|
||||||
|
&cZero, randJsonFunc, 0, 0);
|
||||||
|
if( rc==SQLITE_OK ){
|
||||||
|
rc = sqlite3_create_function(db, "random_json5", 1,
|
||||||
|
SQLITE_UTF8|SQLITE_INNOCUOUS|SQLITE_DETERMINISTIC,
|
||||||
|
&cOne, randJsonFunc, 0, 0);
|
||||||
|
}
|
||||||
|
return rc;
|
||||||
|
}
|
34
manifest
34
manifest
@@ -1,5 +1,5 @@
|
|||||||
C Fix\stypos\sin\scomments\sin\ssqlite3session.h\spreventing\sdocumentation\sfrom\sbeing\scorrectly\sgenerated.
|
C Add\ssupport\sfor\sJSON5.
|
||||||
D 2023-05-01T15:59:20.750
|
D 2023-05-01T18:28:48.240
|
||||||
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
|
||||||
@@ -302,6 +302,7 @@ F ext/misc/normalize.c bd84355c118e297522aba74de34a4fd286fc775524e0499b14473918d
|
|||||||
F ext/misc/percentile.c b9086e223d583bdaf8cb73c98a6539d501a2fc4282654adbfea576453d82e691
|
F ext/misc/percentile.c b9086e223d583bdaf8cb73c98a6539d501a2fc4282654adbfea576453d82e691
|
||||||
F ext/misc/prefixes.c 0f4f8cff5aebc00a7e3ac4021fd59cfe1a8e17c800ceaf592859ecb9cbc38196
|
F ext/misc/prefixes.c 0f4f8cff5aebc00a7e3ac4021fd59cfe1a8e17c800ceaf592859ecb9cbc38196
|
||||||
F ext/misc/qpvtab.c 09738419e25f603a35c0ac8bd0a04daab794f48d08a9bc07a6085b9057b99009
|
F ext/misc/qpvtab.c 09738419e25f603a35c0ac8bd0a04daab794f48d08a9bc07a6085b9057b99009
|
||||||
|
F ext/misc/randomjson.c 7dd13664155319d47b9facc0d8dbf45e13062966a47168e54e3f26d48240d7ea
|
||||||
F ext/misc/regexp.c f50ab59bfa8934b7ed98de069d2c74c187f2ef523fb09e85f8840f6459a90942
|
F ext/misc/regexp.c f50ab59bfa8934b7ed98de069d2c74c187f2ef523fb09e85f8840f6459a90942
|
||||||
F ext/misc/remember.c add730f0f7e7436cd15ea3fd6a90fd83c3f706ab44169f7f048438b7d6baa69c
|
F ext/misc/remember.c add730f0f7e7436cd15ea3fd6a90fd83c3f706ab44169f7f048438b7d6baa69c
|
||||||
F ext/misc/rot13.c 51ac5f51e9d5fd811db58a9c23c628ad5f333c173f1fc53c8491a3603d38556c
|
F ext/misc/rot13.c 51ac5f51e9d5fd811db58a9c23c628ad5f333c173f1fc53c8491a3603d38556c
|
||||||
@@ -588,13 +589,13 @@ F src/expr.c 871cfd80c516ee39d90414b2d3da2b5bc9c9e21fe87b7eb787ea7ae4b6461758
|
|||||||
F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007
|
F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007
|
||||||
F src/fkey.c 03c134cc8bffe54835f742ddea0b72ebfc8f6b32773d175c71b8afeea6cb5c83
|
F src/fkey.c 03c134cc8bffe54835f742ddea0b72ebfc8f6b32773d175c71b8afeea6cb5c83
|
||||||
F src/func.c d187be57a886ddf4e6b7ef584a494361899be3df5eee6d4a747b68ff4aff4122
|
F src/func.c d187be57a886ddf4e6b7ef584a494361899be3df5eee6d4a747b68ff4aff4122
|
||||||
F src/global.c 428d2580a1cdf5dbe1f356d1feab83710ae0cc862ece0fb57bc8259e43838c74
|
F src/global.c bd0892ade7289f6e20bff44c07d06371f2ff9b53cea359e7854b9b72f65adc30
|
||||||
F src/hash.c c6af5f96a7a76d000f07c5402c48c318c2566beecdee9e78b9d9f60ce7119565
|
F src/hash.c c6af5f96a7a76d000f07c5402c48c318c2566beecdee9e78b9d9f60ce7119565
|
||||||
F src/hash.h 3340ab6e1d13e725571d7cee6d3e3135f0779a7d8e76a9ce0a85971fa3953c51
|
F src/hash.h 3340ab6e1d13e725571d7cee6d3e3135f0779a7d8e76a9ce0a85971fa3953c51
|
||||||
F src/hwtime.h b638809e083b601b618df877b2e89cb87c2a47a01f4def10be4c4ebb54664ac7
|
F src/hwtime.h b638809e083b601b618df877b2e89cb87c2a47a01f4def10be4c4ebb54664ac7
|
||||||
F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71
|
F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71
|
||||||
F src/insert.c a8de1db43335fc4946370a7a7e47d89975ad678ddb15078a150e993ba2fb37d4
|
F src/insert.c a8de1db43335fc4946370a7a7e47d89975ad678ddb15078a150e993ba2fb37d4
|
||||||
F src/json.c edae65fe1f66ce8b1e7fa6eb036a3d8cf525dacd91d58f12068e80a81ac34f61
|
F src/json.c dd76caa9c9f1b417f7d7cdee06baabcbfc4c5ee18a578150d8f19c28260abeac
|
||||||
F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa
|
F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa
|
||||||
F src/loadext.c be5af440f3192c58681b5d43167dbca3ccbfce394d89faa22378a14264781136
|
F src/loadext.c be5af440f3192c58681b5d43167dbca3ccbfce394d89faa22378a14264781136
|
||||||
F src/main.c 09bc5191f75dc48fc4dfddda143cb864c0c3dbc3297eb9a9c8e01fea58ff847d
|
F src/main.c 09bc5191f75dc48fc4dfddda143cb864c0c3dbc3297eb9a9c8e01fea58ff847d
|
||||||
@@ -639,7 +640,7 @@ F src/shell.c.in 09097e1b9df1f8092e85bf89979e12ca7b608d7efc84551b5d0c8de4dded779
|
|||||||
F src/sqlite.h.in 6066996620c2a97193518148ab2d3cedf37d8ee7667dafa96c207a86152b2cfb
|
F src/sqlite.h.in 6066996620c2a97193518148ab2d3cedf37d8ee7667dafa96c207a86152b2cfb
|
||||||
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
|
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
|
||||||
F src/sqlite3ext.h da473ce2b3d0ae407a6300c4a164589b9a6bfdbec9462688a8593ff16f3bb6e4
|
F src/sqlite3ext.h da473ce2b3d0ae407a6300c4a164589b9a6bfdbec9462688a8593ff16f3bb6e4
|
||||||
F src/sqliteInt.h bf15f7db635d2e64a227bbf86845bc19755dbd932021a6461d6dd15b0da2cfd3
|
F src/sqliteInt.h 6766b36c215e33d2cbfd48e632b7cc516092273d909672fdc095bcbd8c005ba1
|
||||||
F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a31657
|
F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a31657
|
||||||
F src/status.c 160c445d7d28c984a0eae38c144f6419311ed3eace59b44ac6dafc20db4af749
|
F src/status.c 160c445d7d28c984a0eae38c144f6419311ed3eace59b44ac6dafc20db4af749
|
||||||
F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1
|
F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1
|
||||||
@@ -702,7 +703,7 @@ F src/trigger.c ad6ab9452715fa9a8075442e15196022275b414b9141b566af8cdb7a1605f2b0
|
|||||||
F src/update.c 3f4fb5ad7c9b48d7911974d6579192bb3a6c27f46140b6cbb9139cc8a77b8691
|
F src/update.c 3f4fb5ad7c9b48d7911974d6579192bb3a6c27f46140b6cbb9139cc8a77b8691
|
||||||
F src/upsert.c 5303dc6c518fa7d4b280ec65170f465c7a70b7ac2b22491598f6d0b4875b3145
|
F src/upsert.c 5303dc6c518fa7d4b280ec65170f465c7a70b7ac2b22491598f6d0b4875b3145
|
||||||
F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0
|
F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0
|
||||||
F src/util.c b1d8d87c4c8c77e70f48c43f91444fd66d91532693573b70b837afd572010176
|
F src/util.c d4bcb560471cd94e6e17d448311f8d5bf81a7e5276295a53501058ef1b95dd1a
|
||||||
F src/vacuum.c 84ce7f01f8a7a08748e107a441db83bcec13970190ddcb0c9ff522adbc1c23fd
|
F src/vacuum.c 84ce7f01f8a7a08748e107a441db83bcec13970190ddcb0c9ff522adbc1c23fd
|
||||||
F src/vdbe.c 94d5520d2a287216c47e6fb641ee88ffd934b0d40c235d693d38bcd0e0750357
|
F src/vdbe.c 94d5520d2a287216c47e6fb641ee88ffd934b0d40c235d693d38bcd0e0750357
|
||||||
F src/vdbe.h 637ae853b7d42ae3951034cc63ab7c8af837861f79504cdb5399552fcd89a884
|
F src/vdbe.h 637ae853b7d42ae3951034cc63ab7c8af837861f79504cdb5399552fcd89a884
|
||||||
@@ -1251,11 +1252,17 @@ F test/journal3.test 7c3cf23ffc77db06601c1fcfc9743de8441cb77db9d1aa931863d94f5ff
|
|||||||
F test/jrnlmode.test 9b5bc01dac22223cb60ec2d5f97acf568d73820794386de5634dcadbea9e1946
|
F test/jrnlmode.test 9b5bc01dac22223cb60ec2d5f97acf568d73820794386de5634dcadbea9e1946
|
||||||
F test/jrnlmode2.test 8759a1d4657c064637f8b079592651530db738419e1d649c6df7048cd724363d
|
F test/jrnlmode2.test 8759a1d4657c064637f8b079592651530db738419e1d649c6df7048cd724363d
|
||||||
F test/jrnlmode3.test 556b447a05be0e0963f4311e95ab1632b11c9eaa
|
F test/jrnlmode3.test 556b447a05be0e0963f4311e95ab1632b11c9eaa
|
||||||
F test/json101.test c7707ee623c57a24845ef260d4388a6fade1eb294e450caadd7f1d9ced19dea7
|
F test/json/README.md 506af1f54574b524106acb50d1a341ab5ddfa6d83fe25095007892b07e663e85
|
||||||
F test/json102.test 327e77275f338c028faefa2da5164daf6b142a165e3015ff2a6e4251ddc6a0ac
|
F test/json/json-generator.tcl dc0dd0f393800c98658fc4c47eaa6af29d4e17527380cd28656fb261bddc8a3f
|
||||||
|
F test/json/json-q1.txt 335a7c8ab291d354f33b7decc9559e99a2823d4142291c4be7aa339a631f3c2d
|
||||||
|
F test/json/json-speed-check.sh 8b7babf530faa58bd59d6d362cec8e9036a68c5457ff46f3b1f1511d21af6737 x
|
||||||
|
F test/json101.test 211d75638782370c07e10a847bd66e501ea1537f39c7da4447bfa055c0f261db
|
||||||
|
F test/json102.test 13dc9e7b7f359ecb861e02f9bd7019f7342a63d1c354273b0a8f3904050560a8
|
||||||
F test/json103.test 53df87f83a4e5fa0c0a56eb29ff6c94055c6eb919f33316d62161a8880112dbe
|
F test/json103.test 53df87f83a4e5fa0c0a56eb29ff6c94055c6eb919f33316d62161a8880112dbe
|
||||||
F test/json104.test a502dc01853aada95d721b3b275afbe2dc18fffdac1fea6e96fb20c13586bbb5
|
F test/json104.test 1b844a70cddcfa2e4cd81a5db0657b2e61e7f00868310f24f56a9ba0114348c1
|
||||||
F test/json105.test 11670a4387f4308ae0318cadcbd6a918ea7edcd19fbafde020720a073952675d
|
F test/json105.test 11670a4387f4308ae0318cadcbd6a918ea7edcd19fbafde020720a073952675d
|
||||||
|
F test/json501.test f71710f60fa45b19dc336fbaac9e8362f70f80cf81badefdb845ed3f7c7c2ccc
|
||||||
|
F test/json502.test 66d150cc098674b8bf4354526a8dd411b926f43ca892306bcb3b6d3f93fef7be
|
||||||
F test/keyword1.test 37ef6bba5d2ed5b07ecdd6810571de2956599dff
|
F test/keyword1.test 37ef6bba5d2ed5b07ecdd6810571de2956599dff
|
||||||
F test/kvtest.c feb4358fb022da8ebd098c45811f2f6507688bb6c43aa72b3e840df19026317b
|
F test/kvtest.c feb4358fb022da8ebd098c45811f2f6507688bb6c43aa72b3e840df19026317b
|
||||||
F test/lastinsert.test 42e948fd6442f07d60acbd15d33fb86473e0ef63
|
F test/lastinsert.test 42e948fd6442f07d60acbd15d33fb86473e0ef63
|
||||||
@@ -2061,8 +2068,9 @@ 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 d74011a3c495719fe1816e15251269824396ac2a40e41f7b96f0dd507c9be609
|
P ab75170d5609c477613466e8880f20b74b0069281db6536fe09db06ea9d7cff3 1b991c78141a9915ae9350ecb347a758e50d7d25c8a0f4cc098ae10d47c27043
|
||||||
R 94e403657c9a5bd8b38c0149c27e975a
|
R d47f0442b266c4b31be73caa106551c0
|
||||||
U dan
|
T +closed 1b991c78141a9915ae9350ecb347a758e50d7d25c8a0f4cc098ae10d47c27043
|
||||||
Z fbd061bc3bd6b18ca241f57c968aece1
|
U drh
|
||||||
|
Z 86cda36754b86452b62afe6022ca194a
|
||||||
# Remove this line to create a well-formed Fossil manifest.
|
# Remove this line to create a well-formed Fossil manifest.
|
||||||
|
@@ -1 +1 @@
|
|||||||
ab75170d5609c477613466e8880f20b74b0069281db6536fe09db06ea9d7cff3
|
f8c3ed23a6931b1da3b93b3274b132387078112a5c8e8d06b5312c47987d3937
|
@@ -97,7 +97,7 @@ const unsigned char *sqlite3aGTb = &sqlite3UpperToLower[256+12-OP_Ne];
|
|||||||
** isalnum() 0x06
|
** isalnum() 0x06
|
||||||
** isxdigit() 0x08
|
** isxdigit() 0x08
|
||||||
** toupper() 0x20
|
** toupper() 0x20
|
||||||
** SQLite identifier character 0x40
|
** SQLite identifier character 0x40 $, _, or non-ascii
|
||||||
** Quote character 0x80
|
** Quote character 0x80
|
||||||
**
|
**
|
||||||
** Bit 0x20 is set if the mapped character requires translation to upper
|
** Bit 0x20 is set if the mapped character requires translation to upper
|
||||||
|
981
src/json.c
981
src/json.c
File diff suppressed because it is too large
Load Diff
@@ -4456,6 +4456,8 @@ int sqlite3CantopenError(int);
|
|||||||
# define sqlite3Isxdigit(x) (sqlite3CtypeMap[(unsigned char)(x)]&0x08)
|
# define sqlite3Isxdigit(x) (sqlite3CtypeMap[(unsigned char)(x)]&0x08)
|
||||||
# define sqlite3Tolower(x) (sqlite3UpperToLower[(unsigned char)(x)])
|
# define sqlite3Tolower(x) (sqlite3UpperToLower[(unsigned char)(x)])
|
||||||
# define sqlite3Isquote(x) (sqlite3CtypeMap[(unsigned char)(x)]&0x80)
|
# define sqlite3Isquote(x) (sqlite3CtypeMap[(unsigned char)(x)]&0x80)
|
||||||
|
# define sqlite3JsonId1(x) (sqlite3CtypeMap[(unsigned char)(x)]&0x42)
|
||||||
|
# define sqlite3JsonId2(x) (sqlite3CtypeMap[(unsigned char)(x)]&0x46)
|
||||||
#else
|
#else
|
||||||
# define sqlite3Toupper(x) toupper((unsigned char)(x))
|
# define sqlite3Toupper(x) toupper((unsigned char)(x))
|
||||||
# define sqlite3Isspace(x) isspace((unsigned char)(x))
|
# define sqlite3Isspace(x) isspace((unsigned char)(x))
|
||||||
@@ -4465,6 +4467,8 @@ int sqlite3CantopenError(int);
|
|||||||
# define sqlite3Isxdigit(x) isxdigit((unsigned char)(x))
|
# define sqlite3Isxdigit(x) isxdigit((unsigned char)(x))
|
||||||
# define sqlite3Tolower(x) tolower((unsigned char)(x))
|
# define sqlite3Tolower(x) tolower((unsigned char)(x))
|
||||||
# define sqlite3Isquote(x) ((x)=='"'||(x)=='\''||(x)=='['||(x)=='`')
|
# define sqlite3Isquote(x) ((x)=='"'||(x)=='\''||(x)=='['||(x)=='`')
|
||||||
|
# define sqlite3JsonId1(x) (sqlite3IsIdChar(x)&&(x)<'0')
|
||||||
|
# define sqlite3JsonId2(x) sqlite3IsIdChar(x)
|
||||||
#endif
|
#endif
|
||||||
int sqlite3IsIdChar(u8);
|
int sqlite3IsIdChar(u8);
|
||||||
|
|
||||||
|
@@ -843,7 +843,9 @@ int sqlite3DecOrHexToI64(const char *z, i64 *pOut){
|
|||||||
u = u*16 + sqlite3HexToInt(z[k]);
|
u = u*16 + sqlite3HexToInt(z[k]);
|
||||||
}
|
}
|
||||||
memcpy(pOut, &u, 8);
|
memcpy(pOut, &u, 8);
|
||||||
return (z[k]==0 && k-i<=16) ? 0 : 2;
|
if( k-i>16 ) return 2;
|
||||||
|
if( z[k]!=0 ) return 1;
|
||||||
|
return 0;
|
||||||
}else
|
}else
|
||||||
#endif /* SQLITE_OMIT_HEX_INTEGER */
|
#endif /* SQLITE_OMIT_HEX_INTEGER */
|
||||||
{
|
{
|
||||||
|
27
test/json/README.md
Normal file
27
test/json/README.md
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
The files in this subdirectory are used to help measure the performance
|
||||||
|
of the SQLite JSON parser.
|
||||||
|
|
||||||
|
# 1.0 Prerequisites
|
||||||
|
|
||||||
|
1. Valgrind
|
||||||
|
|
||||||
|
2. Fossil
|
||||||
|
|
||||||
|
# 2.0 Setup
|
||||||
|
|
||||||
|
1. Run: "`tclsh json-generator.tcl | sqlite3 json100mb.db`" to create
|
||||||
|
the 100 megabyte test database. Do this so that the "json100mb.db"
|
||||||
|
file lands in the directory from which you will run tests, not in
|
||||||
|
the test/json subdirectory of the source tree.
|
||||||
|
|
||||||
|
2. Build the baseline sqlite3.c file. ("`make sqlite3.c`")
|
||||||
|
|
||||||
|
3. Run "`sh json-speed-check-1.sh trunk`". This creates the baseline
|
||||||
|
profile in "jout-trunk.txt".
|
||||||
|
|
||||||
|
# 3.0 Testing
|
||||||
|
|
||||||
|
1. Build the sqlite3.c to be tested.
|
||||||
|
|
||||||
|
2. Run "`sh json-speed-check-1.sh x1`". The profile output will appear
|
||||||
|
in jout-x1.txt. Substitute any label you want in place of "x1".
|
401
test/json/json-generator.tcl
Normal file
401
test/json/json-generator.tcl
Normal file
@@ -0,0 +1,401 @@
|
|||||||
|
#!/usr/bin/tclsh
|
||||||
|
#
|
||||||
|
# Generate SQL that will populate an SQLite database with about 100 megabytes
|
||||||
|
# of pseudo-random JSON text.
|
||||||
|
#
|
||||||
|
# tclsh json-generator.tcl | sqlite3 json110mb.db
|
||||||
|
#
|
||||||
|
# srand() is used to initialize the random seed so that the same JSON
|
||||||
|
# is generated for every run.
|
||||||
|
#
|
||||||
|
expr srand(12345678)
|
||||||
|
set wordlist {
|
||||||
|
ability able abroad access account act
|
||||||
|
action active actor add address adept
|
||||||
|
adroit advance advice affect age ageless
|
||||||
|
agency agent agile agree air airfare
|
||||||
|
airline airport alert almond alpha always
|
||||||
|
amend amount amplify analyst anchor angel
|
||||||
|
angelic angle ankle annual answer antique
|
||||||
|
anybody anyhow appeal apple apricot apt
|
||||||
|
area argon arm army arrival arsenic
|
||||||
|
art artful article arugula aside ask
|
||||||
|
aspect assist assume atom atone attempt
|
||||||
|
author autumn average avocado award awl
|
||||||
|
azure back bacon bag bagel bake
|
||||||
|
baker balance ball balloon bamboo banana
|
||||||
|
band banjo bank barium base basil
|
||||||
|
basin basis basket bass bat bath
|
||||||
|
battery beach beak bean bear bearcub
|
||||||
|
beauty beef beet beige being bell
|
||||||
|
belly belt bench bend benefit best
|
||||||
|
beta better beyond bicycle bid big
|
||||||
|
bike bill bird biscuit bismuth bisque
|
||||||
|
bit black blank blest blind bliss
|
||||||
|
block bloom blue board boat body
|
||||||
|
bokchoy bone bonus book bookish boot
|
||||||
|
border boron boss bossy bottle bottom
|
||||||
|
bow bowl bowtie box brain brainy
|
||||||
|
branch brave bravely bread break breath
|
||||||
|
breezy brick bridge brie brief briefly
|
||||||
|
bright broad broil bromine bronze brother
|
||||||
|
brow brown brush buddy budget buffalo
|
||||||
|
bug bugle bull bunch burger burly
|
||||||
|
burrito bus busy butter button buy
|
||||||
|
buyer byte cab cabbage cabinet cable
|
||||||
|
cadet cadmium caesium cake calcium caliper
|
||||||
|
call caller calm calmly camera camp
|
||||||
|
can canary cancel candle candy cap
|
||||||
|
capable caper capital captain car carbon
|
||||||
|
card care career careful carp carpet
|
||||||
|
carrot carry case cash cassava casual
|
||||||
|
cat catch catfish catsear catsup cause
|
||||||
|
cave celery cell century chain chair
|
||||||
|
chalk chance change channel chapter chard
|
||||||
|
charge charity chart check cheddar cheery
|
||||||
|
cheese chicken chicory chiffon child chin
|
||||||
|
chip chives choice chowder chum church
|
||||||
|
circle city claim clam class classic
|
||||||
|
classy clay clean cleaner clear clearly
|
||||||
|
clerk click client climate clock clorine
|
||||||
|
closet clothes cloud clown club clue
|
||||||
|
cluster coach coast coat cobbler cobolt
|
||||||
|
cod code coffee colby cold collar
|
||||||
|
college comb combine comet comfort command
|
||||||
|
comment common company complex concept concern
|
||||||
|
concert conduit consist contact contest context
|
||||||
|
control convert cook cookie copilot copper
|
||||||
|
copy coral cordial corn corner corny
|
||||||
|
correct cost count counter country county
|
||||||
|
couple courage course court cover cow
|
||||||
|
cowbird crab crack craft crash crazy
|
||||||
|
cream credit creek cress crevice crew
|
||||||
|
crimson croaker crop cross crowd cube
|
||||||
|
cuckoo cuisine culture cup current curve
|
||||||
|
cut cyan cycle dagger daily dance
|
||||||
|
dare darter data date day daylily
|
||||||
|
deal dear dearly debate debit decade
|
||||||
|
decimal deep deft deftly degree delay
|
||||||
|
deluxe deposit depth design desk detail
|
||||||
|
device dew diamond diet dig dill
|
||||||
|
dinner dip direct dirt dish disk
|
||||||
|
display diver divide divine doctor dodger
|
||||||
|
donut door dot double dough draft
|
||||||
|
drag dragon drama draw drawer drawing
|
||||||
|
dream drill drink drive driver drop
|
||||||
|
drum dry dryer drywall duck due
|
||||||
|
dump dusk dust duty dye eagle
|
||||||
|
ear earring earth ease east easy
|
||||||
|
eat economy edge editor eel effect
|
||||||
|
effort egg eight elbow elegant element
|
||||||
|
elf elk email emerald employ end
|
||||||
|
endive endless energy engine enjoy enter
|
||||||
|
entry equal equip error escape essay
|
||||||
|
eternal evening event exam example excuse
|
||||||
|
exit expert extent extreme eye face
|
||||||
|
fact factor factual fail failure fair
|
||||||
|
fajita fall family fan fang farm
|
||||||
|
farmer fat fault feature feed feel
|
||||||
|
feeling fench fennel festive few fiber
|
||||||
|
field fig figure file fill film
|
||||||
|
filter final finance finding finger finish
|
||||||
|
fire fish fishing fit fitting five
|
||||||
|
fix flier flight floor floral florine
|
||||||
|
flour flow flower fly flying focus
|
||||||
|
fold folding food foot force forest
|
||||||
|
forever forgive form formal format fortune
|
||||||
|
forum frame free freedom freely fresh
|
||||||
|
friend frog front fruit fuchsia fuel
|
||||||
|
fun funny future gain galaxy gallium
|
||||||
|
game gamma gap garage garden garlic
|
||||||
|
gas gate gather gauge gear gem
|
||||||
|
gene general gentle gently gherkin ghost
|
||||||
|
gift give glad glass gleeful glossy
|
||||||
|
glove glue goal goat goby gold
|
||||||
|
goldeye golf good gouda goulash gourd
|
||||||
|
grab grace grade gram grand grape
|
||||||
|
grapes grass gravy gray great green
|
||||||
|
grits grocery ground group grouper grout
|
||||||
|
growth guard guave guess guest guide
|
||||||
|
guitar gumbo guppy habit hacksaw haddock
|
||||||
|
hafnium hagfish hair half halibut hall
|
||||||
|
hammer hand handle handy hanger happy
|
||||||
|
hat havarti hay haybale head health
|
||||||
|
healthy hearing heart hearty heat heavy
|
||||||
|
heel height helium hello help helpful
|
||||||
|
herald herring hide high highly highway
|
||||||
|
hill hip hipster hire history hit
|
||||||
|
hoki hold hole holiday holly home
|
||||||
|
honest honey hook hope hopeful horizon
|
||||||
|
horn horse host hotel hour house
|
||||||
|
housing human humane humor hunt hurry
|
||||||
|
ice icecube icefish icy idea ideal
|
||||||
|
image impact impress inch income indigo
|
||||||
|
initial inkpen insect inside intense invite
|
||||||
|
iodine iridium iron island issue item
|
||||||
|
ivory jacket jargon javelin jello jelly
|
||||||
|
jewel job jocund join joint joke
|
||||||
|
jovial joy joyful joyous judge juice
|
||||||
|
jump junior jury just justice kale
|
||||||
|
keel keep kelp ketchup key keyhole
|
||||||
|
keyway khaki kick kid kidney kiloohm
|
||||||
|
kind kindly king kitchen kite kiwi
|
||||||
|
knee knife krill krypton kumquat lab
|
||||||
|
lace lack ladder lake lamp lamprey
|
||||||
|
land laser laugh law lawn lawyer
|
||||||
|
layer lead leader leading leaf leafy
|
||||||
|
league leather leave lecture leek leg
|
||||||
|
lemon length lentil lesson let letter
|
||||||
|
lettuce level library life lift light
|
||||||
|
lily lime limit line linen link
|
||||||
|
lip list listen lithium lively living
|
||||||
|
lizard load loan lobster local lock
|
||||||
|
log long longfin look lotus love
|
||||||
|
lovely loving low lucid luck luffa
|
||||||
|
lunch lung machine magenta magnet mail
|
||||||
|
main major make mall manager mango
|
||||||
|
manner many map march market maroon
|
||||||
|
martian master match math matter maximum
|
||||||
|
maybe meal meaning meat media medium
|
||||||
|
meet meeting melody melon member memory
|
||||||
|
mention menu mercury merry mess message
|
||||||
|
messy metal meter method micron middle
|
||||||
|
might mile milk mind mine minimum
|
||||||
|
minnow minor mint minute mirror miss
|
||||||
|
mission misty mix mixer mixture mobile
|
||||||
|
mode model moment monitor monk month
|
||||||
|
moon moray morning most motor mouse
|
||||||
|
mouth move mover movie much mud
|
||||||
|
mudfish muffin mullet munster muon muscle
|
||||||
|
music mustard nail name nation native
|
||||||
|
natural nature navy neat neatly nebula
|
||||||
|
neck needle neon nerve net network
|
||||||
|
neutron news nibble nice nickel night
|
||||||
|
niobium nobody noise noodle normal north
|
||||||
|
nose note nothing notice nova novel
|
||||||
|
number nurse nursery oar object offer
|
||||||
|
office officer oil okay okra old
|
||||||
|
olive one onion open opening opinion
|
||||||
|
option orange orbit orchid order oregano
|
||||||
|
other ounce outcome outside oven owner
|
||||||
|
oxygen oyster pace pack package page
|
||||||
|
pager paint pair pale pan pancake
|
||||||
|
papaya paper pardon parent park parking
|
||||||
|
parsley parsnip part partner party pass
|
||||||
|
passage past pasta path patient pattern
|
||||||
|
pause pay pea peace peach peacock
|
||||||
|
peahen peak peanut pear pearl pen
|
||||||
|
penalty pencil pension people pepper perch
|
||||||
|
perfect period permit person phase phone
|
||||||
|
photo phrase physics piano pick picture
|
||||||
|
pie piece pigeon pike pilot pin
|
||||||
|
pink pinkie pious pipe pitch pizza
|
||||||
|
place plan plane planet plant planter
|
||||||
|
plastic plate play player playful plenty
|
||||||
|
pliers plum pod poem poet poetry
|
||||||
|
point police policy pollock pony pool
|
||||||
|
pop popover poptart pork port portal
|
||||||
|
post pot potato pound powder power
|
||||||
|
present press price pride primary print
|
||||||
|
prior private prize problem process produce
|
||||||
|
product profile profit program project promise
|
||||||
|
prompt proof proper protein proton public
|
||||||
|
puff puffer pull pumpkin pup pupfish
|
||||||
|
pure purple purpose push put quality
|
||||||
|
quark quarter quiet quill quit quote
|
||||||
|
rabbit raccoon race radiant radio radish
|
||||||
|
radium radon rain rainbow raise ramp
|
||||||
|
ranch range rasp rate ratio ray
|
||||||
|
razor reach read reading real reality
|
||||||
|
reason recipe record recover red redeem
|
||||||
|
reed reef refuse region regret regular
|
||||||
|
relaxed release relief relish remote remove
|
||||||
|
rent repair repeat reply report request
|
||||||
|
reserve resist resolve resort rest result
|
||||||
|
return reveal review reward ribbon rice
|
||||||
|
rich ride ridge right ring rise
|
||||||
|
risk river rivet road roast rock
|
||||||
|
rocket role roll roof room rope
|
||||||
|
rose rough roughy round row royal
|
||||||
|
rub ruby rudder ruin rule run
|
||||||
|
runner rush rust sacred saddle safe
|
||||||
|
safety sail salad salami sale salmon
|
||||||
|
salt sample sand sander sandy sauce
|
||||||
|
save saving saw scale scampi scene
|
||||||
|
scheme school score screen script sea
|
||||||
|
search season seat second secret sector
|
||||||
|
seemly self sell senate senior sense
|
||||||
|
series serve set shake shape share
|
||||||
|
shark shell shift shine shiny ship
|
||||||
|
shock shoe shoot shop shovel show
|
||||||
|
side sign signal silk silly silver
|
||||||
|
simple sing singer single sink site
|
||||||
|
size skill skin sky slate sleep
|
||||||
|
sleepy slice slide slip smart smell
|
||||||
|
smelt smile smoke smooth snap snipe
|
||||||
|
snow snowy sock socket sodium soft
|
||||||
|
softly soil sole solid song sorrel
|
||||||
|
sort soul sound soup source south
|
||||||
|
space spare speech speed spell spend
|
||||||
|
sphere spice spider spirit spite split
|
||||||
|
spoon sport spot spray spread spring
|
||||||
|
squab square squash stable staff stage
|
||||||
|
stand staple star start state status
|
||||||
|
stay steak steel step stern stew
|
||||||
|
stick still stock stone stop store
|
||||||
|
storm story strain street stress strike
|
||||||
|
string stroke strong studio study stuff
|
||||||
|
style sugar suit sulfur summer sun
|
||||||
|
sunny sunset super superb surf survey
|
||||||
|
sweet swim swing switch symbol system
|
||||||
|
table tackle tail tale talk tan
|
||||||
|
tank tap tape target task taste
|
||||||
|
tau tea teach teal team tear
|
||||||
|
tell ten tender tennis tent term
|
||||||
|
test tetra text thanks theme theory
|
||||||
|
thing think thread throat thumb ticket
|
||||||
|
tidy tie tiger till time timely
|
||||||
|
tin tip title toast today toe
|
||||||
|
tomato tone tongue tool tooth top
|
||||||
|
topic total touch tough tour towel
|
||||||
|
tower town track trade train trash
|
||||||
|
travel tray treat tree trick trip
|
||||||
|
trout trowel truck trupet trust truth
|
||||||
|
try tube tuna tune turf turkey
|
||||||
|
turn turnip tutor tux tweet twist
|
||||||
|
two type union unique unit upbeat
|
||||||
|
upper use useful user usual valley
|
||||||
|
value van vase vast veil vein
|
||||||
|
velvet verse very vessel vest video
|
||||||
|
view violet visit visual vivid voice
|
||||||
|
volume vowel voyage waffle wait wake
|
||||||
|
walk wall warm warmth wasabi wash
|
||||||
|
watch water wave wax way wealth
|
||||||
|
wear web wedge week weekly weight
|
||||||
|
west whale what wheat wheel when
|
||||||
|
where while who whole why will
|
||||||
|
win wind window wing winner winter
|
||||||
|
wire wish witty wolf wonder wood
|
||||||
|
wool woolly word work worker world
|
||||||
|
worry worth worthy wrap wrench wrist
|
||||||
|
writer xenon yak yam yard yarrow
|
||||||
|
year yearly yellow yew yogurt young
|
||||||
|
youth zebra zephyr zinc zone zoo
|
||||||
|
}
|
||||||
|
set nwordlist [llength $wordlist]
|
||||||
|
|
||||||
|
proc random_char {} {
|
||||||
|
return [string index \
|
||||||
|
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" \
|
||||||
|
[expr {int(rand()*52)}]]
|
||||||
|
}
|
||||||
|
proc random_label {} {
|
||||||
|
set label [random_char]
|
||||||
|
while {rand()>0.8} {
|
||||||
|
append label [random_char]
|
||||||
|
}
|
||||||
|
if {rand()>0.9} {append label -}
|
||||||
|
append label [format %d [expr {int(rand()*100)}]]
|
||||||
|
return $label
|
||||||
|
}
|
||||||
|
proc random_numeric {} {
|
||||||
|
set n [expr {(rand()*2-1.0)*1e6}]
|
||||||
|
switch [expr {int(rand()*6)}] {
|
||||||
|
0 {set format %.3f}
|
||||||
|
1 {set format %.6E}
|
||||||
|
2 {set format %.4e}
|
||||||
|
default {set format %g}
|
||||||
|
}
|
||||||
|
return [format $format $n]
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
proc random_json {limit indent} {
|
||||||
|
global nwordlist wordlist
|
||||||
|
set res {}
|
||||||
|
if {$indent==0 || ($limit>0 && rand()>0.5)} {
|
||||||
|
incr limit -1
|
||||||
|
incr indent 2
|
||||||
|
set n [expr {int(rand()*5)+1}]
|
||||||
|
if {$n==5} {incr n [expr {int(rand()*10)}]}
|
||||||
|
if {rand()>0.5} {
|
||||||
|
set res \173\n
|
||||||
|
for {set i 0} {$i<$n} {incr i} {
|
||||||
|
append res [string repeat { } $indent]
|
||||||
|
if {rand()>0.8} {
|
||||||
|
if {rand()>0.5} {
|
||||||
|
set sep ":\n [string repeat { } $indent]"
|
||||||
|
} else {
|
||||||
|
set sep " : "
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
set sep :
|
||||||
|
}
|
||||||
|
append res \"[random_label]\"$sep[random_json $limit $indent]
|
||||||
|
if {$i<$n-1} {append res ,}
|
||||||
|
append res \n
|
||||||
|
}
|
||||||
|
incr indent -2
|
||||||
|
append res [string repeat { } $indent]
|
||||||
|
append res \175
|
||||||
|
return $res
|
||||||
|
} else {
|
||||||
|
set res \[\n
|
||||||
|
for {set i 0} {$i<$n} {incr i} {
|
||||||
|
append res [string repeat { } $indent]
|
||||||
|
append res [random_json $limit $indent]
|
||||||
|
if {$i<$n-1} {append res ,}
|
||||||
|
append res \n
|
||||||
|
}
|
||||||
|
incr indent -2
|
||||||
|
append res [string repeat { } $indent]
|
||||||
|
append res \]
|
||||||
|
return $res
|
||||||
|
}
|
||||||
|
} elseif {rand()>0.9} {
|
||||||
|
if {rand()>0.7} {return "true"}
|
||||||
|
if {rand()>0.5} {return "false"}
|
||||||
|
return "null"
|
||||||
|
} elseif {rand()>0.5} {
|
||||||
|
return [random_numeric]
|
||||||
|
} else {
|
||||||
|
set res \"
|
||||||
|
set n [expr {int(rand()*4)+1}]
|
||||||
|
if {$n>=4} {set n [expr {$n+int(rand()*6)}]}
|
||||||
|
for {set i 0} {$i<$n} {incr i} {
|
||||||
|
if {rand()<0.05} {
|
||||||
|
set w [random_numeric]
|
||||||
|
} else {
|
||||||
|
set k [expr {int(rand()*$nwordlist)}]
|
||||||
|
set w [lindex $wordlist $k]
|
||||||
|
}
|
||||||
|
if {rand()<0.07} {
|
||||||
|
set w \\\"$w\\\"
|
||||||
|
}
|
||||||
|
if {$i<$n-1} {
|
||||||
|
switch [expr {int(rand()*9)}] {
|
||||||
|
0 {set sp {, }}
|
||||||
|
1 {set sp "\\n "}
|
||||||
|
2 {set sp "-"}
|
||||||
|
default {set sp { }}
|
||||||
|
}
|
||||||
|
append res $w$sp
|
||||||
|
} else {
|
||||||
|
append res $w
|
||||||
|
if {rand()<0.2} {append res .}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $res\"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
puts "CREATE TABLE IF NOT EXISTS data1(x JSON);"
|
||||||
|
puts "BEGIN;"
|
||||||
|
set sz 0
|
||||||
|
for {set i 0} {$sz<100000000} {incr i} {
|
||||||
|
set j [random_json 7 0]
|
||||||
|
incr sz [string length $j]
|
||||||
|
puts "INSERT INTO data1(x) VALUES('$j');"
|
||||||
|
}
|
||||||
|
puts "COMMIT;"
|
||||||
|
puts "SELECT sum(length(x)) FROM data1;"
|
4
test/json/json-q1.txt
Normal file
4
test/json/json-q1.txt
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
.mode qbox
|
||||||
|
.timer on
|
||||||
|
.param set $label 'q87'
|
||||||
|
SELECT rowid, x->>$label FROM data1 WHERE x->>$label IS NOT NULL;
|
80
test/json/json-speed-check.sh
Executable file
80
test/json/json-speed-check.sh
Executable file
@@ -0,0 +1,80 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
#
|
||||||
|
# This is a template for a script used for day-to-day size and
|
||||||
|
# performance monitoring of SQLite. Typical usage:
|
||||||
|
#
|
||||||
|
# sh speed-check.sh trunk # Baseline measurement of trunk
|
||||||
|
# sh speed-check.sh x1 # Measure some experimental change
|
||||||
|
# fossil xdiff --tk jout-trunk.txt jout-x1.txt # View chanages
|
||||||
|
#
|
||||||
|
# There are multiple output files, all with a base name given by
|
||||||
|
# the first argument:
|
||||||
|
#
|
||||||
|
# summary-$BASE.txt # Copy of standard output
|
||||||
|
# jout-$BASE.txt # cachegrind output
|
||||||
|
# explain-$BASE.txt # EXPLAIN listings (only with --explain)
|
||||||
|
#
|
||||||
|
if test "$1" = ""
|
||||||
|
then
|
||||||
|
echo "Usage: $0 OUTPUTFILE [OPTIONS]"
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
NAME=$1
|
||||||
|
shift
|
||||||
|
#CC_OPTS="-DSQLITE_ENABLE_RTREE -DSQLITE_ENABLE_MEMSYS5"
|
||||||
|
CC_OPTS="-DSQLITE_ENABLE_MEMSYS5"
|
||||||
|
CC=gcc
|
||||||
|
LEAN_OPTS="-DSQLITE_THREADSAFE=0"
|
||||||
|
LEAN_OPTS="$LEAN_OPTS -DSQLITE_DEFAULT_MEMSTATUS=0"
|
||||||
|
LEAN_OPTS="$LEAN_OPTS -DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1"
|
||||||
|
LEAN_OPTS="$LEAN_OPTS -DSQLITE_LIKE_DOESNT_MATCH_BLOBS"
|
||||||
|
LEAN_OPTS="$LEAN_OPTS -DSQLITE_MAX_EXPR_DEPTH=0"
|
||||||
|
LEAN_OPTS="$LEAN_OPTS -DSQLITE_OMIT_DECLTYPE"
|
||||||
|
LEAN_OPTS="$LEAN_OPTS -DSQLITE_OMIT_DEPRECATED"
|
||||||
|
LEAN_OPTS="$LEAN_OPTS -DSQLITE_OMIT_PROGRESS_CALLBACK"
|
||||||
|
LEAN_OPTS="$LEAN_OPTS -DSQLITE_OMIT_SHARED_CACHE"
|
||||||
|
LEAN_OPTS="$LEAN_OPTS -DSQLITE_USE_ALLOCA"
|
||||||
|
BASELINE="trunk"
|
||||||
|
doExplain=0
|
||||||
|
doCachegrind=1
|
||||||
|
doVdbeProfile=0
|
||||||
|
doWal=1
|
||||||
|
doDiff=1
|
||||||
|
while test "$1" != ""; do
|
||||||
|
case $1 in
|
||||||
|
--nodiff)
|
||||||
|
doDiff=0
|
||||||
|
;;
|
||||||
|
--lean)
|
||||||
|
CC_OPTS="$CC_OPTS $LEAN_OPTS"
|
||||||
|
;;
|
||||||
|
--clang)
|
||||||
|
CC=clang
|
||||||
|
;;
|
||||||
|
--gcc7)
|
||||||
|
CC=gcc-7
|
||||||
|
;;
|
||||||
|
-*)
|
||||||
|
CC_OPTS="$CC_OPTS $1"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
BASELINE=$1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
shift
|
||||||
|
done
|
||||||
|
echo "NAME = $NAME" | tee summary-$NAME.txt
|
||||||
|
echo "CC_OPTS = $CC_OPTS" | tee -a summary-$NAME.txt
|
||||||
|
rm -f cachegrind.out.* jsonshell
|
||||||
|
$CC -g -Os -Wall -I. $CC_OPTS ./shell.c ./sqlite3.c -o jsonshell -ldl -lpthread
|
||||||
|
ls -l jsonshell | tee -a summary-$NAME.txt
|
||||||
|
home=`echo $0 | sed -e 's,/[^/]*$,,'`
|
||||||
|
echo ./jsonshell json100mb.db "<$home/json-q1.txt"
|
||||||
|
valgrind --tool=cachegrind ./jsonshell json100mb.db <$home/json-q1.txt \
|
||||||
|
2>&1 | tee -a summary-$NAME.txt
|
||||||
|
cg_anno.tcl cachegrind.out.* >jout-$NAME.txt
|
||||||
|
echo '*****************************************************' >>jout-$NAME.txt
|
||||||
|
sed 's/^[0-9=-]\{9\}/==00000==/' summary-$NAME.txt >>jout-$NAME.txt
|
||||||
|
if test "$NAME" != "$BASELINE"; then
|
||||||
|
fossil xdiff --tk -c 20 jout-$BASELINE.txt jout-$NAME.txt
|
||||||
|
fi
|
@@ -310,12 +310,33 @@ do_execsql_test json-6.1 {
|
|||||||
SELECT json_valid('{"a":55,"b":72,}');
|
SELECT json_valid('{"a":55,"b":72,}');
|
||||||
} {0}
|
} {0}
|
||||||
do_execsql_test json-6.2 {
|
do_execsql_test json-6.2 {
|
||||||
|
SELECT json_error_position('{"a":55,"b":72,}');
|
||||||
|
} {0}
|
||||||
|
do_execsql_test json-6.3 {
|
||||||
|
SELECT json_valid(json('{"a":55,"b":72,}'));
|
||||||
|
} {1}
|
||||||
|
do_execsql_test json-6.4 {
|
||||||
|
SELECT json_valid('{"a":55,"b":72 , }');
|
||||||
|
} {0}
|
||||||
|
do_execsql_test json-6.5 {
|
||||||
|
SELECT json_error_position('{"a":55,"b":72 , }');
|
||||||
|
} {0}
|
||||||
|
do_execsql_test json-6.6 {
|
||||||
|
SELECT json_error_position('{"a":55,"b":72,,}');
|
||||||
|
} {16}
|
||||||
|
do_execsql_test json-6.7 {
|
||||||
SELECT json_valid('{"a":55,"b":72}');
|
SELECT json_valid('{"a":55,"b":72}');
|
||||||
} {1}
|
} {1}
|
||||||
do_execsql_test json-6.3 {
|
do_execsql_test json-6.8 {
|
||||||
SELECT json_valid('["a",55,"b",72,]');
|
SELECT json_error_position('["a",55,"b",72,]');
|
||||||
} {0}
|
} {0}
|
||||||
do_execsql_test json-6.4 {
|
do_execsql_test json-6.9 {
|
||||||
|
SELECT json_error_position('["a",55,"b",72 , ]');
|
||||||
|
} {0}
|
||||||
|
do_execsql_test json-6.10 {
|
||||||
|
SELECT json_error_position('["a",55,"b",72,,]');
|
||||||
|
} {16}
|
||||||
|
do_execsql_test json-6.11 {
|
||||||
SELECT json_valid('["a",55,"b",72]');
|
SELECT json_valid('["a",55,"b",72]');
|
||||||
} {1}
|
} {1}
|
||||||
|
|
||||||
|
@@ -301,18 +301,27 @@ for {set i 0} {$i<100} {incr i} {
|
|||||||
# allowing them. The following tests verify that the problem is now
|
# allowing them. The following tests verify that the problem is now
|
||||||
# fixed.
|
# fixed.
|
||||||
#
|
#
|
||||||
do_execsql_test json102-1401 { SELECT json_valid('{"x":01}') } 0
|
foreach {id j x0 x5} {
|
||||||
do_execsql_test json102-1402 { SELECT json_valid('{"x":-01}') } 0
|
1401 {'{"x":01}'} 0 0
|
||||||
do_execsql_test json102-1403 { SELECT json_valid('{"x":0}') } 1
|
1402 {'{"x":-01}'} 0 0
|
||||||
do_execsql_test json102-1404 { SELECT json_valid('{"x":-0}') } 1
|
1403 {'{"x":0}'} 1 1
|
||||||
do_execsql_test json102-1405 { SELECT json_valid('{"x":0.1}') } 1
|
1404 {'{"x":-0}'} 1 1
|
||||||
do_execsql_test json102-1406 { SELECT json_valid('{"x":-0.1}') } 1
|
1405 {'{"x":0.1}'} 1 1
|
||||||
do_execsql_test json102-1407 { SELECT json_valid('{"x":0.0000}') } 1
|
1406 {'{"x":-0.1}'} 1 1
|
||||||
do_execsql_test json102-1408 { SELECT json_valid('{"x":-0.0000}') } 1
|
1407 {'{"x":0.0000}'} 1 1
|
||||||
do_execsql_test json102-1409 { SELECT json_valid('{"x":01.5}') } 0
|
1408 {'{"x":-0.0000}'} 1 1
|
||||||
do_execsql_test json102-1410 { SELECT json_valid('{"x":-01.5}') } 0
|
1409 {'{"x":01.5}'} 0 0
|
||||||
do_execsql_test json102-1411 { SELECT json_valid('{"x":00}') } 0
|
1410 {'{"x":-01.5}'} 0 0
|
||||||
do_execsql_test json102-1412 { SELECT json_valid('{"x":-00}') } 0
|
1411 {'{"x":00}'} 0 0
|
||||||
|
1412 {'{"x":-00}'} 0 0
|
||||||
|
1413 {'{"x":+0}'} 0 1
|
||||||
|
1414 {'{"x":+5}'} 0 1
|
||||||
|
1415 {'{"x":+5.5}'} 0 1
|
||||||
|
} {
|
||||||
|
do_execsql_test json102-$id "
|
||||||
|
SELECT json_valid($j), NOT json_error_position($j);
|
||||||
|
" [list $x0 $x5]
|
||||||
|
}
|
||||||
|
|
||||||
#------------------------------------------------------------------------
|
#------------------------------------------------------------------------
|
||||||
# 2017-04-10 ticket 6c9b5514077fed34551f98e64c09a10dc2fc8e16
|
# 2017-04-10 ticket 6c9b5514077fed34551f98e64c09a10dc2fc8e16
|
||||||
|
@@ -30,6 +30,48 @@ do_execsql_test json104-100 {
|
|||||||
}
|
}
|
||||||
}');
|
}');
|
||||||
} {{{"a":"z","c":{"d":"e"}}}}
|
} {{{"a":"z","c":{"d":"e"}}}}
|
||||||
|
do_execsql_test json104-101 {
|
||||||
|
SELECT json_patch('{
|
||||||
|
"a": "b",
|
||||||
|
"c": {
|
||||||
|
"d": "e",
|
||||||
|
"f": "g"
|
||||||
|
}
|
||||||
|
}','{
|
||||||
|
a:"z",
|
||||||
|
c: {
|
||||||
|
f: null
|
||||||
|
}
|
||||||
|
}');
|
||||||
|
} {{{"a":"z","c":{"d":"e"}}}}
|
||||||
|
do_execsql_test json104-102 {
|
||||||
|
SELECT json_patch('{
|
||||||
|
a: "b",
|
||||||
|
c: {
|
||||||
|
d: "e",
|
||||||
|
f: "g"
|
||||||
|
}
|
||||||
|
}','{
|
||||||
|
"a":"z",
|
||||||
|
"c": {
|
||||||
|
"f": null
|
||||||
|
}
|
||||||
|
}');
|
||||||
|
} {{{"a":"z","c":{"d":"e"}}}}
|
||||||
|
do_execsql_test json104-103 {
|
||||||
|
SELECT json_patch('{
|
||||||
|
a: "b",
|
||||||
|
c: {
|
||||||
|
d: "e",
|
||||||
|
f: "g"
|
||||||
|
}
|
||||||
|
}','{
|
||||||
|
a:"z",
|
||||||
|
c: {
|
||||||
|
f: null
|
||||||
|
}
|
||||||
|
}');
|
||||||
|
} {{{"a":"z","c":{"d":"e"}}}}
|
||||||
|
|
||||||
|
|
||||||
# This is the example from pages 4 and 5 of RFC-7396
|
# This is the example from pages 4 and 5 of RFC-7396
|
||||||
|
304
test/json501.test
Normal file
304
test/json501.test
Normal file
@@ -0,0 +1,304 @@
|
|||||||
|
# 2023-04-27
|
||||||
|
#
|
||||||
|
# The author disclaims copyright to this source code. In place of
|
||||||
|
# a legal notice, here is a blessing:
|
||||||
|
#
|
||||||
|
# May you do good and not evil.
|
||||||
|
# May you find forgiveness for yourself and forgive others.
|
||||||
|
# May you share freely, never taking more than you give.
|
||||||
|
#
|
||||||
|
#***********************************************************************
|
||||||
|
# This file implements tests for the JSON5 enhancements to the
|
||||||
|
# JSON SQL functions extension to the SQLite library.
|
||||||
|
#
|
||||||
|
|
||||||
|
set testdir [file dirname $argv0]
|
||||||
|
source $testdir/tester.tcl
|
||||||
|
set testprefix json501
|
||||||
|
|
||||||
|
# From https://spec.json5.org/#introduction
|
||||||
|
#
|
||||||
|
#-----------------------------------------------------------------------------
|
||||||
|
# Summary of Features
|
||||||
|
#
|
||||||
|
# The following ECMAScript 5.1 features, which are not supported in JSON, have
|
||||||
|
# been extended to JSON5.
|
||||||
|
#
|
||||||
|
# Objects
|
||||||
|
#
|
||||||
|
# 1) Object keys may be an ECMAScript 5.1 IdentifierName.
|
||||||
|
# 2) Objects may have a single trailing comma.
|
||||||
|
#
|
||||||
|
# Arrays
|
||||||
|
#
|
||||||
|
# 3) Arrays may have a single trailing comma.
|
||||||
|
#
|
||||||
|
# Strings
|
||||||
|
#
|
||||||
|
# 4) Strings may be single quoted.
|
||||||
|
# 5) Strings may span multiple lines by escaping new line characters.
|
||||||
|
# 6) Strings may include character escapes.
|
||||||
|
#
|
||||||
|
# Numbers
|
||||||
|
#
|
||||||
|
# 7) Numbers may be hexadecimal.
|
||||||
|
# 8) Numbers may have a leading or trailing decimal point.
|
||||||
|
# 9) Numbers may be IEEE 754 positive infinity, negative infinity, and NaN.
|
||||||
|
# 10) Numbers may begin with an explicit plus sign.
|
||||||
|
#
|
||||||
|
# Comments
|
||||||
|
#
|
||||||
|
# 11) Single and multi-line comments are allowed.
|
||||||
|
#
|
||||||
|
# White Space
|
||||||
|
#
|
||||||
|
# 12) Additional white space characters are allowed.
|
||||||
|
#-----------------------------------------------------------------------------
|
||||||
|
#
|
||||||
|
# Test number in this file are of the form X.Y where X is one of the item
|
||||||
|
# numbers in the feature list above and Y is the test sequence number.
|
||||||
|
#
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# 1) Object keys may be an ECMAScript 5.1 IdentifierName.
|
||||||
|
do_execsql_test 1.1 {
|
||||||
|
WITH c(x) AS (VALUES('{a:5,b:6}'))
|
||||||
|
SELECT x->>'a', json(x), json_valid(x), NOT json_error_position(x) FROM c;
|
||||||
|
} {5 {{"a":5,"b":6}} 0 1}
|
||||||
|
do_execsql_test 1.2 {
|
||||||
|
SELECT '[7,null,{a:5,b:6},[8,9]]'->>'$[2].b';
|
||||||
|
} {6}
|
||||||
|
do_execsql_test 1.3 {
|
||||||
|
SELECT '{ $123 : 789 }'->>'$."$123"';
|
||||||
|
} 789
|
||||||
|
do_execsql_test 1.4 {
|
||||||
|
SELECT '{ _123$xyz : 789 }'->>'$."_123$xyz"';
|
||||||
|
} 789
|
||||||
|
do_execsql_test 1.5 {
|
||||||
|
SELECT '{ MNO_123$xyz : 789 }'->>'$."MNO_123$xyz"';
|
||||||
|
} 789
|
||||||
|
|
||||||
|
do_execsql_test 1.6 {
|
||||||
|
SELECT json('{ MNO_123$xyz : 789 }');
|
||||||
|
} [list {{"MNO_123$xyz":789}}]
|
||||||
|
|
||||||
|
do_catchsql_test 1.10 {
|
||||||
|
SELECT json('{ MNO_123/xyz : 789 }');
|
||||||
|
} {1 {malformed JSON}}
|
||||||
|
|
||||||
|
do_execsql_test 1.11 {
|
||||||
|
SELECT '{ MNO_123æxyz : 789 }'->>'MNO_123æxyz';
|
||||||
|
} {789}
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# 2) Objects may have a single trailing comma.
|
||||||
|
|
||||||
|
do_execsql_test 2.1 {
|
||||||
|
WITH c(x) AS (VALUES('{"a":5, "b":6, }'))
|
||||||
|
SELECT x->>'b', json(x), json_valid(x), NOT json_error_position(x) FROM c;
|
||||||
|
} {6 {{"a":5,"b":6}} 0 1}
|
||||||
|
do_execsql_test 2.2 {
|
||||||
|
SELECT '{a:5, b:6 , }'->>'b';
|
||||||
|
} 6
|
||||||
|
do_catchsql_test 2.3 {
|
||||||
|
SELECT '{a:5, b:6 ,, }'->>'b';
|
||||||
|
} {1 {malformed JSON}}
|
||||||
|
do_catchsql_test 2.4 {
|
||||||
|
SELECT '{a:5, b:6, ,}'->>'b';
|
||||||
|
} {1 {malformed JSON}}
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# 3) Arrays may have a single trailing comma.
|
||||||
|
|
||||||
|
do_execsql_test 3.1 {
|
||||||
|
WITH c(x) AS (VALUES('[5, 6,]'))
|
||||||
|
SELECT x->>1, json(x), json_valid(x), NOT json_error_position(x) FROM c;
|
||||||
|
} {6 {[5,6]} 0 1}
|
||||||
|
do_execsql_test 3.2 {
|
||||||
|
SELECT '[5, 6 , ]'->>1;
|
||||||
|
} 6
|
||||||
|
do_catchsql_test 3.3 {
|
||||||
|
SELECT '[5, 6,,]'->>1;
|
||||||
|
} {1 {malformed JSON}}
|
||||||
|
do_catchsql_test 3.4 {
|
||||||
|
SELECT '[5, 6 , , ]'->>1;
|
||||||
|
} {1 {malformed JSON}}
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# 4) Strings may be single quoted.
|
||||||
|
|
||||||
|
do_execsql_test 4.1 {
|
||||||
|
WITH c(x) AS (VALUES('{"a": ''abcd''}'))
|
||||||
|
SELECT x->>'a', json(x), json_valid(x), NOT json_error_position(x) FROM c;
|
||||||
|
} {abcd {{"a":"abcd"}} 0 1}
|
||||||
|
do_execsql_test 4.2 {
|
||||||
|
SELECT '{b: 123, ''a'': ''ab\''cd''}'->>'a';
|
||||||
|
} {ab'cd}
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# 5) Strings may span multiple lines by escaping new line characters.
|
||||||
|
|
||||||
|
do_execsql_test 5.1 {
|
||||||
|
WITH c(x) AS (VALUES('{a: "abc'||char(0x5c,0x0a)||'xyz"}'))
|
||||||
|
SELECT x->>'a', json(x), json_valid(x), NOT json_error_position(x) FROM c;
|
||||||
|
} {abcxyz {{"a":"abcxyz"}} 0 1}
|
||||||
|
do_execsql_test 5.2 {
|
||||||
|
SELECT ('{a: "abc'||char(0x5c,0x0d)||'xyz"}')->>'a';
|
||||||
|
} {abcxyz}
|
||||||
|
do_execsql_test 5.3 {
|
||||||
|
SELECT ('{a: "abc'||char(0x5c,0x0d,0x0a)||'xyz"}')->>'a';
|
||||||
|
} {abcxyz}
|
||||||
|
do_execsql_test 5.4 {
|
||||||
|
SELECT ('{a: "abc'||char(0x5c,0x2028)||'xyz"}')->>'a';
|
||||||
|
} {abcxyz}
|
||||||
|
do_execsql_test 5.5 {
|
||||||
|
SELECT ('{a: "abc'||char(0x5c,0x2029)||'xyz"}')->>'a';
|
||||||
|
} {abcxyz}
|
||||||
|
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# 6) Strings may include character escapes.
|
||||||
|
|
||||||
|
do_execsql_test 6.1 {
|
||||||
|
SELECT ('{a: "abc'||char(0x5c,0x27)||'xyz"}')->>'a';
|
||||||
|
} {abc'xyz}
|
||||||
|
do_execsql_test 6.2 {
|
||||||
|
SELECT ('{a: "abc'||char(0x5c,0x22)||'xyz"}')->>'a';
|
||||||
|
} {abc"xyz}
|
||||||
|
do_execsql_test 6.3 {
|
||||||
|
SELECT ('{a: "abc'||char(0x5c,0x5c)||'xyz"}')->>'a';
|
||||||
|
} {{abc\xyz}}
|
||||||
|
do_execsql_test 6.4 {
|
||||||
|
SELECT hex(('{a: "abc\bxyz"}')->>'a');
|
||||||
|
} {6162630878797A}
|
||||||
|
do_execsql_test 6.5 {
|
||||||
|
SELECT hex(('{a: "abc\f\n\r\t\vxyz"}')->>'a');
|
||||||
|
} {6162630C0A0D090B78797A}
|
||||||
|
do_execsql_test 6.6 {
|
||||||
|
SELECT hex(('{a: "abc\0xyz"}')->>'a');
|
||||||
|
} {6162630078797A}
|
||||||
|
do_execsql_test 6.7 {
|
||||||
|
SELECT '{a: "abc\x35\x4f\x6Exyz"}'->>'a';
|
||||||
|
} {abc5Onxyz}
|
||||||
|
do_execsql_test 6.8 {
|
||||||
|
SELECT '{a: "\x6a\x6A\x6b\x6B\x6c\x6C\x6d\x6D\x6e\x6E\x6f\x6F"}'->>'a';
|
||||||
|
} {jjkkllmmnnoo}
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# 7) Numbers may be hexadecimal.
|
||||||
|
|
||||||
|
do_execsql_test 7.1 {
|
||||||
|
SELECT '{a: 0x0}'->>'a';
|
||||||
|
} 0
|
||||||
|
do_execsql_test 7.2 {
|
||||||
|
SELECT '{a: -0x0}'->>'a';
|
||||||
|
} 0
|
||||||
|
do_execsql_test 7.3 {
|
||||||
|
SELECT '{a: +0x0}'->>'a';
|
||||||
|
} 0
|
||||||
|
do_execsql_test 7.4 {
|
||||||
|
SELECT '{a: 0xabcdef}'->>'a';
|
||||||
|
} 11259375
|
||||||
|
do_execsql_test 7.5 {
|
||||||
|
SELECT '{a: -0xaBcDeF}'->>'a';
|
||||||
|
} -11259375
|
||||||
|
do_execsql_test 7.6 {
|
||||||
|
SELECT '{a: +0xABCDEF}'->>'a';
|
||||||
|
} 11259375
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# 8) Numbers may have a leading or trailing decimal point.
|
||||||
|
|
||||||
|
do_execsql_test 8.1 {
|
||||||
|
WITH c(x) AS (VALUES('{x: 4.}')) SELECT x->>'x', json(x) FROM c;
|
||||||
|
} {4.0 {{"x":4.0}}}
|
||||||
|
do_execsql_test 8.2 {
|
||||||
|
WITH c(x) AS (VALUES('{x: +4.}')) SELECT x->>'x', json(x) FROM c;
|
||||||
|
} {4.0 {{"x":4.0}}}
|
||||||
|
do_execsql_test 8.3 {
|
||||||
|
WITH c(x) AS (VALUES('{x: -4.}')) SELECT x->>'x', json(x) FROM c;
|
||||||
|
} {-4.0 {{"x":-4.0}}}
|
||||||
|
do_execsql_test 8.3 {
|
||||||
|
WITH c(x) AS (VALUES('{x: .5}')) SELECT x->>'x', json(x) FROM c;
|
||||||
|
} {0.5 {{"x":0.5}}}
|
||||||
|
do_execsql_test 8.4 {
|
||||||
|
WITH c(x) AS (VALUES('{x: -.5}')) SELECT x->>'x', json(x) FROM c;
|
||||||
|
} {-0.5 {{"x":-0.5}}}
|
||||||
|
do_execsql_test 8.5 {
|
||||||
|
WITH c(x) AS (VALUES('{x: +.5}')) SELECT x->>'x', json(x) FROM c;
|
||||||
|
} {0.5 {{"x":0.5}}}
|
||||||
|
do_execsql_test 8.6 {
|
||||||
|
WITH c(x) AS (VALUES('{x: 4.e0}')) SELECT x->>'x', json(x) FROM c;
|
||||||
|
} {4.0 {{"x":4.0e0}}}
|
||||||
|
do_execsql_test 8.7 {
|
||||||
|
WITH c(x) AS (VALUES('{x: +4.e1}')) SELECT x->>'x', json(x) FROM c;
|
||||||
|
} {40.0 {{"x":4.0e1}}}
|
||||||
|
do_execsql_test 8.8 {
|
||||||
|
WITH c(x) AS (VALUES('{x: -4.e2}')) SELECT x->>'x', json(x) FROM c;
|
||||||
|
} {-400.0 {{"x":-4.0e2}}}
|
||||||
|
do_execsql_test 8.9 {
|
||||||
|
WITH c(x) AS (VALUES('{x: .5e3}')) SELECT x->>'x', json(x) FROM c;
|
||||||
|
} {500.0 {{"x":0.5e3}}}
|
||||||
|
do_execsql_test 8.10 {
|
||||||
|
WITH c(x) AS (VALUES('{x: -.5e-1}')) SELECT x->>'x', json(x) FROM c;
|
||||||
|
} {-0.05 {{"x":-0.5e-1}}}
|
||||||
|
do_execsql_test 8.11 {
|
||||||
|
WITH c(x) AS (VALUES('{x: +.5e-2}')) SELECT x->>'x', json(x) FROM c;
|
||||||
|
} {0.005 {{"x":0.5e-2}}}
|
||||||
|
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# 9) Numbers may be IEEE 754 positive infinity, negative infinity, and NaN.
|
||||||
|
|
||||||
|
do_execsql_test 9.1 {
|
||||||
|
WITH c(x) AS (VALUES('{x: +Infinity}')) SELECT x->>'x', json(x) FROM c;
|
||||||
|
} {Inf {{"x":9.0e999}}}
|
||||||
|
do_execsql_test 9.2 {
|
||||||
|
WITH c(x) AS (VALUES('{x: -Infinity}')) SELECT x->>'x', json(x) FROM c;
|
||||||
|
} {-Inf {{"x":-9.0e999}}}
|
||||||
|
do_execsql_test 9.3 {
|
||||||
|
WITH c(x) AS (VALUES('{x: Infinity}')) SELECT x->>'x', json(x) FROM c;
|
||||||
|
} {Inf {{"x":9.0e999}}}
|
||||||
|
do_execsql_test 9.4 {
|
||||||
|
WITH c(x) AS (VALUES('{x: NaN}')) SELECT x->>'x', json(x) FROM c;
|
||||||
|
} {{} {{"x":null}}}
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# 10) Numbers may begin with an explicit plus sign.
|
||||||
|
|
||||||
|
do_execsql_test 10.1 {
|
||||||
|
SELECT '{a: +123}'->'a';
|
||||||
|
} 123
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# 11) Single and multi-line comments are allowed.
|
||||||
|
|
||||||
|
do_execsql_test 11.1 {
|
||||||
|
SELECT ' /* abc */ { /*def*/ aaa /* xyz */ : // to the end of line
|
||||||
|
123 /* xyz */ , /* 123 */ }'->>'aaa';
|
||||||
|
} 123
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# 12) Additional white space characters are allowed.
|
||||||
|
|
||||||
|
do_execsql_test 12.1 {
|
||||||
|
SELECT (char(0x09,0x0a,0x0b,0x0c,0x0d,0x20,0xa0,0x2028,0x2029)
|
||||||
|
|| '{a: "xyz"}')->>'a';
|
||||||
|
} xyz
|
||||||
|
do_execsql_test 12.2 {
|
||||||
|
SELECT ('{a:' || char(0x09,0x0a,0x0b,0x0c,0x0d,0x20,0xa0,0x2028,0x2029)
|
||||||
|
|| '"xyz"}')->>'a';
|
||||||
|
} xyz
|
||||||
|
do_execsql_test 12.3 {
|
||||||
|
SELECT (char(0x1680,0x2000,0x2001,0x2002,0x2003,0x2004,0x2005,
|
||||||
|
0x2006,0x2007,0x2008,0x2009,0x200a,0x3000,0xfeff)
|
||||||
|
|| '{a: "xyz"}')->>'a';
|
||||||
|
} xyz
|
||||||
|
do_execsql_test 12.4 {
|
||||||
|
SELECT ('{a: ' ||char(0x1680,0x2000,0x2001,0x2002,0x2003,0x2004,0x2005,
|
||||||
|
0x2006,0x2007,0x2008,0x2009,0x200a,0x3000,0xfeff)
|
||||||
|
|| ' "xyz"}')->>'a';
|
||||||
|
} xyz
|
||||||
|
|
||||||
|
|
||||||
|
finish_test
|
25
test/json502.test
Normal file
25
test/json502.test
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
# 2023-04-28
|
||||||
|
#
|
||||||
|
# The author disclaims copyright to this source code. In place of
|
||||||
|
# a legal notice, here is a blessing:
|
||||||
|
#
|
||||||
|
# May you do good and not evil.
|
||||||
|
# May you find forgiveness for yourself and forgive others.
|
||||||
|
# May you share freely, never taking more than you give.
|
||||||
|
#
|
||||||
|
#***********************************************************************
|
||||||
|
# This file implements tests for the JSON5 enhancements to the
|
||||||
|
# JSON SQL functions extension to the SQLite library.
|
||||||
|
#
|
||||||
|
|
||||||
|
set testdir [file dirname $argv0]
|
||||||
|
source $testdir/tester.tcl
|
||||||
|
set testprefix json502
|
||||||
|
|
||||||
|
do_execsql_test 1.1 {
|
||||||
|
CREATE TABLE t1(x JSON);
|
||||||
|
INSERT INTO t1(x) VALUES('{a:{b:{c:"hello",},},}');
|
||||||
|
SELECT fullkey FROM t1, json_tree(x);
|
||||||
|
} {{$} {$.a} {$.a.b} {$.a.b.c}}
|
||||||
|
|
||||||
|
finish_test
|
Reference in New Issue
Block a user