sqlite3: Vendor import of sqlite3 3.54.1

Release notes at https://sqlite.org/releaselog/3_54_1.html.

Obtained from:	https://www.sqlite.org/2026/sqlite-autoconf-3540100.tar.gz
Security:	84cd82e1-d49f-11f1-bae2-3497f65b111b
		CVE-2026-119371
		CVE-2026-119372
		CVE-2026-119373
		CVE-2026-119374
		CVE-2026-119375
		CVE-2026-119376
		CVE-2026-119377
		CVE-2026-119378
		CVE-2026-119379
		CVE-2026-119591
MFC after:	1 day

Merge commit '8fcea37c441fdc95cbfc8c34eeb0dcddbc02dca1'
This commit is contained in:
Cy Schubert committed 2026-11-03 09:59:24 -07:00
commit 71bb028fc1
12 files changed
+11341 -6033

No files matched your search

+1 -1
View File
@@ -1 +1 @@
3.53.3
3.54.1
+1 -1
View File
@@ -583,7 +583,7 @@ proc cctest {args} {
configlog "============"
}
file delete $src
file delete $tmp
catch {file delete $tmp}
# cache it
set ::cc_cache($cmdline,$lines) $ok
+10 -8
View File
@@ -12,13 +12,15 @@ if {![file exists $libdir]} {
puts stderr "tclsh reported library directory \"$libdir\" does not exist"
exit 1
}
if {![file exists $libdir/tclConfig.sh]} {
set n1 $libdir/tcl$::tcl_version
if {[file exists $n1/tclConfig.sh]} {
set libdir $n1
} else {
puts stderr "cannot find tclConfig.sh in either $libdir or $n1"
exit 1
set candidates [list $libdir $libdir/tcl$::tcl_version]
foreach d $::tcl_pkgPath {
lappend candidates $d $d/tcl$::tcl_version
}
foreach d $candidates {
if {[file exists $d/tclConfig.sh]} {
puts $d
exit 0
}
}
puts $libdir
puts stderr "cannot find tclConfig.sh in any of: [join $candidates {, }]"
exit 1
File diff suppressed because it is too large. Load diff
+2 -2
View File
@@ -2028,7 +2028,7 @@ array set proj__Cache {}
# Returns a cache key for the given argument:
#
# integer: relative call stack levels to get the scope name of for
# use as a key. [proj-scope [expr {1 + $arg + addLevel}]] is
# use as a key. [proj-scope [expr {1 + $arg + $addLevel}]] is
# then used to generate the key. i.e. the default of 0 uses the
# calling scope's name as the key.
#
@@ -2226,7 +2226,7 @@ proc proj-coalesce {args} {
#
# Pragmas:
#
# Passing :PRAGMAS to this function may modify how it works. The
# The prototype list may contain :PRAGMAS to modify how it works. The
# following pragmas are supported (note the leading ":"):
#
# :all-flags indicates that the whole input list should be scanned,
+162 -87
View File
@@ -223,39 +223,44 @@ proc sqlite-configure {buildMode configScript} {
dbpage => {Enable the sqlite3_dbpage extension}
dbstat => {Enable the sqlite3_dbstat extension}
carray=1 => {Disable the CARRAY extension}
column-metadata => {Enable the column metadata APIs}
all=$::sqliteConfig(all-flag-default) => {$allFlagHelp}
largefile=1
=> {This legacy flag has no effect on the library but may influence
the generated sqlite_cfg.h by adding #define HAVE_LFS}
}
{canonical} {
column-metadata => {Enable the column metadata APIs}
# ^^^ Affects how sqlite3.c is generated, so is not available in
# the autoconf build.
}
}
# Options for TCL support
# Options for Tcl support
tcl {
{canonical} {
tcl=1
=> {Disable components which require TCL, including all tests.
This tree requires TCL for code generation but can use the in-tree
copy of autosetup/jimsh0.c for that. The SQLite TCL extension and the
=> {Disable components which require Tcl, including all tests.
This tree requires Tcl for code generation but can use the in-tree
copy of autosetup/jimsh0.c for that. The SQLite Tcl extension and the
test code require a canonical tclsh.}
with-tcl:DIR
=> {Directory containing tclConfig.sh or a directory one level up from
that, from which we can derive a directory containing tclConfig.sh.
A dir name of "prefix" is equivalent to the directory specified by
the --prefix flag.}
the --prefix flag.
This determines the Tcl that SQLite will link against. It
does not affect the Tcl that is executed as part of the
build.}
with-tclsh:PATH
=> {Full pathname of tclsh to use. It is used for (A) trying to find
tclConfig.sh and (B) all TCL-based code generation. Use --with-tcl
unless you have a specific need for this flag. Warning: if its
containing dir has multiple tclsh versions, it may select the
wrong tclConfig.sh!}
=> {Full pathname of tclsh to use. It is used for all Tcl-based
code generation.
Additionally, when doing a native (build = host) build, it
may also be used as a legacy fallback to find tclConfig.sh
if --with-tcl does not say where that is. Relying on that
is not recommended. Warning: if its containing dir has
multiple tclsh versions, it may select the wrong
tclConfig.sh! The safe thing is to only pass --with-tclsh
if one also passes --with-tcl.}
static-tclsqlite3=0
=> {Statically-link tclsqlite3. This only works if TCL support is
=> {Statically-link tclsqlite3. This only works if Tcl support is
enabled and all requisite libraries are available in
static form. Note that glibc is unable to fully statically
link certain libraries required by tclsqlite3, so this won't
@@ -448,7 +453,7 @@ proc sqlite-configure {buildMode configScript} {
if {[catch {options {}} msg xopts]} {
# Workaround for <https://github.com/msteveb/autosetup/issues/73>
# where [options] behaves oddly on _some_ TCL builds when it's
# where [options] behaves oddly on _some_ Tcl builds when it's
# called from deeper than the global scope.
dict incr xopts -level
return {*}$xopts $msg
@@ -466,7 +471,7 @@ proc sqlite-configure {buildMode configScript} {
proc sqlite-configure-phase1 {buildMode} {
define PACKAGE_NAME sqlite
define PACKAGE_URL {https://sqlite.org}
define PACKAGE_BUGREPORT [get-define PACKAGE_URL]/forum
define PACKAGE_BUGREPORT [get-define PACKAGE_URL]/bugs
define PACKAGE_STRING "[get-define PACKAGE_NAME] [get-define PACKAGE_VERSION]"
proj-xfer-options-aliases {
# Carry values from hidden --flag aliases over to their canonical
@@ -1067,7 +1072,7 @@ proc sqlite-get-readline-dir-list {} {
}
*-haiku {
lappend dirs /boot/system/develop/headers
if {[opt-val with-readline-ldflags] in {auto ""}} {
if {![opt-bool editline] && [opt-val with-readline-ldflags] in {auto ""}} {
# If the user did not supply their own --with-readline-ldflags
# value, hijack that flag to inject options which are known to
# work on Haiku OS installations.
@@ -1094,16 +1099,30 @@ proc sqlite-get-readline-dir-list {} {
# - HAVE_LINENOISE to 0, 1, or 2
# - HAVE_EDITLINE to 0 or 1
#
# Only one of ^^^ those will be set to non-0.
# Those will be set as follows:
#
# HAVE_LINENOISE=0, HAVE_EDITLINE=0, HAVE_READLINE=0: no line editing
#
# HAVE_LINENOISE>0: 1=antirez flavor, 2=msteveb flavor
#
# HAVE_EDITLINE=0, HAVE_READLINE=1: use GNU readline
#
# HAVE_EDITLINE=1, HAVE_READLINE=1: use BSD editline header
# <readline/readline.h>.
#
# HAVE_EDITLINE=1, HAVE_READLINE=0: use BSD editline header
# <editline/readline.h>.
#
# Other defines it sets:
#
# - LDFLAGS_READLINE = linker flags or empty string
#
# - CFLAGS_READLINE = compilation flags for clients or empty string.
#
# Note that LDFLAGS_READLINE and CFLAGS_READLINE may refer to
# linenoise or editline, not necessarily libreadline. In some cases
# it will set HAVE_READLINE=1 when it's really using editline, for
# reasons described in this function's comments.
# Both LDFLAGS_READLINE and CFLAGS_READLINE may refer to linenoise or
# editline, not necessarily libreadline. In some cases it will set
# HAVE_READLINE=1 when it's really using editline, for reasons
# described in this function's comments.
#
# Returns a string describing which line-editing approach to use, or
# "none" if no option is available.
@@ -1141,7 +1160,7 @@ proc sqlite-check-line-editing {} {
# If none of --with-linenoise, --enable-readline, or --enable-editline
# are provided, but there exists a directory "linenoise" at $HOME or
# a sibling of the build or source directory, then try to use that linenoise
# direcctory.
# directory.
#
if {"" eq $dirLn
&& ![proj-opt-was-provided readline]
@@ -1210,6 +1229,7 @@ proc sqlite-check-line-editing {} {
set failIfNotFound 1
set libsForReadline {edit}
set editLibName editline
set editLibDef HAVE_EDITLINE
} elseif {![opt-bool readline]} {
msg-result "Readline support explicitly disabled with --disable-readline"
return "none"
@@ -1305,14 +1325,18 @@ proc sqlite-check-line-editing {} {
# If we found a library, configure the build to use it...
if {"" ne $rlLib} {
if {"editline" eq $editLibName && "HAVE_READLINE" eq $editLibDef} {
# Alert the user that, despite outward appearances, we won't be
# linking to the GPL'd libreadline. Presumably that distinction is
# significant for those using --editline.
proj-indented-notice {
NOTE: the local libedit uses <readline/readline.h> so we
will compile with -DHAVE_READLINE=1 but will link with
libedit.
if {"editline" eq $editLibName} {
# sqlite-add-shell-opt -DEL_WIDECHAR=1;
if {"HAVE_READLINE" eq $editLibDef} {
sqlite-add-shell-opt -DHAVE_EDITLINE=1
# Alert the user that, despite outward appearances, we won't be
# linking to the GPL'd libreadline. Presumably that distinction is
# significant for those using --editline.
proj-indented-notice {
NOTE: the local libedit uses <readline/readline.h> so we
will compile with -DHAVE_READLINE=1 but will link with
libedit.
}
}
}
set rlLib [join $rlLib]
@@ -1633,13 +1657,15 @@ proc sqlite-handle-dll-basename {} {
}
########################################################################
# Handles the --out-implib flag.
#
# [define]s LDFLAGS_OUT_IMPLIB to either an empty string or to a
# -Wl,... flag for the platform-specific --out-implib flag, which is
# used for building an "import library .dll.a" file on some platforms
# (e.g. msys2, mingw). SQLITE_OUT_IMPLIB is defined to the name of the
# import lib or an empty string. Returns 1 if supported, else 0.
# (e.g. msys2, mingw). Returns 1 if supported, else 0.
#
# The name of the import library is [define]d in SQLITE_OUT_IMPLIB.
# The name of the import library is [define]d in SQLITE_OUT_IMPLIB,
# as an empty string if it's not supported.
#
# If the configure flag --out-implib is not used (or programmatically
# set) then this simply sets the above-listed defines to empty strings
@@ -1892,39 +1918,59 @@ proc sqlite-handle-wasi-sdk {} {
}; # sqlite-handle-wasi-sdk
########################################################################
# TCL...
# Tcl...
#
# sqlite-check-tcl performs most of the --with-tcl and --with-tclsh
# handling. Some related bits and pieces are performed before and
# after that function is called.
#
# Important [define]'d vars:
# Important [define]'d vars. They can be split into library and tool vars.
#
# - HAVE_TCL indicates whether we have a tclsh suitable for building
# the TCL SQLite extension and, by extension, the testing
# infrastructure. This must only be 1 for environments where
# tclConfig.sh can be found.
# Tcl library vars:
#
# - TCLSH_CMD is the path to the canonical tclsh or "". It never
# refers to jimtcl.
# - HAVE_TCL indicates whether we have the Tcl that the SQLite Tcl
# extension will be linked with, and so whether that extension is
# built. This is 1 for environments where tclConfig.sh can be found.
# That file describes a library to link against, so whether any tclsh
# can be run is a separate matter, and none is needed for this.
#
# - TCL_CONFIG_SH is the path to tclConfig.sh or "".
#
# - TCLLIBDIR is the dir to which libtclsqlite3 gets installed.
#
# Tcl tool vars:
#
# - TCLSH_CMD is the path to the canonical tclsh or "". It never
# refers to jimtcl.
#
# - BTCLSH = the path to the tcl interpreter used for in-tree code
# generation. It may be jimtcl or the canonical tclsh but may not
# be empty - this tree requires TCL to generated numerous
# generation. It may be jimtcl or the canonical tclsh but may not be
# empty, as Tcl code is run as part of the build to generate numerous
# components.
#
# If --tcl or --with-tcl are provided but no TCL is found, this
# The two configure CLI flags are separated by which set of variables
# they affect. --with-tcl affects only Tcl library vars, and
# --with-tclsh almost only affects Tcl tool vars. There is just one
# exception: when compiling natively, a tclsh is asked where its own
# tclConfig.sh is if --with-tcl is not passed.
#
# This distinction is good in any event to separate concerns, but it is
# especially important for cross compilation. In that case, the Tcl that
# SQLite links against will be one that runs on the host platform, while
# the Tcl that SQLite's build scripts use at build time will run on the
# build platform. Mixing up the two flags and the two kinds of vars is
# likely to break cross compilation; that is why the one exception to
# the separation is strictly confined to the native compilation case.
# See: https://sqlite.org/forum/forumpost/fe9e99eb27c8c2ba
#
# If --tcl or --with-tcl are provided but no Tcl is found, this
# function fails fatally. If they are not explicitly provided then
# failure to find TCL is not fatal but a loud warning will be emitted.
# failure to find Tcl is not fatal but a loud warning will be emitted.
#
proc sqlite-check-tcl {} {
define TCLSH_CMD false ; # Significant is that it exits with non-0
define HAVE_TCL 0 ; # Will be enabled via --tcl or a successful search
define TCLLIBDIR "" ; # Installation dir for TCL extension lib
define TCLLIBDIR "" ; # Installation dir for Tcl extension lib
define TCL_CONFIG_SH ""; # full path to tclConfig.sh
# Clear out all vars which would harvest from tclConfig.sh so that
@@ -1935,8 +1981,8 @@ proc sqlite-check-tcl {} {
file delete -force ".tclenv.sh"; # ensure no stale state from previous configures.
if {![opt-bool tcl]} {
proj-indented-notice {
NOTE: TCL is disabled via --disable-tcl. This means that none
of the TCL-based components will be built, including tests
NOTE: Tcl is disabled via --disable-tcl. This means that none
of the Tcl-based components will be built, including tests
and sqlite3_analyzer.
}
return
@@ -1963,23 +2009,39 @@ proc sqlite-check-tcl {} {
set doConfigLookup 1 ; # set to 0 to test the tclConfig.sh-not-found cases
if {"" ne $with_tclsh} {
# --with-tclsh was provided or found above. Validate it and use it
# to trump any value passed via --with-tcl=DIR.
# --with-tclsh was provided or found above. Validate it and, if
# nothing better is to be had, ask it where its tclConfig.sh is.
# The two name different things: the shell runs here, whereas
# tclConfig.sh describes the library the extension is linked
# against. The shell is a guide to that only when neither
# --with-tcl=DIR says where it is nor cross compiling puts it on
# another platform entirely.
if {![file-isexec $with_tclsh]} {
proj-fatal "TCL shell $with_tclsh is not executable"
proj-fatal "Tcl shell $with_tclsh is not executable"
} else {
define TCLSH_CMD $with_tclsh
#msg-result "Using tclsh: $with_tclsh"
}
if {$doConfigLookup &&
[catch {exec $with_tclsh $::autosetup(libdir)/find_tclconfig.tcl} result] == 0} {
set with_tcl $result
}
if {"" ne $with_tcl && [file isdir $with_tcl]} {
msg-result "$with_tclsh recommends the tclConfig.sh from $with_tcl"
if {"" ne $with_tcl} {
# --with-tcl was given explicitly; do not second-guess it with tclsh.
} elseif {$::sqliteConfig(is-cross-compiling)} {
# This tclsh runs on the build platform, so the tclConfig.sh it would
# recommend describes Tcl for here, not for the host platform.
proj-warn "Cannot ask $with_tclsh to recommend a tclConfig.sh because we are cross compiling."
# Leave with_tcl empty and do not set use_tcl either way so the $libdir
# search below can still attempt to find one.
} else {
proj-warn "$with_tclsh is unable to recommend a tclConfig.sh"
set use_tcl 0
if {$doConfigLookup &&
[catch {exec $with_tclsh $::autosetup(libdir)/find_tclconfig.tcl} result] == 0} {
set with_tcl $result
}
if {"" ne $with_tcl && [file isdir $with_tcl]} {
msg-result "$with_tclsh recommends the tclConfig.sh from $with_tcl"
} else {
proj-warn "$with_tclsh is unable to recommend a tclConfig.sh"
set use_tcl 0
}
}
}
set cfg ""
@@ -2026,7 +2088,7 @@ proc sqlite-check-tcl {} {
break
}
define TCL_CONFIG_SH $cfg
# Export a subset of tclConfig.sh to the current TCL-space. If $cfg
# Export a subset of tclConfig.sh to the current Tcl-space. If $cfg
# is an empty string, this emits empty-string entries for the
# various options we're interested in.
proj-tclConfig-sh-to-autosetup $cfg
@@ -2046,7 +2108,7 @@ proc sqlite-check-tcl {} {
}
}
if {![file-isexec $with_tclsh]} {
proj-warn "Cannot find a usable tclsh (tried: $tryThese)
proj-warn "Cannot find a usable tclsh (tried: $tryThese)"
}
}
define TCLSH_CMD $with_tclsh
@@ -2062,14 +2124,16 @@ proc sqlite-check-tcl {} {
set tcllibdir [get-env TCLLIBDIR ""]
set sq3Ver [get-define PACKAGE_VERSION]
if {"" eq $tcllibdir} {
# Attempt to extract TCLLIBDIR from TCL's $auto_path
# Attempt to extract TCLLIBDIR from Tcl's $auto_path
if {"" ne $with_tclsh &&
[catch {exec echo "puts stdout \$auto_path" | "$with_tclsh"} result] == 0} {
foreach i $result {
if {[file isdir $i]} {
if {![string match "//zipfs:*" $i] && [file isdir $i]} {
# Tcl9 may report //zipfs paths as dirs. Filter those out.
set tcllibdir $i/sqlite${sq3Ver}
break
}
# proj-warn "filtering out auto_path $i"
}
} else {
proj-warn "Cannot determine TCLLIBDIR."
@@ -2083,57 +2147,65 @@ proc sqlite-check-tcl {} {
if {[file-isexec $with_tclsh]} {
msg-result "Using tclsh: $with_tclsh"
if {$cfg ne ""} {
define HAVE_TCL 1
} else {
proj-warn "Found tclsh but no tclConfig.sh."
}
}
# tclConfig.sh describes what the extension is built against.
# Whether a tclsh can be run here is a separate question, affecting
# code generation and the test suite.
if {$cfg ne ""} {
define HAVE_TCL 1
} elseif {[file-isexec $with_tclsh]} {
proj-warn "Found tclsh (${with_tclsh}) but no tclConfig.sh."
}
show-notices
# If TCL is not found: if it was explicitly requested then fail
# If Tcl is not found: if it was explicitly requested then fail
# fatally, else just emit a warning. If we can find the APIs needed
# to generate a working JimTCL then that will suffice for build-time
# TCL purposes (see: proc sqlite-determine-codegen-tcl).
# to generate a working JimTcl then that will suffice for build-time
# Tcl purposes (see: proc sqlite-determine-codegen-tcl).
if {![get-define HAVE_TCL] &&
([proj-opt-was-provided tcl] || [proj-opt-was-provided with-tcl])} {
proj-fatal "TCL support was requested but no tclConfig.sh could be found."
proj-fatal "Tcl support was requested but no tclConfig.sh could be found."
}
if {"" eq $cfg} {
proj-assert {0 == [get-define HAVE_TCL]}
proj-indented-notice {
WARNING: Cannot find a usable tclConfig.sh file. Use
--with-tcl=DIR to specify a directory where tclConfig.sh can be
found. SQLite does not use TCL internally, but some optional
components require TCL, including tests and sqlite3_analyzer.
found. SQLite does not use Tcl internally, but some optional
components require Tcl, including tests and sqlite3_analyzer.
}
}
}; # sqlite-check-tcl
########################################################################
# sqlite-determine-codegen-tcl checks which TCL to use as a code
# sqlite-determine-codegen-tcl checks which Tcl to use as a code
# generator. By default, prefer jimsh simply because we have it
# in-tree (it's part of autosetup) unless --with-tclsh=X is used, in
# which case prefer X.
#
# Returns the human-readable name of the TCL it selects. Fails fatally
# if it cannot detect a TCL appropriate for code generation.
# Returns the human-readable name of the Tcl it selects. Fails fatally
# if it cannot detect a Tcl appropriate for code generation.
#
# Defines:
#
# - BTCLSH = the TCL shell used for code generation. It may set this
# - BTCLSH = the Tcl shell used for code generation. It may set this
# to an unexpanded makefile var name.
#
# - CFLAGS_JIMSH = any flags needed for buildng a BTCLSH-compatible
# jimsh. The defaults may be passed on to configure as
# CFLAGS_JIMSH=...
proc sqlite-determine-codegen-tcl {} {
msg-result "Checking for TCL to use for code generation... "
msg-result "Checking for Tcl to use for code generation... "
define CFLAGS_JIMSH [proj-get-env CFLAGS_JIMSH {-O1}]
set cgtcl [opt-val with-tclsh jimsh]
if {"jimsh" ne $cgtcl} {
# When --with-tclsh=X is used, use that for all TCL purposes,
# including in-tree code generation, per developer request.
define BTCLSH "\$(TCLSH_CMD)"
# When --with-tclsh=X is used, generate code with X rather than with
# the in-tree jimsh, per developer request.
#
# Name it directly rather than through the $(TCLSH_CMD) makefile
# var, which gets set to "false" when the extension is not built,
# but we need code generation regardless of whether the extension
# is built.
define BTCLSH $cgtcl
return $cgtcl
}
set flagsToRestore {CC CFLAGS AS_CFLAGS CPPFLAGS AS_CPPFLAGS LDFLAGS LINKFLAGS LIBS CROSS}
@@ -2149,7 +2221,7 @@ proc sqlite-determine-codegen-tcl {} {
# block.
foreach flag $flagsToRestore {define $flag ""}
define CC [get-define CC_FOR_BUILD]
# These headers are technically optional for JimTCL but necessary if
# These headers are technically optional for JimTcl but necessary if
# we want to use it for code generation:
set sysh [cc-check-includes dirent.h sys/time.h]
# jimsh0.c hard-codes #define's for HAVE_DIRENT_H and
@@ -2158,6 +2230,9 @@ proc sqlite-determine-codegen-tcl {} {
# so that we can avoid the situation that we later, at
# make-time, try to compile jimsh but it then fails due to
# missing headers (i.e. fail earlier rather than later).
#
# One of HAVE_REALPATH or HAVE__FULLPATH are required here for
# jimsh's [file normalize] to work.
if {$sysh && [cc-check-functions realpath]} {
define-append CFLAGS_JIMSH -DHAVE_REALPATH
define BTCLSH "\$(JIMSH)"
@@ -2204,7 +2279,7 @@ proc sqlite-determine-codegen-tcl {} {
proc sqlite-handle-tcl {} {
sqlite-check-tcl
if {"canonical" ne $::sqliteConfig(build-mode)} return
msg-result "TCL for code generation: [sqlite-determine-codegen-tcl]"
msg-result "Tcl for code generation: [sqlite-determine-codegen-tcl]"
# Determine the base name of the Tcl extension's DLL
#
+3375 -809
View File
File diff suppressed because it is too large. Load diff
+5618 -4100
View File
File diff suppressed because it is too large. Load diff
+126 -28
View File
@@ -146,12 +146,12 @@ extern "C" {
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
** [sqlite_version()] and [sqlite_source_id()].
*/
#define SQLITE_VERSION "3.53.3"
#define SQLITE_VERSION_NUMBER 3053003
#define SQLITE_SOURCE_ID "2026-06-26 20:14:12 d4c0e51e4aeb96955b99185ab9cde75c339e2c29c3f3f12428d364a10d782c62"
#define SQLITE_SCM_BRANCH "branch-3.53"
#define SQLITE_SCM_TAGS "release version-3.53.3"
#define SQLITE_SCM_DATETIME "2026-06-26T20:14:12.354Z"
#define SQLITE_VERSION "3.54.1"
#define SQLITE_VERSION_NUMBER 3054001
#define SQLITE_SOURCE_ID "2026-10-16 14:45:20 555e07ef33f69a0957d24d8e555b702464a131d6f1607f4c3c1e4551e8e6ca76"
#define SQLITE_SCM_BRANCH "branch-3.54"
#define SQLITE_SCM_TAGS "release version-3.54.1"
#define SQLITE_SCM_DATETIME "2026-10-16T14:45:20.546Z"
/*
** CAPI3REF: Run-Time Library Version Numbers
@@ -463,7 +463,7 @@ SQLITE_API int sqlite3_exec(
#define SQLITE_FULL 13 /* Insertion failed because database is full */
#define SQLITE_CANTOPEN 14 /* Unable to open the database file */
#define SQLITE_PROTOCOL 15 /* Database lock protocol error */
#define SQLITE_EMPTY 16 /* Internal use only */
#define SQLITE_EMPTY 16 /* No content */
#define SQLITE_SCHEMA 17 /* The database schema changed */
#define SQLITE_TOOBIG 18 /* String or BLOB exceeds size limit */
#define SQLITE_CONSTRAINT 19 /* Abort due to constraint violation */
@@ -2960,8 +2960,9 @@ SQLITE_API int sqlite3_is_interrupted(sqlite3*);
** These routines are useful during command-line input to determine if the
** currently entered text seems to form a complete SQL statement or
** if additional input is needed before sending the text into
** SQLite for parsing. ^These routines return 1 if the input string
** appears to be a complete SQL statement. ^A statement is judged to be
** SQLite for parsing. ^The sqlite3_complete(X) and sqlite3_complete16(X)
** routines return 1 if the input string X appears to be a complete SQL
** statement. ^A statement is judged to be
** complete if it ends with a semicolon token and is not a prefix of a
** well-formed CREATE TRIGGER statement. ^Semicolons that are embedded within
** string literals or quoted identifier names or comments are not
@@ -2969,11 +2970,25 @@ SQLITE_API int sqlite3_is_interrupted(sqlite3*);
** embedded) and thus do not count as a statement terminator. ^Whitespace
** and comments that follow the final semicolon are ignored.
**
** ^These routines return 0 if the statement is incomplete. ^If a
** memory allocation fails, then SQLITE_NOMEM is returned.
** ^The sqlite3_complete(X) and sqlite3_complete16(X) routines return 0
** if the statement is incomplete. ^If a memory allocation fails, then
** SQLITE_NOMEM is returned.
**
** ^These routines do not parse the SQL statements and thus
** will not detect syntactically incorrect SQL.
** The [sqlite3_incomplete(X)] routine is similar to [sqlite3_complete(X)]
** except that sqlite3_incomplete(X) returns SQLITE_OK if the input X is
** complete, SQLITE_EMPTY if input X consists entirely of whitespace and/or
** comments, SQLITE_MISUSE if X is a NULL pointer, and some other non-zero
** value if X is incomplete. The non-zero return from
** sqlite3_incomplete(X) contains additional information about what is
** needed to complete the input X. See the header comment on the
** implemenation of the sqlite3_incomplete() routine for a full description
** of its non-zero return values. The sqlite3_incomplete(X) interface
** is only available for UTF-8 text.
**
** ^None of these routines do a full parse the SQL statements and thus
** will not detect syntactically incorrect SQL. They only determine if
** input text has properly terminated comments, string literals, and
** quoted identifiers, and if the statement ends with a semicolon.
**
** ^(If SQLite has not been initialized using [sqlite3_initialize()] prior
** to invoking sqlite3_complete16() then sqlite3_initialize() is invoked
@@ -2981,14 +2996,15 @@ SQLITE_API int sqlite3_is_interrupted(sqlite3*);
** then the return value from sqlite3_complete16() will be non-zero
** regardless of whether or not the input SQL is complete.)^
**
** The input to [sqlite3_complete()] must be a zero-terminated
** UTF-8 string.
** The X input to [sqlite3_complete(X)] and [sqlite3_incomplete(X)]
** must be a zero-terminated UTF-8 string.
**
** The input to [sqlite3_complete16()] must be a zero-terminated
** UTF-16 string in native byte order.
*/
SQLITE_API int sqlite3_complete(const char *sql);
SQLITE_API int sqlite3_complete16(const void *sql);
SQLITE_API sqlite3_int64 sqlite3_incomplete(const char *sql);
/*
** CAPI3REF: Register A Callback To Handle SQLITE_BUSY Errors
@@ -3401,7 +3417,7 @@ SQLITE_API void sqlite3_randomness(int N, void *P);
**
** ^The first parameter to the authorizer callback is a copy of the third
** parameter to the sqlite3_set_authorizer() interface. ^The second parameter
** to the callback is an integer [SQLITE_COPY | action code] that specifies
** to the callback is an integer [SQLITE_READ | action code] that specifies
** the particular action to be authorized. ^The third through sixth parameters
** to the callback are either NULL pointers or zero-terminated strings
** that contain additional details about the action to be authorized.
@@ -3444,21 +3460,33 @@ SQLITE_API void sqlite3_randomness(int N, void *P);
** previous call.)^ ^Disable the authorizer by installing a NULL callback.
** The authorizer is disabled by default.
**
** The authorizer callback must not do anything that will modify
** <h3>Limitations And Caveats</h3><ul>
**
** <li>The authorizer callback must not do anything that will modify
** the database connection that invoked the authorizer callback.
** Note that [sqlite3_prepare_v2()] and [sqlite3_step()] both modify their
** database connections for the meaning of "modify" in this paragraph.
**
** ^When [sqlite3_prepare_v2()] is used to prepare a statement, the
** <li>^When [sqlite3_prepare_v2()] is used to prepare a statement, the
** statement might be re-prepared during [sqlite3_step()] due to a
** schema change. Hence, the application should ensure that the
** correct authorizer callback remains in place during the [sqlite3_step()].
**
** ^Note that the authorizer callback is invoked only during
** <li>^The authorizer callback is invoked only during
** [sqlite3_prepare()] or its variants. Authorization is not
** performed during statement evaluation in [sqlite3_step()], unless
** as stated in the previous paragraph, sqlite3_step() invokes
** sqlite3_prepare_v2() to reprepare a statement after a schema change.
**
** <li>Authorizer callbacks for the expressions of a
** [generated column] are invoked when the schema is parsed (and specifically
** when the [CREATE TABLE] statement that contains the generated column is
** parsed) not when the generated column is used in a DML statement.
** This is deliberate, as one of the purposes of generated columns
** is to give schema designers the ability to provide gated access
** to privileged columns and/or functions.
**
** </ul>
*/
SQLITE_API int sqlite3_set_authorizer(
sqlite3*,
@@ -3499,6 +3527,11 @@ SQLITE_API int sqlite3_set_authorizer(
** is the name of the inner-most trigger or view that is responsible for
** the access attempt or NULL if this access attempt is directly from
** top-level SQL code.
**
** The case of strings in the 3rd through the 6th argument to the
** authorization callback is arbitrary. Authorization callbacks
** implementations should use [sqlite3_stricmp()] or similar when
** doing comparisons against those values.
*/
/******************************************* 3rd ************ 4th ***********/
#define SQLITE_CREATE_INDEX 1 /* Index Name Table Name */
@@ -3533,9 +3566,14 @@ SQLITE_API int sqlite3_set_authorizer(
#define SQLITE_DROP_VTABLE 30 /* Table Name Module Name */
#define SQLITE_FUNCTION 31 /* NULL Function Name */
#define SQLITE_SAVEPOINT 32 /* Operation Savepoint Name */
#define SQLITE_COPY 0 /* No longer used */
#define SQLITE_RECURSIVE 33 /* NULL NULL */
/*
** Note: The SQLITE_COPY macro (with value 0) used to be one of the
** action codes above. That macro has now been repurposed as a possible
** value to the 3rd argument to sqlite3_result_str().
*/
/*
** CAPI3REF: Deprecated Tracing And Profiling Functions
** DEPRECATED
@@ -4042,8 +4080,7 @@ SQLITE_API int sqlite3_open_v2(
**
** The sqlite3_uri_int64(F,P,D) routine converts the value of P into a
** 64-bit signed integer and returns that integer, or D if P does not
** exist. If the value of P is something other than an integer, then
** zero is returned.
** exist or if the value of P is something other than an integer.
**
** The sqlite3_uri_key(F,N) returns a pointer to the name (not
** the value) of the N-th query parameter for filename F, or a NULL
@@ -4404,6 +4441,14 @@ SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal);
** [[SQLITE_LIMIT_WORKER_THREADS]] ^(<dt>SQLITE_LIMIT_WORKER_THREADS</dt>
** <dd>The maximum number of auxiliary worker threads that a single
** [prepared statement] may start.</dd>)^
**
** [[SQLITE_LIMIT_SCHEMA]] ^(<dt>SQLITE_LIMIT_SCHEMA</dt>
** <dd>The maximum number of objects (tables, indexes, triggers, and views)
** defined by the database schema.</dd>)^
**
** [[SQLITE_LIMIT_TRIGGER_STEPS]] ^(<dt>SQLITE_LIMIT_TRIGGER_STEPS</dt>
** <dd>The maximum number of SQL statements that can be contained within
** a single trigger.</dd>)^
** </dl>
*/
#define SQLITE_LIMIT_LENGTH 0
@@ -4419,6 +4464,8 @@ SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal);
#define SQLITE_LIMIT_TRIGGER_DEPTH 10
#define SQLITE_LIMIT_WORKER_THREADS 11
#define SQLITE_LIMIT_PARSER_DEPTH 12
#define SQLITE_LIMIT_SCHEMA 13
#define SQLITE_LIMIT_TRIGGER_STEPS 14
/*
** CAPI3REF: Prepare Flags
@@ -4530,6 +4577,8 @@ SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal);
** the nul-terminator.
** Note that nByte measures the length of the input in bytes, not
** characters, even for the UTF-16 interfaces.
** For the sqlite3_prepare16() and sqlite3_prepare16_v2() interfaces,
** the nByte value must be even or undefined behavior can result.
**
** ^If pzTail is not NULL then *pzTail is made to point to the first byte
** past the end of the first SQL statement in zSql. These routines only
@@ -5276,7 +5325,7 @@ SQLITE_API const void *sqlite3_column_decltype16(sqlite3_stmt*,int);
** [prepared statement]. ^In the "v2" interface,
** the more specific error code is returned directly by sqlite3_step().
**
** [SQLITE_MISUSE] means that the this routine was called inappropriately.
** [SQLITE_MISUSE] means that this routine was called inappropriately.
** Perhaps it was called on a [prepared statement] that has
** already been [sqlite3_finalize | finalized] or on one that had
** previously returned [SQLITE_ERROR] or [SQLITE_DONE]. Or it could
@@ -6449,7 +6498,11 @@ typedef void (*sqlite3_destructor_type)(void*);
**
** ^The sqlite3_result_zeroblob(C,N) and sqlite3_result_zeroblob64(C,N)
** interfaces set the result of the application-defined function to be
** a BLOB containing all zero bytes and N bytes in size.
** a BLOB containing all zero bytes and N bytes in size. The
** zeroblob64(C,N) interface returns a [result code], which is normally
** [SQLITE_OK] but might be some other value if the requested operation
** could not be complete, for example if insufficient memory is available
** or if the value of N is out of range.
**
** ^The sqlite3_result_double() interface sets the result from
** an application-defined function to be a floating point value specified
@@ -8787,8 +8840,8 @@ SQLITE_API int sqlite3_keyword_check(const char*,int);
** <li> ^The sqlite3_str object is created using [sqlite3_str_new()].
** <li> ^Text is appended to the sqlite3_str object using various
** methods, such as [sqlite3_str_appendf()].
** <li> ^The sqlite3_str object is destroyed and the string it created
** is returned using the [sqlite3_str_finish()] interface.
** <li> The sqlite3_str object is destroyed and the string it created
** is returned using [sqlite3_str_finish()] or [sqlite3_result_str()].
** </ol>
*/
typedef struct sqlite3_str sqlite3_str;
@@ -8840,6 +8893,40 @@ SQLITE_API sqlite3_str *sqlite3_str_new(sqlite3*);
SQLITE_API char *sqlite3_str_finish(sqlite3_str*);
SQLITE_API void sqlite3_str_free(sqlite3_str*);
/*
** CAPI3REF: Return A Dynamic String From an SQL Function
**
** The [sqlite3_result_str(C,S,F)] interface causes the
** [sqlite3_str|dynamic string] S to become the return value for the
** application-defined function or virtual table that uses
** [sqlite3_context] C. The F flag can be one of [SQLITE_COPY]
** or [SQLITE_XFER] or [SQLITE_FINISH].
**
** If the dynamic string is invalid or incomplete due to an out-of-memory
** or string-too-large error, then this routine transfers that error
** over to the SQL function.
**
** If the F argument is SQLITE_COPY, then a copy of the dynamic string
** content is made and the dynamic string object is unchanged.
** If the F argument is SQLITE_XFER, then ownership of the content
** in the dynamic is transferred to the SQL function (via a pointer copy
** rather than a string copy) and the dynamic string is reset to an
** empty string. The SQLITE_FINISH value for F works like SQLITE_RESET
** except that it also invokes the [sqlite3_str_free(S)] destructor
** on the dynamic string object.
*/
SQLITE_API void sqlite3_result_str(sqlite3_context*, sqlite3_str*, int);
/*
** CAPI3REF: Control Flags For sqlite3_result_str()
**
** The following integers can be used as the third "F" argument
** to [sqlite3_result_str(C,S,F)].
*/
#define SQLITE_COPY 0 /* Results copied. Dynamic string unchanged */
#define SQLITE_XFER 1 /* Results transfered. Dynamic string reset */
#define SQLITE_FINISH 2 /* Like SQLITE_XFER, plus dynamic string freed */
/*
** CAPI3REF: Add Content To A Dynamic String
** METHOD: sqlite3_str
@@ -11205,8 +11292,19 @@ SQLITE_API unsigned char *sqlite3_serialize(
** used. The serialized database P is N bytes in size. M is the size
** of the buffer P, which might be larger than N. If M is larger than
** N, and the SQLITE_DESERIALIZE_READONLY bit is not set in F, then
** SQLite is permitted to add content to the in-memory database as
** long as the total size does not exceed M bytes.
** SQLite is permitted to add content to the in-memory database, in
** page-sized chunks, as long as the total size does not exceed M bytes.
**
** The parameter M must be greater than or equal to N. Ideally, M
** should have a value which is N+(512&times;K)+20 where K determines how
** must extra space is available to hold new content as the database
** grows. K can be 0 if the database is read-only.
**
** If the database content in P is malformed in a malicious way then
** it is possible that SQLite might try to read a few more than N bytes
** from P. If the veracity of the database content P is uncertain,
** then applications are advised to allocate about 20 extra bytes on
** the end of the P buffer to avoid a memory error.
**
** If the SQLITE_DESERIALIZE_FREEONCLOSE bit is set in F, then SQLite will
** invoke sqlite3_free() on the serialization buffer when the database
+14 -8
View File
@@ -109,7 +109,7 @@ struct sqlite3_api_routines {
const char * (*libversion)(void);
int (*libversion_number)(void);
void *(*malloc)(int);
char * (*mprintf)(const char*,...);
char *(SQLITE_CDECL*mprintf)(const char*,...);
int (*open)(const char*,sqlite3**);
int (*open16)(const void*,sqlite3**);
int (*prepare)(sqlite3*,const char*,int,sqlite3_stmt**,const char**);
@@ -130,11 +130,11 @@ struct sqlite3_api_routines {
void (*result_text16be)(sqlite3_context*,const void*,int,void(*)(void*));
void (*result_text16le)(sqlite3_context*,const void*,int,void(*)(void*));
void (*result_value)(sqlite3_context*,sqlite3_value*);
void * (*rollback_hook)(sqlite3*,void(*)(void*),void*);
void *(*rollback_hook)(sqlite3*,void(*)(void*),void*);
int (*set_authorizer)(sqlite3*,int(*)(void*,int,const char*,const char*,
const char*,const char*),void*);
void (*set_auxdata)(sqlite3_context*,int,void*,void (*)(void*));
char * (*xsnprintf)(int,char*,const char*,...);
char *(SQLITE_CDECL*xsnprintf)(int,char*,const char*,...);
int (*step)(sqlite3_stmt*);
int (*table_column_metadata)(sqlite3*,const char*,const char*,const char*,
char const**,char const**,int*,int*,int*);
@@ -198,7 +198,7 @@ struct sqlite3_api_routines {
int (*xthreadsafe)(void);
void (*result_zeroblob)(sqlite3_context*,int);
void (*result_error_code)(sqlite3_context*,int);
int (*test_control)(int, ...);
int (SQLITE_CDECL*test_control)(int, ...);
void (*randomness)(int,void*);
sqlite3 *(*context_db_handle)(sqlite3_context*);
int (*extended_result_codes)(sqlite3*,int);
@@ -218,11 +218,11 @@ struct sqlite3_api_routines {
void (*xStep)(sqlite3_context*,int,sqlite3_value**),
void (*xFinal)(sqlite3_context*),
void(*xDestroy)(void*));
int (*db_config)(sqlite3*,int,...);
int (SQLITE_CDECL*db_config)(sqlite3*,int,...);
sqlite3_mutex *(*db_mutex)(sqlite3*);
int (*db_status)(sqlite3*,int,int*,int*,int);
int (*extended_errcode)(sqlite3*);
void (*log)(int,const char*,...);
void (SQLITE_CDECL*log)(int,const char*,...);
sqlite3_int64 (*soft_heap_limit64)(sqlite3_int64);
const char *(*sourceid)(void);
int (*stmt_status)(sqlite3_stmt*,int,int);
@@ -232,7 +232,7 @@ struct sqlite3_api_routines {
int (*wal_checkpoint)(sqlite3*,const char*);
void *(*wal_hook)(sqlite3*,int(*)(void*,sqlite3*,const char*,int),void*);
int (*blob_reopen)(sqlite3_blob*,sqlite3_int64);
int (*vtab_config)(sqlite3*,int op,...);
int (SQLITE_CDECL*vtab_config)(sqlite3*,int op,...);
int (*vtab_on_conflict)(sqlite3*);
/* Version 3.7.16 and later */
int (*close_v2)(sqlite3*);
@@ -301,7 +301,7 @@ struct sqlite3_api_routines {
int (*keyword_check)(const char*,int);
sqlite3_str *(*str_new)(sqlite3*);
char *(*str_finish)(sqlite3_str*);
void (*str_appendf)(sqlite3_str*, const char *zFormat, ...);
void (SQLITE_CDECL*str_appendf)(sqlite3_str*, const char *zFormat, ...);
void (*str_vappendf)(sqlite3_str*, const char *zFormat, va_list);
void (*str_append)(sqlite3_str*, const char *zIn, int N);
void (*str_appendall)(sqlite3_str*, const char *zIn);
@@ -376,6 +376,9 @@ struct sqlite3_api_routines {
void (*str_free)(sqlite3_str*);
int (*carray_bind)(sqlite3_stmt*,int,void*,int,int,void(*)(void*));
int (*carray_bind_v2)(sqlite3_stmt*,int,void*,int,int,void(*)(void*),void*);
/* Version 3.54.0 and later */
sqlite3_int64 (*incomplete)(const char*);
void (*result_str)(sqlite3_context*,sqlite3_str*,int);
};
/*
@@ -719,6 +722,9 @@ typedef int (*sqlite3_loadext_entry)(
#define sqlite3_str_free sqlite3_api->str_free
#define sqlite3_carray_bind sqlite3_api->carray_bind
#define sqlite3_carray_bind_v2 sqlite3_api->carray_bind_v2
/* Version 3.54.0 and later */
#define sqlite3_incomplete sqlite3_api->incomplete
#define sqlite3_result_str sqlite3_api->result_str
#endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */
#if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
+1 -1
View File
@@ -1,3 +1,3 @@
#ifndef SQLITE_RESOURCE_VERSION
#define SQLITE_RESOURCE_VERSION 3,53,3
#define SQLITE_RESOURCE_VERSION 3,54,1
#endif
+72 -15
View File
@@ -1135,7 +1135,7 @@ static void tclSqlFunc(sqlite3_context *context, int argc, sqlite3_value**argv){
switch( eType ){
case SQLITE_BLOB: {
data = Tcl_GetByteArrayFromObj(pVar, &n);
sqlite3_result_blob(context, data, n, SQLITE_TRANSIENT);
sqlite3_result_blob64(context, data, n, SQLITE_TRANSIENT);
break;
}
case SQLITE_INTEGER: {
@@ -1527,7 +1527,7 @@ static int dbPrepareAndBind(
** it has no string representation or the host
** parameter name begins with "@". */
data = Tcl_GetByteArrayFromObj(pVar, &n);
sqlite3_bind_blob(pStmt, i, data, n, SQLITE_STATIC);
sqlite3_bind_blob64(pStmt, i, data, n, SQLITE_STATIC);
Tcl_IncrRefCount(pVar);
pPreStmt->apParm[iParm++] = pVar;
}else if( c=='b' && pVar->bytes==0
@@ -2071,6 +2071,7 @@ static void DbHookCmd(
** -defaultalign ("auto"|"left"|...) Default alignment
** -titalalign ("auto"|"left"|"right"|...) Default column name alignment
** -border ("auto"|"off"|"on") Border for box and table styles
** -rowcount ("auto"|"off"|"on") Show row counts
** -wrap NUMBER Max width of any single column
** -screenwidth NUMBER Width of the display TTY
** -linelimit NUMBER Max lines for any cell
@@ -2083,6 +2084,8 @@ static void DbHookCmd(
** -rowsep TEXT Row separator text
** -tablename TEXT Table name for style "insert"
** -null TEXT Text for NULL values
** -ifmt STRING Format for integer values
** -fpfmt STRING Format for floating-point values
**
** A mapping from TCL "format" command options to sqlite3_qrf_spec fields
** is below. Use this to reference the QRF documentation:
@@ -2092,7 +2095,7 @@ static void DbHookCmd(
** -style eStyle
** -esc eEsc
** -text eText
** -title eTitle, bTitle
** -title eTitle, bTitles
** -blob eBlob
** -wordwrap bWordWrap
** -textjsonb bTextJsonb
@@ -2100,6 +2103,7 @@ static void DbHookCmd(
** -defaultalign eDfltAlign
** -titlealign eTitleAlign
** -border bBorder
** -rowcount bRowCount
** -wrap nWrap
** -screenwidth nScreenWidth
** -linelimit nLineLimit
@@ -2112,6 +2116,28 @@ static void DbHookCmd(
** -rowsep zRowSep
** -tablename zTableName
** -null zNull
** -ifmt zIFmt
** -fpfmt zFpFmt
**
** The TCL -title option maps to eTitle and bTitles as follows:
**
** -title eTitle bTitles
** ------- ----------------- ------------
** off QRF_TEXT_Auto QRF_Off
** on QRF_TEXT_Auto QRF_On
** always QRF_TEXT_Auto QRF_Always
** auto QRF_TEXT_Auto QRF_On
** csv QRF_TEXT_Csv QRF_On
** html QRF_TEXT_Html QRF_On
** json QRF_TEXT_Json QRF_On
** plain QRF_TEXT_Plain QRF_On
** relaxed QRF_TEXT_Relaxed QRF_On
** sql QRF_TEXT_Sql QRF_On
** tcl QRF_TEXT_Tcl QRF_On
**
** Note in particular that for the last seven entries ("csv" through "tcl"),
** the CLI .mode --title option sets bTitles to QRF_Always, whereas this TCL
** interface set it to QRF_On.
*/
static int dbQrf(SqliteDb *pDb, int objc, Tcl_Obj *const*objv){
#ifndef SQLITE_QRF_H
@@ -2141,7 +2167,7 @@ static int dbQrf(SqliteDb *pDb, int objc, Tcl_Obj *const*objv){
};
memset(&qrf, 0, sizeof(qrf));
qrf.iVersion = 1;
qrf.iVersion = 2;
qrf.pzOutput = &zResult;
for(i=2; i<objc; i++){
const char *zArg = Tcl_GetString(objv[i]);
@@ -2155,7 +2181,7 @@ static int dbQrf(SqliteDb *pDb, int objc, Tcl_Obj *const*objv){
}
zSql = zArg;
}else if( i==objc-1 ){
Tcl_AppendResult(pDb->interp, "option has no argument: ", zArg, (char*)0);
Tcl_AppendResult(pDb->interp, "option has no argument: ", zArg,(char*)0);
rc = TCL_ERROR;
goto format_failed;
}else if( strcmp(zArg,"-style")==0 ){
@@ -2200,7 +2226,7 @@ static int dbQrf(SqliteDb *pDb, int objc, Tcl_Obj *const*objv){
/* NB: --title can be "off" or "on but --text may not be. Thus we put
** the "off" and "on" choices first and start the search on the
** thrid element of the array when processing --text */
static const char *azText[] = { "off", "on",
static const char *azText[] = { "off", "on", "always",
"auto", "csv", "html",
"json", "plain", "relaxed",
"sql", "tcl", 0
@@ -2212,17 +2238,20 @@ static int dbQrf(SqliteDb *pDb, int objc, Tcl_Obj *const*objv){
};
int txt;
int k = zArg[2]=='e';
rc = Tcl_GetIndexFromObj(pDb->interp, objv[i+1], &azText[k*2], zArg,
rc = Tcl_GetIndexFromObj(pDb->interp, objv[i+1], &azText[k*3], zArg,
0, &txt);
if( rc ) goto format_failed;
if( k ){
qrf.eText = aTextMap[txt];
}else if( txt<=1 ){
qrf.bTitles = txt ? QRF_Yes : QRF_No;
}else if( txt<=2 ){
assert( QRF_No==1 );
assert( QRF_Yes==2 );
assert( QRF_Always==3 );
qrf.bTitles = txt+QRF_No;
qrf.eTitle = QRF_TEXT_Auto;
}else{
qrf.bTitles = QRF_Yes;
qrf.eTitle = aTextMap[txt-2];
qrf.eTitle = aTextMap[txt-3];
}
i++;
}else if( strcmp(zArg,"-blob")==0 ){
@@ -2252,6 +2281,7 @@ static int dbQrf(SqliteDb *pDb, int objc, Tcl_Obj *const*objv){
}else if( strcmp(zArg,"-textjsonb")==0
|| strcmp(zArg,"-splitcolumn")==0
|| strcmp(zArg,"-border")==0
|| strcmp(zArg,"-rowcount")==0
){
int v = 0;
rc = Tcl_GetIndexFromObj(pDb->interp, objv[i+1], azBool,
@@ -2261,11 +2291,14 @@ static int dbQrf(SqliteDb *pDb, int objc, Tcl_Obj *const*objv){
qrf.bTextJsonb = aBoolMap[v];
}else if( zArg[1]=='b' ){
qrf.bBorder = aBoolMap[v];
}else if( zArg[1]=='r' ){
qrf.bRowCount = aBoolMap[v];
}else{
qrf.bSplitColumn = aBoolMap[v];
}
i++;
}else if( strcmp(zArg,"-defaultalign")==0 || strcmp(zArg,"-titlealign")==0){
}else if( strcmp(zArg,"-defaultalign")==0
|| strcmp(zArg,"-titlealign")==0){
int ax = 0;
rc = Tcl_GetIndexFromObj(pDb->interp, objv[i+1], azAlign,
zArg[1]=='d' ? "default alignment (-defaultalign)" :
@@ -2380,6 +2413,28 @@ static int dbQrf(SqliteDb *pDb, int objc, Tcl_Obj *const*objv){
}else if( strcmp(zArg,"-null")==0 ){
qrf.zNull = Tcl_GetString(objv[i+1]);
i++;
}else if( strcmp(zArg,"-ifmt")==0 ){
char *zFmt = Tcl_GetString(objv[i+1]);
if( zFmt[0]==0 || strcmp(zFmt,"auto")==0 ){
zFmt = 0;
}else if( sqlite3_qrf_ckformat(zFmt)!=1 ){
Tcl_AppendResult(pDb->interp, "bad format for -ifmt", (char*)0);
rc = TCL_ERROR;
goto format_failed;
}
qrf.zIFmt = zFmt;
i++;
}else if( strcmp(zArg,"-fpfmt")==0 ){
char *zFmt = Tcl_GetString(objv[i+1]);
if( zFmt[0]==0 || strcmp(zFmt,"auto")==0 ){
zFmt = 0;
}else if( sqlite3_qrf_ckformat(zFmt)!=2 ){
Tcl_AppendResult(pDb->interp, "bad format for -fpfmt", (char*)0);
rc = TCL_ERROR;
goto format_failed;
}
qrf.zFpFmt = zFmt;
i++;
}else if( strcmp(zArg,"-version")==0 ){
/* Undocumented. Testing use only */
qrf.iVersion = atoi(Tcl_GetString(objv[i+1]));
@@ -3118,6 +3173,9 @@ static int SQLITE_TCLAPI DbObjCmd(
if( zCommit[0] == 'C' ){
/* success, set result as number of lines processed */
pResult = Tcl_GetObjResult(interp);
if( Tcl_IsShared(pResult) ){
pResult = Tcl_DuplicateObj(pResult);
}
Tcl_SetIntObj(pResult, lineno);
rc = TCL_OK;
}else{
@@ -4186,10 +4244,9 @@ deserialize_error:
** most recent sqlite3_stmt in the statement cache.
*/
if( strcmp(zArg, "-last-stmt-ptr")==0 ){
char zBuf[100];
sqlite3_snprintf(sizeof(zBuf), zBuf, "%p",
pDb->stmtList ? pDb->stmtList->pStmt: 0);
Tcl_SetResult(interp, zBuf, TCL_VOLATILE);
extern const char *sqlite3TestPtrToText(void*);
void *ptr = (void*)(pDb->stmtList ? pDb->stmtList->pStmt: 0);
Tcl_SetResult(interp, (char*)sqlite3TestPtrToText(ptr), TCL_VOLATILE);
}else
#endif /* SQLITE_TEST */
{