Compare commits
150 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 5e2e34aef8 | |||
| f47095a5a0 | |||
| 791b767b26 | |||
| ce53b80819 | |||
| b867030b1a | |||
| 7efded5edc | |||
| f07576429e | |||
| 14fcb8252a | |||
| a79f685533 | |||
| 240397bb03 | |||
| 4ac766cc05 | |||
| 73caea1764 | |||
| 998ebf1de7 | |||
| 051e942f5d | |||
| 4182294987 | |||
| c55d8262cf | |||
| 66b37e991b | |||
| 0aca0ccf2c | |||
| 748c0adb62 | |||
| e77530050e | |||
| 366e0ed80c | |||
| 201066302e | |||
| 29bdac3ee5 | |||
| 53ba0b80f2 | |||
| c2aa8e3875 | |||
| b799156a31 | |||
| 23e4ae2121 | |||
| abc23b5404 | |||
| e977440d79 | |||
| bb3b269ba9 | |||
| 1bf7eb3d49 | |||
| f1c37a357e | |||
| d95fffc9af | |||
| 4733884eae | |||
| 0dfa31d279 | |||
| 15c6d88381 | |||
| eaacb4ac37 | |||
| 0c747e1653 | |||
| e5c8467a8e | |||
| b2b8ab6bc8 | |||
| 7f70085071 | |||
| a183595edd | |||
| 63ab7c625c | |||
| 1c19c06246 | |||
| da17de532f | |||
| 1ed6441bb1 | |||
| c129de05bb | |||
| 6acd8d28fd | |||
| 139ec38ac8 | |||
| 41fda52f3c | |||
| 7fb2545905 | |||
| 3a61466a2f | |||
| 916fc1129c | |||
| a8a99becb5 | |||
| f3b396494f | |||
| 4ebf49168a | |||
| c6b86ba2ab | |||
| c5ff2aa7cf | |||
| cb36dc3f3e | |||
| bc5e0be7f8 | |||
| 7c86a0321e | |||
| d443f0a95f | |||
| 34b1bf16ec | |||
| 74cd3c53f9 | |||
| ffbfc27fab | |||
| 5a9ada593f | |||
| 9c0770537f | |||
| 6cc222c3be | |||
| db0d47b749 | |||
| e34f35c833 | |||
| 626351d444 | |||
| 6e27846323 | |||
| 8ce786f173 | |||
| 6b9230d2a1 | |||
| 241004f8fc | |||
| 89a9efe840 | |||
| 4f177f1d3e | |||
| d4ead9b9e4 | |||
| f57d368078 | |||
| 3fceae3b95 | |||
| 38113d392d | |||
| a105989856 | |||
| ecbeefecd0 | |||
| 2b24d8957e | |||
| 726e836108 | |||
| 7be565f0cc | |||
| c053b57716 | |||
| 0d859b4828 | |||
| ab29c24dc3 | |||
| dcc07d3ca6 | |||
| 234c6c4bf0 | |||
| 86319b841a | |||
| f4e66056ac | |||
| 76db3a6e66 | |||
| 003737d1dc | |||
| 02c5f3976f | |||
| be4d0c2e2f | |||
| aeb886bc53 | |||
| 2f9311c5cb | |||
| 093b26e8e0 | |||
| 63ee854264 | |||
| 3ba506d9cc | |||
| 67fa337744 | |||
| 033dbac510 | |||
| 9af334f54a | |||
| 4bb53ab2e4 | |||
| 7adc9a5978 | |||
| acdda1075d | |||
| bc2691d5c1 | |||
| 95c188d557 | |||
| 4043096408 | |||
| d06a0be514 | |||
| 984e446891 | |||
| 774ce0ba43 | |||
| d41f5ef7e6 | |||
| efe8ae567c | |||
| 21c57abc53 | |||
| 31c86ca0a8 | |||
| 9f36870a77 | |||
| 9c3fcd932d | |||
| 0a585a64d2 | |||
| 6eaeea0a3b | |||
| e826aa8e00 | |||
| ff5d4c348c | |||
| f66a0600d8 | |||
| 34c1e04cbf | |||
| f83df5b150 | |||
| d6cb2ccee6 | |||
| e7cf3fe4c8 | |||
| efde2f6059 | |||
| 53a6b7d138 | |||
| 4472c967a6 | |||
| abe709be8d | |||
| 5dbbe50758 | |||
| 9f136fc5ed | |||
| 898ac77f55 | |||
| 264bcad69a | |||
| a8bb50ce95 | |||
| c93270ebc7 | |||
| 94356039d0 | |||
| ee4676b3f7 | |||
| e4eaf174a5 | |||
| 59e1ab5576 | |||
| 974b8d7df0 | |||
| 8f6b797a1b | |||
| c49ff175ef | |||
| 51e3a140c9 | |||
| 7cbfa5b0d1 | |||
| 16eedfbdda | |||
| 3e17953beb |
+10
-16
@@ -30,14 +30,12 @@ The public domain source files usually contain a header comment
|
||||
similar to the following to make it clear that the software is
|
||||
public domain.
|
||||
|
||||
> ~~~
|
||||
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.
|
||||
~~~
|
||||
> 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.
|
||||
|
||||
Almost every file you find in this source repository will be
|
||||
public domain. But there are a small number of exceptions:
|
||||
@@ -49,9 +47,7 @@ This repository contains a (relatively) small amount of non-public-domain
|
||||
code used to help implement the configuration and build logic. In other
|
||||
words, there are some non-public-domain files used to implement:
|
||||
|
||||
> ~~~
|
||||
./configure && make
|
||||
~~~
|
||||
> ./configure && make
|
||||
|
||||
In all cases, the non-public-domain files included with this
|
||||
repository have generous BSD-style licenses. So anyone is free to
|
||||
@@ -69,7 +65,7 @@ third-party build scripts in order to compile SQLite.
|
||||
Non-public-domain code included in this respository includes:
|
||||
|
||||
* The ["autosetup"](http://msteveb.github.io/autosetup/) configuration
|
||||
system that is contained (mostly) the autosetup/ directory, but also
|
||||
system that is contained (mostly) in the autosetup/ directory, but also
|
||||
includes the "./configure" script at the top-level of this archive.
|
||||
Autosetup has a separate BSD-style license. See the
|
||||
[autosetup/LICENSE](http://msteveb.github.io/autosetup/license/)
|
||||
@@ -79,13 +75,11 @@ Non-public-domain code included in this respository includes:
|
||||
software found in the legacy autoconf/ directory and its
|
||||
subdirectories.
|
||||
|
||||
The following unix shell command is can be run from the top-level
|
||||
The following unix shell command can be run from the top-level
|
||||
of this source repository in order to remove all non-public-domain
|
||||
code:
|
||||
|
||||
> ~~~
|
||||
rm -rf configure autosetup autoconf
|
||||
~~~
|
||||
> rm -rf configure autosetup autoconf
|
||||
|
||||
If you unpack this source repository and then run the command above, what
|
||||
is left will be 100% public domain.
|
||||
|
||||
@@ -1770,6 +1770,7 @@ SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_OFFSET_SQL_FUNC=1
|
||||
SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_PERCENTILE=1
|
||||
SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_UNKNOWN_SQL_FUNCTION=1
|
||||
SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_STMT_SCANSTATUS=1
|
||||
SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_BYTECODE_VTAB=1
|
||||
SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_STRICT_SUBTYPE=1
|
||||
!ENDIF
|
||||
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
|
||||
This repository contains the complete source code for the
|
||||
[SQLite database engine](https://sqlite.org/), including
|
||||
many test scripts. However, other test scripts
|
||||
and most of the documentation are managed separately.
|
||||
many tests. Additional tests and most documentation
|
||||
are managed separately.
|
||||
|
||||
See the [on-line documentation](https://sqlite.org/) for more information
|
||||
about what SQLite is and how it works from a user's perspective. This
|
||||
@@ -53,39 +53,32 @@ then no longer be fully in the public domain.
|
||||
|
||||
## Obtaining The SQLite Source Code
|
||||
|
||||
If you do not want to use Fossil, you can download tarballs or ZIP
|
||||
archives or [SQLite archives](https://sqlite.org/cli.html#sqlar) as follows:
|
||||
Source code tarballs or ZIP archives are available at:
|
||||
|
||||
* Latest trunk check-in as
|
||||
[Tarball](https://sqlite.org/src/tarball/sqlite.tar.gz),
|
||||
[ZIP-archive](https://sqlite.org/src/zip/sqlite.zip), or
|
||||
[SQLite-archive](https://sqlite.org/src/sqlar/sqlite.sqlar).
|
||||
* [Latest trunk check-in](https://sqlite.org/src/rchvdwnld/trunk).
|
||||
|
||||
* Latest release as
|
||||
[Tarball](https://sqlite.org/src/tarball/sqlite.tar.gz?r=release),
|
||||
[ZIP-archive](https://sqlite.org/src/zip/sqlite.zip?r=release), or
|
||||
[SQLite-archive](https://sqlite.org/src/sqlar/sqlite.sqlar?r=release).
|
||||
* [Latest release](https://sqlite.org/src/rchvdwnld/release)
|
||||
|
||||
* For other check-ins, substitute an appropriate branch name or
|
||||
tag or hash prefix in place of "release" in the URLs of the previous
|
||||
bullet. Or browse the [timeline](https://sqlite.org/src/timeline)
|
||||
to locate the check-in desired, click on its information page link,
|
||||
then click on the "Tarball" or "ZIP Archive" links on the information
|
||||
page.
|
||||
* For other check-ins, browse the
|
||||
[project timeline](https://sqlite.org/src/timeline?y=ci) and
|
||||
click on the check-in hash of the check-in you want to download.
|
||||
On the resulting "info" page, click one of the options to the
|
||||
right of the "**Downloads:**" label in the "**Overview**" section
|
||||
near the top.
|
||||
|
||||
To access sources directly using [Fossil](https://fossil-scm.org/home),
|
||||
first install Fossil version 2.0 or later.
|
||||
Source tarballs and precompiled binaries available at
|
||||
Source tarballs and precompiled binaries for Fossil are available at
|
||||
<https://fossil-scm.org/home/uv/download.html>. Fossil is
|
||||
a stand-alone program. To install, simply download or build the single
|
||||
executable file and put that file someplace on your $PATH.
|
||||
executable file and put that file someplace on your $PATH or %PATH%.
|
||||
Then run commands like this:
|
||||
|
||||
mkdir -p ~/sqlite
|
||||
cd ~/sqlite
|
||||
fossil open https://sqlite.org/src
|
||||
|
||||
The "fossil open" command will take two or three minutes. Afterwards,
|
||||
The initial "fossil open" command will take two or three minutes. Afterwards,
|
||||
you can do fast, bandwidth-efficient updates to the whatever versions
|
||||
of SQLite you like. Some examples:
|
||||
|
||||
@@ -152,7 +145,8 @@ show what changes are needed.
|
||||
## Compiling for Windows Using MSVC
|
||||
|
||||
On Windows, everything can be compiled with MSVC.
|
||||
You will also need a working installation of TCL.
|
||||
You will also need a working installation of TCL if you want to run tests.
|
||||
TCL is not required if you just want to build SQLite itself.
|
||||
See the [compile-for-windows.md](doc/compile-for-windows.md) document for
|
||||
additional information about how to install MSVC and TCL and configure your
|
||||
build environment.
|
||||
@@ -164,8 +158,8 @@ TCL library, using a command like this:
|
||||
|
||||
SQLite uses "tclsh.exe" as part of the build process, and so that
|
||||
program will need to be somewhere on your %PATH%. SQLite itself
|
||||
does not contain any TCL code, but it does use TCL to help with the
|
||||
build process and to run tests. You may need to install TCL development
|
||||
does not contain any TCL code, but it does use TCL to run tests.
|
||||
You may need to install TCL development
|
||||
libraries in order to successfully complete some makefile targets.
|
||||
It is helpful, but is not required, to install the SQLite TCL extension
|
||||
(the "tclextension-install" target) prior to running tests.
|
||||
|
||||
@@ -119,7 +119,7 @@ TCLLIBDIR = @TCLLIBDIR@
|
||||
# typically come from the ./configure command-line invocation).
|
||||
#
|
||||
CFLAGS.configure = @SH_CFLAGS@ @TEAISH_CFLAGS@ @CFLAGS@ @CPPFLAGS@ $(TCL_INCLUDE_SPEC)
|
||||
#CFLAGS.configure += -DUSE_TCL_STUBS=1
|
||||
CFLAGS.configure += -DUSE_TCL_STUBS=@TEAISH_USE_STUBS@
|
||||
|
||||
#
|
||||
# LDFLAGS.configure = LDFLAGS as known at configure-time.
|
||||
@@ -153,6 +153,7 @@ tx.src = @TEAISH_EXT_SRC@
|
||||
# gets set up via the configure script.
|
||||
#
|
||||
tx.CFLAGS =
|
||||
tx.CPPFLAGS =
|
||||
|
||||
#
|
||||
# tx.LDFLAGS is typically set by teaish.make, whereas TEAISH_LDFLAGS
|
||||
@@ -218,7 +219,7 @@ config.log: @TEAISH_TEST_TCL_IN@
|
||||
# CC variant for compiling Tcl-using sources.
|
||||
#
|
||||
CC.tcl = \
|
||||
$(CC) -o $@ $(CFLAGS.configure) $(CFLAGS) $(tx.CFLAGS)
|
||||
$(CC) -o $@ $(CFLAGS.configure) $(CFLAGS) $(tx.CFLAGS) $(tx.CPPFLAGS)
|
||||
|
||||
#
|
||||
# CC variant for linking $(tx.src) into an extension DLL. Note that
|
||||
|
||||
+1
-1
@@ -557,7 +557,7 @@ proc proj-opt-define-bool {args} {
|
||||
if {$invert} {
|
||||
set rc [expr {!$rc}]
|
||||
}
|
||||
msg-result $rc
|
||||
msg-result [string map {0 no 1 yes} $rc]
|
||||
define $defName $rc
|
||||
return $rc
|
||||
}
|
||||
|
||||
@@ -481,11 +481,7 @@ proc sqlite-configure-phase1 {buildMode} {
|
||||
proj-setup-autoreconfig SQLITE_AUTORECONFIG
|
||||
proj-file-extensions
|
||||
if {".exe" eq [get-define TARGET_EXEEXT]} {
|
||||
if {$::tcl_platform(platform) eq "unix"} {
|
||||
define SQLITE_OS_UNIX 1
|
||||
} else {
|
||||
define SQLITE_OS_UNIX 0
|
||||
}
|
||||
define SQLITE_OS_UNIX 0
|
||||
define SQLITE_OS_WIN 1
|
||||
} else {
|
||||
define SQLITE_OS_UNIX 1
|
||||
@@ -561,7 +557,25 @@ proc proc-debug {msg} {
|
||||
}
|
||||
|
||||
define OPT_FEATURE_FLAGS {} ; # -DSQLITE_OMIT/ENABLE flags.
|
||||
define OPT_SHELL {} ; # Feature-related CFLAGS for the sqlite3 CLI app
|
||||
#
|
||||
# OPT_SHELL = feature-related CFLAGS for the sqlite3 CLI app. The
|
||||
# list's initial values are defaults which are always applied and not
|
||||
# affected by --feature-flags. The list is appended to by various
|
||||
# --feature-flags.
|
||||
define OPT_SHELL {
|
||||
-DSQLITE_DQS=0
|
||||
-DSQLITE_ENABLE_FTS4
|
||||
-DSQLITE_ENABLE_RTREE
|
||||
-DSQLITE_ENABLE_EXPLAIN_COMMENTS
|
||||
-DSQLITE_ENABLE_UNKNOWN_SQL_FUNCTION
|
||||
-DSQLITE_ENABLE_STMTVTAB
|
||||
-DSQLITE_ENABLE_DBPAGE_VTAB
|
||||
-DSQLITE_ENABLE_DBSTAT_VTAB
|
||||
-DSQLITE_ENABLE_BYTECODE_VTAB
|
||||
-DSQLITE_ENABLE_OFFSET_SQL_FUNC
|
||||
-DSQLITE_ENABLE_PERCENTILE
|
||||
-DSQLITE_STRICT_SUBTYPE=1
|
||||
}
|
||||
########################################################################
|
||||
# Adds $args, if not empty, to OPT_FEATURE_FLAGS. If the first arg is
|
||||
# -shell then it strips that arg and passes the remaining args the
|
||||
@@ -635,7 +649,7 @@ proc sqlite-check-common-system-deps {} {
|
||||
|
||||
# Check for needed/wanted functions
|
||||
cc-check-functions gmtime_r isnan localtime_r localtime_s \
|
||||
strchrnul usleep utime pread pread64 pwrite pwrite64
|
||||
usleep utime pread pread64 pwrite pwrite64
|
||||
|
||||
apply {{} {
|
||||
set ldrt ""
|
||||
|
||||
@@ -220,7 +220,9 @@ proc teaish-configure-core {} {
|
||||
=> {Full pathname of tclsh to use. It is used for trying to find
|
||||
tclConfig.sh. Warning: if its containing dir has multiple tclsh
|
||||
versions, it may select the wrong tclConfig.sh!
|
||||
Defaults to the $TCLSH environment variable.}
|
||||
Defaults to the $TCLSH environment variable.}
|
||||
|
||||
tcl-stubs=0 => {Enable use of Tcl stubs library.}
|
||||
|
||||
# TEA has --with-tclinclude but it appears to only be useful for
|
||||
# building an extension against an uninstalled copy of TCL's own
|
||||
@@ -498,6 +500,8 @@ proc teaish__configure_phase1 {} {
|
||||
}
|
||||
teaish-checks-run -post
|
||||
|
||||
define TEAISH_USE_STUBS [opt-bool tcl-stubs]
|
||||
|
||||
apply {{} {
|
||||
# Set up "vsatisfies" code for pkgIndex.tcl.in,
|
||||
# _teaish.tester.tcl.in, and for a configure-time check. We would
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# Notes On Compiling SQLite On Windows 11
|
||||
|
||||
Below are step-by-step instructions on how to build SQLite from
|
||||
canonical source on a new Windows 11 PC, as of 2024-10-09.
|
||||
canonical source on a new Windows 11 PC, as of 2025-10-31.
|
||||
See [](./compile-for-unix.md) for a similar guide for unix-like
|
||||
systems, including MacOS.
|
||||
|
||||
@@ -24,7 +24,8 @@ systems, including MacOS.
|
||||
application to your task bar, as you will use it a lot. Bring up
|
||||
an instance of this command prompt and do all of the subsequent steps
|
||||
in that "x64 Native Tools" command prompt. (Or use "x86" if you want
|
||||
a 32-bit build.) The subsequent steps will not work in a vanilla
|
||||
a 32-bit build. Or use "ARM64" if you want to do a build for Windows
|
||||
on ARM.) The subsequent steps will not work in a vanilla
|
||||
DOS prompt. Nor will they work in PowerShell.
|
||||
|
||||
3. *(Optional):* Install TCL development libraries.
|
||||
@@ -133,9 +134,7 @@ following minor changes:
|
||||
The command the developers use for building the deliverable DLL on the
|
||||
[download page](https://sqlite.org/download.html) is as follows:
|
||||
|
||||
> ~~~~
|
||||
nmake /f Makefile.msc sqlite3.dll USE_NATIVE_LIBPATHS=1 "OPTS=-DSQLITE_ENABLE_FTS3=1 -DSQLITE_ENABLE_FTS4=1 -DSQLITE_ENABLE_FTS5=1 -DSQLITE_ENABLE_RTREE=1 -DSQLITE_ENABLE_JSON1=1 -DSQLITE_ENABLE_GEOPOLY=1 -DSQLITE_ENABLE_SESSION=1 -DSQLITE_ENABLE_PREUPDATE_HOOK=1 -DSQLITE_ENABLE_SERIALIZE=1 -DSQLITE_ENABLE_MATH_FUNCTIONS=1"
|
||||
~~~~
|
||||
> nmake /f Makefile.msc sqlite3.dll USE_NATIVE_LIBPATHS=1 "OPTS=-DSQLITE_ENABLE_FTS3=1 -DSQLITE_ENABLE_FTS4=1 -DSQLITE_ENABLE_FTS5=1 -DSQLITE_ENABLE_RTREE=1 -DSQLITE_ENABLE_JSON1=1 -DSQLITE_ENABLE_GEOPOLY=1 -DSQLITE_ENABLE_SESSION=1 -DSQLITE_ENABLE_PREUPDATE_HOOK=1 -DSQLITE_ENABLE_SERIALIZE=1 -DSQLITE_ENABLE_MATH_FUNCTIONS=1"
|
||||
|
||||
That command generates both the sqlite3.dll and sqlite3.def files. The same
|
||||
command works for both 32-bit and 64-bit builds.
|
||||
@@ -147,9 +146,7 @@ with TCL in order to function. The [sqlite3_analyzer.exe program](https://sqlit
|
||||
is an example. You can build as described above, and then
|
||||
enter:
|
||||
|
||||
> ~~~~
|
||||
nmake /f Makefile.msc sqlite3_analyzer.exe
|
||||
~~~~
|
||||
> nmake /f Makefile.msc sqlite3_analyzer.exe
|
||||
|
||||
And you will end up with a working executable. However, that executable
|
||||
will depend on having the "tcl98.dll" library somewhere on your %PATH%.
|
||||
@@ -175,17 +172,11 @@ statically linked so that it does not depend on separate DLL:
|
||||
5. CD into your SQLite source code directory and build the desired
|
||||
utility program, but add the following extra argument to the
|
||||
nmake command line:
|
||||
<blockquote><pre>
|
||||
STATICALLY_LINK_TCL=1
|
||||
</pre></blockquote>
|
||||
<blockquote><pre>STATICALLY_LINK_TCL=1</pre></blockquote>
|
||||
<p>So, for example, to build a statically linked version of
|
||||
sqlite3_analyzer.exe, you might type:
|
||||
<blockquote><pre>
|
||||
nmake /f Makefile.msc STATICALLY_LINK_TCL=1 sqlite3_analyzer.exe
|
||||
</pre></blockquote>
|
||||
<blockquote><pre>nmake /f Makefile.msc STATICALLY_LINK_TCL=1 sqlite3_analyzer.exe</pre></blockquote>
|
||||
|
||||
6. After your executable is built, you can verify that it does not
|
||||
depend on the TCL DLL by running:
|
||||
<blockquote><pre>
|
||||
dumpbin /dependents sqlite3_analyzer.exe
|
||||
</pre></blockquote>
|
||||
<blockquote><pre>dumpbin /dependents sqlite3_analyzer.exe</pre></blockquote>
|
||||
|
||||
+27
-25
@@ -172,11 +172,11 @@ struct sqlite3expert {
|
||||
** Allocate and return nByte bytes of zeroed memory using sqlite3_malloc().
|
||||
** If the allocation fails, set *pRc to SQLITE_NOMEM and return NULL.
|
||||
*/
|
||||
static void *idxMalloc(int *pRc, int nByte){
|
||||
static void *idxMalloc(int *pRc, i64 nByte){
|
||||
void *pRet;
|
||||
assert( *pRc==SQLITE_OK );
|
||||
assert( nByte>0 );
|
||||
pRet = sqlite3_malloc(nByte);
|
||||
pRet = sqlite3_malloc64(nByte);
|
||||
if( pRet ){
|
||||
memset(pRet, 0, nByte);
|
||||
}else{
|
||||
@@ -243,7 +243,7 @@ static int idxHashAdd(
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
pEntry = idxMalloc(pRc, sizeof(IdxHashEntry) + nKey+1 + nVal+1);
|
||||
pEntry = idxMalloc(pRc, sizeof(IdxHashEntry) + (i64)nKey+1 + (i64)nVal+1);
|
||||
if( pEntry ){
|
||||
pEntry->zKey = (char*)&pEntry[1];
|
||||
memcpy(pEntry->zKey, zKey, nKey);
|
||||
@@ -378,15 +378,15 @@ struct ExpertCsr {
|
||||
};
|
||||
|
||||
static char *expertDequote(const char *zIn){
|
||||
int n = STRLEN(zIn);
|
||||
char *zRet = sqlite3_malloc(n);
|
||||
i64 n = STRLEN(zIn);
|
||||
char *zRet = sqlite3_malloc64(n);
|
||||
|
||||
assert( zIn[0]=='\'' );
|
||||
assert( zIn[n-1]=='\'' );
|
||||
|
||||
if( zRet ){
|
||||
int iOut = 0;
|
||||
int iIn = 0;
|
||||
i64 iOut = 0;
|
||||
i64 iIn = 0;
|
||||
for(iIn=1; iIn<(n-1); iIn++){
|
||||
if( zIn[iIn]=='\'' ){
|
||||
assert( zIn[iIn+1]=='\'' );
|
||||
@@ -699,7 +699,7 @@ static int idxGetTableInfo(
|
||||
sqlite3_stmt *p1 = 0;
|
||||
int nCol = 0;
|
||||
int nTab;
|
||||
int nByte;
|
||||
i64 nByte;
|
||||
IdxTable *pNew = 0;
|
||||
int rc, rc2;
|
||||
char *pCsr = 0;
|
||||
@@ -791,14 +791,14 @@ static char *idxAppendText(int *pRc, char *zIn, const char *zFmt, ...){
|
||||
va_list ap;
|
||||
char *zAppend = 0;
|
||||
char *zRet = 0;
|
||||
int nIn = zIn ? STRLEN(zIn) : 0;
|
||||
int nAppend = 0;
|
||||
i64 nIn = zIn ? STRLEN(zIn) : 0;
|
||||
i64 nAppend = 0;
|
||||
va_start(ap, zFmt);
|
||||
if( *pRc==SQLITE_OK ){
|
||||
zAppend = sqlite3_vmprintf(zFmt, ap);
|
||||
if( zAppend ){
|
||||
nAppend = STRLEN(zAppend);
|
||||
zRet = (char*)sqlite3_malloc(nIn + nAppend + 1);
|
||||
zRet = (char*)sqlite3_malloc64(nIn + nAppend + 1);
|
||||
}
|
||||
if( zAppend && zRet ){
|
||||
if( nIn ) memcpy(zRet, zIn, nIn);
|
||||
@@ -1562,8 +1562,8 @@ struct IdxRemCtx {
|
||||
int eType; /* SQLITE_NULL, INTEGER, REAL, TEXT, BLOB */
|
||||
i64 iVal; /* SQLITE_INTEGER value */
|
||||
double rVal; /* SQLITE_FLOAT value */
|
||||
int nByte; /* Bytes of space allocated at z */
|
||||
int n; /* Size of buffer z */
|
||||
i64 nByte; /* Bytes of space allocated at z */
|
||||
i64 n; /* Size of buffer z */
|
||||
char *z; /* SQLITE_TEXT/BLOB value */
|
||||
} aSlot[1];
|
||||
};
|
||||
@@ -1599,11 +1599,13 @@ static void idxRemFunc(
|
||||
break;
|
||||
|
||||
case SQLITE_BLOB:
|
||||
sqlite3_result_blob(pCtx, pSlot->z, pSlot->n, SQLITE_TRANSIENT);
|
||||
assert( pSlot->n <= 0x7fffffff );
|
||||
sqlite3_result_blob(pCtx, pSlot->z, (int)pSlot->n, SQLITE_TRANSIENT);
|
||||
break;
|
||||
|
||||
case SQLITE_TEXT:
|
||||
sqlite3_result_text(pCtx, pSlot->z, pSlot->n, SQLITE_TRANSIENT);
|
||||
assert( pSlot->n <= 0x7fffffff );
|
||||
sqlite3_result_text(pCtx, pSlot->z, (int)pSlot->n, SQLITE_TRANSIENT);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1623,10 +1625,10 @@ static void idxRemFunc(
|
||||
|
||||
case SQLITE_BLOB:
|
||||
case SQLITE_TEXT: {
|
||||
int nByte = sqlite3_value_bytes(argv[1]);
|
||||
i64 nByte = sqlite3_value_bytes(argv[1]);
|
||||
const void *pData = 0;
|
||||
if( nByte>pSlot->nByte ){
|
||||
char *zNew = (char*)sqlite3_realloc(pSlot->z, nByte*2);
|
||||
char *zNew = (char*)sqlite3_realloc64(pSlot->z, nByte*2);
|
||||
if( zNew==0 ){
|
||||
sqlite3_result_error_nomem(pCtx);
|
||||
return;
|
||||
@@ -1681,7 +1683,7 @@ static int idxPopulateOneStat1(
|
||||
int nCol = 0;
|
||||
int i;
|
||||
sqlite3_stmt *pQuery = 0;
|
||||
int *aStat = 0;
|
||||
i64 *aStat = 0;
|
||||
int rc = SQLITE_OK;
|
||||
|
||||
assert( p->iSample>0 );
|
||||
@@ -1727,7 +1729,7 @@ static int idxPopulateOneStat1(
|
||||
sqlite3_free(zQuery);
|
||||
|
||||
if( rc==SQLITE_OK ){
|
||||
aStat = (int*)idxMalloc(&rc, sizeof(int)*(nCol+1));
|
||||
aStat = (i64*)idxMalloc(&rc, sizeof(i64)*(nCol+1));
|
||||
}
|
||||
if( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pQuery) ){
|
||||
IdxHashEntry *pEntry;
|
||||
@@ -1744,11 +1746,11 @@ static int idxPopulateOneStat1(
|
||||
}
|
||||
|
||||
if( rc==SQLITE_OK ){
|
||||
int s0 = aStat[0];
|
||||
zStat = sqlite3_mprintf("%d", s0);
|
||||
i64 s0 = aStat[0];
|
||||
zStat = sqlite3_mprintf("%lld", s0);
|
||||
if( zStat==0 ) rc = SQLITE_NOMEM;
|
||||
for(i=1; rc==SQLITE_OK && i<=nCol; i++){
|
||||
zStat = idxAppendText(&rc, zStat, " %d", (s0+aStat[i]/2) / aStat[i]);
|
||||
zStat = idxAppendText(&rc, zStat, " %lld", (s0+aStat[i]/2) / aStat[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1827,7 +1829,7 @@ static int idxPopulateStat1(sqlite3expert *p, char **pzErr){
|
||||
rc = sqlite3_exec(p->dbm, "ANALYZE; PRAGMA writable_schema=1", 0, 0, 0);
|
||||
|
||||
if( rc==SQLITE_OK ){
|
||||
int nByte = sizeof(struct IdxRemCtx) + (sizeof(struct IdxRemSlot) * nMax);
|
||||
i64 nByte = sizeof(struct IdxRemCtx) + (sizeof(struct IdxRemSlot) * nMax);
|
||||
pCtx = (struct IdxRemCtx*)idxMalloc(&rc, nByte);
|
||||
}
|
||||
|
||||
@@ -1844,7 +1846,7 @@ static int idxPopulateStat1(sqlite3expert *p, char **pzErr){
|
||||
}
|
||||
|
||||
if( rc==SQLITE_OK ){
|
||||
pCtx->nSlot = nMax+1;
|
||||
pCtx->nSlot = (i64)nMax+1;
|
||||
rc = idxPrepareStmt(p->dbm, &pAllIndex, pzErr, zAllIndex);
|
||||
}
|
||||
if( rc==SQLITE_OK ){
|
||||
@@ -2111,7 +2113,7 @@ int sqlite3_expert_sql(
|
||||
if( pStmt ){
|
||||
IdxStatement *pNew;
|
||||
const char *z = sqlite3_sql(pStmt);
|
||||
int n = STRLEN(z);
|
||||
i64 n = STRLEN(z);
|
||||
pNew = (IdxStatement*)idxMalloc(&rc, sizeof(IdxStatement) + n+1);
|
||||
if( rc==SQLITE_OK ){
|
||||
pNew->zSql = (char*)&pNew[1];
|
||||
|
||||
@@ -877,9 +877,9 @@ static Fts5Data *fts5DataRead(Fts5Index *p, i64 iRowid){
|
||||
|
||||
if( rc==SQLITE_OK ){
|
||||
u8 *aOut = 0; /* Read blob data into this buffer */
|
||||
int nByte = sqlite3_blob_bytes(p->pReader);
|
||||
int szData = (sizeof(Fts5Data) + 7) & ~7;
|
||||
sqlite3_int64 nAlloc = szData + nByte + FTS5_DATA_PADDING;
|
||||
i64 nByte = sqlite3_blob_bytes(p->pReader);
|
||||
i64 szData = (sizeof(Fts5Data) + 7) & ~7;
|
||||
i64 nAlloc = szData + nByte + FTS5_DATA_PADDING;
|
||||
pRet = (Fts5Data*)sqlite3_malloc64(nAlloc);
|
||||
if( pRet ){
|
||||
pRet->nn = nByte;
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
# 2025 October 13
|
||||
#
|
||||
# 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 test is focused on really large position lists. Those that require
|
||||
# 4 or 5 byte position-list size varints. Because of the amount of memory
|
||||
# required, these tests only run on 64-bit platforms.
|
||||
#
|
||||
|
||||
source [file join [file dirname [info script]] fts5_common.tcl]
|
||||
set testprefix fts5corruptbig
|
||||
|
||||
# If SQLITE_ENABLE_FTS5 is not defined, omit this file.
|
||||
ifcapable !fts5 {
|
||||
finish_test
|
||||
return
|
||||
}
|
||||
|
||||
if { $tcl_platform(wordSize)<8 } {
|
||||
finish_test
|
||||
return
|
||||
}
|
||||
|
||||
if { $SQLITE_MAX_LENGTH!=0x7FFFFFFF } {
|
||||
finish_test
|
||||
return
|
||||
}
|
||||
|
||||
do_execsql_test 1.0 {
|
||||
CREATE VIRTUAL TABLE t1 USING fts5(x);
|
||||
}
|
||||
|
||||
do_execsql_test 1.1 {
|
||||
UPDATE t1_data SET block = zeroblob(2147483640) WHERE id=10;
|
||||
}
|
||||
|
||||
do_execsql_test 1.2 {
|
||||
SELECT id, length(block) FROM t1_data
|
||||
} {1 0 10 2147483640}
|
||||
|
||||
do_catchsql_test 1.3 {
|
||||
SELECT * FROM t1('abc')
|
||||
} {1 {out of memory}}
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -160,6 +160,7 @@ static char *intckMprintf(sqlite3_intck *p, const char *zFmt, ...){
|
||||
sqlite3_free(zRet);
|
||||
zRet = 0;
|
||||
}
|
||||
va_end(ap);
|
||||
return zRet;
|
||||
}
|
||||
|
||||
|
||||
+19
-16
@@ -13,11 +13,14 @@ Technical support is available in the forum:
|
||||
<https://sqlite.org/forum>
|
||||
|
||||
|
||||
> **FOREWARNING:** this subproject is very much in development and
|
||||
subject to any number of changes. Please do not rely on any
|
||||
information about its API until this disclaimer is removed. The JNI
|
||||
bindings released with version 3.43 are a "tech preview." Once
|
||||
finalized, strong backward compatibility guarantees will apply.
|
||||
> **FOREWARNING:** the JNI subproject is experimental and subject to
|
||||
any number of changes. This API is "feature-complete", with only a
|
||||
few difficult-to-reach corners of the C API not represented here,
|
||||
but it is not a supported deliverable of the project so does not
|
||||
have same backward compatibility guarantees which the C APIs
|
||||
do. That said: the [C-style API](#1to1ish) is especially resistent
|
||||
to compatibility breakage because it's designed to be as close to
|
||||
the C API as feasible.
|
||||
|
||||
Project goals/requirements:
|
||||
|
||||
@@ -162,11 +165,13 @@ or propagate exceptions and must return error information (if any) via
|
||||
result codes or `null`. The only cases where the C-style APIs may
|
||||
throw is through client-side misuse, e.g. passing in a null where it
|
||||
may cause a `NullPointerException`. The APIs clearly mark function
|
||||
parameters which should not be null, but does not generally actively
|
||||
defend itself against such misuse. Some C-style APIs explicitly accept
|
||||
`null` as a no-op for usability's sake, and some of the JNI APIs
|
||||
deliberately return an error code, instead of segfaulting, when passed
|
||||
a `null`.
|
||||
parameters which should not be null, and it internally uses the
|
||||
`SQLITE_API_ARMOR` mechanism to help product against such misuse. Some
|
||||
C-style APIs explicitly accept `null` as a no-op for usability's sake,
|
||||
and some of the JNI APIs deliberately return an error code, instead of
|
||||
segfaulting, when passed a `null`. There are no known cases where it
|
||||
will misuse memory if passed a `null` or out-of-range value from
|
||||
client code.
|
||||
|
||||
Client-defined callbacks _must never throw exceptions_ unless _very
|
||||
explicitly documented_ as being throw-safe. Exceptions are generally
|
||||
@@ -194,7 +199,8 @@ Some constructs, when modelled 1-to-1 from C to Java, are unduly
|
||||
clumsy to work with in Java because they try to shoehorn C's way of
|
||||
doing certain things into Java's wildly different ways. The following
|
||||
subsections cover those, starting with a verbose explanation and
|
||||
demonstration of where such changes are "really necessary"...
|
||||
demonstration of where such changes are "really necessary" for
|
||||
usability's sake...
|
||||
|
||||
### Custom Collations
|
||||
|
||||
@@ -286,12 +292,9 @@ binding. The Java API has only one core function-registration function:
|
||||
|
||||
```java
|
||||
int sqlite3_create_function(sqlite3 db, String funcName, int nArgs,
|
||||
int encoding, SQLFunction func);
|
||||
int flags, SQLFunction func);
|
||||
```
|
||||
|
||||
> Design question: does the encoding argument serve any purpose in
|
||||
Java? That's as-yet undetermined. If not, it will be removed.
|
||||
|
||||
`SQLFunction` is not used directly, but is instead instantiated via
|
||||
one of its three subclasses:
|
||||
|
||||
@@ -313,4 +316,4 @@ in-flux nature of this API.
|
||||
Various APIs which accept callbacks, e.g. `sqlite3_trace_v2()` and
|
||||
`sqlite3_update_hook()`, use interfaces similar to those shown above.
|
||||
Despite the changes in signature, the JNI layer makes every effort to
|
||||
provide the same semantics as the C API documentation suggests.
|
||||
provide the same semantics as the C API documentation describes.
|
||||
|
||||
@@ -245,8 +245,10 @@ extern "C" {
|
||||
#define org_sqlite_jni_capi_CApi_SQLITE_DBSTATUS_CACHE_USED_SHARED 11L
|
||||
#undef org_sqlite_jni_capi_CApi_SQLITE_DBSTATUS_CACHE_SPILL
|
||||
#define org_sqlite_jni_capi_CApi_SQLITE_DBSTATUS_CACHE_SPILL 12L
|
||||
#undef org_sqlite_jni_capi_CApi_SQLITE_DBSTATUS_TEMPBUF_SPILL
|
||||
#define org_sqlite_jni_capi_CApi_SQLITE_DBSTATUS_TEMPBUF_SPILL 13L
|
||||
#undef org_sqlite_jni_capi_CApi_SQLITE_DBSTATUS_MAX
|
||||
#define org_sqlite_jni_capi_CApi_SQLITE_DBSTATUS_MAX 12L
|
||||
#define org_sqlite_jni_capi_CApi_SQLITE_DBSTATUS_MAX 13L
|
||||
#undef org_sqlite_jni_capi_CApi_SQLITE_UTF8
|
||||
#define org_sqlite_jni_capi_CApi_SQLITE_UTF8 1L
|
||||
#undef org_sqlite_jni_capi_CApi_SQLITE_UTF16LE
|
||||
|
||||
@@ -115,8 +115,9 @@ public final class CApi {
|
||||
JNIEnv is not cached, else returns true, but this information is
|
||||
primarily for testing of the JNI bindings and is not information
|
||||
which client-level code can use to make any informed
|
||||
decisions. Its return type and semantics are not considered
|
||||
stable and may change at any time.
|
||||
decisions. The semantics of its return type and value are not
|
||||
considered stable and may change at any time. i.e. act as if it
|
||||
returns null.
|
||||
*/
|
||||
public static native boolean sqlite3_java_uncache_thread();
|
||||
|
||||
@@ -2585,7 +2586,8 @@ public final class CApi {
|
||||
public static final int SQLITE_DBSTATUS_DEFERRED_FKS = 10;
|
||||
public static final int SQLITE_DBSTATUS_CACHE_USED_SHARED = 11;
|
||||
public static final int SQLITE_DBSTATUS_CACHE_SPILL = 12;
|
||||
public static final int SQLITE_DBSTATUS_MAX = 12;
|
||||
public static final int SQLITE_DBSTATUS_TEMPBUF_SPILL = 13;
|
||||
public static final int SQLITE_DBSTATUS_MAX = 13;
|
||||
|
||||
// encodings
|
||||
public static final int SQLITE_UTF8 = 1;
|
||||
|
||||
@@ -171,6 +171,7 @@ public final class Sqlite implements AutoCloseable {
|
||||
public static final int DBSTATUS_DEFERRED_FKS = CApi.SQLITE_DBSTATUS_DEFERRED_FKS;
|
||||
public static final int DBSTATUS_CACHE_USED_SHARED = CApi.SQLITE_DBSTATUS_CACHE_USED_SHARED;
|
||||
public static final int DBSTATUS_CACHE_SPILL = CApi.SQLITE_DBSTATUS_CACHE_SPILL;
|
||||
public static final int DBSTATUS_TEMPBUF_SPILL = CApi.SQLITE_DBSTATUS_TEMPBUF_SPILL;
|
||||
|
||||
// Limits
|
||||
public static final int LIMIT_LENGTH = CApi.SQLITE_LIMIT_LENGTH;
|
||||
|
||||
+5
-5
@@ -514,7 +514,7 @@ struct amatch_cursor {
|
||||
sqlite3_int64 iRowid; /* The rowid of the current word */
|
||||
amatch_langid iLang; /* Use this language ID */
|
||||
amatch_cost rLimit; /* Maximum cost of any term */
|
||||
int nBuf; /* Space allocated for zBuf */
|
||||
sqlite3_int64 nBuf; /* Space allocated for zBuf */
|
||||
int oomErr; /* True following an OOM error */
|
||||
int nWord; /* Number of amatch_word objects */
|
||||
char *zBuf; /* Temp-use buffer space */
|
||||
@@ -1039,7 +1039,7 @@ static void amatchAddWord(
|
||||
nTail = (int)strlen(zWordTail);
|
||||
if( nBase+nTail+3>pCur->nBuf ){
|
||||
pCur->nBuf = nBase+nTail+100;
|
||||
pCur->zBuf = sqlite3_realloc(pCur->zBuf, pCur->nBuf);
|
||||
pCur->zBuf = sqlite3_realloc64(pCur->zBuf, pCur->nBuf);
|
||||
if( pCur->zBuf==0 ){
|
||||
pCur->nBuf = 0;
|
||||
return;
|
||||
@@ -1105,13 +1105,13 @@ static int amatchNext(sqlite3_vtab_cursor *cur){
|
||||
amatch_avl *pNode;
|
||||
int isMatch = 0;
|
||||
amatch_vtab *p = pCur->pVtab;
|
||||
int nWord;
|
||||
sqlite3_int64 nWord;
|
||||
int rc;
|
||||
int i;
|
||||
const char *zW;
|
||||
amatch_rule *pRule;
|
||||
char *zBuf = 0;
|
||||
char nBuf = 0;
|
||||
sqlite3_int64 nBuf = 0;
|
||||
char zNext[8];
|
||||
char zNextIn[8];
|
||||
int nNextIn;
|
||||
@@ -1158,7 +1158,7 @@ static int amatchNext(sqlite3_vtab_cursor *cur){
|
||||
nWord = (int)strlen(pWord->zWord+2);
|
||||
if( nWord+20>nBuf ){
|
||||
nBuf = (char)(nWord+100);
|
||||
zBuf = sqlite3_realloc(zBuf, nBuf);
|
||||
zBuf = sqlite3_realloc64(zBuf, nBuf);
|
||||
if( zBuf==0 ) return SQLITE_NOMEM;
|
||||
}
|
||||
amatchStrcpy(zBuf, pWord->zWord+2);
|
||||
|
||||
+8
-5
@@ -128,7 +128,8 @@ static Decimal *decimalNewFromText(const char *zIn, int n){
|
||||
}
|
||||
}
|
||||
if( iExp>0 ){
|
||||
p->a = sqlite3_realloc64(p->a, p->nDigit + iExp + 1 );
|
||||
p->a = sqlite3_realloc64(p->a, (sqlite3_int64)p->nDigit
|
||||
+ (sqlite3_int64)iExp + 1 );
|
||||
if( p->a==0 ) goto new_from_text_failed;
|
||||
memset(p->a+p->nDigit, 0, iExp);
|
||||
p->nDigit += iExp;
|
||||
@@ -147,7 +148,8 @@ static Decimal *decimalNewFromText(const char *zIn, int n){
|
||||
}
|
||||
}
|
||||
if( iExp>0 ){
|
||||
p->a = sqlite3_realloc64(p->a, p->nDigit + iExp + 1 );
|
||||
p->a = sqlite3_realloc64(p->a, (sqlite3_int64)p->nDigit
|
||||
+ (sqlite3_int64)iExp + 1 );
|
||||
if( p->a==0 ) goto new_from_text_failed;
|
||||
memmove(p->a+iExp, p->a, p->nDigit);
|
||||
memset(p->a, 0, iExp);
|
||||
@@ -251,7 +253,7 @@ static void decimal_result(sqlite3_context *pCtx, Decimal *p){
|
||||
sqlite3_result_null(pCtx);
|
||||
return;
|
||||
}
|
||||
z = sqlite3_malloc( p->nDigit+4 );
|
||||
z = sqlite3_malloc64( (sqlite3_int64)p->nDigit+4 );
|
||||
if( z==0 ){
|
||||
sqlite3_result_error_nomem(pCtx);
|
||||
return;
|
||||
@@ -316,7 +318,7 @@ static void decimal_result_sci(sqlite3_context *pCtx, Decimal *p){
|
||||
for(nZero=0; nZero<nDigit && p->a[nZero]==0; nZero++){}
|
||||
nFrac = p->nFrac + (nDigit - p->nDigit);
|
||||
nDigit -= nZero;
|
||||
z = sqlite3_malloc( nDigit+20 );
|
||||
z = sqlite3_malloc64( (sqlite3_int64)nDigit+20 );
|
||||
if( z==0 ){
|
||||
sqlite3_result_error_nomem(pCtx);
|
||||
return;
|
||||
@@ -537,7 +539,8 @@ static void decimalMul(Decimal *pA, Decimal *pB){
|
||||
){
|
||||
goto mul_end;
|
||||
}
|
||||
acc = sqlite3_malloc64( pA->nDigit + pB->nDigit + 2 );
|
||||
acc = sqlite3_malloc64( (sqlite3_int64)pA->nDigit +
|
||||
(sqlite3_int64)pB->nDigit + 2 );
|
||||
if( acc==0 ){
|
||||
pA->oom = 1;
|
||||
goto mul_end;
|
||||
|
||||
+1
-9
@@ -760,7 +760,7 @@ static int fsdirNext(sqlite3_vtab_cursor *cur){
|
||||
pCur->zPath = 0;
|
||||
pLvl->pDir = opendir(pLvl->zDir);
|
||||
if( pLvl->pDir==0 ){
|
||||
fsdirSetErrmsg(pCur, "cannot read directory: %s", pCur->zPath);
|
||||
fsdirSetErrmsg(pCur, "cannot read directory: %s", pLvl->zDir);
|
||||
return SQLITE_ERROR;
|
||||
}
|
||||
}
|
||||
@@ -1122,11 +1122,3 @@ int sqlite3_fileio_init(
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
#if defined(FILEIO_WIN32_DLL) && (defined(_WIN32) || defined(WIN32))
|
||||
/* To allow a standalone DLL, make test_windirent.c use the same
|
||||
* redefined SQLite API calls as the above extension code does.
|
||||
* Just pull in this .c to accomplish this. As a beneficial side
|
||||
* effect, this extension becomes a single translation unit. */
|
||||
# include "test_windirent.c"
|
||||
#endif
|
||||
|
||||
@@ -297,8 +297,9 @@ static const unsigned char sqlite3CtypeMap[256] = {
|
||||
** Return the length (in bytes) of the token that begins at z[0].
|
||||
** Store the token type in *tokenType before returning.
|
||||
*/
|
||||
static int sqlite3GetToken(const unsigned char *z, int *tokenType){
|
||||
int i, c;
|
||||
static sqlite3_int64 sqlite3GetToken(const unsigned char *z, int *tokenType){
|
||||
sqlite3_int64 i;
|
||||
int c;
|
||||
switch( aiClass[*z] ){ /* Switch on the character-class of the first byte
|
||||
** of the token. See the comment on the CC_ defines
|
||||
** above. */
|
||||
@@ -559,7 +560,7 @@ char *sqlite3_normalize(const char *zSql){
|
||||
int i; /* Next character to read from zSql[] */
|
||||
int j; /* Next slot to fill in on z[] */
|
||||
int tokenType; /* Type of the next token */
|
||||
int n; /* Size of the next token */
|
||||
sqlite3_int64 n; /* Size of the next token */
|
||||
int k; /* Loop counter */
|
||||
|
||||
nSql = strlen(zSql);
|
||||
|
||||
+10
-1
@@ -650,6 +650,15 @@ static void re_free(ReCompiled *pRe){
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Version of re_free() that accepts a pointer of type (void*). Required
|
||||
** to satisfy sanitizers when the re_free() function is called via a
|
||||
** function pointer.
|
||||
*/
|
||||
static void re_free_voidptr(void *p){
|
||||
re_free((ReCompiled*)p);
|
||||
}
|
||||
|
||||
/*
|
||||
** Compile a textual regular expression in zIn[] into a compiled regular
|
||||
** expression suitable for us by re_match() and return a pointer to the
|
||||
@@ -781,7 +790,7 @@ static void re_sql_func(
|
||||
sqlite3_result_int(context, re_match(pRe, zStr, -1));
|
||||
}
|
||||
if( setAux ){
|
||||
sqlite3_set_auxdata(context, 0, pRe, (void(*)(void*))re_free);
|
||||
sqlite3_set_auxdata(context, 0, pRe, re_free_voidptr);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-2
@@ -642,7 +642,6 @@ static int seriesFilter(
|
||||
/* Apply LIMIT and OFFSET constraints, if any */
|
||||
assert( pCur->iStep!=0 );
|
||||
if( idxNum & 0x20 ){
|
||||
sqlite3_uint64 nStep;
|
||||
if( iOffset>0 ){
|
||||
if( seriesSteps(pCur) < (sqlite3_uint64)iOffset ){
|
||||
goto series_no_rows;
|
||||
@@ -652,7 +651,7 @@ static int seriesFilter(
|
||||
pCur->iBase = add64(pCur->iBase, pCur->iStep*iOffset);
|
||||
}
|
||||
}
|
||||
if( iLimit>=0 && (nStep = seriesSteps(pCur)) > (sqlite3_uint64)iLimit ){
|
||||
if( iLimit>=0 && seriesSteps(pCur) > (sqlite3_uint64)iLimit ){
|
||||
pCur->iTerm = add64(pCur->iBase, (iLimit - 1)*pCur->iStep);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -206,6 +206,10 @@ static int vtablogConnectCreate(
|
||||
}
|
||||
if( zSchema==0 ){
|
||||
zSchema = sqlite3_mprintf("%s","CREATE TABLE x(a,b);");
|
||||
if( zSchema==0 ){
|
||||
rc = SQLITE_NOMEM;
|
||||
goto vtablog_end_connect;
|
||||
}
|
||||
}
|
||||
printf(" schema = '%s'\n", zSchema);
|
||||
rc = sqlite3_declare_vtab(db, zSchema);
|
||||
|
||||
+1
-1
@@ -62,7 +62,7 @@
|
||||
#else
|
||||
#include "sqlite3.h"
|
||||
#endif
|
||||
int sqlite3GetToken(const unsigned char*,int*); /* In the SQLite core */
|
||||
sqlite3_int64 sqlite3GetToken(const unsigned char*,int*); /* In SQLite core */
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
_fiddle_db_arg
|
||||
_fiddle_db_filename
|
||||
_fiddle_exec
|
||||
_fiddle_experiment
|
||||
_fiddle_interrupt
|
||||
_fiddle_main
|
||||
_fiddle_reset_db
|
||||
_fiddle_db_handle
|
||||
_fiddle_db_vfs
|
||||
_fiddle_export_db
|
||||
+44
-58
@@ -227,7 +227,7 @@ endef
|
||||
# Args: as for $(b.c-pp.shcmd).
|
||||
define b.c-pp.target
|
||||
$(3): $$(MAKEFILE_LIST) $$(bin.c-pp) $(2)
|
||||
@$$(call b.c-pp.shcmd,$(1),$(2),$(3),$(4))
|
||||
@$$(call b.c-pp.shcmd,$(1),$(2),$(3),$(4) $(b.c-pp.target.flags))
|
||||
CLEAN_FILES += $(3)
|
||||
endef
|
||||
|
||||
@@ -249,37 +249,7 @@ c-pp.D.64bit = -Dbits64
|
||||
# This is intended to be used in makefile targets which generate an
|
||||
# Emscripten module and where $@ is the module's .js/.mjs file.
|
||||
b.strip-js-emcc-bindings = \
|
||||
sed -i -e '/^.*= \(_sqlite3\|_fiddle\)[^=]*=.*createExportWrapper/d' \
|
||||
-e '/^var \(_sqlite3\|_fiddle\)[^=]*=.*makeInvalidEarlyAccess/d' $@ || exit; \
|
||||
echo '$(1) $(emo.garbage) (Probably) /createExportWrapper()/d and /makeInvalidEarlyAccess()/d'
|
||||
|
||||
|
||||
#
|
||||
# bin.version-info = binary to output various sqlite3 version info for
|
||||
# embedding in the JS files and in building the distribution zip file.
|
||||
# It must NOT be in $(dir.tmp) because we need it to survive the
|
||||
# cleanup process for the dist build to work properly.
|
||||
#
|
||||
# Slight caveat: this uses the version info from the in-tree
|
||||
# sqlite3.c/h, which may diff from a user-provided $(sqlite3.c). The
|
||||
# end result is that the generated JS files may have static version
|
||||
# info from $(bin.version-info) which differ from their runtime-emitted
|
||||
# version info (e.g. from sqlite3_libversion()).
|
||||
bin.version-info = $(dir.top)/version-info
|
||||
$(bin.version-info): $(dir.tool)/version-info.c $(sqlite3.h) $(dir.top)/Makefile
|
||||
$(MAKE) -C $(dir.top) version-info
|
||||
t-version-info: $(bin.version-info)
|
||||
#
|
||||
# bin.stripcomments is used for stripping C/C++-style comments from JS
|
||||
# files. The JS files contain large chunks of documentation which we
|
||||
# don't need for all builds. That app's -k flag is of particular
|
||||
# importance here, as it allows us to retain the opening comment
|
||||
# block(s), which contain the license header and version info.
|
||||
bin.stripccomments = $(dir.tool)/stripccomments
|
||||
$(bin.stripccomments): $(bin.stripccomments).c $(MAKEFILE)
|
||||
$(CC) -o $@ $<
|
||||
t-stripccomments: $(bin.stripccomments)
|
||||
DISTCLEAN_FILES += $(bin.stripccomments)
|
||||
echo '$(1) $(emo.bug) (disabled because it breaks emsdk 4.0.16+)'
|
||||
|
||||
|
||||
#
|
||||
@@ -301,7 +271,30 @@ DISTCLEAN_FILES += $(bin.stripccomments)
|
||||
# is required for certain utility and test code.
|
||||
sqlite3.canonical.c = $(dir.top)/sqlite3.c
|
||||
sqlite3.c ?= $(firstword $(wildcard $(dir.top)/sqlite3-see.c) $(sqlite3.canonical.c))
|
||||
sqlite3.h = $(dir.top)/sqlite3.h
|
||||
sqlite3.h = $(dir $(sqlite3.c))/sqlite3.h
|
||||
|
||||
#
|
||||
# bin.version-info = binary to output various sqlite3 version info for
|
||||
# embedding in the JS files and in building the distribution zip file.
|
||||
# It must NOT be in $(dir.tmp) because we need it to survive the
|
||||
# cleanup process for the dist build to work properly.
|
||||
bin.version-info = ./version-info
|
||||
$(bin.version-info): $(dir.tool)/version-info.c $(sqlite3.h) $(dir.top)/Makefile
|
||||
$(CC) -o $@ -I$(dir $(sqlite3.h)) $(dir.tool)/version-info.c
|
||||
t-version-info: $(bin.version-info)
|
||||
DISTCLEAN_FILES += $(bin.version-info)
|
||||
#
|
||||
# bin.stripcomments is used for stripping C/C++-style comments from JS
|
||||
# files. The JS files contain large chunks of documentation which we
|
||||
# don't need for all builds. That app's -k flag is of particular
|
||||
# importance here, as it allows us to retain the opening comment
|
||||
# block(s), which contain the license header and version info.
|
||||
bin.stripccomments = $(dir.tool)/stripccomments
|
||||
$(bin.stripccomments): $(bin.stripccomments).c $(MAKEFILE)
|
||||
$(CC) -o $@ $<
|
||||
t-stripccomments: $(bin.stripccomments)
|
||||
DISTCLEAN_FILES += $(bin.stripccomments)
|
||||
|
||||
|
||||
ifeq (1,$(MAKING_CLEAN))
|
||||
SQLITE_C_IS_SEE = 0
|
||||
@@ -314,7 +307,6 @@ else
|
||||
endif
|
||||
endif
|
||||
|
||||
|
||||
#
|
||||
# barebones=1 disables all "extraneous" stuff from sqlite3-wasm.c, the
|
||||
# goal being to create a WASM file with only the core APIs.
|
||||
@@ -594,18 +586,16 @@ emcc_opt_full = $(emcc_opt) -g3
|
||||
########################################################################
|
||||
# EXPORTED_FUNCTIONS.* = files for use with Emscripten's
|
||||
# -sEXPORTED_FUNCTION flag.
|
||||
EXPORTED_FUNCTIONS.api.core = $(dir.api)/EXPORTED_FUNCTIONS.sqlite3-core
|
||||
EXPORTED_FUNCTIONS.api.in = $(EXPORTED_FUNCTIONS.api.core)
|
||||
ifeq (1,$(SQLITE_C_IS_SEE))
|
||||
EXPORTED_FUNCTIONS.api.in += $(dir.api)/EXPORTED_FUNCTIONS.sqlite3-see
|
||||
endif
|
||||
ifeq (0,$(wasm-bare-bones))
|
||||
EXPORTED_FUNCTIONS.api.in += $(dir.api)/EXPORTED_FUNCTIONS.sqlite3-extras
|
||||
endif
|
||||
EXPORTED_FUNCTIONS.api.in = $(dir.api)/EXPORTED_FUNCTIONS.c-pp
|
||||
EXPORTED_FUNCTIONS.api = $(dir.tmp)/EXPORTED_FUNCTIONS.api
|
||||
$(EXPORTED_FUNCTIONS.api): $(EXPORTED_FUNCTIONS.api.in) $(sqlite3.c) $(MAKEFILE)
|
||||
@$(call b.mkdir@)
|
||||
cat $(EXPORTED_FUNCTIONS.api.in) > $@
|
||||
EXPORTED_FUNCTIONS.c-pp.flags =
|
||||
ifeq (1,$(wasm-bare-bones))
|
||||
EXPORTED_FUNCTIONS.c-pp.flags += -Dbare-bones
|
||||
endif
|
||||
$(eval $(call b.c-pp.target,filter,\
|
||||
$(EXPORTED_FUNCTIONS.api.in),\
|
||||
$(EXPORTED_FUNCTIONS.api),\
|
||||
$(EXPORTED_FUNCTIONS.c-pp.flags)))
|
||||
|
||||
########################################################################
|
||||
# emcc flags for .c/.o/.wasm/.js.
|
||||
@@ -859,8 +849,8 @@ sqlite3-api.jses += $(dir.api)/sqlite3-api-cleanup.js
|
||||
sqlite3-license-version.js = $(dir.tmp)/sqlite3-license-version.js
|
||||
$(sqlite3-license-version.js): $(bin.version-info) \
|
||||
$(dir.api)/sqlite3-license-version-header.js
|
||||
@echo '$(logtag.@) $(emo.disk)'; { \
|
||||
$(call b.mkdir@); \
|
||||
@echo '$(logtag.@) $(emo.disk)'; \
|
||||
$(call b.mkdir@); { \
|
||||
cat $(dir.api)/sqlite3-license-version-header.js || exit $$?; \
|
||||
echo '/*'; \
|
||||
echo '** This code was built from sqlite3 version...'; \
|
||||
@@ -964,9 +954,10 @@ endif
|
||||
########################################################################
|
||||
|
||||
EXPORTED_FUNCTIONS.fiddle = $(dir.tmp)/EXPORTED_FUNCTIONS.fiddle
|
||||
$(EXPORTED_FUNCTIONS.fiddle): $(fiddle.EXPORTED_FUNCTIONS.in) $(MAKEFILE_LIST)
|
||||
@$(b.call.mkdir@)
|
||||
@sort -u $(fiddle.EXPORTED_FUNCTIONS.in) > $@
|
||||
$(EXPORTED_FUNCTIONS.fiddle): $(EXPORTED_FUNCTIONS.api.in) $(MAKEFILE_LIST)
|
||||
@$(b.mkdir@)
|
||||
@$(call b.c-pp.shcmd,filter,$(EXPORTED_FUNCTIONS.api.in),\
|
||||
$@,$(EXPORTED_FUNCTIONS.c-pp.flags) -Dfiddle)
|
||||
@echo $(logtag.@) $(emo.disk)
|
||||
|
||||
emcc.flags.fiddle = \
|
||||
@@ -999,7 +990,7 @@ clean-fiddle:
|
||||
$(dir.fiddle)/*.wasm \
|
||||
$(dir.fiddle)/sqlite3-opfs-*.js \
|
||||
$(dir.fiddle)/*.gz \
|
||||
EXPORTED_FUNCTIONS.fiddle
|
||||
$(EXPORTED_FUNCTIONS.fiddle)
|
||||
rm -fr $(dir.fiddle-debug)
|
||||
|
||||
emcc.flags.fiddle.debug = $(emcc.flags.fiddle) \
|
||||
@@ -1007,11 +998,6 @@ emcc.flags.fiddle.debug = $(emcc.flags.fiddle) \
|
||||
-DSQLITE_ENABLE_SELECTTRACE \
|
||||
-DSQLITE_ENABLE_WHERETRACE
|
||||
|
||||
fiddle.EXPORTED_FUNCTIONS.in = \
|
||||
EXPORTED_FUNCTIONS.fiddle.in \
|
||||
$(dir.api)/EXPORTED_FUNCTIONS.sqlite3-core \
|
||||
$(dir.api)/EXPORTED_FUNCTIONS.sqlite3-extras
|
||||
|
||||
fiddle.c.in = $(dir.top)/shell.c $(sqlite3-wasm.c)
|
||||
|
||||
#
|
||||
@@ -1205,10 +1191,10 @@ speedtest1.exit-runtime1 = -sEXIT_RUNTIME=1
|
||||
# -sEXIT_RUNTIME=1 but we need EXIT_RUNTIME=0 for the worker-based app
|
||||
# which runs speedtest1 multiple times.
|
||||
|
||||
$(EXPORTED_FUNCTIONS.speedtest1): $(EXPORTED_FUNCTIONS.api.core)
|
||||
$(EXPORTED_FUNCTIONS.speedtest1): $(EXPORTED_FUNCTIONS.api)
|
||||
@$(call b.echo,@,$(emo.disk)); \
|
||||
$(call b.mkdir@); \
|
||||
{ echo _wasm_main; cat $(EXPORTED_FUNCTIONS.api.core); } > $@ || exit
|
||||
{ echo _wasm_main; cat $(EXPORTED_FUNCTIONS.api); } > $@ || exit
|
||||
speedtest1: b-speedtest1
|
||||
|
||||
#
|
||||
|
||||
+20
-2
@@ -1,8 +1,9 @@
|
||||
This directory houses the [Web Assembly (WASM)](https://en.wikipedia.org/wiki/WebAssembly)
|
||||
parts of the sqlite3 build.
|
||||
|
||||
It requires [emscripten][] and that the build environment be set up for
|
||||
emscripten. A mini-HOWTO for setting that up follows...
|
||||
It requires [emscripten][] and that the build environment be set up
|
||||
for emscripten. _Release_ builds also require [the wabt tools](#wabt),
|
||||
but dev builds do not. A mini-HOWTO for setting that up follows...
|
||||
|
||||
First, install the Emscripten SDK, as documented
|
||||
[here](https://emscripten.org/docs/getting_started/downloads.html) and summarized
|
||||
@@ -125,6 +126,23 @@ connection). Since the web-server is on a different machine from the
|
||||
web-broser, the localhost requirement means that the connection must
|
||||
be tunneled using SSH.
|
||||
|
||||
<a id="wabt"></a>
|
||||
# The wabt Tools
|
||||
|
||||
_Release_ builds require the wabt tools:
|
||||
|
||||
<https://github.com/WebAssembly/wabt>
|
||||
|
||||
Specifically, we need `wasm-strip` so that the resulting WASM file is not
|
||||
several megabytes.
|
||||
|
||||
Pre-built binaries can be downloaded from:
|
||||
|
||||
<https://github.com/WebAssembly/wabt/releases>
|
||||
|
||||
As of 2025-10-14, versions 1.36.0 or higher are known to work and
|
||||
1.34.0 is known to not work with current Emscripten output.
|
||||
|
||||
|
||||
[emscripten]: https://emscripten.org
|
||||
[althttpd]: https://sqlite.org/althttpd
|
||||
|
||||
@@ -47,6 +47,7 @@ _sqlite3_db_handle
|
||||
_sqlite3_db_name
|
||||
_sqlite3_db_readonly
|
||||
_sqlite3_db_status
|
||||
_sqlite3_db_status64
|
||||
_sqlite3_deserialize
|
||||
_sqlite3_errcode
|
||||
_sqlite3_errmsg
|
||||
@@ -154,3 +155,92 @@ _sqlite3_vtab_in_next
|
||||
_sqlite3_vtab_nochange
|
||||
_sqlite3_vtab_on_conflict
|
||||
_sqlite3_vtab_rhs_value
|
||||
//#if not bare-bones
|
||||
_sqlite3_column_database_name
|
||||
_sqlite3_column_origin_name
|
||||
_sqlite3_column_table_name
|
||||
_sqlite3_create_module
|
||||
_sqlite3_create_module_v2
|
||||
_sqlite3_create_window_function
|
||||
_sqlite3_declare_vtab
|
||||
_sqlite3_drop_modules
|
||||
_sqlite3_preupdate_blobwrite
|
||||
_sqlite3_preupdate_count
|
||||
_sqlite3_preupdate_depth
|
||||
_sqlite3_preupdate_hook
|
||||
_sqlite3_preupdate_new
|
||||
_sqlite3_preupdate_old
|
||||
_sqlite3_progress_handler
|
||||
_sqlite3_set_authorizer
|
||||
_sqlite3_vtab_collation
|
||||
_sqlite3_vtab_distinct
|
||||
_sqlite3_vtab_in
|
||||
_sqlite3_vtab_in_first
|
||||
_sqlite3_vtab_in_next
|
||||
_sqlite3_vtab_nochange
|
||||
_sqlite3_vtab_on_conflict
|
||||
_sqlite3_vtab_rhs_value
|
||||
_sqlite3changegroup_add
|
||||
_sqlite3changegroup_add_strm
|
||||
_sqlite3changegroup_delete
|
||||
_sqlite3changegroup_new
|
||||
_sqlite3changegroup_output
|
||||
_sqlite3changegroup_output_strm
|
||||
_sqlite3changeset_apply
|
||||
_sqlite3changeset_apply_strm
|
||||
_sqlite3changeset_apply_v2
|
||||
_sqlite3changeset_apply_v2_strm
|
||||
_sqlite3changeset_apply_v3
|
||||
_sqlite3changeset_apply_v3_strm
|
||||
_sqlite3changeset_concat
|
||||
_sqlite3changeset_concat_strm
|
||||
_sqlite3changeset_conflict
|
||||
_sqlite3changeset_finalize
|
||||
_sqlite3changeset_fk_conflicts
|
||||
_sqlite3changeset_invert
|
||||
_sqlite3changeset_invert_strm
|
||||
_sqlite3changeset_new
|
||||
_sqlite3changeset_next
|
||||
_sqlite3changeset_old
|
||||
_sqlite3changeset_op
|
||||
_sqlite3changeset_pk
|
||||
_sqlite3changeset_start
|
||||
_sqlite3changeset_start_strm
|
||||
_sqlite3changeset_start_v2
|
||||
_sqlite3changeset_start_v2_strm
|
||||
_sqlite3session_attach
|
||||
_sqlite3session_changeset
|
||||
_sqlite3session_changeset_size
|
||||
_sqlite3session_changeset_strm
|
||||
_sqlite3session_config
|
||||
_sqlite3session_create
|
||||
_sqlite3session_delete
|
||||
_sqlite3session_diff
|
||||
_sqlite3session_enable
|
||||
_sqlite3session_indirect
|
||||
_sqlite3session_isempty
|
||||
_sqlite3session_memory_used
|
||||
_sqlite3session_object_config
|
||||
_sqlite3session_patchset
|
||||
_sqlite3session_patchset_strm
|
||||
_sqlite3session_table_filter
|
||||
//#endif not bare-bones
|
||||
//#if enable-see
|
||||
_sqlite3_key
|
||||
_sqlite3_key_v2
|
||||
_sqlite3_rekey
|
||||
_sqlite3_rekey_v2
|
||||
_sqlite3_activate_see
|
||||
//#endif enable-see
|
||||
//#if fiddle
|
||||
_fiddle_db_arg
|
||||
_fiddle_db_filename
|
||||
_fiddle_exec
|
||||
_fiddle_experiment
|
||||
_fiddle_interrupt
|
||||
_fiddle_main
|
||||
_fiddle_reset_db
|
||||
_fiddle_db_handle
|
||||
_fiddle_db_vfs
|
||||
_fiddle_export_db
|
||||
//#endif fiddle
|
||||
@@ -1,66 +0,0 @@
|
||||
_sqlite3_column_database_name
|
||||
_sqlite3_column_origin_name
|
||||
_sqlite3_column_table_name
|
||||
_sqlite3_create_module
|
||||
_sqlite3_create_module_v2
|
||||
_sqlite3_create_window_function
|
||||
_sqlite3_declare_vtab
|
||||
_sqlite3_drop_modules
|
||||
_sqlite3_preupdate_blobwrite
|
||||
_sqlite3_preupdate_count
|
||||
_sqlite3_preupdate_depth
|
||||
_sqlite3_preupdate_hook
|
||||
_sqlite3_preupdate_new
|
||||
_sqlite3_preupdate_old
|
||||
_sqlite3_progress_handler
|
||||
_sqlite3_set_authorizer
|
||||
_sqlite3_vtab_collation
|
||||
_sqlite3_vtab_distinct
|
||||
_sqlite3_vtab_in
|
||||
_sqlite3_vtab_in_first
|
||||
_sqlite3_vtab_in_next
|
||||
_sqlite3_vtab_nochange
|
||||
_sqlite3_vtab_on_conflict
|
||||
_sqlite3_vtab_rhs_value
|
||||
_sqlite3changegroup_add
|
||||
_sqlite3changegroup_add_strm
|
||||
_sqlite3changegroup_delete
|
||||
_sqlite3changegroup_new
|
||||
_sqlite3changegroup_output
|
||||
_sqlite3changegroup_output_strm
|
||||
_sqlite3changeset_apply
|
||||
_sqlite3changeset_apply_strm
|
||||
_sqlite3changeset_apply_v2
|
||||
_sqlite3changeset_apply_v2_strm
|
||||
_sqlite3changeset_concat
|
||||
_sqlite3changeset_concat_strm
|
||||
_sqlite3changeset_conflict
|
||||
_sqlite3changeset_finalize
|
||||
_sqlite3changeset_fk_conflicts
|
||||
_sqlite3changeset_invert
|
||||
_sqlite3changeset_invert_strm
|
||||
_sqlite3changeset_new
|
||||
_sqlite3changeset_next
|
||||
_sqlite3changeset_old
|
||||
_sqlite3changeset_op
|
||||
_sqlite3changeset_pk
|
||||
_sqlite3changeset_start
|
||||
_sqlite3changeset_start_strm
|
||||
_sqlite3changeset_start_v2
|
||||
_sqlite3changeset_start_v2_strm
|
||||
_sqlite3session_attach
|
||||
_sqlite3session_changeset
|
||||
_sqlite3session_changeset_size
|
||||
_sqlite3session_changeset_strm
|
||||
_sqlite3session_config
|
||||
_sqlite3session_create
|
||||
_sqlite3session_delete
|
||||
_sqlite3session_diff
|
||||
_sqlite3session_enable
|
||||
_sqlite3session_indirect
|
||||
_sqlite3session_isempty
|
||||
_sqlite3session_memory_used
|
||||
_sqlite3session_object_config
|
||||
_sqlite3session_patchset
|
||||
_sqlite3session_patchset_strm
|
||||
_sqlite3session_table_filter
|
||||
@@ -1,5 +0,0 @@
|
||||
_sqlite3_key
|
||||
_sqlite3_key_v2
|
||||
_sqlite3_rekey
|
||||
_sqlite3_rekey_v2
|
||||
_sqlite3_activate_see
|
||||
@@ -1,3 +0,0 @@
|
||||
FS
|
||||
wasmMemory
|
||||
|
||||
@@ -23,7 +23,7 @@ this writing, but is not set in stone forever and may change at any
|
||||
time. This doc targets maintainers of this code and those wanting to
|
||||
dive in to the details, not end user.
|
||||
|
||||
First off, a pikchr of the proverbial onion:
|
||||
First off, a [pikchr][] of the proverbial onion:
|
||||
|
||||
```pikchr toggle center
|
||||
scale = 0.85
|
||||
@@ -205,9 +205,10 @@ Preprocessing of Source Files
|
||||
Certain files in the build require preprocessing to filter in/out
|
||||
parts which differ between vanilla JS, ES6 Modules, and node.js
|
||||
builds. The preprocessor application itself is in
|
||||
[`c-pp.c`](/file/ext/wasm/c-pp.c) and the complete technical details
|
||||
of such preprocessing are maintained in
|
||||
[`c-pp-lite.c`](/file/ext/wasm/c-pp-lite.c) and the complete technical
|
||||
details of such preprocessing are maintained in
|
||||
[`GNUMakefile`](/file/ext/wasm/GNUmakefile).
|
||||
|
||||
|
||||
[OPFS]: https://developer.mozilla.org/en-US/docs/Web/API/File_System_API/Origin_private_file_system
|
||||
[pikchr]: https://pikchr.org
|
||||
|
||||
@@ -26,7 +26,7 @@ const toExportForESM =
|
||||
*/
|
||||
const originalInit = sqlite3InitModule;
|
||||
if(!originalInit){
|
||||
throw new Error("Expecting globalThis.sqlite3InitModule to be defined by the Emscripten build.");
|
||||
throw new Error("Expecting sqlite3InitModule to be defined by the Emscripten build.");
|
||||
}
|
||||
/**
|
||||
We need to add some state which our custom Module.locateFile()
|
||||
|
||||
@@ -14,6 +14,23 @@
|
||||
itself. i.e. try to keep file-local symbol names obnoxiously
|
||||
collision-resistant.
|
||||
*/
|
||||
/**
|
||||
This file was preprocessed using:
|
||||
|
||||
//#@policy error
|
||||
@c-pp::ARGV@
|
||||
//#@policy off
|
||||
*/
|
||||
//#if unsupported-build
|
||||
/**
|
||||
UNSUPPORTED BUILD:
|
||||
|
||||
This SQLite JS build configuration is entirely unsupported! It has
|
||||
not been tested beyond the ability to compile it. It may not
|
||||
load. It may not work properly. Only builds targeting browser
|
||||
environments are supported and tested.
|
||||
*/
|
||||
//#endif
|
||||
(function(Module){
|
||||
const sIMS =
|
||||
globalThis.sqlite3InitModuleState/*from extern-post-js.c-pp.js*/
|
||||
|
||||
@@ -55,12 +55,7 @@ try{
|
||||
}
|
||||
);
|
||||
|
||||
/** Figure out if this is a 32- or 64-bit WASM build. */
|
||||
bootstrapConfig.wasmPtrIR =
|
||||
'number'===(typeof bootstrapConfig.exports.sqlite3_libversion())
|
||||
? 'i32' :'i64';
|
||||
const sIMS = sqlite3InitScriptInfo;
|
||||
sIMS.debugModule("Bootstrapping lib config", sIMS);
|
||||
sqlite3InitScriptInfo.debugModule("Bootstrapping lib config", bootstrapConfig);
|
||||
|
||||
/**
|
||||
For purposes of the Emscripten build, call sqlite3ApiBootstrap().
|
||||
|
||||
@@ -120,7 +120,11 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
||||
["sqlite3_column_double","f64", "sqlite3_stmt*", "int"],
|
||||
["sqlite3_column_int","int", "sqlite3_stmt*", "int"],
|
||||
["sqlite3_column_name","string", "sqlite3_stmt*", "int"],
|
||||
//#define proxy-text-apis=1
|
||||
//#if not proxy-text-apis
|
||||
/* Search this file for tag:proxy-text-apis to see what this is about. */
|
||||
["sqlite3_column_text","string", "sqlite3_stmt*", "int"],
|
||||
//#endif
|
||||
["sqlite3_column_type","int", "sqlite3_stmt*", "int"],
|
||||
["sqlite3_column_value","sqlite3_value*", "sqlite3_stmt*", "int"],
|
||||
["sqlite3_commit_hook", "void*", [
|
||||
@@ -317,7 +321,9 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
||||
["sqlite3_value_numeric_type", "int", "sqlite3_value*"],
|
||||
["sqlite3_value_pointer", "*", "sqlite3_value*", "string:static"],
|
||||
["sqlite3_value_subtype", "int", "sqlite3_value*"],
|
||||
//#if not proxy-text-apis
|
||||
["sqlite3_value_text", "string", "sqlite3_value*"],
|
||||
//#endif
|
||||
["sqlite3_value_type", "int", "sqlite3_value*"],
|
||||
["sqlite3_vfs_find", "*", "string"],
|
||||
["sqlite3_vfs_register", "int", "sqlite3_vfs*", "int"],
|
||||
@@ -358,6 +364,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
||||
["sqlite3_serialize","*", "sqlite3*", "string", "*", "int"],
|
||||
["sqlite3_set_last_insert_rowid", undefined, ["sqlite3*", "i64"]],
|
||||
["sqlite3_status64", "int", "int", "*", "*", "int"],
|
||||
["sqlite3_db_status64", "int", "sqlite3*", "int", "*", "*", "int"],
|
||||
["sqlite3_total_changes64", "i64", ["sqlite3*"]],
|
||||
["sqlite3_update_hook", "*", [
|
||||
"sqlite3*",
|
||||
@@ -479,9 +486,10 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
||||
build is generally incompatible with SEE's license conditions.
|
||||
The project's official stance on WASM builds of SEE is: it is
|
||||
permitted for use internally within organizations which have
|
||||
licensed SEE, but not for public sites because exposing an SEE
|
||||
build of sqlite3.wasm effectively provides all clients with a
|
||||
working copy of SEE.
|
||||
licensed SEE, but not for sites made available to the public or
|
||||
to unlicensed end users because exposing an SEE build of
|
||||
sqlite3.wasm effectively provides all clients with a working
|
||||
copy of SEE.
|
||||
*/
|
||||
bindingSignatures.core.push(
|
||||
["sqlite3_key", "int", "sqlite3*", "string", "int"],
|
||||
@@ -628,6 +636,31 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
||||
}),
|
||||
'void*', '**', 'int*', 'int'
|
||||
]],
|
||||
['sqlite3changeset_apply_v3', 'int', [
|
||||
'sqlite3*', 'int', 'void*',
|
||||
new wasm.xWrap.FuncPtrAdapter({
|
||||
name: 'xFilter', signature: 'i(pp)', bindScope: 'transient'
|
||||
}),
|
||||
new wasm.xWrap.FuncPtrAdapter({
|
||||
name: 'xConflict', signature: 'i(pip)', bindScope: 'transient'
|
||||
}),
|
||||
'void*', '**', 'int*', 'int'
|
||||
|
||||
]],
|
||||
['sqlite3changeset_apply_v3_strm', 'int', [
|
||||
'sqlite3*',
|
||||
new wasm.xWrap.FuncPtrAdapter({
|
||||
name: 'xInput', signature: 'i(ppp)', bindScope: 'transient'
|
||||
}),
|
||||
'void*',
|
||||
new wasm.xWrap.FuncPtrAdapter({
|
||||
name: 'xFilter', signature: 'i(pp)', bindScope: 'transient'
|
||||
}),
|
||||
new wasm.xWrap.FuncPtrAdapter({
|
||||
name: 'xConflict', signature: 'i(pip)', bindScope: 'transient'
|
||||
}),
|
||||
'void*', '**', 'int*', 'int'
|
||||
]],
|
||||
['sqlite3changeset_concat', 'int', ['int','void*', 'int', 'void*', 'int*', '**']],
|
||||
['sqlite3changeset_concat_strm', 'int', [
|
||||
new wasm.xWrap.FuncPtrAdapter({
|
||||
@@ -1627,6 +1660,45 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
||||
|
||||
}/*sqlite3_bind_text/blob()*/
|
||||
|
||||
//#if proxy-text-apis
|
||||
if(!capi.sqlite3_column_text){
|
||||
/*[tag:proxy-text-apis]
|
||||
As discussed at:
|
||||
|
||||
https://sqlite.org/forum/forumpost/d77281aec2df9ada
|
||||
|
||||
Summary: there are opinions that sqlite3_column_text() and
|
||||
sqlite3_value_text() should handle strings such that embedded
|
||||
NULs are retained. This block does that. This block does _not_
|
||||
apply that special-case behavior to any number of _other_
|
||||
APIs which return C-strings. That discrepancy makes this
|
||||
block highly arguable, but one can also argue that these two
|
||||
specific functions can get away with such acrobatics without
|
||||
it being called voodoo in a pejorative sense.
|
||||
*/
|
||||
const argStmt = wasm.xWrap.argAdapter('sqlite3_stmt*'),
|
||||
argInt = wasm.xWrap.argAdapter('int'),
|
||||
argValue = wasm.xWrap.argAdapter('sqlite3_value*'),
|
||||
newStr =
|
||||
(cstr,n)=>wasm.typedArrayToString(wasm.heap8u(),
|
||||
Number(cstr), Number(cstr)+n)
|
||||
capi.sqlite3_column_text = function(stmt, colIndex){
|
||||
const a0 = argStmt(stmt), a1 = argInt(colIndex);
|
||||
const cstr = wasm.exports.sqlite3_column_text(a0, a1);
|
||||
return cstr
|
||||
? newStr(cstr,wasm.exports.sqlite3_column_bytes(a0, a1))
|
||||
: null;
|
||||
};
|
||||
capi.sqlite3_value_text = function(val){
|
||||
const a0 = argValue(val);
|
||||
const cstr = wasm.exports.sqlite3_value_text(a0);
|
||||
return cstr
|
||||
? newStr(cstr,wasm.exports.sqlite3_value_bytes(a0))
|
||||
: null;
|
||||
};
|
||||
}/*text-return-related bindings*/
|
||||
//#endif proxy-text-apis
|
||||
|
||||
{/* sqlite3_config() */
|
||||
/**
|
||||
Wraps a small subset of the C API's sqlite3_config() options.
|
||||
@@ -1809,6 +1881,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
||||
for anything other than local/sessionStorage. It "can"
|
||||
be used that way but it's not really intended to be. */
|
||||
capi.sqlite3_vfs_unregister(pKvvfs);
|
||||
delete capi.sqlite3_kvvfs_methods;
|
||||
}
|
||||
}/*pKvvfs*/
|
||||
|
||||
@@ -1917,7 +1990,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
||||
}
|
||||
tgt[memKey] = fProxy;
|
||||
}else{
|
||||
const pFunc = wasm.installFunction(fProxy, tgt.memberSignature(name));
|
||||
const pFunc = wasm.installFunction(fProxy, sigN);
|
||||
tgt[memKey] = pFunc;
|
||||
if(!tgt.ondispose || !tgt.ondispose.__removeFuncList){
|
||||
tgt.addOnDispose('ondispose.__removeFuncList handler',
|
||||
|
||||
@@ -799,22 +799,6 @@ globalThis.sqlite3ApiBootstrap = async function sqlite3ApiBootstrap(
|
||||
environment via whwashutil.js.
|
||||
*/
|
||||
Object.assign(wasm, {
|
||||
/**
|
||||
The WASM IR (Intermediate Representation) value for
|
||||
pointer-type values. If set then it MUST be one of 'i32' or
|
||||
'i64' (else an exception will be thrown). If it's not set, it
|
||||
will default to 'i32'.
|
||||
*/
|
||||
pointerIR: config.wasmPtrIR,
|
||||
|
||||
/**
|
||||
True if BigInt support was enabled via (e.g.) the
|
||||
Emscripten -sWASM_BIGINT flag, else false. When
|
||||
enabled, certain 64-bit sqlite3 APIs are enabled which
|
||||
are not otherwise enabled due to JS/WASM int64
|
||||
impedance mismatches.
|
||||
*/
|
||||
bigIntEnabled: !!config.bigIntEnabled,
|
||||
|
||||
/**
|
||||
The symbols exported by the WASM environment.
|
||||
@@ -834,6 +818,29 @@ globalThis.sqlite3ApiBootstrap = async function sqlite3ApiBootstrap(
|
||||
"in either config.exports.memory (exported)",
|
||||
"or config.memory (imported)."),
|
||||
|
||||
/**
|
||||
The WASM pointer size. If set then it MUST be one of 4 or 8 and
|
||||
it MUST correspond to the WASM environment's pointer size. We
|
||||
figure out the size by calling some un-JS-wrapped WASM function
|
||||
which returns a pointer-type value. If that value is a BigInt,
|
||||
it's 64-bit, else it's 32-bit. The pieces which populate
|
||||
sqlite3.wasm (whwasmutil.js) can figure this out _if_ they can
|
||||
allocate, but we have a chicken/egg situation there which makes
|
||||
it illegal for that code to invoke wasm.dealloc() at the time
|
||||
it would be needed. So we need to configure it ahead of time
|
||||
(here) instead.
|
||||
*/
|
||||
pointerSize: ('number'===typeof config.exports.sqlite3_libversion()) ? 4 : 8,
|
||||
|
||||
/**
|
||||
True if BigInt support was enabled via (e.g.) the
|
||||
Emscripten -sWASM_BIGINT flag, else false. When
|
||||
enabled, certain 64-bit sqlite3 APIs are enabled which
|
||||
are not otherwise enabled due to JS/WASM int64
|
||||
impedance mismatches.
|
||||
*/
|
||||
bigIntEnabled: !!config.bigIntEnabled,
|
||||
|
||||
/**
|
||||
WebAssembly.Table object holding the indirect function call
|
||||
table. Defaults to exports.__indirect_function_table.
|
||||
@@ -921,9 +928,11 @@ globalThis.sqlite3ApiBootstrap = async function sqlite3ApiBootstrap(
|
||||
srcTypedArray = new Uint8Array(srcTypedArray);
|
||||
}
|
||||
affirmBindableTypedArray(srcTypedArray);
|
||||
const heap = wasm.heapForSize(srcTypedArray.constructor);
|
||||
const pRet = wasm.alloc(srcTypedArray.byteLength || 1);
|
||||
heap.set(srcTypedArray.byteLength ? srcTypedArray : [0], Number(pRet));
|
||||
wasm.heapForSize(srcTypedArray.constructor)
|
||||
.set(srcTypedArray.byteLength ? srcTypedArray : [0], Number(pRet))
|
||||
/* Maintenance note: the order of alloc() and heapForSize() calls
|
||||
is significant: https://sqlite.org/forum/forumpost/05b77273be104532 */;
|
||||
return pRet;
|
||||
};
|
||||
|
||||
|
||||
@@ -326,7 +326,7 @@ SQLITE_WASM_EXPORT void * sqlite3__wasm_pstack_ptr(void){
|
||||
*/
|
||||
SQLITE_WASM_EXPORT void sqlite3__wasm_pstack_restore(unsigned char * p){
|
||||
assert(p>=PStack.pBegin && p<=PStack.pEnd && p>=PStack.pPos);
|
||||
assert(0==((unsigned long long)p & 0x7));
|
||||
assert(0==((unsigned long long)p & 0x7) /* 8-byte aligned */);
|
||||
if(p>=PStack.pBegin && p<=PStack.pEnd /*&& p>=PStack.pPos*/){
|
||||
PStack.pPos = p;
|
||||
}
|
||||
@@ -613,6 +613,7 @@ const char * sqlite3__wasm_enum_json(void){
|
||||
DefInt(SQLITE_DBSTATUS_DEFERRED_FKS);
|
||||
DefInt(SQLITE_DBSTATUS_CACHE_USED_SHARED);
|
||||
DefInt(SQLITE_DBSTATUS_CACHE_SPILL);
|
||||
DefInt(SQLITE_DBSTATUS_TEMPBUF_SPILL);
|
||||
DefInt(SQLITE_DBSTATUS_MAX);
|
||||
} _DefGroup;
|
||||
|
||||
|
||||
+111
-39
@@ -386,6 +386,9 @@ static void g_stderrv(char const *zFmt, va_list);
|
||||
if(lvl<=g.flags.doDebug) g_stderr("%s @ %s():%d: ",g.zArgv0,__func__,__LINE__); \
|
||||
if(lvl<=g.flags.doDebug) g_stderr pfexpr
|
||||
|
||||
#define g_warn(zFmt,...) g_stderr("%s:%d %s() " zFmt "\n", __FILE__, __LINE__, __func__, __VA_ARGS__)
|
||||
#define g_warn0(zMsg) g_stderr("%s:%d %s() %s\n", __FILE__, __LINE__, __func__, zMsg)
|
||||
|
||||
void cmpp_free(void *p){
|
||||
sqlite3_free(p);
|
||||
}
|
||||
@@ -657,7 +660,6 @@ static void CmppLevel_pop(CmppTokenizer * const t);
|
||||
*/
|
||||
static CmppLevel * CmppLevel_get(CmppTokenizer * const t);
|
||||
|
||||
#define CMPPLEVEL_GET
|
||||
/*
|
||||
** Policies for how to handle undefined @tokens@ when performing
|
||||
** content filtering.
|
||||
@@ -968,7 +970,6 @@ void db_prepare(sqlite3_stmt **pStmt, const char * zSql, ...){
|
||||
char * z = 0;
|
||||
int n = 0;
|
||||
va_list va;
|
||||
if(!str) fatal("sqlite3_str_new() failed");
|
||||
va_start(va, zSql);
|
||||
sqlite3_str_vappendf(str, zSql, va);
|
||||
va_end(va);
|
||||
@@ -1101,6 +1102,7 @@ static void db_define_add_file(const char * zKey){
|
||||
kvp.v.z ? kvp.v.z : ""));
|
||||
}
|
||||
|
||||
#define ustr_c(X) ((unsigned char const *)X)
|
||||
|
||||
static inline unsigned int cmpp_strlen(char const *z, int n){
|
||||
return n<0 ? (int)strlen(z) : (unsigned)n;
|
||||
@@ -1284,9 +1286,11 @@ void g_FileWrapper_close(FileWrapper *fp){
|
||||
}
|
||||
|
||||
static void g_cleanup(int bCloseFileChain){
|
||||
if( g.db ){
|
||||
#define E(N,S) sqlite3_finalize(g.stmt.N); g.stmt.N = 0;
|
||||
GStmt_map(E)
|
||||
#undef E
|
||||
}
|
||||
if( bCloseFileChain ){
|
||||
FileWrapper * fpNext = 0;
|
||||
for( FileWrapper * fp=g.pFiles; fp; fp=fpNext ){
|
||||
@@ -1296,7 +1300,10 @@ static void g_cleanup(int bCloseFileChain){
|
||||
}
|
||||
}
|
||||
FileWrapper_close(&g.out);
|
||||
if(g.db) sqlite3_close(g.db);
|
||||
if(g.db){
|
||||
sqlite3_close(g.db);
|
||||
g.db = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void cmpp_atexit(void){
|
||||
@@ -1449,7 +1456,11 @@ static void cmpp_t_out_expand(CmppTokenizer * const t,
|
||||
unsigned int n);
|
||||
|
||||
static inline int cmpp__isspace(int ch){
|
||||
return ' '==ch || '\n'==ch || '\t'==ch || '\r'==ch;
|
||||
return ' '==ch || '\t'==ch;
|
||||
}
|
||||
|
||||
static inline unsigned cmpp__strlenu(unsigned char const *z, int n){
|
||||
return n<0 ? (unsigned)strlen((char const *)z) : (unsigned)n;
|
||||
}
|
||||
|
||||
static inline void cmpp__skip_space_c( unsigned char const **p,
|
||||
@@ -1459,6 +1470,9 @@ static inline void cmpp__skip_space_c( unsigned char const **p,
|
||||
*p = z;
|
||||
}
|
||||
|
||||
#define ustr_c(X) ((unsigned char const *)X)
|
||||
//#define ustr_nc(X) ((unsigned char *)X)
|
||||
|
||||
/**
|
||||
Scan [t->zPos,t->zEnd) for a derective delimiter. Emits any
|
||||
non-delimiter output found along the way.
|
||||
@@ -1468,7 +1482,7 @@ static inline void cmpp__skip_space_c( unsigned char const **p,
|
||||
If a delimiter is found, it updates t->token and returns 0.
|
||||
On no match returns 0.
|
||||
*/
|
||||
//static
|
||||
static
|
||||
int CmppTokenizer__delim_search(CmppTokenizer * const t){
|
||||
if(!t->zPos) t->zPos = t->zBegin;
|
||||
if( t->zPos>=t->zEnd ){
|
||||
@@ -1493,27 +1507,52 @@ int CmppTokenizer__delim_search(CmppTokenizer * const t){
|
||||
cmpp_t_out_expand(t, zLeft, (unsigned)(z-zLeft)); \
|
||||
} zLeft = z
|
||||
while(z < zEnd){
|
||||
size_t const nNl = strcspn((char const *)z, "\n");
|
||||
unsigned char const * const zNl = (z + nNl > zEnd ? zEnd : z + nNl);
|
||||
if( nNl >= CmppArgs_BufSize /* too long */
|
||||
size_t nNlTotal = 0;
|
||||
unsigned char const * zNl;
|
||||
size_t nNl2 = strcspn((char const *)z, "\n");
|
||||
zNl = (z + nNl2 >= zEnd ? zEnd : z + nNl2);
|
||||
if( nNl2 >= CmppArgs_BufSize /* too long */
|
||||
//|| '\n'!=(char)*zNl /* end of input */
|
||||
/* ^^^ we have to accept a missing trailing EOL for the
|
||||
sake of -e scripts. */
|
||||
){
|
||||
/* we'd like to error out here, but only if we know we're
|
||||
reading reading a directive line. */
|
||||
++t->lineNo;
|
||||
z = zNl + 1;
|
||||
tflush;
|
||||
continue;
|
||||
}
|
||||
nNlTotal += nNl2;
|
||||
assert( '\n'==*zNl || !*zNl );
|
||||
//g_stderr("input: zNl=%d z=<<<%.*s>>>\n", (int)*zNl, (zNl-z), z);
|
||||
assert( '\n'==*zNl || zNl==zEnd );
|
||||
//g_stderr("input: zNl=%d z=<<<%.*s>>>", (int)*zNl, (zNl-z), z);
|
||||
unsigned char const * const zBOL = z;
|
||||
cmpp__skip_space_c(&z, zNl);
|
||||
if( z+nD < zNl && 0==memcmp(z, zD, nD) ){
|
||||
/* Found a directive delimiter. */
|
||||
if( zBOL!=z ){
|
||||
/* Do not emit space which preceeds a delimiter */
|
||||
/* Do not emit space from the same line which preceeds a
|
||||
delimiter */
|
||||
zLeft = z;
|
||||
}
|
||||
while( zNl>z && zNl<zEnd
|
||||
&& '\n'==*zNl && '\\'==zNl[-1] ){
|
||||
/* Backslash-escaped newline: extend the token
|
||||
to consume it all. */
|
||||
++t->lineNo;
|
||||
++zNl;
|
||||
nNl2 = strcspn((char const *)zNl, "\n");
|
||||
if( !nNl2 ) break;
|
||||
nNlTotal += nNl2;
|
||||
zNl += nNl2;
|
||||
}
|
||||
assert( zNl<=zEnd && "Else our input was not NUL-terminated");
|
||||
if( nNlTotal >= CmppArgs_BufSize ){
|
||||
fatal("Directive line is too long (%u)",
|
||||
(unsigned)(zNl-z));
|
||||
break;
|
||||
}
|
||||
tflush;
|
||||
t->token.zBegin = z + nD;
|
||||
t->token.zEnd = zNl;
|
||||
@@ -1521,14 +1560,16 @@ int CmppTokenizer__delim_search(CmppTokenizer * const t){
|
||||
t->token.ttype = TT_Line;
|
||||
t->token.lineNo = t->lineNo++;
|
||||
t->zPos = t->token.zEnd + 1;
|
||||
|
||||
//g_stderr("token=%.*s\n", (zNl - t->token.zBegin), t->token.zBegin);
|
||||
if( 0 ){
|
||||
g_stderr("token=<<%.*s>>", (t->token.zEnd - t->token.zBegin),
|
||||
t->token.zBegin);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
z = zNl+1;
|
||||
++t->lineNo;
|
||||
tflush;
|
||||
//g_stderr0("line #%d no match\n",(int)t->lineNO);
|
||||
//g_stderr("line #%d no match\n",(int)t->lineNo);
|
||||
}
|
||||
tflush;
|
||||
t->zPos = z;
|
||||
@@ -1585,17 +1626,18 @@ static void cmpp_t_out_expand(CmppTokenizer * const t,
|
||||
unsigned char const chEol = (unsigned char)'\n';
|
||||
int state = 0 /* 0==looking for opening @
|
||||
** 1==looking for closing @ */;
|
||||
if( 0 ){
|
||||
g_warn("zLeft=%d %c", (int)*zLeft, *zLeft);
|
||||
}
|
||||
#define tflush \
|
||||
if(z>zEnd) z=zEnd; \
|
||||
if(zLeft<z){ cmpp_t_out(t, zLeft, (z-zLeft)); } zLeft = z
|
||||
for( ; z<zEnd; ++z ){
|
||||
zLeft = z;
|
||||
for( ;z<zEnd; ++z ){
|
||||
if( chEol==*z ){
|
||||
state = 0;
|
||||
++z /*ensure that we flush the EOL now*/;
|
||||
tflush;
|
||||
--z/*And make sure that zLeft does the right thing*/;
|
||||
break;
|
||||
continue;
|
||||
}
|
||||
if( g.delim.chAt==*z ){
|
||||
if( 0==state ){
|
||||
@@ -2379,31 +2421,38 @@ void cmpp_process_keyword(CmppTokenizer * const t){
|
||||
t->args.argc = 0;
|
||||
}
|
||||
|
||||
void cmpp_process_file(const char * zName){
|
||||
FileWrapper fw = FileWrapper_empty;
|
||||
void cmpp_process_string(const char * zName,
|
||||
unsigned char const * zIn,
|
||||
int nIn){
|
||||
nIn = cmpp__strlenu(zIn, nIn);
|
||||
if( !nIn ) return;
|
||||
CmppTokenizer const * const oldTok = g.tok;
|
||||
CmppTokenizer ct = CmppTokenizer_empty;
|
||||
g.tok = &ct;
|
||||
ct.zName = zName;
|
||||
ct.zBegin = zIn;
|
||||
ct.zEnd = zIn + nIn;
|
||||
while(cmpp_next_keyword_line(&ct)){
|
||||
cmpp_process_keyword(&ct);
|
||||
}
|
||||
if(0!=ct.level.ndx){
|
||||
CmppLevel const * const lv = CmppLevel_get(&ct);
|
||||
fatal("Input ended inside an unterminated nested construct "
|
||||
"opened at [%s] line %u", zName, lv->token.lineNo);
|
||||
}
|
||||
CmppTokenizer_cleanup(&ct);
|
||||
g.tok = oldTok;
|
||||
}
|
||||
|
||||
void cmpp_process_file(const char * zName){
|
||||
FileWrapper fw = FileWrapper_empty;
|
||||
FileWrapper_open(&fw, zName, "r");
|
||||
g_FileWrapper_link(&fw);
|
||||
FileWrapper_slurp(&fw);
|
||||
g_debug(1,("Read %u byte(s) from [%s]\n", fw.nContent, fw.zName));
|
||||
if( fw.zContent ){
|
||||
ct.zName = zName;
|
||||
ct.zBegin = fw.zContent;
|
||||
ct.zEnd = fw.zContent + fw.nContent;
|
||||
while(cmpp_next_keyword_line(&ct)){
|
||||
cmpp_process_keyword(&ct);
|
||||
}
|
||||
cmpp_process_string(zName, fw.zContent, fw.nContent);
|
||||
}
|
||||
g_FileWrapper_close(&fw);
|
||||
if(0!=ct.level.ndx){
|
||||
CmppLevel * const lv = CmppLevel_get(&ct);
|
||||
fatal("Input ended inside an unterminated nested construct"
|
||||
"opened at [%s] line %u", zName, lv->token.lineNo);
|
||||
}
|
||||
CmppTokenizer_cleanup(&ct);
|
||||
g.tok = oldTok;
|
||||
}
|
||||
|
||||
|
||||
@@ -2530,6 +2579,21 @@ static int arg_is_flag( char const *zFlag, char const *zArg,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void define_argv(int argc, char const * const * argv){
|
||||
sqlite3_str * const s = sqlite3_str_new(g.db);
|
||||
sqlite3_str_append(s, "c-pp::ARGV=", 11);
|
||||
for( int i = 0; i < argc; ++i ){
|
||||
if( i ) sqlite3_str_appendchar(s, 1, ' ');
|
||||
sqlite3_str_appendf(s, "%s", argv[i]);
|
||||
}
|
||||
char * const z = sqlite3_str_finish(s);
|
||||
assert(z);
|
||||
if(z){
|
||||
db_define_add(z, NULL);
|
||||
sqlite3_free(z);
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char const * const * argv){
|
||||
int rc = 0;
|
||||
int inclCount = 0;
|
||||
@@ -2542,6 +2606,9 @@ int main(int argc, char const * const * argv){
|
||||
#define ISFLAG(X) else if(M(X))
|
||||
#define ISFLAG2(X,Y) else if(M(X) || M(Y))
|
||||
#define NOVAL if( zVal ) fatal("Unexpected value for %s", zArg)
|
||||
#define g_out_open \
|
||||
if(!g.out.pFile) FileWrapper_open(&g.out, "-", "w"); \
|
||||
if(!inclCount){ db_include_dir_add("."); ++inclCount; } (void)0
|
||||
|
||||
g.zArgv0 = argv[0];
|
||||
#define DOIT if(doIt)
|
||||
@@ -2564,6 +2631,7 @@ int main(int argc, char const * const * argv){
|
||||
g.sqlTrace.expandSql = expandMode;
|
||||
}
|
||||
cmpp_initdb();
|
||||
define_argv(argc, argv);
|
||||
}
|
||||
for(int i = 1; i < argc; ++i){
|
||||
int negate = 0;
|
||||
@@ -2620,14 +2688,18 @@ int main(int argc, char const * const * argv){
|
||||
do_infile:
|
||||
DOIT {
|
||||
++nFile;
|
||||
if(!g.out.pFile) FileWrapper_open(&g.out, "-", "w");
|
||||
if(!inclCount){
|
||||
db_include_dir_add(".");
|
||||
++inclCount;
|
||||
}
|
||||
g_out_open;
|
||||
cmpp_process_file(zVal);
|
||||
}
|
||||
}
|
||||
ISFLAG("e"){
|
||||
ARGVAL;
|
||||
DOIT {
|
||||
++nFile;
|
||||
g_out_open;
|
||||
cmpp_process_string("-e script", ustr_c(zVal), -1);
|
||||
}
|
||||
}
|
||||
ISFLAG("@"){
|
||||
NOVAL;
|
||||
DOIT {
|
||||
@@ -2705,6 +2777,6 @@ int main(int argc, char const * const * argv){
|
||||
}
|
||||
}
|
||||
end:
|
||||
g_cleanup(0);
|
||||
g_cleanup(1);
|
||||
return rc ? EXIT_FAILURE : EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -227,6 +227,14 @@ globalThis.WhWasmUtilInstaller = function(target){
|
||||
all args with a space between each. */
|
||||
const toss = (...args)=>{throw new Error(args.join(' '))};
|
||||
|
||||
if( !target.pointerSize && !target.pointerIR
|
||||
&& target.alloc && target.dealloc ){
|
||||
/* Try to determine the pointer size by allocating. */
|
||||
const ptr = target.alloc(1);
|
||||
target.pointerSize = ('bigint'===typeof ptr ? 8 : 4);
|
||||
target.dealloc(ptr);
|
||||
}
|
||||
|
||||
/**
|
||||
As of 2025-09-21, this library works with 64-bit WASM modules
|
||||
built with Emscripten's -sMEMORY64=1.
|
||||
@@ -996,12 +1004,12 @@ globalThis.WhWasmUtilInstaller = function(target){
|
||||
target.heap8u().
|
||||
*/
|
||||
target.cstrlen = function(ptr){
|
||||
if(!ptr || !target.isPtr(ptr)) return null;
|
||||
if(!ptr || !target.isPtr/*64*/(ptr)) return null;
|
||||
ptr = Number(ptr) /*tag:64bit*/;
|
||||
const h = heapWrappers().HEAP8U;
|
||||
let pos = ptr;
|
||||
for( ; h[pos] !== 0; ++pos ){}
|
||||
return Number(pos - ptr);
|
||||
return pos - ptr;
|
||||
};
|
||||
|
||||
/** Internal helper to use in operations which need to distinguish
|
||||
|
||||
+365
-96
@@ -32,7 +32,7 @@ globalThis.Jaccwabyt = function StructBinderFactory(config){
|
||||
|
||||
if(!(config.heap instanceof WebAssembly.Memory)
|
||||
&& !(config.heap instanceof Function)){
|
||||
toss("config.heap must be WebAssembly.Memory instance or a function.");
|
||||
toss("config.heap must be WebAssembly.Memory instance or a function which returns one.");
|
||||
}
|
||||
['alloc','dealloc'].forEach(function(k){
|
||||
(config[k] instanceof Function) ||
|
||||
@@ -48,14 +48,19 @@ globalThis.Jaccwabyt = function StructBinderFactory(config){
|
||||
memberSuffix = (config.memberSuffix || ""),
|
||||
BigInt = globalThis['BigInt'],
|
||||
BigInt64Array = globalThis['BigInt64Array'],
|
||||
bigIntEnabled = config.bigIntEnabled ?? !!BigInt64Array,
|
||||
ptrIR = config.pointerIR
|
||||
|| config.ptrIR/*deprecated*/
|
||||
|| 'i32',
|
||||
/* Undocumented (on purpose) config options: */
|
||||
ptrSize = config.ptrSize/*deprecated*/
|
||||
|| ('i32'===ptrIR ? 4 : 8)
|
||||
;
|
||||
bigIntEnabled = config.bigIntEnabled ?? !!BigInt64Array;
|
||||
|
||||
//console.warn("config",config);
|
||||
let ptr = alloc(1);
|
||||
const ptrIR = config.pointerIR
|
||||
|| config.ptrIR/*deprecated*/
|
||||
|| ('bigint'===typeof ptr ? 'i64' : 'i32');
|
||||
/* Undocumented (on purpose) config options: */
|
||||
const ptrSize = config.ptrSize/*deprecated*/
|
||||
|| ('i32'===ptrIR ? 4 : 8);
|
||||
dealloc(ptr);
|
||||
ptr = undefined;
|
||||
//console.warn("ptrIR =",ptrIR,"ptrSize =",ptrSize);
|
||||
|
||||
if(ptrIR!=='i32' && ptrIR!=='i64') toss("Invalid pointer representation:",ptrIR);
|
||||
if(ptrSize!==4 && ptrSize!==8) toss("Invalid pointer size:",ptrSize);
|
||||
@@ -136,11 +141,11 @@ globalThis.Jaccwabyt = function StructBinderFactory(config){
|
||||
/** True if SIG s looks like a function signature, else
|
||||
false. */
|
||||
const isFuncSig = (s)=>'('===s[1];
|
||||
/** True if SIG s is-a pointer signature. */
|
||||
const isPtrSig = (s)=>'p'===s || 'P'===s;
|
||||
/** True if SIG s is-a pointer-type signature. */
|
||||
const isPtrSig = (s)=>'p'===s || 'P'===s || 's'===s;
|
||||
const isAutoPtrSig = (s)=>'P'===s /*EXPERIMENTAL*/;
|
||||
/** Returns p if SIG s is a function SIG, else returns s[0]. */
|
||||
const sigLetter = (s)=>isFuncSig(s) ? 'p' : s[0];
|
||||
const sigLetter = (s)=>s ? (isFuncSig(s) ? 'p' : s[0]) : undefined;
|
||||
/** Returns the WASM IR form of the Emscripten-conventional letter
|
||||
at SIG s[0]. Throws for an unknown SIG. */
|
||||
const sigIR = function(s){
|
||||
@@ -154,6 +159,19 @@ globalThis.Jaccwabyt = function StructBinderFactory(config){
|
||||
}
|
||||
toss("Unhandled signature IR:",s);
|
||||
};
|
||||
/** Returns the WASM sizeof of the Emscripten-conventional letter
|
||||
at SIG s[0]. Throws for an unknown SIG. */
|
||||
const sigSize = function(s){
|
||||
switch(sigLetter(s)){
|
||||
case 'c': case 'C': return 1;
|
||||
case 'i': return 4;
|
||||
case 'p': case 'P': case 's': return ptrSize;
|
||||
case 'j': return 8;
|
||||
case 'f': return 4;
|
||||
case 'd': return 8;
|
||||
}
|
||||
toss("Unhandled signature sizeof:",s);
|
||||
};
|
||||
|
||||
const affirmBigIntArray = BigInt64Array
|
||||
? ()=>true : ()=>toss('BigInt64Array is not available.');
|
||||
@@ -232,11 +250,22 @@ globalThis.Jaccwabyt = function StructBinderFactory(config){
|
||||
accessible via boundObject.pointer, which is gated behind a
|
||||
property interceptor, but are not exposed anywhere else in the
|
||||
object.
|
||||
|
||||
This approach means we cannot proxy arrays, or any type which
|
||||
might be realloced, as that pointer could change out from under
|
||||
us. That's not an issue for nested structs, but it might be for a
|
||||
struct they're embedded in. In the case of nested structs we
|
||||
"could" record their top-most parent object and their offset into
|
||||
that object, instead of storing the pointer itself. We could that
|
||||
by allowing a function instead of a pointer in this map, that
|
||||
function returning the (lazily-calculated) address. Hmm.
|
||||
*/
|
||||
const __instancePointerMap = new WeakMap();
|
||||
|
||||
const getInstancePtr = (obj)=>__instancePointerMap.get(obj);
|
||||
|
||||
/** Property name for the pointer-is-external marker. */
|
||||
const xPtrPropName = '(pointer-is-external)';
|
||||
const xPtrPropName = Symbol('(pointer-is-external)');
|
||||
|
||||
const __isPtr32 = (ptr)=>('number'===typeof ptr && (ptr===(ptr|0)) && ptr>=0);
|
||||
const __isPtr64 = (ptr)=>(
|
||||
@@ -252,7 +281,7 @@ globalThis.Jaccwabyt = function StructBinderFactory(config){
|
||||
/** Frees the obj.pointer memory and clears the pointer
|
||||
property. */
|
||||
const __freeStruct = function(ctor, obj, m){
|
||||
if(!m) m = __instancePointerMap.get(obj);
|
||||
if(!m) m = getInstancePtr(obj);
|
||||
if(m) {
|
||||
__instancePointerMap.delete(obj);
|
||||
if(Array.isArray(obj.ondispose)){
|
||||
@@ -283,7 +312,12 @@ globalThis.Jaccwabyt = function StructBinderFactory(config){
|
||||
ctor.structName,"instance:",
|
||||
ctor.structInfo.sizeof,"bytes @"+m);
|
||||
}
|
||||
if(!obj[xPtrPropName]) dealloc(m);
|
||||
if(!obj[xPtrPropName]){
|
||||
if( ctor.structInfo.zeroOnFree ){
|
||||
heap().fill(0, Number(m), Number(m)+ctor.structInfo.sizeof);
|
||||
}
|
||||
dealloc(m);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -324,8 +358,69 @@ globalThis.Jaccwabyt = function StructBinderFactory(config){
|
||||
: null;
|
||||
};
|
||||
|
||||
/** True if sig looks like an emscripten/jaccwabyt
|
||||
type signature, else false. */
|
||||
const looksLikeASig = function f(sig){
|
||||
f.rxSig1 ??= /^[ipPsjfdcC]$/;
|
||||
f.rxSig2 ??= /^[vipPsjfdcC]\([ipPsjfdcC]*\)$/;
|
||||
return f.rxSig1.test(sig) || f.rxSig2.test(sig);
|
||||
};
|
||||
|
||||
/** Returns a pair of adaptor maps (objects) in a length-3
|
||||
array specific to the given object. */
|
||||
const __adaptorsFor = function(who){
|
||||
let x = this.get(who);
|
||||
if( !x ){
|
||||
x = [ Object.create(null), Object.create(null), Object.create(null) ];
|
||||
this.set(who, x);
|
||||
}
|
||||
return x;
|
||||
}.bind(new WeakMap);
|
||||
|
||||
/** Code de-duplifier for __adaptGet(), __adaptSet(), and
|
||||
__adaptStruct(). */
|
||||
const __adaptor = function(who, which, key, proxy){
|
||||
const a = __adaptorsFor(who)[which];
|
||||
if(3===arguments.length) return a[key];
|
||||
if( proxy ) return a[key] = proxy;
|
||||
return delete a[key];
|
||||
};
|
||||
|
||||
const noopAdapter = (x)=>x;
|
||||
|
||||
// StructBinder::adaptGet()
|
||||
const __adaptGet = function(key, ...args){
|
||||
/*if( looksLikeASig(key) ){
|
||||
toss("Getter adaptor's name (",key,") collides with a data type signature.");
|
||||
}*/
|
||||
return __adaptor(this, 0, key, ...args);
|
||||
};
|
||||
|
||||
// StructBinder::adaptSet()
|
||||
const __adaptSet = function(key, ...args){
|
||||
if( looksLikeASig(key) ){
|
||||
toss("Setter adaptor's name (",key,") collides with a data type signature.");
|
||||
}
|
||||
return __adaptor(this, 1, key, ...args);
|
||||
};
|
||||
|
||||
// StructBinder::adaptStruct()
|
||||
const __adaptStruct = function(key, ...args){
|
||||
return __adaptor(this, 2, key, ...args);
|
||||
};
|
||||
|
||||
const __adaptStruct2 = function(who,key){
|
||||
const si = ('string'===typeof key)
|
||||
? __adaptor(who, 2, key) : key;
|
||||
if( 'object'!==typeof si ){
|
||||
toss("Invalid struct mapping object. Arg =",key,JSON.stringify(si));
|
||||
}
|
||||
return si;
|
||||
};
|
||||
|
||||
const __memberKey = (k)=>memberPrefix + k + memberSuffix;
|
||||
const __memberKeyProp = rop(__memberKey);
|
||||
//const __adaptGetProp = rop(__adaptGet);
|
||||
|
||||
/**
|
||||
Looks up a struct member in structInfo.members. Throws if found
|
||||
@@ -342,7 +437,8 @@ globalThis.Jaccwabyt = function StructBinderFactory(config){
|
||||
if(v.key===memberName){ m = v; break; }
|
||||
}
|
||||
if(!m && tossIfNotFound){
|
||||
toss(sPropName(structInfo.name,memberName),'is not a mapped struct member.');
|
||||
toss(sPropName(structInfo.name || structInfo.structName, memberName),
|
||||
'is not a mapped struct member.');
|
||||
}
|
||||
}
|
||||
return m;
|
||||
@@ -361,7 +457,7 @@ globalThis.Jaccwabyt = function StructBinderFactory(config){
|
||||
|
||||
const __ptrPropDescriptor = {
|
||||
configurable: false, enumerable: false,
|
||||
get: function(){return __instancePointerMap.get(this)},
|
||||
get: function(){return getInstancePtr(this)},
|
||||
set: ()=>toss("Cannot assign the 'pointer' property of a struct.")
|
||||
// Reminder: leaving `set` undefined makes assignments
|
||||
// to the property _silently_ do nothing. Current unit tests
|
||||
@@ -558,78 +654,176 @@ globalThis.Jaccwabyt = function StructBinderFactory(config){
|
||||
});
|
||||
|
||||
/**
|
||||
Pass this a StructBinder-generated prototype, and the struct
|
||||
member description object. It will define property accessors for
|
||||
proto[memberKey] which read from/write to memory in
|
||||
this.pointer. It modifies descr to make certain downstream
|
||||
operations much simpler.
|
||||
If struct description object si has a getter proxy, return it (a
|
||||
function), else return undefined.
|
||||
*/
|
||||
const makeMemberWrapper = function f(ctor,name, descr){
|
||||
const memberGetterProxy = function(si){
|
||||
return si.get || (si.adaptGet
|
||||
? StructBinder.adaptGet(si.adaptGet)
|
||||
: undefined);
|
||||
};
|
||||
|
||||
/**
|
||||
If struct description object si has a setter proxy, return it (a
|
||||
function), else return undefined.
|
||||
*/
|
||||
const memberSetterProxy = function(si){
|
||||
return si.set || (si.adaptSet
|
||||
? StructBinder.adaptSet(si.adaptSet)
|
||||
: undefined);
|
||||
};
|
||||
|
||||
/**
|
||||
To be called by makeMemberWrapper() when si has a 'members'
|
||||
member, i.e. is an embedded struct. This function sets up that
|
||||
struct like any other and also sets up property accessor for
|
||||
ctor.memberKey(name) which returns an instance of that new
|
||||
StructType when the member is accessed. That instance wraps the
|
||||
memory of the member's part of the containing C struct instance.
|
||||
|
||||
That is, if struct Foo has member bar which is an inner struct
|
||||
then:
|
||||
|
||||
const f = new Foo;
|
||||
const b = f.bar;
|
||||
assert( b is-a StructType object );
|
||||
assert( b.pointer === f.b.pointer );
|
||||
|
||||
b will be disposed of when f() is. Calling b.dispose() will not
|
||||
do any permanent harm, as the wrapper object will be recreated
|
||||
when accessing f.bar, pointing to the same memory in f.
|
||||
|
||||
The si.zeroOnFree flag has no effect on embedded structs because
|
||||
they wrap "external" memory, so do not own it, and are thus never
|
||||
freed, as such.
|
||||
*/
|
||||
const makeMemberStructWrapper = function callee(ctor, name, si){
|
||||
/**
|
||||
Where we store inner-struct member proxies. Keys are a
|
||||
combination of the parent object's pointer address and the
|
||||
property's name. The values are StructType instances.
|
||||
*/
|
||||
const __innerStructs = (callee.innerStructs ??= new Map());
|
||||
const key = ctor.memberKey(name);
|
||||
if( undefined!==si.signature ){
|
||||
toss("'signature' cannot be used on an embedded struct (",
|
||||
ctor.structName,".",key,").");
|
||||
}
|
||||
if( memberSetterProxy(si) ){
|
||||
toss("'set' and 'adaptSet' are not permitted for nested struct members.");
|
||||
}
|
||||
//console.warn("si =",ctor.structName, name, JSON.stringify(si,' '));
|
||||
si.structName ??= ctor.structName+'::'+name;
|
||||
si.key = key;
|
||||
si.name = name;
|
||||
si.constructor = this.call(this, si.structName, si);
|
||||
//console.warn("si.constructor =",si.constructor);
|
||||
//console.warn("si =",si,"ctor=",ctor);
|
||||
const getterProxy = memberGetterProxy(si);
|
||||
const prop = Object.assign(Object.create(null),{
|
||||
configurable: false,
|
||||
enumerable: false,
|
||||
set: __propThrowOnSet(ctor/*not si.constructor*/.structName, key),
|
||||
get: function(){
|
||||
const dbg = si.constructor.prototype.debugFlags.__flags;
|
||||
const p = this.pointer;
|
||||
const k = p+'.'+key;
|
||||
let s = __innerStructs.get(k);
|
||||
if(dbg.getter){ log("debug.getter: k =",k); }
|
||||
if( !s ){
|
||||
s = new si.constructor(__ptrAdd(p, si.offset));
|
||||
__innerStructs.set(k, s);
|
||||
this.addOnDispose(()=>s.dispose());
|
||||
s.addOnDispose(()=>__innerStructs.delete(k));
|
||||
//console.warn("Created",k,"proxy");
|
||||
}
|
||||
if(getterProxy) s = getterProxy.apply(this,[s,key]);
|
||||
if(dbg.getter) log("debug.getter: result =",s);
|
||||
return s;
|
||||
}
|
||||
});
|
||||
Object.defineProperty(ctor.prototype, key, prop);
|
||||
}/*makeMemberStructWrapper()*/;
|
||||
|
||||
/**
|
||||
Pass this a StructBinderImpl-generated constructor, a member
|
||||
property name, and the struct member description object. It will
|
||||
define property accessors for proto[memberKey] which read
|
||||
from/write to memory in this.pointer. It modifies si to make
|
||||
certain downstream operations simpler.
|
||||
*/
|
||||
const makeMemberWrapper = function f(ctor, name, si){
|
||||
si = __adaptStruct2(this, si);
|
||||
if( si.members ){
|
||||
return makeMemberStructWrapper.call(this, ctor, name, si);
|
||||
}
|
||||
|
||||
if(!f._){
|
||||
/*cache all available getters/setters/set-wrappers for
|
||||
direct reuse in each accessor function. */
|
||||
/* Cache all available getters/setters/set-wrappers for
|
||||
direct reuse in each accessor function. */
|
||||
f._ = {getters: {}, setters: {}, sw:{}};
|
||||
const a = ['i','c','C','p','P','s','f','d','v()'];
|
||||
if(bigIntEnabled) a.push('j');
|
||||
a.forEach(function(v){
|
||||
//const ir = sigIR(v);
|
||||
f._.getters[v] = sigDVGetter(v) /* DataView[MethodName] values for GETTERS */;
|
||||
f._.setters[v] = sigDVSetter(v) /* DataView[MethodName] values for SETTERS */;
|
||||
f._.sw[v] = sigDVSetWrapper(v) /* BigInt or Number ctor to wrap around values
|
||||
for conversion */;
|
||||
});
|
||||
const rxSig1 = /^[ipPsjfdcC]$/,
|
||||
rxSig2 = /^[vipPsjfdcC]\([ipPsjfdcC]*\)$/;
|
||||
f.sigCheck = function(obj, name, key,sig){
|
||||
if(Object.prototype.hasOwnProperty.call(obj, key)){
|
||||
toss(obj.structName,'already has a property named',key+'.');
|
||||
}
|
||||
rxSig1.test(sig) || rxSig2.test(sig)
|
||||
looksLikeASig(sig)
|
||||
|| toss("Malformed signature for",
|
||||
sPropName(obj.structName,name)+":",sig);
|
||||
};
|
||||
}
|
||||
const key = ctor.memberKey(name);
|
||||
f.sigCheck(ctor.prototype, name, key, descr.signature);
|
||||
descr.key = key;
|
||||
descr.name = name;
|
||||
const sigGlyph = sigLetter(descr.signature);
|
||||
f.sigCheck(ctor.prototype, name, key, si.signature);
|
||||
si.key = key;
|
||||
si.name = name;
|
||||
const sigGlyph = sigLetter(si.signature);
|
||||
const xPropName = sPropName(ctor.prototype.structName,key);
|
||||
const dbg = ctor.prototype.debugFlags.__flags;
|
||||
/*
|
||||
TODO?: set prototype of descr to an object which can set/fetch
|
||||
TODO?: set prototype of si to an object which can set/fetch
|
||||
its preferred representation, e.g. conversion to string or mapped
|
||||
function. Advantage: we can avoid doing that via if/else if/else
|
||||
in the get/set methods.
|
||||
*/
|
||||
const getterProxy = memberGetterProxy(si);
|
||||
const prop = Object.create(null);
|
||||
prop.configurable = false;
|
||||
prop.enumerable = false;
|
||||
prop.get = function(){
|
||||
if(dbg.getter){
|
||||
log("debug.getter:",f._.getters[sigGlyph],"for", sigIR(sigGlyph),
|
||||
xPropName,'@', this.pointer,'+',descr.offset,'sz',descr.sizeof);
|
||||
xPropName,'@', this.pointer,'+',si.offset,'sz',si.sizeof);
|
||||
}
|
||||
let rc = (
|
||||
new DataView(heap().buffer, Number(this.pointer) + descr.offset, descr.sizeof)
|
||||
new DataView(heap().buffer, Number(this.pointer) + si.offset, si.sizeof)
|
||||
)[f._.getters[sigGlyph]](0, isLittleEndian);
|
||||
if(getterProxy) rc = getterProxy.apply(this,[rc,key]);
|
||||
if(dbg.getter) log("debug.getter:",xPropName,"result =",rc);
|
||||
return rc;
|
||||
};
|
||||
if(descr.readOnly){
|
||||
if(si.readOnly){
|
||||
prop.set = __propThrowOnSet(ctor.prototype.structName,key);
|
||||
}else{
|
||||
const setterProxy = memberSetterProxy(si);
|
||||
prop.set = function(v){
|
||||
if(dbg.setter){
|
||||
log("debug.setter:",f._.setters[sigGlyph],"for", sigIR(sigGlyph),
|
||||
xPropName,'@', this.pointer,'+',descr.offset,'sz',descr.sizeof, v);
|
||||
xPropName,'@', this.pointer,'+',si.offset,'sz',si.sizeof, v);
|
||||
}
|
||||
if(!this.pointer){
|
||||
toss("Cannot set struct property on disposed instance.");
|
||||
toss("Cannot set native property on a disposed struct instance.");
|
||||
}
|
||||
if(null===v) v = __NullPtr;
|
||||
else while(!__isPtr(v)){
|
||||
if(isAutoPtrSig(descr.signature) && (v instanceof StructType)){
|
||||
if( setterProxy ) v = setterProxy.apply(this,[v]);
|
||||
if( null===v || undefined===v ) v = __NullPtr;
|
||||
else while( isPtrSig(si.signature) && !__isPtr(v) ){
|
||||
if(isAutoPtrSig(si.signature) && (v instanceof StructType)){
|
||||
// It's a struct instance: let's store its pointer value!
|
||||
v = v.pointer || __NullPtr;
|
||||
if(dbg.setter) log("debug.setter:",xPropName,"resolved to",v);
|
||||
@@ -638,66 +832,45 @@ globalThis.Jaccwabyt = function StructBinderFactory(config){
|
||||
toss("Invalid value for pointer-type",xPropName+'.');
|
||||
}
|
||||
(
|
||||
new DataView(heap().buffer, Number(this.pointer) + descr.offset,
|
||||
descr.sizeof)
|
||||
new DataView(heap().buffer, Number(this.pointer) + si.offset,
|
||||
si.sizeof)
|
||||
)[f._.setters[sigGlyph]](0, f._.sw[sigGlyph](v), isLittleEndian);
|
||||
};
|
||||
}
|
||||
Object.defineProperty(ctor.prototype, key, prop);
|
||||
}/*makeMemberWrapper*/;
|
||||
}/*makeMemberWrapper()*/;
|
||||
|
||||
/**
|
||||
The main factory function which will be returned to the
|
||||
caller.
|
||||
caller. The third argument is structly for internal use.
|
||||
|
||||
This level of indirection is to avoid that clients can pass a
|
||||
third argument to this, as that's only for internal use.
|
||||
|
||||
internalOpt options:
|
||||
|
||||
- None right now. This is for potential use in recursion.
|
||||
|
||||
Usages:
|
||||
|
||||
StructBinder(string, obj [,optObj]);
|
||||
StructBinder(obj);
|
||||
*/
|
||||
const StructBinder = function StructBinder(structName, structInfo){
|
||||
if(1===arguments.length){
|
||||
structInfo = structName;
|
||||
structName = structInfo.name;
|
||||
}else if(!structInfo.name){
|
||||
structInfo.name = structName;
|
||||
}
|
||||
if(!structName) toss("Struct name is required.");
|
||||
let lastMember = false;
|
||||
Object.keys(structInfo.members).forEach((k)=>{
|
||||
// Sanity checks of sizeof/offset info...
|
||||
const m = structInfo.members[k];
|
||||
if(!m.sizeof) toss(structName,"member",k,"is missing sizeof.");
|
||||
else if(m.sizeof===1){
|
||||
(m.signature === 'c' || m.signature === 'C') ||
|
||||
toss("Unexpected sizeof==1 member",
|
||||
sPropName(structInfo.name,k),
|
||||
"with signature",m.signature);
|
||||
}else{
|
||||
// sizes and offsets of size-1 members may be odd values, but
|
||||
// others may not.
|
||||
if(0!==(m.sizeof%4)){
|
||||
console.warn("Invalid struct member description =",m,"from",structInfo);
|
||||
toss(structName,"member",k,"sizeof is not aligned. sizeof="+m.sizeof);
|
||||
}
|
||||
if(0!==(m.offset%4)){
|
||||
console.warn("Invalid struct member description =",m,"from",structInfo);
|
||||
toss(structName,"member",k,"offset is not aligned. offset="+m.offset);
|
||||
}
|
||||
}
|
||||
if(!lastMember || lastMember.offset < m.offset) lastMember = m;
|
||||
});
|
||||
if(!lastMember) toss("No member property descriptions found.");
|
||||
else if(structInfo.sizeof < lastMember.offset+lastMember.sizeof){
|
||||
toss("Invalid struct config:",structName,
|
||||
"max member offset ("+lastMember.offset+") ",
|
||||
"extends past end of struct (sizeof="+structInfo.sizeof+").");
|
||||
}
|
||||
const debugFlags = rop(SBF.__makeDebugFlags(StructBinder.debugFlags));
|
||||
/** Constructor for the StructCtor. */
|
||||
const zeroAsPtr = __asPtrType(0);
|
||||
const StructBinderImpl = function StructBinderImpl(
|
||||
structName, si, opt = Object.create(null)
|
||||
){
|
||||
/**
|
||||
StructCtor is the eventual return value of this function. We
|
||||
need to populate this early on so that we can do some trickery
|
||||
in feeding it through recursion.
|
||||
*/
|
||||
const StructCtor = function StructCtor(externalMemory){
|
||||
externalMemory = __asPtrType(externalMemory);
|
||||
//console.warn("externalMemory",externalMemory,arguments[0]);
|
||||
if(!(this instanceof StructCtor)){
|
||||
toss("The",structName,"constructor may only be called via 'new'.");
|
||||
}else if(arguments.length){
|
||||
if(Number.isNaN(externalMemory) || externalMemory<=zeroAsPtr){
|
||||
if( !__isPtr(externalMemory) ){
|
||||
toss("Invalid pointer value",arguments[0],"for",structName,"constructor.");
|
||||
}
|
||||
__allocStruct(StructCtor, this, externalMemory);
|
||||
@@ -705,31 +878,127 @@ globalThis.Jaccwabyt = function StructBinderFactory(config){
|
||||
__allocStruct(StructCtor, this);
|
||||
}
|
||||
};
|
||||
const self = this;
|
||||
/**
|
||||
"Convert" struct description x to a struct description, if
|
||||
needed.
|
||||
*/
|
||||
const ads = (x)=>{
|
||||
//console.warn("looksLikeASig(",x,") =",looksLikeASig(x));
|
||||
return (('string'===typeof x) && looksLikeASig(x))
|
||||
? {signature: x} : __adaptStruct2(self,x);
|
||||
};
|
||||
if(1===arguments.length){
|
||||
si = ads(structName);
|
||||
structName = si.structName || si.name;
|
||||
}else if(2===arguments.length){
|
||||
si = ads(si);
|
||||
si.name ??= structName;
|
||||
}else{
|
||||
si = ads(si);
|
||||
}
|
||||
structName ??= si.structName;
|
||||
//console.warn("arguments =",JSON.stringify(arguments));
|
||||
structName ??= opt.structName;
|
||||
if( !structName ) toss("One of 'name' or 'structName' are required.");
|
||||
if( si.adapt ){
|
||||
Object.keys(si.adapt.struct||{}).forEach((k)=>{
|
||||
__adaptStruct.call(StructBinderImpl, k, si.adapt.struct[k]);
|
||||
});
|
||||
Object.keys(si.adapt.set||{}).forEach((k)=>{
|
||||
__adaptSet.call(StructBinderImpl, k, si.adapt.set[k]);
|
||||
});
|
||||
Object.keys(si.adapt.get||{}).forEach((k)=>{
|
||||
__adaptGet.call(StructBinderImpl, k, si.adapt.get[k]);
|
||||
});
|
||||
}
|
||||
if(!si.members && !si.sizeof){
|
||||
si.sizeof = sigSize(si.signature);
|
||||
}
|
||||
|
||||
const debugFlags = rop(SBF.__makeDebugFlags(StructBinder.debugFlags));
|
||||
Object.defineProperties(StructCtor,{
|
||||
debugFlags: debugFlags,
|
||||
isA: rop((v)=>v instanceof StructCtor),
|
||||
memberKey: __memberKeyProp,
|
||||
memberKeys: __structMemberKeys,
|
||||
methodInfoForKey: rop(function(mKey){
|
||||
}),
|
||||
structInfo: rop(structInfo),
|
||||
//methodInfoForKey: rop(function(mKey){/*???*/}),
|
||||
structInfo: rop(si),
|
||||
structName: rop(structName)
|
||||
});
|
||||
StructCtor.prototype = new StructType(structName, structInfo, rop);
|
||||
StructCtor.prototype = new StructType(structName, si, rop);
|
||||
Object.defineProperties(StructCtor.prototype,{
|
||||
debugFlags: debugFlags,
|
||||
constructor: rop(StructCtor)
|
||||
/*if we assign StructCtor.prototype and don't do
|
||||
this then StructCtor!==instance.constructor!*/
|
||||
this then StructCtor!==instance.constructor*/
|
||||
});
|
||||
Object.keys(structInfo.members).forEach(
|
||||
(name)=>makeMemberWrapper(StructCtor, name, structInfo.members[name])
|
||||
);
|
||||
|
||||
|
||||
let lastMember = false;
|
||||
let offset = 0;
|
||||
//console.warn(structName,"si =",si);
|
||||
si.offset ??= 0;
|
||||
Object.keys(si.members || {}).forEach((k)=>{
|
||||
// Sanity checks of sizeof/offset info...
|
||||
let m = ads(si.members[k]);
|
||||
if(!m.members && !m.sizeof){
|
||||
/* ^^^^ fixme: we need to recursively collect all sizeofs
|
||||
before updating that. */
|
||||
m.sizeof = sigSize(m.signature);
|
||||
if(!m.sizeof){
|
||||
toss(sPropName(structName,k), "is missing a sizeof property.",m);
|
||||
}
|
||||
}
|
||||
if( undefined===m.offset ){
|
||||
m.offset = offset;
|
||||
}
|
||||
si.members[k] = m;
|
||||
if(!lastMember || lastMember.offset < m.offset) lastMember = m;
|
||||
makeMemberWrapper.call(self, StructCtor, k, m)
|
||||
offset += m.sizeof;
|
||||
//console.warn("offset",sPropName(structName,k),offset);
|
||||
});
|
||||
|
||||
if( !lastMember ) toss("No member property descriptions found.");
|
||||
if( !si.sizeof ) si.sizeof = offset;
|
||||
if(si.sizeof===1){
|
||||
(si.signature === 'c' || si.signature === 'C') ||
|
||||
toss("Unexpected sizeof==1 member",
|
||||
sPropName(structName,k),
|
||||
"with signature",si.signature);
|
||||
}else{
|
||||
// sizes and offsets of size-1 members may be odd values, but
|
||||
// others may not.
|
||||
if(0!==(si.sizeof%4)){
|
||||
console.warn("Invalid struct member description",si);
|
||||
toss(structName,"sizeof is not aligned. sizeof="+si.sizeof);
|
||||
}
|
||||
if(0!==(si.offset%4)){
|
||||
console.warn("Invalid struct member description",si);
|
||||
toss(structName,"offset is not aligned. offset="+si.offset);
|
||||
}
|
||||
}
|
||||
|
||||
if( si.sizeof < offset ){
|
||||
console.warn("Suspect struct description:",si,"offset =",offset);
|
||||
toss("Mismatch in the calculated vs. the provided sizeof/offset info.",
|
||||
"Expected sizeof",offset,"but got",si.sizeof,"for",si);
|
||||
}
|
||||
return StructCtor;
|
||||
}/*StructBinderImpl*/;
|
||||
|
||||
const StructBinder = function StructBinder(structName, structInfo){
|
||||
return (1==arguments.length)
|
||||
? StructBinderImpl.call(StructBinder, structName)
|
||||
: StructBinderImpl.call(StructBinder, structName, structInfo);
|
||||
};
|
||||
StructBinder.StructType = StructType;
|
||||
StructBinder.config = config;
|
||||
StructBinder.allocCString = __allocCString;
|
||||
StructBinder.adaptGet = __adaptGet;
|
||||
StructBinder.adaptSet = __adaptSet;
|
||||
StructBinder.adaptStruct = __adaptStruct;
|
||||
if(!StructBinder.debugFlags){
|
||||
StructBinder.debugFlags = SBF.__makeDebugFlags(SBF.debugFlags);
|
||||
}
|
||||
|
||||
+4
-1
@@ -98,6 +98,7 @@ tgtFiles=(
|
||||
tester1.js
|
||||
tester1.mjs
|
||||
)
|
||||
tgtFiles+=(jswasm/sqlite3-node.mjs); # https://github.com/sqlite/sqlite-wasm/issues/118
|
||||
|
||||
if [[ 1 = $b64 ]]; then
|
||||
tgtFiles+=(
|
||||
@@ -148,6 +149,7 @@ fJ1=(
|
||||
sqlite3-worker1-promiser.mjs
|
||||
sqlite3-worker1-promiser-bundler-friendly.mjs
|
||||
)
|
||||
fJ1+=(sqlite3-node.mjs); # https://github.com/sqlite/sqlite-wasm/issues/118
|
||||
fJ2=(
|
||||
sqlite3.js
|
||||
sqlite3.mjs
|
||||
@@ -193,8 +195,9 @@ done
|
||||
#
|
||||
# Done copying files. Now zip it up...
|
||||
#
|
||||
svi=${dirTop}/version-info
|
||||
svi=./version-info
|
||||
vnum=$($svi --download-version)
|
||||
[ "" = "$vnum" ] && die "version number is empty!"
|
||||
vdir=${buildName}-${vnum}
|
||||
fzip=${vdir}.zip
|
||||
rm -fr ${vdir} ${fzip}
|
||||
|
||||
+22
-9
@@ -371,7 +371,7 @@ const BuildDefs oBuildDefs = {
|
||||
.node = {
|
||||
.zEmo = "🍟",
|
||||
.zBaseName = "sqlite3-node",
|
||||
.zDotWasm = 0,
|
||||
.zDotWasm = "sqlite3",
|
||||
.zCmppD = "-Dtarget:node $(c-pp.D.bundler)",
|
||||
.zEmcc = 0,
|
||||
.zEmccExtra = 0,
|
||||
@@ -382,21 +382,21 @@ const BuildDefs oBuildDefs = {
|
||||
** node. */,
|
||||
.zDeps = 0,
|
||||
.zIfCond = 0,
|
||||
.flags = CP_ALL | F_UNSUPPORTED | F_NODEJS
|
||||
.flags = CP_ALL | F_UNSUPPORTED | F_ESM | F_NODEJS
|
||||
},
|
||||
|
||||
/* 64-bit node. */
|
||||
.node64 = {
|
||||
.zEmo = "🍔",
|
||||
.zBaseName = "sqlite3-node-64bit",
|
||||
.zDotWasm = 0,
|
||||
.zDotWasm = "sqlite3-64it",
|
||||
.zCmppD = "-Dtarget:node $(c-pp.D.bundler)",
|
||||
.zEmcc = 0,
|
||||
.zEmccExtra = 0,
|
||||
.zEnv = "node",
|
||||
.zDeps = 0,
|
||||
.zIfCond = 0,
|
||||
.flags = CP_ALL | F_UNSUPPORTED | F_NODEJS | F_64BIT
|
||||
.flags = CP_ALL | F_UNSUPPORTED | F_ESM | F_NODEJS | F_64BIT
|
||||
},
|
||||
|
||||
/* Entirely unsupported. */
|
||||
@@ -444,6 +444,11 @@ static void mk_prologue(void){
|
||||
ps("endif");
|
||||
}
|
||||
|
||||
ps("define label.unsupported-build\n"
|
||||
"$(emo.fire)$(emo.fire)$(emo.fire)Unsupported build:"
|
||||
" use at your own risk!\n"
|
||||
"endef");
|
||||
|
||||
ps(zBanner
|
||||
/** $1 = build name */
|
||||
"b.call.wasm-strip = "
|
||||
@@ -624,7 +629,8 @@ static void mk_pre_post(char const *zBuildName, BuildDef const * pB){
|
||||
** Module.instantiateWasm() to use that file instead of
|
||||
** the default.
|
||||
*/
|
||||
pf("$(pre-js.%s.js): $(pre-js.in.js) $(MAKEFILE_LIST)", zBuildName);
|
||||
pf("$(pre-js.%s.js): $(pre-js.in.js) $(bin.c-pp) $(MAKEFILE_LIST)",
|
||||
zBuildName);
|
||||
if( pB->zDotWasm ){
|
||||
pf(" $(dir.dout)/%s.wasm" /* This .wasm is from some other
|
||||
build, so this may trigger a full
|
||||
@@ -658,7 +664,7 @@ static void mk_pre_post(char const *zBuildName, BuildDef const * pB){
|
||||
"))\n",
|
||||
zBuildName, zBuildName, zBuildName, zBuildName);
|
||||
|
||||
pf("$(post-js.%s.js): $(post-js.%s.in)\n",
|
||||
pf("$(post-js.%s.js): $(post-js.%s.in) $(bin.c-pp)\n",
|
||||
zBuildName, zBuildName);
|
||||
|
||||
ps("\n# --extern-post-js=...");
|
||||
@@ -778,6 +784,9 @@ static void mk_lib_mode(const char *zBuildName, const BuildDef * pB){
|
||||
if( pB->flags & F_64BIT ){
|
||||
pf("c-pp.D.%s += $(c-pp.D.64bit)\n", zBuildName);
|
||||
}
|
||||
if( pB->flags & F_UNSUPPORTED ){
|
||||
pf("c-pp.D.%s += -Dunsupported-build\n", zBuildName);
|
||||
}
|
||||
|
||||
pf("emcc.environment.%s ?= %s\n", zBuildName,
|
||||
pB->zEnv ? pB->zEnv : oBuildDefs.vanilla.zEnv);
|
||||
@@ -803,8 +812,8 @@ static void mk_lib_mode(const char *zBuildName, const BuildDef * pB){
|
||||
emit_compile_start(zBuildName);
|
||||
|
||||
if( F_UNSUPPORTED & pB->flags ){
|
||||
pf("\t@echo '$(logtag.%s) $(emo.fire)$(emo.fire)$(emo.fire): "
|
||||
"unsupported build. Use at your own risk.'\n", zBuildName);
|
||||
pf("\t@echo '$(logtag.%s) $(label.unsupported-build)'\n",
|
||||
zBuildName);
|
||||
}
|
||||
|
||||
/* emcc ... */
|
||||
@@ -900,7 +909,11 @@ static void mk_lib_mode(const char *zBuildName, const BuildDef * pB){
|
||||
|
||||
}
|
||||
}
|
||||
pf("\t@$(call b.echo,%s,$(emo.done) done!)\n", zBuildName);
|
||||
pf("\t@$(call b.echo,%s,$(emo.done) done!%s)\n",
|
||||
zBuildName,
|
||||
(F_UNSUPPORTED & pB->flags)
|
||||
? " $(label.unsupported-build)"
|
||||
: "");
|
||||
|
||||
pf("\n%dbit: $(out.%s.js)\n"
|
||||
"$(out.%s.wasm): $(out.%s.js)\n"
|
||||
|
||||
@@ -12,11 +12,19 @@
|
||||
</head>
|
||||
<body>
|
||||
<h1 id='color-target'>sqlite3 tester #1: Worker thread (@bitness@-bit WASM)</h1>
|
||||
<div>Variants:
|
||||
<a href='tester1.html' target='tester1.html'>conventional UI thread</a>,
|
||||
<a href='tester1-worker.html' target='tester1-worker.html'>conventional worker</a>,
|
||||
<a href='tester1-esm.html' target='tester1-esm.html'>ESM in UI thread</a>,
|
||||
<a href='tester1-worker.html?esm' target='tester1-worker.html?esm'>ESM worker</a>
|
||||
<div>Variants (32-bit):
|
||||
conventional UI thread:
|
||||
(<a href='tester1.html' target='tester1.html'>32-bit</a>,
|
||||
<a href='tester1-64bit.html' target='tester1-64bit.html'>64-bit</a>),
|
||||
conventional worker:
|
||||
(<a href='tester1-worker.html' target='tester1-worker.html'>32-bit</a>,
|
||||
<a href='tester1-worker-64bit.html' target='tester1-worker-64bit.html'>64-bit</a>),
|
||||
ESM in UI thread:
|
||||
(<a href='tester1-esm.html' target='tester1-esm.html'>32-bit</a>,
|
||||
<a href='tester1-esm-64bit.html' target='tester1-esm-64bit.html'>64-bit</a>),
|
||||
ESM worker:</a>
|
||||
(<a href='tester1-worker.html?esm' target='tester1-worker.html?esm'>32-bit</a>
|
||||
<a href='tester1-worker-64bit.html?esm' target='tester1-worker-64bit.html?esm'>64-bit</a>)
|
||||
</div>
|
||||
<div class='input-wrapper'>
|
||||
<input type='checkbox' id='cb-log-reverse'>
|
||||
|
||||
@@ -11,11 +11,19 @@
|
||||
<style></style>
|
||||
</head>
|
||||
<body><h1 id='color-target'></h1>
|
||||
<div>Variants:
|
||||
<a href='tester1.html' target='tester1.html'>conventional UI thread</a>,
|
||||
<a href='tester1-worker.html' target='tester1-worker.html'>conventional worker</a>,
|
||||
<a href='tester1-esm.html' target='tester1-esm.html'>ESM in UI thread</a>,
|
||||
<a href='tester1-worker.html?esm' target='tester1-worker.html?esm'>ESM worker</a>
|
||||
<div>Variants (32-bit):
|
||||
conventional UI thread:
|
||||
(<a href='tester1.html' target='tester1.html'>32-bit</a>,
|
||||
<a href='tester1-64bit.html' target='tester1-64bit.html'>64-bit</a>),
|
||||
conventional worker:
|
||||
(<a href='tester1-worker.html' target='tester1-worker.html'>32-bit</a>,
|
||||
<a href='tester1-worker-64bit.html' target='tester1-worker-64bit.html'>64-bit</a>),
|
||||
ESM in UI thread:
|
||||
(<a href='tester1-esm.html' target='tester1-esm.html'>32-bit</a>,
|
||||
<a href='tester1-esm-64bit.html' target='tester1-esm-64bit.html'>64-bit</a>),
|
||||
ESM worker:</a>
|
||||
(<a href='tester1-worker.html?esm' target='tester1-worker.html?esm'>32-bit</a>
|
||||
<a href='tester1-worker-64bit.html?esm' target='tester1-worker-64bit.html?esm'>64-bit</a>)
|
||||
</div>
|
||||
<div class='input-wrapper'>
|
||||
<input type='checkbox' id='cb-log-reverse'>
|
||||
|
||||
+182
-105
@@ -369,6 +369,88 @@ globalThis.sqlite3InitModule = sqlite3InitModule;
|
||||
clearOnInit: true,
|
||||
initialCapacity: 6
|
||||
};
|
||||
|
||||
//#if enable-see
|
||||
/**
|
||||
Code consolidator for SEE sanity checks for various VFSes. ctor
|
||||
is the VFS's oo1.DB-type constructor. ctorOptFunc(bool) is a
|
||||
function which must return a constructor args object for ctor. It
|
||||
is passed true if the db needs to be cleaned up/unlinked before
|
||||
opening it (OPFS) and false if not (how that is done is
|
||||
VFS-dependent). dbUnlink is a function which is expected to
|
||||
unlink() the db file if the ctorOpfFunc does not do so when
|
||||
passed true (kvvfs).
|
||||
|
||||
This function initializes the db described by ctorOptFunc(...),
|
||||
writes some secret info into it, and re-opens it twice to
|
||||
confirmi that it can be read with an SEE key and cannot be read
|
||||
without one.
|
||||
*/
|
||||
T.seeBaseCheck = function(ctor, ctorOptFunc, dbUnlink){
|
||||
let initDb = true;
|
||||
const tryKey = function(keyKey, key, expectCount){
|
||||
let db;
|
||||
//console.debug('tryKey()',arguments);
|
||||
try {
|
||||
if (initDb) {
|
||||
const ctoropt = ctorOptFunc(initDb);
|
||||
initDb = false;
|
||||
db = new ctor({
|
||||
...ctoropt,
|
||||
[keyKey]: key
|
||||
});
|
||||
db.exec([
|
||||
"drop table if exists t;",
|
||||
"create table t(a);"
|
||||
]);
|
||||
db.close();
|
||||
db = null;
|
||||
// Ensure that it's actually encrypted...
|
||||
let err;
|
||||
try {
|
||||
db = new ctor(ctorOptFunc(false));
|
||||
T.assert(db, 'db opened') /* opening is fine, but... */;
|
||||
db.exec("select 1 from sqlite_schema");
|
||||
console.warn("(should not be reached) sessionStorage =", sessionStorage);
|
||||
} catch (e) {
|
||||
err = e;
|
||||
} finally {
|
||||
db.close()
|
||||
db = null;
|
||||
}
|
||||
T.assert(err, "Expecting an exception")
|
||||
.assert(capi.SQLITE_NOTADB == err.resultCode,
|
||||
"Expecting NOTADB");
|
||||
}/*initDb*/
|
||||
db = new ctor({
|
||||
...ctorOptFunc(false),
|
||||
[keyKey]: key
|
||||
});
|
||||
db.exec("insert into t(a) values (1),(2)");
|
||||
T.assert(expectCount === db.selectValue('select sum(a) from t'));
|
||||
} finally {
|
||||
if (db) db.close();
|
||||
}
|
||||
};
|
||||
const hexFoo = new Uint8Array([0x66,0x6f,0x6f]/*=="foo"*/);
|
||||
dbUnlink();
|
||||
tryKey('textkey', 'foo', 3);
|
||||
T.assert( !initDb );
|
||||
tryKey('textkey', 'foo', 6);
|
||||
dbUnlink();
|
||||
initDb = true;
|
||||
tryKey('key', 'foo', 3);
|
||||
T.assert( !initDb );
|
||||
tryKey('key', hexFoo, 6);
|
||||
dbUnlink();
|
||||
initDb = true;
|
||||
tryKey('hexkey', hexFoo, 3);
|
||||
T.assert( !initDb );
|
||||
tryKey('hexkey', hexFoo, 6);
|
||||
dbUnlink();
|
||||
},
|
||||
//#endif enable-see
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// End of infrastructure setup. Now define the tests...
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
@@ -945,7 +1027,7 @@ globalThis.sqlite3InitModule = sqlite3InitModule;
|
||||
let ptr = k1.pointer;
|
||||
k1.dispose();
|
||||
T.assert(undefined === k1.pointer).
|
||||
mustThrowMatching(()=>{k1.$pP=1}, /disposed instance/);
|
||||
mustThrowMatching(()=>{k1.$pP=1}, /disposed struct instance/);
|
||||
}finally{
|
||||
k1.dispose();
|
||||
k2.dispose();
|
||||
@@ -1353,7 +1435,7 @@ globalThis.sqlite3InitModule = sqlite3InitModule;
|
||||
})/*oo1.DB/Stmt.wrapHandle()*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
.t('sqlite3_db_config() and sqlite3_db_status()', function(sqlite3){
|
||||
.t('sqlite3_db_config() and sqlite3_status()', function(sqlite3){
|
||||
let rc = capi.sqlite3_db_config(this.db, capi.SQLITE_DBCONFIG_LEGACY_ALTER_TABLE, 0, 0);
|
||||
T.assert(0===rc);
|
||||
rc = capi.sqlite3_db_config(this.db, capi.SQLITE_DBCONFIG_MAX+1, 0);
|
||||
@@ -1549,6 +1631,9 @@ globalThis.sqlite3InitModule = sqlite3InitModule;
|
||||
T.assert(blob instanceof Uint8Array).
|
||||
assert(0x68===blob[0] && 0x69===blob[1]);
|
||||
blob = null;
|
||||
blob = db.selectValue("select ?1", new Uint8Array([97,0,98,0,99]),
|
||||
sqlite3.capi.SQLITE_TEXT);
|
||||
T.assert("a\0b\0c"===blob, "Something is amiss with embedded NULs");
|
||||
let counter = 0, colNames = [];
|
||||
list.length = 0;
|
||||
db.exec(new TextEncoder('utf-8').encode("SELECT a a, b b FROM t"),{
|
||||
@@ -2836,71 +2921,9 @@ globalThis.sqlite3InitModule = sqlite3InitModule;
|
||||
predicate: ()=>(isUIThread()
|
||||
|| "Only available in main thread."),
|
||||
test: function(sqlite3){
|
||||
this.kvvfsUnlink();
|
||||
let initDb = true;
|
||||
const tryKey = function(keyKey, key, expectCount){
|
||||
let db;
|
||||
//console.debug('tryKey()',arguments);
|
||||
const ctoropt = {
|
||||
filename: this.kvvfsDbFile
|
||||
//vfs: 'kvvfs'
|
||||
//,flags: 'ct'
|
||||
};
|
||||
try {
|
||||
if (initDb) {
|
||||
initDb = false;
|
||||
db = new this.JDb({
|
||||
...ctoropt,
|
||||
[keyKey]: key
|
||||
});
|
||||
db.exec([
|
||||
"drop table if exists t;",
|
||||
"create table t(a);"
|
||||
]);
|
||||
db.close();
|
||||
// Ensure that it's actually encrypted...
|
||||
let err;
|
||||
try {
|
||||
db = new this.JDb(ctoropt);
|
||||
T.assert(db, 'db opened') /* opening is fine, but... */;
|
||||
db.exec("select 1 from sqlite_schema");
|
||||
console.warn("(should not be reached) sessionStorage =", sessionStorage);
|
||||
} catch (e) {
|
||||
err = e;
|
||||
} finally {
|
||||
db.close()
|
||||
}
|
||||
T.assert(err, "Expecting an exception")
|
||||
.assert(sqlite3.capi.SQLITE_NOTADB == err.resultCode,
|
||||
"Expecting NOTADB");
|
||||
}/*initDb*/
|
||||
//console.debug('tryKey()',arguments);
|
||||
db = new sqlite3.oo1.DB({
|
||||
...ctoropt,
|
||||
vfs: 'kvvfs',
|
||||
[keyKey]: key
|
||||
});
|
||||
db.exec("insert into t(a) values (1),(2)");
|
||||
T.assert(expectCount === db.selectValue('select sum(a) from t'));
|
||||
} finally {
|
||||
if (db) db.close();
|
||||
}
|
||||
}.bind(this);
|
||||
const hexFoo = new Uint8Array([0x66,0x6f,0x6f]/*=="foo"*/);
|
||||
tryKey('textkey', 'foo', 3);
|
||||
T.assert( !initDb );
|
||||
tryKey('textkey', 'foo', 6);
|
||||
this.kvvfsUnlink();
|
||||
initDb = true;
|
||||
tryKey('key', 'foo', 3);
|
||||
T.assert( !initDb );
|
||||
tryKey('key', hexFoo, 6);
|
||||
this.kvvfsUnlink();
|
||||
initDb = true;
|
||||
tryKey('hexkey', hexFoo, 3);
|
||||
T.assert( !initDb );
|
||||
tryKey('hexkey', hexFoo, 6);
|
||||
this.kvvfsUnlink();
|
||||
T.seeBaseCheck(sqlite3.oo1.JsStorageDb, (isInit)=>{
|
||||
return {filename: "session"};
|
||||
}, ()=>this.kvvfsUnlink());
|
||||
}
|
||||
})/*kvvfs with SEE*/
|
||||
//#endif enable-see
|
||||
@@ -3311,6 +3334,21 @@ globalThis.sqlite3InitModule = sqlite3InitModule;
|
||||
"entryExists(",testDir,") should have failed");
|
||||
}
|
||||
}/*OPFS util sanity checks*/)
|
||||
//#if enable-see
|
||||
.t({
|
||||
name: 'OPFS with SEE encryption',
|
||||
test: function(sqlite3){
|
||||
T.seeBaseCheck(
|
||||
sqlite3.oo1.OpfsDb,
|
||||
function(isInit){
|
||||
const opt = {filename: 'file:///sqlite3-see.edb'};
|
||||
if( isInit ) opt.filename += '?delete-before-open=1';
|
||||
return opt;
|
||||
},
|
||||
()=>{});
|
||||
}
|
||||
})/*OPFS with SEE*/
|
||||
//#endif enable-see
|
||||
;/* end OPFS tests */
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
@@ -3492,7 +3530,36 @@ globalThis.sqlite3InitModule = sqlite3InitModule;
|
||||
.assert(true === await u3.removeVfs())
|
||||
.assert(false === await P3b.removeVfs());
|
||||
}
|
||||
}/*OPFS SAH Pool sanity checks*/);
|
||||
}/*OPFS SAH Pool sanity checks*/)
|
||||
//#if enable-see
|
||||
.t({
|
||||
name: 'OPFS SAHPool with SEE encryption',
|
||||
test: async function(sqlite3){
|
||||
const inst = sqlite3.installOpfsSAHPoolVfs,
|
||||
catcher = (e)=>{
|
||||
error("Cannot load SAH pool VFS.",
|
||||
"This might not be a problem,",
|
||||
"depending on the environment.");
|
||||
return false;
|
||||
};
|
||||
const poolConfig = {
|
||||
name: 'opfs-sahpool-see',
|
||||
clearOnInit: true,
|
||||
initialCapacity: 6
|
||||
}
|
||||
let poolUtil;
|
||||
const P1 = await inst(poolConfig).then(u=>poolUtil = u).catch(catcher);
|
||||
const dbFile = '/sqlite3-see.edb';
|
||||
T.seeBaseCheck(
|
||||
poolUtil.OpfsSAHPoolDb,
|
||||
(isInit)=>{return {filename: dbFile}},
|
||||
()=>poolUtil.unlink(dbFile)
|
||||
);
|
||||
poolUtil.removeVfs();
|
||||
}
|
||||
})/*opfs-sahpool with SEE*/
|
||||
//#endif enable-see
|
||||
;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
T.g('Misc. APIs')
|
||||
@@ -3556,44 +3623,54 @@ globalThis.sqlite3InitModule = sqlite3InitModule;
|
||||
.t("Misc. stmt_...", function(sqlite3){
|
||||
const db = new sqlite3.oo1.DB();
|
||||
db.exec("create table t(a doggiebiscuits); insert into t(a) values(123)");
|
||||
const stmt = db.prepare("select a, a+1 from t");
|
||||
T.assert( stmt.isReadOnly() )
|
||||
.assert( 0===capi.sqlite3_stmt_isexplain(stmt) )
|
||||
.assert( 0===capi.sqlite3_stmt_explain(stmt, 1) )
|
||||
.assert( 0!==capi.sqlite3_stmt_isexplain(stmt) )
|
||||
.assert( 0===capi.sqlite3_stmt_explain(stmt, 2) )
|
||||
.assert( 0!==capi.sqlite3_stmt_isexplain(stmt) )
|
||||
.assert( 0===capi.sqlite3_stmt_explain(stmt, 0) )
|
||||
.assert( 0===capi.sqlite3_stmt_isexplain(stmt) );
|
||||
let n = 0;
|
||||
while( capi.SQLITE_ROW === capi.sqlite3_step(stmt) ){
|
||||
++n;
|
||||
T.assert( 0!==capi.sqlite3_stmt_explain(stmt, 1),
|
||||
"Because stmt is busy" )
|
||||
.assert( capi.sqlite3_stmt_busy(stmt) )
|
||||
.assert( stmt.isBusy() )
|
||||
.assert( 0!==capi.sqlite3_stmt_readonly(stmt) )
|
||||
.assert( true===stmt.isReadOnly() );
|
||||
const sv = capi.sqlite3_column_value(stmt, 0);
|
||||
T.assert( 123===capi.sqlite3_value_int(sv) )
|
||||
.assert( "doggiebiscuits"===capi.sqlite3_column_decltype(stmt,0) )
|
||||
.assert( null===capi.sqlite3_column_decltype(stmt,1) );
|
||||
let stmt;
|
||||
try{
|
||||
stmt = db.prepare("select a, a+1 from t");
|
||||
T.assert( stmt.isReadOnly() )
|
||||
.assert( 0===capi.sqlite3_stmt_isexplain(stmt) )
|
||||
.assert( 0===capi.sqlite3_stmt_explain(stmt, 1) )
|
||||
.assert( 0!==capi.sqlite3_stmt_isexplain(stmt) )
|
||||
.assert( 0===capi.sqlite3_stmt_explain(stmt, 2) )
|
||||
.assert( 0!==capi.sqlite3_stmt_isexplain(stmt) )
|
||||
.assert( 0===capi.sqlite3_stmt_explain(stmt, 0) )
|
||||
.assert( 0===capi.sqlite3_stmt_isexplain(stmt) );
|
||||
let n = 0;
|
||||
while( capi.SQLITE_ROW === capi.sqlite3_step(stmt) ){
|
||||
++n;
|
||||
T.assert( 0!==capi.sqlite3_stmt_explain(stmt, 1),
|
||||
"Because stmt is busy" )
|
||||
.assert( capi.sqlite3_stmt_busy(stmt) )
|
||||
.assert( stmt.isBusy() )
|
||||
.assert( 0!==capi.sqlite3_stmt_readonly(stmt) )
|
||||
.assert( true===stmt.isReadOnly() );
|
||||
const sv = capi.sqlite3_column_value(stmt, 0);
|
||||
T.assert( 123===capi.sqlite3_value_int(sv) )
|
||||
.assert( "doggiebiscuits"===capi.sqlite3_column_decltype(stmt,0) )
|
||||
.assert( null===capi.sqlite3_column_decltype(stmt,1) );
|
||||
}
|
||||
T.assert( 1===n )
|
||||
.assert( 0===capi.sqlite3_stmt_busy(stmt) )
|
||||
.assert( !stmt.isBusy() );
|
||||
|
||||
if( wasm.exports.sqlite3_column_origin_name ){
|
||||
log("Column metadata APIs enabled");
|
||||
T.assert( "t" === capi.sqlite3_column_table_name(stmt, 0))
|
||||
.assert("a" === capi.sqlite3_column_origin_name(stmt, 0))
|
||||
.assert("main" === capi.sqlite3_column_database_name(stmt, 0))
|
||||
}else{
|
||||
log("Column metadata APIs not enabled");
|
||||
} // column metadata APIs
|
||||
stmt.finalize();
|
||||
stmt = null;
|
||||
stmt = db.prepare("select ?1").bind(new Uint8Array([97,0,98,0,99]));
|
||||
stmt.step();
|
||||
const sv = capi.sqlite3_column_value(stmt,0);
|
||||
T.assert("a\0b\0c"===capi.sqlite3_value_text(sv),
|
||||
"Expecting NULs to have survived.");
|
||||
}finally{
|
||||
if(stmt) stmt.finalize();
|
||||
db.close();
|
||||
}
|
||||
T.assert( 1===n )
|
||||
.assert( 0===capi.sqlite3_stmt_busy(stmt) )
|
||||
.assert( !stmt.isBusy() );
|
||||
|
||||
if( wasm.exports.sqlite3_column_origin_name ){
|
||||
log("Column metadata APIs enabled");
|
||||
T.assert( "t" === capi.sqlite3_column_table_name(stmt, 0))
|
||||
.assert("a" === capi.sqlite3_column_origin_name(stmt, 0))
|
||||
.assert("main" === capi.sqlite3_column_database_name(stmt, 0))
|
||||
}else{
|
||||
log("Column metadata APIs not enabled");
|
||||
} // column metadata APIs
|
||||
|
||||
stmt.finalize();
|
||||
db.close();
|
||||
})
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -952,25 +952,6 @@ FUZZDATA = \
|
||||
#
|
||||
TESTOPTS = --verbose=file --output=test-out.txt
|
||||
|
||||
#
|
||||
# Extra compiler options for various shell tools
|
||||
#
|
||||
# Note that some of these will only apply when embedding sqlite3.c
|
||||
# into the shell, as these flags are not otherwise passed on to the
|
||||
# library.
|
||||
SHELL_OPT += -DSQLITE_DQS=0
|
||||
SHELL_OPT += -DSQLITE_ENABLE_FTS4
|
||||
#SHELL_OPT += -DSQLITE_ENABLE_FTS5
|
||||
SHELL_OPT += -DSQLITE_ENABLE_RTREE
|
||||
SHELL_OPT += -DSQLITE_ENABLE_EXPLAIN_COMMENTS
|
||||
SHELL_OPT += -DSQLITE_ENABLE_UNKNOWN_SQL_FUNCTION
|
||||
SHELL_OPT += -DSQLITE_ENABLE_STMTVTAB
|
||||
SHELL_OPT += -DSQLITE_ENABLE_DBPAGE_VTAB
|
||||
SHELL_OPT += -DSQLITE_ENABLE_DBSTAT_VTAB
|
||||
SHELL_OPT += -DSQLITE_ENABLE_BYTECODE_VTAB
|
||||
SHELL_OPT += -DSQLITE_ENABLE_OFFSET_SQL_FUNC
|
||||
SHELL_OPT += -DSQLITE_ENABLE_PERCENTILE
|
||||
SHELL_OPT += -DSQLITE_STRICT_SUBTYPE=1
|
||||
FUZZERSHELL_OPT =
|
||||
FUZZCHECK_OPT += -I$(TOP)/test
|
||||
FUZZCHECK_OPT += -I$(TOP)/ext/recover
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
C Merge\strunk\sinto\sthe\scygwin-fixes\sbranch.\sWith\stcl9\sthis\spasses\sall\sbut\sone\stest,\swhich\sfails\swith:\serror\scopying\s...:\sNo\serror
|
||||
D 2025-10-11T20:06:54.784
|
||||
C Re-add\sthe\s(still)\sunsupported\sand\s(still\s100%)\suntested\ssqlite3-node.mjs\sback\sto\sthe\sdist\sbundle,\sas\sits\sremoval\sin\s3.51\shas\s[caused\ssome\sdownstream\sdisruption](https://github.com/sqlite/sqlite-wasm/issues/118).\sThis\sis\sstashed\sin\sa\sbranch\sfor\snow\sand\smay\snever\sbe\smerged\s-\swe're\sstill\snegotiating\sthe\sterms\sof\sits\sre-addition\sand\smy\seventual\scapitulation.
|
||||
D 2025-11-13T08:36:52.956
|
||||
F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x
|
||||
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
|
||||
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
|
||||
F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d
|
||||
F LICENSE.md 6bc480fc673fb4acbc4094e77edb326267dd460162d7723c7f30bee2d3d9e97d
|
||||
F Makefile.in 3ce07126d7e87c7464301482e161fdae6a51d0a2aa06b200b8f0000ef4d6163b
|
||||
F Makefile.linux-generic bd3e3cacd369821a6241d4ea1967395c962dfe3057e38cb0a435cee0e8b789d0
|
||||
F Makefile.msc 8dd676302f3165984c046f81af14b6676a334418fa30255efaf439f8033042fa
|
||||
F README.md e28077cfbef795e99c9c75ed95aa7257a1166709b562076441a8506ac421b7c1
|
||||
F Makefile.msc 523bab2f6569e912a0aaf2d13e0b3f9bcb36d52310b236d950b354068c9de3f3
|
||||
F README.md dae499194b75deed76a13a4a83c82493f2530331882d7dfe5754d63287d3f8f7
|
||||
F VERSION 16eddb43056a79c1977427ab7a05f3457c373fa159dcdced8754eb89ce7e06b8
|
||||
F art/icon-243x273.gif 9750b734f82fdb3dc43127753d5e6fbf3b62c9f4e136c2fbf573b2f57ea87af5
|
||||
F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d87031
|
||||
@@ -22,7 +22,7 @@ F autoconf/Makefile.msc 803aa9e23b6a764751f6a91d0673620eefa46729fb80faf51391120e
|
||||
F autoconf/README.first f1d3876e9a7852c22f275a6f06814e64934cecbc0b5b9617d64849094c1fd136
|
||||
F autoconf/README.txt b749816b8452b3af994dc6d607394bef3df1736d7e09359f1087de8439a52807
|
||||
F autoconf/auto.def 3d994f3a9cc9b712dbce92a5708570ddcf3b988141b6eb738f2ed16127a9f0ac
|
||||
F autoconf/tea/Makefile.in bf6b43eafcd18766d81a8f0085cfc9cb051d8abae9031a8e7c3f5f1246e8f166
|
||||
F autoconf/tea/Makefile.in 00e60cf3bf5580f31bfdcf3c914e9ba1831d676948363962de92ce65e5be4431
|
||||
F autoconf/tea/README.txt 23475876343498ef2b514cc7510e8f1559a17e8e03fbc7a41c1c8a3b89e7b7e3
|
||||
F autoconf/tea/_teaish.tester.tcl.in 8253b44be88e2e3f21de95a65d3a90c2be8e70b7bdd08a5b80e337ba7402f8f1
|
||||
F autoconf/tea/auto.def ce95b9450e2fa4ba5dc857e208fe10f4e6f2d737796ac3278aee6079db417529
|
||||
@@ -46,18 +46,18 @@ F autosetup/cc.tcl c0fcc50ca91deff8741e449ddad05bcd08268bc31177e613a6343bbd1fd3e
|
||||
F autosetup/find_tclconfig.tcl e64886ffe3b982d4df42cd28ed91fe0b5940c2c5785e126c1821baf61bc86a7e
|
||||
F autosetup/jimsh0.c a57c16e65dcffc9c76e496757cb3f7fb47e01ecbd1631a0a5e01751fc856f049
|
||||
F autosetup/pkg-config.tcl 4e635bf39022ff65e0d5434339dd41503ea48fc53822c9c5bde88b02d3d952ba
|
||||
F autosetup/proj.tcl ec30c4bc301b6e9eb937655744a7315f863f804fc66400d975bcf9352ac96a1d
|
||||
F autosetup/sqlite-config.tcl 2e3c81148c78e0340544662bdb448b2ea02cc2acb6a93d4c00949b7a3c8a486e
|
||||
F autosetup/proj.tcl 6fc14ef82b19b77a95788ffbcfad7989b4e3cb4ce96a21dcb5cf7312f362fba9
|
||||
F autosetup/sqlite-config.tcl 1fd7c55394051fbfba2fb9fa9192c027ee7d74612dbf772b06e27feb9f1de5df
|
||||
F autosetup/system.tcl 51d4be76cd9a9074704b584e5c9cbba616202c8468cf9ba8a4f8294a7ab1dba9
|
||||
F autosetup/teaish/README.txt b40071e6f8506500a2f7f71d5fc69e0bf87b9d7678dd9da1e5b4d0acbf40b1ca
|
||||
F autosetup/teaish/core.tcl aee092fc71986d1272b835ea7492bb55ffc213a289502e4f14da80cf67b7e3c3
|
||||
F autosetup/teaish/core.tcl e014dd95900c7f9a34e8e0f460f47e94841059827bce8b4c49668b0c7ae3f1a0
|
||||
F autosetup/teaish/feature.tcl 18194fb79a24d30e5bbdeab40999616f39278b53a27525349ded033af2fd73be
|
||||
F autosetup/teaish/tester.tcl 1799514c2652db49561b3386c5242b94534d1663f2cfac861a955e071895fdd0
|
||||
F configure 9a00b21dfd13757bbfb8d89b30660a89ec1f8f3a79402b8f9f9b6fc475c3303a x
|
||||
F contrib/sqlitecon.tcl eb4c6578e08dd353263958da0dc620f8400b869a50d06e271ab0be85a51a08d3
|
||||
F doc/F2FS.txt c1d4a0ae9711cfe0e1d8b019d154f1c29e0d3abfe820787ba1e9ed7691160fcd
|
||||
F doc/compile-for-unix.md c9dce1ddd4bf0d25efccc5c63eb047e78c01ce06a6ff29c73e0a8af4a0f4adbc
|
||||
F doc/compile-for-windows.md 5141661e783c9ca9e3fd30e813345898712f5c311d71316f183db87038fa28a6
|
||||
F doc/compile-for-windows.md f9e74d74da88f384edd5809f825035e071608f00f7f39c0e448df7b3982f979c
|
||||
F doc/json-enhancements.md e356fc834781f1f1aa22ee300027a270b2c960122468499bf347bb123ce1ea4f
|
||||
F doc/jsonb.md acd77fc3a709f51242655ad7803510c886aa8304202fa9cf2abc5f5c4e9d7ae5
|
||||
F doc/lemon.html 89ea833a6f71773ab1a9063fbb7fb9b32147bc0b1057b53ecab94a3b30c0aef5
|
||||
@@ -72,7 +72,7 @@ F ext/README.md 6eb1ac267d917767952ed0ef63f55de003b6a5da433ce1fa389e1a9532e73132
|
||||
F ext/expert/README.md b321c2762bb93c18ea102d5a5f7753a4b8bac646cb392b3b437f633caf2020c3
|
||||
F ext/expert/expert.c d548d603a4cc9e61f446cc179c120c6713511c413f82a4a32b1e1e69d3f086a4
|
||||
F ext/expert/expert1.test 1d2da6606623b57bb47064e02140823ce1daecd4cacbf402c73ad3473d7f000c
|
||||
F ext/expert/sqlite3expert.c cf4b1e5584862f486a4c6014ddb081831f1c512065dcf35644638d57179979d6
|
||||
F ext/expert/sqlite3expert.c 546010043fbec93544f762de5161b3d553165859e6bd853c4b85c05f93484260
|
||||
F ext/expert/sqlite3expert.h ca81efc2679a92373a13a3e76a6138d0310e32be53d6c3bfaedabd158ea8969b
|
||||
F ext/expert/test_expert.c c395134bd6d4efa594a7d26578a1cb624c4027b79b4b5fcd44736c5ef1f5f725
|
||||
F ext/fts3/README.content b9078d0843a094d86af0d48dffbff13c906702b4c3558012e67b9c7cc3bf59ee
|
||||
@@ -113,7 +113,7 @@ F ext/fts5/fts5_buffer.c f1e6d0324d7c55329d340673befc26681a372a4d36086caa8d1ec7d
|
||||
F ext/fts5/fts5_config.c e7d8dd062b44a66cd77e5a0f74f23a2354cd1f3f8575afb967b2773c3384f7f8
|
||||
F ext/fts5/fts5_expr.c b8c32da1127bafaf10d6b4768b0dcb92285798524bed2d87a8686f99a8e8d259
|
||||
F ext/fts5/fts5_hash.c a6266cedd801ab7964fa9e74ebcdda6d30ec6a96107fa24148ec6b7b5b80f6e0
|
||||
F ext/fts5/fts5_index.c 1e5009261966215b61bbe3b46d79916346efac775b57c1487a478f684c971111
|
||||
F ext/fts5/fts5_index.c 8dbda33a9830764167d7697f1c9980c8a6ee74f5decb28206b963222583b8cdd
|
||||
F ext/fts5/fts5_main.c 42025174a556257287071e90516d3ab8115daf1dd525a301883544469a260014
|
||||
F ext/fts5/fts5_storage.c 19bc7c4cbe1e6a2dd9849ef7d84b5ca1fcbf194cefc3e386b901e00e08bf05c2
|
||||
F ext/fts5/fts5_tcl.c 7fb5a3d3404099075aaa2457307cb459bbc257c0de3dbd52b1e80a5b503e0329
|
||||
@@ -168,6 +168,7 @@ F ext/fts5/test/fts5corrupt5.test 73985d4fe6d8f0d5d5c7bcf79ae7c6522c376cd6ad710a
|
||||
F ext/fts5/test/fts5corrupt6.test 2d72db743db7b5d9c9a6d0cfef24d799ed1aa5e8192b66c40e871a37ed9eed06
|
||||
F ext/fts5/test/fts5corrupt7.test 814aab492d7a09abb5bfdd81cc66fc206d7f3868f9a3bae91876e02efc466fb3
|
||||
F ext/fts5/test/fts5corrupt8.test 0b10750caf8aa23fa1c379ca4caf6130d41454505e4d5315590f4061eedcbe44
|
||||
F ext/fts5/test/fts5corruptbig.test 9f95b40fa36e292feceab02b2ef06e21878bfa1ac7afefa138aae05518b51774
|
||||
F ext/fts5/test/fts5delete.test 2a5008f8b1174ef41d1974e606928c20e4f9da77d9f8347aed818994d89cced4
|
||||
F ext/fts5/test/fts5detail.test 54015e9c43ec4ba542cfb93268abdf280e0300f350efd08ee411284b03595cc4
|
||||
F ext/fts5/test/fts5determin.test 1b77879b2ae818b5b71c859e534ee334dac088b7cf3ff3bf76a2c82b1c788d11
|
||||
@@ -283,14 +284,14 @@ F ext/intck/intck_common.tcl a61fd2697ae55b0a3d89847ca0b590c6e0d8ff64bebb70920d9
|
||||
F ext/intck/intckbusy.test d5ed4ef85a4b1dc1dee2484bd14a4bb68529659cca743327df0c775f005fa387
|
||||
F ext/intck/intckcorrupt.test f6c302792326fb3db9dcfc70b554c55369bc4b52882eaaf039cfe0b74c821029
|
||||
F ext/intck/intckfault.test cff3f75dff74abb3edfcb13f6aa53f6436746ab64b09fe5e2028f051e985efab
|
||||
F ext/intck/sqlite3intck.c 0d10df36e2b7b438aa80ecd3f5e584d41b747586b038258fe6b407f66b81e7c5
|
||||
F ext/intck/sqlite3intck.c b1c8a86f90fc00741d13314db9c58f7e2f92d1d19c5ad1c6904ec83a6bbd5c96
|
||||
F ext/intck/sqlite3intck.h 2b40c38e7063ab822c974c0bd4aed97dabb579ccfe2e180a4639bb3bbef0f1c9
|
||||
F ext/intck/test_intck.c 4f9eaadaedccb9df1d26ba41116a0a8e5b0c5556dc3098c8ff68633adcccdea8
|
||||
F ext/jni/GNUmakefile 8a94e3a1953b88cf117fb2a5380480feada8b4f5316f02572cab425030a720b4
|
||||
F ext/jni/README.md e3fbd47c774683539b7fdc95a667eb9cd6e64d8510f3ee327e7fa0c61c8aa787
|
||||
F ext/jni/README.md 1479c83dbe26125264a060ee6873531795a7082dbc0d43c4067683371331559f
|
||||
F ext/jni/jar-dist.make 030aaa4ae71dd86e4ec5e7c1e6cd86f9dfa47c4592c070d2e35157e42498e1fa
|
||||
F ext/jni/src/c/sqlite3-jni.c 3d84a0176af779737ae977ba1c90d2ffe2537b8299c5d9f6552620493f12ac4b
|
||||
F ext/jni/src/c/sqlite3-jni.h ac180ba9b21978727006c790d3006a95a2402a4c3ec7a0def92707ed89b79945
|
||||
F ext/jni/src/c/sqlite3-jni.h df43024cced914c49485633d0f90168689e70577b3b17b0ecbdaf16e4a417bff
|
||||
F ext/jni/src/org/sqlite/jni/annotation/Experimental.java 8603498634e41d0f7c70f661f64e05df64376562ea8f126829fd1e0cdd47e82b
|
||||
F ext/jni/src/org/sqlite/jni/annotation/NotNull.java be6cc3e8e114485822331630097cc0f816377e8503af2fc02f9305ff2b353917
|
||||
F ext/jni/src/org/sqlite/jni/annotation/Nullable.java 56e3dee1f3f703a545dfdeddc1c3d64d1581172b1ad01ffcae95c18547fafd90
|
||||
@@ -300,7 +301,7 @@ F ext/jni/src/org/sqlite/jni/capi/AggregateFunction.java 0e28a0df51368c7127e505f
|
||||
F ext/jni/src/org/sqlite/jni/capi/AuthorizerCallback.java c045a5b47e02bb5f1af91973814a905f12048c428a3504fbc5266d1c1be3de5a
|
||||
F ext/jni/src/org/sqlite/jni/capi/AutoExtensionCallback.java 74cc4998a73d6563542ecb90804a3c4f4e828cb4bd69e61226d1a51f4646e759
|
||||
F ext/jni/src/org/sqlite/jni/capi/BusyHandlerCallback.java 7b8e19810c42b0ad21a04b5d8c804b32ee5905d137148703f16a75b612c380ca
|
||||
F ext/jni/src/org/sqlite/jni/capi/CApi.java 3d275f5f4fbdbe4fff15f4d42cf5ff559f9a4897e7373fa99f3b1dc9cf7f849c
|
||||
F ext/jni/src/org/sqlite/jni/capi/CApi.java a9701cbe736b8bef5bc72ae465be0250e137f67bdb5a3ab62497972b6f51572d
|
||||
F ext/jni/src/org/sqlite/jni/capi/CallbackProxy.java 1b3baf5b772f266e8baf8f35f0ddc5bd87fc8c4927ec69115c46fd6fba6701c3
|
||||
F ext/jni/src/org/sqlite/jni/capi/CollationCallback.java e29bcfc540fdd343e2f5cca4d27235113f2886acb13380686756d5cabdfd065a
|
||||
F ext/jni/src/org/sqlite/jni/capi/CollationNeededCallback.java 5bfa226a8e7a92e804fd52d6e42b4c7b875fa7a94f8e2c330af8cc244a8920ab
|
||||
@@ -345,7 +346,7 @@ F ext/jni/src/org/sqlite/jni/test-script-interpreter.md d7987b432870d23f7c72a780
|
||||
F ext/jni/src/org/sqlite/jni/wrapper1/AggregateFunction.java d5c108b02afd3c63c9e5e53f71f85273c1bfdc461ae526e0a0bb2b25e4df6483
|
||||
F ext/jni/src/org/sqlite/jni/wrapper1/ScalarFunction.java 326ffba29aab836a6ea189703c3d7fb573305fd93da2d14b0f9e9dcf314c8290
|
||||
F ext/jni/src/org/sqlite/jni/wrapper1/SqlFunction.java e920f7a031e04975579240d4a07ac5e4a9d0f8de31b0aa7a4be753c98ae596c9
|
||||
F ext/jni/src/org/sqlite/jni/wrapper1/Sqlite.java c82bc00c1988f86246a89f721d3c41f0d952f33f934aa6677ec87f7ca42519a0
|
||||
F ext/jni/src/org/sqlite/jni/wrapper1/Sqlite.java ce8aef867e06a21685658eb0173768c355e9e1e2dfdc75f382643fa62c7ee779
|
||||
F ext/jni/src/org/sqlite/jni/wrapper1/SqliteException.java 982538ddb4c0719ef87dfa664cd137b09890b546029a7477810bd64d4c47ee35
|
||||
F ext/jni/src/org/sqlite/jni/wrapper1/Tester2.java 08f92d52be2cec28a7b4555479cc54b7ebeeb94985256144eeb727154ec3f85b
|
||||
F ext/jni/src/org/sqlite/jni/wrapper1/ValueHolder.java a84e90c43724a69c2ecebd601bc8e5139f869b7d08cb705c77ef757dacdd0593
|
||||
@@ -354,7 +355,7 @@ F ext/jni/src/tests/000-000-sanity.test c3427a0e0ac84d7cbe4c95fdc1cd4b61f9ddcf43
|
||||
F ext/jni/src/tests/000-001-ignored.test e17e874c6ab3c437f1293d88093cf06286083b65bf162317f91bbfd92f961b70
|
||||
F ext/jni/src/tests/900-001-fts.test bf0ce17a8d082773450e91f2388f5bbb2dfa316d0b676c313c637a91198090f0
|
||||
F ext/misc/README.md 6243cdc4d7eb791c41ef0716f3980b8b5f6aa8c61ff76a3958cbf0031c6ebfa7
|
||||
F ext/misc/amatch.c 2db45b1499b275d8340af6337a13d6216e4ceb2ddb41f4042b9801be7b5e593d
|
||||
F ext/misc/amatch.c 0e0124c1e03ee4cb99b25969f6b7b39c53a847b8bf12279efbcb896b0df1059a
|
||||
F ext/misc/anycollseq.c 5ffdfde9829eeac52219136ad6aa7cd9a4edb3b15f4f2532de52f4a22525eddb
|
||||
F ext/misc/appendvfs.c 9642c7a194a2a25dca7ad3e36af24a0a46d7702168c4ad7e59c9f9b0e16a3824
|
||||
F ext/misc/base64.c 8dc0a08cee11722822858a62625f1b63e5d5f1adac1cf4492d5732b571e37aa0
|
||||
@@ -368,10 +369,10 @@ F ext/misc/completion.c c27b64fdd0943c1b7f152376599814cee2641f7d67a7bb9bd2b957c2
|
||||
F ext/misc/compress.c 2c79a74330e0e0ba6cb3f7397f8ba5af12d46377ef5d3ee075e12dd8a6ed57f0
|
||||
F ext/misc/csv.c 7cae8c2666a058a58fb8994ed2457339a06c97d31c251d9a8445cdd966629890
|
||||
F ext/misc/dbdump.c 678f1b9ae2317b4473f65d03132a2482c3f4b08920799ed80feedd2941a06680
|
||||
F ext/misc/decimal.c 96a0ccd0b5f28720271d8e4409066ad4e2804d6987a9c1042016774dded79df8
|
||||
F ext/misc/decimal.c d4883de142f6dcd36eda23da40b55e2b51374e7b01eb54a7173940191389fc5e
|
||||
F ext/misc/eval.c 04bc9aada78c888394204b4ed996ab834b99726fb59603b0ee3ed6e049755dc1
|
||||
F ext/misc/explain.c 606100185fb90d6a1eade1ed0414d53503c86820d8956a06e3b0a56291894f2b
|
||||
F ext/misc/fileio.c 88cb2e5744296de6638af02ef6349fd468c2eb5e5f41ba405f88d9b4ad500f8e
|
||||
F ext/misc/fileio.c 61af623160c073b605b4ff1f67d278c4c348956efa08f6201756577c7a050d17
|
||||
F ext/misc/fossildelta.c 2fc2dd4f34f478df674887db62586b1071c4cd3c9e73ee40f9ee669670e482d1
|
||||
F ext/misc/fuzzer.c 6b231352815304ba60d8e9ec2ee73d4918e74d9b76bda8940ba2b64e8777515e
|
||||
F ext/misc/ieee754.c 176c061c94857b543313959289cb60cf777c999fd002f82b53d194b95e9f347a
|
||||
@@ -380,17 +381,17 @@ F ext/misc/memtrace.c 7c0d115d2ef716ad0ba632c91e05bd119cb16c1aedf3bec9f06196ead2
|
||||
F ext/misc/mmapwarm.c a81af4aaec00f24f308e2f4c19bf1d88f3ac3ce848c36daa7a4cd38145c4080d
|
||||
F ext/misc/nextchar.c 7877914c2a80c2f181dd04c3dbef550dfb54c93495dc03da2403b5dd58f34edd
|
||||
F ext/misc/noop.c f1a21cc9b7a4e667e5c8458d80ba680b8bd4315a003f256006046879f679c5a0
|
||||
F ext/misc/normalize.c 4782be3b74b9bd9f67281036ff1f41e5edcad20ad486171a2d671c4bb2586011
|
||||
F ext/misc/normalize.c fbb144a861809686ff2b5b6eee8bb2e1207f9bf13ce7376e5273c700a1eafbd5
|
||||
F ext/misc/pcachetrace.c f4227ce03fb16aa8d6f321b72dd051097419d7a028a9853af048bee7645cb405
|
||||
F ext/misc/percentile.c 72e05a21db20a2fa85264b99515941f00ae698824c9db82d7edfbb16cea8ec80
|
||||
F ext/misc/prefixes.c 82645f79229877afab08c8b08ca1e7fa31921280906b90a61c294e4f540cd2a6
|
||||
F ext/misc/qpvtab.c fc189e127f68f791af90a487f4460ec91539a716daf45a0c357e963fd47cc06c
|
||||
F ext/misc/randomjson.c ef835fc64289e76ac4873b85fe12f9463a036168d7683cf2b773e36e6262c4ed
|
||||
F ext/misc/regexp.c 548151f3e57506fda678e6a65e85a763f4eece653287e1ad44e167f9485e0c6b
|
||||
F ext/misc/regexp.c f1f7cfe90fc027b33d2b5ae7d6235eecce69c3aca71c9afce56fec62342c8b44
|
||||
F ext/misc/remember.c add730f0f7e7436cd15ea3fd6a90fd83c3f706ab44169f7f048438b7d6baa69c
|
||||
F ext/misc/rot13.c 51ac5f51e9d5fd811db58a9c23c628ad5f333c173f1fc53c8491a3603d38556c
|
||||
F ext/misc/scrub.c 2a44b0d44c69584c0580ad2553f6290a307a49df4668941d2812135bfb96a946
|
||||
F ext/misc/series.c 4017451155f1b792346f2601f3242132368f670f0a14db11b26170ad6baaeb60
|
||||
F ext/misc/series.c 22c6d8f00cc1b5089b1b37392e9097e9df9a5db53be86daf9a7669d95bb179f4
|
||||
F ext/misc/sha1.c cb5002148c2661b5946f34561701e9105e9d339b713ec8ac057fd888b196dcb9
|
||||
F ext/misc/shathree.c fd22d70620f86a0467acfdd3acd8435d5cb54eb1e2d9ff36ae44e389826993df
|
||||
F ext/misc/showauth.c 732578f0fe4ce42d577e1c86dc89dd14a006ab52
|
||||
@@ -409,7 +410,7 @@ F ext/misc/uuid.c 5bb2264c1b64d163efa46509544fd7500cb8769cb7c16dd52052da8d961505
|
||||
F ext/misc/vfslog.c 3932ab932eeb2601dbc4447cb14d445aaa9fbe43b863ef5f014401c3420afd20
|
||||
F ext/misc/vfsstat.c 0b23c0a69a2b63dc0ef0af44f9c1fc977300c480a1f7a9814500369d8211f56e
|
||||
F ext/misc/vfstrace.c 0e4b8b17ac0675ea90f6d168d8214687e06ca3efbc0060aad4814994d82b41fb
|
||||
F ext/misc/vtablog.c 9f7e02e9e8de585f3bfb48405db36c2eb4b680a23a67d7a4b738dd20f6ad7aec
|
||||
F ext/misc/vtablog.c 2d04386c2f5a3bb93bc9ae978f0b7dcd5a264e126abd640dd6d82aa9067cbd48
|
||||
F ext/misc/vtshim.c e5bce24ab8c532f4fdc600148718fe1802cb6ed57417f1c1032d8961f72b0e8f
|
||||
F ext/misc/wholenumber.c 0fa0c082676b7868bf2fa918e911133f2b349bcdceabd1198bba5f65b4fc0668
|
||||
F ext/misc/windirent.h 02211ce51f3034c675f2dbf4d228194d51b3ee05734678bad5106fff6292e60c
|
||||
@@ -492,7 +493,7 @@ F ext/repair/test/checkindex01.test b530f141413b587c9eb78ff734de6bb79bc3515c3350
|
||||
F ext/repair/test/test.tcl 686d76d888dffd021f64260abf29a55c57b2cedfa7fc69150b42b1d6119aac3c
|
||||
F ext/rtree/README 734aa36238bcd2dee91db5dba107d5fcbdb02396612811377a8ad50f1272b1c1
|
||||
F ext/rtree/geopoly.c f0573d5109fdc658a180db0db6eec86ab2a1cf5ce58ec66cbf3356167ea757eb
|
||||
F ext/rtree/rtree.c 86967c5a501f895b9705366b8cd9c37f15a9ebdff770ceb719c7deeeb2c22b72
|
||||
F ext/rtree/rtree.c 95401e6812a399b5ef2e5de1249ab7e2844601cb4153ca2c3f14122ff3625569
|
||||
F ext/rtree/rtree.h 4a690463901cb5e6127cf05eb8e642f127012fd5003830dbc974eca5802d9412
|
||||
F ext/rtree/rtree1.test e0608db762b2aadca0ecb6f97396cf66244490adc3ba88f2a292b27be3e1da3e
|
||||
F ext/rtree/rtree2.test 9d9deddbb16fd0c30c36e6b4fdc3ee3132d765567f0f9432ee71e1303d32603d
|
||||
@@ -574,29 +575,25 @@ F ext/session/sessionwor.test 6fd9a2256442cebde5b2284936ae9e0d54bde692d0f5fd009e
|
||||
F ext/session/sqlite3session.c b3de195ce668cace9b324599bf6255a70290cbfb5451e826e946f3aee6e64c54
|
||||
F ext/session/sqlite3session.h 7404723606074fcb2afdc6b72c206072cdb2b7d8ba097ca1559174a80bc26f7a
|
||||
F ext/session/test_session.c 8766b5973a6323934cb51248f621c3dc87ad2a98f023c3cc280d79e7d78d36fb
|
||||
F ext/wasm/EXPORTED_FUNCTIONS.fiddle.in 27450c8b8c70875a260aca55435ec927068b34cef801a96205adb81bdcefc65c
|
||||
F ext/wasm/GNUmakefile 0bc887cb6ed6e197359f9c8838913d44fe6077b1c3ff3aafc770daf9577f4dc0
|
||||
F ext/wasm/GNUmakefile 74c73254fb44c82d517a8907da9866d5d3ef1a533addaeb4322f470e0fb81ba3
|
||||
F ext/wasm/README-dist.txt f01081a850ce38a56706af6b481e3a7878e24e42b314cfcd4b129f0f8427066a
|
||||
F ext/wasm/README.md 66ace67ae98a45e4116f2ca5425b716887bcee4d64febee804ff6398e1ae9ec7
|
||||
F ext/wasm/README.md 2e87804e12c98f1d194b7a06162a88441d33bb443efcfe00dc6565a780d2f259
|
||||
F ext/wasm/SQLTester/GNUmakefile e0794f676d55819951bbfae45cc5e8d7818dc460492dc317ce7f0d2eca15caff
|
||||
F ext/wasm/SQLTester/SQLTester.mjs 6b3c52ed36a5573ca4883176f326332a8d4c0cecf5efd80489528267fa5d9ed4
|
||||
F ext/wasm/SQLTester/SQLTester.run.mjs 57f2adb33f43f2784abbf8026c1bfd049d8013af1998e7dcb8b50c89ffc332e0
|
||||
F ext/wasm/SQLTester/index.html 64f3435084c7d6139b08d1f2a713828a73f68de2ae6a3112cbb5980d991ba06f
|
||||
F ext/wasm/SQLTester/touint8array.c 2d5ece04ec1393a6a60c4bf96385bda5e1a10ad49f3038b96460fc5e5aa7e536
|
||||
F ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-core e5cf4fa7610a09d51017d75faf50be38172058c0d781837d8257d16ddcaaea33
|
||||
F ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-extras cb4fa8842c875b6ee99381523792975c5ebb7371bd27fbd1bd863a43c7f3505a
|
||||
F ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-see fb29e62082a658f0d81102488414d422c393c4b20cc2f685b216bc566237957b
|
||||
F ext/wasm/api/EXPORTED_RUNTIME_METHODS.sqlite3-api 1ec3c73e7d66e95529c3c64ac3de2470b0e9e7fbf7a5b41261c367cf4f1b7287
|
||||
F ext/wasm/api/README.md f4c0d67caaee21a77b8938c30b5f79667bfc9d0c95d01b51df77ea35ee773884
|
||||
F ext/wasm/api/extern-post-js.c-pp.js 205f55aacfc62c580985db5c790300779de3876a76a5c7e1bfb13e71c8b4506b
|
||||
F ext/wasm/api/EXPORTED_FUNCTIONS.c-pp d609c22bc05e25991bdd2eeed4497485a3756446158b2794471426e5e3517056
|
||||
F ext/wasm/api/README.md df476398c6d80affae807a8208c5a97d1615786e1d6767b5292bfe67edb59b18
|
||||
F ext/wasm/api/extern-post-js.c-pp.js 4b310c9891886e7c1ea4e2419966ff45dfeda825b897fdaa4119332509f7e3d1
|
||||
F ext/wasm/api/extern-pre-js.js cc61c09c7a24a07dbecb4c352453c3985170cec12b4e7e7e7a4d11d43c5c8f41
|
||||
F ext/wasm/api/post-js-footer.js 5bd7170b5e8ce7b62102702bbcf47ef7b3b49cd56ed40c043fd990aa715b74ee
|
||||
F ext/wasm/api/post-js-header.js 79d078aec33d93b640a19c574b504d88bb2446432f38e2fbb3bb8e36da436e70
|
||||
F ext/wasm/api/pre-js.c-pp.js a876c6399dff29b6fe9e434036beb89889164cc872334e184291723ecc7cb072
|
||||
F ext/wasm/api/sqlite3-api-cleanup.js a3d6b9e449aefbb8bba283c2ba9477e2333a0eeb94a7a26b5bf952736f65a6dd
|
||||
F ext/wasm/api/sqlite3-api-glue.c-pp.js 12f5b36775fab1e7bf5385689fded2b2a9f77360562515e9849acb5e66602e2d
|
||||
F ext/wasm/api/pre-js.c-pp.js b1a7a09d14df1f36de11e801ba06cb92c0ddeb520e5b2f28836af0ec8146e288
|
||||
F ext/wasm/api/sqlite3-api-cleanup.js 79b54a566291e17c0c3e165c6c4969c48ec17cd297755180151af65ac616dfa0
|
||||
F ext/wasm/api/sqlite3-api-glue.c-pp.js 79a54b54ca6324d28e31e19b56bbaebb7d2cc4b3079066e7e901333fa5047c53
|
||||
F ext/wasm/api/sqlite3-api-oo1.c-pp.js 31dbfd470c91ffd96d77399b749bab6b69e3ba9074188833f97ac13f087cf07b
|
||||
F ext/wasm/api/sqlite3-api-prologue.js b5a55ae74efcdcd0aa6a143d59e34137e43ae732f02b563dcab22d735f1599a4
|
||||
F ext/wasm/api/sqlite3-api-prologue.js b6b2fd1720c484e168705909862442b4524a1e61e16b4549a5725dd28c3cecc2
|
||||
F ext/wasm/api/sqlite3-api-worker1.c-pp.js 1041dd645e8e821c082b628cd8d9acf70c667430f9d45167569633ffc7567938
|
||||
F ext/wasm/api/sqlite3-license-version-header.js 0c807a421f0187e778dc1078f10d2994b915123c1223fe752b60afdcd1263f89
|
||||
F ext/wasm/api/sqlite3-opfs-async-proxy.js 9654b565b346dc609b75d15337f20acfa7af7d9d558da1afeb9b6d8eaa404966
|
||||
@@ -604,14 +601,14 @@ F ext/wasm/api/sqlite3-vfs-helper.c-pp.js 3f828cc66758acb40e9c5b4dcfd87fd478a14c
|
||||
F ext/wasm/api/sqlite3-vfs-opfs-sahpool.c-pp.js 26cb41d5a62f46a106b6371eb00fef02de3cdbfaa51338ba087a45f53028e0d0
|
||||
F ext/wasm/api/sqlite3-vfs-opfs.c-pp.js 418c33fe284739564daab3c7a7a88882fdd3c99137497900f98eddec1e409af5
|
||||
F ext/wasm/api/sqlite3-vtab-helper.c-pp.js 9097074724172e31e56ce20ccd7482259cf72a76124213cbc9469d757676da86
|
||||
F ext/wasm/api/sqlite3-wasm.c 929d4c5619a321fa2fb9ef921ec8e4ccfdac27745df543062b267f9f928de3a7
|
||||
F ext/wasm/api/sqlite3-wasm.c 2d1cbe498f7b0fb64b11451eda481f458df74d6258baea635513e637fcbb8b1a
|
||||
F ext/wasm/api/sqlite3-worker1-promiser.c-pp.js bda1c75bd674a92a0e27cc2f3d46dbbf21e422413f8046814515a0bd7409328a
|
||||
F ext/wasm/api/sqlite3-worker1.c-pp.js 802d69ead8c38dc1be52c83afbfc77e757da8a91a2e159e7ed3ecda8b8dba2e7
|
||||
F ext/wasm/c-pp-lite.c 16250600fe18723e0cee4227161101ccb54f10fa6136bd208b479cf596df0f75
|
||||
F ext/wasm/c-pp-lite.c 67e86d9ea47cf3e70a4067acd92788f4f8e6271fae02a68490b069303d7597be
|
||||
F ext/wasm/common/SqliteTestUtil.js 7adaeffef757d8708418dc9190f72df22367b531831775804b31598b44f6aa51
|
||||
F ext/wasm/common/emscripten.css 11bd104b6c0d597c67d40cc8ecc0a60dae2b965151e3b6a37fa5708bac3acd15
|
||||
F ext/wasm/common/testing.css e97549bab24126c24e0daabfe2de9bb478fb0a69fdb2ddd0a73a992c091aad6f
|
||||
F ext/wasm/common/whwasmutil.js 0d539324097fc83b953e9844267359ba0fd02286caa784ea2f597ced279ea640
|
||||
F ext/wasm/common/whwasmutil.js b4fd73fac162406e67f276647ff8bae51881e15eebdf4b725aeb2b10ab1e056a
|
||||
F ext/wasm/config.make.in c424ae1cc3c89274520ad312509d36c4daa34a3fce5d0c688e5f8f4365e1049a
|
||||
F ext/wasm/demo-123-worker.html a0b58d9caef098a626a1a1db567076fca4245e8d60ba94557ede8684350a81ed
|
||||
F ext/wasm/demo-123.html 8c70a412ce386bd3796534257935eb1e3ea5c581e5d5aea0490b8232e570a508
|
||||
@@ -628,10 +625,10 @@ F ext/wasm/fiddle/fiddle.js 84fd75967e0af8b69d3dd849818342227d0f81d13db92e0dcbc6
|
||||
F ext/wasm/fiddle/index.html a27b8127ef9ecf19612da93b2a6a73bdb3777b5c56b5450bb7200a94bc108ff9
|
||||
F ext/wasm/index-dist.html db23748044e286773f2768eec287669501703b5d5f72755e8db73607dc54d290
|
||||
F ext/wasm/index.html 54e27db740695ab2cb296e02d42c4c66b3f11b65797340d19fa6590f5b287da1
|
||||
F ext/wasm/jaccwabyt/jaccwabyt.js bbac67bc7a79dca34afe6215fd16b27768d84e22273507206f888c117e2ede7d
|
||||
F ext/wasm/jaccwabyt/jaccwabyt.js 1e734c624205cdf621f322972dfb0fc8013d573a5882f57492a6830e5ec23e17
|
||||
F ext/wasm/jaccwabyt/jaccwabyt.md 167fc0b624c9bc2c477846e336de9403842d81b1a24fc4d3b24317cb9eba734f
|
||||
F ext/wasm/mkdist.sh 29f8a37a7aba41fa5df8e89b1fab02b83b35c43473c5cf808584872e022514b8 x
|
||||
F ext/wasm/mkwasmbuilds.c 0216fd7273314b9e433ca17d7692cce844a362b31a192e44d31fc13cdb27ad8c
|
||||
F ext/wasm/mkdist.sh f774603c758e87fb115ceae192670aa10eeece9474ce2147671156d2e665b871 x
|
||||
F ext/wasm/mkwasmbuilds.c 8f945702c48aa55d8f3a801bde70f1a2c7a8364f38defc1e026bd0628280aee8
|
||||
F ext/wasm/module-symbols.html e54f42112e0aac2a31f850ab33e7f2630a2ea4f63496f484a12469a2501e07e2
|
||||
F ext/wasm/scratchpad-wasmfs.html a3d7388f3c4b263676b58b526846e9d02dfcb4014ff29d3a5040935286af5b96
|
||||
F ext/wasm/scratchpad-wasmfs.mjs 66034b9256b218de59248aad796760a1584c1dd842231505895eff00dbd57c63
|
||||
@@ -645,9 +642,9 @@ F ext/wasm/sql/000-mandelbrot.sql 775337a4b80938ac8146aedf88808282f04d02d983d826
|
||||
F ext/wasm/sql/001-sudoku.sql 35b7cb7239ba5d5f193bc05ec379bcf66891bce6f2a5b3879f2f78d0917299b5
|
||||
F ext/wasm/test-opfs-vfs.html 1f2d672f3f3fce810dfd48a8d56914aba22e45c6834e262555e685bce3da8c3f
|
||||
F ext/wasm/test-opfs-vfs.js 1618670e466f424aa289859fe0ec8ded223e42e9e69b5c851f809baaaca1a00c
|
||||
F ext/wasm/tester1-worker.c-pp.html 883881eeac14eeeecc8ff22acf9fe0f18a97cacb48be08ebb0bae891ceded584
|
||||
F ext/wasm/tester1.c-pp.html 949920126dcf477925d8d540093d9cc374d3ab4c4ddee920c1dcadcf37917306
|
||||
F ext/wasm/tester1.c-pp.js 23fc1223e75228f054148eeb8469ad114e9b2881b9f437fa291b8da06d021ce3
|
||||
F ext/wasm/tester1-worker.c-pp.html 0e432ec2c0d99cd470484337066e8d27e7aee4641d97115338f7d962bf7b081a
|
||||
F ext/wasm/tester1.c-pp.html 52d88fe2c6f21a046030a36410b4839b632f4424028197a45a3d5669ea724ddb
|
||||
F ext/wasm/tester1.c-pp.js 2c255093205a0dac9dae7475030665c2c9d6dccc857de68ee7daf49aa82e6de8
|
||||
F ext/wasm/tests/opfs/concurrency/index.html 657578a6e9ce1e9b8be951549ed93a6a471f4520a99e5b545928668f4285fb5e
|
||||
F ext/wasm/tests/opfs/concurrency/test.js d08889a5bb6e61937d0b8cbb78c9efbefbf65ad09f510589c779b7cc6a803a88
|
||||
F ext/wasm/tests/opfs/concurrency/worker.js 0a8c1a3e6ebb38aabbee24f122693f1fb29d599948915c76906681bb7da1d3d2
|
||||
@@ -657,12 +654,12 @@ F ext/wasm/tests/opfs/sahpool/index.html be736567fd92d3ecb9754c145755037cbbd2bca
|
||||
F ext/wasm/tests/opfs/sahpool/sahpool-pausing.js f264925cfc82155de38cecb3d204c36e0f6991460fff0cb7c15079454679a4e2
|
||||
F ext/wasm/tests/opfs/sahpool/sahpool-worker.js bd25a43fc2ab2d1bafd8f2854ad3943ef673f7c3be03e95ecf1612ff6e8e2a61
|
||||
F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0
|
||||
F main.mk 00dd631c66c1f7922b2d691631163899eff1c3d1da780ff37a62f8d997b368e1
|
||||
F main.mk 29078d11f7545a8fae4347305b164bb4e777b801da16baeb48214014a8d63a06
|
||||
F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271
|
||||
F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504
|
||||
F mptest/crash01.test 61e61469e257df0850df4293d7d4d6c2af301421
|
||||
F mptest/crash02.subtest f4ef05adcd15d60e5d2bd654204f2c008b519df8
|
||||
F mptest/mptest.c aa41ace6dbc5050d76b02548d3521e6bbccae4f0
|
||||
F mptest/mptest.c 7ecf39040c1187d9cbc487409bc052f194e93c165f667c55b052690a741d9d71
|
||||
F mptest/multiwrite01.test dab5c5f8f9534971efce679152c5146da265222d
|
||||
F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b
|
||||
F sqlite3.1 1b9c24374a85dfc7eb8fa7c4266ee0db4f9609cceecfc5481cd8307e5af04366
|
||||
@@ -674,31 +671,31 @@ F src/auth.c 54ab9c6c5803b47c0d45b76ce27eff22a03b4b1f767c5945a3a4eb13aa4c78dc
|
||||
F src/backup.c 5c97e8023aab1ce14a42387eb3ae00ba5a0644569e3476f38661fa6f824c3523
|
||||
F src/bitvec.c e242d4496774dfc88fa278177dd23b607dce369ccafb3f61b41638eea2c9b399
|
||||
F src/btmutex.c 30dada73a819a1ef5b7583786370dce1842e12e1ad941e4d05ac29695528daea
|
||||
F src/btree.c cb5b8ceb9baa02a63a2f83dec09c4153e1cfbdf9c2adef5c62c26d2160eeb067
|
||||
F src/btree.c 0ad524883ec4ccac3221c97bdc2c5d5f6e149504e14cf269bbed31362c3f4393
|
||||
F src/btree.h e823c46d87f63d904d735a24b76146d19f51f04445ea561f71cc3382fd1307f0
|
||||
F src/btreeInt.h 9c0f9ea5c9b5f4dcaea18111d43efe95f2ac276cd86d770dce10fd99ccc93886
|
||||
F src/build.c 611e07299d72ff04bbcb9e7109183467e30925d203c3e121ef9bb3cf6876289b
|
||||
F src/callback.c acae8c8dddda41ee85cfdf19b926eefe830f371069f8aadca3aa39adf5b1c859
|
||||
F src/carray.c a6f26cb349ca700d706c0e76d5b2895d76e2a1c392a2b909cf543a0dd4d4d047
|
||||
F src/callback.c afa59adfaa483f668260ce69f740c8273dee3e6fee9106846e0499ebdd1ac076
|
||||
F src/carray.c ff6081a31878fc34df8fa1052a9cbf17ddc22652544dcb3e2326886ed1053b55
|
||||
F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e
|
||||
F src/date.c e19e0cfff9a41bfdd884c655755f6f00bca4c1a22272b56e0dd6667b7ea893a2
|
||||
F src/dbpage.c 081c59d84f187aa0eb48d98faf9578a00bde360f68438d646a86b618653d2479
|
||||
F src/dbpage.c c9ea81c11727f27e02874611e92773e68e2a90a875ef2404b084564c235fd91f
|
||||
F src/dbstat.c 73362c0df0f40ad5523a6f5501224959d0976757b511299bf892313e79d14f5c
|
||||
F src/delete.c 03a77ba20e54f0f42ebd8eddf15411ed6bdb06a2c472ac4b6b336521bf7cea42
|
||||
F src/expr.c 4d63c8f6d50fe20637de8bdaf57757a0e424e4ac5e2c3313e621d64727a48a1c
|
||||
F src/expr.c 17b0cbe08e004c1653030f5de9b6b050e84feaa112239f7f576af2dc5e53a5fb
|
||||
F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007
|
||||
F src/fkey.c 928ed2517e8732113d2b9821aa37af639688d752f4ea9ac6e0e393d713eeb76f
|
||||
F src/func.c 338477566488c2c7aa0244793b89973c4708b76264d86a5e5ba75f5bf2eed0bd
|
||||
F src/func.c 0b802107498048d3dcac0b757720bcb8506507ce02159e213ab8161458eb293b
|
||||
F src/global.c a19e4b1ca1335f560e9560e590fc13081e21f670643367f99cb9e8f9dc7d615b
|
||||
F src/hash.c 73934a7f7ab1cb110614a9388cb516893b0cf5b7b69e4fd1a0780ac4ce166be7
|
||||
F src/hash.h 46b92795a95bfefb210f52f0c316e9d7cdbcdd7e7fcfb0d8be796d3a5767cddf
|
||||
F src/hwtime.h f9c2dfb84dce7acf95ce6d289e46f5f9d3d1afd328e53da8f8e9008e3b3caae6
|
||||
F src/hash.c dff10fa89d4a8280b764df9599b29342ea98cba2b868dccb5dfb3c419841a3f0
|
||||
F src/hash.h c5f4a02aaf1dca835a68b51c8b906af265c6ca3d8d53d255e0453f0abce561be
|
||||
F src/hwtime.h d4d1b98c1afdc56986a5c0eba882786ef017e2180a320da25b4231b8e7e463e8
|
||||
F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71
|
||||
F src/insert.c dfd311b0ac2d4f6359e62013db67799757f4d2cc56cca5c10f4888acfbbfa3fd
|
||||
F src/json.c fb031340edee159c07ad37dbe668ffe945ed86f525b0eb3822e4a67cbc498a72
|
||||
F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa
|
||||
F src/loadext.c 96904a9215b78b51351c01a4f3891f38d10cf4f6b828728e91c9195abd8a7f43
|
||||
F src/main.c ce69a2650e3d359ed6a8a2867ccafb27ac62ce1d39f3120a84ff513320952a6c
|
||||
F src/loadext.c a3bc9a2522dc3b960e38b7582d1818f6245a49289387c2c7b19f27bfeabf1e81
|
||||
F src/main.c eaf5215917b7e8b34ddea013524287f6d5021ba0fc70202e7602e225ef0d16bf
|
||||
F src/malloc.c 410e570b30c26cc36e3372577df50f7a96ee3eed5b2b161c6b6b48773c650c5e
|
||||
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
|
||||
F src/mem1.c 3bb59158c38e05f6270e761a9f435bf19827a264c13d1631c58b84bdc96d73b2
|
||||
@@ -709,7 +706,7 @@ F src/memdb.c a3feb427cdd4036ea2db0ba56d152f14c8212ca760ccb05fb7aa49ff6b897df3
|
||||
F src/memjournal.c c283c6c95d940eb9dc70f1863eef3ee40382dbd35e5a1108026e7817c206e8a0
|
||||
F src/msvc.h 80b35f95d93bf996ccb3e498535255f2ef1118c78764719a7cd15ab4106ccac9
|
||||
F src/mutex.c 06bcd9c3dbf2d9b21fcd182606c00fafb9bfe0287983c8e17acd13d2c81a2fa9
|
||||
F src/mutex.h e2159f6ce3201c90d63045701f0eaa669e9154e8b79d000982d2fa1467432a94
|
||||
F src/mutex.h a7b2293c48db5f27007c3bdb21d438873637d12658f5a0bf8ad025bb96803c4a
|
||||
F src/mutex_noop.c 9d4309c075ba9cc7249e19412d3d62f7f94839c4
|
||||
F src/mutex_unix.c f7ee5a2061a4c11815a2bf4fc0e2bfa6fb8d9dc89390eb613ca0cec32fc9a3d1
|
||||
F src/mutex_w32.c 28f8d480387db5b2ef5248705dd4e19db0cfc12c3ba426695a7d2c45c48e6885
|
||||
@@ -718,34 +715,34 @@ F src/os.c 509452169d5ea739723e213b8e2481cf0e587f0e88579a912d200db5269f5f6d
|
||||
F src/os.h 1ff5ae51d339d0e30d8a9d814f4b8f8e448169304d83a7ed9db66a65732f3e63
|
||||
F src/os_common.h 6c0eb8dd40ef3e12fe585a13e709710267a258e2c8dd1c40b1948a1d14582e06
|
||||
F src/os_kv.c fb7ba8d6204197357f1eb7e1c7450d09c10043bf7e99aba602f4aa46b8fb11a3
|
||||
F src/os_setup.h b526af209201988782226983ecbaecc24caad2c657357c24b2fb5d346078e26d
|
||||
F src/os_unix.c 42cddd1d6e6e4963b369930356dc9cb8c1d7c8f6c027130f84e7d05e74f34d94
|
||||
F src/os_win.c 10e6b13041be4529dc22de1e1dbcb0eccf25dd15dd4ea3bf6f3b05e4a4a4da55
|
||||
F src/os_setup.h 8efc64eda6a6c2f221387eefc2e7e45fd5a3d5c8337a7a83519ba4fbd2957ae2
|
||||
F src/os_unix.c 7945ede1e85b2d1b910e1b4af9ba342e964b1e30e79f4176480a60736445cb36
|
||||
F src/os_win.c a89b501fc195085c7d6c9eec7f5bd782625e94bb2a96b000f4d009703df1083f
|
||||
F src/os_win.h 4c247cdb6d407c75186c94a1e84d5a22cbae4adcec93fcae8d2bc1f956fd1f19
|
||||
F src/pager.c 113f9149092ccff6cf90e97c2611200e5a237f13d26c394bc9fd933377852764
|
||||
F src/pager.c a81461de271ac4886ad75b7ca2cca8157a48635820c4646cd2714acdc2c17e5f
|
||||
F src/pager.h 6137149346e6c8a3ddc1eeb40aee46381e9bc8b0fcc6dda8a1efde993c2275b8
|
||||
F src/parse.y 619c3e92a54686c5e47923688c4b9bf7ec534a4690db5677acc28b299c403250
|
||||
F src/pcache.c 588cc3c5ccaaadde689ed35ce5c5c891a1f7b1f4d1f56f6cf0143b74d8ee6484
|
||||
F src/pcache.h 1497ce1b823cf00094bb0cf3bac37b345937e6f910890c626b16512316d3abf5
|
||||
F src/pcache1.c 131ca0daf4e66b4608d2945ae76d6ed90de3f60539afbd5ef9ec65667a5f2fcd
|
||||
F src/pragma.c 401a5421f5d391b9b3048241860976b13218e0fbed2bd675b44078f7bc47244a
|
||||
F src/pragma.c ecec75795c1821520266e4f93fa8840cce48979af532db06f085e36a7813860f
|
||||
F src/prepare.c 2af0b5c1ec787c8eebd21baa9d79caf4a4dc3a18e76ce2edbf2027d706bca37a
|
||||
F src/printf.c 7297c2aeed4d90d80c5ba82920d9e57b7bfad04b3466be1d7e042db382fe296e
|
||||
F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c
|
||||
F src/resolve.c f8d1d011aba0964ff1bdccd049d4d2c2fec217efd90d202a4bb775e926b2c25d
|
||||
F src/resolve.c 5616fbcf3b833c7c705b24371828215ad0925d0c0073216c4f153348d5753f0a
|
||||
F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97
|
||||
F src/select.c b95181711d59c36d9789e67f76c4cfec64b99f9629a50be5e6566e117b87d957
|
||||
F src/shell.c.in c63c9d77565c43c02a889164486edbfcdcdf4417fbad6780e4b0ec8aefa28d08
|
||||
F src/sqlite.h.in 5706a425081d1712be81b31456801919c5760087cf3de32bbf86885994db26fe
|
||||
F src/select.c ba9cd07ffa3277883c1986085f6ddc4320f4d35d5f212ab58df79a7ecc1a576a
|
||||
F src/shell.c.in ceb0a9cc008ac82d8d2e6ef353db14a54bc40dfd60a8cfbb6bc98d071f538761
|
||||
F src/sqlite.h.in 684c19c3b093cca7a38e3f6405d067777464285f17a58a78f7f89d6763e011e7
|
||||
F src/sqlite3.rc 015537e6ac1eec6c7050e17b616c2ffe6f70fca241835a84a4f0d5937383c479
|
||||
F src/sqlite3ext.h 3f0c4ed6934e7309a61c6f3c30f70a30a5b869f785bb3d9f721a36c5e4359126
|
||||
F src/sqliteInt.h 9edbf62c1fd6bff720ed39eaf3fa28534dc445d936b1d78552c47d7b174d8cc3
|
||||
F src/sqlite3ext.h 7f236ca1b175ffe03316d974ef57df79b3938466c28d2f95caef5e08c57f3a52
|
||||
F src/sqliteInt.h 88f7fc9ce1630d9a5f7e0a8e1f3287cdc63882fba985c18e7eee1b9f457f59aa
|
||||
F src/sqliteLimit.h fe70bd8983e5d317a264f2ea97473b359faf3ebb0827877a76813f5cf0cdc364
|
||||
F src/status.c 0e72e4f6be6ccfde2488eb63210297e75f569f3ce9920f6c3d77590ec6ce5ffd
|
||||
F src/status.c 7565d63a79aa2f326339a24a0461a60096d0bd2bce711fefb50b5c89335f3592
|
||||
F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1
|
||||
F src/tclsqlite.c 3c604c49e6cf4211960a9ddb9505280fd22cde32175f40884c641c0f5a286036
|
||||
F src/tclsqlite.h 614b3780a62522bc9f8f2b9fb22689e8009958e7aa77e572d0f3149050af348a
|
||||
F src/test1.c f880ab766eeedf2c063662bd9538b923fd42c4341b7bfc2150a6d93ab8b9341c
|
||||
F src/test1.c d27c91455865fb191eb1b2c892e7586c5e3d9d3977f54913c8e70e2e8e5148b3
|
||||
F src/test2.c 62f0830958f9075692c29c6de51b495ae8969e1bef85f239ffcd9ba5fb44a5ff
|
||||
F src/test3.c 432646f581d8af1bb495e58fc98234380250954f5d5535e507fc785eccc3987a
|
||||
F src/test4.c 0ac87fc13cdb334ab3a71823f99b6c32a6bebe5d603cd6a71d84c823d43a25a0
|
||||
@@ -770,7 +767,7 @@ F src/test_intarray.c 3fcf8ca7bb5c8776ea83f6aa9b66f8df0d1f37a99207b0097c8486f9c1
|
||||
F src/test_intarray.h 6c3534641108cd1bea517a8e117dcba237081310a29a4c35bd2190caa8972293
|
||||
F src/test_journal.c a0b9709b2f12b1ec819eea8a1176f283bca6d688a6d4a502bd6fd79786f4e287
|
||||
F src/test_loadext.c 337056bae59f80b9eb00ba82088b39d0f4fe6dfd
|
||||
F src/test_malloc.c f1901a7a32fadff1978d6aca8e3bd2c6cc1e41b790ff19d369cc0367116a1828
|
||||
F src/test_malloc.c 55e2b5398f6e184300d91278b8a84768f6a740735adc030411181945d5276da0
|
||||
F src/test_md5.c 811a45330c9391933360f998156a8907ee29909c828ab83ac05d329942cbea8f
|
||||
F src/test_multiplex.c 82f0aa8eee629b6949782cfab8782ed35a9b56dc80d12877af52147f304d22b8
|
||||
F src/test_multiplex.h f0ff5b6f4462bfd46dac165d6375b9530d08089b7bcbe75e88e0926110db5363
|
||||
@@ -784,7 +781,7 @@ F src/test_rtree.c d844d746a3cc027247318b970025a927f14772339c991f40e7911583ea5ed
|
||||
F src/test_schema.c b06d3ddc3edc173c143878f3edb869dd200d57d918ae2f38820534f9a5e3d7d9
|
||||
F src/test_sqllog.c 5abf04865758c0a3915b4ec2b2ee5ab75f74c00e2f05bf503b9083e0ab6829d7
|
||||
F src/test_superlock.c 3387fc794a68d8c6b6ed059aabacbfe870dc502c5cf65562f36aac78b4a4d629
|
||||
F src/test_syscall.c 39117e85eef73ad74360a7f87b33febca4ffe59dbbd16a4763cdc6868a67fd4e
|
||||
F src/test_syscall.c c5bf039261973135068aa68f4d185a6147333dcf266977989f8245b3a1968f1b
|
||||
F src/test_tclsh.c c01706ac60bd3176754d3ccd37da74c6ad97c2e14489f8ed71b497c1c0ac0dd4
|
||||
F src/test_tclvar.c ae873248a0188459b1c16ca7cc431265dacce524399e8b46725c2b3b7e048424
|
||||
F src/test_thread.c 3edb4a5b5aeb1a6e9a275dccc848ac95acab7f496b3e9230f6d2d04953a2b862
|
||||
@@ -793,7 +790,7 @@ F src/test_vfs.c b4135c1308516adf0dfd494e6d6c33114e03732be899eace0502919b674586b
|
||||
F src/test_window.c 6d80e11fba89a1796525e6f0048ff0c7789aa2c6b0b11c80827dc1437bd8ea72
|
||||
F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9
|
||||
F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c
|
||||
F src/tokenize.c 8400646d2830afc2f2dc465a75e3a92e4bedeea623f19dbd79c0c12d0dd6dda2
|
||||
F src/tokenize.c cb3294cf23c11106b50d9af6998a6c1bf389b52e15b17698c9fab97bbaa9b37f
|
||||
F src/treeview.c 3ce7ac9835d2d70cc1c868b01b747ae8a062322e155701e58e3d62ca79aada7a
|
||||
F src/trigger.c d5cf2541ff048f30b6a0507eb3d1ec4e695c53584e3b2298a5bf248714fe185e
|
||||
F src/update.c 3e5e7ff66fa19ebe4d1b113d480639a24cc1175adbefabbd1a948a07f28e37cf
|
||||
@@ -801,19 +798,19 @@ F src/upsert.c 215328c3f91623c520ec8672c44323553f12caeb4f01b1090ebdca99fdf7b4f1
|
||||
F src/utf.c 7267c3fb9e2467020507601af3354c2446c61f444387e094c779dccd5ca62165
|
||||
F src/util.c 36fb1150062957280777655976f3f9a75db236cb8207a0770ceae8d5ec17fcd3
|
||||
F src/vacuum.c 1bacdd0a81d2b5dc1c508fbf0d938c89fa78dd8d5b46ec92686d44030d4f4789
|
||||
F src/vdbe.c 07084aa0152c8d4e74e7b86c0cf744732f0f9b1fd62bd7098252cadb741c630a
|
||||
F src/vdbe.c b44c366e83412d3b8c190feb1f029b7d02e1bd69252a57b32f195107f0d03964
|
||||
F src/vdbe.h be33bd7b17f2ec92939642416030491508c51071f6c14e27cd195983fec56b63
|
||||
F src/vdbeInt.h 52896dd4d5b62190c53db14b09fc2484434eb594c963df0fa66eb8a94527b02e
|
||||
F src/vdbeapi.c 869a0da5d855495055f4d35c6ada582f64ce995ce14b26ff9d336274d497266c
|
||||
F src/vdbeaux.c cb907297d03b374544a5a4f81ca981497ff4d09d13838f06de507118367f0b73
|
||||
F src/vdbeInt.h 2aaeb6df2938b181b4700a9328688a3986f2bba71e8b96f6a80671316618fa49
|
||||
F src/vdbeapi.c 6a2181cfd27c86b4cc1d8abb27ae11f3b3f0357567814fa276ec37b043542938
|
||||
F src/vdbeaux.c 908d8a191aed444b2e4c920159249127f3ff67b94c56a16fad1dfdf9c7488f20
|
||||
F src/vdbeblob.c b3f0640db9642fbdc88bd6ebcc83d6009514cafc98f062f675f2c8d505d82692
|
||||
F src/vdbemem.c e67d9c6484d868c879d20c70d00bf4a9058082f1d4058607ca15d50eb3aebc21
|
||||
F src/vdbesort.c cb6f472e83ca12c46aa7de0ac0a9d11458b357986f2617a1c90dfb19a542ecbe
|
||||
F src/vdbetrace.c fe0bc29ebd4e02c8bc5c1945f1d2e6be5927ec12c06d89b03ef2a4def34bf823
|
||||
F src/vdbemem.c 48e562ff27e6386eb8613207ac27d3d98c1f67fdc4775a1ab13759d2c2a1c021
|
||||
F src/vdbesort.c b69220f4ea9ffea5fdef34d968c60305444eea909252a81933b54c296d9cca70
|
||||
F src/vdbetrace.c 49e689f751505839742f4a243a1a566e57d5c9eaf0d33bbaa26e2de3febf7b41
|
||||
F src/vdbevtab.c fc46b9cbd759dc013f0b3724549cc0d71379183c667df3a5988f7e2f1bd485f3
|
||||
F src/vtab.c 828221bdbeaaa6d62126ee6d07fd4ec0d09dcaea846f87ad01944d8b7e548859
|
||||
F src/vxworks.h 9d18819c5235b49c2340a8a4d48195ec5d5afb637b152406de95a9436beeaeab
|
||||
F src/wal.c a278339ecf5f194fd71fff1f0da1368de50e3a32edc3e9944e1ee1f4610476ff
|
||||
F src/wal.c 505a98fbc599a971d92cb90371cf54546c404cd61e04fd093e7b0c8ff978f9b6
|
||||
F src/wal.h ba252daaa94f889f4b2c17c027e823d9be47ce39da1d3799886bbd51f0490452
|
||||
F src/walker.c d5006d6b005e4ea7302ad390957a8d41ed83faa177e412f89bc5600a7462a014
|
||||
F src/where.c 7d17cd5cb883b2166097957e20c4aab2d0d98e0c1141002ef77b5f6b9deed844
|
||||
@@ -918,7 +915,7 @@ F test/between.test e7587149796101cbe8d5f8abae8d2a7b87f04d8226610aa1091615005dcf
|
||||
F test/bigfile.test aa74f4e5db51c8e54a1d9de9fa65d01d1eb20b59
|
||||
F test/bigfile2.test 1b489a3a39ae90c7f027b79110d6b4e1dbc71bfc
|
||||
F test/bigmmap.test 6021e205487347c6d7e5a541aa472a4b8efc4e9f4a3799a823b61a8e6616105d
|
||||
F test/bigrow.test f0aeb7573dcb8caaafea76454be3ade29b7fc747
|
||||
F test/bigrow.test 3e6b189dea465a78306eac67fc6754c1cf90eb1694a25c88c338900c216c1e6b
|
||||
F test/bigsort.test 997e172009905873c06426145e4b3794c7dfe2d563724cb2fd39d45f319cf3d2
|
||||
F test/bind.test 1e136709b306f7ed3192d349c2930d89df6ab621654ad6f1a72381d3fe76f483
|
||||
F test/bind2.test 918bc35135f4141809ead7585909cde57d44db90a7a62aef540127148f91aab7
|
||||
@@ -1038,7 +1035,7 @@ F test/dblwidth-a.sql eb4141518610e52f931a55a984310075e98dc31eee5a28ae806b1e3537
|
||||
F test/dbpage.test 63fab1eb026bada121107e53436fa749bbf83281dc9dea17af422f7a5c0f289f
|
||||
F test/dbpagefault.test ea39de2ca86041a9c6df1135645180a76d0a8da93ac159e2fafe38e39636530b
|
||||
F test/dbstatus.test 4a4221a883025ffd39696b3d1b3910b928fb097d77e671351acb35f3aed42759
|
||||
F test/dbstatus2.test f5fe0afed3fa45e57cfa70d1147606c20d2ba23feac78e9a172f2fe8ab5b78ef
|
||||
F test/dbstatus2.test a36518c0f0951d8fd5a3dc36f99948ad1af93fb7fc0d2e03e5bb5a643186cf52
|
||||
F test/decimal.test a11b87a2c3294eb4c11b55f3168aeac63d683fa8ada35921a6ec1d511eff7648
|
||||
F test/default.test c7124864cded213a3f118bc7e2e26f34b7c36dfa26cf6945cc8b7f5db1191277
|
||||
F test/delete.test 2686e1c98d552ef37d79ad55b17b93fe96fad9737786917ce3839767f734c48f
|
||||
@@ -1062,7 +1059,7 @@ F test/e_createtable.test 31b9bcb6ac8876bc7ec342d86d9c231a84c62b442093a6651dfd0f
|
||||
F test/e_delete.test ab39084f26ae1f033c940b70ebdbbd523dc4962e
|
||||
F test/e_droptrigger.test 235c610f8bf8ec44513e222b9085c7e49fad65ad0c1975ac2577109dd06fd8fa
|
||||
F test/e_dropview.test 74e405df7fa0f762e0c9445b166fe03955856532e2bb234c372f7c51228d75e7
|
||||
F test/e_expr.test 57a50ffd09c274b066883a59272efaf32a955c73af9f176d1c8889f0125bd2db
|
||||
F test/e_expr.test 0a1e175caddc78b27306647cb4ce2362c55790190f8cdd178b75fd6262eb8f76
|
||||
F test/e_fkey.test feeba6238aeff9d809fb6236b351da8df4ae9bda89e088e54526b31a0cbfeec5
|
||||
F test/e_fts3.test 17ba7c373aba4d4f5696ba147ee23fd1a1ef70782af050e03e262ca187c5ee07
|
||||
F test/e_insert.test f02f7f17852b2163732c6611d193f84fc67bc641fb4882c77a464076e5eba80e
|
||||
@@ -1095,7 +1092,7 @@ F test/exists.test 79a75323c78f02bbe9c251ea502a092f9ef63dac
|
||||
F test/existsexpr.test 9c4b77c4729281cc2ae63b9b460d0598ce28cc7876135e3e2c21629bbc8d077a
|
||||
F test/existsexpr2.test dc23e76389eff3d29f6488ff733012a3560cd67ec8cfaecbecd52cced5d5af11
|
||||
F test/existsfault.test ff41c11f3052c1bbd4f8dd557802310026253d67d7c4e3a180c16d2f0862973e
|
||||
F test/expr.test 4ada8eb822c45ef27a36851a258004d43c1e95e7c82585a1217e732084e4482c
|
||||
F test/expr.test db981f8a85520e99ae20aab7ad2e9b5b0437ed09159b57ced434c672075d2e61
|
||||
F test/expr2.test c27327ae9c017a7ff6280123f67aff496f912da74d78c888926d68b46ec75fd8
|
||||
F test/exprfault.test da33606d799718e2f8e34efd0e5858884a1ad87f608774c552a7f5517cc27181
|
||||
F test/exprfault2.test c49e84273898969af5dbc4fe6a3f4335f14639799f343590336c9ddf84425965
|
||||
@@ -1229,7 +1226,7 @@ F test/func5.test 863e6d1bd0013d09c17236f8a13ea34008dd857d87d85a13a673960e4c25d8
|
||||
F test/func6.test 3bc89ec0f2605736d3a118f43d25ef58115a7db4dba8ae939a363917d815c0bb
|
||||
F test/func7.test 7e009275f52c52954c8c028fdb62f8bc16cc47276fcc8753c1d2b22c6e074598
|
||||
F test/func8.test c4e2ecacf9f16e47a245e7a25fbabcc7e78f9c7c41a80f158527cdfdc6dd299d
|
||||
F test/func9.test 8901e97e2c3a52e5ea06a0f0c6199212957c7d6c3f727056a96abf5b81928512
|
||||
F test/func9.test 32c7d53b9bc99ddd45fad29457add438f2aca43d24920793773a96b13610f552
|
||||
F test/fuzz-oss1.test 514dcabb24687818ea949fa6760229eaacad74ca70157743ef36d35bbe01ffb0
|
||||
F test/fuzz.test 819ea7e483bcee91209aacbe6f9eaf3287baa1841479ee5f639f57c5e7c42b86
|
||||
F test/fuzz2.test 76dc35b32b6d6f965259508508abce75a6c4d7e1
|
||||
@@ -1331,7 +1328,7 @@ F test/joinC.test 1f1a602c2127f55f136e2cbd3bf2d26546614bf8cffe5902ec1ac9c07f87f2
|
||||
F test/joinD.test 2ce62e7353a0702ca5e70008faf319c1d4686aa19fba34275c6d1da0e960be28
|
||||
F test/joinE.test d5d182f3812771e2c0d97c9dcf5dbe4c41c8e21c82560e59358731c4a3981d6b
|
||||
F test/joinF.test 53dd66158806823ea680dd7543b5406af151b5aafa5cd06a7f3231cd94938127
|
||||
F test/joinH.test fd76024ff104baec16417db5cafc0894ad4e0863e70803e63c1bba0322706339
|
||||
F test/joinH.test 1d2fc3190be68525fd9ce749b9468c40ba2930181e52fb5ee6f836051b38effb
|
||||
F test/joinI.test fc7d24a2b1e444979b83bd92c30ebb975cebb5b9eae4442ce94969bd8d083053
|
||||
F test/journal1.test bc61a4228db11bffca118bd358ba4b868524bf080f3532749de6c539656e20fa
|
||||
F test/journal2.test 9dac6b4ba0ca79c3b21446bbae993a462c2397c4
|
||||
@@ -1428,7 +1425,7 @@ F test/misc5.test 02fcaf4d42405be02ec975e946270a50b0282dac98c78303ade0d1392839d2
|
||||
F test/misc6.test 953cc693924d88e6117aeba16f46f0bf5abede91
|
||||
F test/misc7.test d595599972ec0b436985f0f02f243b68500ffc977b9b3194ec66c0866cfddcab
|
||||
F test/misc8.test 08d2380bc435486b12161521f225043ac2be26f02471c2c1ea4cac0b1548edbd
|
||||
F test/misuse.test 46d42ffdf375833ea5828796e56f84660344f7548659b493059f152f00e66840
|
||||
F test/misuse.test 859f37014d9824ca66bd90c36372c08c80c51c9593a7cfa8a31d4f92cd4d5b7f
|
||||
F test/mjournal.test 28a08d5cb5fb5b5702a46e19176e45e964e0800d1f894677169e79f34030e152
|
||||
F test/mmap1.test 18de3fd7b70a777af6004ca2feecfcdd3d0be17fa04058e808baf530c94b1a1d
|
||||
F test/mmap2.test dba452dc7db91e9df10f70bdd73dc4190c7b8ee7b5133b4684f04277ada0b9ac
|
||||
@@ -1474,7 +1471,7 @@ F test/orderby9.test 87fb9548debcc2cd141c5299002dd94672fa76a3
|
||||
F test/orderbyA.test df608e59efc2ef50c1eddf1a773b272de3252e9401bfec86d04b52fd973866d5
|
||||
F test/orderbyB.test 32576c7b138105bc72f7fbf33bd320ca3a7d303641fc939e0e56af6cba884b3d
|
||||
F test/oserror.test ee3fad06ec8671c4d047c2c92a567fc2e0e8161caaec7edd6d48325c5ac97f30
|
||||
F test/ossfuzz.c 9636dad2092a05a32110df0ca06713038dd0c43dd89a77dabe4b8b0d71096715
|
||||
F test/ossfuzz.c b5d232d9717fc999a121c82c4880ae5b9d7fb3ae55d2d87a8da906bc80020906
|
||||
F test/ossshell.c f125c5bd16e537a2549aa579b328dd1c59905e7ab1338dfc210e755bb7b69f17
|
||||
F test/ovfl.test 199c482696defceacee8c8e0e0ef36da62726b2f
|
||||
F test/pager1.test b083c2d5d89df8e979658d9320bfc0b9d50b4ef8ae1d9e115a692ff0b9768393
|
||||
@@ -1525,7 +1522,7 @@ F test/reindex.test cd9d6021729910ece82267b4f5e1b5ac2911a7566c43b43c176a6a4732e2
|
||||
F test/reservebytes.test 6163640b5a5120c0dee6591481e673a0fa0bf0d12d4da7513bad692c1a49a162
|
||||
F test/resetdb.test 54c06f18bc832ac6d6319e5ab23d5c8dd49fdbeec7c696d791682a8006bd5fc3
|
||||
F test/resolver01.test f4022acafda7f4d40eca94dbf16bc5fc4ac30ceb
|
||||
F test/returning1.test 212cd4111bb941a60abf608f20250db666c21eb1bc4d49217e96c87ff3ab9d1a
|
||||
F test/returning1.test cd32517148948859db214dd814354597dd40e7489259590fac1a4f7bf44deb97
|
||||
F test/returningfault.test ae4c4b5e8745813287a359d9ccdb9d5c883c2e68afb18fb0767937d5de5692a4
|
||||
F test/rollback.test 952c4d805bca96adc2be76f621ea22115fe40b330015af36fcc8028c8547fcee
|
||||
F test/rollback2.test 3f3a4e20401825017df7e7671e9f31b6de5fae5620c2b9b49917f52f8c160a8f
|
||||
@@ -1599,10 +1596,10 @@ F test/sharedA.test 64bdd21216dda2c6a3bd3475348ccdc108160f34682c97f2f51c19fc0e21
|
||||
F test/sharedB.test 1a84863d7a2204e0d42f2e1606577c5e92e4473fa37ea0f5bdf829e4bf8ee707
|
||||
F test/shared_err.test 32634e404a3317eeb94abc7a099c556a346fdb8fb3858dbe222a4cbb8926a939
|
||||
F test/sharedlock.test 5ede3c37439067c43b0198f580fd374ebf15d304
|
||||
F test/shell1.test 396c04132628fe1c627fd4807a93a116f712cfb1cfe9ca5d553b1c89361a899f
|
||||
F test/shell1.test ebe953d64c937ad42a0f33170ac0d2d2568faae26813fc7a95203756446d54aa
|
||||
F test/shell2.test ab23f01ea2347e4b72bb2399af7ee82aa00f9c059141749f7c4064abca5ad728
|
||||
F test/shell3.test 603b448e917537cf77be0f265c05c6f63bc677c63a533c8e96aae923b56f4a0e
|
||||
F test/shell4.test ad7eee983b5e7f1dd92d8c87bc0f39474086bc32c980c00f3934c54aabc636a2
|
||||
F test/shell4.test 03593fa7908a55f255916ffeda707cdf55680c777736e3da62b1d78cde0d684d
|
||||
F test/shell5.test d17e7927ab8b7f720efbdd9b5d05fceb6c3c56c25917901b315400214bf24ef4
|
||||
F test/shell6.test e3b883b61d4916b6906678a35f9d19054861123ad91b856461e0a456273bdbb8
|
||||
F test/shell7.test 43fd8e511c533bab5232e95c7b4be93b243451709e89582600d4b6e67693d5c3
|
||||
@@ -1643,7 +1640,7 @@ F test/speed4.test abc0ad3399dcf9703abed2fff8705e4f8e416715
|
||||
F test/speed4p.explain 6b5f104ebeb34a038b2f714150f51d01143e59aa
|
||||
F test/speed4p.test 377a0c48e5a92e0b11c1c5ebb1bc9d83a7312c922bc0cb05970ef5d6a96d1f0c
|
||||
F test/speedtest.md ee958457ae1b729d9715ae33c0320600000bf1d9ddea1a88dcf79f56729d6fad
|
||||
F test/speedtest.tcl 405411356fbc54af15987b7ffeec330a49138f71584220fb8fe1948b2f7ac907 x
|
||||
F test/speedtest.tcl 6b66974d833d35a63d0e9ec344e0ffa92fbbfac83e173556f700a61cb3be96fc x
|
||||
F test/speedtest1.c 6c01252e66f46de0b6b8d5316e03521e2151782104f3608c10262aa5dce85721
|
||||
F test/spellfix.test 951a6405d49d1a23d6b78027d3877b4a33eeb8221dcab5704b499755bb4f552e
|
||||
F test/spellfix2.test dfc8f519a3fc204cb2dfa8b4f29821ae90f6f8c3
|
||||
@@ -1691,8 +1688,9 @@ F test/temptable2.test 76821347810ecc88203e6ef0dd6897b6036ac788e9dd3e6b04fd4d163
|
||||
F test/temptable3.test d11a0974e52b347e45ee54ef1923c91ed91e4637
|
||||
F test/temptrigger.test 38f0ca479b1822d3117069e014daabcaacefffcc
|
||||
F test/tester.tcl 463ae33b8bf75ac77451df19bd65e7c415c2e9891227c7c9e657d0a2d8e1074a
|
||||
F test/testrunner.tcl 9da764507f6bc752961555c0beb58eb6584b9fb0f989342c7eaab3336380f560 x
|
||||
F test/testrunner_data.tcl 497a0680747dc2b1b59b1ed17d2b808734b77260e327740006d835aee2f8d74c
|
||||
F test/testloadext.c 862b848783eaed9985fbce46c65cd214664376b549fae252b364d5d1ef350a27
|
||||
F test/testrunner.tcl 86179a8e78997e9257cb8f738c5624cb23897da5297855578ba74715e64f1602 x
|
||||
F test/testrunner_data.tcl c507a9afa911c03446ed90442ffd4a98aca02882c3d51bd1177c24795674def8
|
||||
F test/testrunner_estwork.tcl 7927a84327259a32854926f68a75292e33a61e7e052fdbfcb01f18696c99c724
|
||||
F test/thread001.test a0985c117eab62c0c65526e9fa5d1360dd1cac5b03bde223902763274ce21899
|
||||
F test/thread002.test c24c83408e35ba5a952a3638b7ac03ccdf1ce4409289c54a050ac4c5f1de7502
|
||||
@@ -1999,7 +1997,7 @@ F test/walsetlk_recover.test adccbffc59e365063a4efd2da6b661ae2fcf15d775b6719fe46
|
||||
F test/walsetlk_snapshot.test 86d5588380f9927d8fcbbd75133b0a34fddf959378d6823c6f164a390123f70a
|
||||
F test/walshared.test 42e3808582504878af237ea02c42ca793e8a0efaa19df7df26ac573370dbc7a3
|
||||
F test/walslow.test 0c51843836c9dcf40a5ac05aa781bfb977b396ee2c872d92bd48b79d5dd9aa23
|
||||
F test/walthread.test 14b20fcfa6ae152f5d8e12f5dc8a8a724b7ef189f5d8ef1e2ceab79f2af51747
|
||||
F test/walthread.test d562f51a61191ccfab64940df7aa1cef87c902fa5ab742590ef7f859dfe6a44b
|
||||
F test/walvfs.test e1a6ad0f3c78e98b55c3d5f0889cf366cc0d0a1cb2bccb44ac9ec67384adc4a1
|
||||
F test/where.test 5087c72d26fd075a1644c8512be9fe18de9bf2d2b0754f7fd9b74a1c6540c4fc
|
||||
F test/where2.test 52237a8cb27ebbf6583469429bb5733d1b94ac37d09c3dbd0f487952ed0ab3f8
|
||||
@@ -2107,7 +2105,7 @@ F tool/index_usage.c f62a0c701b2c7ff2f3e21d206f093c123f222dbf07136a10ffd1ca15a5c
|
||||
F tool/lemon.c 8f6c122e5727cb0e5f302b8efc91489b1947a8d98206d7a1b1cfc0ed685b6e7c
|
||||
F tool/lempar.c bdffd3b233a4e4e78056c9c01fadd2bb3fe902435abde3bce3d769fdf0d5cca2
|
||||
F tool/libvers.c caafc3b689638a1d88d44bc5f526c2278760d9b9
|
||||
F tool/loadfts.c c3c64e4d5e90e8ba41159232c2189dba4be7b862
|
||||
F tool/loadfts.c 63412f9790e5e8538fbde0b4f6db154aaaf80f7a10a01e3c94d14b773a8dd5a6
|
||||
F tool/logest.c c34e5944318415de513d29a6098df247a9618c96d83c38d4abd88641fe46e669
|
||||
F tool/max-limits.c cbb635fbb37ae4d05f240bfb5b5270bb63c54439
|
||||
F tool/merge-test.tcl de76b62f2de2a92d4c1ca4f976bce0aea6899e0229e250479b229b2a1914b176
|
||||
@@ -2120,7 +2118,7 @@ F tool/mkmsvcmin.tcl d76c45efda1cce2d4005bcea7b8a22bb752e3256009f331120fb4fecb14
|
||||
F tool/mkopcodec.tcl 33d20791e191df43209b77d37f0ff0904620b28465cca6990cf8d60da61a07ef
|
||||
F tool/mkopcodeh.tcl 2b4e6967a670ef21bf53a164964c35c6163277d002a4c6f56fa231d68c88d023
|
||||
F tool/mkopts.tcl 680f785fdb09729fd9ac50632413da4eadbdf9071535e3f26d03795828ab07fa
|
||||
F tool/mkpragmatab.tcl 5615f8ea9ae6990b73da765c5f121117cbc2a5197b65bed25c56f71c7ab2f42a
|
||||
F tool/mkpragmatab.tcl 3801ce32f8c55fe63a3b279f231fb26c2c1a2ea9a09d2dd599239d87a609acec
|
||||
F tool/mkshellc.tcl bab0a72a68384181a5706712dfdf6815f6526446d4e8aacace2de5e80cda91b2
|
||||
F tool/mksourceid.c 36aa8020014aed0836fd13c51d6dc9219b0df1761d6b5f58ff5b616211b079b9
|
||||
F tool/mksqlite3c-noext.tcl 351c55256213154cabb051a3c870ef9f4487de905015141ae50dc7578a901b84
|
||||
@@ -2143,7 +2141,7 @@ F tool/showdb.c 3956d71e5193162609a60e8c9edfcf09274c00cfea2b1d221261427adb2b5cca
|
||||
F tool/showjournal.c 5bad7ae8784a43d2b270d953060423b8bd480818
|
||||
F tool/showlocks.c 9cc5e66d4ebbf2d194f39db2527ece92077e86ae627ddd233ee48e16e8142564
|
||||
F tool/showshm.c a0ab6ec32dd1f11218ca2a4018f8fb875b59414801ab8ceed8b2e69b7b45a809
|
||||
F tool/showstat4.c 0682ebea7abf4d3657f53c4a243f2e7eab48eab344ed36a94bb75dcd19a5c2a1
|
||||
F tool/showstat4.c b706fcbc4cd1a6e4a73ac32549afc4b460479d650402d64b23e8d813516e8de4
|
||||
F tool/showwal.c 11eca547980a066b081f512636151233350ac679f29ecf4ebfce7f4530230b3d
|
||||
F tool/soak1.tcl a3892082ed1079671565c044e93b55c3c7f38829aedf53cc597c65d23ffdaddf
|
||||
F tool/spaceanal.tcl 1f83962090a6b60e1d7bf92495d643e622bef9fe82ea3f2d22350dcbce9a12d0
|
||||
@@ -2156,7 +2154,7 @@ F tool/sqltclsh.c.in 1bcc2e9da58fadf17b0bf6a50e68c1159e602ce057210b655d50bad5aaa
|
||||
F tool/sqltclsh.tcl 862f4cf1418df5e1315b5db3b5ebe88969e2a784525af5fbf9596592f14ed848
|
||||
F tool/src-verify.c 6c655d9a8d6b30f3648fc78a79bf3838ed68f8543869d380c43ea9f17b3b8501
|
||||
F tool/srcck1.c 559e703c6cca1d70398bdba1d7f91036c1a71adf718a1aaa6401a562ccaed154
|
||||
F tool/srctree-check.tcl fa4d82dd3e8a38d5cbce7d6ade8abef2f42b9eca0394484d521dc8d086739460 x
|
||||
F tool/srctree-check.tcl fa4d82dd3e8a38d5cbce7d6ade8abef2f42b9eca0394484d521dc8d086739460
|
||||
F tool/stack_usage.tcl f8e71b92cdb099a147dad572375595eae55eca43
|
||||
F tool/stripccomments.c 68d2aa8cb504439f541ce66b8f128067612bdd16f5fb7bfe540f3fcb67c9c197
|
||||
F tool/symbols-mingw.sh 4dbcea7e74768305384c9fd2ed2b41bbf9f0414d
|
||||
@@ -2167,10 +2165,13 @@ F tool/vdbe-compress.tcl fa2f37ab39b2a0087fafb6a7f3ce19503e25e624ffa8ed9951717ab
|
||||
F tool/vdbe_profile.tcl 3ac5a4a9449f4baf77059358ea050db3e34395ccf59c5464d29b91746d5b961e
|
||||
F tool/version-info.c 33d0390ef484b3b1cb685d59362be891ea162123cea181cb8e6d2cf6ddf2700c
|
||||
F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7
|
||||
F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd
|
||||
F tool/warnings.sh d924598cf2f55a4ecbc2aeb055c10bd5f48114793e7ba25f9585435da29e7e98
|
||||
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
|
||||
P 38807d8bce50114fcaaa656bba0437fd3c3164c7051e9938a39c2791c8f4725b e6b9bfdb6f8f86d4d2891d65fee4274dcbc61c9e998d81f90232153c05788cab
|
||||
R a2360b58313ffdb82688d1798b44ecee
|
||||
P 42f95ea71e5e7e927685de3a6da2ede38abe7cabdd1fc71b9a14bebe9f54a65e
|
||||
R 6ccca5a4124b16122b6a766379fbe805
|
||||
T *branch * sqlite3-node.mjs
|
||||
T *sym-sqlite3-node.mjs *
|
||||
T -sym-trunk * Cancelled\sby\sbranch.
|
||||
U stephan
|
||||
Z eb375049ccc04e2e9e9409c5a07225cf
|
||||
Z 351cb48117de9374caee3897f1c40064
|
||||
# Remove this line to create a well-formed Fossil manifest.
|
||||
|
||||
+2
-2
@@ -1,2 +1,2 @@
|
||||
branch cygwin-fixes
|
||||
tag cygwin-fixes
|
||||
branch sqlite3-node.mjs
|
||||
tag sqlite3-node.mjs
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
aeb983a65051c2233e88511f69d1456945a15e94d3e38a12837f782f7cc1e525
|
||||
8611cf643b11335cd490da1856c34b4f10ac8b82856e0857be1192e36da31f17
|
||||
|
||||
@@ -1037,6 +1037,10 @@ static void runScript(
|
||||
for(k=(int)strlen(zFilename)-1; k>=0 && !isDirSep(zFilename[k]); k--){}
|
||||
if( k>0 ){
|
||||
zNewFile = zToDel = sqlite3_mprintf("%.*s/%s", k,zFilename,zNewFile);
|
||||
if( zNewFile==0 ){
|
||||
fprintf(stderr, "out of memory\n");
|
||||
abort();
|
||||
}
|
||||
}
|
||||
}
|
||||
zNewScript = readFile(zNewFile);
|
||||
|
||||
+1
-1
@@ -9758,7 +9758,7 @@ int sqlite3BtreeTransferRow(BtCursor *pDest, BtCursor *pSrc, i64 iKey){
|
||||
}while( rc==SQLITE_OK && nOut>0 );
|
||||
|
||||
if( rc==SQLITE_OK && nRem>0 && ALWAYS(pPgnoOut) ){
|
||||
Pgno pgnoNew;
|
||||
Pgno pgnoNew = 0; /* Prevent harmless static-analyzer warning */
|
||||
MemPage *pNew = 0;
|
||||
rc = allocateBtreePage(pBt, &pNew, &pgnoNew, 0, 0);
|
||||
put4byte(pPgnoOut, pgnoNew);
|
||||
|
||||
+10
-2
@@ -504,8 +504,16 @@ void sqlite3SchemaClear(void *p){
|
||||
temp2 = pSchema->trigHash;
|
||||
sqlite3HashInit(&pSchema->trigHash);
|
||||
sqlite3HashClear(&pSchema->idxHash);
|
||||
for(pElem=sqliteHashFirst(&temp2); pElem; pElem=sqliteHashNext(pElem)){
|
||||
sqlite3DeleteTrigger(&xdb, (Trigger*)sqliteHashData(pElem));
|
||||
for(pElem=sqliteHashFirst(&temp2); pElem; ){
|
||||
HashElem *pNext = sqliteHashNext(pElem);
|
||||
Trigger *pTrig = (Trigger*)sqliteHashData(pElem);
|
||||
if( pTrig->bReturning ){
|
||||
/* Do not remove RETURNING triggers from the temp-triggers hash */
|
||||
sqlite3HashTransfer(&pSchema->trigHash, &temp2, pElem);
|
||||
}else{
|
||||
sqlite3DeleteTrigger(&xdb, pTrig);
|
||||
}
|
||||
pElem = pNext;
|
||||
}
|
||||
sqlite3HashClear(&temp2);
|
||||
sqlite3HashInit(&pSchema->tblHash);
|
||||
|
||||
+7
-6
@@ -66,8 +66,9 @@
|
||||
/*
|
||||
** Names of allowed datatypes
|
||||
*/
|
||||
static const char *azType[] = { "int32", "int64", "double", "char*",
|
||||
"struct iovec" };
|
||||
static const char *azCarrayType[] = {
|
||||
"int32", "int64", "double", "char*", "struct iovec"
|
||||
};
|
||||
|
||||
/*
|
||||
** Structure used to hold the sqlite3_carray_bind() information
|
||||
@@ -186,7 +187,7 @@ static int carrayColumn(
|
||||
case CARRAY_COLUMN_POINTER: return SQLITE_OK;
|
||||
case CARRAY_COLUMN_COUNT: x = pCur->iCnt; break;
|
||||
case CARRAY_COLUMN_CTYPE: {
|
||||
sqlite3_result_text(ctx, azType[pCur->eType], -1, SQLITE_STATIC);
|
||||
sqlite3_result_text(ctx, azCarrayType[pCur->eType], -1, SQLITE_STATIC);
|
||||
return SQLITE_OK;
|
||||
}
|
||||
default: {
|
||||
@@ -274,10 +275,10 @@ static int carrayFilter(
|
||||
}else{
|
||||
unsigned char i;
|
||||
const char *zType = (const char*)sqlite3_value_text(argv[2]);
|
||||
for(i=0; i<sizeof(azType)/sizeof(azType[0]); i++){
|
||||
if( sqlite3_stricmp(zType, azType[i])==0 ) break;
|
||||
for(i=0; i<sizeof(azCarrayType)/sizeof(azCarrayType[0]); i++){
|
||||
if( sqlite3_stricmp(zType, azCarrayType[i])==0 ) break;
|
||||
}
|
||||
if( i>=sizeof(azType)/sizeof(azType[0]) ){
|
||||
if( i>=sizeof(azCarrayType)/sizeof(azCarrayType[0]) ){
|
||||
pVtabCursor->pVtab->zErrMsg = sqlite3_mprintf(
|
||||
"unknown datatype: %Q", zType);
|
||||
return SQLITE_ERROR;
|
||||
|
||||
+2
-1
@@ -418,7 +418,8 @@ static int dbpageUpdate(
|
||||
memcpy(aPage, pData, szPage);
|
||||
pTab->pgnoTrunc = 0;
|
||||
}
|
||||
}else{
|
||||
}
|
||||
if( rc!=SQLITE_OK ){
|
||||
pTab->pgnoTrunc = 0;
|
||||
}
|
||||
sqlite3PagerUnref(pDbPage);
|
||||
|
||||
+1
-1
@@ -4844,7 +4844,7 @@ static SQLITE_NOINLINE int exprCodeTargetAndOr(
|
||||
pAlt = sqlite3ExprSimplifiedAndOr(pExpr);
|
||||
if( pAlt!=pExpr ){
|
||||
r1 = sqlite3ExprCodeTarget(pParse, pAlt, target);
|
||||
sqlite3VdbeAddOp3(v, OP_BitAnd, r1, r1, target);
|
||||
sqlite3VdbeAddOp3(v, OP_And, r1, r1, target);
|
||||
return target;
|
||||
}
|
||||
skipOp = op==TK_AND ? OP_IfNot : OP_If;
|
||||
|
||||
+66
-11
@@ -485,7 +485,7 @@ static void *contextMalloc(sqlite3_context *context, i64 nByte){
|
||||
sqlite3 *db = sqlite3_context_db_handle(context);
|
||||
assert( nByte>0 );
|
||||
testcase( nByte==db->aLimit[SQLITE_LIMIT_LENGTH] );
|
||||
testcase( nByte==db->aLimit[SQLITE_LIMIT_LENGTH]+1 );
|
||||
testcase( nByte==(i64)db->aLimit[SQLITE_LIMIT_LENGTH]+1 );
|
||||
if( nByte>db->aLimit[SQLITE_LIMIT_LENGTH] ){
|
||||
sqlite3_result_error_toobig(context);
|
||||
z = 0;
|
||||
@@ -1669,6 +1669,7 @@ static void concatFuncCore(
|
||||
){
|
||||
i64 j, n = 0;
|
||||
int i;
|
||||
int bNotNull = 0; /* True after at least NOT NULL argument seen */
|
||||
char *z;
|
||||
for(i=0; i<argc; i++){
|
||||
n += sqlite3_value_bytes(argv[i]);
|
||||
@@ -1685,12 +1686,13 @@ static void concatFuncCore(
|
||||
int k = sqlite3_value_bytes(argv[i]);
|
||||
const char *v = (const char*)sqlite3_value_text(argv[i]);
|
||||
if( v!=0 ){
|
||||
if( j>0 && nSep>0 ){
|
||||
if( bNotNull && nSep>0 ){
|
||||
memcpy(&z[j], zSep, nSep);
|
||||
j += nSep;
|
||||
}
|
||||
memcpy(&z[j], v, k);
|
||||
j += k;
|
||||
bNotNull = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2748,8 +2750,8 @@ static void signFunc(
|
||||
*/
|
||||
typedef struct Percentile Percentile;
|
||||
struct Percentile {
|
||||
unsigned nAlloc; /* Number of slots allocated for a[] */
|
||||
unsigned nUsed; /* Number of slots actually used in a[] */
|
||||
u64 nAlloc; /* Number of slots allocated for a[] */
|
||||
u64 nUsed; /* Number of slots actually used in a[] */
|
||||
char bSorted; /* True if a[] is already in sorted order */
|
||||
char bKeepSorted; /* True if advantageous to keep a[] sorted */
|
||||
char bPctValid; /* True if rPct is valid */
|
||||
@@ -2786,11 +2788,11 @@ static int percentSameValue(double a, double b){
|
||||
** order. The smallest return value in this case will be 0, and
|
||||
** the largest return value will be p->nUsed.
|
||||
*/
|
||||
static int percentBinarySearch(Percentile *p, double y, int bExact){
|
||||
int iFirst = 0; /* First element of search range */
|
||||
int iLast = p->nUsed - 1; /* Last element of search range */
|
||||
static i64 percentBinarySearch(Percentile *p, double y, int bExact){
|
||||
i64 iFirst = 0; /* First element of search range */
|
||||
i64 iLast = (i64)p->nUsed - 1; /* Last element of search range */
|
||||
while( iLast>=iFirst ){
|
||||
int iMid = (iFirst+iLast)/2;
|
||||
i64 iMid = (iFirst+iLast)/2;
|
||||
double x = p->a[iMid];
|
||||
if( x<y ){
|
||||
iFirst = iMid + 1;
|
||||
@@ -2893,7 +2895,7 @@ static void percentStep(sqlite3_context *pCtx, int argc, sqlite3_value **argv){
|
||||
|
||||
/* Allocate and store the Y */
|
||||
if( p->nUsed>=p->nAlloc ){
|
||||
unsigned n = p->nAlloc*2 + 250;
|
||||
u64 n = p->nAlloc*2 + 250;
|
||||
double *a = sqlite3_realloc64(p->a, sizeof(double)*n);
|
||||
if( a==0 ){
|
||||
sqlite3_free(p->a);
|
||||
@@ -2910,7 +2912,7 @@ static void percentStep(sqlite3_context *pCtx, int argc, sqlite3_value **argv){
|
||||
}else if( !p->bSorted || y>=p->a[p->nUsed-1] ){
|
||||
p->a[p->nUsed++] = y;
|
||||
}else if( p->bKeepSorted ){
|
||||
int i;
|
||||
i64 i;
|
||||
i = percentBinarySearch(p, y, 0);
|
||||
if( i<(int)p->nUsed ){
|
||||
memmove(&p->a[i+1], &p->a[i], (p->nUsed-i)*sizeof(p->a[0]));
|
||||
@@ -2995,7 +2997,7 @@ static void percentInverse(sqlite3_context *pCtx,int argc,sqlite3_value **argv){
|
||||
Percentile *p;
|
||||
int eType;
|
||||
double y;
|
||||
int i;
|
||||
i64 i;
|
||||
assert( argc==2 || argc==1 );
|
||||
|
||||
/* Allocate the session context. */
|
||||
@@ -3081,6 +3083,56 @@ static void percentValue(sqlite3_context *pCtx){
|
||||
/****** End of percentile family of functions ******/
|
||||
#endif /* SQLITE_ENABLE_PERCENTILE */
|
||||
|
||||
#if defined(SQLITE_DEBUG) || defined(SQLITE_ENABLE_FILESTAT)
|
||||
/*
|
||||
** Implementation of sqlite_filestat(SCHEMA).
|
||||
**
|
||||
** Return JSON text that describes low-level debug/diagnostic information
|
||||
** about the sqlite3_file object associated with SCHEMA.
|
||||
*/
|
||||
static void filestatFunc(
|
||||
sqlite3_context *context,
|
||||
int argc,
|
||||
sqlite3_value **argv
|
||||
){
|
||||
sqlite3 *db = sqlite3_context_db_handle(context);
|
||||
const char *zDbName;
|
||||
sqlite3_str *pStr;
|
||||
Btree *pBtree;
|
||||
|
||||
zDbName = (const char*)sqlite3_value_text(argv[0]);
|
||||
pBtree = sqlite3DbNameToBtree(db, zDbName);
|
||||
if( pBtree ){
|
||||
Pager *pPager;
|
||||
sqlite3_file *fd;
|
||||
int rc;
|
||||
sqlite3BtreeEnter(pBtree);
|
||||
pPager = sqlite3BtreePager(pBtree);
|
||||
assert( pPager!=0 );
|
||||
fd = sqlite3PagerFile(pPager);
|
||||
pStr = sqlite3_str_new(db);
|
||||
if( pStr==0 ){
|
||||
sqlite3_result_error_nomem(context);
|
||||
}else{
|
||||
sqlite3_str_append(pStr, "{\"db\":", 6);
|
||||
rc = sqlite3OsFileControl(fd, SQLITE_FCNTL_FILESTAT, pStr);
|
||||
if( rc ) sqlite3_str_append(pStr, "null", 4);
|
||||
fd = sqlite3PagerJrnlFile(pPager);
|
||||
if( fd && fd->pMethods!=0 ){
|
||||
sqlite3_str_appendall(pStr, ",\"journal\":");
|
||||
rc = sqlite3OsFileControl(fd, SQLITE_FCNTL_FILESTAT, pStr);
|
||||
if( rc ) sqlite3_str_append(pStr, "null", 4);
|
||||
}
|
||||
sqlite3_str_append(pStr, "}", 1);
|
||||
sqlite3_result_text(context, sqlite3_str_finish(pStr), -1,
|
||||
sqlite3_free);
|
||||
}
|
||||
sqlite3BtreeLeave(pBtree);
|
||||
}else{
|
||||
sqlite3_result_text(context, "{}", 2, SQLITE_STATIC);
|
||||
}
|
||||
}
|
||||
#endif /* SQLITE_DEBUG || SQLITE_ENABLE_FILESTAT */
|
||||
|
||||
#ifdef SQLITE_DEBUG
|
||||
/*
|
||||
@@ -3239,6 +3291,9 @@ void sqlite3RegisterBuiltinFunctions(void){
|
||||
INLINE_FUNC(likely, 1, INLINEFUNC_unlikely, SQLITE_FUNC_UNLIKELY),
|
||||
#ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC
|
||||
INLINE_FUNC(sqlite_offset, 1, INLINEFUNC_sqlite_offset, 0 ),
|
||||
#endif
|
||||
#if defined(SQLITE_DEBUG) || defined(SQLITE_ENABLE_FILESTAT)
|
||||
FUNCTION(sqlite_filestat, 1, 0, 0, filestatFunc ),
|
||||
#endif
|
||||
FUNCTION(ltrim, 1, 1, 0, trimFunc ),
|
||||
FUNCTION(ltrim, 2, 1, 0, trimFunc ),
|
||||
|
||||
+23
@@ -270,3 +270,26 @@ void *sqlite3HashInsert(Hash *pH, const char *pKey, void *data){
|
||||
insertElement(pH, pH->ht ? &pH->ht[new_elem->h % pH->htsize] : 0, new_elem);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
** Parameter pElem is currently part of hash table pFrom. Add it to hash
|
||||
** table pTo.
|
||||
**
|
||||
** This procedure corrupts hash table pFrom. Specifically, it removes element
|
||||
** pElem from the list of all elements in the hash table, but may leave
|
||||
** a pointer to it in one of the hash buckets of pFrom. This is not a problem
|
||||
** because this function is only called if hash table pFrom will be cleared
|
||||
** before any further lookups or inserts are attempted.
|
||||
*/
|
||||
void sqlite3HashTransfer(Hash *pTo, Hash *pFrom, HashElem *pElem){
|
||||
if( pElem->prev ){
|
||||
pElem->prev->next = pElem->next;
|
||||
}else{
|
||||
assert( pFrom->first==pElem );
|
||||
pFrom->first = pElem->next;
|
||||
}
|
||||
pTo->count++;
|
||||
insertElement(pTo, pTo->ht ? &pTo->ht[pElem->h % pTo->htsize] : 0, pElem);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -70,6 +70,7 @@ void sqlite3HashInit(Hash*);
|
||||
void *sqlite3HashInsert(Hash*, const char *pKey, void *pData);
|
||||
void *sqlite3HashFind(const Hash*, const char *pKey);
|
||||
void sqlite3HashClear(Hash*);
|
||||
void sqlite3HashTransfer(Hash*, Hash*, HashElem *pElem);
|
||||
|
||||
/*
|
||||
** Macros for looping over all elements of a hash table. The idiom is
|
||||
|
||||
+19
-21
@@ -16,17 +16,18 @@
|
||||
#ifndef SQLITE_HWTIME_H
|
||||
#define SQLITE_HWTIME_H
|
||||
|
||||
/*
|
||||
** The following routine only works on Pentium-class (or newer) processors.
|
||||
** It uses the RDTSC opcode to read the cycle count value out of the
|
||||
** processor and returns that value. This can be used for high-res
|
||||
** profiling.
|
||||
*/
|
||||
#if !defined(__STRICT_ANSI__) && \
|
||||
(defined(__GNUC__) || defined(_MSC_VER)) && \
|
||||
(defined(i386) || defined(__i386__) || defined(_M_IX86))
|
||||
#if defined(_MSC_VER) && defined(_WIN32)
|
||||
|
||||
#if defined(__GNUC__)
|
||||
#include <profileapi.h>
|
||||
|
||||
__inline sqlite3_uint64 sqlite3Hwtime(void){
|
||||
LARGE_INTEGER tm;
|
||||
QueryPerformanceCounter(&tm);
|
||||
return (sqlite3_uint64)tm.QuadPart;
|
||||
}
|
||||
|
||||
#elif !defined(__STRICT_ANSI__) && defined(__GNUC__) && \
|
||||
(defined(i386) || defined(__i386__) || defined(_M_IX86))
|
||||
|
||||
__inline__ sqlite_uint64 sqlite3Hwtime(void){
|
||||
unsigned int lo, hi;
|
||||
@@ -34,17 +35,6 @@
|
||||
return (sqlite_uint64)hi << 32 | lo;
|
||||
}
|
||||
|
||||
#elif defined(_MSC_VER)
|
||||
|
||||
__declspec(naked) __inline sqlite_uint64 __cdecl sqlite3Hwtime(void){
|
||||
__asm {
|
||||
rdtsc
|
||||
ret ; return value at EDX:EAX
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#elif !defined(__STRICT_ANSI__) && (defined(__GNUC__) && defined(__x86_64__))
|
||||
|
||||
__inline__ sqlite_uint64 sqlite3Hwtime(void){
|
||||
@@ -52,6 +42,14 @@
|
||||
__asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi));
|
||||
return (sqlite_uint64)hi << 32 | lo;
|
||||
}
|
||||
|
||||
#elif !defined(__STRICT_ANSI__) && defined(__GNUC__) && defined(__aarch64__)
|
||||
|
||||
__inline__ sqlite_uint64 sqlite3Hwtime(void){
|
||||
sqlite3_uint64 cnt;
|
||||
__asm__ __volatile__ ("mrs %0, cntvct_el0" : "=r" (cnt));
|
||||
return cnt;
|
||||
}
|
||||
|
||||
#elif !defined(__STRICT_ANSI__) && (defined(__GNUC__) && defined(__ppc__))
|
||||
|
||||
|
||||
+3
-2
@@ -521,7 +521,8 @@ static const sqlite3_api_routines sqlite3Apis = {
|
||||
/* Version 3.50.0 and later */
|
||||
sqlite3_setlk_timeout,
|
||||
/* Version 3.51.0 and later */
|
||||
sqlite3_set_errmsg
|
||||
sqlite3_set_errmsg,
|
||||
sqlite3_db_status64
|
||||
};
|
||||
|
||||
/* True if x is the directory separator character
|
||||
@@ -563,7 +564,7 @@ static int sqlite3LoadExtension(
|
||||
|
||||
/* Shared library endings to try if zFile cannot be loaded as written */
|
||||
static const char *azEndings[] = {
|
||||
#if SQLITE_OS_WIN || defined(__CYGWIN__)
|
||||
#if SQLITE_OS_WIN
|
||||
"dll"
|
||||
#elif defined(__APPLE__)
|
||||
"dylib"
|
||||
|
||||
+11
-1
@@ -1394,6 +1394,7 @@ void sqlite3LeaveMutexAndCloseZombie(sqlite3 *db){
|
||||
/* Clear the TEMP schema separately and last */
|
||||
if( db->aDb[1].pSchema ){
|
||||
sqlite3SchemaClear(db->aDb[1].pSchema);
|
||||
assert( db->aDb[1].pSchema->trigHash.count==0 );
|
||||
}
|
||||
sqlite3VtabUnlockList(db);
|
||||
|
||||
@@ -2525,6 +2526,9 @@ void *sqlite3_wal_hook(
|
||||
sqlite3_mutex_leave(db->mutex);
|
||||
return pRet;
|
||||
#else
|
||||
UNUSED_PARAMETER(db);
|
||||
UNUSED_PARAMETER(xCallback);
|
||||
UNUSED_PARAMETER(pArg);
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
@@ -2540,6 +2544,11 @@ int sqlite3_wal_checkpoint_v2(
|
||||
int *pnCkpt /* OUT: Total number of frames checkpointed */
|
||||
){
|
||||
#ifdef SQLITE_OMIT_WAL
|
||||
UNUSED_PARAMETER(db);
|
||||
UNUSED_PARAMETER(zDb);
|
||||
UNUSED_PARAMETER(eMode);
|
||||
UNUSED_PARAMETER(pnLog);
|
||||
UNUSED_PARAMETER(pnCkpt);
|
||||
return SQLITE_OK;
|
||||
#else
|
||||
int rc; /* Return code */
|
||||
@@ -2722,7 +2731,7 @@ const char *sqlite3_errmsg(sqlite3 *db){
|
||||
*/
|
||||
int sqlite3_set_errmsg(sqlite3 *db, int errcode, const char *zMsg){
|
||||
int rc = SQLITE_OK;
|
||||
if( !sqlite3SafetyCheckSickOrOk(db) ){
|
||||
if( !sqlite3SafetyCheckOk(db) ){
|
||||
return SQLITE_MISUSE_BKPT;
|
||||
}
|
||||
sqlite3_mutex_enter(db->mutex);
|
||||
@@ -4902,6 +4911,7 @@ const char *sqlite3_filename_journal(const char *zFilename){
|
||||
}
|
||||
const char *sqlite3_filename_wal(const char *zFilename){
|
||||
#ifdef SQLITE_OMIT_WAL
|
||||
UNUSED_PARAMETER(zFilename);
|
||||
return 0;
|
||||
#else
|
||||
zFilename = sqlite3_filename_journal(zFilename);
|
||||
|
||||
+1
-1
@@ -41,7 +41,7 @@
|
||||
# define SQLITE_MUTEX_OMIT
|
||||
#endif
|
||||
#if SQLITE_THREADSAFE && !defined(SQLITE_MUTEX_NOOP)
|
||||
# if SQLITE_OS_UNIX || defined(__CYGWIN__)
|
||||
# if SQLITE_OS_UNIX
|
||||
# define SQLITE_MUTEX_PTHREADS
|
||||
# elif SQLITE_OS_WIN
|
||||
# define SQLITE_MUTEX_W32
|
||||
|
||||
+1
-9
@@ -30,7 +30,6 @@
|
||||
** will defined to either 1 or 0. One of them will be 1. The others will be 0.
|
||||
** If none of the macros are initially defined, then select either
|
||||
** SQLITE_OS_UNIX or SQLITE_OS_WIN depending on the target platform.
|
||||
** One exception: On Cygwin, both SQLITE_OS_UNIX and SQLITE_OS_WIN can be 1.
|
||||
**
|
||||
** If SQLITE_OS_OTHER=1 is specified at compile-time, then the application
|
||||
** must provide its own VFS implementation together with sqlite3_os_init()
|
||||
@@ -38,10 +37,7 @@
|
||||
*/
|
||||
#if SQLITE_OS_KV+1<=1 && SQLITE_OS_OTHER+1<=1 && \
|
||||
SQLITE_OS_WIN+1<=1 && SQLITE_OS_UNIX+1<=1
|
||||
# if defined(__CYGWIN__)
|
||||
# define SQLITE_OS_WIN 1
|
||||
# define SQLITE_OS_UNIX 1
|
||||
# elif defined(_WIN32) || defined(WIN32) || \
|
||||
# if defined(_WIN32) || defined(WIN32) || defined(__CYGWIN__) || \
|
||||
defined(__MINGW32__) || defined(__BORLANDC__)
|
||||
# define SQLITE_OS_WIN 1
|
||||
# define SQLITE_OS_UNIX 0
|
||||
@@ -79,20 +75,16 @@
|
||||
# define SQLITE_OS_KV 0
|
||||
# undef SQLITE_OS_OTHER
|
||||
# define SQLITE_OS_OTHER 0
|
||||
# if !defined(__CYGWIN__) || !defined(SQLITE_OS_WIN)
|
||||
# undef SQLITE_OS_WIN
|
||||
# define SQLITE_OS_WIN 0
|
||||
# endif
|
||||
#endif
|
||||
#if SQLITE_OS_WIN+1>1
|
||||
# undef SQLITE_OS_KV
|
||||
# define SQLITE_OS_KV 0
|
||||
# undef SQLITE_OS_OTHER
|
||||
# define SQLITE_OS_OTHER 0
|
||||
# if !defined(__CYGWIN__) || !defined(SQLITE_OS_WIN)
|
||||
# undef SQLITE_OS_UNIX
|
||||
# define SQLITE_OS_UNIX 0
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
+257
-31
@@ -420,7 +420,6 @@ static int unixGetpagesize(void);
|
||||
** testing and sandboxing. The following array holds the names and pointers
|
||||
** to all overrideable system calls.
|
||||
*/
|
||||
#define aSyscall aUnixSyscall
|
||||
static struct unix_syscall {
|
||||
const char *zName; /* Name of the system call */
|
||||
sqlite3_syscall_ptr pCurrent; /* Current value of the system call */
|
||||
@@ -597,6 +596,119 @@ static struct unix_syscall {
|
||||
}; /* End of the overrideable system calls */
|
||||
|
||||
|
||||
#if defined(SQLITE_DEBUG) || defined(SQLITE_ENABLE_FILESTAT)
|
||||
/*
|
||||
** Extract Posix Advisory Locking information about file description fd
|
||||
** from the /proc/PID/fdinfo/FD pseudo-file. Fill the string buffer a[16]
|
||||
** with characters to indicate which SQLite-relevant locks are held.
|
||||
** a[16] will be a 15-character zero-terminated string with the following
|
||||
** schema:
|
||||
**
|
||||
** AAA/B.DDD.DDDDD
|
||||
**
|
||||
** Each of character A-D will be "w" or "r" or "-" to indicate either a
|
||||
** write-lock, a read-lock, or no-lock, respectively. The "." and "/"
|
||||
** characters are delimiters intended to make the string more easily
|
||||
** readable by humans. Here are the meaning of the specific letters:
|
||||
**
|
||||
** AAA -> The main database locks. PENDING_BYTE, RESERVED_BYTE,
|
||||
** and SHARED_FIRST, respectively.
|
||||
**
|
||||
** B -> The deadman switch lock. Offset 128 of the -shm file.
|
||||
**
|
||||
** CCC -> WAL locks: WRITE, CKPT, RECOVER
|
||||
**
|
||||
** DDDDD -> WAL read-locks 0 through 5
|
||||
**
|
||||
** Note that elements before the "/" apply to the main database file and
|
||||
** elements after the "/" apply to the -shm file in WAL mode.
|
||||
**
|
||||
** Here is another way of thinking about the meaning of the result string:
|
||||
**
|
||||
** AAA/B.CCC.DDDDD
|
||||
** ||| | ||| \___/
|
||||
** PENDING--'|| | ||| `----- READ 0-5
|
||||
** RESERVED--'| | ||`---- RECOVER
|
||||
** SHARED ----' | |`----- CKPT
|
||||
** DMS ------' `------ WRITE
|
||||
**
|
||||
** Return SQLITE_OK on success and SQLITE_ERROR_UNABLE if the /proc
|
||||
** pseudo-filesystem is unavailable.
|
||||
*/
|
||||
static int unixPosixAdvisoryLocks(
|
||||
int fd, /* The file descriptor to analyze */
|
||||
char a[16] /* Write a text description of PALs here */
|
||||
){
|
||||
int in;
|
||||
ssize_t n;
|
||||
char *p, *pNext, *x;
|
||||
char z[2000];
|
||||
|
||||
/* 1 */
|
||||
/* 012 4 678 01234 */
|
||||
memcpy(a, "---/-.---.-----", 16);
|
||||
sqlite3_snprintf(sizeof(z), z, "/proc/%d/fdinfo/%d", getpid(), fd);
|
||||
in = osOpen(z, O_RDONLY, 0);
|
||||
if( in<0 ){
|
||||
return SQLITE_ERROR_UNABLE;
|
||||
}
|
||||
n = osRead(in, z, sizeof(z)-1);
|
||||
osClose(in);
|
||||
if( n<=0 ) return SQLITE_ERROR_UNABLE;
|
||||
z[n] = 0;
|
||||
|
||||
/* We are looking for lines that begin with "lock:\t". Examples:
|
||||
**
|
||||
** lock: 1: POSIX ADVISORY READ 494716 08:02:5277597 1073741826 1073742335
|
||||
** lock: 1: POSIX ADVISORY WRITE 494716 08:02:5282282 120 120
|
||||
** lock: 2: POSIX ADVISORY READ 494716 08:02:5282282 123 123
|
||||
** lock: 3: POSIX ADVISORY READ 494716 08:02:5282282 128 128
|
||||
*/
|
||||
pNext = strstr(z, "lock:\t");
|
||||
while( pNext ){
|
||||
char cType = 0;
|
||||
sqlite3_int64 iFirst, iLast;
|
||||
p = pNext+6;
|
||||
pNext = strstr(p, "lock:\t");
|
||||
if( pNext ) pNext[-1] = 0;
|
||||
if( (x = strstr(p, " READ "))!=0 ){
|
||||
cType = 'r';
|
||||
x += 6;
|
||||
}else if( (x = strstr(p, " WRITE "))!=0 ){
|
||||
cType = 'w';
|
||||
x += 7;
|
||||
}else{
|
||||
continue;
|
||||
}
|
||||
x = strrchr(x, ' ');
|
||||
if( x==0 ) continue;
|
||||
iLast = strtoll(x+1, 0, 10);
|
||||
*x = 0;
|
||||
x = strrchr(p, ' ');
|
||||
if( x==0 ) continue;
|
||||
iFirst = strtoll(x+1, 0, 10);
|
||||
if( iLast>=PENDING_BYTE ){
|
||||
if( iFirst<=PENDING_BYTE && iLast>=PENDING_BYTE ) a[0] = cType;
|
||||
if( iFirst<=PENDING_BYTE+1 && iLast>=PENDING_BYTE+1 ) a[1] = cType;
|
||||
if( iFirst<=PENDING_BYTE+2 && iLast>=PENDING_BYTE+510 ) a[2] = cType;
|
||||
}else if( iLast<=128 ){
|
||||
if( iFirst<=128 && iLast>=128 ) a[4] = cType;
|
||||
if( iFirst<=120 && iLast>=120 ) a[6] = cType;
|
||||
if( iFirst<=121 && iLast>=121 ) a[7] = cType;
|
||||
if( iFirst<=122 && iLast>=122 ) a[8] = cType;
|
||||
if( iFirst<=123 && iLast>=123 ) a[10] = cType;
|
||||
if( iFirst<=124 && iLast>=124 ) a[11] = cType;
|
||||
if( iFirst<=125 && iLast>=125 ) a[12] = cType;
|
||||
if( iFirst<=126 && iLast>=126 ) a[13] = cType;
|
||||
if( iFirst<=127 && iLast>=127 ) a[14] = cType;
|
||||
}
|
||||
}
|
||||
return SQLITE_OK;
|
||||
}
|
||||
#else
|
||||
# define unixPosixAdvisoryLocks(A,B) SQLITE_ERROR_UNABLE
|
||||
#endif /* SQLITE_DEBUG || SQLITE_ENABLE_FILESTAT */
|
||||
|
||||
/*
|
||||
** On some systems, calls to fchown() will trigger a message in a security
|
||||
** log if they come from non-root processes. So avoid calling fchown() if
|
||||
@@ -1275,7 +1387,7 @@ static int unixLogErrorAtLine(
|
||||
const char *zPath, /* File path associated with error */
|
||||
int iLine /* Source line number where error occurred */
|
||||
){
|
||||
const char *zErr; /* Message from strerror() or equivalent */
|
||||
char *zErr; /* Message from strerror() or equivalent */
|
||||
int iErrno = errno; /* Saved syscall error number */
|
||||
|
||||
/* If this is not a threadsafe build (SQLITE_THREADSAFE==0), then use
|
||||
@@ -1709,7 +1821,7 @@ static int unixFileLock(unixFile *pFile, struct flock *pLock){
|
||||
}
|
||||
}else{
|
||||
#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
|
||||
if( pFile->bBlockOnConnect && pLock->l_type==F_RDLCK
|
||||
if( pFile->bBlockOnConnect && pLock->l_type==F_RDLCK
|
||||
&& pLock->l_start==SHARED_FIRST && pLock->l_len==SHARED_SIZE
|
||||
){
|
||||
rc = osFcntl(pFile->h, F_SETLKW, pLock);
|
||||
@@ -1720,6 +1832,13 @@ static int unixFileLock(unixFile *pFile, struct flock *pLock){
|
||||
return rc;
|
||||
}
|
||||
|
||||
#if !defined(SQLITE_WASI) && !defined(SQLITE_OMIT_WAL)
|
||||
/* Forward reference */
|
||||
static int unixIsSharingShmNode(unixFile*);
|
||||
#else
|
||||
#define unixIsSharingShmNode(pFile) (0)
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Lock the file with the lock specified by parameter eFileLock - one
|
||||
** of the following:
|
||||
@@ -1908,7 +2027,9 @@ static int unixLock(sqlite3_file *id, int eFileLock){
|
||||
pInode->nLock++;
|
||||
pInode->nShared = 1;
|
||||
}
|
||||
}else if( eFileLock==EXCLUSIVE_LOCK && pInode->nShared>1 ){
|
||||
}else if( (eFileLock==EXCLUSIVE_LOCK && pInode->nShared>1)
|
||||
|| unixIsSharingShmNode(pFile)
|
||||
){
|
||||
/* We are trying for an exclusive lock but another thread in this
|
||||
** same process is still holding a shared lock. */
|
||||
rc = SQLITE_BUSY;
|
||||
@@ -3598,13 +3719,9 @@ static int unixWrite(
|
||||
** Count the number of fullsyncs and normal syncs. This is used to test
|
||||
** that syncs and fullsyncs are occurring at the right times.
|
||||
*/
|
||||
#if SQLITE_OS_WIN
|
||||
extern int sqlite3_sync_count, sqlite3_fullsync_count;
|
||||
#else
|
||||
int sqlite3_sync_count = 0;
|
||||
int sqlite3_fullsync_count = 0;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
** We do not trust systems to provide a working fdatasync(). Some do.
|
||||
@@ -4007,6 +4124,10 @@ static int unixGetTempname(int nBuf, char *zBuf);
|
||||
#if !defined(SQLITE_WASI) && !defined(SQLITE_OMIT_WAL)
|
||||
static int unixFcntlExternalReader(unixFile*, int*);
|
||||
#endif
|
||||
#if defined(SQLITE_DEBUG) || defined(SQLITE_ENABLE_FILESTAT)
|
||||
static void unixDescribeShm(sqlite3_str*,unixShm*);
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
** Information and control of an open file handle.
|
||||
@@ -4149,6 +4270,66 @@ static int unixFileControl(sqlite3_file *id, int op, void *pArg){
|
||||
return SQLITE_OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(SQLITE_DEBUG) || defined(SQLITE_ENABLE_FILESTAT)
|
||||
case SQLITE_FCNTL_FILESTAT: {
|
||||
sqlite3_str *pStr = (sqlite3_str*)pArg;
|
||||
char aLck[16];
|
||||
unixInodeInfo *pInode;
|
||||
static const char *azLock[] = { "SHARED", "RESERVED",
|
||||
"PENDING", "EXCLUSIVE" };
|
||||
sqlite3_str_appendf(pStr, "{\"h\":%d", pFile->h);
|
||||
sqlite3_str_appendf(pStr, ",\"vfs\":\"%s\"", pFile->pVfs->zName);
|
||||
if( pFile->eFileLock ){
|
||||
sqlite3_str_appendf(pStr, ",\"eFileLock\":\"%s\"",
|
||||
azLock[pFile->eFileLock-1]);
|
||||
if( unixPosixAdvisoryLocks(pFile->h, aLck)==SQLITE_OK ){
|
||||
sqlite3_str_appendf(pStr, ",\"pal\":\"%s\"", aLck);
|
||||
}
|
||||
}
|
||||
unixEnterMutex();
|
||||
if( pFile->pShm ){
|
||||
sqlite3_str_appendall(pStr, ",\"shm\":");
|
||||
unixDescribeShm(pStr, pFile->pShm);
|
||||
}
|
||||
#if SQLITE_MAX_MMAP_SIZE>0
|
||||
if( pFile->mmapSize ){
|
||||
sqlite3_str_appendf(pStr, ",\"mmapSize\":%lld", pFile->mmapSize);
|
||||
sqlite3_str_appendf(pStr, ",\"nFetchOut\":%d", pFile->nFetchOut);
|
||||
}
|
||||
#endif
|
||||
if( (pInode = pFile->pInode)!=0 ){
|
||||
sqlite3_str_appendf(pStr, ",\"inode\":{\"nRef\":%d",pInode->nRef);
|
||||
sqlite3_mutex_enter(pInode->pLockMutex);
|
||||
sqlite3_str_appendf(pStr, ",\"nShared\":%d", pInode->nShared);
|
||||
if( pInode->eFileLock ){
|
||||
sqlite3_str_appendf(pStr, ",\"eFileLock\":\"%s\"",
|
||||
azLock[pInode->eFileLock-1]);
|
||||
}
|
||||
if( pInode->pUnused ){
|
||||
char cSep = '[';
|
||||
UnixUnusedFd *pUFd = pFile->pInode->pUnused;
|
||||
sqlite3_str_appendall(pStr, ",\"unusedFd\":");
|
||||
while( pUFd ){
|
||||
sqlite3_str_appendf(pStr, "%c{\"fd\":%d,\"flags\":%d",
|
||||
cSep, pUFd->fd, pUFd->flags);
|
||||
cSep = ',';
|
||||
if( unixPosixAdvisoryLocks(pUFd->fd, aLck)==SQLITE_OK ){
|
||||
sqlite3_str_appendf(pStr, ",\"pal\":\"%s\"", aLck);
|
||||
}
|
||||
sqlite3_str_append(pStr, "}", 1);
|
||||
pUFd = pUFd->pNext;
|
||||
}
|
||||
sqlite3_str_append(pStr, "]", 1);
|
||||
}
|
||||
sqlite3_mutex_leave(pInode->pLockMutex);
|
||||
sqlite3_str_append(pStr, "}", 1);
|
||||
}
|
||||
unixLeaveMutex();
|
||||
sqlite3_str_append(pStr, "}", 1);
|
||||
return SQLITE_OK;
|
||||
}
|
||||
#endif /* SQLITE_DEBUG || SQLITE_ENABLE_FILESTAT */
|
||||
}
|
||||
return SQLITE_NOTFOUND;
|
||||
}
|
||||
@@ -4415,6 +4596,26 @@ struct unixShm {
|
||||
#define UNIX_SHM_BASE ((22+SQLITE_SHM_NLOCK)*4) /* first lock byte */
|
||||
#define UNIX_SHM_DMS (UNIX_SHM_BASE+SQLITE_SHM_NLOCK) /* deadman switch */
|
||||
|
||||
#if defined(SQLITE_DEBUG) || defined(SQLITE_ENABLE_FILESTAT)
|
||||
/*
|
||||
** Describe the pShm object using JSON. Used for diagnostics only.
|
||||
*/
|
||||
static void unixDescribeShm(sqlite3_str *pStr, unixShm *pShm){
|
||||
unixShmNode *pNode = pShm->pShmNode;
|
||||
char aLck[16];
|
||||
sqlite3_str_appendf(pStr, "{\"h\":%d", pNode->hShm);
|
||||
assert( unixMutexHeld() );
|
||||
sqlite3_str_appendf(pStr, ",\"nRef\":%d", pNode->nRef);
|
||||
sqlite3_str_appendf(pStr, ",\"id\":%d", pShm->id);
|
||||
sqlite3_str_appendf(pStr, ",\"sharedMask\":%d", pShm->sharedMask);
|
||||
sqlite3_str_appendf(pStr, ",\"exclMask\":%d", pShm->exclMask);
|
||||
if( unixPosixAdvisoryLocks(pNode->hShm, aLck)==SQLITE_OK ){
|
||||
sqlite3_str_appendf(pStr, ",\"pal\":\"%s\"", aLck);
|
||||
}
|
||||
sqlite3_str_append(pStr, "}", 1);
|
||||
}
|
||||
#endif /* SQLITE_DEBUG || SQLITE_ENABLE_FILESTAT */
|
||||
|
||||
/*
|
||||
** Use F_GETLK to check whether or not there are any readers with open
|
||||
** wal-mode transactions in other processes on database file pFile. If
|
||||
@@ -4448,6 +4649,49 @@ static int unixFcntlExternalReader(unixFile *pFile, int *piOut){
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
** If pFile has a -shm file open and it is sharing that file with some
|
||||
** other connection, either in the same process or in a separate process,
|
||||
** then return true. Return false if either pFile does not have a -shm
|
||||
** file open or if it is the only connection to that -shm file across the
|
||||
** entire system.
|
||||
**
|
||||
** This routine is not required for correct operation. It can always return
|
||||
** false and SQLite will continue to operate according to spec. However,
|
||||
** when this routine does its job, it adds extra robustness in cases
|
||||
** where database file locks have been erroneously deleted in a WAL-mode
|
||||
** database by doing close(open(DATABASE_PATHNAME)) or similar.
|
||||
**
|
||||
** With false negatives, SQLite still operates to spec, though with less
|
||||
** robustness. With false positives, the last database connection on a
|
||||
** WAL-mode database will fail to unlink the -wal and -shm files, which
|
||||
** is annoying but harmless. False positives will also prevent a database
|
||||
** connection from running "PRAGMA journal_mode=DELETE" in order to take
|
||||
** the database out of WAL mode, which is perhaps more serious, but is
|
||||
** still not a disaster.
|
||||
*/
|
||||
static int unixIsSharingShmNode(unixFile *pFile){
|
||||
int rc;
|
||||
unixShmNode *pShmNode;
|
||||
if( pFile->pShm==0 ) return 0;
|
||||
if( pFile->ctrlFlags & UNIXFILE_EXCL ) return 0;
|
||||
pShmNode = pFile->pShm->pShmNode;
|
||||
rc = 1;
|
||||
unixEnterMutex();
|
||||
if( ALWAYS(pShmNode->nRef==1) ){
|
||||
struct flock lock;
|
||||
lock.l_whence = SEEK_SET;
|
||||
lock.l_start = UNIX_SHM_DMS;
|
||||
lock.l_len = 1;
|
||||
lock.l_type = F_WRLCK;
|
||||
osFcntl(pShmNode->hShm, F_GETLK, &lock);
|
||||
if( lock.l_type==F_UNLCK ){
|
||||
rc = 0;
|
||||
}
|
||||
}
|
||||
unixLeaveMutex();
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
** Apply posix advisory locks for all bytes from ofst through ofst+n-1.
|
||||
@@ -4493,7 +4737,8 @@ static int unixShmSystemLock(
|
||||
|
||||
/* Locks are within range */
|
||||
assert( n>=1 && n<=SQLITE_SHM_NLOCK );
|
||||
assert( ofst>=UNIX_SHM_BASE && ofst<=(UNIX_SHM_DMS+SQLITE_SHM_NLOCK) );
|
||||
assert( ofst>=UNIX_SHM_BASE && ofst<=UNIX_SHM_DMS );
|
||||
assert( ofst+n-1<=UNIX_SHM_DMS );
|
||||
|
||||
if( pShmNode->hShm>=0 ){
|
||||
int res;
|
||||
@@ -4536,7 +4781,7 @@ static int unixShmSystemLock(
|
||||
}
|
||||
#endif
|
||||
|
||||
return rc;
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -5025,7 +5270,7 @@ static int assertLockingArrayOk(unixShmNode *pShmNode){
|
||||
return (memcmp(pShmNode->aLock, aLock, sizeof(aLock))==0);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
#endif /* !defined(SQLITE_WASI) && !defined(SQLITE_OMIT_WAL) */
|
||||
|
||||
/*
|
||||
** Change the lock state for a shared-memory segment.
|
||||
@@ -6083,7 +6328,7 @@ static int unixGetTempname(int nBuf, char *zBuf){
|
||||
sqlite3_randomness(sizeof(r), &r);
|
||||
assert( nBuf>2 );
|
||||
zBuf[nBuf-2] = 0;
|
||||
sqlite3_snprintf(nBuf, zBuf, "%s/" SQLITE_TEMP_FILE_PREFIX "%llx%c",
|
||||
sqlite3_snprintf(nBuf, zBuf, "%s/"SQLITE_TEMP_FILE_PREFIX"%llx%c",
|
||||
zDir, r, 0);
|
||||
if( zBuf[nBuf-2]!=0 || (iLimit++)>10 ){
|
||||
rc = SQLITE_ERROR;
|
||||
@@ -6931,11 +7176,7 @@ static int unixSleep(sqlite3_vfs *NotUsed, int microseconds){
|
||||
** sqlite3OsCurrentTime() during testing.
|
||||
*/
|
||||
#ifdef SQLITE_TEST
|
||||
# if SQLITE_OS_WIN
|
||||
extern int sqlite3_current_time; /* Fake system time in seconds since 1970. */
|
||||
# else
|
||||
int sqlite3_current_time = 0; /* Fake system time in seconds since 1970. */
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
@@ -8203,14 +8444,7 @@ static int proxyClose(sqlite3_file *id) {
|
||||
** necessarily been initialized when this routine is called, and so they
|
||||
** should not be used.
|
||||
*/
|
||||
#if SQLITE_OS_WIN
|
||||
#if defined(SQLITE_AMALGAMATION)
|
||||
static
|
||||
#endif
|
||||
int sqlite3_os_unix_init(void){
|
||||
#else
|
||||
int sqlite3_os_init(void){
|
||||
#endif
|
||||
/*
|
||||
** The following macro defines an initializer for an sqlite3_vfs object.
|
||||
** The name of the VFS is NAME. The pAppData is a pointer to a pointer
|
||||
@@ -8336,7 +8570,6 @@ int sqlite3_os_init(void){
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
#undef aSyscall
|
||||
/*
|
||||
** Shutdown the operating system interface.
|
||||
**
|
||||
@@ -8344,14 +8577,7 @@ int sqlite3_os_init(void){
|
||||
** to release dynamically allocated objects. But not on unix.
|
||||
** This routine is a no-op for unix.
|
||||
*/
|
||||
#if SQLITE_OS_WIN
|
||||
#if defined(SQLITE_AMALGAMATION)
|
||||
static
|
||||
#endif
|
||||
int sqlite3_os_unix_end(void){
|
||||
#else
|
||||
int sqlite3_os_end(void){
|
||||
#endif
|
||||
unixBigLock = 0;
|
||||
#if OS_VXWORKS
|
||||
vxworksMutex = 0;
|
||||
|
||||
+40
-28
@@ -489,9 +489,9 @@ const sqlite3_mem_methods *sqlite3MemGetWin32(void);
|
||||
** can manually set this value to 1 to emulate Win98 behavior.
|
||||
*/
|
||||
#ifdef SQLITE_TEST
|
||||
int SQLITE_WIN32_VOLATILE sqlite3_os_type = 0;
|
||||
LONG SQLITE_WIN32_VOLATILE sqlite3_os_type = 0;
|
||||
#else
|
||||
static int SQLITE_WIN32_VOLATILE sqlite3_os_type = 0;
|
||||
static LONG SQLITE_WIN32_VOLATILE sqlite3_os_type = 0;
|
||||
#endif
|
||||
|
||||
#ifndef SYSCALL
|
||||
@@ -1229,7 +1229,7 @@ static struct win_syscall {
|
||||
{ "getcwd", (SYSCALL)0, 0 },
|
||||
#endif
|
||||
|
||||
#define cygGetcwd ((char*(*)(char*,size_t))aSyscall[84].pCurrent)
|
||||
#define osGetcwd ((char*(*)(char*,size_t))aSyscall[84].pCurrent)
|
||||
|
||||
#ifndef _WIN32
|
||||
{ "readlink", (SYSCALL)readlink, 0 },
|
||||
@@ -1237,7 +1237,7 @@ static struct win_syscall {
|
||||
{ "readlink", (SYSCALL)0, 0 },
|
||||
#endif
|
||||
|
||||
#define cygReadlink ((ssize_t(*)(const char*,char*,size_t))aSyscall[85].pCurrent)
|
||||
#define osReadlink ((ssize_t(*)(const char*,char*,size_t))aSyscall[85].pCurrent)
|
||||
|
||||
#ifndef _WIN32
|
||||
{ "lstat", (SYSCALL)lstat, 0 },
|
||||
@@ -1245,7 +1245,7 @@ static struct win_syscall {
|
||||
{ "lstat", (SYSCALL)0, 0 },
|
||||
#endif
|
||||
|
||||
#define cygLstat ((int(*)(const char*,struct stat*))aSyscall[86].pCurrent)
|
||||
#define osLstat ((int(*)(const char*,struct stat*))aSyscall[86].pCurrent)
|
||||
|
||||
#ifndef _WIN32
|
||||
{ "__errno", (SYSCALL)__errno, 0 },
|
||||
@@ -1490,9 +1490,6 @@ void sqlite3_win32_write_debug(const char *zBuf, int nBuf){
|
||||
static HANDLE sleepObj = NULL;
|
||||
#endif
|
||||
|
||||
#if defined(__CYGWIN__) && defined(SQLITE_AMALGAMATION)
|
||||
static
|
||||
#endif
|
||||
void sqlite3_win32_sleep(DWORD milliseconds){
|
||||
#if SQLITE_OS_WINRT
|
||||
if ( sleepObj==NULL ){
|
||||
@@ -2666,6 +2663,7 @@ static BOOL winLockFile(
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef SQLITE_OMIT_WAL
|
||||
/*
|
||||
** Lock a region of nByte bytes starting at offset offset of file hFile.
|
||||
** Take an EXCLUSIVE lock if parameter bExclusive is true, or a SHARED lock
|
||||
@@ -2748,6 +2746,7 @@ static int winHandleLockTimeout(
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
#endif /* #ifndef SQLITE_OMIT_WAL */
|
||||
|
||||
/*
|
||||
** Unlock a file region.
|
||||
@@ -2782,6 +2781,7 @@ static BOOL winUnlockFile(
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef SQLITE_OMIT_WAL
|
||||
/*
|
||||
** Remove an nByte lock starting at offset iOff from HANDLE h.
|
||||
*/
|
||||
@@ -2789,6 +2789,7 @@ static int winHandleUnlock(HANDLE h, int iOff, int nByte){
|
||||
BOOL ret = winUnlockFile(&h, iOff, 0, nByte, 0);
|
||||
return (ret ? SQLITE_OK : SQLITE_IOERR_UNLOCK);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*****************************************************************************
|
||||
** The next group of routines implement the I/O methods specified
|
||||
@@ -2806,7 +2807,7 @@ static int winHandleUnlock(HANDLE h, int iOff, int nByte){
|
||||
** Seek the file handle h to offset nByte of the file.
|
||||
**
|
||||
** If successful, return SQLITE_OK. Or, if an error occurs, return an SQLite
|
||||
** error code.
|
||||
** error code.
|
||||
*/
|
||||
static int winHandleSeek(HANDLE h, sqlite3_int64 iOffset){
|
||||
int rc = SQLITE_OK; /* Return value */
|
||||
@@ -3126,6 +3127,7 @@ static int winWrite(
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
#ifndef SQLITE_OMIT_WAL
|
||||
/*
|
||||
** Truncate the file opened by handle h to nByte bytes in size.
|
||||
*/
|
||||
@@ -3179,6 +3181,7 @@ static void winHandleClose(HANDLE h){
|
||||
osCloseHandle(h);
|
||||
}
|
||||
}
|
||||
#endif /* #ifndef SQLITE_OMIT_WAL */
|
||||
|
||||
/*
|
||||
** Truncate an open file to a specified size
|
||||
@@ -3956,6 +3959,28 @@ static int winFileControl(sqlite3_file *id, int op, void *pArg){
|
||||
}
|
||||
#endif /* SQLITE_ENABLE_SETLK_TIMEOUT */
|
||||
|
||||
#if defined(SQLITE_DEBUG) || defined(SQLITE_ENABLE_FILESTAT)
|
||||
case SQLITE_FCNTL_FILESTAT: {
|
||||
sqlite3_str *pStr = (sqlite3_str*)pArg;
|
||||
sqlite3_str_appendf(pStr, "{\"h\":%llu", (sqlite3_uint64)pFile->h);
|
||||
sqlite3_str_appendf(pStr, ",\"vfs\":\"%s\"", pFile->pVfs->zName);
|
||||
if( pFile->locktype ){
|
||||
static const char *azLock[] = { "SHARED", "RESERVED",
|
||||
"PENDING", "EXCLUSIVE" };
|
||||
sqlite3_str_appendf(pStr, ",\"locktype\":\"%s\"",
|
||||
azLock[pFile->locktype-1]);
|
||||
}
|
||||
#if SQLITE_MAX_MMAP_SIZE>0
|
||||
if( pFile->mmapSize ){
|
||||
sqlite3_str_appendf(pStr, ",\"mmapSize\":%lld", pFile->mmapSize);
|
||||
sqlite3_str_appendf(pStr, ",\"nFetchOut\":%d", pFile->nFetchOut);
|
||||
}
|
||||
#endif
|
||||
sqlite3_str_append(pStr, "}", 1);
|
||||
return SQLITE_OK;
|
||||
}
|
||||
#endif /* SQLITE_DEBUG || SQLITE_ENABLE_FILESTAT */
|
||||
|
||||
}
|
||||
OSTRACE(("FCNTL file=%p, rc=SQLITE_NOTFOUND\n", pFile->h));
|
||||
return SQLITE_NOTFOUND;
|
||||
@@ -6116,7 +6141,7 @@ static int mkFullPathname(
|
||||
int nPath = sqlite3Strlen30(zPath);
|
||||
int iOff = 0;
|
||||
if( zPath[0]!='/' ){
|
||||
if( cygGetcwd(zOut, nOut-2)==0 ){
|
||||
if( osGetcwd(zOut, nOut-2)==0 ){
|
||||
return winLogError(SQLITE_CANTOPEN_BKPT, (DWORD)osErrno, "getcwd", zPath);
|
||||
}
|
||||
iOff = sqlite3Strlen30(zOut);
|
||||
@@ -6161,7 +6186,7 @@ static int winFullPathnameNoMutex(
|
||||
SimulateIOError( return SQLITE_ERROR );
|
||||
|
||||
#ifdef __CYGWIN__
|
||||
if( cygGetcwd ){
|
||||
if( osGetcwd ){
|
||||
zFull[nFull-1] = '\0';
|
||||
if( !winIsDriveLetterAndColon(zRelative) || !winIsDirSep(zRelative[2]) ){
|
||||
int rc = SQLITE_OK;
|
||||
@@ -6176,8 +6201,8 @@ static int winFullPathnameNoMutex(
|
||||
/* Call lstat() on path zIn. Set bLink to true if the path is a symbolic
|
||||
** link, or false otherwise. */
|
||||
int bLink = 0;
|
||||
if( cygLstat && cygReadlink ) {
|
||||
if( cygLstat(zIn, &buf)!=0 ){
|
||||
if( osLstat && osReadlink ) {
|
||||
if( osLstat(zIn, &buf)!=0 ){
|
||||
int myErrno = osErrno;
|
||||
if( myErrno!=ENOENT ){
|
||||
rc = winLogError(SQLITE_CANTOPEN_BKPT, (DWORD)myErrno, "lstat", zIn);
|
||||
@@ -6195,7 +6220,7 @@ static int winFullPathnameNoMutex(
|
||||
}
|
||||
|
||||
if( rc==SQLITE_OK ){
|
||||
nByte = cygReadlink(zIn, zDel, nFull-1);
|
||||
nByte = osReadlink(zIn, zDel, nFull-1);
|
||||
if( nByte ==(DWORD)-1 ){
|
||||
rc = winLogError(SQLITE_CANTOPEN_BKPT, (DWORD)osErrno, "readlink", zIn);
|
||||
}else{
|
||||
@@ -6336,7 +6361,7 @@ static int winFullPathnameNoMutex(
|
||||
}else{
|
||||
char *p = zOut+6;
|
||||
*p = '\\';
|
||||
if( cygGetcwd ){
|
||||
if( osGetcwd ){
|
||||
/* On Cygwin, UNC paths use forward slashes */
|
||||
while( *p ){
|
||||
if( *p=='\\' ) *p = '/';
|
||||
@@ -6620,11 +6645,6 @@ static int winGetLastError(sqlite3_vfs *pVfs, int nBuf, char *zBuf){
|
||||
return e;
|
||||
}
|
||||
|
||||
#if SQLITE_OS_UNIX && !defined(SQLITE_AMALGAMATION)
|
||||
int sqlite3_os_unix_init(void);
|
||||
int sqlite3_os_unix_end(void);
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Initialize and deinitialize the operating system interface.
|
||||
*/
|
||||
@@ -6744,10 +6764,6 @@ int sqlite3_os_init(void){
|
||||
assert( winSysInfo.dwAllocationGranularity>0 );
|
||||
assert( winSysInfo.dwPageSize>0 );
|
||||
|
||||
#if SQLITE_OS_UNIX
|
||||
sqlite3_os_unix_init();
|
||||
#endif
|
||||
|
||||
sqlite3_vfs_register(&winVfs, 1);
|
||||
|
||||
#if defined(SQLITE_WIN32_HAS_WIDE)
|
||||
@@ -6779,10 +6795,6 @@ int sqlite3_os_end(void){
|
||||
winBigLock = 0;
|
||||
#endif
|
||||
|
||||
#if SQLITE_OS_UNIX
|
||||
sqlite3_os_unix_end();
|
||||
#endif
|
||||
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
|
||||
+5
-1
@@ -813,6 +813,8 @@ int sqlite3PagerDirectReadOk(Pager *pPager, Pgno pgno){
|
||||
(void)sqlite3WalFindFrame(pPager->pWal, pgno, &iRead);
|
||||
if( iRead ) return 0; /* Case (4) */
|
||||
}
|
||||
#else
|
||||
UNUSED_PARAMETER(pgno);
|
||||
#endif
|
||||
assert( pPager->fd->pMethods->xDeviceCharacteristics!=0 );
|
||||
if( (pPager->fd->pMethods->xDeviceCharacteristics(pPager->fd)
|
||||
@@ -1856,7 +1858,7 @@ static void pager_unlock(Pager *pPager){
|
||||
** have sqlite3WalEndReadTransaction() drop the write-lock, as it once
|
||||
** did, because this would break "BEGIN EXCLUSIVE" handling for
|
||||
** SQLITE_ENABLE_SETLK_TIMEOUT builds. */
|
||||
sqlite3WalEndWriteTransaction(pPager->pWal);
|
||||
(void)sqlite3WalEndWriteTransaction(pPager->pWal);
|
||||
}
|
||||
sqlite3WalEndReadTransaction(pPager->pWal);
|
||||
pPager->eState = PAGER_OPEN;
|
||||
@@ -4192,6 +4194,8 @@ int sqlite3PagerClose(Pager *pPager, sqlite3 *db){
|
||||
sqlite3WalClose(pPager->pWal, db, pPager->walSyncFlags, pPager->pageSize,a);
|
||||
pPager->pWal = 0;
|
||||
}
|
||||
#else
|
||||
UNUSED_PARAMETER(db);
|
||||
#endif
|
||||
pager_reset(pPager);
|
||||
if( MEMDB ){
|
||||
|
||||
+1
-1
@@ -1041,7 +1041,7 @@ void sqlite3Pragma(
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
#if SQLITE_OS_WIN
|
||||
/*
|
||||
** PRAGMA data_store_directory
|
||||
** PRAGMA data_store_directory = ""|"directory_name"
|
||||
|
||||
+5
-2
@@ -373,10 +373,13 @@ static int lookupName(
|
||||
if( cnt>0 ){
|
||||
if( pItem->fg.isUsing==0
|
||||
|| sqlite3IdListIndex(pItem->u3.pUsing, zCol)<0
|
||||
|| pMatch==pItem
|
||||
){
|
||||
/* Two or more tables have the same column name which is
|
||||
** not joined by USING. This is an error. Signal as much
|
||||
** by clearing pFJMatch and letting cnt go above 1. */
|
||||
** not joined by USING. Or, a single table has two columns
|
||||
** that match a USING term (if pMatch==pItem). These are both
|
||||
** "ambiguous column name" errors. Signal as much by clearing
|
||||
** pFJMatch and letting cnt go above 1. */
|
||||
sqlite3ExprListDelete(db, pFJMatch);
|
||||
pFJMatch = 0;
|
||||
}else
|
||||
|
||||
@@ -6823,6 +6823,7 @@ static void resetAccumulator(Parse *pParse, AggInfo *pAggInfo){
|
||||
if( pFunc->bOBPayload ){
|
||||
/* extra columns for the function arguments */
|
||||
assert( ExprUseXList(pFunc->pFExpr) );
|
||||
assert( pFunc->pFExpr->x.pList!=0 );
|
||||
nExtra += pFunc->pFExpr->x.pList->nExpr;
|
||||
}
|
||||
if( pFunc->bUseSubtype ){
|
||||
|
||||
+148
-70
@@ -1516,7 +1516,7 @@ struct ShellState {
|
||||
int inputNesting; /* Track nesting level of .read and other redirects */
|
||||
int outCount; /* Revert to stdout when reaching zero */
|
||||
int cnt; /* Number of records displayed so far */
|
||||
int lineno; /* Line number of last line read from in */
|
||||
i64 lineno; /* Line number of last line read from in */
|
||||
int openFlags; /* Additional flags to open. (SQLITE_OPEN_NOFOLLOW) */
|
||||
FILE *in; /* Read commands from this stream */
|
||||
FILE *out; /* Write results here */
|
||||
@@ -1752,7 +1752,7 @@ static void failIfSafeMode(
|
||||
va_start(ap, zErrMsg);
|
||||
zMsg = sqlite3_vmprintf(zErrMsg, ap);
|
||||
va_end(ap);
|
||||
sqlite3_fprintf(stderr, "line %d: %s\n", p->lineno, zMsg);
|
||||
sqlite3_fprintf(stderr, "line %lld: %s\n", p->lineno, zMsg);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
@@ -3418,8 +3418,8 @@ static int display_stats(
|
||||
ShellState *pArg, /* Pointer to ShellState */
|
||||
int bReset /* True to reset the stats */
|
||||
){
|
||||
int iCur;
|
||||
int iHiwtr;
|
||||
int iCur, iHiwtr;
|
||||
sqlite3_int64 iCur64, iHiwtr64;
|
||||
FILE *out;
|
||||
if( pArg==0 || pArg->out==0 ) return 0;
|
||||
out = pArg->out;
|
||||
@@ -3508,6 +3508,9 @@ static int display_stats(
|
||||
sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_MISS, &iCur, &iHiwtr, 1);
|
||||
sqlite3_fprintf(out,
|
||||
"Page cache misses: %d\n", iCur);
|
||||
iHiwtr64 = iCur64 = -1;
|
||||
sqlite3_db_status64(db, SQLITE_DBSTATUS_TEMPBUF_SPILL, &iCur64, &iHiwtr64,
|
||||
0);
|
||||
iHiwtr = iCur = -1;
|
||||
sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_WRITE, &iCur, &iHiwtr, 1);
|
||||
sqlite3_fprintf(out,
|
||||
@@ -3516,6 +3519,10 @@ static int display_stats(
|
||||
sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_SPILL, &iCur, &iHiwtr, 1);
|
||||
sqlite3_fprintf(out,
|
||||
"Page cache spills: %d\n", iCur);
|
||||
sqlite3_fprintf(out,
|
||||
"Temporary data spilled to disk: %lld\n", iCur64);
|
||||
sqlite3_db_status64(db, SQLITE_DBSTATUS_TEMPBUF_SPILL, &iCur64, &iHiwtr64,
|
||||
1);
|
||||
iHiwtr = iCur = -1;
|
||||
sqlite3_db_status(db, SQLITE_DBSTATUS_SCHEMA_USED, &iCur, &iHiwtr, bReset);
|
||||
sqlite3_fprintf(out,
|
||||
@@ -4956,6 +4963,9 @@ static void toggleSelectOrder(sqlite3 *db){
|
||||
sqlite3_exec(db, zStmt, 0, 0, 0);
|
||||
}
|
||||
|
||||
/* Forward reference */
|
||||
static int db_int(sqlite3 *db, const char *zSql, ...);
|
||||
|
||||
/*
|
||||
** This is a different callback routine used for dumping the database.
|
||||
** Each row received by this callback consists of a table name,
|
||||
@@ -4982,7 +4992,21 @@ static int dump_callback(void *pArg, int nArg, char **azArg, char **azNotUsed){
|
||||
noSys = (p->shellFlgs & SHFLG_DumpNoSys)!=0;
|
||||
|
||||
if( cli_strcmp(zTable, "sqlite_sequence")==0 && !noSys ){
|
||||
/* no-op */
|
||||
/* The sqlite_sequence table is repopulated last. Delete content
|
||||
** in the sqlite_sequence table added by prior repopulations prior to
|
||||
** repopulating sqlite_sequence itself. But only do this if the
|
||||
** table is non-empty, because if it is empty the table might not
|
||||
** have been recreated by prior repopulations. See forum posts:
|
||||
** 2024-10-13T17:10:01z and 2025-10-29T19:38:43z
|
||||
*/
|
||||
if( db_int(p->db, "SELECT count(*) FROM sqlite_sequence")>0 ){
|
||||
if( !p->writableSchema ){
|
||||
sqlite3_fputs("PRAGMA writable_schema=ON;\n", p->out);
|
||||
p->writableSchema = 1;
|
||||
}
|
||||
sqlite3_fputs("CREATE TABLE IF NOT EXISTS sqlite_sequence(name,seq);\n"
|
||||
"DELETE FROM sqlite_sequence;\n", p->out);
|
||||
}
|
||||
}else if( sqlite3_strglob("sqlite_stat?", zTable)==0 && !noSys ){
|
||||
if( !dataOnly ) sqlite3_fputs("ANALYZE sqlite_schema;\n", p->out);
|
||||
}else if( cli_strncmp(zTable, "sqlite_", 7)==0 ){
|
||||
@@ -5224,7 +5248,7 @@ static const char *(azHelp[]) = {
|
||||
" input text.",
|
||||
#endif
|
||||
#ifndef SQLITE_OMIT_TEST_CONTROL
|
||||
",imposter INDEX TABLE Create imposter table TABLE on index INDEX",
|
||||
".imposter INDEX TABLE Create imposter table TABLE on index INDEX",
|
||||
#endif
|
||||
".indexes ?TABLE? Show names of indexes",
|
||||
" If TABLE is specified, only show indexes for",
|
||||
@@ -5301,6 +5325,7 @@ static const char *(azHelp[]) = {
|
||||
" --maxsize N Maximum size for --hexdb or --deserialized database",
|
||||
#endif
|
||||
" --new Initialize FILE to an empty database",
|
||||
" --normal FILE is an ordinary SQLite database",
|
||||
" --nofollow Do not follow symbolic links",
|
||||
" --readonly Open FILE readonly",
|
||||
" --zip FILE is a ZIP archive",
|
||||
@@ -5535,7 +5560,7 @@ static int showHelp(FILE *out, const char *zPattern){
|
||||
}
|
||||
|
||||
/* Forward reference */
|
||||
static int process_input(ShellState *p);
|
||||
static int process_input(ShellState *p, const char*);
|
||||
|
||||
/*
|
||||
** Read the content of file zName into memory obtained from sqlite3_malloc64()
|
||||
@@ -5642,18 +5667,26 @@ static int session_filter(void *pCtx, const char *zTab){
|
||||
** Otherwise, assume an ordinary database regardless of the filename if
|
||||
** the type cannot be determined from content.
|
||||
*/
|
||||
int deduceDatabaseType(const char *zName, int dfltZip){
|
||||
FILE *f = sqlite3_fopen(zName, "rb");
|
||||
int deduceDatabaseType(const char *zName, int dfltZip, int openFlags){
|
||||
FILE *f;
|
||||
size_t n;
|
||||
sqlite3 *db = 0;
|
||||
sqlite3_stmt *pStmt = 0;
|
||||
int rc = SHELL_OPEN_UNSPEC;
|
||||
char zBuf[100];
|
||||
if( f==0 ){
|
||||
if( dfltZip && sqlite3_strlike("%.zip",zName,0)==0 ){
|
||||
return SHELL_OPEN_ZIPFILE;
|
||||
}else{
|
||||
return SHELL_OPEN_NORMAL;
|
||||
}
|
||||
if( access(zName,0)!=0 ) goto database_type_by_name;
|
||||
if( sqlite3_open_v2(zName, &db, openFlags, 0)==SQLITE_OK
|
||||
&& sqlite3_prepare_v2(db,"SELECT count(*) FROM sqlite_schema",-1,&pStmt,0)
|
||||
==SQLITE_OK
|
||||
&& sqlite3_step(pStmt)==SQLITE_ROW
|
||||
){
|
||||
rc = SHELL_OPEN_NORMAL;
|
||||
}
|
||||
sqlite3_finalize(pStmt);
|
||||
sqlite3_close(db);
|
||||
if( rc==SHELL_OPEN_NORMAL ) return SHELL_OPEN_NORMAL;
|
||||
f = sqlite3_fopen(zName, "rb");
|
||||
if( f==0 ) goto database_type_by_name;
|
||||
n = fread(zBuf, 16, 1, f);
|
||||
if( n==1 && memcmp(zBuf, "SQLite format 3", 16)==0 ){
|
||||
fclose(f);
|
||||
@@ -5675,6 +5708,14 @@ int deduceDatabaseType(const char *zName, int dfltZip){
|
||||
}
|
||||
fclose(f);
|
||||
return rc;
|
||||
|
||||
database_type_by_name:
|
||||
if( dfltZip && sqlite3_strlike("%.zip",zName,0)==0 ){
|
||||
rc = SHELL_OPEN_ZIPFILE;
|
||||
}else{
|
||||
rc = SHELL_OPEN_NORMAL;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
#ifndef SQLITE_OMIT_DESERIALIZE
|
||||
@@ -5685,7 +5726,7 @@ int deduceDatabaseType(const char *zName, int dfltZip){
|
||||
*/
|
||||
static unsigned char *readHexDb(ShellState *p, int *pnData){
|
||||
unsigned char *a = 0;
|
||||
int nLine;
|
||||
i64 nLine;
|
||||
int n = 0; /* Size of db per first line of hex dump */
|
||||
i64 sz = 0; /* n rounded up to nearest page boundary */
|
||||
int pgsz = 0;
|
||||
@@ -5724,6 +5765,10 @@ static unsigned char *readHexDb(ShellState *p, int *pnData){
|
||||
for(nLine++; sqlite3_fgets(zLine, sizeof(zLine), in)!=0; nLine++){
|
||||
int j = 0; /* Page number from "| page" line */
|
||||
int k = 0; /* Offset from "| page" line */
|
||||
if( nLine>=2000000000 ){
|
||||
sqlite3_fprintf(stderr, "input too big\n");
|
||||
goto readHexDb_error;
|
||||
}
|
||||
rc = sscanf(zLine, "| page %d offset %d", &j, &k);
|
||||
if( rc==2 ){
|
||||
iOffset = k;
|
||||
@@ -5762,7 +5807,7 @@ readHexDb_error:
|
||||
p->lineno = nLine;
|
||||
}
|
||||
sqlite3_free(a);
|
||||
sqlite3_fprintf(stderr,"Error on line %d of --hexdb input\n", nLine);
|
||||
sqlite3_fprintf(stderr,"Error on line %lld of --hexdb input\n", nLine);
|
||||
return 0;
|
||||
}
|
||||
#endif /* SQLITE_OMIT_DESERIALIZE */
|
||||
@@ -5839,7 +5884,7 @@ static void open_db(ShellState *p, int openFlags){
|
||||
p->openMode = SHELL_OPEN_NORMAL;
|
||||
}else{
|
||||
p->openMode = (u8)deduceDatabaseType(zDbFilename,
|
||||
(openFlags & OPEN_DB_ZIPFILE)!=0);
|
||||
(openFlags & OPEN_DB_ZIPFILE)!=0, p->openFlags);
|
||||
}
|
||||
}
|
||||
if( (p->openFlags & (SQLITE_OPEN_READONLY|SQLITE_OPEN_READWRITE))==0 ){
|
||||
@@ -7180,39 +7225,42 @@ static void clearTempFile(ShellState *p){
|
||||
p->zTempFile = 0;
|
||||
}
|
||||
|
||||
/* Forward reference */
|
||||
static char *find_home_dir(int clearFlag);
|
||||
|
||||
/*
|
||||
** Create a new temp file name with the given suffix.
|
||||
**
|
||||
** Because the classic temp folders like /tmp are no longer
|
||||
** accessible to web browsers, for security reasons, create the
|
||||
** temp file in the user's home directory.
|
||||
*/
|
||||
static void newTempFile(ShellState *p, const char *zSuffix){
|
||||
char *zHome; /* Home directory */
|
||||
int i; /* Loop counter */
|
||||
sqlite3_uint64 r = 0; /* Integer with 64 bits of randomness */
|
||||
char zRand[32]; /* Text string with 160 bits of randomness */
|
||||
#ifdef _WIN32
|
||||
const char cDirSep = '\\';
|
||||
#else
|
||||
const char cDirSep = '/';
|
||||
#endif
|
||||
|
||||
for(i=0; i<31; i++){
|
||||
if( (i%12)==0 ) sqlite3_randomness(sizeof(r),&r);
|
||||
zRand[i] = "0123456789abcdefghijklmnopqrstuvwxyz"[r%36];
|
||||
r /= 36;
|
||||
}
|
||||
zRand[i] = 0;
|
||||
clearTempFile(p);
|
||||
sqlite3_free(p->zTempFile);
|
||||
p->zTempFile = 0;
|
||||
if( p->db ){
|
||||
sqlite3_file_control(p->db, 0, SQLITE_FCNTL_TEMPFILENAME, &p->zTempFile);
|
||||
}
|
||||
if( p->zTempFile==0 ){
|
||||
/* If p->db is an in-memory database then the TEMPFILENAME file-control
|
||||
** will not work and we will need to fallback to guessing */
|
||||
char *zTemp;
|
||||
sqlite3_uint64 r;
|
||||
sqlite3_randomness(sizeof(r), &r);
|
||||
zTemp = getenv("TEMP");
|
||||
if( zTemp==0 ) zTemp = getenv("TMP");
|
||||
if( zTemp==0 ){
|
||||
#ifdef _WIN32
|
||||
zTemp = "\\tmp";
|
||||
#else
|
||||
zTemp = "/tmp";
|
||||
#endif
|
||||
}
|
||||
p->zTempFile = sqlite3_mprintf("%s/temp%llx.%s", zTemp, r, zSuffix);
|
||||
}else{
|
||||
p->zTempFile = sqlite3_mprintf("%z.%s", p->zTempFile, zSuffix);
|
||||
}
|
||||
zHome = find_home_dir(0);
|
||||
p->zTempFile = sqlite3_mprintf("%s%ctemp-%s.%s",
|
||||
zHome,cDirSep,zRand,zSuffix);
|
||||
shell_check_oom(p->zTempFile);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** The implementation of SQL scalar function fkey_collate_clause(), used
|
||||
** by the ".lint fkey-indexes" command. This scalar function is always
|
||||
@@ -7866,25 +7914,41 @@ static void arWhereClause(
|
||||
char **pzWhere /* OUT: New WHERE clause */
|
||||
){
|
||||
char *zWhere = 0;
|
||||
const char *zSameOp = (pAr->bGlob)? "GLOB" : "=";
|
||||
if( *pRc==SQLITE_OK ){
|
||||
if( pAr->nArg==0 ){
|
||||
zWhere = sqlite3_mprintf("1");
|
||||
}else{
|
||||
char *z1 = sqlite3_mprintf(pAr->bGlob ? "" : "name IN(");
|
||||
char *z2 = sqlite3_mprintf("");
|
||||
const char *zSep1 = "";
|
||||
const char *zSep2 = "";
|
||||
|
||||
int i;
|
||||
const char *zSep = "";
|
||||
for(i=0; i<pAr->nArg; i++){
|
||||
for(i=0; i<pAr->nArg && z1 && z2; i++){
|
||||
const char *z = pAr->azArg[i];
|
||||
zWhere = sqlite3_mprintf(
|
||||
"%z%s name %s '%q' OR substr(name,1,%d) %s '%q/'",
|
||||
zWhere, zSep, zSameOp, z, strlen30(z)+1, zSameOp, z
|
||||
);
|
||||
if( zWhere==0 ){
|
||||
*pRc = SQLITE_NOMEM;
|
||||
break;
|
||||
int n = strlen30(z);
|
||||
|
||||
if( pAr->bGlob ){
|
||||
z1 = sqlite3_mprintf("%z%sname GLOB '%q'", z1, zSep2, z);
|
||||
z2 = sqlite3_mprintf(
|
||||
"%z%ssubstr(name,1,%d) GLOB '%q/'", z2, zSep2, n+1,z
|
||||
);
|
||||
}else{
|
||||
z1 = sqlite3_mprintf("%z%s'%q'", z1, zSep1, z);
|
||||
z2 = sqlite3_mprintf("%z%ssubstr(name,1,%d) = '%q/'",z2,zSep2,n+1,z);
|
||||
}
|
||||
zSep = " OR ";
|
||||
zSep1 = ", ";
|
||||
zSep2 = " OR ";
|
||||
}
|
||||
if( z1==0 || z2==0 ){
|
||||
*pRc = SQLITE_NOMEM;
|
||||
}else{
|
||||
zWhere = sqlite3_mprintf("(%s%s OR (name GLOB '*/*' AND (%s))) ",
|
||||
z1, pAr->bGlob==0 ? ")" : "", z2
|
||||
);
|
||||
}
|
||||
sqlite3_free(z1);
|
||||
sqlite3_free(z2);
|
||||
}
|
||||
}
|
||||
*pzWhere = zWhere;
|
||||
@@ -8204,7 +8268,7 @@ static int arDotCommand(
|
||||
cmd.out = pState->out;
|
||||
cmd.db = pState->db;
|
||||
if( cmd.zFile ){
|
||||
eDbType = deduceDatabaseType(cmd.zFile, 1);
|
||||
eDbType = deduceDatabaseType(cmd.zFile, 1, 0);
|
||||
}else{
|
||||
eDbType = pState->openMode;
|
||||
}
|
||||
@@ -9200,6 +9264,7 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
}
|
||||
p->showHeader = savedShowHeader;
|
||||
p->shellFlgs = savedShellFlags;
|
||||
rc = p->nErr>0;
|
||||
}else
|
||||
|
||||
if( c=='e' && cli_strncmp(azArg[0], "echo", n)==0 ){
|
||||
@@ -9526,7 +9591,7 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
ImportCtx sCtx; /* Reader context */
|
||||
char *(SQLITE_CDECL *xRead)(ImportCtx*); /* Func to read one value */
|
||||
int eVerbose = 0; /* Larger for more console output */
|
||||
int nSkip = 0; /* Initial lines to skip */
|
||||
i64 nSkip = 0; /* Initial lines to skip */
|
||||
int useOutputMode = 1; /* Use output mode to determine separators */
|
||||
char *zCreate = 0; /* CREATE TABLE statement text */
|
||||
|
||||
@@ -9653,7 +9718,8 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
shell_out_of_memory();
|
||||
}
|
||||
/* Below, resources must be freed before exit. */
|
||||
while( (nSkip--)>0 ){
|
||||
while( nSkip>0 ){
|
||||
nSkip--;
|
||||
while( xRead(&sCtx) && sCtx.cTerm==sCtx.cColSep ){}
|
||||
}
|
||||
import_append_char(&sCtx, 0); /* To ensure sCtx.z is allocated */
|
||||
@@ -10251,7 +10317,7 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
eputz("Usage: .nonce NONCE\n");
|
||||
rc = 1;
|
||||
}else if( p->zNonce==0 || cli_strcmp(azArg[1],p->zNonce)!=0 ){
|
||||
sqlite3_fprintf(stderr,"line %d: incorrect nonce: \"%s\"\n",
|
||||
sqlite3_fprintf(stderr,"line %lld: incorrect nonce: \"%s\"\n",
|
||||
p->lineno, azArg[1]);
|
||||
exit(1);
|
||||
}else{
|
||||
@@ -10306,6 +10372,8 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
openMode = SHELL_OPEN_DESERIALIZE;
|
||||
}else if( optionMatch(z, "hexdb") ){
|
||||
openMode = SHELL_OPEN_HEXDB;
|
||||
}else if( optionMatch(z, "normal") ){
|
||||
openMode = SHELL_OPEN_NORMAL;
|
||||
}else if( optionMatch(z, "maxsize") && iName+1<nArg ){
|
||||
p->szMax = integerValue(azArg[++iName]);
|
||||
#endif /* SQLITE_OMIT_DESERIALIZE */
|
||||
@@ -10424,6 +10492,7 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
"ERROR: unknown option: \"%s\". Usage:\n", azArg[i]);
|
||||
showHelp(p->out, azArg[0]);
|
||||
rc = 1;
|
||||
sqlite3_free(zFile);
|
||||
goto meta_command_exit;
|
||||
}
|
||||
}else if( zFile==0 && eMode==0 ){
|
||||
@@ -10707,7 +10776,7 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
#ifndef SQLITE_SHELL_FIDDLE
|
||||
if( c=='r' && n>=3 && cli_strncmp(azArg[0], "read", n)==0 ){
|
||||
FILE *inSaved = p->in;
|
||||
int savedLineno = p->lineno;
|
||||
i64 savedLineno = p->lineno;
|
||||
failIfSafeMode(p, "cannot run .read in safe mode");
|
||||
if( nArg!=2 ){
|
||||
eputz("Usage: .read FILE\n");
|
||||
@@ -10724,7 +10793,7 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
sqlite3_fprintf(stderr,"Error: cannot open \"%s\"\n", azArg[1]);
|
||||
rc = 1;
|
||||
}else{
|
||||
rc = process_input(p);
|
||||
rc = process_input(p, "<pipe>");
|
||||
pclose(p->in);
|
||||
}
|
||||
#endif
|
||||
@@ -10732,7 +10801,7 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
sqlite3_fprintf(stderr,"Error: cannot open \"%s\"\n", azArg[1]);
|
||||
rc = 1;
|
||||
}else{
|
||||
rc = process_input(p);
|
||||
rc = process_input(p, azArg[1]);
|
||||
fclose(p->in);
|
||||
}
|
||||
p->in = inSaved;
|
||||
@@ -11664,10 +11733,10 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
while( sqlite3_step(pStmt)==SQLITE_ROW ){
|
||||
if( nRow>=nAlloc ){
|
||||
char **azNew;
|
||||
int n2 = nAlloc*2 + 10;
|
||||
sqlite3_int64 n2 = 2*(sqlite3_int64)nAlloc + 10;
|
||||
azNew = sqlite3_realloc64(azResult, sizeof(azResult[0])*n2);
|
||||
shell_check_oom(azNew);
|
||||
nAlloc = n2;
|
||||
nAlloc = (int)n2;
|
||||
azResult = azNew;
|
||||
}
|
||||
azResult[nRow] = sqlite3_mprintf("%s", sqlite3_column_text(pStmt, 0));
|
||||
@@ -12723,7 +12792,7 @@ static char *one_input_line(FILE *in, char *zPrior, int isContinuation){
|
||||
**
|
||||
** Return the number of errors.
|
||||
*/
|
||||
static int process_input(ShellState *p){
|
||||
static int process_input(ShellState *p, const char *zSrc){
|
||||
char *zLine = 0; /* A single input line */
|
||||
char *zSql = 0; /* Accumulated SQL text */
|
||||
i64 nLine; /* Length of current line */
|
||||
@@ -12736,8 +12805,8 @@ static int process_input(ShellState *p){
|
||||
|
||||
if( p->inputNesting==MAX_INPUT_NESTING ){
|
||||
/* This will be more informative in a later version. */
|
||||
sqlite3_fprintf(stderr,"Input nesting limit (%d) reached at line %d."
|
||||
" Check recursion.\n", MAX_INPUT_NESTING, p->lineno);
|
||||
sqlite3_fprintf(stderr,"%s: Input nesting limit (%d) reached at line %lld."
|
||||
" Check recursion.\n", zSrc, MAX_INPUT_NESTING, p->lineno);
|
||||
return 1;
|
||||
}
|
||||
++p->inputNesting;
|
||||
@@ -12802,7 +12871,15 @@ static int process_input(ShellState *p){
|
||||
memcpy(zSql+nSql, zLine, nLine+1);
|
||||
nSql += nLine;
|
||||
}
|
||||
if( nSql && QSS_SEMITERM(qss) && sqlite3_complete(zSql) ){
|
||||
if( nSql>0x7fff0000 ){
|
||||
char zSize[100];
|
||||
sqlite3_snprintf(sizeof(zSize),zSize,"%,lld",nSql);
|
||||
sqlite3_fprintf(stderr, "%s:%lld: Input SQL is too big: %s bytes\n",
|
||||
zSrc, startline, zSize);
|
||||
nSql = 0;
|
||||
errCnt++;
|
||||
break;
|
||||
}else if( nSql && QSS_SEMITERM(qss) && sqlite3_complete(zSql) ){
|
||||
echo_group_input(p, zSql);
|
||||
errCnt += runOneSqlLine(p, zSql, p->in, startline);
|
||||
CONTINUE_PROMPT_RESET;
|
||||
@@ -12970,7 +13047,7 @@ static void process_sqliterc(
|
||||
char *home_dir = NULL;
|
||||
char *sqliterc = (char*)sqliterc_override;
|
||||
FILE *inSaved = p->in;
|
||||
int savedLineno = p->lineno;
|
||||
i64 savedLineno = p->lineno;
|
||||
|
||||
if( sqliterc == NULL ){
|
||||
sqliterc = find_xdg_file("XDG_CONFIG_HOME",
|
||||
@@ -12992,7 +13069,7 @@ static void process_sqliterc(
|
||||
if( stdin_is_interactive ){
|
||||
sqlite3_fprintf(stderr,"-- Loading resources from %s\n", sqliterc);
|
||||
}
|
||||
if( process_input(p) && bail_on_error ) exit(1);
|
||||
if( process_input(p, sqliterc) && bail_on_error ) exit(1);
|
||||
fclose(p->in);
|
||||
}else if( sqliterc_override!=0 ){
|
||||
sqlite3_fprintf(stderr,"cannot open: \"%s\"\n", sqliterc);
|
||||
@@ -13721,6 +13798,7 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
|
||||
rc = shell_exec(&data, z, &zErrMsg);
|
||||
if( zErrMsg!=0 ){
|
||||
shellEmitError(zErrMsg);
|
||||
sqlite3_free(zErrMsg);
|
||||
if( bail_on_error ) return rc!=0 ? rc : 1;
|
||||
}else if( rc!=0 ){
|
||||
sqlite3_fprintf(stderr,"Error: unable to process SQL \"%s\"\n", z);
|
||||
@@ -13823,7 +13901,7 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
|
||||
linenoiseSetCompletionCallback(linenoise_completion, NULL);
|
||||
#endif
|
||||
data.in = 0;
|
||||
rc = process_input(&data);
|
||||
rc = process_input(&data, "<stdin>");
|
||||
if( zHistory ){
|
||||
shell_stifle_history(2000);
|
||||
shell_write_history(zHistory);
|
||||
@@ -13831,7 +13909,7 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
|
||||
}
|
||||
}else{
|
||||
data.in = stdin;
|
||||
rc = process_input(&data);
|
||||
rc = process_input(&data, "<stdin>");
|
||||
}
|
||||
}
|
||||
#ifndef SQLITE_SHELL_FIDDLE
|
||||
@@ -14013,7 +14091,7 @@ void fiddle_exec(const char * zSql){
|
||||
if('.'==*zSql) puts(zSql);
|
||||
shellState.wasm.zInput = zSql;
|
||||
shellState.wasm.zPos = zSql;
|
||||
process_input(&shellState);
|
||||
process_input(&shellState, "<stdin>");
|
||||
shellState.wasm.zInput = shellState.wasm.zPos = 0;
|
||||
}
|
||||
}
|
||||
|
||||
+65
-21
@@ -144,7 +144,7 @@ extern "C" {
|
||||
**
|
||||
** See also: [sqlite3_libversion()],
|
||||
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
|
||||
** [sqlite_version()] and [sqlite_sourceid()].
|
||||
** [sqlite_version()] and [sqlite_source_id()].
|
||||
*/
|
||||
#define SQLITE_VERSION "--VERS--"
|
||||
#define SQLITE_VERSION_NUMBER --VERSION-NUMBER--
|
||||
@@ -183,7 +183,7 @@ extern "C" {
|
||||
** using an edited copy of [the amalgamation], then the last four characters
|
||||
** of the hash might be different from [SQLITE_SOURCE_ID].)^
|
||||
**
|
||||
** See also: [sqlite_version()] and [sqlite_sourceid()].
|
||||
** See also: [sqlite_version()] and [sqlite_source_id()].
|
||||
*/
|
||||
SQLITE_EXTERN const char sqlite3_version[];
|
||||
const char *sqlite3_libversion(void);
|
||||
@@ -932,7 +932,7 @@ struct sqlite3_io_methods {
|
||||
** connection. See also [SQLITE_FCNTL_FILE_POINTER].
|
||||
**
|
||||
** <li>[[SQLITE_FCNTL_SYNC_OMITTED]]
|
||||
** No longer in use.
|
||||
** The SQLITE_FCNTL_SYNC_OMITTED file-control is no longer used.
|
||||
**
|
||||
** <li>[[SQLITE_FCNTL_SYNC]]
|
||||
** The [SQLITE_FCNTL_SYNC] opcode is generated internally by SQLite and
|
||||
@@ -1229,6 +1229,15 @@ struct sqlite3_io_methods {
|
||||
** database is not a temp db, then the [SQLITE_FCNTL_RESET_CACHE] file-control
|
||||
** purges the contents of the in-memory page cache. If there is an open
|
||||
** transaction, or if the db is a temp-db, this opcode is a no-op, not an error.
|
||||
**
|
||||
** <li>[[SQLITE_FCNTL_FILESTAT]]
|
||||
** The [SQLITE_FCNTL_FILESTAT] opcode returns low-level diagnostic information
|
||||
** about the [sqlite3_file] objects used access the database and journal files
|
||||
** for the given schema. The fourth parameter to [sqlite3_file_control()]
|
||||
** should be an initialized [sqlite3_str] pointer. JSON text describing
|
||||
** various aspects of the sqlite3_file object is appended to the sqlite3_str.
|
||||
** The SQLITE_FCNTL_FILESTAT opcode is usually a no-op, unless compile-time
|
||||
** options are used to enable it.
|
||||
** </ul>
|
||||
*/
|
||||
#define SQLITE_FCNTL_LOCKSTATE 1
|
||||
@@ -1274,6 +1283,7 @@ struct sqlite3_io_methods {
|
||||
#define SQLITE_FCNTL_RESET_CACHE 42
|
||||
#define SQLITE_FCNTL_NULL_IO 43
|
||||
#define SQLITE_FCNTL_BLOCK_ON_CONNECT 44
|
||||
#define SQLITE_FCNTL_FILESTAT 45
|
||||
|
||||
/* deprecated names */
|
||||
#define SQLITE_GET_LOCKPROXYFILE SQLITE_FCNTL_GET_LOCKPROXYFILE
|
||||
@@ -2557,12 +2567,15 @@ struct sqlite3_mem_methods {
|
||||
** [[SQLITE_DBCONFIG_STMT_SCANSTATUS]]
|
||||
** <dt>SQLITE_DBCONFIG_STMT_SCANSTATUS</dt>
|
||||
** <dd>The SQLITE_DBCONFIG_STMT_SCANSTATUS option is only useful in
|
||||
** SQLITE_ENABLE_STMT_SCANSTATUS builds. In this case, it sets or clears
|
||||
** a flag that enables collection of the sqlite3_stmt_scanstatus_v2()
|
||||
** statistics. For statistics to be collected, the flag must be set on
|
||||
** the database handle both when the SQL statement is prepared and when it
|
||||
** is stepped. The flag is set (collection of statistics is enabled)
|
||||
** by default. <p>This option takes two arguments: an integer and a pointer to
|
||||
** [SQLITE_ENABLE_STMT_SCANSTATUS] builds. In this case, it sets or clears
|
||||
** a flag that enables collection of run-time performance statistics
|
||||
** used by [sqlite3_stmt_scanstatus_v2()] and the [nexec and ncycle]
|
||||
** columns of the [bytecode virtual table].
|
||||
** For statistics to be collected, the flag must be set on
|
||||
** the database handle both when the SQL statement is
|
||||
** [sqlite3_prepare|prepared] and when it is [sqlite3_step|stepped].
|
||||
** The flag is set (collection of statistics is enabled) by default.
|
||||
** <p>This option takes two arguments: an integer and a pointer to
|
||||
** an integer. The first argument is 1, 0, or -1 to enable, disable, or
|
||||
** leave unchanged the statement scanstatus option. If the second argument
|
||||
** is not NULL, then the value of the statement scanstatus setting after
|
||||
@@ -4207,7 +4220,7 @@ const char *sqlite3_errstr(int);
|
||||
int sqlite3_error_offset(sqlite3 *db);
|
||||
|
||||
/*
|
||||
** CAPI3REF: Set Error Codes And Message
|
||||
** CAPI3REF: Set Error Code And Message
|
||||
** METHOD: sqlite3
|
||||
**
|
||||
** Set the error code of the database handle passed as the first argument
|
||||
@@ -4907,9 +4920,11 @@ typedef struct sqlite3_context sqlite3_context;
|
||||
** associated with the pointer P of type T. ^D is either a NULL pointer or
|
||||
** a pointer to a destructor function for P. ^SQLite will invoke the
|
||||
** destructor D with a single argument of P when it is finished using
|
||||
** P. The T parameter should be a static string, preferably a string
|
||||
** literal. The sqlite3_bind_pointer() routine is part of the
|
||||
** [pointer passing interface] added for SQLite 3.20.0.
|
||||
** P, even if the call to sqlite3_bind_pointer() fails. Due to a
|
||||
** historical design quirk, results are undefined if D is
|
||||
** SQLITE_TRANSIENT. The T parameter should be a static string,
|
||||
** preferably a string literal. The sqlite3_bind_pointer() routine is
|
||||
** part of the [pointer passing interface] added for SQLite 3.20.0.
|
||||
**
|
||||
** ^If any of the sqlite3_bind_*() routines are called with a NULL pointer
|
||||
** for the [prepared statement] or with a prepared statement for which
|
||||
@@ -8921,9 +8936,18 @@ int sqlite3_status64(
|
||||
** ^The sqlite3_db_status() routine returns SQLITE_OK on success and a
|
||||
** non-zero [error code] on failure.
|
||||
**
|
||||
** ^The sqlite3_db_status64(D,O,C,H,R) routine works exactly the same
|
||||
** way as sqlite3_db_status(D,O,C,H,R) routine except that the C and H
|
||||
** parameters are pointer to 64-bit integers (type: sqlite3_int64) instead
|
||||
** of pointers to 32-bit integers, which allows larger status values
|
||||
** to be returned. If a status value exceeds 2,147,483,647 then
|
||||
** sqlite3_db_status() will truncate the value whereas sqlite3_db_status64()
|
||||
** will return the full value.
|
||||
**
|
||||
** See also: [sqlite3_status()] and [sqlite3_stmt_status()].
|
||||
*/
|
||||
int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int resetFlg);
|
||||
int sqlite3_db_status64(sqlite3*,int,sqlite3_int64*,sqlite3_int64*,int);
|
||||
|
||||
/*
|
||||
** CAPI3REF: Status Parameters for database connections
|
||||
@@ -9020,6 +9044,10 @@ int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int resetFlg);
|
||||
** If an IO or other error occurs while writing a page to disk, the effect
|
||||
** on subsequent SQLITE_DBSTATUS_CACHE_WRITE requests is undefined.)^ ^The
|
||||
** highwater mark associated with SQLITE_DBSTATUS_CACHE_WRITE is always 0.
|
||||
** <p>
|
||||
** ^(There is overlap between the quantities measured by this parameter
|
||||
** (SQLITE_DBSTATUS_CACHE_WRITE) and SQLITE_DBSTATUS_TEMPBUF_SPILL.
|
||||
** Resetting one will reduce the other.)^
|
||||
** </dd>
|
||||
**
|
||||
** [[SQLITE_DBSTATUS_CACHE_SPILL]] ^(<dt>SQLITE_DBSTATUS_CACHE_SPILL</dt>
|
||||
@@ -9035,6 +9063,18 @@ int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int resetFlg);
|
||||
** <dd>This parameter returns zero for the current value if and only if
|
||||
** all foreign key constraints (deferred or immediate) have been
|
||||
** resolved.)^ ^The highwater mark is always 0.
|
||||
**
|
||||
** [[SQLITE_DBSTATUS_TEMPBUF_SPILL] ^(<dt>SQLITE_DBSTATUS_TEMPBUF_SPILL</dt>
|
||||
** <dd>^(This parameter returns the number of bytes written to temporary
|
||||
** files on disk that could have been kept in memory had sufficient memory
|
||||
** been available. This value includes writes to intermediate tables that
|
||||
** are part of complex queries, external sorts that spill to disk, and
|
||||
** writes to TEMP tables.)^
|
||||
** ^The highwater mark is always 0.
|
||||
** <p>
|
||||
** ^(There is overlap between the quantities measured by this parameter
|
||||
** (SQLITE_DBSTATUS_TEMPBUF_SPILL) and SQLITE_DBSTATUS_CACHE_WRITE.
|
||||
** Resetting one will reduce the other.)^
|
||||
** </dd>
|
||||
** </dl>
|
||||
*/
|
||||
@@ -9051,7 +9091,8 @@ int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int resetFlg);
|
||||
#define SQLITE_DBSTATUS_DEFERRED_FKS 10
|
||||
#define SQLITE_DBSTATUS_CACHE_USED_SHARED 11
|
||||
#define SQLITE_DBSTATUS_CACHE_SPILL 12
|
||||
#define SQLITE_DBSTATUS_MAX 12 /* Largest defined DBSTATUS */
|
||||
#define SQLITE_DBSTATUS_TEMPBUF_SPILL 13
|
||||
#define SQLITE_DBSTATUS_MAX 13 /* Largest defined DBSTATUS */
|
||||
|
||||
|
||||
/*
|
||||
@@ -10388,7 +10429,7 @@ int sqlite3_vtab_in(sqlite3_index_info*, int iCons, int bHandle);
|
||||
** ){
|
||||
** // do something with pVal
|
||||
** }
|
||||
** if( rc!=SQLITE_OK ){
|
||||
** if( rc!=SQLITE_DONE ){
|
||||
** // an error has occurred
|
||||
** }
|
||||
** </pre></blockquote>)^
|
||||
@@ -10560,9 +10601,9 @@ int sqlite3_vtab_rhs_value(sqlite3_index_info*, int, sqlite3_value **ppVal);
|
||||
** a variable pointed to by the "pOut" parameter.
|
||||
**
|
||||
** The "flags" parameter must be passed a mask of flags. At present only
|
||||
** one flag is defined - SQLITE_SCANSTAT_COMPLEX. If SQLITE_SCANSTAT_COMPLEX
|
||||
** one flag is defined - [SQLITE_SCANSTAT_COMPLEX]. If SQLITE_SCANSTAT_COMPLEX
|
||||
** is specified, then status information is available for all elements
|
||||
** of a query plan that are reported by "EXPLAIN QUERY PLAN" output. If
|
||||
** of a query plan that are reported by "[EXPLAIN QUERY PLAN]" output. If
|
||||
** SQLITE_SCANSTAT_COMPLEX is not specified, then only query plan elements
|
||||
** that correspond to query loops (the "SCAN..." and "SEARCH..." elements of
|
||||
** the EXPLAIN QUERY PLAN output) are available. Invoking API
|
||||
@@ -10576,7 +10617,8 @@ int sqlite3_vtab_rhs_value(sqlite3_index_info*, int, sqlite3_value **ppVal);
|
||||
** elements used to implement the statement - a non-zero value is returned and
|
||||
** the variable that pOut points to is unchanged.
|
||||
**
|
||||
** See also: [sqlite3_stmt_scanstatus_reset()]
|
||||
** See also: [sqlite3_stmt_scanstatus_reset()] and the
|
||||
** [nexec and ncycle] columnes of the [bytecode virtual table].
|
||||
*/
|
||||
int sqlite3_stmt_scanstatus(
|
||||
sqlite3_stmt *pStmt, /* Prepared statement for which info desired */
|
||||
@@ -11127,9 +11169,11 @@ int sqlite3_deserialize(
|
||||
** [SQLITE_CARRAY_DOUBLE], [SQLITE_CARRAY_TEXT], or [SQLITE_CARRAY_BLOB] to
|
||||
** indicate the datatype of the array being bound. The X argument is not a
|
||||
** NULL pointer, then SQLite will invoke the function X on the P parameter
|
||||
** after it has finished using P.
|
||||
** after it has finished using P, even if the call to
|
||||
** sqlite3_carray_bind() fails. The special-case finalizer
|
||||
** SQLITE_TRANSIENT has no effect here.
|
||||
*/
|
||||
SQLITE_API int sqlite3_carray_bind(
|
||||
int sqlite3_carray_bind(
|
||||
sqlite3_stmt *pStmt, /* Statement to be bound */
|
||||
int i, /* Parameter index */
|
||||
void *aData, /* Pointer to array data */
|
||||
@@ -11139,7 +11183,7 @@ SQLITE_API int sqlite3_carray_bind(
|
||||
);
|
||||
|
||||
/*
|
||||
** CAPI3REF: Datatypes for the CARRAY table-valued funtion
|
||||
** CAPI3REF: Datatypes for the CARRAY table-valued function
|
||||
**
|
||||
** The fifth argument to the [sqlite3_carray_bind()] interface musts be
|
||||
** one of the following constants, to specify the datatype of the array
|
||||
|
||||
@@ -370,6 +370,8 @@ struct sqlite3_api_routines {
|
||||
int (*setlk_timeout)(sqlite3*,int,int);
|
||||
/* Version 3.51.0 and later */
|
||||
int (*set_errmsg)(sqlite3*,int,const char*);
|
||||
int (*db_status64)(sqlite3*,int,sqlite3_int64*,sqlite3_int64*,int);
|
||||
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -707,6 +709,7 @@ typedef int (*sqlite3_loadext_entry)(
|
||||
#define sqlite3_setlk_timeout sqlite3_api->setlk_timeout
|
||||
/* Version 3.51.0 and later */
|
||||
#define sqlite3_set_errmsg sqlite3_api->set_errmsg
|
||||
#define sqlite3_db_status64 sqlite3_api->db_status64
|
||||
#endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */
|
||||
|
||||
#if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
|
||||
|
||||
+2
-1
@@ -1784,6 +1784,7 @@ struct sqlite3 {
|
||||
i64 nDeferredImmCons; /* Net deferred immediate constraints */
|
||||
int *pnBytesFreed; /* If not NULL, increment this in DbFree() */
|
||||
DbClientData *pDbData; /* sqlite3_set_clientdata() content */
|
||||
u64 nSpill; /* TEMP content spilled to disk */
|
||||
#ifdef SQLITE_ENABLE_UNLOCK_NOTIFY
|
||||
/* The following variables are all protected by the STATIC_MAIN
|
||||
** mutex, not by sqlite3.mutex. They are used by code in notify.c.
|
||||
@@ -5451,7 +5452,7 @@ void sqlite3Reindex(Parse*, Token*, Token*);
|
||||
void sqlite3AlterFunctions(void);
|
||||
void sqlite3AlterRenameTable(Parse*, SrcList*, Token*);
|
||||
void sqlite3AlterRenameColumn(Parse*, SrcList*, Token*, Token*);
|
||||
int sqlite3GetToken(const unsigned char *, int *);
|
||||
i64 sqlite3GetToken(const unsigned char *, int *);
|
||||
void sqlite3NestedParse(Parse*, const char*, ...);
|
||||
void sqlite3ExpirePreparedStatements(sqlite3*, int);
|
||||
void sqlite3CodeRhsOfIN(Parse*, Expr*, int);
|
||||
|
||||
+69
-22
@@ -200,23 +200,25 @@ int sqlite3LookasideUsed(sqlite3 *db, int *pHighwater){
|
||||
/*
|
||||
** Query status information for a single database connection
|
||||
*/
|
||||
int sqlite3_db_status(
|
||||
sqlite3 *db, /* The database connection whose status is desired */
|
||||
int op, /* Status verb */
|
||||
int *pCurrent, /* Write current value here */
|
||||
int *pHighwater, /* Write high-water mark here */
|
||||
int resetFlag /* Reset high-water mark if true */
|
||||
int sqlite3_db_status64(
|
||||
sqlite3 *db, /* The database connection whose status is desired */
|
||||
int op, /* Status verb */
|
||||
sqlite3_int64 *pCurrent, /* Write current value here */
|
||||
sqlite3_int64 *pHighwtr, /* Write high-water mark here */
|
||||
int resetFlag /* Reset high-water mark if true */
|
||||
){
|
||||
int rc = SQLITE_OK; /* Return code */
|
||||
#ifdef SQLITE_ENABLE_API_ARMOR
|
||||
if( !sqlite3SafetyCheckOk(db) || pCurrent==0|| pHighwater==0 ){
|
||||
if( !sqlite3SafetyCheckOk(db) || pCurrent==0|| pHighwtr==0 ){
|
||||
return SQLITE_MISUSE_BKPT;
|
||||
}
|
||||
#endif
|
||||
sqlite3_mutex_enter(db->mutex);
|
||||
switch( op ){
|
||||
case SQLITE_DBSTATUS_LOOKASIDE_USED: {
|
||||
*pCurrent = sqlite3LookasideUsed(db, pHighwater);
|
||||
int H = 0;
|
||||
*pCurrent = sqlite3LookasideUsed(db, &H);
|
||||
*pHighwtr = H;
|
||||
if( resetFlag ){
|
||||
LookasideSlot *p = db->lookaside.pFree;
|
||||
if( p ){
|
||||
@@ -247,7 +249,7 @@ int sqlite3_db_status(
|
||||
assert( (op-SQLITE_DBSTATUS_LOOKASIDE_HIT)>=0 );
|
||||
assert( (op-SQLITE_DBSTATUS_LOOKASIDE_HIT)<3 );
|
||||
*pCurrent = 0;
|
||||
*pHighwater = (int)db->lookaside.anStat[op-SQLITE_DBSTATUS_LOOKASIDE_HIT];
|
||||
*pHighwtr = db->lookaside.anStat[op-SQLITE_DBSTATUS_LOOKASIDE_HIT];
|
||||
if( resetFlag ){
|
||||
db->lookaside.anStat[op - SQLITE_DBSTATUS_LOOKASIDE_HIT] = 0;
|
||||
}
|
||||
@@ -261,7 +263,7 @@ int sqlite3_db_status(
|
||||
*/
|
||||
case SQLITE_DBSTATUS_CACHE_USED_SHARED:
|
||||
case SQLITE_DBSTATUS_CACHE_USED: {
|
||||
int totalUsed = 0;
|
||||
sqlite3_int64 totalUsed = 0;
|
||||
int i;
|
||||
sqlite3BtreeEnterAll(db);
|
||||
for(i=0; i<db->nDb; i++){
|
||||
@@ -277,18 +279,18 @@ int sqlite3_db_status(
|
||||
}
|
||||
sqlite3BtreeLeaveAll(db);
|
||||
*pCurrent = totalUsed;
|
||||
*pHighwater = 0;
|
||||
*pHighwtr = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
** *pCurrent gets an accurate estimate of the amount of memory used
|
||||
** to store the schema for all databases (main, temp, and any ATTACHed
|
||||
** databases. *pHighwater is set to zero.
|
||||
** databases. *pHighwtr is set to zero.
|
||||
*/
|
||||
case SQLITE_DBSTATUS_SCHEMA_USED: {
|
||||
int i; /* Used to iterate through schemas */
|
||||
int nByte = 0; /* Used to accumulate return value */
|
||||
int i; /* Used to iterate through schemas */
|
||||
int nByte = 0; /* Used to accumulate return value */
|
||||
|
||||
sqlite3BtreeEnterAll(db);
|
||||
db->pnBytesFreed = &nByte;
|
||||
@@ -322,7 +324,7 @@ int sqlite3_db_status(
|
||||
db->lookaside.pEnd = db->lookaside.pTrueEnd;
|
||||
sqlite3BtreeLeaveAll(db);
|
||||
|
||||
*pHighwater = 0;
|
||||
*pHighwtr = 0;
|
||||
*pCurrent = nByte;
|
||||
break;
|
||||
}
|
||||
@@ -330,7 +332,7 @@ int sqlite3_db_status(
|
||||
/*
|
||||
** *pCurrent gets an accurate estimate of the amount of memory used
|
||||
** to store all prepared statements.
|
||||
** *pHighwater is set to zero.
|
||||
** *pHighwtr is set to zero.
|
||||
*/
|
||||
case SQLITE_DBSTATUS_STMT_USED: {
|
||||
struct Vdbe *pVdbe; /* Used to iterate through VMs */
|
||||
@@ -345,7 +347,7 @@ int sqlite3_db_status(
|
||||
db->lookaside.pEnd = db->lookaside.pTrueEnd;
|
||||
db->pnBytesFreed = 0;
|
||||
|
||||
*pHighwater = 0; /* IMP: R-64479-57858 */
|
||||
*pHighwtr = 0; /* IMP: R-64479-57858 */
|
||||
*pCurrent = nByte;
|
||||
|
||||
break;
|
||||
@@ -353,7 +355,7 @@ int sqlite3_db_status(
|
||||
|
||||
/*
|
||||
** Set *pCurrent to the total cache hits or misses encountered by all
|
||||
** pagers the database handle is connected to. *pHighwater is always set
|
||||
** pagers the database handle is connected to. *pHighwtr is always set
|
||||
** to zero.
|
||||
*/
|
||||
case SQLITE_DBSTATUS_CACHE_SPILL:
|
||||
@@ -373,19 +375,39 @@ int sqlite3_db_status(
|
||||
sqlite3PagerCacheStat(pPager, op, resetFlag, &nRet);
|
||||
}
|
||||
}
|
||||
*pHighwater = 0; /* IMP: R-42420-56072 */
|
||||
*pHighwtr = 0; /* IMP: R-42420-56072 */
|
||||
/* IMP: R-54100-20147 */
|
||||
/* IMP: R-29431-39229 */
|
||||
*pCurrent = (int)nRet & 0x7fffffff;
|
||||
*pCurrent = nRet;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Set *pCurrent to the number of bytes that the db database connection
|
||||
** has spilled to the filesystem in temporary files that could have been
|
||||
** stored in memory, had sufficient memory been available.
|
||||
** The *pHighwater is always set to zero.
|
||||
*/
|
||||
case SQLITE_DBSTATUS_TEMPBUF_SPILL: {
|
||||
u64 nRet = 0;
|
||||
if( db->aDb[1].pBt ){
|
||||
Pager *pPager = sqlite3BtreePager(db->aDb[1].pBt);
|
||||
sqlite3PagerCacheStat(pPager, SQLITE_DBSTATUS_CACHE_WRITE,
|
||||
resetFlag, &nRet);
|
||||
nRet *= sqlite3BtreeGetPageSize(db->aDb[1].pBt);
|
||||
}
|
||||
nRet += db->nSpill;
|
||||
if( resetFlag ) db->nSpill = 0;
|
||||
*pHighwtr = 0;
|
||||
*pCurrent = nRet;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Set *pCurrent to non-zero if there are unresolved deferred foreign
|
||||
** key constraints. Set *pCurrent to zero if all foreign key constraints
|
||||
** have been satisfied. The *pHighwater is always set to zero.
|
||||
** have been satisfied. The *pHighwtr is always set to zero.
|
||||
*/
|
||||
case SQLITE_DBSTATUS_DEFERRED_FKS: {
|
||||
*pHighwater = 0; /* IMP: R-11967-56545 */
|
||||
*pHighwtr = 0; /* IMP: R-11967-56545 */
|
||||
*pCurrent = db->nDeferredImmCons>0 || db->nDeferredCons>0;
|
||||
break;
|
||||
}
|
||||
@@ -397,3 +419,28 @@ int sqlite3_db_status(
|
||||
sqlite3_mutex_leave(db->mutex);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
** 32-bit variant of sqlite3_db_status64()
|
||||
*/
|
||||
int sqlite3_db_status(
|
||||
sqlite3 *db, /* The database connection whose status is desired */
|
||||
int op, /* Status verb */
|
||||
int *pCurrent, /* Write current value here */
|
||||
int *pHighwtr, /* Write high-water mark here */
|
||||
int resetFlag /* Reset high-water mark if true */
|
||||
){
|
||||
sqlite3_int64 C = 0, H = 0;
|
||||
int rc;
|
||||
#ifdef SQLITE_ENABLE_API_ARMOR
|
||||
if( !sqlite3SafetyCheckOk(db) || pCurrent==0|| pHighwtr==0 ){
|
||||
return SQLITE_MISUSE_BKPT;
|
||||
}
|
||||
#endif
|
||||
rc = sqlite3_db_status64(db, op, &C, &H, resetFlag);
|
||||
if( rc==0 ){
|
||||
*pCurrent = C & 0x7fffffff;
|
||||
*pHighwtr = H & 0x7fffffff;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
+32
@@ -4972,6 +4972,37 @@ static int SQLITE_TCLAPI test_errmsg16(
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Usage: sqlite3_set_errmsg DB ERRCODE ERRMSG
|
||||
*/
|
||||
static int SQLITE_TCLAPI test_set_errmsg(
|
||||
void * clientData,
|
||||
Tcl_Interp *interp,
|
||||
int objc,
|
||||
Tcl_Obj *CONST objv[]
|
||||
){
|
||||
const char *zDb = 0;
|
||||
const char *zErr = 0;
|
||||
int iErr = 0;
|
||||
sqlite3 *db = 0;
|
||||
int rc;
|
||||
|
||||
if( objc!=4 ){
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "DB ERRCODE ERRMSG");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
zDb = Tcl_GetString(objv[1]);
|
||||
if( zDb[0] ){
|
||||
if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
|
||||
}
|
||||
if( Tcl_GetIntFromObj(interp, objv[2], &iErr) ) return TCL_ERROR;
|
||||
zErr = Tcl_GetString(objv[3]);
|
||||
|
||||
rc = sqlite3_set_errmsg(db, iErr, (zErr[0] ? zErr : 0));
|
||||
Tcl_SetResult(interp, (char *)t1ErrorName(rc), 0);
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Usage: sqlite3_prepare DB sql bytes ?tailvar?
|
||||
**
|
||||
@@ -9077,6 +9108,7 @@ int Sqlitetest1_Init(Tcl_Interp *interp){
|
||||
{ "sqlite3_errmsg", test_errmsg ,0 },
|
||||
{ "sqlite3_error_offset", test_error_offset ,0 },
|
||||
{ "sqlite3_errmsg16", test_errmsg16 ,0 },
|
||||
{ "sqlite3_set_errmsg", test_set_errmsg ,0 },
|
||||
{ "sqlite3_open", test_open ,0 },
|
||||
{ "sqlite3_open16", test_open16 ,0 },
|
||||
{ "sqlite3_open_v2", test_open_v2 ,0 },
|
||||
|
||||
@@ -1368,6 +1368,7 @@ static int SQLITE_TCLAPI test_db_status(
|
||||
{ "DEFERRED_FKS", SQLITE_DBSTATUS_DEFERRED_FKS },
|
||||
{ "CACHE_USED_SHARED", SQLITE_DBSTATUS_CACHE_USED_SHARED },
|
||||
{ "CACHE_SPILL", SQLITE_DBSTATUS_CACHE_SPILL },
|
||||
{ "TEMPBUF_SPILL", SQLITE_DBSTATUS_TEMPBUF_SPILL },
|
||||
};
|
||||
Tcl_Obj *pResult;
|
||||
if( objc!=4 ){
|
||||
|
||||
+3
-3
@@ -81,7 +81,7 @@
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#if SQLITE_OS_UNIX && !defined(__CYGWIN__)
|
||||
#if SQLITE_OS_UNIX
|
||||
|
||||
/* From main.c */
|
||||
extern const char *sqlite3ErrName(int);
|
||||
@@ -426,7 +426,7 @@ static int SQLITE_TCLAPI test_syscall_install(
|
||||
){
|
||||
sqlite3_vfs *pVfs;
|
||||
Tcl_Size nElem;
|
||||
Tcl_Size i;
|
||||
int i;
|
||||
Tcl_Obj **apElem;
|
||||
|
||||
if( objc!=3 ){
|
||||
@@ -438,7 +438,7 @@ static int SQLITE_TCLAPI test_syscall_install(
|
||||
}
|
||||
pVfs = sqlite3_vfs_find(0);
|
||||
|
||||
for(i=0; i<nElem; i++){
|
||||
for(i=0; i<(int)nElem; i++){
|
||||
int iCall;
|
||||
int rc = Tcl_GetIndexFromObjStruct(interp,
|
||||
apElem[i], aSyscall, sizeof(aSyscall[0]), "system-call", 0, &iCall
|
||||
|
||||
+7
-6
@@ -270,8 +270,9 @@ static int analyzeFilterKeyword(const unsigned char *z, int lastToken){
|
||||
** Return the length (in bytes) of the token that begins at z[0].
|
||||
** Store the token type in *tokenType before returning.
|
||||
*/
|
||||
int sqlite3GetToken(const unsigned char *z, int *tokenType){
|
||||
int i, c;
|
||||
i64 sqlite3GetToken(const unsigned char *z, int *tokenType){
|
||||
i64 i;
|
||||
int c;
|
||||
switch( aiClass[*z] ){ /* Switch on the character-class of the first byte
|
||||
** of the token. See the comment on the CC_ defines
|
||||
** above. */
|
||||
@@ -599,7 +600,7 @@ int sqlite3GetToken(const unsigned char *z, int *tokenType){
|
||||
int sqlite3RunParser(Parse *pParse, const char *zSql){
|
||||
int nErr = 0; /* Number of errors encountered */
|
||||
void *pEngine; /* The LEMON-generated LALR(1) parser */
|
||||
int n = 0; /* Length of the next token token */
|
||||
i64 n = 0; /* Length of the next token token */
|
||||
int tokenType; /* type of the next token */
|
||||
int lastTokenParsed = -1; /* type of the previous token */
|
||||
sqlite3 *db = pParse->db; /* The database connection */
|
||||
@@ -702,13 +703,13 @@ int sqlite3RunParser(Parse *pParse, const char *zSql){
|
||||
}else if( tokenType!=TK_QNUMBER ){
|
||||
Token x;
|
||||
x.z = zSql;
|
||||
x.n = n;
|
||||
x.n = (u32)n;
|
||||
sqlite3ErrorMsg(pParse, "unrecognized token: \"%T\"", &x);
|
||||
break;
|
||||
}
|
||||
}
|
||||
pParse->sLastToken.z = zSql;
|
||||
pParse->sLastToken.n = n;
|
||||
pParse->sLastToken.n = (u32)n;
|
||||
sqlite3Parser(pEngine, tokenType, pParse->sLastToken);
|
||||
lastTokenParsed = tokenType;
|
||||
zSql += n;
|
||||
@@ -784,7 +785,7 @@ char *sqlite3Normalize(
|
||||
){
|
||||
sqlite3 *db; /* The database connection */
|
||||
int i; /* Next unread byte of zSql[] */
|
||||
int n; /* length of current token */
|
||||
i64 n; /* length of current token */
|
||||
int tokenType; /* type of current token */
|
||||
int prevType = 0; /* Previous non-whitespace token */
|
||||
int nParen; /* Number of nested levels of parentheses */
|
||||
|
||||
+7
-3
@@ -717,7 +717,7 @@ static u64 filterHash(const Mem *aMem, const Op *pOp){
|
||||
static SQLITE_NOINLINE int vdbeColumnFromOverflow(
|
||||
VdbeCursor *pC, /* The BTree cursor from which we are reading */
|
||||
int iCol, /* The column to read */
|
||||
int t, /* The serial-type code for the column value */
|
||||
u32 t, /* The serial-type code for the column value */
|
||||
i64 iOffset, /* Offset to the start of the content value */
|
||||
u32 cacheStatus, /* Current Vdbe.cacheCtr value */
|
||||
u32 colCacheCtr, /* Current value of the column cache counter */
|
||||
@@ -1818,10 +1818,14 @@ case OP_Concat: { /* same as TK_CONCAT, in1, in2, out3 */
|
||||
if( sqlite3VdbeMemExpandBlob(pIn2) ) goto no_mem;
|
||||
flags2 = pIn2->flags & ~MEM_Str;
|
||||
}
|
||||
nByte = pIn1->n + pIn2->n;
|
||||
nByte = pIn1->n;
|
||||
nByte += pIn2->n;
|
||||
if( nByte>db->aLimit[SQLITE_LIMIT_LENGTH] ){
|
||||
goto too_big;
|
||||
}
|
||||
#if SQLITE_MAX_LENGTH>2147483645
|
||||
if( nByte>2147483645 ){ goto too_big; }
|
||||
#endif
|
||||
if( sqlite3VdbeMemGrow(pOut, (int)nByte+2, pOut==pIn2) ){
|
||||
goto no_mem;
|
||||
}
|
||||
@@ -3643,7 +3647,7 @@ case OP_MakeRecord: {
|
||||
len = (u32)pRec->n;
|
||||
serial_type = (len*2) + 12 + ((pRec->flags & MEM_Str)!=0);
|
||||
if( pRec->flags & MEM_Zero ){
|
||||
serial_type += pRec->u.nZero*2;
|
||||
serial_type += (u32)pRec->u.nZero*2;
|
||||
if( nData ){
|
||||
if( sqlite3VdbeMemExpandBlob(pRec) ) goto no_mem;
|
||||
len += pRec->u.nZero;
|
||||
|
||||
+1
-2
@@ -557,8 +557,7 @@ struct PreUpdate {
|
||||
Table *pTab; /* Schema object being updated */
|
||||
Index *pPk; /* PK index if pTab is WITHOUT ROWID */
|
||||
sqlite3_value **apDflt; /* Array of default values, if required */
|
||||
union {
|
||||
KeyInfo sKey;
|
||||
struct {
|
||||
u8 keyinfoSpace[SZ_KEYINFO_0]; /* Space to hold pKeyinfo[0] content */
|
||||
} uKey;
|
||||
};
|
||||
|
||||
@@ -736,6 +736,8 @@ static int doWalCallbacks(sqlite3 *db){
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
UNUSED_PARAMETER(db);
|
||||
#endif
|
||||
return rc;
|
||||
}
|
||||
|
||||
+1
-1
@@ -5538,7 +5538,7 @@ void sqlite3VdbePreUpdateHook(
|
||||
preupdate.pCsr = pCsr;
|
||||
preupdate.op = op;
|
||||
preupdate.iNewReg = iReg;
|
||||
preupdate.pKeyinfo = &preupdate.uKey.sKey;
|
||||
preupdate.pKeyinfo = (KeyInfo*)&preupdate.uKey;
|
||||
preupdate.pKeyinfo->db = db;
|
||||
preupdate.pKeyinfo->enc = ENC(db);
|
||||
preupdate.pKeyinfo->nKeyField = pTab->nCol;
|
||||
|
||||
@@ -1226,6 +1226,7 @@ int sqlite3VdbeMemSetStr(
|
||||
if( sqlite3VdbeMemClearAndResize(pMem, (int)MAX(nAlloc,32)) ){
|
||||
return SQLITE_NOMEM_BKPT;
|
||||
}
|
||||
assert( pMem->z!=0 );
|
||||
memcpy(pMem->z, z, nAlloc);
|
||||
}else{
|
||||
sqlite3VdbeMemRelease(pMem);
|
||||
|
||||
+16
-4
@@ -302,6 +302,7 @@ struct SortSubtask {
|
||||
SorterCompare xCompare; /* Compare function to use */
|
||||
SorterFile file; /* Temp file for level-0 PMAs */
|
||||
SorterFile file2; /* Space for other PMAs */
|
||||
u64 nSpill; /* Total bytes written by this task */
|
||||
};
|
||||
|
||||
|
||||
@@ -422,6 +423,7 @@ struct PmaWriter {
|
||||
int iBufEnd; /* Last byte of buffer to write */
|
||||
i64 iWriteOff; /* Offset of start of buffer in file */
|
||||
sqlite3_file *pFd; /* File handle to write to */
|
||||
u64 nPmaSpill; /* Total number of bytes written */
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -1280,6 +1282,12 @@ void sqlite3VdbeSorterClose(sqlite3 *db, VdbeCursor *pCsr){
|
||||
assert( pCsr->eCurType==CURTYPE_SORTER );
|
||||
pSorter = pCsr->uc.pSorter;
|
||||
if( pSorter ){
|
||||
/* Increment db->nSpill by the total number of bytes of data written
|
||||
** to temp files by this sort operation. */
|
||||
int ii;
|
||||
for(ii=0; ii<pSorter->nTask; ii++){
|
||||
db->nSpill += pSorter->aTask[ii].nSpill;
|
||||
}
|
||||
sqlite3VdbeSorterReset(db, pSorter);
|
||||
sqlite3_free(pSorter->list.aMemory);
|
||||
sqlite3DbFree(db, pSorter);
|
||||
@@ -1505,6 +1513,7 @@ static void vdbePmaWriteBlob(PmaWriter *p, u8 *pData, int nData){
|
||||
&p->aBuffer[p->iBufStart], p->iBufEnd - p->iBufStart,
|
||||
p->iWriteOff + p->iBufStart
|
||||
);
|
||||
p->nPmaSpill += (p->iBufEnd - p->iBufStart);
|
||||
p->iBufStart = p->iBufEnd = 0;
|
||||
p->iWriteOff += p->nBuffer;
|
||||
}
|
||||
@@ -1521,17 +1530,20 @@ static void vdbePmaWriteBlob(PmaWriter *p, u8 *pData, int nData){
|
||||
** required. Otherwise, return an SQLite error code.
|
||||
**
|
||||
** Before returning, set *piEof to the offset immediately following the
|
||||
** last byte written to the file.
|
||||
** last byte written to the file. Also, increment (*pnSpill) by the total
|
||||
** number of bytes written to the file.
|
||||
*/
|
||||
static int vdbePmaWriterFinish(PmaWriter *p, i64 *piEof){
|
||||
static int vdbePmaWriterFinish(PmaWriter *p, i64 *piEof, u64 *pnSpill){
|
||||
int rc;
|
||||
if( p->eFWErr==0 && ALWAYS(p->aBuffer) && p->iBufEnd>p->iBufStart ){
|
||||
p->eFWErr = sqlite3OsWrite(p->pFd,
|
||||
&p->aBuffer[p->iBufStart], p->iBufEnd - p->iBufStart,
|
||||
p->iWriteOff + p->iBufStart
|
||||
);
|
||||
p->nPmaSpill += (p->iBufEnd - p->iBufStart);
|
||||
}
|
||||
*piEof = (p->iWriteOff + p->iBufEnd);
|
||||
*pnSpill += p->nPmaSpill;
|
||||
sqlite3_free(p->aBuffer);
|
||||
rc = p->eFWErr;
|
||||
memset(p, 0, sizeof(PmaWriter));
|
||||
@@ -1611,7 +1623,7 @@ static int vdbeSorterListToPMA(SortSubtask *pTask, SorterList *pList){
|
||||
if( pList->aMemory==0 ) sqlite3_free(p);
|
||||
}
|
||||
pList->pList = p;
|
||||
rc = vdbePmaWriterFinish(&writer, &pTask->file.iEof);
|
||||
rc = vdbePmaWriterFinish(&writer, &pTask->file.iEof, &pTask->nSpill);
|
||||
}
|
||||
|
||||
vdbeSorterWorkDebug(pTask, "exit");
|
||||
@@ -1925,7 +1937,7 @@ static int vdbeIncrPopulate(IncrMerger *pIncr){
|
||||
rc = vdbeMergeEngineStep(pIncr->pMerger, &dummy);
|
||||
}
|
||||
|
||||
rc2 = vdbePmaWriterFinish(&writer, &pOut->iEof);
|
||||
rc2 = vdbePmaWriterFinish(&writer, &pOut->iEof, &pTask->nSpill);
|
||||
if( rc==SQLITE_OK ) rc = rc2;
|
||||
vdbeSorterPopulateDebug(pTask, "exit");
|
||||
return rc;
|
||||
|
||||
+5
-5
@@ -26,10 +26,10 @@
|
||||
** a host parameter. If the text contains no host parameters, return
|
||||
** the total number of bytes in the text.
|
||||
*/
|
||||
static int findNextHostParameter(const char *zSql, int *pnToken){
|
||||
static i64 findNextHostParameter(const char *zSql, i64 *pnToken){
|
||||
int tokenType;
|
||||
int nTotal = 0;
|
||||
int n;
|
||||
i64 nTotal = 0;
|
||||
i64 n;
|
||||
|
||||
*pnToken = 0;
|
||||
while( zSql[0] ){
|
||||
@@ -76,8 +76,8 @@ char *sqlite3VdbeExpandSql(
|
||||
sqlite3 *db; /* The database connection */
|
||||
int idx = 0; /* Index of a host parameter */
|
||||
int nextIndex = 1; /* Index of next ? host parameter */
|
||||
int n; /* Length of a token prefix */
|
||||
int nToken; /* Length of the parameter token */
|
||||
i64 n; /* Length of a token prefix */
|
||||
i64 nToken; /* Length of the parameter token */
|
||||
int i; /* Loop counter */
|
||||
Mem *pVar; /* Value of a host parameter */
|
||||
StrAccum out; /* Accumulate the output here */
|
||||
|
||||
@@ -602,7 +602,7 @@ struct WalIterator {
|
||||
|
||||
/* Size (in bytes) of a WalIterator object suitable for N or fewer segments */
|
||||
#define SZ_WALITERATOR(N) \
|
||||
(offsetof(WalIterator,aSegment)*(N)*sizeof(struct WalSegment))
|
||||
(offsetof(WalIterator,aSegment)+(N)*sizeof(struct WalSegment))
|
||||
|
||||
/*
|
||||
** Define the parameters of the hash tables in the wal-index file. There
|
||||
@@ -3488,7 +3488,7 @@ void sqlite3WalEndReadTransaction(Wal *pWal){
|
||||
assert( pWal->writeLock==0 || pWal->readLock<0 );
|
||||
#endif
|
||||
if( pWal->readLock>=0 ){
|
||||
sqlite3WalEndWriteTransaction(pWal);
|
||||
(void)sqlite3WalEndWriteTransaction(pWal);
|
||||
walUnlockShared(pWal, WAL_READ_LOCK(pWal->readLock));
|
||||
pWal->readLock = -1;
|
||||
}
|
||||
@@ -4395,7 +4395,7 @@ int sqlite3WalCheckpoint(
|
||||
sqlite3WalDb(pWal, 0);
|
||||
|
||||
/* Release the locks. */
|
||||
sqlite3WalEndWriteTransaction(pWal);
|
||||
(void)sqlite3WalEndWriteTransaction(pWal);
|
||||
if( pWal->ckptLock ){
|
||||
walUnlockExclusive(pWal, WAL_CKPT_LOCK, 1);
|
||||
pWal->ckptLock = 0;
|
||||
|
||||
@@ -220,4 +220,15 @@ do_test bigrow-5.99 {
|
||||
execsql {DROP TABLE t1}
|
||||
} {}
|
||||
|
||||
if {$SQLITE_MAX_LENGTH > 1200*1000*1000} {
|
||||
# If SQLITE_MAX_LENGTH is large enough, check that a serial type greater
|
||||
# than 0x7FFFFFFF does not cause trouble.
|
||||
set v [string repeat A 1100000000]
|
||||
do_execsql_test bigrow-6.0 {
|
||||
CREATE TABLE docs(content TEXT);
|
||||
INSERT INTO docs VALUES ( $v );
|
||||
}
|
||||
do_execsql_test bigrow-6.1 { SELECT content FROM docs } [list $v]
|
||||
}
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -41,6 +41,10 @@ proc db_spill {db {reset 0}} {
|
||||
sqlite3_db_status $db CACHE_SPILL $reset
|
||||
}
|
||||
|
||||
proc db_temp_spill {db {reset 0}} {
|
||||
sqlite3_db_status $db TEMPBUF_SPILL $reset
|
||||
}
|
||||
|
||||
do_test 1.1 {
|
||||
db close
|
||||
sqlite3 db test.db
|
||||
@@ -111,5 +115,50 @@ do_execsql_test 3.2 {
|
||||
UPDATE t1 SET b=randomblob(1000);
|
||||
} {delete}
|
||||
do_test 3.3 { db_spill db 0 } {0 8 0}
|
||||
|
||||
|
||||
if {$::TEMP_STORE<3} {
|
||||
do_execsql_test 4.0 {
|
||||
PRAGMA temp_store = file;
|
||||
PRAGMA cache_size = -1024;
|
||||
} {}
|
||||
|
||||
do_test 4.1 { db_temp_spill db 0 } {0 0 0}
|
||||
|
||||
do_execsql_test 4.2 {
|
||||
CREATE TABLE data(a INTEGER, b BLOB);
|
||||
|
||||
-- Insert 5-6 MB of data.
|
||||
WITH s(i) AS ( SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<75000 )
|
||||
INSERT INTO data SELECT i, hex(randomblob(50)) FROM s;
|
||||
}
|
||||
|
||||
do_test 4.3 { db_temp_spill db 0 } {0 0 0}
|
||||
|
||||
do_test 4.4 {
|
||||
execsql { SELECT a, b FROM data ORDER BY a }
|
||||
set nTmpSpill [lindex [db_temp_spill db 1] 1]
|
||||
expr {($nTmpSpill>7*1000*1000) && ($nTmpSpill<10*1000*1000)?"ok":$nTmpSpill}
|
||||
} ok
|
||||
|
||||
# The previous test case reset the status value.
|
||||
do_test 4.5 { db_temp_spill db 0 } {0 0 0}
|
||||
|
||||
do_test 4.6 {
|
||||
execsql { CREATE INDEX i1 ON data(a) }
|
||||
set nTmpSpill [lindex [db_temp_spill db 1] 1]
|
||||
expr {($nTmpSpill>384*1000) && ($nTmpSpill<768*1000)?"ok":$nTmpSpill}
|
||||
} ok
|
||||
|
||||
# The previous test case reset the status value.
|
||||
do_test 4.7 { db_temp_spill db 0 } {0 0 0}
|
||||
|
||||
# Same query as in (4.4). Now does not require temp space.
|
||||
do_test 4.8 {
|
||||
execsql { SELECT a, b FROM data ORDER BY a }
|
||||
db_temp_spill db 0
|
||||
} {0 0 0}
|
||||
}
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -144,7 +144,6 @@ foreach op1 $oplist {
|
||||
foreach op {* AND OR + || & |} { unset untested($op,$op) }
|
||||
unset untested(+,-) ;# Since (a+b)-c == a+(b-c)
|
||||
unset untested(*,<<) ;# Since (a*b)<<c == a*(b<<c)
|
||||
foreach op {>> & * <<} {unset untested(AND,$op)}
|
||||
|
||||
do_test e_expr-1.1 { array names untested } {}
|
||||
|
||||
|
||||
@@ -71,6 +71,9 @@ test_expr expr-1.28 {i1=1, i2=2} {i1=2 AND i2=1} {0}
|
||||
test_expr expr-1.29 {i1=1, i2=2} {i1=1 AND i2=1} {0}
|
||||
test_expr expr-1.30 {i1=1, i2=2} {i1=2 AND i2=2} {0}
|
||||
test_expr expr-1.31 {i1=1, i2=2} {i1==1 OR i2=2} {1}
|
||||
test_expr expr-1.31b {i1=1} {0 OR 2} {1}
|
||||
test_expr expr-1.31c {i1=1} {false OR true} {1}
|
||||
test_expr expr-1.31d {i1=1} {99 OR false} {1}
|
||||
test_expr expr-1.32 {i1=1, i2=2} {i1=2 OR i2=1} {0}
|
||||
test_expr expr-1.33 {i1=1, i2=2} {i1=1 OR i2=1} {1}
|
||||
test_expr expr-1.34 {i1=1, i2=2} {i1=2 OR i2=2} {1}
|
||||
|
||||
@@ -29,6 +29,15 @@ do_execsql_test func9-130 {
|
||||
do_execsql_test func9-131 {
|
||||
SELECT concat_ws(',',1,2,3,4,'',6,7,8,NULL,9,10,11,12);
|
||||
} {1,2,3,4,,6,7,8,9,10,11,12}
|
||||
do_execsql_test func9-132 {
|
||||
SELECT concat_ws(',','',2,3,4,'',6,7,8,NULL,9,10,11,12);
|
||||
} {,2,3,4,,6,7,8,9,10,11,12}
|
||||
do_execsql_test func9-133 {
|
||||
SELECT concat_ws(',',NULL,'',3,4,'',6,7,8,NULL,9,10,11,12);
|
||||
} {,3,4,,6,7,8,9,10,11,12}
|
||||
do_execsql_test func9-134 {
|
||||
SELECT concat_ws(',',NULL,NULL,NULL,'',3,4,'',6,7,8,NULL,9,10,11,12);
|
||||
} {,3,4,,6,7,8,9,10,11,12}
|
||||
do_execsql_test func9-140 {
|
||||
SELECT concat_ws(NULL,1,2,3,4,5,6,7,8,NULL,9,10,11,12);
|
||||
} {{}}
|
||||
|
||||
@@ -411,4 +411,67 @@ do_execsql_test 15.2 {
|
||||
SELECT lower(x), quote(y) FROM x1 LEFT JOIN x2 USING (x) JOIN x3 USING (x) FULL JOIN t4;
|
||||
} {abc NULL}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
reset_db
|
||||
do_execsql_test 16.0 {
|
||||
CREATE TABLE t0_a (c0 INT);
|
||||
CREATE TABLE t0_b (c0 INT);
|
||||
|
||||
CREATE TABLE t2 (c0 INT);
|
||||
INSERT INTO t2 VALUES (1);
|
||||
}
|
||||
|
||||
do_execsql_test 16.1 {
|
||||
SELECT * FROM t2 LEFT JOIN t0_b
|
||||
} {1 {}}
|
||||
|
||||
do_execsql_test 16.2.1 {
|
||||
SELECT * FROM (t0_a RIGHT JOIN ( t2 LEFT JOIN t0_b))
|
||||
} {{} 1 {}}
|
||||
do_execsql_test 16.2.2 {
|
||||
SELECT * FROM (t0_a RIGHT JOIN (SELECT * FROM t2 LEFT JOIN t0_b))
|
||||
} {{} 1 {}}
|
||||
|
||||
|
||||
do_catchsql_test 16.3.1 {
|
||||
SELECT * FROM (t0_a RIGHT JOIN ( t2 LEFT JOIN t0_b) USING (c0));
|
||||
} {1 {ambiguous column name: c0}}
|
||||
|
||||
do_execsql_test 16.3.2 {
|
||||
SELECT * FROM (t0_a RIGHT JOIN (SELECT * FROM t2 LEFT JOIN t0_b) USING (c0));
|
||||
} {1 {}}
|
||||
|
||||
do_execsql_test 16.4.0 {
|
||||
CREATE TABLE x0(a TEXT);
|
||||
CREATE TABLE x1(a TEXT);
|
||||
CREATE TABLE x2(a TEXT);
|
||||
|
||||
INSERT INTO x1 VALUES('blue');
|
||||
INSERT INTO x2 VALUES('red');
|
||||
}
|
||||
|
||||
do_catchsql_test 16.4.1 {
|
||||
SELECT * FROM x0 RIGHT JOIN ( x1, x2) USING (a)
|
||||
} {1 {ambiguous column name: a}}
|
||||
|
||||
do_execsql_test 16.4.2 {
|
||||
SELECT * FROM x0 RIGHT JOIN (SELECT * FROM x1, x2) USING (a)
|
||||
} {blue red}
|
||||
|
||||
reset_db
|
||||
do_execsql_test 16.5.0 {
|
||||
CREATE TABLE t0 (c0 INT);
|
||||
CREATE TABLE t1 (c0 INT);
|
||||
CREATE TABLE t2 (c0 INT);
|
||||
|
||||
INSERT INTO t1(c0) VALUES (NULL);
|
||||
INSERT INTO t2 VALUES (1);
|
||||
|
||||
CREATE VIEW v0(c0) AS SELECT 1 AS col_0 FROM t0;
|
||||
}
|
||||
|
||||
do_catchsql_test 16.5.2 {
|
||||
SELECT * FROM (t0 NATURAL RIGHT JOIN (t0 FULL JOIN (v0 NATURAL FULL JOIN t2) ON TRUE)) NATURAL FULL JOIN t1;
|
||||
} {1 {ambiguous column name: c0}}
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -211,4 +211,16 @@ if {[clang_sanitize_address]==0 && 0} {
|
||||
} {1 {(21) bad parameter or other API misuse}}
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
reset_db
|
||||
do_test misuse-6.0 {
|
||||
sqlite3_set_errmsg db 1 "an error has occurred"
|
||||
} {SQLITE_OK}
|
||||
do_test misuse-6.1 {
|
||||
sqlite3_errmsg db
|
||||
} {an error has occurred}
|
||||
do_test misuse-6.2 {
|
||||
sqlite3_set_errmsg "" 1 "an error has occurred"
|
||||
} {SQLITE_MISUSE}
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -155,6 +155,11 @@ int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
|
||||
/* Set a limit on the maximum size of a prepared statement */
|
||||
sqlite3_limit(cx.db, SQLITE_LIMIT_VDBE_OP, 25000);
|
||||
|
||||
/* Set a limit on the maximum LIKE or GLOB pattern length due to
|
||||
** https://issues.oss-fuzz.com/issues/453240497. The default is 50K
|
||||
** which is causing timeouts in OSS-Fuzz */
|
||||
sqlite3_limit(cx.db, SQLITE_LIMIT_LIKE_PATTERN_LENGTH, 250);
|
||||
|
||||
/* Limit total memory available to SQLite to 20MB */
|
||||
sqlite3_hard_heap_limit64(20000000);
|
||||
|
||||
|
||||
@@ -544,4 +544,54 @@ do_catchsql_test 22.1 {
|
||||
} {1 {no such column: sqlite_master.name}}
|
||||
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
reset_db
|
||||
do_execsql_test 23.0 {
|
||||
PRAGMA recursive_triggers = 1;
|
||||
CREATE TABLE t1(x, y);
|
||||
CREATE TRIGGER t1insert AFTER INSERT ON t1 WHEN new.x<5 BEGIN
|
||||
INSERT INTO t1 VALUES(new.x+1, new.y);
|
||||
END;
|
||||
}
|
||||
|
||||
do_execsql_test 23.1 {
|
||||
INSERT INTO t1 VALUES(1, 'one') RETURNING *;
|
||||
} {1 one}
|
||||
|
||||
do_execsql_test 23.2 {
|
||||
SELECT * FROM t1
|
||||
} {1 one 2 one 3 one 4 one 5 one}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
reset_db
|
||||
ifcapable fts5 {
|
||||
|
||||
do_execsql_test 24.0 {
|
||||
CREATE VIRTUAL TABLE ft USING fts5(c);
|
||||
CREATE TABLE t1(x);
|
||||
INSERT INTO t1 VALUES('x');
|
||||
}
|
||||
|
||||
db close
|
||||
|
||||
sqlite3 db test.db
|
||||
sqlite3 db2 test.db
|
||||
|
||||
do_execsql_test 24.1 {
|
||||
SELECT * FROM t1
|
||||
} {x}
|
||||
|
||||
do_execsql_test -db db2 24.2 {
|
||||
CREATE TABLE t2(y);
|
||||
INSERT INTO t2 VALUES('y');
|
||||
} {}
|
||||
|
||||
db2 close
|
||||
|
||||
do_execsql_test 24.3 {
|
||||
INSERT INTO ft VALUES('hello world') RETURNING *
|
||||
} {{hello world}}
|
||||
}
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -945,6 +945,71 @@ do_test shell1-4.1.6 {
|
||||
|
||||
}
|
||||
|
||||
# DELETE content of sqlite_sequence prior to repopulating,
|
||||
# but only if the sqlite_sequence table is non-empty.
|
||||
# Forum: 2024-10-13T17:10:01z and 2025-10-29T19:38:43z
|
||||
#
|
||||
do_test shell1-4.1.7 {
|
||||
db close
|
||||
forcedelete test2.db
|
||||
sqlite3 db test2.db
|
||||
db eval {
|
||||
CREATE TABLE t1(a INTEGER PRIMARY KEY AUTOINCREMENT, b);
|
||||
INSERT INTO t1 VALUES(1,2),(20,21),(15,16);
|
||||
}
|
||||
catchcmd test2.db {.dump}
|
||||
} {0 {PRAGMA foreign_keys=OFF;
|
||||
BEGIN TRANSACTION;
|
||||
CREATE TABLE t1(a INTEGER PRIMARY KEY AUTOINCREMENT, b);
|
||||
INSERT INTO t1 VALUES(1,2);
|
||||
INSERT INTO t1 VALUES(15,16);
|
||||
INSERT INTO t1 VALUES(20,21);
|
||||
PRAGMA writable_schema=ON;
|
||||
CREATE TABLE IF NOT EXISTS sqlite_sequence(name,seq);
|
||||
DELETE FROM sqlite_sequence;
|
||||
INSERT INTO sqlite_sequence VALUES('t1',20);
|
||||
PRAGMA writable_schema=OFF;
|
||||
COMMIT;}}
|
||||
do_test shell1-4.1.8 {
|
||||
db close
|
||||
forcedelete test2.db
|
||||
sqlite3 db test2.db
|
||||
db eval {
|
||||
CREATE TABLE t1(a INTEGER PRIMARY KEY AUTOINCREMENT, b);
|
||||
INSERT INTO t1 VALUES(1,2),(20,21),(15,16);
|
||||
CREATE TABLE t2(x,y);
|
||||
INSERT INTO t2 VALUES(99,88);
|
||||
DROP TABLE t1;
|
||||
}
|
||||
catchcmd test2.db {.dump}
|
||||
} {0 {PRAGMA foreign_keys=OFF;
|
||||
BEGIN TRANSACTION;
|
||||
CREATE TABLE t2(x,y);
|
||||
INSERT INTO t2 VALUES(99,88);
|
||||
COMMIT;}}
|
||||
do_test shell1-4.1.9 {
|
||||
db close
|
||||
forcedelete test2.db
|
||||
sqlite3 db test2.db
|
||||
db eval {
|
||||
CREATE TABLE t1(a INTEGER PRIMARY KEY AUTOINCREMENT, b);
|
||||
INSERT INTO t1 VALUES(1,2),(20,21),(15,16);
|
||||
CREATE TABLE t2(x,y);
|
||||
INSERT INTO t2 VALUES(99,88);
|
||||
INSERT INTO sqlite_sequence VALUES('extra',999);
|
||||
DROP TABLE t1;
|
||||
}
|
||||
catchcmd test2.db {.dump}
|
||||
} {0 {PRAGMA foreign_keys=OFF;
|
||||
BEGIN TRANSACTION;
|
||||
CREATE TABLE t2(x,y);
|
||||
INSERT INTO t2 VALUES(99,88);
|
||||
PRAGMA writable_schema=ON;
|
||||
CREATE TABLE IF NOT EXISTS sqlite_sequence(name,seq);
|
||||
DELETE FROM sqlite_sequence;
|
||||
INSERT INTO sqlite_sequence VALUES('extra',999);
|
||||
PRAGMA writable_schema=OFF;
|
||||
COMMIT;}}
|
||||
|
||||
# Test the output of ".mode insert"
|
||||
#
|
||||
|
||||
+1
-1
@@ -152,6 +152,6 @@ do_test shell4-4.1 {
|
||||
puts $fd ".read t1.txt"
|
||||
close $fd
|
||||
catchcmd ":memory:" ".read t1.txt"
|
||||
} {1 {Input nesting limit (25) reached at line 1. Check recursion.}}
|
||||
} {1 {t1.txt: Input nesting limit (25) reached at line 1. Check recursion.}}
|
||||
|
||||
finish_test
|
||||
|
||||
+1
-1
@@ -116,7 +116,7 @@ for {set i 0} {$i<[llength $argv]} {incr i} {
|
||||
continue
|
||||
}
|
||||
if {[string match CC=* $arg]} {
|
||||
set cc [lrange $arg 3 end]
|
||||
set cc [string range $arg 3 end]
|
||||
continue
|
||||
}
|
||||
if {[string match *.c $arg]} {
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
** 2025-10-14
|
||||
**
|
||||
** 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.
|
||||
**
|
||||
******************************************************************************
|
||||
**
|
||||
** Test the ability of run-time extension loading to use the
|
||||
** very latest interfaces.
|
||||
**
|
||||
** Compile something like this:
|
||||
**
|
||||
** Linux: gcc -g -fPIC shared testloadext.c -o testloadext.so
|
||||
**
|
||||
** Mac: cc -g -fPIC -dynamiclib testloadext.c -o testloadext.dylib
|
||||
**
|
||||
** Win11: cl testloadext.c -link -dll -out:testloadext.dll
|
||||
*/
|
||||
#include "sqlite3ext.h"
|
||||
SQLITE_EXTENSION_INIT1
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
/*
|
||||
** Implementation of the set_errmsg(CODE,MSG) SQL function.
|
||||
**
|
||||
** Raise an error that has numeric code CODE and text message MSG
|
||||
** using the sqlite3_set_errmsg() API.
|
||||
*/
|
||||
static void seterrmsgfunc(
|
||||
sqlite3_context *context,
|
||||
int argc,
|
||||
sqlite3_value **argv
|
||||
){
|
||||
sqlite3 *db;
|
||||
char *zRes;
|
||||
int rc;
|
||||
assert( argc==2 );
|
||||
db = sqlite3_context_db_handle(context);
|
||||
rc = sqlite3_set_errmsg(db,
|
||||
sqlite3_value_int(argv[0]),
|
||||
sqlite3_value_text(argv[1]));
|
||||
zRes = sqlite3_mprintf("%d %d %s",
|
||||
rc, sqlite3_errcode(db), sqlite3_errmsg(db));
|
||||
sqlite3_result_text64(context, zRes, strlen(zRes),
|
||||
SQLITE_TRANSIENT, SQLITE_UTF8);
|
||||
sqlite3_free(zRes);
|
||||
}
|
||||
|
||||
/*
|
||||
** Implementation of the tempbuf_spill() SQL function.
|
||||
**
|
||||
** Return the value of SQLITE_DBSTATUS_TEMPBUF_SPILL.
|
||||
*/
|
||||
static void tempbuf_spill_func(
|
||||
sqlite3_context *context,
|
||||
int argc,
|
||||
sqlite3_value **argv
|
||||
){
|
||||
sqlite3 *db;
|
||||
sqlite3_int64 iHi = 0, iCur = 0;
|
||||
int rc;
|
||||
int bReset;
|
||||
assert( argc==1 );
|
||||
bReset = sqlite3_value_int(argv[0]);
|
||||
db = sqlite3_context_db_handle(context);
|
||||
(void)sqlite3_db_status64(db, SQLITE_DBSTATUS_TEMPBUF_SPILL,
|
||||
&iCur, &iHi, bReset);
|
||||
sqlite3_result_int64(context, iCur);
|
||||
}
|
||||
|
||||
|
||||
#ifdef _WIN32
|
||||
__declspec(dllexport)
|
||||
#endif
|
||||
int sqlite3_testloadext_init(
|
||||
sqlite3 *db,
|
||||
char **pzErrMsg,
|
||||
const sqlite3_api_routines *pApi
|
||||
){
|
||||
int rc = SQLITE_OK;
|
||||
SQLITE_EXTENSION_INIT2(pApi);
|
||||
(void)pzErrMsg; /* Unused parameter */
|
||||
rc = sqlite3_create_function(db, "set_errmsg", 2,
|
||||
SQLITE_UTF8,
|
||||
0, seterrmsgfunc, 0, 0);
|
||||
if( rc ) return rc;
|
||||
rc = sqlite3_create_function(db, "tempbuf_spill", 1,
|
||||
SQLITE_UTF8,
|
||||
0, tempbuf_spill_func, 0, 0);
|
||||
if( rc ) return rc;
|
||||
return SQLITE_OK;
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user