aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordrh <>2023-11-07 19:03:13 +0000
committerdrh <>2023-11-07 19:03:13 +0000
commit17a32953873c52b91a18f79f371bd15887a022ed (patch)
tree68fba5e521280fdab2b3b07954997118fd0157a7 /src
parent637922acac23fe995fd2772559eaf5b75d057c9b (diff)
downloadsqlite-17a32953873c52b91a18f79f371bd15887a022ed.tar.gz
sqlite-17a32953873c52b91a18f79f371bd15887a022ed.zip
Update the documentation to the sqlite3_set_auxdata() and sqlite3_get_auxdata()
routines to make it clear that they do not work as one might expect when they are called during query planning, instead of during query execution. The JSON routines misuse those interfaces, so add a special flag to JSON routines that prevents them from being invoked during query planning. Fix for the problem in [forum:/forumpost/a655ee159eca1ea5|forum post a655ee159eca1ea5]. FossilOrigin-Name: 796a23f9ee33da0803844a2f40c1733db894cc4ef7fbaa1fa94af6af2d3b873b
Diffstat (limited to 'src')
-rw-r--r--src/sqlite.h.in14
-rw-r--r--src/sqliteInt.h4
-rw-r--r--src/vdbemem.c2
3 files changed, 14 insertions, 6 deletions
diff --git a/src/sqlite.h.in b/src/sqlite.h.in
index 01a7f4d4e..2317d98f7 100644
--- a/src/sqlite.h.in
+++ b/src/sqlite.h.in
@@ -5913,14 +5913,22 @@ sqlite3 *sqlite3_context_db_handle(sqlite3_context*);
** <li> ^(when sqlite3_set_auxdata() is invoked again on the same
** parameter)^, or
** <li> ^(during the original sqlite3_set_auxdata() call when a memory
-** allocation error occurs.)^ </ul>
+** allocation error occurs.)^
+** <li> ^(during the original sqlite3_set_auxdata() call if the function
+** is evaluated during query planning instead of during query execution,
+** as sometimes happens with [SQLITE_ENABLE_STAT4].)^ </ul>
**
-** Note the last bullet in particular. The destructor X in
+** Note the last two bullets in particular. The destructor X in
** sqlite3_set_auxdata(C,N,P,X) might be called immediately, before the
** sqlite3_set_auxdata() interface even returns. Hence sqlite3_set_auxdata()
** should be called near the end of the function implementation and the
** function implementation should not make any use of P after
-** sqlite3_set_auxdata() has been called.
+** sqlite3_set_auxdata() has been called. Furthermore, a call to
+** sqlite3_get_auxdata() that occurs immediately after a corresponding call
+** to sqlite3_set_auxdata() might still return NULL if an out-of-memory
+** condition occurred during the sqlite3_set_auxdata() call or if the
+** function is being evaluated during query planning rather than during
+** query execution.
**
** ^(In practice, auxiliary data is preserved between function calls for
** function parameters that are compile-time constants, including literal
diff --git a/src/sqliteInt.h b/src/sqliteInt.h
index 23beb48de..1a2250053 100644
--- a/src/sqliteInt.h
+++ b/src/sqliteInt.h
@@ -2014,7 +2014,7 @@ struct FuncDestructor {
#define SQLITE_FUNC_SLOCHNG 0x2000 /* "Slow Change". Value constant during a
** single query - might change over time */
#define SQLITE_FUNC_TEST 0x4000 /* Built-in testing functions */
-/* 0x8000 -- available for reuse */
+#define SQLITE_FUNC_RUNONLY 0x8000 /* Cannot be used by valueFromFunction */
#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 */
@@ -2115,7 +2115,7 @@ struct FuncDestructor {
xPtr, 0, xFunc, 0, 0, 0, #zName, {0} }
#define JFUNCTION(zName, nArg, iArg, xFunc) \
{nArg, SQLITE_FUNC_BUILTIN|SQLITE_DETERMINISTIC|\
- SQLITE_FUNC_CONSTANT|SQLITE_UTF8, \
+ SQLITE_FUNC_CONSTANT|SQLITE_UTF8|SQLITE_FUNC_RUNONLY, \
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/vdbemem.c b/src/vdbemem.c
index eee828143..d52716468 100644
--- a/src/vdbemem.c
+++ b/src/vdbemem.c
@@ -1515,7 +1515,7 @@ static int valueFromFunction(
#endif
assert( pFunc );
if( (pFunc->funcFlags & (SQLITE_FUNC_CONSTANT|SQLITE_FUNC_SLOCHNG))==0
- || (pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL)
+ || (pFunc->funcFlags & (SQLITE_FUNC_NEEDCOLL|SQLITE_FUNC_RUNONLY))!=0
){
return SQLITE_OK;
}