Compare commits
88 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| ccc132c5be | |||
| 5e132e142f | |||
| b9e656f6f7 | |||
| c867ce4b89 | |||
| ceb66403bb | |||
| 6c1aa834f6 | |||
| e7d405200a | |||
| c911dda3d3 | |||
| edec48cd40 | |||
| f7915390d5 | |||
| 42be6fdf22 | |||
| 31a9e5c5d9 | |||
| 0851e6a4fe | |||
| b2543d0098 | |||
| 4902f35e63 | |||
| 2a95fade33 | |||
| 193a8f3673 | |||
| 81ceb00b00 | |||
| 8626a528e1 | |||
| b8c5fe2c19 | |||
| c3a422d794 | |||
| d542c33c9d | |||
| fa5d2efbfc | |||
| c22fe7a31c | |||
| a15c394233 | |||
| d38b6c0a19 | |||
| 600eb440c2 | |||
| e9b5658888 | |||
| e44fc2ba34 | |||
| 18bc656fe1 | |||
| 2e6dc01ea7 | |||
| bf5c8d7d16 | |||
| 48aa50931a | |||
| 9bb1173b4f | |||
| 2b6b982a77 | |||
| 22bce652b3 | |||
| c4a831733f | |||
| 9f426fa956 | |||
| 18bdf31933 | |||
| 2c6e131593 | |||
| f034bd10f0 | |||
| 0d8e4e27b7 | |||
| dfc91368e7 | |||
| d75e0a89ad | |||
| 0d56a90b3d | |||
| 62587d292b | |||
| 4e2383b65b | |||
| 0b223f1027 | |||
| 83f261d5a0 | |||
| 8d36080bd5 | |||
| 1cddaab5f9 | |||
| a66d74e1de | |||
| 574d888a10 | |||
| a523e20bba | |||
| 3580d166e5 | |||
| 1e4ec59e3f | |||
| af24f5e21e | |||
| 7678510ff2 | |||
| 066b667313 | |||
| e0b995b2a6 | |||
| 9db56a4935 | |||
| a5ce91b319 | |||
| 0268517163 | |||
| ccd445d76a | |||
| b14b7681f4 | |||
| 55f2cf294f | |||
| 10305aa4a4 | |||
| 20847aca95 | |||
| e64e95b437 | |||
| 27e808ff2c | |||
| 0e4b46a649 | |||
| 2ba7864bc4 | |||
| 2114d8bbd2 | |||
| 928890f18f | |||
| 7b3ed290d3 | |||
| 002226b549 | |||
| 7ad112014b | |||
| f9c7f9fb52 | |||
| 02bd4aa037 | |||
| 8113b83c01 | |||
| 4c6c2ed134 | |||
| df330b6f92 | |||
| ef152ec09f | |||
| 2c01c19968 | |||
| 81fa34e507 | |||
| 1bb371e6d3 | |||
| 916f74e485 | |||
| 282e2cea0a |
@@ -1,125 +0,0 @@
|
||||
# AGENTS.md
|
||||
|
||||
Guidance for AI coding agents working in this repository.
|
||||
|
||||
## Project nature
|
||||
|
||||
SQLite is a self-contained, serverless SQL database engine written in C. The
|
||||
source is **public domain** — no copyright or license header should ever be
|
||||
added to any file. The blessing comment that appears at the top of each source
|
||||
file is intentional and should be preserved unchanged.
|
||||
|
||||
SQLite does not accept pull requests without prior agreement and/or
|
||||
accompanying legal paperwork that places the pull request in the public domain.
|
||||
However, the human SQLite developers will review a concise and well-written
|
||||
pull request as a proof-of-concept prior to reimplementing the changes
|
||||
themselves.
|
||||
|
||||
SQLite does not accept agentic code. However the project
|
||||
will accept agentic bug reports that include a reproducible test case.
|
||||
Patches or pull requests demonstrating a possible fix, for documentation
|
||||
purposes, are welcomed.
|
||||
|
||||
SQLite uses the [Fossil](https://fossil-scm.org/) for version control,
|
||||
not Git. The canonical repository is at <https://sqlite.org/src>.
|
||||
|
||||
## Build
|
||||
|
||||
The configure script uses [autosetup](https://msteveb.github.io/autosetup/),
|
||||
not GNU Autoconf.
|
||||
|
||||
```bash
|
||||
apt install gcc make tcl-dev # prerequisites (Debian/Ubuntu)
|
||||
|
||||
./configure --dev # debug build
|
||||
make sqlite3 # CLI shell
|
||||
make sqlite3d # Debugging variant of the CLI shell
|
||||
make sqlite3.c # amalgamation (single-file distribution form)
|
||||
make testfixture # test runner binary (requires tcl-dev)
|
||||
make tclextension-install # install TCL extension before running tests
|
||||
```
|
||||
|
||||
## Testing
|
||||
|
||||
Tests are TCL scripts run through the `testfixture` enhanced interpreter.
|
||||
|
||||
```bash
|
||||
# From the build directory:
|
||||
./testfixture test/main.test # single test file
|
||||
test/testrunner.tcl # quick suite
|
||||
test/testrunner.tcl full # full suite
|
||||
test/testrunner.tcl fts5% # pattern match
|
||||
|
||||
# Check for failures:
|
||||
grep '!' testrunner.log
|
||||
```
|
||||
|
||||
`make devtest` is the fastest way to run a representative subset. Always run
|
||||
at least `devtest` after any change to `src/`.
|
||||
|
||||
## Architecture
|
||||
|
||||
SQL text → **tokenizer** (`tokenize.c`) → **parser** (`parse.y` / Lemon) →
|
||||
**code generator** (`build.c`, `select.c`, `insert.c`, `update.c`, `delete.c`,
|
||||
`expr.c`) → **optimizer** (`where*.c`) → **VDBE** (`vdbe.c`) → **B-Tree**
|
||||
(`btree.c`) → **Pager** (`pager.c`) → **WAL** (`wal.c`) → **VFS**
|
||||
(`os_unix.c`, `os_win.c`).
|
||||
|
||||
The master internal header is `src/sqliteInt.h`. Major subsystems have private
|
||||
headers: `vdbeInt.h`, `btreeInt.h`, `whereInt.h`. The public API is defined in
|
||||
`src/sqlite.h.in` (template) which generates `sqlite3.h`.
|
||||
|
||||
## Do not edit generated files
|
||||
|
||||
These files are produced by scripts and must not be edited by hand:
|
||||
|
||||
| File | Regenerate with |
|
||||
|---|---|
|
||||
| `sqlite3.h` | `tool/mksqlite3h.tcl` |
|
||||
| `parse.c`, `parse.h` | build lemon (`tool/lemon.c`) then run on `src/parse.y` |
|
||||
| `opcodes.h` | `tool/mkopcodeh.tcl` (reads `src/vdbe.c`) |
|
||||
| `opcodes.c` | `tool/mkopcodec.tcl` (reads `opcodes.h`) |
|
||||
| `keywordhash.h` | `tool/mkkeywordhash.c` |
|
||||
| `pragma.h` | `tool/mkpragmatab.tcl` |
|
||||
| `sqlite3.c` | `tool/mksqlite3c.tcl` (the amalgamation) |
|
||||
|
||||
Editing rules:
|
||||
- To add a PRAGMA: edit `tool/mkpragmatab.tcl`, then regenerate `pragma.h`.
|
||||
- To add a VDBE opcode: add the `case OP_Xxx:` handler in `src/vdbe.c`; the
|
||||
opcode number and name are extracted automatically by `mkopcodeh.tcl`.
|
||||
- To change the SQL grammar: edit `src/parse.y`, not `parse.c`.
|
||||
|
||||
## Coding conventions
|
||||
|
||||
- C89/C99 compatible C only. No C++, no STL, no exceptions, no VLAs.
|
||||
- All memory allocation goes through `sqlite3Malloc` / `sqlite3_malloc64`
|
||||
(never raw `malloc`). The `sqlite3MallocZero` variant zero-initializes.
|
||||
- Integer widths: use `i64` (`sqlite3_int64`) for 64-bit values, `u32`/`u64`
|
||||
for unsigned. Avoid bare `long` or `int` for values that could exceed 2G.
|
||||
- Error propagation: functions return `SQLITE_OK` (0) on success and a
|
||||
`SQLITE_*` error code on failure. Many routines also set `db->mallocFailed`
|
||||
on OOM, allowing deferred error checking.
|
||||
- Assert liberally for invariants that must hold in correct code; use
|
||||
`ALWAYS(x)` / `NEVER(x)` for conditions that are logically always
|
||||
true/false but that the compiler cannot prove.
|
||||
|
||||
## Extensions (`ext/`)
|
||||
|
||||
Extensions are compiled separately from the core and are not part of the
|
||||
amalgamation by default (except where explicitly included). Major subsystems:
|
||||
|
||||
- `ext/fts5/` — Full-Text Search 5 (current)
|
||||
- `ext/rtree/` — R-Tree spatial indexing
|
||||
- `ext/session/` — Changesets and sessions
|
||||
- `ext/recover/` — Database file recovery
|
||||
- `ext/misc/` — Single-file utility extensions (many included in the CLI)
|
||||
- `ext/qrf/` — Query Result Formatter utility library
|
||||
|
||||
## Useful references
|
||||
|
||||
- Architecture: <https://sqlite.org/arch.html>
|
||||
- File format: <https://sqlite.org/fileformat2.html>
|
||||
- VDBE opcodes: <https://sqlite.org/opcode.html>
|
||||
- Query planner: <https://sqlite.org/optoverview.html>
|
||||
- Lemon parser generator: <https://sqlite.org/doc/trunk/doc/lemon.html>
|
||||
- Compile-time options: <https://sqlite.org/compile.html>
|
||||
@@ -1770,7 +1770,6 @@ FUZZCHECK_SRC = $(FUZZCHECK_SRC) $(TOP)\ext\misc\base64.c
|
||||
FUZZCHECK_SRC = $(FUZZCHECK_SRC) $(TOP)\ext\misc\base85.c
|
||||
FUZZCHECK_SRC = $(FUZZCHECK_SRC) $(TOP)\ext\misc\completion.c
|
||||
FUZZCHECK_SRC = $(FUZZCHECK_SRC) $(TOP)\ext\misc\decimal.c
|
||||
FUZZCHECK_SRC = $(FUZZCHECK_SRC) $(TOP)\ext\misc\diskused.c
|
||||
FUZZCHECK_SRC = $(FUZZCHECK_SRC) $(TOP)\ext\misc\ieee754.c
|
||||
FUZZCHECK_SRC = $(FUZZCHECK_SRC) $(TOP)\ext\misc\randomjson.c
|
||||
FUZZCHECK_SRC = $(FUZZCHECK_SRC) $(TOP)\ext\misc\regexp.c
|
||||
@@ -2345,7 +2344,6 @@ SHELL_DEP = \
|
||||
$(TOP)\ext\misc\base85.c \
|
||||
$(TOP)\ext\misc\completion.c \
|
||||
$(TOP)\ext\misc\decimal.c \
|
||||
$(TOP)\ext\misc\diskused.c \
|
||||
$(TOP)\ext\misc\fileio.c \
|
||||
$(TOP)\ext\misc\ieee754.c \
|
||||
$(TOP)\ext\misc\memtrace.c \
|
||||
@@ -2740,9 +2738,6 @@ rbu.exe: $(TOP)\ext\rbu\rbu.c $(TOP)\ext\rbu\sqlite3rbu.c $(SQLITE3C) $(SQLITE3H
|
||||
$(LTLINK) $(NO_WARN) -DSQLITE_ENABLE_RBU \
|
||||
$(TOP)\ext\rbu\rbu.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
|
||||
|
||||
$(AUXTEST).exe: $(TOP)\test\c\$(AUXTEST).c
|
||||
$(LTLINK) $(NO_WARN) $(TOP)\test\c\$(AUXTEST).c sqlite3.lo /link $(LDFLAGS) $(LTLINKOPTS)
|
||||
|
||||
THREADTEST3_SRC = \
|
||||
$(TOP)\test\threadtest3.c \
|
||||
$(TOP)\test\tt3_checkpoint.c \
|
||||
@@ -2939,5 +2934,4 @@ clean:
|
||||
del /Q fts5.* fts5parse.* 2>NUL
|
||||
del /q src-verify.exe 2>NUL
|
||||
del /q jimsh.exe jimsh0.exe 2>NUL
|
||||
-$(TCLSH_CMD) test/testrunner.tcl clean
|
||||
# <</mark>>
|
||||
|
||||
@@ -33,11 +33,10 @@ verify its integrity, there are hints on how to do that in the
|
||||
|
||||
## Contacting The SQLite Developers
|
||||
|
||||
The preferred way to ask questions or make comments about SQLite is to
|
||||
visit the [SQLite Forum](https://sqlite.org/forum) at
|
||||
<https://sqlite.org/forum/>. Anonymous postings are permitted. For
|
||||
bug reports, please use the [SQLite bugs
|
||||
forum](https://sqlite.org/bugs) at <https://sqlite.org/bugs>.
|
||||
The preferred way to ask questions or make comments about SQLite or to
|
||||
report bugs against SQLite is to visit the
|
||||
[SQLite Forum](https://sqlite.org/forum) at <https://sqlite.org/forum/>.
|
||||
Anonymous postings are permitted.
|
||||
|
||||
If you think you have found a bug that has security implications and
|
||||
you do not want to report it on the public forum, you can send a private
|
||||
@@ -81,8 +80,8 @@ Then run commands like this:
|
||||
fossil open https://sqlite.org/src
|
||||
|
||||
The initial "fossil open" command will take two or three minutes. Afterwards,
|
||||
you can do fast, bandwidth-efficient updates to whatever versions of SQLite you
|
||||
like. Some examples:
|
||||
you can do fast, bandwidth-efficient updates to the whatever versions
|
||||
of SQLite you like. Some examples:
|
||||
|
||||
fossil update trunk ;# latest trunk check-in
|
||||
fossil update release ;# latest official release
|
||||
|
||||
+966
-1651
File diff suppressed because it is too large
Load Diff
+2
-2
@@ -2028,7 +2028,7 @@ array set proj__Cache {}
|
||||
# Returns a cache key for the given argument:
|
||||
#
|
||||
# integer: relative call stack levels to get the scope name of for
|
||||
# use as a key. [proj-scope [expr {1 + $arg + $addLevel}]] is
|
||||
# use as a key. [proj-scope [expr {1 + $arg + addLevel}]] is
|
||||
# then used to generate the key. i.e. the default of 0 uses the
|
||||
# calling scope's name as the key.
|
||||
#
|
||||
@@ -2226,7 +2226,7 @@ proc proj-coalesce {args} {
|
||||
#
|
||||
# Pragmas:
|
||||
#
|
||||
# The prototype list may contain :PRAGMAS to modify how it works. The
|
||||
# Passing :PRAGMAS to this function may modify how it works. The
|
||||
# following pragmas are supported (note the leading ":"):
|
||||
#
|
||||
# :all-flags indicates that the whole input list should be scanned,
|
||||
|
||||
+16
-34
@@ -1067,7 +1067,7 @@ proc sqlite-get-readline-dir-list {} {
|
||||
}
|
||||
*-haiku {
|
||||
lappend dirs /boot/system/develop/headers
|
||||
if {![opt-bool editline] && [opt-val with-readline-ldflags] in {auto ""}} {
|
||||
if {[opt-val with-readline-ldflags] in {auto ""}} {
|
||||
# If the user did not supply their own --with-readline-ldflags
|
||||
# value, hijack that flag to inject options which are known to
|
||||
# work on Haiku OS installations.
|
||||
@@ -1094,30 +1094,16 @@ proc sqlite-get-readline-dir-list {} {
|
||||
# - HAVE_LINENOISE to 0, 1, or 2
|
||||
# - HAVE_EDITLINE to 0 or 1
|
||||
#
|
||||
# Those will be set as follows:
|
||||
#
|
||||
# HAVE_LINENOISE=0, HAVE_EDITLINE=0, HAVE_READLINE=0: no line editing
|
||||
#
|
||||
# HAVE_LINENOISE>0: 1=antirez flavor, 2=msteveb flavor
|
||||
#
|
||||
# HAVE_EDITLINE=0, HAVE_READLINE=1: use GNU readline
|
||||
#
|
||||
# HAVE_EDITLINE=1, HAVE_READLINE=1: use BSD editline header
|
||||
# <readline/readline.h>.
|
||||
#
|
||||
# HAVE_EDITLINE=1, HAVE_READLINE=0: use BSD editline header
|
||||
# <editline/readline.h>.
|
||||
#
|
||||
# Other defines it sets:
|
||||
# Only one of ^^^ those will be set to non-0.
|
||||
#
|
||||
# - LDFLAGS_READLINE = linker flags or empty string
|
||||
#
|
||||
# - CFLAGS_READLINE = compilation flags for clients or empty string.
|
||||
#
|
||||
# Both LDFLAGS_READLINE and CFLAGS_READLINE may refer to linenoise or
|
||||
# editline, not necessarily libreadline. In some cases it will set
|
||||
# HAVE_READLINE=1 when it's really using editline, for reasons
|
||||
# described in this function's comments.
|
||||
# Note that LDFLAGS_READLINE and CFLAGS_READLINE may refer to
|
||||
# linenoise or editline, not necessarily libreadline. In some cases
|
||||
# it will set HAVE_READLINE=1 when it's really using editline, for
|
||||
# reasons described in this function's comments.
|
||||
#
|
||||
# Returns a string describing which line-editing approach to use, or
|
||||
# "none" if no option is available.
|
||||
@@ -1155,7 +1141,7 @@ proc sqlite-check-line-editing {} {
|
||||
# If none of --with-linenoise, --enable-readline, or --enable-editline
|
||||
# are provided, but there exists a directory "linenoise" at $HOME or
|
||||
# a sibling of the build or source directory, then try to use that linenoise
|
||||
# directory.
|
||||
# direcctory.
|
||||
#
|
||||
if {"" eq $dirLn
|
||||
&& ![proj-opt-was-provided readline]
|
||||
@@ -1319,18 +1305,14 @@ proc sqlite-check-line-editing {} {
|
||||
|
||||
# If we found a library, configure the build to use it...
|
||||
if {"" ne $rlLib} {
|
||||
if {"editline" eq $editLibName} {
|
||||
# sqlite-add-shell-opt -DEL_WIDECHAR=1;
|
||||
if {"HAVE_READLINE" eq $editLibDef} {
|
||||
sqlite-add-shell-opt -DHAVE_EDITLINE=1
|
||||
# Alert the user that, despite outward appearances, we won't be
|
||||
# linking to the GPL'd libreadline. Presumably that distinction is
|
||||
# significant for those using --editline.
|
||||
proj-indented-notice {
|
||||
NOTE: the local libedit uses <readline/readline.h> so we
|
||||
will compile with -DHAVE_READLINE=1 but will link with
|
||||
libedit.
|
||||
}
|
||||
if {"editline" eq $editLibName && "HAVE_READLINE" eq $editLibDef} {
|
||||
# Alert the user that, despite outward appearances, we won't be
|
||||
# linking to the GPL'd libreadline. Presumably that distinction is
|
||||
# significant for those using --editline.
|
||||
proj-indented-notice {
|
||||
NOTE: the local libedit uses <readline/readline.h> so we
|
||||
will compile with -DHAVE_READLINE=1 but will link with
|
||||
libedit.
|
||||
}
|
||||
}
|
||||
set rlLib [join $rlLib]
|
||||
@@ -2064,7 +2046,7 @@ proc sqlite-check-tcl {} {
|
||||
}
|
||||
}
|
||||
if {![file-isexec $with_tclsh]} {
|
||||
proj-warn "Cannot find a usable tclsh (tried: $tryThese)"
|
||||
proj-warn "Cannot find a usable tclsh (tried: $tryThese)
|
||||
}
|
||||
}
|
||||
define TCLSH_CMD $with_tclsh
|
||||
|
||||
+1
-6
@@ -33,7 +33,7 @@
|
||||
The testrunner.tcl program is a Tcl script used to run multiple SQLite
|
||||
tests in parallel, thus reducing testing time on multi-core machines.
|
||||
The testrunner.tcl supports running tests that based on `testfixture`,
|
||||
`sqlite3`, `fuzzcheck`, and C programs found in test/c.
|
||||
`sqlite3`, and `fuzzcheck`.
|
||||
|
||||
<a name="runtr"></a>
|
||||
## 1.1 Running testrunner.tcl
|
||||
@@ -59,16 +59,11 @@ up front.
|
||||
The standard Makefiles for SQLite include targets that invoke
|
||||
testrunner.tcl. So the following commands also run testrunner.tcl:
|
||||
|
||||
* `make test`
|
||||
* `make devtest`
|
||||
* `make releasetest`
|
||||
* `make sdevtest`
|
||||
* `make testrunner`
|
||||
|
||||
Since SQLite 3.53.0, there is a "<tt>make.bat</tt>" script in the root
|
||||
of the source tree that causes the "make" command to work on Windows.
|
||||
There is no need to do something different using "nmake" on Windows.
|
||||
|
||||
<a name="outputs"></a>
|
||||
## 1.3 Outputs from testrunner.tcl
|
||||
|
||||
|
||||
@@ -606,40 +606,4 @@ ifcapable fts5 {
|
||||
}
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
reset_db
|
||||
|
||||
set ci {CREATE INDEX i1 ON t1(a COLLATE "binary,sqlite_expert_rem(999,0)");}
|
||||
|
||||
do_execsql_test 8.0 {
|
||||
BEGIN TRANSACTION;
|
||||
CREATE TABLE t1(a TEXT, b TEXT);
|
||||
INSERT INTO t1 VALUES('v0','d0');
|
||||
INSERT INTO t1 VALUES('v1','d1');
|
||||
INSERT INTO t1 VALUES('v2','d2');
|
||||
INSERT INTO t1 VALUES('v3','d3');
|
||||
INSERT INTO t1 VALUES('v4','d4');
|
||||
INSERT INTO t1 VALUES('v5','d5');
|
||||
INSERT INTO t1 VALUES('v6','d6');
|
||||
INSERT INTO t1 VALUES('v7','d7');
|
||||
INSERT INTO t1 VALUES('v8','d8');
|
||||
INSERT INTO t1 VALUES('v9','d9');
|
||||
CREATE INDEX i1 ON t1(a);
|
||||
COMMIT;
|
||||
PRAGMA writable_schema = ON;
|
||||
UPDATE sqlite_schema SET sql = $ci WHERE name = 'i1';
|
||||
}
|
||||
|
||||
db close
|
||||
sqlite3 db test.db
|
||||
|
||||
do_test 8.1 {
|
||||
set expert [sqlite3_expert_new db]
|
||||
$expert sql { SELECT 1234 }
|
||||
list [catch { $expert analyze } msg] $msg
|
||||
} {1 {no such collation sequence: binary,sqlite_expert_rem(999,0)}}
|
||||
|
||||
$expert destroy
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -1501,7 +1501,7 @@ static int idxCreateVtabSchema(sqlite3expert *p, char **pzErrmsg){
|
||||
/* The statement the vtab will pass to sqlite3_declare_vtab() */
|
||||
zInner = idxAppendText(&rc, 0, "CREATE TABLE x(");
|
||||
for(i=0; i<pTab->nCol; i++){
|
||||
zInner = idxAppendText(&rc, zInner, "%s%Q COLLATE %Q",
|
||||
zInner = idxAppendText(&rc, zInner, "%s%Q COLLATE %s",
|
||||
(i==0 ? "" : ", "), pTab->aCol[i].zName, pTab->aCol[i].zColl
|
||||
);
|
||||
}
|
||||
@@ -1701,7 +1701,7 @@ static int idxPopulateOneStat1(
|
||||
return sqlite3_reset(pIndexXInfo);
|
||||
}
|
||||
zCols = idxAppendText(&rc, zCols,
|
||||
"%sx.%Q IS sqlite_expert_rem(%d, x.%Q) COLLATE %Q",
|
||||
"%sx.%Q IS sqlite_expert_rem(%d, x.%Q) COLLATE %s",
|
||||
zComma, zName, nCol, zName, zColl
|
||||
);
|
||||
zOrder = idxAppendText(&rc, zOrder, "%s%d", zComma, ++nCol);
|
||||
|
||||
+2
-7
@@ -2073,13 +2073,8 @@ static void fts3PutDeltaVarint(
|
||||
sqlite3_int64 iVal /* Write this value to the list */
|
||||
){
|
||||
assert_fts3_nc( iVal-*piPrev > 0 || (*piPrev==0 && iVal==0) );
|
||||
if( iVal-(*piPrev)>=0 ){
|
||||
/* Refuse to write a negative delta integer. This only happens with a
|
||||
** corrupt db (see the assert above) and can cause buffer overwrites
|
||||
** in some cases. */
|
||||
*pp += sqlite3Fts3PutVarint(*pp, iVal-*piPrev);
|
||||
*piPrev = iVal;
|
||||
}
|
||||
*pp += sqlite3Fts3PutVarint(*pp, iVal-*piPrev);
|
||||
*piPrev = iVal;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
+10
-9
@@ -132,9 +132,10 @@ struct StrBuffer {
|
||||
/*
|
||||
** Allocate a two-slot MatchinfoBuffer object.
|
||||
*/
|
||||
static MatchinfoBuffer *fts3MIBufferNew(i64 nElem, const char *zMatchinfo){
|
||||
static MatchinfoBuffer *fts3MIBufferNew(size_t nElem, const char *zMatchinfo){
|
||||
MatchinfoBuffer *pRet;
|
||||
sqlite3_int64 nByte = sizeof(u32) * (2*(i64)nElem+1) + SZ_MATCHINFOBUFFER(1);
|
||||
sqlite3_int64 nByte = sizeof(u32) * (2*(sqlite3_int64)nElem + 1)
|
||||
+ SZ_MATCHINFOBUFFER(1);
|
||||
sqlite3_int64 nStr = strlen(zMatchinfo);
|
||||
|
||||
pRet = sqlite3Fts3MallocZero(nByte + nStr+1);
|
||||
@@ -1005,8 +1006,8 @@ static int fts3MatchinfoCheck(
|
||||
return SQLITE_ERROR;
|
||||
}
|
||||
|
||||
static i64 fts3MatchinfoSize(MatchInfo *pInfo, char cArg){
|
||||
i64 nVal; /* Number of integers output by cArg */
|
||||
static size_t fts3MatchinfoSize(MatchInfo *pInfo, char cArg){
|
||||
size_t nVal; /* Number of integers output by cArg */
|
||||
|
||||
switch( cArg ){
|
||||
case FTS3_MATCHINFO_NDOC:
|
||||
@@ -1022,16 +1023,16 @@ static i64 fts3MatchinfoSize(MatchInfo *pInfo, char cArg){
|
||||
break;
|
||||
|
||||
case FTS3_MATCHINFO_LHITS:
|
||||
nVal = (i64)pInfo->nCol * pInfo->nPhrase;
|
||||
nVal = (size_t)pInfo->nCol * pInfo->nPhrase;
|
||||
break;
|
||||
|
||||
case FTS3_MATCHINFO_LHITS_BM:
|
||||
nVal = (i64)pInfo->nPhrase * ((pInfo->nCol + 31) / 32);
|
||||
nVal = (size_t)pInfo->nPhrase * ((pInfo->nCol + 31) / 32);
|
||||
break;
|
||||
|
||||
default:
|
||||
assert( cArg==FTS3_MATCHINFO_HITS );
|
||||
nVal = (i64)pInfo->nCol * pInfo->nPhrase * 3;
|
||||
nVal = (size_t)pInfo->nCol * pInfo->nPhrase * 3;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1313,7 +1314,7 @@ static int fts3MatchinfoValues(
|
||||
|
||||
case FTS3_MATCHINFO_LHITS_BM:
|
||||
case FTS3_MATCHINFO_LHITS: {
|
||||
i64 nZero = fts3MatchinfoSize(pInfo, zArg[i]) * sizeof(u32);
|
||||
size_t nZero = fts3MatchinfoSize(pInfo, zArg[i]) * sizeof(u32);
|
||||
memset(pInfo->aMatchinfo, 0, nZero);
|
||||
rc = fts3ExprLHitGather(pCsr->pExpr, pInfo);
|
||||
break;
|
||||
@@ -1382,7 +1383,7 @@ static void fts3GetMatchinfo(
|
||||
** initialize those elements that are constant for every row.
|
||||
*/
|
||||
if( pCsr->pMIBuffer==0 ){
|
||||
i64 nMatchinfo = 0; /* Number of u32 elements in match-info */
|
||||
size_t nMatchinfo = 0; /* Number of u32 elements in match-info */
|
||||
int i; /* Used to iterate through zArg */
|
||||
|
||||
/* Determine the number of phrases in the query */
|
||||
|
||||
@@ -3129,10 +3129,6 @@ static void fts3ReadEndBlockField(
|
||||
for(/* no-op */; zText[i]>='0' && zText[i]<='9'; i++){
|
||||
iVal = iVal*10 + (zText[i] - '0');
|
||||
}
|
||||
|
||||
/* This if() clause is just to avoid an integer overflow. The record is
|
||||
** corrupt in this case. */
|
||||
if( (i64)iVal==SMALLEST_INT64 ) iMul = 1;
|
||||
*pnByte = ((i64)iVal * (i64)iMul);
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -426,7 +426,7 @@ static void fts5SnippetFunction(
|
||||
int rc = SQLITE_OK; /* Return code */
|
||||
int iCol; /* 1st argument to snippet() */
|
||||
const char *zEllips; /* 4th argument to snippet() */
|
||||
i64 nToken; /* 5th argument to snippet() */
|
||||
int nToken; /* 5th argument to snippet() */
|
||||
int nInst = 0; /* Number of instance matches this row */
|
||||
int i; /* Used to iterate through instances */
|
||||
int nPhrase; /* Number of phrases in query */
|
||||
@@ -451,7 +451,7 @@ static void fts5SnippetFunction(
|
||||
ctx.zClose = fts5ValueToText(apVal[2]);
|
||||
ctx.iRangeEnd = -1;
|
||||
zEllips = fts5ValueToText(apVal[3]);
|
||||
nToken = (int)(MIN( MAX(sqlite3_value_int64(apVal[4]), 0), 64));
|
||||
nToken = sqlite3_value_int(apVal[4]);
|
||||
|
||||
iBestCol = (iCol>=0 ? iCol : 0);
|
||||
nPhrase = pApi->xPhraseCount(pFts);
|
||||
|
||||
@@ -807,7 +807,7 @@ static int fts5ExprNearIsMatch(int *pRc, Fts5ExprNearset *pNear){
|
||||
i64 iPos = a[i].reader.iPos;
|
||||
Fts5PoslistWriter *pWriter = &a[i].writer;
|
||||
if( a[i].pOut->n==0 || iPos!=pWriter->iPrev ){
|
||||
sqlite3Fts5PoslistSafeAppend(a[i].pOut, &pWriter->iPrev, iPos);
|
||||
sqlite3Fts5PoslistWriterAppend(a[i].pOut, pWriter, iPos);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1758,10 +1758,10 @@ static int fts5ParseTokenize(
|
||||
memset(pSyn, 0, (size_t)nByte);
|
||||
pSyn->pTerm = ((char*)pSyn) + sizeof(Fts5ExprTerm) + sizeof(Fts5Buffer);
|
||||
pSyn->nFullTerm = pSyn->nQueryTerm = nToken;
|
||||
memcpy(pSyn->pTerm, pToken, nToken);
|
||||
if( pCtx->pConfig->bTokendata ){
|
||||
pSyn->nQueryTerm = (int)strlen(pSyn->pTerm);
|
||||
}
|
||||
memcpy(pSyn->pTerm, pToken, nToken);
|
||||
pSyn->pSynonym = pPhrase->aTerm[pPhrase->nTerm-1].pSynonym;
|
||||
pPhrase->aTerm[pPhrase->nTerm-1].pSynonym = pSyn;
|
||||
}
|
||||
|
||||
@@ -323,7 +323,7 @@ int sqlite3Fts5HashWrite(
|
||||
** + 5 bytes for the new position offset (32-bit max).
|
||||
*/
|
||||
if( (p->nAlloc - p->nData) < (9 + 4 + 1 + 3 + 5) ){
|
||||
sqlite3_int64 nNew = (i64)p->nAlloc * 2;
|
||||
sqlite3_int64 nNew = p->nAlloc * 2;
|
||||
Fts5HashEntry *pNew;
|
||||
Fts5HashEntry **pp;
|
||||
pNew = (Fts5HashEntry*)sqlite3_realloc64(p, nNew);
|
||||
|
||||
+13
-17
@@ -1695,7 +1695,6 @@ static int fts5DlidxLvlPrev(Fts5DlidxLvl *pLvl){
|
||||
pLvl->bEof = 1;
|
||||
}else{
|
||||
u8 *a = pLvl->pData->p;
|
||||
int nn = pLvl->pData->nn;
|
||||
|
||||
pLvl->iOff = 0;
|
||||
fts5DlidxLvlNext(pLvl);
|
||||
@@ -1704,7 +1703,7 @@ static int fts5DlidxLvlPrev(Fts5DlidxLvl *pLvl){
|
||||
int ii = pLvl->iOff;
|
||||
u64 delta = 0;
|
||||
|
||||
while( ii<nn && a[ii]==0 ){
|
||||
while( a[ii]==0 ){
|
||||
nZero++;
|
||||
ii++;
|
||||
}
|
||||
@@ -2123,7 +2122,7 @@ static void fts5SegIterReverseNewPage(Fts5Index *p, Fts5SegIter *pIter){
|
||||
while( p->rc==SQLITE_OK && pIter->iLeafPgno>pIter->iTermLeafPgno ){
|
||||
Fts5Data *pNew;
|
||||
pIter->iLeafPgno--;
|
||||
pNew = fts5LeafRead(p, FTS5_SEGMENT_ROWID(
|
||||
pNew = fts5DataRead(p, FTS5_SEGMENT_ROWID(
|
||||
pIter->pSeg->iSegid, pIter->iLeafPgno
|
||||
));
|
||||
if( pNew ){
|
||||
@@ -7991,8 +7990,8 @@ static void fts5IndexTombstoneRebuild(
|
||||
){
|
||||
const int MINSLOT = 32;
|
||||
int nSlotPerPage = MAX(MINSLOT, (p->pConfig->pgsz - 8) / szKey);
|
||||
i64 nSlot = 0; /* Number of slots in each output page */
|
||||
i64 nOut = 0;
|
||||
int nSlot = 0; /* Number of slots in each output page */
|
||||
int nOut = 0;
|
||||
|
||||
/* Figure out how many output pages (nOut) and how many slots per
|
||||
** page (nSlot). There are three possibilities:
|
||||
@@ -8017,26 +8016,23 @@ static void fts5IndexTombstoneRebuild(
|
||||
nSlot = MINSLOT;
|
||||
}else if( pSeg->nPgTombstone==1 ){
|
||||
/* Case 2. */
|
||||
u32 nElem = fts5GetU32(&pData1->p[4]);
|
||||
int nElem = (int)fts5GetU32(&pData1->p[4]);
|
||||
assert( pData1 && iPg1==0 );
|
||||
if( nElem>((u32)nSlotPerPage/4) ){
|
||||
nOut = 0;
|
||||
}else{
|
||||
nOut = 1;
|
||||
nSlot = MAX((i64)nElem*4, MINSLOT);
|
||||
}
|
||||
nOut = 1;
|
||||
nSlot = MAX(nElem*4, MINSLOT);
|
||||
if( nSlot>nSlotPerPage ) nOut = 0;
|
||||
}
|
||||
if( nOut==0 ){
|
||||
/* Case 3. */
|
||||
nOut = ((i64)pSeg->nPgTombstone * 2 + 1);
|
||||
nOut = (pSeg->nPgTombstone * 2 + 1);
|
||||
nSlot = nSlotPerPage;
|
||||
}
|
||||
|
||||
/* Allocate the required array and output pages */
|
||||
while( 1 ){
|
||||
int res = 0;
|
||||
i64 ii = 0;
|
||||
i64 szPage = 0;
|
||||
int ii = 0;
|
||||
int szPage = 0;
|
||||
Fts5Data **apOut = 0;
|
||||
|
||||
/* Allocate space for the new hash table */
|
||||
@@ -8574,7 +8570,7 @@ static void fts5IndexIntegrityCheckSegment(
|
||||
/* Check any rowid-less pages that occur before the current leaf. */
|
||||
for(iPg=iPrevLeaf+1; iPg<fts5DlidxIterPgno(pDlidx); iPg++){
|
||||
iKey = FTS5_SEGMENT_ROWID(iSegid, iPg);
|
||||
pLeaf = fts5LeafRead(p, iKey);
|
||||
pLeaf = fts5DataRead(p, iKey);
|
||||
if( pLeaf ){
|
||||
if( fts5LeafFirstRowidOff(pLeaf)!=0 ) FTS5_CORRUPT_ROWID(p, iKey);
|
||||
fts5DataRelease(pLeaf);
|
||||
@@ -8585,7 +8581,7 @@ static void fts5IndexIntegrityCheckSegment(
|
||||
/* Check that the leaf page indicated by the iterator really does
|
||||
** contain the rowid suggested by the same. */
|
||||
iKey = FTS5_SEGMENT_ROWID(iSegid, iPrevLeaf);
|
||||
pLeaf = fts5LeafRead(p, iKey);
|
||||
pLeaf = fts5DataRead(p, iKey);
|
||||
if( pLeaf ){
|
||||
i64 iRowid;
|
||||
int iRowidOff = fts5LeafFirstRowidOff(pLeaf);
|
||||
|
||||
@@ -718,9 +718,9 @@ static int fts5Porter_Ostar(char *zStem, int nStem){
|
||||
for(i=0; i<nStem; i++){
|
||||
bCons = !fts5PorterIsVowel(zStem[i], bCons);
|
||||
assert( bCons==0 || bCons==1 );
|
||||
mask = ((mask << 1) + bCons) & 0x0007;
|
||||
mask = (mask << 1) + bCons;
|
||||
}
|
||||
return (mask==0x0005);
|
||||
return ((mask & 0x0007)==0x0005);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -191,29 +191,6 @@ do_execsql_test 5.6 {
|
||||
SELECT snippet(p1, 0, '[', NULL, '...', 6) FROM p1('x OR ' || x'DB');
|
||||
} {{[x a a a a a...}}
|
||||
|
||||
do_execsql_test 5.7.1 {
|
||||
SELECT snippet(p1, 0, '[', NULL, '...', -2147483647) FROM p1('x OR ' || x'DB')
|
||||
} {{[x...}}
|
||||
do_execsql_test 5.7.2 {
|
||||
SELECT snippet(p1, 0, '[', NULL, '...', -2147483648) FROM p1('x OR ' || x'DB')
|
||||
} {{[x...}}
|
||||
do_execsql_test 5.7.3 {
|
||||
SELECT snippet(p1, 0, '[', NULL, '...', -2147483649) FROM p1('x OR ' || x'DB')
|
||||
} {{[x...}}
|
||||
do_execsql_test 5.7.4 {
|
||||
SELECT snippet(p1, 0, '[', NULL, '...', 0) FROM p1('x OR ' || x'DB')
|
||||
} {{[x...}}
|
||||
|
||||
do_execsql_test 5.8.1 {
|
||||
SELECT snippet(p1, 0, '[', NULL, '...', 2147483647) FROM p1('x OR ' || x'DB')
|
||||
} {{[x a a a a a a a a a a}}
|
||||
do_execsql_test 5.8.2 {
|
||||
SELECT snippet(p1, 0, '[', NULL, '...', 2147483648) FROM p1('x OR ' || x'DB')
|
||||
} {{[x a a a a a a a a a a}}
|
||||
do_execsql_test 5.8.3 {
|
||||
SELECT snippet(p1, 0, '[', NULL, '...', 2147483649) FROM p1('x OR ' || x'DB')
|
||||
} {{[x a a a a a a a a a a}}
|
||||
|
||||
} ;# foreach_detail_mode
|
||||
|
||||
reset_db
|
||||
|
||||
@@ -1,28 +0,0 @@
|
||||
# 2026 June 19
|
||||
#
|
||||
# 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 file implements regression tests for SQLite library. The
|
||||
# focus of this script is testing the FTS5 module.
|
||||
#
|
||||
|
||||
source [file join [file dirname [info script]] fts5_common.tcl]
|
||||
set testprefix fts5bigtok2
|
||||
return_if_no_fts5
|
||||
|
||||
set big [string repeat a 1080000000]
|
||||
do_execsql_test 1.0 {
|
||||
CREATE VIRTUAL TABLE t USING fts5(x);
|
||||
}
|
||||
|
||||
do_catchsql_test 1.1 { INSERT INTO t VALUES($big); } {1 {out of memory}}
|
||||
|
||||
set big {}
|
||||
|
||||
finish_test
|
||||
@@ -124,150 +124,5 @@ do_test 3.1 {
|
||||
set {} {}
|
||||
} {}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
reset_db
|
||||
do_execsql_test 4.0 {
|
||||
CREATE VIRTUAL TABLE t1 USING fts5(content);
|
||||
INSERT INTO t1(t1, rank) VALUES('pgsz', 32);
|
||||
BEGIN;
|
||||
WITH s(i) AS (
|
||||
SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<5000
|
||||
)
|
||||
INSERT INTO t1(content) SELECT 'xyzterm' FROM s;
|
||||
COMMIT;
|
||||
INSERT INTO t1(t1) VALUES('optimize');
|
||||
}
|
||||
|
||||
do_test 4.1 {
|
||||
db eval {
|
||||
SELECT rowid AS a, hex(block) AS block FROM t1_data
|
||||
WHERE ((rowid>>36) & 0x01)==1
|
||||
AND ((rowid>>31) & 0x1F)==0
|
||||
} {
|
||||
set n [string length $block]
|
||||
set block [string range $block 0 11]
|
||||
append block [string repeat "00" [expr ($n/2)-7-2]]
|
||||
append block "8080"
|
||||
db eval {
|
||||
UPDATE t1_data SET block = unhex($block) WHERE rowid = $a
|
||||
}
|
||||
}
|
||||
} {}
|
||||
|
||||
do_catchsql_test 4.2 {
|
||||
SELECT count(*) FROM (
|
||||
SELECT rowid FROM t1 WHERE t1 MATCH 'xyzterm' ORDER BY rowid ASC
|
||||
)
|
||||
} {0 5000}
|
||||
|
||||
do_catchsql_test 4.3 {
|
||||
SELECT count(*) FROM (
|
||||
SELECT rowid FROM t1 WHERE t1 MATCH 'xyzterm' ORDER BY rowid DESC
|
||||
)
|
||||
} {0 4987}
|
||||
|
||||
do_test 4.4 {
|
||||
db eval {
|
||||
SELECT rowid AS a, hex(block) AS block FROM t1_data
|
||||
WHERE ((rowid>>36) & 0x01)==1
|
||||
AND ((rowid>>31) & 0x1F)==0
|
||||
} {
|
||||
set n [string length $block]
|
||||
set block [string range $block 0 $n-5]
|
||||
append block [string repeat "00" 2]
|
||||
db eval {
|
||||
UPDATE t1_data SET block = unhex($block) WHERE rowid = $a
|
||||
}
|
||||
}
|
||||
} {}
|
||||
|
||||
do_catchsql_test 4.5 {
|
||||
SELECT count(*) FROM (
|
||||
SELECT rowid FROM t1 WHERE t1 MATCH 'xyzterm' ORDER BY rowid ASC
|
||||
)
|
||||
} {0 5000}
|
||||
|
||||
do_catchsql_test 4.6 {
|
||||
SELECT count(*) FROM (
|
||||
SELECT rowid FROM t1 WHERE t1 MATCH 'xyzterm' ORDER BY rowid DESC
|
||||
)
|
||||
} {0 4879}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
reset_db
|
||||
|
||||
do_execsql_test 5.0 {
|
||||
CREATE VIRTUAL TABLE t USING fts5(x);
|
||||
INSERT INTO t(t,rank) VALUES('pgsz', 64);
|
||||
WITH s(i) AS (
|
||||
SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<80
|
||||
)
|
||||
INSERT INTO t SELECT 'shared word' || (i%10) || ' shared shared' FROM s;
|
||||
INSERT INTO t(t) VALUES('optimize');
|
||||
}
|
||||
|
||||
set lLeaf [db eval { SELECT id FROM t_data }]
|
||||
db_save_and_close
|
||||
|
||||
foreach leaf $lLeaf {
|
||||
db_restore_and_reopen
|
||||
set leaf [expr $leaf]
|
||||
set hex [db one {
|
||||
SELECT hex(block) FROM t_data WHERE id=$leaf
|
||||
}]
|
||||
|
||||
# Replace the first 4 bytes of each leaf page with the size of the leaf in
|
||||
# bytes plus 50 as a 2 byte integer, followed by 0x7FFF.
|
||||
#
|
||||
set nn [expr [string length $hex]/2]
|
||||
set first "[format %.4x [expr $nn+50]]7FFF"
|
||||
set hex [string replace $hex 0 7 $first]
|
||||
|
||||
db eval { UPDATE t_data SET block=unhex($hex) WHERE id=$leaf }
|
||||
do_test 5.1.$leaf {
|
||||
catchsql {
|
||||
SELECT rowid FROM t WHERE t MATCH 'shared' ORDER BY rowid DESC;
|
||||
}
|
||||
set {} {}
|
||||
} {}
|
||||
|
||||
do_test 5.1.$leaf.2 {
|
||||
catchsql {
|
||||
PRAGMA integrity_check;
|
||||
}
|
||||
set {} {}
|
||||
} {}
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
reset_db
|
||||
|
||||
do_execsql_test 6.0 {
|
||||
CREATE VIRTUAL TABLE t USING fts5(x, content='', contentless_delete=1);
|
||||
INSERT INTO t(rowid,x)
|
||||
VALUES(1,'a b'), (2,'c d'), (3,'e f'), (4,'g h'), (5,'i j');
|
||||
INSERT INTO t(t) VALUES('optimize');
|
||||
DELETE FROM t WHERE rowid=2;
|
||||
}
|
||||
|
||||
do_test 6.1 {
|
||||
db eval {
|
||||
SELECT rowid AS rid, hex(block) AS blk
|
||||
FROM t_data WHERE rowid>1_000_000_000_000
|
||||
} {}
|
||||
|
||||
set blk [string replace $blk 8 15 20000000]
|
||||
execsql {
|
||||
UPDATE t_data SET block = unhex($blk) WHERE rowid=$rid
|
||||
}
|
||||
} {}
|
||||
|
||||
do_execsql_test 6.2 {
|
||||
DELETE FROM t WHERE rowid=3;
|
||||
}
|
||||
|
||||
|
||||
sqlite3_fts5_may_be_corrupt 0
|
||||
finish_test
|
||||
|
||||
|
||||
|
||||
@@ -66,18 +66,5 @@ do_near_test 1.23 "a b c d e f g h i" { NEAR(a+b+c+d i b+c, 4) } 0
|
||||
do_near_test 1.24 "a b c d e f g h i" { NEAR(i a+b+c+d b+c, 5) } 1
|
||||
do_near_test 1.25 "a b c d e f g h i" { NEAR(i a+b+c+d b+c, 4) } 0
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# Check that https://sqlite.org/bugs/forumpost/16bb36f7e8 is fixed.
|
||||
#
|
||||
reset_db
|
||||
do_execsql_test 2.0 {
|
||||
CREATE VIRTUAL TABLE t USING fts5(x, tokenize=trigram);
|
||||
INSERT INTO t
|
||||
VALUES('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa');
|
||||
}
|
||||
|
||||
do_execsql_test 2.1 {
|
||||
SELECT count(*) FROM t WHERE t MATCH 'NEAR(aaa aaa, 4)';
|
||||
} {1}
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -65,13 +65,5 @@ foreach {in out} $test_vocab {
|
||||
incr i
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
reset_db
|
||||
|
||||
do_execsql_test 2.0 {
|
||||
CREATE VIRTUAL TABLE tbl USING fts5(t, tokenize='porter unicode61');
|
||||
INSERT INTO tbl VALUES(' andeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee');
|
||||
}
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -418,34 +418,6 @@ do_execsql_test 7.1.2 {
|
||||
INSERT INTO t2(t2) VALUES('integrity-check');
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
|
||||
reset_db
|
||||
fts5_aux_test_functions db
|
||||
|
||||
proc tcl_create {args} { return "tcl_tokenize" }
|
||||
sqlite3_fts5_create_tokenizer db tcl tcl_create
|
||||
|
||||
proc tcl_tokenize {tflags text} {
|
||||
foreach {w iStart iEnd} [fts5_tokenize_split $text] {
|
||||
sqlite3_fts5_token $w $iStart $iEnd
|
||||
if {$w=="usa"} {
|
||||
sqlite3_fts5_token -colo "united" $iStart $iEnd
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
do_execsql_test 8.0 {
|
||||
CREATE VIRTUAL TABLE t1 USING fts5(x, tokenize='tcl', tokendata=1);
|
||||
INSERT INTO t1 VALUES('usa is great');
|
||||
INSERT INTO t1 VALUES('canada is cool');
|
||||
INSERT INTO t1 VALUES('australia is what matters');
|
||||
}
|
||||
|
||||
do_execsql_test 8.1 {
|
||||
SELECT * FROM t1 WHERE t1 MATCH 'usa*';
|
||||
} {{usa is great}}
|
||||
|
||||
} ;# foreach_detail_mode
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -105,9 +105,6 @@ static const unsigned char icuUtf8Trans1[] = {
|
||||
while( (*zIn & 0xc0)==0x80 ){ \
|
||||
c = (c<<6) + (0x3f & *(zIn++)); \
|
||||
} \
|
||||
if( c<0x80 \
|
||||
|| (c&0xFFFFF800)==0xD800 \
|
||||
|| (c&0xFFFFFFFE)==0xFFFE ){ c = 0xFFFD; } \
|
||||
}
|
||||
|
||||
#define SQLITE_ICU_SKIP_UTF8(zIn) \
|
||||
@@ -519,7 +516,6 @@ static void icuLoadCollation(
|
||||
}
|
||||
sqlite3_result_error(p, sqlite3_str_value(pStr), -1);
|
||||
sqlite3_free(sqlite3_str_finish(pStr));
|
||||
ucol_close(pUCollator);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -1157,7 +1157,7 @@ static int amatchNext(sqlite3_vtab_cursor *cur){
|
||||
#endif
|
||||
nWord = (int)strlen(pWord->zWord+2);
|
||||
if( nWord+20>nBuf ){
|
||||
nBuf = nWord+100;
|
||||
nBuf = (char)(nWord+100);
|
||||
zBuf = sqlite3_realloc64(zBuf, nBuf);
|
||||
if( zBuf==0 ) return SQLITE_NOMEM;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,152 @@
|
||||
/*
|
||||
** 2019-03-30
|
||||
**
|
||||
** 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.
|
||||
**
|
||||
******************************************************************************
|
||||
**
|
||||
** An SQL function that uses the incremental BLOB I/O mechanism of SQLite
|
||||
** to read or write part of a blob. This is intended for debugging use
|
||||
** in the CLI.
|
||||
**
|
||||
** readblob(SCHEMA,TABLE,COLUMN,ROWID,OFFSET,N)
|
||||
**
|
||||
** Returns N bytes of the blob starting at OFFSET.
|
||||
**
|
||||
** writeblob(SCHEMA,TABLE,COLUMN,ROWID,OFFSET,NEWDATA)
|
||||
**
|
||||
** NEWDATA must be a blob. The content of NEWDATA overwrites the
|
||||
** existing BLOB data at SCHEMA.TABLE.COLUMN for row ROWID beginning
|
||||
** at OFFSET bytes into the blob.
|
||||
*/
|
||||
#include "sqlite3ext.h"
|
||||
SQLITE_EXTENSION_INIT1
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
static void readblobFunc(
|
||||
sqlite3_context *context,
|
||||
int argc,
|
||||
sqlite3_value **argv
|
||||
){
|
||||
sqlite3_blob *pBlob = 0;
|
||||
const char *zSchema;
|
||||
const char *zTable;
|
||||
const char *zColumn;
|
||||
sqlite3_int64 iRowid;
|
||||
int iOfst;
|
||||
unsigned char *aData;
|
||||
int nData;
|
||||
sqlite3 *db;
|
||||
int rc;
|
||||
|
||||
zSchema = (const char*)sqlite3_value_text(argv[0]);
|
||||
zTable = (const char*)sqlite3_value_text(argv[1]);
|
||||
if( zTable==0 ){
|
||||
sqlite3_result_error(context, "bad table name", -1);
|
||||
return;
|
||||
}
|
||||
zColumn = (const char*)sqlite3_value_text(argv[2]);
|
||||
if( zTable==0 ){
|
||||
sqlite3_result_error(context, "bad column name", -1);
|
||||
return;
|
||||
}
|
||||
iRowid = sqlite3_value_int64(argv[3]);
|
||||
iOfst = sqlite3_value_int(argv[4]);
|
||||
nData = sqlite3_value_int(argv[5]);
|
||||
if( nData<=0 ) return;
|
||||
aData = sqlite3_malloc64( nData+1 );
|
||||
if( aData==0 ){
|
||||
sqlite3_result_error_nomem(context);
|
||||
return;
|
||||
}
|
||||
db = sqlite3_context_db_handle(context);
|
||||
rc = sqlite3_blob_open(db, zSchema, zTable, zColumn, iRowid, 0, &pBlob);
|
||||
if( rc ){
|
||||
sqlite3_free(aData);
|
||||
sqlite3_result_error(context, "cannot open BLOB pointer", -1);
|
||||
return;
|
||||
}
|
||||
rc = sqlite3_blob_read(pBlob, aData, nData, iOfst);
|
||||
sqlite3_blob_close(pBlob);
|
||||
if( rc ){
|
||||
sqlite3_free(aData);
|
||||
sqlite3_result_error(context, "BLOB read failed", -1);
|
||||
}else{
|
||||
sqlite3_result_blob(context, aData, nData, sqlite3_free);
|
||||
}
|
||||
}
|
||||
|
||||
static void writeblobFunc(
|
||||
sqlite3_context *context,
|
||||
int argc,
|
||||
sqlite3_value **argv
|
||||
){
|
||||
sqlite3_blob *pBlob = 0;
|
||||
const char *zSchema;
|
||||
const char *zTable;
|
||||
const char *zColumn;
|
||||
sqlite3_int64 iRowid;
|
||||
int iOfst;
|
||||
unsigned char *aData;
|
||||
int nData;
|
||||
sqlite3 *db;
|
||||
int rc;
|
||||
|
||||
zSchema = (const char*)sqlite3_value_text(argv[0]);
|
||||
zTable = (const char*)sqlite3_value_text(argv[1]);
|
||||
if( zTable==0 ){
|
||||
sqlite3_result_error(context, "bad table name", -1);
|
||||
return;
|
||||
}
|
||||
zColumn = (const char*)sqlite3_value_text(argv[2]);
|
||||
if( zTable==0 ){
|
||||
sqlite3_result_error(context, "bad column name", -1);
|
||||
return;
|
||||
}
|
||||
iRowid = sqlite3_value_int64(argv[3]);
|
||||
iOfst = sqlite3_value_int(argv[4]);
|
||||
if( sqlite3_value_type(argv[5])!=SQLITE_BLOB ){
|
||||
sqlite3_result_error(context, "6th argument must be a BLOB", -1);
|
||||
return;
|
||||
}
|
||||
nData = sqlite3_value_bytes(argv[5]);
|
||||
aData = (unsigned char *)sqlite3_value_blob(argv[5]);
|
||||
db = sqlite3_context_db_handle(context);
|
||||
rc = sqlite3_blob_open(db, zSchema, zTable, zColumn, iRowid, 1, &pBlob);
|
||||
if( rc ){
|
||||
sqlite3_result_error(context, "cannot open BLOB pointer", -1);
|
||||
return;
|
||||
}
|
||||
rc = sqlite3_blob_write(pBlob, aData, nData, iOfst);
|
||||
sqlite3_blob_close(pBlob);
|
||||
if( rc ){
|
||||
sqlite3_result_error(context, "BLOB write failed", -1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifdef _WIN32
|
||||
__declspec(dllexport)
|
||||
#endif
|
||||
int sqlite3_blobio_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, "readblob", 6, SQLITE_UTF8, 0,
|
||||
readblobFunc, 0, 0);
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = sqlite3_create_function(db, "writeblob", 6, SQLITE_UTF8, 0,
|
||||
writeblobFunc, 0, 0);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
@@ -60,13 +60,6 @@
|
||||
**
|
||||
** SELECT name FROM sqlite_btreeinfo
|
||||
** WHERE type='table' AND NOT hasRowid;
|
||||
**
|
||||
** UNUSED, UNTESTED, UNSUPPORTED
|
||||
**
|
||||
** This extension exists for information and demonstration purposes
|
||||
** only. The developers are not aware of any real-world use of this
|
||||
** extension. The extension has no formal test cases. The developers
|
||||
** do not actively support it.
|
||||
*/
|
||||
#if !defined(SQLITEINT_H)
|
||||
#include "sqlite3ext.h"
|
||||
@@ -293,11 +286,6 @@ static int binfoCompute(sqlite3 *db, int pgno, BinfoCursor *pCsr){
|
||||
pCsr->depth = 1;
|
||||
while(1){
|
||||
sqlite3_bind_int(pStmt, 1, pgno);
|
||||
if( pCsr->depth>25 ){
|
||||
sqlite3_set_errmsg(db, SQLITE_CORRUPT, "btree nested too deep");
|
||||
rc = SQLITE_ERROR;
|
||||
break;
|
||||
}
|
||||
rc = sqlite3_step(pStmt);
|
||||
if( rc!=SQLITE_ROW ){
|
||||
rc = SQLITE_ERROR;
|
||||
|
||||
+2
-7
@@ -547,10 +547,6 @@ static int csvtabConnect(
|
||||
if( nCol<=0 ){
|
||||
csv_errmsg(&sRdr, "column= value must be positive");
|
||||
goto csvtab_connect_error;
|
||||
}else if( nCol>sqlite3_limit(db,SQLITE_LIMIT_COLUMN,-1) ){
|
||||
csv_errmsg(&sRdr, "column= value too big, max %d",
|
||||
sqlite3_limit(db, SQLITE_LIMIT_COLUMN,-1));
|
||||
goto csvtab_connect_error;
|
||||
}
|
||||
}else
|
||||
{
|
||||
@@ -713,9 +709,8 @@ static int csvtabClose(sqlite3_vtab_cursor *cur){
|
||||
static int csvtabOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
|
||||
CsvTable *pTab = (CsvTable*)p;
|
||||
CsvCursor *pCur;
|
||||
sqlite3_int64 nByte = pTab->nCol;
|
||||
assert( pTab->nCol<32768 );
|
||||
nByte = sizeof(*pCur) + (sizeof(char*)+sizeof(i64))*nByte;
|
||||
size_t nByte;
|
||||
nByte = sizeof(*pCur) + (sizeof(char*)+sizeof(i64))*pTab->nCol;
|
||||
pCur = sqlite3_malloc64( nByte );
|
||||
if( pCur==0 ) return SQLITE_NOMEM;
|
||||
memset(pCur, 0, nByte);
|
||||
|
||||
+7
-16
@@ -261,7 +261,7 @@ static void decimal_result(sqlite3_context *pCtx, Decimal *p){
|
||||
sqlite3_result_null(pCtx);
|
||||
return;
|
||||
}
|
||||
z = sqlite3_malloc64( (sqlite3_int64)p->nDigit+8 );
|
||||
z = sqlite3_malloc64( (sqlite3_int64)p->nDigit+4 );
|
||||
if( z==0 ){
|
||||
sqlite3_result_error_nomem(pCtx);
|
||||
return;
|
||||
@@ -299,37 +299,28 @@ static void decimal_result(sqlite3_context *pCtx, Decimal *p){
|
||||
sqlite3_result_text(pCtx, z, i, sqlite3_free);
|
||||
}
|
||||
|
||||
/* Forward declaration */
|
||||
static void decimal_expand(Decimal *p, int nDigit, int nFrac);
|
||||
|
||||
/*
|
||||
** Round a decimal value to N significant digits. N must be positive.
|
||||
*/
|
||||
static void decimal_round(Decimal *p, int N){
|
||||
int i;
|
||||
int nZero; /* Number of leading zeros */
|
||||
int nZero;
|
||||
if( N<1 ) return;
|
||||
if( p==0 ) return;
|
||||
if( p->nDigit<=N ) return;
|
||||
for(nZero=0; nZero<p->nDigit && p->a[nZero]==0; nZero++){}
|
||||
N += nZero;
|
||||
if( p->nDigit<=N ) return;
|
||||
if( p->a[N]>=5 ){
|
||||
/* If all leading digits are 9, increase the number of digits
|
||||
** by adding a new 0 to the front */
|
||||
for(i=0; i<N && p->a[i]==9; i++){}
|
||||
if( i==N ){
|
||||
decimal_expand(p, p->nDigit+1, 0);
|
||||
if( p->oom ) return;
|
||||
}
|
||||
|
||||
/* Do the rounding */
|
||||
if( p->a[N]>4 ){
|
||||
p->a[N-1]++;
|
||||
for(i=N-1; i>0 && p->a[i]>9; i--){
|
||||
p->a[i] = 0;
|
||||
p->a[i-1]++;
|
||||
}
|
||||
assert( p->a[0]<=9 );
|
||||
if( p->a[0]>9 ){
|
||||
p->a[0] = 1;
|
||||
p->nFrac--;
|
||||
}
|
||||
}
|
||||
memset(&p->a[N], 0, p->nDigit - N);
|
||||
}
|
||||
|
||||
@@ -1,847 +0,0 @@
|
||||
/*
|
||||
** 2026-04-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 extension implements an SQL function:
|
||||
**
|
||||
** diskused(X)
|
||||
**
|
||||
** Where X is the schema name (typically 'main'). The output is text
|
||||
** that describes how much filesystem space the various tables and indexes
|
||||
** of the database consume.
|
||||
**
|
||||
** This function is a replacement for the (now deprecated)
|
||||
** "sqlite3_analyzer" utility program. This function is built
|
||||
** into the CLI and is used to implement the ".diskused" command there.
|
||||
*/
|
||||
#include "sqlite3ext.h"
|
||||
SQLITE_EXTENSION_INIT1
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <math.h>
|
||||
|
||||
/*
|
||||
** State information for the analysis
|
||||
*/
|
||||
typedef struct DiskUsed DiskUsed;
|
||||
struct DiskUsed {
|
||||
sqlite3 *db; /* Database connection */
|
||||
sqlite3_context *context; /* SQL function context */
|
||||
sqlite3_str *pOut; /* Write output here */
|
||||
char *zSU; /* Name of the temp.space_used table */
|
||||
const char *zSchema; /* Schema to be analyzed */
|
||||
};
|
||||
|
||||
/*
|
||||
** Free all resources that the DiskUsed object references and
|
||||
** reset the DiskUsed object.
|
||||
**
|
||||
** Call this routine multiple times on the same DiskUsed object
|
||||
** is a harmless no-op, as long as the memory for the object itself
|
||||
** has not been freed.
|
||||
*/
|
||||
static void diskusedReset(DiskUsed *p){
|
||||
if( p->zSU ){
|
||||
char *zSql = sqlite3_mprintf("DROP TABLE temp.%s;", p->zSU);
|
||||
if( zSql ){
|
||||
sqlite3_exec(p->db, zSql, 0, 0, 0);
|
||||
sqlite3_free(zSql);
|
||||
}
|
||||
}
|
||||
sqlite3_str_free(p->pOut);
|
||||
sqlite3_free(p->zSU);
|
||||
memset(p, 0, sizeof(*p));
|
||||
}
|
||||
|
||||
/*
|
||||
** Report an error using formatted text. If zFormat==NULL then report
|
||||
** an OOM error.
|
||||
*/
|
||||
static void diskusedError(DiskUsed *p, const char *zFormat, ...){
|
||||
char *zErr;
|
||||
if( zFormat ){
|
||||
va_list ap;
|
||||
va_start(ap, zFormat);
|
||||
zErr = sqlite3_vmprintf(zFormat, ap);
|
||||
va_end(ap);
|
||||
}else{
|
||||
zErr = 0;
|
||||
}
|
||||
if( zErr==0 ){
|
||||
sqlite3_result_error_nomem(p->context);
|
||||
}else{
|
||||
sqlite3_result_error(p->context, zErr, -1);
|
||||
sqlite3_free(zErr);
|
||||
}
|
||||
diskusedReset(p);
|
||||
}
|
||||
|
||||
/*
|
||||
** Prepare and return an SQL statement.
|
||||
*/
|
||||
static sqlite3_stmt *diskusedVPrep(DiskUsed *p, const char *zFmt, va_list ap){
|
||||
char *zSql;
|
||||
int rc;
|
||||
sqlite3_stmt *pStmt = 0;
|
||||
zSql = sqlite3_vmprintf(zFmt, ap);
|
||||
if( zSql==0 ){ diskusedError(p,0); return 0; }
|
||||
rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
|
||||
if( rc ){
|
||||
diskusedError(p, "SQL parse error: %s\nOriginal SQL: %s",
|
||||
sqlite3_errmsg(p->db), zSql);
|
||||
sqlite3_finalize(pStmt);
|
||||
diskusedReset(p);
|
||||
pStmt = 0;
|
||||
}
|
||||
sqlite3_free(zSql);
|
||||
return pStmt;
|
||||
}
|
||||
static sqlite3_stmt *diskusedPrepare(DiskUsed *p, const char *zFormat, ...){
|
||||
va_list ap;
|
||||
sqlite3_stmt *pStmt = 0;
|
||||
va_start(ap, zFormat);
|
||||
pStmt = diskusedVPrep(p,zFormat,ap);
|
||||
va_end(ap);
|
||||
return pStmt;
|
||||
}
|
||||
|
||||
/*
|
||||
** If rc is something other than SQLITE_DONE or SQLITE_OK, then report
|
||||
** an error and return true.
|
||||
**
|
||||
** If rc is SQLITE_DONE or SQLITE_OK, then return false.
|
||||
**
|
||||
** The prepared statement is closed in either case.
|
||||
*/
|
||||
static int diskusedStmtFinish(DiskUsed *p, int rc, sqlite3_stmt *pStmt){
|
||||
if( rc==SQLITE_DONE ){
|
||||
rc = SQLITE_OK;
|
||||
}
|
||||
if( rc!=SQLITE_OK || (rc = sqlite3_reset(pStmt))!=SQLITE_OK ){
|
||||
diskusedError(p, "SQL run-time error: %s\nOriginal SQL: %s",
|
||||
sqlite3_errmsg(p->db), sqlite3_sql(pStmt));
|
||||
diskusedReset(p);
|
||||
}
|
||||
sqlite3_finalize(pStmt);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
** Run SQL. Return the number of errors.
|
||||
*/
|
||||
static int diskusedSql(DiskUsed *p, const char *zFormat, ...){
|
||||
va_list ap;
|
||||
int rc;
|
||||
sqlite3_stmt *pStmt = 0;
|
||||
va_start(ap, zFormat);
|
||||
pStmt = diskusedVPrep(p,zFormat,ap);
|
||||
va_end(ap);
|
||||
if( pStmt==0 ) return 1;
|
||||
while( (rc = sqlite3_step(pStmt))==SQLITE_ROW ){}
|
||||
if( rc==SQLITE_DONE ){
|
||||
rc = SQLITE_OK;
|
||||
}else{
|
||||
diskusedError(p, "SQL run-time error: %s\nOriginal SQL: %s",
|
||||
sqlite3_errmsg(p->db), sqlite3_sql(pStmt));
|
||||
diskusedReset(p);
|
||||
}
|
||||
sqlite3_finalize(pStmt);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
** Run an SQL query that returns an integer. Write that integer
|
||||
** into *piRes. Return the number of errors.
|
||||
*/
|
||||
static int diskusedSqlInt(
|
||||
DiskUsed *p,
|
||||
sqlite3_int64 *piRes,
|
||||
const char *zFormat, ...
|
||||
){
|
||||
va_list ap;
|
||||
int rc;
|
||||
sqlite3_stmt *pStmt = 0;
|
||||
va_start(ap, zFormat);
|
||||
pStmt = diskusedVPrep(p,zFormat,ap);
|
||||
va_end(ap);
|
||||
if( pStmt==0 ) return 1;
|
||||
rc = sqlite3_step(pStmt);
|
||||
if( rc==SQLITE_ROW ){
|
||||
*piRes = sqlite3_column_int64(pStmt, 0);
|
||||
rc = SQLITE_OK;
|
||||
}else if( rc==SQLITE_DONE ){
|
||||
rc = SQLITE_OK;
|
||||
}else{
|
||||
if( p->db ){
|
||||
/* p->db is NULL if there was some prior error */
|
||||
diskusedError(p, "SQL run-time error: %s\nOriginal SQL: %s",
|
||||
sqlite3_errmsg(p->db), sqlite3_sql(pStmt));
|
||||
}
|
||||
diskusedReset(p);
|
||||
}
|
||||
sqlite3_finalize(pStmt);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
** Add to the output a title line that contains the text determined
|
||||
** by the format string. If the output is initially empty, begin
|
||||
** the title line with "/" so that it forms the beginning of a C-style
|
||||
** comment. Otherwise begin with a new-line. Always finish with a
|
||||
** newline.
|
||||
*/
|
||||
static void diskusedTitle(DiskUsed *p, const char *zFormat, ...){
|
||||
char *zFirst;
|
||||
char *zTitle;
|
||||
size_t nTitle;
|
||||
va_list ap;
|
||||
va_start(ap, zFormat);
|
||||
zTitle = sqlite3_vmprintf(zFormat, ap);
|
||||
va_end(ap);
|
||||
if( zTitle==0 ){
|
||||
diskusedError(p, 0);
|
||||
return;
|
||||
}
|
||||
zFirst = sqlite3_str_length(p->pOut)==0 ? "/" : "\n*";
|
||||
nTitle = strlen(zTitle);
|
||||
if( nTitle>=75 ){
|
||||
sqlite3_str_appendf(p->pOut, "%s** %z\n\n", zFirst, zTitle);
|
||||
}else{
|
||||
int nExtra = 74 - (int)nTitle;
|
||||
sqlite3_str_appendf(p->pOut, "%s** %z %.*c\n\n", zFirst, zTitle,
|
||||
nExtra, '*');
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Add an output line that begins with the zDesc text extended out to
|
||||
** 50 columns with "." characters, and followed by whatever text is
|
||||
** described by zFormat.
|
||||
*/
|
||||
static void diskusedLine(
|
||||
DiskUsed *p, /* DiskUsed context */
|
||||
const char *zDesc, /* Description */
|
||||
const char *zFormat, /* Argument to the description */
|
||||
...
|
||||
){
|
||||
char *zTxt;
|
||||
size_t nDesc;
|
||||
va_list ap;
|
||||
va_start(ap, zFormat);
|
||||
zTxt = sqlite3_vmprintf(zFormat, ap);
|
||||
va_end(ap);
|
||||
if( zTxt==0 ){
|
||||
diskusedError(p, 0);
|
||||
return;
|
||||
}
|
||||
nDesc = zDesc ? strlen(zDesc) : 0;
|
||||
if( nDesc>=50 ){
|
||||
sqlite3_str_appendf(p->pOut, "%s %z", zDesc, zTxt);
|
||||
}else{
|
||||
int nExtra = 50 - (int)nDesc;
|
||||
sqlite3_str_appendf(p->pOut, "%s%.*c %z", zDesc, nExtra, '.', zTxt);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Write a percentage into the output. The number written should show
|
||||
** two or three significant digits, with the decimal point being the fourth
|
||||
** character.
|
||||
*/
|
||||
static void diskusedPercent(DiskUsed *p, double r){
|
||||
char zNum[100];
|
||||
char *zDP;
|
||||
int nLeadingDigit;
|
||||
int sz;
|
||||
sqlite3_snprintf(sizeof(zNum)-5, zNum, r>=10.0 ? "%.3g" :"%.2g", r);
|
||||
sz = (int)strlen(zNum);
|
||||
zDP = strchr(zNum, '.');
|
||||
if( zDP==0 ){
|
||||
memcpy(zNum+sz,".0",3);
|
||||
nLeadingDigit = sz;
|
||||
sz += 2;
|
||||
}else{
|
||||
nLeadingDigit = (int)(zDP - zNum);
|
||||
}
|
||||
if( nLeadingDigit<3 ){
|
||||
sqlite3_str_appendchar(p->pOut, 3-nLeadingDigit, ' ');
|
||||
}
|
||||
sqlite3_str_append(p->pOut, zNum, sz);
|
||||
sqlite3_str_append(p->pOut, "%\n", 2);
|
||||
}
|
||||
|
||||
/*
|
||||
** Create a subreport on a subset of tables and/or indexes.
|
||||
**
|
||||
** The title if the subreport is given by zTitle. zWhere is
|
||||
** a boolean expression that can go in the WHERE clause to select
|
||||
** the relevant rows of the s.zSU table.
|
||||
*/
|
||||
static int diskusedSubreport(
|
||||
DiskUsed *p, /* DiskUsed context */
|
||||
char *zTitle, /* Title for this subreport */
|
||||
char *zWhere, /* WHERE clause for this subreport */
|
||||
sqlite3_int64 pgsz, /* Database page size */
|
||||
sqlite3_int64 nPage /* Number of pages in entire database */
|
||||
){
|
||||
sqlite3_stmt *pStmt; /* Statement to query p->zSU */
|
||||
sqlite3_int64 nentry; /* Number of btree entires */
|
||||
sqlite3_int64 payload; /* Payload in bytes */
|
||||
sqlite3_int64 ovfl_payload; /* overflow payload in bytes */
|
||||
sqlite3_int64 mx_payload; /* largest individual payload */
|
||||
sqlite3_int64 ovfl_cnt; /* Number entries using overflow */
|
||||
sqlite3_int64 leaf_pages; /* Leaf pages */
|
||||
sqlite3_int64 int_pages; /* internal pages */
|
||||
sqlite3_int64 ovfl_pages; /* overflow pages */
|
||||
sqlite3_int64 leaf_unused; /* unused bytes on leaf pages */
|
||||
sqlite3_int64 int_unused; /* unused bytes on internal pages */
|
||||
sqlite3_int64 ovfl_unused; /* unused bytes on overflow pages */
|
||||
sqlite3_int64 int_cell; /* B-tree entries on internal pages */
|
||||
sqlite3_int64 depth; /* btree depth */
|
||||
sqlite3_int64 cnt; /* Number of s.zSU entries that match */
|
||||
sqlite3_int64 storage; /* Total bytes */
|
||||
sqlite3_int64 total_pages; /* Total page count */
|
||||
sqlite3_int64 total_unused; /* Total unused bytes */
|
||||
sqlite3_int64 total_meta; /* Total metadata */
|
||||
int rc;
|
||||
|
||||
if( zTitle==0 || zWhere==0 ){
|
||||
diskusedError(p, 0);
|
||||
return SQLITE_NOMEM;
|
||||
}
|
||||
pStmt = diskusedPrepare(p,
|
||||
"SELECT\n"
|
||||
" sum(if(is_without_rowid OR is_index,nentry,leaf_entries)),\n" /* 0 */
|
||||
" sum(payload),\n" /* 1 */
|
||||
" sum(ovfl_payload),\n" /* 2 */
|
||||
" max(mx_payload),\n" /* 3 */
|
||||
" sum(ovfl_cnt),\n" /* 4 */
|
||||
" sum(leaf_pages),\n" /* 5 */
|
||||
" sum(int_pages),\n" /* 6 */
|
||||
" sum(ovfl_pages),\n" /* 7 */
|
||||
" sum(leaf_unused),\n" /* 8 */
|
||||
" sum(int_unused),\n" /* 9 */
|
||||
" sum(ovfl_unused),\n" /* 10 */
|
||||
" max(depth),\n" /* 11 */
|
||||
" count(*),\n" /* 12 */
|
||||
" sum(int_entries)\n" /* 13 */
|
||||
" FROM temp.%s WHERE %s",
|
||||
p->zSU, zWhere);
|
||||
if( pStmt==0 ) return 1;
|
||||
rc = sqlite3_step(pStmt);
|
||||
if( rc==SQLITE_ROW ){
|
||||
diskusedTitle(p, "%s", zTitle);
|
||||
|
||||
nentry = sqlite3_column_int64(pStmt, 0);
|
||||
payload = sqlite3_column_int64(pStmt, 1);
|
||||
ovfl_payload = sqlite3_column_int64(pStmt, 2);
|
||||
mx_payload = sqlite3_column_int64(pStmt, 3);
|
||||
ovfl_cnt = sqlite3_column_int64(pStmt, 4);
|
||||
leaf_pages = sqlite3_column_int64(pStmt, 5);
|
||||
int_pages = sqlite3_column_int64(pStmt, 6);
|
||||
ovfl_pages = sqlite3_column_int64(pStmt, 7);
|
||||
leaf_unused = sqlite3_column_int64(pStmt, 8);
|
||||
int_unused = sqlite3_column_int64(pStmt, 9);
|
||||
ovfl_unused = sqlite3_column_int64(pStmt, 10);
|
||||
depth = sqlite3_column_int64(pStmt, 11);
|
||||
cnt = sqlite3_column_int64(pStmt, 12);
|
||||
int_cell = sqlite3_column_int64(pStmt, 13);
|
||||
rc = SQLITE_DONE;
|
||||
|
||||
total_pages = leaf_pages + int_pages + ovfl_pages;
|
||||
diskusedLine(p, "Percentage of total database", "%.3g%%\n",
|
||||
(total_pages*100.0)/(double)nPage);
|
||||
diskusedLine(p, "Number of entries", "%lld\n", nentry);
|
||||
storage = total_pages*pgsz;
|
||||
diskusedLine(p, "Bytes of storage consumed", "%lld\n", storage);
|
||||
diskusedLine(p, "Bytes of payload", "%-11lld ", payload);
|
||||
diskusedPercent(p, payload*100.0/(double)storage);
|
||||
if( ovfl_cnt>0 ){
|
||||
diskusedLine(p, "Bytes of payload in overflow","%-11lld ",ovfl_payload);
|
||||
diskusedPercent(p, ovfl_payload*100.0/(double)payload);
|
||||
}
|
||||
total_unused = leaf_unused + int_unused + ovfl_unused;
|
||||
total_meta = storage - payload - total_unused;
|
||||
diskusedLine(p, "Bytes of metadata","%-11lld ", total_meta);
|
||||
diskusedPercent(p, total_meta*100.0/(double)storage);
|
||||
if( cnt==1 ){
|
||||
diskusedLine(p, "B-tree depth", "%lld\n", depth);
|
||||
if( int_cell>1 ){
|
||||
diskusedLine(p, "Average fanout", "%.1f\n",
|
||||
(double)(int_cell+int_pages)/(double)int_pages);
|
||||
}
|
||||
}
|
||||
if( nentry>0 ){
|
||||
diskusedLine(p, "Average payload per entry", "%.1f\n",
|
||||
(double)payload/(double)nentry);
|
||||
diskusedLine(p, "Average unused bytes per entry", "%.1f\n",
|
||||
(double)total_unused/(double)nentry);
|
||||
diskusedLine(p, "Average metadata per entry", "%.1f\n",
|
||||
(double)total_meta/(double)nentry);
|
||||
}
|
||||
diskusedLine(p, "Maximum single-entry payload", "%lld\n", mx_payload);
|
||||
if( nentry>0 ){
|
||||
diskusedLine(p, "Entries that use overflow", "%-11lld ", ovfl_cnt);
|
||||
diskusedPercent(p, ovfl_cnt*100.0/(double)nentry);
|
||||
}
|
||||
if( int_pages>0 ){
|
||||
diskusedLine(p, "Index pages used", "%lld\n", int_pages);
|
||||
}
|
||||
diskusedLine(p, "Primary pages used", "%lld\n", leaf_pages);
|
||||
if( ovfl_cnt ){
|
||||
diskusedLine(p, "Overflow pages used", "%lld\n", ovfl_pages);
|
||||
}
|
||||
diskusedLine(p, "Total pages used", "%lld\n", total_pages);
|
||||
if( int_pages>0 ){
|
||||
diskusedLine(p, "Unused bytes on index pages", "%lld\n", int_unused);
|
||||
}
|
||||
diskusedLine(p, "Unused bytes on primary pages", "%lld\n", leaf_unused);
|
||||
if( ovfl_cnt ){
|
||||
diskusedLine(p, "Unused bytes on overflow pages", "%lld\n", ovfl_unused);
|
||||
}
|
||||
diskusedLine(p, "Unused bytes on all pages", "%-11lld ", total_unused);
|
||||
diskusedPercent(p, total_unused*100.0/(double)storage);
|
||||
}
|
||||
return diskusedStmtFinish(p, rc, pStmt);
|
||||
}
|
||||
|
||||
/*
|
||||
** SQL Function: diskused(SCHEMA)
|
||||
**
|
||||
** Analyze the database schema named in the argument. Return text
|
||||
** containing the space utilization stats.
|
||||
*/
|
||||
static void diskusedFunc(
|
||||
sqlite3_context *context,
|
||||
int argc,
|
||||
sqlite3_value **argv
|
||||
){
|
||||
int rc;
|
||||
sqlite3_stmt *pStmt;
|
||||
int n;
|
||||
sqlite3_int64 ii;
|
||||
sqlite3_int64 pgsz;
|
||||
sqlite3_int64 nPage;
|
||||
sqlite3_int64 nPageInUse;
|
||||
sqlite3_int64 nFreeList;
|
||||
sqlite3_int64 nIndex;
|
||||
sqlite3_int64 nWORowid;
|
||||
DiskUsed s;
|
||||
sqlite3_uint64 r[2];
|
||||
|
||||
(void)argc;
|
||||
memset(&s, 0, sizeof(s));
|
||||
s.db = sqlite3_context_db_handle(context);
|
||||
s.context = context;
|
||||
s.pOut = sqlite3_str_new(0);
|
||||
if( sqlite3_str_errcode(s.pOut) ){
|
||||
diskusedError(&s, 0);
|
||||
return;
|
||||
}
|
||||
s.zSchema = (const char*)sqlite3_value_text(argv[0]);
|
||||
if( s.zSchema==0 ){
|
||||
s.zSchema = "main";
|
||||
}else if( sqlite3_strlike("temp",s.zSchema,0)==0 ){
|
||||
diskusedReset(&s);
|
||||
sqlite3_result_text(context, "cannot analyze \"temp\"",-1,SQLITE_STATIC);
|
||||
return;
|
||||
}
|
||||
ii = 0;
|
||||
rc = diskusedSqlInt(&s,&ii,"SELECT 1 FROM pragma_database_list"
|
||||
" WHERE name=%Q COLLATE nocase",s.zSchema);
|
||||
if( rc || ii==0 ){
|
||||
diskusedReset(&s);
|
||||
sqlite3_result_text(context,"no such database",-1,SQLITE_STATIC);
|
||||
return;
|
||||
}
|
||||
sqlite3_randomness(sizeof(r), &r);
|
||||
s.zSU = sqlite3_mprintf("diskused%016llx%016llx", r[0], r[1]);
|
||||
if( s.zSU==0 ){ diskusedError(&s, 0); return; }
|
||||
|
||||
/* The s.zSU table contains the data used for the analysis.
|
||||
** The table name contains 128-bits of randomness to avoid
|
||||
** collisions with preexisting tables in temp.
|
||||
*/
|
||||
rc = diskusedSql(&s,
|
||||
"CREATE TABLE temp.%s(\n"
|
||||
" name text, -- A table or index\n"
|
||||
" tblname text, -- Table that owns name\n"
|
||||
" is_index boolean, -- TRUE if it is an index\n"
|
||||
" is_without_rowid boolean, -- TRUE if WITHOUT ROWID table\n"
|
||||
" nentry int, -- Number of entries in the BTree\n"
|
||||
" leaf_entries int, -- Number of leaf entries\n"
|
||||
" depth int, -- Depth of the b-tree\n"
|
||||
" payload int, -- Total data stored in this table/index\n"
|
||||
" ovfl_payload int, -- Total data stored on overflow pages\n"
|
||||
" ovfl_cnt int, -- Number of entries that use overflow\n"
|
||||
" mx_payload int, -- Maximum payload size\n"
|
||||
" int_pages int, -- Interior pages used\n"
|
||||
" leaf_pages int, -- Leaf pages used\n"
|
||||
" ovfl_pages int, -- Overflow pages used\n"
|
||||
" int_unused int, -- Unused bytes on interior pages\n"
|
||||
" leaf_unused int, -- Unused bytes on primary pages\n"
|
||||
" ovfl_unused int, -- Unused bytes on overflow pages\n"
|
||||
" int_entries int -- Btree cells on internal pages\n"
|
||||
");",
|
||||
s.zSU
|
||||
);
|
||||
if( rc ) return;
|
||||
|
||||
/* Populate the s.zSU table
|
||||
*/
|
||||
rc = diskusedSql(&s,
|
||||
"WITH\n"
|
||||
" allidx(idxname) AS (\n"
|
||||
" SELECT name FROM \"%w\".sqlite_schema WHERE type='index'\n"
|
||||
" ),\n"
|
||||
" allobj(allname,tblname,isidx,isworowid) AS (\n"
|
||||
" SELECT 'sqlite_schema',\n"
|
||||
" 'sqlite_schema',\n"
|
||||
" 0,\n"
|
||||
" 0\n"
|
||||
" UNION ALL\n"
|
||||
" SELECT name,\n"
|
||||
" tbl_name,\n"
|
||||
" type='index',\n"
|
||||
" EXISTS(SELECT 1\n"
|
||||
" FROM pragma_index_list(sqlite_schema.name,%Q)\n"
|
||||
" WHERE pragma_index_list.origin='pk'\n"
|
||||
" AND pragma_index_list.name NOT IN allidx)\n"
|
||||
" FROM \"%w\".sqlite_schema\n"
|
||||
" )\n"
|
||||
"INSERT INTO temp.%s\n"
|
||||
" SELECT\n"
|
||||
" allname,\n"
|
||||
" tblname,\n"
|
||||
" isidx,\n"
|
||||
" isworowid,\n"
|
||||
" sum(ncell),\n"
|
||||
" sum((pagetype='leaf')*ncell),\n"
|
||||
" max((length(if(path GLOB '*+*','',path))+3)/4),\n"
|
||||
" sum(payload),\n"
|
||||
" sum((pagetype='overflow')*payload),\n"
|
||||
" sum(path GLOB '*+000000'),\n"
|
||||
" max(mx_payload),\n"
|
||||
" sum(pagetype='internal'),\n"
|
||||
" sum(pagetype='leaf'),\n"
|
||||
" sum(pagetype='overflow'),\n"
|
||||
" sum((pagetype='internal')*unused),\n"
|
||||
" sum((pagetype='leaf')*unused),\n"
|
||||
" sum((pagetype='overflow')*unused),\n"
|
||||
" sum(if(pagetype='internal',ncell))\n"
|
||||
" FROM allobj CROSS JOIN dbstat(%Q) \n"
|
||||
" WHERE dbstat.name=allobj.allname\n"
|
||||
" GROUP BY allname;\n",
|
||||
s.zSchema, /* %w.sqlite_schema -- in allidx */
|
||||
s.zSchema, /* pragma_index_list(...,%Q) */
|
||||
s.zSchema, /* %w.sqlite_schema */
|
||||
s.zSU, /* INTO temp.%s */
|
||||
s.zSchema /* JOIN dbstat(%Q) */
|
||||
);
|
||||
if( rc ) return;
|
||||
|
||||
nPage = 0;
|
||||
rc = diskusedSqlInt(&s, &nPage, "PRAGMA \"%w\".page_count", s.zSchema);
|
||||
if( rc ) return;
|
||||
if( nPage<=0 ){
|
||||
/* Very brief reply for an empty database */
|
||||
diskusedReset(&s);
|
||||
sqlite3_result_text(context, "empty database", -1, SQLITE_STATIC);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Begin generating the report */
|
||||
diskusedTitle(&s, "Database storage utilization report");
|
||||
pgsz = 0;
|
||||
rc = diskusedSqlInt(&s, &pgsz, "PRAGMA \"%w\".page_size", s.zSchema);
|
||||
if( rc ) return;
|
||||
diskusedLine(&s, "Page size in bytes","%lld\n",pgsz);
|
||||
diskusedLine(&s, "Pages in the database", "%lld\n", nPage);
|
||||
|
||||
nPageInUse = 0;
|
||||
rc = diskusedSqlInt(&s, &nPageInUse,
|
||||
"SELECT sum(leaf_pages+int_pages+ovfl_pages) FROM temp.%s", s.zSU);
|
||||
if( rc ) return;
|
||||
diskusedLine(&s, "Pages that store data", "%-11lld ", nPageInUse);
|
||||
diskusedPercent(&s, (nPageInUse*100.0)/(double)nPage);
|
||||
|
||||
nFreeList = 0;
|
||||
rc = diskusedSqlInt(&s, &nFreeList, "PRAGMA \"%w\".freelist_count",s.zSchema);
|
||||
if( rc ) return;
|
||||
diskusedLine(&s, "Pages on the freelist", "%-11lld ", nFreeList);
|
||||
diskusedPercent(&s, (nFreeList*100.0)/(double)nPage);
|
||||
|
||||
ii = 0;
|
||||
rc = diskusedSqlInt(&s, &ii, "PRAGMA \"%w\".auto_vacuum", s.zSchema);
|
||||
if( rc ) return;
|
||||
if( ii==0 || nPage<=1 ){
|
||||
ii = 0;
|
||||
}else{
|
||||
double rPtrsPerPage = pgsz/5;
|
||||
double rAvPage = (nPage-1.0)/(rPtrsPerPage+1.0);
|
||||
ii = (sqlite3_int64)ceil(rAvPage);
|
||||
}
|
||||
diskusedLine(&s, "Pages of auto-vacuum overhead", "%-11lld ", ii);
|
||||
diskusedPercent(&s, (ii*100.0)/(double)nPage);
|
||||
|
||||
ii = 0;
|
||||
rc = diskusedSqlInt(&s, &ii,
|
||||
"SELECT count(*)+1 FROM \"%w\".sqlite_schema WHERE type='table'",
|
||||
s.zSchema);
|
||||
if( rc ) return;
|
||||
diskusedLine(&s, "Number of tables", "%lld\n", ii);
|
||||
nWORowid = 0;
|
||||
rc = diskusedSqlInt(&s, &nWORowid,
|
||||
"SELECT count(*) FROM \"%w\".pragma_table_list WHERE wr",
|
||||
s.zSchema);
|
||||
if( rc ) return;
|
||||
if( nWORowid>0 ){
|
||||
diskusedLine(&s, "Number of WITHOUT ROWID tables", "%lld\n", nWORowid);
|
||||
diskusedLine(&s, "Number of rowid tables", "%lld\n", ii - nWORowid);
|
||||
}
|
||||
nIndex = 0;
|
||||
rc = diskusedSqlInt(&s, &nIndex,
|
||||
"SELECT count(*) FROM \"%w\".sqlite_schema WHERE type='index'",
|
||||
s.zSchema);
|
||||
if( rc ) return;
|
||||
diskusedLine(&s, "Number of indexes", "%lld\n", nIndex);
|
||||
ii = 0;
|
||||
rc = diskusedSqlInt(&s, &ii,
|
||||
"SELECT count(*) FROM \"%w\".sqlite_schema"
|
||||
" WHERE name GLOB 'sqlite_autoindex_*' AND type='index'",
|
||||
s.zSchema);
|
||||
if( rc ) return;
|
||||
diskusedLine(&s, "Number of defined indexes", "%lld\n", nIndex - ii);
|
||||
diskusedLine(&s, "Number of implied indexes", "%lld\n", ii);
|
||||
diskusedLine(&s, "Size of the database in bytes", "%lld\n", pgsz*nPage);
|
||||
ii = 0;
|
||||
rc = diskusedSqlInt(&s, &ii,
|
||||
"SELECT sum(payload) FROM temp.%s"
|
||||
" WHERE NOT is_index AND name NOT LIKE 'sqlite_schema'",
|
||||
s.zSU);
|
||||
if( rc ) return;
|
||||
diskusedLine(&s, "Bytes of payload", "%-11lld ", ii);
|
||||
diskusedPercent(&s, ii*100.0/(double)(pgsz*nPage));
|
||||
|
||||
diskusedTitle(&s, "Page counts for all tables with their indexes");
|
||||
pStmt = diskusedPrepare(&s,
|
||||
"SELECT upper(tblname),\n"
|
||||
" sum(int_pages+leaf_pages+ovfl_pages)\n"
|
||||
" FROM temp.%s\n"
|
||||
" WHERE tblname IS NOT NULL\n"
|
||||
" GROUP BY 1\n"
|
||||
" ORDER BY 2 DESC, 1;",
|
||||
s.zSU);
|
||||
if( pStmt==0 ) return;
|
||||
while( (rc = sqlite3_step(pStmt))==SQLITE_ROW ){
|
||||
sqlite3_int64 nn = sqlite3_column_int64(pStmt,1);
|
||||
diskusedLine(&s, (const char*)sqlite3_column_text(pStmt,0), "%-11lld ", nn);
|
||||
diskusedPercent(&s, (nn*100.0)/(double)nPage);
|
||||
}
|
||||
if( diskusedStmtFinish(&s, rc, pStmt) ) return;
|
||||
|
||||
diskusedTitle(&s, "Page counts for all tables and indexes separately");
|
||||
pStmt = diskusedPrepare(&s,
|
||||
"SELECT upper(name),\n"
|
||||
" sum(int_pages+leaf_pages+ovfl_pages)\n"
|
||||
" FROM temp.%s\n"
|
||||
" WHERE name IS NOT NULL\n"
|
||||
" GROUP BY 1\n"
|
||||
" ORDER BY 2 DESC, 1;",
|
||||
s.zSU);
|
||||
if( pStmt==0 ) return;
|
||||
while( (rc = sqlite3_step(pStmt))==SQLITE_ROW ){
|
||||
sqlite3_int64 nn = sqlite3_column_int64(pStmt,1);
|
||||
diskusedLine(&s, (const char*)sqlite3_column_text(pStmt,0), "%-11lld ", nn);
|
||||
diskusedPercent(&s, (nn*100.0)/(double)nPage);
|
||||
}
|
||||
if( diskusedStmtFinish(&s, rc, pStmt) ) return;
|
||||
|
||||
rc = diskusedSubreport(&s, "All tables and indexes", "1", pgsz, nPage);
|
||||
if( rc ) return;
|
||||
rc = diskusedSubreport(&s, "All tables", "NOT is_index", pgsz, nPage);
|
||||
if( rc ) return;
|
||||
if( nWORowid>0 ){
|
||||
rc = diskusedSubreport(&s, "All WITHOUT ROWID tables", "is_without_rowid",
|
||||
pgsz, nPage);
|
||||
if( rc ) return;
|
||||
rc = diskusedSubreport(&s, "All rowid tables",
|
||||
"NOT is_without_rowid AND NOT is_index",
|
||||
pgsz, nPage);
|
||||
if( rc ) return;
|
||||
}
|
||||
rc = diskusedSubreport(&s, "All indexes", "is_index", pgsz, nPage);
|
||||
if( rc ) return;
|
||||
|
||||
pStmt = diskusedPrepare(&s,
|
||||
"SELECT upper(tblname), tblname, sum(is_index) FROM temp.%s"
|
||||
" GROUP BY 1 ORDER BY 1",
|
||||
s.zSU);
|
||||
if( pStmt==0 ) return;
|
||||
while( (rc = sqlite3_step(pStmt))==SQLITE_ROW ){
|
||||
const char *zUpper = (const char*)sqlite3_column_text(pStmt, 0);
|
||||
const char *zName = (const char*)sqlite3_column_text(pStmt, 1);
|
||||
int nSubIndex = sqlite3_column_int(pStmt, 2);
|
||||
if( nSubIndex==0 ){
|
||||
char *zTitle = sqlite3_mprintf("Table %s", zUpper);
|
||||
char *zWhere = sqlite3_mprintf("name=%Q", zName);
|
||||
rc = diskusedSubreport(&s, zTitle, zWhere, pgsz, nPage);
|
||||
sqlite3_free(zTitle);
|
||||
sqlite3_free(zWhere);
|
||||
if( rc ) break;
|
||||
}else{
|
||||
sqlite3_stmt *pS2;
|
||||
char *zTitle = sqlite3_mprintf("Table %s and all its indexes", zUpper);
|
||||
char *zWhere = sqlite3_mprintf("tblname=%Q", zName);
|
||||
rc = diskusedSubreport(&s, zTitle, zWhere, pgsz, nPage);
|
||||
sqlite3_free(zTitle);
|
||||
sqlite3_free(zWhere);
|
||||
if( rc ) break;
|
||||
zTitle = sqlite3_mprintf("Table %s w/o any indexes", zUpper);
|
||||
zWhere = sqlite3_mprintf("name=%Q", zName);
|
||||
rc = diskusedSubreport(&s, zTitle, zWhere, pgsz, nPage);
|
||||
sqlite3_free(zTitle);
|
||||
sqlite3_free(zWhere);
|
||||
if( rc ) break;
|
||||
if( nSubIndex>1 ){
|
||||
zTitle = sqlite3_mprintf("All indexes of table %s", zUpper);
|
||||
zWhere = sqlite3_mprintf("tblname=%Q AND is_index", zName);
|
||||
rc = diskusedSubreport(&s, zTitle, zWhere, pgsz, nPage);
|
||||
sqlite3_free(zTitle);
|
||||
sqlite3_free(zWhere);
|
||||
if( rc ) break;
|
||||
}
|
||||
pS2 = diskusedPrepare(&s,
|
||||
"SELECT name, upper(name) FROM temp.%s"
|
||||
" WHERE is_index AND tblname=%Q",
|
||||
s.zSU, zName);
|
||||
if( pS2==0 ){
|
||||
rc = SQLITE_NOMEM;
|
||||
break;
|
||||
}
|
||||
while( (rc = sqlite3_step(pS2))==SQLITE_ROW ){
|
||||
const char *zU = (const char*)sqlite3_column_text(pS2, 1);
|
||||
const char *zN = (const char*)sqlite3_column_text(pS2, 0);
|
||||
zTitle = sqlite3_mprintf("Index %s", zU);
|
||||
zWhere = sqlite3_mprintf("name=%Q", zN);
|
||||
rc = diskusedSubreport(&s, zTitle, zWhere, pgsz, nPage);
|
||||
sqlite3_free(zTitle);
|
||||
sqlite3_free(zWhere);
|
||||
if( rc ) break;
|
||||
}
|
||||
rc = diskusedStmtFinish(&s, rc, pS2);
|
||||
if( rc ) break;
|
||||
}
|
||||
}
|
||||
if( diskusedStmtFinish(&s, rc, pStmt) ) return;
|
||||
|
||||
/* Append SQL statements that will recreate the raw data used for
|
||||
** the analysis.
|
||||
*/
|
||||
diskusedTitle(&s, "Raw data used to generate this report");
|
||||
sqlite3_str_appendf(s.pOut,
|
||||
"The following SQL will create a table named \"space_used\" which\n"
|
||||
"contains most of the information used to generate the report above.\n"
|
||||
"*/\n"
|
||||
);
|
||||
sqlite3_str_appendf(s.pOut,
|
||||
"BEGIN;\n"
|
||||
"CREATE TABLE space_used(\n"
|
||||
" name text, -- A table or index\n" /* 0 */
|
||||
" tblname text, -- Table that owns name\n" /* 1 */
|
||||
" is_index boolean, -- TRUE if it is an index\n" /* 2 */
|
||||
" is_without_rowid boolean, -- TRUE if WITHOUT ROWID table\n" /* 3 */
|
||||
" nentry int, -- Number of entries in the BTree\n" /* 4 */
|
||||
" leaf_entries int, -- Number of leaf entries\n" /* 5 */
|
||||
" depth int, -- Depth of the b-tree\n" /* 6 */
|
||||
" payload int, -- Total data in this table/index\n" /* 7 */
|
||||
" ovfl_payload int, -- Total data on overflow pages\n" /* 8 */
|
||||
" ovfl_cnt int, -- Entries that use overflow\n" /* 9 */
|
||||
" mx_payload int, -- Maximum payload size\n" /* 10 */
|
||||
" int_pages int, -- Interior pages used\n" /* 11 */
|
||||
" leaf_pages int, -- Leaf pages used\n" /* 12 */
|
||||
" ovfl_pages int, -- Overflow pages used\n" /* 13 */
|
||||
" int_unused int, -- Unused bytes on interior pages\n" /* 14 */
|
||||
" leaf_unused int, -- Unused bytes on primary pages\n" /* 15 */
|
||||
" ovfl_unused int, -- Unused bytes on overflow pages\n" /* 16 */
|
||||
" int_entries int -- B-tree entries on internal pages\n"/* 17 */
|
||||
");\n"
|
||||
"INSERT INTO space_used VALUES\n"
|
||||
);
|
||||
pStmt = diskusedPrepare(&s,
|
||||
"SELECT quote(name), quote(tblname),\n" /* 0..1 */
|
||||
" is_index, is_without_rowid, nentry, leaf_entries,\n" /* 2..5 */
|
||||
" depth, payload, ovfl_payload, ovfl_cnt, mx_payload,\n" /* 6..10 */
|
||||
" int_pages, leaf_pages, ovfl_pages, int_unused,\n" /* 11..14 */
|
||||
" leaf_unused, ovfl_unused, int_entries\n" /* 15..17 */
|
||||
" FROM temp.%s;",
|
||||
s.zSU);
|
||||
if( pStmt==0 ) return;
|
||||
n = 0;
|
||||
while( (rc = sqlite3_step(pStmt))==SQLITE_ROW ){
|
||||
if( n++ ) sqlite3_str_appendf(s.pOut,",\n");
|
||||
sqlite3_str_appendf(s.pOut,
|
||||
" (%s,%s,%lld,%lld,%lld,%lld,%lld,%lld,%lld,"
|
||||
"%lld,%lld,%lld,%lld,%lld,%lld,%lld,%lld,%lld)",
|
||||
sqlite3_column_text(pStmt, 0),
|
||||
sqlite3_column_text(pStmt, 1),
|
||||
sqlite3_column_int64(pStmt, 2),
|
||||
sqlite3_column_int64(pStmt, 3),
|
||||
sqlite3_column_int64(pStmt, 4),
|
||||
sqlite3_column_int64(pStmt, 5),
|
||||
sqlite3_column_int64(pStmt, 6),
|
||||
sqlite3_column_int64(pStmt, 7),
|
||||
sqlite3_column_int64(pStmt, 8),
|
||||
sqlite3_column_int64(pStmt, 9),
|
||||
sqlite3_column_int64(pStmt, 10),
|
||||
sqlite3_column_int64(pStmt, 11),
|
||||
sqlite3_column_int64(pStmt, 12),
|
||||
sqlite3_column_int64(pStmt, 13),
|
||||
sqlite3_column_int64(pStmt, 14),
|
||||
sqlite3_column_int64(pStmt, 15),
|
||||
sqlite3_column_int64(pStmt, 16),
|
||||
sqlite3_column_int64(pStmt, 17));
|
||||
}
|
||||
if( rc!=SQLITE_DONE ){
|
||||
diskusedError(&s, "SQL run-time error: %s\nSQL: %s",
|
||||
sqlite3_errmsg(s.db), sqlite3_sql(pStmt));
|
||||
sqlite3_finalize(pStmt);
|
||||
return;
|
||||
}
|
||||
sqlite3_str_appendf(s.pOut,";\nCOMMIT;");
|
||||
sqlite3_finalize(pStmt);
|
||||
|
||||
if( sqlite3_str_length(s.pOut) ){
|
||||
sqlite3_result_text(context, sqlite3_str_finish(s.pOut), -1,
|
||||
sqlite3_free);
|
||||
s.pOut = 0;
|
||||
}
|
||||
diskusedReset(&s);
|
||||
}
|
||||
|
||||
|
||||
#ifdef _WIN32
|
||||
__declspec(dllexport)
|
||||
#endif
|
||||
int sqlite3_diskused_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, "diskused", 1,
|
||||
SQLITE_UTF8|SQLITE_INNOCUOUS,
|
||||
0, diskusedFunc, 0, 0);
|
||||
return rc;
|
||||
}
|
||||
+9
-66
@@ -97,6 +97,8 @@ SQLITE_EXTENSION_INIT1
|
||||
# define STRUCT_STAT struct _stat
|
||||
# define chmod(path,mode) fileio_chmod(path,mode)
|
||||
# define mkdir(path,mode) fileio_mkdir(path)
|
||||
extern LPWSTR sqlite3_win32_utf8_to_unicode(const char*);
|
||||
extern char *sqlite3_win32_unicode_to_utf8(LPCWSTR);
|
||||
#endif
|
||||
#include <time.h>
|
||||
#include <errno.h>
|
||||
@@ -123,69 +125,13 @@ SQLITE_EXTENSION_INIT1
|
||||
#define FSDIR_COLUMN_PATH 5 /* Path to top of search */
|
||||
#define FSDIR_COLUMN_DIR 6 /* Path is relative to this directory */
|
||||
|
||||
#ifdef _WIN32
|
||||
/*
|
||||
** Convert a UTF-8 string to Microsoft Unicode.
|
||||
**
|
||||
** Space to hold the returned string is obtained from sqlite3_malloc().
|
||||
*/
|
||||
static wchar_t *winUtf8To16(const char *zText){
|
||||
int nChar;
|
||||
wchar_t *zWideText;
|
||||
|
||||
nChar = MultiByteToWideChar(CP_UTF8, 0, zText, -1, NULL, 0);
|
||||
if( nChar==0 ){
|
||||
return 0;
|
||||
}
|
||||
zWideText = sqlite3_malloc64(nChar*sizeof(WCHAR) );
|
||||
if( zWideText==0 ){
|
||||
return 0;
|
||||
}
|
||||
nChar = MultiByteToWideChar(CP_UTF8, 0, zText, -1, zWideText,
|
||||
nChar);
|
||||
if( nChar==0 ){
|
||||
sqlite3_free(zWideText);
|
||||
zWideText = 0;
|
||||
}
|
||||
return zWideText;
|
||||
}
|
||||
#endif /* _WIN32 */
|
||||
|
||||
#ifdef _WIN32
|
||||
/*
|
||||
** Convert a Microsoft Unicode string to UTF-8.
|
||||
**
|
||||
** Space to hold the returned string is obtained from sqlite3_malloc().
|
||||
*/
|
||||
static char *winUtf16To8(wchar_t *zWideText){
|
||||
int nByte;
|
||||
char *zText;
|
||||
|
||||
nByte = WideCharToMultiByte(CP_UTF8, 0, zWideText, -1, 0, 0, 0, 0);
|
||||
if( nByte == 0 ){
|
||||
return 0;
|
||||
}
|
||||
zText = sqlite3_malloc64( nByte );
|
||||
if( zText==0 ){
|
||||
return 0;
|
||||
}
|
||||
nByte = WideCharToMultiByte(CP_UTF8, 0, zWideText, -1, zText, nByte,
|
||||
0, 0);
|
||||
if( nByte == 0 ){
|
||||
sqlite3_free(zText);
|
||||
zText = 0;
|
||||
}
|
||||
return zText;
|
||||
}
|
||||
#endif /* _WIN32 */
|
||||
|
||||
/*
|
||||
** UTF8 chmod() function for Windows
|
||||
*/
|
||||
#if defined(_WIN32) || defined(WIN32)
|
||||
static int fileio_chmod(const char *zPath, int pmode){
|
||||
int rc;
|
||||
wchar_t *b1 = winUtf8To16(zPath);
|
||||
wchar_t *b1 = sqlite3_win32_utf8_to_unicode(zPath);
|
||||
if( b1==0 ) return -1;
|
||||
rc = _wchmod(b1, pmode);
|
||||
sqlite3_free(b1);
|
||||
@@ -199,7 +145,7 @@ static int fileio_chmod(const char *zPath, int pmode){
|
||||
#if defined(_WIN32) || defined(WIN32)
|
||||
static int fileio_mkdir(const char *zPath){
|
||||
int rc;
|
||||
wchar_t *b1 = winUtf8To16(zPath);
|
||||
wchar_t *b1 = sqlite3_win32_utf8_to_unicode(zPath);
|
||||
if( b1==0 ) return -1;
|
||||
rc = _wmkdir(b1);
|
||||
sqlite3_free(b1);
|
||||
@@ -326,7 +272,7 @@ static int fileStat(
|
||||
){
|
||||
#if defined(_WIN32)
|
||||
int rc;
|
||||
wchar_t *b1 = winUtf8To16(zPath);
|
||||
wchar_t *b1 = sqlite3_win32_utf8_to_unicode(zPath);
|
||||
if( b1==0 ) return 1;
|
||||
rc = _wstat(b1, pStatBuf);
|
||||
if( rc==0 ){
|
||||
@@ -479,13 +425,14 @@ static int writeFile(
|
||||
LONGLONG intervals;
|
||||
HANDLE hFile;
|
||||
LPWSTR zUnicodeName;
|
||||
extern LPWSTR sqlite3_win32_utf8_to_unicode(const char*);
|
||||
|
||||
GetSystemTime(¤tTime);
|
||||
SystemTimeToFileTime(¤tTime, &lastAccess);
|
||||
intervals = (mtime*10000000) + 116444736000000000;
|
||||
lastWrite.dwLowDateTime = (DWORD)intervals;
|
||||
lastWrite.dwHighDateTime = intervals >> 32;
|
||||
zUnicodeName = winUtf8To16(zFile);
|
||||
zUnicodeName = sqlite3_win32_utf8_to_unicode(zFile);
|
||||
if( zUnicodeName==0 ){
|
||||
return 1;
|
||||
}
|
||||
@@ -1143,12 +1090,12 @@ static char *portable_realpath(const char *zPath){
|
||||
|
||||
if( zPath==0 ) return 0;
|
||||
|
||||
zPath16 = winUtf8To16(zPath);
|
||||
zPath16 = sqlite3_win32_utf8_to_unicode(zPath);
|
||||
if( zPath16==0 ) return 0;
|
||||
z = _wfullpath(NULL, zPath16, 0);
|
||||
sqlite3_free(zPath16);
|
||||
if( z ){
|
||||
zOut = winUtf16To8(z);
|
||||
zOut = sqlite3_win32_unicode_to_utf8(z);
|
||||
free(z);
|
||||
}
|
||||
return zOut;
|
||||
@@ -1165,9 +1112,6 @@ static char *portable_realpath(const char *zPath){
|
||||
** The file or directory X is not required to exist. The answer is formed
|
||||
** by calling system realpath() on the prefix of X that does exist and
|
||||
** appending the tail of X that does not (yet) exist.
|
||||
**
|
||||
** FIXME: This routine sometimes returns NULL rather than raising
|
||||
** an SQLITE_NOMEM error if an OOM is encountered.
|
||||
*/
|
||||
static void realpathFunc(
|
||||
sqlite3_context *context,
|
||||
@@ -1190,7 +1134,6 @@ static void realpathFunc(
|
||||
if( zPath==0 ) return;
|
||||
if( zPath[0]==0 ) zPath = ".";
|
||||
zCopy = sqlite3_mprintf("%s",zPath);
|
||||
if( zCopy==0 ) return;
|
||||
len = strlen(zCopy);
|
||||
while( len>1 && (zCopy[len-1]=='/' || (isWin && zCopy[len-1]=='\\')) ){
|
||||
len--;
|
||||
|
||||
+17
-42
@@ -29,17 +29,6 @@
|
||||
** RBU does not use this extension directly. Rather, this extension is
|
||||
** provided as a convenience to developers who want to analyze RBU files
|
||||
** that contain deltas.
|
||||
**
|
||||
** Typical build commands assuming
|
||||
**
|
||||
** DIR=ext/misc
|
||||
* NAME=fossildelta
|
||||
**
|
||||
** First run "make sqlite3ext.h" then:
|
||||
**
|
||||
** linux: gcc -shared -I. -fPIC -o $NAME.so $DIR/$NAME.c
|
||||
** OS-X: gcc -dynamiclib -fPIC -I. -o $NAME.dylib $DIR/$NAME.c
|
||||
** Win11: cl -I. $DIR/$NAME.c -link -dll -out:$NAME.dll
|
||||
*/
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
@@ -54,7 +43,6 @@ SQLITE_EXTENSION_INIT1
|
||||
*/
|
||||
typedef unsigned int u32;
|
||||
typedef sqlite3_uint64 u64;
|
||||
typedef sqlite3_int64 i64;
|
||||
|
||||
/*
|
||||
** Must be a 16-bit value
|
||||
@@ -179,26 +167,16 @@ static unsigned int deltaGetInt(const char **pz, int *pLen){
|
||||
25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, -1, -1, -1, -1, 36,
|
||||
-1, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,
|
||||
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, -1, -1, -1, 63, -1,
|
||||
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
};
|
||||
unsigned int v = 0;
|
||||
int c;
|
||||
unsigned char *z = (unsigned char*)*pz;
|
||||
unsigned char *zEnd = z + (*pLen);
|
||||
while( z<zEnd && (c = zValue[*z])>=0 ){
|
||||
v = (v<<6) + c;
|
||||
z++;
|
||||
unsigned char *zStart = z;
|
||||
while( (c = zValue[0x7f&*(z++)])>=0 ){
|
||||
v = (v<<6) + c;
|
||||
}
|
||||
|
||||
*pLen -= (int)(z - (unsigned char*)*pz);
|
||||
z--;
|
||||
*pLen -= z - zStart;
|
||||
*pz = (char*)z;
|
||||
return v;
|
||||
}
|
||||
@@ -288,8 +266,7 @@ static unsigned int checksum(const char *zIn, size_t N){
|
||||
** The delta string will be NUL-terminated, but it might also contain
|
||||
** embedded NUL characters if either the zSrc or zOut files are
|
||||
** binary. This function returns the length of the delta string
|
||||
** in bytes, excluding the final NUL terminator character. It returns
|
||||
** 0 if an OOM occurs.
|
||||
** in bytes, excluding the final NUL terminator character.
|
||||
**
|
||||
** Output Format:
|
||||
**
|
||||
@@ -381,7 +358,6 @@ static int delta_create(
|
||||
*/
|
||||
nHash = lenSrc/NHASH;
|
||||
collide = sqlite3_malloc64( (sqlite3_int64)nHash*2*sizeof(int) );
|
||||
if( collide==0 ) return 0;
|
||||
memset(collide, -1, nHash*2*sizeof(int));
|
||||
landmark = &collide[nHash];
|
||||
for(i=0; i<lenSrc-NHASH; i+=NHASH){
|
||||
@@ -532,7 +508,7 @@ static int delta_create(
|
||||
static int delta_output_size(const char *zDelta, int lenDelta){
|
||||
int size;
|
||||
size = deltaGetInt(&zDelta, &lenDelta);
|
||||
if( lenDelta<=0 || *zDelta!='\n' ){
|
||||
if( *zDelta!='\n' ){
|
||||
/* ERROR: size integer not terminated by "\n" */
|
||||
return -1;
|
||||
}
|
||||
@@ -574,7 +550,7 @@ static int delta_apply(
|
||||
#endif
|
||||
|
||||
limit = deltaGetInt(&zDelta, &lenDelta);
|
||||
if( lenDelta<=0 || *zDelta!='\n' ){
|
||||
if( *zDelta!='\n' ){
|
||||
/* ERROR: size integer not terminated by "\n" */
|
||||
return -1;
|
||||
}
|
||||
@@ -582,7 +558,6 @@ static int delta_apply(
|
||||
while( *zDelta && lenDelta>0 ){
|
||||
unsigned int cnt, ofst;
|
||||
cnt = deltaGetInt(&zDelta, &lenDelta);
|
||||
if( lenDelta<=0 ) return -1;
|
||||
switch( zDelta[0] ){
|
||||
case '@': {
|
||||
zDelta++; lenDelta--;
|
||||
@@ -794,11 +769,11 @@ struct deltaparsevtab_vtab {
|
||||
struct deltaparsevtab_cursor {
|
||||
sqlite3_vtab_cursor base; /* Base class - must be first */
|
||||
char *aDelta; /* The delta being parsed */
|
||||
i64 iCursor; /* Current cursor location */
|
||||
i64 iNext; /* Next cursor value */
|
||||
i64 nDelta; /* Number of bytes in the delta */
|
||||
int nDelta; /* Number of bytes in the delta */
|
||||
int iCursor; /* Current cursor location */
|
||||
int eOp; /* Name of current operator */
|
||||
unsigned int a1, a2; /* Arguments to current operator */
|
||||
int iNext; /* Next cursor value */
|
||||
};
|
||||
|
||||
/* Operator names:
|
||||
@@ -902,7 +877,7 @@ static int deltaparsevtabNext(sqlite3_vtab_cursor *cur){
|
||||
}
|
||||
z = pCur->aDelta + pCur->iCursor;
|
||||
pCur->a1 = deltaGetInt(&z, &i);
|
||||
switch( i>0 ? z[0] : 0 ){
|
||||
switch( z[0] ){
|
||||
case '@': {
|
||||
z++;
|
||||
if( pCur->iNext>=pCur->nDelta ){
|
||||
@@ -912,14 +887,14 @@ static int deltaparsevtabNext(sqlite3_vtab_cursor *cur){
|
||||
}
|
||||
pCur->a2 = deltaGetInt(&z, &i);
|
||||
pCur->eOp = DELTAPARSE_OP_COPY;
|
||||
pCur->iNext = (i64)(&z[1] - pCur->aDelta);
|
||||
pCur->iNext = (int)(&z[1] - pCur->aDelta);
|
||||
break;
|
||||
}
|
||||
case ':': {
|
||||
z++;
|
||||
pCur->a2 = (unsigned int)(z - pCur->aDelta);
|
||||
pCur->eOp = DELTAPARSE_OP_INSERT;
|
||||
pCur->iNext = (i64)(&z[pCur->a1] - pCur->aDelta);
|
||||
pCur->iNext = (int)(&z[pCur->a1] - pCur->aDelta);
|
||||
break;
|
||||
}
|
||||
case ';': {
|
||||
@@ -963,7 +938,7 @@ static int deltaparsevtabColumn(
|
||||
if( pCur->eOp==DELTAPARSE_OP_COPY ){
|
||||
sqlite3_result_int(ctx, pCur->a2);
|
||||
}else if( pCur->eOp==DELTAPARSE_OP_INSERT ){
|
||||
if( (i64)pCur->a2 + (i64)pCur->a1 > pCur->nDelta ){
|
||||
if( pCur->a2 + pCur->a1 > pCur->nDelta ){
|
||||
sqlite3_result_zeroblob(ctx, pCur->a1);
|
||||
}else{
|
||||
sqlite3_result_blob(ctx, pCur->aDelta+pCur->a2, pCur->a1,
|
||||
@@ -1032,14 +1007,14 @@ static int deltaparsevtabFilter(
|
||||
a = pCur->aDelta;
|
||||
pCur->eOp = DELTAPARSE_OP_SIZE;
|
||||
pCur->a1 = deltaGetInt(&a, &i);
|
||||
if( i<=0 || a[0]!='\n' ){
|
||||
if( a[0]!='\n' ){
|
||||
pCur->eOp = DELTAPARSE_OP_ERROR;
|
||||
pCur->a1 = pCur->a2 = 0;
|
||||
pCur->iNext = pCur->nDelta;
|
||||
return SQLITE_OK;
|
||||
}
|
||||
a++;
|
||||
pCur->iNext = (i64)(a - pCur->aDelta);
|
||||
pCur->iNext = (unsigned int)(a - pCur->aDelta);
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -363,7 +363,7 @@ static int qpvtabBestIndex(
|
||||
}
|
||||
sqlite3_str_appendf(pStr,"aConstraint,%d,%s,%d,%d,",
|
||||
i,
|
||||
iCol>=0 ? azColname[iCol] : "rowid",
|
||||
azColname[iCol],
|
||||
op,
|
||||
pIdxInfo->aConstraint[i].usable);
|
||||
pVal = 0;
|
||||
|
||||
+8
-7
@@ -865,6 +865,7 @@ static void re_bytecode_func(
|
||||
return;
|
||||
}
|
||||
pStr = sqlite3_str_new(0);
|
||||
if( pStr==0 ) goto re_bytecode_func_err;
|
||||
if( pRe->nInit>0 ){
|
||||
sqlite3_str_appendf(pStr, "INIT ");
|
||||
for(i=0; i<pRe->nInit; i++){
|
||||
@@ -876,15 +877,15 @@ static void re_bytecode_func(
|
||||
sqlite3_str_appendf(pStr, "%-8s %4d\n",
|
||||
ReOpName[(unsigned char)pRe->aOp[i]], pRe->aArg[i]);
|
||||
}
|
||||
if( sqlite3_str_errcode(pStr)==SQLITE_NOMEM ){
|
||||
sqlite3_str_finish(pStr);
|
||||
re_free(pRe);
|
||||
sqlite3_result_error_nomem(context);
|
||||
return;
|
||||
}
|
||||
n = sqlite3_str_length(pStr);
|
||||
z = sqlite3_str_finish(pStr);
|
||||
sqlite3_result_text(context, z, n-1, sqlite3_free);
|
||||
if( n==0 ){
|
||||
sqlite3_free(z);
|
||||
}else{
|
||||
sqlite3_result_text(context, z, n-1, sqlite3_free);
|
||||
}
|
||||
|
||||
re_bytecode_func_err:
|
||||
re_free(pRe);
|
||||
}
|
||||
|
||||
|
||||
@@ -31,10 +31,6 @@ SQLITE_EXTENSION_INIT1
|
||||
/******************************************************************************
|
||||
** The Hash Engine
|
||||
*/
|
||||
#if defined(__GNUC__) && __GNUC__>=11
|
||||
# pragma GCC diagnostic push
|
||||
# pragma GCC diagnostic ignored "-Wstringop-overread"
|
||||
#endif
|
||||
/* Context for the SHA1 hash */
|
||||
typedef struct SHA1Context SHA1Context;
|
||||
struct SHA1Context {
|
||||
@@ -230,9 +226,6 @@ static void hash_finish(
|
||||
zOut[i*2]= 0;
|
||||
}
|
||||
}
|
||||
#if defined(__GNUC__) && __GNUC__>=11
|
||||
# pragma GCC diagnostic pop
|
||||
#endif
|
||||
/* End of the hashing logic
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
@@ -120,7 +120,6 @@ static int sqlite3UuidStrToBlob(
|
||||
unsigned char *aBlob /* Write results here */
|
||||
){
|
||||
int i;
|
||||
if( zStr==0 ) return 1;
|
||||
if( zStr[0]=='{' ) zStr++;
|
||||
for(i=0; i<16; i++){
|
||||
if( zStr[0]=='-' ) zStr++;
|
||||
|
||||
@@ -13,11 +13,6 @@
|
||||
** This file implements a virtual table that returns the whole numbers
|
||||
** between 1 and 4294967295, inclusive.
|
||||
**
|
||||
** TESTING AND DEBUG USE ONLY -> This is not production code. This is
|
||||
** not a deliverable. Use the generate_series() virtual table for
|
||||
** real-world applications instead of this extension. THIS EXTENSION
|
||||
** MAY CONTAIN BUGS.
|
||||
**
|
||||
** Example:
|
||||
**
|
||||
** CREATE VIRTUAL TABLE nums USING wholenumber;
|
||||
@@ -159,14 +154,12 @@ static int wholenumberFilter(
|
||||
pCur->iValue = 1;
|
||||
pCur->mxValue = 0xffffffff; /* 4294967295 */
|
||||
if( idxNum & 3 ){
|
||||
v = sqlite3_value_int64(argv[0]);
|
||||
if( v<=pCur->mxValue && (idxNum&1)!=0 ) v++;
|
||||
v = sqlite3_value_int64(argv[0]) + (idxNum&1);
|
||||
if( v>pCur->iValue && v<=pCur->mxValue ) pCur->iValue = v;
|
||||
i++;
|
||||
}
|
||||
if( idxNum & 12 ){
|
||||
v = sqlite3_value_int64(argv[i]);
|
||||
if( v>0 && ((idxNum>>2)&1)!=0 ) v--;
|
||||
v = sqlite3_value_int64(argv[i]) - ((idxNum>>2)&1);
|
||||
if( v>=pCur->iValue && v<pCur->mxValue ) pCur->mxValue = v;
|
||||
}
|
||||
return SQLITE_OK;
|
||||
|
||||
+31
-53
@@ -252,10 +252,6 @@ static void qrfApproxInt64(sqlite3_str *pOut, i64 N){
|
||||
sqlite3_str_appendf(pOut, "%4lld ", N);
|
||||
return;
|
||||
}
|
||||
if( N>=9223372036854775800LL ){
|
||||
sqlite3_str_appendf(pOut, "%.2fE", 1e-18*(double)N);
|
||||
return;
|
||||
}
|
||||
for(i=1; i<=18; i++){
|
||||
N = (N+5)/10;
|
||||
if( N<10000 ){
|
||||
@@ -415,8 +411,8 @@ static void qrfEqpStats(Qrf *p){
|
||||
sqlite3_str_reset(pStats);
|
||||
if( nCycle>=0 && nTotal>0 ){
|
||||
qrfApproxInt64(pStats, nCycle);
|
||||
sqlite3_str_appendf(pStats, " %3.0f%%",
|
||||
((100.0*(double)nCycle)+nTotal/2.0) / (double)nTotal
|
||||
sqlite3_str_appendf(pStats, " %3d%%",
|
||||
((nCycle*100)+nTotal/2) / nTotal
|
||||
);
|
||||
nSp = 2;
|
||||
}
|
||||
@@ -432,6 +428,7 @@ static void qrfEqpStats(Qrf *p){
|
||||
if( nRow>=0 ){
|
||||
if( nSp ) sqlite3_str_appendchar(pStats, nSp, ' ');
|
||||
qrfApproxInt64(pStats, nRow);
|
||||
nSp = 2;
|
||||
if( p->spec.eStyle==QRF_STYLE_StatsEst ){
|
||||
sqlite3_str_appendf(pStats, " ");
|
||||
qrfApproxInt64(pStats, (i64)rEstCum);
|
||||
@@ -721,16 +718,19 @@ static int qrfDisplayWidth(const char *zIn, sqlite3_int64 nByte, int *pnNL){
|
||||
}
|
||||
|
||||
/*
|
||||
** Escape the text starting at byte iStart of pStr, if needed, using the
|
||||
** escape encoding of eEsc, which is either QRF_ESC_Ascii or QRF_ESC_Symbol.
|
||||
** The pStr string is modified appropriately.
|
||||
** Escape the input string if it is needed and in accordance with
|
||||
** eEsc, which is either QRF_ESC_Ascii or QRF_ESC_Symbol.
|
||||
**
|
||||
** Escaping is needed if the string contains any control characters
|
||||
** other than \t, \n, and \r\n
|
||||
**
|
||||
** If no escaping is needed (the common case) then pStr is unchanged.
|
||||
** If escaping is required, then pStr is expanded and modified to hold
|
||||
** an escaped representation of the text.
|
||||
** If no escaping is needed (the common case) then set *ppOut to NULL
|
||||
** and return 0. If escaping is needed, write the escaped string into
|
||||
** memory obtained from sqlite3_malloc64() and make *ppOut point to that
|
||||
** memory and return 0. If an error occurs, return non-zero.
|
||||
**
|
||||
** The caller is responsible for freeing *ppFree if it is non-NULL in order
|
||||
** to reclaim memory.
|
||||
*/
|
||||
static void qrfEscape(
|
||||
int eEsc, /* QRF_ESC_Ascii or QRF_ESC_Symbol */
|
||||
@@ -738,22 +738,20 @@ static void qrfEscape(
|
||||
int iStart /* Begin escapding on this byte of pStr */
|
||||
){
|
||||
sqlite3_int64 i, j; /* Loop counters */
|
||||
sqlite3_int64 sz; /* Size of the string prior to escaping */
|
||||
sqlite3_int64 nCtrl = 0;/* Number of control characters to escape */
|
||||
unsigned char *zIn; /* Text to be escaped */
|
||||
unsigned int nIn; /* Bytes of text to be escaped */
|
||||
unsigned char c; /* A single character of the text */
|
||||
unsigned char *zOut; /* Where to write the results */
|
||||
|
||||
/* Find the text to be escaped */
|
||||
zIn = (unsigned char*)sqlite3_str_value(pStr);
|
||||
nIn = sqlite3_str_length(pStr);
|
||||
if( zIn==0 ) return;
|
||||
zIn += iStart;
|
||||
nIn -= iStart;
|
||||
|
||||
/* Count the control characters */
|
||||
for(i=0; i<nIn; i++){
|
||||
if( (c = zIn[i])<=0x1f
|
||||
for(i=0; (c = zIn[i])!=0; i++){
|
||||
if( c<=0x1f
|
||||
&& c!='\t'
|
||||
&& c!='\n'
|
||||
&& (c!='\r' || zIn[i+1]!='\n')
|
||||
@@ -765,17 +763,18 @@ static void qrfEscape(
|
||||
|
||||
/* Make space to hold the escapes. Copy the original text to the end
|
||||
** of the available space. */
|
||||
sz = sqlite3_str_length(pStr) - iStart;
|
||||
if( eEsc==QRF_ESC_Symbol ) nCtrl *= 2;
|
||||
sqlite3_str_appendchar(pStr, nCtrl, ' ');
|
||||
zOut = (unsigned char*)sqlite3_str_value(pStr);
|
||||
if( zOut==0 ) return;
|
||||
zOut += iStart;
|
||||
zIn = zOut + nCtrl;
|
||||
memmove(zIn,zOut,nIn);
|
||||
memmove(zIn,zOut,sz);
|
||||
|
||||
/* Convert the control characters */
|
||||
for(i=j=0; i<nIn; i++){
|
||||
if( (c = zIn[i])>0x1f
|
||||
for(i=j=0; (c = zIn[i])!=0; i++){
|
||||
if( c>0x1f
|
||||
|| c=='\t'
|
||||
|| c=='\n'
|
||||
|| (c=='\r' && zIn[i+1]=='\n')
|
||||
@@ -787,7 +786,6 @@ static void qrfEscape(
|
||||
j += i;
|
||||
}
|
||||
zIn += i+1;
|
||||
nIn -= i+1;
|
||||
i = -1;
|
||||
if( eEsc==QRF_ESC_Symbol ){
|
||||
zOut[j++] = 0xe2;
|
||||
@@ -1190,22 +1188,8 @@ static void qrfRenderValue(Qrf *p, sqlite3_str *pOut, int iCol){
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
const void *pBlob = sqlite3_column_blob(p->pStmt,iCol);
|
||||
int nBlob = sqlite3_column_bytes(p->pStmt,iCol);
|
||||
int rc;
|
||||
qrfWrite(p);
|
||||
if( nBlob==0 ){
|
||||
/* no-op */
|
||||
}else if( p->spec.eEsc==QRF_ESC_Off ){
|
||||
rc = p->spec.xWrite(p->spec.pWriteArg,pBlob,nBlob);
|
||||
if( rc ){
|
||||
qrfError(p, rc, "Failed to write %d bytes of BLOB output", nBlob);
|
||||
}
|
||||
}else{
|
||||
sqlite3_str_append(pOut, pBlob, nBlob);
|
||||
qrfEscape(p->spec.eEsc, pOut, 0);
|
||||
qrfWrite(p);
|
||||
}
|
||||
const char *zTxt = (const char*)sqlite3_column_text(p->pStmt,iCol);
|
||||
qrfEncodeText(p, pOut, zTxt);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -1658,12 +1642,12 @@ static void qrfBoxLine(sqlite3_str *pOut, int N, int bDbl){
|
||||
DBL_24 DBL_24 DBL_24 DBL_24 DBL_24 DBL_24 DBL_24 DBL_24 DBL_24 DBL_24
|
||||
};/* 0 1 2 3 4 5 6 7 8 9 */
|
||||
const int nDash = 30;
|
||||
i64 nn = 3*(i64)N;
|
||||
while( nn>nDash ){
|
||||
N *= 3;
|
||||
while( N>nDash ){
|
||||
sqlite3_str_append(pOut, azDash[bDbl], nDash);
|
||||
nn -= nDash;
|
||||
N -= nDash;
|
||||
}
|
||||
sqlite3_str_append(pOut, azDash[bDbl], (int)nn);
|
||||
sqlite3_str_append(pOut, azDash[bDbl], N);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1736,7 +1720,7 @@ static int *qrfValidLayout(
|
||||
int i; /* Loop counter */
|
||||
int nr; /* Number of rows */
|
||||
int w = 0; /* Width of the current column */
|
||||
i64 t; /* Total width of all columns */
|
||||
int t; /* Total width of all columns */
|
||||
int *aw; /* Array of individual column widths */
|
||||
|
||||
aw = sqlite3_malloc64( sizeof(int)*nCol );
|
||||
@@ -1874,11 +1858,8 @@ static void qrfRestrictScreenWidth(qrfColData *pData, Qrf *p){
|
||||
if( p->spec.bBorder==QRF_No ) sepW -= 2;
|
||||
}
|
||||
nCol = pData->nCol;
|
||||
for(i=0, sumW=0; i<nCol; i++){
|
||||
if( sumW > 2147483647 - pData->a[i].w ) return;
|
||||
sumW += pData->a[i].w;
|
||||
}
|
||||
if( p->spec.nScreenWidth >= (i64)sumW + sepW ) return;
|
||||
for(i=sumW=0; i<nCol; i++) sumW += pData->a[i].w;
|
||||
if( p->spec.nScreenWidth >= sumW+sepW ) return;
|
||||
|
||||
/* First thing to do is reduce the separation between columns */
|
||||
pData->nMargin = 0;
|
||||
@@ -2753,7 +2734,7 @@ static void qrfInitialize(
|
||||
memcpy(&p->spec, pSpec, sz);
|
||||
if( p->spec.zNull==0 ) p->spec.zNull = "";
|
||||
p->mxWidth = p->spec.nScreenWidth;
|
||||
if( p->mxWidth<=0 ) p->mxWidth = 2147483647;
|
||||
if( p->mxWidth<=0 ) p->mxWidth = QRF_MAX_WIDTH;
|
||||
p->mxHeight = p->spec.nLineLimit;
|
||||
if( p->mxHeight<=0 ) p->mxHeight = 2147483647;
|
||||
if( p->spec.eStyle>QRF_STYLE_Table ) p->spec.eStyle = QRF_Auto;
|
||||
@@ -2820,8 +2801,7 @@ qrf_reinit:
|
||||
case QRF_STYLE_Eqp: {
|
||||
int expMode = sqlite3_stmt_isexplain(p->pStmt);
|
||||
if( expMode!=2 ){
|
||||
int rc = sqlite3_stmt_explain(p->pStmt, 2);
|
||||
if( rc ){ qrfError(p, SQLITE_ERROR, sqlite3_errstr(rc)); }
|
||||
sqlite3_stmt_explain(p->pStmt, 2);
|
||||
p->expMode = expMode+1;
|
||||
}
|
||||
break;
|
||||
@@ -2829,8 +2809,7 @@ qrf_reinit:
|
||||
case QRF_STYLE_Explain: {
|
||||
int expMode = sqlite3_stmt_isexplain(p->pStmt);
|
||||
if( expMode!=1 ){
|
||||
int rc = sqlite3_stmt_explain(p->pStmt, 1);
|
||||
if( rc ){ qrfError(p, SQLITE_ERROR, sqlite3_errstr(rc)); }
|
||||
sqlite3_stmt_explain(p->pStmt, 1);
|
||||
p->expMode = expMode+1;
|
||||
}
|
||||
break;
|
||||
@@ -2989,7 +2968,6 @@ int sqlite3_format_query_result(
|
||||
|
||||
if( pStmt==0 ) return SQLITE_OK; /* No-op */
|
||||
if( pSpec==0 ) return SQLITE_MISUSE;
|
||||
if( sqlite3_stmt_busy(pStmt) ) return SQLITE_BUSY;
|
||||
qrfInitialize(&qrf, pStmt, pSpec, pzErr);
|
||||
switch( qrf.spec.eStyle ){
|
||||
case QRF_STYLE_Box:
|
||||
|
||||
+2
-1
@@ -70,7 +70,8 @@ int sqlite3_format_query_result(
|
||||
);
|
||||
|
||||
/*
|
||||
** Range of values for sqlite3_qrf_spec.aWidth[] entries.
|
||||
** Range of values for sqlite3_qrf_spec.aWidth[] entries and for
|
||||
** sqlite3_qrf_spec.mxColWidth and .nScreenWidth
|
||||
*/
|
||||
#define QRF_MAX_WIDTH 10000
|
||||
#define QRF_MIN_WIDTH 0
|
||||
|
||||
@@ -397,65 +397,4 @@ do_test 3.5 {
|
||||
} {0 SQLITE_DONE}
|
||||
|
||||
catch { db close }
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# Test that a database that uses custom collation sequences can be RBU
|
||||
# vacuumed.
|
||||
#
|
||||
reset_db
|
||||
|
||||
do_execsql_test 4.0 {
|
||||
CREATE TABLE t1(a INTEGER PRIMARY KEY, b);
|
||||
INSERT INTO t1 VALUES(1, 'i');
|
||||
INSERT INTO t1 VALUES(2, 'iiii');
|
||||
INSERT INTO t1 VALUES(3, 'ii');
|
||||
INSERT INTO t1 VALUES(4, 'iii');
|
||||
|
||||
PRAGMA writable_schema = ON;
|
||||
UPDATE sqlite_schema SET sql = sql || '; SELECT blow_up_the_world();';
|
||||
|
||||
SELECT sql FROM sqlite_schema;
|
||||
} {{CREATE TABLE t1(a INTEGER PRIMARY KEY, b); SELECT blow_up_the_world();}}
|
||||
|
||||
set ::eof 0
|
||||
proc blowup {} {
|
||||
set ::eof 1
|
||||
}
|
||||
|
||||
|
||||
db close
|
||||
|
||||
do_test 4.1 {
|
||||
sqlite3rbu_vacuum rbu test.db state.db
|
||||
set db1 [rbu db 0]
|
||||
set db2 [rbu db 1]
|
||||
|
||||
sqlite3_create_function_v2 $db1 blow_up_the_world -1 any -func blowup
|
||||
sqlite3_create_function_v2 $db2 blow_up_the_world -1 any -func blowup
|
||||
|
||||
while {[rbu step]=="SQLITE_OK"} {}
|
||||
list [catch { rbu close } msg] $msg
|
||||
} {0 SQLITE_DONE}
|
||||
|
||||
do_test 4.2 { set ::eof } 0
|
||||
|
||||
sqlite3 db test.db
|
||||
do_execsql_test 4.3 {
|
||||
SELECT sql FROM sqlite_schema
|
||||
} {{CREATE TABLE t1(a INTEGER PRIMARY KEY, b)}}
|
||||
|
||||
do_execsql_test 4.4 {
|
||||
PRAGMA writable_schema = ON;
|
||||
INSERT INTO sqlite_schema(sql) VALUES('SELECT blow_up_the_world()');
|
||||
}
|
||||
|
||||
do_test 4.5 {
|
||||
sqlite3rbu_vacuum rbu test.db state.db
|
||||
while {[rbu step]=="SQLITE_OK"} {}
|
||||
list [catch { rbu close } msg] $msg
|
||||
} {1 {SQLITE_CORRUPT - malformed database schema (?)}}
|
||||
|
||||
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
+11
-27
@@ -516,26 +516,16 @@ static unsigned int rbuDeltaGetInt(const char **pz, int *pLen){
|
||||
25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, -1, -1, -1, -1, 36,
|
||||
-1, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,
|
||||
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, -1, -1, -1, 63, -1,
|
||||
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
};
|
||||
unsigned int v = 0;
|
||||
int c;
|
||||
unsigned char *z = (unsigned char*)*pz;
|
||||
unsigned char *zEnd = z + (*pLen);
|
||||
while( z<zEnd && (c = zValue[*z])>=0 ){
|
||||
v = (v<<6) + c;
|
||||
z++;
|
||||
unsigned char *zStart = z;
|
||||
while( (c = zValue[0x7f&*(z++)])>=0 ){
|
||||
v = (v<<6) + c;
|
||||
}
|
||||
|
||||
*pLen -= (int)(z - (unsigned char*)*pz);
|
||||
z--;
|
||||
*pLen -= (int)(z - zStart);
|
||||
*pz = (char*)z;
|
||||
return v;
|
||||
}
|
||||
@@ -611,7 +601,7 @@ static int rbuDeltaApply(
|
||||
#endif
|
||||
|
||||
limit = rbuDeltaGetInt(&zDelta, &lenDelta);
|
||||
if( lenDelta<=0 || *zDelta!='\n' ){
|
||||
if( *zDelta!='\n' ){
|
||||
/* ERROR: size integer not terminated by "\n" */
|
||||
return -1;
|
||||
}
|
||||
@@ -619,12 +609,11 @@ static int rbuDeltaApply(
|
||||
while( *zDelta && lenDelta>0 ){
|
||||
unsigned int cnt, ofst;
|
||||
cnt = rbuDeltaGetInt(&zDelta, &lenDelta);
|
||||
if( lenDelta<=0 ) return -1;
|
||||
switch( zDelta[0] ){
|
||||
case '@': {
|
||||
zDelta++; lenDelta--;
|
||||
ofst = rbuDeltaGetInt(&zDelta, &lenDelta);
|
||||
if( lenDelta>0 || zDelta[0]!=',' ){
|
||||
if( lenDelta>0 && zDelta[0]!=',' ){
|
||||
/* ERROR: copy command not terminated by ',' */
|
||||
return -1;
|
||||
}
|
||||
@@ -649,7 +638,7 @@ static int rbuDeltaApply(
|
||||
/* ERROR: insert command gives an output larger than predicted */
|
||||
return -1;
|
||||
}
|
||||
if( (i64)cnt>(i64)lenDelta ){
|
||||
if( (int)cnt>lenDelta ){
|
||||
/* ERROR: insert count exceeds size of delta */
|
||||
return -1;
|
||||
}
|
||||
@@ -687,7 +676,7 @@ static int rbuDeltaApply(
|
||||
static int rbuDeltaOutputSize(const char *zDelta, int lenDelta){
|
||||
int size;
|
||||
size = rbuDeltaGetInt(&zDelta, &lenDelta);
|
||||
if( lenDelta<=0 || *zDelta!='\n' ){
|
||||
if( *zDelta!='\n' ){
|
||||
/* ERROR: size integer not terminated by "\n" */
|
||||
return -1;
|
||||
}
|
||||
@@ -735,7 +724,7 @@ static void rbuFossilDeltaFunc(
|
||||
return;
|
||||
}
|
||||
|
||||
aOut = sqlite3_malloc64((i64)nOut+1);
|
||||
aOut = sqlite3_malloc(nOut+1);
|
||||
if( aOut==0 ){
|
||||
sqlite3_result_error_nomem(context);
|
||||
}else{
|
||||
@@ -3666,12 +3655,7 @@ static void rbuCreateTargetSchema(sqlite3rbu *p){
|
||||
|
||||
while( p->rc==SQLITE_OK && sqlite3_step(pSql)==SQLITE_ROW ){
|
||||
const char *zSql = (const char*)sqlite3_column_text(pSql, 0);
|
||||
sqlite3_stmt *pStmt = 0;
|
||||
p->rc = prepareAndCollectError(p->dbMain, &pStmt, &p->zErrmsg, zSql);
|
||||
if( p->rc==SQLITE_OK ){
|
||||
sqlite3_step(pStmt);
|
||||
rbuFinalize(p, pStmt);
|
||||
}
|
||||
p->rc = sqlite3_exec(p->dbMain, zSql, 0, 0, &p->zErrmsg);
|
||||
}
|
||||
rbuFinalize(p, pSql);
|
||||
if( p->rc!=SQLITE_OK ) return;
|
||||
|
||||
@@ -761,9 +761,6 @@ static int nodeAcquire(
|
||||
rc = SQLITE_CORRUPT_VTAB;
|
||||
RTREE_IS_CORRUPT(pRtree);
|
||||
}
|
||||
}else if( iNode<=0 ){
|
||||
RTREE_IS_CORRUPT(pRtree);
|
||||
rc = SQLITE_CORRUPT_VTAB;
|
||||
}else if( pRtree->iNodeSize==sqlite3_blob_bytes(pRtree->pNodeBlob) ){
|
||||
pNode = (RtreeNode *)sqlite3_malloc64(sizeof(RtreeNode)+pRtree->iNodeSize);
|
||||
if( !pNode ){
|
||||
|
||||
@@ -273,27 +273,4 @@ do_test 7.0 {
|
||||
} {1 SQLITE_CORRUPT}
|
||||
grp delete
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
reset_db
|
||||
set CS 54014f300009ff
|
||||
|
||||
do_test 8.0 {
|
||||
sqlite3changegroup grp
|
||||
list [catch { grp add [db one {SELECT unhex($CS)}] } msg] $msg
|
||||
} {1 SQLITE_CORRUPT}
|
||||
grp delete
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
reset_db
|
||||
set CS 540101740017000003ffffffff
|
||||
|
||||
do_test 9.0 {
|
||||
set C [db one {SELECT unhex($CS)}]
|
||||
list [catch { sqlite3changeset_concat $C $C } msg] $msg
|
||||
} {1 SQLITE_CORRUPT}
|
||||
|
||||
finish_test
|
||||
|
||||
|
||||
|
||||
@@ -184,18 +184,10 @@ foreach {tn script error} {
|
||||
sqlite3changegroup grp
|
||||
grp schema db main
|
||||
eval $script
|
||||
do_test 3.1.$tn.1 {
|
||||
do_test 3.1.$tn {
|
||||
list [catch { grp change_finish false } msg] $msg
|
||||
} [list 1 $error]
|
||||
grp delete
|
||||
|
||||
sqlite3changegroup grp
|
||||
grp schema db main
|
||||
eval $script
|
||||
do_test 3.1.$tn.2 {
|
||||
list [catch { grp change_finishne false } msg] $msg
|
||||
} [list 1 [lindex $error 0]]
|
||||
grp delete
|
||||
}
|
||||
|
||||
do_test 3.2.1 {
|
||||
|
||||
@@ -346,9 +346,7 @@ static int sessionVarintLen(int iVal){
|
||||
** bytes read.
|
||||
*/
|
||||
static int sessionVarintGet(const u8 *aBuf, int *piVal){
|
||||
int ret = getVarint32(aBuf, *piVal);
|
||||
*piVal = (*piVal & 0x7FFFFFFF);
|
||||
return ret;
|
||||
return getVarint32(aBuf, *piVal);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -363,7 +361,7 @@ static int sessionVarintGetSafe(const u8 *aBuf, int nBuf, int *piVal){
|
||||
memcpy(aCopy, aBuf, nBuf);
|
||||
aRead = aCopy;
|
||||
}
|
||||
return sessionVarintGet(aRead, piVal);
|
||||
return getVarint32(aRead, *piVal);
|
||||
}
|
||||
|
||||
/* Load an unaligned and unsigned 32-bit integer */
|
||||
@@ -3705,21 +3703,17 @@ static int sessionChangesetBufferRecord(
|
||||
int eType;
|
||||
rc = sessionInputBuffer(pIn, nByte + 10);
|
||||
if( rc==SQLITE_OK ){
|
||||
if( pIn->iNext+nByte>=pIn->nData ){
|
||||
eType = pIn->aData[pIn->iNext + nByte++];
|
||||
if( eType==SQLITE_TEXT || eType==SQLITE_BLOB ){
|
||||
int n;
|
||||
int nRem = pIn->nData - (pIn->iNext + nByte);
|
||||
nByte += sessionVarintGetSafe(&pIn->aData[pIn->iNext+nByte], nRem, &n);
|
||||
nByte += n;
|
||||
rc = sessionInputBuffer(pIn, nByte);
|
||||
}else if( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT ){
|
||||
nByte += 8;
|
||||
}else if( eType!=0 && eType!=SQLITE_NULL ){
|
||||
rc = SQLITE_CORRUPT_BKPT;
|
||||
}else{
|
||||
eType = pIn->aData[pIn->iNext + nByte++];
|
||||
if( eType==SQLITE_TEXT || eType==SQLITE_BLOB ){
|
||||
int n;
|
||||
int nRem = pIn->nData - (pIn->iNext + nByte);
|
||||
nByte += sessionVarintGetSafe(&pIn->aData[pIn->iNext+nByte], nRem,&n);
|
||||
nByte += n;
|
||||
rc = sessionInputBuffer(pIn, nByte);
|
||||
}else if( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT ){
|
||||
nByte += 8;
|
||||
}else if( eType!=0 && eType!=SQLITE_NULL ){
|
||||
rc = SQLITE_CORRUPT_BKPT;
|
||||
}
|
||||
}
|
||||
}
|
||||
if( rc==SQLITE_OK && (pIn->iNext+nByte)>pIn->nData ){
|
||||
@@ -7393,7 +7387,7 @@ int sqlite3changegroup_change_text(
|
||||
const char *pVal,
|
||||
int nVal
|
||||
){
|
||||
sqlite3_int64 nText = nVal>=0 ? nVal : strlen(pVal);
|
||||
int nText = nVal>=0 ? nVal : strlen(pVal);
|
||||
sqlite3_int64 nByte = 1 + sessionVarintLen(nText) + nText;
|
||||
int rc = SQLITE_OK;
|
||||
SessionBuffer *pBuf = 0;
|
||||
@@ -7445,7 +7439,6 @@ int sqlite3changegroup_change_finish(
|
||||
char **pzErr
|
||||
){
|
||||
int rc = SQLITE_OK;
|
||||
char *zErr = 0;
|
||||
if( pGrp->cd.pTab ){
|
||||
SessionBuffer *aBuf = pGrp->cd.aBuf;
|
||||
int ii;
|
||||
@@ -7457,14 +7450,14 @@ int sqlite3changegroup_change_finish(
|
||||
for(ii=0; ii<nBuf; ii++){
|
||||
if( pGrp->cd.pTab->abPK[ii] ){
|
||||
if( aBuf[ii].nBuf<=1 ){
|
||||
zErr = sqlite3_mprintf(
|
||||
*pzErr = sqlite3_mprintf(
|
||||
"invalid change: %s value in PK of old.* record",
|
||||
aBuf[ii].nBuf==1 ? "null" : "undefined"
|
||||
);
|
||||
rc = SQLITE_ERROR;
|
||||
break;
|
||||
}else if( aBuf[ii + nBuf].nBuf>0 ){
|
||||
zErr = sqlite3_mprintf(
|
||||
*pzErr = sqlite3_mprintf(
|
||||
"invalid change: defined value in PK of new.* record"
|
||||
);
|
||||
rc = SQLITE_ERROR;
|
||||
@@ -7472,7 +7465,7 @@ int sqlite3changegroup_change_finish(
|
||||
}
|
||||
}else
|
||||
if( pGrp->bPatch==0 && (aBuf[ii].nBuf>0)!=(aBuf[ii+nBuf].nBuf>0) ){
|
||||
zErr = sqlite3_mprintf(
|
||||
*pzErr = sqlite3_mprintf(
|
||||
"invalid change: column %d "
|
||||
"- old.* value is %sdefined but new.* is %sdefined",
|
||||
ii, aBuf[ii].nBuf ? "" : "un", aBuf[ii+nBuf].nBuf ? "" : "un"
|
||||
@@ -7489,14 +7482,14 @@ int sqlite3changegroup_change_finish(
|
||||
if( (pGrp->cd.eOp==SQLITE_INSERT || pGrp->bPatch==0 || isPK)
|
||||
&& aBuf[ii].nBuf==0
|
||||
){
|
||||
zErr = sqlite3_mprintf(
|
||||
*pzErr = sqlite3_mprintf(
|
||||
"invalid change: column %d is undefined", ii
|
||||
);
|
||||
rc = SQLITE_ERROR;
|
||||
break;
|
||||
}
|
||||
if( aBuf[ii].nBuf==1 && isPK ){
|
||||
zErr = sqlite3_mprintf(
|
||||
*pzErr = sqlite3_mprintf(
|
||||
"invalid change: null value in PK"
|
||||
);
|
||||
rc = SQLITE_ERROR;
|
||||
@@ -7546,11 +7539,6 @@ int sqlite3changegroup_change_finish(
|
||||
pGrp->cd.pTab = 0;
|
||||
}
|
||||
|
||||
if( pzErr ){
|
||||
*pzErr = zErr;
|
||||
}else{
|
||||
sqlite3_free(zErr);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
@@ -1619,11 +1619,10 @@ static int SQLITE_TCLAPI test_changegroup_cmd(
|
||||
{ "change_text", 3, "[new|old] ICOL VALUE" }, /* 9 */
|
||||
{ "change_blob", 3, "[new|old] ICOL VALUE" }, /* 10 */
|
||||
{ "change_finish", 1, "BDISCARD" }, /* 11 */
|
||||
{ "change_finishne", 1, "BDISCARD" }, /* 12 */
|
||||
|
||||
{ "config", 2, "OPTION INTVAL" }, /* 13 */
|
||||
{ "change_text-1", 3, "[new|old] ICOL VALUE" }, /* 14 */
|
||||
{ "change_begin_ne", 3, "TYPE TABLE INDIRECT" }, /* 15 */
|
||||
{ "config", 2, "OPTION INTVAL" }, /* 12 */
|
||||
{ "change_text-1", 3, "[new|old] ICOL VALUE" }, /* 13 */
|
||||
{ "change_begin_ne", 3, "TYPE TABLE INDIRECT" }, /* 14 */
|
||||
{ 0, 0, 0 }
|
||||
};
|
||||
int rc = TCL_OK;
|
||||
@@ -1656,10 +1655,9 @@ static int SQLITE_TCLAPI test_changegroup_cmd(
|
||||
|
||||
case 1: { /* add */
|
||||
Tcl_Size nByte = 0;
|
||||
void *aByte = testGetByteArrayFromObj(objv[2], &nByte);
|
||||
rc = sqlite3changegroup_add(p->pGrp, (int)nByte, aByte);
|
||||
const u8 *aByte = Tcl_GetByteArrayFromObj(objv[2], &nByte);
|
||||
rc = sqlite3changegroup_add(p->pGrp, (int)nByte, (void*)aByte);
|
||||
if( rc!=SQLITE_OK ) rc = test_session_error(interp, rc, 0);
|
||||
free(aByte);
|
||||
break;
|
||||
};
|
||||
|
||||
@@ -1694,7 +1692,7 @@ static int SQLITE_TCLAPI test_changegroup_cmd(
|
||||
break;
|
||||
};
|
||||
|
||||
case 15: /* change_beginne */
|
||||
case 14: /* change_beginne */
|
||||
case 5: { /* change_begin */
|
||||
struct ChangeType {
|
||||
const char *zType;
|
||||
@@ -1821,16 +1819,13 @@ static int SQLITE_TCLAPI test_changegroup_cmd(
|
||||
break;
|
||||
}
|
||||
|
||||
case 12: /* change_finishne */
|
||||
case 11: { /* change_finish */
|
||||
int bDiscard = 0;
|
||||
if( TCL_OK!=Tcl_GetBooleanFromObj(interp, objv[2], &bDiscard) ){
|
||||
rc = TCL_ERROR;
|
||||
}else{
|
||||
char *zErr = 0;
|
||||
char **pz = &zErr;
|
||||
if( iSub==12 ) pz = 0;
|
||||
rc = sqlite3changegroup_change_finish(p->pGrp, bDiscard, pz);
|
||||
rc = sqlite3changegroup_change_finish(p->pGrp, bDiscard, &zErr);
|
||||
if( rc!=SQLITE_OK ){
|
||||
rc = test_session_error(interp, rc, zErr);
|
||||
}
|
||||
@@ -1838,7 +1833,7 @@ static int SQLITE_TCLAPI test_changegroup_cmd(
|
||||
break;
|
||||
}
|
||||
|
||||
case 13: { /* config */
|
||||
case 12: { /* config */
|
||||
struct OptionName {
|
||||
const char *zOpt;
|
||||
int op;
|
||||
@@ -1867,7 +1862,7 @@ static int SQLITE_TCLAPI test_changegroup_cmd(
|
||||
break;
|
||||
}
|
||||
|
||||
case 14: { /* change_text-1 */
|
||||
case 13: { /* change_text-1 */
|
||||
int bNew = 0;
|
||||
int iCol = 0;
|
||||
if( TCL_OK!=testGetNewOrOld(interp, objv[2], &bNew)
|
||||
|
||||
@@ -352,7 +352,7 @@ else
|
||||
SQLITE_C_IS_SEE = 0
|
||||
else
|
||||
SQLITE_C_IS_SEE = 1
|
||||
$(info $(emo.lock)$(emo.lock)$(emo.lock) This is an SEE build $(emo.lock)$(emo.lock)$(emo.lock))
|
||||
$(info This is an SEE build)
|
||||
endif
|
||||
endif
|
||||
|
||||
|
||||
@@ -245,5 +245,4 @@ _fiddle_reset_db
|
||||
_fiddle_db_handle
|
||||
_fiddle_db_vfs
|
||||
_fiddle_export_db
|
||||
_fiddle_get_prompt
|
||||
//#/if fiddle
|
||||
|
||||
@@ -363,15 +363,11 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
||||
called this way, the resolved value of the returned Promise is
|
||||
the number of bytes written to the target file.
|
||||
|
||||
It very specifically requires the input to be an SQLite3 database
|
||||
and throws if that's not the case. It does so in order to
|
||||
prevent this function from taking on a larger scope than it is
|
||||
specifically intended to. i.e. we do not want it to become a
|
||||
convenience for importing arbitrary files into OPFS. Caveat: as
|
||||
of 3.54 in SEE builds, the "is this a db?" check is necessarily
|
||||
lax to account for SEE-encrypted databases not having a legible
|
||||
header. In such builds, only the db size is relevant for the
|
||||
check.
|
||||
It very specifically requires the input to be an SQLite3
|
||||
database and throws if that's not the case. It does so in
|
||||
order to prevent this function from taking on a larger scope
|
||||
than it is specifically intended to. i.e. we do not want it to
|
||||
become a convenience for importing arbitrary files into OPFS.
|
||||
|
||||
This routine rewrites the database header bytes in the output
|
||||
file (not the input array) to force disabling of WAL mode.
|
||||
|
||||
@@ -771,11 +771,7 @@ globalThis.sqlite3ApiBootstrap = async function sqlite3ApiBootstrap(
|
||||
lead bytes of that buffer do not hold a SQLite3 database header,
|
||||
else it returns without side effects.
|
||||
|
||||
Added in 3.44. As of 3.54 in SEE builds it performs only a
|
||||
rudimentary length check and does not fail for invalid header
|
||||
bytes, under the assumption that the input may be an encrypted
|
||||
db. We cannot unambiguously distinguish an encrypted db from
|
||||
garbage bytes.
|
||||
Added in 3.44.
|
||||
*/
|
||||
affirmDbHeader: function(bytes){
|
||||
if(bytes instanceof ArrayBuffer) bytes = new Uint8Array(bytes);
|
||||
@@ -785,12 +781,7 @@ globalThis.sqlite3ApiBootstrap = async function sqlite3ApiBootstrap(
|
||||
}
|
||||
for(let i = 0; i < header.length; ++i){
|
||||
if( header.charCodeAt(i) !== bytes[i] ){
|
||||
//#if enable-see
|
||||
break /* assume this might be an encrypted db.
|
||||
https://sqlite.org/see/forumpost/f84bef3552 */;
|
||||
//#else
|
||||
toss3("Input does not contain an SQLite3 database header.");
|
||||
//#/if
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -800,8 +791,7 @@ globalThis.sqlite3ApiBootstrap = async function sqlite3ApiBootstrap(
|
||||
database. It only examines the size and header, but further
|
||||
checks may be added in the future.
|
||||
|
||||
Added in 3.44. See notes in affirmDbHeader() regarding SEE
|
||||
builds.
|
||||
Added in 3.44.
|
||||
*/
|
||||
affirmIsDb: function(bytes){
|
||||
if(bytes instanceof ArrayBuffer) bytes = new Uint8Array(bytes);
|
||||
|
||||
@@ -1040,11 +1040,19 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
||||
importDb(name, bytes){
|
||||
if( bytes instanceof ArrayBuffer ) bytes = new Uint8Array(bytes);
|
||||
else if( bytes instanceof Function ) return this.importDbChunked(name, bytes);
|
||||
util.affirmIsDb(bytes);
|
||||
const sah = this.#mapFilenameToSAH.get(name)
|
||||
|| this.nextAvailableSAH()
|
||||
|| toss("No available handles to import to.");
|
||||
const n = bytes.byteLength;
|
||||
if(n<512 || n%512!=0){
|
||||
toss("Byte array size is invalid for an SQLite db.");
|
||||
}
|
||||
const header = "SQLite format 3";
|
||||
for(let i = 0; i < header.length; ++i){
|
||||
if( header.charCodeAt(i) !== bytes[i] ){
|
||||
toss("Input does not contain an SQLite database header.");
|
||||
}
|
||||
}
|
||||
const nWrote = sah.write(bytes, {at: HEADER_OFFSET_DATA});
|
||||
if(nWrote != n){
|
||||
this.setAssociatedPath(sah, '', 0);
|
||||
|
||||
@@ -1557,7 +1557,7 @@ SQLITE_WASM_EXPORT2(int,sqlite3__wasm_posix_create_file,
|
||||
SQLITE_WASM_EXPORT2(const char *,sqlite3__wasm_kvvfsMakeKey,
|
||||
(const char *zClass, const char *zKeyIn)){
|
||||
static char buf[SQLITE_KVOS_SZ+1] = {0};
|
||||
assert(sqlite3KvvfsMethods.nKeySize>=32);
|
||||
assert(sqlite3KvvfsMethods.nKeySize>24);
|
||||
if( zClass && *zClass ){
|
||||
kvrecordMakeKey(zClass, zKeyIn, buf);
|
||||
return buf;
|
||||
|
||||
@@ -172,7 +172,7 @@
|
||||
if(capi.sqlite3_vfs_find("opfs")){
|
||||
stdout("\nOPFS is available. To open a persistent db, use:\n\n",
|
||||
" .open file:name?vfs=opfs\n\nbut note that some",
|
||||
"features (e.g. upload) do not work with OPFS.");
|
||||
"features (e.g. upload) do not yet work with OPFS.");
|
||||
}
|
||||
stdout('\nEnter ".help" for usage hints.');
|
||||
return true;
|
||||
@@ -186,7 +186,6 @@
|
||||
if(!f._){
|
||||
if(!this.runMain()) return;
|
||||
f._ = sqlite3.wasm.xWrap('fiddle_exec', undefined, ['string']);
|
||||
f.getPrompt = sqlite3.wasm.xWrap('fiddle_get_prompt', 'string:dealloc', []);
|
||||
}
|
||||
if(fiddleModule.isDead){
|
||||
stderr("shell module has exit()ed. Cannot run SQL.");
|
||||
@@ -208,8 +207,7 @@
|
||||
wMsg('working','end');
|
||||
wMsg('wasm-info', {
|
||||
pointerSize: sqlite3.wasm.ptr.size,
|
||||
heapSize: sqlite3.wasm.heap8().byteLength,
|
||||
prompt: f.getPrompt()
|
||||
heapSize: sqlite3.wasm.heap8().byteLength
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
@@ -349,10 +349,9 @@
|
||||
SF.e.wasmInfo.innerText = 'WASM: '+(
|
||||
4===v.pointerSize ? 32 : 64
|
||||
)+'-bit'
|
||||
+' heap: '+Number(v.heapSize)
|
||||
//+' heap size: '+Number(v.heapSize)
|
||||
// Heap size is not changing even when loading a huge db?
|
||||
;
|
||||
SF.jqTerm?.set_prompt?.(v.prompt);
|
||||
});
|
||||
|
||||
/* querySelectorAll() proxy */
|
||||
@@ -866,14 +865,8 @@
|
||||
const jqeTerm = window.jQuery(SF.e.terminal).empty();
|
||||
SF.jqTerm = jqeTerm.terminal(SF.dbExec.bind(SF),{
|
||||
prompt: 'sqlite> ',
|
||||
greetings: false /* the docs incorrectly call this 'greeting' */
|
||||
greetings: false /* note that the docs incorrectly call this 'greeting' */
|
||||
});
|
||||
/* Disable all special handling of the input:
|
||||
https://sqlite.org/forum/forumpost/c6665017c0dbba1f
|
||||
https://github.com/jcubic/jquery.terminal/issues/1044 */
|
||||
const no_formatting = (str)=>window.jQuery.terminal.escape_formatting(str);
|
||||
no_formatting.__meta__ = true;
|
||||
window.jQuery.terminal.new_formatter(no_formatting);
|
||||
EAll('.unhide-if-terminal-available').forEach(e=>{
|
||||
e.classList.remove('hidden');
|
||||
});
|
||||
@@ -897,6 +890,5 @@
|
||||
SF.dbExec(urlParams.get('sql') || null);
|
||||
delete SF.ForceResizeKludge.$disabled;
|
||||
SF.ForceResizeKludge();
|
||||
globalThis.fiddle = SF;
|
||||
}/*onSFLoaded()*/;
|
||||
})();
|
||||
|
||||
@@ -322,9 +322,8 @@
|
||||
<h1>Usage Summary</h1>
|
||||
|
||||
<ul>
|
||||
<li class='hidden unhide-if-terminal-available'>In
|
||||
<a href="https://github.com/jcubic/jquery.terminal">"terminal
|
||||
mode"</a> it accepts input just like the CLI shell does.</li>
|
||||
<li class='hidden unhide-if-terminal-available'>In "terminal
|
||||
mode" it accepts input just like the CLI shell does.</li>
|
||||
<li>In split-view mode:
|
||||
<ul>
|
||||
<li>Input can be executed with either the Run
|
||||
|
||||
+22
-68
@@ -380,19 +380,16 @@ globalThis.sqlite3InitModule = sqlite3InitModule;
|
||||
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 _synchronous_ function which is
|
||||
expected to unlink() the db file if the ctorOpfFunc does not do
|
||||
so when passed true (namely for kvvfs).
|
||||
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 the result of
|
||||
ctorOptFunc(bool), writes some secret info into it, and re-opens
|
||||
it twice to confirm that it can be read with an SEE key and
|
||||
cannot be read without one.
|
||||
|
||||
If unlinkDbAtEnd is truthy then dbUnlink() is (on success)
|
||||
called before returning.
|
||||
This function initializes the db described by ctorOptFunc(...),
|
||||
writes some secret info into it, and re-opens it twice to
|
||||
confirm that it can be read with an SEE key and cannot be read
|
||||
without one.
|
||||
*/
|
||||
T.seeBaseCheck = function(ctor, ctorOptFunc, dbUnlink, unlinkDbAtEnd=true){
|
||||
T.seeBaseCheck = function(ctor, ctorOptFunc, dbUnlink){
|
||||
let initDb = true;
|
||||
const tryKey = function(keyKey, key, expectCount){
|
||||
let db;
|
||||
@@ -453,7 +450,7 @@ globalThis.sqlite3InitModule = sqlite3InitModule;
|
||||
tryKey('hexkey', hexFoo, 3);
|
||||
T.assert( !initDb );
|
||||
tryKey('hexkey', hexFoo, 6);
|
||||
if( unlinkDbAtEnd ) dbUnlink();
|
||||
dbUnlink();
|
||||
};
|
||||
//#/if enable-see
|
||||
|
||||
@@ -3599,7 +3596,7 @@ globalThis.sqlite3InitModule = sqlite3InitModule;
|
||||
name: 'kvvfs SEE encryption in sessionStorage',
|
||||
predicate: ()=>(!!globalThis.sessionStorage
|
||||
|| "sessionStorage is not available"),
|
||||
test: async function(sqlite3){
|
||||
test: function(sqlite3){
|
||||
const JDb = sqlite3.oo1.JsStorageDb;
|
||||
T.seeBaseCheck(JDb,
|
||||
(isInit)=>{
|
||||
@@ -3926,39 +3923,16 @@ globalThis.sqlite3InitModule = sqlite3InitModule;
|
||||
.t({
|
||||
name: '@vfsName@ with SEE encryption',
|
||||
predicate: (sqlite3)=>!!sqlite3.oo1.@oo1Ctor@,
|
||||
test: async function(sqlite3){
|
||||
const ctor = sqlite3.oo1.@oo1Ctor@;
|
||||
const filename = 'sqlite3-see.edb';
|
||||
const ctorOpt = {filename: 'file:///'+filename};
|
||||
const opfs = sqlite3.opfs;
|
||||
const initer = function(isInit){
|
||||
const opt = {...ctorOpt};
|
||||
if( isInit ) opt.filename += '?delete-before-open=1';
|
||||
return opt;
|
||||
};
|
||||
|
||||
T.seeBaseCheck(ctor, initer, ()=>{}, false);
|
||||
/*
|
||||
Ensure that ctor.importDb() correctly handles SEE-encrypted
|
||||
dbs. For more details search below for forumpost/f84bef3552.
|
||||
*/
|
||||
let exp = await opfs.getRootDir()
|
||||
.then(d=>d.getFileHandle(filename))
|
||||
.then(fh=>fh.getFile())
|
||||
.then(f=>f.bytes());
|
||||
await opfs.unlink(filename);
|
||||
T.assert( exp.byteLength > 100 && 0===(exp.byteLength % 512) );
|
||||
const got = await ctor.importDb(filename, exp);
|
||||
T.assert(exp.byteLength === got);
|
||||
exp = null;
|
||||
const db = new ctor({...initer(false), key: 'foo'});
|
||||
try{
|
||||
T.assert( 4 === db.selectValue("select count(*) from t") )
|
||||
.assert( 6 === db.selectValue("select sum(a) from t") );
|
||||
}finally{
|
||||
db.close();
|
||||
await opfs.unlink(filename);
|
||||
}
|
||||
test: function(sqlite3){
|
||||
T.seeBaseCheck(
|
||||
sqlite3.oo1.@oo1Ctor@,
|
||||
function(isInit){
|
||||
const opt = {filename: 'file:///sqlite3-see.edb'};
|
||||
if( isInit ) opt.filename += '?delete-before-open=1';
|
||||
return opt;
|
||||
},
|
||||
()=>{}
|
||||
);
|
||||
}
|
||||
})
|
||||
//#/if enable-see
|
||||
@@ -3966,7 +3940,7 @@ globalThis.sqlite3InitModule = sqlite3InitModule;
|
||||
//#/query
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
T.g('OPFS SyncAccessHandle Pool VFS',
|
||||
(sqlite3)=>((isWorker() && !!sqlite3.installOpfsSAHPoolVfs) || "requires OPFS SAH Pool APIs"))
|
||||
(sqlite3)=>(isWorker() && !!sqlite3.installOpfsSAHPoolVfs || "requires OPFS SAH Pool APIs"))
|
||||
.t({
|
||||
name: 'SAH sanity checks',
|
||||
test: async function(sqlite3){
|
||||
@@ -4162,32 +4136,12 @@ globalThis.sqlite3InitModule = sqlite3InitModule;
|
||||
}
|
||||
let poolUtil;
|
||||
const P1 = await inst(poolConfig).then(u=>poolUtil = u).catch(catcher);
|
||||
if( !poolUtil ) return;
|
||||
const dbFile = '/sqlite3-see.edb';
|
||||
T.seeBaseCheck(
|
||||
poolUtil.OpfsSAHPoolDb,
|
||||
(isInit)=>{return {filename: dbFile}},
|
||||
()=>poolUtil.unlink(dbFile),
|
||||
false
|
||||
()=>poolUtil.unlink(dbFile)
|
||||
);
|
||||
/* Ensure that importDb() does the right thing for an
|
||||
SEE-encrypted DB: https://sqlite.org/see/forumpost/f84bef3552 */
|
||||
let exp = poolUtil.exportFile(dbFile);
|
||||
T.assert( exp.byteLength > 100 && 0===(exp.byteLength % 512) );
|
||||
poolUtil.unlink(dbFile);
|
||||
const got = poolUtil.importDb(dbFile, exp);
|
||||
T.assert(exp.byteLength === got);
|
||||
exp = null;
|
||||
const db = new poolUtil.OpfsSAHPoolDb({
|
||||
filename: dbFile,
|
||||
key: 'foo'
|
||||
});
|
||||
try{
|
||||
T.assert( 4 === db.selectValue("select count(*) from t") )
|
||||
.assert( 6 === db.selectValue("select sum(a) from t") );
|
||||
}finally{
|
||||
db.close();
|
||||
}
|
||||
poolUtil.removeVfs();
|
||||
}
|
||||
})/*opfs-sahpool with SEE*/
|
||||
|
||||
@@ -986,7 +986,6 @@ FUZZCHECK_SRC = sqlite3.c \
|
||||
$(TOP)/ext/misc/base85.c \
|
||||
$(TOP)/ext/misc/completion.c \
|
||||
$(TOP)/ext/misc/decimal.c \
|
||||
$(TOP)/ext/misc/diskused.c \
|
||||
$(TOP)/ext/misc/ieee754.c \
|
||||
$(TOP)/ext/misc/randomjson.c \
|
||||
$(TOP)/ext/misc/regexp.c \
|
||||
@@ -2345,7 +2344,6 @@ SHELL_DEP = \
|
||||
$(TOP)/ext/misc/base85.c \
|
||||
$(TOP)/ext/misc/completion.c \
|
||||
$(TOP)/ext/misc/decimal.c \
|
||||
$(TOP)/ext/misc/diskused.c \
|
||||
$(TOP)/ext/misc/fileio.c \
|
||||
$(TOP)/ext/misc/ieee754.c \
|
||||
$(TOP)/ext/misc/memtrace.c \
|
||||
@@ -2422,10 +2420,6 @@ sqlite3session.o: $(TOP)/ext/session/sqlite3session.c $(DEPS_EXT_COMMON)
|
||||
stmt.o: $(TOP)/ext/misc/stmt.c $(DEPS_EXT_COMMON)
|
||||
$(T.cc.extension) -c $(TOP)/ext/misc/stmt.c
|
||||
|
||||
$(AUXTEST): $(TOP)/test/c/$(AUXTEST).c
|
||||
$(T.cc.sqlite) -o $@ $(TOP)/test/c/$(AUXTEST).c sqlite3.o $(LDFLAGS.libsqlite3)
|
||||
|
||||
|
||||
#
|
||||
# Windows section
|
||||
#
|
||||
@@ -2509,7 +2503,7 @@ tidy:
|
||||
# Removes build products and test logs. Retains ./configure outputs.
|
||||
#
|
||||
clean: tidy
|
||||
rm -rf omittest* testrunner* testrun_* testdir*
|
||||
rm -rf omittest* testrunner* testdir*
|
||||
|
||||
#
|
||||
# Clean up everything. No exceptions. From an out-of-tree build which
|
||||
|
||||
@@ -1,15 +1,14 @@
|
||||
C Revert\sthe\snative\simpl\sof\skvvfs's\sxOpen()\s(as\sdistinct\sfrom\sthe\sJS\simpl\swhich\sthe\swasm\sbuild\suses)\sto\sthe\shistorical\sdb\sname\srestrictions\sof\s'local'\sor\s'session',\sfailing\swith\sSQLITE_CANTOPEN\sif\spassed\sanother\sname.\s[ec866b04d088e53b]\soverhauled\ssupport\sfor\skvvfs\sdb\snames\sin\sJS\sbut\sit\sturns\sout\sthat\sthe\snative\simpl\sstill\srelies\son\sthose\snames\sin\sorder\sto\smatch\sjournals\sto\sdatabases.\sCorrect\sa\srelated\stoo-lenient\sassert()\sin\sthe\sWASM\spieces.
|
||||
D 2026-06-15T12:22:06.262
|
||||
C Version\s3.53.2
|
||||
D 2026-06-03T19:12:13.350
|
||||
F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x
|
||||
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
|
||||
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
|
||||
F AGENTS.md 44ddfb38ef23e277888bd70ae378e6cbf5f5cab0e2a4420bd21d89b6caff7a4a
|
||||
F LICENSE.md 6bc480fc673fb4acbc4094e77edb326267dd460162d7723c7f30bee2d3d9e97d
|
||||
F Makefile.in 5fda086f33b144da08119255da1d2557f983d0764a13707f05acf0159fd89ba5
|
||||
F Makefile.linux-generic bd3e3cacd369821a6241d4ea1967395c962dfe3057e38cb0a435cee0e8b789d0
|
||||
F Makefile.msc 46ff6560f0046d92017ccafc91a3cd6cb2b54fbd25c56b2b6890cd84ed268159
|
||||
F README.md f00091ffb5c6379b783afb57ca5f443a5742e119082f37c407f64a5e16c56346
|
||||
F VERSION 99cf3be5f13d091183e4314b7fc2e0c0e69accfbe64608b45a313338bbdd7b62
|
||||
F Makefile.msc 1d6098faf066e14bc181f9460b002285248eee32cfaaa7babcb37f4381928408
|
||||
F README.md f49fbd826941842e348242f3ab62f240c985ceafdf8fbe576abf4eb75317468c
|
||||
F VERSION 7441adea0de9103e8e0541375ba322afed1a5d614a39bffcdbda09b69619bba7
|
||||
F art/icon-243x273.gif 9750b734f82fdb3dc43127753d5e6fbf3b62c9f4e136c2fbf573b2f57ea87af5
|
||||
F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d87031
|
||||
F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2
|
||||
@@ -45,10 +44,10 @@ F autosetup/cc-lib.tcl 493c5935b5dd3bf9bd4eca89b07c8b1b1a9356d61783035144e21795f
|
||||
F autosetup/cc-shared.tcl 163eda58c14cd662fd8a504bd2ad8a716ef4db7015dc1de0095d5de8dd601a4b
|
||||
F autosetup/cc.tcl c0fcc50ca91deff8741e449ddad05bcd08268bc31177e613a6343bbd1fd3e45f
|
||||
F autosetup/find_tclconfig.tcl e64886ffe3b982d4df42cd28ed91fe0b5940c2c5785e126c1821baf61bc86a7e
|
||||
F autosetup/jimsh0.c 740dc8cbfaedaff1f27b54b32e0015b22fa6c1a439492b9795968d61e56bab75
|
||||
F autosetup/jimsh0.c 916bbdf8023fbda9937afae57d81a853d8c2ea00f2320aa27becbc33574f963d
|
||||
F autosetup/pkg-config.tcl 4e635bf39022ff65e0d5434339dd41503ea48fc53822c9c5bde88b02d3d952ba
|
||||
F autosetup/proj.tcl 67683f214977a416baafc4c1020f9940ff047a7306b2292c5872d6287460b7d5
|
||||
F autosetup/sqlite-config.tcl 2205b8bcc193a5d46584ebc1cf44c7a93a977d155e20dc38b18dcce720e58074
|
||||
F autosetup/proj.tcl ce301197f364f7ce2acabbbd84b43d19e917ec73653157ca134a06f32d322712
|
||||
F autosetup/sqlite-config.tcl 7ff8dad28d6ea2ad95f0288c61274042e6594145511b58ec4d42daacbee15f0d
|
||||
F autosetup/system.tcl 51d4be76cd9a9074704b584e5c9cbba616202c8468cf9ba8a4f8294a7ab1dba9
|
||||
F autosetup/teaish/README.txt b40071e6f8506500a2f7f71d5fc69e0bf87b9d7678dd9da1e5b4d0acbf40b1ca
|
||||
F autosetup/teaish/core.tcl e014dd95900c7f9a34e8e0f460f47e94841059827bce8b4c49668b0c7ae3f1a0
|
||||
@@ -64,7 +63,7 @@ F doc/jsonb.md acd77fc3a709f51242655ad7803510c886aa8304202fa9cf2abc5f5c4e9d7ae5
|
||||
F doc/lemon.html 2085fda0a90a94fe92159a79dccc5c30d5a2313524887a31659cd66162f17233
|
||||
F doc/pager-invariants.txt 83aa3a4724b2d7970cc3f3461f0295c46d4fc19a835a5781cbb35cb52feb0577
|
||||
F doc/tcl-extension-testing.md b88861804fc1eaf83249f8e206334189b61e150c360e1b80d0dcf91af82354f5
|
||||
F doc/testrunner.md 3589f7914d36adaff6d108566e09b2c6166887bea00580e5343f8b43615ffe12
|
||||
F doc/testrunner.md daffa0ebbbe397a73537ae1b19b3124d489ce5f89dfe570781d1f1ef1809597c
|
||||
F doc/trusted-schema.md 33625008620e879c7bcfbbfa079587612c434fa094d338b08242288d358c3e8a
|
||||
F doc/vdbesort-memory.md 4da2639c14cd24a31e0af694b1a8dd37eaf277aff3867e9a8cc14046bc49df56
|
||||
F doc/vfs-shm.txt 1a55f3f0e7b6745931b117ba5c9df3640d7a0536f532ef0052563100f4416f86
|
||||
@@ -72,15 +71,15 @@ F doc/wal-lock.md 7db0cd61e2000b545b78ce89b0c2a9a8dd8d64c097839258ac10d7c5c4156e
|
||||
F ext/README.md 6eb1ac267d917767952ed0ef63f55de003b6a5da433ce1fa389e1a9532e73132
|
||||
F ext/expert/README.md b321c2762bb93c18ea102d5a5f7753a4b8bac646cb392b3b437f633caf2020c3
|
||||
F ext/expert/expert.c d548d603a4cc9e61f446cc179c120c6713511c413f82a4a32b1e1e69d3f086a4
|
||||
F ext/expert/expert1.test 5292f9f488ca396fa0973e8ed5d26914bc29a0cdb5979db3d9e05416f30858c3
|
||||
F ext/expert/sqlite3expert.c 1a5296245bf80c201b2f5fa5947ef54a7d2b7e90428cb86240dd18076242ec1f
|
||||
F ext/expert/expert1.test d9dfbf7fb527cfd43049e30a6238ef02c94484041fa4461ed41acbc6435425d6
|
||||
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
|
||||
F ext/fts3/README.syntax b72477722e9b4fe43f8403227d790a1c94221bfad15c27863a4b36d1052e892b
|
||||
F ext/fts3/README.tokenizers b92bdeb8b46503f0dd301d364efc5ef59ef9fa8e2758b8e742f39fa93a2e422d
|
||||
F ext/fts3/README.txt 8c18f41574404623b76917b9da66fcb0ab38328d
|
||||
F ext/fts3/fts3.c 4e62e96794ee8a5e73b1357e63d9b7749c30e0f712db3dfe27cd515e50afce9d
|
||||
F ext/fts3/fts3.c 1716994c40715223431d98e5132c40a3c1a00c011c5bde2270bad1bd06be3ccd
|
||||
F ext/fts3/fts3.h 3a10a0af180d502cecc50df77b1b22df142817fe
|
||||
F ext/fts3/fts3Int.h 277f32f304e82f4397fc2a74793c0a95318b7abb9670b519e4805a00946cbd9b
|
||||
F ext/fts3/fts3_aux.c bbb614abcc995bf748cba4717e9fd8de67898e33c80f60379f6feb2358189b4b
|
||||
@@ -89,7 +88,7 @@ F ext/fts3/fts3_hash.c d9dba473741445789330c7513d4f65737c92df23c3212784312931641
|
||||
F ext/fts3/fts3_hash.h 39cf6874dc239d6b4e30479b1975fe5b22a3caaf
|
||||
F ext/fts3/fts3_icu.c 305ce7fb6036484085b5556a9c8e62acdc7763f0f4cdf5fd538212a9f3720116
|
||||
F ext/fts3/fts3_porter.c 024417020c57dd1ab39816f5fe6cf45222a857b78a1f6412f040ada1ceabd4ff
|
||||
F ext/fts3/fts3_snippet.c 004923c49dca8c711f83fd31d3abe2e663df174afeae096b1c902cc52fda2097
|
||||
F ext/fts3/fts3_snippet.c 65e178107b59ad4724a11339a645f2e3789f3cf59b2f4e29c90efd864e53c5b4
|
||||
F ext/fts3/fts3_term.c 6a96027ad364001432545fe43322b6af04ed28bb5619ec51af1f59d0710d6d69
|
||||
F ext/fts3/fts3_test.c cc329471e573f95a6ea9fbca87e89dcfa1d355591c80172ffcd759ac521d25d8
|
||||
F ext/fts3/fts3_tokenize_vtab.c 66eba6c2baa04b2b15e80d68341b8fd0b4d3831f6b2edb33916a2906ff2d4389
|
||||
@@ -98,7 +97,7 @@ F ext/fts3/fts3_tokenizer.h 64c6ef6c5272c51ebe60fc607a896e84288fcbc3
|
||||
F ext/fts3/fts3_tokenizer1.c c1de4ae28356ad98ccb8b2e3388a7fdcce7607b5523738c9afb6275dab765154
|
||||
F ext/fts3/fts3_unicode.c de426ff05c1c2e7bce161cf6b706638419c3a1d9c2667de9cb9dc0458c18e226
|
||||
F ext/fts3/fts3_unicode2.c 416eb7e1e81142703520d284b768ca2751d40e31fa912cae24ba74860532bf0f
|
||||
F ext/fts3/fts3_write.c b84f9808f6df7b19db34af2397d82a7c5db4d30486c428f4f296d286996cea02
|
||||
F ext/fts3/fts3_write.c d218b687fb55bce8c9340c6dbb368a10d94647cbe39801d85492d576a4e7da75
|
||||
F ext/fts3/fts3speed.tcl b54caf6a18d38174f1a6e84219950d85e98bb1e9
|
||||
F ext/fts3/tool/fts3cov.sh c331d006359456cf6f8f953e37f2b9c7d568f3863f00bb5f7eb87fea4ac01b73
|
||||
F ext/fts3/tool/fts3view.c 413c346399159df81f86c4928b7c4a455caab73bfbc8cd68f950f632e5751674
|
||||
@@ -109,18 +108,18 @@ F ext/fts3/unicode/parseunicode.tcl a981bd6466d12dd17967515801c3ff23f74a281be1a0
|
||||
F ext/fts5/extract_api_docs.tcl 009cf59c77afa86d137b0cca3e3b1a5efbe2264faa2df233f9a7aa8563926d15
|
||||
F ext/fts5/fts5.h ff5d3cc88b29e41612bfb29eb723e29e38973de62ca75ba3e8f94ccb67f5b5f2
|
||||
F ext/fts5/fts5Int.h 8d98f8e180fe28d6067e240ed45b9011735d29d5cfb5bac194e1e376baa7c708
|
||||
F ext/fts5/fts5_aux.c 27af933e1a052d9f12d62a45bc60e0b65023997e0cea8f0476ef3cf66e724599
|
||||
F ext/fts5/fts5_aux.c 042da27e97d38071312c111cf18f3cb7983b75ba5e724aa1c3164e61e90f428a
|
||||
F ext/fts5/fts5_buffer.c dcc3f0352339fe79c9d8abbc1c2009bc3469206467880bf43558447ef4f846fb
|
||||
F ext/fts5/fts5_config.c bfba970fe1e4eed18ee57c8d51458e226db9a960ddf775c5e50e3d76603a667e
|
||||
F ext/fts5/fts5_expr.c b906c59e9e842805cc3eea4e131b822e586bb01260e542f67920c61798dcb53d
|
||||
F ext/fts5/fts5_hash.c 341a08ad0153b397b819ef3d7a7959c1dc3c84a6988a431d93dece8bd62ae10e
|
||||
F ext/fts5/fts5_index.c 96ccae2fa74b419b1ce56ae10523d681f74dba3c7b86fff6948cfa05c49e1e75
|
||||
F ext/fts5/fts5_expr.c 71d48e8cf0358deace4949276647d317ff7665db6db09f40b81e2e7fe6664c7c
|
||||
F ext/fts5/fts5_hash.c d5871df92ce3fa210a650cf419ee916b87c29977e86084d06612edf772bff6f5
|
||||
F ext/fts5/fts5_index.c 1627d9c184dec6be913647ba1e31a906e825b8460c9575e1c367ee27fe847f0c
|
||||
F ext/fts5/fts5_main.c b0fed47b3b4420ba6810373480a75bc28a9c0b7d16478d19a396436fb3ff17d7
|
||||
F ext/fts5/fts5_storage.c 19bc7c4cbe1e6a2dd9849ef7d84b5ca1fcbf194cefc3e386b901e00e08bf05c2
|
||||
F ext/fts5/fts5_tcl.c 2be6cc14f9448f720fd4418339cd202961a0801ea9424cb3d9de946f8f5a051c
|
||||
F ext/fts5/fts5_test_mi.c 4308d5658cb1f5eee5998dcbaac7d5bdf7a2ef43c8192ca6e0c843f856ccee26
|
||||
F ext/fts5/fts5_test_tok.c 6021033bd4f4feffe8579efb6e1f58156ed462256bf99a2acdbd629246529204
|
||||
F ext/fts5/fts5_tokenize.c 0469b30e7bf25255fbb7c101e2b549a521fb501342e7269cf73cbb6b2dbd8da2
|
||||
F ext/fts5/fts5_tokenize.c 21078ea9f496ba9b0c4dd15ac2404933251df8bebab9907f6a5a47d4321c77fd
|
||||
F ext/fts5/fts5_unicode2.c 536a6dae41d16edadd6a6b58c56e2ebbb133f0dfe757562a2edbcdc9b8362e50
|
||||
F ext/fts5/fts5_varint.c e64d2113f6e1bfee0032972cffc1207b77af63319746951bf1d09885d1dadf80
|
||||
F ext/fts5/fts5_vocab.c bebee4aabcd056a44b3731166433cfdecf17ece750c08cb58733216222bd39e2
|
||||
@@ -132,7 +131,7 @@ F ext/fts5/test/fts5ab.test c7e5c1519afb20366cb40d0179897a3c39d9fc06ba6b9c286d79
|
||||
F ext/fts5/test/fts5ac.test 4a73626de86f3d17c95738034880c4f0de8d54741fb943d819b528373657e59b
|
||||
F ext/fts5/test/fts5ad.test 058e616612964e61d19f70295f0e6eaedceb4b29b1fbf4f859615ef7e779dc22
|
||||
F ext/fts5/test/fts5ae.test 3d49edbd50bb0684199a2e7568aeb30d1d29718f5c0f61751983740fa836d15f
|
||||
F ext/fts5/test/fts5af.test 06f05ef35e8c66d8200204379e03d386673cf0c6f052bd67ddc3091dac3d32e9
|
||||
F ext/fts5/test/fts5af.test ae81f08b8da4c5f9b3ec1ef538a4ab6b7c278e92fa9058d6dc5d842c5d9771b9
|
||||
F ext/fts5/test/fts5ag.test 6667807b5d3fbf460892e756763fbe3d87a2fffe345a06514ba010ca6f6641f7
|
||||
F ext/fts5/test/fts5ah.test e1f01314b35745a30e1b494b46045b82005d71cae74f1ebd9f1338566b77f9fc
|
||||
F ext/fts5/test/fts5ai.test cbe26d78030998f535bc103f37915350b137a822c71a9db439a077d7666a3539
|
||||
@@ -147,7 +146,6 @@ F ext/fts5/test/fts5auxdata.test 372549088ff792655f73e62b9dfaf4863ce74f5e604c06c
|
||||
F ext/fts5/test/fts5bigid.test 2860854c2561a57594192b00c33a29f91cb85e25f3d6c03b5c2b8f62708f39dd
|
||||
F ext/fts5/test/fts5bigpl.test 8f09858aab866c33593560e6480b2b6975ae7ff29ca32ad7b77e2da61402f8ef
|
||||
F ext/fts5/test/fts5bigtok.test 541119e616c637caea925a8c028c37c2c29e94383e00aa2f9198d530724b6e36
|
||||
F ext/fts5/test/fts5bigtok2.test d519c0c7c45fcbe75093cb9f4ea47defabbb4e8dd5d44411c8b12da47df538d9
|
||||
F ext/fts5/test/fts5blob.test 9644a5f917306690e08c5f89a470a3f2489376eaa52026eeca3209d149d6af74
|
||||
F ext/fts5/test/fts5cat.test bf67dd335f964482ee658287521b81e2b88697b45eb7f73933e15f198ed447cb
|
||||
F ext/fts5/test/fts5circref.test 0918c69440a73fff429bc9797b07086fc74d018eb3abb1cf9738980390bb2713
|
||||
@@ -171,7 +169,7 @@ F ext/fts5/test/fts5corrupt6.test 2d72db743db7b5d9c9a6d0cfef24d799ed1aa5e8192b66
|
||||
F ext/fts5/test/fts5corrupt7.test 9664c15360e8b649ad76f457a0bbf5a7271b8eff1a8ee141ea039bc63240c934
|
||||
F ext/fts5/test/fts5corrupt8.test 0b10750caf8aa23fa1c379ca4caf6130d41454505e4d5315590f4061eedcbe44
|
||||
F ext/fts5/test/fts5corrupt9.test 4253b9b59f33effac8b67da72ec34309c738aca2d5e8e2656bfbbd6a489a1dfe
|
||||
F ext/fts5/test/fts5corruptA.test 43bc56d8ec0ac87f82f6ac1700c16c902d952451f75f5c7dc02292c7b0a1d1b1
|
||||
F ext/fts5/test/fts5corruptA.test 7b31551444569420903d34ae50a55a1227d16969264f0b50de2dc812bc0b3414
|
||||
F ext/fts5/test/fts5corruptbig.test 9f95b40fa36e292feceab02b2ef06e21878bfa1ac7afefa138aae05518b51774
|
||||
F ext/fts5/test/fts5delete.test 2a5008f8b1174ef41d1974e606928c20e4f9da77d9f8347aed818994d89cced4
|
||||
F ext/fts5/test/fts5detail.test 54015e9c43ec4ba542cfb93268abdf280e0300f350efd08ee411284b03595cc4
|
||||
@@ -216,7 +214,7 @@ F ext/fts5/test/fts5merge2.test 3ebad1a59d6ad3fb66eff6523a09e95dc6367cbefb3cd731
|
||||
F ext/fts5/test/fts5misc.test 83d6c5101a092c5db8fb631cfdd69a6482e20528b2750427641ac9050d9d0381
|
||||
F ext/fts5/test/fts5multi.test a15bc91cdb717492e6e1b66fec1c356cb57386b980c7ba5af1915f97fe878581
|
||||
F ext/fts5/test/fts5multiclient.test 5ff811c028d6108045ffef737f1e9f05028af2458e456c0937c1d1b8dea56d45
|
||||
F ext/fts5/test/fts5near.test b173a56a3c45ac9fdd1626db2ddf923c42632489a4ccedfe68a806c1a0734286
|
||||
F ext/fts5/test/fts5near.test 33d60867581066e5db7016deb5d651628125d7ff4e0233a88175aa5b65874c74
|
||||
F ext/fts5/test/fts5onepass.test b56d4109e841c2bc83555c162515748780ea6e0c455c54cf4afd4bd940d14b84
|
||||
F ext/fts5/test/fts5optimize.test 264b9101721c17d06d1d174feb743fda3ddc89fad41dee980fef821428258e47
|
||||
F ext/fts5/test/fts5optimize2.test 795d4ae5f66a7239cf8d5aef4c2ea96aeb8bcd907bd9be0cfe22064fc71a44ed
|
||||
@@ -230,7 +228,7 @@ F ext/fts5/test/fts5origintext6.test 09eb1347cb0dceaebbebf3d3e6bd5d24c7c1006efdd
|
||||
F ext/fts5/test/fts5phrase.test bb2554bb61d15f859678c96dc89a7de415cd5fc3b7b54c29b82a0d0ad138091c
|
||||
F ext/fts5/test/fts5plan.test f8b0d752a818059a934cdc96c0f77de058a67a0a57bb3a8181d28307ab5b1626
|
||||
F ext/fts5/test/fts5porter.test 15b514fac8690b58e99c330efe5bf5615bc43f2fae4a3cca3f923dbaff55a0c0
|
||||
F ext/fts5/test/fts5porter2.test 1dab0fe41342ebed32ca36a145de3e50be9093cb71e9f5250f6ebc589207982a
|
||||
F ext/fts5/test/fts5porter2.test 94f0e4351e2c99b4e74f1fae05a4ddf1cb5b926620a8c14554160d075ddc7a59
|
||||
F ext/fts5/test/fts5prefix.test c0b7842f1a2d830c0b146cd438a95ea4c5a25635719ed0d973ffe41907338b83
|
||||
F ext/fts5/test/fts5prefix2.test a5bb43b8a2687efafa7ac4e5ccff6812015cf8cf18e3086bb0eb3126f30fbbf6
|
||||
F ext/fts5/test/fts5query.test 0320a7a4b58a6e3e50ec8910b301649da90ace675001f9e0bf6392750ad4591d
|
||||
@@ -251,7 +249,7 @@ F ext/fts5/test/fts5securefault.test c34a28c7cd2f31a8b8907563889e1329a97da975c08
|
||||
F ext/fts5/test/fts5simple.test 302cdb4f8a3350b091f4f1bccd82d05610428657f6f9e81c17703ba48267ec40
|
||||
F ext/fts5/test/fts5simple2.test d10d963a357b8ec77b99032e4c816459b4dbdb1f6eee25eada7ef3ed245cb2dc
|
||||
F ext/fts5/test/fts5simple3.test 4e03b82e669dc07bf9c9a04c306fa493764bc49c93e539896d87d88bd374fece
|
||||
F ext/fts5/test/fts5synonym.test e7facc771e5d00f24df64e169d466cb544b584f5cccc9a346eb30235e6dff82c
|
||||
F ext/fts5/test/fts5synonym.test becc8cea6cfc958a50b30c572c68cbfdf7455971d0fe988202ce67638d2c6cf6
|
||||
F ext/fts5/test/fts5synonym2.test 58f357b997cf2fedeeb9d0de4db9f880fa96fa2fe27a743bfe7d7b96895bdd87
|
||||
F ext/fts5/test/fts5tok1.test 1f7817499f5971450d8c4a652114b3d833393c8134e32422d0af27884ffe9cef
|
||||
F ext/fts5/test/fts5tok2.test dcacb32d4a2a3f0dd3215d4a3987f78ae4be21a2
|
||||
@@ -281,7 +279,7 @@ F ext/fts5/tool/loadfts5.tcl 95b03429ee6b138645703c6ca192c3ac96eaf093
|
||||
F ext/fts5/tool/mkfts5c.tcl 135b9e160f8e10211c10c5873d5e8c3eaebd3da9ec56a12ae4db157d4738ffe4
|
||||
F ext/fts5/tool/showfts5.tcl d54da0e067306663e2d5d523965ca487698e722c
|
||||
F ext/icu/README.txt 1f8d76e10d2385fc77914a14ccd99acfbaf68111dfcf26a360ad9063787f57fb
|
||||
F ext/icu/icu.c 4793f95ec022a2f77eade71a7fb2199095756e5b8187b4753ada0e25dbd134b5
|
||||
F ext/icu/icu.c 535d0d61f109e760a56e1afc450414ebfb0e2d594e2233b30315b815e3433ac2
|
||||
F ext/icu/sqliteicu.h fa373836ed5a1ee7478bdf8a1650689294e41d0c89c1daab26e9ae78a32075a8
|
||||
F ext/intck/intck1.test 53d885075abeb45aeb1eeffeaa8560b329060835ade4af5c44cf5fcb581c1e63
|
||||
F ext/intck/intck2.test a29343a8e65c5c3400e10747f394924f3df95a5b2de94f46e9b5c9b97f5e7339
|
||||
@@ -360,25 +358,25 @@ 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 972a250631d481f38736b46740bf7f5c9646a0f2bb53800543299a746ff1bac6
|
||||
F ext/misc/amatch.c 8d237cc014b3736922c26a76a451050d244aa4980c47c531f368f817b1e77b49
|
||||
F ext/misc/anycollseq.c 5ffdfde9829eeac52219136ad6aa7cd9a4edb3b15f4f2532de52f4a22525eddb
|
||||
F ext/misc/appendvfs.c 9642c7a194a2a25dca7ad3e36af24a0a46d7702168c4ad7e59c9f9b0e16a3824
|
||||
F ext/misc/base64.c 1445761667c16356e827fc6418294c869468be934429aaa8315035e76dd58acf
|
||||
F ext/misc/base85.c c713c7c81b05558c488cbdd8c68d612d5a97f9f0b8adf1167148dd7c89ce3f96
|
||||
F ext/misc/basexx.c 89ad6b76558efbceb627afd5e2ef1d84b2e96d9aaf9b7ecb20e3d00b51be6fcf
|
||||
F ext/misc/btreeinfo.c 5fe97f798a9ee90e92b3031ed7969ec3f558661bb36b821c3ba045a17cfb951c
|
||||
F ext/misc/blobio.c a867c4c4617f6ec223a307ebfe0eabb45e0992f74dd47722b96f3e631c0edb2a
|
||||
F ext/misc/btreeinfo.c 13bc9e9f1c13cde370d0e4a6a2683e9f1926a4cead7fb72c71871b11a06d78a1
|
||||
F ext/misc/cksumvfs.c 9d7d0cf1a8893ac5d48922bfe9f3f217b4a61a6265f559263a02bb2001259913
|
||||
F ext/misc/closure.c c983987a8d7846c3e52b1885ed3e20af7d4ca52a81a8f94ec6d1cd68f93acc86
|
||||
F ext/misc/completion.c 3f5db28e88c3313103b2dd86d910a2944fd500c46754e473493968ce81e994a4
|
||||
F ext/misc/compress.c 5cc142aa82d1589a31c384657d0418c0eb0871348a2201e5dca32d24a0dd6654
|
||||
F ext/misc/csv.c 5ca451b9ce77322c4ce8476766e7ed18160e5c8b19e7cab76e13006d631b9e8f
|
||||
F ext/misc/csv.c 5e9d4dd749e762c144104c0f01db5bf4458735b19081ebe481a64e589a66687a
|
||||
F ext/misc/dbdump.c 678f1b9ae2317b4473f65d03132a2482c3f4b08920799ed80feedd2941a06680
|
||||
F ext/misc/decimal.c 75f206e86072bd772041e6731d153517094e298a4b8c763a9f68d73d21b52651
|
||||
F ext/misc/diskused.c 8acb4f27488fd8b9bdb0a3d300a7bd761b797b6e7858ac8038398263cededc48
|
||||
F ext/misc/decimal.c 23698283d9365ce66d54b5bb97c01e69b4aa7ac804f226f9117a0d42efd15a65
|
||||
F ext/misc/eval.c 04bc9aada78c888394204b4ed996ab834b99726fb59603b0ee3ed6e049755dc1
|
||||
F ext/misc/explain.c 9670c8ff7b255eea7845abc5123a4958e74016c16990b10497e56380f91704b9
|
||||
F ext/misc/fileio.c a8caf3ffb59af6e9870d1a1c739981727ba165cd667bda085fa21ccfc8694059
|
||||
F ext/misc/fossildelta.c 37b67b2710a0dd2da7b3aeea19388a069471eb0fc04702a0521237770d0d04f1
|
||||
F ext/misc/fileio.c e72033f987894ed821bf324a426ed462743399c274f1290dcb646349b6d7548f
|
||||
F ext/misc/fossildelta.c 40add35db7f355d29ae856fe09043e66802fceff6f2551baccb28d794cadbc77
|
||||
F ext/misc/fuzzer.c decaca5a3479dfba69576cd41d4e17161eaf154a5438e12d316bbc5853571802
|
||||
F ext/misc/ieee754.c 2901d08a586d00a1d3c0fd89e03c57ee9e2b5f013b0daab9e49c7a48a9d5946b
|
||||
F ext/misc/memstat.c 03ab52d2d841eb3f55118105c1964d5225f152b23bd708844c648b48d14ccbcf
|
||||
@@ -390,13 +388,13 @@ F ext/misc/normalize.c fbb144a861809686ff2b5b6eee8bb2e1207f9bf13ce7376e5273c700a
|
||||
F ext/misc/pcachetrace.c f4227ce03fb16aa8d6f321b72dd051097419d7a028a9853af048bee7645cb405
|
||||
F ext/misc/percentile.c b6b9c740f0dc42838efd776eec0f68a93bc5ac86524c71337a70950860bf6c4d
|
||||
F ext/misc/prefixes.c e7d3e7a39174db412c5f77c266fa221c2dc3cb2621a9422835a607ad08805eb2
|
||||
F ext/misc/qpvtab.c eeb04e4fcead64648629d6375077a5d5fd48c0384023edd21defa32730714d5e
|
||||
F ext/misc/qpvtab.c 470a5fffba005c8e1994209e59c1848122351e19522de71beb68d666c4fa39a5
|
||||
F ext/misc/randomjson.c ef835fc64289e76ac4873b85fe12f9463a036168d7683cf2b773e36e6262c4ed
|
||||
F ext/misc/regexp.c 378e6e84516952a4b9f3f4df88927f20e6538e2609f55b773ed78899dab8206e
|
||||
F ext/misc/regexp.c 9dada9e9aa91f0cc23e35429e5d1111f110cc201b4c8dcc49aa6d2fc4b2a865d
|
||||
F ext/misc/remember.c add730f0f7e7436cd15ea3fd6a90fd83c3f706ab44169f7f048438b7d6baa69c
|
||||
F ext/misc/rot13.c 51ac5f51e9d5fd811db58a9c23c628ad5f333c173f1fc53c8491a3603d38556c
|
||||
F ext/misc/series.c 496f43bac9bad2ee2cea63fb5212036f30ad3003b4cd317d5c2d6f3ad7c7d264
|
||||
F ext/misc/sha1.c 9a11826db885e8afd997c0a1b28bb799a43e462ef770ac33f19e744887c9c6fa
|
||||
F ext/misc/sha1.c 8bf60344c11a525384c2efd1ae77f160b06be336db679effaadf292d4b41451c
|
||||
F ext/misc/shathree.c fd22d70620f86a0467acfdd3acd8435d5cb54eb1e2d9ff36ae44e389826993df
|
||||
F ext/misc/showauth.c 732578f0fe4ce42d577e1c86dc89dd14a006ab52
|
||||
F ext/misc/spellfix.c e9e951f9712b6c302e4ee84f5db5a7b18daab87aa229867c66f34684d2dfbb40
|
||||
@@ -411,20 +409,20 @@ F ext/misc/totype.c ba11aac3c0b52c685bd25aa4e0f80c41c624fb1cc5ab763250e09ddc762b
|
||||
F ext/misc/uint.c 327afc166058acf566f33a15bf47c869d2d3564612644d9ff81a23efc8b36039
|
||||
F ext/misc/unionvtab.c 716d385256d5fb4beea31b0efede640807e423e85c9784d21d22f0cce010a785
|
||||
F ext/misc/urifuncs.c f71360d14fa9e7626b563f1f781c6148109462741c5235ac63ae0f8917b9c751
|
||||
F ext/misc/uuid.c 37297e61935c2d0c425b742100f904d02c866fdeabe0427fe59aed1543e7c0ec
|
||||
F ext/misc/uuid.c 5bb2264c1b64d163efa46509544fd7500cb8769cb7c16dd52052da8d961505cf
|
||||
F ext/misc/vfslog.c 3932ab932eeb2601dbc4447cb14d445aaa9fbe43b863ef5f014401c3420afd20
|
||||
F ext/misc/vfsstat.c 2b21efa93062ce814fbe28e6dff2acfafa4073a14b8d02cacfb4da1d604d05a5
|
||||
F ext/misc/vfstrace.c fc8c393a8316a8c20867b7e6e92908c4f81060c9e1f24d6ad9aefdc91c01dd13
|
||||
F ext/misc/vtablog.c 6c0c11c4822ab6c1a205718ea7c6d1bb561d96b27104b9c1fe84d01aa62d6c9c
|
||||
F ext/misc/vtshim.c f5ab480d1e33fa46a0b138359bedc9979e32798d72348e04bbe6093f9ae95c7b
|
||||
F ext/misc/wholenumber.c e41953e078894e66a0ff05dd6c76a61f904828c9a4620c7255fac26754f30d3a
|
||||
F ext/misc/wholenumber.c aa5e6d786fe8d79bc100ea0e852249c026a91ae65a5c1bcb2b869cd1a7cdd6d5
|
||||
F ext/misc/windirent.h 02211ce51f3034c675f2dbf4d228194d51b3ee05734678bad5106fff6292e60c
|
||||
F ext/misc/zipfile.c 58d535e6f177709c3f3607e19aa8e1b4c3c57c1f2c78bd4cdfac15e0b2f53e5a
|
||||
F ext/misc/zorder.c bddff2e1b9661a90c95c2a9a9c7ecd8908afab5763256294dd12d609d4664eee
|
||||
F ext/qrf/README.md 9e644615d7d7b77ef7e9db798765679e50c5ed12eda48bce21c9ef9eb4715e9d
|
||||
F ext/qrf/dev-notes.md e68a6d91ce4c7eb296ef2daadc2bb79c95c317ad15b9fafe40850c67b29c2430
|
||||
F ext/qrf/qrf.c c8e1badc5f48dcf5e31fb6a4c9da786d64f981784be116a55b5503127d27eb17
|
||||
F ext/qrf/qrf.h 7a832022bc3f40dc09fff1cb6f18025395a19313de090265a4a1d22bb9b400be
|
||||
F ext/qrf/qrf.c b82987a8b9bc24710e44e5f0120ee6be8d55f270688f0ddad2baa331d20ba7a5
|
||||
F ext/qrf/qrf.h fbb223ff5789b324b3e9c22e787e4c1f53e217cff7cc5a243164d4b2e8410f4b
|
||||
F ext/rbu/rbu.c 801450b24eaf14440d8fd20385aacc751d5c9d6123398df41b1b5aa804bf4ce8
|
||||
F ext/rbu/rbu1.test 25870dd7db7eb5597e2b4d6e29e7a7e095abf332660f67d89959552ce8f8f255
|
||||
F ext/rbu/rbu10.test 7c22caa32c2ff26983ca8320779a31495a6555737684af7aba3daaf762ef3363
|
||||
@@ -465,11 +463,11 @@ F ext/rbu/rburesume.test 1403752d152b55efb7fc25749c0fccc790061371ec9ffe428cc04f8
|
||||
F ext/rbu/rbusave.test 588b618dad9d65c4b13d03a79931de82213503fedc26bdf5789c996ecf427fba
|
||||
F ext/rbu/rbusplit.test a6dedd23cf37bcf2e8646d9d7139846e96d60d92f9bc6d6ba6ca8c24c0bd1f72
|
||||
F ext/rbu/rbutemplimit.test 4980df2d4b74f4dd982add8f78809106154ef5a3c4bdce747422ab0b0481e029
|
||||
F ext/rbu/rbuvacuum.test e3585cfda220038e8186c583e9bd2aaa9eccd0a5c2e40ed861de3c987c93f68c
|
||||
F ext/rbu/rbuvacuum.test 542561741ff2b262e3694bc6012b44694ee62c545845319a06f323783b15311e
|
||||
F ext/rbu/rbuvacuum2.test 1a9bd41f127be2826de2a65204df9118525a8af8d16e61e6bc63ba3ac0010a23
|
||||
F ext/rbu/rbuvacuum3.test 3ce42695fdf21aaa3499e857d7d4253bc499ad759bcd6c9362042c13cd37d8de
|
||||
F ext/rbu/rbuvacuum4.test ffccd22f67e2d0b380d2889685742159dfe0d19a3880ca3d2d1d69eefaebb205
|
||||
F ext/rbu/sqlite3rbu.c c84dd68888640c56aa4d713e38013a202b10bf1ef2e423f7be2167bd826e69d8
|
||||
F ext/rbu/sqlite3rbu.c e99400d29d029936075e27495b269a2dcdceae3cf8c86b1d0869b4af487be3ab
|
||||
F ext/rbu/sqlite3rbu.h e3a5bf21e09ca93ce4e8740e00d6a853e90a697968ec0ea98f40826938bdb68e
|
||||
F ext/rbu/test_rbu.c 8b6e64e486c28c41ef29f6f4ea6be7b3091958987812784904f5e903f6b56418
|
||||
F ext/recover/dbdata.c 10d3c56968a9af6853722a47280805ad1564714d79ea45ac6f7da14bb57fd137
|
||||
@@ -493,7 +491,7 @@ F ext/recover/sqlite3recover.h 011c799f02deb70ab685916f6f538e6bb32c4e0025e79bfd0
|
||||
F ext/recover/test_recover.c 3d0fb1df7823f5bc22a0b93955034d16a2dfa2eb1e443e9a0123a77f120599a3
|
||||
F ext/rtree/README 734aa36238bcd2dee91db5dba107d5fcbdb02396612811377a8ad50f1272b1c1
|
||||
F ext/rtree/geopoly.c 77bad24162b6ae84a2fd6de3f1f8ad0b255a4ceb572f50f8771d1ac9d4d986d8
|
||||
F ext/rtree/rtree.c 0e7e3dd53ef90ab540ed991df3395f4e2e2204e85351a2e6bc3e6ae55c23640c
|
||||
F ext/rtree/rtree.c e350bb1c7adefab45cd4ce77e11393c7f3a9ee21c27345a684b6e1c04fae1a12
|
||||
F ext/rtree/rtree.h 4a690463901cb5e6127cf05eb8e642f127012fd5003830dbc974eca5802d9412
|
||||
F ext/rtree/rtree1.test e0608db762b2aadca0ecb6f97396cf66244490adc3ba88f2a292b27be3e1da3e
|
||||
F ext/rtree/rtree2.test 9d9deddbb16fd0c30c36e6b4fdc3ee3132d765567f0f9432ee71e1303d32603d
|
||||
@@ -542,7 +540,7 @@ F ext/session/session8.test 326f3273abf9d5d2d7d559eee8f5994c4ea74a5d935562454605
|
||||
F ext/session/session9.test ce2b898aa4caf0e492b57c29cb707224e0a33479e4f019785a81828273143ba5
|
||||
F ext/session/sessionA.test 1feeab0b8e03527f08f2f1defb442da25480138f
|
||||
F ext/session/sessionB.test c4fb7f8a688787111606e123a555f18ee04f65bb9f2a4bb2aa71d55ce4e6d02c
|
||||
F ext/session/sessionC.test 7c9b5e90194b3b7ad8bcbc6fcbac77d2c572ec3566a30fce1e82f4d64fb9aa3f
|
||||
F ext/session/sessionC.test de98b5e173fd86c79af0d0541534398d2ea75dc0d5d74a00103eb26151b76959
|
||||
F ext/session/sessionD.test 470ff917dc849e2eb78142ade63aaabd729d773833cff0ff01bca0eda68a21ce
|
||||
F ext/session/sessionE.test b2010949c9d7415306f64e3c2072ddabc4b8250c98478d3c0c4d064bce83111d
|
||||
F ext/session/sessionF.test d37ed800881e742c208df443537bf29aa49fd56eac520d0f0c6df3e6320f3401
|
||||
@@ -557,7 +555,7 @@ F ext/session/sessionat.test 00c8badb35e43a2f12a716d2734a44d614ff62361979b6b8541
|
||||
F ext/session/sessionbig.test 47c381e7acfabeef17d98519a3080d69151723354d220afa2053852182ca7adf
|
||||
F ext/session/sessionblob.test 87faf667870b72f08e91969abd9f52a383ab7b514506ee194d64a39d8faff00a
|
||||
F ext/session/sessionchange.test 6618cb1c1338a4b6df173b6ac42d09623fb71269962abf23ebb7617fe9f45a50
|
||||
F ext/session/sessionchange2.test 8f59185216882adc8b34bb5ba63887459acf3df58493bcffa12e4d05ab6a6b85
|
||||
F ext/session/sessionchange2.test 6b5b7e3d1cc4ede43817f7fb68e3771aac4aa6500adb21a458b3e5a9fd841f83
|
||||
F ext/session/sessionconflict.test 19e4a53795c4c930bfec49e809311e09b2a9e202d9446e56d7a8b139046a0c07 x
|
||||
F ext/session/sessionconflict2.test d7f4caf59360dbca8a4698b9a3a322adf6f547f810ad41d131cacb730e02dd5e x
|
||||
F ext/session/sessiondiff.test e89f7aedcdd89e5ebac3a455224eb553a171e9586fc3e1e6a7b3388d2648ba8d
|
||||
@@ -574,10 +572,10 @@ F ext/session/sessionrowid.test 85187c2f1b38861a5844868126f69f9ec62223a03449a98a
|
||||
F ext/session/sessionsize.test 8fcf4685993c3dbaa46a24183940ab9f5aa9ed0d23e5fb63bfffbdb56134b795
|
||||
F ext/session/sessionstat1.test 5e718d5888c0c49bbb33a7a4f816366db85f59f6a4f97544a806421b85dc2dec
|
||||
F ext/session/sessionwor.test 6fd9a2256442cebde5b2284936ae9e0d54bde692d0f5fd009ecef8511f4cf3fc
|
||||
F ext/session/sqlite3session.c ce9f2ce2cc6b17f46854788e47016ba9be1b59ca4037728b6c025397b98edb12
|
||||
F ext/session/sqlite3session.c 1010718d9d88eeb1efd1bf3d6bcbc85e598e9d5bb094c2d202515622d2233481
|
||||
F ext/session/sqlite3session.h ca7c4422c1514a95056cc8d333217df6b1829d39058126b1de85d10cd62d7a9c
|
||||
F ext/session/test_session.c d3275da24b8d362e3c2b393c00d5248f75f1cd474dadf29d8c4683f75cb52e6d
|
||||
F ext/wasm/GNUmakefile 65feef4ec48e62249f90278c4c08a3fe3c69e2461ff560b61c03cd73606e0949
|
||||
F ext/session/test_session.c 95fbf8fc721fdb1a0d00268f930d6763c5299ed766b317f9dd3cf9ca5262e337
|
||||
F ext/wasm/GNUmakefile 68c750f173106d9d63f12c1edf1256c6f4bad9894b155da5db64322f4912de4b
|
||||
F ext/wasm/README-dist.txt f01081a850ce38a56706af6b481e3a7878e24e42b314cfcd4b129f0f8427066a
|
||||
F ext/wasm/README.md 2e87804e12c98f1d194b7a06162a88441d33bb443efcfe00dc6565a780d2f259
|
||||
F ext/wasm/SQLTester/GNUmakefile e0794f676d55819951bbfae45cc5e8d7818dc460492dc317ce7f0d2eca15caff
|
||||
@@ -585,28 +583,28 @@ F ext/wasm/SQLTester/SQLTester.mjs 6b3c52ed36a5573ca4883176f326332a8d4c0cecf5efd
|
||||
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.c-pp 189935d0106bca86661efc991ab13e1d5d6e1f55ec34dc7b5055a99321397edd
|
||||
F ext/wasm/api/EXPORTED_FUNCTIONS.c-pp de2ce128aebeff9ef4161cff7a0ff0089be866121bcb8941ad44a38a65f1d436
|
||||
F ext/wasm/api/README.md a905d5c6bfc3e2df875bd391d6d6b7b48d41b43bdee02ad115b47244781a7e81
|
||||
F ext/wasm/api/extern-post-js.c-pp.js 80accc53cc6ea1e61c721595f42ba95baa7c7ea636807d9507e69403301f8c54
|
||||
F ext/wasm/api/extern-pre-js.js cc61c09c7a24a07dbecb4c352453c3985170cec12b4e7e7e7a4d11d43c5c8f41
|
||||
F ext/wasm/api/opfs-common-inline.c-pp.js 496ca858af09b7fef2efaece467960611d35f57254078424bcdeac42ded9e85d
|
||||
F ext/wasm/api/opfs-common-shared.c-pp.js d0a62a1d367d850d8e07c06e82499a5006f347e4025dbd59a8623048d858e7a1
|
||||
F ext/wasm/api/opfs-common-shared.c-pp.js 5b5880ced26977931a4fb33aafc6c71206fbee519e82abf9614898d8fa5ec241
|
||||
F ext/wasm/api/post-js-footer.js a50c1a2c4d008aede7b2aa1f18891a7ee71437c2f415b8aeb3db237ddce2935b
|
||||
F ext/wasm/api/post-js-header.js f35d2dcf1ab7f22a93d565f8e0b622a2934fc4e743edf3b708e4dd8140eeff55
|
||||
F ext/wasm/api/pre-js.c-pp.js d6bf82f83f60caa2904bddb95a29cb738b310f672d2796cdc5fe54463ab0d6cd
|
||||
F ext/wasm/api/sqlite3-api-glue.c-pp.js 31a721ada7225838a61310a9f3f797fa5275353f8e9b0ae769d85b437be061f5
|
||||
F ext/wasm/api/sqlite3-api-oo1.c-pp.js 35e4727010f15fd72ead0dd1eb4e3c2c9bb1cc60e51544cbdff1f7c14f209de2
|
||||
F ext/wasm/api/sqlite3-api-prologue.js 0084e15d66fbcd75cacbaa58e3b473d5e57082c30f3122be7fdadff5589cf6b6
|
||||
F ext/wasm/api/sqlite3-api-prologue.js 29ca376ff5d5f189714cf10b2b93b136e91b06ec8616579b53b2af9dfb4796bf
|
||||
F ext/wasm/api/sqlite3-api-worker1.c-pp.js 1fa34e9b0e3b90a8898e4f700d7125e44c81877f182627bb8564b97989bc6e78
|
||||
F ext/wasm/api/sqlite3-license-version-header.js 98d90255a12d02214db634e041c8e7f2f133d9361a8ebf000ba9c9af4c6761cc
|
||||
F ext/wasm/api/sqlite3-opfs-async-proxy.c-pp.js 25e31482b04293a33d7599f1459eb552b3eb36ca10c02c816122d3308bf80cb2
|
||||
F ext/wasm/api/sqlite3-vfs-helper.c-pp.js 3f828cc66758acb40e9c5b4dcfd87fd478a14c8fb7f0630264e6c7fa0e57515d
|
||||
F ext/wasm/api/sqlite3-vfs-kvvfs.c-pp.js 27fb135ba3b805b66c90a7333b56080345bf1db79335c3e48b6d01ad7aa09607
|
||||
F ext/wasm/api/sqlite3-vfs-opfs-sahpool.c-pp.js 4325cb9a5ebfbff7cd3060e309b167116a2a1bcb9f8d69dd8e6d023dbdd783bb
|
||||
F ext/wasm/api/sqlite3-vfs-opfs-sahpool.c-pp.js 1c742ed92c0515c8ef97d2b132feb01168252bfd847fed5d52607d8a42d23c6a
|
||||
F ext/wasm/api/sqlite3-vfs-opfs-wl.c-pp.js 3dbd918ef037cd8fa9c7b4dccb3c8637b228638654c429e7df6acab5981c75e2
|
||||
F ext/wasm/api/sqlite3-vfs-opfs.c-pp.js 3da8fe72dc9e76614a9c102b92e777ce03f81d788b607701c828d8fcbac44b06
|
||||
F ext/wasm/api/sqlite3-vtab-helper.c-pp.js 366596d8ff73d4cefb938bbe95bc839d503c3fab6c8335ce4bf52f0d8a7dee81
|
||||
F ext/wasm/api/sqlite3-wasm.c 67ea19a4a664abdec95bcff5ed87f2f0a7106e0f9cf382f12f70b4ebd7013c21
|
||||
F ext/wasm/api/sqlite3-wasm.c ddf9d435b2e901eaceb805ff694e9609c2f32b5cf89a4f164e734a6fa303fdd2
|
||||
F ext/wasm/api/sqlite3-worker1-promiser.c-pp.js 46919740f8176c10f691431a81c769c35657e3b537e2ed2bde691f9017b0ee8a
|
||||
F ext/wasm/api/sqlite3-worker1.c-pp.js 21b20d3b8d43471d1647123616a7e5435b1e4b6fa447714f91ffc7f950ea01e8
|
||||
F ext/wasm/common/SqliteTestUtil.js dae753b95e72248c4395d8de8359e0d055cd9928488e8dd84aef89e46d23b32e
|
||||
@@ -624,9 +622,9 @@ F ext/wasm/demo-worker1-promiser.c-pp.js d210aa1e8a74ea6244fe2290de5710bb55b3a9e
|
||||
F ext/wasm/demo-worker1.html 2c178c1890a2beb5a5fecb1453e796d067a4b8d3d2a04d65ca2eb1ab2c68ef5d
|
||||
F ext/wasm/demo-worker1.js fdfa90aa9d6b402bfed802cf1595fe4da6cc834ac38c8ff854bf1ee01f5ff9bb
|
||||
F ext/wasm/example_extra_init.c 2347cd69d19d839ef4e5e77b7855103a7fe3ef2af86f2e8c95839afd8b05862f
|
||||
F ext/wasm/fiddle/fiddle-worker.js e45bfe9ce4cf0d0270ca0ed254af8deecc7d46c399db4a56fd1d0846d5e258ec
|
||||
F ext/wasm/fiddle/fiddle.js 2a0984cc4a35e6889c0d84ee9bf853317d5545ddb3966dfb995bbe589f923c4c
|
||||
F ext/wasm/fiddle/index.c-pp.html 5fd1f462864710d1b00d27fc4bc6190cb846cc865d7cc93b99644423f2c4cc84
|
||||
F ext/wasm/fiddle/fiddle-worker.js 6c72acac2d381480bc9f5eb538e3f2faf2c1f72dd4fcbd05d3b409818a9a8fd5
|
||||
F ext/wasm/fiddle/fiddle.js 84fd75967e0af8b69d3dd849818342227d0f81d13db92e0dcbc63649b31a4893
|
||||
F ext/wasm/fiddle/index.c-pp.html 02f063ef30b8124f311029855c4439e77bc6505d1bf65a163d88c064a63ee9d9
|
||||
F ext/wasm/index-dist.html db23748044e286773f2768eec287669501703b5d5f72755e8db73607dc54d290
|
||||
F ext/wasm/index.html 5bf6cf1b0a3c8b9f5f54d77f2219d7ae87a15162055ce308109c49b1dcab4239
|
||||
F ext/wasm/jaccwabyt/jaccwabyt.js 4e2b797dc170851c9c530c3567679f4aa509eec0fab73b466d945b00b356574b
|
||||
@@ -649,7 +647,7 @@ F ext/wasm/test-opfs-vfs.html 1f2d672f3f3fce810dfd48a8d56914aba22e45c6834e262555
|
||||
F ext/wasm/test-opfs-vfs.js 1618670e466f424aa289859fe0ec8ded223e42e9e69b5c851f809baaaca1a00c
|
||||
F ext/wasm/tester1-worker.c-pp.html 7171022e7f4da8f46e5f50ea81dd6ce840b9235c47653a5deeb3764ccc2fe472
|
||||
F ext/wasm/tester1.c-pp.html bd927ccf51ddd65e924660a0487add99e1b044afe03950e49d87ccf44efdddb6
|
||||
F ext/wasm/tester1.c-pp.js 38beb509f2136851760db79becd41a1ec0abcaaec01de27749b0fafcb0372e54
|
||||
F ext/wasm/tester1.c-pp.js 54ce4a08d3752cb52cf60926d7da47a21ae63d620f90679770dd9c04002722b4
|
||||
F ext/wasm/tests/opfs/concurrency/index.html 706eab6308343c04ac2360aba6001af4ffaf46d8f33a0ccd02c64d93e3216a43
|
||||
F ext/wasm/tests/opfs/concurrency/test.js 6919778fceaac1b7cc78caf41d796f545d2c4433b31188aa9689f05b5ad28828
|
||||
F ext/wasm/tests/opfs/concurrency/worker.js 704d82c5e287e47f612349e027765943a58ad967dcf178fb5a1c3a8eaafb09af
|
||||
@@ -659,7 +657,7 @@ 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 77e33a16a795abd4a07a55f7eb2e11136326998db597b67c8655d5d2d9b98054
|
||||
F main.mk 582cb3ab67cb5b8887c087265e700f7a132dace4316e1656419e8e4c049ba683
|
||||
F make.bat a136fd0b1c93e89854a86d5f4edcf0386d211e5d5ec2434480f6eea436c7420c
|
||||
F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271
|
||||
F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504
|
||||
@@ -673,35 +671,35 @@ F sqlite3.pc.in e6dee284fba59ef500092fdc1843df3be8433323a3733c91da96690a50a5b398
|
||||
F src/alter.c d7cbe4332a7a2c3a21ab58ee2609efade493f6ae78254613ada0759898629ee3
|
||||
F src/analyze.c 03bcfc083fc0cccaa9ded93604e1d4244ea245c17285d463ef6a60425fcb247d
|
||||
F src/attach.c c58278c7d2d954785591c4fde81669ec3e4d52f348c453b028a19ae8adf4f338
|
||||
F src/auth.c b5ece4e1edccad082c0332fa0087df225473bae0feea9269f824312201377185
|
||||
F src/backup.c 6ebe22ccbedfcb92423833992130e8d65824be4e6599c3a03f540ab38fc7d13c
|
||||
F src/auth.c ebec42df26b34a62b6750d30d9c2c03554a1c522020182476f7729a439fef04f
|
||||
F src/backup.c 5c97e8023aab1ce14a42387eb3ae00ba5a0644569e3476f38661fa6f824c3523
|
||||
F src/bitvec.c e242d4496774dfc88fa278177dd23b607dce369ccafb3f61b41638eea2c9b399
|
||||
F src/btmutex.c 30dada73a819a1ef5b7583786370dce1842e12e1ad941e4d05ac29695528daea
|
||||
F src/btree.c c9b13797b0b68e0c057ec796976b1ab1e8b4e766d1a7c7f919b2d8a1d2193a80
|
||||
F src/btree.c 377b98fbe170ae38298a3fcea5355ec88404f63238f80741992cda765ac91aeb
|
||||
F src/btree.h e823c46d87f63d904d735a24b76146d19f51f04445ea561f71cc3382fd1307f0
|
||||
F src/btreeInt.h 9c0f9ea5c9b5f4dcaea18111d43efe95f2ac276cd86d770dce10fd99ccc93886
|
||||
F src/build.c 866e584cdf40fbc83f530af9fd4d0991582a6fdbd8a9911b7cdbbea5f26a4a9e
|
||||
F src/build.c 8581de0af3b6c448f5d64e2d18a91ac1e7057b3bcb8b8827e1240f80d87486a4
|
||||
F src/callback.c 3605bbf02bd7ed46c79cd48346db4a32fc51d67624400539c0532f4eead804ad
|
||||
F src/carray.c 3efe3982d5fb323334c29328a4e189ccaef6b95612a6084ad5fa124fd5db1179
|
||||
F src/complete.c f216b970ce99c5a657556cf1f17e7ddd494515d3beb63df426bf59ff43bd3d9a
|
||||
F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e
|
||||
F src/date.c 61e92f1f7e2e88e1cd91e91dc69eb2b2854e7877254470f9fabd776bfac922b8
|
||||
F src/dbpage.c c6a9de13b0a01f0bc94a41e16213ab1ecd15ccfe86df7255ced40fda9446257d
|
||||
F src/dbpage.c 98c716bc5c0c70af4e7934bfcddd707f14e78b5d4cf1e0602a07b485e1af2e74
|
||||
F src/dbstat.c 73362c0df0f40ad5523a6f5501224959d0976757b511299bf892313e79d14f5c
|
||||
F src/delete.c 59eeca3fb88c29329afc41bb803ee568b120d9dd7470b5f38ab55cc38390b451
|
||||
F src/expr.c e97dd9f6ada4c448764e225d8963091bf630b3efb2c92e4d0762571cca2a14e5
|
||||
F src/delete.c 1f2268d6fe3c78fc1bf794ba65d7026498b78e2342ffaf85825dedae546e6fde
|
||||
F src/expr.c 8a458928fe502526d4ce90fa4e084a6e1a4dceb6da747381973b5b0086b1492c
|
||||
F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007
|
||||
F src/fkey.c 931f74cec1dc8038a0217ef340c91ce147dd1bbed08dc40c47ee0ec6edfffb08
|
||||
F src/func.c 555d5f7686f9eef20fe3574889403f307a6cb16ada5b05cbc6a9288dcf75aaeb
|
||||
F src/func.c 6f6abe78831fba92ebb5c3d347273f37656ae357f5902e1fb48aa297d57fbcc6
|
||||
F src/global.c a19e4b1ca1335f560e9560e590fc13081e21f670643367f99cb9e8f9dc7d615b
|
||||
F src/hash.c 03c8c0f4be9e8bcb6de65aa26d34a61d48a9430747084a69f9469fbb00ea52ca
|
||||
F src/hash.h 46b92795a95bfefb210f52f0c316e9d7cdbcdd7e7fcfb0d8be796d3a5767cddf
|
||||
F src/hwtime.h 5cb15147c8583d0fc4748e1c12ea6f38c9deaeefa147a4d8d379fd9bc81fee9a
|
||||
F src/hwtime.h 21c2cf1f736e7b97502c3674d0c386db3f06870d6f10d0cf8174e2a4b8cb726e
|
||||
F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71
|
||||
F src/insert.c 8dbc22f6ddcc5f0af3abf11daeb89b1978f00059cda15ebc61251fa7724fc7ee
|
||||
F src/json.c f058c449acb9fdb1d3d1bb9f7e97b225ba773f5b6fdcec4310d3f49980125ed4
|
||||
F src/insert.c dfd311b0ac2d4f6359e62013db67799757f4d2cc56cca5c10f4888acfbbfa3fd
|
||||
F src/json.c 82b685636c9ff9d677734682e170f637fbfef3a14febf8cb274c4b7e7a272dcc
|
||||
F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa
|
||||
F src/loadext.c 78d5b06f18996ffa1203129b28fea043f63a87a4117539678f1d761c30b4ff65
|
||||
F src/main.c efd782fadd65b8e67952f439d56d7605134582346573018a614a8e082e074bd7
|
||||
F src/loadext.c 56a542244fbefc739a2ef57fac007c16b2aefdb4377f584e9547db2ce3e071f9
|
||||
F src/main.c 387bb9d0216d6d35b221481ba8e661d94ad043060cd89581b6422c269ce680a0
|
||||
F src/malloc.c 422f7e0498e1c9ef967f06283b6f2c0b16db6b905d8e06f6dbc8baaa3e4e6c5a
|
||||
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
|
||||
F src/mem1.c 3bb59158c38e05f6270e761a9f435bf19827a264c13d1631c58b84bdc96d73b2
|
||||
@@ -714,41 +712,41 @@ F src/msvc.h 80b35f95d93bf996ccb3e498535255f2ef1118c78764719a7cd15ab4106ccac9
|
||||
F src/mutex.c 00b8cee206a67fd764d001f3a148494331d8d0b3b9c3974ecd69ff29bb444462
|
||||
F src/mutex.h a7b2293c48db5f27007c3bdb21d438873637d12658f5a0bf8ad025bb96803c4a
|
||||
F src/mutex_noop.c 9d4309c075ba9cc7249e19412d3d62f7f94839c4
|
||||
F src/mutex_unix.c caec9862aeebad01f6c8997cf709a239abeb0715fcce1895720b87fe7e2ef42f
|
||||
F src/mutex_w32.c d44e94c064f8ab39e0318fb6fa00171cf7e5645bd4241129b07d655a8ddbd44b
|
||||
F src/mutex_unix.c f7ee5a2061a4c11815a2bf4fc0e2bfa6fb8d9dc89390eb613ca0cec32fc9a3d1
|
||||
F src/mutex_w32.c e1d317d29cb623667d43de94714264d1e1871cc4bb39fa67dd17048e8138c739
|
||||
F src/notify.c 57c2d1a2805d6dee32acd5d250d928ab94e02d76369ae057dee7d445fd64e878
|
||||
F src/os.c 509452169d5ea739723e213b8e2481cf0e587f0e88579a912d200db5269f5f6d
|
||||
F src/os.h 1ff5ae51d339d0e30d8a9d814f4b8f8e448169304d83a7ed9db66a65732f3e63
|
||||
F src/os_common.h 6c0eb8dd40ef3e12fe585a13e709710267a258e2c8dd1c40b1948a1d14582e06
|
||||
F src/os_kv.c a8f93adde10d74923f28dffb744162134599249c02d505f5043745dd1b4b917f
|
||||
F src/os_kv.c e7d96727db5b67e39d590a68cc61c86daf4c093c36c011a09ebfb521182ec28d
|
||||
F src/os_setup.h 8efc64eda6a6c2f221387eefc2e7e45fd5a3d5c8337a7a83519ba4fbd2957ae2
|
||||
F src/os_unix.c 83759942d1ea8d59daed50901c123016f845fada74caf3496b8a2537c9a08838
|
||||
F src/os_win.c 68b1c31693a5aeeb8126f618c95f7b53fb39e254836f9a95fbf2733461a7e01d
|
||||
F src/os_win.h c06ccc3a090cf54202ea58981c298817f3309d4c9e4d52ad0a02927346493721
|
||||
F src/pager.c f88073a00933c885b167b6d25afc4d1b83c1706943572f5653fb64a7f5bde105
|
||||
F src/os_unix.c 92a1773139e0c6206a927c7e1648b06287583570b6e253210a06ee3886739d39
|
||||
F src/os_win.c 938805c15e855819cb0874aea560c3a7250175d311a5494b47a4f8b69dcd59c0
|
||||
F src/os_win.h 5e168adf482484327195d10f9c3bce3520f598e04e07ffe62c9c5a8067c1037b
|
||||
F src/pager.c 5e98a67fad5e33c9588460c42063859d22aca8d3140865fd411056dd360b26c2
|
||||
F src/pager.h 6137149346e6c8a3ddc1eeb40aee46381e9bc8b0fcc6dda8a1efde993c2275b8
|
||||
F src/parse.y d5a3c5b0277a441c38b35071c05e2b61ff5fc918a63309c809f4b6706179c320
|
||||
F src/pcache.c 588cc3c5ccaaadde689ed35ce5c5c891a1f7b1f4d1f56f6cf0143b74d8ee6484
|
||||
F src/pcache.h 092b758d2c5e4dabb30eae46d8dfad77c0f70b16bf3ff1943f7a232b0fe0d4ba
|
||||
F src/pcache1.c d7ee0f95992501a65379f620b3de1430b64e52e397769938668a9fd9dd1c8145
|
||||
F src/pcache1.c 131ca0daf4e66b4608d2945ae76d6ed90de3f60539afbd5ef9ec65667a5f2fcd
|
||||
F src/pragma.c 789ef67117b74b5be0a2db6681f7f0c55e6913791b9da309aefd280de2c8a74d
|
||||
F src/prepare.c 084a037fd3810cb7ffbfc001cd58c0ffac68ba36598a5084b55ea2a090014ebd
|
||||
F src/printf.c 1b3d26ed8ea9a900317832625d5e83b833c7cf14640d7d98a2c235e172b6fefc
|
||||
F src/prepare.c f6a6e28a281bd1d1da12f47d370a81af46159b40f73bf7fa0b276b664f9c8b7d
|
||||
F src/printf.c ed43bcd6b551b590e47b905115aa1c35504267f532680590102e79894230a06b
|
||||
F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c
|
||||
F src/resolve.c d0724113da9f5c0430d2052808ce59519f51ae7c4fbb1f5ef21fe3a832956086
|
||||
F src/resolve.c f5a780a7b604d43b78bca290cace7479bca0c7d8ef9ce855830d9498b975baec
|
||||
F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97
|
||||
F src/select.c 5c3a5e3c1e6c3f8ccabeb414e18dce64e6f3e797de225ee93034f2c9e76f289c
|
||||
F src/shell.c.in a4e83895cfa336065ad7f7a7dea8fc2a19d050f7ce7466621c67208acaac9e44
|
||||
F src/sqlite.h.in 22674c0fc97b5ee21ace65b9bc1ed805dab35f433326d8022a642676c3b8a9d1
|
||||
F src/shell.c.in cbb7ae029cea6d8789924d9009574081b4f3c0619ce736ed36e8c7564ef13547
|
||||
F src/sqlite.h.in e2915e4a86d5e0783afb5cb72411df38d987c7f3c5aa2d5441b8e74d30b649d8
|
||||
F src/sqlite3.rc 015537e6ac1eec6c7050e17b616c2ffe6f70fca241835a84a4f0d5937383c479
|
||||
F src/sqlite3ext.h 9788c301f95370fa30e808861f1d2e6f022a816ddbe2a4f67486784c1b31db2e
|
||||
F src/sqliteInt.h 5bec8cfdc8346a122b35312452eb6af33fc750a6c901f2c651a2f53eba0b979f
|
||||
F src/sqlite3ext.h 1b7a0ee438bb5c2896d0609c537e917d8057b3340f6ad004d2de44f03e3d3cca
|
||||
F src/sqliteInt.h 9f152ad54b9ce85040365b96eb6d2a985146dc760bb295cc645f48d38100ad85
|
||||
F src/sqliteLimit.h c70656b67ab5b96741a8f1c812bdd80c81f2b1c1e443d0cc3ea8c33bb1f1a092
|
||||
F src/status.c 7565d63a79aa2f326339a24a0461a60096d0bd2bce711fefb50b5c89335f3592
|
||||
F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1
|
||||
F src/tclsqlite.c 7401c73c917a4d1b380c896a324c8d8eb533a999559d9e339d479596553bebfd
|
||||
F src/tclsqlite.h 614b3780a62522bc9f8f2b9fb22689e8009958e7aa77e572d0f3149050af348a
|
||||
F src/test1.c fe1316579a1778eb96d0bd12807f9dddc5e3984f5950127e2e1718c050cb6304
|
||||
F src/test1.c 3e3b013f59ffcb57dce00c90d55907072d71d4e970cb0a590cb261efe11bae9c
|
||||
F src/test2.c 2b9ab96bba63a1c369d5769390475259ad210f144a877805f2e32e563f9e93c1
|
||||
F src/test3.c 432646f581d8af1bb495e58fc98234380250954f5d5535e507fc785eccc3987a
|
||||
F src/test4.c 0ac87fc13cdb334ab3a71823f99b6c32a6bebe5d603cd6a71d84c823d43a25a0
|
||||
@@ -802,27 +800,27 @@ F src/trigger.c 4bf3bfb3851d165e4404a9f9e69357345f3f7103378c07e07139fdd8aeb7bd20
|
||||
F src/update.c 3e5e7ff66fa19ebe4d1b113d480639a24cc1175adbefabbd1a948a07f28e37cf
|
||||
F src/upsert.c 215328c3f91623c520ec8672c44323553f12caeb4f01b1090ebdca99fdf7b4f1
|
||||
F src/utf.c 7267c3fb9e2467020507601af3354c2446c61f444387e094c779dccd5ca62165
|
||||
F src/util.c 98cf12c8ba65623a76c1eb6e6afa98ff40107c9919bf79af42f4bfc70e654232
|
||||
F src/util.c 2053344769bc602b2c23ce193f4d24f89777ab67fa768b80fa197d3876dc3017
|
||||
F src/vacuum.c d3d35d8ae893d419ade5fa196d761a83bddcbb62137a1a157ae751ef38b26e82
|
||||
F src/vdbe.c 8ed6f274dff8b9fb961d050a9ab933e7f6509221718bec862e85729d171c1606
|
||||
F src/vdbe.c 6c57525d7db0232d52687d30da1093db0c152f14206c2ef1adf0c19a09d863e3
|
||||
F src/vdbe.h 70e862ac8a11b590f8c1eaac17a0078429d42bc4ea3f757a9af0f451dd966a71
|
||||
F src/vdbeInt.h c31ba4dc8d280c2b1dc89c6fcee68f2555e3813ab34279552c20b964c0e338b1
|
||||
F src/vdbeapi.c 6cdcbe5c7afa754c998e73d2d5d2805556268362914b952811bdfb9c78a37cf1
|
||||
F src/vdbeaux.c bd3aaf77593a5590f617ce173e8677a21eca18522eadc1c4bc81b53f6d1c7e19
|
||||
F src/vdbeaux.c 81687c55682b9f4d942186695f4f7fa4743c564a985e0889def52eded9076d61
|
||||
F src/vdbeblob.c b3f0640db9642fbdc88bd6ebcc83d6009514cafc98f062f675f2c8d505d82692
|
||||
F src/vdbemem.c 6e7ad67507c9a8e625b46256a9c003929331d6a27b99bbe139b8f0dab636e1f2
|
||||
F src/vdbemem.c efacb8f229422d2a4db0ed38e49b7f3897862a98d82b261aa3b43d7a2d98c6da
|
||||
F src/vdbesort.c b69220f4ea9ffea5fdef34d968c60305444eea909252a81933b54c296d9cca70
|
||||
F src/vdbetrace.c 49e689f751505839742f4a243a1a566e57d5c9eaf0d33bbaa26e2de3febf7b41
|
||||
F src/vdbevtab.c fc46b9cbd759dc013f0b3724549cc0d71379183c667df3a5988f7e2f1bd485f3
|
||||
F src/vtab.c 5437ce986db2f70e639ce8a3fe68dcdfe64b0f1abb14eaebecdabd5e0766cc68
|
||||
F src/vxworks.h 9d18819c5235b49c2340a8a4d48195ec5d5afb637b152406de95a9436beeaeab
|
||||
F src/wal.c abfd99239725a258af4f733681b24dd7a9ee298babe389a36d29c197e2443ebf
|
||||
F src/wal.c 7340d4f9bb827bd349127cac6b2cf0cb7f76b9fda645f7b9b0bf7a6e0b1e2e7c
|
||||
F src/wal.h ba252daaa94f889f4b2c17c027e823d9be47ce39da1d3799886bbd51f0490452
|
||||
F src/walker.c d5006d6b005e4ea7302ad390957a8d41ed83faa177e412f89bc5600a7462a014
|
||||
F src/where.c 33e4a6558ee69f33d6a4e7069e3a40a55959d14e5653a9a83926e70305d471f3
|
||||
F src/where.c a1caeb656f74e58de7e7310ee91c6dfb40e975c7dd9b18e61a965aea46a610f2
|
||||
F src/whereInt.h 8d94cb116c9e06205c3d5ac87af065fc044f8cf08bfdccd94b6ea1c1308e65da
|
||||
F src/wherecode.c bc39ccbe3648f01157038b16cc55bdbff128590972b7185521b5526dc2815765
|
||||
F src/whereexpr.c a1e22cf9f6cb59770d9652c757dcf1924078ad2d48a9da89e254be9327677465
|
||||
F src/whereexpr.c 61b1c9d98d39f6bcd79fcb4ebb4c9478effb259fefac4c7d3e78e4957f97f75a
|
||||
F src/window.c c0a38cd32473e8e8e7bc435039f914a36ca42465506dc491c65870c01ddac9fb
|
||||
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
|
||||
F test/affinity2.test 4d7a34d328e58ca2a2d78fd76c27614a41ca7ddf4312ded9c68c04f430b3b47d
|
||||
@@ -833,7 +831,7 @@ F test/aggnested.test 610b0ce2c3e8f3daee25f9752800ee8d785db10da4aa1fbeea0ea1aaba
|
||||
F test/aggorderby.test 7be65e743f82ee49ba62da1c799e59341d23884a99edfe093df0cdfaac94cbbb
|
||||
F test/alias.test 4529fbc152f190268a15f9384a5651bbbabc9d87
|
||||
F test/all.test cf929f721e20960ca9db89471fa44f9176322ba8f25e97193f91881c223643b3
|
||||
F test/alter.test 3acf3819d2cb1f0524a1b64c42b50a6b0d395c4f890f24dde5ec9e0d2e2eacc3
|
||||
F test/alter.test 3c00eff1e2036b9f93e9cd0f3d3e63750ac87ecb5bc71b9d7bd07cbf2ac4c494
|
||||
F test/alter2.test 7e3d26ab409df52df887b366a63902c3429b935c41cb962fd58ffc25784f2f19
|
||||
F test/alter3.test dcdd5f850f30656a45a0f05e41abfb52b74bbf6ccba165d0f7adf6b0116e4fd6
|
||||
F test/alter4.test 37cafe164067a6590a0ee4cec780bddbbaa33dc50b11542dcfbe0e65626494fd
|
||||
@@ -855,9 +853,9 @@ F test/altertab.test 8a2712f9076da5012a002d0b5cc0a421398a5bf61c25bab41b77c427586
|
||||
F test/altertab2.test 0889ba0700cc1cdb7bc7d25975aa61fece34f621de963d0886e2395716b38576
|
||||
F test/altertab3.test 575e771e2f02b13eb98798dc92eabacd187d6dbcf596e70f11d699b0b6b5d0b2
|
||||
F test/altertrig.test b1590647076add5a47aea0f2236c609ca0bc8a7a2462463edd3e5882c7894802
|
||||
F test/amatch1.test 8a9405f497a57705a368f242658e2aea900dd2efbc48a48024263b0df6fc1ea0
|
||||
F test/amatch1.test b5ae7065f042b7f4c1c922933f4700add50cdb9f
|
||||
F test/analyze.test 2fb21d7d64748636384e6cb8998dbf83968caf644c07fcb4f76c18f2e7ede94b
|
||||
F test/analyze3.test 42adfaedaddca1d93d9f4ac38465791e25a2e4b7a261a5278e92f554ac1e15f1
|
||||
F test/analyze3.test c5156cef33f04b90a6b9e9d5d0bbc273a0fb44147d4508407bf1080811e2c6c8
|
||||
F test/analyze4.test 68bd069f3ac7ac1e652ddd9f04f57d5606ddb4208450f5297005db7aa0dd707d
|
||||
F test/analyze5.test fa5131952303ac4146aba101b116b9c8cb89e2637531c334a6df7f7d19dddc0d
|
||||
F test/analyze6.test 028f5bdfc9e5b5294768fa9a7185b8cd1d019aa7aab5b2f8ee42d7271d9a3b28
|
||||
@@ -881,7 +879,7 @@ F test/attach3.test c59d92791070c59272e00183b7353eeb94915976
|
||||
F test/attach4.test 00e754484859998d124d144de6d114d920f2ed6ca2f961e6a7f4183c714f885e
|
||||
F test/attachmalloc.test 67309af95c6b765c13e7d2279d7fccbef78e6eb0565d75d51cefd5dc88784549
|
||||
F test/auth.test 2a01bf5bf3a0f10adf8ae3a3fd2c05af8a8c1b7a52fae227adb4ccd931915b5c
|
||||
F test/auth2.test fb34df35ceca8d24e01219e993a3c1d9cb646e83b434627e158343bda1f6e0da
|
||||
F test/auth2.test 9eb7fce9f34bf1f50d3f366fb3e606be5a2000a1
|
||||
F test/auth3.test 76d20a7fa136d63bcfcf8bcb65c0b1455ed71078d81f22bcd0550d3eb18594ab
|
||||
F test/autoanalyze1.test b9cc3f32a990fa56669b668d237c6d53e983554ae80c0604992e18869a0b2dec
|
||||
F test/autoinc.test 9df9930966dbe92c55ef37a4d89112cfd537be0d0596d397177c12db9e581be0
|
||||
@@ -902,7 +900,7 @@ F test/backup4.test 8f6fd48e0dfde77b9a3bb26dc471ede3e101df32
|
||||
F test/backup5.test ee5da6d7fe5082f5b9b0bbfa31d016f52412a2e4
|
||||
F test/backup_ioerr.test 4c3c7147cee85b024ecf6e150e090c32fdbb5135
|
||||
F test/backup_malloc.test 0c9abdf74c51e7bedb66d504cd684f28d4bd4027
|
||||
F test/badutf.test cff75b714866a4ffa0cdda252eb8fe8765483f5872c0076223c92d52b4fffd1b
|
||||
F test/badutf.test d5360fc31f643d37a973ab0d8b4fb85799c3169f
|
||||
F test/badutf2.test f310fd3b24a491b6b77bccdf14923b85d6ebcce751068c180d93a6b8ff854399
|
||||
F test/basexx1.test 4ae6ddbd92a7ebcabb5d844664c3e755d29fb69c8ddcf0c8d59bbe4e07c23919
|
||||
F test/bc_common.tcl c70b896d1d4ce72f769d2c7c1fc15b2cb07559eb2093f2736c8ca51664b29ff5
|
||||
@@ -947,8 +945,6 @@ F test/btreefault.test a82a23b0578bc587afbf9a622c8f54a54f63762f062ba8a35613cfee3
|
||||
F test/busy.test caff7164c16ce06a53af51f9e4c2753d4cc64250e00790a5e48b9c4f4be37597
|
||||
F test/busy2.test 20823a5d7c42fb257d9f108c66312d90b1bb4ec3d80ba6b4e371073727560f98
|
||||
F test/c/changeblob1.c c2f51ff87ed628634badfe635d987c21ffcc6a03554a29bff7f68607e6deb9ab
|
||||
F test/c/malloc1.c 2869384011b5dc1f019ddd94e5248a1f2dfd07db06c6ce854793c91da173b811
|
||||
F test/c/snprintf1.c a66a1ce1195bd409740a60ebeea008686ce3fbacb445840fc0a45419823b7f3f
|
||||
F test/cache.test 13bc046b26210471ca6f2889aceb1ea52dc717de
|
||||
F test/cacheflush.test af25bb1509df04c1da10e38d8f322d66eceedf61
|
||||
F test/cachespill.test 895997f84a25b323b166aecb69baab2d6380ea98f9e0bcc688c4493c535cfab9
|
||||
@@ -1029,7 +1025,7 @@ F test/crashM.test d95f59046fa749b0d0822edf18a717788c8f318d
|
||||
F test/crashtest1.c 09c1c7d728ccf4feb9e481671e29dda5669bbcc2
|
||||
F test/createtab.test 85cdfdae5c3de331cd888d6c66e1aba575b47c2e3c3cc4a1d6f54140699f5165
|
||||
F test/cse.test 00b3aea44b16828833c94fbe92475fd6977583fcb064ae0bc590986812b38d0c
|
||||
F test/csv01.test 96bc1634961682363a7b4ad5c0e38450e6e9743b38ac626422e1b56cbdc06cd8
|
||||
F test/csv01.test 2ab5514005fd308995c8910bc313e47f0368b94213b9d6c27f9a2da78796a091
|
||||
F test/ctime.test 340f362f41f92972bbd71f44e10569a5cc694062b692231bd08aa6fe6c1c4773
|
||||
F test/cursorhint.test 05cf0febe5c5f8a31f199401fd1c9322249e753950d55f26f9d5aca61408a270
|
||||
F test/cursorhint2.test 6f3aa9cb19e7418967a10ec6905209bcbb5968054da855fc36c8beee9ae9c42f
|
||||
@@ -1049,7 +1045,7 @@ F test/dbpage.test 2e3a50548edea551ef974b8f121f975852de9c5b16cb3284ac4bf2c9f2ed5
|
||||
F test/dbpagefault.test ea39de2ca86041a9c6df1135645180a76d0a8da93ac159e2fafe38e39636530b
|
||||
F test/dbstatus.test 4a4221a883025ffd39696b3d1b3910b928fb097d77e671351acb35f3aed42759
|
||||
F test/dbstatus2.test a36518c0f0951d8fd5a3dc36f99948ad1af93fb7fc0d2e03e5bb5a643186cf52
|
||||
F test/decimal.test 9e1c40ff2835775a3dae88e1e2f0d81438070e987aafa4d9aeb0a22d60e5bf44
|
||||
F test/decimal.test a11b87a2c3294eb4c11b55f3168aeac63d683fa8ada35921a6ec1d511eff7648
|
||||
F test/default.test c7124864cded213a3f118bc7e2e26f34b7c36dfa26cf6945cc8b7f5db1191277
|
||||
F test/delete.test 2686e1c98d552ef37d79ad55b17b93fe96fad9737786917ce3839767f734c48f
|
||||
F test/delete2.test 3a03f2cca1f9a67ec469915cb8babd6485db43fa
|
||||
@@ -1095,7 +1091,7 @@ F test/enc2.test 872afe58db772e7dfa1ad8e0759f8cc820e9efc8172d460fae83023101c2e43
|
||||
F test/enc3.test 55ef64416d72975c66167310a51dc9fc544ba3ae4858b8d5ab22f4cb6500b087
|
||||
F test/enc4.test c8f1ce3618508fd0909945beb8b8831feef2c020
|
||||
F test/eqp.test 1d653fe8d2612cd6764e5ea2f16dcf5f13a9f50448b9233bb1573804bccd7579
|
||||
F test/eqp2.test 188bc2293b9dab0932b6ac50c3fec62976815df072d7814d5547c821a8630819
|
||||
F test/eqp2.test 6e8996148de88f0e7670491e92e712a2920a369b4406f21a27c3c9b6a46b68dd
|
||||
F test/errmsg.test eae9f091eb39ce7e20305de45d8e5d115b68fa856fba4ea6757b6ca3705ff7f9
|
||||
F test/errofst1.test 6da78363739ba8991f498396ab331b5d64e7ab5c4172c12b5884683ef523ac53
|
||||
F test/eval.test 73969a2d43a511bf44080c44485a8c4d796b6a4f038d19e491867081155692c0
|
||||
@@ -1108,10 +1104,9 @@ F test/existsexpr2.test dc23e76389eff3d29f6488ff733012a3560cd67ec8cfaecbecd52cce
|
||||
F test/existsfault.test ff41c11f3052c1bbd4f8dd557802310026253d67d7c4e3a180c16d2f0862973e
|
||||
F test/expr.test db981f8a85520e99ae20aab7ad2e9b5b0437ed09159b57ced434c672075d2e61
|
||||
F test/expr2.test c27327ae9c017a7ff6280123f67aff496f912da74d78c888926d68b46ec75fd8
|
||||
F test/exprfault.test 7475e363c7221847855722e9dd2459cf60088f6b172c0c808dba75f89e1704b8
|
||||
F test/exprfault.test da33606d799718e2f8e34efd0e5858884a1ad87f608774c552a7f5517cc27181
|
||||
F test/exprfault2.test c49e84273898969af5dbc4fe6a3f4335f14639799f343590336c9ddf84425965
|
||||
F test/expridx1.test b464520126e1d781a7800f8540621c82e8bbc526f089ff8b0b57ffc51feea6b7
|
||||
F test/expridx2.test 13348ed208a5d18d9cef7d0a70f8e17948d3c0b5b46508c0573b7e983456165f
|
||||
F test/extension01.test 5de412c66276105901c370770175003381fdcb0c4da7054fa43cf4a31e0bfa3a
|
||||
F test/external_reader.test 6fdec43eeca23eb32faad1e95a4d1abc402bc8b3db70df12d6fc08a637f4a2b5
|
||||
F test/extraquick.test cb254400bd42bfb777ff675356aabf3287978f79
|
||||
@@ -1171,7 +1166,7 @@ F test/fts3corrupt3.test 0d5b69a0998b4adf868cc301fc78f3d0707745f1d984ce044c205cd
|
||||
F test/fts3corrupt4.test c7f414fe29b97a478d15c90382c4ae077a2bbd2283bf8c63bf66dadaaed3edb8
|
||||
F test/fts3corrupt5.test 0549f85ec4bd22e992f645f13c59b99d652f2f5e643dac75568bfd23a6db7ed5
|
||||
F test/fts3corrupt6.test f417c910254f32c0bc9ead7affa991a1d5aec35b3b32a183ffb05eea78289525
|
||||
F test/fts3corrupt7.test 8564d278801a7947d1c74d8819adee7dfed18b81574d0c42f8a1acc6759fc65a
|
||||
F test/fts3corrupt7.test 93622a4336b161a733accbd66311d93749660243cdda268fd647c21e1e680770
|
||||
F test/fts3cov.test 1e5ecea0e4c1394cea97adcfb9fd3d2d5998fd563dacf465f413e6c7fa5cffb3
|
||||
F test/fts3d.test 2bd8c97bcb9975f2334147173b4872505b6a41359a4f9068960a36afe07a679f
|
||||
F test/fts3defer.test f4c20e4c7153d20a98ee49ee5f3faef624fefc9a067f8d8d629db380c4d9f1de
|
||||
@@ -1252,7 +1247,7 @@ F test/fuzz3.test 70ba57260364b83e964707b9d4b5625284239768ab907dd387c740c0370ce3
|
||||
F test/fuzz4.test c229bcdb45518a89e1d208a21343e061503460ac69fae1539320a89f572eb634
|
||||
F test/fuzz_common.tcl b7197de6ed1ee8250a4f82d67876f4561b42ee8cbbfc6160dcb66331bad3f830
|
||||
F test/fuzz_malloc.test f348276e732e814802e39f042b1f6da6362a610af73a528d8f76898fde6b22f2
|
||||
F test/fuzzcheck.c 674d246742da18270abeef9e8510e3cd9e0e14cddca1f1e8131428928e996a6f
|
||||
F test/fuzzcheck.c 207d3d1c1d578928f16dec20df781c5d13c2fd4694b4d70e72242f4dcb799830
|
||||
F test/fuzzdata1.db 3e86d9cf5aea68ddb8e27c02d7dfdaa226347426c7eb814918e4d95475bf8517
|
||||
F test/fuzzdata2.db 128b3feeb78918d075c9b14b48610145a0dd4c8d6f1ca7c2870c7e425f5bf31f
|
||||
F test/fuzzdata3.db c6586d3e3cef0fbc18108f9bb649aa77bfc38aba
|
||||
@@ -1273,9 +1268,9 @@ F test/hexlit.test 4a6a5f46e3c65c4bf1fa06f5dd5a9507a5627751
|
||||
F test/hidden.test 23c1393a79e846d68fd902d72c85d5e5dcf98711
|
||||
F test/hook.test 2d89bf9480646feb8093be3a58ea502d6521906779ed960de31dd9c4502c0541
|
||||
F test/hook2.test b9ff3b8c6519fb67f33192f1afe86e7782ee4ac8
|
||||
F test/icu.test 3903d97f414741036e48d74af6be904eb69170f5bca7a0031ff3b33925c85582
|
||||
F test/icu.test 8da7d52cd9722c82f33b0466ed915460cb03c23a38f18a9a2d3ff97da9a4a8c0
|
||||
F test/ieee754.test 0d3ab84ab2069c9994c833a7cd820ee6037f0cf888e206a4a7fc05f735d5790a
|
||||
F test/import01.sql d9561059f4ad3f14eff20c269e64b09afd697b1aad00b03a7d5010e167dcba83
|
||||
F test/import01.sql 11a5f8325b8b04c66fe489d30558d462411432adf750cef1c0f7b06564691a8c
|
||||
F test/imposter1.sql fc5ad0945bb19622688c7a1cd7dfd1cefa4b013bac9e2628c22b03c7309f021f
|
||||
F test/imposter1.test 5a20b2cdeb53e65fc57cdb10a33750bd4ef6259909eaf1972253b9e79f7a3fb2
|
||||
F test/in.test edf979bff3244b9e47849e2b43886631354c8213791f42da92216f08012141af
|
||||
@@ -1307,7 +1302,7 @@ F test/index8.test caa097735c91dbc23d8a402f5e63a2a03c83840ba3928733ed7f9a03f8a91
|
||||
F test/index9.test 2ac891806a4136ef3e91280477e23114e67575207dc331e6797fa0ed9379f997
|
||||
F test/indexA.test 11d84f6995e6e5b9d8315953fb1b6d29772ee7c7803ee9112715e7e4dd3e4974
|
||||
F test/indexedby.test 444fb04ce0b21a3daf79f84e6735b49e5a5b3396623b37df5431eb09c8b8f557
|
||||
F test/indexexpr1.test e1e6a851d1054fa4fa43b60ad51f350519fabe756e313bc687af430a1efbff6e
|
||||
F test/indexexpr1.test d32dba192b8a566a81bb437ee8b6219931458e010c2d94610da775fa9d318f17
|
||||
F test/indexexpr2.test 1c382e81ef996d8ae8b834a74f2a9013dddf59214c32201d7c8a656d739f999a
|
||||
F test/indexexpr3.test 47b91bc7999805c9a34d356f672259bc49295ecc797448511cae554a309b47cd
|
||||
F test/indexfault.test 98d78a8ff1f5335628b62f886a1cb7c7dac1ef6d48fa39c51ec871c87dce9811
|
||||
@@ -1315,7 +1310,7 @@ F test/init.test 15c823093fdabbf7b531fe22cf037134d09587a7
|
||||
F test/insert.test 97cfb30b83ca1622b9422a1e4c4831b4cb767cf5d654660945036d1e72067e70
|
||||
F test/insert2.test 4d14b8f1b810a41995f6286b64a6943215d52208
|
||||
F test/insert3.test 1b7db95a03ad9c5013fdf7d6722b6cd66ee55e30
|
||||
F test/insert4.test 3186fea9f85a4c88f50a9a9b64d23a064fb765c34505691244952fc51c243382
|
||||
F test/insert4.test 2bf81535a990c969665d66db51fcf76c23499b39893b5109f413d1de4ad34cd3
|
||||
F test/insert5.test 79f6b6efd0d3db5f4e3ff442300b7d9e7185adb345b29aacc3ea5a9c58ab9beb
|
||||
F test/insertfault.test ac63d14ea3b49c573673a572f4014b9117383a03e497c58f308b5c776e4a7f74
|
||||
F test/instr.test 67ba309e9697c24a304e98a7c8f372456177dd4e32237d2a305e1e05f7bb79c2
|
||||
@@ -1427,7 +1422,7 @@ F test/malloctraceviewer.tcl 3e3ddf11e30d2b20f53aa16aa6615082fb24a100bea61cca721
|
||||
F test/manydb.test 28385ae2087967aa05c38624cec7d96ec74feb3e
|
||||
F test/mem5.test c6460fba403c5703141348cd90de1c294188c68f
|
||||
F test/memdb.test c1f2a343ad14398d5d6debda6ea33e80d0dafcc7
|
||||
F test/memdb1.test 413f845c0c2d20dc9808d4084de9e57d55759070eed2a4cf23cd30335a96c295
|
||||
F test/memdb1.test 916093ae5ad097660a742890a9986d1f217a620ac95efb64884041ee4c408603
|
||||
F test/memdb2.test 4ba1fc09e2f51df80d148a540e4a3fa66d0462e91167b27497084de4d1f6b5b4
|
||||
F test/memjournal.test 70f3a00c7f84ee2978ad14e831231caa1e7f23915a2c54b4f775a021d5740c6c
|
||||
F test/memjournal2.test dbc2c5cb5f7b38950f4f6dc3e73fcecf0fcbed3fc32c7ce913bba164d288da1e
|
||||
@@ -1474,8 +1469,7 @@ F test/notnull.test a37b663d5bb728d66fc182016613fb8e4a0a4bbf3d75b8876a7527f7d4ed
|
||||
F test/notnull2.test c2c7b670fb8fa6ffe5f9cc08af88864fbb8237e28b56ad528e8dee921019c5fe
|
||||
F test/notnullfault.test fc4bb7845582a2b3db376001ef49118393b1b11abe0d24adb03db057ee2b73d5
|
||||
F test/null.test b7ff206a1c60fe01aa2abd33ef9ea83c93727d993ca8a613de86e925c9f2bc6f
|
||||
F test/nulls1.test 642c27ae0792d5fc92969815eb8c4a17636cdcc164cb5b20f3d2b55a1a5d169d
|
||||
F test/nulls2.test 20356ab1de69f78363faed9c2cd8eb455bb92f805572c405131f1c5d8f2d37fb
|
||||
F test/nulls1.test 8fc70d75ab363b0f2ce9151669c2cb897def5064e2e30f7d9322970480bf6e87
|
||||
F test/numcast.test 5d126f7f581432e86a90d1e35cac625164aec4a1
|
||||
F test/numindex1.test 20a5450d4b056e48cd5db30e659f13347a099823
|
||||
F test/offset1.test c21e67d2d5ae8ed310243fbe84fc2f0dca49e9ffed3ea89110c0d5914c0de620
|
||||
@@ -1497,7 +1491,6 @@ F test/orderbyB.test 32576c7b138105bc72f7fbf33bd320ca3a7d303641fc939e0e56af6cba8
|
||||
F test/oserror.test ee3fad06ec8671c4d047c2c92a567fc2e0e8161caaec7edd6d48325c5ac97f30
|
||||
F test/ossfuzz.c b5d232d9717fc999a121c82c4880ae5b9d7fb3ae55d2d87a8da906bc80020906
|
||||
F test/ossshell.c f125c5bd16e537a2549aa579b328dd1c59905e7ab1338dfc210e755bb7b69f17
|
||||
F test/output-redirect-test.txt aeebac99f766f1e54bb2628b13c2d89a3d77de942138a01210c8a814b54c2bc8
|
||||
F test/ovfl.test 199c482696defceacee8c8e0e0ef36da62726b2f
|
||||
F test/pager1.test b083c2d5d89df8e979658d9320bfc0b9d50b4ef8ae1d9e115a692ff0b9768393
|
||||
F test/pager2.test c0ede15952b607f9a38f653acdfa73c19e657958e9104aab1a71950ea7b71831
|
||||
@@ -1510,10 +1503,10 @@ F test/pageropt.test 84e4cc5cbca285357f7906e99b21be4f2bf5abc0
|
||||
F test/pagesize.test 5769fc62d8c890a83a503f67d47508dfdc543305
|
||||
F test/parser1.test 131f4733472252d53d8ed681115257866f55740ab697fa05900d766049348f27
|
||||
F test/pcache.test c8acbedd3b6fd0f9a7ca887a83b11d24a007972b
|
||||
F test/pcache2.test 8a801d2b8e4b0ebb99701f026a67a9e84634c8aa24799a842c44003b93250da1
|
||||
F test/pcache2.test af7f3deb1a819f77a6d0d81534e97d1cf62cd442
|
||||
F test/pendingrace.test e99efc5ab3584da3dfc8cd6a0ec4e5a42214820574f5ea24ee93f1d84655f463
|
||||
F test/percentile.test fd78896fa882fa4fbf693640097859721f3629926c2ccf804af5bcb7001fd35b
|
||||
F test/permutations.test 99c5e11130387da85c216a839412b882a779596f3f2e0ecb7e0703c564182cdb
|
||||
F test/permutations.test e6de4f5777f7785737ac3d1d964b8656e5477a134665b2fe8a91884ab9b685b3
|
||||
F test/pg_common.tcl 3b27542224db1e713ae387459b5d117c836a5f6e328846922993b6d2b7640d9f
|
||||
F test/pragma.test 7d07b7bb76e273215d6a20c4f83c3062cc28976c737ccb70a686025801e86c8f
|
||||
F test/pragma2.test e5d5c176360c321344249354c0c16aec46214c9f
|
||||
@@ -1523,7 +1516,7 @@ F test/pragma5.test 7b33fc43e2e41abf17f35fb73f71b49671a380ea92a6c94b6ce530a25f8d
|
||||
F test/pragma6.test c5ec577ba087954b4dfa619a3cbe97b155b60a0af487527abe89b10fc17e6512
|
||||
F test/pragmafault.test 275edaf3161771d37de60e5c2b412627ac94cef11739236bec12ed1258b240f8
|
||||
F test/prefixes.test fe52bb0c2fee10fb9b918a095d443ebf31dd48e5e2c7a1b21feba594fe7ff2d0
|
||||
F test/printf.test 854ddc19b31e83de41142a6b0c8dbb812fcdbbb127cdcafc0c5efef58b790eee
|
||||
F test/printf.test bcb093ef5cbd17e2d94d93d62045ee61ed0f465c1ca123f284774e474e73a9ea
|
||||
F test/printf2.test 3f55c1871a5a65507416076f6eb97e738d5210aeda7595a74ee895f2224cce60
|
||||
F test/progress.test ebab27f670bd0d4eb9d20d49cef96e68141d92fb
|
||||
F test/ptrchng.test ef1aa72d6cf35a2bbd0869a649b744e9d84977fc
|
||||
@@ -1615,7 +1608,7 @@ F test/selectG.test 089f7d3d7e6db91566f00b036cb353107a2cca6220eb1cb264085a836dae
|
||||
F test/selectH.test 0b54599f1917d99568c9b929df22ec6261ed7b6d2f02a46b5945ef81b7871aac
|
||||
F test/session.test 78fa2365e93d3663a6e933f86e7afc395adf18be
|
||||
F test/sessionfuzz-data1.db 1f8d5def831f19b1c74571037f0d53a588ea49a6c4ca2a028fc0c27ef896dbcb
|
||||
F test/sessionfuzz.c 0ec813258fbfd222c62ba6867c6a5a015f098fcaa6d89e7e0ee623ea91145cf0
|
||||
F test/sessionfuzz.c f693b8827034a3bed7616d89c65fb4fe8b7ff3c0f000c6ea6beda69b7f1aced3
|
||||
F test/shared.test 50bd8091735b272732125928c363476a17b5fb264835de7d19e90c72055c888b
|
||||
F test/shared2.test 03eb4a8d372e290107d34b6ce1809919a698e879
|
||||
F test/shared3.test cb92d083003ddf0f313166e494ec2fcafa55fdebf648628923ded3169dba8850
|
||||
@@ -1628,18 +1621,17 @@ F test/sharedA.test 64bdd21216dda2c6a3bd3475348ccdc108160f34682c97f2f51c19fc0e21
|
||||
F test/sharedB.test 1a84863d7a2204e0d42f2e1606577c5e92e4473fa37ea0f5bdf829e4bf8ee707
|
||||
F test/shared_err.test 32634e404a3317eeb94abc7a099c556a346fdb8fb3858dbe222a4cbb8926a939
|
||||
F test/sharedlock.test 5ede3c37439067c43b0198f580fd374ebf15d304
|
||||
F test/shell-prompt.sql 8a320a78812d75349bd5e1a95178f7ff1f2194bb4cceee572865d127c51684b3
|
||||
F test/shell1.test 2795124bb812d84ae7995fbfda4e518328cd9f31874bc2e5eb2bfe44ac31fa16
|
||||
F test/shell1.test eda2e527435f139224dda67db6bbd2466597408d4fe5883d647d67fa32d88f7c
|
||||
F test/shell2.test dc541d2681503e55466a24d35a4cbf8ca5b90b8fcdef37fc4db07373a67d31d3
|
||||
F test/shell3.test 91efdd545097a61a1f72cf79c9ad5b49da080f3f10282eaf4c3c272cd1012db2
|
||||
F test/shell4.test e25580a792b7b54560c3a76b6968bd8189261f38979fe28e6bc6312c5db280db
|
||||
F test/shell5.test a0c43d82a811a463a5d07d6418c5a045ab01a072544db8aa31ae394e93845d8d
|
||||
F test/shell6.test 596f2eb385a1097d4e9130b4d4f663a24cba294b35f13b774b8f13553dec307d
|
||||
F test/shell7.test 6b006d296b569a7ec78b8168af77578b3bde8f58b79c32d9f46cff1eaf763a29
|
||||
F test/shell5.test a9cd2c8b62e125049ef500937674f47dd6787f0157ac0515aa554044a4dc3ea9
|
||||
F test/shell6.test e3b883b61d4916b6906678a35f9d19054861123ad91b856461e0a456273bdbb8
|
||||
F test/shell7.test 43fd8e511c533bab5232e95c7b4be93b243451709e89582600d4b6e67693d5c3
|
||||
F test/shell8.test 38c9e4d7e85d2a3ecfacaa9f6cda4f7a81bf4fffb5f3f37f9cd76827c6883192
|
||||
F test/shell9.test c0e8871061a92151450b3332279a893b516fa73a6c46d4f51a0998407cbf8c89
|
||||
F test/shellA.test 05cdaafa1f79913654487ce3aefa038d4106245d58f52e02faf506140a76d480
|
||||
F test/shellB.test 82622da7783c32ce931138bec3d5016e802d70361b9f9364b5d49c1dfc2f5af9
|
||||
F test/shellB.test 31df04230f6062069bb7c5d0e5c5439ca44448fa9da1a55aa461a4b872fe6bd9
|
||||
F test/shmlock.test 9f1f729a7fe2c46c88b156af819ac9b72c0714ac6f7246638a73c5752b5fd13c
|
||||
F test/shortread1.test bb591ef20f0fd9ed26d0d12e80eee6d7ac8897a3
|
||||
F test/show_speedtest1_rtree.tcl 32e6c5f073d7426148a6936a0408f4b5b169aba5
|
||||
@@ -1675,7 +1667,7 @@ F test/speed4p.explain 6b5f104ebeb34a038b2f714150f51d01143e59aa
|
||||
F test/speed4p.test 377a0c48e5a92e0b11c1c5ebb1bc9d83a7312c922bc0cb05970ef5d6a96d1f0c
|
||||
F test/speedtest.md ea0c85ebe0ecff8b45ba6cdb26e694871f469009a5a29dcfe634b055f05ab241
|
||||
F test/speedtest.tcl b06f6321ef90bb68f18f7b0e430e25203d9da79b80f8926986a0d5f21ac485fb x
|
||||
F test/speedtest1.c f9f30f35431bfc1d3ee9acc561624e0c0b4614071044bc302169dd27206a0fca
|
||||
F test/speedtest1.c 6c01252e66f46de0b6b8d5316e03521e2151782104f3608c10262aa5dce85721
|
||||
F test/spellfix.test 951a6405d49d1a23d6b78027d3877b4a33eeb8221dcab5704b499755bb4f552e
|
||||
F test/spellfix2.test dfc8f519a3fc204cb2dfa8b4f29821ae90f6f8c3
|
||||
F test/spellfix3.test 0f9efaaa502a0e0a09848028518a6fb096c8ad33
|
||||
@@ -1724,8 +1716,8 @@ F test/temptrigfault.tes fc5918e64f3867156fefe7cfca9d8e1f495134a5229b2b511b0dc11
|
||||
F test/temptrigger.test a00f258ed8d21a0e8fd4f322f15e8cfb5cef2e43655670e07a753e3fb4769d61
|
||||
F test/tester.tcl 2d943f60200e0a36bcd3f1f0baf181a751cd3604ef6b6bd4c8dc39b4e8a53116
|
||||
F test/testloadext.c 862b848783eaed9985fbce46c65cd214664376b549fae252b364d5d1ef350a27
|
||||
F test/testrunner.tcl 8171b887ab78d55b73fd971e22690eff0fabec913fbf3b5fbeaf159b3f00b2dc x
|
||||
F test/testrunner_data.tcl 4b3cf036d39c98b83f9289a5c047eb01089c932d4f59a81bf764f6800589b959
|
||||
F test/testrunner.tcl 8d92cacf9989aefdf33229c414adac56d389b5b6d9d31d9ebed34d5ab4e13833 x
|
||||
F test/testrunner_data.tcl 48c8a230fcada37f4809f95c2ba49e44bc3d520b6165c09173249c6e65b01cc1
|
||||
F test/testrunner_estwork.tcl 81e2ae10238f50540f42fbf2d94913052a99bfb494b69e546506323f195dcff9
|
||||
F test/thread001.test a0985c117eab62c0c65526e9fa5d1360dd1cac5b03bde223902763274ce21899
|
||||
F test/thread002.test c24c83408e35ba5a952a3638b7ac03ccdf1ce4409289c54a050ac4c5f1de7502
|
||||
@@ -2110,7 +2102,7 @@ F test/writecrash.test 13520af28f376bfc8c0bcd130efc1fff20bb165198e8b94cf153f1f75
|
||||
F test/zeroblob.test 7b74cefc7b281dfa2b07cd237987fbe94b4a2037a7771e9e83f2d5f608b1d99e
|
||||
F test/zeroblobfault.test 861d8191a0d944dfebb3cb4d2c5b4e46a5a119eaec5a63dd996c2389f8063441
|
||||
F test/zerodamage.test 9c41628db7e8d9e8a0181e59ea5f189df311a9f6ce99cc376dc461f66db6f8dc
|
||||
F test/zipfile.test 756af25d30ffd25073b113865f1ebeb12f7edfa5dddd8c37bca70e4c3150ab62
|
||||
F test/zipfile.test 7b5c2f43ce9f7c882237e74822a331d94f4f83891e7a64c503519b434d06a5bf
|
||||
F test/zipfile2.test 21afaffcf4f7769df38bf16e4a9c4dfa6ba1b0f5b695f844ec61fafb92db0db7
|
||||
F test/zipfilefault.test 44d4d7a7f7cca7521d569d7f71026b241d65a6b1757aa409c1a168827edbbc2c
|
||||
F tool/GetFile.cs 47852aa0d806fe47ed1ac5138bdce7f000fe87aaa7f28107d0cb1e26682aeb44
|
||||
@@ -2125,7 +2117,7 @@ F tool/cktclsh.sh 6075eef9c6b9ba4b38fef2ca2a66d25f2311bd3c610498d18a9b01f861629c
|
||||
F tool/cp.tcl 9a0d663ad45828de13763ee7ca0200f31f56c6d742cf104a56ae80e027c242d8
|
||||
F tool/custom.txt 24ed55e71c5edae0067ba159bbf09240d58b160331f7716e95816cd3aa0ba5c4
|
||||
F tool/dbhash.c 5da0c61032d23d74f2ab84ffc5740f0e8abec94f2c45c0b4306be7eb3ae96df0
|
||||
F tool/dbtotxt.c 88805565e06596f8b2f7143054f74d7aeaf022769b4c3d916f148a1fa17082ef
|
||||
F tool/dbtotxt.c cfeb957571735af345f253ba8417256031fa0dddf79468eefad184262d17211e
|
||||
F tool/dbtotxt.md c9a57af8739957ef36d2cfad5c4b1443ff3688ed33e4901ee200c8b651f43f3c
|
||||
F tool/emcc.sh.in 41a049468c8155433e37e656ba5bae063a000768b1d627025f277732c4e7c4a4
|
||||
F tool/enlargedb.c 3e8b2612b985cfa7e3e8800031ee191b43ae80de96abb5abbd5eada62651ee21
|
||||
@@ -2139,7 +2131,7 @@ F tool/genfkey.test b6afd7b825d797a1e1274f519ab5695373552ecad5cd373530c63533638a
|
||||
F tool/getlock.c f4c39b651370156cae979501a7b156bdba50e7ce
|
||||
F tool/index_usage.c f62a0c701b2c7ff2f3e21d206f093c123f222dbf07136a10ffd1ca15a5c706c5
|
||||
F tool/lemon.c 3fdc16b23f1ea0c91c049b518fc3f75c71843dbfe2b447fcb3cd92d9e4f219f8
|
||||
F tool/lempar.c a8de510526f9cbfb45ff0aca9d16f1c828600246f198c1c7d49c8d5492142ffa
|
||||
F tool/lempar.c b57e1780bf8098dd4a9a5bba537f994276ea825a420f6165153e5894dc2dfb07
|
||||
F tool/libvers.c caafc3b689638a1d88d44bc5f526c2278760d9b9
|
||||
F tool/loadfts.c 63412f9790e5e8538fbde0b4f6db154aaaf80f7a10a01e3c94d14b773a8dd5a6
|
||||
F tool/logest.c c34e5944318415de513d29a6098df247a9618c96d83c38d4abd88641fe46e669
|
||||
@@ -2172,7 +2164,6 @@ F tool/omittest-msvc.tcl d6b8f501ac1d7798c4126065030f89812379012cad98a1735d6d722
|
||||
F tool/omittest.tcl 436b7072e00e25e9b77145a9f67aa8e0eeabd186168827435fd03f8f981aac32
|
||||
F tool/opcodesum.tcl 740ed206ba8c5040018988129abbf3089a0ccf4a
|
||||
F tool/pagesig.c f98909b4168d9cac11a2de7f031adea0e2f3131faa7515a72807c03ec58eafeb
|
||||
F tool/renumber-win-thunk.tcl d6320eeba3a1ddfa4624003ad77e96a01819e56b4df58a698c2267ea71b79d39
|
||||
F tool/replace.tcl 511c61acfe563dfb58675efb4628bb158a13d48ff8322123ac447e9d25a82d9a
|
||||
F tool/restore_jrnl.tcl 1079ecba47cc82fa82115b81c1f68097ab1f956f357ee8da5fc4b2589af6bd98
|
||||
F tool/rollback-test.c 9fc98427d1e23e84429d7e6d07d9094fbdec65a5
|
||||
@@ -2187,7 +2178,7 @@ F tool/soak1.tcl a3892082ed1079671565c044e93b55c3c7f38829aedf53cc597c65d23ffdadd
|
||||
F tool/spaceanal.tcl 1f83962090a6b60e1d7bf92495d643e622bef9fe82ea3f2d22350dcbce9a12d0
|
||||
F tool/spellsift.tcl 52b4b04dc4333c7ab024f09d9d66ed6b6f7c6eb00b38497a09f338fa55d40618 x
|
||||
F tool/split-sqlite3c.tcl 4969fd642dad0ea483e4e104163021d92baf98f6a8eac981fe48525f9b873430
|
||||
F tool/sqldiff.c e581749af18f02a72cd18f56b465df1bef630544aebdf13993e2be55e4158f94
|
||||
F tool/sqldiff.c 847edc1e0d1e1feb652d3d6128e504456deaf254ab9ad3e7cebd4317d2037182
|
||||
F tool/sqlite3_analyzer.c.in 14f02cb5ec3c264cd6107d1f1dad77092b1cf440fc196c30b69ae87b56a1a43b
|
||||
F tool/sqlite3_rsync.c d9ce999e5b3aa9f36de44b321755622e52258774889bd804ba56f00eca01af50
|
||||
F tool/sqltclsh.c.in c103c6fc7d42bce611f9d4596774d60b7ef3d0b291a1f58c9e6184e458b89296
|
||||
@@ -2208,8 +2199,10 @@ F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee
|
||||
F tool/warnings.sh a554d13f6e5cf3760f041b87939e3d616ec6961859c3245e8ef701d1eafc2ca2
|
||||
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
|
||||
F tool/winmain.c 00c8fb88e365c9017db14c73d3c78af62194d9644feaf60e220ab0f411f3604c
|
||||
P 323d87541a63f0b2c64271c78ad6ebd5d04220da59aebfdfbc07caa691af816a
|
||||
R 51cfc435247acd41a9fef55ac14421e5
|
||||
U stephan
|
||||
Z e2e94c5a7431ca24ffccdea8baf0e5ef
|
||||
P ac00a18dcf132180295d41299f31fbc68087a27b61782d00b9633dd9661ded2b
|
||||
R 58c568d42a018658d9c21e84f3d9ab9d
|
||||
T +sym-release *
|
||||
T +sym-version-3.53.2 *
|
||||
U drh
|
||||
Z a64dcb64a02448f95d399730d70f1fe2
|
||||
# Remove this line to create a well-formed Fossil manifest.
|
||||
|
||||
+4
-2
@@ -1,2 +1,4 @@
|
||||
branch mistake
|
||||
tag mistake
|
||||
branch branch-3.53
|
||||
tag release
|
||||
tag branch-3.53
|
||||
tag version-3.53.2
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
fabcad09176cce96cacdd55ef3dde3be5b8062f513ac13a70e3db874358e6be2
|
||||
d6e03d8c777cfa2d35e3b60d8ec3e0187f3e9f99d8e2ee9cac695fd6fcdf1a24
|
||||
|
||||
+2
-21
@@ -189,14 +189,8 @@ void sqlite3AuthRead(
|
||||
** either SQLITE_OK (zero) or SQLITE_IGNORE or SQLITE_DENY. If SQLITE_DENY
|
||||
** is returned, then the error count and error message in pParse are
|
||||
** modified appropriately.
|
||||
**
|
||||
** Divided into two routines. realAuthCheck() does the work. The
|
||||
** sqlite3AuthCheck() routine is usually a fast no-op but invokes
|
||||
** realAuthCheck() (and spends time doing some stack pushes and pops
|
||||
** as a result) in the uncommon case where an authorization check is
|
||||
** actually needed.
|
||||
*/
|
||||
static int SQLITE_NOINLINE realAuthCheck(
|
||||
int sqlite3AuthCheck(
|
||||
Parse *pParse,
|
||||
int code,
|
||||
const char *zArg1,
|
||||
@@ -210,7 +204,7 @@ static int SQLITE_NOINLINE realAuthCheck(
|
||||
** or if the parser is being invoked from within sqlite3_declare_vtab.
|
||||
*/
|
||||
assert( !IN_RENAME_OBJECT || db->xAuth==0 );
|
||||
if( IN_SPECIAL_PARSE ){
|
||||
if( db->xAuth==0 || db->init.busy || IN_SPECIAL_PARSE ){
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
@@ -235,19 +229,6 @@ static int SQLITE_NOINLINE realAuthCheck(
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
int sqlite3AuthCheck(
|
||||
Parse *pParse,
|
||||
int code,
|
||||
const char *zArg1,
|
||||
const char *zArg2,
|
||||
const char *zArg3
|
||||
){
|
||||
if( pParse->db->xAuth!=0 && pParse->db->init.busy==0 ){
|
||||
return realAuthCheck(pParse,code,zArg1,zArg2,zArg3);
|
||||
}else{
|
||||
return SQLITE_OK;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Push an authorization context. After this routine is called, the
|
||||
|
||||
+54
-66
@@ -20,13 +20,13 @@
|
||||
*/
|
||||
struct sqlite3_backup {
|
||||
sqlite3* pDestDb; /* Destination database handle */
|
||||
Db *pDest; /* Destination db file */
|
||||
Btree *pDest; /* Destination b-tree file */
|
||||
u32 iDestSchema; /* Original schema cookie in destination */
|
||||
int bDestLocked; /* True once a write-transaction is open on pDest */
|
||||
|
||||
Pgno iNext; /* Page number of the next source page to copy */
|
||||
sqlite3* pSrcDb; /* Source database handle */
|
||||
Db *pSrc; /* Source db file */
|
||||
Btree *pSrc; /* Source b-tree file */
|
||||
|
||||
int rc; /* Backup process error code */
|
||||
|
||||
@@ -79,7 +79,7 @@ struct sqlite3_backup {
|
||||
** function. If an error occurs while doing so, return 0 and write an
|
||||
** error message to pErrorDb.
|
||||
*/
|
||||
static Db *findDatabase(sqlite3 *pErrorDb, sqlite3 *pDb, const char *zDb){
|
||||
static Btree *findBtree(sqlite3 *pErrorDb, sqlite3 *pDb, const char *zDb){
|
||||
int i = sqlite3FindDbName(pDb, zDb);
|
||||
|
||||
if( i==1 ){
|
||||
@@ -102,7 +102,7 @@ static Db *findDatabase(sqlite3 *pErrorDb, sqlite3 *pDb, const char *zDb){
|
||||
return 0;
|
||||
}
|
||||
|
||||
return &pDb->aDb[i];
|
||||
return pDb->aDb[i].pBt;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -110,9 +110,9 @@ static Db *findDatabase(sqlite3 *pErrorDb, sqlite3 *pDb, const char *zDb){
|
||||
** of the source.
|
||||
*/
|
||||
static int setDestPgsz(sqlite3_backup *p){
|
||||
return sqlite3BtreeSetPageSize(p->pDest->pBt,
|
||||
sqlite3BtreeGetPageSize(p->pSrc->pBt), 0, 0
|
||||
);
|
||||
int rc;
|
||||
rc = sqlite3BtreeSetPageSize(p->pDest,sqlite3BtreeGetPageSize(p->pSrc),0,0);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -181,15 +181,15 @@ sqlite3_backup *sqlite3_backup_init(
|
||||
|
||||
/* If the allocation succeeded, populate the new object. */
|
||||
if( p ){
|
||||
p->pSrc = findDatabase(pDestDb, pSrcDb, zSrcDb);
|
||||
p->pDest = findDatabase(pDestDb, pDestDb, zDestDb);
|
||||
p->pSrc = findBtree(pDestDb, pSrcDb, zSrcDb);
|
||||
p->pDest = findBtree(pDestDb, pDestDb, zDestDb);
|
||||
p->pDestDb = pDestDb;
|
||||
p->pSrcDb = pSrcDb;
|
||||
p->iNext = 1;
|
||||
p->isAttached = 0;
|
||||
|
||||
if( 0==p->pSrc || 0==p->pDest
|
||||
|| checkReadTransaction(pDestDb, p->pDest->pBt)!=SQLITE_OK
|
||||
|| checkReadTransaction(pDestDb, p->pDest)!=SQLITE_OK
|
||||
){
|
||||
/* One (or both) of the named databases did not exist or an OOM
|
||||
** error was hit. Or there is a transaction open on the destination
|
||||
@@ -201,7 +201,7 @@ sqlite3_backup *sqlite3_backup_init(
|
||||
}
|
||||
}
|
||||
if( p ){
|
||||
p->pSrc->pBt->nBackup++;
|
||||
p->pSrc->nBackup++;
|
||||
}
|
||||
|
||||
sqlite3_mutex_leave(pDestDb->mutex);
|
||||
@@ -229,18 +229,18 @@ static int backupOnePage(
|
||||
const u8 *zSrcData, /* Source database page data */
|
||||
int bUpdate /* True for an update, false otherwise */
|
||||
){
|
||||
Pager * const pDestPager = sqlite3BtreePager(p->pDest->pBt);
|
||||
const int nSrcPgsz = sqlite3BtreeGetPageSize(p->pSrc->pBt);
|
||||
int nDestPgsz = sqlite3BtreeGetPageSize(p->pDest->pBt);
|
||||
Pager * const pDestPager = sqlite3BtreePager(p->pDest);
|
||||
const int nSrcPgsz = sqlite3BtreeGetPageSize(p->pSrc);
|
||||
int nDestPgsz = sqlite3BtreeGetPageSize(p->pDest);
|
||||
const int nCopy = MIN(nSrcPgsz, nDestPgsz);
|
||||
const i64 iEnd = (i64)iSrcPg*(i64)nSrcPgsz;
|
||||
int rc = SQLITE_OK;
|
||||
i64 iOff;
|
||||
|
||||
assert( sqlite3BtreeGetReserveNoMutex(p->pSrc->pBt)>=0 );
|
||||
assert( sqlite3BtreeGetReserveNoMutex(p->pSrc)>=0 );
|
||||
assert( p->bDestLocked );
|
||||
assert( !isFatalError(p->rc) );
|
||||
assert( iSrcPg!=PENDING_BYTE_PAGE(p->pSrc->pBt->pBt) );
|
||||
assert( iSrcPg!=PENDING_BYTE_PAGE(p->pSrc->pBt) );
|
||||
assert( zSrcData );
|
||||
assert( nSrcPgsz==nDestPgsz || sqlite3PagerIsMemdb(pDestPager)==0 );
|
||||
|
||||
@@ -251,7 +251,7 @@ static int backupOnePage(
|
||||
for(iOff=iEnd-(i64)nSrcPgsz; rc==SQLITE_OK && iOff<iEnd; iOff+=nDestPgsz){
|
||||
DbPage *pDestPg = 0;
|
||||
Pgno iDest = (Pgno)(iOff/nDestPgsz)+1;
|
||||
if( iDest==PENDING_BYTE_PAGE(p->pDest->pBt->pBt) ) continue;
|
||||
if( iDest==PENDING_BYTE_PAGE(p->pDest->pBt) ) continue;
|
||||
if( SQLITE_OK==(rc = sqlite3PagerGet(pDestPager, iDest, &pDestPg, 0))
|
||||
&& SQLITE_OK==(rc = sqlite3PagerWrite(pDestPg))
|
||||
){
|
||||
@@ -269,7 +269,7 @@ static int backupOnePage(
|
||||
memcpy(zOut, zIn, nCopy);
|
||||
((u8 *)sqlite3PagerGetExtra(pDestPg))[0] = 0;
|
||||
if( iOff==0 && bUpdate==0 ){
|
||||
sqlite3Put4byte(&zOut[28], sqlite3BtreeLastPage(p->pSrc->pBt));
|
||||
sqlite3Put4byte(&zOut[28], sqlite3BtreeLastPage(p->pSrc));
|
||||
}
|
||||
}
|
||||
sqlite3PagerUnref(pDestPg);
|
||||
@@ -301,8 +301,8 @@ static int backupTruncateFile(sqlite3_file *pFile, i64 iSize){
|
||||
*/
|
||||
static void attachBackupObject(sqlite3_backup *p){
|
||||
sqlite3_backup **pp;
|
||||
assert( sqlite3BtreeHoldsMutex(p->pSrc->pBt) );
|
||||
pp = sqlite3PagerBackupPtr(sqlite3BtreePager(p->pSrc->pBt));
|
||||
assert( sqlite3BtreeHoldsMutex(p->pSrc) );
|
||||
pp = sqlite3PagerBackupPtr(sqlite3BtreePager(p->pSrc));
|
||||
p->pNext = *pp;
|
||||
*pp = p;
|
||||
p->isAttached = 1;
|
||||
@@ -316,26 +316,20 @@ int sqlite3_backup_step(sqlite3_backup *p, int nPage){
|
||||
int destMode; /* Destination journal mode */
|
||||
int pgszSrc = 0; /* Source page size */
|
||||
int pgszDest = 0; /* Destination page size */
|
||||
Btree *pDest;
|
||||
Btree *pSrc;
|
||||
|
||||
#ifdef SQLITE_ENABLE_API_ARMOR
|
||||
if( p==0 ) return SQLITE_MISUSE_BKPT;
|
||||
#endif
|
||||
assert( p->pDest );
|
||||
assert( p->pSrc );
|
||||
pDest = p->pDest->pBt;
|
||||
pSrc = p->pSrc->pBt;
|
||||
sqlite3_mutex_enter(p->pSrcDb->mutex);
|
||||
sqlite3BtreeEnter(pSrc);
|
||||
sqlite3BtreeEnter(p->pSrc);
|
||||
if( p->pDestDb ){
|
||||
sqlite3_mutex_enter(p->pDestDb->mutex);
|
||||
}
|
||||
|
||||
rc = p->rc;
|
||||
if( !isFatalError(rc) ){
|
||||
Pager * const pSrcPager = sqlite3BtreePager(pSrc); /* Source pager */
|
||||
Pager * const pDestPager = sqlite3BtreePager(pDest); /* Dest pager */
|
||||
Pager * const pSrcPager = sqlite3BtreePager(p->pSrc); /* Source pager */
|
||||
Pager * const pDestPager = sqlite3BtreePager(p->pDest); /* Dest pager */
|
||||
int ii; /* Iterator variable */
|
||||
int nSrcPage = -1; /* Size of source db in pages */
|
||||
int bCloseTrans = 0; /* True if src db requires unlocking */
|
||||
@@ -343,7 +337,7 @@ int sqlite3_backup_step(sqlite3_backup *p, int nPage){
|
||||
/* If the source pager is currently in a write-transaction, return
|
||||
** SQLITE_BUSY immediately.
|
||||
*/
|
||||
if( p->pDestDb && pSrc->pBt->inTransaction==TRANS_WRITE ){
|
||||
if( p->pDestDb && p->pSrc->pBt->inTransaction==TRANS_WRITE ){
|
||||
rc = SQLITE_BUSY;
|
||||
}else{
|
||||
rc = SQLITE_OK;
|
||||
@@ -353,8 +347,8 @@ int sqlite3_backup_step(sqlite3_backup *p, int nPage){
|
||||
** one now. If a transaction is opened here, then it will be closed
|
||||
** before this function exits.
|
||||
*/
|
||||
if( rc==SQLITE_OK && SQLITE_TXN_NONE==sqlite3BtreeTxnState(pSrc) ){
|
||||
rc = sqlite3BtreeBeginTrans(pSrc, 0, 0);
|
||||
if( rc==SQLITE_OK && SQLITE_TXN_NONE==sqlite3BtreeTxnState(p->pSrc) ){
|
||||
rc = sqlite3BtreeBeginTrans(p->pSrc, 0, 0);
|
||||
bCloseTrans = 1;
|
||||
}
|
||||
|
||||
@@ -370,7 +364,7 @@ int sqlite3_backup_step(sqlite3_backup *p, int nPage){
|
||||
|
||||
/* Lock the destination database, if it is not locked already. */
|
||||
if( SQLITE_OK==rc && p->bDestLocked==0
|
||||
&& SQLITE_OK==(rc = sqlite3BtreeBeginTrans(pDest, 2,
|
||||
&& SQLITE_OK==(rc = sqlite3BtreeBeginTrans(p->pDest, 2,
|
||||
(int*)&p->iDestSchema))
|
||||
){
|
||||
p->bDestLocked = 1;
|
||||
@@ -378,9 +372,9 @@ int sqlite3_backup_step(sqlite3_backup *p, int nPage){
|
||||
|
||||
/* Do not allow backup if the destination database is in WAL mode
|
||||
** and the page sizes are different between source and destination */
|
||||
pgszSrc = sqlite3BtreeGetPageSize(pSrc);
|
||||
pgszDest = sqlite3BtreeGetPageSize(pDest);
|
||||
destMode = sqlite3PagerGetJournalMode(sqlite3BtreePager(pDest));
|
||||
pgszSrc = sqlite3BtreeGetPageSize(p->pSrc);
|
||||
pgszDest = sqlite3BtreeGetPageSize(p->pDest);
|
||||
destMode = sqlite3PagerGetJournalMode(sqlite3BtreePager(p->pDest));
|
||||
if( SQLITE_OK==rc
|
||||
&& (destMode==PAGER_JOURNALMODE_WAL || sqlite3PagerIsMemdb(pDestPager))
|
||||
&& pgszSrc!=pgszDest
|
||||
@@ -391,11 +385,11 @@ int sqlite3_backup_step(sqlite3_backup *p, int nPage){
|
||||
/* Now that there is a read-lock on the source database, query the
|
||||
** source pager for the number of pages in the database.
|
||||
*/
|
||||
nSrcPage = (int)sqlite3BtreeLastPage(pSrc);
|
||||
nSrcPage = (int)sqlite3BtreeLastPage(p->pSrc);
|
||||
assert( nSrcPage>=0 );
|
||||
for(ii=0; (nPage<0 || ii<nPage) && p->iNext<=(Pgno)nSrcPage && !rc; ii++){
|
||||
const Pgno iSrcPg = p->iNext; /* Source page number */
|
||||
if( iSrcPg!=PENDING_BYTE_PAGE(pSrc->pBt) ){
|
||||
if( iSrcPg!=PENDING_BYTE_PAGE(p->pSrc->pBt) ){
|
||||
DbPage *pSrcPg; /* Source page object */
|
||||
rc = sqlite3PagerGet(pSrcPager, iSrcPg, &pSrcPg,PAGER_GET_READONLY);
|
||||
if( rc==SQLITE_OK ){
|
||||
@@ -422,18 +416,18 @@ int sqlite3_backup_step(sqlite3_backup *p, int nPage){
|
||||
*/
|
||||
if( rc==SQLITE_DONE ){
|
||||
if( nSrcPage==0 ){
|
||||
rc = sqlite3BtreeNewDb(pDest);
|
||||
rc = sqlite3BtreeNewDb(p->pDest);
|
||||
nSrcPage = 1;
|
||||
}
|
||||
if( rc==SQLITE_OK || rc==SQLITE_DONE ){
|
||||
rc = sqlite3BtreeUpdateMeta(pDest,1,p->iDestSchema+1);
|
||||
rc = sqlite3BtreeUpdateMeta(p->pDest,1,p->iDestSchema+1);
|
||||
}
|
||||
if( rc==SQLITE_OK ){
|
||||
if( p->pDestDb ){
|
||||
sqlite3ResetAllSchemasOfConnection(p->pDestDb);
|
||||
}
|
||||
if( destMode==PAGER_JOURNALMODE_WAL ){
|
||||
rc = sqlite3BtreeSetVersion(pDest, 2);
|
||||
rc = sqlite3BtreeSetVersion(p->pDest, 2);
|
||||
}
|
||||
}
|
||||
if( rc==SQLITE_OK ){
|
||||
@@ -450,12 +444,12 @@ int sqlite3_backup_step(sqlite3_backup *p, int nPage){
|
||||
** journalled by PagerCommitPhaseOne() before they are destroyed
|
||||
** by the file truncation.
|
||||
*/
|
||||
assert( pgszSrc==sqlite3BtreeGetPageSize(pSrc) );
|
||||
assert( pgszDest==sqlite3BtreeGetPageSize(pDest) );
|
||||
assert( pgszSrc==sqlite3BtreeGetPageSize(p->pSrc) );
|
||||
assert( pgszDest==sqlite3BtreeGetPageSize(p->pDest) );
|
||||
if( pgszSrc<pgszDest ){
|
||||
int ratio = pgszDest/pgszSrc;
|
||||
nDestTruncate = (nSrcPage+ratio-1)/ratio;
|
||||
if( nDestTruncate==(int)PENDING_BYTE_PAGE(pDest->pBt) ){
|
||||
if( nDestTruncate==(int)PENDING_BYTE_PAGE(p->pDest->pBt) ){
|
||||
nDestTruncate--;
|
||||
}
|
||||
}else{
|
||||
@@ -483,7 +477,7 @@ int sqlite3_backup_step(sqlite3_backup *p, int nPage){
|
||||
assert( pFile );
|
||||
assert( nDestTruncate==0
|
||||
|| (i64)nDestTruncate*(i64)pgszDest >= iSize || (
|
||||
nDestTruncate==(int)(PENDING_BYTE_PAGE(pDest->pBt)-1)
|
||||
nDestTruncate==(int)(PENDING_BYTE_PAGE(p->pDest->pBt)-1)
|
||||
&& iSize>=PENDING_BYTE && iSize<=PENDING_BYTE+pgszDest
|
||||
));
|
||||
|
||||
@@ -495,7 +489,7 @@ int sqlite3_backup_step(sqlite3_backup *p, int nPage){
|
||||
** journal file. */
|
||||
sqlite3PagerPagecount(pDestPager, &nDstPage);
|
||||
for(iPg=nDestTruncate; rc==SQLITE_OK && iPg<=(Pgno)nDstPage; iPg++){
|
||||
if( iPg!=PENDING_BYTE_PAGE(pDest->pBt) ){
|
||||
if( iPg!=PENDING_BYTE_PAGE(p->pDest->pBt) ){
|
||||
DbPage *pPg;
|
||||
rc = sqlite3PagerGet(pDestPager, iPg, &pPg, 0);
|
||||
if( rc==SQLITE_OK ){
|
||||
@@ -539,7 +533,7 @@ int sqlite3_backup_step(sqlite3_backup *p, int nPage){
|
||||
|
||||
/* Finish committing the transaction to the destination database. */
|
||||
if( SQLITE_OK==rc
|
||||
&& SQLITE_OK==(rc = sqlite3BtreeCommitPhaseTwo(pDest, 0))
|
||||
&& SQLITE_OK==(rc = sqlite3BtreeCommitPhaseTwo(p->pDest, 0))
|
||||
){
|
||||
rc = SQLITE_DONE;
|
||||
}
|
||||
@@ -553,8 +547,8 @@ int sqlite3_backup_step(sqlite3_backup *p, int nPage){
|
||||
*/
|
||||
if( bCloseTrans ){
|
||||
TESTONLY( int rc2 );
|
||||
TESTONLY( rc2 = ) sqlite3BtreeCommitPhaseOne(pSrc, 0);
|
||||
TESTONLY( rc2 |= ) sqlite3BtreeCommitPhaseTwo(pSrc, 0);
|
||||
TESTONLY( rc2 = ) sqlite3BtreeCommitPhaseOne(p->pSrc, 0);
|
||||
TESTONLY( rc2 |= ) sqlite3BtreeCommitPhaseTwo(p->pSrc, 0);
|
||||
assert( rc2==SQLITE_OK );
|
||||
}
|
||||
|
||||
@@ -566,7 +560,7 @@ int sqlite3_backup_step(sqlite3_backup *p, int nPage){
|
||||
if( p->pDestDb ){
|
||||
sqlite3_mutex_leave(p->pDestDb->mutex);
|
||||
}
|
||||
sqlite3BtreeLeave(pSrc);
|
||||
sqlite3BtreeLeave(p->pSrc);
|
||||
sqlite3_mutex_leave(p->pSrcDb->mutex);
|
||||
return rc;
|
||||
}
|
||||
@@ -583,17 +577,17 @@ int sqlite3_backup_finish(sqlite3_backup *p){
|
||||
if( p==0 ) return SQLITE_OK;
|
||||
pSrcDb = p->pSrcDb;
|
||||
sqlite3_mutex_enter(pSrcDb->mutex);
|
||||
sqlite3BtreeEnter(p->pSrc->pBt);
|
||||
sqlite3BtreeEnter(p->pSrc);
|
||||
if( p->pDestDb ){
|
||||
sqlite3_mutex_enter(p->pDestDb->mutex);
|
||||
}
|
||||
|
||||
/* Detach this backup from the source pager. */
|
||||
if( p->pDestDb ){
|
||||
p->pSrc->pBt->nBackup--;
|
||||
p->pSrc->nBackup--;
|
||||
}
|
||||
if( p->isAttached ){
|
||||
pp = sqlite3PagerBackupPtr(sqlite3BtreePager(p->pSrc->pBt));
|
||||
pp = sqlite3PagerBackupPtr(sqlite3BtreePager(p->pSrc));
|
||||
assert( pp!=0 );
|
||||
while( *pp!=p ){
|
||||
pp = &(*pp)->pNext;
|
||||
@@ -603,7 +597,7 @@ int sqlite3_backup_finish(sqlite3_backup *p){
|
||||
}
|
||||
|
||||
/* If a transaction is still open on the Btree, roll it back. */
|
||||
sqlite3BtreeRollback(p->pDest->pBt, SQLITE_OK, 0);
|
||||
sqlite3BtreeRollback(p->pDest, SQLITE_OK, 0);
|
||||
|
||||
/* Set the error code of the destination database handle. */
|
||||
rc = (p->rc==SQLITE_DONE) ? SQLITE_OK : p->rc;
|
||||
@@ -613,7 +607,7 @@ int sqlite3_backup_finish(sqlite3_backup *p){
|
||||
/* Exit the mutexes and free the backup context structure. */
|
||||
sqlite3LeaveMutexAndCloseZombie(p->pDestDb);
|
||||
}
|
||||
sqlite3BtreeLeave(p->pSrc->pBt);
|
||||
sqlite3BtreeLeave(p->pSrc);
|
||||
if( p->pDestDb ){
|
||||
/* EVIDENCE-OF: R-64852-21591 The sqlite3_backup object is created by a
|
||||
** call to sqlite3_backup_init() and is destroyed by a call to
|
||||
@@ -671,7 +665,7 @@ static SQLITE_NOINLINE void backupUpdate(
|
||||
){
|
||||
assert( p!=0 );
|
||||
do{
|
||||
assert( sqlite3_mutex_held(p->pSrc->pBt->pBt->mutex) );
|
||||
assert( sqlite3_mutex_held(p->pSrc->pBt->mutex) );
|
||||
if( !isFatalError(p->rc) && iPage<p->iNext ){
|
||||
/* The backup process p has already copied page iPage. But now it
|
||||
** has been modified by a transaction on the source pager. Copy
|
||||
@@ -707,7 +701,7 @@ void sqlite3BackupUpdate(sqlite3_backup *pBackup, Pgno iPage, const u8 *aData){
|
||||
void sqlite3BackupRestart(sqlite3_backup *pBackup){
|
||||
sqlite3_backup *p; /* Iterator variable */
|
||||
for(p=pBackup; p; p=p->pNext){
|
||||
assert( sqlite3_mutex_held(p->pSrc->pBt->pBt->mutex) );
|
||||
assert( sqlite3_mutex_held(p->pSrc->pBt->mutex) );
|
||||
p->iNext = 1;
|
||||
}
|
||||
}
|
||||
@@ -725,8 +719,6 @@ int sqlite3BtreeCopyFile(Btree *pTo, Btree *pFrom){
|
||||
int rc;
|
||||
sqlite3_file *pFd; /* File descriptor for database pTo */
|
||||
sqlite3_backup b;
|
||||
Db dbDest;
|
||||
Db dbSrc;
|
||||
sqlite3BtreeEnter(pTo);
|
||||
sqlite3BtreeEnter(pFrom);
|
||||
|
||||
@@ -745,13 +737,9 @@ int sqlite3BtreeCopyFile(Btree *pTo, Btree *pFrom){
|
||||
** from this function, not directly by the user.
|
||||
*/
|
||||
memset(&b, 0, sizeof(b));
|
||||
memset(&dbDest, 0, sizeof(dbDest));
|
||||
memset(&dbSrc, 0, sizeof(dbSrc));
|
||||
dbDest.pBt = pTo;
|
||||
dbSrc.pBt = pFrom;
|
||||
b.pSrcDb = pFrom->db;
|
||||
b.pSrc = &dbSrc;
|
||||
b.pDest = &dbDest;
|
||||
b.pSrc = pFrom;
|
||||
b.pDest = pTo;
|
||||
b.iNext = 1;
|
||||
|
||||
/* 0x7FFFFFFF is the hard limit for the number of pages in a database
|
||||
@@ -767,7 +755,7 @@ int sqlite3BtreeCopyFile(Btree *pTo, Btree *pFrom){
|
||||
if( rc==SQLITE_OK ){
|
||||
pTo->pBt->btsFlags &= ~BTS_PAGESIZE_FIXED;
|
||||
}else{
|
||||
sqlite3PagerClearCache(sqlite3BtreePager(pTo));
|
||||
sqlite3PagerClearCache(sqlite3BtreePager(b.pDest));
|
||||
}
|
||||
|
||||
assert( sqlite3BtreeTxnState(pTo)!=SQLITE_TXN_WRITE );
|
||||
|
||||
+4
-28
@@ -15,16 +15,6 @@
|
||||
*/
|
||||
#include "btreeInt.h"
|
||||
|
||||
/*
|
||||
** Suppress false-positive compiler warnings from GCC. Warnings are
|
||||
** re-enabled at the bottom of this source file.
|
||||
*/
|
||||
#if defined(__GNUC__) && __GNUC__>=11
|
||||
# pragma GCC diagnostic push
|
||||
# pragma GCC diagnostic ignored "-Wstringop-overread"
|
||||
# pragma GCC diagnostic ignored "-Wstringop-overflow"
|
||||
#endif
|
||||
|
||||
/*
|
||||
** The header string that appears at the beginning of every
|
||||
** SQLite database.
|
||||
@@ -5304,9 +5294,7 @@ static int accessPayload(
|
||||
if( rc==SQLITE_OK ){
|
||||
if( eOp!=0
|
||||
&& (sqlite3PagerPageRefcount(pDbPage)!=1
|
||||
|| NEVER(((MemPage*)sqlite3PagerGetExtra(pDbPage))->isInit))
|
||||
&& sqlite3FaultSim(411)==SQLITE_OK
|
||||
){
|
||||
|| NEVER(((MemPage*)sqlite3PagerGetExtra(pDbPage))->isInit)) ){
|
||||
sqlite3PagerUnref(pDbPage);
|
||||
return SQLITE_CORRUPT_PAGE(pPage);
|
||||
}
|
||||
@@ -5959,12 +5947,12 @@ moveto_table_finish:
|
||||
** zero if the cell is less than or equal pIdxKey. Return positive
|
||||
** if unknown.
|
||||
**
|
||||
** Return value negative: Cell at pPage[idx] less than pIdxKey
|
||||
** Return value negative: Cell at pCur[idx] less than pIdxKey
|
||||
**
|
||||
** Return value is zero: Cell at pPage[idx] equals pIdxKey
|
||||
** Return value is zero: Cell at pCur[idx] equals pIdxKey
|
||||
**
|
||||
** Return value positive: Nothing is known about the relationship
|
||||
** of the cell at pPage[idx] and pIdxKey.
|
||||
** of the cell at pCur[idx] and pIdxKey.
|
||||
**
|
||||
** This routine is part of an optimization. It is always safe to return
|
||||
** a positive value as that will cause the optimization to be skipped.
|
||||
@@ -10984,11 +10972,6 @@ static int checkTreePage(
|
||||
doCoverageCheck = 0;
|
||||
continue;
|
||||
}
|
||||
if( info.nPayload && info.pPayload[0]<2 ){
|
||||
checkAppendMsg(pCheck, "Bad cell header size");
|
||||
doCoverageCheck = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Check for integer primary key out of range */
|
||||
if( pPage->intKey ){
|
||||
@@ -11591,10 +11574,3 @@ int sqlite3BtreeConnectionCount(Btree *p){
|
||||
return p->pBt->nRef;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Re-enable GCC compiler warnings that were suppressed at the top
|
||||
** of this source file to prevent annoying false-positives.
|
||||
*/
|
||||
#if defined(__GNUC__) && __GNUC__>=11
|
||||
# pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
-18
@@ -714,19 +714,6 @@ Expr *sqlite3ColumnExpr(Table *pTab, Column *pCol){
|
||||
return pTab->u.tab.pDfltList->a[pCol->iDflt-1].pExpr;
|
||||
}
|
||||
|
||||
/*
|
||||
** Suppress false-positive warning message generated with -O3 in GCC
|
||||
** on the second call to sqlite3Strlen30() in the sqlite3ColumnSetColl()
|
||||
** function below. See the forum thread beginning on 2026-05-10T01:11:22Z.
|
||||
**
|
||||
** See also the "pop" pragma to undo this warning suppression immediately
|
||||
** after the function.
|
||||
*/
|
||||
#if defined(__GNUC__) && __GNUC__>=11
|
||||
# pragma GCC diagnostic push
|
||||
# pragma GCC diagnostic ignored "-Wstringop-overread"
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Set the collating sequence name for a column.
|
||||
*/
|
||||
@@ -752,11 +739,6 @@ void sqlite3ColumnSetColl(
|
||||
}
|
||||
}
|
||||
|
||||
/* Undo the false-positive warning suppression above. */
|
||||
#if defined(__GNUC__) && __GNUC__>=11
|
||||
# pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Return the collating sequence name for a column
|
||||
*/
|
||||
|
||||
+10
-91
@@ -49,51 +49,12 @@ extern const char sqlite3IsEbcdicIdChar[];
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Return zero if the given SQL string is complete - if all comments,
|
||||
** string and blob literals, and quoted identifiers have been closed and
|
||||
** if the entire string ends with ";" and possible with ";END;" if the
|
||||
** string is a CREATE TRIGGER statement. A non-zero return indicates
|
||||
** that the string is incomplete. Bits of the return value indicate
|
||||
** what is missing and is needed to close out the statement.
|
||||
** Return TRUE if the given SQL string ends in a semicolon.
|
||||
**
|
||||
** Special handling is require for CREATE TRIGGER statements.
|
||||
** Whenever the CREATE TRIGGER keywords are seen, the statement
|
||||
** must end with ";END;".
|
||||
**
|
||||
** Let the return code be a value R. R is split up into various
|
||||
** subfields, at byte boundaries:
|
||||
**
|
||||
** R = 0xwwwwwwww00xxyyzz
|
||||
**
|
||||
** In other words, zz is the least significant byte, yy is the next
|
||||
** most significant byte, xx is the third byte, wwwwwwww is a 32-bit
|
||||
** value from the middle.
|
||||
**
|
||||
** zz == SQLITE_OK Input is complete
|
||||
** zz == SQLITE_ERROR Input is incomplete
|
||||
** zz == SQLITE_MISUSE Input is a NULL pointer
|
||||
** zz != 0 New values for zz may be added in the future
|
||||
**
|
||||
** yy == 0x01 Need a semicolon at the end
|
||||
** yy == 0x02 Need "END" and a semicolon
|
||||
** yy == 0x03 Need semicolon, "END", and semicolon
|
||||
** yy != 0 New values for yy may be added in the future
|
||||
**
|
||||
** xx == '\'' Incomplete string or blob literal
|
||||
** xx == '"' Incomplete quoted identifier
|
||||
** xx == '`' Incompelte MySQL-style quoted identifier
|
||||
** xx == ']' Incomplete SQLServer-style quoted identifer
|
||||
** xx == '-' Incomplete SQL-style comment
|
||||
** xx == '/' Incomplete C-style comment
|
||||
** xx != 0 New values of xx may be added in the future
|
||||
**
|
||||
** wwwwwwww Interpret as a signed integer, the number
|
||||
** of unmatched "(". Negative means there are
|
||||
** more ")" and "(".
|
||||
**
|
||||
** ((R>>24)&0xff)!=0 New uses for the 4th byte may be added
|
||||
** in the future
|
||||
**
|
||||
** This implementation uses a state machine with 8 states:
|
||||
**
|
||||
** (0) INVALID We have not yet seen a non-whitespace character.
|
||||
@@ -140,11 +101,9 @@ extern const char sqlite3IsEbcdicIdChar[];
|
||||
** to recognize the end of a trigger can be omitted. All we have to do
|
||||
** is look for a semicolon that is not part of an string or comment.
|
||||
*/
|
||||
sqlite3_int64 sqlite3_incomplete(const char *zSql){
|
||||
int sqlite3_complete(const char *zSql){
|
||||
u8 state = 0; /* Current state, using numbers defined in header comment */
|
||||
u8 token; /* Value of the next token */
|
||||
u8 pending = 0; /* unmatched structure character */
|
||||
int nParen = 0; /* Nested parentheses */
|
||||
|
||||
#ifndef SQLITE_OMIT_TRIGGER
|
||||
/* A complex statement machine used to detect the end of a CREATE TRIGGER
|
||||
@@ -174,21 +133,11 @@ sqlite3_int64 sqlite3_incomplete(const char *zSql){
|
||||
/* 2 NORMAL: */ { 1, 2, 2, },
|
||||
};
|
||||
#endif /* SQLITE_OMIT_TRIGGER */
|
||||
/* Mapping state number to yy value for the return */
|
||||
static const u8 statemap[8] = {
|
||||
/* 0 INVALID */ 1,
|
||||
/* 1 START */ 0,
|
||||
/* 2 NORMAL */ 1,
|
||||
/* 3 EXPLAIN */ 1,
|
||||
/* 4 CREATE */ 1,
|
||||
/* 5 TRIGGER */ 3,
|
||||
/* 6 SEMI */ 2,
|
||||
/* 7 END */ 1,
|
||||
};
|
||||
|
||||
#ifdef SQLITE_ENABLE_API_ARMOR
|
||||
if( zSql==0 ){
|
||||
return SQLITE_MISUSE_BKPT;
|
||||
(void)SQLITE_MISUSE_BKPT;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -213,10 +162,7 @@ sqlite3_int64 sqlite3_incomplete(const char *zSql){
|
||||
}
|
||||
zSql += 2;
|
||||
while( zSql[0] && (zSql[0]!='*' || zSql[1]!='/') ){ zSql++; }
|
||||
if( zSql[0]==0 ){
|
||||
pending = '/';
|
||||
goto incomplete_finish;
|
||||
}
|
||||
if( zSql[0]==0 ) return 0;
|
||||
zSql++;
|
||||
token = tkWS;
|
||||
break;
|
||||
@@ -227,20 +173,14 @@ sqlite3_int64 sqlite3_incomplete(const char *zSql){
|
||||
break;
|
||||
}
|
||||
while( *zSql && *zSql!='\n' ){ zSql++; }
|
||||
if( *zSql==0 ){
|
||||
if( state!=1 ) pending = '-';
|
||||
goto incomplete_finish;
|
||||
}
|
||||
if( *zSql==0 ) return state==1;
|
||||
token = tkWS;
|
||||
break;
|
||||
}
|
||||
case '[': { /* Microsoft-style identifiers in [...] */
|
||||
zSql++;
|
||||
while( *zSql && *zSql!=']' ){ zSql++; }
|
||||
if( *zSql==0 ){
|
||||
pending = ']';
|
||||
goto incomplete_finish;
|
||||
}
|
||||
if( *zSql==0 ) return 0;
|
||||
token = tkOTHER;
|
||||
break;
|
||||
}
|
||||
@@ -250,20 +190,7 @@ sqlite3_int64 sqlite3_incomplete(const char *zSql){
|
||||
int c = *zSql;
|
||||
zSql++;
|
||||
while( *zSql && *zSql!=c ){ zSql++; }
|
||||
if( *zSql==0 ){
|
||||
pending = c;
|
||||
goto incomplete_finish;
|
||||
}
|
||||
token = tkOTHER;
|
||||
break;
|
||||
}
|
||||
case '(': {
|
||||
nParen++;
|
||||
token = tkOTHER;
|
||||
break;
|
||||
}
|
||||
case ')': {
|
||||
nParen--;
|
||||
if( *zSql==0 ) return 0;
|
||||
token = tkOTHER;
|
||||
break;
|
||||
}
|
||||
@@ -330,15 +257,7 @@ sqlite3_int64 sqlite3_incomplete(const char *zSql){
|
||||
state = trans[state][token];
|
||||
zSql++;
|
||||
}
|
||||
incomplete_finish:
|
||||
if( state==1 ) nParen = 0;
|
||||
return (i64)((((u64)nParen)<<32) |
|
||||
((u64)pending<<16) |
|
||||
((u64)statemap[state]<<8) |
|
||||
(state!=1));
|
||||
}
|
||||
int sqlite3_complete(const char *zSql){
|
||||
return sqlite3_incomplete(zSql)==0;
|
||||
return state==1;
|
||||
}
|
||||
|
||||
#ifndef SQLITE_OMIT_UTF16
|
||||
@@ -360,7 +279,7 @@ int sqlite3_complete16(const void *zSql){
|
||||
sqlite3ValueSetStr(pVal, -1, zSql, SQLITE_UTF16NATIVE, SQLITE_STATIC);
|
||||
zSql8 = sqlite3ValueText(pVal, SQLITE_UTF8);
|
||||
if( zSql8 ){
|
||||
rc = sqlite3_incomplete(zSql8)==0;
|
||||
rc = sqlite3_complete(zSql8);
|
||||
}else{
|
||||
rc = SQLITE_NOMEM_BKPT;
|
||||
}
|
||||
|
||||
+4
-6
@@ -345,7 +345,6 @@ static int dbpageUpdate(
|
||||
){
|
||||
DbpageTable *pTab = (DbpageTable *)pVtab;
|
||||
Pgno pgno;
|
||||
sqlite3_int64 pgno64;
|
||||
DbPage *pDbPage = 0;
|
||||
int rc = SQLITE_OK;
|
||||
char *zErr = 0;
|
||||
@@ -365,11 +364,11 @@ static int dbpageUpdate(
|
||||
goto update_fail;
|
||||
}
|
||||
if( sqlite3_value_type(argv[0])==SQLITE_NULL ){
|
||||
pgno64 = sqlite3_value_int64(argv[2]);
|
||||
pgno = (Pgno)sqlite3_value_int64(argv[2]);
|
||||
isInsert = 1;
|
||||
}else{
|
||||
pgno64 = (Pgno)sqlite3_value_int64(argv[0]);
|
||||
if( sqlite3_value_int64(argv[1])!=pgno64 ){
|
||||
pgno = (Pgno)sqlite3_value_int64(argv[0]);
|
||||
if( (Pgno)sqlite3_value_int(argv[1])!=pgno ){
|
||||
zErr = "cannot insert";
|
||||
goto update_fail;
|
||||
}
|
||||
@@ -386,11 +385,10 @@ static int dbpageUpdate(
|
||||
}
|
||||
}
|
||||
pBt = pTab->db->aDb[iDb].pBt;
|
||||
if( pgno64<1 || pgno64>4294967294 || NEVER(pBt==0) ){
|
||||
if( pgno<1 || NEVER(pBt==0) ){
|
||||
zErr = "bad page number";
|
||||
goto update_fail;
|
||||
}
|
||||
pgno = (Pgno)pgno64;
|
||||
szPage = sqlite3BtreeGetPageSize(pBt);
|
||||
if( sqlite3_value_type(argv[3])!=SQLITE_BLOB
|
||||
|| sqlite3_value_bytes(argv[3])!=szPage
|
||||
|
||||
+3
-6
@@ -915,7 +915,6 @@ void sqlite3GenerateRowIndexDelete(
|
||||
v = pParse->pVdbe;
|
||||
pPk = HasRowid(pTab) ? 0 : sqlite3PrimaryKeyIndex(pTab);
|
||||
for(i=0, pIdx=pTab->pIndex; pIdx; i++, pIdx=pIdx->pNext){
|
||||
int p3 = 0;
|
||||
assert( iIdxCur+i!=iDataCur || pPk==pIdx );
|
||||
if( aRegIdx!=0 && aRegIdx[i]==0 ) continue;
|
||||
if( pIdx==pPk ) continue;
|
||||
@@ -923,12 +922,10 @@ void sqlite3GenerateRowIndexDelete(
|
||||
VdbeModuleComment((v, "GenRowIdxDel for %s", pIdx->zName));
|
||||
r1 = sqlite3GenerateIndexKey(pParse, pIdx, iDataCur, 0, 1,
|
||||
&iPartIdxLabel, pPrior, r1);
|
||||
if( pIdx->bHasExpr && aRegIdx ){
|
||||
p3 = aRegIdx[i];
|
||||
}
|
||||
sqlite3VdbeAddOp3(v, OP_IdxDelete, iIdxCur+i, r1, p3);
|
||||
sqlite3VdbeAddOp3(v, OP_IdxDelete, iIdxCur+i, r1,
|
||||
pIdx->uniqNotNull ? pIdx->nKeyCol : pIdx->nColumn
|
||||
);
|
||||
sqlite3VdbeChangeP4(v, -1, (const char*)pIdx, P4_INDEX);
|
||||
sqlite3VdbeChangeP5(v, pIdx->uniqNotNull ? pIdx->nKeyCol : pIdx->nColumn);
|
||||
sqlite3ResolvePartIdxLabel(pParse, iPartIdxLabel);
|
||||
pPrior = pIdx;
|
||||
}
|
||||
|
||||
+5
-10
@@ -331,9 +331,7 @@ CollSeq *sqlite3ExprNNCollSeq(Parse *pParse, const Expr *pExpr){
|
||||
int sqlite3ExprCollSeqMatch(Parse *pParse, const Expr *pE1, const Expr *pE2){
|
||||
CollSeq *pColl1 = sqlite3ExprNNCollSeq(pParse, pE1);
|
||||
CollSeq *pColl2 = sqlite3ExprNNCollSeq(pParse, pE2);
|
||||
assert( (pColl1==pColl2) ==
|
||||
(sqlite3_stricmp(pColl1->zName,pColl2->zName)==0) );
|
||||
return pColl1==pColl2;
|
||||
return sqlite3StrICmp(pColl1->zName, pColl2->zName)==0;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -2652,7 +2650,7 @@ int sqlite3ExprIsConstant(Parse *pParse, Expr *p){
|
||||
** Walk an expression tree. Return non-zero if
|
||||
**
|
||||
** (1) the expression is constant, and
|
||||
** (2) the expression does not originate in the ON or USING clause
|
||||
** (2) the expression does originate in the ON or USING clause
|
||||
** of a LEFT JOIN, and
|
||||
** (3) the expression does not contain any EP_FixedCol TK_COLUMN
|
||||
** operands created by the constant propagation optimization.
|
||||
@@ -4170,7 +4168,6 @@ static void sqlite3ExprCodeIN(
|
||||
int rLhsOrig = rLhs;
|
||||
rLhs = sqlite3GetTempRange(pParse, nVector);
|
||||
for(i=0; i<nVector; i++){
|
||||
testcase( aiMap[i]!=i );
|
||||
sqlite3VdbeAddOp3(v, OP_Copy, rLhsOrig+i, rLhs+aiMap[i], 0);
|
||||
}
|
||||
sqlite3ReleaseTempReg(pParse, rLhsOrig);
|
||||
@@ -4191,8 +4188,7 @@ static void sqlite3ExprCodeIN(
|
||||
Expr *p = sqlite3VectorFieldSubexpr(pExpr->pLeft, i);
|
||||
if( pParse->nErr ) goto sqlite3ExprCodeIN_oom_error;
|
||||
if( sqlite3ExprCanBeNull(p) ){
|
||||
testcase( aiMap[i]!=i );
|
||||
sqlite3VdbeAddOp2(v, OP_IsNull, rLhs+aiMap[i], destStep2);
|
||||
sqlite3VdbeAddOp2(v, OP_IsNull, rLhs+i, destStep2);
|
||||
VdbeCoverage(v);
|
||||
}
|
||||
}
|
||||
@@ -4276,9 +4272,8 @@ static void sqlite3ExprCodeIN(
|
||||
** ...)" is the collating sequence of x.". */
|
||||
pColl = sqlite3ExprCollSeq(pParse, p);
|
||||
}
|
||||
testcase( aiMap[i]!=i );
|
||||
sqlite3VdbeAddOp3(v, OP_Column, iTab, aiMap[i], r3);
|
||||
sqlite3VdbeAddOp4(v, OP_Ne, rLhs+aiMap[i], destNotNull, r3,
|
||||
sqlite3VdbeAddOp3(v, OP_Column, iTab, i, r3);
|
||||
sqlite3VdbeAddOp4(v, OP_Ne, rLhs+i, destNotNull, r3,
|
||||
(void*)pColl, P4_COLLSEQ);
|
||||
VdbeCoverage(v);
|
||||
sqlite3ReleaseTempReg(pParse, r3);
|
||||
|
||||
+16
-39
@@ -130,17 +130,13 @@ static void lengthFunc(
|
||||
case SQLITE_TEXT: {
|
||||
const unsigned char *z = sqlite3_value_text(argv[0]);
|
||||
const unsigned char *z0;
|
||||
unsigned char c;
|
||||
if( z==0 ) return;
|
||||
z0 = z;
|
||||
while( 1 /*exit-by-break*/ ){
|
||||
/* vvvvvv---- See tag-20260418-01 */
|
||||
if( (u8)(z[0]-1)<(0x80-1) ){
|
||||
z++;
|
||||
}else if( z[0]==0 ){
|
||||
break;
|
||||
}else{
|
||||
z++;
|
||||
while( (z[0]&0xc0)==0x80 ){ z++; z0++; }
|
||||
while( (c = *z)!=0 ){
|
||||
z++;
|
||||
if( c>=0xc0 ){
|
||||
while( (*z & 0xc0)==0x80 ){ z++; z0++; }
|
||||
}
|
||||
}
|
||||
sqlite3_result_int(context, (int)(z-z0));
|
||||
@@ -428,25 +424,12 @@ static void substrFunc(
|
||||
}
|
||||
assert( p1>=0 && p2>=0 );
|
||||
if( p0type!=SQLITE_BLOB ){
|
||||
for( ; p1>0; p1--){
|
||||
/* vvvvvv---- See tag-20260418-01 */
|
||||
if( (u8)(z[0]-1)<(0x80-1) ){
|
||||
z++;
|
||||
}else if( z[0]==0 ){
|
||||
break;
|
||||
}else{
|
||||
do{ z++; }while( (z[0]&0xc0)==0x80 );
|
||||
}
|
||||
while( *z && p1 ){
|
||||
SQLITE_SKIP_UTF8(z);
|
||||
p1--;
|
||||
}
|
||||
for(z2=z; p2>0; p2--){
|
||||
/* vvvvvv---- See tag-20260418-01 */
|
||||
if( (u8)(z2[0]-1)<(0x80-1) ){
|
||||
z2++;
|
||||
}else if( z2[0]==0 ){
|
||||
break;
|
||||
}else{
|
||||
do{ z2++; }while( (z2[0]&0xc0)==0x80 );
|
||||
}
|
||||
for(z2=z; *z2 && p2; p2--){
|
||||
SQLITE_SKIP_UTF8(z2);
|
||||
}
|
||||
sqlite3_result_text64(context, (char*)z, z2-z, SQLITE_TRANSIENT,
|
||||
SQLITE_UTF8);
|
||||
@@ -1513,7 +1496,7 @@ static void replaceFunc(
|
||||
int nRep; /* Size of zRep */
|
||||
i64 nOut; /* Maximum size of zOut */
|
||||
int loopLimit; /* Last zStr[] that might match zPattern[] */
|
||||
i64 i, j; /* Loop counters */
|
||||
int i, j; /* Loop counters */
|
||||
unsigned cntExpand; /* Number zOut expansions */
|
||||
sqlite3 *db = sqlite3_context_db_handle(context);
|
||||
|
||||
@@ -2974,8 +2957,7 @@ static void percentSort(double *a, unsigned int n){
|
||||
int i; /* Loop counter */
|
||||
double rPivot; /* The pivot value */
|
||||
|
||||
assert( n>=2 );
|
||||
do{
|
||||
while( n>=2 ){
|
||||
if( a[0]>a[n-1] ){
|
||||
SWAP_DOUBLE(a[0],a[n-1])
|
||||
}
|
||||
@@ -3004,12 +2986,7 @@ static void percentSort(double *a, unsigned int n){
|
||||
i++;
|
||||
}
|
||||
}while( i<iGt );
|
||||
|
||||
/* Recurse on the smaller partition only. The smaller partition
|
||||
** will hold n/2 or fewer entries, which assures that the stack
|
||||
** depth will not exceed O(log(n)), even for pathological cases.
|
||||
** Loop without recursion for the larger partition. */
|
||||
if( iLt>(int)(n/2) ){
|
||||
if( iLt>n/2 ){
|
||||
if( n-iGt>=2 ) percentSort(a+iGt, n-iGt);
|
||||
n = iLt;
|
||||
}else{
|
||||
@@ -3017,7 +2994,7 @@ static void percentSort(double *a, unsigned int n){
|
||||
a += iGt;
|
||||
n -= iGt;
|
||||
}
|
||||
}while( n>=2 );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -3142,7 +3119,7 @@ static void filestatFunc(
|
||||
assert( pPager!=0 );
|
||||
fd = sqlite3PagerFile(pPager);
|
||||
pStr = sqlite3_str_new(db);
|
||||
if( sqlite3_str_errcode(pStr) ){
|
||||
if( pStr==0 ){
|
||||
sqlite3_result_error_nomem(context);
|
||||
}else{
|
||||
sqlite3_str_append(pStr, "{\"db\":", 6);
|
||||
@@ -3245,7 +3222,7 @@ static void parseuriFunc(
|
||||
flgs = (unsigned int)sqlite3_value_int(argv[1]);
|
||||
rc = sqlite3ParseUri(zVfs, zUri, &flgs, &pVfs, &zFile, &zErr);
|
||||
pResult = sqlite3_str_new(0);
|
||||
if( !sqlite3_str_errcode(pResult) ){
|
||||
if( pResult ){
|
||||
int i;
|
||||
sqlite3_str_appendf(pResult, "rc=%d", rc);
|
||||
sqlite3_str_appendf(pResult, ", flags=0x%x", flgs);
|
||||
|
||||
+1
-1
@@ -28,7 +28,7 @@
|
||||
}
|
||||
|
||||
#elif !defined(__STRICT_ANSI__) && defined(__GNUC__) && \
|
||||
(defined(i586) || defined(__i586__) || defined(_M_IX86))
|
||||
(defined(i386) || defined(__i386__) || defined(_M_IX86))
|
||||
|
||||
__inline__ sqlite_uint64 sqlite3Hwtime(void){
|
||||
unsigned int lo, hi;
|
||||
|
||||
+4
-68
@@ -2809,10 +2809,7 @@ void sqlite3CompleteInsertion(
|
||||
|| pIdx->pNext==0
|
||||
|| pIdx->pNext->onError==OE_Replace );
|
||||
if( aRegIdx[i]==0 ) continue;
|
||||
if( pIdx->pPartIdxWhere || (update_flags && pIdx->bHasExpr) ){
|
||||
/* If this is a partial index, or an UPDATE of an index on an
|
||||
** expression, then the record register may be set to NULL to indicate
|
||||
** that no record should be inserted into this index. */
|
||||
if( pIdx->pPartIdxWhere ){
|
||||
sqlite3VdbeAddOp2(v, OP_IsNull, aRegIdx[i], sqlite3VdbeCurrentAddr(v)+2);
|
||||
VdbeCoverage(v);
|
||||
}
|
||||
@@ -2987,44 +2984,6 @@ static int xferCompatibleIndex(Index *pDest, Index *pSrc){
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
** Examine an expression node and abort if it references the ROWID.
|
||||
** This is a Walker callback used by xferCompatibleCheck()
|
||||
*/
|
||||
static int xferCheckRowid(Walker *pWalk, Expr *pExpr){
|
||||
if( pExpr->op==TK_COLUMN && pExpr->iColumn<0 ){
|
||||
pWalk->eCode = 1;
|
||||
return WRC_Abort;
|
||||
}else{
|
||||
return WRC_Continue;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Analyze CHECK constraints on the source and destination tables and
|
||||
** return true if those CHECK constraints are compatible with the
|
||||
** xfer-optimization.
|
||||
**
|
||||
** * The pDest and pSrc tables must have identical CHECK constraints.
|
||||
**
|
||||
** * If the destination table, pDest, does not have an
|
||||
** INTEGER PRIMARY KEY column, then no CHECK constraint may
|
||||
** referenced the ROWID. (See forum post 2026-05-11T13:15:57Z)
|
||||
*/
|
||||
static int xferCompatibleCheck(Table *pDest, Table *pSrc){
|
||||
if( sqlite3ExprListCompare(pSrc->pCheck,pDest->pCheck,-1) ){
|
||||
return 0;
|
||||
}
|
||||
if( pDest->iPKey<0 ){
|
||||
Walker w;
|
||||
memset(&w, 0, sizeof(w));
|
||||
w.xExprCallback = xferCheckRowid;
|
||||
sqlite3WalkExprList(&w,pDest->pCheck);
|
||||
if( w.eCode ) return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
** Attempt the transfer optimization on INSERTs of the form
|
||||
**
|
||||
@@ -3151,19 +3110,8 @@ static int xferOptimization(
|
||||
if( pDest->iPKey!=pSrc->iPKey ){
|
||||
return 0; /* Both tables must have the same INTEGER PRIMARY KEY */
|
||||
}
|
||||
if( (pDest->tabFlags & TF_Strict)!=0 ){
|
||||
if( (pSrc->tabFlags & TF_Strict)==0 ){
|
||||
return 0; /* Cannot feed from a non-strict into a strict table */
|
||||
}
|
||||
for(i=0; i<pDest->nCol; i++){
|
||||
unsigned eDestType = pDest->aCol[i].eCType;
|
||||
unsigned eSrcType = pSrc->aCol[i].eCType;
|
||||
if( eDestType==COLTYPE_ANY ) continue;
|
||||
if( eDestType==eSrcType ) continue;
|
||||
if( eDestType==COLTYPE_INT && eSrcType==COLTYPE_INTEGER ) continue;
|
||||
if( eDestType==COLTYPE_INTEGER && eSrcType==COLTYPE_INT ) continue;
|
||||
return 0; /* Incompatible types in source and destination */
|
||||
}
|
||||
if( (pDest->tabFlags & TF_Strict)!=0 && (pSrc->tabFlags & TF_Strict)==0 ){
|
||||
return 0; /* Cannot feed from a non-strict into a strict table */
|
||||
}
|
||||
for(i=0; i<pDest->nCol; i++){
|
||||
Column *pDestCol = &pDest->aCol[i];
|
||||
@@ -3257,7 +3205,7 @@ static int xferOptimization(
|
||||
#ifndef SQLITE_OMIT_CHECK
|
||||
if( pDest->pCheck
|
||||
&& (db->mDbFlags & DBFLAG_Vacuum)==0
|
||||
&& !xferCompatibleCheck(pDest,pSrc)
|
||||
&& sqlite3ExprListCompare(pSrc->pCheck,pDest->pCheck,-1)
|
||||
){
|
||||
return 0; /* Tables have different CHECK constraints. Ticket #2252 */
|
||||
}
|
||||
@@ -3278,18 +3226,6 @@ static int xferOptimization(
|
||||
if( (db->flags & SQLITE_CountRows)!=0 ){
|
||||
return 0; /* xfer opt does not play well with PRAGMA count_changes */
|
||||
}
|
||||
#ifndef SQLITE_OMIT_AUTHORIZATION
|
||||
if( db->xAuth ){
|
||||
int iDb = sqlite3SchemaToIndex(db, pSrc->pSchema);
|
||||
if( sqlite3AuthCheck(pParse, SQLITE_SELECT, 0, 0, 0) ) return 0;
|
||||
for(i=0; i<pSrc->nCol; i++){
|
||||
Column *pSrcCol = &pSrc->aCol[i];
|
||||
if( sqlite3AuthReadCol(pParse, pSrc->zName, pSrcCol->zCnName, iDb) ){
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* If we get this far, it means that the xfer optimization is at
|
||||
** least a possibility, though it might only work if the destination
|
||||
|
||||
+8
-13
@@ -2341,7 +2341,7 @@ static u32 jsonTranslateBlobToText(
|
||||
break;
|
||||
case 0xe2:
|
||||
/* '\' followed by either U+2028 or U+2029 is ignored as
|
||||
** whitespace. Note that in UTF8, U+2028 is 0xe2 0x80 0x29.
|
||||
** whitespace. Not that in UTF8, U+2028 is 0xe2 0x80 0x29.
|
||||
** U+2029 is the same except for the last byte */
|
||||
if( sz2<4
|
||||
|| 0x80!=(u8)zIn[2]
|
||||
@@ -5255,15 +5255,6 @@ static void jsonAppendPathName(JsonEachCursor *p){
|
||||
}
|
||||
}
|
||||
|
||||
/* Report a "malformed JSON" or OOM error against the cursor.
|
||||
*/
|
||||
static int jsonEachMalformedInput(sqlite3_vtab_cursor *cur){
|
||||
sqlite3_free(cur->pVtab->zErrMsg);
|
||||
cur->pVtab->zErrMsg = sqlite3_mprintf("malformed JSON");
|
||||
jsonEachCursorReset((JsonEachCursor*)cur);
|
||||
return cur->pVtab->zErrMsg ? SQLITE_ERROR : SQLITE_NOMEM;
|
||||
}
|
||||
|
||||
/* Advance the cursor to the next element for json_tree() */
|
||||
static int jsonEachNext(sqlite3_vtab_cursor *cur){
|
||||
JsonEachCursor *p = (JsonEachCursor*)cur;
|
||||
@@ -5275,7 +5266,6 @@ static int jsonEachNext(sqlite3_vtab_cursor *cur){
|
||||
u32 i = jsonSkipLabel(p);
|
||||
x = p->sParse.aBlob[i] & 0x0f;
|
||||
n = jsonbPayloadSize(&p->sParse, i, &sz);
|
||||
if( n==0 )return jsonEachMalformedInput(cur);
|
||||
if( x==JSONB_OBJECT || x==JSONB_ARRAY ){
|
||||
JsonParent *pParent;
|
||||
if( p->nParent>=p->nParentAlloc ){
|
||||
@@ -5321,7 +5311,6 @@ static int jsonEachNext(sqlite3_vtab_cursor *cur){
|
||||
u32 n, sz = 0;
|
||||
u32 i = jsonSkipLabel(p);
|
||||
n = jsonbPayloadSize(&p->sParse, i, &sz);
|
||||
if( n==0 )return jsonEachMalformedInput(cur);
|
||||
p->i = i + n + sz;
|
||||
}
|
||||
if( p->eType==JSONB_ARRAY && p->nParent ){
|
||||
@@ -5558,7 +5547,7 @@ static int jsonEachFilter(
|
||||
if( p->sParse.oom ){
|
||||
return SQLITE_NOMEM;
|
||||
}
|
||||
return jsonEachMalformedInput(cur);
|
||||
goto json_each_malformed_input;
|
||||
}
|
||||
}
|
||||
if( idxNum==3 ){
|
||||
@@ -5619,6 +5608,12 @@ static int jsonEachFilter(
|
||||
p->aParent[0].iValue = i;
|
||||
}
|
||||
return SQLITE_OK;
|
||||
|
||||
json_each_malformed_input:
|
||||
sqlite3_free(cur->pVtab->zErrMsg);
|
||||
cur->pVtab->zErrMsg = sqlite3_mprintf("malformed JSON");
|
||||
jsonEachCursorReset(p);
|
||||
return cur->pVtab->zErrMsg ? SQLITE_ERROR : SQLITE_NOMEM;
|
||||
}
|
||||
|
||||
/* The methods of the json_each virtual table */
|
||||
|
||||
+2
-3
@@ -528,12 +528,11 @@ static const sqlite3_api_routines sqlite3Apis = {
|
||||
sqlite3_str_free,
|
||||
#ifdef SQLITE_ENABLE_CARRAY
|
||||
sqlite3_carray_bind,
|
||||
sqlite3_carray_bind_v2,
|
||||
sqlite3_carray_bind_v2
|
||||
#else
|
||||
0,
|
||||
0,
|
||||
0
|
||||
#endif
|
||||
sqlite3_incomplete
|
||||
};
|
||||
|
||||
/* True if x is the directory separator character
|
||||
|
||||
+2
-3
@@ -518,7 +518,7 @@ int sqlite3_config(int op, ...){
|
||||
break;
|
||||
}
|
||||
case SQLITE_CONFIG_SMALL_MALLOC: {
|
||||
sqlite3GlobalConfig.bSmallMalloc = va_arg(ap, int)!=0;
|
||||
sqlite3GlobalConfig.bSmallMalloc = va_arg(ap, int);
|
||||
break;
|
||||
}
|
||||
case SQLITE_CONFIG_PAGECACHE: {
|
||||
@@ -1136,8 +1136,7 @@ void sqlite3_set_last_insert_rowid(sqlite3 *db, sqlite3_int64 iRowid){
|
||||
}
|
||||
|
||||
/*
|
||||
** Return the number of changes in the most recently executed DML
|
||||
** statement.
|
||||
** Return the number of changes in the most recent call to sqlite3_exec().
|
||||
*/
|
||||
sqlite3_int64 sqlite3_changes64(sqlite3 *db){
|
||||
#ifdef SQLITE_ENABLE_API_ARMOR
|
||||
|
||||
+16
-35
@@ -35,15 +35,8 @@
|
||||
# define SQLITE_MUTEX_NREF 0
|
||||
#endif
|
||||
|
||||
#if GCC_VERSION>0
|
||||
# define ALIGN128 __attribute__((aligned(128)))
|
||||
#else
|
||||
# define ALIGN128
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Each SQLite mutex is an instance of the following structure.
|
||||
**
|
||||
** Each recursive mutex is an instance of the following structure.
|
||||
*/
|
||||
struct sqlite3_mutex {
|
||||
pthread_mutex_t mutex; /* Mutex controlling the lock */
|
||||
@@ -158,31 +151,19 @@ static int pthreadMutexEnd(void){ return SQLITE_OK; }
|
||||
** the same type number.
|
||||
*/
|
||||
static sqlite3_mutex *pthreadMutexAlloc(int iType){
|
||||
/* Static mutexes - those with IDs of 2 or more...
|
||||
**
|
||||
** The ALIGN128 macro attempts to force 128-byte alignment on mutexes,
|
||||
** so that adjacent mutex objects are always on different cache lines
|
||||
** in the CPU. This is CPU-dependent, of course, but 128-byte alignment
|
||||
** seems to work well for all contemporary processors. Experiments show
|
||||
** that 64 works just as well most of the time, but the internet says
|
||||
** that 128-byte alignment works better.
|
||||
*/
|
||||
static ALIGN128 union staticMutex {
|
||||
sqlite3_mutex m;
|
||||
char aSpacer[128];
|
||||
} aMutex[] = {
|
||||
{ .m = SQLITE3_MUTEX_INITIALIZER(2) },
|
||||
{ .m = SQLITE3_MUTEX_INITIALIZER(3) },
|
||||
{ .m = SQLITE3_MUTEX_INITIALIZER(4) },
|
||||
{ .m = SQLITE3_MUTEX_INITIALIZER(5) },
|
||||
{ .m = SQLITE3_MUTEX_INITIALIZER(6) },
|
||||
{ .m = SQLITE3_MUTEX_INITIALIZER(7) },
|
||||
{ .m = SQLITE3_MUTEX_INITIALIZER(8) },
|
||||
{ .m = SQLITE3_MUTEX_INITIALIZER(9) },
|
||||
{ .m = SQLITE3_MUTEX_INITIALIZER(10) },
|
||||
{ .m = SQLITE3_MUTEX_INITIALIZER(11) },
|
||||
{ .m = SQLITE3_MUTEX_INITIALIZER(12) },
|
||||
{ .m = SQLITE3_MUTEX_INITIALIZER(13) },
|
||||
static sqlite3_mutex staticMutexes[] = {
|
||||
SQLITE3_MUTEX_INITIALIZER(2),
|
||||
SQLITE3_MUTEX_INITIALIZER(3),
|
||||
SQLITE3_MUTEX_INITIALIZER(4),
|
||||
SQLITE3_MUTEX_INITIALIZER(5),
|
||||
SQLITE3_MUTEX_INITIALIZER(6),
|
||||
SQLITE3_MUTEX_INITIALIZER(7),
|
||||
SQLITE3_MUTEX_INITIALIZER(8),
|
||||
SQLITE3_MUTEX_INITIALIZER(9),
|
||||
SQLITE3_MUTEX_INITIALIZER(10),
|
||||
SQLITE3_MUTEX_INITIALIZER(11),
|
||||
SQLITE3_MUTEX_INITIALIZER(12),
|
||||
SQLITE3_MUTEX_INITIALIZER(13)
|
||||
};
|
||||
sqlite3_mutex *p;
|
||||
switch( iType ){
|
||||
@@ -219,12 +200,12 @@ static sqlite3_mutex *pthreadMutexAlloc(int iType){
|
||||
}
|
||||
default: {
|
||||
#ifdef SQLITE_ENABLE_API_ARMOR
|
||||
if( iType-2<0 || iType-2>=ArraySize(aMutex) ){
|
||||
if( iType-2<0 || iType-2>=ArraySize(staticMutexes) ){
|
||||
(void)SQLITE_MISUSE_BKPT;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
p = &aMutex[iType-2].m;
|
||||
p = &staticMutexes[iType-2];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
+94
-87
@@ -31,29 +31,11 @@
|
||||
*/
|
||||
#ifdef SQLITE_MUTEX_W32
|
||||
|
||||
#if MSVC_VERSION>0
|
||||
# define ALIGN128 __declspec(align(128))
|
||||
#else
|
||||
# define ALIGN128
|
||||
#endif
|
||||
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable: 4324)
|
||||
/*
|
||||
** Each SQLite mutex is an instance of the following structure.
|
||||
**
|
||||
** The ALIGN128 macro attempts to force 128-byte alignment on mutexes,
|
||||
** so that adjacent mutex objects are always on different cache lines
|
||||
** in the CPU. This is CPU-dependent, of course, but 128-byte alignment
|
||||
** seems to work well for all contemporary processors. Experiments show
|
||||
** that 64 works just as well most of the time, but the internet says
|
||||
** that 128-byte alignment works better.
|
||||
** Each recursive mutex is an instance of the following structure.
|
||||
*/
|
||||
struct sqlite3_mutex {
|
||||
union {
|
||||
CRITICAL_SECTION cs; /* The CRITICAL_SECTION mutex. id==1 */
|
||||
SRWLOCK srwl; /* The Slim reader/writer lock. id!=1 */
|
||||
} u;
|
||||
struct sqlite3_mutex {
|
||||
CRITICAL_SECTION mutex; /* Mutex controlling the lock */
|
||||
int id; /* Mutex type */
|
||||
#ifdef SQLITE_DEBUG
|
||||
volatile int nRef; /* Number of entrances */
|
||||
@@ -61,7 +43,20 @@ struct sqlite3_mutex {
|
||||
volatile LONG trace; /* True to trace changes */
|
||||
#endif
|
||||
};
|
||||
#pragma warning(pop)
|
||||
|
||||
/*
|
||||
** These are the initializer values used when declaring a "static" mutex
|
||||
** on Win32. It should be noted that all mutexes require initialization
|
||||
** on the Win32 platform.
|
||||
*/
|
||||
#define SQLITE_W32_MUTEX_INITIALIZER { 0 }
|
||||
|
||||
#ifdef SQLITE_DEBUG
|
||||
#define SQLITE3_MUTEX_INITIALIZER(id) { SQLITE_W32_MUTEX_INITIALIZER, id, \
|
||||
0L, (DWORD)0, 0 }
|
||||
#else
|
||||
#define SQLITE3_MUTEX_INITIALIZER(id) { SQLITE_W32_MUTEX_INITIALIZER, id }
|
||||
#endif
|
||||
|
||||
#ifdef SQLITE_DEBUG
|
||||
/*
|
||||
@@ -72,8 +67,13 @@ static int winMutexHeld(sqlite3_mutex *p){
|
||||
return p->nRef!=0 && p->owner==GetCurrentThreadId();
|
||||
}
|
||||
|
||||
static int winMutexNotheld2(sqlite3_mutex *p, DWORD tid){
|
||||
return p->nRef==0 || p->owner!=tid;
|
||||
}
|
||||
|
||||
static int winMutexNotheld(sqlite3_mutex *p){
|
||||
return p->nRef==0 || p->owner!=GetCurrentThreadId();
|
||||
DWORD tid = GetCurrentThreadId();
|
||||
return winMutexNotheld2(p, tid);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -95,42 +95,41 @@ void sqlite3MemoryBarrier(void){
|
||||
}
|
||||
|
||||
/*
|
||||
** Static mutexes.
|
||||
**
|
||||
** The ALIGN128 macro on the static mutex array forces 128-byte alignment
|
||||
** on the mutexes so that adjacent mutex objects are always on different
|
||||
** cache lines in the CPU. This is CPU-dependent, of course, but 128-byte
|
||||
** alignment seems to work well for all contemporary processors.
|
||||
** Experiments show that 64 works just as well most of the time, but
|
||||
** the internet says that 128-byte alignment works better.
|
||||
** Initialize and deinitialize the mutex subsystem.
|
||||
*/
|
||||
static ALIGN128 union staticMutexes {
|
||||
sqlite3_mutex m;
|
||||
char spacer[128];
|
||||
} aWindowsMutex[12];
|
||||
static sqlite3_mutex winMutex_staticMutexes[] = {
|
||||
SQLITE3_MUTEX_INITIALIZER(2),
|
||||
SQLITE3_MUTEX_INITIALIZER(3),
|
||||
SQLITE3_MUTEX_INITIALIZER(4),
|
||||
SQLITE3_MUTEX_INITIALIZER(5),
|
||||
SQLITE3_MUTEX_INITIALIZER(6),
|
||||
SQLITE3_MUTEX_INITIALIZER(7),
|
||||
SQLITE3_MUTEX_INITIALIZER(8),
|
||||
SQLITE3_MUTEX_INITIALIZER(9),
|
||||
SQLITE3_MUTEX_INITIALIZER(10),
|
||||
SQLITE3_MUTEX_INITIALIZER(11),
|
||||
SQLITE3_MUTEX_INITIALIZER(12),
|
||||
SQLITE3_MUTEX_INITIALIZER(13)
|
||||
};
|
||||
|
||||
static int winMutex_isInit = 0;
|
||||
static int winMutex_isNt = -1; /* <0 means "need to query" */
|
||||
|
||||
/* As the winMutexInit() and winMutexEnd() functions are called as part
|
||||
** of the sqlite3_initialize() and sqlite3_shutdown() processing, the
|
||||
** "interlocked" magic used here is probably not strictly necessary.
|
||||
*/
|
||||
static LONG volatile winMutex_lock = 0;
|
||||
static LONG SQLITE_WIN32_VOLATILE winMutex_lock = 0;
|
||||
|
||||
int sqlite3_win32_is_nt(void); /* os_win.c */
|
||||
void sqlite3_win32_sleep(DWORD milliseconds); /* os_win.c */
|
||||
|
||||
static int winMutexInit(void){
|
||||
/* The first to increment to 1 does actual initialization */
|
||||
if( InterlockedCompareExchange(&winMutex_lock, 1, 0)==0 ){
|
||||
int i;
|
||||
for(i=0; i<ArraySize(aWindowsMutex); i++){
|
||||
sqlite3_mutex *p = &aWindowsMutex[i].m;
|
||||
p->id = i+2;
|
||||
InitializeSRWLock(&p->u.srwl);
|
||||
#ifdef SQLITE_DEBUG
|
||||
p->nRef = 0;
|
||||
p->owner = 0;
|
||||
p->trace = 0;
|
||||
#endif
|
||||
for(i=0; i<ArraySize(winMutex_staticMutexes); i++){
|
||||
InitializeCriticalSection(&winMutex_staticMutexes[i].mutex);
|
||||
}
|
||||
winMutex_isInit = 1;
|
||||
}else{
|
||||
@@ -148,6 +147,10 @@ static int winMutexEnd(void){
|
||||
** (which should be the last to shutdown.) */
|
||||
if( InterlockedCompareExchange(&winMutex_lock, 0, 1)==1 ){
|
||||
if( winMutex_isInit==1 ){
|
||||
int i;
|
||||
for(i=0; i<ArraySize(winMutex_staticMutexes); i++){
|
||||
DeleteCriticalSection(&winMutex_staticMutexes[i].mutex);
|
||||
}
|
||||
winMutex_isInit = 0;
|
||||
}
|
||||
}
|
||||
@@ -216,22 +219,18 @@ static sqlite3_mutex *winMutexAlloc(int iType){
|
||||
p->trace = 1;
|
||||
#endif
|
||||
#endif
|
||||
if( iType==SQLITE_MUTEX_RECURSIVE ){
|
||||
InitializeCriticalSection(&p->u.cs);
|
||||
}else{
|
||||
InitializeSRWLock(&p->u.srwl);
|
||||
}
|
||||
InitializeCriticalSection(&p->mutex);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
#ifdef SQLITE_ENABLE_API_ARMOR
|
||||
if( iType-2<0 || iType-2>=ArraySize(aWindowsMutex) ){
|
||||
if( iType-2<0 || iType-2>=ArraySize(winMutex_staticMutexes) ){
|
||||
(void)SQLITE_MISUSE_BKPT;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
p = &aWindowsMutex[iType-2].m;
|
||||
p = &winMutex_staticMutexes[iType-2];
|
||||
#ifdef SQLITE_DEBUG
|
||||
#ifdef SQLITE_WIN32_MUTEX_TRACE_STATIC
|
||||
InterlockedCompareExchange(&p->trace, 1, 0);
|
||||
@@ -253,10 +252,8 @@ static sqlite3_mutex *winMutexAlloc(int iType){
|
||||
static void winMutexFree(sqlite3_mutex *p){
|
||||
assert( p );
|
||||
assert( p->nRef==0 && p->owner==0 );
|
||||
if( p->id==SQLITE_MUTEX_FAST ){
|
||||
sqlite3_free(p);
|
||||
}else if( p->id==SQLITE_MUTEX_RECURSIVE ){
|
||||
DeleteCriticalSection(&p->u.cs);
|
||||
if( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE ){
|
||||
DeleteCriticalSection(&p->mutex);
|
||||
sqlite3_free(p);
|
||||
}else{
|
||||
#ifdef SQLITE_ENABLE_API_ARMOR
|
||||
@@ -277,56 +274,67 @@ static void winMutexFree(sqlite3_mutex *p){
|
||||
** more than once, the behavior is undefined.
|
||||
*/
|
||||
static void winMutexEnter(sqlite3_mutex *p){
|
||||
assert( p );
|
||||
#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
|
||||
DWORD tid = GetCurrentThreadId();
|
||||
#endif
|
||||
#ifdef SQLITE_DEBUG
|
||||
assert( p->id==SQLITE_MUTEX_RECURSIVE || winMutexNotheld(p) );
|
||||
assert( p );
|
||||
assert( p->id==SQLITE_MUTEX_RECURSIVE || winMutexNotheld2(p, tid) );
|
||||
#else
|
||||
assert( p );
|
||||
#endif
|
||||
assert( winMutex_isInit==1 );
|
||||
if( p->id==SQLITE_MUTEX_RECURSIVE ){
|
||||
EnterCriticalSection(&p->u.cs);
|
||||
}else{
|
||||
AcquireSRWLockExclusive(&p->u.srwl);
|
||||
}
|
||||
EnterCriticalSection(&p->mutex);
|
||||
#ifdef SQLITE_DEBUG
|
||||
assert( p->nRef>0 || p->owner==0 );
|
||||
p->owner = GetCurrentThreadId();
|
||||
p->owner = tid;
|
||||
p->nRef++;
|
||||
if( p->trace ){
|
||||
OSTRACE(("ENTER-MUTEX tid=%lu, mutex(%d)=%p (%d), nRef=%d\n",
|
||||
GetCurrentThreadId(), p->id, p, p->trace, p->nRef));
|
||||
tid, p->id, p, p->trace, p->nRef));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static int winMutexTry(sqlite3_mutex *p){
|
||||
#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
|
||||
DWORD tid = GetCurrentThreadId();
|
||||
#endif
|
||||
int rc = SQLITE_BUSY;
|
||||
assert( p );
|
||||
assert( p->id==SQLITE_MUTEX_RECURSIVE || winMutexNotheld(p) );
|
||||
assert( p->id==SQLITE_MUTEX_RECURSIVE || winMutexNotheld2(p, tid) );
|
||||
/*
|
||||
** The sqlite3_mutex_try() routine is seldom used, and when it is
|
||||
** used it is merely an optimization. So it is OK for it to always
|
||||
** The sqlite3_mutex_try() routine is very rarely used, and when it
|
||||
** is used it is merely an optimization. So it is OK for it to always
|
||||
** fail.
|
||||
**
|
||||
** The TryEnterCriticalSection() interface is only available on WinNT.
|
||||
** And some windows compilers complain if you try to use it without
|
||||
** first doing some #defines that prevent SQLite from building on Win98.
|
||||
** For that reason, we will omit this optimization for now. See
|
||||
** ticket #2685.
|
||||
*/
|
||||
if( p->id==SQLITE_MUTEX_RECURSIVE ){
|
||||
rc = TryEnterCriticalSection(&p->u.cs);
|
||||
}else{
|
||||
rc = TryAcquireSRWLockExclusive(&p->u.srwl);
|
||||
#if defined(_WIN32_WINNT) && _WIN32_WINNT >= 0x0400
|
||||
assert( winMutex_isInit==1 );
|
||||
assert( winMutex_isNt>=-1 && winMutex_isNt<=1 );
|
||||
if( winMutex_isNt<0 ){
|
||||
winMutex_isNt = sqlite3_win32_is_nt();
|
||||
}
|
||||
if( rc ){
|
||||
assert( winMutex_isNt==0 || winMutex_isNt==1 );
|
||||
if( winMutex_isNt && TryEnterCriticalSection(&p->mutex) ){
|
||||
#ifdef SQLITE_DEBUG
|
||||
p->owner = GetCurrentThreadId();
|
||||
p->owner = tid;
|
||||
p->nRef++;
|
||||
#endif
|
||||
rc = SQLITE_OK;
|
||||
}else{
|
||||
rc = SQLITE_BUSY;
|
||||
}
|
||||
#else
|
||||
UNUSED_PARAMETER(p);
|
||||
#endif
|
||||
#ifdef SQLITE_DEBUG
|
||||
if( p->trace ){
|
||||
OSTRACE((
|
||||
"TRY-MUTEX tid=%lu, mutex(%d)=%p (%d), owner=%lu, nRef=%d, rc=%s\n",
|
||||
GetCurrentThreadId(), p->id, p, p->trace, p->owner, p->nRef,
|
||||
sqlite3ErrName(rc)));
|
||||
OSTRACE(("TRY-MUTEX tid=%lu, mutex(%d)=%p (%d), owner=%lu, nRef=%d, rc=%s\n",
|
||||
tid, p->id, p, p->trace, p->owner, p->nRef, sqlite3ErrName(rc)));
|
||||
}
|
||||
#endif
|
||||
return rc;
|
||||
@@ -339,24 +347,23 @@ static int winMutexTry(sqlite3_mutex *p){
|
||||
** is not currently allocated. SQLite will never do either.
|
||||
*/
|
||||
static void winMutexLeave(sqlite3_mutex *p){
|
||||
#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
|
||||
DWORD tid = GetCurrentThreadId();
|
||||
#endif
|
||||
assert( p );
|
||||
#ifdef SQLITE_DEBUG
|
||||
assert( p->nRef>0 );
|
||||
assert( p->owner==GetCurrentThreadId() );
|
||||
assert( p->owner==tid );
|
||||
p->nRef--;
|
||||
if( p->nRef==0 ) p->owner = 0;
|
||||
assert( p->nRef==0 || p->id==SQLITE_MUTEX_RECURSIVE );
|
||||
#endif
|
||||
assert( winMutex_isInit==1 );
|
||||
if( p->id==SQLITE_MUTEX_RECURSIVE ){
|
||||
LeaveCriticalSection(&p->u.cs);
|
||||
}else{
|
||||
ReleaseSRWLockExclusive(&p->u.srwl);
|
||||
}
|
||||
LeaveCriticalSection(&p->mutex);
|
||||
#ifdef SQLITE_DEBUG
|
||||
if( p->trace ){
|
||||
OSTRACE(("LEAVE-MUTEX tid=%lu, mutex(%d)=%p (%d), nRef=%d\n",
|
||||
GetCurrentThreadId(), p->id, p, p->trace, p->nRef));
|
||||
tid, p->id, p, p->trace, p->nRef));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
+2
-27
@@ -13,22 +13,6 @@
|
||||
** This file contains an experimental VFS layer that operates on a
|
||||
** Key/Value storage engine where both keys and values must be pure
|
||||
** text.
|
||||
**
|
||||
** DEBUG AND TEST
|
||||
**
|
||||
** For testing on Unix, compile using:
|
||||
**
|
||||
** make clean sqlite3d CFLAGS='-DSQLITE_OS_KV_OPTIONAL'
|
||||
**
|
||||
** Then start up a shell using something like:
|
||||
**
|
||||
** ./sqlite3d 'file:dbname?vfs=kvvfs'
|
||||
**
|
||||
** Each K/V entry is stored in a separate file in the working
|
||||
** directory that has a name like "kvvfs-dbname-*". Due to limitations
|
||||
** on the key size, the name of the database must be very short - just
|
||||
** a few characters. If the database name is too long, the VFS will
|
||||
** malfunction and you will get SQLITE_CORRUPT errors.
|
||||
*/
|
||||
#include <sqliteInt.h>
|
||||
#if SQLITE_OS_KV || (SQLITE_OS_UNIX && defined(SQLITE_OS_KV_OPTIONAL))
|
||||
@@ -331,7 +315,7 @@ struct sqlite3_kvvfs_methods {
|
||||
int (*xRcrdRead)(const char*, const char *zKey, char *zBuf, int nBuf);
|
||||
int (*xRcrdWrite)(const char*, const char *zKey, const char *zData);
|
||||
int (*xRcrdDelete)(const char*, const char *zKey);
|
||||
const int nKeySize; /* Used by the JS bindings */
|
||||
const int nKeySize;
|
||||
const int nBufferSize;
|
||||
#ifndef SQLITE_WASM
|
||||
# define MAYBE_CONST const
|
||||
@@ -481,14 +465,12 @@ int kvvfsDecode(const char *a, char *aOut, int nOut){
|
||||
memset(&aOut[j], 0, n);
|
||||
j += n;
|
||||
if( c==0 || mult==1 ) break; /* progress stalled if mult==1 */
|
||||
}else if( j<nOut ){
|
||||
}else{
|
||||
aOut[j] = c<<4;
|
||||
c = kvvfsHexValue[aIn[++i]];
|
||||
if( c<0 ) return -1 /* hex bytes are always in pairs */;
|
||||
aOut[j++] += c;
|
||||
i++;
|
||||
}else{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return j;
|
||||
@@ -914,13 +896,6 @@ static int kvvfsOpen(
|
||||
pFile->base.pMethods = &kvvfs_db_io_methods;
|
||||
}
|
||||
if( !pFile->zClass ){
|
||||
|
||||
if( strlen(zName) >= (KVRECORD_KEY_SZ
|
||||
- 6 /* "kvvfs-" */
|
||||
- 11 /* "-##########" */) ){
|
||||
/* Historical naming restriction, lifted in the JS impl. */
|
||||
return SQLITE_CANTOPEN;
|
||||
}
|
||||
pFile->zClass = zName;
|
||||
}
|
||||
pFile->aData = sqlite3_malloc64(SQLITE_KVOS_SZ);
|
||||
|
||||
+1
-16
@@ -6646,22 +6646,7 @@ static int unixOpen(
|
||||
|
||||
}else if( !zName ){
|
||||
/* If zName is NULL, the upper layer is requesting a temp file. */
|
||||
assert( isDelete );
|
||||
assert( !isNewJrnl );
|
||||
assert( isExclusive );
|
||||
assert( isReadWrite );
|
||||
#if defined(__linux__) && defined(O_TMPFILE)
|
||||
/* On systems that support O_TMPFILE, use that flag to create a more
|
||||
** secure temporary file that cannot be accessed by other processes
|
||||
*/
|
||||
zName = unixTempFileDir();
|
||||
if( zName
|
||||
&& (fd = robust_open(zName, O_RDWR|O_CREAT|O_EXCL|O_TMPFILE, 0600))>=0
|
||||
){
|
||||
rc = fillInUnixFile(pVfs, fd, pFile, zPath, ctrlFlags);
|
||||
goto open_finished;
|
||||
}
|
||||
#endif
|
||||
assert(isDelete && !isNewJrnl);
|
||||
rc = unixGetTempname(pVfs->mxPathname, zTmpname);
|
||||
if( rc!=SQLITE_OK ){
|
||||
return rc;
|
||||
|
||||
+1608
-454
File diff suppressed because it is too large
Load Diff
+43
-1
@@ -27,11 +27,53 @@
|
||||
# include <errno.h> /* amalgamator: dontcache */
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Determine if we are dealing with Windows NT.
|
||||
**
|
||||
** We ought to be able to determine if we are compiling for Windows 9x or
|
||||
** Windows NT using the _WIN32_WINNT macro as follows:
|
||||
**
|
||||
** #if defined(_WIN32_WINNT)
|
||||
** # define SQLITE_OS_WINNT 1
|
||||
** #else
|
||||
** # define SQLITE_OS_WINNT 0
|
||||
** #endif
|
||||
**
|
||||
** However, Visual Studio 2005 does not set _WIN32_WINNT by default, as
|
||||
** it ought to, so the above test does not work. We'll just assume that
|
||||
** everything is Windows NT unless the programmer explicitly says otherwise
|
||||
** by setting SQLITE_OS_WINNT to 0.
|
||||
*/
|
||||
#if SQLITE_OS_WIN && !defined(SQLITE_OS_WINNT)
|
||||
# define SQLITE_OS_WINNT 1
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Determine if we are dealing with Windows CE - which has a much reduced
|
||||
** API.
|
||||
*/
|
||||
#if defined(_WIN32_WCE)
|
||||
# define SQLITE_OS_WINCE 1
|
||||
#else
|
||||
# define SQLITE_OS_WINCE 0
|
||||
#endif
|
||||
|
||||
/*
|
||||
** For WinCE, some API function parameters do not appear to be declared as
|
||||
** volatile.
|
||||
*/
|
||||
#if SQLITE_OS_WINCE
|
||||
# define SQLITE_WIN32_VOLATILE
|
||||
#else
|
||||
# define SQLITE_WIN32_VOLATILE volatile
|
||||
#endif
|
||||
|
||||
/*
|
||||
** For some Windows sub-platforms, the _beginthreadex() / _endthreadex()
|
||||
** functions are not available (e.g. those not using MSVC, Cygwin, etc).
|
||||
*/
|
||||
#if SQLITE_OS_WIN && SQLITE_THREADSAFE>0 && !defined(__CYGWIN__)
|
||||
#if SQLITE_OS_WIN && !SQLITE_OS_WINCE && \
|
||||
SQLITE_THREADSAFE>0 && !defined(__CYGWIN__)
|
||||
# define SQLITE_OS_WIN_THREADS 1
|
||||
#else
|
||||
# define SQLITE_OS_WIN_THREADS 0
|
||||
|
||||
+78
-72
@@ -1272,43 +1272,39 @@ static void checkPage(PgHdr *pPg){
|
||||
#endif /* SQLITE_CHECK_PAGES */
|
||||
|
||||
/*
|
||||
** Free a buffer allocated by the readSuperJournal() function.
|
||||
** When this is called the journal file for pager pPager must be open.
|
||||
** This function attempts to read a super-journal file name from the
|
||||
** end of the file and, if successful, copies it into memory supplied
|
||||
** by the caller. See comments above writeSuperJournal() for the format
|
||||
** used to store a super-journal file name at the end of a journal file.
|
||||
**
|
||||
** zSuper must point to a buffer of at least nSuper bytes allocated by
|
||||
** the caller. This should be sqlite3_vfs.mxPathname+1 (to ensure there is
|
||||
** enough space to write the super-journal name). If the super-journal
|
||||
** name in the journal is longer than nSuper bytes (including a
|
||||
** nul-terminator), then this is handled as if no super-journal name
|
||||
** were present in the journal.
|
||||
**
|
||||
** If a super-journal file name is present at the end of the journal
|
||||
** file, then it is copied into the buffer pointed to by zSuper. A
|
||||
** nul-terminator byte is appended to the buffer following the
|
||||
** super-journal file name.
|
||||
**
|
||||
** If it is determined that no super-journal file name is present
|
||||
** zSuper[0] is set to 0 and SQLITE_OK returned.
|
||||
**
|
||||
** If an error occurs while reading from the journal file, an SQLite
|
||||
** error code is returned.
|
||||
*/
|
||||
static void freeSuperJournal(char *zSuper){
|
||||
if( zSuper ){
|
||||
sqlite3_free(&zSuper[-4]);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Parameter pJrnl is a file-handle open on a journal file. This function
|
||||
** attempts to read a super-journal file name from the end of the journal
|
||||
** file. If successful, it sets output parameter (*pzSuper) to point to a
|
||||
** buffer containing the super-journal name as a nul-terminated string.
|
||||
** The caller is responsible for freeing the buffer using freeSuperJournal().
|
||||
**
|
||||
** Refer to comments above writeSuperJournal() for the format used to store
|
||||
** a super-journal file name at the end of a journal file.
|
||||
**
|
||||
** Parameter nSuper is passed the maximum allowable size of the super journal
|
||||
** name in bytes. If the super-journal name in the journal is longer than
|
||||
** nSuper bytes (including a nul-terminator), then this is handled as if no
|
||||
** super-journal name were present in the journal.
|
||||
**
|
||||
** If there is no super-journal name at the end of pJrnl, (*pzSuper) is
|
||||
** set to 0 and SQLITE_OK is returned. Or, if an error occurs while reading
|
||||
** the super-journal name, an SQLite error code is returned and (*pzSuper)
|
||||
** is set to 0.
|
||||
*/
|
||||
static int readSuperJournal(sqlite3_file *pJrnl, u64 nSuper, char **pzSuper){
|
||||
static int readSuperJournal(sqlite3_file *pJrnl, char *zSuper, u64 nSuper){
|
||||
int rc; /* Return code */
|
||||
u32 len; /* Length in bytes of super-journal name */
|
||||
i64 szJ; /* Total size in bytes of journal file pJrnl */
|
||||
u32 cksum; /* MJ checksum value read from journal */
|
||||
u32 u; /* Unsigned loop counter */
|
||||
unsigned char aMagic[8]; /* A buffer to hold the magic header */
|
||||
char *zOut = 0;
|
||||
zSuper[0] = '\0';
|
||||
|
||||
*pzSuper = 0;
|
||||
if( SQLITE_OK!=(rc = sqlite3OsFileSize(pJrnl, &szJ))
|
||||
|| szJ<16
|
||||
|| SQLITE_OK!=(rc = read32bits(pJrnl, szJ-16, &len))
|
||||
@@ -1318,34 +1314,27 @@ static int readSuperJournal(sqlite3_file *pJrnl, u64 nSuper, char **pzSuper){
|
||||
|| SQLITE_OK!=(rc = read32bits(pJrnl, szJ-12, &cksum))
|
||||
|| SQLITE_OK!=(rc = sqlite3OsRead(pJrnl, aMagic, 8, szJ-8))
|
||||
|| memcmp(aMagic, aJournalMagic, 8)
|
||||
|| SQLITE_OK!=(rc = sqlite3OsRead(pJrnl, zSuper, len, szJ-16-len))
|
||||
){
|
||||
return rc;
|
||||
}
|
||||
|
||||
zOut = (char*)sqlite3MallocZero(4 + len + 2);
|
||||
if( !zOut ){
|
||||
rc = SQLITE_NOMEM_BKPT;
|
||||
}else{
|
||||
zOut = &zOut[4];
|
||||
if( SQLITE_OK==(rc = sqlite3OsRead(pJrnl, zOut, len, szJ-16-len)) ){
|
||||
u32 u; /* Unsigned loop counter */
|
||||
/* See if the checksum matches the super-journal name */
|
||||
for(u=0; u<len; u++){
|
||||
cksum -= zOut[u];
|
||||
}
|
||||
}
|
||||
if( rc!=SQLITE_OK || cksum ){
|
||||
/* If the checksum doesn't add up, then one or more of the disk sectors
|
||||
** containing the super-journal filename is corrupted. This means
|
||||
** definitely roll back, so just return SQLITE_OK and report a (nul)
|
||||
** super-journal filename. */
|
||||
freeSuperJournal(zOut);
|
||||
zOut = 0;
|
||||
}
|
||||
/* See if the checksum matches the super-journal name */
|
||||
for(u=0; u<len; u++){
|
||||
cksum -= zSuper[u];
|
||||
}
|
||||
|
||||
*pzSuper = zOut;
|
||||
return rc;
|
||||
if( cksum ){
|
||||
/* If the checksum doesn't add up, then one or more of the disk sectors
|
||||
** containing the super-journal filename is corrupted. This means
|
||||
** definitely roll back, so just return SQLITE_OK and report a (nul)
|
||||
** super-journal filename.
|
||||
*/
|
||||
len = 0;
|
||||
}
|
||||
zSuper[len] = '\0';
|
||||
zSuper[len+1] = '\0';
|
||||
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -2004,7 +1993,7 @@ static int pagerFlushOnCommit(Pager *pPager, int bCommit){
|
||||
** database transaction.
|
||||
**
|
||||
** This routine is never called in PAGER_ERROR state. If it is called
|
||||
** in PAGER_OPEN or PAGER_READER state and the lock held is less
|
||||
** in PAGER_NONE or PAGER_SHARED state and the lock held is less
|
||||
** exclusive than a RESERVED lock, it is a no-op.
|
||||
**
|
||||
** Otherwise, any active savepoints are released.
|
||||
@@ -2550,7 +2539,9 @@ static int pager_delsuper(Pager *pPager, const char *zSuper){
|
||||
char *zSuperJournal = 0; /* Contents of super-journal file */
|
||||
i64 nSuperJournal; /* Size of super-journal file */
|
||||
char *zJournal; /* Pointer to one journal within MJ file */
|
||||
char *zSuperPtr; /* Space to hold super-journal filename */
|
||||
char *zFree = 0; /* Free this buffer */
|
||||
i64 nSuperPtr; /* Amount of space allocated to zSuperPtr[] */
|
||||
|
||||
/* Allocate space for both the pJournal and pSuper file descriptors.
|
||||
** If successful, open the super-journal file for reading.
|
||||
@@ -2573,8 +2564,9 @@ static int pager_delsuper(Pager *pPager, const char *zSuper){
|
||||
*/
|
||||
rc = sqlite3OsFileSize(pSuper, &nSuperJournal);
|
||||
if( rc!=SQLITE_OK ) goto delsuper_out;
|
||||
assert( nSuperJournal>=0 );
|
||||
zFree = sqlite3Malloc(4 + nSuperJournal + 2);
|
||||
nSuperPtr = 1 + (i64)pVfs->mxPathname;
|
||||
assert( nSuperJournal>=0 && nSuperPtr>0 );
|
||||
zFree = sqlite3Malloc(4 + nSuperJournal + 2 + nSuperPtr + 2);
|
||||
if( !zFree ){
|
||||
rc = SQLITE_NOMEM_BKPT;
|
||||
goto delsuper_out;
|
||||
@@ -2583,6 +2575,7 @@ static int pager_delsuper(Pager *pPager, const char *zSuper){
|
||||
}
|
||||
zFree[0] = zFree[1] = zFree[2] = zFree[3] = 0;
|
||||
zSuperJournal = &zFree[4];
|
||||
zSuperPtr = &zSuperJournal[nSuperJournal+2];
|
||||
rc = sqlite3OsRead(pSuper, zSuperJournal, (int)nSuperJournal, 0);
|
||||
if( rc!=SQLITE_OK ) goto delsuper_out;
|
||||
zSuperJournal[nSuperJournal] = 0;
|
||||
@@ -2596,8 +2589,6 @@ static int pager_delsuper(Pager *pPager, const char *zSuper){
|
||||
goto delsuper_out;
|
||||
}
|
||||
if( exists ){
|
||||
char *zSuperPtr = 0;
|
||||
|
||||
/* One of the journals pointed to by the super-journal exists.
|
||||
** Open it and check if it points at the super-journal. If
|
||||
** so, return without deleting the super-journal file.
|
||||
@@ -2612,15 +2603,13 @@ static int pager_delsuper(Pager *pPager, const char *zSuper){
|
||||
goto delsuper_out;
|
||||
}
|
||||
|
||||
rc = readSuperJournal(pJournal, 1+(u64)pVfs->mxPathname, &zSuperPtr);
|
||||
rc = readSuperJournal(pJournal, zSuperPtr, nSuperPtr);
|
||||
sqlite3OsClose(pJournal);
|
||||
if( rc!=SQLITE_OK ){
|
||||
assert( zSuperPtr==0 );
|
||||
goto delsuper_out;
|
||||
}
|
||||
|
||||
c = zSuperPtr!=0 && strcmp(zSuperPtr, zSuper)==0;
|
||||
freeSuperJournal(zSuperPtr);
|
||||
c = zSuperPtr[0]!=0 && strcmp(zSuperPtr, zSuper)==0;
|
||||
if( c ){
|
||||
/* We have a match. Do not delete the super-journal file. */
|
||||
goto delsuper_out;
|
||||
@@ -2835,11 +2824,19 @@ static int pager_playback(Pager *pPager, int isHot){
|
||||
** If a super-journal file name is specified, but the file is not
|
||||
** present on disk, then the journal is not hot and does not need to be
|
||||
** played back.
|
||||
*/
|
||||
rc = readSuperJournal(pPager->jfd, 1+(i64)pPager->pVfs->mxPathname, &zSuper);
|
||||
if( rc==SQLITE_OK && zSuper ){
|
||||
**
|
||||
** TODO: Technically the following is an error because it assumes that
|
||||
** buffer Pager.pTmpSpace is (mxPathname+1) bytes or larger. i.e. that
|
||||
** ((pPager->pageSize+8) >= pPager->pVfs->mxPathname+1). Using os_unix.c,
|
||||
** mxPathname is 512, which is the same as the minimum allowable value
|
||||
** for pageSize, and so this assumption holds. But it might not for some
|
||||
** custom VFS. */
|
||||
zSuper = pPager->pTmpSpace;
|
||||
rc = readSuperJournal(pPager->jfd, zSuper, 1+(i64)pPager->pVfs->mxPathname);
|
||||
if( rc==SQLITE_OK && zSuper[0] ){
|
||||
rc = sqlite3OsAccess(pVfs, zSuper, SQLITE_ACCESS_EXISTS, &res);
|
||||
}
|
||||
zSuper = 0;
|
||||
if( rc!=SQLITE_OK || !res ){
|
||||
goto end_playback;
|
||||
}
|
||||
@@ -2968,20 +2965,30 @@ end_playback:
|
||||
*/
|
||||
pPager->changeCountDone = pPager->tempFile;
|
||||
|
||||
if( rc==SQLITE_OK ){
|
||||
/* Leave 4 bytes of space before the super-journal filename in memory.
|
||||
** This is because it may end up being passed to sqlite3OsOpen(), in
|
||||
** which case it requires 4 0x00 bytes in memory immediately before
|
||||
** the filename. */
|
||||
zSuper = &pPager->pTmpSpace[4];
|
||||
rc = readSuperJournal(pPager->jfd, zSuper, 1+(i64)pPager->pVfs->mxPathname);
|
||||
testcase( rc!=SQLITE_OK );
|
||||
}
|
||||
if( rc==SQLITE_OK
|
||||
&& (pPager->eState>=PAGER_WRITER_DBMOD || pPager->eState==PAGER_OPEN)
|
||||
){
|
||||
rc = sqlite3PagerSync(pPager, 0);
|
||||
}
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = pager_end_transaction(pPager, zSuper!=0, 0);
|
||||
rc = pager_end_transaction(pPager, zSuper[0]!='\0', 0);
|
||||
testcase( rc!=SQLITE_OK );
|
||||
}
|
||||
if( rc==SQLITE_OK && zSuper && res ){
|
||||
if( rc==SQLITE_OK && zSuper[0] && res ){
|
||||
/* If there was a super-journal and this routine will return success,
|
||||
** see if it is possible to delete the super-journal.
|
||||
*/
|
||||
assert( memcmp(&zSuper[-4], "\0\0\0\0", 4)==0 );
|
||||
assert( zSuper==&pPager->pTmpSpace[4] );
|
||||
memset(pPager->pTmpSpace, 0, 4);
|
||||
rc = pager_delsuper(pPager, zSuper);
|
||||
testcase( rc!=SQLITE_OK );
|
||||
}
|
||||
@@ -2994,7 +3001,6 @@ end_playback:
|
||||
** back a journal created by a process with a different sector size
|
||||
** value. Reset it to the correct value for this process.
|
||||
*/
|
||||
freeSuperJournal(zSuper);
|
||||
setSectorSize(pPager);
|
||||
return rc;
|
||||
}
|
||||
@@ -3748,7 +3754,7 @@ void sqlite3PagerSetBusyHandler(
|
||||
**
|
||||
** then the pager object page size is set to *pPageSize.
|
||||
**
|
||||
** If the page size is changed, then this function uses sqlite3PageMalloc()
|
||||
** If the page size is changed, then this function uses sqlite3PagerMalloc()
|
||||
** to obtain a new Pager.pTmpSpace buffer. If this allocation attempt
|
||||
** fails, SQLITE_NOMEM is returned and the page size remains unchanged.
|
||||
** In all other cases, SQLITE_OK is returned.
|
||||
@@ -5095,8 +5101,8 @@ sqlite3_file *sqlite3_database_file_object(const char *zName){
|
||||
|
||||
|
||||
/*
|
||||
** This function is called while transitioning from PAGER_OPEN to a
|
||||
** higher state. It tests if there is a hot journal present in
|
||||
** This function is called after transitioning from PAGER_UNLOCK to
|
||||
** PAGER_SHARED state. It tests if there is a hot journal present in
|
||||
** the file-system for the given pager. A hot journal is one that
|
||||
** needs to be played back. According to this function, a hot-journal
|
||||
** file exists if the following criteria are met:
|
||||
|
||||
+16
-18
@@ -309,24 +309,22 @@ static int pcache1InitBulk(PCache1 *pCache){
|
||||
if( szBulk > pCache->szAlloc*(i64)pCache->nMax ){
|
||||
szBulk = pCache->szAlloc*(i64)pCache->nMax;
|
||||
}
|
||||
if( szBulk>=pCache->szAlloc ){
|
||||
zBulk = pCache->pBulk = sqlite3Malloc( szBulk );
|
||||
sqlite3EndBenignMalloc();
|
||||
if( zBulk ){
|
||||
int nBulk = sqlite3MallocSize(zBulk)/pCache->szAlloc;
|
||||
do{
|
||||
PgHdr1 *pX = (PgHdr1*)&zBulk[pCache->szPage];
|
||||
pX->page.pBuf = zBulk;
|
||||
pX->page.pExtra = (u8*)pX + ROUND8(sizeof(*pX));
|
||||
assert( EIGHT_BYTE_ALIGNMENT( pX->page.pExtra ) );
|
||||
pX->isBulkLocal = 1;
|
||||
pX->isAnchor = 0;
|
||||
pX->pNext = pCache->pFree;
|
||||
pX->pLruPrev = 0; /* Initializing this saves a valgrind error */
|
||||
pCache->pFree = pX;
|
||||
zBulk += pCache->szAlloc;
|
||||
}while( --nBulk );
|
||||
}
|
||||
zBulk = pCache->pBulk = sqlite3Malloc( szBulk );
|
||||
sqlite3EndBenignMalloc();
|
||||
if( zBulk ){
|
||||
int nBulk = sqlite3MallocSize(zBulk)/pCache->szAlloc;
|
||||
do{
|
||||
PgHdr1 *pX = (PgHdr1*)&zBulk[pCache->szPage];
|
||||
pX->page.pBuf = zBulk;
|
||||
pX->page.pExtra = (u8*)pX + ROUND8(sizeof(*pX));
|
||||
assert( EIGHT_BYTE_ALIGNMENT( pX->page.pExtra ) );
|
||||
pX->isBulkLocal = 1;
|
||||
pX->isAnchor = 0;
|
||||
pX->pNext = pCache->pFree;
|
||||
pX->pLruPrev = 0; /* Initializing this saves a valgrind error */
|
||||
pCache->pFree = pX;
|
||||
zBulk += pCache->szAlloc;
|
||||
}while( --nBulk );
|
||||
}
|
||||
return pCache->pFree!=0;
|
||||
}
|
||||
|
||||
+1
-7
@@ -216,13 +216,7 @@ int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg, u32 mFlags){
|
||||
assert( sqlite3_mutex_held(db->mutex) );
|
||||
assert( iDb==1 || sqlite3BtreeHoldsMutex(db->aDb[iDb].pBt) );
|
||||
|
||||
db->init.busy = 1 + ((mFlags & INITFLAG_AlterAdd)!=0);
|
||||
/* ^--- Any non-zero value for init.busy means that we are scanning
|
||||
** the sqlite_schema table to build the internal schema representation,
|
||||
** rather than running actual CREATE statements. init.busy==2 has the
|
||||
** additional meaning that the scan is happening as part of
|
||||
** ALTER TABLE ADD COLUMN, which is stricter in its enforcement of
|
||||
** function name resolution. */
|
||||
db->init.busy = 1;
|
||||
|
||||
/* Construct the in-memory representation schema tables (sqlite_schema or
|
||||
** sqlite_temp_schema) by invoking the parser directly. The appropriate
|
||||
|
||||
+32
-114
@@ -34,10 +34,8 @@
|
||||
#define etESCAPE_w 14 /* %w -> Strings with '\"' doubled */
|
||||
#define etORDINAL 15 /* %r -> 1st, 2nd, 3rd, 4th, etc. English only */
|
||||
#define etDECIMAL 16 /* %d or %u, but not %x, %o */
|
||||
#define etESCAPE_j 17 /* %j -> JSON string literal w/o "..." */
|
||||
#define etESCAPE_J 18 /* %J -> JSON string literal with "..." */
|
||||
|
||||
#define etINVALID 19 /* Any unrecognized conversion type */
|
||||
#define etINVALID 17 /* Any unrecognized conversion type */
|
||||
|
||||
|
||||
/*
|
||||
@@ -67,20 +65,20 @@ typedef struct et_info { /* Information about each format field */
|
||||
|
||||
/*
|
||||
** The table is searched by hash. In the case of %C where C is the character
|
||||
** and that character has ASCII value j, then the hash is j%25.
|
||||
** and that character has ASCII value j, then the hash is j%23.
|
||||
**
|
||||
** The order of the entries in fmtinfo[] and the hash chain was entered
|
||||
** manually, but based on the output of the following TCL script:
|
||||
*/
|
||||
#if 0 /***** Beginning of script ******/
|
||||
foreach c {d s g z q Q w c o u x X f e E G i n % p T S r J j} {
|
||||
foreach c {d s g z q Q w c o u x X f e E G i n % p T S r} {
|
||||
scan $c %c x
|
||||
set n($c) $x
|
||||
}
|
||||
set mx [llength [array names n]]
|
||||
puts "count: $mx"
|
||||
|
||||
set mx 25
|
||||
set mx 27
|
||||
puts "*********** mx=$mx ************"
|
||||
for {set r 0} {$r<$mx} {incr r} {
|
||||
puts -nonewline [format %2d: $r]
|
||||
@@ -92,34 +90,31 @@ for {set r 0} {$r<$mx} {incr r} {
|
||||
#endif /***** End of script ********/
|
||||
|
||||
static const char aDigits[] = "0123456789ABCDEF0123456789abcdef";
|
||||
static const char aHex[] = "0123456789abcdef";
|
||||
static const char aPrefix[] = "-x0\000X0";
|
||||
static const et_info fmtinfo[25] = {
|
||||
/* 0 */ { 'd', 10, 1, etDECIMAL, 0, 0, 0 },
|
||||
/* 1 */ { 'e', 0, 1, etEXP, 30, 0, 0 },
|
||||
/* 2 */ { 'f', 0, 1, etFLOAT, 0, 0, 0 },
|
||||
/* 3 */ { 'g', 0, 1, etGENERIC, 30, 0, 0 },
|
||||
/* 4 */ { 'j', 0, 0, etESCAPE_j, 0, 0, 0 }, /* Hash: 6 */
|
||||
/* 5 */ { 'i', 10, 1, etDECIMAL, 0, 0, 0 },
|
||||
/* 6 */ { 'Q', 0, 4, etESCAPE_Q, 0, 0, 4 },
|
||||
/* 7 */ { 'p', 16, 0, etPOINTER, 0, 1, 0 }, /* Hash: 12 */
|
||||
/* 8 */ { 'S', 0, 0, etSRCITEM, 0, 0, 0 },
|
||||
/* 9 */ { 'T', 0, 0, etTOKEN, 0, 0, 0 },
|
||||
/* 10 */ { 'n', 0, 0, etSIZE, 0, 0, 0 },
|
||||
/* 11 */ { 'o', 8, 0, etRADIX, 0, 2, 0 },
|
||||
/* 12 */ { '%', 0, 0, etPERCENT, 0, 0, 7 },
|
||||
/* 13 */ { 'q', 0, 4, etESCAPE_q, 0, 0, 16 },
|
||||
/* 14 */ { 'r', 10, 1, etORDINAL, 0, 0, 0 },
|
||||
/* 15 */ { 's', 0, 4, etSTRING, 0, 0, 0 },
|
||||
/* 16 */ { 'X', 16, 0, etRADIX, 0, 4, 0 }, /* Hash: 13 */
|
||||
/* 17 */ { 'u', 10, 0, etDECIMAL, 0, 0, 0 },
|
||||
/* 18 */ { 'w', 0, 4, etESCAPE_w, 0, 0, 0 }, /* Hash: 19 */
|
||||
/* 19 */ { 'E', 0, 1, etEXP, 14, 0, 18 },
|
||||
/* 20 */ { 'x', 16, 0, etRADIX, 16, 1, 0 },
|
||||
/* 21 */ { 'G', 0, 1, etGENERIC, 14, 0, 0 },
|
||||
/* 22 */ { 'z', 0, 4, etDYNSTRING, 0, 0, 0 },
|
||||
/* 23 */ { 'J', 0, 0, etESCAPE_J, 0, 0, 0 }, /* Hash: 24 */
|
||||
/* 24 */ { 'c', 0, 0, etCHARX, 0, 0, 23 }
|
||||
static const et_info fmtinfo[23] = {
|
||||
/* 0 */ { 's', 0, 4, etSTRING, 0, 0, 1 },
|
||||
/* 1 */ { 'E', 0, 1, etEXP, 14, 0, 0 }, /* Hash: 0 */
|
||||
/* 2 */ { 'u', 10, 0, etDECIMAL, 0, 0, 3 },
|
||||
/* 3 */ { 'G', 0, 1, etGENERIC, 14, 0, 0 }, /* Hash: 2 */
|
||||
/* 4 */ { 'w', 0, 4, etESCAPE_w, 0, 0, 0 },
|
||||
/* 5 */ { 'x', 16, 0, etRADIX, 16, 1, 0 },
|
||||
/* 6 */ { 'c', 0, 0, etCHARX, 0, 0, 0 }, /* Hash: 7 */
|
||||
/* 7 */ { 'z', 0, 4, etDYNSTRING, 0, 0, 6 },
|
||||
/* 8 */ { 'd', 10, 1, etDECIMAL, 0, 0, 0 },
|
||||
/* 9 */ { 'e', 0, 1, etEXP, 30, 0, 0 },
|
||||
/* 10 */ { 'f', 0, 1, etFLOAT, 0, 0, 0 },
|
||||
/* 11 */ { 'g', 0, 1, etGENERIC, 30, 0, 0 },
|
||||
/* 12 */ { 'Q', 0, 4, etESCAPE_Q, 0, 0, 0 },
|
||||
/* 13 */ { 'i', 10, 1, etDECIMAL, 0, 0, 0 },
|
||||
/* 14 */ { '%', 0, 0, etPERCENT, 0, 0, 16 },
|
||||
/* 15 */ { 'T', 0, 0, etTOKEN, 0, 0, 0 },
|
||||
/* 16 */ { 'S', 0, 0, etSRCITEM, 0, 0, 0 }, /* Hash: 14 */
|
||||
/* 17 */ { 'X', 16, 0, etRADIX, 0, 4, 0 }, /* Hash: 19 */
|
||||
/* 18 */ { 'n', 0, 0, etSIZE, 0, 0, 0 },
|
||||
/* 19 */ { 'o', 8, 0, etRADIX, 0, 2, 17 },
|
||||
/* 20 */ { 'p', 16, 0, etPOINTER, 0, 1, 0 },
|
||||
/* 21 */ { 'q', 0, 4, etESCAPE_q, 0, 0, 0 },
|
||||
/* 22 */ { 'r', 10, 1, etORDINAL, 0, 0, 0 }
|
||||
};
|
||||
|
||||
/* Additional Notes:
|
||||
@@ -380,8 +375,8 @@ void sqlite3_str_vappendf(
|
||||
}
|
||||
#else
|
||||
/* Fast hash-table lookup */
|
||||
assert( ArraySize(fmtinfo)==25 );
|
||||
idx = ((unsigned)c) % 25;
|
||||
assert( ArraySize(fmtinfo)==23 );
|
||||
idx = ((unsigned)c) % 23;
|
||||
if( fmtinfo[idx].fmttype==c
|
||||
|| fmtinfo[idx = fmtinfo[idx].iNxt].fmttype==c
|
||||
){
|
||||
@@ -752,7 +747,7 @@ void sqlite3_str_vappendf(
|
||||
|
||||
if( zExtra==0 ){
|
||||
/* The result is being rendered directory into pAccum. This
|
||||
** is the common and fast case */
|
||||
** is the command and fast case */
|
||||
pAccum->nChar += length;
|
||||
zOut[length] = 0;
|
||||
continue;
|
||||
@@ -872,83 +867,6 @@ void sqlite3_str_vappendf(
|
||||
while( ii>=0 ) if( (bufpt[ii--] & 0xc0)==0x80 ) width++;
|
||||
}
|
||||
break;
|
||||
case etESCAPE_j: /* %j: JSON string literal w/o "..." */
|
||||
case etESCAPE_J: { /* %J: Generate a JSON string literal */
|
||||
char *escarg;
|
||||
i64 i, j, px, iStart;
|
||||
unsigned char ch;
|
||||
|
||||
if( bArgList ){
|
||||
escarg = getTextArg(pArgList);
|
||||
}else{
|
||||
escarg = va_arg(ap,char*);
|
||||
}
|
||||
iStart = sqlite3_str_length(pAccum);
|
||||
if( escarg==0 ){
|
||||
if( xtype==etESCAPE_J ) sqlite3_str_append(pAccum, "null", 4);
|
||||
}else{
|
||||
if( xtype==etESCAPE_J ) sqlite3_str_append(pAccum, "\"", 1);
|
||||
px = precision;
|
||||
testcase( px==0 );
|
||||
if( px<0 ){
|
||||
px = 0x7fffffff;
|
||||
}else if( flag_altform2 ){
|
||||
/* Convert precision from code-points to bytes */
|
||||
for(i=0; i<px && escarg[i]; i++){
|
||||
if( (escarg[i]&0xc0)==0x80 ) px++;
|
||||
}
|
||||
if( i==px ){
|
||||
while( (escarg[px]&0xc0)==0x80 ) px++;
|
||||
}
|
||||
}
|
||||
for(i=j=0; i<px; i++){
|
||||
if( (ch = ((u8*)escarg)[i])<=0x1f || ch=='"' || ch=='\\' ){
|
||||
if( j<i ) sqlite3_str_append(pAccum, &escarg[j], i-j);
|
||||
j = i+1;
|
||||
if( ch==0 ) break;
|
||||
sqlite3_str_appendchar(pAccum, 1, '\\');
|
||||
if( ch>0x1f ){
|
||||
sqlite3_str_appendchar(pAccum, 1, ch);
|
||||
}else if( ((1u<<ch)&0x3700)!=0 ){
|
||||
ch = "btn?fr"[ch-8];
|
||||
sqlite3_str_appendchar(pAccum, 1, ch);
|
||||
}else{
|
||||
sqlite3_str_append(pAccum, "u00", 3);
|
||||
sqlite3_str_appendchar(pAccum, 1, aHex[ch>>4]);
|
||||
sqlite3_str_appendchar(pAccum, 1, aHex[ch&0xf]);
|
||||
}
|
||||
}
|
||||
}
|
||||
if( j<i ) sqlite3_str_append(pAccum, &escarg[j], i-j);
|
||||
if( xtype==etESCAPE_J ) sqlite3_str_append(pAccum, "\"", 1);
|
||||
}
|
||||
if( width>0 && sqlite3_str_errcode(pAccum)==SQLITE_OK ){
|
||||
sqlite3_int64 n = sqlite3_str_length(pAccum) - iStart;
|
||||
sqlite3_int64 len = n;
|
||||
char *zz;
|
||||
if( flag_altform2 && n>0 ){
|
||||
zz = sqlite3_str_value(pAccum);
|
||||
for(i=iStart; zz[i]; i++){
|
||||
if( (zz[i]&0xc0)==0x80 ) len--;
|
||||
}
|
||||
}
|
||||
if( width>len ){
|
||||
sqlite3_int64 sp = width-len;
|
||||
assert( sp>0 && sp<0x7fffffff );
|
||||
sqlite3_str_appendchar(pAccum, (int)sp, ' ');
|
||||
if( !flag_leftjustify
|
||||
&& n>0
|
||||
&& sqlite3_str_errcode(pAccum)==0
|
||||
){
|
||||
zz = sqlite3_str_value(pAccum);
|
||||
zz += iStart;
|
||||
memmove(zz+sp, zz, n);
|
||||
memset(zz, ' ', sp);
|
||||
}
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
case etESCAPE_q: /* %q: Escape ' characters */
|
||||
case etESCAPE_Q: /* %Q: Escape ' and enclose in '...' */
|
||||
case etESCAPE_w: { /* %w: Escape " characters */
|
||||
@@ -1040,7 +958,7 @@ void sqlite3_str_vappendf(
|
||||
bufpt[j++] = '0';
|
||||
bufpt[j++] = '0';
|
||||
bufpt[j++] = ch>=0x10 ? '1' : '0';
|
||||
bufpt[j++] = aHex[ch&0xf];
|
||||
bufpt[j++] = "0123456789abcdef"[ch&0xf];
|
||||
}
|
||||
}
|
||||
}else{
|
||||
|
||||
+10
-29
@@ -754,7 +754,7 @@ static int lookupName(
|
||||
** cnt>1 means there were two or more matches.
|
||||
**
|
||||
** cnt==0 is always an error. cnt>1 is often an error, but might
|
||||
** be multiple matches for a NATURAL OUTER JOIN or a OUTER JOIN USING.
|
||||
** be multiple matches for a NATURAL LEFT JOIN or a LEFT JOIN USING.
|
||||
*/
|
||||
assert( pFJMatch==0 || cnt>0 );
|
||||
assert( !ExprHasProperty(pExpr, EP_xIsSelect|EP_IntValue) );
|
||||
@@ -837,18 +837,11 @@ lookupname_end:
|
||||
if( cnt==1 ){
|
||||
assert( pNC!=0 );
|
||||
#ifndef SQLITE_OMIT_AUTHORIZATION
|
||||
if( db->xAuth ){
|
||||
if( pFJMatch ){
|
||||
assert( pExpr->op==TK_FUNCTION );
|
||||
assert( sqlite3_stricmp(pExpr->u.zToken,"coalesce")==0 );
|
||||
assert( pExpr->x.pList==pFJMatch );
|
||||
assert( pFJMatch->nExpr>0 );
|
||||
pExpr = pFJMatch->a[0].pExpr;
|
||||
}
|
||||
if( pExpr->op==TK_COLUMN || pExpr->op==TK_TRIGGER ){
|
||||
sqlite3AuthRead(pParse, pExpr, pSchema, pNC->pSrcList);
|
||||
}
|
||||
}
|
||||
if( pParse->db->xAuth
|
||||
&& (pExpr->op==TK_COLUMN || pExpr->op==TK_TRIGGER)
|
||||
){
|
||||
sqlite3AuthRead(pParse, pExpr, pSchema, pNC->pSrcList);
|
||||
}
|
||||
#endif
|
||||
/* Increment the nRef value on all name contexts from TopNC up to
|
||||
** the point where the name matched. */
|
||||
@@ -1244,13 +1237,8 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
|
||||
/* Internal-use-only functions are disallowed unless the
|
||||
** SQL is being compiled using sqlite3NestedParse() or
|
||||
** the SQLITE_TESTCTRL_INTERNAL_FUNCTIONS test-control has be
|
||||
** used to activate internal functions for testing purposes.
|
||||
**
|
||||
** The 2 value for no_such_func means that the function is
|
||||
** an internal-use-only function which should be treated as a
|
||||
** non-existant function for name resolution purposes.
|
||||
*/
|
||||
no_such_func = 2;
|
||||
** used to activate internal functions for testing purposes */
|
||||
no_such_func = 1;
|
||||
pDef = 0;
|
||||
}else
|
||||
if( (pDef->funcFlags & (SQLITE_FUNC_DIRECT|SQLITE_FUNC_UNSAFE))!=0
|
||||
@@ -1294,16 +1282,9 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
|
||||
is_agg = 0;
|
||||
}
|
||||
#endif
|
||||
else if( no_such_func
|
||||
&& (pParse->db->init.busy==0 ||
|
||||
(no_such_func==2 && pParse->db->init.busy==2))
|
||||
/* Suppress "no such function" errors when reading
|
||||
** the sqlite_schema table. Except, do raise the error
|
||||
** if init.busy is 2, meaning the schema parse is due
|
||||
** to an ALTER TABLE ADD COLUMN statement, and the function
|
||||
** is an internal-use-only function (no_such_func==2). */
|
||||
else if( no_such_func && pParse->db->init.busy==0
|
||||
#ifdef SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION
|
||||
&& pParse->explain==0
|
||||
&& pParse->explain==0
|
||||
#endif
|
||||
){
|
||||
sqlite3ErrorMsg(pParse, "no such function: %#T", pExpr);
|
||||
|
||||
+407
-1139
File diff suppressed because it is too large
Load Diff
+12
-34
@@ -2960,9 +2960,8 @@ int sqlite3_is_interrupted(sqlite3*);
|
||||
** These routines are useful during command-line input to determine if the
|
||||
** currently entered text seems to form a complete SQL statement or
|
||||
** if additional input is needed before sending the text into
|
||||
** SQLite for parsing. ^The sqlite3_complete(X) and sqlite3_complete16(X)
|
||||
** routines return 1 if the input string X appears to be a complete SQL
|
||||
** statement. ^A statement is judged to be
|
||||
** SQLite for parsing. ^These routines return 1 if the input string
|
||||
** appears to be a complete SQL statement. ^A statement is judged to be
|
||||
** complete if it ends with a semicolon token and is not a prefix of a
|
||||
** well-formed CREATE TRIGGER statement. ^Semicolons that are embedded within
|
||||
** string literals or quoted identifier names or comments are not
|
||||
@@ -2970,21 +2969,11 @@ int sqlite3_is_interrupted(sqlite3*);
|
||||
** embedded) and thus do not count as a statement terminator. ^Whitespace
|
||||
** and comments that follow the final semicolon are ignored.
|
||||
**
|
||||
** ^The sqlite3_complete(X) and sqlite3_complete16(X) routines return 0
|
||||
** if the statement is incomplete. ^If a memory allocation fails, then
|
||||
** SQLITE_NOMEM is returned.
|
||||
** ^These routines return 0 if the statement is incomplete. ^If a
|
||||
** memory allocation fails, then SQLITE_NOMEM is returned.
|
||||
**
|
||||
** The [sqlite3_incomplete(X)] routine is similar to [sqlite3_complete(X)]
|
||||
** except that sqlite3_incomplete(X) returns 0 if the input X is complete
|
||||
** and non-zero if X is incomplete. The non-zero return from
|
||||
** sqlite3_incomplete(X) contains additional information about what is
|
||||
** needed to complete the input X. The sqlite3_incomplete(X) interface
|
||||
** is only available for UTF-8 text.
|
||||
**
|
||||
** ^None of these routines do a full parse the SQL statements and thus
|
||||
** will not detect syntactically incorrect SQL. They only determine if
|
||||
** input text has properly terminated comments, string literals, and
|
||||
** quoted identifiers, and if the statement ends with a semicolon.
|
||||
** ^These routines do not parse the SQL statements and thus
|
||||
** will not detect syntactically incorrect SQL.
|
||||
**
|
||||
** ^(If SQLite has not been initialized using [sqlite3_initialize()] prior
|
||||
** to invoking sqlite3_complete16() then sqlite3_initialize() is invoked
|
||||
@@ -2992,15 +2981,14 @@ int sqlite3_is_interrupted(sqlite3*);
|
||||
** then the return value from sqlite3_complete16() will be non-zero
|
||||
** regardless of whether or not the input SQL is complete.)^
|
||||
**
|
||||
** The X input to [sqlite3_complete(X)] and [sqlite3_incomplete(X)]
|
||||
** must be a zero-terminated UTF-8 string.
|
||||
** The input to [sqlite3_complete()] must be a zero-terminated
|
||||
** UTF-8 string.
|
||||
**
|
||||
** The input to [sqlite3_complete16()] must be a zero-terminated
|
||||
** UTF-16 string in native byte order.
|
||||
*/
|
||||
int sqlite3_complete(const char *sql);
|
||||
int sqlite3_complete16(const void *sql);
|
||||
sqlite3_int64 sqlite3_incomplete(const char *sql);
|
||||
|
||||
/*
|
||||
** CAPI3REF: Register A Callback To Handle SQLITE_BUSY Errors
|
||||
@@ -4054,7 +4042,8 @@ int sqlite3_open_v2(
|
||||
**
|
||||
** The sqlite3_uri_int64(F,P,D) routine converts the value of P into a
|
||||
** 64-bit signed integer and returns that integer, or D if P does not
|
||||
** exist or ff the value of P is something other than an integer.
|
||||
** exist. If the value of P is something other than an integer, then
|
||||
** zero is returned.
|
||||
**
|
||||
** The sqlite3_uri_key(F,N) returns a pointer to the name (not
|
||||
** the value) of the N-th query parameter for filename F, or a NULL
|
||||
@@ -11214,19 +11203,8 @@ unsigned char *sqlite3_serialize(
|
||||
** used. The serialized database P is N bytes in size. M is the size
|
||||
** of the buffer P, which might be larger than N. If M is larger than
|
||||
** N, and the SQLITE_DESERIALIZE_READONLY bit is not set in F, then
|
||||
** SQLite is permitted to add content to the in-memory database, in
|
||||
** page-sized chunks, as long as the total size does not exceed M bytes.
|
||||
**
|
||||
** The parameter M must be greater than or equal to N. Ideally, M
|
||||
** should have a value which is N+(512×K)+20 where K determines how
|
||||
** must extra space is available to hold new content as the database
|
||||
** grows. K can be 0 if the database is read-only.
|
||||
**
|
||||
** If the database content in P is malformed in a malicious way then
|
||||
** it is possible that SQLite might try to read a few more than N bytes
|
||||
** from P. If the veracity of the database content P is uncertain,
|
||||
** then applications are advised to allocate about 20 extra bytes on
|
||||
** the end of the P buffer to avoid a memory error.
|
||||
** SQLite is permitted to add content to the in-memory database as
|
||||
** long as the total size does not exceed M bytes.
|
||||
**
|
||||
** If the SQLITE_DESERIALIZE_FREEONCLOSE bit is set in F, then SQLite will
|
||||
** invoke sqlite3_free() on the serialization buffer when the database
|
||||
|
||||
@@ -376,8 +376,6 @@ struct sqlite3_api_routines {
|
||||
void (*str_free)(sqlite3_str*);
|
||||
int (*carray_bind)(sqlite3_stmt*,int,void*,int,int,void(*)(void*));
|
||||
int (*carray_bind_v2)(sqlite3_stmt*,int,void*,int,int,void(*)(void*),void*);
|
||||
/* Version 3.54.0 and later */
|
||||
sqlite3_int64 (*incomplete)(const char*);
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -721,8 +719,6 @@ typedef int (*sqlite3_loadext_entry)(
|
||||
#define sqlite3_str_free sqlite3_api->str_free
|
||||
#define sqlite3_carray_bind sqlite3_api->carray_bind
|
||||
#define sqlite3_carray_bind_v2 sqlite3_api->carray_bind_v2
|
||||
/* Version 3.54.0 and later */
|
||||
#define sqlite3_incomplete sqlite3_api->incomplete
|
||||
#endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */
|
||||
|
||||
#if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
|
||||
|
||||
+3
-54
@@ -202,7 +202,7 @@
|
||||
#include "sqlite3.h"
|
||||
|
||||
/*
|
||||
** Reuse the STATIC_VFS1 for mutex access to sqlite3_temp_directory.
|
||||
** Reuse the STATIC_LRU for mutex access to sqlite3_temp_directory.
|
||||
*/
|
||||
#define SQLITE_MUTEX_STATIC_TEMPDIR SQLITE_MUTEX_STATIC_VFS1
|
||||
|
||||
@@ -1700,7 +1700,7 @@ struct sqlite3 {
|
||||
struct sqlite3InitInfo { /* Information used during initialization */
|
||||
Pgno newTnum; /* Rootpage of table being initialized */
|
||||
u8 iDb; /* Which db file is being initialized */
|
||||
u8 busy; /* TRUE if initing. 2 if due to ADD COLUMN */
|
||||
u8 busy; /* TRUE if currently initializing */
|
||||
unsigned orphanTrigger : 1; /* Last statement is orphaned TEMP trigger */
|
||||
unsigned imposterTable : 2; /* Building an imposter table */
|
||||
unsigned reopenMemdb : 1; /* ATTACH is really a reopen using MemDB */
|
||||
@@ -4251,7 +4251,7 @@ typedef struct {
|
||||
#define INITFLAG_AlterRename 0x0001 /* Reparse after a RENAME */
|
||||
#define INITFLAG_AlterDrop 0x0002 /* Reparse after a DROP COLUMN */
|
||||
#define INITFLAG_AlterAdd 0x0003 /* Reparse after an ADD COLUMN */
|
||||
#define INITFLAG_AlterDropCons 0x0004 /* Reparse after a DROP CONSTRAINT */
|
||||
#define INITFLAG_AlterDropCons 0x0004 /* Reparse after an ADD COLUMN */
|
||||
|
||||
/* Tuning parameters are set using SQLITE_TESTCTRL_TUNE and are controlled
|
||||
** on debug-builds of the CLI using ".testctrl tune ID VALUE". Tuning
|
||||
@@ -4612,57 +4612,6 @@ Window *sqlite3WindowAssemble(Parse*, Window*, ExprList*, ExprList*, Token*);
|
||||
/*
|
||||
** Assuming zIn points to the first byte of a UTF-8 character,
|
||||
** advance zIn to point to the first byte of the next UTF-8 character.
|
||||
**
|
||||
** # Dividing malformed UTF-8 into characters (tag-20260418-01)
|
||||
**
|
||||
** If a text input is malformed UTF-8, SQLite does not make any guarantees
|
||||
** about how the bytes are divided up into characters. The system promises
|
||||
** to not overflow an array or cause other memory errors when presented
|
||||
** with malformed UTF-8. And it promises to preserve the specific
|
||||
** sequence of bytes as long as no conversion occur. But beyond that,
|
||||
** there are no guarantees. Results can vary from one version to the
|
||||
** next.
|
||||
**
|
||||
** The SQLITE_SKIP_UTF8 macro below is one technique for dividing UTF-8
|
||||
** into characters. The length() and substr() SQL functions use a
|
||||
** different technique when searching across multiple characters, a
|
||||
** technique that exchanges a subtraction for comparison of z and results
|
||||
** in faster machine code on some compilers and architectures. The code
|
||||
** in substr() to skip over p1 characters goes something like this:
|
||||
**
|
||||
** for( ; p1>0; p1--){
|
||||
** // vvvv--- tag-20260418-01
|
||||
** if( (u8)(z[0]-1)<(0x80-1) ){
|
||||
** z++;
|
||||
** }else if( z[0]==0 ){
|
||||
** break;
|
||||
** }else{
|
||||
** do{ z++; }while( (z[0]&0xc0)==0x80 );
|
||||
** }
|
||||
** }
|
||||
**
|
||||
** In valid UTF-8, multibyte characters always begin with a byte with the
|
||||
** two most significant bits set and that is followed by one or more bytes
|
||||
** for which the two most significant bits are 10. In other words:
|
||||
**
|
||||
** First byte: (BYTE & 0xc0)==0xc0
|
||||
** Following bytes: (BYTE & 0xc0)==0x80
|
||||
**
|
||||
** What to do if the input byte sequence contain a "following byte" that
|
||||
** is not preceded by a "first byte"? How many characters are in the
|
||||
** byte sequence: 0x61 0x81 0x82 0x7a? 3 or 4 or something else?
|
||||
**
|
||||
** If you use the macro below, the answer will be 4. If you use the code
|
||||
** snippet demonstrated at tag-20260418-01, then answer is 3. If you
|
||||
** use a variant of tag-20260418-01 where the constant of comparison is
|
||||
** 0xc0-1 instead of 0x80-1 then the answer is again 4. The key point is
|
||||
** that because the input is malformed UTF-8, so is no "correct" answer.
|
||||
** SQLite is free to use either value.
|
||||
**
|
||||
** It turns out that GCC 13.3.0 is able to generate faster code (at least
|
||||
** on x86-64) if the constant at tag-20260418-01 is (0x80-1). If you make
|
||||
** that constant (0xc0-1) instead, gcc 13.3.0 generates code that runs slower.
|
||||
** So the (0x80-1) constant is used for substr() and length().
|
||||
*/
|
||||
#define SQLITE_SKIP_UTF8(zIn) { \
|
||||
if( (*(zIn++))>=0xc0 ){ \
|
||||
|
||||
+1
-1
@@ -355,7 +355,7 @@ static int SQLITE_TCLAPI test_exec_hex(
|
||||
if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
|
||||
zHex = argv[2];
|
||||
for(i=j=0; i<(sizeof(zSql)-1) && zHex[j]; i++, j++){
|
||||
if( zHex[j]=='%' && zHex[j+1] && zHex[j+2] ){
|
||||
if( zHex[j]=='%' && zHex[j+2] && zHex[j+2] ){
|
||||
zSql[i] = (testHexToInt(zHex[j+1])<<4) + testHexToInt(zHex[j+2]);
|
||||
j += 2;
|
||||
}else{
|
||||
|
||||
+2
-9
@@ -19,15 +19,8 @@
|
||||
#include <stdarg.h>
|
||||
#ifndef SQLITE_OMIT_FLOATING_POINT
|
||||
#include <math.h>
|
||||
|
||||
/* Work around a bug in older Microsoft compilers
|
||||
** Forum post 2026-04-10T06:33:11z */
|
||||
#if !defined(INFINITY) && defined(_MSC_VER)
|
||||
# define INFINITY HUGE_VAL
|
||||
#endif
|
||||
|
||||
#endif /* SQLITE_OMIT_FLOATING_POINT */
|
||||
|
||||
/*
|
||||
** Calls to sqlite3FaultSim() are used to simulate a failure during testing,
|
||||
** or to bypass normal error detection during testing in order to let
|
||||
@@ -790,7 +783,7 @@ static double sqlite3Fp10Convert2(u64 d, int p){
|
||||
u64 pwr10h, x, hi, lo, sticky, u, m;
|
||||
double r;
|
||||
if( p<POWERSOF10_FIRST ) return 0.0;
|
||||
if( p>POWERSOF10_LAST ) return (double)INFINITY;
|
||||
if( p>POWERSOF10_LAST ) return INFINITY;
|
||||
b = 64 - countLeadingZeros(d);
|
||||
lp = pwr10to2(p);
|
||||
e = 53 - b - lp;
|
||||
@@ -820,7 +813,7 @@ static double sqlite3Fp10Convert2(u64 d, int p){
|
||||
e -= adj;
|
||||
}
|
||||
m = (u + 1 + ((u>>2)&1)) >> 2;
|
||||
if( e<=(-972) ) return (double)INFINITY;
|
||||
if( e<=(-972) ) return INFINITY;
|
||||
if((m & U64_BIT(52)) != 0){
|
||||
m = (m & ~U64_BIT(52)) | ((u64)(1075-e)<<52);
|
||||
}
|
||||
|
||||
+11
-67
@@ -437,12 +437,10 @@ int sqlite3_value_numeric_type(sqlite3_value *pVal){
|
||||
int eType = sqlite3_value_type(pVal);
|
||||
if( eType==SQLITE_TEXT ){
|
||||
Mem *pMem = (Mem*)pVal;
|
||||
#if SQLITE_THREADSAFE>0
|
||||
sqlite3_mutex *pMutex = pMem->db ? pMem->db->mutex : 0;
|
||||
#endif
|
||||
sqlite3_mutex_enter(pMutex);
|
||||
assert( pMem->db!=0 );
|
||||
sqlite3_mutex_enter(pMem->db->mutex);
|
||||
applyNumericAffinity(pMem, 0);
|
||||
sqlite3_mutex_leave(pMutex);
|
||||
sqlite3_mutex_leave(pMem->db->mutex);
|
||||
eType = sqlite3_value_type(pVal);
|
||||
}
|
||||
return eType;
|
||||
@@ -710,6 +708,7 @@ static u64 filterHash(const Mem *aMem, const Op *pOp){
|
||||
return h;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** For OP_Column, factor out the case where content is loaded from
|
||||
** overflow pages, so that the code to implement this case is separate
|
||||
@@ -795,40 +794,6 @@ static SQLITE_NOINLINE int vdbeColumnFromOverflow(
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
** Memory cell pMem may contain a blob or a NULL value. Cursor pCsr is
|
||||
** open on an index. If the current index entry matches the blob value in
|
||||
** pMem byte-for-byte, set pMem to NULL and return 1. Otherwise, return 0.
|
||||
**
|
||||
** If an error occurs, set (*pRc) to an SQLite error code. Return 1 in this
|
||||
** case as well.
|
||||
*/
|
||||
static SQLITE_NOINLINE int vdbeIndexKeyCompare(
|
||||
BtCursor *pCsr, /* Cursor to compare key to */
|
||||
Mem *pMem,
|
||||
int *pRc
|
||||
){
|
||||
int ret = 0;
|
||||
u32 nKey = 0;
|
||||
|
||||
assert( pMem->flags & (MEM_Blob|MEM_Null) );
|
||||
nKey = sqlite3BtreePayloadSize(pCsr);
|
||||
if( nKey==(u32)pMem->n && ALWAYS((pMem->flags & MEM_Blob)!=0) ){
|
||||
/* This code could just use sqlite3BtreePayloadFetch(). But calling that
|
||||
** function here apparently prevents compilers from inlining it in other,
|
||||
** more performance critical, places. So this code uses
|
||||
** MemFromBtreeZeroOffset(), which is just as fast in most cases, but also
|
||||
** handles the case where the index record uses overflow pages. */
|
||||
Mem m;
|
||||
memset(&m, 0, sizeof(m));
|
||||
*pRc = sqlite3VdbeMemFromBtreeZeroOffset(pCsr, nKey, &m);
|
||||
ret = (*pRc!=SQLITE_OK || 0==memcmp(pMem->z, m.z, nKey));
|
||||
sqlite3VdbeMemReleaseMalloc(&m);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
** Send a "statement aborts" message to the error log.
|
||||
*/
|
||||
@@ -6657,20 +6622,15 @@ case OP_SorterInsert: { /* in2 */
|
||||
break;
|
||||
}
|
||||
|
||||
/* Opcode: IdxDelete P1 P2 P3 P4 P5
|
||||
** Synopsis: key=r[P2@P5]
|
||||
/* Opcode: IdxDelete P1 P2 P3 P4 *
|
||||
** Synopsis: key=r[P2@P3]
|
||||
**
|
||||
** The content of P5 registers starting at register P2 form
|
||||
** The content of P3 registers starting at register P2 form
|
||||
** an unpacked index key. This opcode removes that entry from the
|
||||
** index opened by cursor P1.
|
||||
**
|
||||
** P4 is a pointer to an Index structure.
|
||||
**
|
||||
** If P3 is non-zero, it is the register number of a register holding
|
||||
** a record that will be inserted into this index. If that record is
|
||||
** identical to the one that would be deleted by this instruction,
|
||||
** skip the delete and set register P3 to NULL.
|
||||
**
|
||||
** Raise an SQLITE_CORRUPT_INDEX error if no matching index entry is found
|
||||
** and not in writable_schema mode.
|
||||
*/
|
||||
@@ -6680,8 +6640,8 @@ case OP_IdxDelete: {
|
||||
int res;
|
||||
UnpackedRecord r;
|
||||
|
||||
assert( pOp->p5>0 );
|
||||
assert( pOp->p2>0 && pOp->p2+pOp->p5<=(p->nMem+1 - p->nCursor)+1 );
|
||||
assert( pOp->p3>0 );
|
||||
assert( pOp->p2>0 && pOp->p2+pOp->p3<=(p->nMem+1 - p->nCursor)+1 );
|
||||
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
|
||||
pC = p->apCsr[pOp->p1];
|
||||
assert( pC!=0 );
|
||||
@@ -6690,7 +6650,7 @@ case OP_IdxDelete: {
|
||||
pCrsr = pC->uc.pCursor;
|
||||
assert( pCrsr!=0 );
|
||||
r.pKeyInfo = pC->pKeyInfo;
|
||||
r.nField = pOp->p5;
|
||||
r.nField = (u16)pOp->p3;
|
||||
r.default_rc = 0;
|
||||
r.aMem = &aMem[pOp->p2];
|
||||
rc = sqlite3BtreeIndexMoveto(pCrsr, &r, &res);
|
||||
@@ -6709,13 +6669,6 @@ case OP_IdxDelete: {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( pOp->p3 && vdbeIndexKeyCompare(pCrsr, &aMem[pOp->p3], &rc) ){
|
||||
if( rc ) goto abort_due_to_error;
|
||||
sqlite3VdbeMemSetNull(&aMem[pOp->p3]);
|
||||
break;
|
||||
}
|
||||
|
||||
rc = sqlite3BtreeDelete(pCrsr, BTREE_AUXDELETE);
|
||||
if( rc ) goto abort_due_to_error;
|
||||
assert( pC->deferredMoveto==0 );
|
||||
@@ -7149,19 +7102,12 @@ case OP_SqlExec: {
|
||||
break;
|
||||
}
|
||||
|
||||
/* Opcode: ParseSchema P1 * * P4 P5
|
||||
/* Opcode: ParseSchema P1 * * P4 *
|
||||
**
|
||||
** Read and parse all entries from the schema table of database P1
|
||||
** that match the WHERE clause P4. If P4 is a NULL pointer, then the
|
||||
** entire schema for P1 is reparsed.
|
||||
**
|
||||
** When P4 is NULL, the P5 value is used as the mFlags argument
|
||||
** to sqlite3InitOne(). In other words, P5 should be a mask composed
|
||||
** of INITFLAG_* values.
|
||||
**
|
||||
** The P4==0 case is only used by ALTER TABLE and P5!=0 for all such
|
||||
** cases. For uses other than ALTER TABLE, P4<>0 and P5==0.
|
||||
**
|
||||
** This opcode invokes the parser to create a new virtual machine,
|
||||
** then runs the new virtual machine. It is thus a re-entrant opcode.
|
||||
*/
|
||||
@@ -7189,7 +7135,6 @@ case OP_ParseSchema: {
|
||||
|
||||
#ifndef SQLITE_OMIT_ALTERTABLE
|
||||
if( pOp->p4.z==0 ){
|
||||
assert( pOp->p5!=0 );
|
||||
sqlite3SchemaClear(db->aDb[iDb].pSchema);
|
||||
db->mDbFlags &= ~DBFLAG_SchemaKnownOk;
|
||||
rc = sqlite3InitOne(db, iDb, &p->zErrMsg, pOp->p5);
|
||||
@@ -7198,7 +7143,6 @@ case OP_ParseSchema: {
|
||||
}else
|
||||
#endif
|
||||
{
|
||||
assert( pOp->p5==0 );
|
||||
zSchema = LEGACY_SCHEMA_TABLE;
|
||||
initData.db = db;
|
||||
initData.iDb = iDb;
|
||||
|
||||
+9
-18
@@ -556,21 +556,11 @@ void sqlite3VdbeExplainPop(Parse *pParse){
|
||||
** sqlite3VdbeAddOp4() since it needs to also needs to mark all btrees
|
||||
** as having been used.
|
||||
**
|
||||
** zWhere is a WHERE clause that defines which entries of the schema
|
||||
** to reparse. If zWhere==0, that means all entries. p5 is a mask
|
||||
** of INITFLAG_* values for the parse.
|
||||
**
|
||||
** In the current usage, the following are always true:
|
||||
**
|
||||
** ALTER TABLE: zWhere==0, p5!=0
|
||||
** Otherwise: zWhere!=0, p5==0
|
||||
**
|
||||
** The zWhere string must have been obtained from sqlite3DbMalloc().
|
||||
** The zWhere string must have been obtained from sqlite3_malloc().
|
||||
** This routine will take ownership of the allocated memory.
|
||||
*/
|
||||
void sqlite3VdbeAddParseSchemaOp(Vdbe *p, int iDb, char *zWhere, u16 p5){
|
||||
int j;
|
||||
assert( p5==0 || zWhere==0 );
|
||||
sqlite3VdbeAddOp4(p, OP_ParseSchema, iDb, 0, 0, zWhere, P4_DYNAMIC);
|
||||
sqlite3VdbeChangeP5(p, p5);
|
||||
for(j=0; j<p->db->nDb; j++) sqlite3VdbeUsesBtree(p, j);
|
||||
@@ -1910,6 +1900,7 @@ static void displayP4Expr(StrAccum *p, Expr *pExpr){
|
||||
#if VDBE_DISPLAY_P4
|
||||
/*
|
||||
** Compute a string that describes the P4 parameter for an opcode.
|
||||
** Use zTemp for any required temporary buffer space.
|
||||
*/
|
||||
char *sqlite3VdbeDisplayP4(sqlite3 *db, Op *pOp){
|
||||
char *zP4 = 0;
|
||||
@@ -5459,12 +5450,12 @@ static int vdbeIsMatchingIndexKey(
|
||||
){
|
||||
u8 *aRec = 0;
|
||||
u32 nRec = 0;
|
||||
Mem m;
|
||||
Mem mem;
|
||||
int rc = SQLITE_OK;
|
||||
|
||||
memset(&m, 0, sizeof(m));
|
||||
m.enc = p->pKeyInfo->enc;
|
||||
m.db = p->pKeyInfo->db;
|
||||
memset(&mem, 0, sizeof(mem));
|
||||
mem.enc = p->pKeyInfo->enc;
|
||||
mem.db = p->pKeyInfo->db;
|
||||
nRec = sqlite3BtreePayloadSize(pCur);
|
||||
if( nRec>0x7fffffff ){
|
||||
return SQLITE_CORRUPT_BKPT;
|
||||
@@ -5506,9 +5497,9 @@ static int vdbeIsMatchingIndexKey(
|
||||
if( (idxRec+nSerial)>nRec ){
|
||||
rc = SQLITE_CORRUPT_BKPT;
|
||||
}else{
|
||||
sqlite3VdbeSerialGet(&aRec[idxRec], iSerial, &m);
|
||||
if( vdbeSkipField(mask, ii, &p->aMem[ii], &m, bInt)==0 ){
|
||||
res = sqlite3MemCompare(&m, &p->aMem[ii], p->pKeyInfo->aColl[ii]);
|
||||
sqlite3VdbeSerialGet(&aRec[idxRec], iSerial, &mem);
|
||||
if( vdbeSkipField(mask, ii, &p->aMem[ii], &mem, bInt)==0 ){
|
||||
res = sqlite3MemCompare(&mem, &p->aMem[ii], p->pKeyInfo->aColl[ii]);
|
||||
if( res!=0 ) break;
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -114,8 +114,8 @@ static void vdbeMemRenderNum(int sz, char *zBuf, Mem *p){
|
||||
** https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114659
|
||||
** The problem appears to be fixed in GCC 15 */
|
||||
i64 x;
|
||||
assert( (sqlite3Config.bSmallMalloc!=0xee)*8==sizeof(x) );
|
||||
memcpy(&x, (char*)&p->u.i, (sqlite3Config.bSmallMalloc!=0xee)*8);
|
||||
assert( (MEM_Str&~p->flags)*4==sizeof(x) );
|
||||
memcpy(&x, (char*)&p->u, (MEM_Str&~p->flags)*4);
|
||||
p->n = sqlite3Int64ToText(x, zBuf);
|
||||
#else
|
||||
p->n = sqlite3Int64ToText(p->u.i, zBuf);
|
||||
|
||||
@@ -1023,12 +1023,6 @@ static int walDecodeFrame(
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Need a valid page size
|
||||
*/
|
||||
if( !pWal->szPage ){
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* A frame is only valid if a checksum of the WAL header,
|
||||
** all prior frames, the first 16 bytes of this frame-header,
|
||||
** and the frame-data matches the checksum in the last 8
|
||||
@@ -2883,7 +2877,7 @@ static int walBeginShmUnreliable(Wal *pWal, int *pChanged){
|
||||
|
||||
/* Allocate a buffer to read frames into */
|
||||
assert( (pWal->szPage & (pWal->szPage-1))==0 );
|
||||
assert( (pWal->szPage>=512 && pWal->szPage<=65536) || pWal->szPage==0 );
|
||||
assert( pWal->szPage>=512 && pWal->szPage<=65536 );
|
||||
szFrame = pWal->szPage + WAL_FRAME_HDRSIZE;
|
||||
aFrame = (u8 *)sqlite3_malloc64(szFrame);
|
||||
if( aFrame==0 ){
|
||||
|
||||
+2
-3
@@ -163,7 +163,7 @@ int sqlite3WhereBreakLabel(WhereInfo *pWInfo){
|
||||
** If the ONEPASS optimization is used (if this routine returns true)
|
||||
** then also write the indices of open cursors used by ONEPASS
|
||||
** into aiCur[0] and aiCur[1]. iaCur[0] gets the cursor of the data
|
||||
** table and aiCur[1] gets the cursor used by an auxiliary index.
|
||||
** table and iaCur[1] gets the cursor used by an auxiliary index.
|
||||
** Either value may be -1, indicating that cursor is not used.
|
||||
** Any cursors returned will have been opened for writing.
|
||||
**
|
||||
@@ -3088,10 +3088,9 @@ static void whereLoopOutputAdjust(
|
||||
&& (pTerm->wtFlags & TERM_HIGHTRUTH)==0 /* tag-20200224-1 */
|
||||
){
|
||||
Expr *pRight = pOpExpr->pRight;
|
||||
Parse *pParse = pWC->pWInfo->pParse;
|
||||
int k = 0;
|
||||
testcase( pOpExpr->op==TK_IS );
|
||||
if( sqlite3ExprIsInteger(pRight, &k, pParse) && k>=(-1) && k<=1 ){
|
||||
if( sqlite3ExprIsInteger(pRight, &k, 0) && k>=(-1) && k<=1 ){
|
||||
k = 10;
|
||||
}else{
|
||||
k = 20;
|
||||
|
||||
@@ -515,10 +515,7 @@ static void transferJoinMarkings(Expr *pDerived, Expr *pBase){
|
||||
static void markTermAsChild(WhereClause *pWC, int iChild, int iParent){
|
||||
pWC->a[iChild].iParent = iParent;
|
||||
pWC->a[iChild].truthProb = pWC->a[iParent].truthProb;
|
||||
assert( pWC->a[iParent].nChild < UMXV(pWC->a[0].nChild) );
|
||||
pWC->a[iParent].nChild++;
|
||||
testcase( pWC->a[iParent].nChild == UMXV(pWC->a[0].nChild) );
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1295,7 +1292,6 @@ static void exprAnalyze(
|
||||
pList = pExpr->x.pList;
|
||||
assert( pList!=0 );
|
||||
assert( pList->nExpr==2 );
|
||||
assert( pWC->a[idxTerm].nChild==0 );
|
||||
for(i=0; i<2; i++){
|
||||
Expr *pNewExpr;
|
||||
int idxNew;
|
||||
@@ -1506,11 +1502,8 @@ static void exprAnalyze(
|
||||
&& pExpr->x.pSelect->pWin==0
|
||||
#endif
|
||||
&& pWC->op==TK_AND
|
||||
&& pExpr->x.pSelect->pEList->nExpr <= UMXV(pTerm->nChild)
|
||||
/* ^-- See bug 2026-06-04T10:00:49Z */
|
||||
){
|
||||
int i;
|
||||
assert( pTerm->nChild==0 );
|
||||
for(i=0; i<sqlite3ExprVectorSize(pExpr->pLeft); i++){
|
||||
int idxNew;
|
||||
idxNew = whereClauseInsert(pWC, pExpr, TERM_VIRTUAL|TERM_SLICE);
|
||||
|
||||
+1
-10
@@ -981,15 +981,6 @@ do_execsql_test alter-21.4 {
|
||||
SELECT name, type FROM sqlite_schema ORDER BY name;
|
||||
} {r2 trigger t1 table t99 table}
|
||||
|
||||
# 2026-05-12 Verify that ADD COLUMN cannot insert internal-use-only
|
||||
# functions.
|
||||
#
|
||||
reset_db
|
||||
do_execsql_test alter-22.1 {
|
||||
CREATE TABLE t1(a,b);
|
||||
}
|
||||
do_catchsql_test alter-22.2 {
|
||||
ALTER TABLE t1 ADD COLUMN c CHECK( if(c<10,1,sqlite_fail('bummer',1)));
|
||||
} {1 {error in table t1 after add column: no such function: sqlite_fail}}
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -114,20 +114,4 @@ do_execsql_test amatch1-2.22 {
|
||||
WHERE word MATCH 'joxxph' AND distance<300;
|
||||
} {}
|
||||
|
||||
# Forum post 2026-05-09T05:48:28Z
|
||||
reset_db
|
||||
load_static_extension db amatch
|
||||
do_execsql_test amatch1-3.0 {
|
||||
CREATE TABLE cost(iLang,cFrom,cTo,Cost);
|
||||
INSERT INTO cost VALUES(0,'?','?',1);
|
||||
CREATE TABLE vocab(word TEXT PRIMARY KEY);
|
||||
CREATE VIRTUAL TABLE am USING approximate_match(
|
||||
vocabulary_table=vocab,
|
||||
vocabulary_word=word,
|
||||
edit_distances=cost
|
||||
);
|
||||
INSERT INTO vocab(word) VALUES(format('%.81c','a'));
|
||||
SELECT length(word) FROM am WHERE word MATCH format('%.81c','a');
|
||||
} {81}
|
||||
|
||||
finish_test
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user