- C An\sattempt\sto\sintegrate\sthe\sJSON\sfunctions\sdirectly\sinto\sthe\sSQLite\score,\nrather\sthan\sholding\sthem\sas\san\sextension.
- D 2022-01-06T01:40:09.292
-C Improved\scommenting\sof\schanges\sin\sthe\sjson1.c\sextension.
-D 2022-01-08T15:05:53.556
++C Merge\sthe\sJSON\sfunction\senhancements\sfrom\sthe\sjson-enhancements\sbranch\sinto\njson-in-core.
++D 2022-01-08T15:37:13.201
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
-F Makefile.in 0e91c42a1dd13a569b1fa4f4dfb7d3632f3164a1c05c71341533d67db5b641dd
+F Makefile.in fd537743957bfe87997dc5727783d8eec82098921e15eab984d6711cd46f001b
F Makefile.linux-gcc f609543700659711fbd230eced1f01353117621dccae7b9fb70daa64236c5241
- F Makefile.msc 8ba680ec26e6d6f348954e0fee719607688075ef6c242e50e20d28e8ded7cc08
-F Makefile.msc 517f22463b99b56f6c4c81afcf09c7bf3a0289d08f2dadcc0d5322819dbd6017
++F Makefile.msc 22ce0007874c61c8eb51fc22b84f72af175ce2d7431c242253bdffa39c163da4
F README.md 2dd87a5c1d108b224921f3dd47dea567973f706e1f6959386282a626f459a70c
F VERSION 392c2f83569705069415a5d98b1c138ec8fe8a56a663a0d94cea019e806537b2
F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50
F config.guess 883205ddf25b46f10c181818bf42c09da9888884af96f79e1719264345053bd6
F config.h.in 6376abec766e9a0785178b1823b5a587e9f1ccbc
F config.sub c2d0260f17f3e4bc0b6808fccf1b291cb5e9126c14fc5890efc77b9fd0175559
-F configure 56f2a6637cdba53788673ccc229c4f95ab3ab6fe67036e0b1291dc615e531a58 x
-F configure.ac c8ba54bac7e73e000acdfef5e394fe21a3876aa09d0f5c07131bf5ac5a525299
+F configure a2877fe63cc821af0df41abe70f1f7c4e97cb7e23a42e0a1402e8a2f55a88aa2 x
+F configure.ac 3ef6eeff4387585bfcab76b0c3f6e15a0618587bb90245dd5d44e4378141bb35
F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad
F doc/F2FS.txt c1d4a0ae9711cfe0e1d8b019d154f1c29e0d3abfe820787ba1e9ed7691160fcd
+ F doc/json-enhancements.md b026346e18a18a90d84dbda457e3127282468ad26baaefc005a1656429fa4232
F doc/lemon.html efc0cd2345d66905505d98f862e1c571512def0ceb5b016cb658fd4918eb76a3
F doc/pager-invariants.txt 27fed9a70ddad2088750c4a2b493b63853da2710
F doc/trusted-schema.md 33625008620e879c7bcfbbfa079587612c434fa094d338b08242288d358c3e8a
F src/btree.h 74d64b8f28cfa4a894d14d4ed64fa432cd697b98b61708d4351482ae15913e22
F src/btreeInt.h ee9348c4cb9077243b049edc93a82c1f32ca48baeabf2140d41362b9f9139ff7
F src/build.c 6e16f7b539bfc55149a039bf0cda26b089640339df6147070b072df2d1c4f771
--F src/callback.c 106b585da1edd57d75fa579d823a5218e0bf37f191dbf7417eeb4a8a9a267dbc
++F src/callback.c 4c19af69835787bfe790ac560f3071a824eb629f34e41f97b52ce5235c77de1c
F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e
-F src/ctime.c 8159d5f706551861c18ec6c8f6bdf105e15ea00367f05d9ab65d31a1077facc1
+F src/ctime.c b09ce320b78718d5e0c4a7a59b8705abe8ee4683d9fa4b33768fe347e1b2a42a
F src/date.c ab8e01d928f201f5dee0bc6d54d6702fdcec96dff4d58c387447671f6a46d191
F src/dbpage.c 8a01e865bf8bc6d7b1844b4314443a6436c07c3efe1d488ed89e81719047833a
F src/dbstat.c 861e08690fcb0f2ee1165eff0060ea8d4f3e2ea10f80dab7d32ad70443a6ff2d
F src/hwtime.h cb1d7e3e1ed94b7aa6fde95ae2c2daccc3df826be26fc9ed7fd90d1750ae6144
F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71
F src/insert.c e528416ff5d86fc5d656ea6a26f03fde39836b6175f93048c32a03cb2ee16743
- F src/json.c 973b36a733cc5d3c8347bbdb3479c1124c0916ee7416341d0126895d055d2447 w ext/misc/json1.c
++F src/json.c 726f1901ecc66bc359d785c268e70c2f10fcec22b212613b00d7da5aa561d462
F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa
F src/loadext.c 95db1fe62c5973f1c5d9c53f6083e21a73ece14cdd47eeca0639691332e85c4d
-F src/main.c aa24539f6c26460543d51027ea14b79cad35e34bc9d4907bc349b52b71066644
+F src/main.c 2b6b0dbfeb14d4bb57e368604b0736b2aa42b51b00339d399b01d6b1fc9b4960
F src/malloc.c ef796bcc0e81d845d59a469f1cf235056caf9024172fd524e32136e65593647b
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
F src/mem1.c c12a42539b1ba105e3707d0e628ad70e611040d8f5e38cf942cee30c867083de
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
- P b6a82f3c3b9d89fdf628c7f117b6a4a64383a36c84fe84d47c80e845c9bd8a4f
- R 512e6db3c5e4ab4d0c8ece9f791ebefa
- T *branch * json-in-core
- T *sym-json-in-core *
- T -sym-trunk *
-P 18160985ea6b2bbf27de25e0f4f3a1ebcdb079a36af039fc06e37a834e49e772
-R ea25b8b6843a230f65190e794ee89370
++P 583b47d865fb8d2c9ae4d3a4e70356a8a758978efb0a282f6b19775bf41fb748 4d81425e1bf2cff6fa961d0a7936b5f62d3f8ffe9bffea89c1e8b8ddf8fad6f4
++R 9de2cc0789b4af5e569fa6f6937afbf5
U drh
- Z a41c104f7d21d7e5237fb8ae1a000e0b
-Z 72ca0ba8118c37c05f41d020549c1f4e
++Z 5d4090391a2a7b92e27e5b55336ae1bf
# Remove this line to create a well-formed Fossil manifest.
JsonParse *p; /* The parse */
JsonNode *pNode;
const char *zPath;
- int flags = *(int*)sqlite3_user_data(ctx);
++ int flags = SQLITE_PTR_TO_INT(sqlite3_user_data(ctx));
JsonString jx;
- int i;
if( argc<2 ) return;
- p = jsonParseCached(ctx, argv, ctx);
- if( p==0 ) return;
- jsonInit(&jx, ctx);
- jsonAppendChar(&jx, '[');
- for(i=1; i<argc; i++){
- zPath = (const char*)sqlite3_value_text(argv[i]);
- pNode = jsonLookup(p, zPath, 0, ctx);
- if( p->nErr ) break;
- if( argc>2 ){
+ p = jsonParseCached(ctx, argv, (flags & JSON_NULLERR)!=0 ? 0 : ctx);
+ if( p==0 ){
+ /* If the form is "json_nextract(IN,'$')" and IN is not well-formed JSON,
+ ** then return IN as a quoted JSON string. */
+ if( (flags & JSON_NULLERR)!=0
+ && argc==2
+ && (zPath = (const char*)sqlite3_value_text(argv[1]))!=0
+ && zPath[0]=='$' && zPath[1]==0
+ ){
+ jsonQuoteFunc(ctx, argc, argv);
+ }
+ return;
+ }
+ if( argc==2 ){
+ /* With a single PATH argument, the return is the unquoted SQL value */
+ zPath = (const char*)sqlite3_value_text(argv[1]);
+ if( zPath && zPath[0]!='$' && zPath[0]!=0 && (flags & JSON_ABPATH)!=0 ){
+ /* The -> and ->> operators accept abbreviated PATH arguments. This
+ ** is mostly for compatibility with PostgreSQL, but also for convenience.
+ **
+ ** NUMBER ==> $[NUMBER] // PG compatible
+ ** LABEL ==> $.LABEL // PG compatible
+ ** [NUMBER] ==> $[NUMBER] // Not PG. Purely for convenience
+ */
+ jsonInit(&jx, ctx);
- if( safe_isdigit(zPath[0]) ){
++ if( sqlite3Isdigit(zPath[0]) ){
+ jsonAppendRaw(&jx, "$[", 2);
+ jsonAppendRaw(&jx, zPath, (int)strlen(zPath));
+ jsonAppendRaw(&jx, "]", 2);
+ }else{
+ jsonAppendRaw(&jx, "$.", 1 + (zPath[0]!='['));
+ jsonAppendRaw(&jx, zPath, (int)strlen(zPath));
+ jsonAppendChar(&jx, 0);
+ }
+ pNode = jx.bErr ? 0 : jsonLookup(p, jx.zBuf, 0, ctx);
+ jsonReset(&jx);
+ }else{
+ pNode = jsonLookup(p, zPath, 0, ctx);
+ }
+ if( p->nErr ) return;
+ if( pNode ) jsonReturn(pNode, ctx, 0);
+ }else{
+ /* Two or more PATH arguments results in a JSON array with each
+ ** element of the array being the value selected by one of the PATHs */
+ int i;
+ jsonInit(&jx, ctx);
+ jsonAppendChar(&jx, '[');
+ for(i=1; i<argc; i++){
+ zPath = (const char*)sqlite3_value_text(argv[i]);
+ pNode = jsonLookup(p, zPath, 0, ctx);
+ if( p->nErr ) break;
jsonAppendSeparator(&jx);
if( pNode ){
jsonRenderNode(pNode, &jx, 0);
const char *zPath;
JsonNode *pNode;
- p = jsonParseCached(ctx, argv, ctx);
- p = jsonParseCached(ctx, argv, *(int*)sqlite3_user_data(ctx) ? 0 : ctx);
++ p = jsonParseCached(ctx, argv, sqlite3_user_data(ctx)!=0 ? 0 : ctx);
if( p==0 ) return;
if( argc==2 ){
zPath = (const char*)sqlite3_value_text(argv[1]);
0 /* xShadowName */
};
#endif /* SQLITE_OMIT_VIRTUALTABLE */
+#endif /* !defined(SQLITE_OMIT_JSON) */
-/****************************************************************************
-** The following routines are the only publically visible identifiers in this
-** file. Call the following routines in order to register the various SQL
-** functions and the virtual table implemented by this file.
-****************************************************************************/
-
-int sqlite3Json1Init(sqlite3 *db){
- int rc = SQLITE_OK;
- unsigned int i;
- static const struct {
- const char *zName;
- void (*xFunc)(sqlite3_context*,int,sqlite3_value**);
- int nArg;
- int flag;
- } aFunc[] = {
- { "json", jsonRemoveFunc, 1, 0 },
- { "json_array", jsonArrayFunc, -1, 0 },
- { "json_array_length", jsonArrayLengthFunc, 1, 0 },
- { "json_array_length", jsonArrayLengthFunc, 2, 0 },
- { "json_extract", jsonExtractFunc, -1, 0 },
- { "json_nextract", jsonExtractFunc, -1, JSON_NULLERR },
- { "->", jsonExtractFunc, 2, JSON_NULLERR|JSON_ABPATH },
- { "->>", jsonExtractFunc, 2, JSON_ABPATH },
- { "json_insert", jsonSetFunc, -1, 0 },
- { "json_object", jsonObjectFunc, -1, 0 },
- { "json_patch", jsonPatchFunc, 2, 0 },
- { "json_quote", jsonQuoteFunc, 1, 0 },
- { "json_remove", jsonRemoveFunc, -1, 0 },
- { "json_replace", jsonReplaceFunc, -1, 0 },
- { "json_set", jsonSetFunc, -1, JSON_ISSET },
- { "json_type", jsonTypeFunc, 1, 0 },
- { "json_ntype", jsonTypeFunc, 1, JSON_NULLERR },
- { "json_type", jsonTypeFunc, 2, 0 },
- { "json_valid", jsonValidFunc, 1, 0 },
-
+/*
+** Register JSON functions.
+*/
+void sqlite3RegisterJsonFunctions(void){
+#ifndef SQLITE_OMIT_JSON
+ static FuncDef aJsonFunc[] = {
- JFUNCTION(json, 1, 0, jsonRemoveFunc),
- JFUNCTION(json_array, -1, 0, jsonArrayFunc),
- JFUNCTION(json_array_length, 1, 0, jsonArrayLengthFunc),
- JFUNCTION(json_array_length, 2, 0, jsonArrayLengthFunc),
- JFUNCTION(json_extract, -1, 0, jsonExtractFunc),
- JFUNCTION(json_insert, -1, 0, jsonSetFunc),
- JFUNCTION(json_object, -1, 0, jsonObjectFunc),
- JFUNCTION(json_patch, 2, 0, jsonPatchFunc),
- JFUNCTION(json_quote, 1, 0, jsonQuoteFunc),
- JFUNCTION(json_remove, -1, 0, jsonRemoveFunc),
- JFUNCTION(json_replace, -1, 0, jsonReplaceFunc),
- JFUNCTION(json_set, -1, 1, jsonSetFunc),
- JFUNCTION(json_type, 1, 0, jsonTypeFunc),
- JFUNCTION(json_type, 2, 0, jsonTypeFunc),
- JFUNCTION(json_valid, 1, 0, jsonValidFunc),
++ JFUNCTION(json, 1, 0, jsonRemoveFunc),
++ JFUNCTION(json_array, -1, 0, jsonArrayFunc),
++ JFUNCTION(json_array_length, 1, 0, jsonArrayLengthFunc),
++ JFUNCTION(json_array_length, 2, 0, jsonArrayLengthFunc),
++ JFUNCTION(json_extract, -1, 0, jsonExtractFunc),
++ JFUNCTION(json_nextract, -1, JSON_NULLERR, jsonExtractFunc),
++ JFUNCTION(->, 2, JSON_NULLERR|JSON_ABPATH, jsonExtractFunc),
++ JFUNCTION(->>, 2, JSON_ABPATH, jsonExtractFunc),
++ JFUNCTION(json_insert, -1, 0, jsonSetFunc),
++ JFUNCTION(json_ntype, 1, JSON_NULLERR, jsonTypeFunc),
++ JFUNCTION(json_object, -1, 0, jsonObjectFunc),
++ JFUNCTION(json_patch, 2, 0, jsonPatchFunc),
++ JFUNCTION(json_quote, 1, 0, jsonQuoteFunc),
++ JFUNCTION(json_remove, -1, 0, jsonRemoveFunc),
++ JFUNCTION(json_replace, -1, 0, jsonReplaceFunc),
++ JFUNCTION(json_set, -1, JSON_ISSET, jsonSetFunc),
++ JFUNCTION(json_type, 1, 0, jsonTypeFunc),
++ JFUNCTION(json_type, 2, 0, jsonTypeFunc),
++ JFUNCTION(json_valid, 1, 0, jsonValidFunc),
#if SQLITE_DEBUG
- JFUNCTION(json_parse, 1, 0, jsonParseFunc),
- JFUNCTION(json_test1, 1, 0, jsonTest1Func),
- /* DEBUG and TESTING functions */
- { "json_parse", jsonParseFunc, 1, 0 },
- { "json_test1", jsonTest1Func, 1, 0 },
++ JFUNCTION(json_parse, 1, 0, jsonParseFunc),
++ JFUNCTION(json_test1, 1, 0, jsonTest1Func),
#endif
- WAGGREGATE(json_group_array, 1, 0, 0,
++ WAGGREGATE(json_group_array, 1, 0, 0,
+ jsonArrayStep, jsonArrayFinal, jsonArrayValue, jsonGroupInverse,
+ SQLITE_SUBTYPE|SQLITE_UTF8|SQLITE_DETERMINISTIC|SQLITE_INNOCUOUS),
- WAGGREGATE(json_group_object, 2, 0, 0,
++ WAGGREGATE(json_group_object, 2, 0, 0,
+ jsonObjectStep, jsonObjectFinal, jsonObjectValue, jsonGroupInverse,
+ SQLITE_SUBTYPE|SQLITE_UTF8|SQLITE_DETERMINISTIC|SQLITE_INNOCUOUS)
};
+ sqlite3InsertBuiltinFuncs(aJsonFunc, ArraySize(aJsonFunc));
+#endif
+}
+
+#if !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_OMIT_JSON)
+/*
+** Register the JSON table-valued functions
+*/
+int sqlite3JsonTableFunctions(sqlite3 *db){
+ int rc = SQLITE_OK;
static const struct {
- const char *zName;
- int nArg;
- void (*xStep)(sqlite3_context*,int,sqlite3_value**);
- void (*xFinal)(sqlite3_context*);
- void (*xValue)(sqlite3_context*);
- } aAgg[] = {
- { "json_group_array", 1,
- jsonArrayStep, jsonArrayFinal, jsonArrayValue },
- { "json_group_object", 2,
- jsonObjectStep, jsonObjectFinal, jsonObjectValue },
- };
-#ifndef SQLITE_OMIT_VIRTUALTABLE
- static const struct {
-- const char *zName;
-- sqlite3_module *pModule;
++ const char *zName;
++ sqlite3_module *pModule;
} aMod[] = {
{ "json_each", &jsonEachModule },
{ "json_tree", &jsonTreeModule },