aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--manifest24
-rw-r--r--manifest.uuid2
-rw-r--r--src/json.c56
-rw-r--r--src/sqlite.h.in36
-rw-r--r--src/sqliteInt.h8
-rw-r--r--src/where.c5
-rw-r--r--src/window.c2
7 files changed, 84 insertions, 49 deletions
diff --git a/manifest b/manifest
index 6996862b8..50b7a2513 100644
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Do\snot\scover\sexpressions\susing\san\sindexed\sexpression\sif\sthe\sindexed\sexpression\nis\sa\sfunction\sthat\smight\sset\sa\ssubtype.
-D 2023-11-08T18:08:07.513
+C Do\snot\sreplace\sexpressions\sthat\sreturn\ssubtypes\swith\svalues\staken\sfrom\san\nindex.
+D 2023-11-09T12:17:57.430
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@@ -684,7 +684,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 82d1237899d5d06dc9722f9a0d9305711ff563c68221b479f0788b33cb114e16
+F src/json.c bf117324d2efff47b392c29f7d3e611a7508933b91491c7ad349101e6d5f5e05
F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa
F src/loadext.c 7432c944ff197046d67a1207790a1b13eec4548c85a9457eb0896bb3641dfb36
F src/main.c e1bc8864834697503d370d94613be945d05ca1c5ebdda43e7d5c8ee8c48d433c
@@ -726,10 +726,10 @@ F src/resolve.c d017bad7ba8e778617701a0e986fdeb393d67d6afa84fb28ef4e8b8ad2acf916
F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97
F src/select.c a19daa26e95f7245106a31f288b2f50c72d1f2cc156703f04c8c91450e111515
F src/shell.c.in 7312c571ebf518fc8927bbb5aeb4fa67e5b0dfb2adae4258dcd1ccae42c11e1f
-F src/sqlite.h.in a0fce680a40fe81b13eae3749d001134d9fe0a43aecc09a8986520d5119acfcd
+F src/sqlite.h.in 8da45c84e79cde72c73fcb4260addcc7c00fac3bc6f5594b81a3792c1b196264
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
F src/sqlite3ext.h 3f046c04ea3595d6bfda99b781926b17e672fd6d27da2ba6d8d8fc39981dcb54
-F src/sqliteInt.h 90bbf1ba8f47753c84f15cdb0e5dc6267d3f391cc66b9fbd6f441881d1bf44a1
+F src/sqliteInt.h cd171cba32c7a553e7623fbd82b68b36a1b6c81079ab963260777ea9b3abe4d9
F src/sqliteLimit.h 33b1c9baba578d34efe7dfdb43193b366111cdf41476b1e82699e14c11ee1fb6
F src/status.c 160c445d7d28c984a0eae38c144f6419311ed3eace59b44ac6dafc20db4af749
F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1
@@ -809,11 +809,11 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9
F src/wal.c bba7db5dae3ffe2c6b9c173fc10be4b570b125e985cb5b95a6c22716213adde4
F src/wal.h ba252daaa94f889f4b2c17c027e823d9be47ce39da1d3799886bbd51f0490452
F src/walker.c 7c7ea0115345851c3da4e04e2e239a29983b61fb5b038b94eede6aba462640e2
-F src/where.c 431309d7920383671b05d43454351230eb9c01d963a6f7d4a516334cbbcce1d4
+F src/where.c 8718d58065745a4b7203a6b5d7c77b00d67eaf31a66d37c54a00f47c0cd23ac5
F src/whereInt.h 4b38c5889514e3aead3f27d0ee9a26e47c3f150efc59e2a8b4e3bc8835e4d7a1
F src/wherecode.c 5d77db30a2a3dd532492ae882de114edba2fae672622056b1c7fd61f5917a8f1
F src/whereexpr.c dc5096eca5ed503999be3bdee8a90c51361289a678d396a220912e9cb73b3c00
-F src/window.c ad21e2b73ec75acc79dde2576c573f54a338b0c49e9de847ce984f9b9595b5e2
+F src/window.c 5b1387d59df30d481ed14cceef5f4d1dab1f8752aa106ba72c8b62777bd139d2
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
F test/affinity2.test ce1aafc86e110685b324e9a763eab4f2a73f737842ec3b687bd965867de90627
F test/affinity3.test f094773025eddf31135c7ad4cde722b7696f8eb07b97511f98585addf2a510a9
@@ -2139,11 +2139,9 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P b2b62546c4a5e9dccb8aa0cb8eda228d662c69159e320b01a377317bc909e89f
-R 3699dfa06af6d8dfe43187d2c78cc578
-T *branch * idx-expr-fix
-T *sym-idx-expr-fix *
-T -sym-trunk *
+P 563ad3be60d22c45f1c5b9a3e67738593f8b38f137147c56514166fbabf95365 e908b26a990929996b3c16f0429e8313cd8fcefe7c883c77f66ea69f4059d6e2
+R 9822cb01a0a25ade383ea6b744dcbd50
+T +closed e908b26a990929996b3c16f0429e8313cd8fcefe7c883c77f66ea69f4059d6e2
U drh
-Z 99b5085d0aa63df2f84ecba864ce3e16
+Z 9cbc66987b5c47a4fc137a8fa57a64ca
# Remove this line to create a well-formed Fossil manifest.
diff --git a/manifest.uuid b/manifest.uuid
index 303299d81..f5689a65a 100644
--- a/manifest.uuid
+++ b/manifest.uuid
@@ -1 +1 @@
-e908b26a990929996b3c16f0429e8313cd8fcefe7c883c77f66ea69f4059d6e2 \ No newline at end of file
+a35d13db09e32ee339f3983fe36b073714753ee3d39f577ae8d20596d7adc3eb \ No newline at end of file
diff --git a/src/json.c b/src/json.c
index 407ca2d0e..132a274cd 100644
--- a/src/json.c
+++ b/src/json.c
@@ -3804,37 +3804,43 @@ static sqlite3_module jsonTreeModule = {
void sqlite3RegisterJsonFunctions(void){
#ifndef SQLITE_OMIT_JSON
static FuncDef aJsonFunc[] = {
- /* Uses cache ------, ,---- Might return JSON (subtype J) */
- /* Num args ________ | | ___ Flags */
- /* \ | | / */
- JFUNCTION(json, 1, 1, 1, 0, jsonRemoveFunc),
- JFUNCTION(json_array, -1, 0, 1, 0, jsonArrayFunc),
- JFUNCTION(json_array_length, 1, 1, 0, 0, jsonArrayLengthFunc),
- JFUNCTION(json_array_length, 2, 1, 0, 0, jsonArrayLengthFunc),
- JFUNCTION(json_error_position,1, 1, 0, 0, jsonErrorFunc),
- JFUNCTION(json_extract, -1, 1, 1, 0, jsonExtractFunc),
- JFUNCTION(->, 2, 1, 1, JSON_JSON, jsonExtractFunc),
- JFUNCTION(->>, 2, 1, 0, JSON_SQL, jsonExtractFunc),
- JFUNCTION(json_insert, -1, 1, 1, 0, jsonSetFunc),
- JFUNCTION(json_object, -1, 0, 1, 0, jsonObjectFunc),
- JFUNCTION(json_patch, 2, 1, 1, 0, jsonPatchFunc),
- JFUNCTION(json_quote, 1, 0, 1, 0, jsonQuoteFunc),
- JFUNCTION(json_remove, -1, 1, 1, 0, jsonRemoveFunc),
- JFUNCTION(json_replace, -1, 1, 1, 0, jsonReplaceFunc),
- JFUNCTION(json_set, -1, 1, 1, JSON_ISSET, jsonSetFunc),
- JFUNCTION(json_type, 1, 1, 0, 0, jsonTypeFunc),
- JFUNCTION(json_type, 2, 1, 0, 0, jsonTypeFunc),
- JFUNCTION(json_valid, 1, 1, 0, 0, jsonValidFunc),
+ /* calls sqlite3_result_subtype() */
+ /* | */
+ /* Uses cache ______ | __ calls sqlite3_value_subtype() */
+ /* | | | */
+ /* Num args _________ | | | ___ Flags */
+ /* | | | | | */
+ /* | | | | | */
+ JFUNCTION(json, 1, 1, 1, 0, 0, jsonRemoveFunc),
+ JFUNCTION(json_array, -1, 0, 1, 1, 0, jsonArrayFunc),
+ JFUNCTION(json_array_length, 1, 1, 0, 0, 0, jsonArrayLengthFunc),
+ JFUNCTION(json_array_length, 2, 1, 0, 0, 0, jsonArrayLengthFunc),
+ JFUNCTION(json_error_position,1, 1, 0, 0, 0, jsonErrorFunc),
+ JFUNCTION(json_extract, -1, 1, 1, 0, 0, jsonExtractFunc),
+ JFUNCTION(->, 2, 1, 1, 0, JSON_JSON, jsonExtractFunc),
+ JFUNCTION(->>, 2, 1, 0, 0, JSON_SQL, jsonExtractFunc),
+ JFUNCTION(json_insert, -1, 1, 1, 1, 0, jsonSetFunc),
+ JFUNCTION(json_object, -1, 0, 1, 1, 0, jsonObjectFunc),
+ JFUNCTION(json_patch, 2, 1, 1, 0, 0, jsonPatchFunc),
+ JFUNCTION(json_quote, 1, 0, 1, 1, 0, jsonQuoteFunc),
+ JFUNCTION(json_remove, -1, 1, 1, 0, 0, jsonRemoveFunc),
+ JFUNCTION(json_replace, -1, 1, 1, 1, 0, jsonReplaceFunc),
+ JFUNCTION(json_set, -1, 1, 1, 1, JSON_ISSET, jsonSetFunc),
+ JFUNCTION(json_type, 1, 1, 0, 0, 0, jsonTypeFunc),
+ JFUNCTION(json_type, 2, 1, 0, 0, 0, jsonTypeFunc),
+ JFUNCTION(json_valid, 1, 1, 0, 0, 0, jsonValidFunc),
#if SQLITE_DEBUG
- JFUNCTION(json_parse, 1, 1, 0, 0, jsonParseFunc),
- JFUNCTION(json_test1, 1, 1, 0, 0, jsonTest1Func),
+ JFUNCTION(json_parse, 1, 1, 1, 0, 0, jsonParseFunc),
+ JFUNCTION(json_test1, 1, 1, 0, 1, 0, jsonTest1Func),
#endif
WAGGREGATE(json_group_array, 1, 0, 0,
jsonArrayStep, jsonArrayFinal, jsonArrayValue, jsonGroupInverse,
- SQLITE_SUBTYPE|SQLITE_UTF8|SQLITE_DETERMINISTIC),
+ SQLITE_SUBTYPE|SQLITE_RESULT_SUBTYPE|SQLITE_UTF8|
+ SQLITE_DETERMINISTIC),
WAGGREGATE(json_group_object, 2, 0, 0,
jsonObjectStep, jsonObjectFinal, jsonObjectValue, jsonGroupInverse,
- SQLITE_SUBTYPE|SQLITE_UTF8|SQLITE_DETERMINISTIC)
+ SQLITE_SUBTYPE|SQLITE_RESULT_SUBTYPE|SQLITE_UTF8|
+ SQLITE_DETERMINISTIC)
};
sqlite3InsertBuiltinFuncs(aJsonFunc, ArraySize(aJsonFunc));
#endif
diff --git a/src/sqlite.h.in b/src/sqlite.h.in
index 2317d98f7..09e6f4765 100644
--- a/src/sqlite.h.in
+++ b/src/sqlite.h.in
@@ -5575,11 +5575,21 @@ int sqlite3_create_window_function(
** [[SQLITE_SUBTYPE]] <dt>SQLITE_SUBTYPE</dt><dd>
** The SQLITE_SUBTYPE flag indicates to SQLite that a function may call
** [sqlite3_value_subtype()] to inspect the sub-types of its arguments.
-** Specifying this flag makes no difference for scalar or aggregate user
-** functions. However, if it is not specified for a user-defined window
-** function, then any sub-types belonging to arguments passed to the window
-** function may be discarded before the window function is called (i.e.
-** sqlite3_value_subtype() will always return 0).
+** Every function that invokes [sqlite3_value_subtype()] should have this
+** property. If it does not, then the query planner might generate
+** incorrect code for queries that use that function.
+**
+** [[SQLITE_RESULT_SUBTYPE]] <dt>SQLITE_RESULT_SUBTYPE</dt><dd>
+** The SQLITE_RESULT_SUBTYPE flag indicates to SQLite that a function might call
+** [sqlite3_result_subtype()] to cause a sub-type to be associated with its
+** result.
+** Every function that invokes [sqlite3_result_subtype()] should have this
+** property. If it does not, then the call to [sqlite3_result_subtype()]
+** might become a no-op if the function is used as term in an
+** [expression index]. On the other hand, SQL functions that never invoke
+** [sqlite3_result_subtype()] should avoid setting this property, as the
+** purpose of this property is to disable certain optimizations that are
+** incompatible with subtypes.
** </dd>
** </dl>
*/
@@ -5587,6 +5597,7 @@ int sqlite3_create_window_function(
#define SQLITE_DIRECTONLY 0x000080000
#define SQLITE_SUBTYPE 0x000100000
#define SQLITE_INNOCUOUS 0x000200000
+#define SQLITE_RESULT_SUBTYPE 0x001000000
/*
** CAPI3REF: Deprecated Functions
@@ -5783,6 +5794,13 @@ int sqlite3_value_encoding(sqlite3_value*);
** information can be used to pass a limited amount of context from
** one SQL function to another. Use the [sqlite3_result_subtype()]
** routine to set the subtype for the return value of an SQL function.
+**
+** Every [application-defined SQL function] that invoke this interface
+** <i>must</i> include the [SQLITE_SUBTYPE] property in the text
+** encoding argument when the function is [sqlite3_create_function|registered].
+** The sqlite3_value_subtype() can return an incorrect answer if it
+** is invoked from within an application-defined SQL function that does
+** not have the [SQLITE_SUBTYPE] property.
*/
unsigned int sqlite3_value_subtype(sqlite3_value*);
@@ -6202,6 +6220,14 @@ int sqlite3_result_zeroblob64(sqlite3_context*, sqlite3_uint64 n);
** higher order bits are discarded.
** The number of subtype bytes preserved by SQLite might increase
** in future releases of SQLite.
+**
+** Every [application-defined SQL function] that invokes this interface
+** <i>must</i> include the [SQLITE_RESULT_SUBTYPE] property in its
+** text encoding argument when the SQL function is
+** [sqlite3_create_function|registered]. If the sqlite3_result_subtype()
+** interface is invoked within an SQL function that does not have the
+** SQLITE_RESULT_SUBTYPE property, then sqlite3_result_subtype()
+** might fail to set the result subtype.
*/
void sqlite3_result_subtype(sqlite3_context*,unsigned int);
diff --git a/src/sqliteInt.h b/src/sqliteInt.h
index 20e23ed2b..bb61cb691 100644
--- a/src/sqliteInt.h
+++ b/src/sqliteInt.h
@@ -2018,10 +2018,11 @@ struct FuncDestructor {
#define SQLITE_FUNC_WINDOW 0x00010000 /* Built-in window-only function */
#define SQLITE_FUNC_INTERNAL 0x00040000 /* For use by NestedParse() only */
#define SQLITE_FUNC_DIRECT 0x00080000 /* Not for use in TRIGGERs or VIEWs */
-#define SQLITE_FUNC_SUBTYPE 0x00100000 /* Result likely to have sub-type */
+/* SQLITE_SUBTYPE 0x00100000 // Consumer of subtypes */
#define SQLITE_FUNC_UNSAFE 0x00200000 /* Function has side effects */
#define SQLITE_FUNC_INLINE 0x00400000 /* Functions implemented in-line */
#define SQLITE_FUNC_BUILTIN 0x00800000 /* This is a built-in function */
+/* SQLITE_RESULT_SUBTYPE 0x01000000 // Generator of subtypes */
#define SQLITE_FUNC_ANYORDER 0x08000000 /* count/min/max aggregate */
/* Identifier numbers for each in-line function */
@@ -2113,9 +2114,10 @@ struct FuncDestructor {
#define MFUNCTION(zName, nArg, xPtr, xFunc) \
{nArg, SQLITE_FUNC_BUILTIN|SQLITE_FUNC_CONSTANT|SQLITE_UTF8, \
xPtr, 0, xFunc, 0, 0, 0, #zName, {0} }
-#define JFUNCTION(zName, nArg, bUseCache, bSubtype, iArg, xFunc) \
+#define JFUNCTION(zName, nArg, bUseCache, bWS, bRS, iArg, xFunc) \
{nArg, SQLITE_FUNC_BUILTIN|SQLITE_DETERMINISTIC|SQLITE_FUNC_CONSTANT|\
- SQLITE_UTF8|((bUseCache)*SQLITE_FUNC_RUNONLY)|((bSubtype)*SQLITE_SUBTYPE), \
+ SQLITE_UTF8|((bUseCache)*SQLITE_FUNC_RUNONLY)|\
+ ((bRS)*SQLITE_SUBTYPE)|((bWS)*SQLITE_RESULT_SUBTYPE), \
SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, 0, #zName, {0} }
#define INLINE_FUNC(zName, nArg, iArg, mFlags) \
{nArg, SQLITE_FUNC_BUILTIN|\
diff --git a/src/where.c b/src/where.c
index cfee45f87..448fe27c1 100644
--- a/src/where.c
+++ b/src/where.c
@@ -5811,13 +5811,16 @@ static SQLITE_NOINLINE void whereAddIndexedExpr(
}
if( sqlite3ExprIsConstant(pExpr) ) continue;
if( pExpr->op==TK_FUNCTION ){
+ /* Functions that might set a subtype should not be replaced by the
+ ** value taken from an expression index since the index omits the
+ ** subtype. https://sqlite.org/forum/forumpost/68d284c86b082c3e */
int n;
FuncDef *pDef;
sqlite3 *db = pParse->db;
assert( ExprUseXList(pExpr) );
n = pExpr->x.pList ? pExpr->x.pList->nExpr : 0;
pDef = sqlite3FindFunction(db, pExpr->u.zToken, n, ENC(db), 0);
- if( NEVER(pDef==0) || (pDef->funcFlags & SQLITE_FUNC_SUBTYPE)!=0 ){
+ if( NEVER(pDef==0) || (pDef->funcFlags & SQLITE_RESULT_SUBTYPE)!=0 ){
continue;
}
}
diff --git a/src/window.c b/src/window.c
index 2c449592d..62df349fb 100644
--- a/src/window.c
+++ b/src/window.c
@@ -1038,7 +1038,7 @@ int sqlite3WindowRewrite(Parse *pParse, Select *p){
assert( ExprUseXList(pWin->pOwner) );
assert( pWin->pWFunc!=0 );
pArgs = pWin->pOwner->x.pList;
- if( pWin->pWFunc->funcFlags & SQLITE_FUNC_SUBTYPE ){
+ if( pWin->pWFunc->funcFlags & SQLITE_SUBTYPE ){
selectWindowRewriteEList(pParse, pMWin, pSrc, pArgs, pTab, &pSublist);
pWin->iArgCol = (pSublist ? pSublist->nExpr : 0);
pWin->bExprArgs = 1;