diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-06-03 05:16:43 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-06-03 05:16:43 +0000 |
commit | fd8f22aa0eaf2a7726a6db288946cd904388ac4e (patch) | |
tree | 483f8cace8e3e64c9df42cef34c474bd225209ab | |
parent | Adding upstream version 3.45.3. (diff) | |
download | sqlite3-fd8f22aa0eaf2a7726a6db288946cd904388ac4e.tar.xz sqlite3-fd8f22aa0eaf2a7726a6db288946cd904388ac4e.zip |
Adding upstream version 3.46.0.upstream/3.46.0
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
267 files changed, 14520 insertions, 3815 deletions
diff --git a/Makefile.in b/Makefile.in index cb89466..c16e1c1 100644 --- a/Makefile.in +++ b/Makefile.in @@ -418,6 +418,8 @@ TESTSRC = \ $(TOP)/ext/recover/sqlite3recover.c \ $(TOP)/ext/recover/dbdata.c \ $(TOP)/ext/recover/test_recover.c \ + $(TOP)/ext/intck/test_intck.c \ + $(TOP)/ext/intck/sqlite3intck.c \ $(TOP)/ext/rbu/test_rbu.c # Statically linked extensions @@ -815,7 +817,7 @@ has_tclsh85: touch .target_source sqlite3.c: .target_source $(TOP)/tool/mksqlite3c.tcl src-verify has_tclsh84 - $(TCLSH_CMD) $(TOP)/tool/mksqlite3c.tcl $(AMALGAMATION_LINE_MACROS) + $(TCLSH_CMD) $(TOP)/tool/mksqlite3c.tcl $(AMALGAMATION_LINE_MACROS) $(EXTRA_SRC) cp tsrc/sqlite3ext.h . cp $(TOP)/ext/session/sqlite3session.h . @@ -826,7 +828,7 @@ sqlite3r.c: sqlite3.c sqlite3r.h has_tclsh84 cp $(TOP)/ext/recover/sqlite3recover.c tsrc/ cp $(TOP)/ext/recover/sqlite3recover.h tsrc/ cp $(TOP)/ext/recover/dbdata.c tsrc/ - $(TCLSH_CMD) $(TOP)/tool/mksqlite3c.tcl --enable-recover $(AMALGAMATION_LINE_MACROS) + $(TCLSH_CMD) $(TOP)/tool/mksqlite3c.tcl --enable-recover $(AMALGAMATION_LINE_MACROS) $(EXTRA_SRC) sqlite3ext.h: .target_source cp tsrc/sqlite3ext.h . @@ -1152,35 +1154,37 @@ keywordhash.h: $(TOP)/tool/mkkeywordhash.c $(BCC) -o mkkeywordhash$(BEXE) $(OPT_FEATURE_FLAGS) $(OPTS) $(TOP)/tool/mkkeywordhash.c ./mkkeywordhash$(BEXE) >keywordhash.h -# Source files that go into making shell.c -SHELL_SRC = \ - $(TOP)/src/shell.c.in \ - $(TOP)/ext/consio/console_io.c \ - $(TOP)/ext/consio/console_io.h \ - $(TOP)/ext/misc/appendvfs.c \ - $(TOP)/ext/misc/completion.c \ - $(TOP)/ext/misc/decimal.c \ - $(TOP)/ext/misc/basexx.c \ - $(TOP)/ext/misc/base64.c \ - $(TOP)/ext/misc/base85.c \ - $(TOP)/ext/misc/fileio.c \ - $(TOP)/ext/misc/ieee754.c \ - $(TOP)/ext/misc/regexp.c \ - $(TOP)/ext/misc/series.c \ - $(TOP)/ext/misc/shathree.c \ - $(TOP)/ext/misc/sqlar.c \ - $(TOP)/ext/misc/uint.c \ - $(TOP)/ext/expert/sqlite3expert.c \ - $(TOP)/ext/expert/sqlite3expert.h \ - $(TOP)/ext/misc/zipfile.c \ - $(TOP)/ext/misc/memtrace.c \ - $(TOP)/ext/misc/pcachetrace.c \ - $(TOP)/ext/recover/dbdata.c \ - $(TOP)/ext/recover/sqlite3recover.c \ - $(TOP)/ext/recover/sqlite3recover.h \ - $(TOP)/src/test_windirent.c - -shell.c: $(SHELL_SRC) $(TOP)/tool/mkshellc.tcl has_tclsh84 +# Source and header files that shell.c depends on +SHELL_DEP = \ + $(TOP)/src/shell.c.in \ + $(TOP)/ext/consio/console_io.c \ + $(TOP)/ext/consio/console_io.h \ + $(TOP)/ext/expert/sqlite3expert.c \ + $(TOP)/ext/expert/sqlite3expert.h \ + $(TOP)/ext/intck/sqlite3intck.c \ + $(TOP)/ext/intck/sqlite3intck.h \ + $(TOP)/ext/misc/appendvfs.c \ + $(TOP)/ext/misc/base64.c \ + $(TOP)/ext/misc/base85.c \ + $(TOP)/ext/misc/completion.c \ + $(TOP)/ext/misc/decimal.c \ + $(TOP)/ext/misc/fileio.c \ + $(TOP)/ext/misc/ieee754.c \ + $(TOP)/ext/misc/memtrace.c \ + $(TOP)/ext/misc/pcachetrace.c \ + $(TOP)/ext/misc/regexp.c \ + $(TOP)/ext/misc/series.c \ + $(TOP)/ext/misc/shathree.c \ + $(TOP)/ext/misc/sqlar.c \ + $(TOP)/ext/misc/uint.c \ + $(TOP)/ext/misc/zipfile.c \ + $(TOP)/ext/recover/dbdata.c \ + $(TOP)/ext/recover/sqlite3recover.c \ + $(TOP)/ext/recover/sqlite3recover.h \ + $(TOP)/src/test_windirent.c \ + $(TOP)/src/test_windirent.h + +shell.c: $(SHELL_DEP) $(TOP)/tool/mkshellc.tcl has_tclsh84 $(TCLSH_CMD) $(TOP)/tool/mkshellc.tcl >shell.c @@ -1308,9 +1312,9 @@ testfixture$(TEXE): has_tclsh85 $(TESTFIXTURE_SRC) $(LTLINK) -DSQLITE_NO_SYNC=1 $(TEMP_STORE) $(TESTFIXTURE_FLAGS) \ -o $@ $(TESTFIXTURE_SRC) $(LIBTCL) $(TLIBS) -coretestprogs: $(TESTPROGS) +coretestprogs: testfixture$(BEXE) sqlite3$(BEXE) -testprogs: coretestprogs srcck1$(BEXE) fuzzcheck$(TEXE) sessionfuzz$(TEXE) +testprogs: $(TESTPROGS) srcck1$(BEXE) fuzzcheck$(TEXE) sessionfuzz$(TEXE) # A very detailed test running most or all test cases fulltest: alltest fuzztest diff --git a/Makefile.msc b/Makefile.msc index 19bfe2f..5257cee 100644 --- a/Makefile.msc +++ b/Makefile.msc @@ -18,6 +18,13 @@ USE_AMALGAMATION = 1 !ENDIF # <</mark>> +# Optionally set EXTRA_SRC to a list of C files to append to +# the generated sqlite3.c. +# +!IFNDEF EXTRA_SRC +EXTRA_SRC = +!ENDIF + # Set this non-0 to enable full warnings (-W4, etc) when compiling. # !IFNDEF USE_FULLWARN @@ -1595,6 +1602,8 @@ TESTEXT = \ $(TOP)\ext\rtree\test_rtreedoc.c \ $(TOP)\ext\recover\sqlite3recover.c \ $(TOP)\ext\recover\test_recover.c \ + $(TOP)\ext\intck\test_intck.c \ + $(TOP)\ext\intck\sqlite3intck.c \ $(TOP)\ext\recover\dbdata.c # If use of zlib is enabled, add the "zipfile.c" source file. @@ -1913,7 +1922,7 @@ mptest: mptester.exe echo > .target_source sqlite3.c: .target_source sqlite3ext.h sqlite3session.h $(MKSQLITE3C_TOOL) src-verify.exe - $(TCLSH_CMD) $(MKSQLITE3C_TOOL) $(MKSQLITE3C_ARGS) + $(TCLSH_CMD) $(MKSQLITE3C_TOOL) $(MKSQLITE3C_ARGS) $(EXTRA_SRC) sqlite3-all.c: sqlite3.c $(TOP)\tool\split-sqlite3c.tcl $(TCLSH_CMD) $(TOP)\tool\split-sqlite3c.tcl @@ -2263,39 +2272,44 @@ mkkeywordhash.exe: $(TOP)\tool\mkkeywordhash.c keywordhash.h: $(TOP)\tool\mkkeywordhash.c mkkeywordhash.exe .\mkkeywordhash.exe > keywordhash.h -# Source files that go into making shell.c -SHELL_SRC = \ - $(TOP)\src\shell.c.in \ - $(TOP)\ext\consio\console_io.c \ - $(TOP)\ext\consio\console_io.h \ - $(TOP)\ext\misc\appendvfs.c \ - $(TOP)\ext\misc\completion.c \ - $(TOP)\ext\misc\base64.c \ - $(TOP)\ext\misc\base85.c \ - $(TOP)\ext\misc\decimal.c \ - $(TOP)\ext\misc\fileio.c \ - $(TOP)\ext\misc\ieee754.c \ - $(TOP)\ext\misc\regexp.c \ - $(TOP)\ext\misc\series.c \ - $(TOP)\ext\misc\shathree.c \ - $(TOP)\ext\misc\uint.c \ - $(TOP)\ext\expert\sqlite3expert.c \ - $(TOP)\ext\expert\sqlite3expert.h \ - $(TOP)\ext\misc\memtrace.c \ - $(TOP)\ext\misc\pcachetrace.c \ - $(TOP)\ext\recover\dbdata.c \ - $(TOP)\ext\recover\sqlite3recover.c \ - $(TOP)\ext\recover\sqlite3recover.h \ - $(TOP)\src\test_windirent.c +# Source and header files that shell.c depends on +SHELL_DEP = \ + $(TOP)\src\shell.c.in \ + $(TOP)\ext\consio\console_io.c \ + $(TOP)\ext\consio\console_io.h \ + $(TOP)\ext\expert\sqlite3expert.c \ + $(TOP)\ext\expert\sqlite3expert.h \ + $(TOP)\ext\intck\sqlite3intck.c \ + $(TOP)\ext\intck\sqlite3intck.h \ + $(TOP)\ext\misc\appendvfs.c \ + $(TOP)\ext\misc\base64.c \ + $(TOP)\ext\misc\base85.c \ + $(TOP)\ext\misc\completion.c \ + $(TOP)\ext\misc\decimal.c \ + $(TOP)\ext\misc\fileio.c \ + $(TOP)\ext\misc\ieee754.c \ + $(TOP)\ext\misc\memtrace.c \ + $(TOP)\ext\misc\pcachetrace.c \ + $(TOP)\ext\misc\regexp.c \ + $(TOP)\ext\misc\series.c \ + $(TOP)\ext\misc\shathree.c \ + $(TOP)\ext\misc\sqlar.c \ + $(TOP)\ext\misc\uint.c \ + $(TOP)\ext\misc\zipfile.c \ + $(TOP)\ext\recover\dbdata.c \ + $(TOP)\ext\recover\sqlite3recover.c \ + $(TOP)\ext\recover\sqlite3recover.h \ + $(TOP)\src\test_windirent.c \ + $(TOP)\src\test_windirent.h # If use of zlib is enabled, add the "zipfile.c" source file. # !IF $(USE_ZLIB)!=0 -SHELL_SRC = $(SHELL_SRC) $(TOP)\ext\misc\sqlar.c -SHELL_SRC = $(SHELL_SRC) $(TOP)\ext\misc\zipfile.c +SHELL_DEP = $(SHELL_DEP) $(TOP)\ext\misc\sqlar.c +SHELL_DEP = $(SHELL_DEP) $(TOP)\ext\misc\zipfile.c !ENDIF -shell.c: $(SHELL_SRC) $(TOP)\tool\mkshellc.tcl +shell.c: $(SHELL_DEP) $(TOP)\tool\mkshellc.tcl $(TCLSH_CMD) $(TOP)\tool\mkshellc.tcl > shell.c zlib: @@ -2482,9 +2496,9 @@ extensiontest: testfixture.exe testloadext.dll tool-zip: testfixture.exe sqlite3.exe sqldiff.exe sqlite3_analyzer.exe $(TOP)\tool\mktoolzip.tcl .\testfixture.exe $(TOP)\tool\mktoolzip.tcl -coretestprogs: $(TESTPROGS) +coretestprogs: testfixture.exe sqlite3.exe -testprogs: coretestprogs srcck1.exe fuzzcheck.exe sessionfuzz.exe +testprogs: $(TESTPROGS) srcck1.exe fuzzcheck.exe sessionfuzz.exe fulltest: alltest fuzztest @@ -2539,7 +2553,7 @@ mdevtest: # Testing for a release # -releasetest: testfixture.exe fuzztest +releasetest: testfixture.exe testfixture.exe $(TOP)\test\testrunner.tcl release @@ -1 +1 @@ -3.45.3 +3.46.0 diff --git a/art/icon-243x273.gif b/art/icon-243x273.gif Binary files differnew file mode 100644 index 0000000..e1cdfd0 --- /dev/null +++ b/art/icon-243x273.gif diff --git a/art/icon-80x90.gif b/art/icon-80x90.gif Binary files differnew file mode 100644 index 0000000..ebb2390 --- /dev/null +++ b/art/icon-80x90.gif diff --git a/autoconf/Makefile.msc b/autoconf/Makefile.msc index 45a07a9..a4270fb 100644 --- a/autoconf/Makefile.msc +++ b/autoconf/Makefile.msc @@ -18,6 +18,13 @@ TOP = . +# Optionally set EXTRA_SRC to a list of C files to append to +# the generated sqlite3.c. +# +!IFNDEF EXTRA_SRC +EXTRA_SRC = +!ENDIF + # Set this non-0 to enable full warnings (-W4, etc) when compiling. # !IFNDEF USE_FULLWARN diff --git a/autoconf/tea/configure.ac b/autoconf/tea/configure.ac index ba4690a..f188f22 100644 --- a/autoconf/tea/configure.ac +++ b/autoconf/tea/configure.ac @@ -19,7 +19,7 @@ dnl to configure the system for the local environment. # so that we create the export library with the dll. #----------------------------------------------------------------------- -AC_INIT([sqlite],[3.45.3]) +AC_INIT([sqlite],[3.46.0]) #-------------------------------------------------------------------- # Call TEA_INIT as the first TEA_ macro to set up initial vars. @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for sqlite 3.45.3. +# Generated by GNU Autoconf 2.69 for sqlite 3.46.0. # # # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. @@ -726,8 +726,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='sqlite' PACKAGE_TARNAME='sqlite' -PACKAGE_VERSION='3.45.3' -PACKAGE_STRING='sqlite 3.45.3' +PACKAGE_VERSION='3.46.0' +PACKAGE_STRING='sqlite 3.46.0' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -1472,7 +1472,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures sqlite 3.45.3 to adapt to many kinds of systems. +\`configure' configures sqlite 3.46.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1537,7 +1537,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of sqlite 3.45.3:";; + short | recursive ) echo "Configuration of sqlite 3.46.0:";; esac cat <<\_ACEOF @@ -1668,7 +1668,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -sqlite configure 3.45.3 +sqlite configure 3.46.0 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -2087,7 +2087,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by sqlite $as_me 3.45.3, which was +It was created by sqlite $as_me 3.46.0, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -12481,7 +12481,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by sqlite $as_me 3.45.3, which was +This file was extended by sqlite $as_me 3.46.0, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -12547,7 +12547,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -sqlite config.status 3.45.3 +sqlite config.status 3.46.0 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" diff --git a/doc/lemon.html b/doc/lemon.html index 66665f4..4147d9b 100644 --- a/doc/lemon.html +++ b/doc/lemon.html @@ -683,6 +683,7 @@ other than that, the order of directives in Lemon is arbitrary.</p> <li><tt><a href='#pifdef'>%endif</a></tt> <li><tt><a href='#extraarg'>%extra_argument</a></tt> <li><tt><a href='#pfallback'>%fallback</a></tt> +<li><tt><a href='#reallc'>%free</a></tt> <li><tt><a href='#pifdef'>%if</a></tt> <li><tt><a href='#pifdef'>%ifdef</a></tt> <li><tt><a href='#pifdef'>%ifndef</a></tt> @@ -693,6 +694,7 @@ other than that, the order of directives in Lemon is arbitrary.</p> <li><tt><a href='#parse_accept'>%parse_accept</a></tt> <li><tt><a href='#parse_failure'>%parse_failure</a></tt> <li><tt><a href='#pright'>%right</a></tt> +<li><tt><a href='#reallc'>%realloc</a></tt> <li><tt><a href='#stack_overflow'>%stack_overflow</a></tt> <li><tt><a href='#stack_size'>%stack_size</a></tt> <li><tt><a href='#start_symbol'>%start_symbol</a></tt> @@ -1200,6 +1202,21 @@ match any input token.</p> the wildcard token and some other token, the other token is always used. The wildcard token is only matched if there are no alternatives.</p> +<a id='reallc'></a> +<h4>4.4.26 The <tt>%realloc</tt> and <tt>%free</tt> directives</h4> + +<p>The <tt>%realloc</tt> and <tt>%free</tt> directives defines function +that allocate and free heap memory. The signatures of these functions +should be the same as the realloc() and free() functions from the standard +C library. + +<p>If both of these functions are defined +then these functions are used to allocate and free +memory for supplemental parser stack space, if the initial +parse stack space is exceeded. The initial parser stack size +is specified by either <tt>%stack_size</tt> or the +-DYYSTACKDEPTH compile-time flag. + <a id='errors'></a> <h2>5.0 Error Processing</h2> @@ -1224,6 +1241,7 @@ to begin parsing a new file. This is what will happen at the very first syntax error, of course, if there are no instances of the "error" non-terminal in your grammar.</p> + <a id='history'></a> <h2>6.0 History of Lemon</h2> diff --git a/doc/testrunner.md b/doc/testrunner.md index d420076..d024857 100644 --- a/doc/testrunner.md +++ b/doc/testrunner.md @@ -17,7 +17,6 @@ <li> 3.3. <a href=#source_code_test_failures>Investigating Source Code Test Failures</a> </ul> <li> 4. <a href=#testrunner_options>Extra testrunner.tcl Options</a> -# 4. Extra testrunner.tcl Options <li> 5. <a href=#cpu_cores>Controlling CPU Core Utilization</a> </ul> @@ -29,12 +28,18 @@ multiple jobs. It supports the following types of tests: * Tcl test scripts. - * Tests run with [make] commands. Specifically, at time of writing, - [make fuzztest], [make mptest], [make sourcetest] and [make threadtest]. + * Tests run with `make` commands. Examples: + - `make mdevtest` + - `make releasetest` + - `make sdevtest` + - `make testrunner` testrunner.tcl pipes the output of all tests and builds run into log file -**testrunner.log**, created in the cwd directory. Searching this file for -"failed" is a good way to find the output of a failed test. +**testrunner.log**, created in the current working directory. Search this +file to find details of errors. Suggested search commands: + + * `grep "^!" testrunner.log` + * `grep failed testrunner.log` testrunner.tcl also populates SQLite database **testrunner.db**. This database contains details of all tests run, running and to be run. A useful query @@ -60,7 +65,7 @@ Running: in another terminal is a good way to keep an eye on a long running test. -Sometimes testrunner.tcl uses the [testfixture] binary that it is run with +Sometimes testrunner.tcl uses the `testfixture` binary that it is run with to run tests (see "Binary Tests" below). Sometimes it builds testfixture and other binaries in specific configurations to test (see "Source Tests"). @@ -68,9 +73,9 @@ other binaries in specific configurations to test (see "Source Tests"). # 2. Binary Tests The commands described in this section all run various combinations of the Tcl -test scripts using the [testfixture] binary used to run the testrunner.tcl +test scripts using the `testfixture` binary used to run the testrunner.tcl script (i.e. they do not invoke the compiler to build new binaries, or the -[make] command to run tests that are not Tcl scripts). The procedure to run +`make` command to run tests that are not Tcl scripts). The procedure to run these tests is therefore: 1. Build the "testfixture" (or "testfixture.exe" for windows) binary using @@ -193,7 +198,7 @@ TODO: ./configure + Makefile.msc build systems. ## 3.1. Commands to Run SQLite Tests The **mdevtest** command is equivalent to running the veryquick tests and -the [make fuzztest] target once for each of two --enable-all builds - one +the `make fuzztest` target once for each of two --enable-all builds - one with debugging enabled and one without: ``` @@ -283,7 +288,7 @@ a dos \*.bat file on windows. For example: ``` The generated bash or \*.bat file script accepts a single argument - a makefile -target to build. This may be used either to run a [make] command test directly, +target to build. This may be used either to run a `make` command test directly, or else to build a testfixture (or testfixture.exe) binary with which to run a Tcl test script, as <a href=#binary_test_failures>described above</a>. @@ -310,6 +315,16 @@ would normally execute into the testrunner.log file. Example: tclsh $TESTDIR/testrunner.tcl --dryrun mdevtest" ``` +The **--explain** option is similar to --dryrun in that it prevents testrunner.tcl +from building any binaries or running any tests. The difference is that --explain +prints on standard output a human-readable summary of all the builds and tests that +would have been run. + +``` + # Show what builds and tests would have been run + tclsh $TESTDIR/testrunner.tcl --explain mdevtest +``` + <a name=cpu_cores></a> # 5. Controlling CPU Core Utilization @@ -339,6 +354,3 @@ testrunner.log and testrunner.db files: ``` $ ./testfixture $TESTDIR/testrunner.tcl njob $NEW_NUMBER_OF_JOBS ``` - - - diff --git a/ext/expert/expert1.test b/ext/expert/expert1.test index 4533342..c456c30 100644 --- a/ext/expert/expert1.test +++ b/ext/expert/expert1.test @@ -8,6 +8,7 @@ # May you share freely, never taking more than you give. # #*********************************************************************** +# TESTRUNNER: shell # # The focus of this file is testing the CLI shell tool. Specifically, # the ".recommend" command. diff --git a/ext/expert/sqlite3expert.c b/ext/expert/sqlite3expert.c index 33d6222..276c2cc 100644 --- a/ext/expert/sqlite3expert.c +++ b/ext/expert/sqlite3expert.c @@ -1948,7 +1948,7 @@ sqlite3expert *sqlite3_expert_new(sqlite3 *db, char **pzErrmsg){ sqlite3_stmt *pSql = 0; rc = idxPrintfPrepareStmt(pNew->db, &pSql, pzErrmsg, "SELECT sql FROM sqlite_schema WHERE name NOT LIKE 'sqlite_%%'" - " AND sql NOT LIKE 'CREATE VIRTUAL %%'" + " AND sql NOT LIKE 'CREATE VIRTUAL %%' ORDER BY rowid" ); while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pSql) ){ const char *zSql = (const char*)sqlite3_column_text(pSql, 0); diff --git a/ext/fts3/fts3.c b/ext/fts3/fts3.c index 3795901..f977aab 100644 --- a/ext/fts3/fts3.c +++ b/ext/fts3/fts3.c @@ -4014,22 +4014,24 @@ static int fts3IntegrityMethod( char **pzErr /* Write error message here */ ){ Fts3Table *p = (Fts3Table*)pVtab; - int rc; + int rc = SQLITE_OK; int bOk = 0; UNUSED_PARAMETER(isQuick); rc = sqlite3Fts3IntegrityCheck(p, &bOk); - assert( rc!=SQLITE_CORRUPT_VTAB || bOk==0 ); - if( rc!=SQLITE_OK && rc!=SQLITE_CORRUPT_VTAB ){ + assert( rc!=SQLITE_CORRUPT_VTAB ); + if( rc==SQLITE_ERROR || (rc&0xFF)==SQLITE_CORRUPT ){ *pzErr = sqlite3_mprintf("unable to validate the inverted index for" " FTS%d table %s.%s: %s", p->bFts4 ? 4 : 3, zSchema, zTabname, sqlite3_errstr(rc)); - }else if( bOk==0 ){ + if( *pzErr ) rc = SQLITE_OK; + }else if( rc==SQLITE_OK && bOk==0 ){ *pzErr = sqlite3_mprintf("malformed inverted index for FTS%d table %s.%s", p->bFts4 ? 4 : 3, zSchema, zTabname); + if( *pzErr==0 ) rc = SQLITE_NOMEM; } sqlite3Fts3SegmentsClose(p); - return SQLITE_OK; + return rc; } diff --git a/ext/fts3/fts3_snippet.c b/ext/fts3/fts3_snippet.c index 227c5f0..f6caabf 100644 --- a/ext/fts3/fts3_snippet.c +++ b/ext/fts3/fts3_snippet.c @@ -446,7 +446,7 @@ static void fts3SnippetDetails( } mCover |= mPhrase; - for(j=0; j<pPhrase->nToken; j++){ + for(j=0; j<pPhrase->nToken && j<pIter->nSnippet; j++){ mHighlight |= (mPos>>j); } diff --git a/ext/fts3/fts3_write.c b/ext/fts3/fts3_write.c index 2516a39..5a449de 100644 --- a/ext/fts3/fts3_write.c +++ b/ext/fts3/fts3_write.c @@ -5372,7 +5372,12 @@ int sqlite3Fts3IntegrityCheck(Fts3Table *p, int *pbOk){ sqlite3_finalize(pStmt); } - *pbOk = (rc==SQLITE_OK && cksum1==cksum2); + if( rc==SQLITE_CORRUPT_VTAB ){ + rc = SQLITE_OK; + *pbOk = 0; + }else{ + *pbOk = (rc==SQLITE_OK && cksum1==cksum2); + } return rc; } diff --git a/ext/fts5/fts5.h b/ext/fts5/fts5.h index 250d2ee..551618e 100644 --- a/ext/fts5/fts5.h +++ b/ext/fts5/fts5.h @@ -55,8 +55,8 @@ struct Fts5PhraseIter { ** EXTENSION API FUNCTIONS ** ** xUserData(pFts): -** Return a copy of the context pointer the extension function was -** registered with. +** Return a copy of the pUserData pointer passed to the xCreateFunction() +** API when the extension function was registered. ** ** xColumnTotalSize(pFts, iCol, pnToken): ** If parameter iCol is less than zero, set output variable *pnToken diff --git a/ext/fts5/fts5_main.c b/ext/fts5/fts5_main.c index 7c818ce..f609f7f 100644 --- a/ext/fts5/fts5_main.c +++ b/ext/fts5/fts5_main.c @@ -2979,6 +2979,7 @@ static int fts5IntegrityMethod( if( (rc&0xff)==SQLITE_CORRUPT ){ *pzErr = sqlite3_mprintf("malformed inverted index for FTS5 table %s.%s", zSchema, zTabname); + rc = (*pzErr) ? SQLITE_OK : SQLITE_NOMEM; }else if( rc!=SQLITE_OK ){ *pzErr = sqlite3_mprintf("unable to validate the inverted index for" " FTS5 table %s.%s: %s", @@ -2986,7 +2987,7 @@ static int fts5IntegrityMethod( } sqlite3Fts5IndexCloseReader(pTab->p.pIndex); - return SQLITE_OK; + return rc; } static int fts5Init(sqlite3 *db){ diff --git a/ext/fts5/test/fts5fault8.test b/ext/fts5/test/fts5fault8.test index 5afab77..dc060a1 100644 --- a/ext/fts5/test/fts5fault8.test +++ b/ext/fts5/test/fts5fault8.test @@ -57,7 +57,6 @@ foreach_detail_mode $testprefix { } ;# foreach_detail_mode... - do_execsql_test 4.0 { CREATE VIRTUAL TABLE x2 USING fts5(a); INSERT INTO x2(x2, rank) VALUES('crisismerge', 2); @@ -80,5 +79,18 @@ do_faultsim_test 4 -faults oom-* -prep { faultsim_test_result {0 {}} {1 SQLITE_NOMEM} } +set TMPDBERROR {1 {unable to open a temporary database file for storing temporary tables}} + +do_faultsim_test 5 -faults oom-t* -prep { + faultsim_restore_and_reopen + execsql { PRAGMA temp_store = memory } +} -body { + execsql { PRAGMA integrity_check } +} -test { + if {[string match {*error code=7*} $testresult]==0} { + faultsim_test_result {0 ok} {1 SQLITE_NOMEM} $::TMPDBERROR + } +} + finish_test diff --git a/ext/icu/icu.c b/ext/icu/icu.c index e745ab0..69867bf 100644 --- a/ext/icu/icu.c +++ b/ext/icu/icu.c @@ -471,7 +471,7 @@ static void icuLoadCollation( UCollator *pUCollator; /* ICU library collation object */ int rc; /* Return code from sqlite3_create_collation_x() */ - assert(nArg==2); + assert(nArg==2 || nArg==3); (void)nArg; /* Unused parameter */ zLocale = (const char *)sqlite3_value_text(apArg[0]); zName = (const char *)sqlite3_value_text(apArg[1]); @@ -486,7 +486,39 @@ static void icuLoadCollation( return; } assert(p); - + if(nArg==3){ + const char *zOption = (const char*)sqlite3_value_text(apArg[2]); + static const struct { + const char *zName; + UColAttributeValue val; + } aStrength[] = { + { "PRIMARY", UCOL_PRIMARY }, + { "SECONDARY", UCOL_SECONDARY }, + { "TERTIARY", UCOL_TERTIARY }, + { "DEFAULT", UCOL_DEFAULT_STRENGTH }, + { "QUARTERNARY", UCOL_QUATERNARY }, + { "IDENTICAL", UCOL_IDENTICAL }, + }; + unsigned int i; + for(i=0; i<sizeof(aStrength)/sizeof(aStrength[0]); i++){ + if( sqlite3_stricmp(zOption,aStrength[i].zName)==0 ){ + ucol_setStrength(pUCollator, aStrength[i].val); + break; + } + } + if( i>=sizeof(aStrength)/sizeof(aStrength[0]) ){ + sqlite3_str *pStr = sqlite3_str_new(sqlite3_context_db_handle(p)); + sqlite3_str_appendf(pStr, + "unknown collation strength \"%s\" - should be one of:", + zOption); + for(i=0; i<sizeof(aStrength)/sizeof(aStrength[0]); i++){ + sqlite3_str_appendf(pStr, " %s", aStrength[i].zName); + } + sqlite3_result_error(p, sqlite3_str_value(pStr), -1); + sqlite3_free(sqlite3_str_finish(pStr)); + return; + } + } rc = sqlite3_create_collation_v2(db, zName, SQLITE_UTF16, (void *)pUCollator, icuCollationColl, icuCollationDel ); @@ -509,6 +541,7 @@ int sqlite3IcuInit(sqlite3 *db){ void (*xFunc)(sqlite3_context*,int,sqlite3_value**); } scalars[] = { {"icu_load_collation",2,SQLITE_UTF8|SQLITE_DIRECTONLY,1, icuLoadCollation}, + {"icu_load_collation",3,SQLITE_UTF8|SQLITE_DIRECTONLY,1, icuLoadCollation}, #if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_ICU) {"regexp", 2, SQLITE_ANY|SQLITEICU_EXTRAFLAGS, 0, icuRegexpFunc}, {"lower", 1, SQLITE_UTF16|SQLITEICU_EXTRAFLAGS, 0, icuCaseFunc16}, diff --git a/ext/intck/intck1.test b/ext/intck/intck1.test new file mode 100644 index 0000000..187132f --- /dev/null +++ b/ext/intck/intck1.test @@ -0,0 +1,332 @@ +# 2008 Feb 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. +# +#*********************************************************************** +# +# The focus of this file is testing the incremental integrity check +# (intck) extension. +# + +source [file join [file dirname [info script]] intck_common.tcl] +set testprefix intck1 +return_if_no_intck + +foreach {tn sql} { + 1 "CREATE TABLE t1(a PRIMARY KEY, b)" + 2 "CREATE TABLE t2(a PRIMARY KEY, b) WITHOUT ROWID " + 3 "CREATE TABLE t3(a PRIMARY KEY, b) WITHOUT rowID;" + 4 "CREATE TABLE t4(a PRIMARY KEY, ROWID)" + 5 {CREATE TABLE t5(a PRIMARY KEY, ROWID) WITHOUT ROWID + } +} { + do_test 1.1.$tn { + db eval $sql + set {} {} + } {} +} + +set space " \n\v\t\r\f" + +do_execsql_test 1.2 { + SELECT name, (rtrim(sql, $space) LIKE '%rowid') + FROM sqlite_schema WHERE type='table' + ORDER BY 1 +} { + t1 0 + t2 1 + t3 1 + t4 0 + t5 1 +} + +do_execsql_test 1.3 { + CREATE TABLE x1(a COLLATE nocase, b INTEGER, c BLOB); + INSERT INTO x1 VALUES('lEtTeRs', 1234, 1234); +} +do_execsql_test 1.3.1 { + WITH wrapper(c1, c2, c3) AS ( + SELECT a, b, c FROM x1 + ) + SELECT * FROM wrapper WHERE c1='letters'; +} {lEtTeRs 1234 1234} +do_execsql_test 1.3.2 { + WITH wrapper(c1, c2, c3) AS ( + SELECT a, b, c FROM x1 + ) + SELECT * FROM wrapper WHERE c2='1234'; +} {lEtTeRs 1234 1234} +do_execsql_test 1.3.2 { + WITH wrapper(c1, c2, c3) AS ( + SELECT a, b, c FROM x1 + ) + SELECT * FROM wrapper WHERE c3='1234'; +} {} + +do_execsql_test 1.4 { + CREATE TABLE z1(a, b); + CREATE INDEX z1ab ON z1(a+b COLLATE nocase); +} +do_execsql_test 1.4.1 { + SELECT * FROM z1 INDEXED BY z1ab +} + +do_catchsql_test 1.5.1 { + CREATE INDEX z1b ON z1(b ASC NULLS LAST); +} {1 {unsupported use of NULLS LAST}} +do_catchsql_test 1.5.2 { + CREATE INDEX z1b ON z1(b DESC NULLS LAST); +} {1 {unsupported use of NULLS LAST}} +do_catchsql_test 1.5.3 { + CREATE INDEX z1b ON z1(b ASC NULLS FIRST); +} {1 {unsupported use of NULLS FIRST}} +do_catchsql_test 1.5.4 { + CREATE INDEX z1b ON z1(b DESC NULLS FIRST); +} {1 {unsupported use of NULLS FIRST}} + + +reset_db +do_execsql_test 1.6.1 { + CREATE TABLE t1(i INTEGER PRIMARY KEY, b, c); + CREATE INDEX i1 ON t1(b); + ANALYZE; + INSERT INTO sqlite_stat1 VALUES('t1', 'i1', '10000 10000'); + ANALYZE sqlite_schema; +} {} +do_eqp_test 1.6.2 { + SELECT 1 FROM t1 INDEXED BY i1 WHERE (b, i) IS (?, ?); +} {SEARCH} + + + +#------------------------------------------------------------------------- +reset_db + +do_test 2.0 { + set ic [sqlite3_intck db main] + $ic close +} {} + +do_execsql_test 2.1 { + CREATE TABLE t1(a, b); + INSERT INTO t1 VALUES(1, 2); + INSERT INTO t1 VALUES(3, 4); + + CREATE INDEX i1 ON t1(a COLLATE nocase); + CREATE INDEX i2 ON t1(b, a); + CREATE INDEX i3 ON t1(b + a COLLATE nocase) WHERE a!=1; +} + +do_intck_test 2.2 { +} + +# Delete a row from each of the i1 and i2 indexes using the imposter +# table interface. +# +do_test 2.3 { + db eval {SELECT name, rootpage FROM sqlite_schema} { + set R($name) $rootpage + } + sqlite3_test_control SQLITE_TESTCTRL_IMPOSTER db main 1 $R(i1) + db eval { CREATE TABLE imp1(a PRIMARY KEY, rowid) WITHOUT ROWID; } + sqlite3_test_control SQLITE_TESTCTRL_IMPOSTER db main 1 $R(i2) + db eval { CREATE TABLE imp2(b, a, rowid, PRIMARY KEY(b, a)) WITHOUT ROWID; } + sqlite3_test_control SQLITE_TESTCTRL_IMPOSTER db main 0 0 + + db eval { + DELETE FROM imp1 WHERE rowid=1; + DELETE FROM imp2 WHERE rowid=2; + } + + db close + sqlite3 db test.db +} {} + +do_intck_test 2.4 { + {entry (1,1) missing from index i1} + {entry (4,3,2) missing from index i2} +} + +#------------------------------------------------------------------------- +reset_db +do_execsql_test 3.0 { + CREATE TABLE x1(a, b, c, PRIMARY KEY(c, b)) WITHOUT ROWID; + CREATE INDEX x1a ON x1(a COLLATE nocase); + + INSERT INTO x1 VALUES(1, 2, 'three'); + INSERT INTO x1 VALUES(4, 5, 'six'); + INSERT INTO x1 VALUES(7, 8, 'nine'); +} + +do_intck_test 3.1 { } + +do_test 3.2 { + db eval {SELECT name, rootpage FROM sqlite_schema} { + set R($name) $rootpage + } + sqlite3_test_control SQLITE_TESTCTRL_IMPOSTER db main 1 $R(x1a) + db eval { CREATE TABLE imp1(c, b, a, PRIMARY KEY(c, b)) WITHOUT ROWID } + sqlite3_test_control SQLITE_TESTCTRL_IMPOSTER db main 0 0 + + db eval { + DELETE FROM imp1 WHERE a=5; + } + execsql_pp { + } + + db close + sqlite3 db test.db +} {} + +do_intck_test 3.3 { + {entry (4,'six',5) missing from index x1a} +} + +#------------------------------------------------------------------------- +reset_db +do_execsql_test 4.0 { + CREATE TABLE www(x, y, z); + CREATE INDEX w1 ON www( (x+1), z ); + INSERT INTO www VALUES(1, 1, 1), (2, 2, 2); +} + +do_intck_test 4.1 { } + +#------------------------------------------------------------------------- +reset_db +do_execsql_test 5.0 { + CREATE TABLE t1(a, b); + CREATE INDEX i1 ON t1(a COLLATE NOCASE); + INSERT INTO t1 VALUES(1, 1); + INSERT INTO t1 VALUES(2, 2); +} + +do_test 5.1 { + set ic [sqlite3_intck db nosuchdb] + $ic step +} {SQLITE_ERROR} + +do_test 5.2 { + $ic close + set ic [sqlite3_intck db {}] + while {[$ic step]=="SQLITE_OK"} {} + set res [$ic error] + $ic close + set res +} {SQLITE_OK {}} + +do_test 5.3 { test_do_intck db "main" } {} + +do_test 5.4 { + set ret {} + set ic [sqlite3_intck db main] + db eval [$ic test_sql t1] { + if {$error_message!=""} { lappend ret $error_message } + } + $ic close + set ret +} {} + +do_test 5.5 { + set ret {} + set ic [sqlite3_intck db main] + db eval [$ic test_sql {}] { + if {$error_message!=""} { lappend ret $error_message } + } + $ic close + set ret +} {} + +db cache flush + +do_test 5.6 { + set ret {} + set ic [sqlite3_intck db main] + $ic step + db eval [$ic test_sql {}] { + if {$error_message!=""} { lappend ret $error_message } + } + $ic close + set ret +} {} + +#------------------------------------------------------------------------- +reset_db + +do_execsql_test 6.0 { + CREATE TABLE t1(x, y, PRIMARY KEY(x)) WITHOUT ROWID; + CREATE INDEX i1 ON t1(y, x); + INSERT INTO t1 VALUES(X'0000', X'1111'); +} + +do_intck_test 6.1 {} + +do_execsql_test 6.2.1 { + PRAGMA writable_schema = 1; + UPDATE sqlite_schema SET sql = 'CREATE INDEX i1' WHERE name='i1'; +} {} +do_intck_test 6.2.2 {} + +do_execsql_test 6.3.1 { + UPDATE sqlite_schema SET sql = 'CREATE INDEX i1(y' WHERE name='i1'; +} {} +do_intck_test 6.3.2 {} + +do_execsql_test 6.4.1 { + UPDATE sqlite_schema + SET sql = 'CREATE INDEX i1(y) hello world' + WHERE name='i1'; +} {} +do_intck_test 6.4.2 {} + +do_execsql_test 6.5.1 { + UPDATE sqlite_schema + SET sql = 'CREATE INDEX i1(y, x) WHERE 1 ' + WHERE name='i1'; +} {} +do_intck_test 6.5.2 {} + +do_execsql_test 6.6.1 { + UPDATE sqlite_schema + SET sql = 'CREATE INDEX i1( , ) WHERE 1 ' + WHERE name='i1'; +} {} + +do_test 6.7.2 { + set ic [sqlite3_intck db main] + $ic step +} {SQLITE_ERROR} +do_test 6.5.3 { + $ic error +} {SQLITE_ERROR {near "AS": syntax error}} +$ic close + +do_execsql_test 6.6.1 { + UPDATE sqlite_schema + SET sql = 'CREATE INDEX i1([y' + WHERE name='i1'; +} {} +do_intck_test 6.6.2 {} + +#------------------------------------------------------------------------- +reset_db +do_execsql_test 7.0 { + CREATE TABLE x1("1", "22", "3333", four); + CREATE INDEX i1 ON x1( "1" , "22", NULL); + INSERT INTO x1 VALUES(1, 22, 3333, NULL); + INSERT INTO x1 VALUES(1, 22, 3333, NULL); +} +do_execsql_test 7.1 " CREATE INDEX i2 ON x1( \"1\"\r\n\t ) " +do_execsql_test 7.2 { CREATE INDEX i3 ON x1( "22" || 'abc''def' || `1` ) } +do_execsql_test 7.3 { CREATE INDEX i4 ON x1( [22] + [1] ) } +do_execsql_test 7.4 { CREATE INDEX i5 ON x1( four||'hello' ) } + +do_intck_test 7.5 {} + + +finish_test diff --git a/ext/intck/intck2.test b/ext/intck/intck2.test new file mode 100644 index 0000000..23b241b --- /dev/null +++ b/ext/intck/intck2.test @@ -0,0 +1,177 @@ +# 2024 Feb 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. +# +#*********************************************************************** +# +# The focus of this file is testing the incremental integrity check +# (intck) extension. +# + +source [file join [file dirname [info script]] intck_common.tcl] +set testprefix intck2 +return_if_no_intck + + +do_execsql_test 1.0 { + CREATE TABLE t1(a INTEGER PRIMARY KEY, b TEXT); + INSERT INTO t1 VALUES(1, 'one'); + INSERT INTO t1 VALUES(2, 'two'); + INSERT INTO t1 VALUES(3, 'three'); + CREATE INDEX i1 ON t1(b); +} + +proc imposter_edit {obj create sql} { + sqlite3 xdb test.db + set pgno [xdb one {SELECT rootpage FROM sqlite_schema WHERE name=$obj}] + + sqlite3_test_control SQLITE_TESTCTRL_IMPOSTER xdb main 1 $pgno + xdb eval $create + sqlite3_test_control SQLITE_TESTCTRL_IMPOSTER xdb main 0 0 + xdb eval $sql + xdb close +} + +imposter_edit i1 { + CREATE TABLE imp(b, a, PRIMARY KEY(b)) WITHOUT ROWID; +} { + DELETE FROM imp WHERE b='two'; + INSERT INTO imp(b, a) VALUES('four', 4); +} + +do_intck_test 1.1 { + {surplus entry ('four',4) in index i1} + {entry ('two',2) missing from index i1} +} + +#------------------------------------------------------------------------- +reset_db +do_execsql_test 2.0 { + CREATE TABLE x1(a, b, "c d"); + CREATE INDEX x1a ON x1(a COLLATE nocase DESC , b ASC); + CREATE INDEX x1b ON x1( a || b || ' "''" ' COLLATE binary ASC ); + CREATE INDEX x1c ON x1( format('%s', a)ASC, format('%d', "c d" ) ); + INSERT INTO x1 VALUES('one', 2, 3); + INSERT INTO x1 VALUES('One', 4, 5); + INSERT INTO x1 VALUES('ONE', 6, 7); + INSERT INTO x1 VALUES(NULL, NULL, NULL); +} + +do_intck_test 2.1 {} + +imposter_edit x1 { + CREATE TABLE imp(a, b, c); +} { + DELETE FROM imp WHERE c=7; +} +do_intck_test 2.2 { + {surplus entry ('ONE',6,3) in index x1a} + {surplus entry ('ONE6 "''" ',3) in index x1b} + {surplus entry ('ONE','7',3) in index x1c} +} + +#------------------------------------------------------------------------- +reset_db +do_execsql_test 3.0 { + CREATE TABLE x1(a, b, c); + CREATE INDEX x1all ON x1(a DESC, b ASC, c DESC); + INSERT INTO x1 VALUES(2, 1, 2); + INSERT INTO x1 VALUES(2, 1, 1); + INSERT INTO x1 VALUES(2, 2, 2); + INSERT INTO x1 VALUES(2, 2, 1); + INSERT INTO x1 VALUES(1, 1, 2); + INSERT INTO x1 VALUES(1, 1, 1); + INSERT INTO x1 VALUES(1, 2, 2); + INSERT INTO x1 VALUES(1, 2, 1); +} + +do_intck_test 3.1 { +} + +imposter_edit x1 { + CREATE TABLE imp(a, b, c); +} { + DELETE FROM imp WHERE 1; +} + +db close +sqlite3 db test.db + +do_intck_test 3.2 { + {surplus entry (2,1,2,1) in index x1all} + {surplus entry (2,1,1,2) in index x1all} + {surplus entry (2,2,2,3) in index x1all} + {surplus entry (2,2,1,4) in index x1all} + {surplus entry (1,1,2,5) in index x1all} + {surplus entry (1,1,1,6) in index x1all} + {surplus entry (1,2,2,7) in index x1all} + {surplus entry (1,2,1,8) in index x1all} +} + +do_execsql_test 3.3 { + DELETE FROM x1; + INSERT INTO x1 VALUES(NULL, NULL, NULL); + INSERT INTO x1 VALUES(NULL, NULL, NULL); + INSERT INTO x1 VALUES(NULL, NULL, NULL); + INSERT INTO x1 VALUES(NULL, NULL, NULL); +} + +do_intck_test 3.4 { +} + +imposter_edit x1 { + CREATE TABLE imp(a, b, c); +} { + DELETE FROM imp WHERE 1; + INSERT INTO imp(rowid) VALUES(-123); + INSERT INTO imp(rowid) VALUES(456); +} + +db close +sqlite3 db test.db + +do_intck_test 3.5 { + {entry (NULL,NULL,NULL,-123) missing from index x1all} + {entry (NULL,NULL,NULL,456) missing from index x1all} + {surplus entry (NULL,NULL,NULL,1) in index x1all} + {surplus entry (NULL,NULL,NULL,2) in index x1all} + {surplus entry (NULL,NULL,NULL,3) in index x1all} + {surplus entry (NULL,NULL,NULL,4) in index x1all} +} + +reset_db + +do_execsql_test 3.6 { + CREATE TABLE w1(a PRIMARY KEY, b, c); + INSERT INTO w1 VALUES(1.0, NULL, NULL); + INSERT INTO w1 VALUES(33.0, NULL, NULL); + INSERT INTO w1 VALUES(100.0, NULL, NULL); + CREATE INDEX w1bc ON w1(b, c); +} + +do_intck_test 3.7 { +} + +imposter_edit w1 { + CREATE TABLE imp(a, b, c); +} { + DELETE FROM imp WHERE a=33; + INSERT INTO imp(a) VALUES(1234.5); + INSERT INTO imp(a) VALUES(-1234.5); +} + +do_intck_test 3.8 { + {surplus entry (33.0,2) in index sqlite_autoindex_w1_1} + {entry (1234.5,4) missing from index sqlite_autoindex_w1_1} + {entry (NULL,NULL,4) missing from index w1bc} + {entry (-1234.5,5) missing from index sqlite_autoindex_w1_1} + {entry (NULL,NULL,5) missing from index w1bc} + {surplus entry (NULL,NULL,2) in index w1bc} +} + +finish_test diff --git a/ext/intck/intck_common.tcl b/ext/intck/intck_common.tcl new file mode 100644 index 0000000..1e216b5 --- /dev/null +++ b/ext/intck/intck_common.tcl @@ -0,0 +1,66 @@ +# 2024 Feb 18 +# +# 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. +# +#*********************************************************************** +# + +if {![info exists testdir]} { + set testdir [file join [file dirname [info script]] .. .. test] +} +source $testdir/tester.tcl + +ifcapable !vtab||!pragma { + proc return_if_no_intck {} { + finish_test + return -code return + } + return +} else { + proc return_if_no_intck {} {} +} + +proc do_intck {db {bSuspend 0}} { + set ic [sqlite3_intck $db main] + + set ret [list] + while {"SQLITE_OK"==[$ic step]} { + set msg [$ic message] + if {$msg!=""} { + lappend ret $msg + } + if {$bSuspend} { + $ic unlock + #puts "SQL: [$ic test_sql {}]" + #execsql_pp "EXPLAIN query plan [$ic test_sql {}]" + #explain_i [$ic test_sql {}] + } + } + + set err [$ic error] + if {[lindex $err 0]!="SQLITE_OK"} { + error $err + } + $ic close + + return $ret +} + +proc intck_sql {db tbl} { + set ic [sqlite3_intck $db main] + set sql [$ic test_sql $tbl] + $ic close + return $sql +} + +proc do_intck_test {tn expect} { + uplevel [list do_test $tn.a [list do_intck db] [list {*}$expect]] + uplevel [list do_test $tn.b [list do_intck db 1] [list {*}$expect]] +} + + diff --git a/ext/intck/intckbusy.test b/ext/intck/intckbusy.test new file mode 100644 index 0000000..7c65b68 --- /dev/null +++ b/ext/intck/intckbusy.test @@ -0,0 +1,49 @@ +# 2024 February 24 +# +# 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. +# +#*********************************************************************** +# + +source [file join [file dirname [info script]] intck_common.tcl] +set testprefix intckbusy +return_if_no_intck + + + +do_execsql_test 1.0 { + CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c); + INSERT INTO t1 VALUES(1, 2, 3); + INSERT INTO t1 VALUES(2, 'two', 'three'); + INSERT INTO t1 VALUES(3, NULL, NULL); + CREATE INDEX i1 ON t1(b, c); +} + +sqlite3 db2 test.db + +do_execsql_test -db db2 1.1 { + BEGIN EXCLUSIVE; + INSERT INTO t1 VALUES(4, 5, 6); +} + +do_test 1.2 { + set ic [sqlite3_intck db main] + $ic step +} {SQLITE_BUSY} +do_test 1.3 { + $ic unlock +} {SQLITE_BUSY} +do_test 1.4 { + $ic error +} {SQLITE_BUSY {database is locked}} +do_test 1.4 { + $ic close +} {} + +finish_test + diff --git a/ext/intck/intckcorrupt.test b/ext/intck/intckcorrupt.test new file mode 100644 index 0000000..eee63b3 --- /dev/null +++ b/ext/intck/intckcorrupt.test @@ -0,0 +1,236 @@ +# 2024 Feb 21 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# +# The focus of this file is testing the intck extensions response +# to corruption at the b-tree level. +# + +source [file join [file dirname [info script]] intck_common.tcl] +set testprefix intckcorrupt +return_if_no_intck + +#------------------------------------------------------------------------- +reset_db +do_test 1.0 { + sqlite3 db {} + db deserialize [decode_hexdb { +| size 356352 pagesize 4096 filename crash-acaae0347204ae.db +| page 1 offset 0 +| 0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00 SQLite format 3. +| 16: 10 00 01 01 00 40 20 20 00 00 00 00 d0 00 00 00 .....@ ........ +| 32: 40 00 ea 00 00 00 00 00 00 40 00 00 00 40 00 00 @........@...@.. +| 96: 00 00 00 00 0d 00 00 00 04 0e 9c 00 0f ad 0f 4f ...............O +| 112: 0e fc 0e 9c 00 00 00 00 00 00 00 00 00 00 00 00 ................ +| 3728: 00 00 00 00 00 00 00 00 00 00 00 00 5e 04 07 17 ............^... +| 3744: 1f 1f 01 81 0b 74 61 62 6c 65 74 31 5f 70 61 72 .....tablet1_par +| 3760: 65 6e 74 74 31 5f 70 61 72 65 6e 74 04 43 52 45 entt1_parent.CRE +| 3776: 41 54 45 20 54 41 42 4c 45 20 22 74 31 5f 70 61 ATE TABLE .t1_pa +| 3792: 72 65 6e 74 22 28 6e 6f 64 65 6e 6f 20 49 4e 54 rent.(nodeno INT +| 3808: 45 47 45 52 20 50 52 49 4d 41 52 59 20 4b 45 59 EGER PRIMARY KEY +| 3824: 2c 70 61 72 65 6e 74 6e 6f 64 65 29 51 03 06 17 ,parentnode)Q... +| 3840: 1b 1b 01 7b 74 61 62 6c 65 74 31 5f 6e 6f 64 65 ....tablet1_node +| 3856: 74 31 5f 6e 6f 64 65 03 43 52 45 41 54 45 20 54 t1_node.CREATE T +| 3872: 41 42 4c 45 20 22 74 31 5f 6e 6f 64 65 22 28 6e ABLE .t1_node.(n +| 3888: 6f 64 65 6e 6f 20 49 4e 54 45 47 45 52 20 50 52 odeno INTEGER PR +| 3904: 49 4d 41 52 59 20 4b 45 59 2c 64 61 74 61 29 5c IMARY KEY,data). +| 3920: 02 07 17 1d 1d 01 81 0b 74 61 62 6c 65 74 31 5f ........tablet1_ +| 3936: 72 6f 77 69 64 74 31 5f 72 6f 77 69 64 02 43 52 rowidt1_rowid.CR +| 3952: 45 41 54 45 20 54 41 42 4c 45 20 22 74 31 5f 72 EATE TABLE .t1_r +| 3968: 6f 77 69 64 22 28 72 6f 77 69 64 20 49 4e 54 45 owid.(rowid INTE +| 3984: 47 45 52 20 50 52 49 4d 41 52 59 20 4b 45 59 2c GER PRIMARY KEY, +| 4000: 6e 6f 64 65 6e 6f 2c 61 30 2c 61 31 29 51 01 07 nodeno,a0,a1)Q.. +| 4016: 17 11 11 08 81 0f 74 61 62 6c 65 74 31 74 31 43 ......tablet1t1C +| 4032: 52 45 41 54 45 20 56 49 52 54 55 41 4c 20 54 41 REATE VIRTUAL TA +| 4048: 42 4c 45 20 74 31 20 55 53 49 4e 47 20 72 74 72 BLE t1 USING rtr +| 4064: 65 65 28 69 64 2c 78 30 20 50 52 49 4d 41 52 59 ee(id,x0 PRIMARY +| 4080: 20 4b 45 59 2c 70 61 72 65 6e 74 6e 6f 64 65 29 KEY,parentnode) +| page 2 offset 4096 +| 0: 51 03 06 17 1b 1b 01 7b 74 61 62 6c 65 74 31 5f Q.......tablet1_ +| 16: 6e 6f 64 65 74 31 5f 6e 6f 64 65 03 43 52 45 41 nodet1_node.CREA +| 32: 54 45 20 54 41 42 4c 45 20 22 74 31 5f 6e 6f 64 TE TABLE .t1_nod +| 48: 65 22 28 6e 6f 64 65 6e 6f 20 49 4e 54 45 47 45 e.(nodeno INTEGE +| 64: 52 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 64 61 R PRIMARY KEY,da +| 80: 74 61 29 5c 02 07 17 1d 1d 01 81 0b 74 61 62 6c ta).........tabl +| 96: 65 74 31 5f 72 6f 77 69 64 74 31 5f 72 6f 77 69 et1_rowidt1_rowi +| 112: 64 02 43 52 45 41 54 45 20 54 41 42 4c 45 00 00 d.CREATE TABLE.. +| 128: 01 0a 02 00 00 00 01 0e 0d 00 00 00 00 24 0e 0d .............$.. +| 144: 0c 1a 06 85 50 46 60 27 70 08 00 00 00 00 00 00 ....PF`'p....... +| 3824: 00 00 00 00 00 00 00 0d 0e 05 00 09 1d 00 74 6f ..............to +| 3840: 79 20 68 61 6c 66 10 0d 05 00 09 23 00 62 6f 74 y half.....#.bot +| 3856: 74 6f 6d 20 68 61 6c 66 0f 0c 05 00 09 21 00 72 tom half.....!.r +| 3872: 69 67 68 74 20 68 61 6c 66 0e 0b 05 00 09 1f 00 ight half....... +| 3888: 6c 65 66 74 20 43 15 f6 e6 f6 46 50 34 35 24 54 left C....FP45$T +| 3904: 15 44 52 05 44 14 24 c4 52 02 27 43 15 f6 e6 f6 .DR.D.$.R.'C.... +| 3920: 46 52 22 8e 6f 64 65 6e 6f 20 49 4e 54 45 47 45 FR..odeno INTEGE +| 3936: 52 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 64 61 R PRIMARY KEY,da +| 3952: 74 61 29 5c 02 07 17 1d 1d 01 81 0b 74 61 62 6c ta).........tabl +| 3968: 65 74 31 5f 72 6f 74 74 6f 6d 20 65 64 67 65 0f et1_rottom edge. +| 3984: 07 05 00 09 21 00 72 69 67 68 74 20 65 64 67 65 ....!.right edge +| 4000: 0e 06 05 00 09 1f 00 6c 65 66 74 20 65 64 67 65 .......left edge +| 4016: 0b 05 05 00 09 19 00 63 65 6e 74 65 72 17 04 05 .......center... +| 4032: 00 09 31 00 75 70 70 65 72 2d 72 69 67 68 74 20 ..1.upper-right +| 4048: 63 6f 72 6e 65 72 17 03 05 00 09 31 00 6c 6f 77 corner.....1.low +| 4064: 65 72 2d 72 69 67 68 74 20 63 6f 72 6e 65 72 16 er-right corner. +| 4080: 02 05 00 09 2f 00 75 70 70 65 72 2d 6c 65 66 74 ..../.upper-left +| page 3 offset 8192 +| 0: 20 63 6f 72 6e 65 72 16 01 05 00 09 2f 01 8c 6f corner...../..o +| 16: 77 65 72 2d 6c 53 51 4c 69 74 65 20 66 6f 72 6d wer-lSQLite form +| 32: 61 74 20 33 00 10 00 01 01 00 40 20 20 00 00 00 at 3......@ ... +| 48: 00 00 00 00 2f 00 00 0d eb 13 00 00 00 03 00 00 ..../........... +| 64: 00 04 00 00 00 00 00 00 00 06 00 00 00 01 00 00 ................ +| 80: 00 00 00 00 00 01 00 00 00 00 00 00 00 00 00 00 ................ +| page 6 offset 20480 +| 128: 00 00 00 00 00 00 00 00 97 3d 04 ae 7c 01 00 00 .........=..|... +| 624: 00 00 00 00 00 00 21 97 3d 04 ae 7c 01 00 00 00 ......!.=..|.... +| 1120: 00 00 00 00 00 20 97 3d 04 ae 7c 01 00 00 00 00 ..... .=..|..... +| 1616: 00 00 00 00 1f 97 3d 04 ae 7c 01 00 00 00 00 00 ......=..|...... +| 2112: 00 00 00 1e 97 3d 04 ae 7c 01 00 00 00 00 00 00 .....=..|....... +| 2608: 00 00 1d 97 d3 d0 4a e7 c0 00 00 00 00 00 00 00 ......J......... +| 3088: 00 00 00 00 00 00 00 00 00 00 00 00 01 f3 00 00 ................ +| 3600: 23 97 3d 04 ae 7c 01 00 00 00 00 00 00 00 00 00 #.=..|.......... +| 4080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 26 ...............& +| page 8 offset 28672 +| 0: 0d 00 00 00 01 04 30 00 04 30 00 00 00 00 00 00 ......0..0...... +| 1072: 97 4d 1e 14 00 ae 7c 00 00 00 00 00 00 00 00 00 .M....|......... +| 1088: 00 00 00 00 00 00 01 00 00 00 00 00 00 00 00 00 ................ +| 4080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 03 ................ +| page 10 offset 36864 +| 0: 0d 00 00 00 01 04 30 00 04 30 00 00 00 00 00 00 ......0..0...... +| 1072: 9a ee c1 80 fd 78 1f ce 1b ae eb b4 00 00 00 00 .....x.......... +| 1088: 13 20 ff 20 00 70 00 00 00 60 50 00 00 00 11 e0 . . .p...`P..... +| 1104: 00 00 00 70 00 00 00 60 50 05 35 14 c6 97 46 52 ...p...`P.5...FR +| 1120: 06 66 f7 26 d6 17 42 03 30 01 00 00 10 10 04 02 .f.&..B.0....... +| 1136: 02 00 00 00 00 00 00 00 00 40 00 00 00 00 00 00 .........@...... +| 1152: 00 00 00 00 00 40 00 00 00 40 00 00 00 00 00 00 .....@...@...... +| 4080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 05 ................ +| page 12 offset 45056 +| 0: 0d 00 00 00 01 04 30 00 04 30 e1 b4 30 97 4d 46 ......0..0..0.MF +| 16: 14 00 ae 7c 00 00 00 00 00 00 00 03 00 00 43 00 ...|..........C. +| page 47 offset 188416 +| 2512: 00 00 00 00 00 00 00 00 be 00 00 00 00 00 00 00 ................ +| page 87 offset 352256 +| 2512: 00 00 00 00 00 00 00 00 aa 00 00 00 00 00 00 00 ................ +| end crash-acaae0347204ae.db +}]} {} + +do_intck_test 1.1 { + {corruption found while reading database schema} +} + +#------------------------------------------------------------------------- +reset_db +do_test 2.0 { + sqlite3 db {} + db deserialize [decode_hexdb { +| size 28672 pagesize 4096 filename crash-3afa1ca9e9c1bd.db +| page 1 offset 0 +| 0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00 SQLite format 3. +| 16: 10 00 01 01 00 40 20 20 00 00 00 00 00 00 00 07 .....@ ........ +| 32: 00 00 00 00 00 00 00 00 00 00 00 06 00 00 00 04 ................ +| 48: 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00 ................ +| 96: 00 00 00 00 0d 00 00 00 06 0e 88 00 0f b8 0f 6d ...............m +| 112: 0f 3a 0f 0b 0e d5 0e 88 01 00 00 00 00 00 00 00 .:.............. +| 3712: 00 00 00 00 00 00 00 00 4b 06 06 17 25 25 01 5b ........K...%%.[ +| 3728: 74 61 62 6c 65 73 71 6c 69 74 65 5f 73 74 61 74 tablesqlite_stat +| 3744: 31 73 71 6c 69 74 65 5f 73 74 61 74 31 07 43 52 1sqlite_stat1.CR +| 3760: 45 41 54 45 20 54 41 42 4c 45 20 73 71 6c 69 74 EATE TABLE sqlit +| 3776: 65 5f 73 74 61 74 31 28 74 62 6c 2c 69 64 78 2c e_stat1(tbl,idx, +| 3792: 73 74 61 74 29 34 05 06 17 13 11 01 53 69 6e 64 stat)4......Sind +| 3808: 65 78 63 31 63 63 31 06 43 52 45 41 54 45 20 55 exc1cc1.CREATE U +| 3824: 4e 49 51 55 45 20 49 4e 44 45 58 20 63 31 63 20 NIQUE INDEX c1c +| 3840: 4f 4e 20 63 31 28 63 2c 20 62 29 2d 04 06 17 13 ON c1(c, b)-.... +| 3856: 11 01 45 69 6e 64 65 78 63 31 64 63 31 05 43 52 ..Eindexc1dc1.CR +| 3872: 45 41 54 45 20 49 4e 44 45 58 20 63 31 64 20 4f EATE INDEX c1d O +| 3888: 4e 20 63 31 28 64 2c 20 62 29 31 03 06 17 13 11 N c1(d, b)1..... +| 3904: 01 4d 69 6e 64 65 78 62 31 63 62 31 05 43 52 45 .Mindexb1cb1.CRE +| 3920: 41 54 45 20 55 4e 49 51 55 45 20 49 4e 44 45 58 ATE UNIQUE INDEX +| 3936: 20 62 31 63 20 4f 4e 20 62 31 28 63 29 49 02 06 b1c ON b1(c)I.. +| 3952: 17 11 11 0f 7f 74 61 62 6c 65 63 31 63 31 03 43 .....tablec1c1.C +| 3968: 52 45 41 54 45 20 54 41 42 4c 45 20 63 31 28 61 REATE TABLE c1(a +| 3984: 20 49 4e 54 20 50 52 49 4d 41 52 59 20 4b 45 59 INT PRIMARY KEY +| 4000: 2c 20 62 2c 20 63 2c 20 64 29 20 57 49 54 48 4f , b, c, d) WITHO +| 4016: 55 54 20 52 4f 57 49 44 46 01 06 17 11 11 01 79 UT ROWIDF......y +| 4032: 74 61 62 6c 65 62 31 62 31 02 43 52 45 41 54 45 tableb1b1.CREATE +| 4048: 20 54 41 42 4c 45 20 62 31 28 61 20 49 4e 54 20 TABLE b1(a INT +| 4064: 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 62 2c 20 PRIMARY KEY, b, +| 4080: 63 29 20 57 49 54 48 4f 55 54 20 52 4f 57 49 44 c) WITHOUT ROWID +| page 2 offset 4096 +| 0: 0a 00 00 00 07 0f ca 00 0f fa 0f f2 0f ea 0f e2 ................ +| 16: 0f da 00 00 00 01 00 00 00 00 00 00 00 00 00 00 ................ +| 4032: 00 00 00 00 00 00 00 00 00 00 07 04 01 0f 01 06 ................ +| 4048: 67 07 07 04 01 0f 01 06 66 06 07 04 01 0f 01 05 g.......f....... +| 4064: 65 05 07 04 01 0f 01 04 64 04 07 04 01 0f 01 03 e.......d....... +| 4080: 63 03 07 04 01 0f 01 02 62 0f 05 04 09 0f 09 61 c.......b......a +| page 3 offset 8192 +| 0: 0a 00 00 00 07 0f bd 00 0f f9 0f ef 0f e5 0f db ................ +| 16: 0f d1 0f c7 0f bd 00 00 00 00 01 00 00 00 00 00 ................ +| 4016: 00 00 00 00 00 00 00 00 00 00 00 00 00 09 05 01 ................ +| 4032: 0f 01 01 07 61 07 07 09 05 01 0f 01 01 06 61 06 ....a.........a. +| 4048: 06 09 05 01 0f 01 01 05 61 05 05 09 05 01 0f 01 ........a....... +| 4064: 01 04 61 04 04 09 05 01 0f 01 01 03 61 03 03 09 ..a.........a... +| 4080: 05 01 0f 01 01 02 61 0f 02 06 05 09 0f 09 09 61 ......a........a +| page 4 offset 12288 +| 0: 0a 00 00 00 07 0f d8 00 0f fc 0f f0 0f ea 0f e4 ................ +| 16: 0f de 0f d8 0f f6 00 00 00 00 00 00 00 00 00 00 ................ +| 4048: 00 00 00 00 00 00 00 00 05 03 01 01 07 07 05 03 ................ +| 4064: 01 01 06 06 05 03 01 01 05 05 05 03 01 01 04 04 ................ +| 4080: 05 03 01 01 03 03 05 03 01 01 0f 02 03 03 09 09 ................ +| page 5 offset 16384 +| 0: 0a 00 00 00 07 0f ca 00 0f fa 0f f2 0f ea 0f 00 ................ +| 4032: 00 00 00 00 00 00 00 00 00 00 07 04 01 0f 01 07 ................ +| 4048: 61 07 07 04 01 0f 01 06 61 06 07 04 01 0f 01 05 a.......a....... +| 4064: 61 05 07 04 01 1f 01 04 61 04 07 04 01 0f 01 03 a.......a....... +| 4080: 61 03 07 04 01 0f 01 02 61 02 05 04 09 0f 09 61 a.......a......a +| page 6 offset 20480 +| 0: 0a 00 00 00 07 0f ca 00 0f fa 0f ea 0f e2 00 00 ................ +| 4032: 00 00 00 00 00 00 00 00 00 00 07 04 01 0f 01 07 ................ +| 4048: 61 07 07 04 01 0f 01 06 61 06 07 04 01 0f 01 05 a.......a....... +| 4064: 61 05 07 04 01 0f 01 04 61 04 07 04 01 0f 01 03 a.......a....... +| 4080: 61 03 07 04 01 0f 01 0f 61 02 05 04 09 0f 09 61 a.......a......a +| page 7 offset 24576 +| 0: 0d 00 00 00 05 0f 1c 00 0f f0 0f e0 0f d3 0f c5 ................ +| 16: 0f b8 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ +| 4016: 00 00 00 00 00 00 00 00 0b 05 04 11 11 13 62 31 ..............b1 +| 4032: 62 31 37 20 31 0c 04 04 11 13 13 62 31 62 31 63 b17 1......b1b1c +| 4048: 37 20 31 0b 03 04 11 11 13 63 31 63 31 37 20 31 7 1......c1c17 1 +| 4064: 0e 02 04 11 13 07 63 31 63 31 64 37 20 31 20 31 ......c1c1d7 1 1 +| 4080: 0e 01 04 11 13 17 63 31 63 31 63 37 20 31 00 00 ......c1c1c7 1.. +| end crash-3afa1ca9e9c1bd.db +}]} {} + +do_intck_test 2.1 { + {corruption found while reading database schema} +} + +#------------------------------------------------------------------------- +reset_db +do_execsql_test 3.0 { + PRAGMA page_size = 1024; + CREATE TABLE t1(a, b); + CREATE INDEX i1 ON t1(a); + INSERT INTO t1 VALUES(1, 1), (2, 2), (3, 3); +} + +do_test 3.1 { + set pgno [db one {SELECT rootpage FROM sqlite_schema WHERE name='t1'}] + db close + hexio_write test.db [expr ($pgno-1)*1024] 0000 +} {2} + +sqlite3 db test.db +do_intck_test 3.2 { + {corruption found while scanning database object i1} + {corruption found while scanning database object t1} +} + +finish_test + + diff --git a/ext/intck/intckfault.test b/ext/intck/intckfault.test new file mode 100644 index 0000000..0bc06e5 --- /dev/null +++ b/ext/intck/intckfault.test @@ -0,0 +1,42 @@ +# 2024 February 24 +# +# 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. +# +#*********************************************************************** +# + +source [file join [file dirname [info script]] intck_common.tcl] +set testprefix intckfault +return_if_no_intck + +do_execsql_test 1.0 { + CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c); + INSERT INTO t1 VALUES(1, 2, 3); + INSERT INTO t1 VALUES(2, 'two', 'three'); + INSERT INTO t1 VALUES(3, NULL, NULL); + CREATE INDEX i1 ON t1(b, c); +} + +do_faultsim_test 1 -faults oom-t* -prep { +} -body { + set ::ic [sqlite3_intck db main] + set nStep 0 + while {"SQLITE_OK"==[$::ic step]} { + incr nStep + if {$nStep==3} { $::ic unlock } + } + set res [$::ic error] + $::ic close + set res +} -test { + catch { $::ic close } + faultsim_test_result {0 {SQLITE_OK {}}} {0 {SQLITE_NOMEM {}}} {0 {SQLITE_NOMEM {out of memory}}} +} + +finish_test + diff --git a/ext/intck/sqlite3intck.c b/ext/intck/sqlite3intck.c new file mode 100644 index 0000000..ed169a2 --- /dev/null +++ b/ext/intck/sqlite3intck.c @@ -0,0 +1,940 @@ +/* +** 2024-02-08 +** +** 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. +** +************************************************************************* +*/ + +#include "sqlite3intck.h" +#include <string.h> +#include <assert.h> + +#include <stdio.h> +#include <stdlib.h> + +/* +** nKeyVal: +** The number of values that make up the 'key' for the current pCheck +** statement. +** +** rc: +** Error code returned by most recent sqlite3_intck_step() or +** sqlite3_intck_unlock() call. This is set to SQLITE_DONE when +** the integrity-check operation is finished. +** +** zErr: +** If the object has entered the error state, this is the error message. +** Is freed using sqlite3_free() when the object is deleted. +** +** zTestSql: +** The value returned by the most recent call to sqlite3_intck_testsql(). +** Each call to testsql() frees the previous zTestSql value (using +** sqlite3_free()) and replaces it with the new value it will return. +*/ +struct sqlite3_intck { + sqlite3 *db; + const char *zDb; /* Copy of zDb parameter to _open() */ + char *zObj; /* Current object. Or NULL. */ + + sqlite3_stmt *pCheck; /* Current check statement */ + char *zKey; + int nKeyVal; + + char *zMessage; + int bCorruptSchema; + + int rc; /* Error code */ + char *zErr; /* Error message */ + char *zTestSql; /* Returned by sqlite3_intck_test_sql() */ +}; + + +/* +** Some error has occurred while using database p->db. Save the error message +** and error code currently held by the database handle in p->rc and p->zErr. +*/ +static void intckSaveErrmsg(sqlite3_intck *p){ + p->rc = sqlite3_errcode(p->db); + sqlite3_free(p->zErr); + p->zErr = sqlite3_mprintf("%s", sqlite3_errmsg(p->db)); +} + +/* +** If the handle passed as the first argument is already in the error state, +** then this function is a no-op (returns NULL immediately). Otherwise, if an +** error occurs within this function, it leaves an error in said handle. +** +** Otherwise, this function attempts to prepare SQL statement zSql and +** return the resulting statement handle to the user. +*/ +static sqlite3_stmt *intckPrepare(sqlite3_intck *p, const char *zSql){ + sqlite3_stmt *pRet = 0; + if( p->rc==SQLITE_OK ){ + p->rc = sqlite3_prepare_v2(p->db, zSql, -1, &pRet, 0); + if( p->rc!=SQLITE_OK ){ + intckSaveErrmsg(p); + assert( pRet==0 ); + } + } + return pRet; +} + +/* +** If the handle passed as the first argument is already in the error state, +** then this function is a no-op (returns NULL immediately). Otherwise, if an +** error occurs within this function, it leaves an error in said handle. +** +** Otherwise, this function treats argument zFmt as a printf() style format +** string. It formats it according to the trailing arguments and then +** attempts to prepare the results and return the resulting prepared +** statement. +*/ +static sqlite3_stmt *intckPrepareFmt(sqlite3_intck *p, const char *zFmt, ...){ + sqlite3_stmt *pRet = 0; + va_list ap; + char *zSql = 0; + va_start(ap, zFmt); + zSql = sqlite3_vmprintf(zFmt, ap); + if( p->rc==SQLITE_OK && zSql==0 ){ + p->rc = SQLITE_NOMEM; + } + pRet = intckPrepare(p, zSql); + sqlite3_free(zSql); + va_end(ap); + return pRet; +} + +/* +** Finalize SQL statement pStmt. If an error occurs and the handle passed +** as the first argument does not already contain an error, store the +** error in the handle. +*/ +static void intckFinalize(sqlite3_intck *p, sqlite3_stmt *pStmt){ + int rc = sqlite3_finalize(pStmt); + if( p->rc==SQLITE_OK && rc!=SQLITE_OK ){ + intckSaveErrmsg(p); + } +} + +/* +** If there is already an error in handle p, return it. Otherwise, call +** sqlite3_step() on the statement handle and return that value. +*/ +static int intckStep(sqlite3_intck *p, sqlite3_stmt *pStmt){ + if( p->rc ) return p->rc; + return sqlite3_step(pStmt); +} + +/* +** Execute SQL statement zSql. There is no way to obtain any results +** returned by the statement. This function uses the sqlite3_intck error +** code convention. +*/ +static void intckExec(sqlite3_intck *p, const char *zSql){ + sqlite3_stmt *pStmt = 0; + pStmt = intckPrepare(p, zSql); + intckStep(p, pStmt); + intckFinalize(p, pStmt); +} + +/* +** A wrapper around sqlite3_mprintf() that uses the sqlite3_intck error +** code convention. +*/ +static char *intckMprintf(sqlite3_intck *p, const char *zFmt, ...){ + va_list ap; + char *zRet = 0; + va_start(ap, zFmt); + zRet = sqlite3_vmprintf(zFmt, ap); + if( p->rc==SQLITE_OK ){ + if( zRet==0 ){ + p->rc = SQLITE_NOMEM; + } + }else{ + sqlite3_free(zRet); + zRet = 0; + } + return zRet; +} + +/* +** This is used by sqlite3_intck_unlock() to save the vector key value +** required to restart the current pCheck query as a nul-terminated string +** in p->zKey. +*/ +static void intckSaveKey(sqlite3_intck *p){ + int ii; + char *zSql = 0; + sqlite3_stmt *pStmt = 0; + sqlite3_stmt *pXinfo = 0; + const char *zDir = 0; + + assert( p->pCheck ); + assert( p->zKey==0 ); + + pXinfo = intckPrepareFmt(p, + "SELECT group_concat(desc, '') FROM %Q.sqlite_schema s, " + "pragma_index_xinfo(%Q, %Q) " + "WHERE s.type='index' AND s.name=%Q", + p->zDb, p->zObj, p->zDb, p->zObj + ); + if( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pXinfo) ){ + zDir = (const char*)sqlite3_column_text(pXinfo, 0); + } + + if( zDir==0 ){ + /* Object is a table, not an index. This is the easy case,as there are + ** no DESC columns or NULL values in a primary key. */ + const char *zSep = "SELECT '(' || "; + for(ii=0; ii<p->nKeyVal; ii++){ + zSql = intckMprintf(p, "%z%squote(?)", zSql, zSep); + zSep = " || ', ' || "; + } + zSql = intckMprintf(p, "%z || ')'", zSql); + }else{ + + /* Object is an index. */ + assert( p->nKeyVal>1 ); + for(ii=p->nKeyVal; ii>0; ii--){ + int bLastIsDesc = zDir[ii-1]=='1'; + int bLastIsNull = sqlite3_column_type(p->pCheck, ii)==SQLITE_NULL; + const char *zLast = sqlite3_column_name(p->pCheck, ii); + char *zLhs = 0; + char *zRhs = 0; + char *zWhere = 0; + + if( bLastIsNull ){ + if( bLastIsDesc ) continue; + zWhere = intckMprintf(p, "'%s IS NOT NULL'", zLast); + }else{ + const char *zOp = bLastIsDesc ? "<" : ">"; + zWhere = intckMprintf(p, "'%s %s ' || quote(?%d)", zLast, zOp, ii); + } + + if( ii>1 ){ + const char *zLhsSep = ""; + const char *zRhsSep = ""; + int jj; + for(jj=0; jj<ii-1; jj++){ + const char *zAlias = (const char*)sqlite3_column_name(p->pCheck,jj+1); + zLhs = intckMprintf(p, "%z%s%s", zLhs, zLhsSep, zAlias); + zRhs = intckMprintf(p, "%z%squote(?%d)", zRhs, zRhsSep, jj+1); + zLhsSep = ","; + zRhsSep = " || ',' || "; + } + + zWhere = intckMprintf(p, + "'(%z) IS (' || %z || ') AND ' || %z", + zLhs, zRhs, zWhere); + } + zWhere = intckMprintf(p, "'WHERE ' || %z", zWhere); + + zSql = intckMprintf(p, "%z%s(quote( %z ) )", + zSql, + (zSql==0 ? "VALUES" : ",\n "), + zWhere + ); + } + zSql = intckMprintf(p, + "WITH wc(q) AS (\n%z\n)" + "SELECT 'VALUES' || group_concat('(' || q || ')', ',\n ') FROM wc" + , zSql + ); + } + + pStmt = intckPrepare(p, zSql); + if( p->rc==SQLITE_OK ){ + for(ii=0; ii<p->nKeyVal; ii++){ + sqlite3_bind_value(pStmt, ii+1, sqlite3_column_value(p->pCheck, ii+1)); + } + if( SQLITE_ROW==sqlite3_step(pStmt) ){ + p->zKey = intckMprintf(p,"%s",(const char*)sqlite3_column_text(pStmt, 0)); + } + intckFinalize(p, pStmt); + } + + sqlite3_free(zSql); + intckFinalize(p, pXinfo); +} + +/* +** Find the next database object (table or index) to check. If successful, +** set sqlite3_intck.zObj to point to a nul-terminated buffer containing +** the object's name before returning. +*/ +static void intckFindObject(sqlite3_intck *p){ + sqlite3_stmt *pStmt = 0; + char *zPrev = p->zObj; + p->zObj = 0; + + assert( p->rc==SQLITE_OK ); + assert( p->pCheck==0 ); + + pStmt = intckPrepareFmt(p, + "WITH tables(table_name) AS (" + " SELECT name" + " FROM %Q.sqlite_schema WHERE (type='table' OR type='index') AND rootpage" + " UNION ALL " + " SELECT 'sqlite_schema'" + ")" + "SELECT table_name FROM tables " + "WHERE ?1 IS NULL OR table_name%s?1 " + "ORDER BY 1" + , p->zDb, (p->zKey ? ">=" : ">") + ); + + if( p->rc==SQLITE_OK ){ + sqlite3_bind_text(pStmt, 1, zPrev, -1, SQLITE_TRANSIENT); + if( sqlite3_step(pStmt)==SQLITE_ROW ){ + p->zObj = intckMprintf(p,"%s",(const char*)sqlite3_column_text(pStmt, 0)); + } + } + intckFinalize(p, pStmt); + + /* If this is a new object, ensure the previous key value is cleared. */ + if( sqlite3_stricmp(p->zObj, zPrev) ){ + sqlite3_free(p->zKey); + p->zKey = 0; + } + + sqlite3_free(zPrev); +} + +/* +** Return the size in bytes of the first token in nul-terminated buffer z. +** For the purposes of this call, a token is either: +** +** * a quoted SQL string, +* * a contiguous series of ascii alphabet characters, or +* * any other single byte. +*/ +static int intckGetToken(const char *z){ + char c = z[0]; + int iRet = 1; + if( c=='\'' || c=='"' || c=='`' ){ + while( 1 ){ + if( z[iRet]==c ){ + iRet++; + if( z[iRet]!=c ) break; + } + iRet++; + } + } + else if( c=='[' ){ + while( z[iRet++]!=']' && z[iRet] ); + } + else if( (c>='A' && c<='Z') || (c>='a' && c<='z') ){ + while( (z[iRet]>='A' && z[iRet]<='Z') || (z[iRet]>='a' && z[iRet]<='z') ){ + iRet++; + } + } + + return iRet; +} + +/* +** Return true if argument c is an ascii whitespace character. +*/ +static int intckIsSpace(char c){ + return (c==' ' || c=='\t' || c=='\n' || c=='\r'); +} + +/* +** Argument z points to the text of a CREATE INDEX statement. This function +** identifies the part of the text that contains either the index WHERE +** clause (if iCol<0) or the iCol'th column of the index. +** +** If (iCol<0), the identified fragment does not include the "WHERE" keyword, +** only the expression that follows it. If (iCol>=0) then the identified +** fragment does not include any trailing sort-order keywords - "ASC" or +** "DESC". +** +** If the CREATE INDEX statement does not contain the requested field or +** clause, NULL is returned and (*pnByte) is set to 0. Otherwise, a pointer to +** the identified fragment is returned and output parameter (*pnByte) set +** to its size in bytes. +*/ +static const char *intckParseCreateIndex(const char *z, int iCol, int *pnByte){ + int iOff = 0; + int iThisCol = 0; + int iStart = 0; + int nOpen = 0; + + const char *zRet = 0; + int nRet = 0; + + int iEndOfCol = 0; + + /* Skip forward until the first "(" token */ + while( z[iOff]!='(' ){ + iOff += intckGetToken(&z[iOff]); + if( z[iOff]=='\0' ) return 0; + } + assert( z[iOff]=='(' ); + + nOpen = 1; + iOff++; + iStart = iOff; + while( z[iOff] ){ + const char *zToken = &z[iOff]; + int nToken = 0; + + /* Check if this is the end of the current column - either a "," or ")" + ** when nOpen==1. */ + if( nOpen==1 ){ + if( z[iOff]==',' || z[iOff]==')' ){ + if( iCol==iThisCol ){ + int iEnd = iEndOfCol ? iEndOfCol : iOff; + nRet = (iEnd - iStart); + zRet = &z[iStart]; + break; + } + iStart = iOff+1; + while( intckIsSpace(z[iStart]) ) iStart++; + iThisCol++; + } + if( z[iOff]==')' ) break; + } + if( z[iOff]=='(' ) nOpen++; + if( z[iOff]==')' ) nOpen--; + nToken = intckGetToken(zToken); + + if( (nToken==3 && 0==sqlite3_strnicmp(zToken, "ASC", nToken)) + || (nToken==4 && 0==sqlite3_strnicmp(zToken, "DESC", nToken)) + ){ + iEndOfCol = iOff; + }else if( 0==intckIsSpace(zToken[0]) ){ + iEndOfCol = 0; + } + + iOff += nToken; + } + + /* iStart is now the byte offset of 1 byte passed the final ')' in the + ** CREATE INDEX statement. Try to find a WHERE clause to return. */ + while( zRet==0 && z[iOff] ){ + int n = intckGetToken(&z[iOff]); + if( n==5 && 0==sqlite3_strnicmp(&z[iOff], "where", 5) ){ + zRet = &z[iOff+5]; + nRet = (int)strlen(zRet); + } + iOff += n; + } + + /* Trim any whitespace from the start and end of the returned string. */ + if( zRet ){ + while( intckIsSpace(zRet[0]) ){ + nRet--; + zRet++; + } + while( nRet>0 && intckIsSpace(zRet[nRet-1]) ) nRet--; + } + + *pnByte = nRet; + return zRet; +} + +/* +** User-defined SQL function wrapper for intckParseCreateIndex(): +** +** SELECT parse_create_index(<sql>, <icol>); +*/ +static void intckParseCreateIndexFunc( + sqlite3_context *pCtx, + int nVal, + sqlite3_value **apVal +){ + const char *zSql = (const char*)sqlite3_value_text(apVal[0]); + int idx = sqlite3_value_int(apVal[1]); + const char *zRes = 0; + int nRes = 0; + + assert( nVal==2 ); + if( zSql ){ + zRes = intckParseCreateIndex(zSql, idx, &nRes); + } + sqlite3_result_text(pCtx, zRes, nRes, SQLITE_TRANSIENT); +} + +/* +** Return true if sqlite3_intck.db has automatic indexes enabled, false +** otherwise. +*/ +static int intckGetAutoIndex(sqlite3_intck *p){ + int bRet = 0; + sqlite3_stmt *pStmt = 0; + pStmt = intckPrepare(p, "PRAGMA automatic_index"); + if( SQLITE_ROW==intckStep(p, pStmt) ){ + bRet = sqlite3_column_int(pStmt, 0); + } + intckFinalize(p, pStmt); + return bRet; +} + +/* +** Return true if zObj is an index, or false otherwise. +*/ +static int intckIsIndex(sqlite3_intck *p, const char *zObj){ + int bRet = 0; + sqlite3_stmt *pStmt = 0; + pStmt = intckPrepareFmt(p, + "SELECT 1 FROM %Q.sqlite_schema WHERE name=%Q AND type='index'", + p->zDb, zObj + ); + if( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){ + bRet = 1; + } + intckFinalize(p, pStmt); + return bRet; +} + +/* +** Return a pointer to a nul-terminated buffer containing the SQL statement +** used to check database object zObj (a table or index) for corruption. +** If parameter zPrev is not NULL, then it must be a string containing the +** vector key required to restart the check where it left off last time. +** If pnKeyVal is not NULL, then (*pnKeyVal) is set to the number of +** columns in the vector key value for the specified object. +** +** This function uses the sqlite3_intck error code convention. +*/ +static char *intckCheckObjectSql( + sqlite3_intck *p, /* Integrity check object */ + const char *zObj, /* Object (table or index) to scan */ + const char *zPrev, /* Restart key vector, if any */ + int *pnKeyVal /* OUT: Number of key-values for this scan */ +){ + char *zRet = 0; + sqlite3_stmt *pStmt = 0; + int bAutoIndex = 0; + int bIsIndex = 0; + + const char *zCommon = + /* Relation without_rowid also contains just one row. Column "b" is + ** set to true if the table being examined is a WITHOUT ROWID table, + ** or false otherwise. */ + ", without_rowid(b) AS (" + " SELECT EXISTS (" + " SELECT 1 FROM tabname, pragma_index_list(tab, db) AS l" + " WHERE origin='pk' " + " AND NOT EXISTS (SELECT 1 FROM sqlite_schema WHERE name=l.name)" + " )" + ")" + "" + /* Table idx_cols contains 1 row for each column in each index on the + ** table being checked. Columns are: + ** + ** idx_name: Name of the index. + ** idx_ispk: True if this index is the PK of a WITHOUT ROWID table. + ** col_name: Name of indexed column, or NULL for index on expression. + ** col_expr: Indexed expression, including COLLATE clause. + ** col_alias: Alias used for column in 'intck_wrapper' table. + */ + ", idx_cols(idx_name, idx_ispk, col_name, col_expr, col_alias) AS (" + " SELECT l.name, (l.origin=='pk' AND w.b), i.name, COALESCE((" + " SELECT parse_create_index(sql, i.seqno) FROM " + " sqlite_schema WHERE name = l.name" + " ), format('\"%w\"', i.name) || ' COLLATE ' || quote(i.coll))," + " 'c' || row_number() OVER ()" + " FROM " + " tabname t," + " without_rowid w," + " pragma_index_list(t.tab, t.db) l," + " pragma_index_xinfo(l.name) i" + " WHERE i.key" + " UNION ALL" + " SELECT '', 1, '_rowid_', '_rowid_', 'r1' FROM without_rowid WHERE b=0" + ")" + "" + "" + /* + ** For a PK declared as "PRIMARY KEY(a, b) ... WITHOUT ROWID", where + ** the intck_wrapper aliases of "a" and "b" are "c1" and "c2": + ** + ** o_pk: "o.c1, o.c2" + ** i_pk: "i.'a', i.'b'" + ** ... + ** n_pk: 2 + */ + ", tabpk(db, tab, idx, o_pk, i_pk, q_pk, eq_pk, ps_pk, pk_pk, n_pk) AS (" + " WITH pkfields(f, a) AS (" + " SELECT i.col_name, i.col_alias FROM idx_cols i WHERE i.idx_ispk" + " )" + " SELECT t.db, t.tab, t.idx, " + " group_concat(a, ', '), " + " group_concat('i.'||quote(f), ', '), " + " group_concat('quote(o.'||a||')', ' || '','' || '), " + " format('(%s)==(%s)'," + " group_concat('o.'||a, ', '), " + " group_concat(format('\"%w\"', f), ', ')" + " )," + " group_concat('%s', ',')," + " group_concat('quote('||a||')', ', '), " + " count(*)" + " FROM tabname t, pkfields" + ")" + "" + ", idx(name, match_expr, partial, partial_alias, idx_ps, idx_idx) AS (" + " SELECT idx_name," + " format('(%s,%s) IS (%s,%s)', " + " group_concat(i.col_expr, ', '), i_pk," + " group_concat('o.'||i.col_alias, ', '), o_pk" + " ), " + " parse_create_index(" + " (SELECT sql FROM sqlite_schema WHERE name=idx_name), -1" + " )," + " 'cond' || row_number() OVER ()" + " , group_concat('%s', ',')" + " , group_concat('quote('||i.col_alias||')', ', ')" + " FROM tabpk t, " + " without_rowid w," + " idx_cols i" + " WHERE i.idx_ispk==0 " + " GROUP BY idx_name" + ")" + "" + ", wrapper_with(s) AS (" + " SELECT 'intck_wrapper AS (\n SELECT\n ' || (" + " WITH f(a, b) AS (" + " SELECT col_expr, col_alias FROM idx_cols" + " UNION ALL " + " SELECT partial, partial_alias FROM idx WHERE partial IS NOT NULL" + " )" + " SELECT group_concat(format('%s AS %s', a, b), ',\n ') FROM f" + " )" + " || format('\n FROM %Q.%Q ', t.db, t.tab)" + /* If the object being checked is a table, append "NOT INDEXED". + ** Otherwise, append "INDEXED BY <index>", and then, if the index + ** is a partial index " WHERE <condition>". */ + " || CASE WHEN t.idx IS NULL THEN " + " 'NOT INDEXED'" + " ELSE" + " format('INDEXED BY %Q%s', t.idx, ' WHERE '||i.partial)" + " END" + " || '\n)'" + " FROM tabname t LEFT JOIN idx i ON (i.name=t.idx)" + ")" + "" + ; + + bAutoIndex = intckGetAutoIndex(p); + if( bAutoIndex ) intckExec(p, "PRAGMA automatic_index = 0"); + + bIsIndex = intckIsIndex(p, zObj); + if( bIsIndex ){ + pStmt = intckPrepareFmt(p, + /* Table idxname contains a single row. The first column, "db", contains + ** the name of the db containing the table (e.g. "main") and the second, + ** "tab", the name of the table itself. */ + "WITH tabname(db, tab, idx) AS (" + " SELECT %Q, (SELECT tbl_name FROM %Q.sqlite_schema WHERE name=%Q), %Q " + ")" + "" + ", whereclause(w_c) AS (%s)" + "" + "%s" /* zCommon */ + "" + ", case_statement(c) AS (" + " SELECT " + " 'CASE WHEN (' || group_concat(col_alias, ', ') || ', 1) IS (\n' " + " || ' SELECT ' || group_concat(col_expr, ', ') || ', 1 FROM '" + " || format('%%Q.%%Q NOT INDEXED WHERE %%s\n', t.db, t.tab, p.eq_pk)" + " || ' )\n THEN NULL\n '" + " || 'ELSE format(''surplus entry ('" + " || group_concat('%%s', ',') || ',' || p.ps_pk" + " || ') in index ' || t.idx || ''', ' " + " || group_concat('quote('||i.col_alias||')', ', ') || ', ' || p.pk_pk" + " || ')'" + " || '\n END AS error_message'" + " FROM tabname t, tabpk p, idx_cols i WHERE i.idx_name=t.idx" + ")" + "" + ", thiskey(k, n) AS (" + " SELECT group_concat(i.col_alias, ', ') || ', ' || p.o_pk, " + " count(*) + p.n_pk " + " FROM tabpk p, idx_cols i WHERE i.idx_name=p.idx" + ")" + "" + ", main_select(m, n) AS (" + " SELECT format(" + " 'WITH %%s\n' ||" + " ', idx_checker AS (\n' ||" + " ' SELECT %%s,\n' ||" + " ' %%s\n' || " + " ' FROM intck_wrapper AS o\n' ||" + " ')\n'," + " ww.s, c, t.k" + " ), t.n" + " FROM case_statement, wrapper_with ww, thiskey t" + ")" + + "SELECT m || " + " group_concat('SELECT * FROM idx_checker ' || w_c, ' UNION ALL '), n" + " FROM " + "main_select, whereclause " + , p->zDb, p->zDb, zObj, zObj + , zPrev ? zPrev : "VALUES('')", zCommon + ); + }else{ + pStmt = intckPrepareFmt(p, + /* Table tabname contains a single row. The first column, "db", contains + ** the name of the db containing the table (e.g. "main") and the second, + ** "tab", the name of the table itself. */ + "WITH tabname(db, tab, idx, prev) AS (SELECT %Q, %Q, NULL, %Q)" + "" + "%s" /* zCommon */ + + /* expr(e) contains one row for each index on table zObj. Value e + ** is set to an expression that evaluates to NULL if the required + ** entry is present in the index, or an error message otherwise. */ + ", expr(e, p) AS (" + " SELECT format('CASE WHEN EXISTS \n" + " (SELECT 1 FROM %%Q.%%Q AS i INDEXED BY %%Q WHERE %%s%%s)\n" + " THEN NULL\n" + " ELSE format(''entry (%%s,%%s) missing from index %%s'', %%s, %%s)\n" + " END\n'" + " , t.db, t.tab, i.name, i.match_expr, ' AND (' || partial || ')'," + " i.idx_ps, t.ps_pk, i.name, i.idx_idx, t.pk_pk)," + " CASE WHEN partial IS NULL THEN NULL ELSE i.partial_alias END" + " FROM tabpk t, idx i" + ")" + + ", numbered(ii, cond, e) AS (" + " SELECT 0, 'n.ii=0', 'NULL'" + " UNION ALL " + " SELECT row_number() OVER ()," + " '(n.ii='||row_number() OVER ()||COALESCE(' AND '||p||')', ')'), e" + " FROM expr" + ")" + + ", counter_with(w) AS (" + " SELECT 'WITH intck_counter(ii) AS (\n ' || " + " group_concat('SELECT '||ii, ' UNION ALL\n ') " + " || '\n)' FROM numbered" + ")" + "" + ", case_statement(c) AS (" + " SELECT 'CASE ' || " + " group_concat(format('\n WHEN %%s THEN (%%s)', cond, e), '') ||" + " '\nEND AS error_message'" + " FROM numbered" + ")" + "" + + /* This table contains a single row consisting of a single value - + ** the text of an SQL expression that may be used by the main SQL + ** statement to output an SQL literal that can be used to resume + ** the scan if it is suspended. e.g. for a rowid table, an expression + ** like: + ** + ** format('(%d,%d)', _rowid_, n.ii) + */ + ", thiskey(k, n) AS (" + " SELECT o_pk || ', ii', n_pk+1 FROM tabpk" + ")" + "" + ", whereclause(w_c) AS (" + " SELECT CASE WHEN prev!='' THEN " + " '\nWHERE (' || o_pk ||', n.ii) > ' || prev" + " ELSE ''" + " END" + " FROM tabpk, tabname" + ")" + "" + ", main_select(m, n) AS (" + " SELECT format(" + " '%%s, %%s\nSELECT %%s,\n%%s\nFROM intck_wrapper AS o" + ", intck_counter AS n%%s\nORDER BY %%s', " + " w, ww.s, c, thiskey.k, whereclause.w_c, t.o_pk" + " ), thiskey.n" + " FROM case_statement, tabpk t, counter_with, " + " wrapper_with ww, thiskey, whereclause" + ")" + + "SELECT m, n FROM main_select", + p->zDb, zObj, zPrev, zCommon + ); + } + + while( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){ + zRet = intckMprintf(p, "%s", (const char*)sqlite3_column_text(pStmt, 0)); + if( pnKeyVal ){ + *pnKeyVal = sqlite3_column_int(pStmt, 1); + } + } + intckFinalize(p, pStmt); + + if( bAutoIndex ) intckExec(p, "PRAGMA automatic_index = 1"); + return zRet; +} + +/* +** Open a new integrity-check object. +*/ +int sqlite3_intck_open( + sqlite3 *db, /* Database handle to operate on */ + const char *zDbArg, /* "main", "temp" etc. */ + sqlite3_intck **ppOut /* OUT: New integrity-check handle */ +){ + sqlite3_intck *pNew = 0; + int rc = SQLITE_OK; + const char *zDb = zDbArg ? zDbArg : "main"; + int nDb = (int)strlen(zDb); + + pNew = (sqlite3_intck*)sqlite3_malloc(sizeof(*pNew) + nDb + 1); + if( pNew==0 ){ + rc = SQLITE_NOMEM; + }else{ + memset(pNew, 0, sizeof(*pNew)); + pNew->db = db; + pNew->zDb = (const char*)&pNew[1]; + memcpy(&pNew[1], zDb, nDb+1); + rc = sqlite3_create_function(db, "parse_create_index", + 2, SQLITE_UTF8, 0, intckParseCreateIndexFunc, 0, 0 + ); + if( rc!=SQLITE_OK ){ + sqlite3_intck_close(pNew); + pNew = 0; + } + } + + *ppOut = pNew; + return rc; +} + +/* +** Free the integrity-check object. +*/ +void sqlite3_intck_close(sqlite3_intck *p){ + if( p ){ + sqlite3_finalize(p->pCheck); + sqlite3_create_function( + p->db, "parse_create_index", 1, SQLITE_UTF8, 0, 0, 0, 0 + ); + sqlite3_free(p->zObj); + sqlite3_free(p->zKey); + sqlite3_free(p->zTestSql); + sqlite3_free(p->zErr); + sqlite3_free(p->zMessage); + sqlite3_free(p); + } +} + +/* +** Step the integrity-check object. +*/ +int sqlite3_intck_step(sqlite3_intck *p){ + if( p->rc==SQLITE_OK ){ + + if( p->zMessage ){ + sqlite3_free(p->zMessage); + p->zMessage = 0; + } + + if( p->bCorruptSchema ){ + p->rc = SQLITE_DONE; + }else + if( p->pCheck==0 ){ + intckFindObject(p); + if( p->rc==SQLITE_OK ){ + if( p->zObj ){ + char *zSql = 0; + zSql = intckCheckObjectSql(p, p->zObj, p->zKey, &p->nKeyVal); + p->pCheck = intckPrepare(p, zSql); + sqlite3_free(zSql); + sqlite3_free(p->zKey); + p->zKey = 0; + }else{ + p->rc = SQLITE_DONE; + } + }else if( p->rc==SQLITE_CORRUPT ){ + p->rc = SQLITE_OK; + p->zMessage = intckMprintf(p, "%s", + "corruption found while reading database schema" + ); + p->bCorruptSchema = 1; + } + } + + if( p->pCheck ){ + assert( p->rc==SQLITE_OK ); + if( sqlite3_step(p->pCheck)==SQLITE_ROW ){ + /* Normal case, do nothing. */ + }else{ + intckFinalize(p, p->pCheck); + p->pCheck = 0; + p->nKeyVal = 0; + if( p->rc==SQLITE_CORRUPT ){ + p->rc = SQLITE_OK; + p->zMessage = intckMprintf(p, + "corruption found while scanning database object %s", p->zObj + ); + } + } + } + } + + return p->rc; +} + +/* +** Return a message describing the corruption encountered by the most recent +** call to sqlite3_intck_step(), or NULL if no corruption was encountered. +*/ +const char *sqlite3_intck_message(sqlite3_intck *p){ + assert( p->pCheck==0 || p->zMessage==0 ); + if( p->zMessage ){ + return p->zMessage; + } + if( p->pCheck ){ + return (const char*)sqlite3_column_text(p->pCheck, 0); + } + return 0; +} + +/* +** Return the error code and message. +*/ +int sqlite3_intck_error(sqlite3_intck *p, const char **pzErr){ + if( pzErr ) *pzErr = p->zErr; + return (p->rc==SQLITE_DONE ? SQLITE_OK : p->rc); +} + +/* +** Close any read transaction the integrity-check object is holding open +** on the database. +*/ +int sqlite3_intck_unlock(sqlite3_intck *p){ + if( p->rc==SQLITE_OK && p->pCheck ){ + assert( p->zKey==0 && p->nKeyVal>0 ); + intckSaveKey(p); + intckFinalize(p, p->pCheck); + p->pCheck = 0; + } + return p->rc; +} + +/* +** Return the SQL statement used to check object zObj. Or, if zObj is +** NULL, the current SQL statement. +*/ +const char *sqlite3_intck_test_sql(sqlite3_intck *p, const char *zObj){ + sqlite3_free(p->zTestSql); + if( zObj ){ + p->zTestSql = intckCheckObjectSql(p, zObj, 0, 0); + }else{ + if( p->zObj ){ + p->zTestSql = intckCheckObjectSql(p, p->zObj, p->zKey, 0); + }else{ + sqlite3_free(p->zTestSql); + p->zTestSql = 0; + } + } + return p->zTestSql; +} diff --git a/ext/intck/sqlite3intck.h b/ext/intck/sqlite3intck.h new file mode 100644 index 0000000..e08a86f --- /dev/null +++ b/ext/intck/sqlite3intck.h @@ -0,0 +1,171 @@ +/* +** 2024-02-08 +** +** 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. +** +************************************************************************* +*/ + +/* +** Incremental Integrity-Check Extension +** ------------------------------------- +** +** This module contains code to check whether or not an SQLite database +** is well-formed or corrupt. This is the same task as performed by SQLite's +** built-in "PRAGMA integrity_check" command. This module differs from +** "PRAGMA integrity_check" in that: +** +** + It is less thorough - this module does not detect certain types +** of corruption that are detected by the PRAGMA command. However, +** it does detect all kinds of corruption that are likely to cause +** errors in SQLite applications. +** +** + It is slower. Sometimes up to three times slower. +** +** + It allows integrity-check operations to be split into multiple +** transactions, so that the database does not need to be read-locked +** for the duration of the integrity-check. +** +** One way to use the API to run integrity-check on the "main" database +** of handle db is: +** +** int rc = SQLITE_OK; +** sqlite3_intck *p = 0; +** +** sqlite3_intck_open(db, "main", &p); +** while( SQLITE_OK==sqlite3_intck_step(p) ){ +** const char *zMsg = sqlite3_intck_message(p); +** if( zMsg ) printf("corruption: %s\n", zMsg); +** } +** rc = sqlite3_intck_error(p, &zErr); +** if( rc!=SQLITE_OK ){ +** printf("error occured (rc=%d), (errmsg=%s)\n", rc, zErr); +** } +** sqlite3_intck_close(p); +** +** Usually, the sqlite3_intck object opens a read transaction within the +** first call to sqlite3_intck_step() and holds it open until the +** integrity-check is complete. However, if sqlite3_intck_unlock() is +** called, the read transaction is ended and a new read transaction opened +** by the subsequent call to sqlite3_intck_step(). +*/ + +#ifndef _SQLITE_INTCK_H +#define _SQLITE_INTCK_H + +#include "sqlite3.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* +** An ongoing incremental integrity-check operation is represented by an +** opaque pointer of the following type. +*/ +typedef struct sqlite3_intck sqlite3_intck; + +/* +** Open a new incremental integrity-check object. If successful, populate +** output variable (*ppOut) with the new object handle and return SQLITE_OK. +** Or, if an error occurs, set (*ppOut) to NULL and return an SQLite error +** code (e.g. SQLITE_NOMEM). +** +** The integrity-check will be conducted on database zDb (which must be "main", +** "temp", or the name of an attached database) of database handle db. Once +** this function has been called successfully, the caller should not use +** database handle db until the integrity-check object has been destroyed +** using sqlite3_intck_close(). +*/ +int sqlite3_intck_open( + sqlite3 *db, /* Database handle */ + const char *zDb, /* Database name ("main", "temp" etc.) */ + sqlite3_intck **ppOut /* OUT: New sqlite3_intck handle */ +); + +/* +** Close and release all resources associated with a handle opened by an +** earlier call to sqlite3_intck_open(). The results of using an +** integrity-check handle after it has been passed to this function are +** undefined. +*/ +void sqlite3_intck_close(sqlite3_intck *pCk); + +/* +** Do the next step of the integrity-check operation specified by the handle +** passed as the only argument. This function returns SQLITE_DONE if the +** integrity-check operation is finished, or an SQLite error code if +** an error occurs, or SQLITE_OK if no error occurs but the integrity-check +** is not finished. It is not considered an error if database corruption +** is encountered. +** +** Following a successful call to sqlite3_intck_step() (one that returns +** SQLITE_OK), sqlite3_intck_message() returns a non-NULL value if +** corruption was detected in the db. +** +** If an error occurs and a value other than SQLITE_OK or SQLITE_DONE is +** returned, then the integrity-check handle is placed in an error state. +** In this state all subsequent calls to sqlite3_intck_step() or +** sqlite3_intck_unlock() will immediately return the same error. The +** sqlite3_intck_error() method may be used to obtain an English language +** error message in this case. +*/ +int sqlite3_intck_step(sqlite3_intck *pCk); + +/* +** If the previous call to sqlite3_intck_step() encountered corruption +** within the database, then this function returns a pointer to a buffer +** containing a nul-terminated string describing the corruption in +** English. If the previous call to sqlite3_intck_step() did not encounter +** corruption, or if there was no previous call, this function returns +** NULL. +*/ +const char *sqlite3_intck_message(sqlite3_intck *pCk); + +/* +** Close any read-transaction opened by an earlier call to +** sqlite3_intck_step(). Any subsequent call to sqlite3_intck_step() will +** open a new transaction. Return SQLITE_OK if successful, or an SQLite error +** code otherwise. +** +** If an error occurs, then the integrity-check handle is placed in an error +** state. In this state all subsequent calls to sqlite3_intck_step() or +** sqlite3_intck_unlock() will immediately return the same error. The +** sqlite3_intck_error() method may be used to obtain an English language +** error message in this case. +*/ +int sqlite3_intck_unlock(sqlite3_intck *pCk); + +/* +** If an error has occurred in an earlier call to sqlite3_intck_step() +** or sqlite3_intck_unlock(), then this method returns the associated +** SQLite error code. Additionally, if pzErr is not NULL, then (*pzErr) +** may be set to point to a nul-terminated string containing an English +** language error message. Or, if no error message is available, to +** NULL. +** +** If no error has occurred within sqlite3_intck_step() or +** sqlite_intck_unlock() calls on the handle passed as the first argument, +** then SQLITE_OK is returned and (*pzErr) set to NULL. +*/ +int sqlite3_intck_error(sqlite3_intck *pCk, const char **pzErr); + +/* +** This API is used for testing only. It returns the full-text of an SQL +** statement used to test object zObj, which may be a table or index. +** The returned buffer is valid until the next call to either this function +** or sqlite3_intck_close() on the same sqlite3_intck handle. +*/ +const char *sqlite3_intck_test_sql(sqlite3_intck *pCk, const char *zObj); + + +#ifdef __cplusplus +} /* end of the 'extern "C"' block */ +#endif + +#endif /* ifndef _SQLITE_INTCK_H */ diff --git a/ext/intck/test_intck.c b/ext/intck/test_intck.c new file mode 100644 index 0000000..84008fb --- /dev/null +++ b/ext/intck/test_intck.c @@ -0,0 +1,238 @@ +/* +** 2010 August 28 +** +** 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. +** +************************************************************************* +** Code for testing all sorts of SQLite interfaces. This code +** is not included in the SQLite library. +*/ + +#include "sqlite3.h" +#include "sqlite3intck.h" + +#if defined(INCLUDE_SQLITE_TCL_H) +# include "sqlite_tcl.h" +#else +# include "tcl.h" +#endif + +#include <string.h> +#include <assert.h> + +/* In test1.c */ +int getDbPointer(Tcl_Interp *interp, const char *zA, sqlite3 **ppDb); +const char *sqlite3ErrName(int); + +typedef struct TestIntck TestIntck; +struct TestIntck { + sqlite3_intck *intck; +}; + +static int testIntckCmd( + void * clientData, + Tcl_Interp *interp, + int objc, + Tcl_Obj *CONST objv[] +){ + struct Subcmd { + const char *zName; + int nArg; + const char *zExpect; + } aCmd[] = { + {"close", 0, ""}, /* 0 */ + {"step", 0, ""}, /* 1 */ + {"message", 0, ""}, /* 2 */ + {"error", 0, ""}, /* 3 */ + {"unlock", 0, ""}, /* 4 */ + {"test_sql", 1, ""}, /* 5 */ + {0 , 0} + }; + int rc = TCL_OK; + int iIdx = -1; + TestIntck *p = (TestIntck*)clientData; + + if( objc<2 ){ + Tcl_WrongNumArgs(interp, 1, objv, "SUB-COMMAND ..."); + return TCL_ERROR; + } + + rc = Tcl_GetIndexFromObjStruct( + interp, objv[1], aCmd, sizeof(aCmd[0]), "SUB-COMMAND", 0, &iIdx + ); + if( rc ) return rc; + + if( objc!=2+aCmd[iIdx].nArg ){ + Tcl_WrongNumArgs(interp, 2, objv, aCmd[iIdx].zExpect); + return TCL_ERROR; + } + + switch( iIdx ){ + case 0: assert( 0==strcmp("close", aCmd[iIdx].zName) ); { + Tcl_DeleteCommand(interp, Tcl_GetStringFromObj(objv[0], 0)); + break; + } + + case 1: assert( 0==strcmp("step", aCmd[iIdx].zName) ); { + rc = sqlite3_intck_step(p->intck); + Tcl_SetObjResult(interp, Tcl_NewStringObj(sqlite3ErrName(rc), -1)); + break; + } + + case 2: assert( 0==strcmp("message", aCmd[iIdx].zName) ); { + const char *z = sqlite3_intck_message(p->intck); + Tcl_SetObjResult(interp, Tcl_NewStringObj(z ? z : "", -1)); + break; + } + + case 3: assert( 0==strcmp("error", aCmd[iIdx].zName) ); { + const char *zErr = 0; + rc = sqlite3_intck_error(p->intck, 0); + Tcl_Obj *pRes = Tcl_NewObj(); + Tcl_ListObjAppendElement( + interp, pRes, Tcl_NewStringObj(sqlite3ErrName(rc), -1) + ); + sqlite3_intck_error(p->intck, &zErr); + Tcl_ListObjAppendElement( + interp, pRes, Tcl_NewStringObj(zErr ? zErr : 0, -1) + ); + Tcl_SetObjResult(interp, pRes); + break; + } + + case 4: assert( 0==strcmp("unlock", aCmd[iIdx].zName) ); { + rc = sqlite3_intck_unlock(p->intck); + Tcl_SetObjResult(interp, Tcl_NewStringObj(sqlite3ErrName(rc), -1)); + break; + } + + case 5: assert( 0==strcmp("test_sql", aCmd[iIdx].zName) ); { + const char *zObj = Tcl_GetString(objv[2]); + const char *zSql = sqlite3_intck_test_sql(p->intck, zObj[0] ? zObj : 0); + Tcl_SetObjResult(interp, Tcl_NewStringObj(zSql, -1)); + break; + } + } + + return TCL_OK; +} + +/* +** Destructor for commands created by test_sqlite3_intck(). +*/ +static void testIntckFree(void *clientData){ + TestIntck *p = (TestIntck*)clientData; + sqlite3_intck_close(p->intck); + ckfree(p); +} + +/* +** tclcmd: sqlite3_intck DB DBNAME +*/ +static int test_sqlite3_intck( + void * clientData, + Tcl_Interp *interp, + int objc, + Tcl_Obj *CONST objv[] +){ + char zName[64]; + int iName = 0; + Tcl_CmdInfo info; + TestIntck *p = 0; + sqlite3 *db = 0; + const char *zDb = 0; + int rc = SQLITE_OK; + + if( objc!=3 ){ + Tcl_WrongNumArgs(interp, 1, objv, "DB DBNAME"); + return TCL_ERROR; + } + + p = (TestIntck*)ckalloc(sizeof(TestIntck)); + memset(p, 0, sizeof(TestIntck)); + + if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ){ + return TCL_ERROR; + } + zDb = Tcl_GetString(objv[2]); + if( zDb[0]=='\0' ) zDb = 0; + + rc = sqlite3_intck_open(db, zDb, &p->intck); + if( rc!=SQLITE_OK ){ + ckfree(p); + Tcl_SetObjResult(interp, Tcl_NewStringObj(sqlite3_errstr(rc), -1)); + return TCL_ERROR; + } + + do { + sprintf(zName, "intck%d", iName++); + }while( Tcl_GetCommandInfo(interp, zName, &info)!=0 ); + Tcl_CreateObjCommand(interp, zName, testIntckCmd, (void*)p, testIntckFree); + Tcl_SetObjResult(interp, Tcl_NewStringObj(zName, -1)); + + return TCL_OK; +} + +/* +** tclcmd: test_do_intck DB DBNAME +*/ +static int test_do_intck( + void * clientData, + Tcl_Interp *interp, + int objc, + Tcl_Obj *CONST objv[] +){ + sqlite3 *db = 0; + const char *zDb = 0; + int rc = SQLITE_OK; + sqlite3_intck *pCk = 0; + Tcl_Obj *pRet = 0; + const char *zErr = 0; + + if( objc!=3 ){ + Tcl_WrongNumArgs(interp, 1, objv, "DB DBNAME"); + return TCL_ERROR; + } + if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ){ + return TCL_ERROR; + } + zDb = Tcl_GetString(objv[2]); + + pRet = Tcl_NewObj(); + Tcl_IncrRefCount(pRet); + + rc = sqlite3_intck_open(db, zDb, &pCk); + if( rc==SQLITE_OK ){ + while( sqlite3_intck_step(pCk)==SQLITE_OK ){ + const char *zMsg = sqlite3_intck_message(pCk); + if( zMsg ){ + Tcl_ListObjAppendElement(interp, pRet, Tcl_NewStringObj(zMsg, -1)); + } + } + rc = sqlite3_intck_error(pCk, &zErr); + } + if( rc!=SQLITE_OK ){ + if( zErr ){ + Tcl_SetObjResult(interp, Tcl_NewStringObj(zErr, -1)); + }else{ + Tcl_SetObjResult(interp, Tcl_NewStringObj(sqlite3ErrName(rc), -1)); + } + }else{ + Tcl_SetObjResult(interp, pRet); + } + Tcl_DecrRefCount(pRet); + sqlite3_intck_close(pCk); + sqlite3_intck_close(0); + return rc ? TCL_ERROR : TCL_OK; +} + +int Sqlitetestintck_Init(Tcl_Interp *interp){ + Tcl_CreateObjCommand(interp, "sqlite3_intck", test_sqlite3_intck, 0, 0); + Tcl_CreateObjCommand(interp, "test_do_intck", test_do_intck, 0, 0); + return TCL_OK; +} diff --git a/ext/misc/cksumvfs.c b/ext/misc/cksumvfs.c index e7c2c9d..2d7f658 100644 --- a/ext/misc/cksumvfs.c +++ b/ext/misc/cksumvfs.c @@ -446,9 +446,9 @@ static int cksmRead( ** (2) checksum verification is enabled ** (3) we are not in the middle of checkpoint */ - if( iAmt>=512 /* (1) */ - && p->verifyCksm /* (2) */ - && !p->inCkpt /* (3) */ + if( iAmt>=512 && (iAmt & (iAmt-1))==0 /* (1) */ + && p->verifyCksm /* (2) */ + && !p->inCkpt /* (3) */ ){ u8 cksum[8]; cksmCompute((u8*)zBuf, iAmt-8, cksum); diff --git a/ext/misc/fileio.c b/ext/misc/fileio.c index 70546ad..ca8090e 100644 --- a/ext/misc/fileio.c +++ b/ext/misc/fileio.c @@ -372,7 +372,9 @@ static int writeFile( #if !defined(_WIN32) && !defined(WIN32) if( S_ISLNK(mode) ){ const char *zTo = (const char*)sqlite3_value_text(pData); - if( zTo==0 || symlink(zTo, zFile)<0 ) return 1; + if( zTo==0 ) return 1; + unlink(zFile); + if( symlink(zTo, zFile)<0 ) return 1; }else #endif { @@ -458,13 +460,19 @@ static int writeFile( return 1; } #else - /* Legacy unix */ - struct timeval times[2]; - times[0].tv_usec = times[1].tv_usec = 0; - times[0].tv_sec = time(0); - times[1].tv_sec = mtime; - if( utimes(zFile, times) ){ - return 1; + /* Legacy unix. + ** + ** Do not use utimes() on a symbolic link - it sees through the link and + ** modifies the timestamps on the target. Or fails if the target does + ** not exist. */ + if( 0==S_ISLNK(mode) ){ + struct timeval times[2]; + times[0].tv_usec = times[1].tv_usec = 0; + times[0].tv_sec = time(0); + times[1].tv_sec = mtime; + if( utimes(zFile, times) ){ + return 1; + } } #endif } diff --git a/ext/misc/series.c b/ext/misc/series.c index abd6af7..0dfed18 100644 --- a/ext/misc/series.c +++ b/ext/misc/series.c @@ -103,16 +103,20 @@ SQLITE_EXTENSION_INIT1 ** index is ix. The 0th member is given by smBase. The sequence members ** progress per ix increment by smStep. */ -static sqlite3_int64 genSeqMember(sqlite3_int64 smBase, - sqlite3_int64 smStep, - sqlite3_uint64 ix){ - if( ix>=(sqlite3_uint64)LLONG_MAX ){ +static sqlite3_int64 genSeqMember( + sqlite3_int64 smBase, + sqlite3_int64 smStep, + sqlite3_uint64 ix +){ + static const sqlite3_uint64 mxI64 = + ((sqlite3_uint64)0x7fffffff)<<32 | 0xffffffff; + if( ix>=mxI64 ){ /* Get ix into signed i64 range. */ - ix -= (sqlite3_uint64)LLONG_MAX; + ix -= mxI64; /* With 2's complement ALU, this next can be 1 step, but is split into * 2 for UBSAN's satisfaction (and hypothetical 1's complement ALUs.) */ - smBase += (LLONG_MAX/2) * smStep; - smBase += (LLONG_MAX - LLONG_MAX/2) * smStep; + smBase += (mxI64/2) * smStep; + smBase += (mxI64 - mxI64/2) * smStep; } /* Under UBSAN (or on 1's complement machines), must do this last term * in steps to avoid the dreaded (and harmless) signed multiply overlow. */ @@ -372,13 +376,13 @@ static int seriesEof(sqlite3_vtab_cursor *cur){ ** parameter. (idxStr is not used in this implementation.) idxNum ** is a bitmask showing which constraints are available: ** -** 1: start=VALUE -** 2: stop=VALUE -** 4: step=VALUE -** -** Also, if bit 8 is set, that means that the series should be output -** in descending order rather than in ascending order. If bit 16 is -** set, then output must appear in ascending order. +** 0x01: start=VALUE +** 0x02: stop=VALUE +** 0x04: step=VALUE +** 0x08: descending order +** 0x10: ascending order +** 0x20: LIMIT VALUE +** 0x40: OFFSET VALUE ** ** This routine should initialize the cursor and position it so that it ** is pointing at the first row, or pointing off the end of the table @@ -392,26 +396,44 @@ static int seriesFilter( series_cursor *pCur = (series_cursor *)pVtabCursor; int i = 0; (void)idxStrUnused; - if( idxNum & 1 ){ + if( idxNum & 0x01 ){ pCur->ss.iBase = sqlite3_value_int64(argv[i++]); }else{ pCur->ss.iBase = 0; } - if( idxNum & 2 ){ + if( idxNum & 0x02 ){ pCur->ss.iTerm = sqlite3_value_int64(argv[i++]); }else{ pCur->ss.iTerm = 0xffffffff; } - if( idxNum & 4 ){ + if( idxNum & 0x04 ){ pCur->ss.iStep = sqlite3_value_int64(argv[i++]); if( pCur->ss.iStep==0 ){ pCur->ss.iStep = 1; }else if( pCur->ss.iStep<0 ){ - if( (idxNum & 16)==0 ) idxNum |= 8; + if( (idxNum & 0x10)==0 ) idxNum |= 0x08; } }else{ pCur->ss.iStep = 1; } + if( idxNum & 0x20 ){ + sqlite3_int64 iLimit = sqlite3_value_int64(argv[i++]); + sqlite3_int64 iTerm; + if( idxNum & 0x40 ){ + sqlite3_int64 iOffset = sqlite3_value_int64(argv[i++]); + if( iOffset>0 ){ + pCur->ss.iBase += pCur->ss.iStep*iOffset; + } + } + if( iLimit>=0 ){ + iTerm = pCur->ss.iBase + (iLimit - 1)*pCur->ss.iStep; + if( pCur->ss.iStep<0 ){ + if( iTerm>pCur->ss.iTerm ) pCur->ss.iTerm = iTerm; + }else{ + if( iTerm<pCur->ss.iTerm ) pCur->ss.iTerm = iTerm; + } + } + } for(i=0; i<argc; i++){ if( sqlite3_value_type(argv[i])==SQLITE_NULL ){ /* If any of the constraints have a NULL value, then return no rows. @@ -422,7 +444,7 @@ static int seriesFilter( break; } } - if( idxNum & 8 ){ + if( idxNum & 0x08 ){ pCur->ss.isReversing = pCur->ss.iStep > 0; }else{ pCur->ss.isReversing = pCur->ss.iStep < 0; @@ -442,10 +464,13 @@ static int seriesFilter( ** ** The query plan is represented by bits in idxNum: ** -** (1) start = $value -- constraint exists -** (2) stop = $value -- constraint exists -** (4) step = $value -- constraint exists -** (8) output in descending order +** 0x01 start = $value -- constraint exists +** 0x02 stop = $value -- constraint exists +** 0x04 step = $value -- constraint exists +** 0x08 output is in descending order +** 0x10 output is in ascending order +** 0x20 LIMIT $value -- constraint exists +** 0x40 OFFSET $value -- constraint exists */ static int seriesBestIndex( sqlite3_vtab *pVTab, @@ -453,10 +478,12 @@ static int seriesBestIndex( ){ int i, j; /* Loop over constraints */ int idxNum = 0; /* The query plan bitmask */ +#ifndef ZERO_ARGUMENT_GENERATE_SERIES int bStartSeen = 0; /* EQ constraint seen on the START column */ +#endif int unusableMask = 0; /* Mask of unusable constraints */ int nArg = 0; /* Number of arguments that seriesFilter() expects */ - int aIdx[3]; /* Constraints on start, stop, and step */ + int aIdx[5]; /* Constraints on start, stop, step, LIMIT, OFFSET */ const struct sqlite3_index_constraint *pConstraint; /* This implementation assumes that the start, stop, and step columns @@ -464,28 +491,54 @@ static int seriesBestIndex( assert( SERIES_COLUMN_STOP == SERIES_COLUMN_START+1 ); assert( SERIES_COLUMN_STEP == SERIES_COLUMN_START+2 ); - aIdx[0] = aIdx[1] = aIdx[2] = -1; + aIdx[0] = aIdx[1] = aIdx[2] = aIdx[3] = aIdx[4] = -1; pConstraint = pIdxInfo->aConstraint; for(i=0; i<pIdxInfo->nConstraint; i++, pConstraint++){ int iCol; /* 0 for start, 1 for stop, 2 for step */ int iMask; /* bitmask for those column */ + int op = pConstraint->op; + if( op>=SQLITE_INDEX_CONSTRAINT_LIMIT + && op<=SQLITE_INDEX_CONSTRAINT_OFFSET + ){ + if( pConstraint->usable==0 ){ + /* do nothing */ + }else if( op==SQLITE_INDEX_CONSTRAINT_LIMIT ){ + aIdx[3] = i; + idxNum |= 0x20; + }else{ + assert( op==SQLITE_INDEX_CONSTRAINT_OFFSET ); + aIdx[4] = i; + idxNum |= 0x40; + } + continue; + } if( pConstraint->iColumn<SERIES_COLUMN_START ) continue; iCol = pConstraint->iColumn - SERIES_COLUMN_START; assert( iCol>=0 && iCol<=2 ); iMask = 1 << iCol; - if( iCol==0 ) bStartSeen = 1; +#ifndef ZERO_ARGUMENT_GENERATE_SERIES + if( iCol==0 && op==SQLITE_INDEX_CONSTRAINT_EQ ){ + bStartSeen = 1; + } +#endif if( pConstraint->usable==0 ){ unusableMask |= iMask; continue; - }else if( pConstraint->op==SQLITE_INDEX_CONSTRAINT_EQ ){ + }else if( op==SQLITE_INDEX_CONSTRAINT_EQ ){ idxNum |= iMask; aIdx[iCol] = i; } } - for(i=0; i<3; i++){ + if( aIdx[3]==0 ){ + /* Ignore OFFSET if LIMIT is omitted */ + idxNum &= ~0x60; + aIdx[4] = 0; + } + for(i=0; i<5; i++){ if( (j = aIdx[i])>=0 ){ pIdxInfo->aConstraintUsage[j].argvIndex = ++nArg; - pIdxInfo->aConstraintUsage[j].omit = !SQLITE_SERIES_CONSTRAINT_VERIFY; + pIdxInfo->aConstraintUsage[j].omit = + !SQLITE_SERIES_CONSTRAINT_VERIFY || i>=3; } } /* The current generate_column() implementation requires at least one @@ -506,19 +559,22 @@ static int seriesBestIndex( ** this plan is unusable */ return SQLITE_CONSTRAINT; } - if( (idxNum & 3)==3 ){ + if( (idxNum & 0x03)==0x03 ){ /* Both start= and stop= boundaries are available. This is the ** the preferred case */ pIdxInfo->estimatedCost = (double)(2 - ((idxNum&4)!=0)); pIdxInfo->estimatedRows = 1000; if( pIdxInfo->nOrderBy>=1 && pIdxInfo->aOrderBy[0].iColumn==0 ){ if( pIdxInfo->aOrderBy[0].desc ){ - idxNum |= 8; + idxNum |= 0x08; }else{ - idxNum |= 16; + idxNum |= 0x10; } pIdxInfo->orderByConsumed = 1; } + }else if( (idxNum & 0x21)==0x21 ){ + /* We have start= and LIMIT */ + pIdxInfo->estimatedRows = 2500; }else{ /* If either boundary is missing, we have to generate a huge span ** of numbers. Make this case very expensive so that the query diff --git a/ext/misc/sqlar.c b/ext/misc/sqlar.c index be079a5..9f726f0 100644 --- a/ext/misc/sqlar.c +++ b/ext/misc/sqlar.c @@ -81,7 +81,7 @@ static void sqlarUncompressFunc( sqlite3_value **argv ){ uLong nData; - uLongf sz; + sqlite3_int64 sz; assert( argc==2 ); sz = sqlite3_value_int(argv[1]); @@ -89,14 +89,15 @@ static void sqlarUncompressFunc( if( sz<=0 || sz==(nData = sqlite3_value_bytes(argv[0])) ){ sqlite3_result_value(context, argv[0]); }else{ + uLongf szf = sz; const Bytef *pData= sqlite3_value_blob(argv[0]); Bytef *pOut = sqlite3_malloc(sz); if( pOut==0 ){ sqlite3_result_error_nomem(context); - }else if( Z_OK!=uncompress(pOut, &sz, pData, nData) ){ + }else if( Z_OK!=uncompress(pOut, &szf, pData, nData) ){ sqlite3_result_error(context, "error in uncompress()", -1); }else{ - sqlite3_result_blob(context, pOut, sz, SQLITE_TRANSIENT); + sqlite3_result_blob(context, pOut, szf, SQLITE_TRANSIENT); } sqlite3_free(pOut); } diff --git a/ext/misc/vtablog.c b/ext/misc/vtablog.c index e414e7a..2cc29c2 100644 --- a/ext/misc/vtablog.c +++ b/ext/misc/vtablog.c @@ -38,8 +38,9 @@ SQLITE_EXTENSION_INIT1 typedef struct vtablog_vtab vtablog_vtab; struct vtablog_vtab { sqlite3_vtab base; /* Base class - must be first */ + char *zDb; /* Schema name. argv[1] of xConnect/xCreate */ + char *zName; /* Table name. argv[2] of xConnect/xCreate */ int nRow; /* Number of rows in the table */ - int iInst; /* Instance number for this vtablog table */ int nCursor; /* Number of cursors created */ }; @@ -167,15 +168,14 @@ static int vtablogConnectCreate( char **pzErr, int isCreate ){ - static int nInst = 0; vtablog_vtab *pNew; int i; int rc; - int iInst = ++nInst; char *zSchema = 0; char *zNRow = 0; - printf("vtablog%s(tab=%d):\n", isCreate ? "Create" : "Connect", iInst); + printf("%s.%s.%s():\n", argv[1], argv[2], + isCreate ? "xCreate" : "xConnect"); printf(" argc=%d\n", argc); for(i=0; i<argc; i++){ printf(" argv[%d] = ", i); @@ -189,17 +189,18 @@ static int vtablogConnectCreate( for(i=3; i<argc; i++){ const char *z = argv[i]; if( vtablog_string_parameter(pzErr, "schema", z, &zSchema) ){ - return SQLITE_ERROR; + rc = SQLITE_ERROR; + goto vtablog_end_connect; } if( vtablog_string_parameter(pzErr, "rows", z, &zNRow) ){ - return SQLITE_ERROR; + rc = SQLITE_ERROR; + goto vtablog_end_connect; } } - if( zSchema==0 ){ - *pzErr = sqlite3_mprintf("no schema defined"); - return SQLITE_ERROR; + zSchema = sqlite3_mprintf("%s","CREATE TABLE x(a,b);"); } + printf(" schema = '%s'\n", zSchema); rc = sqlite3_declare_vtab(db, zSchema); if( rc==SQLITE_OK ){ pNew = sqlite3_malloc( sizeof(*pNew) ); @@ -208,8 +209,14 @@ static int vtablogConnectCreate( memset(pNew, 0, sizeof(*pNew)); pNew->nRow = 10; if( zNRow ) pNew->nRow = atoi(zNRow); - pNew->iInst = iInst; + printf(" nrow = %d\n", pNew->nRow); + pNew->zDb = sqlite3_mprintf("%s", argv[1]); + pNew->zName = sqlite3_mprintf("%s", argv[2]); } + +vtablog_end_connect: + sqlite3_free(zSchema); + sqlite3_free(zNRow); return rc; } static int vtablogCreate( @@ -237,7 +244,9 @@ static int vtablogConnect( */ static int vtablogDisconnect(sqlite3_vtab *pVtab){ vtablog_vtab *pTab = (vtablog_vtab*)pVtab; - printf("vtablogDisconnect(%d)\n", pTab->iInst); + printf("%s.%s.xDisconnect()\n", pTab->zDb, pTab->zName); + sqlite3_free(pTab->zDb); + sqlite3_free(pTab->zName); sqlite3_free(pVtab); return SQLITE_OK; } @@ -247,7 +256,9 @@ static int vtablogDisconnect(sqlite3_vtab *pVtab){ */ static int vtablogDestroy(sqlite3_vtab *pVtab){ vtablog_vtab *pTab = (vtablog_vtab*)pVtab; - printf("vtablogDestroy(%d)\n", pTab->iInst); + printf("%s.%s.xDestroy()\n", pTab->zDb, pTab->zName); + sqlite3_free(pTab->zDb); + sqlite3_free(pTab->zName); sqlite3_free(pVtab); return SQLITE_OK; } @@ -258,7 +269,8 @@ static int vtablogDestroy(sqlite3_vtab *pVtab){ static int vtablogOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){ vtablog_vtab *pTab = (vtablog_vtab*)p; vtablog_cursor *pCur; - printf("vtablogOpen(tab=%d, cursor=%d)\n", pTab->iInst, ++pTab->nCursor); + printf("%s.%s.xOpen(cursor=%d)\n", pTab->zDb, pTab->zName, + ++pTab->nCursor); pCur = sqlite3_malloc( sizeof(*pCur) ); if( pCur==0 ) return SQLITE_NOMEM; memset(pCur, 0, sizeof(*pCur)); @@ -273,7 +285,7 @@ static int vtablogOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){ static int vtablogClose(sqlite3_vtab_cursor *cur){ vtablog_cursor *pCur = (vtablog_cursor*)cur; vtablog_vtab *pTab = (vtablog_vtab*)cur->pVtab; - printf("vtablogClose(tab=%d, cursor=%d)\n", pTab->iInst, pCur->iCursor); + printf("%s.%s.xClose(cursor=%d)\n", pTab->zDb, pTab->zName, pCur->iCursor); sqlite3_free(cur); return SQLITE_OK; } @@ -285,8 +297,9 @@ static int vtablogClose(sqlite3_vtab_cursor *cur){ static int vtablogNext(sqlite3_vtab_cursor *cur){ vtablog_cursor *pCur = (vtablog_cursor*)cur; vtablog_vtab *pTab = (vtablog_vtab*)cur->pVtab; - printf("vtablogNext(tab=%d, cursor=%d) rowid %d -> %d\n", - pTab->iInst, pCur->iCursor, (int)pCur->iRowid, (int)pCur->iRowid+1); + printf("%s.%s.xNext(cursor=%d) rowid %d -> %d\n", + pTab->zDb, pTab->zName, pCur->iCursor, + (int)pCur->iRowid, (int)pCur->iRowid+1); pCur->iRowid++; return SQLITE_OK; } @@ -310,8 +323,8 @@ static int vtablogColumn( }else{ sqlite3_snprintf(sizeof(zVal),zVal,"{%d}%d", i, pCur->iRowid); } - printf("vtablogColumn(tab=%d, cursor=%d, i=%d): [%s]\n", - pTab->iInst, pCur->iCursor, i, zVal); + printf("%s.%s.xColumn(cursor=%d, i=%d): [%s]\n", + pTab->zDb, pTab->zName, pCur->iCursor, i, zVal); sqlite3_result_text(ctx, zVal, -1, SQLITE_TRANSIENT); return SQLITE_OK; } @@ -323,8 +336,8 @@ static int vtablogColumn( static int vtablogRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){ vtablog_cursor *pCur = (vtablog_cursor*)cur; vtablog_vtab *pTab = (vtablog_vtab*)cur->pVtab; - printf("vtablogRowid(tab=%d, cursor=%d): %d\n", - pTab->iInst, pCur->iCursor, (int)pCur->iRowid); + printf("%s.%s.xRowid(cursor=%d): %d\n", + pTab->zDb, pTab->zName, pCur->iCursor, (int)pCur->iRowid); *pRowid = pCur->iRowid; return SQLITE_OK; } @@ -337,8 +350,8 @@ static int vtablogEof(sqlite3_vtab_cursor *cur){ vtablog_cursor *pCur = (vtablog_cursor*)cur; vtablog_vtab *pTab = (vtablog_vtab*)cur->pVtab; int rc = pCur->iRowid >= pTab->nRow; - printf("vtablogEof(tab=%d, cursor=%d): %d\n", - pTab->iInst, pCur->iCursor, rc); + printf("%s.%s.xEof(cursor=%d): %d\n", + pTab->zDb, pTab->zName, pCur->iCursor, rc); return rc; } @@ -417,7 +430,7 @@ static int vtablogFilter( ){ vtablog_cursor *pCur = (vtablog_cursor *)cur; vtablog_vtab *pTab = (vtablog_vtab*)cur->pVtab; - printf("vtablogFilter(tab=%d, cursor=%d):\n", pTab->iInst, pCur->iCursor); + printf("%s.%s.xFilter(cursor=%d):\n", pTab->zDb, pTab->zName, pCur->iCursor); pCur->iRowid = 0; return SQLITE_OK; } @@ -430,12 +443,37 @@ static int vtablogFilter( */ static int vtablogBestIndex( sqlite3_vtab *tab, - sqlite3_index_info *pIdxInfo + sqlite3_index_info *p ){ vtablog_vtab *pTab = (vtablog_vtab*)tab; - printf("vtablogBestIndex(tab=%d):\n", pTab->iInst); - pIdxInfo->estimatedCost = (double)500; - pIdxInfo->estimatedRows = 500; + int i; + printf("%s.%s.xBestIndex():\n", pTab->zDb, pTab->zName); + printf(" colUsed: 0x%016llx\n", p->colUsed); + printf(" nConstraint: %d\n", p->nConstraint); + for(i=0; i<p->nConstraint; i++){ + printf( + " constraint[%d]: col=%d termid=%d op=%d usabled=%d collseq=%s\n", + i, + p->aConstraint[i].iColumn, + p->aConstraint[i].iTermOffset, + p->aConstraint[i].op, + p->aConstraint[i].usable, + sqlite3_vtab_collation(p,i)); + } + printf(" nOrderBy: %d\n", p->nOrderBy); + for(i=0; i<p->nOrderBy; i++){ + printf(" orderby[%d]: col=%d desc=%d\n", + i, + p->aOrderBy[i].iColumn, + p->aOrderBy[i].desc); + } + p->estimatedCost = (double)500; + p->estimatedRows = 500; + printf(" idxNum=%d\n", p->idxNum); + printf(" idxStr=NULL\n"); + printf(" orderByConsumed=%d\n", p->orderByConsumed); + printf(" estimatedCost=%g\n", p->estimatedCost); + printf(" estimatedRows=%lld\n", p->estimatedRows); return SQLITE_OK; } @@ -454,7 +492,7 @@ static int vtablogUpdate( ){ vtablog_vtab *pTab = (vtablog_vtab*)tab; int i; - printf("vtablogUpdate(tab=%d):\n", pTab->iInst); + printf("%s.%s.xUpdate():\n", pTab->zDb, pTab->zName); printf(" argc=%d\n", argc); for(i=0; i<argc; i++){ printf(" argv[%d]=", i); @@ -464,12 +502,88 @@ static int vtablogUpdate( return SQLITE_OK; } +static int vtablogBegin(sqlite3_vtab *tab){ + vtablog_vtab *pTab = (vtablog_vtab*)tab; + printf("%s.%s.xBegin()\n", pTab->zDb, pTab->zName); + return SQLITE_OK; +} +static int vtablogSync(sqlite3_vtab *tab){ + vtablog_vtab *pTab = (vtablog_vtab*)tab; + printf("%s.%s.xSync()\n", pTab->zDb, pTab->zName); + return SQLITE_OK; +} +static int vtablogCommit(sqlite3_vtab *tab){ + vtablog_vtab *pTab = (vtablog_vtab*)tab; + printf("%s.%s.xCommit()\n", pTab->zDb, pTab->zName); + return SQLITE_OK; +} +static int vtablogRollback(sqlite3_vtab *tab){ + vtablog_vtab *pTab = (vtablog_vtab*)tab; + printf("%s.%s.xRollback()\n", pTab->zDb, pTab->zName); + return SQLITE_OK; +} +static int vtablogSavepoint(sqlite3_vtab *tab, int N){ + vtablog_vtab *pTab = (vtablog_vtab*)tab; + printf("%s.%s.xSavepoint(%d)\n", pTab->zDb, pTab->zName, N); + return SQLITE_OK; +} +static int vtablogRelease(sqlite3_vtab *tab, int N){ + vtablog_vtab *pTab = (vtablog_vtab*)tab; + printf("%s.%s.xRelease(%d)\n", pTab->zDb, pTab->zName, N); + return SQLITE_OK; +} +static int vtablogRollbackTo(sqlite3_vtab *tab, int N){ + vtablog_vtab *pTab = (vtablog_vtab*)tab; + printf("%s.%s.xRollbackTo(%d)\n", pTab->zDb, pTab->zName, N); + return SQLITE_OK; +} + +static int vtablogFindMethod( + sqlite3_vtab *tab, + int nArg, + const char *zName, + void (**pxFunc)(sqlite3_context*,int,sqlite3_value**), + void **ppArg +){ + vtablog_vtab *pTab = (vtablog_vtab*)tab; + printf("%s.%s.xFindMethod(nArg=%d, zName=%s)\n", + pTab->zDb, pTab->zName, nArg, zName); + return SQLITE_OK; +} +static int vtablogRename(sqlite3_vtab *tab, const char *zNew){ + vtablog_vtab *pTab = (vtablog_vtab*)tab; + printf("%s.%s.xRename('%s')\n", pTab->zDb, pTab->zName, zNew); + sqlite3_free(pTab->zName); + pTab->zName = sqlite3_mprintf("%s", zNew); + return SQLITE_OK; +} + +/* Any table name that contains the text "shadow" is seen as a +** shadow table. Nothing else is. +*/ +static int vtablogShadowName(const char *zName){ + printf("vtablog.xShadowName('%s')\n", zName); + return sqlite3_strglob("*shadow*", zName)==0; +} + +static int vtablogIntegrity( + sqlite3_vtab *tab, + const char *zSchema, + const char *zTabName, + int mFlags, + char **pzErr +){ + vtablog_vtab *pTab = (vtablog_vtab*)tab; + printf("%s.%s.xIntegrity(mFlags=0x%x)\n", pTab->zDb, pTab->zName, mFlags); + return 0; +} + /* ** This following structure defines all the methods for the ** vtablog virtual table. */ static sqlite3_module vtablogModule = { - 0, /* iVersion */ + 4, /* iVersion */ vtablogCreate, /* xCreate */ vtablogConnect, /* xConnect */ vtablogBestIndex, /* xBestIndex */ @@ -483,17 +597,17 @@ static sqlite3_module vtablogModule = { vtablogColumn, /* xColumn - read data */ vtablogRowid, /* xRowid - read data */ vtablogUpdate, /* xUpdate */ - 0, /* xBegin */ - 0, /* xSync */ - 0, /* xCommit */ - 0, /* xRollback */ - 0, /* xFindMethod */ - 0, /* xRename */ - 0, /* xSavepoint */ - 0, /* xRelease */ - 0, /* xRollbackTo */ - 0, /* xShadowName */ - 0 /* xIntegrity */ + vtablogBegin, /* xBegin */ + vtablogSync, /* xSync */ + vtablogCommit, /* xCommit */ + vtablogRollback, /* xRollback */ + vtablogFindMethod, /* xFindMethod */ + vtablogRename, /* xRename */ + vtablogSavepoint, /* xSavepoint */ + vtablogRelease, /* xRelease */ + vtablogRollbackTo, /* xRollbackTo */ + vtablogShadowName, /* xShadowName */ + vtablogIntegrity /* xIntegrity */ }; #ifdef _WIN32 diff --git a/ext/rbu/sqlite3rbu.c b/ext/rbu/sqlite3rbu.c index 15b05ce..feb7695 100644 --- a/ext/rbu/sqlite3rbu.c +++ b/ext/rbu/sqlite3rbu.c @@ -199,6 +199,7 @@ typedef unsigned int u32; typedef unsigned short u16; typedef unsigned char u8; typedef sqlite3_int64 i64; +typedef sqlite3_uint64 u64; #endif /* @@ -885,6 +886,7 @@ static int rbuObjIterNext(sqlite3rbu *p, RbuObjIter *pIter){ if( rc!=SQLITE_ROW ){ rc = resetAndCollectError(pIter->pTblIter, &p->zErrmsg); pIter->zTbl = 0; + pIter->zDataTbl = 0; }else{ pIter->zTbl = (const char*)sqlite3_column_text(pIter->pTblIter, 0); pIter->zDataTbl = (const char*)sqlite3_column_text(pIter->pTblIter,1); @@ -2979,7 +2981,7 @@ static i64 rbuShmChecksum(sqlite3rbu *p){ u32 volatile *ptr; p->rc = pDb->pMethods->xShmMap(pDb, 0, 32*1024, 0, (void volatile**)&ptr); if( p->rc==SQLITE_OK ){ - iRet = ((i64)ptr[10] << 32) + ptr[11]; + iRet = (i64)(((u64)ptr[10] << 32) + ptr[11]); } } return iRet; diff --git a/ext/recover/dbdata.c b/ext/recover/dbdata.c index ca63710..109aeef 100644 --- a/ext/recover/dbdata.c +++ b/ext/recover/dbdata.c @@ -88,6 +88,15 @@ typedef unsigned int u32; typedef struct DbdataTable DbdataTable; typedef struct DbdataCursor DbdataCursor; +typedef struct DbdataBuffer DbdataBuffer; + +/* +** Buffer type. +*/ +struct DbdataBuffer { + u8 *aBuf; + sqlite3_int64 nBuf; +}; /* Cursor object */ struct DbdataCursor { @@ -104,7 +113,7 @@ struct DbdataCursor { sqlite3_int64 iRowid; /* Only for the sqlite_dbdata table */ - u8 *pRec; /* Buffer containing current record */ + DbdataBuffer rec; sqlite3_int64 nRec; /* Size of pRec[] in bytes */ sqlite3_int64 nHdr; /* Size of header in bytes */ int iField; /* Current field number */ @@ -150,6 +159,31 @@ struct DbdataTable { ")" /* +** Ensure the buffer passed as the first argument is at least nMin bytes +** in size. If an error occurs while attempting to resize the buffer, +** SQLITE_NOMEM is returned. Otherwise, SQLITE_OK. +*/ +static int dbdataBufferSize(DbdataBuffer *pBuf, sqlite3_int64 nMin){ + if( nMin>pBuf->nBuf ){ + sqlite3_int64 nNew = nMin+16384; + u8 *aNew = (u8*)sqlite3_realloc64(pBuf->aBuf, nNew); + + if( aNew==0 ) return SQLITE_NOMEM; + pBuf->aBuf = aNew; + pBuf->nBuf = nNew; + } + return SQLITE_OK; +} + +/* +** Release the allocation managed by buffer pBuf. +*/ +static void dbdataBufferFree(DbdataBuffer *pBuf){ + sqlite3_free(pBuf->aBuf); + memset(pBuf, 0, sizeof(*pBuf)); +} + +/* ** Connect to an sqlite_dbdata (pAux==0) or sqlite_dbptr (pAux!=0) virtual ** table. */ @@ -289,9 +323,9 @@ static void dbdataResetCursor(DbdataCursor *pCsr){ pCsr->iField = 0; pCsr->bOnePage = 0; sqlite3_free(pCsr->aPage); - sqlite3_free(pCsr->pRec); - pCsr->pRec = 0; + dbdataBufferFree(&pCsr->rec); pCsr->aPage = 0; + pCsr->nRec = 0; } /* @@ -433,63 +467,75 @@ static void dbdataValue( u8 *pData, sqlite3_int64 nData ){ - if( eType>=0 && dbdataValueBytes(eType)<=nData ){ - switch( eType ){ - case 0: - case 10: - case 11: - sqlite3_result_null(pCtx); - break; - - case 8: - sqlite3_result_int(pCtx, 0); - break; - case 9: - sqlite3_result_int(pCtx, 1); - break; - - case 1: case 2: case 3: case 4: case 5: case 6: case 7: { - sqlite3_uint64 v = (signed char)pData[0]; - pData++; - switch( eType ){ - case 7: - case 6: v = (v<<16) + (pData[0]<<8) + pData[1]; pData += 2; - case 5: v = (v<<16) + (pData[0]<<8) + pData[1]; pData += 2; - case 4: v = (v<<8) + pData[0]; pData++; - case 3: v = (v<<8) + pData[0]; pData++; - case 2: v = (v<<8) + pData[0]; pData++; - } - - if( eType==7 ){ - double r; - memcpy(&r, &v, sizeof(r)); - sqlite3_result_double(pCtx, r); - }else{ - sqlite3_result_int64(pCtx, (sqlite3_int64)v); + if( eType>=0 ){ + if( dbdataValueBytes(eType)<=nData ){ + switch( eType ){ + case 0: + case 10: + case 11: + sqlite3_result_null(pCtx); + break; + + case 8: + sqlite3_result_int(pCtx, 0); + break; + case 9: + sqlite3_result_int(pCtx, 1); + break; + + case 1: case 2: case 3: case 4: case 5: case 6: case 7: { + sqlite3_uint64 v = (signed char)pData[0]; + pData++; + switch( eType ){ + case 7: + case 6: v = (v<<16) + (pData[0]<<8) + pData[1]; pData += 2; + case 5: v = (v<<16) + (pData[0]<<8) + pData[1]; pData += 2; + case 4: v = (v<<8) + pData[0]; pData++; + case 3: v = (v<<8) + pData[0]; pData++; + case 2: v = (v<<8) + pData[0]; pData++; + } + + if( eType==7 ){ + double r; + memcpy(&r, &v, sizeof(r)); + sqlite3_result_double(pCtx, r); + }else{ + sqlite3_result_int64(pCtx, (sqlite3_int64)v); + } + break; } - break; - } - - default: { - int n = ((eType-12) / 2); - if( eType % 2 ){ - switch( enc ){ -#ifndef SQLITE_OMIT_UTF16 - case SQLITE_UTF16BE: - sqlite3_result_text16be(pCtx, (void*)pData, n, SQLITE_TRANSIENT); - break; - case SQLITE_UTF16LE: - sqlite3_result_text16le(pCtx, (void*)pData, n, SQLITE_TRANSIENT); - break; -#endif - default: - sqlite3_result_text(pCtx, (char*)pData, n, SQLITE_TRANSIENT); - break; + + default: { + int n = ((eType-12) / 2); + if( eType % 2 ){ + switch( enc ){ + #ifndef SQLITE_OMIT_UTF16 + case SQLITE_UTF16BE: + sqlite3_result_text16be(pCtx, (void*)pData, n, SQLITE_TRANSIENT); + break; + case SQLITE_UTF16LE: + sqlite3_result_text16le(pCtx, (void*)pData, n, SQLITE_TRANSIENT); + break; + #endif + default: + sqlite3_result_text(pCtx, (char*)pData, n, SQLITE_TRANSIENT); + break; + } + }else{ + sqlite3_result_blob(pCtx, pData, n, SQLITE_TRANSIENT); } - }else{ - sqlite3_result_blob(pCtx, pData, n, SQLITE_TRANSIENT); } } + }else{ + if( eType==7 ){ + sqlite3_result_double(pCtx, 0.0); + }else if( eType<7 ){ + sqlite3_result_int(pCtx, 0); + }else if( eType%2 ){ + sqlite3_result_text(pCtx, "", 0, SQLITE_STATIC); + }else{ + sqlite3_result_blob(pCtx, "", 0, SQLITE_STATIC); + } } } } @@ -551,7 +597,8 @@ static int dbdataNext(sqlite3_vtab_cursor *pCursor){ } }else{ /* If there is no record loaded, load it now. */ - if( pCsr->pRec==0 ){ + assert( pCsr->rec.aBuf!=0 || pCsr->nRec==0 ); + if( pCsr->nRec==0 ){ int bHasRowid = 0; int nPointer = 0; sqlite3_int64 nPayload = 0; @@ -595,6 +642,7 @@ static int dbdataNext(sqlite3_vtab_cursor *pCursor){ }else{ iOff += dbdataGetVarintU32(&pCsr->aPage[iOff], &nPayload); if( nPayload>0x7fffff00 ) nPayload &= 0x3fff; + if( nPayload==0 ) nPayload = 1; } /* If this is a leaf intkey cell, load the rowid */ @@ -629,13 +677,12 @@ static int dbdataNext(sqlite3_vtab_cursor *pCursor){ /* Allocate space for payload. And a bit more to catch small buffer ** overruns caused by attempting to read a varint or similar from ** near the end of a corrupt record. */ - pCsr->pRec = (u8*)sqlite3_malloc64(nPayload+DBDATA_PADDING_BYTES); - if( pCsr->pRec==0 ) return SQLITE_NOMEM; - memset(pCsr->pRec, 0, nPayload+DBDATA_PADDING_BYTES); - pCsr->nRec = nPayload; + rc = dbdataBufferSize(&pCsr->rec, nPayload+DBDATA_PADDING_BYTES); + if( rc!=SQLITE_OK ) return rc; + assert( nPayload!=0 ); /* Load the nLocal bytes of payload */ - memcpy(pCsr->pRec, &pCsr->aPage[iOff], nLocal); + memcpy(pCsr->rec.aBuf, &pCsr->aPage[iOff], nLocal); iOff += nLocal; /* Load content from overflow pages */ @@ -653,19 +700,22 @@ static int dbdataNext(sqlite3_vtab_cursor *pCursor){ nCopy = U-4; if( nCopy>nRem ) nCopy = nRem; - memcpy(&pCsr->pRec[nPayload-nRem], &aOvfl[4], nCopy); + memcpy(&pCsr->rec.aBuf[nPayload-nRem], &aOvfl[4], nCopy); nRem -= nCopy; pgnoOvfl = get_uint32(aOvfl); sqlite3_free(aOvfl); } + nPayload -= nRem; } + memset(&pCsr->rec.aBuf[nPayload], 0, DBDATA_PADDING_BYTES); + pCsr->nRec = nPayload; - iHdr = dbdataGetVarintU32(pCsr->pRec, &nHdr); + iHdr = dbdataGetVarintU32(pCsr->rec.aBuf, &nHdr); if( nHdr>nPayload ) nHdr = 0; pCsr->nHdr = nHdr; - pCsr->pHdrPtr = &pCsr->pRec[iHdr]; - pCsr->pPtr = &pCsr->pRec[pCsr->nHdr]; + pCsr->pHdrPtr = &pCsr->rec.aBuf[iHdr]; + pCsr->pPtr = &pCsr->rec.aBuf[pCsr->nHdr]; pCsr->iField = (bHasRowid ? -1 : 0); } } @@ -673,7 +723,7 @@ static int dbdataNext(sqlite3_vtab_cursor *pCursor){ pCsr->iField++; if( pCsr->iField>0 ){ sqlite3_int64 iType; - if( pCsr->pHdrPtr>=&pCsr->pRec[pCsr->nRec] + if( pCsr->pHdrPtr>=&pCsr->rec.aBuf[pCsr->nRec] || pCsr->iField>=DBDATA_MX_FIELD ){ bNextPage = 1; @@ -681,8 +731,8 @@ static int dbdataNext(sqlite3_vtab_cursor *pCursor){ int szField = 0; pCsr->pHdrPtr += dbdataGetVarintU32(pCsr->pHdrPtr, &iType); szField = dbdataValueBytes(iType); - if( (pCsr->nRec - (pCsr->pPtr - pCsr->pRec))<szField ){ - pCsr->pPtr = &pCsr->pRec[pCsr->nRec]; + if( (pCsr->nRec - (pCsr->pPtr - pCsr->rec.aBuf))<szField ){ + pCsr->pPtr = &pCsr->rec.aBuf[pCsr->nRec]; }else{ pCsr->pPtr += szField; } @@ -692,20 +742,18 @@ static int dbdataNext(sqlite3_vtab_cursor *pCursor){ if( bNextPage ){ sqlite3_free(pCsr->aPage); - sqlite3_free(pCsr->pRec); pCsr->aPage = 0; - pCsr->pRec = 0; + pCsr->nRec = 0; if( pCsr->bOnePage ) return SQLITE_OK; pCsr->iPgno++; }else{ - if( pCsr->iField<0 || pCsr->pHdrPtr<&pCsr->pRec[pCsr->nHdr] ){ + if( pCsr->iField<0 || pCsr->pHdrPtr<&pCsr->rec.aBuf[pCsr->nHdr] ){ return SQLITE_OK; } /* Advance to the next cell. The next iteration of the loop will load ** the record and so on. */ - sqlite3_free(pCsr->pRec); - pCsr->pRec = 0; + pCsr->nRec = 0; pCsr->iCell++; } } @@ -895,12 +943,12 @@ static int dbdataColumn( case DBDATA_COLUMN_VALUE: { if( pCsr->iField<0 ){ sqlite3_result_int64(ctx, pCsr->iIntkey); - }else if( &pCsr->pRec[pCsr->nRec] >= pCsr->pPtr ){ + }else if( &pCsr->rec.aBuf[pCsr->nRec] >= pCsr->pPtr ){ sqlite3_int64 iType; dbdataGetVarintU32(pCsr->pHdrPtr, &iType); dbdataValue( ctx, pCsr->enc, iType, pCsr->pPtr, - &pCsr->pRec[pCsr->nRec] - pCsr->pPtr + &pCsr->rec.aBuf[pCsr->nRec] - pCsr->pPtr ); } break; diff --git a/ext/recover/recover1.test b/ext/recover/recover1.test index 070dd03..11a4378 100644 --- a/ext/recover/recover1.test +++ b/ext/recover/recover1.test @@ -342,7 +342,7 @@ foreach enc {utf8 utf16 utf16le utf16be} { DELETE FROM sqlite_schema WHERE name='t1'; } - proc my_sql_hook {sql} { + proc my_sql_hook2 {sql} { if {[string match "INSERT INTO lostandfound*" $sql]} { lappend ::script $sql } @@ -350,7 +350,7 @@ foreach enc {utf8 utf16 utf16le utf16be} { } do_test 18.$enc.2 { set ::script [list] - set R [sqlite3_recover_init_sql db main my_sql_hook] + set R [sqlite3_recover_init_sql db main my_sql_hook2] $R config lostandfound lostandfound $R run $R finish @@ -358,7 +358,18 @@ foreach enc {utf8 utf16 utf16le utf16be} { } {{INSERT INTO lostandfound VALUES(2, 2, 2, 1, 'abc', 'def')}} } +#------------------------------------------------------------------------- +reset_db +do_execsql_test 19.0 { + CREATE TABLE t1(a INTEGER PRIMARY KEY, b TEXT); + INSERT INTO t1 VALUES(1, 'one'); + INSERT INTO t1 VALUES(2, 'two'); + + ALTER TABLE t1 ADD COLUMN c NOT NULL DEFAULT 13; + INSERT INTO t1 VALUES(3, 'three', 'hello world'); +} +do_recover_test 19.1 diff --git a/ext/recover/recovercorrupt3.test b/ext/recover/recovercorrupt3.test new file mode 100644 index 0000000..9a7c2d0 --- /dev/null +++ b/ext/recover/recovercorrupt3.test @@ -0,0 +1,549 @@ +# 2024 May 1 +# +# 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. +# +#*********************************************************************** +# + +source [file join [file dirname [info script]] recover_common.tcl] +set testprefix recovercorrupt3 + +#| 0: d5 d5 9b d5 d5 d5 d5 d5 d5 d5 d5 d5 d5 d5 d5 d5 ................ +#| 16: 04 00 00 00 1d 00 00 00 00 00 00 00 5f 5f 5f 5f ............____ +#| 32: 5f 5f 5f 5f 5f 5f 5f 5f 71 5f 5f 5f 02 02 02 02 ________q___.... +#| 48: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +#| 64: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +#| 80: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +#| 96: 02 02 02 02 + +#------------------------------------------------------------------------- +reset_db +do_test 1.0 { + sqlite3 db {} + db deserialize [decode_hexdb { +| size 3821 pagesize 1024 filename clusterfuzz-testcase-sql_recovery_fuzzer-5803962339885056 +| page 1 offset 0 +| 0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00 SQLite format 3. +| 16: 10 00 01 01 00 40 20 20 00 00 00 01 00 00 00 02 .....@ ........ +| 32: 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 04 ................ +| 48: 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00 ................ +| 80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 ................ +| 96: 00 2e 7a 70 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 112: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 128: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 144: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 160: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 176: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 192: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 208: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 224: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 240: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 256: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 272: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 288: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 304: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 320: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 336: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 352: 02 02 02 02 a0 02 02 02 02 02 02 02 02 02 02 02 ................ +| 368: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 384: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 400: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 416: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 432: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 448: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 29 29 ..............)) +| 464: 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 )))))))))))))))) +| 480: 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 )))))))))))))))) +| 496: 29 29 29 dd dd dd dd dd dd dd dd dd dd dd dd dd )))............. +| 512: dd dd dd dd dd dd dd dd dd 6e 69 d2 e9 e9 e9 d2 .........ni..... +| 528: d2 d2 d2 d2 dd dd dd dd dd dd dd dd dd dd dd dd ................ +| 544: dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd ................ +| 560: dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd ................ +| 576: dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd ................ +| 592: dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd ................ +| 608: dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd ................ +| 624: dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd ................ +| 640: dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd ................ +| 656: dd dd dd dd dd dd dd da dd dd dd dd dd dd dd dd ................ +| 672: dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd ................ +| 688: dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd ................ +| 704: dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd ................ +| 720: dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd ................ +| 736: dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd ................ +| 752: dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd ................ +| 768: dd dd dd dd dd dd dd dd dd dd dd dd dd 29 29 29 .............))) +| 784: 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 )))))))))))))))) +| 800: 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 )))))))))))))))) +| 816: 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 )))))))))))))))) +| 832: 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 )))))))))))))))) +| 848: 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 )))))))))))))))) +| 864: 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 )))))))))))))))) +| 880: 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 )))))))))))))))) +| 896: 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 )))))))))))))))) +| 912: 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 )))))))))))))))) +| 928: 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 )))))))))))))))) +| 944: 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 )))))))))))))))) +| 960: 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 )))))))))))))))) +| 976: 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 )))))))))))))))) +| 992: 29 29 29 29 29 29 29 29 29 29 dd dd dd dd dd dd ))))))))))...... +| 1008: dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd ................ +| page 2 offset 1024 +| 0: dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd ................ +| 16: dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd ................ +| 32: dd dd 6e 69 d2 e9 e9 e9 d2 d2 d2 d2 d2 dd dd dd ..ni............ +| 48: dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd ................ +| 64: dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd ................ +| 80: dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd ................ +| 96: dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd ................ +| 112: dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd ................ +| 128: dd dd dd dd dd dd 29 29 29 29 29 29 29 29 29 29 ......)))))))))) +| 144: 29 29 29 29 29 29 29 29 29 ad a5 29 29 29 29 00 )))))))))..)))). +| 160: 75 9c 11 00 5b e5 64 28 7c ca 09 69 28 2d 69 00 u...[.d(|..i(-i. +| 176: 85 88 6c 81 48 83 a0 93 c0 c0 82 8b 81 84 85 f9 ..l.H........... +| 192: 88 7a 00 7f 00 96 40 7b 12 4b 84 75 a0 00 99 a0 .z....@..K.u.... +| 208: df a0 7e 81 c6 90 8f 7f 84 85 cc 84 82 90 88 60 ..~............` +| 224: 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 ................ +| 240: 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 ................ +| 256: 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 ................ +| 272: 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 ................ +| 288: 80 80 80 80 80 80 80 80 80 80 80 80 80 80 02 02 ................ +| 304: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 320: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 336: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 352: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 368: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 384: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 400: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 416: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 432: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 448: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 464: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 480: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 496: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 512: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 528: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 544: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 560: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 576: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 592: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 608: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 624: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 640: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 656: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 672: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 688: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 704: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 720: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 736: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 752: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 768: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 784: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 800: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 816: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 832: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 848: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 864: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 880: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 896: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 912: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 928: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 944: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 960: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 976: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 992: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 1008: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| page 3 offset 2048 +| 0: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 16: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 32: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 48: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 64: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 80: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 96: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 112: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 128: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 144: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 160: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 176: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 192: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 208: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 224: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 240: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 256: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 272: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 288: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 304: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 320: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 336: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 352: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 368: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 384: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 400: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 416: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 432: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 448: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 464: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 480: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 496: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 512: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 528: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 544: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 560: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 576: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 592: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 608: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 624: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 640: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 656: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 672: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 688: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 704: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 720: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 736: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 752: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 768: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 784: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 800: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 816: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 832: 02 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 ................ +| 848: 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 ................ +| 864: 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 ................ +| 880: 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 ................ +| 896: 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 ................ +| 912: 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 ................ +| 928: 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 ................ +| 944: 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 ................ +| 960: 80 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 976: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 992: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 1008: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| page 4 offset 3072 +| 0: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 16: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 32: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 48: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 64: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 80: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 96: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 112: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 128: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 144: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 160: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 176: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 192: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 208: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 224: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 240: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 256: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 272: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 288: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 304: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 320: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 336: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 352: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 368: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 384: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 400: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 416: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 432: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 448: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 464: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 480: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 496: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 512: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 528: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 544: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 560: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 576: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 592: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 608: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 624: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 640: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 656: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 672: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 688: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 704: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 720: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 736: 5f 5f 5f 5f 5f 5f 5f 00 d5 fe fe fe 08 00 00 00 _______......... +| end clusterfuzz-testcase-sql_recovery_fuzzer-5803962339885056 +}]} {} + +sqlite3_dbdata_init db +do_execsql_test 1.1 { + PRAGMA writable_schema = 1; +} + +do_test 1.2 { + set R [sqlite3_recover_init db main test.db2] + $R run + $R finish +} {} + +#------------------------------------------------------------------------- +reset_db +do_test 2.0 { + sqlite3 db {} + db deserialize [decode_hexdb { +| size 3821 pagesize 1024 filename clusterfuzz-testcase-sql_recovery_fuzzer-5803962339885056 +| page 1 offset 0 +| 0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00 SQLite format 3. +| 16: 04 00 01 01 00 40 20 20 00 00 00 01 00 00 00 02 .....@ ........ +| 32: 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 04 ................ +| 48: 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00 ................ +| 80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 ................ +| 96: 00 2e 7a 70 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 112: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 128: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 144: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 160: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 176: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 192: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 208: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 224: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 240: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 256: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 272: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 288: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 304: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 320: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 336: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 352: 02 02 02 02 a0 02 02 02 02 02 02 02 02 02 02 02 ................ +| 368: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 384: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 400: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 416: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 432: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 448: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 29 29 ..............)) +| 464: 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 )))))))))))))))) +| 480: 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 )))))))))))))))) +| 496: 29 29 29 dd dd dd dd dd dd dd dd dd dd dd dd dd )))............. +| 512: dd dd dd dd dd dd dd dd dd 6e 69 d2 e9 e9 e9 d2 .........ni..... +| 528: d2 d2 d2 d2 dd dd dd dd dd dd dd dd dd dd dd dd ................ +| 544: dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd ................ +| 560: dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd ................ +| 576: dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd ................ +| 592: dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd ................ +| 608: dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd ................ +| 624: dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd ................ +| 640: dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd ................ +| 656: dd dd dd dd dd dd dd da dd dd dd dd dd dd dd dd ................ +| 672: dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd ................ +| 688: dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd ................ +| 704: dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd ................ +| 720: dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd ................ +| 736: dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd ................ +| 752: dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd ................ +| 768: dd dd dd dd dd dd dd dd dd dd dd dd dd 29 29 29 .............))) +| 784: 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 )))))))))))))))) +| 800: 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 )))))))))))))))) +| 816: 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 )))))))))))))))) +| 832: 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 )))))))))))))))) +| 848: 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 )))))))))))))))) +| 864: 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 )))))))))))))))) +| 880: 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 )))))))))))))))) +| 896: 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 )))))))))))))))) +| 912: 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 )))))))))))))))) +| 928: 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 )))))))))))))))) +| 944: 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 )))))))))))))))) +| 960: 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 )))))))))))))))) +| 976: 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 )))))))))))))))) +| 992: 29 29 29 29 29 29 29 29 29 29 dd dd dd dd dd dd ))))))))))...... +| 1008: dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd ................ +| page 2 offset 1024 +| 0: dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd ................ +| 16: dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd ................ +| 32: dd dd 6e 69 d2 e9 e9 e9 d2 d2 d2 d2 d2 dd dd dd ..ni............ +| 48: dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd ................ +| 64: dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd ................ +| 80: dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd ................ +| 96: dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd ................ +| 112: dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd ................ +| 128: dd dd dd dd dd dd 29 29 29 29 29 29 29 29 29 29 ......)))))))))) +| 144: 29 29 29 29 29 29 29 29 29 ad a5 29 29 29 29 00 )))))))))..)))). +| 160: 75 9c 11 00 5b e5 64 28 7c ca 09 69 28 2d 69 00 u...[.d(|..i(-i. +| 176: 85 88 6c 81 48 83 a0 93 c0 c0 82 8b 81 84 85 f9 ..l.H........... +| 192: 88 7a 00 7f 00 96 40 7b 12 4b 84 75 a0 00 99 a0 .z....@..K.u.... +| 208: df a0 7e 81 c6 90 8f 7f 84 85 cc 84 82 90 88 60 ..~............` +| 224: 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 ................ +| 240: 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 ................ +| 256: 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 ................ +| 272: 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 ................ +| 288: 80 80 80 80 80 80 80 80 80 80 80 80 80 80 02 02 ................ +| 304: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 320: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 336: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 352: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 368: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 384: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 400: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 416: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 432: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 448: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 464: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 480: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 496: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 512: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 528: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 544: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 560: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 576: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 592: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 608: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 624: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 640: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 656: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 672: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 688: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 704: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 720: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 736: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 752: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 768: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 784: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 800: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 816: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 832: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 848: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 864: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 880: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 896: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 912: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 928: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 944: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 960: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 976: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 992: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 1008: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| page 3 offset 2048 +| 0: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 16: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 32: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 48: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 64: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 80: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 96: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 112: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 128: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 144: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 160: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 176: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 192: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 208: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 224: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 240: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 256: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 272: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 288: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 304: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 320: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 336: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 352: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 368: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 384: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 400: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 416: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 432: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 448: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 464: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 480: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 496: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 512: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 528: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 544: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 560: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 576: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 592: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 608: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 624: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 640: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 656: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 672: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 688: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 704: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 720: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 736: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 752: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 768: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 784: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 800: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 816: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 832: 02 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 ................ +| 848: 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 ................ +| 864: 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 ................ +| 880: 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 ................ +| 896: 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 ................ +| 912: 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 ................ +| 928: 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 ................ +| 944: 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 ................ +| 960: 80 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 976: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 992: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 1008: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| page 4 offset 3072 +| 0: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 16: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 32: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 48: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 64: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 80: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 96: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 112: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 128: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 144: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 160: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 176: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 192: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 208: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 224: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 240: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 256: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 272: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 288: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 304: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 320: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 336: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 352: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 368: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 384: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 400: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 416: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 432: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 448: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 464: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 480: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 496: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 512: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 528: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 544: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 560: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 576: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 592: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 608: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 624: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 640: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 656: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 672: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 688: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 704: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 720: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................ +| 736: 5f 5f 5f 5f 5f 5f 5f 00 d5 fe fe fe 08 00 00 00 _______......... +| end clusterfuzz-testcase-sql_recovery_fuzzer-5803962339885056 +}]} {} + +sqlite3_dbdata_init db +do_execsql_test 2.1 { + PRAGMA writable_schema = 1; +} + +do_test 2.2 { + set R [sqlite3_recover_init db main test.db2] + $R run + $R finish +} {} + +finish_test + diff --git a/ext/recover/recovercorrupt4.test b/ext/recover/recovercorrupt4.test new file mode 100644 index 0000000..0ff0b50 --- /dev/null +++ b/ext/recover/recovercorrupt4.test @@ -0,0 +1,64 @@ +# 2024 May 15 +# +# 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. +# +#*********************************************************************** +# + +source [file join [file dirname [info script]] recover_common.tcl] +set testprefix recovercorrupt4 + +database_may_be_corrupt + +if {[permutation]!="inmemory_journal"} { + # This test cannot be run with the inmemory_journal permutation, as it + # must open a truncated, corrupt, database file. With the inmemory_journal + # permutation, this fails (SQLITE_CORRUPT error) when the [sqlite3] wrapper + # executes "PRAGMA journal_mode = memory". + do_execsql_test 1.0 { + CREATE TABLE rows(indexed INTEGER NOT NULL, unindexed INTEGER NOT NULL, filler BLOB NOT NULL DEFAULT 13); + -- CREATE UNIQUE INDEX rows_index ON rows(indexed); + INSERT INTO rows(indexed, unindexed, filler) VALUES(1, 1, x'31'); + INSERT INTO rows(indexed, unindexed, filler) VALUES(2, 2, x'32'); + INSERT INTO rows(indexed, unindexed, filler) VALUES(4, 4, x'34'); + INSERT INTO rows(indexed, unindexed, filler) VALUES(8, 8, randomblob(2048)); + } + + db close + + do_test 1.1 { + set sz [expr [file size test.db] - 1024] + set fd [open test.db] + fconfigure $fd -encoding binary -translation binary + + set data [read $fd $sz] + set fd2 [open test.db2 w] + fconfigure $fd2 -encoding binary -translation binary + puts -nonewline $fd2 $data + close $fd2 + set {} {} + } {} + + do_test 1.2 { + forcedelete test.db3 + sqlite3 db test.db2 + set R [sqlite3_recover_init db main test.db3] + $R run + $R finish + } {} + + do_test 1.3 { + sqlite3 db test.db3 + execsql { + SELECT indexed, unindexed FROM rows + } + } {1 1 2 2 4 4 8 8} +} + +finish_test + diff --git a/ext/rtree/rtree.c b/ext/rtree/rtree.c index 02127fa..299b5b5 100644 --- a/ext/rtree/rtree.c +++ b/ext/rtree/rtree.c @@ -1841,6 +1841,8 @@ static int deserializeGeometry(sqlite3_value *pValue, RtreeConstraint *pCons){ return SQLITE_OK; } +int sqlite3IntFloatCompare(i64,double); + /* ** Rtree virtual table module xFilter method. */ @@ -1870,7 +1872,8 @@ static int rtreeFilter( i64 iNode = 0; int eType = sqlite3_value_numeric_type(argv[0]); if( eType==SQLITE_INTEGER - || (eType==SQLITE_FLOAT && sqlite3_value_double(argv[0])==iRowid) + || (eType==SQLITE_FLOAT + && 0==sqlite3IntFloatCompare(iRowid,sqlite3_value_double(argv[0]))) ){ rc = findLeafNode(pRtree, iRowid, &pLeaf, &iNode); }else{ @@ -3225,6 +3228,7 @@ constraint: */ static int rtreeBeginTransaction(sqlite3_vtab *pVtab){ Rtree *pRtree = (Rtree *)pVtab; + assert( pRtree->inWrTrans==0 ); pRtree->inWrTrans = 1; return SQLITE_OK; } diff --git a/ext/rtree/rtree1.test b/ext/rtree/rtree1.test index 61664e1..e596df7 100644 --- a/ext/rtree/rtree1.test +++ b/ext/rtree/rtree1.test @@ -797,4 +797,22 @@ do_test 23.0 { db eval {PRAGMA integrity_check;} } {ok} +reset_db +do_execsql_test 24.0 { + CREATE VIRTUAL TABLE rt1 USING rtree_i32(rid, c1, c2); + INSERT INTO rt1(rid, c1, c2) VALUES (9223372036854775807, 10, 18); +} + +do_execsql_test 24.1 { + SELECT (rid = (CAST (9223372036854775807 AS REAL))) + FROM rt1 WHERE + (rid = (CAST (9223372036854775807 AS REAL))); +} + +do_execsql_test 24.2 { + DELETE FROM rt1; + INSERT INTO rt1(rid, c1, c2) VALUES(1,2,3); + SELECT * FROM rt1 WHERE rid=1.005; +} {} + finish_test diff --git a/ext/session/sessionchange.test b/ext/session/sessionchange.test new file mode 100644 index 0000000..c1c2862 --- /dev/null +++ b/ext/session/sessionchange.test @@ -0,0 +1,101 @@ +# 2011 March 07 +# +# 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. +# + +if {![info exists testdir]} { + set testdir [file join [file dirname [info script]] .. .. test] +} +source [file join [file dirname [info script]] session_common.tcl] +source $testdir/tester.tcl +ifcapable !session {finish_test; return} + +set testprefix sessionchange + +do_execsql_test 1.0 { + CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c); +} + +do_test 1.1 { + set C [changeset_from_sql { + INSERT INTO t1 VALUES(1, 2, 3); + INSERT INTO t1 VALUES(10, 20, 30); + }] + + set res [list] + set iter [sqlite3changeset_start $C] + while {[$iter next]=="SQLITE_ROW"} { + lappend res [$iter data] + } + $iter finalize + + set res +} [list \ + {INSERT t1 0 X.. {} {i 10 i 20 i 30}} \ + {INSERT t1 0 X.. {} {i 1 i 2 i 3}} \ +] + + +do_test 1.2 { + sqlite3changegroup grp + set iter [sqlite3changeset_start $C] + while {[$iter next]=="SQLITE_ROW"} { + grp add_change $iter + } + $iter finalize + + set res [list] + grp output + sqlite3session_foreach c [grp output] { lappend res $c } + grp delete + set res +} [list \ + {INSERT t1 0 X.. {} {i 10 i 20 i 30}} \ + {INSERT t1 0 X.. {} {i 1 i 2 i 3}} \ +] + +do_test 1.3.1 { + set iter [sqlite3changeset_start $C] + sqlite3changegroup grp + list [catch { grp add_change $iter } msg] $msg +} {1 SQLITE_ERROR} +do_test 1.3.2 { + while {[$iter next]=="SQLITE_ROW"} { } + list [catch { grp add_change $iter } msg] $msg +} {1 SQLITE_ERROR} +grp delete +$iter finalize + +do_test 1.4 { + set res [list] + set iter [sqlite3changeset_start -invert $C] + while {[$iter next]=="SQLITE_ROW"} { + lappend res [$iter data] + } + $iter finalize + set res +} [list \ + {DELETE t1 0 X.. {i 10 i 20 i 30} {}} \ + {DELETE t1 0 X.. {i 1 i 2 i 3} {}} \ +] + +do_test 1.5 { + sqlite3changegroup grp + set iter [sqlite3changeset_start -invert $C] + $iter next + list [catch { grp add_change $iter } msg] $msg +} {1 SQLITE_ERROR} +$iter finalize +grp delete + + + +finish_test diff --git a/ext/session/sessionconflict.test b/ext/session/sessionconflict.test new file mode 100644 index 0000000..25b2602 --- /dev/null +++ b/ext/session/sessionconflict.test @@ -0,0 +1,76 @@ +# 2011 March 07 +# +# 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. +# + +if {![info exists testdir]} { + set testdir [file join [file dirname [info script]] .. .. test] +} +source [file join [file dirname [info script]] session_common.tcl] +source $testdir/tester.tcl +ifcapable !session {finish_test; return} + +set testprefix sessionconflict + +db close +sqlite3_shutdown +test_sqlite3_log log +proc log {code msg} { puts "LOG $code $msg" } +sqlite3 db test.db + +forcedelete test.db2 +sqlite3 db2 test.db2 + +do_test 1.0 { + do_common_sql { + CREATE TABLE t1(a PRIMARY KEY, b, c UNIQUE); + INSERT INTO t1 VALUES(1, 1, 1); + INSERT INTO t1 VALUES(2, 2, 2); + INSERT INTO t1 VALUES(3, 3, 3); + } +} {} + +do_execsql_test -db db2 1.1 { + INSERT INTO t1 VALUES(6, 6, 6); +} + +proc xConflict {args} { + return "ABORT" +} + + +do_test 1.2 { + set chng [changeset_from_sql { + UPDATE t1 SET b=10, c=10 WHERE a=1; + UPDATE t1 SET b=444 WHERE a=2; + INSERT INTO t1 VALUES(4, 4, 4); + INSERT INTO t1 VALUES(5, 5, 5); + INSERT INTO t1 VALUES(6, 6, 6); + }] + + execsql BEGIN db2 + set res [list [catch { sqlite3changeset_apply db2 $chng xConflict } msg] $msg] + execsql ROLLBACK db2 + set res +} {1 SQLITE_ABORT} + +do_execsql_test -db db2 1.3 { + SELECT * FROM t1; +} { + 1 1 1 + 2 2 2 + 3 3 3 + 6 6 6 +} + + + +finish_test diff --git a/ext/session/sessionstat1.test b/ext/session/sessionstat1.test index 2757d60..16dc4e2 100644 --- a/ext/session/sessionstat1.test +++ b/ext/session/sessionstat1.test @@ -92,7 +92,7 @@ do_test 2.1 { } {} do_execsql_test -db db2 2.2 { - SELECT * FROM sqlite_stat1 + SELECT * FROM sqlite_stat1 ORDER BY tbl, idx } { t1 sqlite_autoindex_t1_1 {32 1} t1 t1b {32 4} @@ -104,7 +104,7 @@ do_test 2.3 { } {} do_execsql_test -db db2 2.4 { - SELECT * FROM sqlite_stat1 + SELECT * FROM sqlite_stat1 ORDER BY tbl, idx; } { t1 sqlite_autoindex_t1_1 {32 1} t1 t1b {32 4} diff --git a/ext/session/sqlite3session.c b/ext/session/sqlite3session.c index acb9451..7a8132b 100644 --- a/ext/session/sqlite3session.c +++ b/ext/session/sqlite3session.c @@ -3685,14 +3685,14 @@ static int sessionChangesetNextOne( p->rc = sessionInputBuffer(&p->in, 2); if( p->rc!=SQLITE_OK ) return p->rc; + sessionDiscardData(&p->in); + p->in.iCurrent = p->in.iNext; + /* If the iterator is already at the end of the changeset, return DONE. */ if( p->in.iNext>=p->in.nData ){ return SQLITE_DONE; } - sessionDiscardData(&p->in); - p->in.iCurrent = p->in.iNext; - op = p->in.aData[p->in.iNext++]; while( op=='T' || op=='P' ){ if( pbNew ) *pbNew = 1; @@ -5427,6 +5427,7 @@ struct sqlite3_changegroup { int rc; /* Error code */ int bPatch; /* True to accumulate patchsets */ SessionTable *pList; /* List of tables in current patch */ + SessionBuffer rec; sqlite3 *db; /* Configured by changegroup_schema() */ char *zDb; /* Configured by changegroup_schema() */ @@ -5725,108 +5726,128 @@ static int sessionChangesetExtendRecord( } /* -** Add all changes in the changeset traversed by the iterator passed as -** the first argument to the changegroup hash tables. +** Locate or create a SessionTable object that may be used to add the +** change currently pointed to by iterator pIter to changegroup pGrp. +** If successful, set output variable (*ppTab) to point to the table +** object and return SQLITE_OK. Otherwise, if some error occurs, return +** an SQLite error code and leave (*ppTab) set to NULL. */ -static int sessionChangesetToHash( - sqlite3_changeset_iter *pIter, /* Iterator to read from */ - sqlite3_changegroup *pGrp, /* Changegroup object to add changeset to */ - int bRebase /* True if hash table is for rebasing */ +static int sessionChangesetFindTable( + sqlite3_changegroup *pGrp, + const char *zTab, + sqlite3_changeset_iter *pIter, + SessionTable **ppTab ){ - u8 *aRec; - int nRec; int rc = SQLITE_OK; SessionTable *pTab = 0; - SessionBuffer rec = {0, 0, 0}; + int nTab = (int)strlen(zTab); + u8 *abPK = 0; + int nCol = 0; - while( SQLITE_ROW==sessionChangesetNext(pIter, &aRec, &nRec, 0) ){ - const char *zNew; - int nCol; - int op; - int iHash; - int bIndirect; - SessionChange *pChange; - SessionChange *pExist = 0; - SessionChange **pp; - - /* Ensure that only changesets, or only patchsets, but not a mixture - ** of both, are being combined. It is an error to try to combine a - ** changeset and a patchset. */ - if( pGrp->pList==0 ){ - pGrp->bPatch = pIter->bPatchset; - }else if( pIter->bPatchset!=pGrp->bPatch ){ - rc = SQLITE_ERROR; - break; - } + *ppTab = 0; + sqlite3changeset_pk(pIter, &abPK, &nCol); - sqlite3changeset_op(pIter, &zNew, &nCol, &op, &bIndirect); - if( !pTab || sqlite3_stricmp(zNew, pTab->zName) ){ - /* Search the list for a matching table */ - int nNew = (int)strlen(zNew); - u8 *abPK; + /* Search the list for an existing table */ + for(pTab = pGrp->pList; pTab; pTab=pTab->pNext){ + if( 0==sqlite3_strnicmp(pTab->zName, zTab, nTab+1) ) break; + } - sqlite3changeset_pk(pIter, &abPK, 0); - for(pTab = pGrp->pList; pTab; pTab=pTab->pNext){ - if( 0==sqlite3_strnicmp(pTab->zName, zNew, nNew+1) ) break; + /* If one was not found above, create a new table now */ + if( !pTab ){ + SessionTable **ppNew; + + pTab = sqlite3_malloc64(sizeof(SessionTable) + nCol + nTab+1); + if( !pTab ){ + return SQLITE_NOMEM; + } + memset(pTab, 0, sizeof(SessionTable)); + pTab->nCol = nCol; + pTab->abPK = (u8*)&pTab[1]; + memcpy(pTab->abPK, abPK, nCol); + pTab->zName = (char*)&pTab->abPK[nCol]; + memcpy(pTab->zName, zTab, nTab+1); + + if( pGrp->db ){ + pTab->nCol = 0; + rc = sessionInitTable(0, pTab, pGrp->db, pGrp->zDb); + if( rc ){ + assert( pTab->azCol==0 ); + sqlite3_free(pTab); + return rc; } - if( !pTab ){ - SessionTable **ppTab; + } - pTab = sqlite3_malloc64(sizeof(SessionTable) + nCol + nNew+1); - if( !pTab ){ - rc = SQLITE_NOMEM; - break; - } - memset(pTab, 0, sizeof(SessionTable)); - pTab->nCol = nCol; - pTab->abPK = (u8*)&pTab[1]; - memcpy(pTab->abPK, abPK, nCol); - pTab->zName = (char*)&pTab->abPK[nCol]; - memcpy(pTab->zName, zNew, nNew+1); - - if( pGrp->db ){ - pTab->nCol = 0; - rc = sessionInitTable(0, pTab, pGrp->db, pGrp->zDb); - if( rc ){ - assert( pTab->azCol==0 ); - sqlite3_free(pTab); - break; - } - } + /* The new object must be linked on to the end of the list, not + ** simply added to the start of it. This is to ensure that the + ** tables within the output of sqlite3changegroup_output() are in + ** the right order. */ + for(ppNew=&pGrp->pList; *ppNew; ppNew=&(*ppNew)->pNext); + *ppNew = pTab; + } - /* The new object must be linked on to the end of the list, not - ** simply added to the start of it. This is to ensure that the - ** tables within the output of sqlite3changegroup_output() are in - ** the right order. */ - for(ppTab=&pGrp->pList; *ppTab; ppTab=&(*ppTab)->pNext); - *ppTab = pTab; - } + /* Check that the table is compatible. */ + if( !sessionChangesetCheckCompat(pTab, nCol, abPK) ){ + rc = SQLITE_SCHEMA; + } - if( !sessionChangesetCheckCompat(pTab, nCol, abPK) ){ - rc = SQLITE_SCHEMA; - break; - } - } + *ppTab = pTab; + return rc; +} - if( nCol<pTab->nCol ){ - assert( pGrp->db ); - rc = sessionChangesetExtendRecord(pGrp, pTab, nCol, op, aRec, nRec, &rec); - if( rc ) break; - aRec = rec.aBuf; - nRec = rec.nBuf; - } +/* +** Add the change currently indicated by iterator pIter to the hash table +** belonging to changegroup pGrp. +*/ +static int sessionOneChangeToHash( + sqlite3_changegroup *pGrp, + sqlite3_changeset_iter *pIter, + int bRebase +){ + int rc = SQLITE_OK; + int nCol = 0; + int op = 0; + int iHash = 0; + int bIndirect = 0; + SessionChange *pChange = 0; + SessionChange *pExist = 0; + SessionChange **pp = 0; + SessionTable *pTab = 0; + u8 *aRec = &pIter->in.aData[pIter->in.iCurrent + 2]; + int nRec = (pIter->in.iNext - pIter->in.iCurrent) - 2; - if( sessionGrowHash(0, pIter->bPatchset, pTab) ){ - rc = SQLITE_NOMEM; - break; - } + /* Ensure that only changesets, or only patchsets, but not a mixture + ** of both, are being combined. It is an error to try to combine a + ** changeset and a patchset. */ + if( pGrp->pList==0 ){ + pGrp->bPatch = pIter->bPatchset; + }else if( pIter->bPatchset!=pGrp->bPatch ){ + rc = SQLITE_ERROR; + } + + if( rc==SQLITE_OK ){ + const char *zTab = 0; + sqlite3changeset_op(pIter, &zTab, &nCol, &op, &bIndirect); + rc = sessionChangesetFindTable(pGrp, zTab, pIter, &pTab); + } + + if( rc==SQLITE_OK && nCol<pTab->nCol ){ + SessionBuffer *pBuf = &pGrp->rec; + rc = sessionChangesetExtendRecord(pGrp, pTab, nCol, op, aRec, nRec, pBuf); + aRec = pBuf->aBuf; + nRec = pBuf->nBuf; + assert( pGrp->db ); + } + + if( rc==SQLITE_OK && sessionGrowHash(0, pIter->bPatchset, pTab) ){ + rc = SQLITE_NOMEM; + } + + if( rc==SQLITE_OK ){ + /* Search for existing entry. If found, remove it from the hash table. + ** Code below may link it back in. */ iHash = sessionChangeHash( pTab, (pIter->bPatchset && op==SQLITE_DELETE), aRec, pTab->nChange ); - - /* Search for existing entry. If found, remove it from the hash table. - ** Code below may link it back in. - */ for(pp=&pTab->apChange[iHash]; *pp; pp=&(*pp)->pNext){ int bPkOnly1 = 0; int bPkOnly2 = 0; @@ -5841,19 +5862,41 @@ static int sessionChangesetToHash( break; } } + } + if( rc==SQLITE_OK ){ rc = sessionChangeMerge(pTab, bRebase, pIter->bPatchset, pExist, op, bIndirect, aRec, nRec, &pChange ); - if( rc ) break; - if( pChange ){ - pChange->pNext = pTab->apChange[iHash]; - pTab->apChange[iHash] = pChange; - pTab->nEntry++; - } + } + if( rc==SQLITE_OK && pChange ){ + pChange->pNext = pTab->apChange[iHash]; + pTab->apChange[iHash] = pChange; + pTab->nEntry++; + } + + if( rc==SQLITE_OK ) rc = pIter->rc; + return rc; +} + +/* +** Add all changes in the changeset traversed by the iterator passed as +** the first argument to the changegroup hash tables. +*/ +static int sessionChangesetToHash( + sqlite3_changeset_iter *pIter, /* Iterator to read from */ + sqlite3_changegroup *pGrp, /* Changegroup object to add changeset to */ + int bRebase /* True if hash table is for rebasing */ +){ + u8 *aRec; + int nRec; + int rc = SQLITE_OK; + + while( SQLITE_ROW==(sessionChangesetNext(pIter, &aRec, &nRec, 0)) ){ + rc = sessionOneChangeToHash(pGrp, pIter, bRebase); + if( rc!=SQLITE_OK ) break; } - sqlite3_free(rec.aBuf); if( rc==SQLITE_OK ) rc = pIter->rc; return rc; } @@ -5982,6 +6025,23 @@ int sqlite3changegroup_add(sqlite3_changegroup *pGrp, int nData, void *pData){ } /* +** Add a single change to a changeset-group. +*/ +int sqlite3changegroup_add_change( + sqlite3_changegroup *pGrp, + sqlite3_changeset_iter *pIter +){ + if( pIter->in.iCurrent==pIter->in.iNext + || pIter->rc!=SQLITE_OK + || pIter->bInvert + ){ + /* Iterator does not point to any valid entry or is an INVERT iterator. */ + return SQLITE_ERROR; + } + return sessionOneChangeToHash(pGrp, pIter, 0); +} + +/* ** Obtain a buffer containing a changeset representing the concatenation ** of all changesets added to the group so far. */ @@ -6030,6 +6090,7 @@ void sqlite3changegroup_delete(sqlite3_changegroup *pGrp){ if( pGrp ){ sqlite3_free(pGrp->zDb); sessionDeleteTable(0, pGrp->pList); + sqlite3_free(pGrp->rec.aBuf); sqlite3_free(pGrp); } } @@ -6431,6 +6492,7 @@ int sqlite3rebaser_rebase_strm( void sqlite3rebaser_delete(sqlite3_rebaser *p){ if( p ){ sessionDeleteTable(0, p->grp.pList); + sqlite3_free(p->grp.rec.aBuf); sqlite3_free(p); } } diff --git a/ext/session/sqlite3session.h b/ext/session/sqlite3session.h index 160ea87..f950d41 100644 --- a/ext/session/sqlite3session.h +++ b/ext/session/sqlite3session.h @@ -1058,6 +1058,30 @@ int sqlite3changegroup_schema(sqlite3_changegroup*, sqlite3*, const char *zDb); int sqlite3changegroup_add(sqlite3_changegroup*, int nData, void *pData); /* +** CAPI3REF: Add A Single Change To A Changegroup +** METHOD: sqlite3_changegroup +** +** This function adds the single change currently indicated by the iterator +** passed as the second argument to the changegroup object. The rules for +** adding the change are just as described for [sqlite3changegroup_add()]. +** +** If the change is successfully added to the changegroup, SQLITE_OK is +** returned. Otherwise, an SQLite error code is returned. +** +** The iterator must point to a valid entry when this function is called. +** If it does not, SQLITE_ERROR is returned and no change is added to the +** changegroup. Additionally, the iterator must not have been opened with +** the SQLITE_CHANGESETAPPLY_INVERT flag. In this case SQLITE_ERROR is also +** returned. +*/ +int sqlite3changegroup_add_change( + sqlite3_changegroup*, + sqlite3_changeset_iter* +); + + + +/* ** CAPI3REF: Obtain A Composite Changeset From A Changegroup ** METHOD: sqlite3_changegroup ** diff --git a/ext/session/test_session.c b/ext/session/test_session.c index af42351..00c3c25 100644 --- a/ext/session/test_session.c +++ b/ext/session/test_session.c @@ -1038,6 +1038,64 @@ static int SQLITE_TCLAPI test_sqlite3changeset_concat( return rc; } +static Tcl_Obj *testIterData(sqlite3_changeset_iter *pIter){ + Tcl_Obj *pVar = 0; + int nCol; /* Number of columns in table */ + int nCol2; /* Number of columns in table */ + int op; /* SQLITE_INSERT, UPDATE or DELETE */ + const char *zTab; /* Name of table change applies to */ + Tcl_Obj *pOld; /* Vector of old.* values */ + Tcl_Obj *pNew; /* Vector of new.* values */ + int bIndirect; + + char *zPK; + unsigned char *abPK; + int i; + + sqlite3changeset_op(pIter, &zTab, &nCol, &op, &bIndirect); + pVar = Tcl_NewObj(); + + Tcl_ListObjAppendElement(0, pVar, Tcl_NewStringObj( + op==SQLITE_INSERT ? "INSERT" : + op==SQLITE_UPDATE ? "UPDATE" : + "DELETE", -1 + )); + + Tcl_ListObjAppendElement(0, pVar, Tcl_NewStringObj(zTab, -1)); + Tcl_ListObjAppendElement(0, pVar, Tcl_NewBooleanObj(bIndirect)); + + zPK = ckalloc(nCol+1); + memset(zPK, 0, nCol+1); + sqlite3changeset_pk(pIter, &abPK, &nCol2); + assert( nCol==nCol2 ); + for(i=0; i<nCol; i++){ + zPK[i] = (abPK[i] ? 'X' : '.'); + } + Tcl_ListObjAppendElement(0, pVar, Tcl_NewStringObj(zPK, -1)); + ckfree(zPK); + + pOld = Tcl_NewObj(); + if( op!=SQLITE_INSERT ){ + for(i=0; i<nCol; i++){ + sqlite3_value *pVal; + sqlite3changeset_old(pIter, i, &pVal); + test_append_value(pOld, pVal); + } + } + pNew = Tcl_NewObj(); + if( op!=SQLITE_DELETE ){ + for(i=0; i<nCol; i++){ + sqlite3_value *pVal; + sqlite3changeset_new(pIter, i, &pVal); + test_append_value(pNew, pVal); + } + } + Tcl_ListObjAppendElement(0, pVar, pOld); + Tcl_ListObjAppendElement(0, pVar, pNew); + + return pVar; +} + /* ** sqlite3session_foreach VARNAME CHANGESET SCRIPT */ @@ -1111,67 +1169,8 @@ static int SQLITE_TCLAPI test_sqlite3session_foreach( } while( SQLITE_ROW==sqlite3changeset_next(pIter) ){ - int nCol; /* Number of columns in table */ - int nCol2; /* Number of columns in table */ - int op; /* SQLITE_INSERT, UPDATE or DELETE */ - const char *zTab; /* Name of table change applies to */ - Tcl_Obj *pVar; /* Tcl value to set $VARNAME to */ - Tcl_Obj *pOld; /* Vector of old.* values */ - Tcl_Obj *pNew; /* Vector of new.* values */ - int bIndirect; - - char *zPK; - unsigned char *abPK; - int i; - - /* Test that _fk_conflicts() returns SQLITE_MISUSE if called on this - ** iterator. */ - int nDummy; - if( SQLITE_MISUSE!=sqlite3changeset_fk_conflicts(pIter, &nDummy) ){ - sqlite3changeset_finalize(pIter); - return TCL_ERROR; - } - - sqlite3changeset_op(pIter, &zTab, &nCol, &op, &bIndirect); - pVar = Tcl_NewObj(); - Tcl_ListObjAppendElement(0, pVar, Tcl_NewStringObj( - op==SQLITE_INSERT ? "INSERT" : - op==SQLITE_UPDATE ? "UPDATE" : - "DELETE", -1 - )); - - Tcl_ListObjAppendElement(0, pVar, Tcl_NewStringObj(zTab, -1)); - Tcl_ListObjAppendElement(0, pVar, Tcl_NewBooleanObj(bIndirect)); - - zPK = ckalloc(nCol+1); - memset(zPK, 0, nCol+1); - sqlite3changeset_pk(pIter, &abPK, &nCol2); - assert( nCol==nCol2 ); - for(i=0; i<nCol; i++){ - zPK[i] = (abPK[i] ? 'X' : '.'); - } - Tcl_ListObjAppendElement(0, pVar, Tcl_NewStringObj(zPK, -1)); - ckfree(zPK); - - pOld = Tcl_NewObj(); - if( op!=SQLITE_INSERT ){ - for(i=0; i<nCol; i++){ - sqlite3_value *pVal; - sqlite3changeset_old(pIter, i, &pVal); - test_append_value(pOld, pVal); - } - } - pNew = Tcl_NewObj(); - if( op!=SQLITE_DELETE ){ - for(i=0; i<nCol; i++){ - sqlite3_value *pVal; - sqlite3changeset_new(pIter, i, &pVal); - test_append_value(pNew, pVal); - } - } - Tcl_ListObjAppendElement(0, pVar, pOld); - Tcl_ListObjAppendElement(0, pVar, pNew); - + Tcl_Obj *pVar = 0; /* Tcl value to set $VARNAME to */ + pVar = testIterData(pIter); Tcl_ObjSetVar2(interp, pVarname, 0, pVar, 0); rc = Tcl_EvalObjEx(interp, pScript, 0); if( rc!=TCL_OK && rc!=TCL_CONTINUE ){ @@ -1459,6 +1458,12 @@ struct TestChangegroup { sqlite3_changegroup *pGrp; }; +typedef struct TestChangeIter TestChangeIter; +struct TestChangeIter { + sqlite3_changeset_iter *pIter; +}; + + /* ** Destructor for Tcl changegroup command object. */ @@ -1491,6 +1496,7 @@ static int SQLITE_TCLAPI test_changegroup_cmd( { "add", 1, "CHANGESET", }, /* 1 */ { "output", 0, "", }, /* 2 */ { "delete", 0, "", }, /* 3 */ + { "add_change", 1, "ITERATOR", }, /* 4 */ { 0 } }; int rc = TCL_OK; @@ -1542,6 +1548,24 @@ static int SQLITE_TCLAPI test_changegroup_cmd( break; }; + case 4: { /* add_change */ + Tcl_CmdInfo cmdInfo; /* Database Tcl command (objv[2]) info */ + TestChangeIter *pIter = 0; + const char *zIter = Tcl_GetString(objv[2]); + if( 0==Tcl_GetCommandInfo(interp, zIter, &cmdInfo) ){ + Tcl_AppendResult(interp, "no such iter: ", Tcl_GetString(objv[2]), 0); + return TCL_ERROR; + } + + pIter = (struct TestChangeIter*)cmdInfo.objClientData; + + rc = sqlite3changegroup_add_change(p->pGrp, pIter->pIter); + if( rc!=SQLITE_OK ){ + rc = test_session_error(interp, rc, 0); + } + break; + }; + default: { /* delete */ assert( iSub==3 ); Tcl_DeleteCommand(interp, Tcl_GetString(objv[0])); @@ -1585,6 +1609,115 @@ static int SQLITE_TCLAPI test_sqlite3changegroup( return TCL_OK; } +extern const char *sqlite3ErrName(int); + +/* +** Destructor for Tcl iterator command object. +*/ +static void test_iter_del(void *clientData){ + TestChangeIter *p = (TestChangeIter*)clientData; + sqlite3changeset_finalize(p->pIter); + ckfree(p); +} + +static int SQLITE_TCLAPI test_iter_cmd( + void * clientData, + Tcl_Interp *interp, + int objc, + Tcl_Obj *CONST objv[] +){ + static const char *aSub[] = { + "next", /* 0 */ + "data", /* 1 */ + "finalize", /* 2 */ + 0 + }; + int iSub = 0; + + TestChangeIter *p = (TestChangeIter*)clientData; + int rc = SQLITE_OK; + + if( objc<2 ){ + Tcl_WrongNumArgs(interp, 1, objv, "CMD"); + return TCL_ERROR; + } + + if( Tcl_GetIndexFromObj(interp, objv[1], aSub, "sub-command", 0, &iSub) ){ + return TCL_ERROR; + } + switch( iSub ){ + case 0: + rc = sqlite3changeset_next(p->pIter); + Tcl_SetObjResult(interp, Tcl_NewStringObj(sqlite3ErrName(rc), -1)); + break; + case 1: + Tcl_SetObjResult(interp, testIterData(p->pIter)); + break; + case 2: + rc = sqlite3changeset_finalize(p->pIter); + p->pIter = 0; + Tcl_DeleteCommand(interp, Tcl_GetString(objv[0])); + Tcl_SetObjResult(interp, Tcl_NewStringObj(sqlite3ErrName(rc), -1)); + break; + default: + assert( 0 ); + break; + } + + return TCL_OK; +} + +/* +** Tclcmd: sqlite3changeset_start ?-invert? CHANGESET +*/ +static int SQLITE_TCLAPI test_sqlite3changeset_start( + void * clientData, + Tcl_Interp *interp, + int objc, + Tcl_Obj *CONST objv[] +){ + int isInvert = 0; + void *pChangeset = 0; /* Buffer containing changeset */ + int nChangeset = 0; /* Size of buffer aChangeset in bytes */ + TestChangeIter *pNew = 0; + sqlite3_changeset_iter *pIter = 0; + int flags = 0; + int rc = SQLITE_OK; + + static int iCmd = 1; + char zCmd[64]; + + if( objc==3 ){ + int n = 0; + const char *z = Tcl_GetStringFromObj(objv[1], &n); + isInvert = (n>=2 && sqlite3_strnicmp(z, "-invert", n)==0); + } + + if( objc!=2 && (objc!=3 || !isInvert) ){ + Tcl_WrongNumArgs(interp, 1, objv, "?-invert? CHANGESET"); + return TCL_ERROR; + } + + flags = isInvert ? SQLITE_CHANGESETSTART_INVERT : 0; + pChangeset = (void *)Tcl_GetByteArrayFromObj(objv[objc-1], &nChangeset); + rc = sqlite3changeset_start_v2(&pIter, nChangeset, pChangeset, flags); + if( rc!=SQLITE_OK ){ + char *zErr = sqlite3_mprintf( + "error in sqlite3changeset_start_v2() - %d", rc + ); + Tcl_AppendResult(interp, zErr, (char*)0); + return TCL_ERROR; + } + + pNew = (TestChangeIter*)ckalloc(sizeof(TestChangeIter)); + pNew->pIter = pIter; + + sprintf(zCmd, "csiter%d", iCmd++); + Tcl_CreateObjCommand(interp, zCmd, test_iter_cmd, (void*)pNew, test_iter_del); + Tcl_SetObjResult(interp, Tcl_NewStringObj(zCmd, -1)); + return TCL_OK; +} + int TestSession_Init(Tcl_Interp *interp){ struct Cmd { const char *zCmd; @@ -1592,6 +1725,7 @@ int TestSession_Init(Tcl_Interp *interp){ } aCmd[] = { { "sqlite3session", test_sqlite3session }, { "sqlite3changegroup", test_sqlite3changegroup }, + { "sqlite3changeset_start", test_sqlite3changeset_start }, { "sqlite3session_foreach", test_sqlite3session_foreach }, { "sqlite3changeset_invert", test_sqlite3changeset_invert }, { "sqlite3changeset_concat", test_sqlite3changeset_concat }, diff --git a/ext/userauth/user-auth.txt b/ext/userauth/user-auth.txt index ba4eabc..9d6ba23 100644 --- a/ext/userauth/user-auth.txt +++ b/ext/userauth/user-auth.txt @@ -1,3 +1,15 @@ +*********************************** NOTICE ************************************ +* This extension is deprecated. The SQLite developers do not maintain this * +* extension. At some point in the future, it might disappear from the source * +* tree. * +* * +* If you are using this extension and think it should be supported moving * +* forward, visit the SQLite Forum (https://sqlite.org/forum) and argue your * +* case there. * +* * +* This deprecation notice was added on 2024-01-22. * +******************************************************************************* + Activate the user authentication logic by including the ext/userauth/userauth.c source code file in the build and adding the -DSQLITE_USER_AUTHENTICATION compile-time option. diff --git a/ext/wasm/GNUmakefile b/ext/wasm/GNUmakefile index 8f733b6..115374e 100644 --- a/ext/wasm/GNUmakefile +++ b/ext/wasm/GNUmakefile @@ -43,8 +43,9 @@ # which generates the makefile code, rather than using $(call) and # $(eval), or at least centralize the setup of the numerous vars # related to each build variant $(JS_BUILD_MODES). (Update: an -# external script was attempted but it's even less legible than the -# $(eval) indirection going on in this file. +# external script was attempted but generating properly-escaped +# makefile code from within a shell script is even less legible +# than the $(eval) indirection going on in this file.) # default: all #default: quick @@ -288,6 +289,12 @@ endif # embedding in the JS files and in building the distribution zip file. # It must NOT be in $(dir.tmp) because we need it to survive the # cleanup process for the dist build to work properly. +# +# Slight caveat: this uses the version info from the in-tree +# sqlite3.c/h, which may diff from a user-provided $(sqlite3.c). The +# end result is that the generated JS files may have static version +# info from $(bin.version-info) which differ from their runtime-emited +# version info (e.g. from sqlite3_libversion()). bin.version-info := $(dir.top)/version-info .NOTPARALLEL: $(bin.version-info) $(bin.version-info): $(dir.tool)/version-info.c $(sqlite3.h) $(dir.top)/Makefile @@ -306,8 +313,9 @@ DISTCLEAN_FILES += $(bin.stripccomments) ######################################################################## -# C-PP.FILTER: a $(call)able to transform $(1) to $(2) via ./c-pp -f -# $(1) ... +# C-PP.FILTER: a $(call)able to transform $(1) to $(2) via: +# +# ./c-pp -f $(1) -o $(2) $(3) # # Historical notes: # @@ -333,19 +341,26 @@ DISTCLEAN_FILES += $(bin.stripccomments) # # Note that the SQLITE_... build flags used here have NO EFFECT on the # JS/WASM build. They are solely for use with $(bin.c-pp) itself. +# +# -D... flags which should be included in all invocations should be +# appended to $(C-PP.FILTER.global). bin.c-pp := ./c-pp $(bin.c-pp): c-pp.c $(sqlite3.c) $(MAKEFILE) $(CC) -O0 -o $@ c-pp.c $(sqlite3.c) '-DCMPP_DEFAULT_DELIM="//#"' -I$(dir.top) \ -DSQLITE_OMIT_LOAD_EXTENSION -DSQLITE_OMIT_DEPRECATED -DSQLITE_OMIT_UTF16 \ -DSQLITE_OMIT_SHARED_CACHE -DSQLITE_OMIT_WAL -DSQLITE_THREADSAFE=0 \ -DSQLITE_TEMP_STORE=3 +C-PP.FILTER.global ?= +ifeq (1,$(SQLITE_C_IS_SEE)) + C-PP.FILTER.global += -Denable-see +endif define C-PP.FILTER # Create $2 from $1 using $(bin.c-pp) # $1 = Input file: c-pp -f $(1).js # $2 = Output file: c-pp -o $(2).js # $3 = optional c-pp -D... flags $(2): $(1) $$(MAKEFILE) $$(bin.c-pp) - $$(bin.c-pp) -f $(1) -o $$@ $(3) + $$(bin.c-pp) -f $(1) -o $$@ $(3) $(C-PP.FILTER.global) CLEAN_FILES += $(2) endef # /end C-PP.FILTER @@ -432,8 +447,10 @@ sqlite3-api.jses += $(sqlite3-api-build-version.js) sqlite3-api.jses += $(dir.api)/sqlite3-api-oo1.js # sqlite3-api-worker.js = the Worker1 API: sqlite3-api.jses += $(dir.api)/sqlite3-api-worker1.js -# sqlite3-v-helper = helper APIs for VFSes and VTABLEs: -sqlite3-api.jses += $(dir.api)/sqlite3-v-helper.js +# sqlite3-vfs-helper = helper APIs for VFSes: +sqlite3-api.jses += $(dir.api)/sqlite3-vfs-helper.c-pp.js +# sqlite3-vtab-helper = helper APIs for VTABLEs: +sqlite3-api.jses += $(dir.api)/sqlite3-vtab-helper.c-pp.js # sqlite3-vfs-opfs.c-pp.js = the first OPFS VFS: sqlite3-api.jses += $(dir.api)/sqlite3-vfs-opfs.c-pp.js # sqlite3-vfs-opfs-sahpool.c-pp.js = the second OPFS VFS: @@ -449,13 +466,14 @@ sqlite3-api.jses += $(dir.api)/sqlite3-api-cleanup.js # the first OPFS VFS and necessarily an external file. SOAP.js := $(dir.api)/sqlite3-opfs-async-proxy.js SOAP.js.bld := $(dir.dout)/$(notdir $(SOAP.js)) -sqlite3-api.ext.jses += $(SOAP.js.bld) +# +# $(sqlite3-api.ext.jses) = API-related files which are standalone files, +# not part of the amalgamation. +# +sqlite3-api.ext.jses := $(SOAP.js.bld) $(SOAP.js.bld): $(SOAP.js) cp $< $@ -all quick: $(sqlite3-api.ext.jses) -q: quick - ######################################################################## # $(sqlite3-api*.*js) contain the core library code but not the # Emscripten-related glue which deals with loading sqlite3.wasm. In @@ -528,6 +546,10 @@ emcc.jsflags += -sSTRICT_JS=0 # 3.1.31. The fix for that in newer emcc's is to throw a built-time # error if STRICT_JS is used together with those options. +# emcc.jsflags += -sSTRICT=1 +# -sSTRICT=1 Causes failures about unknown symbols which the build +# tools should be installing, e.g. __syscall_geteuid32 + # -sENVIRONMENT values for the various build modes: emcc.environment.vanilla := web,worker emcc.environment.bundler-friendly := $(emcc.environment.vanilla) @@ -548,6 +570,11 @@ emcc.environment.node := node # time with 16mb+ memory and 3X time when starting with 8MB. However, # such test results are inconsistent due to browser internals which # are opaque to us. +# +# 2024-03-04: emsdk 3.1.55 replaces INITIAL_MEMORY with INITIAL_HEAP, +# but also says (in its changelog): "Note that it is currently not +# supported in all configurations (#21071)." +# https://github.com/emscripten-core/emscripten/blob/main/ChangeLog.md emcc.jsflags += -sALLOW_MEMORY_GROWTH emcc.INITIAL_MEMORY.128 := 134217728 emcc.INITIAL_MEMORY.96 := 100663296 @@ -813,13 +840,13 @@ pre-post-jses.deps.common := $(extern-pre-js.js) $(sqlite3-license-version.js) # $4 = resulting sqlite-api JS/MJS file # $5 = resulting JS/MJS file # $6 = -D... flags for $(bin.c-pp) -# $7 = emcc -sXYZ flags (CURRENTLY UNUSED - was factored out) +# $7 = optional extra flags for emcc # # Maintenance reminder: be careful not to introduce spaces around args # ($1, $2), otherwise string concatenation will malfunction. # -# emcc.environment.$(2) must be set to a value for emcc's -# -sENVIRONMENT flag. +# Before calling this, emcc.environment.$(2) must be set to a value +# for emcc's -sENVIRONMENT flag. # # $(cflags.$(1)) and $(cflags.$(1).$(2)) may be defined to append # CFLAGS to a given build mode. @@ -926,18 +953,39 @@ sqlite3-worker1.js.in := $(dir.api)/sqlite3-worker1.c-pp.js sqlite3-worker1-promiser.js.in := $(dir.api)/sqlite3-worker1-promiser.c-pp.js sqlite3-worker1.js := $(dir.dout)/sqlite3-worker1.js sqlite3-worker1-promiser.js := $(dir.dout)/sqlite3-worker1-promiser.js -sqlite3-worker1-bundler-friendly.js := $(dir.dout)/sqlite3-worker1-bundler-friendly.mjs +sqlite3-worker1-promiser.mjs := $(dir.dout)/sqlite3-worker1-promiser.mjs +sqlite3-worker1-bundler-friendly.mjs := $(dir.dout)/sqlite3-worker1-bundler-friendly.mjs sqlite3-worker1-promiser-bundler-friendly.js := $(dir.dout)/sqlite3-worker1-promiser-bundler-friendly.js $(eval $(call C-PP.FILTER,$(sqlite3-worker1.js.in),$(sqlite3-worker1.js))) -$(eval $(call C-PP.FILTER,$(sqlite3-worker1.js.in),$(sqlite3-worker1-bundler-friendly.js),\ +$(eval $(call C-PP.FILTER,$(sqlite3-worker1.js.in),$(sqlite3-worker1-bundler-friendly.mjs),\ $(c-pp.D.sqlite3-bundler-friendly))) $(eval $(call C-PP.FILTER,$(sqlite3-worker1-promiser.js.in),$(sqlite3-worker1-promiser.js))) $(eval $(call C-PP.FILTER,$(sqlite3-worker1-promiser.js.in),\ $(sqlite3-worker1-promiser-bundler-friendly.js),\ $(c-pp.D.sqlite3-bundler-friendly))) -$(sqlite3-bundler-friendly.mjs): $(sqlite3-worker1-bundler-friendly.js) \ +$(eval $(call C-PP.FILTER,$(sqlite3-worker1-promiser.js.in),$(sqlite3-worker1-promiser.mjs),\ + -Dtarget=es6-module -Dtarget=es6-bundler-friendly)) +$(sqlite3-bundler-friendly.mjs): $(sqlite3-worker1-bundler-friendly.mjs) \ $(sqlite3-worker1-promiser-bundler-friendly.js) -$(sqlite3.js) $(sqlite3.mjs): $(sqlite3-worker1.js) $(sqlite3-worker1-promiser.js) +$(eval $(call C-PP.FILTER,demo-worker1-promiser.c-pp.js,demo-worker1-promiser.js)) +$(eval $(call C-PP.FILTER,demo-worker1-promiser.c-pp.js,demo-worker1-promiser.mjs,\ + -Dtarget=es6-module)) +$(eval $(call C-PP.FILTER,demo-worker1-promiser.c-pp.html,demo-worker1-promiser.html)) +$(eval $(call C-PP.FILTER,demo-worker1-promiser.c-pp.html,demo-worker1-promiser-esm.html,\ + -Dtarget=es6-module)) +all: $(sqlite3-worker1.js) \ + $(sqlite3-worker1-promiser.js) $(sqlite3-worker1-promiser.mjs) + +demo-worker1-promiser.html: $(sqlite3-worker1-promiser.js) demo-worker1-promiser.js +demo-worker1-promiser-esm.html: $(sqlite3-worker1-promiser.mjs) demo-worker1-promiser.mjs +all: demo-worker1-promiser.html demo-worker1-promiser-esm.html + +sqlite3-api.ext.jses += \ + $(sqlite3-worker1-promiser.mjs) \ + $(sqlite3-worker1-bundler-friendly.mjs) \ + $(sqlite3-worker1.js) +all quick: $(sqlite3-api.ext.jses) +q: quick ######################################################################## # batch-runner.js is part of one of the test apps which reads in SQL @@ -978,6 +1026,9 @@ emcc.speedtest1.common += -sABORTING_MALLOC emcc.speedtest1.common += -sSTRICT_JS=0 emcc.speedtest1.common += -sMODULARIZE emcc.speedtest1.common += -Wno-limited-postlink-optimizations +emcc.speedtest1.common += -Wno-unused-main +# ^^^^ -Wno-unused-main is for emcc 3.1.52+. speedtest1 has a wasm_main() which is +# exported and called by the JS code. EXPORTED_FUNCTIONS.speedtest1 := $(abspath $(dir.tmp)/EXPORTED_FUNCTIONS.speedtest1) emcc.speedtest1.common += -sSTACK_SIZE=512KB emcc.speedtest1.common += -sEXPORTED_FUNCTIONS=@$(EXPORTED_FUNCTIONS.speedtest1) diff --git a/ext/wasm/SQLTester/SQLTester.mjs b/ext/wasm/SQLTester/SQLTester.mjs index a72399a..71c5d4c 100644 --- a/ext/wasm/SQLTester/SQLTester.mjs +++ b/ext/wasm/SQLTester/SQLTester.mjs @@ -174,11 +174,17 @@ const Rx = newObj({ squiggly: /[{}]/ }); + + const Util = newObj({ toss, - unlink: function(fn){ - return 0==sqlite3.wasm.sqlite3_wasm_vfs_unlink(0,fn); + unlink: function f(fn){ + if(!f.unlink){ + f.unlink = sqlite3.wasm.xWrap('sqlite3__wasm_vfs_unlink','int', + ['*','string']); + } + return 0==f.unlink(0,fn); }, argvToString: (list)=>{ @@ -197,7 +203,7 @@ const Util = newObj({ utf8Encode: (str)=>__utf8Encoder.encode(str), - strglob: sqlite3.wasm.xWrap('sqlite3_wasm_SQLTester_strglob','int', + strglob: sqlite3.wasm.xWrap('sqlite3__wasm_SQLTester_strglob','int', ['string','string']) })/*Util*/; diff --git a/ext/wasm/api/README.md b/ext/wasm/api/README.md index eb0f073..ebd4aaa 100644 --- a/ext/wasm/api/README.md +++ b/ext/wasm/api/README.md @@ -78,10 +78,12 @@ browser client: a Promise-based interface into the Worker #1 API. This is a far user-friendlier way to interface with databases running in a Worker thread. -- **`sqlite3-v-helper.js`**\ - Installs `sqlite3.vfs` and `sqlite3.vtab`, namespaces which contain - helpers for use by downstream code which creates `sqlite3_vfs` - and `sqlite3_module` implementations. +- **`sqlite3-vfs-helper.js`**\ + Installs the `sqlite3.vfs` namespace, which contain helpers for use + by downstream code which creates `sqlite3_vfs` implementations. +- **`sqlite3-vtab-helper.js`**\ + Installs the `sqlite3.vtab` namespace, which contain helpers for use + by downstream code which creates `sqlite3_module` implementations. - **`sqlite3-vfs-opfs.c-pp.js`**\ is an sqlite3 VFS implementation which supports the Origin-Private FileSystem (OPFS) as a storage layer to provide persistent storage diff --git a/ext/wasm/api/post-js-header.js b/ext/wasm/api/post-js-header.js index 0e27e1f..7fd82a7 100644 --- a/ext/wasm/api/post-js-header.js +++ b/ext/wasm/api/post-js-header.js @@ -19,8 +19,10 @@ Module.postRun.push(function(Module/*the Emscripten-style module object*/){ - sqlite3-api-glue.js => glues previous parts together - sqlite3-api-oo.js => SQLite3 OO API #1 - sqlite3-api-worker1.js => Worker-based API - - sqlite3-vfs-helper.js => Internal-use utilities for... - - sqlite3-vfs-opfs.js => OPFS VFS + - sqlite3-vfs-helper.c-pp.js => Utilities for VFS impls + - sqlite3-vtab-helper.c-pp.js => Utilities for virtual table impls + - sqlite3-vfs-opfs.c-pp.js => OPFS VFS + - sqlite3-vfs-opfs-sahpool.c-pp.js => OPFS SAHPool VFS - sqlite3-api-cleanup.js => final API cleanup - post-js-footer.js => closes this postRun() function */ diff --git a/ext/wasm/api/sqlite3-api-glue.js b/ext/wasm/api/sqlite3-api-glue.js index 29efb3e..83b2ee1 100644 --- a/ext/wasm/api/sqlite3-api-glue.js +++ b/ext/wasm/api/sqlite3-api-glue.js @@ -14,7 +14,8 @@ previous steps of the sqlite3-api.js bootstrapping process: sqlite3-api-prologue.js, whwasmutil.js, and jaccwabyt.js. It initializes the main API pieces so that the downstream components - (e.g. sqlite3-api-oo1.js) have all that they need. + (e.g. sqlite3-api-oo1.js) have all of the infrastructure that they + need. */ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ 'use strict'; @@ -328,7 +329,16 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ wasm.bindingSignatures.push(["sqlite3_normalized_sql", "string", "sqlite3_stmt*"]); } - if(wasm.exports.sqlite3_activate_see instanceof Function){ +//#if enable-see + if(wasm.exports.sqlite3_key_v2 instanceof Function){ + /** + This code is capable of using an SEE build but note that an SEE + WASM build is generally incompatible with SEE's license + conditions. It is permitted for use internally in organizations + which have licensed SEE, but not for public sites because + exposing an SEE build of sqlite3.wasm effectively provides all + clients with a working copy of the commercial SEE code. + */ wasm.bindingSignatures.push( ["sqlite3_key", "int", "sqlite3*", "string", "int"], ["sqlite3_key_v2","int","sqlite3*","string","*","int"], @@ -337,10 +347,14 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ ["sqlite3_activate_see", undefined, "string"] ); } +//#endif enable-see + /** Functions which require BigInt (int64) support are separated from the others because we need to conditionally bind them or apply dummy impls, depending on the capabilities of the environment. + (That said: we never actually build without BigInt support, + and such builds are untested.) Note that not all of these functions directly require int64 but are only for use with APIs which require int64. For example, @@ -359,7 +373,10 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ /* Careful! Short version: de/serialize() are problematic because they might use a different allocator than the user for managing the deserialized block. de/serialize() are ONLY safe to use with - sqlite3_malloc(), sqlite3_free(), and its 64-bit variants. */, + sqlite3_malloc(), sqlite3_free(), and its 64-bit variants. Because + of this, the canonical builds of sqlite3.wasm/js guarantee that + sqlite3.wasm.alloc() and friends use those allocators. Custom builds + may not guarantee that, however. */, ["sqlite3_drop_modules", "int", ["sqlite3*", "**"]], ["sqlite3_last_insert_rowid", "i64", ["sqlite3*"]], ["sqlite3_malloc64", "*","i64"], @@ -422,8 +439,6 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ // Add session/changeset APIs... if(wasm.bigIntEnabled && !!wasm.exports.sqlite3changegroup_add){ - /* ACHTUNG: 2022-12-23: the session/changeset API bindings are - COMPLETELY UNTESTED. */ /** FuncPtrAdapter options for session-related callbacks with the native signature "i(ps)". This proxy converts the 2nd argument @@ -601,16 +616,25 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ /** Functions which are intended solely for API-internal use by the WASM components, not client code. These get installed into - sqlite3.wasm. Some of them get exposed to clients via variants - named sqlite3_js_...(). + sqlite3.util. Some of them get exposed to clients via variants + in sqlite3_js_...(). + + 2024-01-11: these were renamed, with two underscores in the + prefix, to ensure that clients do not accidentally depend on + them. They have always been documented as internal-use-only, so + no clients "should" be depending on the old names. */ - wasm.bindingSignatures.wasm = [ - ["sqlite3_wasm_db_reset", "int", "sqlite3*"], - ["sqlite3_wasm_db_vfs", "sqlite3_vfs*", "sqlite3*","string"], - ["sqlite3_wasm_vfs_create_file", "int", - "sqlite3_vfs*","string","*", "int"], - ["sqlite3_wasm_posix_create_file", "int", "string","*", "int"], - ["sqlite3_wasm_vfs_unlink", "int", "sqlite3_vfs*","string"] + wasm.bindingSignatures.wasmInternal = [ + ["sqlite3__wasm_db_reset", "int", "sqlite3*"], + ["sqlite3__wasm_db_vfs", "sqlite3_vfs*", "sqlite3*","string"], + [/* DO NOT USE. This is deprecated since 2023-08-11 because it can + trigger assert() in debug builds when used with file sizes + which are not sizes to a multiple of a valid db page size. */ + "sqlite3__wasm_vfs_create_file", "int", "sqlite3_vfs*","string","*", "int" + ], + ["sqlite3__wasm_posix_create_file", "int", "string","*", "int"], + ["sqlite3__wasm_vfs_unlink", "int", "sqlite3_vfs*","string"], + ["sqlite3__wasm_qfmt_token","string:dealloc", "string","int"] ]; /** @@ -652,7 +676,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ Use case: sqlite3_bind_pointer() and sqlite3_result_pointer() call for "a static string and preferably a string - literal". This converter is used to ensure that the string + literal." This converter is used to ensure that the string value seen by those functions is long-lived and behaves as they need it to. */ @@ -674,14 +698,15 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ `sqlite3_vfs*` via capi.sqlite3_vfs.pointer. */ const __xArgPtr = wasm.xWrap.argAdapter('*'); - const nilType = function(){}/*a class no value can ever be an instance of*/; + const nilType = function(){ + /*a class which no value can ever be an instance of*/ + }; wasm.xWrap.argAdapter('sqlite3_filename', __xArgPtr) ('sqlite3_context*', __xArgPtr) ('sqlite3_value*', __xArgPtr) ('void*', __xArgPtr) ('sqlite3_changegroup*', __xArgPtr) ('sqlite3_changeset_iter*', __xArgPtr) - //('sqlite3_rebaser*', __xArgPtr) ('sqlite3_session*', __xArgPtr) ('sqlite3_stmt*', (v)=> __xArgPtr((v instanceof (sqlite3?.oo1?.Stmt || nilType)) @@ -742,8 +767,8 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ for(const e of wasm.bindingSignatures){ capi[e[0]] = wasm.xWrap.apply(null, e); } - for(const e of wasm.bindingSignatures.wasm){ - wasm[e[0]] = wasm.xWrap.apply(null, e); + for(const e of wasm.bindingSignatures.wasmInternal){ + util[e[0]] = wasm.xWrap.apply(null, e); } /* For C API functions which cannot work properly unless @@ -765,9 +790,9 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ implicitly making it part of the public interface. */ delete wasm.bindingSignatures; - if(wasm.exports.sqlite3_wasm_db_error){ + if(wasm.exports.sqlite3__wasm_db_error){ const __db_err = wasm.xWrap( - 'sqlite3_wasm_db_error', 'int', 'sqlite3*', 'int', 'string' + 'sqlite3__wasm_db_error', 'int', 'sqlite3*', 'int', 'string' ); /** Sets the given db's error state. Accepts: @@ -785,7 +810,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ Returns the resulting code. Pass (pDb,0,0) to clear the error state. */ - util.sqlite3_wasm_db_error = function(pDb, resultCode, message){ + util.sqlite3__wasm_db_error = function(pDb, resultCode, message){ if(resultCode instanceof sqlite3.WasmAllocError){ resultCode = capi.SQLITE_NOMEM; message = 0 /*avoid allocating message string*/; @@ -796,17 +821,17 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ return pDb ? __db_err(pDb, resultCode, message) : resultCode; }; }else{ - util.sqlite3_wasm_db_error = function(pDb,errCode,msg){ - console.warn("sqlite3_wasm_db_error() is not exported.",arguments); + util.sqlite3__wasm_db_error = function(pDb,errCode,msg){ + console.warn("sqlite3__wasm_db_error() is not exported.",arguments); return errCode; }; } }/*xWrap() bindings*/ {/* Import C-level constants and structs... */ - const cJson = wasm.xCall('sqlite3_wasm_enum_json'); + const cJson = wasm.xCall('sqlite3__wasm_enum_json'); if(!cJson){ - toss("Maintenance required: increase sqlite3_wasm_enum_json()'s", + toss("Maintenance required: increase sqlite3__wasm_enum_json()'s", "static buffer size!"); } //console.debug('wasm.ctype length =',wasm.cstrlen(cJson)); @@ -877,7 +902,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ delete capi[k]; } capi.sqlite3_vtab_config = wasm.xWrap( - 'sqlite3_wasm_vtab_config','int',[ + 'sqlite3__wasm_vtab_config','int',[ 'sqlite3*', 'int', 'int'] ); }/* end vtab-related setup */ @@ -889,7 +914,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ consistency with non-special-case wrappings. */ const __dbArgcMismatch = (pDb,f,n)=>{ - return util.sqlite3_wasm_db_error(pDb, capi.SQLITE_MISUSE, + return util.sqlite3__wasm_db_error(pDb, capi.SQLITE_MISUSE, f+"() requires "+n+" argument"+ (1===n?"":'s')+"."); }; @@ -898,7 +923,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ argument and require SQLITE_UTF8. Sets the db error code to SQLITE_FORMAT and returns that code. */ const __errEncoding = (pDb)=>{ - return util.sqlite3_wasm_db_error( + return util.sqlite3__wasm_db_error( pDb, capi.SQLITE_FORMAT, "SQLITE_UTF8 is the only supported encoding." ); }; @@ -1128,7 +1153,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ } return rc; }catch(e){ - return util.sqlite3_wasm_db_error(pDb, e); + return util.sqlite3__wasm_db_error(pDb, e); } }; @@ -1254,7 +1279,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ return rc; }catch(e){ console.error("sqlite3_create_function_v2() setup threw:",e); - return util.sqlite3_wasm_db_error(pDb, e, "Creation of UDF threw: "+e); + return util.sqlite3__wasm_db_error(pDb, e, "Creation of UDF threw: "+e); } }; @@ -1299,7 +1324,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ return rc; }catch(e){ console.error("sqlite3_create_window_function() setup threw:",e); - return util.sqlite3_wasm_db_error(pDb, e, "Creation of UDF threw: "+e); + return util.sqlite3__wasm_db_error(pDb, e, "Creation of UDF threw: "+e); } }; /** @@ -1394,7 +1419,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ case 'string': return __prepare.basic(pDb, xSql, xSqlLen, prepFlags, ppStmt, null); case 'number': return __prepare.full(pDb, xSql, xSqlLen, prepFlags, ppStmt, pzTail); default: - return util.sqlite3_wasm_db_error( + return util.sqlite3__wasm_db_error( pDb, capi.SQLITE_MISUSE, "Invalid SQL argument type for sqlite3_prepare_v2/v3()." ); @@ -1438,7 +1463,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ }else if('string'===typeof text){ [p, n] = wasm.allocCString(text); }else{ - return util.sqlite3_wasm_db_error( + return util.sqlite3__wasm_db_error( capi.sqlite3_db_handle(pStmt), capi.SQLITE_MISUSE, "Invalid 3rd argument type for sqlite3_bind_text()." ); @@ -1446,7 +1471,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ return __bindText(pStmt, iCol, p, n, capi.SQLITE_WASM_DEALLOC); }catch(e){ wasm.dealloc(p); - return util.sqlite3_wasm_db_error( + return util.sqlite3__wasm_db_error( capi.sqlite3_db_handle(pStmt), e ); } @@ -1472,7 +1497,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ }else if('string'===typeof pMem){ [p, n] = wasm.allocCString(pMem); }else{ - return util.sqlite3_wasm_db_error( + return util.sqlite3__wasm_db_error( capi.sqlite3_db_handle(pStmt), capi.SQLITE_MISUSE, "Invalid 3rd argument type for sqlite3_bind_blob()." ); @@ -1480,7 +1505,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ return __bindBlob(pStmt, iCol, p, n, capi.SQLITE_WASM_DEALLOC); }catch(e){ wasm.dealloc(p); - return util.sqlite3_wasm_db_error( + return util.sqlite3__wasm_db_error( capi.sqlite3_db_handle(pStmt), e ); } @@ -1504,11 +1529,11 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ case capi.SQLITE_CONFIG_SORTERREF_SIZE: // 28 /* int nByte */ case capi.SQLITE_CONFIG_STMTJRNL_SPILL: // 26 /* int nByte */ case capi.SQLITE_CONFIG_URI:// 17 /* int */ - return wasm.exports.sqlite3_wasm_config_i(op, args[0]); + return wasm.exports.sqlite3__wasm_config_i(op, args[0]); case capi.SQLITE_CONFIG_LOOKASIDE: // 13 /* int int */ - return wasm.exports.sqlite3_wasm_config_ii(op, args[0], args[1]); + return wasm.exports.sqlite3__wasm_config_ii(op, args[0], args[1]); case capi.SQLITE_CONFIG_MEMDB_MAXSIZE: // 29 /* sqlite3_int64 */ - return wasm.exports.sqlite3_wasm_config_j(op, args[0]); + return wasm.exports.sqlite3__wasm_config_j(op, args[0]); case capi.SQLITE_CONFIG_GETMALLOC: // 5 /* sqlite3_mem_methods* */ case capi.SQLITE_CONFIG_GETMUTEX: // 11 /* sqlite3_mutex_methods* */ case capi.SQLITE_CONFIG_GETPCACHE2: // 19 /* sqlite3_pcache_methods2* */ @@ -1529,6 +1554,10 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ case capi.SQLITE_CONFIG_SQLLOG: // 21 /* xSqllog, void* */ case capi.SQLITE_CONFIG_WIN32_HEAPSIZE: // 23 /* int nByte */ default: + /* maintenance note: we specifically do not include + SQLITE_CONFIG_ROWID_IN_VIEW here, on the grounds that + it's only for legacy support and no apps written with + this API require that. */ return capi.SQLITE_NOTFOUND; } }; @@ -1574,11 +1603,11 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ if( pKvvfs ){/* kvvfs-specific glue */ if(util.isUIThread()){ const kvvfsMethods = new capi.sqlite3_kvvfs_methods( - wasm.exports.sqlite3_wasm_kvvfs_methods() + wasm.exports.sqlite3__wasm_kvvfs_methods() ); delete capi.sqlite3_kvvfs_methods; - const kvvfsMakeKey = wasm.exports.sqlite3_wasm_kvvfsMakeKeyOnPstack, + const kvvfsMakeKey = wasm.exports.sqlite3__wasm_kvvfsMakeKeyOnPstack, pstack = wasm.pstack; const kvvfsStorage = (zClass)=> @@ -1587,7 +1616,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ /** Implementations for members of the object referred to by - sqlite3_wasm_kvvfs_methods(). We swap out the native + sqlite3__wasm_kvvfs_methods(). We swap out the native implementations with these, which use localStorage or sessionStorage for their backing store. */ @@ -1667,5 +1696,181 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ } }/*pKvvfs*/ + /* Warn if client-level code makes use of FuncPtrAdapter. */ wasm.xWrap.FuncPtrAdapter.warnOnUse = true; + + const StructBinder = sqlite3.StructBinder + /* we require a local alias b/c StructBinder is removed from the sqlite3 + object during the final steps of the API cleanup. */; + /** + Installs a StructBinder-bound function pointer member of the + given name and function in the given StructBinder.StructType + target object. + + It creates a WASM proxy for the given function and arranges for + that proxy to be cleaned up when tgt.dispose() is called. Throws + on the slightest hint of error, e.g. tgt is-not-a StructType, + name does not map to a struct-bound member, etc. + + As a special case, if the given function is a pointer, then + `wasm.functionEntry()` is used to validate that it is a known + function. If so, it is used as-is with no extra level of proxying + or cleanup, else an exception is thrown. It is legal to pass a + value of 0, indicating a NULL pointer, with the caveat that 0 + _is_ a legal function pointer in WASM but it will not be accepted + as such _here_. (Justification: the function at address zero must + be one which initially came from the WASM module, not a method we + want to bind to a virtual table or VFS.) + + This function returns a proxy for itself which is bound to tgt + and takes 2 args (name,func). That function returns the same + thing as this one, permitting calls to be chained. + + If called with only 1 arg, it has no side effects but returns a + func with the same signature as described above. + + ACHTUNG: because we cannot generically know how to transform JS + exceptions into result codes, the installed functions do no + automatic catching of exceptions. It is critical, to avoid + undefined behavior in the C layer, that methods mapped via + this function do not throw. The exception, as it were, to that + rule is... + + If applyArgcCheck is true then each JS function (as opposed to + function pointers) gets wrapped in a proxy which asserts that it + is passed the expected number of arguments, throwing if the + argument count does not match expectations. That is only intended + for dev-time usage for sanity checking, and may leave the C + environment in an undefined state. + */ + const installMethod = function callee( + tgt, name, func, applyArgcCheck = callee.installMethodArgcCheck + ){ + if(!(tgt instanceof StructBinder.StructType)){ + toss("Usage error: target object is-not-a StructType."); + }else if(!(func instanceof Function) && !wasm.isPtr(func)){ + toss("Usage errror: expecting a Function or WASM pointer to one."); + } + if(1===arguments.length){ + return (n,f)=>callee(tgt, n, f, applyArgcCheck); + } + if(!callee.argcProxy){ + callee.argcProxy = function(tgt, funcName, func,sig){ + return function(...args){ + if(func.length!==arguments.length){ + toss("Argument mismatch for", + tgt.structInfo.name+"::"+funcName + +": Native signature is:",sig); + } + return func.apply(this, args); + } + }; + /* An ondispose() callback for use with + StructBinder-created types. */ + callee.removeFuncList = function(){ + if(this.ondispose.__removeFuncList){ + this.ondispose.__removeFuncList.forEach( + (v,ndx)=>{ + if('number'===typeof v){ + try{wasm.uninstallFunction(v)} + catch(e){/*ignore*/} + } + /* else it's a descriptive label for the next number in + the list. */ + } + ); + delete this.ondispose.__removeFuncList; + } + }; + }/*static init*/ + const sigN = tgt.memberSignature(name); + if(sigN.length<2){ + toss("Member",name,"does not have a function pointer signature:",sigN); + } + const memKey = tgt.memberKey(name); + const fProxy = (applyArgcCheck && !wasm.isPtr(func)) + /** This middle-man proxy is only for use during development, to + confirm that we always pass the proper number of + arguments. We know that the C-level code will always use the + correct argument count. */ + ? callee.argcProxy(tgt, memKey, func, sigN) + : func; + if(wasm.isPtr(fProxy)){ + if(fProxy && !wasm.functionEntry(fProxy)){ + toss("Pointer",fProxy,"is not a WASM function table entry."); + } + tgt[memKey] = fProxy; + }else{ + const pFunc = wasm.installFunction(fProxy, tgt.memberSignature(name, true)); + tgt[memKey] = pFunc; + if(!tgt.ondispose || !tgt.ondispose.__removeFuncList){ + tgt.addOnDispose('ondispose.__removeFuncList handler', + callee.removeFuncList); + tgt.ondispose.__removeFuncList = []; + } + tgt.ondispose.__removeFuncList.push(memKey, pFunc); + } + return (n,f)=>callee(tgt, n, f, applyArgcCheck); + }/*installMethod*/; + installMethod.installMethodArgcCheck = false; + + /** + Installs methods into the given StructBinder.StructType-type + instance. Each entry in the given methods object must map to a + known member of the given StructType, else an exception will be + triggered. See installMethod() for more details, including the + semantics of the 3rd argument. + + As an exception to the above, if any two or more methods in the + 2nd argument are the exact same function, installMethod() is + _not_ called for the 2nd and subsequent instances, and instead + those instances get assigned the same method pointer which is + created for the first instance. This optimization is primarily to + accommodate special handling of sqlite3_module::xConnect and + xCreate methods. + + On success, returns its first argument. Throws on error. + */ + const installMethods = function( + structInstance, methods, applyArgcCheck = installMethod.installMethodArgcCheck + ){ + const seen = new Map /* map of <Function, memberName> */; + for(const k of Object.keys(methods)){ + const m = methods[k]; + const prior = seen.get(m); + if(prior){ + const mkey = structInstance.memberKey(k); + structInstance[mkey] = structInstance[structInstance.memberKey(prior)]; + }else{ + installMethod(structInstance, k, m, applyArgcCheck); + seen.set(m, k); + } + } + return structInstance; + }; + + /** + Equivalent to calling installMethod(this,...arguments) with a + first argument of this object. If called with 1 or 2 arguments + and the first is an object, it's instead equivalent to calling + installMethods(this,...arguments). + */ + StructBinder.StructType.prototype.installMethod = function callee( + name, func, applyArgcCheck = installMethod.installMethodArgcCheck + ){ + return (arguments.length < 3 && name && 'object'===typeof name) + ? installMethods(this, ...arguments) + : installMethod(this, ...arguments); + }; + + /** + Equivalent to calling installMethods() with a first argument + of this object. + */ + StructBinder.StructType.prototype.installMethods = function( + methods, applyArgcCheck = installMethod.installMethodArgcCheck + ){ + return installMethods(this, methods, applyArgcCheck); + }; + }); diff --git a/ext/wasm/api/sqlite3-api-oo1.js b/ext/wasm/api/sqlite3-api-oo1.js index 160d59d..e557cbd 100644 --- a/ext/wasm/api/sqlite3-api-oo1.js +++ b/ext/wasm/api/sqlite3-api-oo1.js @@ -87,6 +87,104 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ */ const __vfsPostOpenSql = Object.create(null); +//#if enable-see + /** + Converts ArrayBuffer or Uint8Array ba into a string of hex + digits. + */ + const byteArrayToHex = function(ba){ + if( ba instanceof ArrayBuffer ){ + ba = new Uint8Array(ba); + } + const li = []; + const digits = "0123456789abcdef"; + for( const d of ba ){ + li.push( digits[(d & 0xf0) >> 4], digits[d & 0x0f] ); + } + return li.join(''); + }; + + /** + Internal helper to apply an SEE key to a just-opened + database. Requires that db be-a DB object which has just been + opened, opt be the options object processed by its ctor, and opt + must have either the key, hexkey, or textkey properties, either + as a string, an ArrayBuffer, or a Uint8Array. + + This is a no-op in non-SEE builds. It throws on error and returns + without side effects if none of the key/textkey/hexkey options + are set. It throws if more than one is set or if any are set to + values of an invalid type. + + Returns true if it applies the key, else an unspecified falsy value. + */ + const dbCtorApplySEEKey = function(db,opt){ + if( !capi.sqlite3_key_v2 ) return; + let keytype; + let key; + const check = (opt.key ? 1 : 0) + (opt.hexkey ? 1 : 0) + (opt.textkey ? 1 : 0); + if( !check ) return; + else if( check>1 ){ + toss3(capi.SQLITE_MISUSE, + "Only ONE of (key, hexkey, textkey) may be provided."); + } + if( opt.key ){ + /* It is not legal to bind an argument to PRAGMA key=?, so we + convert it to a hexkey... */ + keytype = 'key'; + key = opt.key; + if('string'===typeof key){ + key = new TextEncoder('utf-8').encode(key); + } + if((key instanceof ArrayBuffer) || (key instanceof Uint8Array)){ + key = byteArrayToHex(key); + keytype = 'hexkey'; + }else{ + toss3(capi.SQLITE_MISUSE, + "Invalid value for the 'key' option. Expecting a string,", + "ArrayBuffer, or Uint8Array."); + return; + } + }else if( opt.textkey ){ + /* For textkey we need it to be in string form, so convert it to + a string if it's a byte array... */ + keytype = 'textkey'; + key = opt.textkey; + if(key instanceof ArrayBuffer){ + key = new Uint8Array(key); + } + if(key instanceof Uint8Array){ + key = new TextDecoder('utf-8').decode(key); + }else if('string'!==typeof key){ + toss3(capi.SQLITE_MISUSE, + "Invalid value for the 'textkey' option. Expecting a string,", + "ArrayBuffer, or Uint8Array."); + } + }else if( opt.hexkey ){ + keytype = 'hexkey'; + key = opt.hexkey; + if((key instanceof ArrayBuffer) || (key instanceof Uint8Array)){ + key = byteArrayToHex(key); + }else if('string'!==typeof key){ + toss3(capi.SQLITE_MISUSE, + "Invalid value for the 'hexkey' option. Expecting a string,", + "ArrayBuffer, or Uint8Array."); + } + /* else assume it's valid hex codes */ + }else{ + return; + } + let stmt; + try{ + stmt = db.prepare("PRAGMA "+keytype+"="+util.sqlite3__wasm_qfmt_token(key, 1)); + stmt.step(); + }finally{ + if(stmt) stmt.finalize(); + } + return true; + }; +//#endif enable-see + /** A proxy for DB class constructors. It must be called with the being-construct DB object as its "this". See the DB constructor @@ -175,16 +273,28 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ __ptrMap.set(this, pDb); __stmtMap.set(this, Object.create(null)); try{ +//#if enable-see + dbCtorApplySEEKey(this,opt); +//#endif // Check for per-VFS post-open SQL/callback... - const pVfs = capi.sqlite3_js_db_vfs(pDb); - if(!pVfs) toss3("Internal error: cannot get VFS for new db handle."); + const pVfs = capi.sqlite3_js_db_vfs(pDb) + || toss3("Internal error: cannot get VFS for new db handle."); const postInitSql = __vfsPostOpenSql[pVfs]; - if(postInitSql instanceof Function){ - postInitSql(this, sqlite3); - }else if(postInitSql){ - checkSqlite3Rc( - pDb, capi.sqlite3_exec(pDb, postInitSql, 0, 0, 0) - ); + if(postInitSql){ + /** + Reminder: if this db is encrypted and the client did _not_ pass + in the key, any init code will fail, causing the ctor to throw. + We don't actually know whether the db is encrypted, so we cannot + sensibly apply any heuristics which skip the init code only for + encrypted databases for which no key has yet been supplied. + */ + if(postInitSql instanceof Function){ + postInitSql(this, sqlite3); + }else{ + checkSqlite3Rc( + pDb, capi.sqlite3_exec(pDb, postInitSql, 0, 0, 0) + ); + } } }catch(e){ this.close(); @@ -280,6 +390,36 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ - `flags`: open-mode flags - `vfs`: the VFS fname +//#if enable-see + + SEE-capable builds optionally support ONE of the following + additional options: + + - `key`, `hexkey`, or `textkey`: encryption key as a string, + ArrayBuffer, or Uint8Array. These flags function as documented + for the SEE pragmas of the same names. Using a byte array for + `hexkey` is equivalent to the same series of hex codes in + string form, so `'666f6f'` is equivalent to + `Uint8Array([0x66,0x6f,0x6f])`. A `textkey` byte array is + assumed to be UTF-8. A `key` string is transformed into a UTF-8 + byte array, and a `key` byte array is transformed into a + `hexkey` with the same bytes. + + In non-SEE builds, these options are ignored. In SEE builds, + `PRAGMA key/textkey/hexkey=X` is executed immediately after + opening the db. If more than one of the options is provided, + or any option has an invalid argument type, an exception is + thrown. + + Note that some DB subclasses may run post-initialization SQL + code, e.g. to set a busy-handler timeout or tweak the page cache + size. Such code is run _after_ the SEE key is applied. If no key + is supplied and the database is encrypted, execution of the + post-initialization SQL will fail, causing the constructor to + throw. + +//#endif enable-see + The `filename` and `vfs` arguments may be either JS strings or C-strings allocated via WASM. `flags` is required to be a JS string (because it's specific to this API, which is specific @@ -288,7 +428,8 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ For purposes of passing a DB instance to C-style sqlite3 functions, the DB object's read-only `pointer` property holds its `sqlite3*` pointer value. That property can also be used to check - whether this DB instance is still open. + whether this DB instance is still open: it will evaluate to + `undefined` after the DB object's close() method is called. In the main window thread, the filenames `":localStorage:"` and `":sessionStorage:"` are special: they cause the db to use either @@ -433,40 +574,56 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ out.returnVal = ()=>opt.resultRows; } if(opt.callback || opt.resultRows){ - switch((undefined===opt.rowMode) - ? 'array' : opt.rowMode) { - case 'object': out.cbArg = (stmt)=>stmt.get(Object.create(null)); break; - case 'array': out.cbArg = (stmt)=>stmt.get([]); break; - case 'stmt': - if(Array.isArray(opt.resultRows)){ - toss3("exec(): invalid rowMode for a resultRows array: must", - "be one of 'array', 'object',", - "a result column number, or column name reference."); - } - out.cbArg = (stmt)=>stmt; + switch((undefined===opt.rowMode) ? 'array' : opt.rowMode) { + case 'object': + out.cbArg = (stmt,cache)=>{ + if( !cache.columnNames ) cache.columnNames = stmt.getColumnNames([]); + /* https://sqlite.org/forum/forumpost/3632183d2470617d: + conversion of rows to objects (key/val pairs) is + somewhat expensive for large data sets because of the + native-to-JS conversion of the column names. If we + instead cache the names and build objects from that + list of strings, it can run twice as fast. The + difference is not noticeable for small data sets but + becomes human-perceivable when enough rows are + involved. */ + const row = stmt.get([]); + const rv = Object.create(null); + for( const i in cache.columnNames ) rv[cache.columnNames[i]] = row[i]; + return rv; + }; + break; + case 'array': out.cbArg = (stmt)=>stmt.get([]); break; + case 'stmt': + if(Array.isArray(opt.resultRows)){ + toss3("exec(): invalid rowMode for a resultRows array: must", + "be one of 'array', 'object',", + "a result column number, or column name reference."); + } + out.cbArg = (stmt)=>stmt; + break; + default: + if(util.isInt32(opt.rowMode)){ + out.cbArg = (stmt)=>stmt.get(opt.rowMode); break; - default: - if(util.isInt32(opt.rowMode)){ - out.cbArg = (stmt)=>stmt.get(opt.rowMode); - break; - }else if('string'===typeof opt.rowMode - && opt.rowMode.length>1 - && '$'===opt.rowMode[0]){ - /* "$X": fetch column named "X" (case-sensitive!). Prior - to 2022-12-14 ":X" and "@X" were also permitted, but - having so many options is unnecessary and likely to - cause confusion. */ - const $colName = opt.rowMode.substr(1); - out.cbArg = (stmt)=>{ - const rc = stmt.get(Object.create(null))[$colName]; - return (undefined===rc) - ? toss3(capi.SQLITE_NOTFOUND, - "exec(): unknown result column:",$colName) - : rc; - }; - break; - } - toss3("Invalid rowMode:",opt.rowMode); + }else if('string'===typeof opt.rowMode + && opt.rowMode.length>1 + && '$'===opt.rowMode[0]){ + /* "$X": fetch column named "X" (case-sensitive!). Prior + to 2022-12-14 ":X" and "@X" were also permitted, but + having so many options is unnecessary and likely to + cause confusion. */ + const $colName = opt.rowMode.substr(1); + out.cbArg = (stmt)=>{ + const rc = stmt.get(Object.create(null))[$colName]; + return (undefined===rc) + ? toss3(capi.SQLITE_NOTFOUND, + "exec(): unknown result column:",$colName) + : rc; + }; + break; + } + toss3("Invalid rowMode:",opt.rowMode); } } return out; @@ -884,10 +1041,15 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ and names. */) ? 0 : 1; evalFirstResult = false; if(arg.cbArg || resultRows){ + const cbArgCache = Object.create(null) + /* 2nd arg for arg.cbArg, used by (at least) row-to-object + converter */; for(; stmt.step(); stmt._lockedByExec = false){ - if(0===gotColNames++) stmt.getColumnNames(opt.columnNames); + if(0===gotColNames++){ + stmt.getColumnNames(cbArgCache.columnNames = (opt.columnNames || [])); + } stmt._lockedByExec = true; - const row = arg.cbArg(stmt); + const row = arg.cbArg(stmt,cbArgCache); if(resultRows) resultRows.push(row); if(callback && false === callback.call(opt, row, stmt)){ break; @@ -1522,7 +1684,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ they are larger than 32 bits, else double or int32, depending on whether they have a fractional part. Booleans are bound as integer 0 or 1. It is not expected the distinction of binding - doubles which have no fractional parts is integers is + doubles which have no fractional parts and integers is significant for the majority of clients due to sqlite3's data typing model. If [BigInt] support is enabled then this routine will bind BigInt values as 64-bit integers if they'll @@ -1706,7 +1868,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ an exception is thrown. By default it will determine the data type of the result - automatically. If passed a second arugment, it must be one + automatically. If passed a second argument, it must be one of the enumeration values for sqlite3 types, which are defined as members of the sqlite3 module: SQLITE_INTEGER, SQLITE_FLOAT, SQLITE_TEXT, SQLITE_BLOB. Any other value, @@ -1906,16 +2068,26 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ Functionally equivalent to DB(storageName,'c','kvvfs') except that it throws if the given storage name is not one of 'local' or 'session'. + + As of version 3.46, the argument may optionally be an options + object in the form: + + { + filename: 'session'|'local', + ... etc. (all options supported by the DB ctor) + } + + noting that the 'vfs' option supported by main DB + constructor is ignored here: the vfs is always 'kvvfs'. */ sqlite3.oo1.JsStorageDb = function(storageName='session'){ + const opt = dbCtorHelper.normalizeArgs(...arguments); + storageName = opt.filename; if('session'!==storageName && 'local'!==storageName){ toss3("JsStorageDb db name must be one of 'session' or 'local'."); } - dbCtorHelper.call(this, { - filename: storageName, - flags: 'c', - vfs: "kvvfs" - }); + opt.vfs = 'kvvfs'; + dbCtorHelper.call(this, opt); }; const jdb = sqlite3.oo1.JsStorageDb; jdb.prototype = Object.create(DB.prototype); diff --git a/ext/wasm/api/sqlite3-api-prologue.js b/ext/wasm/api/sqlite3-api-prologue.js index ef1154f..689c79a 100644 --- a/ext/wasm/api/sqlite3-api-prologue.js +++ b/ext/wasm/api/sqlite3-api-prologue.js @@ -37,7 +37,7 @@ This function expects a configuration object, intended to abstract away details specific to any given WASM environment, primarily so - that it can be used without any _direct_ dependency on + that it can be used without any direct dependency on Emscripten. (Note the default values for the config object!) The config object is only honored the first time this is called. Subsequent calls ignore the argument and return the same @@ -98,14 +98,37 @@ The returned object is the top-level sqlite3 namespace object. + + Client code may optionally assign sqlite3ApiBootstrap.defaultConfig + an object-type value before calling sqlite3ApiBootstrap() (without + arguments) in order to tell that call to use this object as its + default config value. The intention of this is to provide + downstream clients with a reasonably flexible approach for plugging + in an environment-suitable configuration without having to define a + new global-scope symbol. + + However, because clients who access this library via an + Emscripten-hosted module will not have an opportunity to call + sqlite3ApiBootstrap() themselves, nor to access it before it is + called, an alternative option for setting the configuration is to + define globalThis.sqlite3ApiConfig to an object. If it is set, it + is used instead of sqlite3ApiBootstrap.defaultConfig if + sqlite3ApiBootstrap() is called without arguments. + + Both sqlite3ApiBootstrap.defaultConfig and + globalThis.sqlite3ApiConfig get deleted by sqlite3ApiBootstrap() + because any changes to them made after that point would have no + useful effect. */ 'use strict'; globalThis.sqlite3ApiBootstrap = function sqlite3ApiBootstrap( apiConfig = (globalThis.sqlite3ApiConfig || sqlite3ApiBootstrap.defaultConfig) ){ if(sqlite3ApiBootstrap.sqlite3){ /* already initalized */ - console.warn("sqlite3ApiBootstrap() called multiple times.", - "Config and external initializers are ignored on calls after the first."); + (sqlite3ApiBootstrap.sqlite3.config || console).warn( + "sqlite3ApiBootstrap() called multiple times.", + "Config and external initializers are ignored on calls after the first." + ); return sqlite3ApiBootstrap.sqlite3; } const config = Object.assign(Object.create(null),{ @@ -114,8 +137,16 @@ globalThis.sqlite3ApiBootstrap = function sqlite3ApiBootstrap( bigIntEnabled: (()=>{ if('undefined'!==typeof Module){ /* Emscripten module will contain HEAPU64 when built with - -sWASM_BIGINT=1, else it will not. */ - return !!Module.HEAPU64; + -sWASM_BIGINT=1, else it will not. + + As of emsdk 3.1.55, when building in strict mode, HEAPxyz + are only available if _explicitly_ included in the exports, + else they are not. We do not (as of 2024-03-04) use -sSTRICT + for the canonical builds. + */ + if( !!Module.HEAPU64 ) return true; + /* Else fall through and hope for the best. Nobody _really_ + builds this without BigInt support, do they? */ } return !!globalThis.BigInt64Array; })(), @@ -149,6 +180,15 @@ globalThis.sqlite3ApiBootstrap = function sqlite3ApiBootstrap( config[k] = config[k](); } }); + + /** + Eliminate any confusion about whether these config objects may + be used after library initialization by eliminating the outward-facing + objects... + */ + delete globalThis.sqlite3ApiConfig; + delete sqlite3ApiBootstrap.defaultConfig; + /** The main sqlite3 binding API gets installed into this object, mimicking the C API as closely as we can. The numerous members @@ -205,7 +245,7 @@ globalThis.sqlite3ApiBootstrap = function sqlite3ApiBootstrap( The exception's message is created by concatenating its arguments with a space between each, except for the - two-args-with-an-objec form and that the first argument will + two-args-with-an-object form and that the first argument will get coerced to a string, as described above, if it's an integer. @@ -1061,7 +1101,7 @@ globalThis.sqlite3ApiBootstrap = function sqlite3ApiBootstrap( are undefined if the passed-in value did not come from this.pointer. */ - restore: wasm.exports.sqlite3_wasm_pstack_restore, + restore: wasm.exports.sqlite3__wasm_pstack_restore, /** Attempts to allocate the given number of bytes from the pstack. On success, it zeroes out a block of memory of the @@ -1083,7 +1123,7 @@ globalThis.sqlite3ApiBootstrap = function sqlite3ApiBootstrap( if('string'===typeof n && !(n = wasm.sizeofIR(n))){ WasmAllocError.toss("Invalid value for pstack.alloc(",arguments[0],")"); } - return wasm.exports.sqlite3_wasm_pstack_alloc(n) + return wasm.exports.sqlite3__wasm_pstack_alloc(n) || WasmAllocError.toss("Could not allocate",n, "bytes from the pstack."); }, @@ -1163,10 +1203,10 @@ globalThis.sqlite3ApiBootstrap = function sqlite3ApiBootstrap( */ pointer: { configurable: false, iterable: true, writeable: false, - get: wasm.exports.sqlite3_wasm_pstack_ptr + get: wasm.exports.sqlite3__wasm_pstack_ptr //Whether or not a setter as an alternative to restore() is //clearer or would just lead to confusion is unclear. - //set: wasm.exports.sqlite3_wasm_pstack_restore + //set: wasm.exports.sqlite3__wasm_pstack_restore }, /** sqlite3.wasm.pstack.quota to the total number of bytes @@ -1175,7 +1215,7 @@ globalThis.sqlite3ApiBootstrap = function sqlite3ApiBootstrap( */ quota: { configurable: false, iterable: true, writeable: false, - get: wasm.exports.sqlite3_wasm_pstack_quota + get: wasm.exports.sqlite3__wasm_pstack_quota }, /** sqlite3.wasm.pstack.remaining resolves to the amount of space @@ -1183,7 +1223,7 @@ globalThis.sqlite3ApiBootstrap = function sqlite3ApiBootstrap( */ remaining: { configurable: false, iterable: true, writeable: false, - get: wasm.exports.sqlite3_wasm_pstack_remaining + get: wasm.exports.sqlite3__wasm_pstack_remaining } })/*wasm.pstack properties*/; @@ -1256,14 +1296,14 @@ globalThis.sqlite3ApiBootstrap = function sqlite3ApiBootstrap( } try{ if(pdir && 0===wasm.xCallWrapped( - 'sqlite3_wasm_init_wasmfs', 'i32', ['string'], pdir + 'sqlite3__wasm_init_wasmfs', 'i32', ['string'], pdir )){ return __wasmfsOpfsDir = pdir; }else{ return __wasmfsOpfsDir = ""; } }catch(e){ - // sqlite3_wasm_init_wasmfs() is not available + // sqlite3__wasm_init_wasmfs() is not available return __wasmfsOpfsDir = ""; } }; @@ -1365,7 +1405,7 @@ globalThis.sqlite3ApiBootstrap = function sqlite3ApiBootstrap( const zSchema = schema ? (wasm.isPtr(schema) ? schema : wasm.scopedAllocCString(''+schema)) : 0; - let rc = wasm.exports.sqlite3_wasm_db_serialize( + let rc = wasm.exports.sqlite3__wasm_db_serialize( pDb, zSchema, ppOut, pSize, 0 ); if(rc){ @@ -1391,7 +1431,7 @@ globalThis.sqlite3ApiBootstrap = function sqlite3ApiBootstrap( or not provided, then "main" is assumed. */ capi.sqlite3_js_db_vfs = - (dbPointer, dbName=0)=>wasm.sqlite3_wasm_db_vfs(dbPointer, dbName); + (dbPointer, dbName=0)=>util.sqlite3__wasm_db_vfs(dbPointer, dbName); /** A thin wrapper around capi.sqlite3_aggregate_context() which @@ -1449,7 +1489,7 @@ globalThis.sqlite3ApiBootstrap = function sqlite3ApiBootstrap( if(!util.isInt32(dataLen) || dataLen<0){ SQLite3Error.toss("Invalid 3rd argument for sqlite3_js_posix_create_file()."); } - const rc = wasm.sqlite3_wasm_posix_create_file(filename, pData, dataLen); + const rc = util.sqlite3__wasm_posix_create_file(filename, pData, dataLen); if(rc) SQLite3Error.toss("Creation of file failed with sqlite3 result code", capi.sqlite3_js_rc_str(rc)); }finally{ @@ -1551,7 +1591,7 @@ globalThis.sqlite3ApiBootstrap = function sqlite3ApiBootstrap( SQLite3Error.toss("Invalid 4th argument for sqlite3_js_vfs_create_file()."); } try{ - const rc = wasm.sqlite3_wasm_vfs_create_file(vfs, filename, pData, dataLen); + const rc = util.sqlite3__wasm_vfs_create_file(vfs, filename, pData, dataLen); if(rc) SQLite3Error.toss("Creation of file failed with sqlite3 result code", capi.sqlite3_js_rc_str(rc)); }finally{ @@ -1672,12 +1712,12 @@ globalThis.sqlite3ApiBootstrap = function sqlite3ApiBootstrap( */ capi.sqlite3_db_config = function(pDb, op, ...args){ if(!this.s){ - this.s = wasm.xWrap('sqlite3_wasm_db_config_s','int', + this.s = wasm.xWrap('sqlite3__wasm_db_config_s','int', ['sqlite3*', 'int', 'string:static'] /* MAINDBNAME requires a static string */); - this.pii = wasm.xWrap('sqlite3_wasm_db_config_pii', 'int', + this.pii = wasm.xWrap('sqlite3__wasm_db_config_pii', 'int', ['sqlite3*', 'int', '*','int', 'int']); - this.ip = wasm.xWrap('sqlite3_wasm_db_config_ip','int', + this.ip = wasm.xWrap('sqlite3__wasm_db_config_ip','int', ['sqlite3*', 'int', 'int','*']); } switch(op){ @@ -1798,7 +1838,7 @@ globalThis.sqlite3ApiBootstrap = function sqlite3ApiBootstrap( /** Calls either sqlite3_result_error_nomem(), if e is-a WasmAllocError, or sqlite3_result_error(). In the latter case, - the second arugment is coerced to a string to create the error + the second argument is coerced to a string to create the error message. The first argument is a (sqlite3_context*). Returns void. diff --git a/ext/wasm/api/sqlite3-api-worker1.js b/ext/wasm/api/sqlite3-api-worker1.js index 3099c19..2e59761 100644 --- a/ext/wasm/api/sqlite3-api-worker1.js +++ b/ext/wasm/api/sqlite3-api-worker1.js @@ -359,6 +359,7 @@ */ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ +const util = sqlite3.util; sqlite3.initWorker1API = function(){ 'use strict'; const toss = (...args)=>{throw new Error(args.join(' '))}; @@ -409,12 +410,12 @@ sqlite3.initWorker1API = function(){ if(db){ delete this.dbs[getDbId(db)]; const filename = db.filename; - const pVfs = sqlite3.wasm.sqlite3_wasm_db_vfs(db.pointer, 0); + const pVfs = util.sqlite3__wasm_db_vfs(db.pointer, 0); db.close(); const ddNdx = this.dbList.indexOf(db); if(ddNdx>=0) this.dbList.splice(ddNdx, 1); if(alsoUnlink && filename && pVfs){ - sqlite3.wasm.sqlite3_wasm_vfs_unlink(pVfs, filename); + util.sqlite3__wasm_vfs_unlink(pVfs, filename); } } }, @@ -458,11 +459,6 @@ sqlite3.initWorker1API = function(){ return wState.dbList[0] && getDbId(wState.dbList[0]); }; - const guessVfs = function(filename){ - const m = /^file:.+(vfs=(\w+))/.exec(filename); - return sqlite3.capi.sqlite3_vfs_find(m ? m[2] : 0); - }; - const isSpecialDbFilename = (n)=>{ return ""===n || ':'===n[0]; }; @@ -484,36 +480,8 @@ sqlite3.initWorker1API = function(){ toss("Throwing because of simulateError flag."); } const rc = Object.create(null); - let byteArray, pVfs; oargs.vfs = args.vfs; - if(isSpecialDbFilename(args.filename)){ - oargs.filename = args.filename || ""; - }else{ - oargs.filename = args.filename; - byteArray = args.byteArray; - if(byteArray) pVfs = guessVfs(args.filename); - } - if(pVfs){ - /* 2022-11-02: this feature is as-yet untested except that - sqlite3_wasm_vfs_create_file() has been tested from the - browser dev console. */ - let pMem; - try{ - pMem = sqlite3.wasm.allocFromTypedArray(byteArray); - const rc = sqlite3.wasm.sqlite3_wasm_vfs_create_file( - pVfs, oargs.filename, pMem, byteArray.byteLength - ); - if(rc) sqlite3.SQLite3Error.toss(rc); - }catch(e){ - throw new sqlite3.SQLite3Error( - e.name+' creating '+args.filename+": "+e.message, { - cause: e - } - ); - }finally{ - if(pMem) sqlite3.wasm.dealloc(pMem); - } - } + oargs.filename = args.filename || ""; const db = wState.open(oargs); rc.filename = db.filename; rc.persistent = !!sqlite3.capi.sqlite3_js_db_uses_vfs(db.pointer, "opfs"); diff --git a/ext/wasm/api/sqlite3-opfs-async-proxy.js b/ext/wasm/api/sqlite3-opfs-async-proxy.js index cafd296..e671094 100644 --- a/ext/wasm/api/sqlite3-opfs-async-proxy.js +++ b/ext/wasm/api/sqlite3-opfs-async-proxy.js @@ -51,7 +51,7 @@ */ "use strict"; const wPost = (type,...args)=>postMessage({type, payload:args}); -const installAsyncProxy = function(self){ +const installAsyncProxy = function(){ const toss = function(...args){throw new Error(args.join(' '))}; if(globalThis.window === globalThis){ toss("This code cannot run from the main thread.", @@ -562,6 +562,14 @@ const installAsyncProxy = function(self){ wTimeEnd(); return; } + if( state.opfsFlags.OPFS_UNLINK_BEFORE_OPEN & opfsFlags ){ + try{ + await hDir.removeEntry(filenamePart); + }catch(e){ + /* ignoring */ + //warn("Ignoring failed Unlink of",filename,":",e); + } + } const hFile = await hDir.getFileHandle(filenamePart, {create}); wTimeEnd(); const fh = Object.assign(Object.create(null),{ @@ -911,5 +919,5 @@ if(!globalThis.SharedArrayBuffer){ !navigator?.storage?.getDirectory){ wPost('opfs-unavailable',"Missing required OPFS APIs."); }else{ - installAsyncProxy(self); + installAsyncProxy(); } diff --git a/ext/wasm/api/sqlite3-vfs-helper.c-pp.js b/ext/wasm/api/sqlite3-vfs-helper.c-pp.js new file mode 100644 index 0000000..4d29c7b --- /dev/null +++ b/ext/wasm/api/sqlite3-vfs-helper.c-pp.js @@ -0,0 +1,103 @@ +/* +** 2022-11-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. +*/ + +/** + This file installs sqlite3.vfs, a namespace of helpers for use in + the creation of JavaScript implementations of sqlite3_vfs. +*/ +'use strict'; +globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ + const wasm = sqlite3.wasm, capi = sqlite3.capi, toss = sqlite3.util.toss3; + const vfs = Object.create(null); + sqlite3.vfs = vfs; + + /** + Uses sqlite3_vfs_register() to register this + sqlite3.capi.sqlite3_vfs instance. This object must have already + been filled out properly. If the first argument is truthy, the + VFS is registered as the default VFS, else it is not. + + On success, returns this object. Throws on error. + */ + capi.sqlite3_vfs.prototype.registerVfs = function(asDefault=false){ + if(!(this instanceof sqlite3.capi.sqlite3_vfs)){ + toss("Expecting a sqlite3_vfs-type argument."); + } + const rc = capi.sqlite3_vfs_register(this, asDefault ? 1 : 0); + if(rc){ + toss("sqlite3_vfs_register(",this,") failed with rc",rc); + } + if(this.pointer !== capi.sqlite3_vfs_find(this.$zName)){ + toss("BUG: sqlite3_vfs_find(vfs.$zName) failed for just-installed VFS", + this); + } + return this; + }; + + /** + A wrapper for + sqlite3.StructBinder.StructType.prototype.installMethods() or + registerVfs() to reduce installation of a VFS and/or its I/O + methods to a single call. + + Accepts an object which contains the properties "io" and/or + "vfs", each of which is itself an object with following properties: + + - `struct`: an sqlite3.StructBinder.StructType-type struct. This + must be a populated (except for the methods) object of type + sqlite3_io_methods (for the "io" entry) or sqlite3_vfs (for the + "vfs" entry). + + - `methods`: an object mapping sqlite3_io_methods method names + (e.g. 'xClose') to JS implementations of those methods. The JS + implementations must be call-compatible with their native + counterparts. + + For each of those object, this function passes its (`struct`, + `methods`, (optional) `applyArgcCheck`) properties to + installMethods(). + + If the `vfs` entry is set then: + + - Its `struct` property's registerVfs() is called. The + `vfs` entry may optionally have an `asDefault` property, which + gets passed as the argument to registerVfs(). + + - If `struct.$zName` is falsy and the entry has a string-type + `name` property, `struct.$zName` is set to the C-string form of + that `name` value before registerVfs() is called. That string + gets added to the on-dispose state of the struct. + + On success returns this object. Throws on error. + */ + vfs.installVfs = function(opt){ + let count = 0; + const propList = ['io','vfs']; + for(const key of propList){ + const o = opt[key]; + if(o){ + ++count; + o.struct.installMethods(o.methods, !!o.applyArgcCheck); + if('vfs'===key){ + if(!o.struct.$zName && 'string'===typeof o.name){ + o.struct.addOnDispose( + o.struct.$zName = wasm.allocCString(o.name) + ); + } + o.struct.registerVfs(!!o.asDefault); + } + } + } + if(!count) toss("Misuse: installVfs() options object requires at least", + "one of:", propList); + return this; + }; +}/*sqlite3ApiBootstrap.initializers.push()*/); diff --git a/ext/wasm/api/sqlite3-vfs-opfs-sahpool.c-pp.js b/ext/wasm/api/sqlite3-vfs-opfs-sahpool.c-pp.js index 2089ece..3f4182d 100644 --- a/ext/wasm/api/sqlite3-vfs-opfs-sahpool.c-pp.js +++ b/ext/wasm/api/sqlite3-vfs-opfs-sahpool.c-pp.js @@ -1137,8 +1137,9 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ existing content. Throws if the pool has no available file slots, on I/O error, or if the input does not appear to be a database. In the latter case, only a cursory examination is made. - Note that this routine is _only_ for importing database files, - not arbitrary files, the reason being that this VFS will + Results are undefined if the given db name refers to an opened + db. Note that this routine is _only_ for importing database + files, not arbitrary files, the reason being that this VFS will automatically clean up any non-database files so importing them is pointless. diff --git a/ext/wasm/api/sqlite3-vfs-opfs.c-pp.js b/ext/wasm/api/sqlite3-vfs-opfs.c-pp.js index af89f21..4c654c3 100644 --- a/ext/wasm/api/sqlite3-vfs-opfs.c-pp.js +++ b/ext/wasm/api/sqlite3-vfs-opfs.c-pp.js @@ -245,7 +245,8 @@ const installOpfsVfs = function callee(options){ opfsIoMethods.$iVersion = 1; opfsVfs.$iVersion = 2/*yes, two*/; opfsVfs.$szOsFile = capi.sqlite3_file.structInfo.sizeof; - opfsVfs.$mxPathname = 1024/*sure, why not?*/; + opfsVfs.$mxPathname = 1024/* sure, why not? The OPFS name length limit + is undocumented/unspecified. */; opfsVfs.$zName = wasm.allocCString("opfs"); // All C-side memory of opfsVfs is zeroed out, but just to be explicit: opfsVfs.$xDlOpen = opfsVfs.$xDlError = opfsVfs.$xDlSym = opfsVfs.$xDlClose = null; @@ -422,11 +423,26 @@ const installOpfsVfs = function callee(options){ }); state.opfsFlags = Object.assign(Object.create(null),{ /** - Flag for use with xOpen(). "opfs-unlock-asap=1" enables - this. See defaultUnlockAsap, below. + Flag for use with xOpen(). URI flag "opfs-unlock-asap=1" + enables this. See defaultUnlockAsap, below. */ OPFS_UNLOCK_ASAP: 0x01, /** + Flag for use with xOpen(). URI flag "delete-before-open=1" + tells the VFS to delete the db file before attempting to open + it. This can be used, e.g., to replace a db which has been + corrupted (without forcing us to expose a delete/unlink() + function in the public API). + + Failure to unlink the file is ignored but may lead to + downstream errors. An unlink can fail if, e.g., another tab + has the handle open. + + It goes without saying that deleting a file out from under another + instance results in Undefined Behavior. + */ + OPFS_UNLINK_BEFORE_OPEN: 0x02, + /** If true, any async routine which implicitly acquires a sync access handle (i.e. an OPFS lock) will release that locks at the end of the call which acquires it. If false, such @@ -874,13 +890,17 @@ const installOpfsVfs = function callee(options){ let opfsFlags = 0; if(0===zName){ zName = randomFilename(); - }else if('number'===typeof zName){ + }else if(wasm.isPtr(zName)){ if(capi.sqlite3_uri_boolean(zName, "opfs-unlock-asap", 0)){ /* -----------------------^^^^^ MUST pass the untranslated C-string here. */ opfsFlags |= state.opfsFlags.OPFS_UNLOCK_ASAP; } + if(capi.sqlite3_uri_boolean(zName, "delete-before-open", 0)){ + opfsFlags |= state.opfsFlags.OPFS_UNLINK_BEFORE_OPEN; + } zName = wasm.cstrToJs(zName); + //warn("xOpen zName =",zName, "opfsFlags =",opfsFlags); } const fh = Object.create(null); fh.fid = pFile; @@ -994,27 +1014,6 @@ const installOpfsVfs = function callee(options){ opfsUtil.randomFilename = randomFilename; /** - Re-registers the OPFS VFS. This is intended only for odd use - cases which have to call sqlite3_shutdown() as part of their - initialization process, which will unregister the VFS - registered by installOpfsVfs(). If passed a truthy value, the - OPFS VFS is registered as the default VFS, else it is not made - the default. Returns the result of the the - sqlite3_vfs_register() call. - - Design note: the problem of having to re-register things after - a shutdown/initialize pair is more general. How to best plug - that in to the library is unclear. In particular, we cannot - hook in to any C-side calls to sqlite3_initialize(), so we - cannot add an after-initialize callback mechanism. - */ - opfsUtil.registerVfs = (asDefault=false)=>{ - return wasm.exports.sqlite3_vfs_register( - opfsVfs.pointer, asDefault ? 1 : 0 - ); - }; - - /** Returns a promise which resolves to an object which represents all files and directories in the OPFS tree. The top-most object has two properties: `dirs` is an array of directory entries @@ -1213,16 +1212,18 @@ const installOpfsVfs = function callee(options){ Asynchronously imports the given bytes (a byte array or ArrayBuffer) into the given database file. + Results are undefined if the given db name refers to an opened + db. + If passed a function for its second argument, its behaviour - changes to async and it imports its data in chunks fed to it by - the given callback function. It calls the callback (which may - be async) repeatedly, expecting either a Uint8Array or - ArrayBuffer (to denote new input) or undefined (to denote - EOF). For so long as the callback continues to return - non-undefined, it will append incoming data to the given - VFS-hosted database file. When called this way, the resolved - value of the returned Promise is the number of bytes written to - the target file. + changes: imports its data in chunks fed to it by the given + callback function. It calls the callback (which may be async) + repeatedly, expecting either a Uint8Array or ArrayBuffer (to + denote new input) or undefined (to denote EOF). For so long as + the callback continues to return non-undefined, it will append + incoming data to the given VFS-hosted database file. When + 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 diff --git a/ext/wasm/api/sqlite3-v-helper.js b/ext/wasm/api/sqlite3-vtab-helper.c-pp.js index e63da8a..7359ea3 100644 --- a/ext/wasm/api/sqlite3-v-helper.js +++ b/ext/wasm/api/sqlite3-vtab-helper.c-pp.js @@ -10,19 +10,13 @@ */ /** - This file installs sqlite3.vfs, and object which exists to assist - in the creation of JavaScript implementations of sqlite3_vfs, along - with its virtual table counterpart, sqlite3.vtab. + This file installs sqlite3.vtab, a namespace of helpers for use in + the creation of JavaScript implementations virtual tables. */ 'use strict'; globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ const wasm = sqlite3.wasm, capi = sqlite3.capi, toss = sqlite3.util.toss3; - const vfs = Object.create(null), vtab = Object.create(null); - - const StructBinder = sqlite3.StructBinder - /* we require a local alias b/c StructBinder is removed from the sqlite3 - object during the final steps of the API cleanup. */; - sqlite3.vfs = vfs; + const vtab = Object.create(null); sqlite3.vtab = vtab; const sii = capi.sqlite3_index_info; @@ -73,257 +67,6 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ }; /** - Installs a StructBinder-bound function pointer member of the - given name and function in the given StructType target object. - - It creates a WASM proxy for the given function and arranges for - that proxy to be cleaned up when tgt.dispose() is called. Throws - on the slightest hint of error, e.g. tgt is-not-a StructType, - name does not map to a struct-bound member, etc. - - As a special case, if the given function is a pointer, then - `wasm.functionEntry()` is used to validate that it is a known - function. If so, it is used as-is with no extra level of proxying - or cleanup, else an exception is thrown. It is legal to pass a - value of 0, indicating a NULL pointer, with the caveat that 0 - _is_ a legal function pointer in WASM but it will not be accepted - as such _here_. (Justification: the function at address zero must - be one which initially came from the WASM module, not a method we - want to bind to a virtual table or VFS.) - - This function returns a proxy for itself which is bound to tgt - and takes 2 args (name,func). That function returns the same - thing as this one, permitting calls to be chained. - - If called with only 1 arg, it has no side effects but returns a - func with the same signature as described above. - - ACHTUNG: because we cannot generically know how to transform JS - exceptions into result codes, the installed functions do no - automatic catching of exceptions. It is critical, to avoid - undefined behavior in the C layer, that methods mapped via - this function do not throw. The exception, as it were, to that - rule is... - - If applyArgcCheck is true then each JS function (as opposed to - function pointers) gets wrapped in a proxy which asserts that it - is passed the expected number of arguments, throwing if the - argument count does not match expectations. That is only intended - for dev-time usage for sanity checking, and will leave the C - environment in an undefined state. - */ - const installMethod = function callee( - tgt, name, func, applyArgcCheck = callee.installMethodArgcCheck - ){ - if(!(tgt instanceof StructBinder.StructType)){ - toss("Usage error: target object is-not-a StructType."); - }else if(!(func instanceof Function) && !wasm.isPtr(func)){ - toss("Usage errror: expecting a Function or WASM pointer to one."); - } - if(1===arguments.length){ - return (n,f)=>callee(tgt, n, f, applyArgcCheck); - } - if(!callee.argcProxy){ - callee.argcProxy = function(tgt, funcName, func,sig){ - return function(...args){ - if(func.length!==arguments.length){ - toss("Argument mismatch for", - tgt.structInfo.name+"::"+funcName - +": Native signature is:",sig); - } - return func.apply(this, args); - } - }; - /* An ondispose() callback for use with - StructBinder-created types. */ - callee.removeFuncList = function(){ - if(this.ondispose.__removeFuncList){ - this.ondispose.__removeFuncList.forEach( - (v,ndx)=>{ - if('number'===typeof v){ - try{wasm.uninstallFunction(v)} - catch(e){/*ignore*/} - } - /* else it's a descriptive label for the next number in - the list. */ - } - ); - delete this.ondispose.__removeFuncList; - } - }; - }/*static init*/ - const sigN = tgt.memberSignature(name); - if(sigN.length<2){ - toss("Member",name,"does not have a function pointer signature:",sigN); - } - const memKey = tgt.memberKey(name); - const fProxy = (applyArgcCheck && !wasm.isPtr(func)) - /** This middle-man proxy is only for use during development, to - confirm that we always pass the proper number of - arguments. We know that the C-level code will always use the - correct argument count. */ - ? callee.argcProxy(tgt, memKey, func, sigN) - : func; - if(wasm.isPtr(fProxy)){ - if(fProxy && !wasm.functionEntry(fProxy)){ - toss("Pointer",fProxy,"is not a WASM function table entry."); - } - tgt[memKey] = fProxy; - }else{ - const pFunc = wasm.installFunction(fProxy, tgt.memberSignature(name, true)); - tgt[memKey] = pFunc; - if(!tgt.ondispose || !tgt.ondispose.__removeFuncList){ - tgt.addOnDispose('ondispose.__removeFuncList handler', - callee.removeFuncList); - tgt.ondispose.__removeFuncList = []; - } - tgt.ondispose.__removeFuncList.push(memKey, pFunc); - } - return (n,f)=>callee(tgt, n, f, applyArgcCheck); - }/*installMethod*/; - installMethod.installMethodArgcCheck = false; - - /** - Installs methods into the given StructType-type instance. Each - entry in the given methods object must map to a known member of - the given StructType, else an exception will be triggered. See - installMethod() for more details, including the semantics of the - 3rd argument. - - As an exception to the above, if any two or more methods in the - 2nd argument are the exact same function, installMethod() is - _not_ called for the 2nd and subsequent instances, and instead - those instances get assigned the same method pointer which is - created for the first instance. This optimization is primarily to - accommodate special handling of sqlite3_module::xConnect and - xCreate methods. - - On success, returns its first argument. Throws on error. - */ - const installMethods = function( - structInstance, methods, applyArgcCheck = installMethod.installMethodArgcCheck - ){ - const seen = new Map /* map of <Function, memberName> */; - for(const k of Object.keys(methods)){ - const m = methods[k]; - const prior = seen.get(m); - if(prior){ - const mkey = structInstance.memberKey(k); - structInstance[mkey] = structInstance[structInstance.memberKey(prior)]; - }else{ - installMethod(structInstance, k, m, applyArgcCheck); - seen.set(m, k); - } - } - return structInstance; - }; - - /** - Equivalent to calling installMethod(this,...arguments) with a - first argument of this object. If called with 1 or 2 arguments - and the first is an object, it's instead equivalent to calling - installMethods(this,...arguments). - */ - StructBinder.StructType.prototype.installMethod = function callee( - name, func, applyArgcCheck = installMethod.installMethodArgcCheck - ){ - return (arguments.length < 3 && name && 'object'===typeof name) - ? installMethods(this, ...arguments) - : installMethod(this, ...arguments); - }; - - /** - Equivalent to calling installMethods() with a first argument - of this object. - */ - StructBinder.StructType.prototype.installMethods = function( - methods, applyArgcCheck = installMethod.installMethodArgcCheck - ){ - return installMethods(this, methods, applyArgcCheck); - }; - - /** - Uses sqlite3_vfs_register() to register this - sqlite3.capi.sqlite3_vfs. This object must have already been - filled out properly. If the first argument is truthy, the VFS is - registered as the default VFS, else it is not. - - On success, returns this object. Throws on error. - */ - capi.sqlite3_vfs.prototype.registerVfs = function(asDefault=false){ - if(!(this instanceof sqlite3.capi.sqlite3_vfs)){ - toss("Expecting a sqlite3_vfs-type argument."); - } - const rc = capi.sqlite3_vfs_register(this, asDefault ? 1 : 0); - if(rc){ - toss("sqlite3_vfs_register(",this,") failed with rc",rc); - } - if(this.pointer !== capi.sqlite3_vfs_find(this.$zName)){ - toss("BUG: sqlite3_vfs_find(vfs.$zName) failed for just-installed VFS", - this); - } - return this; - }; - - /** - A wrapper for installMethods() or registerVfs() to reduce - installation of a VFS and/or its I/O methods to a single - call. - - Accepts an object which contains the properties "io" and/or - "vfs", each of which is itself an object with following properties: - - - `struct`: an sqlite3.StructType-type struct. This must be a - populated (except for the methods) object of type - sqlite3_io_methods (for the "io" entry) or sqlite3_vfs (for the - "vfs" entry). - - - `methods`: an object mapping sqlite3_io_methods method names - (e.g. 'xClose') to JS implementations of those methods. The JS - implementations must be call-compatible with their native - counterparts. - - For each of those object, this function passes its (`struct`, - `methods`, (optional) `applyArgcCheck`) properties to - installMethods(). - - If the `vfs` entry is set then: - - - Its `struct` property's registerVfs() is called. The - `vfs` entry may optionally have an `asDefault` property, which - gets passed as the argument to registerVfs(). - - - If `struct.$zName` is falsy and the entry has a string-type - `name` property, `struct.$zName` is set to the C-string form of - that `name` value before registerVfs() is called. That string - gets added to the on-dispose state of the struct. - - On success returns this object. Throws on error. - */ - vfs.installVfs = function(opt){ - let count = 0; - const propList = ['io','vfs']; - for(const key of propList){ - const o = opt[key]; - if(o){ - ++count; - installMethods(o.struct, o.methods, !!o.applyArgcCheck); - if('vfs'===key){ - if(!o.struct.$zName && 'string'===typeof o.name){ - o.struct.addOnDispose( - o.struct.$zName = wasm.allocCString(o.name) - ); - } - o.struct.registerVfs(!!o.asDefault); - } - } - } - if(!count) toss("Misuse: installVfs() options object requires at least", - "one of:", propList); - return this; - }; - - /** Internal factory function for xVtab and xCursor impls. */ const __xWrapFactory = function(methodName,StructType){ @@ -457,30 +200,6 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ vtab.xIndexInfo = (pIdxInfo)=>new capi.sqlite3_index_info(pIdxInfo); /** - Given an error object, this function returns - sqlite3.capi.SQLITE_NOMEM if (e instanceof - sqlite3.WasmAllocError), else it returns its - second argument. Its intended usage is in the methods - of a sqlite3_vfs or sqlite3_module: - - ``` - try{ - let rc = ... - return rc; - }catch(e){ - return sqlite3.vtab.exceptionToRc(e, sqlite3.capi.SQLITE_XYZ); - // where SQLITE_XYZ is some call-appropriate result code. - } - ``` - */ - /**vfs.exceptionToRc = vtab.exceptionToRc = - (e, defaultRc=capi.SQLITE_ERROR)=>( - (e instanceof sqlite3.WasmAllocError) - ? capi.SQLITE_NOMEM - : defaultRc - );*/ - - /** Given an sqlite3_module method name and error object, this function returns sqlite3.capi.SQLITE_NOMEM if (e instanceof sqlite3.WasmAllocError), else it returns its second argument. Its @@ -526,20 +245,6 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ vtab.xError.errorReporter = 1 ? console.error.bind(console) : false; /** - "The problem" with this is that it introduces an outer function with - a different arity than the passed-in method callback. That means we - cannot do argc validation on these. Additionally, some methods (namely - xConnect) may have call-specific error handling. It would be a shame to - hard-coded that per-method support in this function. - */ - /** vtab.methodCatcher = function(methodName, method, defaultErrRc=capi.SQLITE_ERROR){ - return function(...args){ - try { method(...args); } - }catch(e){ return vtab.xError(methodName, e, defaultRc) } - }; - */ - - /** A helper for sqlite3_vtab::xRowid() and xUpdate() implementations. It must be passed the final argument to one of those methods (an output pointer to an int64 row ID) and the @@ -685,12 +390,12 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ remethods[k] = fwrap(k, m); } } - installMethods(mod, remethods, false); + mod.installMethods(remethods, false); }else{ // No automatic exception handling. Trust the client // to not throw. - installMethods( - mod, methods, !!opt.applyArgcCheck/*undocumented option*/ + mod.installMethods( + methods, !!opt.applyArgcCheck/*undocumented option*/ ); } if(0===mod.$iVersion){ diff --git a/ext/wasm/api/sqlite3-wasm.c b/ext/wasm/api/sqlite3-wasm.c index 618d0f0..48ae229 100644 --- a/ext/wasm/api/sqlite3-wasm.c +++ b/ext/wasm/api/sqlite3-wasm.c @@ -238,28 +238,28 @@ ** Another option is to malloc() a chunk of our own and call that our ** "stack". */ -SQLITE_WASM_EXPORT void * sqlite3_wasm_stack_end(void){ +SQLITE_WASM_EXPORT void * sqlite3__wasm_stack_end(void){ extern void __heap_base /* see https://stackoverflow.com/questions/10038964 */; return &__heap_base; } -SQLITE_WASM_EXPORT void * sqlite3_wasm_stack_begin(void){ +SQLITE_WASM_EXPORT void * sqlite3__wasm_stack_begin(void){ extern void __data_end; return &__data_end; } static void * pWasmStackPtr = 0; -SQLITE_WASM_EXPORT void * sqlite3_wasm_stack_ptr(void){ - if(!pWasmStackPtr) pWasmStackPtr = sqlite3_wasm_stack_end(); +SQLITE_WASM_EXPORT void * sqlite3__wasm_stack_ptr(void){ + if(!pWasmStackPtr) pWasmStackPtr = sqlite3__wasm_stack_end(); return pWasmStackPtr; } -SQLITE_WASM_EXPORT void sqlite3_wasm_stack_restore(void * p){ +SQLITE_WASM_EXPORT void sqlite3__wasm_stack_restore(void * p){ pWasmStackPtr = p; } -SQLITE_WASM_EXPORT void * sqlite3_wasm_stack_alloc(int n){ +SQLITE_WASM_EXPORT void * sqlite3__wasm_stack_alloc(int n){ if(n<=0) return 0; n = (n + 7) & ~7 /* align to 8-byte boundary */; - unsigned char * const p = (unsigned char *)sqlite3_wasm_stack_ptr(); - unsigned const char * const b = (unsigned const char *)sqlite3_wasm_stack_begin(); + unsigned char * const p = (unsigned char *)sqlite3__wasm_stack_ptr(); + unsigned const char * const b = (unsigned const char *)sqlite3__wasm_stack_begin(); if(b + n >= p || b + n < b/*overflow*/) return 0; return pWasmStackPtr = p - n; } @@ -267,7 +267,7 @@ SQLITE_WASM_EXPORT void * sqlite3_wasm_stack_alloc(int n){ /* ** State for the "pseudo-stack" allocator implemented in -** sqlite3_wasm_pstack_xyz(). In order to avoid colliding with +** sqlite3__wasm_pstack_xyz(). In order to avoid colliding with ** Emscripten-controled stack space, it carves out a bit of stack ** memory to use for that purpose. This memory ends up in the ** WASM-managed memory, such that routines which manipulate the wasm @@ -291,14 +291,14 @@ static struct { /* ** Returns the current pstack position. */ -SQLITE_WASM_EXPORT void * sqlite3_wasm_pstack_ptr(void){ +SQLITE_WASM_EXPORT void * sqlite3__wasm_pstack_ptr(void){ return PStack.pPos; } /* ** Sets the pstack position poitner to p. Results are undefined if the -** given value did not come from sqlite3_wasm_pstack_ptr(). +** given value did not come from sqlite3__wasm_pstack_ptr(). */ -SQLITE_WASM_EXPORT void sqlite3_wasm_pstack_restore(unsigned char * p){ +SQLITE_WASM_EXPORT void sqlite3__wasm_pstack_restore(unsigned char * p){ assert(p>=PStack.pBegin && p<=PStack.pEnd && p>=PStack.pPos); assert(0==((unsigned long long)p & 0x7)); if(p>=PStack.pBegin && p<=PStack.pEnd /*&& p>=PStack.pPos*/){ @@ -313,7 +313,7 @@ SQLITE_WASM_EXPORT void sqlite3_wasm_pstack_restore(unsigned char * p){ ** JS code from having to do so, and most uses of the pstack will ** call for doing so). */ -SQLITE_WASM_EXPORT void * sqlite3_wasm_pstack_alloc(int n){ +SQLITE_WASM_EXPORT void * sqlite3__wasm_pstack_alloc(int n){ if( n<=0 ) return 0; //if( n & 0x7 ) n += 8 - (n & 0x7) /* align to 8-byte boundary */; n = (n + 7) & ~7 /* align to 8-byte boundary */; @@ -324,9 +324,9 @@ SQLITE_WASM_EXPORT void * sqlite3_wasm_pstack_alloc(int n){ } /* ** Return the number of bytes left which can be -** sqlite3_wasm_pstack_alloc()'d. +** sqlite3__wasm_pstack_alloc()'d. */ -SQLITE_WASM_EXPORT int sqlite3_wasm_pstack_remaining(void){ +SQLITE_WASM_EXPORT int sqlite3__wasm_pstack_remaining(void){ assert(PStack.pPos >= PStack.pBegin); assert(PStack.pPos <= PStack.pEnd); return (int)(PStack.pPos - PStack.pBegin); @@ -337,7 +337,7 @@ SQLITE_WASM_EXPORT int sqlite3_wasm_pstack_remaining(void){ ** any space which is currently allocated. This value is a ** compile-time constant. */ -SQLITE_WASM_EXPORT int sqlite3_wasm_pstack_quota(void){ +SQLITE_WASM_EXPORT int sqlite3__wasm_pstack_quota(void){ return (int)(PStack.pEnd - PStack.pBegin); } @@ -356,7 +356,7 @@ SQLITE_WASM_EXPORT int sqlite3_wasm_pstack_quota(void){ ** Returns err_code. */ SQLITE_WASM_EXPORT -int sqlite3_wasm_db_error(sqlite3*db, int err_code, const char *zMsg){ +int sqlite3__wasm_db_error(sqlite3*db, int err_code, const char *zMsg){ if( db!=0 ){ if( 0!=zMsg ){ const int nMsg = sqlite3Strlen30(zMsg); @@ -380,7 +380,7 @@ struct WasmTestStruct { }; typedef struct WasmTestStruct WasmTestStruct; SQLITE_WASM_EXPORT -void sqlite3_wasm_test_struct(WasmTestStruct * s){ +void sqlite3__wasm_test_struct(WasmTestStruct * s){ if(s){ s->v4 *= 2; s->v8 = s->v4 * 2; @@ -408,7 +408,7 @@ void sqlite3_wasm_test_struct(WasmTestStruct * s){ ** increased. In debug builds that will trigger an assert(). */ SQLITE_WASM_EXPORT -const char * sqlite3_wasm_enum_json(void){ +const char * sqlite3__wasm_enum_json(void){ static char aBuffer[1024 * 20] = {0} /* where the JSON goes */; int n = 0, nChildren = 0, nStruct = 0 /* output counters for figuring out where commas go */; @@ -425,7 +425,7 @@ const char * sqlite3_wasm_enum_json(void){ /* Core output macros... */ #define lenCheck assert(zPos < zEnd - 128 \ - && "sqlite3_wasm_enum_json() buffer is too small."); \ + && "sqlite3__wasm_enum_json() buffer is too small."); \ if( zPos >= zEnd - 128 ) return 0 #define outf(format,...) \ zPos += snprintf(zPos, ((size_t)(zEnd - zPos)), format, __VA_ARGS__); \ @@ -545,6 +545,10 @@ const char * sqlite3_wasm_enum_json(void){ DefInt(SQLITE_CONFIG_SMALL_MALLOC); DefInt(SQLITE_CONFIG_SORTERREF_SIZE); DefInt(SQLITE_CONFIG_MEMDB_MAXSIZE); + /* maintenance note: we specifically do not include + SQLITE_CONFIG_ROWID_IN_VIEW here, on the grounds that + it's only for legacy support and no apps written with + this API require that. */ } _DefGroup; DefGroup(dataTypes) { @@ -1220,7 +1224,7 @@ const char * sqlite3_wasm_enum_json(void){ ** call is returned. */ SQLITE_WASM_EXPORT -int sqlite3_wasm_vfs_unlink(sqlite3_vfs *pVfs, const char *zName){ +int sqlite3__wasm_vfs_unlink(sqlite3_vfs *pVfs, const char *zName){ int rc = SQLITE_MISUSE /* ??? */; if( 0==pVfs && 0!=zName ) pVfs = sqlite3_vfs_find(0); if( zName && pVfs && pVfs->xDelete ){ @@ -1238,7 +1242,7 @@ int sqlite3_wasm_vfs_unlink(sqlite3_vfs *pVfs, const char *zName){ ** given name is open. */ SQLITE_WASM_EXPORT -sqlite3_vfs * sqlite3_wasm_db_vfs(sqlite3 *pDb, const char *zDbName){ +sqlite3_vfs * sqlite3__wasm_db_vfs(sqlite3 *pDb, const char *zDbName){ sqlite3_vfs * pVfs = 0; sqlite3_file_control(pDb, zDbName ? zDbName : "main", SQLITE_FCNTL_VFS_POINTER, &pVfs); @@ -1261,7 +1265,7 @@ sqlite3_vfs * sqlite3_wasm_db_vfs(sqlite3 *pDb, const char *zDbName){ ** SQLITE_MISUSE if pDb is NULL. */ SQLITE_WASM_EXPORT -int sqlite3_wasm_db_reset(sqlite3 *pDb){ +int sqlite3__wasm_db_reset(sqlite3 *pDb){ int rc = SQLITE_MISUSE; if( pDb ){ sqlite3_table_column_metadata(pDb, "main", 0, 0, 0, 0, 0, 0, 0); @@ -1288,11 +1292,11 @@ int sqlite3_wasm_db_reset(sqlite3 *pDb){ ** takes no measures to ensure that is the case. ** ** This implementation appears to work fine, but -** sqlite3_wasm_db_serialize() is arguably the better way to achieve +** sqlite3__wasm_db_serialize() is arguably the better way to achieve ** this. */ SQLITE_WASM_EXPORT -int sqlite3_wasm_db_export_chunked( sqlite3* pDb, +int sqlite3__wasm_db_export_chunked( sqlite3* pDb, int (*xCallback)(unsigned const char *zOut, int n) ){ sqlite3_int64 nSize = 0; sqlite3_int64 nPos = 0; @@ -1343,7 +1347,7 @@ int sqlite3_wasm_db_export_chunked( sqlite3* pDb, ** sqlite3_free() to free it. */ SQLITE_WASM_EXPORT -int sqlite3_wasm_db_serialize( sqlite3 *pDb, const char *zSchema, +int sqlite3__wasm_db_serialize( sqlite3 *pDb, const char *zSchema, unsigned char **pOut, sqlite3_int64 *nOut, unsigned int mFlags ){ unsigned char * z; @@ -1366,7 +1370,7 @@ int sqlite3_wasm_db_serialize( sqlite3 *pDb, const char *zSchema, ** this function's out-of-scope use of the sqlite3_vfs/file/io_methods ** APIs leads to triggering of assertions in the core library. Its use ** is now deprecated and VFS-specific APIs for importing files need to -** be found to replace it. sqlite3_wasm_posix_create_file() is +** be found to replace it. sqlite3__wasm_posix_create_file() is ** suitable for the "unix" family of VFSes. ** ** Creates a new file using the I/O API of the given VFS, containing @@ -1407,7 +1411,7 @@ int sqlite3_wasm_db_serialize( sqlite3 *pDb, const char *zSchema, ** support is disabled or unavailable. */ SQLITE_WASM_EXPORT -int sqlite3_wasm_vfs_create_file( sqlite3_vfs *pVfs, +int sqlite3__wasm_vfs_create_file( sqlite3_vfs *pVfs, const char *zFilename, const unsigned char * pData, int nData ){ @@ -1497,7 +1501,7 @@ int sqlite3_wasm_vfs_create_file( sqlite3_vfs *pVfs, ** SQLITE_IOERR on error. */ SQLITE_WASM_EXPORT -int sqlite3_wasm_posix_create_file( const char *zFilename, +int sqlite3__wasm_posix_create_file( const char *zFilename, const unsigned char * pData, int nData ){ int rc; @@ -1520,17 +1524,17 @@ int sqlite3_wasm_posix_create_file( const char *zFilename, ** for use by the sqlite project's own JS/WASM bindings. ** ** Allocates sqlite3KvvfsMethods.nKeySize bytes from -** sqlite3_wasm_pstack_alloc() and returns 0 if that allocation fails, +** sqlite3__wasm_pstack_alloc() and returns 0 if that allocation fails, ** else it passes that string to kvstorageMakeKey() and returns a ** NUL-terminated pointer to that string. It is up to the caller to -** use sqlite3_wasm_pstack_restore() to free the returned pointer. +** use sqlite3__wasm_pstack_restore() to free the returned pointer. */ SQLITE_WASM_EXPORT -char * sqlite3_wasm_kvvfsMakeKeyOnPstack(const char *zClass, +char * sqlite3__wasm_kvvfsMakeKeyOnPstack(const char *zClass, const char *zKeyIn){ assert(sqlite3KvvfsMethods.nKeySize>24); char *zKeyOut = - (char *)sqlite3_wasm_pstack_alloc(sqlite3KvvfsMethods.nKeySize); + (char *)sqlite3__wasm_pstack_alloc(sqlite3KvvfsMethods.nKeySize); if(zKeyOut){ kvstorageMakeKey(zClass, zKeyIn, zKeyOut); } @@ -1545,7 +1549,7 @@ char * sqlite3_wasm_kvvfsMakeKeyOnPstack(const char *zClass, ** I/O methods and associated state. */ SQLITE_WASM_EXPORT -sqlite3_kvvfs_methods * sqlite3_wasm_kvvfs_methods(void){ +sqlite3_kvvfs_methods * sqlite3__wasm_kvvfs_methods(void){ return &sqlite3KvvfsMethods; } @@ -1560,7 +1564,7 @@ sqlite3_kvvfs_methods * sqlite3_wasm_kvvfs_methods(void){ ** valid value. */ SQLITE_WASM_EXPORT -int sqlite3_wasm_vtab_config(sqlite3 *pDb, int op, int arg){ +int sqlite3__wasm_vtab_config(sqlite3 *pDb, int op, int arg){ switch(op){ case SQLITE_VTAB_DIRECTONLY: case SQLITE_VTAB_INNOCUOUS: @@ -1580,7 +1584,7 @@ int sqlite3_wasm_vtab_config(sqlite3 *pDb, int op, int arg){ ** (int,int*) variadic args. */ SQLITE_WASM_EXPORT -int sqlite3_wasm_db_config_ip(sqlite3 *pDb, int op, int arg1, int* pArg2){ +int sqlite3__wasm_db_config_ip(sqlite3 *pDb, int op, int arg1, int* pArg2){ switch(op){ case SQLITE_DBCONFIG_ENABLE_FKEY: case SQLITE_DBCONFIG_ENABLE_TRIGGER: @@ -1613,7 +1617,7 @@ int sqlite3_wasm_db_config_ip(sqlite3 *pDb, int op, int arg1, int* pArg2){ ** (void*,int,int) variadic args. */ SQLITE_WASM_EXPORT -int sqlite3_wasm_db_config_pii(sqlite3 *pDb, int op, void * pArg1, int arg2, int arg3){ +int sqlite3__wasm_db_config_pii(sqlite3 *pDb, int op, void * pArg1, int arg2, int arg3){ switch(op){ case SQLITE_DBCONFIG_LOOKASIDE: return sqlite3_db_config(pDb, op, pArg1, arg2, arg3); @@ -1629,7 +1633,7 @@ int sqlite3_wasm_db_config_pii(sqlite3 *pDb, int op, void * pArg1, int arg2, int ** (const char *) variadic args. */ SQLITE_WASM_EXPORT -int sqlite3_wasm_db_config_s(sqlite3 *pDb, int op, const char *zArg){ +int sqlite3__wasm_db_config_s(sqlite3 *pDb, int op, const char *zArg){ switch(op){ case SQLITE_DBCONFIG_MAINDBNAME: return sqlite3_db_config(pDb, op, zArg); @@ -1646,7 +1650,7 @@ int sqlite3_wasm_db_config_s(sqlite3 *pDb, int op, const char *zArg){ ** a single integer argument. */ SQLITE_WASM_EXPORT -int sqlite3_wasm_config_i(int op, int arg){ +int sqlite3__wasm_config_i(int op, int arg){ return sqlite3_config(op, arg); } @@ -1658,7 +1662,7 @@ int sqlite3_wasm_config_i(int op, int arg){ ** two int arguments. */ SQLITE_WASM_EXPORT -int sqlite3_wasm_config_ii(int op, int arg1, int arg2){ +int sqlite3__wasm_config_ii(int op, int arg1, int arg2){ return sqlite3_config(op, arg1, arg2); } @@ -1670,39 +1674,28 @@ int sqlite3_wasm_config_ii(int op, int arg1, int arg2){ ** a single i64 argument. */ SQLITE_WASM_EXPORT -int sqlite3_wasm_config_j(int op, sqlite3_int64 arg){ +int sqlite3__wasm_config_j(int op, sqlite3_int64 arg){ return sqlite3_config(op, arg); } -#if 0 -// Pending removal after verification of a workaround discussed in the -// forum post linked to below. /* ** This function is NOT part of the sqlite3 public API. It is strictly ** for use by the sqlite project's own JS/WASM bindings. ** -** Returns a pointer to sqlite3_free(). In compliant browsers the -** return value, when passed to sqlite3.wasm.exports.functionEntry(), -** must resolve to the same function as -** sqlite3.wasm.exports.sqlite3_free. i.e. from a dev console where -** sqlite3 is exported globally, the following must be true: -** -** ``` -** sqlite3.wasm.functionEntry( -** sqlite3.wasm.exports.sqlite3_wasm_ptr_to_sqlite3_free() -** ) === sqlite3.wasm.exports.sqlite3_free -** ``` -** -** Using a function to return this pointer, as opposed to exporting it -** via sqlite3_wasm_enum_json(), is an attempt to work around a -** Safari-specific quirk covered at -** https://sqlite.org/forum/info/e5b20e1feb37a19a. -**/ +** If z is not NULL, returns the result of passing z to +** sqlite3_mprintf()'s %Q modifier (if addQuotes is true) or %q (if +** addQuotes is 0). Returns NULL if z is NULL or on OOM. +*/ SQLITE_WASM_EXPORT -void * sqlite3_wasm_ptr_to_sqlite3_free(void){ - return (void*)sqlite3_free; +char * sqlite3__wasm_qfmt_token(char *z, int addQuotes){ + char * rc = 0; + if( z ){ + rc = addQuotes + ? sqlite3_mprintf("%Q", z) + : sqlite3_mprintf("%q", z); + } + return rc; } -#endif #if defined(__EMSCRIPTEN__) && defined(SQLITE_ENABLE_WASMFS) #include <emscripten/wasmfs.h> @@ -1729,7 +1722,7 @@ void * sqlite3_wasm_ptr_to_sqlite3_free(void){ ** defined, SQLITE_NOTFOUND is returned without side effects. */ SQLITE_WASM_EXPORT -int sqlite3_wasm_init_wasmfs(const char *zMountPoint){ +int sqlite3__wasm_init_wasmfs(const char *zMountPoint){ static backend_t pOpfs = 0; if( !zMountPoint || !*zMountPoint ) zMountPoint = "/opfs"; if( !pOpfs ){ @@ -1749,7 +1742,7 @@ int sqlite3_wasm_init_wasmfs(const char *zMountPoint){ } #else SQLITE_WASM_EXPORT -int sqlite3_wasm_init_wasmfs(const char *zUnused){ +int sqlite3__wasm_init_wasmfs(const char *zUnused){ //emscripten_console_warn("WASMFS OPFS is not compiled in."); if(zUnused){/*unused*/} return SQLITE_NOTFOUND; @@ -1759,51 +1752,51 @@ int sqlite3_wasm_init_wasmfs(const char *zUnused){ #if SQLITE_WASM_TESTS SQLITE_WASM_EXPORT -int sqlite3_wasm_test_intptr(int * p){ +int sqlite3__wasm_test_intptr(int * p){ return *p = *p * 2; } SQLITE_WASM_EXPORT -void * sqlite3_wasm_test_voidptr(void * p){ +void * sqlite3__wasm_test_voidptr(void * p){ return p; } SQLITE_WASM_EXPORT -int64_t sqlite3_wasm_test_int64_max(void){ +int64_t sqlite3__wasm_test_int64_max(void){ return (int64_t)0x7fffffffffffffff; } SQLITE_WASM_EXPORT -int64_t sqlite3_wasm_test_int64_min(void){ - return ~sqlite3_wasm_test_int64_max(); +int64_t sqlite3__wasm_test_int64_min(void){ + return ~sqlite3__wasm_test_int64_max(); } SQLITE_WASM_EXPORT -int64_t sqlite3_wasm_test_int64_times2(int64_t x){ +int64_t sqlite3__wasm_test_int64_times2(int64_t x){ return x * 2; } SQLITE_WASM_EXPORT -void sqlite3_wasm_test_int64_minmax(int64_t * min, int64_t *max){ - *max = sqlite3_wasm_test_int64_max(); - *min = sqlite3_wasm_test_int64_min(); +void sqlite3__wasm_test_int64_minmax(int64_t * min, int64_t *max){ + *max = sqlite3__wasm_test_int64_max(); + *min = sqlite3__wasm_test_int64_min(); /*printf("minmax: min=%lld, max=%lld\n", *min, *max);*/ } SQLITE_WASM_EXPORT -int64_t sqlite3_wasm_test_int64ptr(int64_t * p){ - /*printf("sqlite3_wasm_test_int64ptr( @%lld = 0x%llx )\n", (int64_t)p, *p);*/ +int64_t sqlite3__wasm_test_int64ptr(int64_t * p){ + /*printf("sqlite3__wasm_test_int64ptr( @%lld = 0x%llx )\n", (int64_t)p, *p);*/ return *p = *p * 2; } SQLITE_WASM_EXPORT -void sqlite3_wasm_test_stack_overflow(int recurse){ - if(recurse) sqlite3_wasm_test_stack_overflow(recurse); +void sqlite3__wasm_test_stack_overflow(int recurse){ + if(recurse) sqlite3__wasm_test_stack_overflow(recurse); } /* For testing the 'string:dealloc' whwasmutil.xWrap() conversion. */ SQLITE_WASM_EXPORT -char * sqlite3_wasm_test_str_hello(int fail){ +char * sqlite3__wasm_test_str_hello(int fail){ char * s = fail ? 0 : (char *)sqlite3_malloc(6); if(s){ memcpy(s, "hello", 5); @@ -1838,12 +1831,12 @@ char * sqlite3_wasm_test_str_hello(int fail){ ** optional + or - sign in front, or a hexadecimal ** literal of the form 0x... */ -static int sqlite3_wasm_SQLTester_strnotglob(const char *zGlob, const char *z){ +static int sqlite3__wasm_SQLTester_strnotglob(const char *zGlob, const char *z){ int c, c2; int invert; int seen; typedef int (*recurse_f)(const char *,const char *); - static const recurse_f recurse = sqlite3_wasm_SQLTester_strnotglob; + static const recurse_f recurse = sqlite3__wasm_SQLTester_strnotglob; while( (c = (*(zGlob++)))!=0 ){ if( c=='*' ){ @@ -1918,11 +1911,10 @@ static int sqlite3_wasm_SQLTester_strnotglob(const char *zGlob, const char *z){ } SQLITE_WASM_EXPORT -int sqlite3_wasm_SQLTester_strglob(const char *zGlob, const char *z){ - return !sqlite3_wasm_SQLTester_strnotglob(zGlob, z); +int sqlite3__wasm_SQLTester_strglob(const char *zGlob, const char *z){ + return !sqlite3__wasm_SQLTester_strnotglob(zGlob, z); } - #endif /* SQLITE_WASM_TESTS */ #undef SQLITE_WASM_EXPORT diff --git a/ext/wasm/api/sqlite3-worker1-promiser.c-pp.js b/ext/wasm/api/sqlite3-worker1-promiser.c-pp.js index cd78ed4..55e497e 100644 --- a/ext/wasm/api/sqlite3-worker1-promiser.c-pp.js +++ b/ext/wasm/api/sqlite3-worker1-promiser.c-pp.js @@ -42,9 +42,13 @@ - `onready` (optional, but...): this callback is called with no arguments when the worker fires its initial 'sqlite3-api'/'worker1-ready' message, which it does when - sqlite3.initWorker1API() completes its initialization. This is - the simplest way to tell the worker to kick off work at the - earliest opportunity. + sqlite3.initWorker1API() completes its initialization. This is the + simplest way to tell the worker to kick off work at the earliest + opportunity, and the only way to know when the worker module has + completed loading. The irony of using a callback for this, instead + of returning a promise from sqlite3Worker1Promiser() is not lost on + the developers: see sqlite3Worker1Promiser.v2() which uses a + Promise instead. - `onunhandled` (optional): a callback which gets passed the message event object for any worker.onmessage() events which @@ -156,6 +160,7 @@ globalThis.sqlite3Worker1Promiser = function callee(config = callee.defaultConfi if(!config.worker) config.worker = callee.defaultConfig.worker; if('function'===typeof config.worker) config.worker = config.worker(); let dbId; + let promiserFunc; config.worker.onmessage = function(ev){ ev = ev.data; debug('worker1.onmessage',ev); @@ -163,7 +168,7 @@ globalThis.sqlite3Worker1Promiser = function callee(config = callee.defaultConfi if(!msgHandler){ if(ev && 'sqlite3-api'===ev.type && 'worker1-ready'===ev.result) { /*fired one time when the Worker1 API initializes*/ - if(config.onready) config.onready(); + if(config.onready) config.onready(promiserFunc); return; } msgHandler = handlerMap[ev.type] /* check for exec per-row callback */; @@ -192,7 +197,7 @@ globalThis.sqlite3Worker1Promiser = function callee(config = callee.defaultConfi try {msgHandler.resolve(ev)} catch(e){msgHandler.reject(e)} }/*worker.onmessage()*/; - return function(/*(msgType, msgArgs) || (msgEnvelope)*/){ + return promiserFunc = function(/*(msgType, msgArgs) || (msgEnvelope)*/){ let msg; if(1===arguments.length){ msg = arguments[0]; @@ -202,7 +207,7 @@ globalThis.sqlite3Worker1Promiser = function callee(config = callee.defaultConfi msg.args = arguments[1]; msg.dbId = msg.args.dbId; }else{ - toss("Invalid arugments for sqlite3Worker1Promiser()-created factory."); + toss("Invalid arguments for sqlite3Worker1Promiser()-created factory."); } if(!msg.dbId && msg.type!=='open') msg.dbId = dbId; msg.messageId = genMsgId(msg); @@ -246,9 +251,10 @@ globalThis.sqlite3Worker1Promiser = function callee(config = callee.defaultConfi return p; }; }/*sqlite3Worker1Promiser()*/; + globalThis.sqlite3Worker1Promiser.defaultConfig = { worker: function(){ -//#if target=es6-bundler-friendly +//#if target=es6-module return new Worker(new URL("sqlite3-worker1-bundler-friendly.mjs", import.meta.url),{ type: 'module' }); @@ -269,14 +275,72 @@ globalThis.sqlite3Worker1Promiser.defaultConfig = { return new Worker(theJs + globalThis.location.search); //#endif } -//#ifnot target=es6-bundler-friendly +//#ifnot target=es6-module .bind({ currentScript: globalThis?.document?.currentScript }) //#endif , onerror: (...args)=>console.error('worker1 promiser error',...args) -}; +}/*defaultConfig*/; + +/** + sqlite3Worker1Promiser.v2(), added in 3.46, works identically to + sqlite3Worker1Promiser() except that it returns a Promise instead + of relying an an onready callback in the config object. The Promise + resolves to the same factory function which + sqlite3Worker1Promiser() returns. + + If config is-a function or is an object which contains an onready + function, that function is replaced by a proxy which will resolve + after calling the original function and will reject if that + function throws. +*/ +sqlite3Worker1Promiser.v2 = function(config){ + let oldFunc; + if( 'function' == typeof config ){ + oldFunc = config; + config = {}; + }else if('function'===typeof config?.onready){ + oldFunc = config.onready; + delete config.onready; + } + const promiseProxy = Object.create(null); + config = Object.assign((config || Object.create(null)),{ + onready: async function(func){ + try { + if( oldFunc ) await oldFunc(func); + promiseProxy.resolve(func); + } + catch(e){promiseProxy.reject(e)} + } + }); + const p = new Promise(function(resolve,reject){ + promiseProxy.resolve = resolve; + promiseProxy.reject = reject; + }); + try{ + this.original(config); + }catch(e){ + promiseProxy.reject(e); + } + return p; +}.bind({ + /* We do this because clients are + recommended to delete globalThis.sqlite3Worker1Promiser. */ + original: sqlite3Worker1Promiser +}); + +//#if target=es6-module +/** + When built as a module, we export sqlite3Worker1Promiser.v2() + instead of sqlite3Worker1Promise() because (A) its interface is more + conventional for ESM usage and (B) the ESM option export option for + this API did not exist until v2 was created, so there's no backwards + incompatibility. +*/ +export default sqlite3Worker1Promiser.v2; +//#endif /* target=es6-module */ //#else /* Built with the omit-oo1 flag. */ //#endif ifnot omit-oo1 diff --git a/ext/wasm/common/whwasmutil.js b/ext/wasm/common/whwasmutil.js index 0437ef3..b8a2a87 100644 --- a/ext/wasm/common/whwasmutil.js +++ b/ext/wasm/common/whwasmutil.js @@ -1382,15 +1382,19 @@ globalThis.WhWasmUtilInstaller = function(target){ conversion of argument or return types, but see xWrap() and xCallWrapped() for variants which do. + If the first argument is a function is is assumed to be + a WASM-bound function and is used as-is instead of looking up + the function via xGet(). + As a special case, if passed only 1 argument after the name and that argument in an Array, that array's entries become the function arguments. (This is not an ambiguous case because it's not legal to pass an Array object to a WASM function.) */ target.xCall = function(fname, ...args){ - const f = target.xGet(fname); + const f = (fname instanceof Function) ? fname : target.xGet(fname); if(!(f instanceof Function)) toss("Exported symbol",fname,"is not a function."); - if(f.length!==args.length) __argcMismatch(fname,f.length) + if(f.length!==args.length) __argcMismatch(((f===fname) ? f.name : fname),f.length) /* This is arguably over-pedantic but we want to help clients keep from shooting themselves in the foot when calling C APIs. */; return (2===arguments.length && Array.isArray(arguments[1])) @@ -1537,7 +1541,7 @@ globalThis.WhWasmUtilInstaller = function(target){ jsFuncToWasm(). - bindScope (string): one of ('transient', 'context', - 'singleton'). Bind scopes are: + 'singleton', 'permanent'). Bind scopes are: - 'transient': it will convert JS functions to WASM only for the duration of the xWrap()'d function call, using @@ -1787,11 +1791,29 @@ globalThis.WhWasmUtilInstaller = function(target){ const __xResultAdapterCheck = (t)=>xResult.get(t) || toss("Result adapter not found:",t); + /** + Fetches the xWrap() argument adapter mapped to t, calls it, + passing in all remaining arguments, and returns the result. + Throws if t is not mapped to an argument converter. + */ cache.xWrap.convertArg = (t,...args)=>__xArgAdapterCheck(t)(...args); + /** + Identical to convertArg() except that it does not perform + an is-defined check on the mapping to t before invoking it. + */ cache.xWrap.convertArgNoCheck = (t,...args)=>xArg.get(t)(...args); + /** + Fetches the xWrap() result adapter mapped to t, calls it, passing + it v, and returns the result. Throws if t is not mapped to an + argument converter. + */ cache.xWrap.convertResult = (t,v)=>(null===t ? v : (t ? __xResultAdapterCheck(t)(v) : undefined)); + /** + Identical to convertResult() except that it does not perform an + is-defined check on the mapping to t before invoking it. + */ cache.xWrap.convertResultNoCheck = (t,v)=>(null===t ? v : (t ? xResult.get(t)(v) : undefined)); @@ -1903,15 +1925,15 @@ globalThis.WhWasmUtilInstaller = function(target){ const C-string, encoded as UTF-8, copies it to a JS string, and returns that JS string. - - `string:dealloc` or `utf8:dealloc) (results): treats the result value - as a non-const UTF-8 C-string, ownership of which has just been - transfered to the caller. It copies the C-string to a JS - string, frees the C-string, and returns the JS string. If such - a result value is NULL, the JS result is `null`. Achtung: when - using an API which returns results from a specific allocator, - e.g. `my_malloc()`, this conversion _is not legal_. Instead, an - equivalent conversion which uses the appropriate deallocator is - required. For example: + - `string:dealloc` or `utf8:dealloc` (results): treats the result + value as a non-const UTF-8 C-string, ownership of which has + just been transfered to the caller. It copies the C-string to a + JS string, frees the C-string, and returns the JS string. If + such a result value is NULL, the JS result is `null`. Achtung: + when using an API which returns results from a specific + allocator, e.g. `my_malloc()`, this conversion _is not + legal_. Instead, an equivalent conversion which uses the + appropriate deallocator is required. For example: ```js target.xWrap.resultAdapter('string:my_free',(i)=>{ @@ -2012,8 +2034,12 @@ globalThis.WhWasmUtilInstaller = function(target){ arguments may be passed in after that one, and what those arguments are, is _not_ part of the public interface and is _not_ stable. + + Maintenance reminder: the Ember framework modifies the core + Array type, breaking for-in loops. */ - for(const i in args) args[i] = cxw.convertArgNoCheck( + let i = 0; + for(; i < args.length; ++i) args[i] = cxw.convertArgNoCheck( argTypes[i], args[i], args, i ); return cxw.convertResultNoCheck(resultType, xf.apply(null,args)); diff --git a/ext/wasm/demo-worker1-promiser.html b/ext/wasm/demo-worker1-promiser.c-pp.html index e99131e..e0b487b 100644 --- a/ext/wasm/demo-worker1-promiser.html +++ b/ext/wasm/demo-worker1-promiser.c-pp.html @@ -6,7 +6,11 @@ <link rel="shortcut icon" href="data:image/x-icon;," type="image/x-icon"> <link rel="stylesheet" href="common/emscripten.css"/> <link rel="stylesheet" href="common/testing.css"/> +//#if target=es6-module + <title>worker-promise (via ESM) tests</title> +//#else <title>worker-promise tests</title> +//#endif </head> <body> <header id='titlebar'><span>worker-promise tests</span></header> @@ -22,13 +26,17 @@ </figure> <div class="emscripten" id="module-status">Downloading...</div> <div class="emscripten"> - <progress value="0" max="100" id="module-progress" hidden='1'></progress> + <progress value="0" max="100" id="module-progress" hidden='1'></progress> </div><!-- /emscripten bits --> <div>Most stuff on this page happens in the dev console.</div> <hr> <div id='test-output'></div> <script src="common/SqliteTestUtil.js"></script> +//#if target=es6-module + <script src="demo-worker1-promiser.mjs" type="module"></script> +//#else <script src="jswasm/sqlite3-worker1-promiser.js"></script> <script src="demo-worker1-promiser.js"></script> +//#endif </body> </html> diff --git a/ext/wasm/demo-worker1-promiser.js b/ext/wasm/demo-worker1-promiser.c-pp.js index c2d2462..f6fc956 100644 --- a/ext/wasm/demo-worker1-promiser.js +++ b/ext/wasm/demo-worker1-promiser.c-pp.js @@ -13,9 +13,15 @@ Demonstration of the sqlite3 Worker API #1 Promiser: a Promise-based proxy for for the sqlite3 Worker #1 API. */ -'use strict'; -(function(){ - const T = self.SqliteTestUtil; +//#if target=es6-module +import {default as promiserFactory} from "./jswasm/sqlite3-worker1-promiser.mjs"; +//#else +"use strict"; +const promiserFactory = globalThis.sqlite3Worker1Promiser.v2; +delete globalThis.sqlite3Worker1Promiser; +//#endif +(async function(){ + const T = globalThis.SqliteTestUtil; const eOutput = document.querySelector('#test-output'); const warn = console.warn.bind(console); const error = console.error.bind(console); @@ -33,31 +39,35 @@ logHtml("","Total test count:",T.counter+". Total time =",(performance.now() - startTime),"ms"); }; - //why is this triggered even when we catch() a Promise? - //window.addEventListener('unhandledrejection', function(event) { - // warn('unhandledrejection',event); - //}); - const promiserConfig = { - worker: ()=>{ - const w = new Worker("jswasm/sqlite3-worker1.js"); - w.onerror = (event)=>error("worker.onerror",event); - return w; +//#ifnot target=es6-module + /** + The v1 interfaces uses an onready function. The v2 interface optionally + accepts one but does not require it. If provided, it is called _before_ + the promise is resolved, and the promise is rejected if onready() throws. + */ + onready: function(f){ + /* f === the function returned by promiserFactory(). + Ostensibly (f === workerPromise) but this function is + called before the promiserFactory() Promise resolves, so + before workerPromise is set. */ + console.warn("This is the v2 interface - you don't need an onready() function."); }, +//#endif debug: 1 ? undefined : (...args)=>console.debug('worker debug',...args), onunhandled: function(ev){ error("Unhandled worker message:",ev.data); }, - onready: function(){ - self.sqlite3TestModule.setStatus(null)/*hide the HTML-side is-loading spinner*/; - runTests(); - }, onerror: function(ev){ error("worker1 error:",ev); } }; - const workerPromise = self.sqlite3Worker1Promiser(promiserConfig); - delete self.sqlite3Worker1Promiser; + const workerPromise = await promiserFactory(promiserConfig) + .then((func)=>{ + console.log("Init complete. Starting tests momentarily."); + globalThis.sqlite3TestModule.setStatus(null)/*hide the HTML-side is-loading spinner*/; + return func; + }); const wtest = async function(msgType, msgArgs, callback){ if(2===arguments.length && 'function'===typeof msgArgs){ @@ -271,5 +281,5 @@ }).finally(()=>logHtml('',"That's all, folks!")); }/*runTests2()*/; - log("Init complete, but async init bits may still be running."); + runTests(); })(); diff --git a/ext/wasm/dist.make b/ext/wasm/dist.make index 5d610e3..e820e06 100644 --- a/ext/wasm/dist.make +++ b/ext/wasm/dist.make @@ -19,10 +19,15 @@ MAKEFILE.dist := $(lastword $(MAKEFILE_LIST)) # built, and won't be built until we expand the dependencies. Thus we # have to use a temporary name for the archive until we can get # that binary built. +ifeq (1,$(SQLITE_C_IS_SEE)) +dist-name-extra := -see +else +dist-name-extra := +endif ifeq (,$(filter snapshot,$(MAKECMDGOALS))) -dist-name-prefix := sqlite-wasm +dist-name-prefix := sqlite-wasm$(dist-name-extra) else -dist-name-prefix := sqlite-wasm-snapshot-$(shell /usr/bin/date +%Y%m%d) +dist-name-prefix := sqlite-wasm$(dist-name-extra)-snapshot-$(shell /usr/bin/date +%Y%m%d) endif dist-name := $(dist-name-prefix)-TEMP @@ -49,12 +54,18 @@ dist.top.extras := \ tester1.js tester1.mjs \ demo-jsstorage.html demo-jsstorage.js \ demo-worker1.html demo-worker1.js \ - demo-worker1-promiser.html demo-worker1-promiser.js -dist.jswasm.extras := $(sqlite3-api.ext.jses) $(sqlite3.wasm) + demo-worker1-promiser.html demo-worker1-promiser.js \ + demo-worker1-promiser-esm.html demo-worker1-promiser.mjs +dist.jswasm.extras := $(sqlite3.wasm) \ + $(sqlite3-api.ext.jses) dist.common.extras := \ $(wildcard $(dir.common)/*.css) \ $(dir.common)/SqliteTestUtil.js +#$(info sqlite3-worker1-promiser.mjs = $(sqlite3-worker1-promiser.mjs)) +#$(info sqlite3-worker1.js = $(sqlite3-worker1.js)) +#$(info sqlite3-api.ext.jses = $(sqlite3-api.ext.jses)) +#$(info dist.jswasm.extras = $(dist.jswasm.extras)) .PHONY: dist snapshot # DIST_STRIP_COMMENTS $(call)able to be used in stripping C-style # from the dist copies of certain files. @@ -67,7 +78,8 @@ endef # STRIP_K1.js = list of JS files which need to be passed through # $(bin.stripcomments) with a single -k flag. STRIP_K1.js := $(sqlite3-worker1.js) $(sqlite3-worker1-promiser.js) \ - $(sqlite3-worker1-bundler-friendly.js) $(sqlite3-worker1-promiser-bundler-friendly.js) + $(sqlite3-worker1-bundler-friendly.js) \ + $(sqlite3-api.ext.jses) # STRIP_K2.js = list of JS files which need to be passed through # $(bin.stripcomments) with two -k flags. STRIP_K2.js := $(sqlite3.js) $(sqlite3.mjs) \ @@ -88,6 +100,7 @@ STRIP_K2.js := $(sqlite3.js) $(sqlite3.mjs) \ dist: \ $(bin.stripccomments) $(bin.version-info) \ $(dist.build) $(STRIP_K1.js) $(STRIP_K2.js) \ + $(dist.jswasm.extras) $(dist.common.extras) \ $(MAKEFILE) $(MAKEFILE.dist) @echo "Making end-user deliverables..." @rm -fr $(dist-dir.top) diff --git a/ext/wasm/fiddle.make b/ext/wasm/fiddle.make index 57141d7..496e518 100644 --- a/ext/wasm/fiddle.make +++ b/ext/wasm/fiddle.make @@ -9,16 +9,18 @@ MAKEFILE.fiddle := $(lastword $(MAKEFILE_LIST)) # shell.c and its build flags... make-np-0 := make -C $(dir.top) -n -p make-np-1 := sed -e 's/(TOP)/(dir.top)/g' +# Extract SHELL_OPT and SHELL_DEP from the top-most makefile and import +# them as vars here... $(eval $(shell $(make-np-0) | grep -e '^SHELL_OPT ' | $(make-np-1))) -$(eval $(shell $(make-np-0) | grep -e '^SHELL_SRC ' | $(make-np-1))) +$(eval $(shell $(make-np-0) | grep -e '^SHELL_DEP ' | $(make-np-1))) # ^^^ can't do that in 1 invocation b/c newlines get stripped ifeq (,$(SHELL_OPT)) $(error Could not parse SHELL_OPT from $(dir.top)/Makefile.) endif -ifeq (,$(SHELL_SRC)) -$(error Could not parse SHELL_SRC from $(dir.top)/Makefile.) +ifeq (,$(SHELL_DEP)) +$(error Could not parse SHELL_DEP from $(dir.top)/Makefile.) endif -$(dir.top)/shell.c: $(SHELL_SRC) $(dir.top)/tool/mkshellc.tcl $(sqlite3.c) +$(dir.top)/shell.c: $(SHELL_DEP) $(dir.top)/tool/mkshellc.tcl $(sqlite3.c) $(MAKE) -C $(dir.top) shell.c # /shell.c ######################################################################## diff --git a/ext/wasm/fiddle/fiddle-worker.js b/ext/wasm/fiddle/fiddle-worker.js index 67f6100..27d915e 100644 --- a/ext/wasm/fiddle/fiddle-worker.js +++ b/ext/wasm/fiddle/fiddle-worker.js @@ -166,11 +166,10 @@ stdout("SQLite version", capi.sqlite3_libversion(), capi.sqlite3_sourceid().substr(0,19)); stdout('Welcome to the "fiddle" shell.'); - if(sqlite3.opfs){ + 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 yet work with OPFS."); - sqlite3.opfs.registerVfs(); } stdout('\nEnter ".help" for usage hints.'); this.exec([ // initialization commands... @@ -317,7 +316,7 @@ }; console.warn("Unknown fiddle-worker message type:",ev); }; - + /** emscripten module for use with build mode -sMODULARIZE. */ @@ -374,9 +373,7 @@ "for use in the dev console.", sqlite3); globalThis.sqlite3 = sqlite3; const dbVfs = sqlite3.wasm.xWrap('fiddle_db_vfs', "*", ['string']); - fiddleModule.fsUnlink = (fn)=>{ - return sqlite3.wasm.sqlite3_wasm_vfs_unlink(dbVfs(0), fn); - }; + fiddleModule.fsUnlink = (fn)=>fiddleModule.FS.unlink(fn); wMsg('fiddle-ready'); }).catch(e=>{ console.error("Fiddle worker init failed:",e); diff --git a/ext/wasm/fiddle/fiddle.js b/ext/wasm/fiddle/fiddle.js index 2a3d174..d285898 100644 --- a/ext/wasm/fiddle/fiddle.js +++ b/ext/wasm/fiddle/fiddle.js @@ -403,8 +403,10 @@ E('#btn-reset').addEventListener('click',()=>SF.resetDb()); const taInput = E('#input'); const btnClearIn = E('#btn-clear'); + const selectExamples = E('#select-examples'); btnClearIn.addEventListener('click',function(){ taInput.value = ''; + selectExamples.selectedIndex = 0; },false); // Ctrl-enter and shift-enter both run the current SQL. taInput.addEventListener('keydown',function(ev){ @@ -733,16 +735,15 @@ ]}, //{name: "Timer on", sql: ".timer on"}, // ^^^ re-enable if emscripten re-enables getrusage() + {name: "Box Mode", sql: ".mode box"}, {name: "Setup table T", sql:[ ".nullvalue NULL\n", "CREATE TABLE t(a,b);\n", "INSERT INTO t(a,b) VALUES('abc',123),('def',456),(NULL,789),('ghi',012);\n", "SELECT * FROM t;\n" ]}, - {name: "Table list", sql: ".tables"}, - {name: "Box Mode", sql: ".mode box"}, - {name: "JSON Mode", sql: ".mode json"}, - {name: "Mandlebrot", sql:[ + {name: "sqlite_schema", sql: "select * from sqlite_schema"}, + {name: "Mandelbrot", sql:[ "WITH RECURSIVE", " xaxis(x) AS (VALUES(-2.0) UNION ALL SELECT x+0.05 FROM xaxis WHERE x<1.2),\n", " yaxis(y) AS (VALUES(-1.0) UNION ALL SELECT y+0.1 FROM yaxis WHERE y<1.0),\n", @@ -760,7 +761,13 @@ " FROM m2 GROUP BY cy\n", " )\n", "SELECT group_concat(rtrim(t),x'0a') as Mandelbrot FROM a;\n", - ]} + ]}, + {name: "JSON pretty-print", + sql: "select json_pretty(json_object('ex',json('[52,3.14159]')))" + }, + {name: "JSON pretty-print (with tabs)", + sql: "select json_pretty(json_object('ex',json('[52,3.14159]')),char(0x09))" + } ]; const newOpt = function(lbl,val){ const o = document.createElement('option'); diff --git a/ext/wasm/index-dist.html b/ext/wasm/index-dist.html index f5bcdc1..7b778b0 100644 --- a/ext/wasm/index-dist.html +++ b/ext/wasm/index-dist.html @@ -97,6 +97,8 @@ wrapper is significantly easier to use, however.</li> <li><a href='demo-worker1-promiser.html'>demo-worker1-promiser</a>: a demo of the Promise-based wrapper of the Worker1 API.</li> + <li><a href='demo-worker1-promiser-esm.html'>demo-worker1-promiser-esm</a>: + same as the previous demo except loads the promiser from an ESM module.</li> </ul> </li> </ul> diff --git a/ext/wasm/index.html b/ext/wasm/index.html index ebbfd67..d12a3aa 100644 --- a/ext/wasm/index.html +++ b/ext/wasm/index.html @@ -84,6 +84,8 @@ wrapper is significantly easier to use, however.</li> <li><a href='demo-worker1-promiser.html'>demo-worker1-promiser</a>: a demo of the Promise-based wrapper of the Worker1 API.</li> + <li><a href='demo-worker1-promiser-esm.html'>demo-worker1-promiser-esm</a>: + same as the previous demo except loads the promiser from an ESM module.</li> </ul> </li> <li>speedtest1 ports (sqlite3's primary benchmarking tool)... diff --git a/ext/wasm/speedtest1-worker.js b/ext/wasm/speedtest1-worker.js index 3abc589..5261c83 100644 --- a/ext/wasm/speedtest1-worker.js +++ b/ext/wasm/speedtest1-worker.js @@ -111,10 +111,6 @@ self.sqlite3InitModule(EmscriptenModule).then(async (sqlite3)=>{ const S = globalThis.S = App.sqlite3 = sqlite3; log("Loaded speedtest1 module. Setting up..."); - App.vfsUnlink = function(pDb, fname){ - const pVfs = S.wasm.sqlite3_wasm_db_vfs(pDb, 0); - if(pVfs) S.wasm.sqlite3_wasm_vfs_unlink(pVfs, fname||0); - }; App.pDir = wasmfsDir(S.wasm); App.wasm = S.wasm; //if(App.pDir) log("Persistent storage:",pDir); diff --git a/ext/wasm/tester1.c-pp.js b/ext/wasm/tester1.c-pp.js index 36ca4c9..fe5bdc8 100644 --- a/ext/wasm/tester1.c-pp.js +++ b/ext/wasm/tester1.c-pp.js @@ -63,7 +63,7 @@ globalThis.sqlite3InitModule = sqlite3InitModule; /* Predicate for tests/groups. */ const testIsTodo = ()=>false; const haveWasmCTests = ()=>{ - return !!wasm.exports.sqlite3_wasm_test_intptr; + return !!wasm.exports.sqlite3__wasm_test_intptr; }; const hasOpfs = ()=>{ return globalThis.FileSystemHandle @@ -722,7 +722,7 @@ globalThis.sqlite3InitModule = sqlite3InitModule; //log("xCall()..."); { - const pJson = w.xCall('sqlite3_wasm_enum_json'); + const pJson = w.xCall('sqlite3__wasm_enum_json'); T.assert(Number.isFinite(pJson)).assert(w.cstrlen(pJson)>300); } @@ -736,9 +736,9 @@ globalThis.sqlite3InitModule = sqlite3InitModule; T.mustThrowMatching(()=>fw(1), /requires 0 arg/); let rc = fw(); T.assert('string'===typeof rc).assert(rc.length>5); - rc = w.xCallWrapped('sqlite3_wasm_enum_json','*'); + rc = w.xCallWrapped('sqlite3__wasm_enum_json','*'); T.assert(rc>0 && Number.isFinite(rc)); - rc = w.xCallWrapped('sqlite3_wasm_enum_json','utf8'); + rc = w.xCallWrapped('sqlite3__wasm_enum_json','utf8'); T.assert('string'===typeof rc).assert(rc.length>300); @@ -821,7 +821,7 @@ globalThis.sqlite3InitModule = sqlite3InitModule; if(haveWasmCTests()){ if(!sqlite3.config.useStdAlloc){ - fw = w.xWrap('sqlite3_wasm_test_str_hello', 'utf8:dealloc',['i32']); + fw = w.xWrap('sqlite3__wasm_test_str_hello', 'utf8:dealloc',['i32']); rc = fw(0); T.assert('hello'===rc); rc = fw(1); @@ -831,14 +831,14 @@ globalThis.sqlite3InitModule = sqlite3InitModule; if(w.bigIntEnabled){ w.xWrap.resultAdapter('thrice', (v)=>3n*BigInt(v)); w.xWrap.argAdapter('twice', (v)=>2n*BigInt(v)); - fw = w.xWrap('sqlite3_wasm_test_int64_times2','thrice','twice'); + fw = w.xWrap('sqlite3__wasm_test_int64_times2','thrice','twice'); rc = fw(1); T.assert(12n===rc); w.scopedAllocCall(function(){ const pI1 = w.scopedAlloc(8), pI2 = pI1+4; w.pokePtr([pI1, pI2], 0); - const f = w.xWrap('sqlite3_wasm_test_int64_minmax',undefined,['i64*','i64*']); + const f = w.xWrap('sqlite3__wasm_test_int64_minmax',undefined,['i64*','i64*']); const [r1, r2] = w.peek64([pI1, pI2]); T.assert(!Number.isSafeInteger(r1)).assert(!Number.isSafeInteger(r2)); }); @@ -942,7 +942,7 @@ globalThis.sqlite3InitModule = sqlite3InitModule; assert(wts.pointer>0).assert(0===wts.$v4).assert(0n===wts.$v8). assert(0===wts.$ppV).assert(0===wts.$xFunc); const testFunc = - W.xGet('sqlite3_wasm_test_struct'/*name gets mangled in -O3 builds!*/); + W.xGet('sqlite3__wasm_test_struct'/*name gets mangled in -O3 builds!*/); let counter = 0; //log("wts.pointer =",wts.pointer); const wtsFunc = function(arg){ @@ -1128,7 +1128,7 @@ globalThis.sqlite3InitModule = sqlite3InitModule; T.g('sqlite3.oo1') .t('Create db', function(sqlite3){ const dbFile = '/tester1.db'; - wasm.sqlite3_wasm_vfs_unlink(0, dbFile); + sqlite3.util.sqlite3__wasm_vfs_unlink(0, dbFile); const db = this.db = new sqlite3.oo1.DB(dbFile, 0 ? 'ct' : 'c'); db.onclose = { disposeAfter: [], @@ -1459,7 +1459,7 @@ globalThis.sqlite3InitModule = sqlite3InitModule; rv = db.exec("SELECT 1 WHERE 0",{rowMode: 0}); T.assert(Array.isArray(rv)).assert(0===rv.length); if(wasm.bigIntEnabled && haveWasmCTests()){ - const mI = wasm.xCall('sqlite3_wasm_test_int64_max'); + const mI = wasm.xCall('sqlite3__wasm_test_int64_max'); const b = BigInt(Number.MAX_SAFE_INTEGER * 2); T.assert(b === db.selectValue("SELECT "+b)). assert(b === db.selectValue("SELECT ?", b)). @@ -1482,7 +1482,7 @@ globalThis.sqlite3InitModule = sqlite3InitModule; /*step() skipped intentionally*/.reset(true); } finally { T.assert(0===st.finalize()) - .assert(undefined===st.finalize()); + .assert(undefined===st.finalize()); } try { @@ -1685,7 +1685,7 @@ globalThis.sqlite3InitModule = sqlite3InitModule; T.assert(n>0 && db2.selectValue(sql) === n); }finally{ db2.close(); - wasm.sqlite3_wasm_vfs_unlink(0, filename); + sqlite3.util.sqlite3__wasm_vfs_unlink(0, filename); } } }/*sqlite3_js_posix_create_file()*/) @@ -2075,7 +2075,7 @@ globalThis.sqlite3InitModule = sqlite3InitModule; try{ ptrInt = w.scopedAlloc(4); w.poke32(ptrInt,origValue); - const cf = w.xGet('sqlite3_wasm_test_intptr'); + const cf = w.xGet('sqlite3__wasm_test_intptr'); const oldPtrInt = ptrInt; T.assert(origValue === w.peek32(ptrInt)); const rc = cf(ptrInt); @@ -2090,13 +2090,13 @@ globalThis.sqlite3InitModule = sqlite3InitModule; const v64 = ()=>w.peek64(pi64) T.assert(v64() == o64); //T.assert(o64 === w.peek64(pi64)); - const cf64w = w.xGet('sqlite3_wasm_test_int64ptr'); + const cf64w = w.xGet('sqlite3__wasm_test_int64ptr'); cf64w(pi64); T.assert(v64() == BigInt(2 * o64)); cf64w(pi64); T.assert(v64() == BigInt(4 * o64)); - const biTimes2 = w.xGet('sqlite3_wasm_test_int64_times2'); + const biTimes2 = w.xGet('sqlite3__wasm_test_int64_times2'); T.assert(BigInt(2 * o64) === biTimes2(BigInt(o64)/*explicit conv. required to avoid TypeError in the call :/ */)); @@ -2106,13 +2106,13 @@ globalThis.sqlite3InitModule = sqlite3InitModule; const g64 = (p)=>w.peek64(p); w.poke64([pMin, pMax], 0); const minMaxI64 = [ - w.xCall('sqlite3_wasm_test_int64_min'), - w.xCall('sqlite3_wasm_test_int64_max') + w.xCall('sqlite3__wasm_test_int64_min'), + w.xCall('sqlite3__wasm_test_int64_max') ]; T.assert(minMaxI64[0] < BigInt(Number.MIN_SAFE_INTEGER)). assert(minMaxI64[1] > BigInt(Number.MAX_SAFE_INTEGER)); //log("int64_min/max() =",minMaxI64, typeof minMaxI64[0]); - w.xCall('sqlite3_wasm_test_int64_minmax', pMin, pMax); + w.xCall('sqlite3__wasm_test_int64_minmax', pMin, pMax); T.assert(g64(pMin) === minMaxI64[0], "int64 mismatch"). assert(g64(pMax) === minMaxI64[1], "int64 mismatch"); //log("pMin",g64(pMin), "pMax",g64(pMax)); @@ -2560,7 +2560,7 @@ globalThis.sqlite3InitModule = sqlite3InitModule; //////////////////////////////////////////////////////////////////////// .t('Close db', function(){ T.assert(this.db).assert(wasm.isPtr(this.db.pointer)); - //wasm.sqlite3_wasm_db_reset(this.db); // will leak virtual tables! + //wasm.sqlite3__wasm_db_reset(this.db); // will leak virtual tables! this.db.close(); T.assert(!this.db.pointer); }) @@ -2587,7 +2587,7 @@ globalThis.sqlite3InitModule = sqlite3InitModule; const pVfs = capi.sqlite3_vfs_find('kvvfs'); T.assert(pVfs); const JDb = this.JDb = sqlite3.oo1.JsStorageDb; - const unlink = this.kvvfsUnlink = ()=>{JDb.clearStorage(filename)}; + const unlink = this.kvvfsUnlink = ()=>JDb.clearStorage(this.kvvfsDbFile); unlink(); let db = new JDb(filename); try { @@ -2605,6 +2605,60 @@ globalThis.sqlite3InitModule = sqlite3InitModule; } } }/*kvvfs sanity checks*/) +//#if enable-see + .t({ + name: 'kvvfs with SEE encryption', + predicate: ()=>(isUIThread() + || "Only available in main thread."), + test: function(sqlite3){ + this.kvvfsUnlink(); + let db; + const encOpt1 = 1 + ? {textkey: 'foo'} + : {key: 'foo'}; + const encOpt2 = encOpt1.textkey + ? encOpt1 + : {hexkey: new Uint8Array([0x66,0x6f,0x6f]/*==>"foo"*/)} + try{ + db = new this.JDb({ + filename: this.kvvfsDbFile, + ...encOpt1 + }); + db.exec([ + "create table t(a,b);", + "insert into t(a,b) values(1,2),(3,4)" + ]); + db.close(); + let err; + try{ + db = new this.JDb({ + filename: this.kvvfsDbFile, + flags: 'ct' + }); + T.assert(db) /* opening is fine, but... */; + db.exec("select 1 from sqlite_schema"); + console.warn("sessionStorage =",sessionStorage); + }catch(e){ + err = e; + }finally{ + db.close(); + } + T.assert(err,"Expecting an exception") + .assert(sqlite3.capi.SQLITE_NOTADB==err.resultCode, + "Expecting NOTADB"); + db = new sqlite3.oo1.DB({ + filename: this.kvvfsDbFile, + vfs: 'kvvfs', + ...encOpt2 + }); + T.assert( 4===db.selectValue('select sum(a) from t') ); + }finally{ + if( db ) db.close(); + this.kvvfsUnlink(); + } + } + })/*kvvfs with SEE*/ +//#endif enable-see ;/* end kvvfs tests */ //////////////////////////////////////////////////////////////////////// @@ -2888,18 +2942,17 @@ globalThis.sqlite3InitModule = sqlite3InitModule; .t({ name: 'OPFS db sanity checks', test: async function(sqlite3){ + T.assert(capi.sqlite3_vfs_find('opfs')); + const opfs = sqlite3.opfs; const filename = this.opfsDbFile = '/dir/sqlite3-tester1.db'; - const pVfs = this.opfsVfs = capi.sqlite3_vfs_find('opfs'); - T.assert(pVfs); - const unlink = this.opfsUnlink = - (fn=filename)=>{wasm.sqlite3_wasm_vfs_unlink(pVfs,fn)}; - unlink(); - let db = new sqlite3.oo1.OpfsDb(filename); + const fileUri = 'file://'+filename+'?delete-before-open=1'; + const initSql = [ + 'create table p(a);', + 'insert into p(a) values(1),(2),(3)' + ]; + let db = new sqlite3.oo1.OpfsDb(fileUri); try { - db.exec([ - 'create table p(a);', - 'insert into p(a) values(1),(2),(3)' - ]); + db.exec(initSql); T.assert(3 === db.selectValue('select count(*) from p')); db.close(); db = new sqlite3.oo1.OpfsDb(filename); @@ -2911,7 +2964,14 @@ globalThis.sqlite3InitModule = sqlite3InitModule; && 0===this.opfsDbExport.byteLength % 512); }finally{ db.close(); - unlink(); + } + T.assert(await opfs.entryExists(filename)); + try { + db = new sqlite3.oo1.OpfsDb(fileUri); + db.exec(initSql) /* will throw if delete-before-open did not work */; + T.assert(3 === db.selectValue('select count(*) from p')); + }finally{ + if(db) db.close(); } } }/*OPFS db sanity checks*/) @@ -2919,15 +2979,17 @@ globalThis.sqlite3InitModule = sqlite3InitModule; name: 'OPFS import', test: async function(sqlite3){ let db; + const filename = this.opfsDbFile; try { const exp = this.opfsDbExport; - const filename = this.opfsDbFile; delete this.opfsDbExport; this.opfsImportSize = await sqlite3.oo1.OpfsDb.importDb(filename, exp); db = new sqlite3.oo1.OpfsDb(this.opfsDbFile); T.assert(6 === db.selectValue('select count(*) from p')). assert( this.opfsImportSize == exp.byteLength ); db.close(); + const unlink = this.opfsUnlink = + (fn=filename)=>sqlite3.util.sqlite3__wasm_vfs_unlink("opfs",fn); this.opfsUnlink(filename); T.assert(!(await sqlite3.opfs.entryExists(filename))); // Try again with a function as an input source: @@ -2954,11 +3016,9 @@ globalThis.sqlite3InitModule = sqlite3InitModule; name: '(Internal-use) OPFS utility APIs', test: async function(sqlite3){ const filename = this.opfsDbFile; - const pVfs = this.opfsVfs; const unlink = this.opfsUnlink; - T.assert(filename && pVfs && !!unlink); + T.assert(filename && !!unlink); delete this.opfsDbFile; - delete this.opfsVfs; delete this.opfsUnlink; /************************************************************** ATTENTION CLIENT-SIDE USERS: sqlite3.opfs is NOT intended @@ -3209,6 +3269,7 @@ globalThis.sqlite3InitModule = sqlite3InitModule; print: log, printErr: error }).then(async function(sqlite3){ + TestUtil.assert(!!sqlite3.util); log("Done initializing WASM/JS bits. Running tests..."); sqlite3.config.warn("Installing sqlite3 bits as global S for local dev/test purposes."); globalThis.S = sqlite3; @@ -3227,9 +3288,9 @@ globalThis.sqlite3InitModule = sqlite3InitModule; logClass('warning',"BigInt/int64 support is disabled."); } if(haveWasmCTests()){ - log("sqlite3_wasm_test_...() APIs are available."); + log("sqlite3__wasm_test_...() APIs are available."); }else{ - logClass('warning',"sqlite3_wasm_test_...() APIs unavailable."); + logClass('warning',"sqlite3__wasm_test_...() APIs unavailable."); } log("registered vfs list =",capi.sqlite3_js_vfs_list().join(', ')); TestUtil.runTests(sqlite3); @@ -230,7 +230,6 @@ SRC += \ SRC += \ $(TOP)/ext/misc/stmt.c - # FTS5 things # FTS5_HDR = \ @@ -375,7 +374,9 @@ TESTSRC += \ $(TOP)/ext/rtree/test_rtreedoc.c \ $(TOP)/ext/recover/sqlite3recover.c \ $(TOP)/ext/recover/dbdata.c \ - $(TOP)/ext/recover/test_recover.c + $(TOP)/ext/recover/test_recover.c \ + $(TOP)/ext/intck/test_intck.c \ + $(TOP)/ext/intck/sqlite3intck.c #TESTSRC += $(TOP)/ext/fts3/fts3_tokenizer.c @@ -659,7 +660,7 @@ target_source: $(SRC) $(TOP)/tool/vdbe-compress.tcl fts5.c touch target_source sqlite3.c: target_source $(TOP)/tool/mksqlite3c.tcl src-verify - tclsh $(TOP)/tool/mksqlite3c.tcl + tclsh $(TOP)/tool/mksqlite3c.tcl $(EXTRA_SRC) cp tsrc/sqlite3ext.h . cp $(TOP)/ext/session/sqlite3session.h . echo '#ifndef USE_SYSTEM_SQLITE' >tclsqlite3.c @@ -671,7 +672,7 @@ sqlite3ext.h: target_source cp tsrc/sqlite3ext.h . sqlite3.c-debug: target_source $(TOP)/tool/mksqlite3c.tcl src-verify - tclsh $(TOP)/tool/mksqlite3c.tcl --linemacros=1 + tclsh $(TOP)/tool/mksqlite3c.tcl --linemacros=1 $(EXTRA_SRC) echo '#ifndef USE_SYSTEM_SQLITE' >tclsqlite3.c cat sqlite3.c >>tclsqlite3.c echo '#endif /* USE_SYSTEM_SQLITE */' >>tclsqlite3.c @@ -717,8 +718,7 @@ opcodes.c: opcodes.h $(TOP)/tool/mkopcodec.tcl tclsh $(TOP)/tool/mkopcodec.tcl opcodes.h >opcodes.c opcodes.h: parse.h $(TOP)/src/vdbe.c $(TOP)/tool/mkopcodeh.tcl - cat parse.h $(TOP)/src/vdbe.c | \ - tclsh $(TOP)/tool/mkopcodeh.tcl >opcodes.h + cat parse.h $(TOP)/src/vdbe.c | tclsh $(TOP)/tool/mkopcodeh.tcl >opcodes.h # Rules to build parse.c and parse.h - the outputs of lemon. # @@ -741,32 +741,37 @@ keywordhash.h: $(TOP)/tool/mkkeywordhash.c $(BCC) -o mkkeywordhash $(OPTS) $(TOP)/tool/mkkeywordhash.c ./mkkeywordhash >keywordhash.h -# Source files that go into making shell.c -SHELL_SRC = \ - $(TOP)/src/shell.c.in \ - $(TOP)/ext/misc/appendvfs.c \ - $(TOP)/ext/misc/completion.c \ - $(TOP)/ext/misc/base64.c \ - $(TOP)/ext/misc/base85.c \ - $(TOP)/ext/misc/decimal.c \ - $(TOP)/ext/misc/fileio.c \ - $(TOP)/ext/misc/ieee754.c \ - $(TOP)/ext/misc/regexp.c \ - $(TOP)/ext/misc/series.c \ - $(TOP)/ext/misc/shathree.c \ - $(TOP)/ext/misc/sqlar.c \ - $(TOP)/ext/misc/uint.c \ - $(TOP)/ext/expert/sqlite3expert.c \ - $(TOP)/ext/expert/sqlite3expert.h \ - $(TOP)/ext/misc/zipfile.c \ - $(TOP)/ext/misc/memtrace.c \ - $(TOP)/ext/misc/pcachetrace.c \ - $(TOP)/ext/recover/dbdata.c \ - $(TOP)/ext/recover/sqlite3recover.c \ - $(TOP)/ext/recover/sqlite3recover.h \ - $(TOP)/src/test_windirent.c - -shell.c: $(SHELL_SRC) $(TOP)/tool/mkshellc.tcl +# Source and header files that shell.c depends on +SHELL_DEP = \ + $(TOP)/src/shell.c.in \ + $(TOP)/ext/consio/console_io.c \ + $(TOP)/ext/consio/console_io.h \ + $(TOP)/ext/expert/sqlite3expert.c \ + $(TOP)/ext/expert/sqlite3expert.h \ + $(TOP)/ext/intck/sqlite3intck.c \ + $(TOP)/ext/intck/sqlite3intck.h \ + $(TOP)/ext/misc/appendvfs.c \ + $(TOP)/ext/misc/base64.c \ + $(TOP)/ext/misc/base85.c \ + $(TOP)/ext/misc/completion.c \ + $(TOP)/ext/misc/decimal.c \ + $(TOP)/ext/misc/fileio.c \ + $(TOP)/ext/misc/ieee754.c \ + $(TOP)/ext/misc/memtrace.c \ + $(TOP)/ext/misc/pcachetrace.c \ + $(TOP)/ext/misc/regexp.c \ + $(TOP)/ext/misc/series.c \ + $(TOP)/ext/misc/shathree.c \ + $(TOP)/ext/misc/sqlar.c \ + $(TOP)/ext/misc/uint.c \ + $(TOP)/ext/misc/zipfile.c \ + $(TOP)/ext/recover/dbdata.c \ + $(TOP)/ext/recover/sqlite3recover.c \ + $(TOP)/ext/recover/sqlite3recover.h \ + $(TOP)/src/test_windirent.c \ + $(TOP)/src/test_windirent.h + +shell.c: $(SHELL_DEP) $(TOP)/tool/mkshellc.tcl tclsh $(TOP)/tool/mkshellc.tcl >shell.c @@ -1,28 +1,30 @@ -C Version\s3.45.3 -D 2024-04-15T13:34:05.554 +C Version\s3.46.0 +D 2024-05-23T13:25:27.566 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 -F Makefile.in 24be65ae641c5727bbc247d60286a15ecc24fb80f14f8fb2d32533bf0ec96e79 +F Makefile.in 993a7874e3d3721df61846f03dda4a9ef7490da11953ae36ba1bb0c0346eaf4a F Makefile.linux-gcc f3842a0b1efbfbb74ac0ef60e56b301836d05b4d867d014f714fa750048f1ab6 -F Makefile.msc df56c06ef05add5ebcdcc9d4823fb2ec66ac16b06acb6971a7420859025886fa +F Makefile.msc e64a52619310d3067f6c38f56eedd15918a82dade70954197d6da486ad99d7f4 F README.md 6358805260a03ebead84e168bbf3740ddf3f683b477e478567186aa7afb490d3 -F VERSION 72f46aae916c0bad94b6e64aef327e60bad69bb591a93b95f079ccedcb32b7c7 +F VERSION c84541c6a9e8426462176fbb1f9ecb5cfd7d1bb56228053ff7eeba8841673eb6 F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50 +F art/icon-243x273.gif 9750b734f82fdb3dc43127753d5e6fbf3b62c9f4e136c2fbf573b2f57ea87af5 +F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d87031 F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac -F autoconf/Makefile.msc ac338c36a338f6b49475da71930f45145a181d6b551578d5a7a64f113ef27b2c +F autoconf/Makefile.msc 7ac6c331fc3b8aa57b6782db995b8c0e49230352decd4e2662fd07c06a9ed623 F autoconf/README.first 6c4f34fe115ff55d4e8dbfa3cecf04a0188292f7 F autoconf/README.txt 42cfd21d0b19dc7d5d85fb5c405c5f3c6a4c923021c39128f6ba685355d8fd56 F autoconf/configure.ac ec7fa914c5e74ff212fe879f9bb6918e1234497e05facfb641f30c4d5893b277 F autoconf/tea/Makefile.in 106a96f2f745d41a0f6193f1de98d7355830b65d45032c18cd7c90295ec24196 F autoconf/tea/README 3e9a3c060f29a44344ab50aec506f4db903fb873 F autoconf/tea/aclocal.m4 52c47aac44ce0ddb1f918b6993e8beb8eee88f43 -F autoconf/tea/configure.ac 13ba7cab3eedc3af6650fa0037deac0de3c21f909165c2e76e0995fd546b958c +F autoconf/tea/configure.ac 9e74135563a901d9b1a019bad1c9d73a6659fa32325f6a565bef72bfb0ec7297 F autoconf/tea/doc/sqlite3.n e1fe45d4f5286ee3d0ccc877aca2a0def488e9bb F autoconf/tea/license.terms 13bd403c9610fd2b76ece0ab50c4c5eda933d523 F autoconf/tea/pkgIndex.tcl.in b9eb6dd37f64e08e637d576b3c83259814b9cddd78bec4af2e5abfc6c5c750ce @@ -33,16 +35,16 @@ F autoconf/tea/win/nmakehlp.c b01f822eabbe1ed2b64e70882d97d48402b42d2689a1ea0034 F autoconf/tea/win/rules.vc c511f222b80064096b705dbeb97060ee1d6b6d63 F config.guess 883205ddf25b46f10c181818bf42c09da9888884af96f79e1719264345053bd6 F config.sub c2d0260f17f3e4bc0b6808fccf1b291cb5e9126c14fc5890efc77b9fd0175559 -F configure 7398a16e7a444c105d0300a6a0f5e7248fb0bef006385c07b53dfaf0d3c7bbd8 x +F configure 40f7af9ed5ca0d44a4b9bc7ad34f1ee4867bb4eeb19e75036be6bed66193a498 x F configure.ac f25bd7843120f2c2b8bc9db5a92b0502bbdd28e68907415c3d42fc8e57c657b9 F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad F doc/F2FS.txt c1d4a0ae9711cfe0e1d8b019d154f1c29e0d3abfe820787ba1e9ed7691160fcd F doc/compile-for-windows.md 50b27d77be96195c66031a3181cb8684ed822327ea834e07f9c014213e5e3bcf F doc/json-enhancements.md e356fc834781f1f1aa22ee300027a270b2c960122468499bf347bb123ce1ea4f F doc/jsonb.md 5fab4b8613aa9153fbeb6259297bd4697988af8b3d23900deba588fa7841456b -F doc/lemon.html 44a53a1d2b42d7751f7b2f478efb23c978e258d794bfd172442307a755b9fa44 +F doc/lemon.html 8b266ff711d2ec7f867c3dca37634963f48a630329908cc282beebfa8c708706 F doc/pager-invariants.txt 27fed9a70ddad2088750c4a2b493b63853da2710 -F doc/testrunner.md 8d36ec692cf4994bb66d84a4645b9afa1ce9d47dc12cbf8d437c5a5fb6ddeedb +F doc/testrunner.md 15583cf8c7d8a1c3378fd5d4319ca769a14c4d950a5df9b015d01d5be290dc69 F doc/trusted-schema.md 33625008620e879c7bcfbbfa079587612c434fa094d338b08242288d358c3e8a F doc/vdbesort-memory.md 4da2639c14cd24a31e0af694b1a8dd37eaf277aff3867e9a8cc14046bc49df56 F doc/vfs-shm.txt e101f27ea02a8387ce46a05be2b1a902a021d37a @@ -55,15 +57,15 @@ F ext/consio/console_io.c f32b757c9ee7fdf68e7586bee306f8368759e7cd12febb2a683919 F ext/consio/console_io.h 0548b83d7c4b7270ad544a67f2bb90cebc519637fa39b1838df4744cf0d87646 F ext/expert/README.md b321c2762bb93c18ea102d5a5f7753a4b8bac646cb392b3b437f633caf2020c3 F ext/expert/expert.c d548d603a4cc9e61f446cc179c120c6713511c413f82a4a32b1e1e69d3f086a4 -F ext/expert/expert1.test 0dd5cb096d66bed593e33053a3b364f6ef52ed72064bf5cf298364636dbf3cd6 -F ext/expert/sqlite3expert.c 90446bb1183429308c68ceb23e00cb8252f43b8886cf5efa3fc7e833b5fa24c8 +F ext/expert/expert1.test 53a749de08939e3bc14f804e97410927d46fa772cbce0247d7e8fa6fc2523b0c +F ext/expert/sqlite3expert.c c8cea5ff15fbe792cccc4992a9b40b706411c41d32611f617897fecac6ff06a4 F ext/expert/sqlite3expert.h ca81efc2679a92373a13a3e76a6138d0310e32be53d6c3bfaedabd158ea8969b F ext/expert/test_expert.c d56c194b769bdc90cf829a14c9ecbc1edca9c850b837a4d0b13be14095c32a72 F ext/fts3/README.content b9078d0843a094d86af0d48dffbff13c906702b4c3558012e67b9c7cc3bf59ee F ext/fts3/README.syntax a19711dc5458c20734b8e485e75fb1981ec2427a F ext/fts3/README.tokenizers b92bdeb8b46503f0dd301d364efc5ef59ef9fa8e2758b8e742f39fa93a2e422d F ext/fts3/README.txt 8c18f41574404623b76917b9da66fcb0ab38328d -F ext/fts3/fts3.c fd64a588471ce00b19da08acb0d6f904277a21ac1d15141d5913c83591afa027 +F ext/fts3/fts3.c c922380b62bd15bce953dae3350337acbd0fff07c10cdc805819409791eb480a F ext/fts3/fts3.h 3a10a0af180d502cecc50df77b1b22df142817fe F ext/fts3/fts3Int.h 968f7d7cae541a6926146e9fd3fb2b2ccbd3845b7890a8ed03de0c06ac776682 F ext/fts3/fts3_aux.c 7eab82a9cf0830f6551ba3abfdbe73ed39e322a4d3940ee82fbf723674ecd9f3 @@ -72,7 +74,7 @@ F ext/fts3/fts3_hash.c 8b6e31bfb0844c27dc6092c2620bdb1fca17ed613072db057d96952c6 F ext/fts3/fts3_hash.h 39cf6874dc239d6b4e30479b1975fe5b22a3caaf F ext/fts3/fts3_icu.c 305ce7fb6036484085b5556a9c8e62acdc7763f0f4cdf5fd538212a9f3720116 F ext/fts3/fts3_porter.c e19807ce0ae31c1c6e9898e89ecc93183d7ec224ea101af039722a4f49e5f2b8 -F ext/fts3/fts3_snippet.c 4d6523e3eddeb7b46e7a82b3476a0a86a0c04821e0e2b8dd40f45ee28057cb13 +F ext/fts3/fts3_snippet.c 610328fe128c047c6b0eba77768982ccf3933daae095d497949a75c9dfd47409 F ext/fts3/fts3_term.c 845f0e2456b1be42f7f1bec1da1dfc05bc347531eff90775ffc6698902c281de F ext/fts3/fts3_test.c d8d7b2734f894e8a489987447658e374cdd3a3bc8575c401decf1911cb7c6454 F ext/fts3/fts3_tokenize_vtab.c 7fd9ef364f257b97218b9c331f2378e307375c592f70fd541f714e747d944962 @@ -81,7 +83,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 c2d7a8dfb6e7a00c6c88ce626785cf4c50ed18eba34b5fbd53cacd60af96d0f2 +F ext/fts3/fts3_write.c 81cd8f7e8003e427a1801e04842776b731af26dd93af206e4e66ea5ae319cad1 F ext/fts3/fts3speed.tcl b54caf6a18d38174f1a6e84219950d85e98bb1e9 F ext/fts3/tool/fts3cov.sh c331d006359456cf6f8f953e37f2b9c7d568f3863f00bb5f7eb87fea4ac01b73 F ext/fts3/tool/fts3view.c 413c346399159df81f86c4928b7c4a455caab73bfbc8cd68f950f632e5751674 @@ -90,7 +92,7 @@ F ext/fts3/unicode/UnicodeData.txt cd07314edb62d49fde34debdaf92fa2aa69011e7 F ext/fts3/unicode/mkunicode.tcl d5aebf022fa4577ee8cdf27468f0d847879993959101f6dbd6348ef0cfc324a7 F ext/fts3/unicode/parseunicode.tcl a981bd6466d12dd17967515801c3ff23f74a281be1a03cf1e6f52a6959fc77eb F ext/fts5/extract_api_docs.tcl bc3a0ca78be7d3df08e7602c00ca48021ebae40682d75eb001bfdf6e54ffb44e -F ext/fts5/fts5.h ecba24fed7b359b3a53016bb07e411b3b4c9cdf163aa141006536423a63b611e +F ext/fts5/fts5.h 8856e11a5f0269cd346754cea0765efe8089635b80cad3222e8bfdb08cd5348a F ext/fts5/fts5Int.h defa43c0932265138ee910ca416e6baccf8b774e0f3d610e74be1ab2880e9834 F ext/fts5/fts5_aux.c 4584e88878e54828bf7d4d0d83deedd232ec60628b7731be02bad6adb62304b1 F ext/fts5/fts5_buffer.c 0eec58bff585f1a44ea9147eae5da2447292080ea435957f7488c70673cb6f09 @@ -98,7 +100,7 @@ F ext/fts5/fts5_config.c 8072a207034b51ae9b7694121d1b5715c794e94b275e088f70ae532 F ext/fts5/fts5_expr.c e91156ebdcc08d837f4f324168f69f3c0d7fdef0e521fd561efb48ef3297b696 F ext/fts5/fts5_hash.c adda4272be401566a6e0ba1acbe70ee5cb97fce944bc2e04dc707152a0ec91b1 F ext/fts5/fts5_index.c ee0f4d50bc0c58a7c5ef7d645e7e38e1e59315b8ea9d722ae00c5f949ee65379 -F ext/fts5/fts5_main.c cd56ed9619e9bc55ae603ecafd5965c3684bb4c1de7dd00893c307ddf98afe88 +F ext/fts5/fts5_main.c d68bd9533d5a638b7f6fae61c3cb0a15257dcdcccedaf3d0b3c9f55940c85048 F ext/fts5/fts5_storage.c f9e31b0d155e9b2c92d5d3a09ad7a56b937fbf1c7f962e10f4ca6281349f3934 F ext/fts5/fts5_tcl.c fdf7e2bb9a9186cfcaf2d2ce11d338309342b7a7593c2812bc54455db53da5d2 F ext/fts5/fts5_test_mi.c 08c11ec968148d4cb4119d96d819f8c1f329812c568bac3684f5464be177d3ee @@ -163,7 +165,7 @@ F ext/fts5/test/fts5fault4.test 87a10d0caee57da587c7588b0c8d25d2930197399b4812ad F ext/fts5/test/fts5fault5.test a336e4e11847de24c9497f80cce18e00bb3fab7fb11f97d04eb9af898900a762 F ext/fts5/test/fts5fault6.test a0fc0a8f99e4b16500c31dfc7e38e1defe0f1693ac47650517ac7b723b1956f8 F ext/fts5/test/fts5fault7.test 0acbec416edb24b8881f154e99c31e9ccf73f539cfcd164090be139e9e97ed4c -F ext/fts5/test/fts5fault8.test 318238659d35f82ad215ecb57ca4c87486ea85d45dbeedaee42f148ff5105ee2 +F ext/fts5/test/fts5fault8.test 9353fe6a2a993c3231e09c49b0f4a12c8d306319555ff2ca6672b5b86fe9b0dd F ext/fts5/test/fts5fault9.test 098e6b894bbdf9b2192f994a30f4043673fb3f338b6b8ab1624c704422f39119 F ext/fts5/test/fts5faultA.test be4487576bff8c22cee6597d1893b312f306504a8c6ccd3c53ca85af12290c8c F ext/fts5/test/fts5faultB.test d606bdb8e81aaeb6f41de3fc9fc7ae315733f0903fbff05cf54f5b045b729ab5 @@ -246,8 +248,17 @@ F ext/fts5/tool/loadfts5.tcl 95b03429ee6b138645703c6ca192c3ac96eaf093 F ext/fts5/tool/mkfts5c.tcl 3eba8e9bee4221ed165f3304b51b2a74a705f4ec5df3d044573a2be539534af8 F ext/fts5/tool/showfts5.tcl d54da0e067306663e2d5d523965ca487698e722c F ext/icu/README.txt 7ab7ced8ae78e3a645b57e78570ff589d4c672b71370f5aa9e1cd7024f400fc9 -F ext/icu/icu.c c074519b46baa484bb5396c7e01e051034da8884bad1a1cb7f09bbe6be3f0282 +F ext/icu/icu.c 3add8197e0a86c1761771a39500ebae749438bcf1836160b407a56b4eaa8721c F ext/icu/sqliteicu.h fa373836ed5a1ee7478bdf8a1650689294e41d0c89c1daab26e9ae78a32075a8 +F ext/intck/intck1.test f3a3cba14b6aeff145ffa5515546dd22f7510dad91512e519f43b92b56514012 +F ext/intck/intck2.test d2457c7e5e5b688046d15ebe08a1e1427cc5e7a6dc8d6af215f42e8bcaf67304 +F ext/intck/intck_common.tcl a61fd2697ae55b0a3d89847ca0b590c6e0d8ff64bebb70920d93724799894159 +F ext/intck/intckbusy.test d5ed4ef85a4b1dc1dee2484bd14a4bb68529659cca743327df0c775f005fa387 +F ext/intck/intckcorrupt.test f6c302792326fb3db9dcfc70b554c55369bc4b52882eaaf039cfe0b74c821029 +F ext/intck/intckfault.test cff3f75dff74abb3edfcb13f6aa53f6436746ab64b09fe5e2028f051e985efab +F ext/intck/sqlite3intck.c 0d10df36e2b7b438aa80ecd3f5e584d41b747586b038258fe6b407f66b81e7c5 +F ext/intck/sqlite3intck.h 2b40c38e7063ab822c974c0bd4aed97dabb579ccfe2e180a4639bb3bbef0f1c9 +F ext/intck/test_intck.c 34243458378a12d1356c79219a03f244800533b3ab65b4a02861f0403364df12 F ext/jni/GNUmakefile 59eb05f2a363bdfac8d15d66bed624bfe1ff289229184f3861b95f98a19cf4b2 F ext/jni/README.md d899789a9082a07b99bf30b1bbb6204ae57c060efcaa634536fa669323918f42 F ext/jni/jar-dist.make 030aaa4ae71dd86e4ec5e7c1e6cd86f9dfa47c4592c070d2e35157e42498e1fa @@ -371,7 +382,7 @@ F ext/misc/blobio.c a867c4c4617f6ec223a307ebfe0eabb45e0992f74dd47722b96f3e631c0e F ext/misc/btreeinfo.c cb952620eedf5c0b7625b678f0f08e54d2ec0011d4e50efda5ebdc97f3df7d04 F ext/misc/carray.c 34fac63770971611c5285de0a9f0ac67d504eaf66be891f637add9290f1c76a5 F ext/misc/carray.h 503209952ccf2431c7fd899ebb92bf46bf7635b38aace42ec8aa1b8d7b6e98a5 -F ext/misc/cksumvfs.c 9224e33cc0cb6aa61ff1d7d7b8fd6fe56beca9f9c47954fa4ae0a69bef608f69 +F ext/misc/cksumvfs.c 3a7931dd30667be6348af919f3f9e6188dfd7646b42af8e399a499b327f5bd63 F ext/misc/closure.c 0e04f52d93e678dd6f950f195f365992edf3c380df246f3d80425cba4c13891e F ext/misc/completion.c ef78835483b43ac18c96be312b90b615d8368189909be03513ab7a9338131298 F ext/misc/compress.c 3354c77a7c8e86e07d849916000cdac451ed96500bfb5bd83b20eb61eee012c9 @@ -380,7 +391,7 @@ F ext/misc/dbdump.c b8592f6f2da292c62991a13864a60d6c573c47a9cc58362131b9e6a64f82 F ext/misc/decimal.c 172cf81a8634e6a0f0bedaf71a8372fee63348cf5a3c4e1b78bb233c35889fdc F ext/misc/eval.c 04bc9aada78c888394204b4ed996ab834b99726fb59603b0ee3ed6e049755dc1 F ext/misc/explain.c 606100185fb90d6a1eade1ed0414d53503c86820d8956a06e3b0a56291894f2b -F ext/misc/fileio.c d88e60f63557d76d4e38acffda5556b2ab42e98f5d830897f22aba65930d975c +F ext/misc/fileio.c 916638042f318701460485032e33981056747d0f92e6757aa9499f2363ea7047 F ext/misc/fossildelta.c 8c026e086e406e2b69947f1856fa3b848fff5379962276430d10085b8756b05a F ext/misc/fuzzer.c 8b28acf1a7e95d50e332bdd47e792ff27054ad99d3f9bc2e91273814d4b31a5a F ext/misc/ieee754.c 62a90978204d2c956d5036eb89e548e736ca5fac0e965912867ddd7bb833256d @@ -400,12 +411,12 @@ F ext/misc/regexp.c 4bdd0045912f81c84908bd535ec5ad3b1c8540b4287c70ab840709636240 F ext/misc/remember.c add730f0f7e7436cd15ea3fd6a90fd83c3f706ab44169f7f048438b7d6baa69c F ext/misc/rot13.c 51ac5f51e9d5fd811db58a9c23c628ad5f333c173f1fc53c8491a3603d38556c F ext/misc/scrub.c 2a44b0d44c69584c0580ad2553f6290a307a49df4668941d2812135bfb96a946 -F ext/misc/series.c 80692f675de989629ee20796f75010ce87ca826cb383131040e84f7e1bea5d7a +F ext/misc/series.c d96e5aac21658c6b5d54f918ac140460ec7197734c1a4fba806950831a7b1e7a F ext/misc/sha1.c 4011aef176616872b2a0d5bccf0ecfb1f7ce3fe5c3d107f3a8e949d8e1e3f08d F ext/misc/shathree.c 543af7ce71d391cd3a9ab6924a6a1124efc63211fd0f2e240dc4b56077ba88ac F ext/misc/showauth.c 732578f0fe4ce42d577e1c86dc89dd14a006ab52 F ext/misc/spellfix.c c0aa7b80d6df45f7da59d912b38752bcac1af53a5766966160e6c5cdd397dbea -F ext/misc/sqlar.c 53e7d48f68d699a24f1a92e68e71eca8b3a9ff991fe9588c2a05bde103c6e7b7 +F ext/misc/sqlar.c a6175790482328171da47095f87608b48a476d4fac78d8a9ff18b03a2454f634 F ext/misc/stmt.c b090086cd6bd6281c21271d38d576eeffe662f0e6b67536352ce32bbaa438321 F ext/misc/templatevtab.c 10f15b165b95423ddef593bc5dcb915ec4eb5e0f1066d585e5435a368b8bc22b F ext/misc/totype.c 75ed9827d19cc3b434fc2aeb60725d4d46e1534373615612a4d1cfdcc3d60922 @@ -415,7 +426,7 @@ F ext/misc/urifuncs.c f71360d14fa9e7626b563f1f781c6148109462741c5235ac63ae0f8917 F ext/misc/uuid.c 5bb2264c1b64d163efa46509544fd7500cb8769cb7c16dd52052da8d961505cf F ext/misc/vfslog.c 3932ab932eeb2601dbc4447cb14d445aaa9fbe43b863ef5f014401c3420afd20 F ext/misc/vfsstat.c a85df08654743922a19410d7b1e3111de41bb7cd07d20dd16eda4e2b808d269d -F ext/misc/vtablog.c f2c9d41afe00b51b2c8307b79f508eb0c2dcd57bae074807944e73376fcf15b7 +F ext/misc/vtablog.c 1100250ce8782db37c833e3a9a5c9a3ecf1af5e15b8325572b82e6e0a138ffb5 F ext/misc/vtshim.c 1976e6dd68dd0d64508c91a6dfab8e75f8aaf6cd F ext/misc/wholenumber.c 0fa0c082676b7868bf2fa918e911133f2b349bcdceabd1198bba5f65b4fc0668 F ext/misc/zipfile.c 64cb3d98b6316586e6056d182051aa9d28fdedfbf4b908e6b7a7d70209b1db11 @@ -464,16 +475,18 @@ F ext/rbu/rbuvacuum.test 542561741ff2b262e3694bc6012b44694ee62c545845319a06f3237 F ext/rbu/rbuvacuum2.test ae097d04feb041446a74fac94b24bffeb3fdd60e32b848c5611e507ab702b81b F ext/rbu/rbuvacuum3.test 3ce42695fdf21aaa3499e857d7d4253bc499ad759bcd6c9362042c13cd37d8de F ext/rbu/rbuvacuum4.test ffccd22f67e2d0b380d2889685742159dfe0d19a3880ca3d2d1d69eefaebb205 -F ext/rbu/sqlite3rbu.c d4ddf8f0e93772556e452a6c2814063cf47efb760a0834391a9d0cd9859fa4b9 +F ext/rbu/sqlite3rbu.c 4a3376c0fb9a844a799ac529fb81260523f6b13c9f629bc270c632dbae5fc1f8 F ext/rbu/sqlite3rbu.h 9d923eb135c5d04aa6afd7c39ca47b0d1d0707c100e02f19fdde6a494e414304 F ext/rbu/test_rbu.c ee6ede75147bc081fe9bc3931e6b206277418d14d3fbceea6fdc6216d9b47055 -F ext/recover/dbdata.c d2e00d3cac74319c9c6def2e56ab2146b4f4ba5d820ab275e8da24e9766c247e -F ext/recover/recover1.test c484d01502239f11b61f23c1cee9f5dd19fa17617f8974e42e74d64639c524cf +F ext/recover/dbdata.c a22ecd689f00ff2ad33b5633c4ef84c8f088c65faeac18d4eb73c128395c7aec +F ext/recover/recover1.test e16d78e94183562abff569967b18b7c77451d7044365516cd0fe14713a284851 F ext/recover/recover_common.tcl a61306c1eb45c0c3fc45652c35b2d4ec19729e340bdf65a272ce4c229cefd85a F ext/recover/recoverbuild.test c74170e0f7b02456af41838afeb5353fdb985a48cc2331d661bbabbca7c6b8e3 F ext/recover/recoverclobber.test 3ba6c0c373c5c63d17e82eced64c05c57ccaf26c1abe1ca7141334022a79f32e F ext/recover/recovercorrupt.test 64c081ad1200ae77b447da99eb724785d6bf71715f394543dc7689642e92bf49 F ext/recover/recovercorrupt2.test 1418f1710debc24ff38276cedfcea234beb37a34205708e7e3e6d76cc4a979db +F ext/recover/recovercorrupt3.test 2e7b9a1b528ca23ed382cec6f64e3fcbbd0f8e852add7562397fd8df83f335d5 +F ext/recover/recovercorrupt4.test cc4a56086c50fba6a5b20db122a3f220195b3d4f11a86e0858c7f5f5d8ba58d1 F ext/recover/recoverfault.test 9d9f88eeb222615a25e7514f234c950d46bee20d24cd8db49d8fff8d650dcfe1 F ext/recover/recoverfault2.test 730e7371bcda769554d15460cb23126abba1be8eca9539ccabf63623e7bb7e09 F ext/recover/recoverold.test 68db3d6f85dd2b98e785b6c4da4f5eea4bbe52ccf6674d9a94c7506dc92596aa @@ -495,9 +508,9 @@ F ext/repair/test/checkindex01.test b530f141413b587c9eb78ff734de6bb79bc3515c3350 F ext/repair/test/test.tcl 686d76d888dffd021f64260abf29a55c57b2cedfa7fc69150b42b1d6119aac3c F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761 F ext/rtree/geopoly.c 0dd4775e896cee6067979d67aff7c998e75c2c9d9cd8d62a1a790c09cde7adca -F ext/rtree/rtree.c bdf97fac91b37b3a6041ab4a0dd06e81c7ba1541601733b40f97fb51e76e79ce +F ext/rtree/rtree.c b6133dba5ae331fa6c1fc34df6aa623eba951b05ac35116f954a0bf7ab550436 F ext/rtree/rtree.h 4a690463901cb5e6127cf05eb8e642f127012fd5003830dbc974eca5802d9412 -F ext/rtree/rtree1.test 2b5b8c719c6a4abe377f57766f428a49af36a93061cb146cccfdc3b30000c0a4 +F ext/rtree/rtree1.test e0608db762b2aadca0ecb6f97396cf66244490adc3ba88f2a292b27be3e1da3e F ext/rtree/rtree2.test 9d9deddbb16fd0c30c36e6b4fdc3ee3132d765567f0f9432ee71e1303d32603d F ext/rtree/rtree3.test 272594f88c344e973864008bbe4c71fd3a41a264c097d568593ee7886d83d409 F ext/rtree/rtree4.test 304de65d484540111b896827e4261815e5dca4ce28eeecd58be648cd73452c4b @@ -555,6 +568,8 @@ F ext/session/session_speed_test.c dcf0ef58d76b70c8fbd9eab3be77cf9deb8bc1638fed8 F ext/session/sessionalter.test 460bdac2832a550519f6bc32e5db2c0cee94f335870aaf25a3a403a81ab20e17 F ext/session/sessionat.test 00c8badb35e43a2f12a716d2734a44d614ff62361979b6b85419035bc04b45ee F ext/session/sessionbig.test 47c381e7acfabeef17d98519a3080d69151723354d220afa2053852182ca7adf +F ext/session/sessionchange.test 77c4702050f24270b58070e2cf01c95c3d232a3ef164b70f31974b386ce69903 +F ext/session/sessionconflict.test 8b8cbd98548e2e636ddc17d0986276f60e833fb865617dd4f88ea5bbe3a16b96 F ext/session/sessiondiff.test ad13dd65664bae26744e1f18eb3cbd5588349b7e9118851d8f9364248d67bcec F ext/session/sessionfault.test 573bf027fb870d57bd4e7cf50822a3e4b17b2b923407438747aaa918dec57a09 F ext/session/sessionfault2.test b0d6a7c1d7398a7e800d84657404909c7d385965ea8576dc79ed344c46fbf41c @@ -567,44 +582,45 @@ F ext/session/sessionnoop2.test de4672dce88464396ec9f30ed08c6c01643a69c53ae540fa F ext/session/sessionrebase.test 702378bdcb5062f1106e74457beca8797d09c113a81768734a58b197b5b334e2 F ext/session/sessionrowid.test 85187c2f1b38861a5844868126f69f9ec62223a03449a98a80600a44396f7363 F ext/session/sessionsize.test 8fcf4685993c3dbaa46a24183940ab9f5aa9ed0d23e5fb63bfffbdb56134b795 -F ext/session/sessionstat1.test b039e38e2ba83767b464baf39b297cc0b1cc6f3292255cb467ea7e12d0d0280c +F ext/session/sessionstat1.test 5e718d5888c0c49bbb33a7a4f816366db85f59f6a4f97544a806421b85dc2dec F ext/session/sessionwor.test 6fd9a2256442cebde5b2284936ae9e0d54bde692d0f5fd009ecef8511f4cf3fc -F ext/session/sqlite3session.c 829d468f0f3d2710aace56b0116a7ca3f414683ce78e3125ae5e21547a895078 -F ext/session/sqlite3session.h 4cf19a51975746d7cff2fdd74db8b769c570958e1c3639ac150d824ac1553b3e -F ext/session/test_session.c 7b94ad945cd4afe6c73ee935aeb3d44b4446186e1729362af616c7695a5283d9 +F ext/session/sqlite3session.c c7473aafbd88f796391a8c25aa90975a8f3729ab7f4f8cf74ab9d3b014e10abe +F ext/session/sqlite3session.h 683ccbf16e2c2521661fc4c1cf918ce57002039efbcabcd8097fa4bca569104b +F ext/session/test_session.c 8bcc857125372e640f75ab63b4188080f9bbab92b65f86dfd160721c574b2044 F ext/userauth/sqlite3userauth.h 7f3ea8c4686db8e40b0a0e7a8e0b00fac13aa7a3 -F ext/userauth/user-auth.txt e6641021a9210364665fe625d067617d03f27b04 +F ext/userauth/user-auth.txt ca7e9ee82ca4e1c1744295f8184dd70edfae1992865d26c64303f539eb6c084c F ext/userauth/userauth.c 7f00cded7dcaa5d47f54539b290a43d2e59f4b1eb5f447545fa865f002fc80cb F ext/wasm/EXPORTED_FUNCTIONS.fiddle.in 27450c8b8c70875a260aca55435ec927068b34cef801a96205adb81bdcefc65c -F ext/wasm/GNUmakefile 8a4d5ca21d7f21c4751ef732f2bb837c915641ee8ad25753929998fa44847e61 +F ext/wasm/GNUmakefile 21f015f342e4ed9b7ff632c10750512259d26c836a34f4f535673fae9a7c9fcc F ext/wasm/README-dist.txt 6382cb9548076fca472fb3330bbdba3a55c1ea0b180ff9253f084f07ff383576 F ext/wasm/README.md a8a2962c3aebdf8d2104a9102e336c5554e78fc6072746e5daf9c61514e7d193 F ext/wasm/SQLTester/GNUmakefile e0794f676d55819951bbfae45cc5e8d7818dc460492dc317ce7f0d2eca15caff -F ext/wasm/SQLTester/SQLTester.mjs ec2f6ba63a0f2f0562941a0fb8e46b7dc55589711513f1952349785966edfe50 +F ext/wasm/SQLTester/SQLTester.mjs ce765c0ad7d57f93553d12ef4dca574deb00300134a26d472daacab49031e1fb F ext/wasm/SQLTester/SQLTester.run.mjs c72b7fe2072d05992f7a3d8c6a1d34e95712513ceabe40849784e24e41c84638 F ext/wasm/SQLTester/index.html 3f8a016df0776be76605abf20e815ecaafbe055abac0e1fe5ea080e7846b760d F ext/wasm/SQLTester/touint8array.c 2d5ece04ec1393a6a60c4bf96385bda5e1a10ad49f3038b96460fc5e5aa7e536 F ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-api f442460ed9a109e637dd3ea1caa4489553ad9414e8988118b208bb7a4bbece6b F ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-see fb29e62082a658f0d81102488414d422c393c4b20cc2f685b216bc566237957b F ext/wasm/api/EXPORTED_RUNTIME_METHODS.sqlite3-api 1ec3c73e7d66e95529c3c64ac3de2470b0e9e7fbf7a5b41261c367cf4f1b7287 -F ext/wasm/api/README.md 5eb44fa02e9c693a1884a3692428647894b0380b24bca120866b7a24c8786134 +F ext/wasm/api/README.md 34fe11466f9c1d81b10a0469e1114e5f1c5a6365c73d80a1a6ca639a1a358b73 F ext/wasm/api/extern-post-js.c-pp.js c4154a7f90c2d7e51fd6738273908152036c3457fdc0b6523f1be3ef51105aac F ext/wasm/api/extern-pre-js.js cc61c09c7a24a07dbecb4c352453c3985170cec12b4e7e7e7a4d11d43c5c8f41 F ext/wasm/api/post-js-footer.js cd0a8ec768501d9bd45d325ab0442037fb0e33d1f3b4f08902f15c34720ee4a1 -F ext/wasm/api/post-js-header.js 47b6b281f39ad59fa6e8b658308cd98ea292c286a68407b35ff3ed9cfd281a62 +F ext/wasm/api/post-js-header.js 04dc12c3edd666b64a1b4ef3b6690c88dcc653f26451fd4734472d8e29c1c122 F ext/wasm/api/pre-js.c-pp.js ad906703f7429590f2fbf5e6498513bf727a1a4f0ebfa057afb08161d7511219 F ext/wasm/api/sqlite3-api-cleanup.js d235ad237df6954145404305040991c72ef8b1881715d2a650dda7b3c2576d0e -F ext/wasm/api/sqlite3-api-glue.js 119b91c8a7ce6648679eb66fcdd1ed07ef7fd892eb501d658fbfefcc962012d9 -F ext/wasm/api/sqlite3-api-oo1.js 7f3bcf0549ac44cde4b9da0b642d771916738d3f6781fb8a1757c50a91e506c0 -F ext/wasm/api/sqlite3-api-prologue.js 9aeba7b45cf41b3a26d34d7fb2525633cd1adfc544888c1ea8dbb077496f4ce9 -F ext/wasm/api/sqlite3-api-worker1.js fd46628ef147dd5856c88f63a9a279a40f744f1fdfddd55251ad8fbc3d8200ae +F ext/wasm/api/sqlite3-api-glue.js 114085f4dceb28e06d20d3fb597b2501a4aa69f4b6cd29234f7cc1cf81d5b92d +F ext/wasm/api/sqlite3-api-oo1.js c373cc04625a96bd3f01ce8ebeac93a5d38dbda6215818c925570df5a945565e +F ext/wasm/api/sqlite3-api-prologue.js b347a0c5350247f90174a0ad9b9e72a99a5f837f31f78f60fcdb829b2ca30b63 +F ext/wasm/api/sqlite3-api-worker1.js 9704b77b5eb9d0d498ceeaf3e7a837021b14c52ac15d6556c7f97e278ec725c3 F ext/wasm/api/sqlite3-license-version-header.js 0c807a421f0187e778dc1078f10d2994b915123c1223fe752b60afdcd1263f89 -F ext/wasm/api/sqlite3-opfs-async-proxy.js 8cf8a897726f14071fae6be6648125162b256dfb4f96555b865dbb7a6b65e379 -F ext/wasm/api/sqlite3-v-helper.js 7daa0eab0a513a25b05e9abae7b5beaaa39209b3ed12f86aeae9ef8d2719ed25 -F ext/wasm/api/sqlite3-vfs-opfs-sahpool.c-pp.js 90d93d3365567d52c6959ed5d6f80adccd173799772d73639ff647ada58193d4 -F ext/wasm/api/sqlite3-vfs-opfs.c-pp.js 46c4afa6c50d7369252c104f274ad977a97e91ccfafc38b400fe36e90bdda88e -F ext/wasm/api/sqlite3-wasm.c dfd1f1a225b267e8fd641dcd6c7d579fbe2b731aeaa123324135efac830a2bcf -F ext/wasm/api/sqlite3-worker1-promiser.c-pp.js f234191fe6bf41a5a1e59c9f43ed816e74a522b3d60d3f556f66c3085c448503 +F ext/wasm/api/sqlite3-opfs-async-proxy.js 196ad83d36ca794e564044788c9d21b964679d63cad865f604da37c4afc9a285 +F ext/wasm/api/sqlite3-vfs-helper.c-pp.js 3f828cc66758acb40e9c5b4dcfd87fd478a14c8fb7f0630264e6c7fa0e57515d +F ext/wasm/api/sqlite3-vfs-opfs-sahpool.c-pp.js 8433ee332d5f5e39fb19427fccb7bad7f44aa99b5504daad3343fc128c311e78 +F ext/wasm/api/sqlite3-vfs-opfs.c-pp.js 3c72f1a0e6a7343c8c882d29d01bb440f10be12c844651605b486e76f3d6cc8c +F ext/wasm/api/sqlite3-vtab-helper.c-pp.js a2fcbc3fecdd0eea229283584ebc122f29d98194083675dbe5cb2cf3a17fe309 +F ext/wasm/api/sqlite3-wasm.c 9267174b9b0591b4f71193542ab57adf95bb9415f7d3453acf4a8ca8052f5e6c +F ext/wasm/api/sqlite3-worker1-promiser.c-pp.js 46f303ba8ddd1b2f0a391798837beddfa72e8c897038c8047eda49ce7d5ed46b F ext/wasm/api/sqlite3-worker1.c-pp.js 5e8706c2c4af2a57fbcdc02f4e7ef79869971bc21bb8ede777687786ce1c92d5 F ext/wasm/batch-runner-sahpool.html e9a38fdeb36a13eac7b50241dfe7ae066fe3f51f5c0b0151e7baee5fce0d07a7 F ext/wasm/batch-runner-sahpool.js 54a3ac228e6c4703fe72fb65c897e19156263a51fe9b7e21d2834a45e876aabd @@ -614,25 +630,25 @@ F ext/wasm/c-pp.c 6d80d8569d85713effe8b0818a3cf51dc779e3f0bf8dc88771b8998552ee25 F ext/wasm/common/SqliteTestUtil.js 7adaeffef757d8708418dc9190f72df22367b531831775804b31598b44f6aa51 F ext/wasm/common/emscripten.css 11bd104b6c0d597c67d40cc8ecc0a60dae2b965151e3b6a37fa5708bac3acd15 F ext/wasm/common/testing.css e97549bab24126c24e0daabfe2de9bb478fb0a69fdb2ddd0a73a992c091aad6f -F ext/wasm/common/whwasmutil.js 4c64594eecc7af4ae64259e95a71ba2a7edf118881aaff0bba86d0c7164e78e4 +F ext/wasm/common/whwasmutil.js f7b3461028899b923fb554029a5c980396b02800b742aabb44346dd8704fd11b F ext/wasm/demo-123-worker.html a0b58d9caef098a626a1a1db567076fca4245e8d60ba94557ede8684350a81ed F ext/wasm/demo-123.html 8c70a412ce386bd3796534257935eb1e3ea5c581e5d5aea0490b8232e570a508 F ext/wasm/demo-123.js c7b3cca50c55841c381a9ca4f9396e5bbdc6114273d0b10a43e378e32e7be5bf F ext/wasm/demo-jsstorage.html 409c4be4af5f207fb2877160724b91b33ea36a3cd8c204e8da1acb828ffe588e F ext/wasm/demo-jsstorage.js 44e3ae7ec2483b6c511384c3c290beb6f305c721186bcf5398ca4e00004a06b8 -F ext/wasm/demo-worker1-promiser.html 1de7c248c7c2cfd4a5783d2aa154bce62d74c6de98ab22f5786620b3354ed15f -F ext/wasm/demo-worker1-promiser.js 5e5c7d7c91cd7aae9cc733afd02569ba9c6928292db413b550e8b842f4b75e87 +F ext/wasm/demo-worker1-promiser.c-pp.html 635cf90685805e21772a5f7a35d1ace80f98a9ef7c42ff04d7a125ddca7e5db8 +F ext/wasm/demo-worker1-promiser.c-pp.js fcc628cb42fcfaf07d250477801de1e6deb1e319d003976612a0db8d76b9fccc F ext/wasm/demo-worker1.html 2c178c1890a2beb5a5fecb1453e796d067a4b8d3d2a04d65ca2eb1ab2c68ef5d F ext/wasm/demo-worker1.js 836bece8615b17b1b572584f7b15912236a5947fe8c68b98d2737d7e287447ef -F ext/wasm/dist.make 3a851858aad72e246a5d9c5aaf6b6a144305f1bf898ac1846760ea7bab95c9a3 +F ext/wasm/dist.make 653e212c1e84aa3be168d62a10616ccea45ee9585b0192745d2706707a5248ce F ext/wasm/example_extra_init.c 2347cd69d19d839ef4e5e77b7855103a7fe3ef2af86f2e8c95839afd8b05862f -F ext/wasm/fiddle.make fa2ba6e90457ba2a71cb745f200d409caf773076df75ae5b177cc225d7627a11 +F ext/wasm/fiddle.make 3c2eace29255d6ddd219f5d8cc2728cb28b9fe717ea80b6062c2a6178947a16b F ext/wasm/fiddle/emscripten.css 3d253a6fdb8983a2ac983855bfbdd4b6fa1ff267c28d69513dd6ef1f289ada3f -F ext/wasm/fiddle/fiddle-worker.js e0153f9af6500805c6f09c0b3cfdb7d857e9d6863dbee9d50d1628fccf5f4b4d -F ext/wasm/fiddle/fiddle.js 974b995119ac443685d7d94d3b3c58c6a36540e9eb3fed7069d5653284071715 +F ext/wasm/fiddle/fiddle-worker.js 850e66fce39b89d59e161d1abac43a181a4caa89ddeea162765d660277cd84ce +F ext/wasm/fiddle/fiddle.js b444a5646a9aac9f3fc06c53d78af5e1912eb235d69a8e6010723e4eb0e9d4a1 F ext/wasm/fiddle/index.html 5daf54e8f3d7777cbb1ca4f93affe28858dbfff25841cb4ab81d694efed28ec2 -F ext/wasm/index-dist.html e91d76e4581185238fd3d42ed86ec600f7023ed3e3a944c5c356f25304bf1263 -F ext/wasm/index.html b31ce41c0da476d5ffcef23069b9d3415b419d65af5779096ebcfbcbade453a9 +F ext/wasm/index-dist.html 564b5ec5669676482c5a25dea9e721d8eafed426ecb155f93d29aeff8507511f +F ext/wasm/index.html 4337f495416756802669f69f9f9f3df9f87ee4c1918e6718719b4b5718e4713a F ext/wasm/jaccwabyt/jaccwabyt.js 1264710db3cfbcb6887d95665b7aeba60c1126eaef789ca4cf1a4a17d5bc7f54 F ext/wasm/jaccwabyt/jaccwabyt.md 59a20df389abcc3606eb4eaea7fb7ba14504beb3e345dbea9b99a0618ba3bec8 F ext/wasm/module-symbols.html dc476b403369b26a1a23773e13b80f41b9a49f0825e81435fe3600a7cfbbe337 @@ -641,7 +657,7 @@ F ext/wasm/scratchpad-wasmfs.mjs 66034b9256b218de59248aad796760a1584c1dd84223150 F ext/wasm/speedtest1-wasmfs.html 0e9d335a9b5b5fafe6e1bc8dc0f0ca7e22e6eb916682a2d7c36218bb7d67379d F ext/wasm/speedtest1-wasmfs.mjs ac5cadbf4ffe69e9eaac8b45e8523f030521e02bb67d654c6eb5236d9c456cbe F ext/wasm/speedtest1-worker.html 864b65ed78ce24847a348c180e7f267621a02ca027068a1863ec1c90187c1852 -F ext/wasm/speedtest1-worker.js 4d2ea70a3c24e05bdca78025202841f33d298c4fa9541a0070c3228661f89ecd +F ext/wasm/speedtest1-worker.js 95e549e13a4d35863a9a7fc66122b5f546c0130d3be7b06dfcc556eb66d24bde F ext/wasm/speedtest1.html ff048b4a623aa192e83e143e48f1ce2a899846dd42c023fdedc8772b6e3f07da F ext/wasm/split-speedtest1-script.sh a3e271938d4d14ee49105eb05567c6a69ba4c1f1293583ad5af0cd3a3779e205 x F ext/wasm/sql/000-mandelbrot.sql 775337a4b80938ac8146aedf88808282f04d02d983d82675bd63d9c2d97a15f0 @@ -650,7 +666,7 @@ F ext/wasm/test-opfs-vfs.html 1f2d672f3f3fce810dfd48a8d56914aba22e45c6834e262555 F ext/wasm/test-opfs-vfs.js 1618670e466f424aa289859fe0ec8ded223e42e9e69b5c851f809baaaca1a00c F ext/wasm/tester1-worker.html ebc4b820a128963afce328ecf63ab200bd923309eb939f4110510ab449e9814c F ext/wasm/tester1.c-pp.html 1c1bc78b858af2019e663b1a31e76657b73dc24bede28ca92fbe917c3a972af2 -F ext/wasm/tester1.c-pp.js a92dc256738dbd1b50f142d1fd0c835294ba09b7bb6526650360e942f88cb63f +F ext/wasm/tester1.c-pp.js 6d0a9aa44a97b4aadd582e0999ce45a2671b854a12ea3205d1c908da6bd4bdef F ext/wasm/tests/opfs/concurrency/index.html 0802373d57034d51835ff6041cda438c7a982deea6079efd98098d3e42fbcbc1 F ext/wasm/tests/opfs/concurrency/test.js a98016113eaf71e81ddbf71655aa29b0fed9a8b79a3cdd3620d1658eb1cc9a5d F ext/wasm/tests/opfs/concurrency/worker.js 0a8c1a3e6ebb38aabbee24f122693f1fb29d599948915c76906681bb7da1d3d2 @@ -658,7 +674,7 @@ F ext/wasm/wasmfs.make 8a4955882aaa0783b3f60a9484a1f0f3d8b6f775c0fcd17c082f31966 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0 -F main.mk ef8d6b0e76b27d2b32d7b71ea30a2b2626b668f998a4f32f6171c9623a310a53 +F main.mk e5da4b6c13f2b15bba7f1efb0a47089dfdde0973e85a024785485655d59fd758 F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 F mptest/crash01.test 61e61469e257df0850df4293d7d4d6c2af301421 @@ -670,25 +686,25 @@ F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b F sqlite3.1 acdff36db796e2d00225b911d3047d580cd136547298435426ce9d40347973cc F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a F sqlite_cfg.h.in baf2e409c63d4e7a765e17769b6ff17c5a82bbd9cbf1e284fd2e4cefaff3fcf2 -F src/alter.c 30c2333b8bb3af71e4eb9adeadee8aa20edb15917ed44b8422e5cd15f3dfcddc -F src/analyze.c 0f15753308c3bca7674f31fa7e0807ffcb8b120c36eef7d00b62b33079ddc854 +F src/alter.c e1b6782b85dd758f89e5c588e4e3eb82638c2dafc0c857b79a43bb8ec1746fca +F src/analyze.c a3df28274e2565ba5656577d7e3fd262169a213e6eb0bd47890e0f0729a4031c F src/attach.c cc9d00d30da916ff656038211410ccf04ed784b7564639b9b61d1839ed69fd39 F src/auth.c 19b7ccacae3dfba23fc6f1d0af68134fa216e9040e53b0681b4715445ea030b4 F src/backup.c 5c97e8023aab1ce14a42387eb3ae00ba5a0644569e3476f38661fa6f824c3523 F src/bitvec.c 9eac5f42c11914d5ef00a75605bb205e934f435c579687f985f1f8b0995c8645 F src/btmutex.c 79a43670447eacc651519a429f6ece9fd638563cf95b469d6891185ddae2b522 -F src/btree.c 0d264fb19a783325fb48be7e74bb19999b17914896e36bdee73c5d31d06d616d -F src/btree.h 03e3356f5208bcab8eed4e094240fdac4a7f9f5ddf5e91045ce589f67d47c240 -F src/btreeInt.h 3e2589726c4f105e653461814f65857465da68be1fac688de340c43b873f4062 -F src/build.c ec93d135f9c02b2a5d174384b6f9c222c16b1c8e473c482284759f3f0a35e336 +F src/btree.c 71b80e77b255144db47180fda8138740608e382a44231942464029b1a45fc036 +F src/btree.h 55066f513eb095db935169dab1dc2f7c7a747ef223c533f5d4ad4dfed346cbd0 +F src/btreeInt.h 98aadb6dcb77b012cab2574d6a728fad56b337fc946839b9898c4b4c969e30b6 +F src/build.c 11ec7014a3c468e7b3ccc8dda8d9111cd5a29a358df18818788601e0600aaabd F src/callback.c db3a45e376deff6a16c0058163fe0ae2b73a2945f3f408ca32cf74960b28d490 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c 64e4b1227b4ed123146f0aa2989131d1fbd9b927b11e80c9d58c6a68f9cd5ce3 -F src/date.c 3b8d02977d160e128469de38493b4085f7c5cf4073193459909a6af3cf6d7c91 +F src/date.c 126ba2ab10aeb2e7ba6e089b5f07b747c0625b8287f78b60da346eda8d23c875 F src/dbpage.c 80e46e1df623ec40486da7a5086cb723b0275a6e2a7b01d9f9b5da0f04ba2782 F src/dbstat.c 3b677254d512fcafd4d0b341bf267b38b235ccfddbef24f9154e19360fa22e43 F src/delete.c cb766727c78e715f9fb7ec8a7d03658ed2a3016343ca687acfcec9083cdca500 -F src/expr.c 1fece60622b8b74d8b3bf59faba4c2509a177ea65d9642dfbd22ceb7ec6eeea5 +F src/expr.c f7bad20d2f74005f1f876e7fbb627222ea28250e44b296b047403720c5c21818 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c a47610f0a5c6cb0ad79f8fcef039c01833dec0c751bb695f28dc0ec6a4c3ba00 F src/func.c 283d4f3b2751a1d9339fd93a8a013d1948fd5f4474a3cab0955eb4fafd445d0f @@ -697,12 +713,12 @@ F src/hash.c 9ee4269fb1d6632a6fecfb9479c93a1f29271bddbbaf215dd60420bcb80c7220 F src/hash.h 3340ab6e1d13e725571d7cee6d3e3135f0779a7d8e76a9ce0a85971fa3953c51 F src/hwtime.h f9c2dfb84dce7acf95ce6d289e46f5f9d3d1afd328e53da8f8e9008e3b3caae6 F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71 -F src/insert.c 7d318f638431af858b5ebd5d2c17d6dacd0adf114dbbfbe23f3033c3c043c7f0 -F src/json.c 29a42bc92c2384653b8b5e5ad26bdee4e2334544c7cfb78ceb4a3ca81d674686 +F src/insert.c 4bd7c7e54a1062dcd0214b7a6296f7194eb10fb14d3ddca1ed20b01c2a86a18c +F src/json.c bf1b51e32158b3d01d96a878d3dba8d2e633a7e5bf2534d4617f89de8a6b9a91 F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa F src/loadext.c 7432c944ff197046d67a1207790a1b13eec4548c85a9457eb0896bb3641dfb36 F src/main.c 8a59d297ec77e6b78550433bfccb95a1b26f2fb69aaaf233206e21579a1cfcc1 -F src/malloc.c f016922435dc7d1f1f5083a03338a3e91f8c67ce2c5bdcfa4cdef62e612f5fcc +F src/malloc.c 410e570b30c26cc36e3372577df50f7a96ee3eed5b2b161c6b6b48773c650c5e F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c 3bb59158c38e05f6270e761a9f435bf19827a264c13d1631c58b84bdc96d73b2 F src/mem2.c c8bfc9446fd0798bddd495eb5d9dbafa7d4b7287d8c22d50a83ac9daa26d8a75 @@ -722,28 +738,28 @@ F src/os.h 1ff5ae51d339d0e30d8a9d814f4b8f8e448169304d83a7ed9db66a65732f3e63 F src/os_common.h 6c0eb8dd40ef3e12fe585a13e709710267a258e2c8dd1c40b1948a1d14582e06 F src/os_kv.c 4d39e1f1c180b11162c6dc4aa8ad34053873a639bac6baae23272fc03349986a F src/os_setup.h 6011ad7af5db4e05155f385eb3a9b4470688de6f65d6166b8956e58a3d872107 -F src/os_unix.c fa9b81b642e60e77ffaf98bd1a2e5fde16c1c2317614ec178bf3bd5864772356 +F src/os_unix.c 6227cbc4ac93046f121436886cf3712da6f4e2082af6314f976eeae1d86b794a F src/os_win.c 6ff43bac175bd9ed79e7c0f96840b139f2f51d01689a638fd05128becf94908a F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a F src/pager.c 9beb80f6e330dd63c5d8ba0f7a7f3a55fff22067a68d424949c389bfc6fa0c56 F src/pager.h 4b1140d691860de0be1347474c51fee07d5420bd7f802d38cbab8ea4ab9f538a -F src/parse.y 020d80386eb216ec9520549106353c517d2bbc89be28752ffdca649a9eaf56ec +F src/parse.y 50516253433303673ff6b009983bb246d1527415e5a9af22acc51b0eedb9a10d F src/pcache.c 040b165f30622a21b7a9a77c6f2e4877a32fb7f22d4c7f0d2a6fa6833a156a75 F src/pcache.h 1497ce1b823cf00094bb0cf3bac37b345937e6f910890c626b16512316d3abf5 F src/pcache1.c 602acb23c471bb8d557a6f0083cc2be641d6cafcafa19e481eba7ef4c9ca0f00 -F src/pragma.c a13593a09da0d27b44a57bf6b2b9f6d163ad78aef4ad1d64c6214897dbe0c9ba +F src/pragma.c 52bfbf6dfd668b69b5eb9bd1186e3a67367c8453807150d6e75239229924f684 F src/pragma.h e690a356c18e98414d2e870ea791c1be1545a714ba623719deb63f7f226d8bb7 -F src/prepare.c 371f6115cb69286ebc12c6f2d7511279c2e47d9f54f475d46a554d687a3b312c -F src/printf.c d3392b2a20ee314ddeef34fb43c904bf4619eb20ff9a9e07e3950a7e4dcd6912 +F src/prepare.c d99931f45416652895e502328ca49fe782cfc4e1ebdcda13b3736d991ebf42ce +F src/printf.c 8b250972305e14b365561be5117ed0fd364e4fd58968776df1ce64c6280b90f9 F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c -F src/resolve.c b81374797e47a2e98c2a10b7152ad70280dfeb228f26ac45470760d02e360318 +F src/resolve.c 22f1fa3423b377c02ae78d451cfeb1c2d96dcf0389c0642cbdcd19d3bfd7ae01 F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97 -F src/select.c 8b9b78a58781955d5bc676efde95e3cbc82174bf7c1b3968c855faff134c24d2 -F src/shell.c.in e4815eb8a7b3110994a1d7e9f42e6b3e9e3576d25ec63f75259b797938cada98 -F src/sqlite.h.in 4f7840e1abb041b80da0af48f870e2ae3552e2a97c902eebe7455fe5a89562e3 +F src/select.c 1a841c38974d45cf15a7611398479182b61ad4c187423c380741d8b1688fe607 +F src/shell.c.in 885dafabb3f16d68bdb4576683afb0e39a1939f50985b162255bf656c470babf +F src/sqlite.h.in c71d9ef76a6d32dc7ff2d373f2e57ce09056af26c1457bcadae5358b7628c7c3 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 3f046c04ea3595d6bfda99b781926b17e672fd6d27da2ba6d8d8fc39981dcb54 -F src/sqliteInt.h 867a6691a5f06ceb6a17a828337f6ace1ad35c44f324bf50d4a2169c3db8571f +F src/sqliteInt.h 6a9fa3902c9faca2b57060e822f2afadfbf96d64c4ede81e201f0e0c42d7e4aa F src/sqliteLimit.h 6878ab64bdeb8c24a1d762d45635e34b96da21132179023338c93f820eee6728 F src/status.c cb11f8589a6912af2da3bb1ec509a94dd8ef27df4d4c1a97e0bcf2309ece972b F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 @@ -759,7 +775,7 @@ F src/test9.c 12e5ba554d2d1cbe0158f6ab3f7ffcd7a86ee4e5 F src/test_async.c 195ab49da082053fdb0f949c114b806a49ca770a F src/test_autoext.c 915d245e736652a219a907909bb6710f0d587871 F src/test_backup.c bf5da90c9926df0a4b941f2d92825a01bbe090a0 -F src/test_bestindex.c f6af1e41cb7901edafb065a8198e4a0192dd42432b642d038965be5e628dec12 +F src/test_bestindex.c 770429c434221afe6216ec81fe4c00ad3bbdad1d5e64576aa613ffb7c5a984f0 F src/test_blob.c ae4a0620b478548afb67963095a7417cd06a4ec0a56adb453542203bfdcb31ce F src/test_btree.c 8b2dc8b8848cf3a4db93f11578f075e82252a274 F src/test_config.c 5fa77ee6064ba546e144c4fea870c5ede2c54314616f81485c6a9c4192100c75 @@ -789,7 +805,7 @@ F src/test_schema.c cbfd7a9a9b6b40d4377d0c76a6c5b2a58387385977f26edab4e77eb5f90a F src/test_sqllog.c 540feaea7280cd5f926168aee9deb1065ae136d0bbbe7361e2ef3541783e187a F src/test_superlock.c 4839644b9201da822f181c5bc406c0b2385f672e F src/test_syscall.c 9fdb13b1df05e639808d44fcb8f6064aaded32b6565c00b215cfd05a060d1aca -F src/test_tclsh.c 3ff5d188a72f00807425954ea3b493dfd3a4b890ecc6700ea83bad2fd1332ecf +F src/test_tclsh.c aaf0d1de4a518a8db5ad38e5262be3e48b4a74ad1909f2dba753cecb30979d5d F src/test_tclvar.c 3273f9d59395b336e381b53cfc68ec6ebdaada4e93106a2e976ffb0550504e1c F src/test_thread.c 7ddcf0c8b79fa3c1d172f82f322302c963d923cdb503c6171f3c8081586d0b01 F src/test_vdbecov.c f60c6f135ec42c0de013a1d5136777aa328a776d33277f92abac648930453d43 @@ -800,34 +816,34 @@ F src/test_windirent.h da2e5b73c32d09905fbdd00f27cd802212a32a58ead882736fe4f5eb7 F src/test_window.c cdae419fdcea5bad6dcd9368c685abdad6deb59e9fc8b84b153de513d394ba3f F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c -F src/tokenize.c 23d9f4539880b40226254ad9072f4ecf12eb1902e62aea47aac29928afafcfd5 -F src/treeview.c c6fc972683fd00f975d8b32a81c1f25d2fb7d4035366bf45c9f5622d3ccd70ee -F src/trigger.c 0905b96b04bb6658509f711a8207287f1315cdbc3df1a1b13ba6483c8e341c81 +F src/tokenize.c 3f703cacdab728d7741e5a6ac242006d74fe1c2754d4f03ed889d7253259bd68 +F src/treeview.c 38eefdc85d2793c4059ae651a611b30eb034389fb428f69e572bbea565da6c78 +F src/trigger.c 0858f75818ed1580332db274f1032bcc5effe567cb132df5c5be8b1d800ca97f F src/update.c 732404a04d1737ef14bb6ec6b84f74edf28b3c102a92ae46b4855438a710efe7 F src/upsert.c 2e60567a0e9e8520c18671b30712a88dc73534474304af94f32bb5f3ef65ac65 F src/utf.c f23165685a67b4caf8ec08fb274cb3f319103decfb2a980b7cfd55d18dfa855e -F src/util.c a94fdaa08e3bbd35e425a1c7aed3065646cffe2a1cdf870885e8c6c61ce22bfc +F src/util.c 4d6d7ebfe6772a1b950c97bbb1d1a72ad4874617ec498ab8aa73b7f5a43e44bb F src/vacuum.c 604fcdaebe76f3497c855afcbf91b8fa5046b32de3045bab89cc008d68e40104 -F src/vdbe.c b2a45392265cb83f60251406039bf5255462d4a6d8deb05b2eaccab5abb2e20b -F src/vdbe.h 88e19a982df9027ec1c177c793d1a5d34dc23d8f06e3b2d997f43688b05ee0eb +F src/vdbe.c 3b1793c5d2235ae89b01ef051a33d7d2ad3704c71799653b112686735ad401ff +F src/vdbe.h c2d78d15112c3fc5ab87f5e8e0b75d2db1c624409de2e858c3d1aafb1650bb4f F src/vdbeInt.h 949669dfd8a41550d27dcb905b494f2ccde9a2e6c1b0b04daa1227e2e74c2b2c -F src/vdbeapi.c 8f57d60c89da0b60e6d4e272358c511f6bae4e24330bdb11f8b42f986d1bf21b -F src/vdbeaux.c 56900c9a41f23260c8346f212bd6005eb9171f9a2f70d0cfb1441a078a0e4b84 +F src/vdbeapi.c 80235ac380e9467fec1cb0883354d841f2a771976e766995f7e0c77f845406df +F src/vdbeaux.c 3bcf13776c39bf660a52b4b97f6389a421c2756f9ffbf4c0d94f73e1935d8d9c F src/vdbeblob.c 13f9287b55b6356b4b1845410382d6bede203ceb29ef69388a4a3d007ffacbe5 -F src/vdbemem.c 0012d5f01cc866833847c2f3ae4c318ac53a1cb3d28acad9c35e688039464cf0 +F src/vdbemem.c 831a244831eaa45335f9ae276b50a7a82ee10d8c46c2c72492d4eb8c98d94d89 F src/vdbesort.c 237840ca1947511fa59bd4e18b9eeae93f2af2468c34d2427b059f896230a547 F src/vdbetrace.c fe0bc29ebd4e02c8bc5c1945f1d2e6be5927ec12c06d89b03ef2a4def34bf823 -F src/vdbevtab.c 2143db7db0ceed69b21422581f434baffc507a08d831565193a7a02882a1b6a7 -F src/vtab.c 11948e105f56e84099ca17f1f434b1944539ea84de26d0d767eadfbc670ce1ea +F src/vdbevtab.c fc46b9cbd759dc013f0b3724549cc0d71379183c667df3a5988f7e2f1bd485f3 +F src/vtab.c 5fb499d20494b7eecaadb7584634af9afcb374cb0524912b475fcb1712458a1b F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c 887fc4ca3f020ebb2e376f222069570834ac63bf50111ef0cbf3ae417048ed89 F src/wal.h ba252daaa94f889f4b2c17c027e823d9be47ce39da1d3799886bbd51f0490452 F src/walker.c 7c7ea0115345851c3da4e04e2e239a29983b61fb5b038b94eede6aba462640e2 -F src/where.c e3cb2a01bc265547b936fcbbbce8d55fdf8b017e7d55803be31b56cfc16d3fae +F src/where.c 6f02c3936d1f9a637d8d7b5ad7362371af3e4434b0ec1eb950189a83de560d59 F src/whereInt.h 82a13766f13d1a53b05387c2e60726289ef26404bc7b9b1f7770204d97357fb8 -F src/wherecode.c 5d77db30a2a3dd532492ae882de114edba2fae672622056b1c7fd61f5917a8f1 -F src/whereexpr.c dc5096eca5ed503999be3bdee8a90c51361289a678d396a220912e9cb73b3c00 -F src/window.c 5b1387d59df30d481ed14cceef5f4d1dab1f8752aa106ba72c8b62777bd139d2 +F src/wherecode.c f5255f49d1f42b6e7e6b0362ff3522fa88cbcaa7213e52f9374744027ecdebca +F src/whereexpr.c 67d15caf88a1a9528283d68ff578e024cf9fe810b517bb0343e5aaf695ad97dd +F src/window.c 5d95122dd330bfaebd732358c8ef067c5a9394a53ac249470d611d0ce2c52be2 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test ce1aafc86e110685b324e9a763eab4f2a73f737842ec3b687bd965867de90627 F test/affinity3.test f094773025eddf31135c7ad4cde722b7696f8eb07b97511f98585addf2a510a9 @@ -838,7 +854,7 @@ F test/aggorderby.test cc3abf5de64d46ff66395ca8c2346b66c2576d5aedb7bffc5b0742508 F test/alias.test 4529fbc152f190268a15f9384a5651bbbabc9d87 F test/all.test 2ecb8bbd52416642e41c9081182a8df05d42c75637afd4488aace78cc4b69e13 F test/alter.test 3c00eff1e2036b9f93e9cd0f3d3e63750ac87ecb5bc71b9d7bd07cbf2ac4c494 -F test/alter2.test a966ccfcddf9ce0a4e0e6ff1aca9e6e7948e0e242cd7e43fc091948521807687 +F test/alter2.test 7e3d26ab409df52df887b366a63902c3429b935c41cb962fd58ffc25784f2f19 F test/alter3.test ffc4ab29ce78a3517a66afd69b2730667e3471622509c283b2bd4c46f680fba3 F test/alter4.test 716caa071dd8a3c6d57225778d15d3c3cbf5e34b2e84ae44199aeb2bbf50a707 F test/alterauth.test 63442ba61ceb0c1eeb63aac1f4f5cebfa509d352276059d27106ae256bafc959 @@ -854,8 +870,8 @@ F test/altermalloc2.test 17fb3724c4b004c469c27dc4ef181608aa644555fbd3f3236767584 F test/altermalloc3.test 8040e486368403f2fdd6fc3998258b499bd4cc2f3ddbb5f8f874cd436f076e81 F test/alterqf.test 8ec03d776de9c391daa0078ea8f838903bdcfb11dfae4ba3576b48436834ccba F test/altertab.test 8a2712f9076da5012a002d0b5cc0a421398a5bf61c25bab41b77c427586a7a27 -F test/altertab2.test 62597b6fd08feaba1b6bfe7d31dac6117c67e06dc9ce9c478a3abe75b5926de0 -F test/altertab3.test 6c432fbb9963e0bd6549bf1422f6861d744ee5a80cb3298564e81e556481df16 +F test/altertab2.test fff90e3f01e8eb0e09282f538b8ec7cfeb035dbedbe570fe1983440f4613ad0e +F test/altertab3.test b331ae34e69594e19605e3297805202d6156fcc8f75379dfd972a2e51cae8721 F test/altertrig.test aacc980b657354fe2d3d4d3a004f07d04ccc1a93e5ef82d68a79088c274ddc6b F test/amatch1.test b5ae7065f042b7f4c1c922933f4700add50cdb9f F test/analyze.test 2fb21d7d64748636384e6cb8998dbf83968caf644c07fcb4f76c18f2e7ede94b @@ -899,7 +915,7 @@ F test/autoindex5.test 2ee94f033b87ca0160e08d81034c507aff8e230df2627f0304fa309b2 F test/autovacuum.test 00671369bbf96c6a49989a9425f5b78b94075d6a4b031e5e00000c2c32f365df F test/autovacuum2.test 76f7eb4fe6a6bf6d33a196a7141dba98886d2fb53a268d7feca285d5da4759d7 F test/autovacuum_ioerr2.test 8a367b224183ad801e0e24dcb7d1501f45f244b4 -F test/avfs.test 0c3a38e03cccb0fc3127838462dc05dc3f4c1480d770c084b388304c25de3652 +F test/avfs.test 76f59743dc1f5fa533840d1818b420fe1ee45e21c0fd6bbac7942ba677903128 F test/avtrans.test b7dc25459ecbd86c6fa9c606ee3068f59d81e225118617dcf2bbb6ded2ade89e F test/backcompat.test 3e64cedda754c778ef6bbe417b6e7a295e662a4d F test/backup.test 3b08fd4af69f0fa786931103a31f4542b184aba16e239e5f22b18c3c2476697f @@ -919,10 +935,11 @@ F test/bestindex4.test 3039894f2dad50f3a68443dffad1b44c9b067ac03870102df1ce3d9a4 F test/bestindex5.test a0c90b2dad7836e80a01379e200e5f8ec9476d49b349af02c0dbff2fb75dc98d F test/bestindex6.test 16942535b551273f3ad9df8d7cc4b7f22b1fcd8882714358859eb049a6f99dd4 F test/bestindex7.test f094c669a6400777f4d2ddc3ed28e39169f1adb5be3d59b55f22ccf8c414b71e -F test/bestindex8.test 333ad8c6a554b885a49b68c019166eda92b05f493a92b36b0acdf7f766d04dad +F test/bestindex8.test b63a4f171a2c83d481bb14c431a8b72e85d27b2ffdaa0435a95d58ca941678f9 F test/bestindex9.test 1a4b93db117fd8abe74ae9be982f86aa72f01e60cd4ac541e6ede39673a451a0 F test/bestindexA.test e1b5def6b190797cacf008e6815ffb78fb30261999030d60a728d572eef44c7f F test/bestindexB.test 328b97b69cd1a20928d5997f9ecb04d2e00f1d18e19ab27f9e9adb44d7bc51ce +F test/bestindexC.test 9e6f184be080fd9c4605a7e5c7097eed1a259372f9af78151c37b072a9086f86 F test/between.test b9a65fb065391980119e8a781a7409d3fcf059d89968279c750e190a9a1d5263 F test/bigfile.test aa74f4e5db51c8e54a1d9de9fa65d01d1eb20b59 F test/bigfile2.test 1b489a3a39ae90c7f027b79110d6b4e1dbc71bfc @@ -946,13 +963,13 @@ F test/boundary4.test 89e02fa66397b8a325d5eb102b5806f961f8ec4b F test/btree01.test fef17d9e999ac4f04095948e3438fbe674f4e07bb2c63bb1cad41d87baee077f F test/btree02.test 7555a5440453d900410160a52554fe6478af4faf53098f7235f1f443d5a1d6cc F test/btreefault.test a82a23b0578bc587afbf9a622c8f54a54f63762f062ba8a35613cfee38ab42f9 -F test/busy.test 510dc6daaad18bcbbc085bcc6217d6dc418def5e73f72ce1475eea0cb7834727 +F test/busy.test caff7164c16ce06a53af51f9e4c2753d4cc64250e00790a5e48b9c4f4be37597 F test/busy2.test 20823a5d7c42fb257d9f108c66312d90b1bb4ec3d80ba6b4e371073727560f98 F test/cache.test 13bc046b26210471ca6f2889aceb1ea52dc717de F test/cacheflush.test af25bb1509df04c1da10e38d8f322d66eceedf61 F test/cachespill.test 895997f84a25b323b166aecb69baab2d6380ea98f9e0bcc688c4493c535cfab9 F test/capi2.test 4ee545824adc3eb33bf57ef89f77440b28188ec3da72e5425ff0fcdba32e8d5a -F test/capi3.test 3910a73c38ac76d69778dd9eb481ab7cd6ed59117fc047b4f6056a5c72529de1 +F test/capi3.test 4892b5e53d2a6941edc9d204a0ab174dd66e8689282d9a15e4384561c3965945 F test/capi3b.test efb2b9cfd127efa84433cd7a2d72ce0454ae0dc4 F test/capi3c.test 31d3a6778f2d06f2d9222bd7660c41a516d1518a059b069e96ebbeadb5a490f7 F test/capi3d.test 8b778794af891b0dca3d900bd345fbc8ebd2aa2aae425a9dccdd10d5233dfbde @@ -965,6 +982,7 @@ F test/changes2.test 07949edcc732af28cb54276bfb7d99723bccc1e905a423648bf57ac5cb0 F test/check.test 56e4ed457e9f8683b9fc56f5b964f461f6e8a8dd5a13f3d495408215d66419ed F test/checkfault.test da6cb3d50247169efcb20bdf57863a3ccfa1d27d9e55cd324f0680096970f014 F test/chunksize.test 427d87791743486cbf0c3b8c625002f3255cb3a89c6eba655a98923b1387b760 +F test/cksumvfs.test 6f05dc95847c06a3dc10eee6b5ab1351d78314a52d0db15717c9388f4cb96646 F test/close.test eccbad8ecd611d974cbf47278c3d4e5874faf02d811338d5d348af42d56d647c F test/closure01.test 9905883f1b171a4638f98fc764879f154e214a306d3d8daf412a15e7f3a9b1e0 F test/coalesce.test cee0dccb9fbd2d494b77234bccf9dc6c6786eb91 @@ -997,8 +1015,8 @@ F test/corrupt8.test 2399dfe40d2c0c63af86706e30f3e6302a8d0516 F test/corrupt9.test 730a3db08d4ab9aa43392ea30d9c2b4879cbff85 F test/corruptA.test 112f4b2ae0b95ebf3ea63718642fb969a93acea557ace3a307234d19c245989b F test/corruptB.test 73a8d6c0b9833697ecf16b63e3c5c05c945b5dec -F test/corruptC.test 9cf32275dae3ca33f645afe5d1d3f5ba5ac2af2b0833dfb5282f9dccb6fb81bb -F test/corruptD.test a828c788535946a372a56a750b242cd96287cd823657abe5a73c5e51b91bdd28 +F test/corruptC.test 7d6d9e907334ea3ccb7111a0656cafa30a28f8a5f2aaf1c45ad712236302856a +F test/corruptD.test 614320aa519f6bf6c7dd2f581f9513ff7b6826954180cca1a606d0e25ea084a3 F test/corruptE.test 4143791f2dfb443aec5b7fabfa5821e6063eccc3b49b06f212c2f014715fd476 F test/corruptF.test be9fde98e4c93648f1ba52b74e5318edc8f59fe4 F test/corruptG.test adf79b669cbfd19e28c8191a610d083ae53a6d51 @@ -1006,10 +1024,10 @@ F test/corruptH.test 79801d97ec5c2f9f3c87739aa1ec2eb786f96454 F test/corruptI.test 9d8cbf6214e492abe9e822e759b9751ae336cec0a6fe3ff3b37bfbd8ff9c22ca F test/corruptJ.test 4d5ccc4bf959464229a836d60142831ef76a5aa4 F test/corruptK.test 5b4212fe346699831c5ad559a62c54e11c0611bdde1ea8423a091f9c01aa32af -F test/corruptL.test 504d90502d9993440226edc355d2275524b89064ea3df5ee5c27f7028ec59d07 +F test/corruptL.test 652fc8ac0763a6fd3eb28b951d481924167b2d9936083bcc68253b2274a0c8fe F test/corruptM.test 7d574320e08c1b36caa3e47262061f186367d593a7e305d35f15289cc2c3e067 F test/corruptN.test 7c099d153a554001b4fb829c799b01f2ea6276cbc32479131e0db0da4efd9cc4 -F test/cost.test b11cdbf9f11ffe8ef99c9881bf390e61fe92baf2182bad1dbe6de59a7295c576 +F test/cost.test cc434a026b1e9d0d98137a147e24e5daf1b1ad09e9ff7da63b34c83ddd136d92 F test/count.test cd4bd531066e8d77ef8fe1e3fc8253d042072e117ccab214b290cf83f1602249 F test/countofview.test 4088e461a10ee33e69803c177a69aa1d7bba81a9ffc2df66d76465a22ca7fdfc F test/coveridxscan.test f35c7208dedc4f98e471c569df64c0f95a49f6e072d8dc7c8f99bdee2697de1b @@ -1030,10 +1048,10 @@ F test/ctime.test 340f362f41f92972bbd71f44e10569a5cc694062b692231bd08aa6fe6c1c47 F test/cursorhint.test 05cf0febe5c5f8a31f199401fd1c9322249e753950d55f26f9d5aca61408a270 F test/cursorhint2.test 6f3aa9cb19e7418967a10ec6905209bcbb5968054da855fc36c8beee9ae9c42f F test/dataversion1.test 6e5e86ac681f0782e766ebcb56c019ae001522d114e0e111e5ebf68ccf2a7bb8 -F test/date.test ff2341a1ef71b9a27979494d299222f9a293aa22cb9ff6e9c38d88a895317ebf +F test/date.test c8ff835023f2107b57ce7a45c92265d51c98a23fc93231e998f12d850831aad6 F test/date2.test 7e12ec14aaf4d5e6294b4ba140445b0eca06ea50062a9c3a69c4ee13d0b6f8b1 F test/date3.test a1b77abf05c6772fe5ca2337cac1398892f2a41e62bce7e6be0f4a08a0e64ae5 -F test/date4.test 8aeb3de5b5e9fda968baa9357e4c0fae573724b7904943410195a19e96e31b6a +F test/date4.test 75dc8401e8c0639a228cd26a6eaa4ff5ea8ccda912b9853d1c9462c476670e17 F test/dbdata.test 042f49acff3438f940eeba5868d3af080ae64ddf26ae78f80c92bec3ca7d8603 F test/dbfuzz.c 73047c920d6210e5912c87cdffd9a1c281d4252e F test/dbfuzz001.test 6c9a4622029d69dc38926f115864b055cb2f39badd25ec22cbfb130c8ba8e9c3 @@ -1044,7 +1062,7 @@ F test/dbpagefault.test 35f06cfb2ef100a9b19d25754e8141b9cba9b7daabd4c60fa5af93fc F test/dbstatus.test 4a4221a883025ffd39696b3d1b3910b928fb097d77e671351acb35f3aed42759 F test/dbstatus2.test f5fe0afed3fa45e57cfa70d1147606c20d2ba23feac78e9a172f2fe8ab5b78ef F test/decimal.test ef731887b43ee32ef86e1c8fddb61a40789f988332c029c601dcf2c319277e9e -F test/default.test 830fad7180cdf0e6a06e93acc0403bf73762314a639363314db5674c631b6127 +F test/default.test c7124864cded213a3f118bc7e2e26f34b7c36dfa26cf6945cc8b7f5db1191277 F test/delete.test 2686e1c98d552ef37d79ad55b17b93fe96fad9737786917ce3839767f734c48f F test/delete2.test 3a03f2cca1f9a67ec469915cb8babd6485db43fa F test/delete3.test 555e84a00a99230b7d049d477a324a631126a6ab @@ -1056,7 +1074,7 @@ F test/descidx3.test 953c831df7ea219c73826dfbf2f6ee02d95040725aa88ccb4fa43d1a199 F test/diskfull.test 106391384780753ea6896b7b4f005d10e9866b6e F test/distinct.test 691c9e850b0d0b56b66e7e235453198cb4cf0760e324b7403d3c5abbeab0a014 F test/distinct2.test bb71cc7b5e58e895787f9910a788c254f679928d324732d063fe9bc202ecbe71 -F test/distinctagg.test ad2b4cf1483cd4cf24867dfafbfa0abb61184d92085fcc9784cea0592b278d64 +F test/distinctagg.test 40d7169ae5846caaf62c6e307d2ca3c333daf9b6f7cde888956a339a97afe85f F test/e_blobbytes.test 4c01dfe4f12087b92b20705a3fdfded45dc4ed16d5a211fed4e1d2786ba68a52 F test/e_blobclose.test 692fc02a058476c2222a63d97e3f3b2b809c1842e5525ded7f854d540ac2e075 F test/e_blobopen.test 29f6055ee453b8e679fe9570c4d3acfedbef821622c5dad16875148c5952ef50 @@ -1070,7 +1088,7 @@ F test/e_expr.test b950818a48269506d75a41c819003bd77a0893bc4a4f2fdee191bc74109c1 F test/e_fkey.test feeba6238aeff9d809fb6236b351da8df4ae9bda89e088e54526b31a0cbfeec5 F test/e_fts3.test 17ba7c373aba4d4f5696ba147ee23fd1a1ef70782af050e03e262ca187c5ee07 F test/e_insert.test f02f7f17852b2163732c6611d193f84fc67bc641fb4882c77a464076e5eba80e -F test/e_reindex.test 2b0e29344497d9a8a999453a003cb476b6b1d2eef2d6c120f83c2d3a429f3164 +F test/e_reindex.test 027bb13d2c7e9e865886eed6349f126a273f8037899b636bf5fb53c7fc815921 F test/e_resolve.test a61751c368b109db73df0f20fc75fb47e166b1d8 F test/e_select.test 327a15f14068bbd6f647cedc67210f8680fcb2f05e481a0a855fccd2abfa1292 F test/e_select2.test aceb80ab927d46fba5ce7586ebabf23e2bb0604f @@ -1087,7 +1105,8 @@ F test/enc.test 9a7be5479da985381d740b15f432800f65e2c87029ee57a318f42cb2eb43763a F test/enc2.test 848bf05f15b011719f478dddb7b5e9aea35e39e457493cba4c4eef75d849a5ec F test/enc3.test 55ef64416d72975c66167310a51dc9fc544ba3ae4858b8d5ab22f4cb6500b087 F test/enc4.test c8f1ce3618508fd0909945beb8b8831feef2c020 -F test/eqp.test f3f7548d2f3df03e2f23ecaf35c7c2cc7b89848bd7c3606d94a010521b7ea4f6 +F test/eqp.test 3302598f611220a6c61e29d9b7bb62fd4a43504509b978dbabdb0b3e56ae3bc0 +F test/eqp2.test 6e8996148de88f0e7670491e92e712a2920a369b4406f21a27c3c9b6a46b68dd F test/errmsg.test eae9f091eb39ce7e20305de45d8e5d115b68fa856fba4ea6757b6ca3705ff7f9 F test/eval.test 73969a2d43a511bf44080c44485a8c4d796b6a4f038d19e491867081155692c0 F test/exclusive.test 7ff63be7503990921838d5c9f77f6e33e68e48ed1a9d48cd28745bf650bf0747 @@ -1097,6 +1116,7 @@ F test/exists.test 79a75323c78f02bbe9c251ea502a092f9ef63dac F test/expr.test 5c06696478212e5a04e04b043f993373f6f8e5ce5a80f5548a84703b123b6caa F test/expr2.test c27327ae9c017a7ff6280123f67aff496f912da74d78c888926d68b46ec75fd8 F test/exprfault.test da33606d799718e2f8e34efd0e5858884a1ad87f608774c552a7f5517cc27181 +F test/exprfault2.test c49e84273898969af5dbc4fe6a3f4335f14639799f343590336c9ddf84425965 F test/extension01.test 00d13cec817f331a687a243e0e5a2d87b0e358c9 F test/external_reader.test c7d34694f1b25c32d866f56ac80c1e29edddc42b4ef90cad589263ffac2cde0c F test/extraquick.test cb254400bd42bfb777ff675356aabf3287978f79 @@ -1168,7 +1188,7 @@ F test/fts3expr5.test a5b9a053becbdb8e973fbf4d6d3abaabeb42d511d1848bd57931f3e0a1 F test/fts3f.test 8c438d5e1cab526b0021988fb1dc70cf3597b006a33ffd6c955ee89929077fe3 F test/fts3fault.test f4e1342acfe6d216a001490e8cd52afac1f9ffe4a11bbcdcb296129a45c5df45 F test/fts3fault2.test 7b2741e5095367238380b0fcdb837f36c24484c7a5f353659b387df63cf039ec -F test/fts3fault3.test 4a39a1618546776255dc1de306213b600aef87eca589ca8428a70c00fd11961b +F test/fts3fault3.test ccdd2292dd2d4e21e30fc5f4c8e064f79e516087eec5ff57ab6bc4f6a7714097 F test/fts3first.test dbdedd20914c8d539aa3206c9b34a23775644641 F test/fts3fuzz001.test c78afcd8ad712ea0b8d2ed50851a8aab3bc9dc52c64a536291e07112f519357c F test/fts3integrity.test 0c6fe7353d7b24d78862f4272ee9df4da2f32b3ff30fa3396945cda8119580a8 @@ -1186,7 +1206,7 @@ F test/fts3rank.test cd99bc83a3c923c8d52afd90d86979cf05fc41849f892faeac3988055ef F test/fts3rnd.test 1320d8826a845e38a96e769562bf83d7a92a15d0 F test/fts3shared.test 57e26a801f21027b7530da77db54286a6fe4997e F test/fts3snippet.test 0887196d67cffbe365edde535b95ecc642a532ce8551ccd9a73aab5999c3ffae -F test/fts3snippet2.test e79afeb1f673713f96d7fc5655726081975399d11e659d15553207be43301dc4 +F test/fts3snippet2.test 03f6738ab3897bea2ba6be424a0613872e167acbf37a66200d655d737b470f65 F test/fts3sort.test ed34c716a11cc2009a35210e84ad5f9c102362ca F test/fts3tok1.test a663f4cac22a9505400bc22aacb818d7055240409c28729669ea7d4cc2120d15 F test/fts3tok_err.test 52273cd193b9036282f7bacb43da78c6be87418d @@ -1217,9 +1237,9 @@ F test/fts4unicode.test 82a9c16b68ba2f358a856226bb2ee02f81583797bc4744061c54401b F test/fts4upfrom.test f25835162c989dffd5e2ef91ec24c4848cc9973093e2d492d1c7b32afac1b49d F test/full.test 6b3c8fb43c6beab6b95438c1675374b95fab245d F test/func.test b56905748ce0567c01d60005f3e6ad1af19453d224ba4730ee687d048fd09ef9 -F test/func2.test 772d66227e4e6684b86053302e2d74a2500e1e0f +F test/func2.test 69f6ae3751b4ec765bdc3b803c0a255aa0f693f28f44805bef03e6b4a3fd242f F test/func3.test 600a632c305a88f3946d38f9a51efe145c989b2e13bd2b2a488db47fe76bab6a -F test/func4.test e8ef9b2bd6a192a213cbd5cf31a3b35e25cd6ff2fdaeea0b58d63be31b03d220 +F test/func4.test a3f9062487dbd826776f54f4e0e9517fe8c3cf689af92735308965774d51fac5 F test/func5.test 863e6d1bd0013d09c17236f8a13ea34008dd857d87d85a13a673960e4c25d82a F test/func6.test 9cc9b1f43b435af34fe1416eb1e318c8920448ea7a6962f2121972f5215cb9b0 F test/func7.test adbfc910385a6ffd15dc47be3c619ef070c542fcb7488964badb17b2d9a4d080 @@ -1232,7 +1252,7 @@ F test/fuzz3.test 9c813e6613b837cb7a277b0383cd66bfa07042b4cf0317157c35852f30043c F test/fuzz4.test c229bcdb45518a89e1d208a21343e061503460ac69fae1539320a89f572eb634 F test/fuzz_common.tcl b7197de6ed1ee8250a4f82d67876f4561b42ee8cbbfc6160dcb66331bad3f830 F test/fuzz_malloc.test f348276e732e814802e39f042b1f6da6362a610af73a528d8f76898fde6b22f2 -F test/fuzzcheck.c e6a40f53ac5624aa5b7c4f31c385f09ba088d524cecc4512fd3057caeed8f530 +F test/fuzzcheck.c dc159967609d00b0cfe619e735cbbf8482570aca85711397034b0662b6c18fc7 F test/fuzzdata1.db 3e86d9cf5aea68ddb8e27c02d7dfdaa226347426c7eb814918e4d95475bf8517 F test/fuzzdata2.db 128b3feeb78918d075c9b14b48610145a0dd4c8d6f1ca7c2870c7e425f5bf31f F test/fuzzdata3.db c6586d3e3cef0fbc18108f9bb649aa77bfc38aba @@ -1244,7 +1264,7 @@ F test/fuzzdata8.db 4a53b6d077c6a5c23b609d8d3ac66996fa55ba3f8d02f9b6efdd0214a767 F test/fuzzer1.test 3d4c4b7e547aba5e5511a2991e3e3d07166cfbb8 F test/fuzzer2.test a85ef814ce071293bce1ad8dffa217cbbaad4c14 F test/fuzzerfault.test f64c4aef4c9e9edf1d6dc0d3f1e65dcc81e67c996403c88d14f09b74807a42bc -F test/fuzzinvariants.c 4355043e98cd8555c62462fcbba91c17c6492b0b017bbbe68656d5f2208f6444 +F test/fuzzinvariants.c 0729b9d8ed77ad0f8c5c7601168a707d5803087d2da030ede9057c51c809cc6c F test/gcfault.test 4ea410ac161e685f17b19e1f606f58514a2850e806c65b846d05f60d436c5b0d F test/gencol1.test e169bdfa11c7ed5e9f322a98a7db3afe9e66235750b68c923efee8e1876b46ec F test/genesis.tcl 1e2e2e8e5cc4058549a154ff1892fe5c9de19f98 @@ -1253,15 +1273,16 @@ F test/hexlit.test 4a6a5f46e3c65c4bf1fa06f5dd5a9507a5627751 F test/hidden.test 23c1393a79e846d68fd902d72c85d5e5dcf98711 F test/hook.test 18cae9140fa7f9a6f346e892a3fe3e31b2ca0be1494cd01b918adb74281016a6 F test/hook2.test b9ff3b8c6519fb67f33192f1afe86e7782ee4ac8 -F test/icu.test 716a6b89fbabe5cc63e0cd4c260befb08fd7b9d761f04d43669233292f0753b1 +F test/icu.test 8da7d52cd9722c82f33b0466ed915460cb03c23a38f18a9a2d3ff97da9a4a8c0 F test/ieee754.test b0945d12be7d255f3dfa18e2511b17ca37e0edd2b803231c52d05b86c04ab26e F test/imposter1.test c3f1db2d3db2c24611a6596a3fc0ffc14f1466c8 F test/in.test d1cad4ededd425568b2e39fb0c31fa9a3772311dd595801ff13ba3912b69bba6 F test/in2.test 5d4c61d17493c832f7d2d32bef785119e87bde75 F test/in3.test 3cbf58c87f4052cee3a58b37b6389777505aa0c0 -F test/in4.test fdd1d8134da8376985c2edba6035a2de1f6c731524d2ffa651419e8fe2cd1c5a -F test/in5.test b32ce7f4a93f44c5dee94af16886d922cc16ebe33c8e1765c73d4049d0f4b40f +F test/in4.test bb767ec1cfd1730256f0a83219f0acda36bc251b63f8b8bb7d8c7cff17875a4f +F test/in5.test 4fd79c70dfa0681313e8cdca07f5ff0400bdc0e20f808a5c59eaef1e4b48082a F test/in6.test f5f40d6816a8bb7c784424b58a10ac38efb76ab29127a2c17399e0cbeeda0e4b +F test/in7.test 742b18c284cd9a9cd1347d3a8affeee44b8de11e875e91a1d40498c18ba16441 F test/incrblob.test c9b96afc292aeff43d6687bcb09b0280aa599822 F test/incrblob2.test a494c9e848560039a23974b9119cfc2cf3ad3bd15cc2694ee6367ae537ef8f1f F test/incrblob3.test 67621a04b3084113bf38ce03797d70eca012d9d8f948193b8f655df577b0da6f @@ -1284,7 +1305,7 @@ F test/index8.test caa097735c91dbc23d8a402f5e63a2a03c83840ba3928733ed7f9a03f8a91 F test/index9.test 2ac891806a4136ef3e91280477e23114e67575207dc331e6797fa0ed9379f997 F test/indexA.test 11d84f6995e6e5b9d8315953fb1b6d29772ee7c7803ee9112715e7e4dd3e4974 F test/indexedby.test f21eca4f7a6ffe14c8500a7ad6cd53166666c99e5ccd311842a28bc94a195fe0 -F test/indexexpr1.test 833f511213a5e26549186813f0566bd72f978177a7e6e98a2d2dd695de3c670d +F test/indexexpr1.test 24fa85a12da384dd1d56f7b24e593c51a8a54b4c5e2e8bbb9e5fdf1099427faf F test/indexexpr2.test 1c382e81ef996d8ae8b834a74f2a9013dddf59214c32201d7c8a656d739f999a F test/indexfault.test 98d78a8ff1f5335628b62f886a1cb7c7dac1ef6d48fa39c51ec871c87dce9811 F test/init.test 15c823093fdabbf7b531fe22cf037134d09587a7 @@ -1337,25 +1358,29 @@ F test/json/json-q1.txt 65f9d1cdcc4cffa9823fb73ed936aae5658700cd001fde448f68bfb9 F test/json/json-speed-check.sh 912ee03e700a65c827ee0c7b4752c21ec5ef69cf7679d2f482ca817042bead52 x F test/json/jsonb-q1.txt 1e180fe6491efab307e318b22879e3a736ac9a96539bbde7911a13ee5b33abc7 F test/json101.test 30db5b055b103ccabc53a29cfe6cda3345d07e171aeb25403dafa04f19e98b19 -F test/json102.test 557a46e16df1aa9bdbc4076a71a45814ea0e7503d6621d87d42a8c04cbc2b0ef +F test/json102.test 4b3a0f94535f033239b67c13dbee8b47d2b5ee467e0f2fdab5eadf370bbe5fd3 F test/json103.test 53df87f83a4e5fa0c0a56eb29ff6c94055c6eb919f33316d62161a8880112dbe F test/json104.test 1b844a70cddcfa2e4cd81a5db0657b2e61e7f00868310f24f56a9ba0114348c1 F test/json105.test 043838b56e68f3252a0dcf5be1689016f6f3f05056f8dcfcdc9d074f4d932988 -F test/json106.test 1d46a9294e2ced35c7f87cebbcb9626d01abab04f1969d7ded7b6f6a1d9be0f2 +F test/json106.test 4aed3afd16549045d198a8d9cea00deea96e1f2ecf55864dce96cac558b8abef F test/json107.test 59054e815c8f6b67d634d44ace421cf975828fb5651c4460aa66015c8e19d562 -F test/json501.test ab168a12eb6eb14d479f8c1cdae3ac062fd5a4679f17f976e96f1af518408330 +F test/json108.test 0a5f1e2d4b35a1bc33052563d2a5ede03052e2099e58cb424547656c898e0f49 +F test/json501.test b95e2d14988b682a5cadf079dd6162f0f85fb74cd59c6b1f1624110104a974eb F test/json502.test 84634d3dbb521d2814e43624025b760c6198456c8197bbec6c977c0236648f5b F test/jsonb01.test f4cdfb4cf5a0c940091b17675ed9583f45add0c938f07d65b0de0e19d3a9a101 F test/keyword1.test 37ef6bba5d2ed5b07ecdd6810571de2956599dff F test/kvtest.c 6e0228409ea7ca0497dad503fbd109badb5e59545d131014b6aaac68b56f484a F test/lastinsert.test 42e948fd6442f07d60acbd15d33fb86473e0ef63 F test/laststmtchanges.test ae613f53819206b3222771828d024154d51db200 -F test/lemon-test01.y 58b764610fd934e189ffbb0bbfa33d171b9cb06019b55bdc04d090d6767e11d7 +F test/lemon-test01.y 70110eff607ab137ccc851edb2bc7e14a6d4f246b5d2d25f82a60b69d87a9ff2 F test/like.test 242ee7f5d08a031144c0daf63bbd7e7710c847ccf387a83347e0b61b3aa69526 F test/like2.test d3be15fefee3e02fc88942a9b98f26c5339bbdef7783c90023c092c4955fe3d3 F test/like3.test a76e5938fadbe6d32807284c796bafd869974a961057bc5fc5a28e06de98745c F test/limit.test 350f5d03c29e7dff9a2cde016f84f8d368d40bcd02fa2b2a52fa10c4bf3cbfaf F test/limit2.test 9409b033284642a859fafc95f29a5a6a557bd57c1f0d7c3f554bd64ed69df77e +F test/literal.test a65dca9fef86e51b8e45544268e37abbd4bb94ba35fd65f6fdcab2f288cd8f79 +F test/literal2.tcl 1499037beaf661aeecdbe48801220a181d805372a64c6128d5f26bb6a4a8f0ce +F test/literal2.test b149e16b5fc9ee6249069a8858ed41052f222014fe0ba7ad43c2fb989c2dada2 F test/loadext.test faa4f6eed07a5aac35d57fdd7bc07f8fc82464cfd327567c10cf0ba3c86cde04 F test/loadext2.test 0408380b57adca04004247179837a18e866a74f7 F test/lock.test be4fe08118fb988fed741f429b7dd5d65e1c90db @@ -1408,11 +1433,11 @@ F test/minmax.test fe638b55d77d2375531a8f549b338eafcd9adfbd2f72df37ed77d9b26ca0a F test/minmax2.test cf9311babb6f0518d04e42fd6a42c619531c4309a9dd790a2c4e9b3bc595e0de F test/minmax3.test cc1e8b010136db0d01a6f2a29ba5a9f321034354 F test/minmax4.test 272ca395257f05937dc96441c9dde4bc9fbf116a8d4fa02baeb0d13d50e36c87 -F test/misc1.test 8d138a4926ab90617c1aa29ce26e7785ae2b83a4d3a195d543b7374e05589dd1 +F test/misc1.test e3e36262aff1bd9b8b9bf1eeb3af04adb3fc1e23f0a92dbff708bba9e939ace1 F test/misc2.test a1a3573cc02662becd967766021d6f16c54684d56df5f227481c7ef0d9df0bd0 F test/misc3.test cf3dda47d5dda3e53fc5804a100d3c82be736c9d F test/misc4.test 10cd6addb2fa9093df4751a1b92b50440175dd5468a6ec84d0386e78f087db0e -F test/misc5.test c4aeaa0fa28faa08f2485309c38db4719e6cd1364215d5687a5b96d340a3fa58 +F test/misc5.test 027cf0ac10314ea534173f335a33bb4059907ddabbac2c16786766d6f26c8923 F test/misc6.test 953cc693924d88e6117aeba16f46f0bf5abede91 F test/misc7.test d912f3d45c2989191b797504a220ca225d6be80b21acad22ba0d35f4a9ee4579 F test/misc8.test 08d2380bc435486b12161521f225043ac2be26f02471c2c1ea4cac0b1548edbd @@ -1422,7 +1447,7 @@ F test/mmap1.test 18de3fd7b70a777af6004ca2feecfcdd3d0be17fa04058e808baf530c94b1a F test/mmap2.test 9d6dd9ddb4ad2379f29cc78f38ce1e63ed418022 F test/mmap3.test b3c297e78e6a8520aafcc1a8f140535594c9086e F test/mmap4.test 2e2b4e32555b58da15176e6fe750f17c9dcf7f93 -F test/mmapcorrupt.test 0d89724591f22a376019f3df60d075b838dd2ba6dae6effb0be465c49cf86d4a +F test/mmapcorrupt.test 470fb44fe92e99c1d23701d156f8c17865f5b027063c9119dcfdb842791f4465 F test/mmapfault.test d4c9eff9cd8c2dc14bc43e71e042f175b0a26fe3 F test/mmapwarm.test 2272005969cd17a910077bd5082f70bc1fefad9a875afec7fc9af483898ecaf3 F test/multiplex.test d74c034e52805f6de8cc5432cef8c9eb774bb64ec29b83a22effc8ca4dac1f08 @@ -1450,7 +1475,7 @@ F test/openv2.test 0d3040974bf402e19b7df4b783e447289d7ab394 F test/optfuzz-db01.c 9f2fa80b8f84ebbf1f2e8b13421a4e0477fe300f6686fbd76cac1d2db66e0fdc F test/optfuzz-db01.txt 21f6bdeadc701cf11528276e2a55c70bfcb846ba42df327f979bd9e7b6ce7041 F test/optfuzz.c 690430a0bf0ad047d5a168bf52b05b2ee97aedaad8c14337e9eb5050faa64994 -F test/orderby1.test 02cfd870127a7342170b829175c5c53e9e7405744451ac1aeb2f7e2b0c18ca76 +F test/orderby1.test 7d0e4ee692a3e808c1026b3c483594ad1e468b68b50dcefa0d678a8c05274ceb F test/orderby2.test bc11009f7cd99d96b1b11e57b199b00633eb5b04 F test/orderby3.test 8619d06a3debdcd80a27c0fdea5c40b468854b99 F test/orderby4.test 4d39bfbaaa3ae64d026ca2ff166353d2edca4ba4 @@ -1478,38 +1503,40 @@ F test/pcache.test c8acbedd3b6fd0f9a7ca887a83b11d24a007972b F test/pcache2.test af7f3deb1a819f77a6d0d81534e97d1cf62cd442 F test/pendingrace.test 6aa33756b950c4529f79c4f3817a9a1e4025bd0d9961571a05c0279bd183d9c6 F test/percentile.test 4243af26b8f3f4555abe166f723715a1f74c77ff -F test/permutations.test f7caf8dd5c7b1da74842a48df116f7f193399c656d4ffc805cd0d9658568c675 +F test/permutations.test 405542f1d659942994a6b38a9e024cf5cfd23eaa68c806aeb24a72d7c9186e80 F test/pg_common.tcl 3b27542224db1e713ae387459b5d117c836a5f6e328846922993b6d2b7640d9f -F test/pragma.test cddd4b534d7fb5cf113d1308dea4231f3548e8a7f3a65d7d1cf4810c87090b5a +F test/pragma.test 11cb9310c42f921918f7f563e3c0b6e70f9f9c3a6a1cf12af8fccb6c574f3882 F test/pragma2.test e5d5c176360c321344249354c0c16aec46214c9f F test/pragma3.test 92a46bbea12322dd94a404f49edcfbfc913a2c98115f0d030a7459bb4712ef31 -F test/pragma4.test c7539e5e63cdfd60b3c8114360ec2cf838e2cd6e3ebfd648152319dd8d6f6be0 +F test/pragma4.test f93f317693e90ece4ed0f5505d9035cae03f9fc684b718278433f2e48703f693 F test/pragma5.test 7b33fc43e2e41abf17f35fb73f71b49671a380ea92a6c94b6ce530a25f8d9102 +F test/pragma6.test c5ec577ba087954b4dfa619a3cbe97b155b60a0af487527abe89b10fc17e6512 F test/pragmafault.test 275edaf3161771d37de60e5c2b412627ac94cef11739236bec12ed1258b240f8 F test/prefixes.test b524a1c44bffec225b9aec98bd728480352aa8532ac4c15771fb85e8beef65d9 F test/printf.test 685fec5a0c5af2490ab0632775a301554361d674211d690f5bee0a97b05333de F test/printf2.test 3f55c1871a5a65507416076f6eb97e738d5210aeda7595a74ee895f2224cce60 F test/progress.test ebab27f670bd0d4eb9d20d49cef96e68141d92fb F test/ptrchng.test ef1aa72d6cf35a2bbd0869a649b744e9d84977fc -F test/pushdown.test 1495a09837a1cedfc0adf07ba42dc6b83be05a2c15de331b67c39a0e22078238 +F test/pushdown.test 3330746a897ea271b1021bc1e7e57c6f8d49bcb8ca7d58a823d01aa64a303cc7 F test/queryonly.test 5f653159e0f552f0552d43259890c1089391dcca F test/quick.test 1681febc928d686362d50057c642f77a02c62e57 F test/quickcheck.test a4b7e878cd97e46108291c409b0bf8214f29e18fddd68a42bc5c1375ad1fb80a F test/quota-glob.test 32901e9eed6705d68ca3faee2a06b73b57cb3c26 F test/quota.test bfb269ce81ea52f593f9648316cd5013d766dd2a F test/quota2.test 7dc12e08b11cbc4c16c9ba2aa2e040ea8d8ab4b8 -F test/quote.test ffb40f0eb7a25c1d8cfe11ee2fe67f8e85fbf3fed348810834114be1fdada142 +F test/quote.test 7b01b2a261bc26d9821aea9f4941ce1e08191d62fc55ba8862440fb3a59197a4 F test/randexpr1.tcl 40dec52119ed3a2b8b2a773bce24b63a3a746459 F test/randexpr1.test eda062a97e60f9c38ae8d806b03b0ddf23d796df F test/rbu.test 168573d353cd0fd10196b87b0caa322c144ef736 F test/rdonly.test 64e2696c322e3538df0b1ed624e21f9a23ed9ff8 -F test/recover.test fd5199f928757cb308661b5fdca1abc19398a798ff7f24b57c3071e9f8e0471e +F test/readonly.test c1985f0b4ab55041f2ba629dadc6578a3ff0f0e5b0ec7912e85c51f49c3e82fe +F test/recover.test 6463509a7404e0c35431dd9b4a1c3b4a29d7a6af8a08462b31670c8a5a616d3a F test/regexp1.test 8f2a8bc1569666e29a4cee6c1a666cd224eb6d50e2470d1dc1df995170f3e0f1 F test/regexp2.test 55ed41da802b0e284ac7e2fe944be3948f93ff25abbca0361a609acfed1368b5 F test/reindex.test cd9d6021729910ece82267b4f5e1b5ac2911a7566c43b43c176a6a4732e2118d F test/resetdb.test 54c06f18bc832ac6d6319e5ab23d5c8dd49fdbeec7c696d791682a8006bd5fc3 F test/resolver01.test f4022acafda7f4d40eca94dbf16bc5fc4ac30ceb -F test/returning1.test 3ead782eddf51f573cdd43bcbb10d1b485ac095a19a76d16c43fd159ea9b7466 +F test/returning1.test 38eee9d07ac1dd4fbd4ce7373497f3783db86b9a76f13ea6a9f9afaf934f888b F test/returningfault.test ae4c4b5e8745813287a359d9ccdb9d5c883c2e68afb18fb0767937d5de5692a4 F test/rollback.test 06680159bc6746d0f26276e339e3ae2f951c64812468308838e0a3362d911eaa F test/rollback2.test 3f3a4e20401825017df7e7671e9f31b6de5fae5620c2b9b49917f52f8c160a8f @@ -1540,7 +1567,7 @@ F test/savepoint6.test f41279c5e137139fa5c21485773332c7adb98cd7 F test/savepoint7.test cde525ea3075283eb950cdcdefe23ead4f700daa F test/savepointfault.test f044eac64b59f09746c7020ee261734de82bf9b2 F test/scanstatus.test b249328caf4d317e71058006872b8012598a5fa045b30bf24a81eeff650ab49e -F test/scanstatus2.test 2cb4d67ebbf578711dbf0377489a44759d0e21cdcce2fd55f0e044364961abec +F test/scanstatus2.test 688adc0c3ab1ffadead218cbce6446b10aa892004a8ea5e3640d59257fb836f2 F test/schema.test 5dd11c96ba64744de955315d2e4f8992e447533690153b93377dffb2a5ef5431 F test/schema2.test 906408621ea881fdb496d878b1822572a34e32c5 F test/schema3.test 8ed4ae66e082cdd8b1b1f22d8549e1e7a0db4527a8e6ee8b6193053ee1e5c9ce @@ -1560,7 +1587,7 @@ F test/select6.test 9b2fb4ffedf52e1b5703cfcae1212e7a4a063f014c0458d78d29aca3db76 F test/select7.test f659f231489349e8c5734e610803d7654207318f F test/select8.test 8c8f5ae43894c891efc5755ed905467d1d67ad5d F test/select9.test f7586b207ce2304ab80dc93d3146469a28fd4403621dd3a82d06644563d3c812 -F test/selectA.test 6aef8b2136a4ac7a3e2e4161d2b8ca7bc6ebe2779de084f9bb66ca9e2323a937 +F test/selectA.test 1da8ce3884c326e11d2855baffb76436b0d7e044404af8a2a70d1399a4ff7e29 F test/selectB.test 954e4e49cf1f896d61794e440669e03a27ceea25 F test/selectC.test 38c530b0cc5728b793c3c11f52b52c70290d39822224acd39011c89c1853bd31 F test/selectD.test 6d1909b49970bf92f45ce657505befcef5fc7cbc13544e18103a316d32189bfb @@ -1570,7 +1597,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 666b47e177c7b25f01ba645d41fb9131d2d54ae673f0d81c08f5af2b3e6ecbda +F test/sessionfuzz.c f693b8827034a3bed7616d89c65fb4fe8b7ff3c0f000c6ea6beda69b7f1aced3 F test/shared.test f022874d9d299fe913529dc10f52ad5a386e4e7ff709270b9b1111b3a0f3420a F test/shared2.test 03eb4a8d372e290107d34b6ce1809919a698e879 F test/shared3.test f8cd07c1a2b7cdb315c01671a0b2f8e3830b11ef31da6baa9a9cd8da88965403 @@ -1583,15 +1610,15 @@ F test/sharedA.test 64bdd21216dda2c6a3bd3475348ccdc108160f34682c97f2f51c19fc0e21 F test/sharedB.test 1a84863d7a2204e0d42f2e1606577c5e92e4473fa37ea0f5bdf829e4bf8ee707 F test/shared_err.test 32634e404a3317eeb94abc7a099c556a346fdb8fb3858dbe222a4cbb8926a939 F test/sharedlock.test 5ede3c37439067c43b0198f580fd374ebf15d304 -F test/shell1.test c7127a5e780ffc9e14c476773127fdf292c6db226529c44c1676f37b3793123f -F test/shell2.test 35226c070a8c7f64fd016dfac2a0db2a40f709b3131f61daacd9dad61536c9cb -F test/shell3.test 91febeac0412812bf6370abb8ed72700e32bf8f9878849414518f662dfd55e8a -F test/shell4.test 947029e5a9efae9054d424b309fc0311439c0c3a0866ebfa3b8a771120708220 -F test/shell5.test 263bfd6a49049295277e3f5bdc221390dc5e72f39954b23d43204ed81993304f -F test/shell6.test 1ceb51b2678c472ba6cf1e5da96679ce8347889fe2c3bf93a0e0fa73f00b00d3 -F test/shell7.test 115132f66d0463417f408562cc2cf534f6bbc6d83a6d50f0072a9eb171bae97f -F test/shell8.test 3fd093d481aaa94dc77fb73f1044c1f19c7efe3477a395cc4f7450133bc54915 -F test/shell9.test f457a96c088344908e0518dbabffd02eda8ac2a8733f278679e5f47c103efbab +F test/shell1.test 17a5ca9c6f24f807b2f505b4b38fcbce143d96cd8664c06c34bbbe0672bf7c30 +F test/shell2.test 56da24128304c9ab67da2964cc80beff7b35761c446ec6e6e98bff2775b15026 +F test/shell3.test 5ad4b2813717956414f2c0c8a2027895cd98ccf7dd54dbacbde4d4f5591ce5a1 +F test/shell4.test 522fdc628c55eff697b061504fb0a9e4e6dfc5d9087a633ab0f3dd11bcc4f807 +F test/shell5.test 5b2ab1c0540217773f939927c24163a56257446da3f564d4724042620bfea762 +F test/shell6.test e3b883b61d4916b6906678a35f9d19054861123ad91b856461e0a456273bdbb8 +F test/shell7.test 753c6ece5361df50025a50cadf378ea36db9cc05fb23d7a96cff7fa130626ef9 +F test/shell8.test aea51ecbcd4494c746b096aeff51d841d04d5f0dc4b62eb42427f16109b87acd +F test/shell9.test 8742a5b390cdcef6369f5aa223e415aa4255a4129ef249b177887dc635a87209 F test/shmlock.test 3dbf017d34ab0c60abe6a44e447d3552154bd0c87b41eaf5ceacd408dd13fda5 F test/shortread1.test bb591ef20f0fd9ed26d0d12e80eee6d7ac8897a3 F test/show_speedtest1_rtree.tcl 32e6c5f073d7426148a6936a0408f4b5b169aba5 @@ -1625,13 +1652,13 @@ F test/speed3.test 694affeb9100526007436334cf7d08f3d74b85ef F test/speed4.test abc0ad3399dcf9703abed2fff8705e4f8e416715 F test/speed4p.explain 6b5f104ebeb34a038b2f714150f51d01143e59aa F test/speed4p.test 377a0c48e5a92e0b11c1c5ebb1bc9d83a7312c922bc0cb05970ef5d6a96d1f0c -F test/speedtest1.c f9505ad6f9c2c3c488a370a2d193e9603a030e51126ef3ecfeb056d21f0e7ad5 +F test/speedtest1.c 19c9b60908d25502d2831f97efee8b81006c356ab8c08327e25d24a4144f2131 F test/spellfix.test 951a6405d49d1a23d6b78027d3877b4a33eeb8221dcab5704b499755bb4f552e F test/spellfix2.test dfc8f519a3fc204cb2dfa8b4f29821ae90f6f8c3 F test/spellfix3.test 0f9efaaa502a0e0a09848028518a6fb096c8ad33 F test/spellfix4.test 51c7c26514ade169855c66bcf130bd5acfb4d7fd090cc624645ab275ae6a41fb F test/sqldiff1.test 1b7ab4f312442c5cc6b3a5f299fa8ca051416d1dd173cb1126fd51bf64f2c3fb -F test/sqllimits1.test b28e5cc8d337aaf290614d96a47e8fbfb720bb7ad35620c9d5432996fd413ac4 +F test/sqllimits1.test dee96a51b83ef866d06ec3c687d4c951d97b02549facc5be88c9dfcb215b98bf F test/sqllog.test 6af6cb0b09f4e44e1917e06ce85be7670302517a F test/startup.c 1beb5ca66fcc0fce95c3444db9d1674f90fc605499a574ae2434dcfc10d22805 F test/stat.test 123212a20ceb496893d5254a5f6c76442ce549fdc08d1702d8288a2bbaac8408 @@ -1641,7 +1668,7 @@ F test/stmtvtab1.test 6873dfb24f8e79cbb5b799b95c2e4349060eb7a3b811982749a84b3594 F test/strict1.test 4d2b492152b984fd7e8196d23eb88e2ccb0ef9e46ca2f96c2ce7147ceef9d168 F test/strict2.test b22c7a98b5000aef937f1990776497f0e979b1a23bc4f63e2d53b00e59b20070 F test/subjournal.test 8d4e2572c0ee9a15549f0d8e40863161295107e52f07a3e8012a2e1fdd093c49 -F test/subquery.test 312c5d26304b0e93a56ba2cb9d4480b8a1c8217e3b2b8f8be2bfb0b2458ac3a7 +F test/subquery.test 903abf41049f8404256f7be24b3151328304a5b25162e17ab0079460237382fc F test/subquery2.test 90cf944b9de8204569cf656028391e4af1ccc8c0cc02d4ef38ee3be8de1ffb12 F test/subselect.test 0966aa8e720224dbd6a5e769a3ec2a723e332303 F test/substr.test a673e3763e247e9b5e497a6cacbaf3da2bd8ec8921c0677145c109f2e633f36b @@ -1657,7 +1684,7 @@ F test/sync.test 89539f4973c010eda5638407e71ca7fddbcd8e0594f4c9980229f804d433309 F test/sync2.test 8f9f7d4f6d5be8ca8941a8dadcc4299e558cb6a1ff653a9469146c7a76ef2039 F test/syscall.test a39d9a36f852ae6e4800f861bc2f2e83f68bbc2112d9399931ecfadeabd2d69d F test/sysfault.test c9f2b0d8d677558f74de750c75e12a5454719d04 -F test/tabfunc01.test 54f27eacd054aa528a8b6e3331192c484104f30aaee351ad035f2b39a00f87c4 +F test/tabfunc01.test f150d206294471d20f50029e6b46b76b87a7a010b16dc57eb44245c76dd02802 F test/table.test 7862a00b58b5541511a26757ea9c5c7c3f8298766e98aa099deec703d9c0a8e0 F test/tableapi.test ecbcc29c4ab62c1912c3717c48ea5c5e59f7d64e4a91034e6148bd2b82f177f4 F test/tableopts.test dba698ba97251017b7c80d738c198d39ab747930 @@ -1670,8 +1697,8 @@ F test/temptable2.test 76821347810ecc88203e6ef0dd6897b6036ac788e9dd3e6b04fd4d163 F test/temptable3.test d11a0974e52b347e45ee54ef1923c91ed91e4637 F test/temptrigger.test 38f0ca479b1822d3117069e014daabcaacefffcc F test/tester.tcl fe617b88c7eb08bdf983d2aaa31c20fbf439eee7b8e0d61ca636fcd0c305bbbf -F test/testrunner.tcl 8e2a5c7550b78d3283eee6103104ae2bcf56aa1df892dbd1608f27b93ebf4de8 -F test/testrunner_data.tcl 7ffd951527bbc614e723fd8d123b6834321878530696adecfdf6035100bac64e +F test/testrunner.tcl 1386667c04207d0a540ce1a9bc5ee0b734f7a3ba856c14a03943fb4f32de55bb +F test/testrunner_data.tcl 3d36660cfd55ea5e20e661e8f94c0520feebcb437848f9b98b33c483cc479c0c F test/thread001.test a0985c117eab62c0c65526e9fa5d1360dd1cac5b03bde223902763274ce21899 F test/thread002.test c24c83408e35ba5a952a3638b7ac03ccdf1ce4409289c54a050ac4c5f1de7502 F test/thread003.test ee4c9efc3b86a6a2767516a37bd64251272560a7 @@ -1716,7 +1743,7 @@ F test/tkt-7a31705a7e6.test 9e9c057b6a9497c8f7ba7b16871029414ccf6550e7345d9085d6 F test/tkt-7bbfb7d442.test e87b59e620700b5a52ecd92f05d56686c1cad9e1aa17456eada55e0bb821b698 F test/tkt-80ba201079.test 105a721e6aad0ae3c5946d7615d1e4d03f6145b8 F test/tkt-80e031a00f.test 7c93af53f43527f50020983a4bcc39b077e77c7362d7af8e04a5fd155fe5e829 -F test/tkt-8454a207b9.test aff2e76143cfa443ddce6f7d85968a2e9b57a3deb0b881b730120740555f9e2f +F test/tkt-8454a207b9.test ead80b7a01438ca1436cee029694a96c821346cf1e24f06de12f8172e139ddbb F test/tkt-868145d012.test a5f941107ece6a64410ca4755c6329b7eb57a356 F test/tkt-8c63ff0ec.test 258b7fc8d7e4e1cb5362c7d65c143528b9c4cbed F test/tkt-91e2e8ba6f.test 08c4f94ae07696b05c9b822da0b4e5337a2f54c5 @@ -1733,7 +1760,7 @@ F test/tkt-b351d95f9.test d14a503c414c5c58fdde3e80f9a3cfef986498c0 F test/tkt-b72787b1.test a95e8cdad0b98af1853ac7f0afd4ab27b77bf5f3 F test/tkt-b75a9ca6b0.test dc6a853c242f7d0326564ae32e9e5eb462b5e8d2bc5b01ea3b18fd24f8e5894b F test/tkt-ba7cbfaedc.test b4c0deccc12aeb55cfdb57935b16b5d67c5a9877 -F test/tkt-bd484a090c.test 60460bf946f79a79712b71f202eda501ca99b898 +F test/tkt-bd484a090c.test e6af3e3a4242cd8f1c91c736364f09075d8e33e3b86f6492a1ee36278ea71b61 F test/tkt-bdc6bbbb38.test fc38bb09bdd440e3513a1f5f98fc60a075182d7d F test/tkt-c48d99d690.test ba61977d62ab612fc515b3c488a6fbd6464a2447 F test/tkt-c694113d5.test 82c461924ada5c14866c47e85535b0b0923ba16a2e907e370061a5ca77f65d77 @@ -1886,7 +1913,7 @@ F test/upfrom2.test 66f3ebf721b3cebd922faee5c386bf244f816d416b57c000753ff51af623 F test/upfrom3.test 6130f24ebf97f5ea865e5d2a14a2d543fe5428a62e87cc60f62d875e45c1f5f0 F test/upfrom4.test 78f742a6577c91a7a55c64edb8811004e7c6aa99b8d57b2320f70a918c357807 F test/upfromfault.test 3a10075a0043f0c4fad6614b2c371f88a8ba5a4acab68b907438413865d6a8d6 -F test/upsert1.test a512e2f884d3a36159fce2e45108c236f78ae38e35bda55f4050db580ceb25d3 +F test/upsert1.test beba4316fbd4b7b9d76784313f6129a548cfe7abea04d46db33e2efce1ab0ac2 F test/upsert2.test 720e94d09f7362a282bc69b3c6b83d51daeaaf0440eb4920a08b86518b8c7496 F test/upsert3.test 88d7d590a1948a9cb6eac1b54b0642f67a9f35a1fc0f19b200e97d5d39e3179c F test/upsert4.test 25d2a1da92f149331ae0c51ca6e3eee78189577585eab92de149900d62994fa5 @@ -1904,9 +1931,11 @@ F test/vacuum4.test 7ea76b769fffeb41f925303b04cbcf5a5bbeabe55e4c60ae754ff24eeeb7 F test/vacuum5.test 263b144d537e92ad8e9ca8a73cc6e1583f41cfd0dda9432b87f7806174a2f48c F test/vacuum6.test b137b04bf3392d3f5c3b8fda0ce85a6775a70ca112f6559f74ff52dc9ce042fd F test/vacuummem.test 4b30f5b95a9ff86e9d5c20741e50a898b2dc10b0962a3211571eb165357003fb +F test/values.test 52102ad9e5068b449429e40a976486a52246041f7cd79d086a2b170e77dec925 +F test/valuesfault.test 2ef23ed965e3bd08e268cdc38a0d11653390ddbbe1e8e2e98d16f55edd30f6e8 F test/varint.test bbce22cda8fc4d135bcc2b589574be8410614e62 F test/veryquick.test 57ab846bacf7b90cf4e9a672721ea5c5b669b661 -F test/view.test d4c4281e1679245829db35597817282f60dc513fc39cc5439078f009bd118487 +F test/view.test 3c23d7a068e9e4a0c4e6907498042772adea725f0630c3d9638ffd4e5a08b92b F test/view2.test db32c8138b5b556f610b35dfddd38c5a58a292f07fda5281eedb0851b2672679 F test/view3.test ad8a8290ee2b55ff6ce66c9ef1ce3f1e47926273a3814e1c425293e128a95456 F test/vt02.c 5b44ac67b1a283fedecf2d6e2ceda61e7a157f01d44dcb4490dcb1e87d057060 @@ -1929,6 +1958,7 @@ F test/vtabH.test 2efb5a24b0bb50796b21eca23032cfb77abfa4b0c03938e38ce5897abac404 F test/vtabI.test 751b07636700dbdea328e4265b6077ccd6811a3f F test/vtabJ.test a6aef49d558af90fae10565b29501f82a95781cb4f797f2d13e2d19f9b6bc77b F test/vtabK.test 13293177528fada1235c0112db0d187d754af1355c5a39371abd365104e3afbf +F test/vtabL.test c7b7f537978005d063fa2f53a3cd5a46ecf651ecd19970cb9ed4203698398deb F test/vtab_alter.test 736e66fb5ec7b4fee58229aa3ada2f27ec58bc58c00edae4836890c3784c6783 F test/vtab_err.test dcc8b7b9cb67522b3fe7a272c73856829dae4ab7fdb30399aea1b6981bda2b65 F test/vtab_shared.test 5253bff2355a9a3f014c15337da7e177ab0ef8ad @@ -1992,8 +2022,9 @@ F test/whereH.test e4b07f7a3c2f5d31195cd33710054c78667573b2 F test/whereI.test c4bb7e2ca56d49bd8ab5c7bd085b8b83e353922b46904d68aefb3c7468643581 F test/whereJ.test fc05e374cc9f2dc204148d6c06822c380ad388895fe97a6d335b94a26a08aecf F test/whereK.test 0270ab7f04ba5436fb9156d31d642a1c82727f4c4bfe5ba90d435c78cf44684a -F test/whereL.test 9d7c8a9f4e5e82d6859e61cf8758c3856c7e0a7fd8be11c92cac8c3ec39228fd +F test/whereL.test 438a397fa883b77bb6361c08a8befa41b52e9cfbe15a2a43715d122f8cfa8649 F test/whereM.test 0dbc9998783458ddcf3cc078ca7c2951d8b2677d472ecf0028f449ed327c0250 +F test/whereN.test 63a3584b71acfb6963416de82f26c6b1644abc5ca6080c76546b9246734c8803 F test/wherefault.test 6cf2a9c5712952d463d3f45ebee7f6caf400984df51a195d884cfb7eb0e837a7 F test/wherelfault.test 9012e4ef5259058b771606616bd007af5d154e64cc25fa9fd4170f6411db44e3 F test/wherelimit.test afb46397c6d7e964e6e294ba3569864a0c570fe3807afc634236c2b752372f31 @@ -2071,8 +2102,8 @@ F tool/genfkey.test b6afd7b825d797a1e1274f519ab5695373552ecad5cd373530c63533638a F tool/getlock.c f4c39b651370156cae979501a7b156bdba50e7ce F tool/index_usage.c f62a0c701b2c7ff2f3e21d206f093c123f222dbf07136a10ffd1ca15a5c706c5 F tool/kvtest-speed.sh 4761a9c4b3530907562314d7757995787f7aef8f -F tool/lemon.c 19e368bc8e97ff4071115119a7911ca3b0c56eba7926d8ada8b4a86fcc69a176 -F tool/lempar.c 57478ea48420da05faa873c6d1616321caa5464644588c97fbe8e0ea04450748 +F tool/lemon.c 2eaee61479f9b97056950741c8f671a13281c819b94246698264a322360319a9 +F tool/lempar.c e6b649778e5c027c8365ff01d7ef39297cd7285fa1f881cce31792689541e79f F tool/libvers.c caafc3b689638a1d88d44bc5f526c2278760d9b9 F tool/loadfts.c c3c64e4d5e90e8ba41159232c2189dba4be7b862 F tool/logest.c c34e5944318415de513d29a6098df247a9618c96d83c38d4abd88641fe46e669 @@ -2084,14 +2115,14 @@ F tool/mkctimec.tcl 060e9785e9503bf51f8b1b11b542bdeef90fd0ceb0738154f6762acec0c6 F tool/mkkeywordhash.c b9faa0ae7e14e4dbbcd951cddd786bf46b8a65bb07b129ba8c0cfade723aaffd F tool/mkmsvcmin.tcl 8897d515ef7f94772322db95a3b6fce6c614d84fe0bdd06ba5a1c786351d5a1d F tool/mkopcodec.tcl 33d20791e191df43209b77d37f0ff0904620b28465cca6990cf8d60da61a07ef -F tool/mkopcodeh.tcl 769d9e6a8b462323150dc13a8539d6064664b72974f7894befe2491cc73e05cd +F tool/mkopcodeh.tcl 2b4e6967a670ef21bf53a164964c35c6163277d002a4c6f56fa231d68c88d023 F tool/mkopts.tcl 680f785fdb09729fd9ac50632413da4eadbdf9071535e3f26d03795828ab07fa F tool/mkpragmatab.tcl 32e359ccb21011958a821955254bd7a5fa7915d01a8c16fed91ffc8b40cb4adf F tool/mkshellc.tcl b7adf08b82de60811d2cb6af05ff59fc17e5cd6f3e98743c14eaaa3f8971fed0 F tool/mksourceid.c 36aa8020014aed0836fd13c51d6dc9219b0df1761d6b5f58ff5b616211b079b9 F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97 F tool/mksqlite3c-noext.tcl 4f7cfef5152b0c91920355cbfc1d608a4ad242cb819f1aea07f6d0274f584a7f -F tool/mksqlite3c.tcl 2c760ab786cb509b47f00c96fea82994866cb99f5e046df81c768288f57897b4 +F tool/mksqlite3c.tcl c6acfdf4e4ef93478ff3ce3cd593e17abb03f446036ce710c3156bcfa18665e0 F tool/mksqlite3h.tcl d391cff7cad0a372ee1406faee9ccc7dad9cb80a0c95cae0f73d10dd26e06762 F tool/mksqlite3internalh.tcl eb994013e833359137eb53a55acdad0b5ae1049b F tool/mktoolzip.tcl c7a9b685f5131d755e7d941cec50cee7f34178b9e34c9a89811eeb08617f8423 @@ -2113,7 +2144,7 @@ F tool/showstat4.c 0682ebea7abf4d3657f53c4a243f2e7eab48eab344ed36a94bb75dcd19a5c F tool/showwal.c 11eca547980a066b081f512636151233350ac679f29ecf4ebfce7f4530230b3d F tool/soak1.tcl 8d407956e1a45b485a8e072470a3e629a27037fe F tool/spaceanal.tcl 70c87c04cfd2e77b3e6f21c33ca768296aa8f67d4ab4874786ac8fbb28433477 -F tool/speed-check.sh 72dc85b2c0484af971ee3e7d10775f72b4e771e27e162c2099b3bf25517c25fb +F tool/speed-check.sh e8d20cc2eb9c85ec1ba562226de144435456dcdff4ee618de49603c6958f6116 F tool/speedtest.tcl 06c76698485ccf597b9e7dbb1ac70706eb873355 F tool/speedtest16.c ecb6542862151c3e6509bbc00509b234562ae81e F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff @@ -2160,10 +2191,11 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 08dd2b927bf8fbda76b4ea07ca1827efa9bb0b68348683abfd19328c117dc405 -R c4d37ec4d4b175414d039c166b6f8ab8 +P 3210e1ca4d0efedf9710c97abd050ba10d3af98cb1f029c26daa84daf42fbc7e +R 03f38bbe86d08cc2accd8330faccbd25 +T +sym-major-release * T +sym-release * -T +sym-version-3.45.3 * +T +sym-version-3.46.0 * U drh -Z 024d96198ee99cc296e773820295fe65 +Z 82f35d0822d1dfbb574e5dd2459b4a36 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 7b96963..7dd5f56 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8653b758870e6ef0c98d46b3ace27849054af85da891eb121e9aaa537f1e8355 +96c92aba00c8375bc32fafcdf12429c58bd8aabfcadab6683e35bbb9cdebf19e diff --git a/src/alter.c b/src/alter.c index ec45e14..c1e0a29 100644 --- a/src/alter.c +++ b/src/alter.c @@ -2262,7 +2262,12 @@ void sqlite3AlterDropColumn(Parse *pParse, SrcList *pSrc, const Token *pName){ if( i==pTab->iPKey ){ sqlite3VdbeAddOp2(v, OP_Null, 0, regOut); }else{ + char aff = pTab->aCol[i].affinity; + if( aff==SQLITE_AFF_REAL ){ + pTab->aCol[i].affinity = SQLITE_AFF_NUMERIC; + } sqlite3ExprCodeGetColumnOfTable(v, pTab, iCur, i, regOut); + pTab->aCol[i].affinity = aff; } nField++; } diff --git a/src/analyze.c b/src/analyze.c index 59e3d98..8c48a8f 100644 --- a/src/analyze.c +++ b/src/analyze.c @@ -872,7 +872,7 @@ static void statGet( if( iVal==2 && p->nRow*10 <= nDistinct*11 ) iVal = 1; sqlite3_str_appendf(&sStat, " %llu", iVal); #ifdef SQLITE_ENABLE_STAT4 - assert( p->current.anEq[i] ); + assert( p->current.anEq[i] || p->nRow==0 ); #endif } sqlite3ResultStrAccum(context, &sStat); @@ -1057,7 +1057,7 @@ static void analyzeOneTable( for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ int nCol; /* Number of columns in pIdx. "N" */ - int addrRewind; /* Address of "OP_Rewind iIdxCur" */ + int addrGotoEnd; /* Address of "OP_Rewind iIdxCur" */ int addrNextRow; /* Address of "next_row:" */ const char *zIdxName; /* Name of the index */ int nColTest; /* Number of columns to test for changes */ @@ -1081,9 +1081,14 @@ static void analyzeOneTable( /* ** Pseudo-code for loop that calls stat_push(): ** - ** Rewind csr - ** if eof(csr) goto end_of_scan; ** regChng = 0 + ** Rewind csr + ** if eof(csr){ + ** stat_init() with count = 0; + ** goto end_of_scan; + ** } + ** count() + ** stat_init() ** goto chng_addr_0; ** ** next_row: @@ -1122,41 +1127,36 @@ static void analyzeOneTable( sqlite3VdbeSetP4KeyInfo(pParse, pIdx); VdbeComment((v, "%s", pIdx->zName)); - /* Invoke the stat_init() function. The arguments are: - ** + /* Implementation of the following: + ** + ** regChng = 0 + ** Rewind csr + ** if eof(csr){ + ** stat_init() with count = 0; + ** goto end_of_scan; + ** } + ** count() + ** stat_init() + ** goto chng_addr_0; + */ + assert( regTemp2==regStat+4 ); + sqlite3VdbeAddOp2(v, OP_Integer, db->nAnalysisLimit, regTemp2); + + /* Arguments to stat_init(): ** (1) the number of columns in the index including the rowid ** (or for a WITHOUT ROWID table, the number of PK columns), ** (2) the number of columns in the key without the rowid/pk - ** (3) estimated number of rows in the index, - */ + ** (3) estimated number of rows in the index. */ sqlite3VdbeAddOp2(v, OP_Integer, nCol, regStat+1); assert( regRowid==regStat+2 ); sqlite3VdbeAddOp2(v, OP_Integer, pIdx->nKeyCol, regRowid); -#ifdef SQLITE_ENABLE_STAT4 - if( OptimizationEnabled(db, SQLITE_Stat4) ){ - sqlite3VdbeAddOp2(v, OP_Count, iIdxCur, regTemp); - addrRewind = sqlite3VdbeAddOp1(v, OP_Rewind, iIdxCur); - VdbeCoverage(v); - }else -#endif - { - addrRewind = sqlite3VdbeAddOp1(v, OP_Rewind, iIdxCur); - VdbeCoverage(v); - sqlite3VdbeAddOp3(v, OP_Count, iIdxCur, regTemp, 1); - } - assert( regTemp2==regStat+4 ); - sqlite3VdbeAddOp2(v, OP_Integer, db->nAnalysisLimit, regTemp2); + sqlite3VdbeAddOp3(v, OP_Count, iIdxCur, regTemp, + OptimizationDisabled(db, SQLITE_Stat4)); sqlite3VdbeAddFunctionCall(pParse, 0, regStat+1, regStat, 4, &statInitFuncdef, 0); + addrGotoEnd = sqlite3VdbeAddOp1(v, OP_Rewind, iIdxCur); + VdbeCoverage(v); - /* Implementation of the following: - ** - ** Rewind csr - ** if eof(csr) goto end_of_scan; - ** regChng = 0 - ** goto next_push_0; - ** - */ sqlite3VdbeAddOp2(v, OP_Integer, 0, regChng); addrNextRow = sqlite3VdbeCurrentAddr(v); @@ -1263,6 +1263,12 @@ static void analyzeOneTable( } /* Add the entry to the stat1 table. */ + if( pIdx->pPartIdxWhere ){ + /* Partial indexes might get a zero-entry in sqlite_stat1. But + ** an empty table is omitted from sqlite_stat1. */ + sqlite3VdbeJumpHere(v, addrGotoEnd); + addrGotoEnd = 0; + } callStatGet(pParse, regStat, STAT_GET_STAT1, regStat1); assert( "BBB"[0]==SQLITE_AFF_TEXT ); sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 3, regTemp, "BBB", 0); @@ -1286,6 +1292,13 @@ static void analyzeOneTable( int addrIsNull; u8 seekOp = HasRowid(pTab) ? OP_NotExists : OP_NotFound; + /* No STAT4 data is generated if the number of rows is zero */ + if( addrGotoEnd==0 ){ + sqlite3VdbeAddOp2(v, OP_Cast, regStat1, SQLITE_AFF_INTEGER); + addrGotoEnd = sqlite3VdbeAddOp1(v, OP_IfNot, regStat1); + VdbeCoverage(v); + } + if( doOnce ){ int mxCol = nCol; Index *pX; @@ -1338,7 +1351,7 @@ static void analyzeOneTable( #endif /* SQLITE_ENABLE_STAT4 */ /* End of analysis */ - sqlite3VdbeJumpHere(v, addrRewind); + if( addrGotoEnd ) sqlite3VdbeJumpHere(v, addrGotoEnd); } diff --git a/src/btree.c b/src/btree.c index 84a70cc..62b8989 100644 --- a/src/btree.c +++ b/src/btree.c @@ -151,8 +151,47 @@ int corruptPageError(int lineno, MemPage *p){ # define SQLITE_CORRUPT_PAGE(pMemPage) SQLITE_CORRUPT_PGNO(pMemPage->pgno) #endif +/* Default value for SHARED_LOCK_TRACE macro if shared-cache is disabled +** or if the lock tracking is disabled. This is always the value for +** release builds. +*/ +#define SHARED_LOCK_TRACE(X,MSG,TAB,TYPE) /*no-op*/ + #ifndef SQLITE_OMIT_SHARED_CACHE +#if 0 +/* ^---- Change to 1 and recompile to enable shared-lock tracing +** for debugging purposes. +** +** Print all shared-cache locks on a BtShared. Debugging use only. +*/ +static void sharedLockTrace( + BtShared *pBt, + const char *zMsg, + int iRoot, + int eLockType +){ + BtLock *pLock; + if( iRoot>0 ){ + printf("%s-%p %u%s:", zMsg, pBt, iRoot, eLockType==READ_LOCK?"R":"W"); + }else{ + printf("%s-%p:", zMsg, pBt); + } + for(pLock=pBt->pLock; pLock; pLock=pLock->pNext){ + printf(" %p/%u%s", pLock->pBtree, pLock->iTable, + pLock->eLock==READ_LOCK ? "R" : "W"); + while( pLock->pNext && pLock->pBtree==pLock->pNext->pBtree ){ + pLock = pLock->pNext; + printf(",%u%s", pLock->iTable, pLock->eLock==READ_LOCK ? "R" : "W"); + } + } + printf("\n"); + fflush(stdout); +} +#undef SHARED_LOCK_TRACE +#define SHARED_LOCK_TRACE(X,MSG,TAB,TYPE) sharedLockTrace(X,MSG,TAB,TYPE) +#endif /* Shared-lock tracing */ + #ifdef SQLITE_DEBUG /* **** This function is only used as part of an assert() statement. *** @@ -229,6 +268,8 @@ static int hasSharedCacheTableLock( iTab = iRoot; } + SHARED_LOCK_TRACE(pBtree->pBt,"hasLock",iRoot,eLockType); + /* Search for the required lock. Either a write-lock on root-page iTab, a ** write-lock on the schema table, or (if the client is reading) a ** read-lock on iTab will suffice. Return 1 if any of these are found. */ @@ -362,6 +403,8 @@ static int setSharedCacheTableLock(Btree *p, Pgno iTable, u8 eLock){ BtLock *pLock = 0; BtLock *pIter; + SHARED_LOCK_TRACE(pBt,"setLock", iTable, eLock); + assert( sqlite3BtreeHoldsMutex(p) ); assert( eLock==READ_LOCK || eLock==WRITE_LOCK ); assert( p->db!=0 ); @@ -429,6 +472,8 @@ static void clearAllSharedCacheTableLocks(Btree *p){ assert( p->sharable || 0==*ppIter ); assert( p->inTrans>0 ); + SHARED_LOCK_TRACE(pBt, "clearAllLocks", 0, 0); + while( *ppIter ){ BtLock *pLock = *ppIter; assert( (pBt->btsFlags & BTS_EXCLUSIVE)==0 || pBt->pWriter==pLock->pBtree ); @@ -467,6 +512,9 @@ static void clearAllSharedCacheTableLocks(Btree *p){ */ static void downgradeAllSharedCacheTableLocks(Btree *p){ BtShared *pBt = p->pBt; + + SHARED_LOCK_TRACE(pBt, "downgradeLocks", 0, 0); + if( pBt->pWriter==p ){ BtLock *pLock; pBt->pWriter = 0; @@ -5080,9 +5128,12 @@ static int accessPayload( if( pCur->aOverflow==0 || nOvfl*(int)sizeof(Pgno) > sqlite3MallocSize(pCur->aOverflow) ){ - Pgno *aNew = (Pgno*)sqlite3Realloc( - pCur->aOverflow, nOvfl*2*sizeof(Pgno) - ); + Pgno *aNew; + if( sqlite3FaultSim(413) ){ + aNew = 0; + }else{ + aNew = (Pgno*)sqlite3Realloc(pCur->aOverflow, nOvfl*2*sizeof(Pgno)); + } if( aNew==0 ){ return SQLITE_NOMEM_BKPT; }else{ @@ -5092,6 +5143,12 @@ static int accessPayload( memset(pCur->aOverflow, 0, nOvfl*sizeof(Pgno)); pCur->curFlags |= BTCF_ValidOvfl; }else{ + /* Sanity check the validity of the overflow page cache */ + assert( pCur->aOverflow[0]==nextPage + || pCur->aOverflow[0]==0 + || CORRUPT_DB ); + assert( pCur->aOverflow[0]!=0 || pCur->aOverflow[offset/ovflSize]==0 ); + /* If the overflow page-list cache has been allocated and the ** entry for the first required overflow page is valid, skip ** directly to it. @@ -5573,6 +5630,23 @@ int sqlite3BtreeFirst(BtCursor *pCur, int *pRes){ return rc; } +#ifdef SQLITE_DEBUG +/* The cursors is CURSOR_VALID and has BTCF_AtLast set. Verify that +** this flags are true for a consistent database. +** +** This routine is is called from within assert() statements only. +** It is an internal verification routine and does not appear in production +** builds. +*/ +static int cursorIsAtLastEntry(BtCursor *pCur){ + int ii; + for(ii=0; ii<pCur->iPage; ii++){ + if( pCur->aiIdx[ii]!=pCur->apPage[ii]->nCell ) return 0; + } + return pCur->ix==pCur->pPage->nCell-1 && pCur->pPage->leaf!=0; +} +#endif + /* Move the cursor to the last entry in the table. Return SQLITE_OK ** on success. Set *pRes to 0 if the cursor actually points to something ** or set *pRes to 1 if the table is empty. @@ -5601,18 +5675,7 @@ int sqlite3BtreeLast(BtCursor *pCur, int *pRes){ /* If the cursor already points to the last entry, this is a no-op. */ if( CURSOR_VALID==pCur->eState && (pCur->curFlags & BTCF_AtLast)!=0 ){ -#ifdef SQLITE_DEBUG - /* This block serves to assert() that the cursor really does point - ** to the last entry in the b-tree. */ - int ii; - for(ii=0; ii<pCur->iPage; ii++){ - assert( pCur->aiIdx[ii]==pCur->apPage[ii]->nCell ); - } - assert( pCur->ix==pCur->pPage->nCell-1 || CORRUPT_DB ); - testcase( pCur->ix!=pCur->pPage->nCell-1 ); - /* ^-- dbsqlfuzz b92b72e4de80b5140c30ab71372ca719b8feb618 */ - assert( pCur->pPage->leaf ); -#endif + assert( cursorIsAtLastEntry(pCur) || CORRUPT_DB ); *pRes = 0; return SQLITE_OK; } @@ -5665,6 +5728,7 @@ int sqlite3BtreeTableMoveto( } if( pCur->info.nKey<intKey ){ if( (pCur->curFlags & BTCF_AtLast)!=0 ){ + assert( cursorIsAtLastEntry(pCur) || CORRUPT_DB ); *pRes = -1; return SQLITE_OK; } @@ -6131,10 +6195,10 @@ i64 sqlite3BtreeRowCountEst(BtCursor *pCur){ assert( cursorOwnsBtShared(pCur) ); assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) ); - /* Currently this interface is only called by the OP_IfSmaller - ** opcode, and it that case the cursor will always be valid and - ** will always point to a leaf node. */ - if( NEVER(pCur->eState!=CURSOR_VALID) ) return -1; + /* Currently this interface is only called by the OP_IfSizeBetween + ** opcode and the OP_Count opcode with P3=1. In either case, + ** the cursor will always be valid unless the btree is empty. */ + if( pCur->eState!=CURSOR_VALID ) return 0; if( NEVER(pCur->pPage->leaf==0) ) return -1; n = pCur->pPage->nCell; @@ -8265,7 +8329,7 @@ static int balance_nonroot( ** table-interior, index-leaf, or index-interior). */ if( pOld->aData[0]!=apOld[0]->aData[0] ){ - rc = SQLITE_CORRUPT_BKPT; + rc = SQLITE_CORRUPT_PAGE(pOld); goto balance_cleanup; } @@ -8289,7 +8353,7 @@ static int balance_nonroot( memset(&b.szCell[b.nCell], 0, sizeof(b.szCell[0])*(limit+pOld->nOverflow)); if( pOld->nOverflow>0 ){ if( NEVER(limit<pOld->aiOvfl[0]) ){ - rc = SQLITE_CORRUPT_BKPT; + rc = SQLITE_CORRUPT_PAGE(pOld); goto balance_cleanup; } limit = pOld->aiOvfl[0]; @@ -8932,7 +8996,7 @@ static int anotherValidCursor(BtCursor *pCur){ && pOther->eState==CURSOR_VALID && pOther->pPage==pCur->pPage ){ - return SQLITE_CORRUPT_BKPT; + return SQLITE_CORRUPT_PAGE(pCur->pPage); } } return SQLITE_OK; @@ -8992,7 +9056,7 @@ static int balance(BtCursor *pCur){ /* The page being written is not a root page, and there is currently ** more than one reference to it. This only happens if the page is one ** of its own ancestor pages. Corruption. */ - rc = SQLITE_CORRUPT_BKPT; + rc = SQLITE_CORRUPT_PAGE(pPage); }else{ MemPage * const pParent = pCur->apPage[iPage-1]; int const iIdx = pCur->aiIdx[iPage-1]; @@ -9156,7 +9220,7 @@ static SQLITE_NOINLINE int btreeOverwriteOverflowCell( rc = btreeGetPage(pBt, ovflPgno, &pPage, 0); if( rc ) return rc; if( sqlite3PagerPageRefcount(pPage->pDbPage)!=1 || pPage->isInit ){ - rc = SQLITE_CORRUPT_BKPT; + rc = SQLITE_CORRUPT_PAGE(pPage); }else{ if( iOffset+ovflPageSize<(u32)nTotal ){ ovflPgno = get4byte(pPage->aData); @@ -9184,7 +9248,7 @@ static int btreeOverwriteCell(BtCursor *pCur, const BtreePayload *pX){ if( pCur->info.pPayload + pCur->info.nLocal > pPage->aDataEnd || pCur->info.pPayload < pPage->aData + pPage->cellOffset ){ - return SQLITE_CORRUPT_BKPT; + return SQLITE_CORRUPT_PAGE(pPage); } if( pCur->info.nLocal==nTotal ){ /* The entire cell is local */ @@ -9265,7 +9329,7 @@ int sqlite3BtreeInsert( ** Which can only happen if the SQLITE_NoSchemaError flag was set when ** the schema was loaded. This cannot be asserted though, as a user might ** set the flag, load the schema, and then unset the flag. */ - return SQLITE_CORRUPT_BKPT; + return SQLITE_CORRUPT_PGNO(pCur->pgnoRoot); } } @@ -9388,7 +9452,7 @@ int sqlite3BtreeInsert( if( pPage->nFree<0 ){ if( NEVER(pCur->eState>CURSOR_INVALID) ){ /* ^^^^^--- due to the moveToRoot() call above */ - rc = SQLITE_CORRUPT_BKPT; + rc = SQLITE_CORRUPT_PAGE(pPage); }else{ rc = btreeComputeFreeSpace(pPage); } @@ -9430,7 +9494,7 @@ int sqlite3BtreeInsert( CellInfo info; assert( idx>=0 ); if( idx>=pPage->nCell ){ - return SQLITE_CORRUPT_BKPT; + return SQLITE_CORRUPT_PAGE(pPage); } rc = sqlite3PagerWrite(pPage->pDbPage); if( rc ){ @@ -9457,10 +9521,10 @@ int sqlite3BtreeInsert( ** necessary to add the PTRMAP_OVERFLOW1 pointer-map entry. */ assert( rc==SQLITE_OK ); /* clearCell never fails when nLocal==nPayload */ if( oldCell < pPage->aData+pPage->hdrOffset+10 ){ - return SQLITE_CORRUPT_BKPT; + return SQLITE_CORRUPT_PAGE(pPage); } if( oldCell+szNew > pPage->aDataEnd ){ - return SQLITE_CORRUPT_BKPT; + return SQLITE_CORRUPT_PAGE(pPage); } memcpy(oldCell, newCell, szNew); return SQLITE_OK; @@ -9562,7 +9626,7 @@ int sqlite3BtreeTransferRow(BtCursor *pDest, BtCursor *pSrc, i64 iKey){ nIn = pSrc->info.nLocal; aIn = pSrc->info.pPayload; if( aIn+nIn>pSrc->pPage->aDataEnd ){ - return SQLITE_CORRUPT_BKPT; + return SQLITE_CORRUPT_PAGE(pSrc->pPage); } nRem = pSrc->info.nPayload; if( nIn==nRem && nIn<pDest->pPage->maxLocal ){ @@ -9587,7 +9651,7 @@ int sqlite3BtreeTransferRow(BtCursor *pDest, BtCursor *pSrc, i64 iKey){ if( nRem>nIn ){ if( aIn+nIn+4>pSrc->pPage->aDataEnd ){ - return SQLITE_CORRUPT_BKPT; + return SQLITE_CORRUPT_PAGE(pSrc->pPage); } ovflIn = get4byte(&pSrc->info.pPayload[nIn]); } @@ -9683,7 +9747,7 @@ int sqlite3BtreeDelete(BtCursor *pCur, u8 flags){ assert( rc!=SQLITE_OK || CORRUPT_DB || pCur->eState==CURSOR_VALID ); if( rc || pCur->eState!=CURSOR_VALID ) return rc; }else{ - return SQLITE_CORRUPT_BKPT; + return SQLITE_CORRUPT_PGNO(pCur->pgnoRoot); } } assert( pCur->eState==CURSOR_VALID ); @@ -9692,14 +9756,14 @@ int sqlite3BtreeDelete(BtCursor *pCur, u8 flags){ iCellIdx = pCur->ix; pPage = pCur->pPage; if( pPage->nCell<=iCellIdx ){ - return SQLITE_CORRUPT_BKPT; + return SQLITE_CORRUPT_PAGE(pPage); } pCell = findCell(pPage, iCellIdx); if( pPage->nFree<0 && btreeComputeFreeSpace(pPage) ){ - return SQLITE_CORRUPT_BKPT; + return SQLITE_CORRUPT_PAGE(pPage); } if( pCell<&pPage->aCellIdx[pPage->nCell] ){ - return SQLITE_CORRUPT_BKPT; + return SQLITE_CORRUPT_PAGE(pPage); } /* If the BTREE_SAVEPOSITION bit is on, then the cursor position must @@ -9790,7 +9854,7 @@ int sqlite3BtreeDelete(BtCursor *pCur, u8 flags){ n = pCur->pPage->pgno; } pCell = findCell(pLeaf, pLeaf->nCell-1); - if( pCell<&pLeaf->aData[4] ) return SQLITE_CORRUPT_BKPT; + if( pCell<&pLeaf->aData[4] ) return SQLITE_CORRUPT_PAGE(pLeaf); nCell = pLeaf->xCellSize(pLeaf, pCell); assert( MX_CELL_SIZE(pBt) >= nCell ); pTmp = pBt->pTmpSpace; @@ -9906,7 +9970,7 @@ static int btreeCreateTable(Btree *p, Pgno *piTable, int createTabFlags){ */ sqlite3BtreeGetMeta(p, BTREE_LARGEST_ROOT_PAGE, &pgnoRoot); if( pgnoRoot>btreePagecount(pBt) ){ - return SQLITE_CORRUPT_BKPT; + return SQLITE_CORRUPT_PGNO(pgnoRoot); } pgnoRoot++; @@ -9954,7 +10018,7 @@ static int btreeCreateTable(Btree *p, Pgno *piTable, int createTabFlags){ } rc = ptrmapGet(pBt, pgnoRoot, &eType, &iPtrPage); if( eType==PTRMAP_ROOTPAGE || eType==PTRMAP_FREEPAGE ){ - rc = SQLITE_CORRUPT_BKPT; + rc = SQLITE_CORRUPT_PGNO(pgnoRoot); } if( rc!=SQLITE_OK ){ releasePage(pRoot); @@ -10044,14 +10108,14 @@ static int clearDatabasePage( assert( sqlite3_mutex_held(pBt->mutex) ); if( pgno>btreePagecount(pBt) ){ - return SQLITE_CORRUPT_BKPT; + return SQLITE_CORRUPT_PGNO(pgno); } rc = getAndInitPage(pBt, pgno, &pPage, 0); if( rc ) return rc; if( (pBt->openFlags & BTREE_SINGLE)==0 && sqlite3PagerPageRefcount(pPage->pDbPage) != (1 + (pgno==1)) ){ - rc = SQLITE_CORRUPT_BKPT; + rc = SQLITE_CORRUPT_PAGE(pPage); goto cleardatabasepage_out; } hdr = pPage->hdrOffset; @@ -10155,7 +10219,7 @@ static int btreeDropTable(Btree *p, Pgno iTable, int *piMoved){ assert( p->inTrans==TRANS_WRITE ); assert( iTable>=2 ); if( iTable>btreePagecount(pBt) ){ - return SQLITE_CORRUPT_BKPT; + return SQLITE_CORRUPT_PGNO(iTable); } rc = sqlite3BtreeClearTable(p, iTable, 0); @@ -10749,6 +10813,9 @@ static int checkTreePage( ** number of cells on the page. */ nCell = get2byte(&data[hdr+3]); assert( pPage->nCell==nCell ); + if( pPage->leaf || pPage->intKey==0 ){ + pCheck->nRow += nCell; + } /* EVIDENCE-OF: R-23882-45353 The cell pointer array of a b-tree page ** immediately follows the b-tree page header. */ @@ -10860,6 +10927,7 @@ static int checkTreePage( btreeHeapInsert(heap, (pc<<16)|(pc+size-1)); } } + assert( heap!=0 ); /* Add the freeblocks to the min-heap ** ** EVIDENCE-OF: R-20690-50594 The second field of the b-tree page header @@ -10959,6 +11027,7 @@ int sqlite3BtreeIntegrityCheck( sqlite3 *db, /* Database connection that is running the check */ Btree *p, /* The btree to be checked */ Pgno *aRoot, /* An array of root pages numbers for individual trees */ + Mem *aCnt, /* Memory cells to write counts for each tree to */ int nRoot, /* Number of entries in aRoot[] */ int mxErr, /* Stop reporting errors after this many */ int *pnErr, /* OUT: Write number of errors seen to this variable */ @@ -10972,7 +11041,9 @@ int sqlite3BtreeIntegrityCheck( int bPartial = 0; /* True if not checking all btrees */ int bCkFreelist = 1; /* True to scan the freelist */ VVA_ONLY( int nRef ); + assert( nRoot>0 ); + assert( aCnt!=0 ); /* aRoot[0]==0 means this is a partial check */ if( aRoot[0]==0 ){ @@ -11045,15 +11116,18 @@ int sqlite3BtreeIntegrityCheck( testcase( pBt->db->flags & SQLITE_CellSizeCk ); pBt->db->flags &= ~(u64)SQLITE_CellSizeCk; for(i=0; (int)i<nRoot && sCheck.mxErr; i++){ - i64 notUsed; - if( aRoot[i]==0 ) continue; + sCheck.nRow = 0; + if( aRoot[i] ){ + i64 notUsed; #ifndef SQLITE_OMIT_AUTOVACUUM - if( pBt->autoVacuum && aRoot[i]>1 && !bPartial ){ - checkPtrmap(&sCheck, aRoot[i], PTRMAP_ROOTPAGE, 0); - } + if( pBt->autoVacuum && aRoot[i]>1 && !bPartial ){ + checkPtrmap(&sCheck, aRoot[i], PTRMAP_ROOTPAGE, 0); + } #endif - sCheck.v0 = aRoot[i]; - checkTreePage(&sCheck, aRoot[i], ¬Used, LARGEST_INT64); + sCheck.v0 = aRoot[i]; + checkTreePage(&sCheck, aRoot[i], ¬Used, LARGEST_INT64); + } + sqlite3MemSetArrayInt64(aCnt, i, sCheck.nRow); } pBt->db->flags = savedDbFlags; diff --git a/src/btree.h b/src/btree.h index b45ace7..9731b8f 100644 --- a/src/btree.h +++ b/src/btree.h @@ -331,6 +331,7 @@ int sqlite3BtreeIntegrityCheck( sqlite3 *db, /* Database connection that is running the check */ Btree *p, /* The btree to be checked */ Pgno *aRoot, /* An array of root pages numbers for individual trees */ + sqlite3_value *aCnt, /* OUT: entry counts for each btree in aRoot[] */ int nRoot, /* Number of entries in aRoot[] */ int mxErr, /* Stop reporting errors after this many */ int *pnErr, /* OUT: Write number of errors seen to this variable */ diff --git a/src/btreeInt.h b/src/btreeInt.h index 67a7db2..1213297 100644 --- a/src/btreeInt.h +++ b/src/btreeInt.h @@ -707,6 +707,7 @@ struct IntegrityCk { StrAccum errMsg; /* Accumulate the error message text here */ u32 *heap; /* Min-heap used for analyzing cell coverage */ sqlite3 *db; /* Database connection running the check */ + i64 nRow; /* Number of rows visited in current tree */ }; /* diff --git a/src/build.c b/src/build.c index 4e46ea0..10aa342 100644 --- a/src/build.c +++ b/src/build.c @@ -189,7 +189,7 @@ void sqlite3FinishCoding(Parse *pParse){ } sqlite3VdbeAddOp0(v, OP_Halt); -#if SQLITE_USER_AUTHENTICATION +#if SQLITE_USER_AUTHENTICATION && !defined(SQLITE_OMIT_SHARED_CACHE) if( pParse->nTableLock>0 && db->init.busy==0 ){ sqlite3UserAuthInit(db); if( db->auth.authLevel<UAUTH_User ){ @@ -2828,20 +2828,20 @@ void sqlite3EndTable( int regRowid; /* Rowid of the next row to insert */ int addrInsLoop; /* Top of the loop for inserting rows */ Table *pSelTab; /* A table that describes the SELECT results */ + int iCsr; /* Write cursor on the new table */ if( IN_SPECIAL_PARSE ){ pParse->rc = SQLITE_ERROR; pParse->nErr++; return; } + iCsr = pParse->nTab++; regYield = ++pParse->nMem; regRec = ++pParse->nMem; regRowid = ++pParse->nMem; - assert(pParse->nTab==1); sqlite3MayAbort(pParse); - sqlite3VdbeAddOp3(v, OP_OpenWrite, 1, pParse->regRoot, iDb); + sqlite3VdbeAddOp3(v, OP_OpenWrite, iCsr, pParse->regRoot, iDb); sqlite3VdbeChangeP5(v, OPFLAG_P2ISREG); - pParse->nTab = 2; addrTop = sqlite3VdbeCurrentAddr(v) + 1; sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, addrTop); if( pParse->nErr ) return; @@ -2862,11 +2862,11 @@ void sqlite3EndTable( VdbeCoverage(v); sqlite3VdbeAddOp3(v, OP_MakeRecord, dest.iSdst, dest.nSdst, regRec); sqlite3TableAffinity(v, p, 0); - sqlite3VdbeAddOp2(v, OP_NewRowid, 1, regRowid); - sqlite3VdbeAddOp3(v, OP_Insert, 1, regRec, regRowid); + sqlite3VdbeAddOp2(v, OP_NewRowid, iCsr, regRowid); + sqlite3VdbeAddOp3(v, OP_Insert, iCsr, regRec, regRowid); sqlite3VdbeGoto(v, addrInsLoop); sqlite3VdbeJumpHere(v, addrInsLoop); - sqlite3VdbeAddOp1(v, OP_Close, 1); + sqlite3VdbeAddOp1(v, OP_Close, iCsr); } /* Compute the complete text of the CREATE statement */ @@ -2923,13 +2923,10 @@ void sqlite3EndTable( /* Test for cycles in generated columns and illegal expressions ** in CHECK constraints and in DEFAULT clauses. */ if( p->tabFlags & TF_HasGenerated ){ - sqlite3VdbeAddOp4(v, OP_SqlExec, 1, 0, 0, + sqlite3VdbeAddOp4(v, OP_SqlExec, 0x0001, 0, 0, sqlite3MPrintf(db, "SELECT*FROM\"%w\".\"%w\"", db->aDb[iDb].zDbSName, p->zName), P4_DYNAMIC); } - sqlite3VdbeAddOp4(v, OP_SqlExec, 1, 0, 0, - sqlite3MPrintf(db, "PRAGMA \"%w\".integrity_check(%Q)", - db->aDb[iDb].zDbSName, p->zName), P4_DYNAMIC); } /* Add the table to the in-memory representation of the database. @@ -71,13 +71,14 @@ struct DateTime { int tz; /* Timezone offset in minutes */ double s; /* Seconds */ char validJD; /* True (1) if iJD is valid */ - char rawS; /* Raw numeric value stored in s */ char validYMD; /* True (1) if Y,M,D are valid */ char validHMS; /* True (1) if h,m,s are valid */ - char validTZ; /* True (1) if tz is valid */ - char tzSet; /* Timezone was set explicitly */ - char isError; /* An overflow has occurred */ - char useSubsec; /* Display subsecond precision */ + char nFloor; /* Days to implement "floor" */ + unsigned rawS : 1; /* Raw numeric value stored in s */ + unsigned isError : 1; /* An overflow has occurred */ + unsigned useSubsec : 1; /* Display subsecond precision */ + unsigned isUtc : 1; /* Time is known to be UTC */ + unsigned isLocal : 1; /* Time is known to be localtime */ }; @@ -175,6 +176,8 @@ static int parseTimezone(const char *zDate, DateTime *p){ sgn = +1; }else if( c=='Z' || c=='z' ){ zDate++; + p->isLocal = 0; + p->isUtc = 1; goto zulu_time; }else{ return c!=0; @@ -187,7 +190,6 @@ static int parseTimezone(const char *zDate, DateTime *p){ p->tz = sgn*(nMn + nHr*60); zulu_time: while( sqlite3Isspace(*zDate) ){ zDate++; } - p->tzSet = 1; return *zDate!=0; } @@ -231,7 +233,6 @@ static int parseHhMmSs(const char *zDate, DateTime *p){ p->m = m; p->s = s + ms; if( parseTimezone(zDate, p) ) return 1; - p->validTZ = (p->tz!=0)?1:0; return 0; } @@ -278,16 +279,41 @@ static void computeJD(DateTime *p){ p->validJD = 1; if( p->validHMS ){ p->iJD += p->h*3600000 + p->m*60000 + (sqlite3_int64)(p->s*1000 + 0.5); - if( p->validTZ ){ + if( p->tz ){ p->iJD -= p->tz*60000; p->validYMD = 0; p->validHMS = 0; - p->validTZ = 0; + p->tz = 0; + p->isUtc = 1; + p->isLocal = 0; } } } /* +** Given the YYYY-MM-DD information current in p, determine if there +** is day-of-month overflow and set nFloor to the number of days that +** would need to be subtracted from the date in order to bring the +** date back to the end of the month. +*/ +static void computeFloor(DateTime *p){ + assert( p->validYMD || p->isError ); + assert( p->D>=0 && p->D<=31 ); + assert( p->M>=0 && p->M<=12 ); + if( p->D<=28 ){ + p->nFloor = 0; + }else if( (1<<p->M) & 0x15aa ){ + p->nFloor = 0; + }else if( p->M!=2 ){ + p->nFloor = (p->D==31); + }else if( p->Y%4!=0 || (p->Y%100==0 && p->Y%400!=0) ){ + p->nFloor = p->D - 28; + }else{ + p->nFloor = p->D - 29; + } +} + +/* ** Parse dates of the form ** ** YYYY-MM-DD HH:MM:SS.FFF @@ -325,12 +351,16 @@ static int parseYyyyMmDd(const char *zDate, DateTime *p){ p->Y = neg ? -Y : Y; p->M = M; p->D = D; - if( p->validTZ ){ + computeFloor(p); + if( p->tz ){ computeJD(p); } return 0; } + +static void clearYMD_HMS_TZ(DateTime *p); /* Forward declaration */ + /* ** Set the time to the current time reported by the VFS. ** @@ -340,6 +370,9 @@ static int setDateTimeToCurrent(sqlite3_context *context, DateTime *p){ p->iJD = sqlite3StmtCurrentTime(context); if( p->iJD>0 ){ p->validJD = 1; + p->isUtc = 1; + p->isLocal = 0; + clearYMD_HMS_TZ(p); return 0; }else{ return 1; @@ -478,7 +511,7 @@ static void computeYMD_HMS(DateTime *p){ static void clearYMD_HMS_TZ(DateTime *p){ p->validYMD = 0; p->validHMS = 0; - p->validTZ = 0; + p->tz = 0; } #ifndef SQLITE_OMIT_LOCALTIME @@ -610,7 +643,7 @@ static int toLocaltime( p->validHMS = 1; p->validJD = 0; p->rawS = 0; - p->validTZ = 0; + p->tz = 0; p->isError = 0; return SQLITE_OK; } @@ -630,12 +663,12 @@ static const struct { float rLimit; /* Maximum NNN value for this transform */ float rXform; /* Constant used for this transform */ } aXformType[] = { - { 6, "second", 4.6427e+14, 1.0 }, - { 6, "minute", 7.7379e+12, 60.0 }, - { 4, "hour", 1.2897e+11, 3600.0 }, - { 3, "day", 5373485.0, 86400.0 }, - { 5, "month", 176546.0, 2592000.0 }, - { 4, "year", 14713.0, 31536000.0 }, + /* 0 */ { 6, "second", 4.6427e+14, 1.0 }, + /* 1 */ { 6, "minute", 7.7379e+12, 60.0 }, + /* 2 */ { 4, "hour", 1.2897e+11, 3600.0 }, + /* 3 */ { 3, "day", 5373485.0, 86400.0 }, + /* 4 */ { 5, "month", 176546.0, 30.0*86400.0 }, + /* 5 */ { 4, "year", 14713.0, 365.0*86400.0 }, }; /* @@ -667,14 +700,20 @@ static void autoAdjustDate(DateTime *p){ ** NNN.NNNN seconds ** NNN months ** NNN years +** +/-YYYY-MM-DD HH:MM:SS.SSS +** ceiling +** floor ** start of month ** start of year ** start of week ** start of day ** weekday N ** unixepoch +** auto ** localtime ** utc +** subsec +** subsecond ** ** Return 0 on success and 1 if there is any kind of error. If the error ** is in a system call (i.e. localtime()), then an error message is written @@ -705,6 +744,37 @@ static int parseModifier( } break; } + case 'c': { + /* + ** ceiling + ** + ** Resolve day-of-month overflow by rolling forward into the next + ** month. As this is the default action, this modifier is really + ** a no-op that is only included for symmetry. See "floor". + */ + if( sqlite3_stricmp(z, "ceiling")==0 ){ + computeJD(p); + clearYMD_HMS_TZ(p); + rc = 0; + p->nFloor = 0; + } + break; + } + case 'f': { + /* + ** floor + ** + ** Resolve day-of-month overflow by rolling back to the end of the + ** previous month. + */ + if( sqlite3_stricmp(z, "floor")==0 ){ + computeJD(p); + p->iJD -= p->nFloor*86400000; + clearYMD_HMS_TZ(p); + rc = 0; + } + break; + } case 'j': { /* ** julianday @@ -731,7 +801,9 @@ static int parseModifier( ** show local time. */ if( sqlite3_stricmp(z, "localtime")==0 && sqlite3NotPureFunc(pCtx) ){ - rc = toLocaltime(p, pCtx); + rc = p->isLocal ? SQLITE_OK : toLocaltime(p, pCtx); + p->isUtc = 0; + p->isLocal = 1; } break; } @@ -756,7 +828,7 @@ static int parseModifier( } #ifndef SQLITE_OMIT_LOCALTIME else if( sqlite3_stricmp(z, "utc")==0 && sqlite3NotPureFunc(pCtx) ){ - if( p->tzSet==0 ){ + if( p->isUtc==0 ){ i64 iOrigJD; /* Original localtime */ i64 iGuess; /* Guess at the corresponding utc time */ int cnt = 0; /* Safety to prevent infinite loop */ @@ -779,7 +851,8 @@ static int parseModifier( memset(p, 0, sizeof(*p)); p->iJD = iGuess; p->validJD = 1; - p->tzSet = 1; + p->isUtc = 1; + p->isLocal = 0; } rc = SQLITE_OK; } @@ -799,7 +872,7 @@ static int parseModifier( && r>=0.0 && r<7.0 && (n=(int)r)==r ){ sqlite3_int64 Z; computeYMD_HMS(p); - p->validTZ = 0; + p->tz = 0; p->validJD = 0; computeJD(p); Z = ((p->iJD + 129600000)/86400000) % 7; @@ -839,7 +912,7 @@ static int parseModifier( p->h = p->m = 0; p->s = 0.0; p->rawS = 0; - p->validTZ = 0; + p->tz = 0; p->validJD = 0; if( sqlite3_stricmp(z,"month")==0 ){ p->D = 1; @@ -910,6 +983,7 @@ static int parseModifier( x = p->M>0 ? (p->M-1)/12 : (p->M-12)/12; p->Y += x; p->M -= x*12; + computeFloor(p); computeJD(p); p->validHMS = 0; p->validYMD = 0; @@ -956,11 +1030,12 @@ static int parseModifier( z += n; while( sqlite3Isspace(*z) ) z++; n = sqlite3Strlen30(z); - if( n>10 || n<3 ) break; + if( n<3 || n>10 ) break; if( sqlite3UpperToLower[(u8)z[n-1]]=='s' ) n--; computeJD(p); assert( rc==1 ); rRounder = r<0 ? -0.5 : +0.5; + p->nFloor = 0; for(i=0; i<ArraySize(aXformType); i++){ if( aXformType[i].nName==n && sqlite3_strnicmp(aXformType[i].zName, z, n)==0 @@ -968,21 +1043,24 @@ static int parseModifier( ){ switch( i ){ case 4: { /* Special processing to add months */ - assert( strcmp(aXformType[i].zName,"month")==0 ); + assert( strcmp(aXformType[4].zName,"month")==0 ); computeYMD_HMS(p); p->M += (int)r; x = p->M>0 ? (p->M-1)/12 : (p->M-12)/12; p->Y += x; p->M -= x*12; + computeFloor(p); p->validJD = 0; r -= (int)r; break; } case 5: { /* Special processing to add years */ int y = (int)r; - assert( strcmp(aXformType[i].zName,"year")==0 ); + assert( strcmp(aXformType[5].zName,"year")==0 ); computeYMD_HMS(p); + assert( p->M>=0 && p->M<=12 ); p->Y += y; + computeFloor(p); p->validJD = 0; r -= (int)r; break; @@ -1237,21 +1315,82 @@ static void dateFunc( } /* +** Compute the number of days after the most recent January 1. +** +** In other words, compute the zero-based day number for the +** current year: +** +** Jan01 = 0, Jan02 = 1, ..., Jan31 = 30, Feb01 = 31, ... +** Dec31 = 364 or 365. +*/ +static int daysAfterJan01(DateTime *pDate){ + DateTime jan01 = *pDate; + assert( jan01.validYMD ); + assert( jan01.validHMS ); + assert( pDate->validJD ); + jan01.validJD = 0; + jan01.M = 1; + jan01.D = 1; + computeJD(&jan01); + return (int)((pDate->iJD-jan01.iJD+43200000)/86400000); +} + +/* +** Return the number of days after the most recent Monday. +** +** In other words, return the day of the week according +** to this code: +** +** 0=Monday, 1=Tuesday, 2=Wednesday, ..., 6=Sunday. +*/ +static int daysAfterMonday(DateTime *pDate){ + assert( pDate->validJD ); + return (int)((pDate->iJD+43200000)/86400000) % 7; +} + +/* +** Return the number of days after the most recent Sunday. +** +** In other words, return the day of the week according +** to this code: +** +** 0=Sunday, 1=Monday, 2=Tues, ..., 6=Saturday +*/ +static int daysAfterSunday(DateTime *pDate){ + assert( pDate->validJD ); + return (int)((pDate->iJD+129600000)/86400000) % 7; +} + +/* ** strftime( FORMAT, TIMESTRING, MOD, MOD, ...) ** ** Return a string described by FORMAT. Conversions as follows: ** -** %d day of month +** %d day of month 01-31 +** %e day of month 1-31 ** %f ** fractional seconds SS.SSS +** %F ISO date. YYYY-MM-DD +** %G ISO year corresponding to %V 0000-9999. +** %g 2-digit ISO year corresponding to %V 00-99 ** %H hour 00-24 -** %j day of year 000-366 +** %k hour 0-24 (leading zero converted to space) +** %I hour 01-12 +** %j day of year 001-366 ** %J ** julian day number +** %l hour 1-12 (leading zero converted to space) ** %m month 01-12 ** %M minute 00-59 +** %p "am" or "pm" +** %P "AM" or "PM" +** %R time as HH:MM ** %s seconds since 1970-01-01 ** %S seconds 00-59 -** %w day of week 0-6 Sunday==0 -** %W week of year 00-53 +** %T time as HH:MM:SS +** %u day of week 1-7 Monday==1, Sunday==7 +** %w day of week 0-6 Sunday==0, Monday==1 +** %U week of year 00-53 (First Sunday is start of week 01) +** %V week of year 01-53 (First week containing Thursday is week 01) +** %W week of year 00-53 (First Monday is start of week 01) ** %Y year 0000-9999 ** %% % */ @@ -1288,7 +1427,7 @@ static void strftimeFunc( sqlite3_str_appendf(&sRes, cf=='d' ? "%02d" : "%2d", x.D); break; } - case 'f': { + case 'f': { /* Fractional seconds. (Non-standard) */ double s = x.s; if( s>59.999 ) s = 59.999; sqlite3_str_appendf(&sRes, "%06.3f", s); @@ -1298,6 +1437,21 @@ static void strftimeFunc( sqlite3_str_appendf(&sRes, "%04d-%02d-%02d", x.Y, x.M, x.D); break; } + case 'G': /* Fall thru */ + case 'g': { + DateTime y = x; + assert( y.validJD ); + /* Move y so that it is the Thursday in the same week as x */ + y.iJD += (3 - daysAfterMonday(&x))*86400000; + y.validYMD = 0; + computeYMD(&y); + if( cf=='g' ){ + sqlite3_str_appendf(&sRes, "%02d", y.Y%100); + }else{ + sqlite3_str_appendf(&sRes, "%04d", y.Y); + } + break; + } case 'H': case 'k': { sqlite3_str_appendf(&sRes, cf=='H' ? "%02d" : "%2d", x.h); @@ -1311,25 +1465,11 @@ static void strftimeFunc( sqlite3_str_appendf(&sRes, cf=='I' ? "%02d" : "%2d", h); break; } - case 'W': /* Fall thru */ - case 'j': { - int nDay; /* Number of days since 1st day of year */ - DateTime y = x; - y.validJD = 0; - y.M = 1; - y.D = 1; - computeJD(&y); - nDay = (int)((x.iJD-y.iJD+43200000)/86400000); - if( cf=='W' ){ - int wd; /* 0=Monday, 1=Tuesday, ... 6=Sunday */ - wd = (int)(((x.iJD+43200000)/86400000)%7); - sqlite3_str_appendf(&sRes,"%02d",(nDay+7-wd)/7); - }else{ - sqlite3_str_appendf(&sRes,"%03d",nDay+1); - } + case 'j': { /* Day of year. Jan01==1, Jan02==2, and so forth */ + sqlite3_str_appendf(&sRes,"%03d",daysAfterJan01(&x)+1); break; } - case 'J': { + case 'J': { /* Julian day number. (Non-standard) */ sqlite3_str_appendf(&sRes,"%.16g",x.iJD/86400000.0); break; } @@ -1372,13 +1512,33 @@ static void strftimeFunc( sqlite3_str_appendf(&sRes,"%02d:%02d:%02d", x.h, x.m, (int)x.s); break; } - case 'u': /* Fall thru */ - case 'w': { - char c = (char)(((x.iJD+129600000)/86400000) % 7) + '0'; + case 'u': /* Day of week. 1 to 7. Monday==1, Sunday==7 */ + case 'w': { /* Day of week. 0 to 6. Sunday==0, Monday==1 */ + char c = (char)daysAfterSunday(&x) + '0'; if( c=='0' && cf=='u' ) c = '7'; sqlite3_str_appendchar(&sRes, 1, c); break; } + case 'U': { /* Week num. 00-53. First Sun of the year is week 01 */ + sqlite3_str_appendf(&sRes,"%02d", + (daysAfterJan01(&x)-daysAfterSunday(&x)+7)/7); + break; + } + case 'V': { /* Week num. 01-53. First week with a Thur is week 01 */ + DateTime y = x; + /* Adjust y so that is the Thursday in the same week as x */ + assert( y.validJD ); + y.iJD += (3 - daysAfterMonday(&x))*86400000; + y.validYMD = 0; + computeYMD(&y); + sqlite3_str_appendf(&sRes,"%02d", daysAfterJan01(&y)/7+1); + break; + } + case 'W': { /* Week num. 00-53. First Mon of the year is week 01 */ + sqlite3_str_appendf(&sRes,"%02d", + (daysAfterJan01(&x)-daysAfterMonday(&x)+7)/7); + break; + } case 'Y': { sqlite3_str_appendf(&sRes,"%04d",x.Y); break; @@ -1525,9 +1685,7 @@ static void timediffFunc( d1.iJD = d2.iJD - d1.iJD; d1.iJD += (u64)1486995408 * (u64)100000; } - d1.validYMD = 0; - d1.validHMS = 0; - d1.validTZ = 0; + clearYMD_HMS_TZ(&d1); computeYMD_HMS(&d1); sqlite3StrAccumInit(&sRes, 0, 0, 0, 100); sqlite3_str_appendf(&sRes, "%c%04d-%02d-%02d %02d:%02d:%06.3f", @@ -1596,6 +1754,36 @@ static void currentTimeFunc( } #endif +#if !defined(SQLITE_OMIT_DATETIME_FUNCS) && defined(SQLITE_DEBUG) +/* +** datedebug(...) +** +** This routine returns JSON that describes the internal DateTime object. +** Used for debugging and testing only. Subject to change. +*/ +static void datedebugFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + DateTime x; + if( isDate(context, argc, argv, &x)==0 ){ + char *zJson; + zJson = sqlite3_mprintf( + "{iJD:%lld,Y:%d,M:%d,D:%d,h:%d,m:%d,tz:%d," + "s:%.3f,validJD:%d,validYMS:%d,validHMS:%d," + "nFloor:%d,rawS:%d,isError:%d,useSubsec:%d," + "isUtc:%d,isLocal:%d}", + x.iJD, x.Y, x.M, x.D, x.h, x.m, x.tz, + x.s, x.validJD, x.validYMD, x.validHMS, + x.nFloor, x.rawS, x.isError, x.useSubsec, + x.isUtc, x.isLocal); + sqlite3_result_text(context, zJson, -1, sqlite3_free); + } +} +#endif /* !SQLITE_OMIT_DATETIME_FUNCS && SQLITE_DEBUG */ + + /* ** This function registered all of the above C functions as SQL ** functions. This should be the only routine in this file with @@ -1611,6 +1799,9 @@ void sqlite3RegisterDateTimeFunctions(void){ PURE_DATE(datetime, -1, 0, 0, datetimeFunc ), PURE_DATE(strftime, -1, 0, 0, strftimeFunc ), PURE_DATE(timediff, 2, 0, 0, timediffFunc ), +#ifdef SQLITE_DEBUG + PURE_DATE(datedebug, -1, 0, 0, datedebugFunc ), +#endif DFUNCTION(current_time, 0, 0, 0, ctimeFunc ), DFUNCTION(current_timestamp, 0, 0, 0, ctimestampFunc), DFUNCTION(current_date, 0, 0, 0, cdateFunc ), @@ -915,11 +915,12 @@ void sqlite3ExprSetErrorOffset(Expr *pExpr, int iOfst){ ** appear to be quoted. If the quotes were of the form "..." (double-quotes) ** then the EP_DblQuoted flag is set on the expression node. ** -** Special case: If op==TK_INTEGER and pToken points to a string that -** can be translated into a 32-bit integer, then the token is not -** stored in u.zToken. Instead, the integer values is written -** into u.iValue and the EP_IntValue flag is set. No extra storage +** Special case (tag-20240227-a): If op==TK_INTEGER and pToken points to +** a string that can be translated into a 32-bit integer, then the token is +** not stored in u.zToken. Instead, the integer values is written +** into u.iValue and the EP_IntValue flag is set. No extra storage ** is allocated to hold the integer text and the dequote flag is ignored. +** See also tag-20240227-b. */ Expr *sqlite3ExprAlloc( sqlite3 *db, /* Handle for sqlite3DbMallocRawNN() */ @@ -935,7 +936,7 @@ Expr *sqlite3ExprAlloc( if( pToken ){ if( op!=TK_INTEGER || pToken->z==0 || sqlite3GetInt32(pToken->z, &iValue)==0 ){ - nExtra = pToken->n+1; + nExtra = pToken->n+1; /* tag-20240227-a */ assert( iValue>=0 ); } } @@ -1367,6 +1368,7 @@ void sqlite3ExprAssignVarNumber(Parse *pParse, Expr *pExpr, u32 n){ static SQLITE_NOINLINE void sqlite3ExprDeleteNN(sqlite3 *db, Expr *p){ assert( p!=0 ); assert( db!=0 ); +exprDeleteRestart: assert( !ExprUseUValue(p) || p->u.iValue>=0 ); assert( !ExprUseYWin(p) || !ExprUseYSub(p) ); assert( !ExprUseYWin(p) || p->y.pWin!=0 || db->mallocFailed ); @@ -1382,7 +1384,6 @@ static SQLITE_NOINLINE void sqlite3ExprDeleteNN(sqlite3 *db, Expr *p){ if( !ExprHasProperty(p, (EP_TokenOnly|EP_Leaf)) ){ /* The Expr.x union is never used at the same time as Expr.pRight */ assert( (ExprUseXList(p) && p->x.pList==0) || p->pRight==0 ); - if( p->pLeft && p->op!=TK_SELECT_COLUMN ) sqlite3ExprDeleteNN(db, p->pLeft); if( p->pRight ){ assert( !ExprHasProperty(p, EP_WinFunc) ); sqlite3ExprDeleteNN(db, p->pRight); @@ -1397,6 +1398,19 @@ static SQLITE_NOINLINE void sqlite3ExprDeleteNN(sqlite3 *db, Expr *p){ } #endif } + if( p->pLeft && p->op!=TK_SELECT_COLUMN ){ + Expr *pLeft = p->pLeft; + if( !ExprHasProperty(p, EP_Static) + && !ExprHasProperty(pLeft, EP_Static) + ){ + /* Avoid unnecessary recursion on unary operators */ + sqlite3DbNNFreeNN(db, p); + p = pLeft; + goto exprDeleteRestart; + }else{ + sqlite3ExprDeleteNN(db, pLeft); + } + } } if( !ExprHasProperty(p, EP_Static) ){ sqlite3DbNNFreeNN(db, p); @@ -1429,11 +1443,11 @@ void sqlite3ClearOnOrUsing(sqlite3 *db, OnOrUsing *p){ ** ** The pExpr might be deleted immediately on an OOM error. ** -** The deferred delete is (currently) implemented by adding the -** pExpr to the pParse->pConstExpr list with a register number of 0. +** Return 0 if the delete was successfully deferred. Return non-zero +** if the delete happened immediately because of an OOM. */ -void sqlite3ExprDeferredDelete(Parse *pParse, Expr *pExpr){ - sqlite3ParserAddCleanup(pParse, sqlite3ExprDeleteGeneric, pExpr); +int sqlite3ExprDeferredDelete(Parse *pParse, Expr *pExpr){ + return 0==sqlite3ParserAddCleanup(pParse, sqlite3ExprDeleteGeneric, pExpr); } /* Invoke sqlite3RenameExprUnmap() and sqlite3ExprDelete() on the @@ -1869,17 +1883,19 @@ SrcList *sqlite3SrcListDup(sqlite3 *db, const SrcList *p, int flags){ pNewItem->iCursor = pOldItem->iCursor; pNewItem->addrFillSub = pOldItem->addrFillSub; pNewItem->regReturn = pOldItem->regReturn; + pNewItem->regResult = pOldItem->regResult; if( pNewItem->fg.isIndexedBy ){ pNewItem->u1.zIndexedBy = sqlite3DbStrDup(db, pOldItem->u1.zIndexedBy); + }else if( pNewItem->fg.isTabFunc ){ + pNewItem->u1.pFuncArg = + sqlite3ExprListDup(db, pOldItem->u1.pFuncArg, flags); + }else{ + pNewItem->u1.nRow = pOldItem->u1.nRow; } pNewItem->u2 = pOldItem->u2; if( pNewItem->fg.isCte ){ pNewItem->u2.pCteUse->nUse++; } - if( pNewItem->fg.isTabFunc ){ - pNewItem->u1.pFuncArg = - sqlite3ExprListDup(db, pOldItem->u1.pFuncArg, flags); - } pTab = pNewItem->pTab = pOldItem->pTab; if( pTab ){ pTab->nTabRef++; @@ -2345,6 +2361,54 @@ Expr *sqlite3ExprSimplifiedAndOr(Expr *pExpr){ return pExpr; } +/* +** pExpr is a TK_FUNCTION node. Try to determine whether or not the +** function is a constant function. A function is constant if all of +** the following are true: +** +** (1) It is a scalar function (not an aggregate or window function) +** (2) It has either the SQLITE_FUNC_CONSTANT or SQLITE_FUNC_SLOCHNG +** property. +** (3) All of its arguments are constants +** +** This routine sets pWalker->eCode to 0 if pExpr is not a constant. +** It makes no changes to pWalker->eCode if pExpr is constant. In +** every case, it returns WRC_Abort. +** +** Called as a service subroutine from exprNodeIsConstant(). +*/ +static SQLITE_NOINLINE int exprNodeIsConstantFunction( + Walker *pWalker, + Expr *pExpr +){ + int n; /* Number of arguments */ + ExprList *pList; /* List of arguments */ + FuncDef *pDef; /* The function */ + sqlite3 *db; /* The database */ + + assert( pExpr->op==TK_FUNCTION ); + if( ExprHasProperty(pExpr, EP_TokenOnly) + || (pList = pExpr->x.pList)==0 + ){; + n = 0; + }else{ + n = pList->nExpr; + sqlite3WalkExprList(pWalker, pList); + if( pWalker->eCode==0 ) return WRC_Abort; + } + db = pWalker->pParse->db; + pDef = sqlite3FindFunction(db, pExpr->u.zToken, n, ENC(db), 0); + if( pDef==0 + || pDef->xFinalize!=0 + || (pDef->funcFlags & (SQLITE_FUNC_CONSTANT|SQLITE_FUNC_SLOCHNG))==0 + || ExprHasProperty(pExpr, EP_WinFunc) + ){ + pWalker->eCode = 0; + return WRC_Abort; + } + return WRC_Prune; +} + /* ** These routines are Walker callbacks used to check expressions to @@ -2373,6 +2437,7 @@ Expr *sqlite3ExprSimplifiedAndOr(Expr *pExpr){ ** malformed schema error. */ static int exprNodeIsConstant(Walker *pWalker, Expr *pExpr){ + assert( pWalker->eCode>0 ); /* If pWalker->eCode is 2 then any term of the expression that comes from ** the ON or USING clauses of an outer join disqualifies the expression @@ -2392,6 +2457,8 @@ static int exprNodeIsConstant(Walker *pWalker, Expr *pExpr){ ){ if( pWalker->eCode==5 ) ExprSetProperty(pExpr, EP_FromDDL); return WRC_Continue; + }else if( pWalker->pParse ){ + return exprNodeIsConstantFunction(pWalker, pExpr); }else{ pWalker->eCode = 0; return WRC_Abort; @@ -2420,9 +2487,11 @@ static int exprNodeIsConstant(Walker *pWalker, Expr *pExpr){ case TK_IF_NULL_ROW: case TK_REGISTER: case TK_DOT: + case TK_RAISE: testcase( pExpr->op==TK_REGISTER ); testcase( pExpr->op==TK_IF_NULL_ROW ); testcase( pExpr->op==TK_DOT ); + testcase( pExpr->op==TK_RAISE ); pWalker->eCode = 0; return WRC_Abort; case TK_VARIABLE: @@ -2444,15 +2513,15 @@ static int exprNodeIsConstant(Walker *pWalker, Expr *pExpr){ return WRC_Continue; } } -static int exprIsConst(Expr *p, int initFlag, int iCur){ +static int exprIsConst(Parse *pParse, Expr *p, int initFlag){ Walker w; w.eCode = initFlag; + w.pParse = pParse; w.xExprCallback = exprNodeIsConstant; w.xSelectCallback = sqlite3SelectWalkFail; #ifdef SQLITE_DEBUG w.xSelectCallback2 = sqlite3SelectWalkAssert2; #endif - w.u.iCur = iCur; sqlite3WalkExpr(&w, p); return w.eCode; } @@ -2464,9 +2533,15 @@ static int exprIsConst(Expr *p, int initFlag, int iCur){ ** For the purposes of this function, a double-quoted string (ex: "abc") ** is considered a variable but a single-quoted string (ex: 'abc') is ** a constant. +** +** The pParse parameter may be NULL. But if it is NULL, there is no way +** to determine if function calls are constant or not, and hence all +** function calls will be considered to be non-constant. If pParse is +** not NULL, then a function call might be constant, depending on the +** function and on its parameters. */ -int sqlite3ExprIsConstant(Expr *p){ - return exprIsConst(p, 1, 0); +int sqlite3ExprIsConstant(Parse *pParse, Expr *p){ + return exprIsConst(pParse, p, 1); } /* @@ -2482,8 +2557,24 @@ int sqlite3ExprIsConstant(Expr *p){ ** can be added to the pParse->pConstExpr list and evaluated once when ** the prepared statement starts up. See sqlite3ExprCodeRunJustOnce(). */ -int sqlite3ExprIsConstantNotJoin(Expr *p){ - return exprIsConst(p, 2, 0); +static int sqlite3ExprIsConstantNotJoin(Parse *pParse, Expr *p){ + return exprIsConst(pParse, p, 2); +} + +/* +** This routine examines sub-SELECT statements as an expression is being +** walked as part of sqlite3ExprIsTableConstant(). Sub-SELECTs are considered +** constant as long as they are uncorrelated - meaning that they do not +** contain any terms from outer contexts. +*/ +static int exprSelectWalkTableConstant(Walker *pWalker, Select *pSelect){ + assert( pSelect!=0 ); + assert( pWalker->eCode==3 || pWalker->eCode==0 ); + if( (pSelect->selFlags & SF_Correlated)!=0 ){ + pWalker->eCode = 0; + return WRC_Abort; + } + return WRC_Prune; } /* @@ -2491,9 +2582,26 @@ int sqlite3ExprIsConstantNotJoin(Expr *p){ ** for any single row of the table with cursor iCur. In other words, the ** expression must not refer to any non-deterministic function nor any ** table other than iCur. +** +** Consider uncorrelated subqueries to be constants if the bAllowSubq +** parameter is true. */ -int sqlite3ExprIsTableConstant(Expr *p, int iCur){ - return exprIsConst(p, 3, iCur); +static int sqlite3ExprIsTableConstant(Expr *p, int iCur, int bAllowSubq){ + Walker w; + w.eCode = 3; + w.pParse = 0; + w.xExprCallback = exprNodeIsConstant; + if( bAllowSubq ){ + w.xSelectCallback = exprSelectWalkTableConstant; + }else{ + w.xSelectCallback = sqlite3SelectWalkFail; +#ifdef SQLITE_DEBUG + w.xSelectCallback2 = sqlite3SelectWalkAssert2; +#endif + } + w.u.iCur = iCur; + sqlite3WalkExpr(&w, p); + return w.eCode; } /* @@ -2511,7 +2619,10 @@ int sqlite3ExprIsTableConstant(Expr *p, int iCur){ ** ** (1) pExpr cannot refer to any table other than pSrc->iCursor. ** -** (2) pExpr cannot use subqueries or non-deterministic functions. +** (2a) pExpr cannot use subqueries unless the bAllowSubq parameter is +** true and the subquery is non-correlated +** +** (2b) pExpr cannot use non-deterministic functions. ** ** (3) pSrc cannot be part of the left operand for a RIGHT JOIN. ** (Is there some way to relax this constraint?) @@ -2540,7 +2651,8 @@ int sqlite3ExprIsTableConstant(Expr *p, int iCur){ int sqlite3ExprIsSingleTableConstraint( Expr *pExpr, /* The constraint */ const SrcList *pSrcList, /* Complete FROM clause */ - int iSrc /* Which element of pSrcList to use */ + int iSrc, /* Which element of pSrcList to use */ + int bAllowSubq /* Allow non-correlated subqueries */ ){ const SrcItem *pSrc = &pSrcList->a[iSrc]; if( pSrc->fg.jointype & JT_LTORJ ){ @@ -2565,7 +2677,8 @@ int sqlite3ExprIsSingleTableConstraint( } } } - return sqlite3ExprIsTableConstant(pExpr, pSrc->iCursor); /* rules (1), (2) */ + /* Rules (1), (2a), and (2b) handled by the following: */ + return sqlite3ExprIsTableConstant(pExpr, pSrc->iCursor, bAllowSubq); } @@ -2650,7 +2763,7 @@ int sqlite3ExprIsConstantOrGroupBy(Parse *pParse, Expr *p, ExprList *pGroupBy){ */ int sqlite3ExprIsConstantOrFunction(Expr *p, u8 isInit){ assert( isInit==0 || isInit==1 ); - return exprIsConst(p, 4+isInit, 0); + return exprIsConst(0, p, 4+isInit); } #ifdef SQLITE_ENABLE_CURSOR_HINTS @@ -2898,13 +3011,13 @@ static void sqlite3SetHasNullFlag(Vdbe *v, int iCur, int regHasNull){ ** The argument is an IN operator with a list (not a subquery) on the ** right-hand side. Return TRUE if that list is constant. */ -static int sqlite3InRhsIsConstant(Expr *pIn){ +static int sqlite3InRhsIsConstant(Parse *pParse, Expr *pIn){ Expr *pLHS; int res; assert( !ExprHasProperty(pIn, EP_xIsSelect) ); pLHS = pIn->pLeft; pIn->pLeft = 0; - res = sqlite3ExprIsConstant(pIn); + res = sqlite3ExprIsConstant(pParse, pIn); pIn->pLeft = pLHS; return res; } @@ -3173,7 +3286,7 @@ int sqlite3FindInIndex( if( eType==0 && (inFlags & IN_INDEX_NOOP_OK) && ExprUseXList(pX) - && (!sqlite3InRhsIsConstant(pX) || pX->x.pList->nExpr<=2) + && (!sqlite3InRhsIsConstant(pParse,pX) || pX->x.pList->nExpr<=2) ){ pParse->nTab--; /* Back out the allocation of the unused cursor */ iTab = -1; /* Cursor is not allocated */ @@ -3456,7 +3569,7 @@ void sqlite3CodeRhsOfIN( ** this code only executes once. Because for a non-constant ** expression we need to rerun this code each time. */ - if( addrOnce && !sqlite3ExprIsConstant(pE2) ){ + if( addrOnce && !sqlite3ExprIsConstant(pParse, pE2) ){ sqlite3VdbeChangeToNoop(v, addrOnce-1); sqlite3VdbeChangeToNoop(v, addrOnce); ExprClearProperty(pExpr, EP_Subrtn); @@ -4620,12 +4733,6 @@ expr_code_doover: assert( pExpr->u.zToken!=0 ); assert( pExpr->u.zToken[0]!=0 ); sqlite3VdbeAddOp2(v, OP_Variable, pExpr->iColumn, target); - if( pExpr->u.zToken[1]!=0 ){ - const char *z = sqlite3VListNumToName(pParse->pVList, pExpr->iColumn); - assert( pExpr->u.zToken[0]=='?' || (z && !strcmp(pExpr->u.zToken, z)) ); - pParse->pVList[0] = 0; /* Indicate VList may no longer be enlarged */ - sqlite3VdbeAppendP4(v, (char*)z, P4_STATIC); - } return target; } case TK_REGISTER: { @@ -4799,7 +4906,9 @@ expr_code_doover: } #endif - if( ConstFactorOk(pParse) && sqlite3ExprIsConstantNotJoin(pExpr) ){ + if( ConstFactorOk(pParse) + && sqlite3ExprIsConstantNotJoin(pParse,pExpr) + ){ /* SQL functions can be expensive. So try to avoid running them ** multiple times if we know they always give the same result */ return sqlite3ExprCodeRunJustOnce(pParse, pExpr, -1); @@ -4830,7 +4939,7 @@ expr_code_doover: } for(i=0; i<nFarg; i++){ - if( i<32 && sqlite3ExprIsConstant(pFarg->a[i].pExpr) ){ + if( i<32 && sqlite3ExprIsConstant(pParse, pFarg->a[i].pExpr) ){ testcase( i==31 ); constMask |= MASKBIT32(i); } @@ -4972,8 +5081,9 @@ expr_code_doover: if( !ExprHasProperty(pExpr, EP_Collate) ){ /* A TK_COLLATE Expr node without the EP_Collate tag is a so-called ** "SOFT-COLLATE" that is added to constraints that are pushed down - ** from outer queries into sub-queries by the push-down optimization. - ** Clear subtypes as subtypes may not cross a subquery boundary. + ** from outer queries into sub-queries by the WHERE-clause push-down + ** optimization. Clear subtypes as subtypes may not cross a subquery + ** boundary. */ assert( pExpr->pLeft ); sqlite3ExprCode(pParse, pExpr->pLeft, target); @@ -5297,7 +5407,7 @@ int sqlite3ExprCodeTemp(Parse *pParse, Expr *pExpr, int *pReg){ if( ConstFactorOk(pParse) && ALWAYS(pExpr!=0) && pExpr->op!=TK_REGISTER - && sqlite3ExprIsConstantNotJoin(pExpr) + && sqlite3ExprIsConstantNotJoin(pParse, pExpr) ){ *pReg = 0; r2 = sqlite3ExprCodeRunJustOnce(pParse, pExpr, -1); @@ -5361,7 +5471,7 @@ void sqlite3ExprCodeCopy(Parse *pParse, Expr *pExpr, int target){ ** might choose to code the expression at initialization time. */ void sqlite3ExprCodeFactorable(Parse *pParse, Expr *pExpr, int target){ - if( pParse->okConstFactor && sqlite3ExprIsConstantNotJoin(pExpr) ){ + if( pParse->okConstFactor && sqlite3ExprIsConstantNotJoin(pParse,pExpr) ){ sqlite3ExprCodeRunJustOnce(pParse, pExpr, target); }else{ sqlite3ExprCodeCopy(pParse, pExpr, target); @@ -5420,7 +5530,7 @@ int sqlite3ExprCodeExprList( sqlite3VdbeAddOp2(v, copyOp, j+srcReg-1, target+i); } }else if( (flags & SQLITE_ECEL_FACTOR)!=0 - && sqlite3ExprIsConstantNotJoin(pExpr) + && sqlite3ExprIsConstantNotJoin(pParse,pExpr) ){ sqlite3ExprCodeRunJustOnce(pParse, pExpr, target+i); }else{ @@ -6571,9 +6681,8 @@ static int agginfoPersistExprCb(Walker *pWalker, Expr *pExpr){ && pAggInfo->aCol[iAgg].pCExpr==pExpr ){ pExpr = sqlite3ExprDup(db, pExpr, 0); - if( pExpr ){ + if( pExpr && !sqlite3ExprDeferredDelete(pParse, pExpr) ){ pAggInfo->aCol[iAgg].pCExpr = pExpr; - sqlite3ExprDeferredDelete(pParse, pExpr); } } }else{ @@ -6582,9 +6691,8 @@ static int agginfoPersistExprCb(Walker *pWalker, Expr *pExpr){ && pAggInfo->aFunc[iAgg].pFExpr==pExpr ){ pExpr = sqlite3ExprDup(db, pExpr, 0); - if( pExpr ){ + if( pExpr && !sqlite3ExprDeferredDelete(pParse, pExpr) ){ pAggInfo->aFunc[iAgg].pFExpr = pExpr; - sqlite3ExprDeferredDelete(pParse, pExpr); } } } diff --git a/src/insert.c b/src/insert.c index c2c2f7c..072386e 100644 --- a/src/insert.c +++ b/src/insert.c @@ -577,6 +577,195 @@ void sqlite3AutoincrementEnd(Parse *pParse){ # define autoIncStep(A,B,C) #endif /* SQLITE_OMIT_AUTOINCREMENT */ +/* +** If argument pVal is a Select object returned by an sqlite3MultiValues() +** that was able to use the co-routine optimization, finish coding the +** co-routine. +*/ +void sqlite3MultiValuesEnd(Parse *pParse, Select *pVal){ + if( ALWAYS(pVal) && pVal->pSrc->nSrc>0 ){ + SrcItem *pItem = &pVal->pSrc->a[0]; + sqlite3VdbeEndCoroutine(pParse->pVdbe, pItem->regReturn); + sqlite3VdbeJumpHere(pParse->pVdbe, pItem->addrFillSub - 1); + } +} + +/* +** Return true if all expressions in the expression-list passed as the +** only argument are constant. +*/ +static int exprListIsConstant(Parse *pParse, ExprList *pRow){ + int ii; + for(ii=0; ii<pRow->nExpr; ii++){ + if( 0==sqlite3ExprIsConstant(pParse, pRow->a[ii].pExpr) ) return 0; + } + return 1; +} + +/* +** Return true if all expressions in the expression-list passed as the +** only argument are both constant and have no affinity. +*/ +static int exprListIsNoAffinity(Parse *pParse, ExprList *pRow){ + int ii; + if( exprListIsConstant(pParse,pRow)==0 ) return 0; + for(ii=0; ii<pRow->nExpr; ii++){ + Expr *pExpr = pRow->a[ii].pExpr; + assert( pExpr->op!=TK_RAISE ); + assert( pExpr->affExpr==0 ); + if( 0!=sqlite3ExprAffinity(pExpr) ) return 0; + } + return 1; + +} + +/* +** This function is called by the parser for the second and subsequent +** rows of a multi-row VALUES clause. Argument pLeft is the part of +** the VALUES clause already parsed, argument pRow is the vector of values +** for the new row. The Select object returned represents the complete +** VALUES clause, including the new row. +** +** There are two ways in which this may be achieved - by incremental +** coding of a co-routine (the "co-routine" method) or by returning a +** Select object equivalent to the following (the "UNION ALL" method): +** +** "pLeft UNION ALL SELECT pRow" +** +** If the VALUES clause contains a lot of rows, this compound Select +** object may consume a lot of memory. +** +** When the co-routine method is used, each row that will be returned +** by the VALUES clause is coded into part of a co-routine as it is +** passed to this function. The returned Select object is equivalent to: +** +** SELECT * FROM ( +** Select object to read co-routine +** ) +** +** The co-routine method is used in most cases. Exceptions are: +** +** a) If the current statement has a WITH clause. This is to avoid +** statements like: +** +** WITH cte AS ( VALUES('x'), ('y') ... ) +** SELECT * FROM cte AS a, cte AS b; +** +** This will not work, as the co-routine uses a hard-coded register +** for its OP_Yield instructions, and so it is not possible for two +** cursors to iterate through it concurrently. +** +** b) The schema is currently being parsed (i.e. the VALUES clause is part +** of a schema item like a VIEW or TRIGGER). In this case there is no VM +** being generated when parsing is taking place, and so generating +** a co-routine is not possible. +** +** c) There are non-constant expressions in the VALUES clause (e.g. +** the VALUES clause is part of a correlated sub-query). +** +** d) One or more of the values in the first row of the VALUES clause +** has an affinity (i.e. is a CAST expression). This causes problems +** because the complex rules SQLite uses (see function +** sqlite3SubqueryColumnTypes() in select.c) to determine the effective +** affinity of such a column for all rows require access to all values in +** the column simultaneously. +*/ +Select *sqlite3MultiValues(Parse *pParse, Select *pLeft, ExprList *pRow){ + + if( pParse->bHasWith /* condition (a) above */ + || pParse->db->init.busy /* condition (b) above */ + || exprListIsConstant(pParse,pRow)==0 /* condition (c) above */ + || (pLeft->pSrc->nSrc==0 && + exprListIsNoAffinity(pParse,pLeft->pEList)==0) /* condition (d) above */ + || IN_SPECIAL_PARSE + ){ + /* The co-routine method cannot be used. Fall back to UNION ALL. */ + Select *pSelect = 0; + int f = SF_Values | SF_MultiValue; + if( pLeft->pSrc->nSrc ){ + sqlite3MultiValuesEnd(pParse, pLeft); + f = SF_Values; + }else if( pLeft->pPrior ){ + /* In this case set the SF_MultiValue flag only if it was set on pLeft */ + f = (f & pLeft->selFlags); + } + pSelect = sqlite3SelectNew(pParse, pRow, 0, 0, 0, 0, 0, f, 0); + pLeft->selFlags &= ~SF_MultiValue; + if( pSelect ){ + pSelect->op = TK_ALL; + pSelect->pPrior = pLeft; + pLeft = pSelect; + } + }else{ + SrcItem *p = 0; /* SrcItem that reads from co-routine */ + + if( pLeft->pSrc->nSrc==0 ){ + /* Co-routine has not yet been started and the special Select object + ** that accesses the co-routine has not yet been created. This block + ** does both those things. */ + Vdbe *v = sqlite3GetVdbe(pParse); + Select *pRet = sqlite3SelectNew(pParse, 0, 0, 0, 0, 0, 0, 0, 0); + + /* Ensure the database schema has been read. This is to ensure we have + ** the correct text encoding. */ + if( (pParse->db->mDbFlags & DBFLAG_SchemaKnownOk)==0 ){ + sqlite3ReadSchema(pParse); + } + + if( pRet ){ + SelectDest dest; + pRet->pSrc->nSrc = 1; + pRet->pPrior = pLeft->pPrior; + pRet->op = pLeft->op; + pLeft->pPrior = 0; + pLeft->op = TK_SELECT; + assert( pLeft->pNext==0 ); + assert( pRet->pNext==0 ); + p = &pRet->pSrc->a[0]; + p->pSelect = pLeft; + p->fg.viaCoroutine = 1; + p->addrFillSub = sqlite3VdbeCurrentAddr(v) + 1; + p->regReturn = ++pParse->nMem; + p->iCursor = -1; + p->u1.nRow = 2; + sqlite3VdbeAddOp3(v,OP_InitCoroutine,p->regReturn,0,p->addrFillSub); + sqlite3SelectDestInit(&dest, SRT_Coroutine, p->regReturn); + + /* Allocate registers for the output of the co-routine. Do so so + ** that there are two unused registers immediately before those + ** used by the co-routine. This allows the code in sqlite3Insert() + ** to use these registers directly, instead of copying the output + ** of the co-routine to a separate array for processing. */ + dest.iSdst = pParse->nMem + 3; + dest.nSdst = pLeft->pEList->nExpr; + pParse->nMem += 2 + dest.nSdst; + + pLeft->selFlags |= SF_MultiValue; + sqlite3Select(pParse, pLeft, &dest); + p->regResult = dest.iSdst; + assert( pParse->nErr || dest.iSdst>0 ); + pLeft = pRet; + } + }else{ + p = &pLeft->pSrc->a[0]; + assert( !p->fg.isTabFunc && !p->fg.isIndexedBy ); + p->u1.nRow++; + } + + if( pParse->nErr==0 ){ + assert( p!=0 ); + if( p->pSelect->pEList->nExpr!=pRow->nExpr ){ + sqlite3SelectWrongNumTermsError(pParse, p->pSelect); + }else{ + sqlite3ExprCodeExprList(pParse, pRow, p->regResult, 0, 0); + sqlite3VdbeAddOp1(pParse->pVdbe, OP_Yield, p->regReturn); + } + } + sqlite3ExprListDelete(pParse->db, pRow); + } + + return pLeft; +} /* Forward declaration */ static int xferOptimization( @@ -913,25 +1102,40 @@ void sqlite3Insert( if( pSelect ){ /* Data is coming from a SELECT or from a multi-row VALUES clause. ** Generate a co-routine to run the SELECT. */ - int regYield; /* Register holding co-routine entry-point */ - int addrTop; /* Top of the co-routine */ int rc; /* Result code */ - regYield = ++pParse->nMem; - addrTop = sqlite3VdbeCurrentAddr(v) + 1; - sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, addrTop); - sqlite3SelectDestInit(&dest, SRT_Coroutine, regYield); - dest.iSdst = bIdListInOrder ? regData : 0; - dest.nSdst = pTab->nCol; - rc = sqlite3Select(pParse, pSelect, &dest); - regFromSelect = dest.iSdst; - assert( db->pParse==pParse ); - if( rc || pParse->nErr ) goto insert_cleanup; - assert( db->mallocFailed==0 ); - sqlite3VdbeEndCoroutine(v, regYield); - sqlite3VdbeJumpHere(v, addrTop - 1); /* label B: */ - assert( pSelect->pEList ); - nColumn = pSelect->pEList->nExpr; + if( pSelect->pSrc->nSrc==1 + && pSelect->pSrc->a[0].fg.viaCoroutine + && pSelect->pPrior==0 + ){ + SrcItem *pItem = &pSelect->pSrc->a[0]; + dest.iSDParm = pItem->regReturn; + regFromSelect = pItem->regResult; + nColumn = pItem->pSelect->pEList->nExpr; + ExplainQueryPlan((pParse, 0, "SCAN %S", pItem)); + if( bIdListInOrder && nColumn==pTab->nCol ){ + regData = regFromSelect; + regRowid = regData - 1; + regIns = regRowid - (IsVirtual(pTab) ? 1 : 0); + } + }else{ + int addrTop; /* Top of the co-routine */ + int regYield = ++pParse->nMem; + addrTop = sqlite3VdbeCurrentAddr(v) + 1; + sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, addrTop); + sqlite3SelectDestInit(&dest, SRT_Coroutine, regYield); + dest.iSdst = bIdListInOrder ? regData : 0; + dest.nSdst = pTab->nCol; + rc = sqlite3Select(pParse, pSelect, &dest); + regFromSelect = dest.iSdst; + assert( db->pParse==pParse ); + if( rc || pParse->nErr ) goto insert_cleanup; + assert( db->mallocFailed==0 ); + sqlite3VdbeEndCoroutine(v, regYield); + sqlite3VdbeJumpHere(v, addrTop - 1); /* label B: */ + assert( pSelect->pEList ); + nColumn = pSelect->pEList->nExpr; + } /* Set useTempTable to TRUE if the result of the SELECT statement ** should be written into a temporary table (template 4). Set to @@ -563,7 +563,6 @@ static void jsonAppendRawNZ(JsonString *p, const char *zIn, u32 N){ } } - /* Append formatted text (not to exceed N bytes) to the JsonString. */ static void jsonPrintf(int N, JsonString *p, const char *zFormat, ...){ @@ -621,6 +620,40 @@ static void jsonAppendSeparator(JsonString *p){ jsonAppendChar(p, ','); } +/* c is a control character. Append the canonical JSON representation +** of that control character to p. +** +** This routine assumes that the output buffer has already been enlarged +** sufficiently to hold the worst-case encoding plus a nul terminator. +*/ +static void jsonAppendControlChar(JsonString *p, u8 c){ + static const char aSpecial[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 'b', 't', 'n', 0, 'f', 'r', 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }; + assert( sizeof(aSpecial)==32 ); + assert( aSpecial['\b']=='b' ); + assert( aSpecial['\f']=='f' ); + assert( aSpecial['\n']=='n' ); + assert( aSpecial['\r']=='r' ); + assert( aSpecial['\t']=='t' ); + assert( c>=0 && c<sizeof(aSpecial) ); + assert( p->nUsed+7 <= p->nAlloc ); + if( aSpecial[c] ){ + p->zBuf[p->nUsed] = '\\'; + p->zBuf[p->nUsed+1] = aSpecial[c]; + p->nUsed += 2; + }else{ + p->zBuf[p->nUsed] = '\\'; + p->zBuf[p->nUsed+1] = 'u'; + p->zBuf[p->nUsed+2] = '0'; + p->zBuf[p->nUsed+3] = '0'; + p->zBuf[p->nUsed+4] = "0123456789abcdef"[c>>4]; + p->zBuf[p->nUsed+5] = "0123456789abcdef"[c&0xf]; + p->nUsed += 6; + } +} + /* Append the N-byte string in zIn to the end of the JsonString string ** under construction. Enclose the string in double-quotes ("...") and ** escape any double-quotes or backslash characters contained within the @@ -680,35 +713,14 @@ static void jsonAppendString(JsonString *p, const char *zIn, u32 N){ } c = z[0]; if( c=='"' || c=='\\' ){ - json_simple_escape: if( (p->nUsed+N+3 > p->nAlloc) && jsonStringGrow(p,N+3)!=0 ) return; p->zBuf[p->nUsed++] = '\\'; p->zBuf[p->nUsed++] = c; }else if( c=='\'' ){ p->zBuf[p->nUsed++] = c; }else{ - static const char aSpecial[] = { - 0, 0, 0, 0, 0, 0, 0, 0, 'b', 't', 'n', 0, 'f', 'r', 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - }; - assert( sizeof(aSpecial)==32 ); - assert( aSpecial['\b']=='b' ); - assert( aSpecial['\f']=='f' ); - assert( aSpecial['\n']=='n' ); - assert( aSpecial['\r']=='r' ); - assert( aSpecial['\t']=='t' ); - assert( c>=0 && c<sizeof(aSpecial) ); - if( aSpecial[c] ){ - c = aSpecial[c]; - goto json_simple_escape; - } if( (p->nUsed+N+7 > p->nAlloc) && jsonStringGrow(p,N+7)!=0 ) return; - p->zBuf[p->nUsed++] = '\\'; - p->zBuf[p->nUsed++] = 'u'; - p->zBuf[p->nUsed++] = '0'; - p->zBuf[p->nUsed++] = '0'; - p->zBuf[p->nUsed++] = "0123456789abcdef"[c>>4]; - p->zBuf[p->nUsed++] = "0123456789abcdef"[c&0xf]; + jsonAppendControlChar(p, c); } z++; N--; @@ -1409,7 +1421,10 @@ static u32 jsonbValidityCheck( if( !jsonIsOk[z[j]] && z[j]!='\'' ){ if( z[j]=='"' ){ if( x==JSONB_TEXTJ ) return j+1; - }else if( z[j]!='\\' || j+1>=k ){ + }else if( z[j]<=0x1f ){ + /* Control characters in JSON5 string literals are ok */ + if( x==JSONB_TEXTJ ) return j+1; + }else if( NEVER(z[j]!='\\') || j+1>=k ){ return j+1; }else if( strchr("\"\\/bfnrt",z[j+1])!=0 ){ j++; @@ -1704,9 +1719,14 @@ json_parse_restart: return -1; } }else if( c<=0x1f ){ - /* Control characters are not allowed in strings */ - pParse->iErr = j; - return -1; + if( c==0 ){ + pParse->iErr = j; + return -1; + } + /* Control characters are not allowed in canonical JSON string + ** literals, but are allowed in JSON5 string literals. */ + opcode = JSONB_TEXT5; + pParse->hasNonstd = 1; }else if( c=='"' ){ opcode = JSONB_TEXT5; } @@ -1922,6 +1942,7 @@ json_parse_restart: return i+4; } /* fall-through into the default case that checks for NaN */ + /* no break */ deliberate_fall_through } default: { u32 k; @@ -2190,7 +2211,7 @@ static u32 jsonTranslateBlobToText( zIn = (const char*)&pParse->aBlob[i+n]; jsonAppendChar(pOut, '"'); while( sz2>0 ){ - for(k=0; k<sz2 && zIn[k]!='\\' && zIn[k]!='"'; k++){} + for(k=0; k<sz2 && (jsonIsOk[(u8)zIn[k]] || zIn[k]=='\''); k++){} if( k>0 ){ jsonAppendRawNZ(pOut, zIn, k); if( k>=sz2 ){ @@ -2205,6 +2226,13 @@ static u32 jsonTranslateBlobToText( sz2--; continue; } + if( zIn[0]<=0x1f ){ + if( pOut->nUsed+7>pOut->nAlloc && jsonStringGrow(pOut,7) ) break; + jsonAppendControlChar(pOut, zIn[0]); + zIn++; + sz2--; + continue; + } assert( zIn[0]=='\\' ); assert( sz2>=1 ); if( sz2<2 ){ @@ -2307,6 +2335,112 @@ static u32 jsonTranslateBlobToText( return i+n+sz; } +/* Context for recursion of json_pretty() +*/ +typedef struct JsonPretty JsonPretty; +struct JsonPretty { + JsonParse *pParse; /* The BLOB being rendered */ + JsonString *pOut; /* Generate pretty output into this string */ + const char *zIndent; /* Use this text for indentation */ + u32 szIndent; /* Bytes in zIndent[] */ + u32 nIndent; /* Current level of indentation */ +}; + +/* Append indentation to the pretty JSON under construction */ +static void jsonPrettyIndent(JsonPretty *pPretty){ + u32 jj; + for(jj=0; jj<pPretty->nIndent; jj++){ + jsonAppendRaw(pPretty->pOut, pPretty->zIndent, pPretty->szIndent); + } +} + +/* +** Translate the binary JSONB representation of JSON beginning at +** pParse->aBlob[i] into a JSON text string. Append the JSON +** text onto the end of pOut. Return the index in pParse->aBlob[] +** of the first byte past the end of the element that is translated. +** +** This is a variant of jsonTranslateBlobToText() that "pretty-prints" +** the output. Extra whitespace is inserted to make the JSON easier +** for humans to read. +** +** If an error is detected in the BLOB input, the pOut->eErr flag +** might get set to JSTRING_MALFORMED. But not all BLOB input errors +** are detected. So a malformed JSONB input might either result +** in an error, or in incorrect JSON. +** +** The pOut->eErr JSTRING_OOM flag is set on a OOM. +*/ +static u32 jsonTranslateBlobToPrettyText( + JsonPretty *pPretty, /* Pretty-printing context */ + u32 i /* Start rendering at this index */ +){ + u32 sz, n, j, iEnd; + const JsonParse *pParse = pPretty->pParse; + JsonString *pOut = pPretty->pOut; + n = jsonbPayloadSize(pParse, i, &sz); + if( n==0 ){ + pOut->eErr |= JSTRING_MALFORMED; + return pParse->nBlob+1; + } + switch( pParse->aBlob[i] & 0x0f ){ + case JSONB_ARRAY: { + j = i+n; + iEnd = j+sz; + jsonAppendChar(pOut, '['); + if( j<iEnd ){ + jsonAppendChar(pOut, '\n'); + pPretty->nIndent++; + while( pOut->eErr==0 ){ + jsonPrettyIndent(pPretty); + j = jsonTranslateBlobToPrettyText(pPretty, j); + if( j>=iEnd ) break; + jsonAppendRawNZ(pOut, ",\n", 2); + } + jsonAppendChar(pOut, '\n'); + pPretty->nIndent--; + jsonPrettyIndent(pPretty); + } + jsonAppendChar(pOut, ']'); + i = iEnd; + break; + } + case JSONB_OBJECT: { + j = i+n; + iEnd = j+sz; + jsonAppendChar(pOut, '{'); + if( j<iEnd ){ + jsonAppendChar(pOut, '\n'); + pPretty->nIndent++; + while( pOut->eErr==0 ){ + jsonPrettyIndent(pPretty); + j = jsonTranslateBlobToText(pParse, j, pOut); + if( j>iEnd ){ + pOut->eErr |= JSTRING_MALFORMED; + break; + } + jsonAppendRawNZ(pOut, ": ", 2); + j = jsonTranslateBlobToPrettyText(pPretty, j); + if( j>=iEnd ) break; + jsonAppendRawNZ(pOut, ",\n", 2); + } + jsonAppendChar(pOut, '\n'); + pPretty->nIndent--; + jsonPrettyIndent(pPretty); + } + jsonAppendChar(pOut, '}'); + i = iEnd; + break; + } + default: { + i = jsonTranslateBlobToText(pParse, i, pOut); + break; + } + } + return i; +} + + /* Return true if the input pJson ** ** For performance reasons, this routine does not do a detailed check of the @@ -3557,11 +3691,12 @@ static void jsonParseFunc( if( p==0 ) return; if( argc==1 ){ jsonDebugPrintBlob(p, 0, p->nBlob, 0, &out); - sqlite3_result_text64(ctx, out.zText, out.nChar, SQLITE_DYNAMIC, SQLITE_UTF8); + sqlite3_result_text64(ctx,out.zText,out.nChar,SQLITE_TRANSIENT,SQLITE_UTF8); }else{ jsonShowParse(p); } jsonParseFree(p); + sqlite3_str_reset(&out); } #endif /* SQLITE_DEBUG */ @@ -3660,13 +3795,6 @@ static void jsonArrayLengthFunc( jsonParseFree(p); } -/* True if the string is all digits */ -static int jsonAllDigits(const char *z, int n){ - int i; - for(i=0; i<n && sqlite3Isdigit(z[i]); i++){} - return i==n; -} - /* True if the string is all alphanumerics and underscores */ static int jsonAllAlphanum(const char *z, int n){ int i; @@ -3731,7 +3859,7 @@ static void jsonExtractFunc( ** [NUMBER] ==> $[NUMBER] // Not PG. Purely for convenience */ jsonStringInit(&jx, ctx); - if( jsonAllDigits(zPath, nPath) ){ + if( sqlite3_value_type(argv[i])==SQLITE_INTEGER ){ jsonAppendRawNZ(&jx, "[", 1); jsonAppendRaw(&jx, zPath, nPath); jsonAppendRawNZ(&jx, "]", 2); @@ -4226,6 +4354,40 @@ json_type_done: } /* +** json_pretty(JSON) +** json_pretty(JSON, INDENT) +** +** Return text that is a pretty-printed rendering of the input JSON. +** If the argument is not valid JSON, return NULL. +** +** The INDENT argument is text that is used for indentation. If omitted, +** it defaults to four spaces (the same as PostgreSQL). +*/ +static void jsonPrettyFunc( + sqlite3_context *ctx, + int argc, + sqlite3_value **argv +){ + JsonString s; /* The output string */ + JsonPretty x; /* Pretty printing context */ + + memset(&x, 0, sizeof(x)); + x.pParse = jsonParseFuncArg(ctx, argv[0], 0); + if( x.pParse==0 ) return; + x.pOut = &s; + jsonStringInit(&s, ctx); + if( argc==1 || (x.zIndent = (const char*)sqlite3_value_text(argv[1]))==0 ){ + x.zIndent = " "; + x.szIndent = 4; + }else{ + x.szIndent = (u32)strlen(x.zIndent); + } + jsonTranslateBlobToPrettyText(&x, 0); + jsonReturnString(&s, 0, 0); + jsonParseFree(x.pParse); +} + +/* ** json_valid(JSON) ** json_valid(JSON, FLAGS) ** @@ -5239,6 +5401,8 @@ void sqlite3RegisterJsonFunctions(void){ JFUNCTION(jsonb_object, -1,0,1, 1,1,0, jsonObjectFunc), JFUNCTION(json_patch, 2,1,1, 0,0,0, jsonPatchFunc), JFUNCTION(jsonb_patch, 2,1,0, 0,1,0, jsonPatchFunc), + JFUNCTION(json_pretty, 1,1,0, 0,0,0, jsonPrettyFunc), + JFUNCTION(json_pretty, 2,1,0, 0,0,0, jsonPrettyFunc), JFUNCTION(json_quote, 1,0,1, 1,0,0, jsonQuoteFunc), JFUNCTION(json_remove, -1,1,1, 0,0,0, jsonRemoveFunc), JFUNCTION(jsonb_remove, -1,1,0, 0,1,0, jsonRemoveFunc), diff --git a/src/malloc.c b/src/malloc.c index 3567506..9a635e7 100644 --- a/src/malloc.c +++ b/src/malloc.c @@ -221,6 +221,24 @@ static void sqlite3MallocAlarm(int nByte){ sqlite3_mutex_enter(mem0.mutex); } +#ifdef SQLITE_DEBUG +/* +** This routine is called whenever an out-of-memory condition is seen, +** It's only purpose to to serve as a breakpoint for gdb or similar +** code debuggers when working on out-of-memory conditions, for example +** caused by PRAGMA hard_heap_limit=N. +*/ +static SQLITE_NOINLINE void test_oom_breakpoint(u64 n){ + static u64 nOomFault = 0; + nOomFault += n; + /* The assert() is never reached in a human lifetime. It is here mostly + ** to prevent code optimizers from optimizing out this function. */ + assert( (nOomFault>>32) < 0xffffffff ); +} +#else +# define test_oom_breakpoint(X) /* No-op for production builds */ +#endif + /* ** Do a memory allocation with statistics and alarms. Assume the ** lock is already held. @@ -247,6 +265,7 @@ static void mallocWithAlarm(int n, void **pp){ if( mem0.hardLimit ){ nUsed = sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED); if( nUsed >= mem0.hardLimit - nFull ){ + test_oom_breakpoint(1); *pp = 0; return; } @@ -535,6 +554,7 @@ void *sqlite3Realloc(void *pOld, u64 nBytes){ sqlite3MallocAlarm(nDiff); if( mem0.hardLimit>0 && nUsed >= mem0.hardLimit - nDiff ){ sqlite3_mutex_leave(mem0.mutex); + test_oom_breakpoint(1); return 0; } } diff --git a/src/os_unix.c b/src/os_unix.c index 4b3d63c..9e7ba05 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -1295,8 +1295,12 @@ static int unixLogErrorAtLine( ** available, the error message will often be an empty string. Not a ** huge problem. Incorrectly concluding that the GNU version is available ** could lead to a segfault though. + ** + ** Forum post 3f13857fa4062301 reports that the Android SDK may use + ** int-type return, depending on its version. */ -#if defined(STRERROR_R_CHAR_P) || defined(__USE_GNU) +#if (defined(STRERROR_R_CHAR_P) || defined(__USE_GNU)) \ + && !defined(ANDROID) && !defined(__ANDROID__) zErr = # endif strerror_r(iErrno, aErr, sizeof(aErr)-1); @@ -6394,12 +6398,19 @@ static int unixOpen( rc = SQLITE_READONLY_DIRECTORY; }else if( errno!=EISDIR && isReadWrite ){ /* Failed to open the file for read/write access. Try read-only. */ + UnixUnusedFd *pReadonly = 0; flags &= ~(SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE); openFlags &= ~(O_RDWR|O_CREAT); flags |= SQLITE_OPEN_READONLY; openFlags |= O_RDONLY; isReadonly = 1; - fd = robust_open(zName, openFlags, openMode); + pReadonly = findReusableFd(zName, flags); + if( pReadonly ){ + fd = pReadonly->fd; + sqlite3_free(pReadonly); + }else{ + fd = robust_open(zName, openFlags, openMode); + } } } if( fd<0 ){ diff --git a/src/parse.y b/src/parse.y index 1949119..071e10a 100644 --- a/src/parse.y +++ b/src/parse.y @@ -21,6 +21,10 @@ */ } +// Function used to enlarge the parser stack, if needed +%realloc parserStackRealloc +%free sqlite3_free + // All token codes are small integers with #defines that begin with "TK_" %token_prefix TK_ @@ -45,7 +49,7 @@ } } %stack_overflow { - sqlite3ErrorMsg(pParse, "parser stack overflow"); + sqlite3OomFault(pParse->db); } // The name of the generated procedure that implements the parser @@ -547,12 +551,21 @@ cmd ::= select(X). { } return pSelect; } + + /* Memory allocator for parser stack resizing. This is a thin wrapper around + ** sqlite3_realloc() that includes a call to sqlite3FaultSim() to facilitate + ** testing. + */ + static void *parserStackRealloc(void *pOld, sqlite3_uint64 newSize){ + return sqlite3FaultSim(700) ? 0 : sqlite3_realloc(pOld, newSize); + } } %ifndef SQLITE_OMIT_CTE select(A) ::= WITH wqlist(W) selectnowith(X). {A = attachWithToSelect(pParse,X,W);} select(A) ::= WITH RECURSIVE wqlist(W) selectnowith(X). {A = attachWithToSelect(pParse,X,W);} + %endif /* SQLITE_OMIT_CTE */ select(A) ::= selectnowith(A). { Select *p = A; @@ -610,24 +623,27 @@ oneselect(A) ::= SELECT distinct(D) selcollist(W) from(X) where_opt(Y) %endif -oneselect(A) ::= values(A). - +// Single row VALUES clause. +// %type values {Select*} +oneselect(A) ::= values(A). %destructor values {sqlite3SelectDelete(pParse->db, $$);} values(A) ::= VALUES LP nexprlist(X) RP. { A = sqlite3SelectNew(pParse,X,0,0,0,0,0,SF_Values,0); } -values(A) ::= values(A) COMMA LP nexprlist(Y) RP. { - Select *pRight, *pLeft = A; - pRight = sqlite3SelectNew(pParse,Y,0,0,0,0,0,SF_Values|SF_MultiValue,0); - if( ALWAYS(pLeft) ) pLeft->selFlags &= ~SF_MultiValue; - if( pRight ){ - pRight->op = TK_ALL; - pRight->pPrior = pLeft; - A = pRight; - }else{ - A = pLeft; - } + +// Multiple row VALUES clause. +// +%type mvalues {Select*} +oneselect(A) ::= mvalues(A). { + sqlite3MultiValuesEnd(pParse, A); +} +%destructor mvalues {sqlite3SelectDelete(pParse->db, $$);} +mvalues(A) ::= values(A) COMMA LP nexprlist(Y) RP. { + A = sqlite3MultiValues(pParse, A, Y); +} +mvalues(A) ::= mvalues(A) COMMA LP nexprlist(Y) RP. { + A = sqlite3MultiValues(pParse, A, Y); } // The "distinct" nonterminal is true (1) if the DISTINCT keyword is @@ -1266,8 +1282,17 @@ expr(A) ::= NOT(B) expr(X). expr(A) ::= BITNOT(B) expr(X). {A = sqlite3PExpr(pParse, @B, X, 0);/*A-overwrites-B*/} expr(A) ::= PLUS|MINUS(B) expr(X). [BITNOT] { - A = sqlite3PExpr(pParse, @B==TK_PLUS ? TK_UPLUS : TK_UMINUS, X, 0); - /*A-overwrites-B*/ + Expr *p = X; + u8 op = @B + (TK_UPLUS-TK_PLUS); + assert( TK_UPLUS>TK_PLUS ); + assert( TK_UMINUS == TK_MINUS + (TK_UPLUS - TK_PLUS) ); + if( p && p->op==TK_UPLUS ){ + p->op = op; + A = p; + }else{ + A = sqlite3PExpr(pParse, op, p, 0); + /*A-overwrites-B*/ + } } expr(A) ::= expr(B) PTR(C) expr(D). { @@ -1309,7 +1334,7 @@ expr(A) ::= expr(A) between_op(N) expr(X) AND expr(Y). [BETWEEN] { if( A ) sqlite3ExprIdToTrueFalse(A); }else{ Expr *pRHS = Y->a[0].pExpr; - if( Y->nExpr==1 && sqlite3ExprIsConstant(pRHS) && A->op!=TK_VECTOR ){ + if( Y->nExpr==1 && sqlite3ExprIsConstant(pParse,pRHS) && A->op!=TK_VECTOR ){ Y->a[0].pExpr = 0; sqlite3ExprListDelete(pParse->db, Y); pRHS = sqlite3PExpr(pParse, TK_UPLUS, pRHS, 0); @@ -1749,9 +1774,10 @@ with ::= WITH RECURSIVE wqlist(W). { sqlite3WithPush(pParse, W, 1); } wqas(A) ::= AS. {A = M10d_Any;} wqas(A) ::= AS MATERIALIZED. {A = M10d_Yes;} wqas(A) ::= AS NOT MATERIALIZED. {A = M10d_No;} -wqitem(A) ::= nm(X) eidlist_opt(Y) wqas(M) LP select(Z) RP. { +wqitem(A) ::= withnm(X) eidlist_opt(Y) wqas(M) LP select(Z) RP. { A = sqlite3CteNew(pParse, &X, Y, Z, M); /*A-overwrites-X*/ } +withnm(A) ::= nm(A). {pParse->bHasWith = 1;} wqlist(A) ::= wqitem(X). { A = sqlite3WithAdd(pParse, 0, X); /*A-overwrites-X*/ } @@ -1912,8 +1938,8 @@ filter_clause(A) ::= FILTER LP WHERE expr(X) RP. { A = X; } TRUEFALSE /* True or false keyword */ ISNOT /* Combination of IS and NOT */ FUNCTION /* A function invocation */ - UMINUS /* Unary minus */ UPLUS /* Unary plus */ + UMINUS /* Unary minus */ TRUTH /* IS TRUE or IS FALSE or IS NOT TRUE or IS NOT FALSE */ REGISTER /* Reference to a VDBE register */ VECTOR /* Vector */ @@ -1923,6 +1949,12 @@ filter_clause(A) ::= FILTER LP WHERE expr(X) RP. { A = X; } SPAN /* The span operator */ ERROR /* An expression containing an error */ . + +term(A) ::= QNUMBER(X). { + A=tokenExpr(pParse,@X,X); + sqlite3DequoteNumber(pParse, A); +} + /* There must be no more than 255 tokens defined above. If this grammar ** is extended with new rules and tokens, they must either be so few in ** number that TK_SPAN is no more than 255, or else the new tokens must diff --git a/src/pragma.c b/src/pragma.c index 0a68732..a8045aa 100644 --- a/src/pragma.c +++ b/src/pragma.c @@ -31,6 +31,34 @@ #include "pragma.h" /* +** When the 0x10 bit of PRAGMA optimize is set, any ANALYZE commands +** will be run with an analysis_limit set to the lessor of the value of +** the following macro or to the actual analysis_limit if it is non-zero, +** in order to prevent PRAGMA optimize from running for too long. +** +** The value of 2000 is chosen emperically so that the worst-case run-time +** for PRAGMA optimize does not exceed 100 milliseconds against a variety +** of test databases on a RaspberryPI-4 compiled using -Os and without +** -DSQLITE_DEBUG. Of course, your mileage may vary. For the purpose of +** this paragraph, "worst-case" means that ANALYZE ends up being +** run on every table in the database. The worst case typically only +** happens if PRAGMA optimize is run on a database file for which ANALYZE +** has not been previously run and the 0x10000 flag is included so that +** all tables are analyzed. The usual case for PRAGMA optimize is that +** no ANALYZE commands will be run at all, or if any ANALYZE happens it +** will be against a single table, so that expected timing for PRAGMA +** optimize on a PI-4 is more like 1 millisecond or less with the 0x10000 +** flag or less than 100 microseconds without the 0x10000 flag. +** +** An analysis limit of 2000 is almost always sufficient for the query +** planner to fully characterize an index. The additional accuracy from +** a larger analysis is not usually helpful. +*/ +#ifndef SQLITE_DEFAULT_OPTIMIZE_LIMIT +# define SQLITE_DEFAULT_OPTIMIZE_LIMIT 2000 +#endif + +/* ** Interpret the given string as a safety level. Return 0 for OFF, ** 1 for ON or NORMAL, 2 for FULL, and 3 for EXTRA. Return 1 for an empty or ** unrecognized string argument. The FULL and EXTRA option is disallowed @@ -1675,7 +1703,7 @@ void sqlite3Pragma( /* Set the maximum error count */ mxErr = SQLITE_INTEGRITY_CHECK_ERROR_MAX; if( zRight ){ - if( sqlite3GetInt32(zRight, &mxErr) ){ + if( sqlite3GetInt32(pValue->z, &mxErr) ){ if( mxErr<=0 ){ mxErr = SQLITE_INTEGRITY_CHECK_ERROR_MAX; } @@ -1692,7 +1720,6 @@ void sqlite3Pragma( Hash *pTbls; /* Set of all tables in the schema */ int *aRoot; /* Array of root page numbers of all btrees */ int cnt = 0; /* Number of entries in aRoot[] */ - int mxIdx = 0; /* Maximum number of indexes for any table */ if( OMIT_TEMPDB && i==1 ) continue; if( iDb>=0 && i!=iDb ) continue; @@ -1714,7 +1741,6 @@ void sqlite3Pragma( if( pObjTab && pObjTab!=pTab ) continue; if( HasRowid(pTab) ) cnt++; for(nIdx=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, nIdx++){ cnt++; } - if( nIdx>mxIdx ) mxIdx = nIdx; } if( cnt==0 ) continue; if( pObjTab ) cnt++; @@ -1734,11 +1760,11 @@ void sqlite3Pragma( aRoot[0] = cnt; /* Make sure sufficient number of registers have been allocated */ - sqlite3TouchRegister(pParse, 8+mxIdx); + sqlite3TouchRegister(pParse, 8+cnt); sqlite3ClearTempRegCache(pParse); /* Do the b-tree integrity checks */ - sqlite3VdbeAddOp4(v, OP_IntegrityCk, 2, cnt, 1, (char*)aRoot,P4_INTARRAY); + sqlite3VdbeAddOp4(v, OP_IntegrityCk, 1, cnt, 8, (char*)aRoot,P4_INTARRAY); sqlite3VdbeChangeP5(v, (u8)i); addr = sqlite3VdbeAddOp1(v, OP_IsNull, 2); VdbeCoverage(v); sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, @@ -1748,6 +1774,36 @@ void sqlite3Pragma( integrityCheckResultRow(v); sqlite3VdbeJumpHere(v, addr); + /* Check that the indexes all have the right number of rows */ + cnt = pObjTab ? 1 : 0; + sqlite3VdbeLoadString(v, 2, "wrong # of entries in index "); + for(x=sqliteHashFirst(pTbls); x; x=sqliteHashNext(x)){ + int iTab = 0; + Table *pTab = sqliteHashData(x); + Index *pIdx; + if( pObjTab && pObjTab!=pTab ) continue; + if( HasRowid(pTab) ){ + iTab = cnt++; + }else{ + iTab = cnt; + for(pIdx=pTab->pIndex; ALWAYS(pIdx); pIdx=pIdx->pNext){ + if( IsPrimaryKeyIndex(pIdx) ) break; + iTab++; + } + } + for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ + if( pIdx->pPartIdxWhere==0 ){ + addr = sqlite3VdbeAddOp3(v, OP_Eq, 8+cnt, 0, 8+iTab); + VdbeCoverageNeverNull(v); + sqlite3VdbeLoadString(v, 4, pIdx->zName); + sqlite3VdbeAddOp3(v, OP_Concat, 4, 2, 3); + integrityCheckResultRow(v); + sqlite3VdbeJumpHere(v, addr); + } + cnt++; + } + } + /* Make sure all the indices are constructed correctly. */ for(x=sqliteHashFirst(pTbls); x; x=sqliteHashNext(x)){ @@ -2071,21 +2127,9 @@ void sqlite3Pragma( } sqlite3VdbeAddOp2(v, OP_Next, iDataCur, loopTop); VdbeCoverage(v); sqlite3VdbeJumpHere(v, loopTop-1); - if( !isQuick ){ - sqlite3VdbeLoadString(v, 2, "wrong # of entries in index "); - for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){ - if( pPk==pIdx ) continue; - sqlite3VdbeAddOp2(v, OP_Count, iIdxCur+j, 3); - addr = sqlite3VdbeAddOp3(v, OP_Eq, 8+j, 0, 3); VdbeCoverage(v); - sqlite3VdbeChangeP5(v, SQLITE_NOTNULL); - sqlite3VdbeLoadString(v, 4, pIdx->zName); - sqlite3VdbeAddOp3(v, OP_Concat, 4, 2, 3); - integrityCheckResultRow(v); - sqlite3VdbeJumpHere(v, addr); - } - if( pPk ){ - sqlite3ReleaseTempRange(pParse, r2, pPk->nKeyCol); - } + if( pPk ){ + assert( !isQuick ); + sqlite3ReleaseTempRange(pParse, r2, pPk->nKeyCol); } } @@ -2383,44 +2427,63 @@ void sqlite3Pragma( ** ** The optional argument is a bitmask of optimizations to perform: ** - ** 0x0001 Debugging mode. Do not actually perform any optimizations - ** but instead return one line of text for each optimization - ** that would have been done. Off by default. + ** 0x00001 Debugging mode. Do not actually perform any optimizations + ** but instead return one line of text for each optimization + ** that would have been done. Off by default. ** - ** 0x0002 Run ANALYZE on tables that might benefit. On by default. - ** See below for additional information. + ** 0x00002 Run ANALYZE on tables that might benefit. On by default. + ** See below for additional information. ** - ** 0x0004 (Not yet implemented) Record usage and performance - ** information from the current session in the - ** database file so that it will be available to "optimize" - ** pragmas run by future database connections. + ** 0x00010 Run all ANALYZE operations using an analysis_limit that + ** is the lessor of the current analysis_limit and the + ** SQLITE_DEFAULT_OPTIMIZE_LIMIT compile-time option. + ** The default value of SQLITE_DEFAULT_OPTIMIZE_LIMIT is + ** currently (2024-02-19) set to 2000, which is such that + ** the worst case run-time for PRAGMA optimize on a 100MB + ** database will usually be less than 100 milliseconds on + ** a RaspberryPI-4 class machine. On by default. ** - ** 0x0008 (Not yet implemented) Create indexes that might have - ** been helpful to recent queries + ** 0x10000 Look at tables to see if they need to be reanalyzed + ** due to growth or shrinkage even if they have not been + ** queried during the current connection. Off by default. ** - ** The default MASK is and always shall be 0xfffe. 0xfffe means perform all - ** of the optimizations listed above except Debug Mode, including new - ** optimizations that have not yet been invented. If new optimizations are - ** ever added that should be off by default, those off-by-default - ** optimizations will have bitmasks of 0x10000 or larger. + ** The default MASK is and always shall be 0x0fffe. In the current + ** implementation, the default mask only covers the 0x00002 optimization, + ** though additional optimizations that are covered by 0x0fffe might be + ** added in the future. Optimizations that are off by default and must + ** be explicitly requested have masks of 0x10000 or greater. ** ** DETERMINATION OF WHEN TO RUN ANALYZE ** ** In the current implementation, a table is analyzed if only if all of ** the following are true: ** - ** (1) MASK bit 0x02 is set. + ** (1) MASK bit 0x00002 is set. + ** + ** (2) The table is an ordinary table, not a virtual table or view. ** - ** (2) The query planner used sqlite_stat1-style statistics for one or - ** more indexes of the table at some point during the lifetime of - ** the current connection. + ** (3) The table name does not begin with "sqlite_". ** - ** (3) One or more indexes of the table are currently unanalyzed OR - ** the number of rows in the table has increased by 25 times or more - ** since the last time ANALYZE was run. + ** (4) One or more of the following is true: + ** (4a) The 0x10000 MASK bit is set. + ** (4b) One or more indexes on the table lacks an entry + ** in the sqlite_stat1 table. + ** (4c) The query planner used sqlite_stat1-style statistics for one + ** or more indexes of the table at some point during the lifetime + ** of the current connection. + ** + ** (5) One or more of the following is true: + ** (5a) One or more indexes on the table lacks an entry + ** in the sqlite_stat1 table. (Same as 4a) + ** (5b) The number of rows in the table has increased or decreased by + ** 10-fold. In other words, the current size of the table is + ** 10 times larger than the size in sqlite_stat1 or else the + ** current size is less than 1/10th the size in sqlite_stat1. ** ** The rules for when tables are analyzed are likely to change in - ** future releases. + ** future releases. Future versions of SQLite might accept a string + ** literal argument to this pragma that contains a mnemonic description + ** of the options rather than a bitmap. */ case PragTyp_OPTIMIZE: { int iDbLast; /* Loop termination point for the schema loop */ @@ -2432,6 +2495,10 @@ void sqlite3Pragma( LogEst szThreshold; /* Size threshold above which reanalysis needed */ char *zSubSql; /* SQL statement for the OP_SqlExec opcode */ u32 opMask; /* Mask of operations to perform */ + int nLimit; /* Analysis limit to use */ + int nCheck = 0; /* Number of tables to be optimized */ + int nBtree = 0; /* Number of btrees to scan */ + int nIndex; /* Number of indexes on the current table */ if( zRight ){ opMask = (u32)sqlite3Atoi(zRight); @@ -2439,6 +2506,14 @@ void sqlite3Pragma( }else{ opMask = 0xfffe; } + if( (opMask & 0x10)==0 ){ + nLimit = 0; + }else if( db->nAnalysisLimit>0 + && db->nAnalysisLimit<SQLITE_DEFAULT_OPTIMIZE_LIMIT ){ + nLimit = 0; + }else{ + nLimit = SQLITE_DEFAULT_OPTIMIZE_LIMIT; + } iTabCur = pParse->nTab++; for(iDbLast = zDb?iDb:db->nDb-1; iDb<=iDbLast; iDb++){ if( iDb==1 ) continue; @@ -2447,23 +2522,61 @@ void sqlite3Pragma( for(k=sqliteHashFirst(&pSchema->tblHash); k; k=sqliteHashNext(k)){ pTab = (Table*)sqliteHashData(k); - /* If table pTab has not been used in a way that would benefit from - ** having analysis statistics during the current session, then skip it. - ** This also has the effect of skipping virtual tables and views */ - if( (pTab->tabFlags & TF_StatsUsed)==0 ) continue; + /* This only works for ordinary tables */ + if( !IsOrdinaryTable(pTab) ) continue; + + /* Do not scan system tables */ + if( 0==sqlite3StrNICmp(pTab->zName, "sqlite_", 7) ) continue; - /* Reanalyze if the table is 25 times larger than the last analysis */ - szThreshold = pTab->nRowLogEst + 46; assert( sqlite3LogEst(25)==46 ); + /* Find the size of the table as last recorded in sqlite_stat1. + ** If any index is unanalyzed, then the threshold is -1 to + ** indicate a new, unanalyzed index + */ + szThreshold = pTab->nRowLogEst; + nIndex = 0; for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ + nIndex++; if( !pIdx->hasStat1 ){ - szThreshold = 0; /* Always analyze if any index lacks statistics */ - break; + szThreshold = -1; /* Always analyze if any index lacks statistics */ } } - if( szThreshold ){ - sqlite3OpenTable(pParse, iTabCur, iDb, pTab, OP_OpenRead); - sqlite3VdbeAddOp3(v, OP_IfSmaller, iTabCur, - sqlite3VdbeCurrentAddr(v)+2+(opMask&1), szThreshold); + + /* If table pTab has not been used in a way that would benefit from + ** having analysis statistics during the current session, then skip it, + ** unless the 0x10000 MASK bit is set. */ + if( (pTab->tabFlags & TF_MaybeReanalyze)!=0 ){ + /* Check for size change if stat1 has been used for a query */ + }else if( opMask & 0x10000 ){ + /* Check for size change if 0x10000 is set */ + }else if( pTab->pIndex!=0 && szThreshold<0 ){ + /* Do analysis if unanalyzed indexes exists */ + }else{ + /* Otherwise, we can skip this table */ + continue; + } + + nCheck++; + if( nCheck==2 ){ + /* If ANALYZE might be invoked two or more times, hold a write + ** transaction for efficiency */ + sqlite3BeginWriteOperation(pParse, 0, iDb); + } + nBtree += nIndex+1; + + /* Reanalyze if the table is 10 times larger or smaller than + ** the last analysis. Unconditional reanalysis if there are + ** unanalyzed indexes. */ + sqlite3OpenTable(pParse, iTabCur, iDb, pTab, OP_OpenRead); + if( szThreshold>=0 ){ + const LogEst iRange = 33; /* 10x size change */ + sqlite3VdbeAddOp4Int(v, OP_IfSizeBetween, iTabCur, + sqlite3VdbeCurrentAddr(v)+2+(opMask&1), + szThreshold>=iRange ? szThreshold-iRange : -1, + szThreshold+iRange); + VdbeCoverage(v); + }else{ + sqlite3VdbeAddOp2(v, OP_Rewind, iTabCur, + sqlite3VdbeCurrentAddr(v)+2+(opMask&1)); VdbeCoverage(v); } zSubSql = sqlite3MPrintf(db, "ANALYZE \"%w\".\"%w\"", @@ -2473,11 +2586,27 @@ void sqlite3Pragma( sqlite3VdbeAddOp4(v, OP_String8, 0, r1, 0, zSubSql, P4_DYNAMIC); sqlite3VdbeAddOp2(v, OP_ResultRow, r1, 1); }else{ - sqlite3VdbeAddOp4(v, OP_SqlExec, 0, 0, 0, zSubSql, P4_DYNAMIC); + sqlite3VdbeAddOp4(v, OP_SqlExec, nLimit ? 0x02 : 00, nLimit, 0, + zSubSql, P4_DYNAMIC); } } } sqlite3VdbeAddOp0(v, OP_Expire); + + /* In a schema with a large number of tables and indexes, scale back + ** the analysis_limit to avoid excess run-time in the worst case. + */ + if( !db->mallocFailed && nLimit>0 && nBtree>100 ){ + int iAddr, iEnd; + VdbeOp *aOp; + nLimit = 100*nLimit/nBtree; + if( nLimit<100 ) nLimit = 100; + aOp = sqlite3VdbeGetOp(v, 0); + iEnd = sqlite3VdbeCurrentAddr(v); + for(iAddr=0; iAddr<iEnd; iAddr++){ + if( aOp[iAddr].opcode==OP_SqlExec ) aOp[iAddr].p2 = nLimit; + } + } break; } @@ -2741,9 +2870,9 @@ static int pragmaVtabBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){ seen[0] = 0; seen[1] = 0; for(i=0; i<pIdxInfo->nConstraint; i++, pConstraint++){ - if( pConstraint->usable==0 ) continue; - if( pConstraint->op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue; if( pConstraint->iColumn < pTab->iHidden ) continue; + if( pConstraint->op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue; + if( pConstraint->usable==0 ) return SQLITE_CONSTRAINT; j = pConstraint->iColumn - pTab->iHidden; assert( j < 2 ); seen[j] = i+1; @@ -2756,16 +2885,13 @@ static int pragmaVtabBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){ j = seen[0]-1; pIdxInfo->aConstraintUsage[j].argvIndex = 1; pIdxInfo->aConstraintUsage[j].omit = 1; - if( seen[1]==0 ){ - pIdxInfo->estimatedCost = (double)1000; - pIdxInfo->estimatedRows = 1000; - return SQLITE_OK; - } pIdxInfo->estimatedCost = (double)20; pIdxInfo->estimatedRows = 20; - j = seen[1]-1; - pIdxInfo->aConstraintUsage[j].argvIndex = 2; - pIdxInfo->aConstraintUsage[j].omit = 1; + if( seen[1] ){ + j = seen[1]-1; + pIdxInfo->aConstraintUsage[j].argvIndex = 2; + pIdxInfo->aConstraintUsage[j].omit = 1; + } return SQLITE_OK; } @@ -2785,6 +2911,7 @@ static void pragmaVtabCursorClear(PragmaVtabCursor *pCsr){ int i; sqlite3_finalize(pCsr->pPragma); pCsr->pPragma = 0; + pCsr->iRowid = 0; for(i=0; i<ArraySize(pCsr->azArg); i++){ sqlite3_free(pCsr->azArg[i]); pCsr->azArg[i] = 0; diff --git a/src/prepare.c b/src/prepare.c index 87569ee..df9c98f 100644 --- a/src/prepare.c +++ b/src/prepare.c @@ -633,7 +633,13 @@ void *sqlite3ParserAddCleanup( void (*xCleanup)(sqlite3*,void*), /* The cleanup routine */ void *pPtr /* Pointer to object to be cleaned up */ ){ - ParseCleanup *pCleanup = sqlite3DbMallocRaw(pParse->db, sizeof(*pCleanup)); + ParseCleanup *pCleanup; + if( sqlite3FaultSim(300) ){ + pCleanup = 0; + sqlite3OomFault(pParse->db); + }else{ + pCleanup = sqlite3DbMallocRaw(pParse->db, sizeof(*pCleanup)); + } if( pCleanup ){ pCleanup->pNext = pParse->pCleanup; pParse->pCleanup = pCleanup; diff --git a/src/printf.c b/src/printf.c index 2e09431..c0dcc5d 100644 --- a/src/printf.c +++ b/src/printf.c @@ -534,13 +534,14 @@ void sqlite3_str_vappendf( } exp = s.iDP-1; - if( xtype==etGENERIC && precision>0 ) precision--; /* ** If the field type is etGENERIC, then convert to either etEXP ** or etFLOAT, as appropriate. */ if( xtype==etGENERIC ){ + assert( precision>0 ); + precision--; flag_rtz = !flag_alternateform; if( exp<-4 || exp>precision ){ xtype = etEXP; @@ -856,9 +857,13 @@ void sqlite3_str_vappendf( sqlite3_str_appendall(pAccum, pItem->zAlias); }else{ Select *pSel = pItem->pSelect; - assert( pSel!=0 ); + assert( pSel!=0 ); /* Because of tag-20240424-1 */ if( pSel->selFlags & SF_NestedFrom ){ sqlite3_str_appendf(pAccum, "(join-%u)", pSel->selId); + }else if( pSel->selFlags & SF_MultiValue ){ + assert( !pItem->fg.isTabFunc && !pItem->fg.isIndexedBy ); + sqlite3_str_appendf(pAccum, "%u-ROW VALUES CLAUSE", + pItem->u1.nRow); }else{ sqlite3_str_appendf(pAccum, "(subquery-%u)", pSel->selId); } diff --git a/src/resolve.c b/src/resolve.c index fdf260d..bf8326a 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -279,7 +279,7 @@ static int lookupName( Parse *pParse, /* The parsing context */ const char *zDb, /* Name of the database containing table, or NULL */ const char *zTab, /* Name of table containing column, or NULL */ - const char *zCol, /* Name of the column. */ + const Expr *pRight, /* Name of the column. */ NameContext *pNC, /* The name context used to resolve the name */ Expr *pExpr /* Make this EXPR node point to the selected column */ ){ @@ -296,6 +296,7 @@ static int lookupName( Table *pTab = 0; /* Table holding the row */ Column *pCol; /* A column of pTab */ ExprList *pFJMatch = 0; /* Matches for FULL JOIN .. USING */ + const char *zCol = pRight->u.zToken; assert( pNC ); /* the name context cannot be NULL. */ assert( zCol ); /* The Z in X.Y.Z cannot be NULL */ @@ -527,7 +528,8 @@ static int lookupName( if( pParse->bReturning ){ if( (pNC->ncFlags & NC_UBaseReg)!=0 && ALWAYS(zTab==0 - || sqlite3StrICmp(zTab,pParse->pTriggerTab->zName)==0) + || sqlite3StrICmp(zTab,pParse->pTriggerTab->zName)==0 + || isValidSchemaTableName(zTab, pParse->pTriggerTab, 0)) ){ pExpr->iTable = op!=TK_DELETE; pTab = pParse->pTriggerTab; @@ -631,6 +633,11 @@ static int lookupName( && ALWAYS(VisibleRowid(pMatch->pTab) || pMatch->fg.isNestedFrom) ){ cnt = cntTab; +#if SQLITE_ALLOW_ROWID_IN_VIEW+0==2 + if( pMatch->pTab!=0 && IsView(pMatch->pTab) ){ + eNewExprOp = TK_NULL; + } +#endif if( pMatch->fg.isNestedFrom==0 ) pExpr->iColumn = -1; pExpr->affExpr = SQLITE_AFF_INTEGER; } @@ -784,6 +791,10 @@ static int lookupName( sqlite3ErrorMsg(pParse, "%s: %s.%s.%s", zErr, zDb, zTab, zCol); }else if( zTab ){ sqlite3ErrorMsg(pParse, "%s: %s.%s", zErr, zTab, zCol); + }else if( cnt==0 && ExprHasProperty(pRight,EP_DblQuoted) ){ + sqlite3ErrorMsg(pParse, "%s: \"%s\" - should this be a" + " string literal in single-quotes?", + zErr, zCol); }else{ sqlite3ErrorMsg(pParse, "%s: %s", zErr, zCol); } @@ -817,8 +828,12 @@ static int lookupName( ** If a generated column is referenced, set bits for every column ** of the table. */ - if( pExpr->iColumn>=0 && cnt==1 && pMatch!=0 ){ - pMatch->colUsed |= sqlite3ExprColUsed(pExpr); + if( pMatch ){ + if( pExpr->iColumn>=0 ){ + pMatch->colUsed |= sqlite3ExprColUsed(pExpr); + }else{ + pMatch->fg.rowidUsed = 1; + } } pExpr->op = eNewExprOp; @@ -1061,7 +1076,6 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ */ case TK_ID: case TK_DOT: { - const char *zColumn; const char *zTable; const char *zDb; Expr *pRight; @@ -1070,7 +1084,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ zDb = 0; zTable = 0; assert( !ExprHasProperty(pExpr, EP_IntValue) ); - zColumn = pExpr->u.zToken; + pRight = pExpr; }else{ Expr *pLeft = pExpr->pLeft; testcase( pNC->ncFlags & NC_IdxExpr ); @@ -1089,14 +1103,13 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ } assert( ExprUseUToken(pLeft) && ExprUseUToken(pRight) ); zTable = pLeft->u.zToken; - zColumn = pRight->u.zToken; assert( ExprUseYTab(pExpr) ); if( IN_RENAME_OBJECT ){ sqlite3RenameTokenRemap(pParse, (void*)pExpr, (void*)pRight); sqlite3RenameTokenRemap(pParse, (void*)&pExpr->y.pTab, (void*)pLeft); } } - return lookupName(pParse, zDb, zTable, zColumn, pNC, pExpr); + return lookupName(pParse, zDb, zTable, pRight, pNC, pExpr); } /* Resolve function names @@ -1272,11 +1285,9 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ #endif } } -#ifndef SQLITE_OMIT_WINDOWFUNC - else if( ExprHasProperty(pExpr, EP_WinFunc) ){ + else if( ExprHasProperty(pExpr, EP_WinFunc) || pExpr->pLeft ){ is_agg = 1; } -#endif sqlite3WalkExprList(pWalker, pList); if( is_agg ){ if( pExpr->pLeft ){ @@ -1346,6 +1357,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ testcase( pNC->ncFlags & NC_PartIdx ); testcase( pNC->ncFlags & NC_IdxExpr ); testcase( pNC->ncFlags & NC_GenCol ); + assert( pExpr->x.pSelect ); if( pNC->ncFlags & NC_SelfRef ){ notValidImpl(pParse, pNC, "subqueries", pExpr, pExpr); }else{ @@ -1354,6 +1366,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ assert( pNC->nRef>=nRef ); if( nRef!=pNC->nRef ){ ExprSetProperty(pExpr, EP_VarSelect); + pExpr->x.pSelect->selFlags |= SF_Correlated; } pNC->ncFlags |= NC_Subquery; } @@ -1879,6 +1892,7 @@ static int resolveSelectStep(Walker *pWalker, Select *p){ if( pOuterNC ) pOuterNC->nNestedSelect++; for(i=0; i<p->pSrc->nSrc; i++){ SrcItem *pItem = &p->pSrc->a[i]; + assert( pItem->zName!=0 || pItem->pSelect!=0 );/* Test of tag-20240424-1*/ if( pItem->pSelect && (pItem->pSelect->selFlags & SF_Resolved)==0 ){ int nRef = pOuterNC ? pOuterNC->nRef : 0; const char *zSavedContext = pParse->zAuthContext; diff --git a/src/select.c b/src/select.c index fdc7f5e..9278ea1 100644 --- a/src/select.c +++ b/src/select.c @@ -1673,9 +1673,16 @@ static void generateSortTail( int addrExplain; /* Address of OP_Explain instruction */ #endif - ExplainQueryPlan2(addrExplain, (pParse, 0, - "USE TEMP B-TREE FOR %sORDER BY", pSort->nOBSat>0?"RIGHT PART OF ":"") - ); + nKey = pOrderBy->nExpr - pSort->nOBSat; + if( pSort->nOBSat==0 || nKey==1 ){ + ExplainQueryPlan2(addrExplain, (pParse, 0, + "USE TEMP B-TREE FOR %sORDER BY", pSort->nOBSat?"LAST TERM OF ":"" + )); + }else{ + ExplainQueryPlan2(addrExplain, (pParse, 0, + "USE TEMP B-TREE FOR LAST %d TERMS OF ORDER BY", nKey + )); + } sqlite3VdbeScanStatusRange(v, addrExplain,pSort->addrPush,pSort->addrPushEnd); sqlite3VdbeScanStatusCounters(v, addrExplain, addrExplain, pSort->addrPush); @@ -1713,7 +1720,6 @@ static void generateSortTail( regRow = sqlite3GetTempRange(pParse, nColumn); } } - nKey = pOrderBy->nExpr - pSort->nOBSat; if( pSort->sortFlags & SORTFLAG_UseSorter ){ int regSortOut = ++pParse->nMem; iSortTab = pParse->nTab++; @@ -2318,8 +2324,7 @@ void sqlite3SubqueryColumnTypes( NameContext sNC; assert( pSelect!=0 ); - testcase( (pSelect->selFlags & SF_Resolved)==0 ); - assert( (pSelect->selFlags & SF_Resolved)!=0 || IN_RENAME_OBJECT ); + assert( (pSelect->selFlags & SF_Resolved)!=0 ); assert( pTab->nCol==pSelect->pEList->nExpr || pParse->nErr>0 ); assert( aff==SQLITE_AFF_NONE || aff==SQLITE_AFF_BLOB ); if( db->mallocFailed || IN_RENAME_OBJECT ) return; @@ -2330,17 +2335,22 @@ void sqlite3SubqueryColumnTypes( for(i=0, pCol=pTab->aCol; i<pTab->nCol; i++, pCol++){ const char *zType; i64 n; + int m = 0; + Select *pS2 = pSelect; pTab->tabFlags |= (pCol->colFlags & COLFLAG_NOINSERT); p = a[i].pExpr; /* pCol->szEst = ... // Column size est for SELECT tables never used */ pCol->affinity = sqlite3ExprAffinity(p); + while( pCol->affinity<=SQLITE_AFF_NONE && pS2->pNext!=0 ){ + m |= sqlite3ExprDataType(pS2->pEList->a[i].pExpr); + pS2 = pS2->pNext; + pCol->affinity = sqlite3ExprAffinity(pS2->pEList->a[i].pExpr); + } if( pCol->affinity<=SQLITE_AFF_NONE ){ pCol->affinity = aff; } - if( pCol->affinity>=SQLITE_AFF_TEXT && pSelect->pNext ){ - int m = 0; - Select *pS2; - for(m=0, pS2=pSelect->pNext; pS2; pS2=pS2->pNext){ + if( pCol->affinity>=SQLITE_AFF_TEXT && (pS2->pNext || pS2!=pSelect) ){ + for(pS2=pS2->pNext; pS2; pS2=pS2->pNext){ m |= sqlite3ExprDataType(pS2->pEList->a[i].pExpr); } if( pCol->affinity==SQLITE_AFF_TEXT && (m&0x01)!=0 ){ @@ -2370,12 +2380,12 @@ void sqlite3SubqueryColumnTypes( } } if( zType ){ - i64 m = sqlite3Strlen30(zType); + const i64 k = sqlite3Strlen30(zType); n = sqlite3Strlen30(pCol->zCnName); - pCol->zCnName = sqlite3DbReallocOrFree(db, pCol->zCnName, n+m+2); + pCol->zCnName = sqlite3DbReallocOrFree(db, pCol->zCnName, n+k+2); pCol->colFlags &= ~(COLFLAG_HASTYPE|COLFLAG_HASCOLL); if( pCol->zCnName ){ - memcpy(&pCol->zCnName[n+1], zType, m+1); + memcpy(&pCol->zCnName[n+1], zType, k+1); pCol->colFlags |= COLFLAG_HASTYPE; } } @@ -4772,7 +4782,7 @@ static void constInsert( ){ int i; assert( pColumn->op==TK_COLUMN ); - assert( sqlite3ExprIsConstant(pValue) ); + assert( sqlite3ExprIsConstant(pConst->pParse, pValue) ); if( ExprHasProperty(pColumn, EP_FixedCol) ) return; if( sqlite3ExprAffinity(pValue)!=0 ) return; @@ -4830,10 +4840,10 @@ static void findConstInWhere(WhereConst *pConst, Expr *pExpr){ pLeft = pExpr->pLeft; assert( pRight!=0 ); assert( pLeft!=0 ); - if( pRight->op==TK_COLUMN && sqlite3ExprIsConstant(pLeft) ){ + if( pRight->op==TK_COLUMN && sqlite3ExprIsConstant(pConst->pParse, pLeft) ){ constInsert(pConst,pRight,pLeft,pExpr); } - if( pLeft->op==TK_COLUMN && sqlite3ExprIsConstant(pRight) ){ + if( pLeft->op==TK_COLUMN && sqlite3ExprIsConstant(pConst->pParse, pRight) ){ constInsert(pConst,pLeft,pRight,pExpr); } } @@ -5054,6 +5064,18 @@ static int pushDownWindowCheck(Parse *pParse, Select *pSubq, Expr *pExpr){ ** The hope is that the terms added to the inner query will make it more ** efficient. ** +** NAME AMBIGUITY +** +** This optimization is called the "WHERE-clause push-down optimization". +** +** Do not confuse this optimization with another unrelated optimization +** with a similar name: The "MySQL push-down optimization" causes WHERE +** clause terms that can be evaluated using only the index and without +** reference to the table are run first, so that if they are false, +** unnecessary table seeks are avoided. +** +** RULES +** ** Do not attempt this optimization if: ** ** (1) (** This restriction was removed on 2017-09-29. We used to @@ -5119,10 +5141,10 @@ static int pushDownWindowCheck(Parse *pParse, Select *pSubq, Expr *pExpr){ ** (9c) There is a RIGHT JOIN (or FULL JOIN) in between the ON/USING ** clause and the subquery. ** -** Without this restriction, the push-down optimization might move -** the ON/USING filter expression from the left side of a RIGHT JOIN -** over to the right side, which leads to incorrect answers. See -** also restriction (6) in sqlite3ExprIsSingleTableConstraint(). +** Without this restriction, the WHERE-clause push-down optimization +** might move the ON/USING filter expression from the left side of a +** RIGHT JOIN over to the right side, which leads to incorrect answers. +** See also restriction (6) in sqlite3ExprIsSingleTableConstraint(). ** ** (10) The inner query is not the right-hand table of a RIGHT JOIN. ** @@ -5254,7 +5276,7 @@ static int pushDownWhereTerms( } #endif - if( sqlite3ExprIsSingleTableConstraint(pWhere, pSrcList, iSrc) ){ + if( sqlite3ExprIsSingleTableConstraint(pWhere, pSrcList, iSrc, 1) ){ nChng++; pSubq->selFlags |= SF_PushDown; while( pSubq ){ @@ -6389,8 +6411,7 @@ static void selectAddSubqueryTypeInfo(Walker *pWalker, Select *p){ if( p->selFlags & SF_HasTypeInfo ) return; p->selFlags |= SF_HasTypeInfo; pParse = pWalker->pParse; - testcase( (p->selFlags & SF_Resolved)==0 ); - assert( (p->selFlags & SF_Resolved) || IN_RENAME_OBJECT ); + assert( (p->selFlags & SF_Resolved) ); pTabList = p->pSrc; for(i=0, pFrom=pTabList->a; i<pTabList->nSrc; i++, pFrom++){ Table *pTab = pFrom->pTab; @@ -6460,6 +6481,8 @@ void sqlite3SelectPrep( */ static void printAggInfo(AggInfo *pAggInfo){ int ii; + sqlite3DebugPrintf("AggInfo %d/%p:\n", + pAggInfo->selId, pAggInfo); for(ii=0; ii<pAggInfo->nColumn; ii++){ struct AggInfo_col *pCol = &pAggInfo->aCol[ii]; sqlite3DebugPrintf( @@ -7650,7 +7673,7 @@ int sqlite3Select( /* Generate code for all sub-queries in the FROM clause */ pSub = pItem->pSelect; - if( pSub==0 ) continue; + if( pSub==0 || pItem->addrFillSub!=0 ) continue; /* The code for a subquery should only be generated once. */ assert( pItem->addrFillSub==0 ); @@ -7681,7 +7704,7 @@ int sqlite3Select( #endif assert( pItem->pSelect && (pItem->pSelect->selFlags & SF_PushDown)!=0 ); }else{ - TREETRACE(0x4000,pParse,p,("Push-down not possible\n")); + TREETRACE(0x4000,pParse,p,("WHERE-lcause push-down not possible\n")); } /* Convert unused result columns of the subquery into simple NULL @@ -8562,6 +8585,12 @@ select_end: sqlite3ExprListDelete(db, pMinMaxOrderBy); #ifdef SQLITE_DEBUG if( pAggInfo && !db->mallocFailed ){ +#if TREETRACE_ENABLED + if( sqlite3TreeTrace & 0x20 ){ + TREETRACE(0x20,pParse,p,("Finished with AggInfo\n")); + printAggInfo(pAggInfo); + } +#endif for(i=0; i<pAggInfo->nColumn; i++){ Expr *pExpr = pAggInfo->aCol[i].pCExpr; if( pExpr==0 ) continue; diff --git a/src/shell.c.in b/src/shell.c.in index 1220b42..0029682 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -268,6 +268,9 @@ INCLUDE ../ext/consio/console_io.c * setOutputStream(FILE *pf) * This is normally the stream that CLI normal output goes to. * For the stand-alone CLI, it is stdout with no .output redirect. + * + * The ?putz(z) forms are required for the Fiddle builds for string literal + * output, in aid of enforcing format string to argument correspondence. */ # define sputz(s,z) fPutsUtf8(z,s) # define sputf fPrintfUtf8 @@ -279,12 +282,18 @@ INCLUDE ../ext/consio/console_io.c #else /* For Fiddle, all console handling and emit redirection is omitted. */ -# define sputz(fp,z) fputs(z,fp) +/* These next 3 macros are for emitting formatted output. When complaints + * from the WASM build are issued for non-formatted output, (when a mere + * string literal is to be emitted, the ?putz(z) forms should be used. + * (This permits compile-time checking of format string / argument mismatch.) + */ +# define oputf(fmt, ...) printf(fmt,__VA_ARGS__) +# define eputf(fmt, ...) fprintf(stderr,fmt,__VA_ARGS__) # define sputf(fp,fmt, ...) fprintf(fp,fmt,__VA_ARGS__) +/* These next 3 macros are for emitting simple string literals. */ # define oputz(z) fputs(z,stdout) -# define oputf(fmt, ...) printf(fmt,__VA_ARGS__) # define eputz(z) fputs(z,stderr) -# define eputf(fmt, ...) fprintf(stderr,fmt,__VA_ARGS__) +# define sputz(fp,z) fputs(z,fp) # define oputb(buf,na) fwrite(buf,1,na,stdout) #endif @@ -1213,6 +1222,9 @@ INCLUDE ../ext/misc/sqlar.c INCLUDE ../ext/expert/sqlite3expert.h INCLUDE ../ext/expert/sqlite3expert.c +INCLUDE ../ext/intck/sqlite3intck.h +INCLUDE ../ext/intck/sqlite3intck.c + #if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB) #define SQLITE_SHELL_HAVE_RECOVER 1 #else @@ -4732,6 +4744,7 @@ static const char *(azHelp[]) = { ".indexes ?TABLE? Show names of indexes", " If TABLE is specified, only show indexes for", " tables matching TABLE using the LIKE operator.", + ".intck ?STEPS_PER_UNLOCK? Run an incremental integrity check on the db", #ifdef SQLITE_ENABLE_IOTRACE ",iotrace FILE Enable I/O diagnostic logging to FILE", #endif @@ -7641,6 +7654,40 @@ static int recoverDatabaseCmd(ShellState *pState, int nArg, char **azArg){ } #endif /* SQLITE_SHELL_HAVE_RECOVER */ +/* +** Implementation of ".intck STEPS_PER_UNLOCK" command. +*/ +static int intckDatabaseCmd(ShellState *pState, i64 nStepPerUnlock){ + sqlite3_intck *p = 0; + int rc = SQLITE_OK; + + rc = sqlite3_intck_open(pState->db, "main", &p); + if( rc==SQLITE_OK ){ + i64 nStep = 0; + i64 nError = 0; + const char *zErr = 0; + while( SQLITE_OK==sqlite3_intck_step(p) ){ + const char *zMsg = sqlite3_intck_message(p); + if( zMsg ){ + oputf("%s\n", zMsg); + nError++; + } + nStep++; + if( nStepPerUnlock && (nStep % nStepPerUnlock)==0 ){ + sqlite3_intck_unlock(p); + } + } + rc = sqlite3_intck_error(p, &zErr); + if( zErr ){ + eputf("%s\n", zErr); + } + sqlite3_intck_close(p); + + oputf("%lld steps, %lld errors\n", nStep, nError); + } + + return rc; +} /* * zAutoColumn(zCol, &db, ?) => Maybe init db, add column zCol to it. @@ -7885,6 +7932,45 @@ static int outputDumpWarning(ShellState *p, const char *zLike){ } /* +** Fault-Simulator state and logic. +*/ +static struct { + int iId; /* ID that triggers a simulated fault. -1 means "any" */ + int iErr; /* The error code to return on a fault */ + int iCnt; /* Trigger the fault only if iCnt is already zero */ + int iInterval; /* Reset iCnt to this value after each fault */ + int eVerbose; /* When to print output */ + int nHit; /* Number of hits seen so far */ + int nRepeat; /* Turn off after this many hits. 0 for never */ + int nSkip; /* Skip this many before first fault */ +} faultsim_state = {-1, 0, 0, 0, 0, 0, 0, 0}; + +/* +** This is the fault-sim callback +*/ +static int faultsim_callback(int iArg){ + if( faultsim_state.iId>0 && faultsim_state.iId!=iArg ){ + return SQLITE_OK; + } + if( faultsim_state.iCnt ){ + if( faultsim_state.iCnt>0 ) faultsim_state.iCnt--; + if( faultsim_state.eVerbose>=2 ){ + oputf("FAULT-SIM id=%d no-fault (cnt=%d)\n", iArg, faultsim_state.iCnt); + } + return SQLITE_OK; + } + if( faultsim_state.eVerbose>=1 ){ + oputf("FAULT-SIM id=%d returns %d\n", iArg, faultsim_state.iErr); + } + faultsim_state.iCnt = faultsim_state.iInterval; + faultsim_state.nHit++; + if( faultsim_state.nRepeat>0 && faultsim_state.nRepeat<=faultsim_state.nHit ){ + faultsim_state.iCnt = -1; + } + return faultsim_state.iErr; +} + +/* ** If an input line begins with "." then invoke this routine to ** process that line. ** @@ -8375,7 +8461,8 @@ static int do_meta_command(char *zLine, ShellState *p){ zSql = sqlite3_mprintf( "SELECT sql FROM sqlite_schema AS o " "WHERE (%s) AND sql NOT NULL" - " AND type IN ('index','trigger','view')", + " AND type IN ('index','trigger','view') " + "ORDER BY type COLLATE NOCASE DESC", zLike ); run_table_dump_query(p, zSql); @@ -9110,6 +9197,21 @@ static int do_meta_command(char *zLine, ShellState *p){ }else #endif /* !defined(SQLITE_OMIT_TEST_CONTROL) */ + if( c=='i' && cli_strncmp(azArg[0], "intck", n)==0 ){ + i64 iArg = 0; + if( nArg==2 ){ + iArg = integerValue(azArg[1]); + if( iArg==0 ) iArg = -1; + } + if( (nArg!=1 && nArg!=2) || iArg<0 ){ + eputf("%s","Usage: .intck STEPS_PER_UNLOCK\n"); + rc = 1; + goto meta_command_exit; + } + open_db(p, 0); + rc = intckDatabaseCmd(p, iArg); + }else + #ifdef SQLITE_ENABLE_IOTRACE if( c=='i' && cli_strncmp(azArg[0], "iotrace", n)==0 ){ SQLITE_API extern void (SQLITE_CDECL *sqlite3IoTrace)(const char*, ...); @@ -10783,7 +10885,7 @@ static int do_meta_command(char *zLine, ShellState *p){ /*{"bitvec_test", SQLITE_TESTCTRL_BITVEC_TEST, 1, "" },*/ {"byteorder", SQLITE_TESTCTRL_BYTEORDER, 0, "" }, {"extra_schema_checks",SQLITE_TESTCTRL_EXTRA_SCHEMA_CHECKS,0,"BOOLEAN" }, - /*{"fault_install", SQLITE_TESTCTRL_FAULT_INSTALL, 1,"" },*/ + {"fault_install", SQLITE_TESTCTRL_FAULT_INSTALL, 1,"args..." }, {"fk_no_action", SQLITE_TESTCTRL_FK_NO_ACTION, 0, "BOOLEAN" }, {"imposter", SQLITE_TESTCTRL_IMPOSTER,1,"SCHEMA ON/OFF ROOTPAGE"}, {"internal_functions", SQLITE_TESTCTRL_INTERNAL_FUNCTIONS,0,"" }, @@ -11016,6 +11118,76 @@ static int do_meta_command(char *zLine, ShellState *p){ } sqlite3_test_control(testctrl, &rc2); break; + case SQLITE_TESTCTRL_FAULT_INSTALL: { + int kk; + int bShowHelp = nArg<=2; + isOk = 3; + for(kk=2; kk<nArg; kk++){ + const char *z = azArg[kk]; + if( z[0]=='-' && z[1]=='-' ) z++; + if( cli_strcmp(z,"off")==0 ){ + sqlite3_test_control(testctrl, 0); + }else if( cli_strcmp(z,"on")==0 ){ + faultsim_state.iCnt = faultsim_state.nSkip; + if( faultsim_state.iErr==0 ) faultsim_state.iErr = 1; + faultsim_state.nHit = 0; + sqlite3_test_control(testctrl, faultsim_callback); + }else if( cli_strcmp(z,"reset")==0 ){ + faultsim_state.iCnt = faultsim_state.nSkip; + faultsim_state.nHit = 0; + sqlite3_test_control(testctrl, faultsim_callback); + }else if( cli_strcmp(z,"status")==0 ){ + oputf("faultsim.iId: %d\n", faultsim_state.iId); + oputf("faultsim.iErr: %d\n", faultsim_state.iErr); + oputf("faultsim.iCnt: %d\n", faultsim_state.iCnt); + oputf("faultsim.nHit: %d\n", faultsim_state.nHit); + oputf("faultsim.iInterval: %d\n", faultsim_state.iInterval); + oputf("faultsim.eVerbose: %d\n", faultsim_state.eVerbose); + oputf("faultsim.nRepeat: %d\n", faultsim_state.nRepeat); + oputf("faultsim.nSkip: %d\n", faultsim_state.nSkip); + }else if( cli_strcmp(z,"-v")==0 ){ + if( faultsim_state.eVerbose<2 ) faultsim_state.eVerbose++; + }else if( cli_strcmp(z,"-q")==0 ){ + if( faultsim_state.eVerbose>0 ) faultsim_state.eVerbose--; + }else if( cli_strcmp(z,"-id")==0 && kk+1<nArg ){ + faultsim_state.iId = atoi(azArg[++kk]); + }else if( cli_strcmp(z,"-errcode")==0 && kk+1<nArg ){ + faultsim_state.iErr = atoi(azArg[++kk]); + }else if( cli_strcmp(z,"-interval")==0 && kk+1<nArg ){ + faultsim_state.iInterval = atoi(azArg[++kk]); + }else if( cli_strcmp(z,"-repeat")==0 && kk+1<nArg ){ + faultsim_state.nRepeat = atoi(azArg[++kk]); + }else if( cli_strcmp(z,"-skip")==0 && kk+1<nArg ){ + faultsim_state.nSkip = atoi(azArg[++kk]); + }else if( cli_strcmp(z,"-?")==0 || sqlite3_strglob("*help*",z)==0){ + bShowHelp = 1; + }else{ + eputf("Unrecognized fault_install argument: \"%s\"\n", + azArg[kk]); + rc = 1; + bShowHelp = 1; + break; + } + } + if( bShowHelp ){ + oputz( + "Usage: .testctrl fault_install ARGS\n" + "Possible arguments:\n" + " off Disable faultsim\n" + " on Activate faultsim\n" + " reset Reset the trigger counter\n" + " status Show current status\n" + " -v Increase verbosity\n" + " -q Decrease verbosity\n" + " --errcode N When triggered, return N as error code\n" + " --id ID Trigger only for the ID specified\n" + " --interval N Trigger only after every N-th call\n" + " --repeat N Turn off after N hits. 0 means never\n" + " --skip N Skip the first N encounters\n" + ); + } + break; + } } } if( isOk==0 && iCtrl>=0 ){ @@ -11938,7 +12110,7 @@ static void usage(int showDetail){ }else{ eputz("Use the -help option for additional information\n"); } - exit(1); + exit(0); } /* @@ -12638,6 +12810,11 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){ #ifndef SQLITE_SHELL_FIDDLE /* In WASM mode we have to leave the db state in place so that ** client code can "push" SQL into it after this call returns. */ +#ifndef SQLITE_OMIT_VIRTUALTABLE + if( data.expert.pExpert ){ + expertFinish(&data, 1, 0); + } +#endif free(azCmd); set_table_name(&data, 0); if( data.db ){ @@ -12704,7 +12881,7 @@ sqlite3_vfs * fiddle_db_vfs(const char *zDbName){ /* Only for emcc experimentation purposes. */ sqlite3 * fiddle_db_arg(sqlite3 *arg){ - printf("fiddle_db_arg(%p)\n", (const void*)arg); + oputf("fiddle_db_arg(%p)\n", (const void*)arg); return arg; } @@ -12730,12 +12907,22 @@ const char * fiddle_db_filename(const char * zDbName){ /* ** Completely wipes out the contents of the currently-opened database -** but leaves its storage intact for reuse. +** but leaves its storage intact for reuse. If any transactions are +** active, they are forcibly rolled back. */ void fiddle_reset_db(void){ if( globalDb ){ - int rc = sqlite3_db_config(globalDb, SQLITE_DBCONFIG_RESET_DATABASE, 1, 0); - if( 0==rc ) rc = sqlite3_exec(globalDb, "VACUUM", 0, 0, 0); + int rc; + while( sqlite3_txn_state(globalDb,0)>0 ){ + /* + ** Resolve problem reported in + ** https://sqlite.org/forum/forumpost/0b41a25d65 + */ + oputz("Rolling back in-progress transaction.\n"); + sqlite3_exec(globalDb,"ROLLBACK", 0, 0, 0); + } + rc = sqlite3_db_config(globalDb, SQLITE_DBCONFIG_RESET_DATABASE, 1, 0); + if( 0==rc ) sqlite3_exec(globalDb, "VACUUM", 0, 0, 0); sqlite3_db_config(globalDb, SQLITE_DBCONFIG_RESET_DATABASE, 0, 0); } } diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 7acdde8..549b52a 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -764,11 +764,11 @@ struct sqlite3_file { ** </ul> ** xLock() upgrades the database file lock. In other words, xLock() moves the ** database file lock in the direction NONE toward EXCLUSIVE. The argument to -** xLock() is always on of SHARED, RESERVED, PENDING, or EXCLUSIVE, never +** xLock() is always one of SHARED, RESERVED, PENDING, or EXCLUSIVE, never ** SQLITE_LOCK_NONE. If the database file lock is already at or above the ** requested lock, then the call to xLock() is a no-op. ** xUnlock() downgrades the database file lock to either SHARED or NONE. -* If the lock is already at or below the requested lock state, then the call +** If the lock is already at or below the requested lock state, then the call ** to xUnlock() is a no-op. ** The xCheckReservedLock() method checks whether any database connection, ** either in this process or in some other process, is holding a RESERVED, @@ -3305,8 +3305,8 @@ int sqlite3_set_authorizer( #define SQLITE_RECURSIVE 33 /* NULL NULL */ /* -** CAPI3REF: Tracing And Profiling Functions -** METHOD: sqlite3 +** CAPI3REF: Deprecated Tracing And Profiling Functions +** DEPRECATED ** ** These routines are deprecated. Use the [sqlite3_trace_v2()] interface ** instead of the routines described here. @@ -6887,6 +6887,12 @@ int sqlite3_autovacuum_pages( ** The exceptions defined in this paragraph might change in a future ** release of SQLite. ** +** Whether the update hook is invoked before or after the +** corresponding change is currently unspecified and may differ +** depending on the type of change. Do not rely on the order of the +** hook call with regards to the final result of the operation which +** triggers the hook. +** ** The update hook implementation must not do anything that will modify ** the database connection that invoked the update hook. Any actions ** to modify the database connection must be deferred until after the @@ -8357,7 +8363,7 @@ int sqlite3_test_control(int op, ...); ** The sqlite3_keyword_count() interface returns the number of distinct ** keywords understood by SQLite. ** -** The sqlite3_keyword_name(N,Z,L) interface finds the N-th keyword and +** The sqlite3_keyword_name(N,Z,L) interface finds the 0-based N-th keyword and ** makes *Z point to that keyword expressed as UTF8 and writes the number ** of bytes in the keyword into *L. The string that *Z points to is not ** zero-terminated. The sqlite3_keyword_name(N,Z,L) routine returns @@ -9936,24 +9942,45 @@ const char *sqlite3_vtab_collation(sqlite3_index_info*,int); ** <li value="2"><p> ** ^(If the sqlite3_vtab_distinct() interface returns 2, that means ** that the query planner does not need the rows returned in any particular -** order, as long as rows with the same values in all "aOrderBy" columns -** are adjacent.)^ ^(Furthermore, only a single row for each particular -** combination of values in the columns identified by the "aOrderBy" field -** needs to be returned.)^ ^It is always ok for two or more rows with the same -** values in all "aOrderBy" columns to be returned, as long as all such rows -** are adjacent. ^The virtual table may, if it chooses, omit extra rows -** that have the same value for all columns identified by "aOrderBy". -** ^However omitting the extra rows is optional. +** order, as long as rows with the same values in all columns identified +** by "aOrderBy" are adjacent.)^ ^(Furthermore, when two or more rows +** contain the same values for all columns identified by "colUsed", all but +** one such row may optionally be omitted from the result.)^ +** The virtual table is not required to omit rows that are duplicates +** over the "colUsed" columns, but if the virtual table can do that without +** too much extra effort, it could potentially help the query to run faster. ** This mode is used for a DISTINCT query. ** <li value="3"><p> -** ^(If the sqlite3_vtab_distinct() interface returns 3, that means -** that the query planner needs only distinct rows but it does need the -** rows to be sorted.)^ ^The virtual table implementation is free to omit -** rows that are identical in all aOrderBy columns, if it wants to, but -** it is not required to omit any rows. This mode is used for queries +** ^(If the sqlite3_vtab_distinct() interface returns 3, that means the +** virtual table must return rows in the order defined by "aOrderBy" as +** if the sqlite3_vtab_distinct() interface had returned 0. However if +** two or more rows in the result have the same values for all columns +** identified by "colUsed", then all but one such row may optionally be +** omitted.)^ Like when the return value is 2, the virtual table +** is not required to omit rows that are duplicates over the "colUsed" +** columns, but if the virtual table can do that without +** too much extra effort, it could potentially help the query to run faster. +** This mode is used for queries ** that have both DISTINCT and ORDER BY clauses. ** </ol> ** +** <p>The following table summarizes the conditions under which the +** virtual table is allowed to set the "orderByConsumed" flag based on +** the value returned by sqlite3_vtab_distinct(). This table is a +** restatement of the previous four paragraphs: +** +** <table border=1 cellspacing=0 cellpadding=10 width="90%"> +** <tr> +** <td valign="top">sqlite3_vtab_distinct() return value +** <td valign="top">Rows are returned in aOrderBy order +** <td valign="top">Rows with the same value in all aOrderBy columns are adjacent +** <td valign="top">Duplicates over all colUsed columns may be omitted +** <tr><td>0<td>yes<td>yes<td>no +** <tr><td>1<td>no<td>yes<td>no +** <tr><td>2<td>no<td>yes<td>yes +** <tr><td>3<td>yes<td>yes<td>yes +** </table> +** ** ^For the purposes of comparing virtual table output values to see if the ** values are same value for sorting purposes, two NULL values are considered ** to be the same. In other words, the comparison operator is "IS" diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 933286b..d98a4f7 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -609,6 +609,8 @@ # define SQLITE_OMIT_ALTERTABLE #endif +#define SQLITE_DIGIT_SEPARATOR '_' + /* ** Return true (non-zero) if the input is an integer that is too large ** to fit in 32-bits. This macro is used inside of various testcase() @@ -886,7 +888,7 @@ typedef INT16_TYPE LogEst; # define SQLITE_PTRSIZE __SIZEOF_POINTER__ # elif defined(i386) || defined(__i386__) || defined(_M_IX86) || \ defined(_M_ARM) || defined(__arm__) || defined(__x86) || \ - (defined(__APPLE__) && defined(__POWERPC__)) || \ + (defined(__APPLE__) && defined(__ppc__)) || \ (defined(__TOS_AIX__) && !defined(__64BIT__)) # define SQLITE_PTRSIZE 4 # else @@ -1154,7 +1156,7 @@ extern u32 sqlite3WhereTrace; ** 0x00000010 Display sqlite3_index_info xBestIndex calls ** 0x00000020 Range an equality scan metrics ** 0x00000040 IN operator decisions -** 0x00000080 WhereLoop cost adjustements +** 0x00000080 WhereLoop cost adjustments ** 0x00000100 ** 0x00000200 Covering index decisions ** 0x00000400 OR optimization @@ -1597,6 +1599,10 @@ struct FuncDefHash { }; #define SQLITE_FUNC_HASH(C,L) (((C)+(L))%SQLITE_FUNC_HASH_SZ) +#if defined(SQLITE_USER_AUTHENTICATION) +# warning "The SQLITE_USER_AUTHENTICATION extension is deprecated. \ + See ext/userauth/user-auth.txt for details." +#endif #ifdef SQLITE_USER_AUTHENTICATION /* ** Information held in the "sqlite3" database connection object and used @@ -1900,7 +1906,7 @@ struct sqlite3 { #define SQLITE_CursorHints 0x00000400 /* Add OP_CursorHint opcodes */ #define SQLITE_Stat4 0x00000800 /* Use STAT4 data */ /* TH3 expects this value ^^^^^^^^^^ to be 0x0000800. Don't change it */ -#define SQLITE_PushDown 0x00001000 /* The push-down optimization */ +#define SQLITE_PushDown 0x00001000 /* WHERE-clause push-down opt */ #define SQLITE_SimplifyJoin 0x00002000 /* Convert LEFT JOIN to JOIN */ #define SQLITE_SkipScan 0x00004000 /* Skip-scans */ #define SQLITE_PropagateConst 0x00008000 /* The constant propagation opt */ @@ -2473,8 +2479,7 @@ struct Table { #define TF_HasStored 0x00000040 /* Has one or more STORED columns */ #define TF_HasGenerated 0x00000060 /* Combo: HasVirtual + HasStored */ #define TF_WithoutRowid 0x00000080 /* No rowid. PRIMARY KEY is the key */ -#define TF_StatsUsed 0x00000100 /* Query planner decisions affected by - ** Index.aiRowLogEst[] values */ +#define TF_MaybeReanalyze 0x00000100 /* Maybe run ANALYZE on this table */ #define TF_NoVisibleRowid 0x00000200 /* No user-visible "rowid" column */ #define TF_OOOHidden 0x00000400 /* Out-of-Order hidden columns */ #define TF_HasNotNull 0x00000800 /* Contains NOT NULL constraints */ @@ -3274,10 +3279,12 @@ struct IdList { ** ** Union member validity: ** -** u1.zIndexedBy fg.isIndexedBy && !fg.isTabFunc -** u1.pFuncArg fg.isTabFunc && !fg.isIndexedBy -** u2.pIBIndex fg.isIndexedBy && !fg.isCte -** u2.pCteUse fg.isCte && !fg.isIndexedBy +** u1.zIndexedBy fg.isIndexedBy && !fg.isTabFunc +** u1.pFuncArg fg.isTabFunc && !fg.isIndexedBy +** u1.nRow !fg.isTabFunc && !fg.isIndexedBy +** +** u2.pIBIndex fg.isIndexedBy && !fg.isCte +** u2.pCteUse fg.isCte && !fg.isIndexedBy */ struct SrcItem { Schema *pSchema; /* Schema to which this item is fixed */ @@ -3305,6 +3312,7 @@ struct SrcItem { unsigned isOn :1; /* u3.pOn was once valid and non-NULL */ unsigned isSynthUsing :1; /* u3.pUsing is synthesized from NATURAL */ unsigned isNestedFrom :1; /* pSelect is a SF_NestedFrom subquery */ + unsigned rowidUsed :1; /* The ROWID of this table is referenced */ } fg; int iCursor; /* The VDBE cursor number used to access this table */ union { @@ -3315,6 +3323,7 @@ struct SrcItem { union { char *zIndexedBy; /* Identifier from "INDEXED BY <zIndex>" clause */ ExprList *pFuncArg; /* Arguments to table-valued-function */ + u32 nRow; /* Number of rows in a VALUES clause */ } u1; union { Index *pIBIndex; /* Index structure corresponding to u1.zIndexedBy */ @@ -3572,11 +3581,12 @@ struct Select { #define SF_View 0x0200000 /* SELECT statement is a view */ #define SF_NoopOrderBy 0x0400000 /* ORDER BY is ignored for this query */ #define SF_UFSrcCheck 0x0800000 /* Check pSrc as required by UPDATE...FROM */ -#define SF_PushDown 0x1000000 /* SELECT has be modified by push-down opt */ +#define SF_PushDown 0x1000000 /* Modified by WHERE-clause push-down opt */ #define SF_MultiPart 0x2000000 /* Has multiple incompatible PARTITIONs */ #define SF_CopyCte 0x4000000 /* SELECT statement is a copy of a CTE */ #define SF_OrderByReqd 0x8000000 /* The ORDER BY clause may not be omitted */ #define SF_UpdateFrom 0x10000000 /* Query originates with UPDATE FROM */ +#define SF_Correlated 0x20000000 /* True if references the outer context */ /* True if S exists and has SF_NestedFrom */ #define IsNestedFrom(S) ((S)!=0 && ((S)->selFlags&SF_NestedFrom)!=0) @@ -3816,6 +3826,7 @@ struct Parse { u8 disableLookaside; /* Number of times lookaside has been disabled */ u8 prepFlags; /* SQLITE_PREPARE_* flags */ u8 withinRJSubrtn; /* Nesting level for RIGHT JOIN body subroutines */ + u8 bHasWith; /* True if statement contains WITH */ #if defined(SQLITE_DEBUG) || defined(SQLITE_COVERAGE_TEST) u8 earlyCleanup; /* OOM inside sqlite3ParserAddCleanup() */ #endif @@ -4495,6 +4506,9 @@ struct Window { ** due to the SQLITE_SUBTYPE flag */ }; +Select *sqlite3MultiValues(Parse *pParse, Select *pLeft, ExprList *pRow); +void sqlite3MultiValuesEnd(Parse *pParse, Select *pVal); + #ifndef SQLITE_OMIT_WINDOWFUNC void sqlite3WindowDelete(sqlite3*, Window*); void sqlite3WindowUnlinkFromSelect(Window*); @@ -4812,6 +4826,7 @@ int sqlite3ErrorToParser(sqlite3*,int); void sqlite3Dequote(char*); void sqlite3DequoteExpr(Expr*); void sqlite3DequoteToken(Token*); +void sqlite3DequoteNumber(Parse*, Expr*); void sqlite3TokenInit(Token*,char*); int sqlite3KeywordCode(const unsigned char*, int); int sqlite3RunParser(Parse*, const char*); @@ -4842,7 +4857,7 @@ void sqlite3ExprFunctionUsable(Parse*,const Expr*,const FuncDef*); void sqlite3ExprAssignVarNumber(Parse*, Expr*, u32); void sqlite3ExprDelete(sqlite3*, Expr*); void sqlite3ExprDeleteGeneric(sqlite3*,void*); -void sqlite3ExprDeferredDelete(Parse*, Expr*); +int sqlite3ExprDeferredDelete(Parse*, Expr*); void sqlite3ExprUnmapAndDelete(Parse*, Expr*); ExprList *sqlite3ExprListAppend(Parse*,ExprList*,Expr*); ExprList *sqlite3ExprListAppendVector(Parse*,ExprList*,IdList*,Expr*); @@ -5065,12 +5080,10 @@ void sqlite3LeaveMutexAndCloseZombie(sqlite3*); u32 sqlite3IsTrueOrFalse(const char*); int sqlite3ExprIdToTrueFalse(Expr*); int sqlite3ExprTruthValue(const Expr*); -int sqlite3ExprIsConstant(Expr*); -int sqlite3ExprIsConstantNotJoin(Expr*); +int sqlite3ExprIsConstant(Parse*,Expr*); int sqlite3ExprIsConstantOrFunction(Expr*, u8); int sqlite3ExprIsConstantOrGroupBy(Parse*, Expr*, ExprList*); -int sqlite3ExprIsTableConstant(Expr*,int); -int sqlite3ExprIsSingleTableConstraint(Expr*,const SrcList*,int); +int sqlite3ExprIsSingleTableConstraint(Expr*,const SrcList*,int,int); #ifdef SQLITE_ENABLE_CURSOR_HINTS int sqlite3ExprContainsSubquery(Expr*); #endif @@ -5255,7 +5268,9 @@ void sqlite3ErrorWithMsg(sqlite3*, int, const char*,...); void sqlite3Error(sqlite3*,int); void sqlite3ErrorClear(sqlite3*); void sqlite3SystemError(sqlite3*,int); +#if !defined(SQLITE_OMIT_BLOB_LITERAL) void *sqlite3HexToBlob(sqlite3*, const char *z, int n); +#endif u8 sqlite3HexToInt(int h); int sqlite3TwoPartName(Parse *, Token *, Token *, Token **); diff --git a/src/test_bestindex.c b/src/test_bestindex.c index 8128530..0e1e86a 100644 --- a/src/test_bestindex.c +++ b/src/test_bestindex.c @@ -215,6 +215,9 @@ static int tclConnect( rc = SQLITE_ERROR; }else{ rc = sqlite3_declare_vtab(db, Tcl_GetStringResult(interp)); + if( rc!=SQLITE_OK ){ + *pzErr = sqlite3_mprintf("declare_vtab: %s", sqlite3_errmsg(db)); + } } if( rc!=SQLITE_OK ){ @@ -226,7 +229,7 @@ static int tclConnect( } sqlite3_free(zCmd); - *ppVtab = &pTab->base; + *ppVtab = pTab ? &pTab->base : 0; return rc; } diff --git a/src/test_tclsh.c b/src/test_tclsh.c index 32aee42..4697c3b 100644 --- a/src/test_tclsh.c +++ b/src/test_tclsh.c @@ -108,6 +108,7 @@ const char *sqlite3TestInit(Tcl_Interp *interp){ extern int Sqlitetest_window_Init(Tcl_Interp *); extern int Sqlitetestvdbecov_Init(Tcl_Interp *); extern int TestRecover_Init(Tcl_Interp*); + extern int Sqlitetestintck_Init(Tcl_Interp*); Tcl_CmdInfo cmdInfo; @@ -175,6 +176,7 @@ const char *sqlite3TestInit(Tcl_Interp *interp){ Sqlitetest_window_Init(interp); Sqlitetestvdbecov_Init(interp); TestRecover_Init(interp); + Sqlitetestintck_Init(interp); Tcl_CreateObjCommand( interp, "load_testfixture_extensions", load_testfixture_extensions,0,0 diff --git a/src/tokenize.c b/src/tokenize.c index f4d013d..65d1fbf 100644 --- a/src/tokenize.c +++ b/src/tokenize.c @@ -437,27 +437,58 @@ int sqlite3GetToken(const unsigned char *z, int *tokenType){ *tokenType = TK_INTEGER; #ifndef SQLITE_OMIT_HEX_INTEGER if( z[0]=='0' && (z[1]=='x' || z[1]=='X') && sqlite3Isxdigit(z[2]) ){ - for(i=3; sqlite3Isxdigit(z[i]); i++){} - return i; - } + for(i=3; 1; i++){ + if( sqlite3Isxdigit(z[i])==0 ){ + if( z[i]==SQLITE_DIGIT_SEPARATOR ){ + *tokenType = TK_QNUMBER; + }else{ + break; + } + } + } + }else #endif - for(i=0; sqlite3Isdigit(z[i]); i++){} + { + for(i=0; 1; i++){ + if( sqlite3Isdigit(z[i])==0 ){ + if( z[i]==SQLITE_DIGIT_SEPARATOR ){ + *tokenType = TK_QNUMBER; + }else{ + break; + } + } + } #ifndef SQLITE_OMIT_FLOATING_POINT - if( z[i]=='.' ){ - i++; - while( sqlite3Isdigit(z[i]) ){ i++; } - *tokenType = TK_FLOAT; - } - if( (z[i]=='e' || z[i]=='E') && - ( sqlite3Isdigit(z[i+1]) - || ((z[i+1]=='+' || z[i+1]=='-') && sqlite3Isdigit(z[i+2])) - ) - ){ - i += 2; - while( sqlite3Isdigit(z[i]) ){ i++; } - *tokenType = TK_FLOAT; - } + if( z[i]=='.' ){ + if( *tokenType==TK_INTEGER ) *tokenType = TK_FLOAT; + for(i++; 1; i++){ + if( sqlite3Isdigit(z[i])==0 ){ + if( z[i]==SQLITE_DIGIT_SEPARATOR ){ + *tokenType = TK_QNUMBER; + }else{ + break; + } + } + } + } + if( (z[i]=='e' || z[i]=='E') && + ( sqlite3Isdigit(z[i+1]) + || ((z[i+1]=='+' || z[i+1]=='-') && sqlite3Isdigit(z[i+2])) + ) + ){ + if( *tokenType==TK_INTEGER ) *tokenType = TK_FLOAT; + for(i+=2; 1; i++){ + if( sqlite3Isdigit(z[i])==0 ){ + if( z[i]==SQLITE_DIGIT_SEPARATOR ){ + *tokenType = TK_QNUMBER; + }else{ + break; + } + } + } + } #endif + } while( IdChar(z[i]) ){ *tokenType = TK_ILLEGAL; i++; @@ -622,10 +653,13 @@ int sqlite3RunParser(Parse *pParse, const char *zSql){ if( tokenType>=TK_WINDOW ){ assert( tokenType==TK_SPACE || tokenType==TK_OVER || tokenType==TK_FILTER || tokenType==TK_ILLEGAL || tokenType==TK_WINDOW + || tokenType==TK_QNUMBER ); #else if( tokenType>=TK_SPACE ){ - assert( tokenType==TK_SPACE || tokenType==TK_ILLEGAL ); + assert( tokenType==TK_SPACE || tokenType==TK_ILLEGAL + || tokenType==TK_QNUMBER + ); #endif /* SQLITE_OMIT_WINDOWFUNC */ if( AtomicLoad(&db->u1.isInterrupted) ){ pParse->rc = SQLITE_INTERRUPT; @@ -658,7 +692,7 @@ int sqlite3RunParser(Parse *pParse, const char *zSql){ assert( n==6 ); tokenType = analyzeFilterKeyword((const u8*)&zSql[6], lastTokenParsed); #endif /* SQLITE_OMIT_WINDOWFUNC */ - }else{ + }else if( tokenType!=TK_QNUMBER ){ Token x; x.z = zSql; x.n = n; diff --git a/src/treeview.c b/src/treeview.c index 2576532..fa9eac6 100644 --- a/src/treeview.c +++ b/src/treeview.c @@ -194,8 +194,10 @@ void sqlite3TreeViewSrcList(TreeView *pView, const SrcList *pSrc){ x.printfFlags |= SQLITE_PRINTF_INTERNAL; sqlite3_str_appendf(&x, "{%d:*} %!S", pItem->iCursor, pItem); if( pItem->pTab ){ - sqlite3_str_appendf(&x, " tab=%Q nCol=%d ptr=%p used=%llx", - pItem->pTab->zName, pItem->pTab->nCol, pItem->pTab, pItem->colUsed); + sqlite3_str_appendf(&x, " tab=%Q nCol=%d ptr=%p used=%llx%s", + pItem->pTab->zName, pItem->pTab->nCol, pItem->pTab, + pItem->colUsed, + pItem->fg.rowidUsed ? "+rowid" : ""); } if( (pItem->fg.jointype & (JT_LEFT|JT_RIGHT))==(JT_LEFT|JT_RIGHT) ){ sqlite3_str_appendf(&x, " FULL-OUTER-JOIN"); @@ -235,12 +237,14 @@ void sqlite3TreeViewSrcList(TreeView *pView, const SrcList *pSrc){ sqlite3TreeViewIdList(pView, pItem->u3.pUsing, (--n)>0, "USING"); } if( pItem->pSelect ){ + sqlite3TreeViewPush(&pView, i+1<pSrc->nSrc); if( pItem->pTab ){ Table *pTab = pItem->pTab; sqlite3TreeViewColumnList(pView, pTab->aCol, pTab->nCol, 1); } assert( (int)pItem->fg.isNestedFrom == IsNestedFrom(pItem->pSelect) ); sqlite3TreeViewSelect(pView, pItem->pSelect, (--n)>0); + sqlite3TreeViewPop(&pView); } if( pItem->fg.isTabFunc ){ sqlite3TreeViewExprList(pView, pItem->u1.pFuncArg, 0, "func-args:"); @@ -344,7 +348,7 @@ void sqlite3TreeViewSelect(TreeView *pView, const Select *p, u8 moreToFollow){ sqlite3TreeViewItem(pView, "LIMIT", (n--)>0); sqlite3TreeViewExpr(pView, p->pLimit->pLeft, p->pLimit->pRight!=0); if( p->pLimit->pRight ){ - sqlite3TreeViewItem(pView, "OFFSET", (n--)>0); + sqlite3TreeViewItem(pView, "OFFSET", 0); sqlite3TreeViewExpr(pView, p->pLimit->pRight, 0); sqlite3TreeViewPop(&pView); } diff --git a/src/trigger.c b/src/trigger.c index 97ca249..98e8da5 100644 --- a/src/trigger.c +++ b/src/trigger.c @@ -951,6 +951,72 @@ static ExprList *sqlite3ExpandReturning( return pNew; } +/* If the Expr node is a subquery or an EXISTS operator or an IN operator that +** uses a subquery, and if the subquery is SF_Correlated, then mark the +** expression as EP_VarSelect. +*/ +static int sqlite3ReturningSubqueryVarSelect(Walker *NotUsed, Expr *pExpr){ + UNUSED_PARAMETER(NotUsed); + if( ExprUseXSelect(pExpr) + && (pExpr->x.pSelect->selFlags & SF_Correlated)!=0 + ){ + testcase( ExprHasProperty(pExpr, EP_VarSelect) ); + ExprSetProperty(pExpr, EP_VarSelect); + } + return WRC_Continue; +} + + +/* +** If the SELECT references the table pWalker->u.pTab, then do two things: +** +** (1) Mark the SELECT as as SF_Correlated. +** (2) Set pWalker->eCode to non-zero so that the caller will know +** that (1) has happened. +*/ +static int sqlite3ReturningSubqueryCorrelated(Walker *pWalker, Select *pSelect){ + int i; + SrcList *pSrc; + assert( pSelect!=0 ); + pSrc = pSelect->pSrc; + assert( pSrc!=0 ); + for(i=0; i<pSrc->nSrc; i++){ + if( pSrc->a[i].pTab==pWalker->u.pTab ){ + testcase( pSelect->selFlags & SF_Correlated ); + pSelect->selFlags |= SF_Correlated; + pWalker->eCode = 1; + break; + } + } + return WRC_Continue; +} + +/* +** Scan the expression list that is the argument to RETURNING looking +** for subqueries that depend on the table which is being modified in the +** statement that is hosting the RETURNING clause (pTab). Mark all such +** subqueries as SF_Correlated. If the subqueries are part of an +** expression, mark the expression as EP_VarSelect. +** +** https://sqlite.org/forum/forumpost/2c83569ce8945d39 +*/ +static void sqlite3ProcessReturningSubqueries( + ExprList *pEList, + Table *pTab +){ + Walker w; + memset(&w, 0, sizeof(w)); + w.xExprCallback = sqlite3ExprWalkNoop; + w.xSelectCallback = sqlite3ReturningSubqueryCorrelated; + w.u.pTab = pTab; + sqlite3WalkExprList(&w, pEList); + if( w.eCode ){ + w.xExprCallback = sqlite3ReturningSubqueryVarSelect; + w.xSelectCallback = sqlite3SelectWalkNoop; + sqlite3WalkExprList(&w, pEList); + } +} + /* ** Generate code for the RETURNING trigger. Unlike other triggers ** that invoke a subprogram in the bytecode, the code for RETURNING @@ -987,6 +1053,7 @@ static void codeReturningTrigger( sSelect.pSrc = &sFrom; sFrom.nSrc = 1; sFrom.a[0].pTab = pTab; + sFrom.a[0].zName = pTab->zName; /* tag-20240424-1 */ sFrom.a[0].iCursor = -1; sqlite3SelectPrep(pParse, &sSelect, 0); if( pParse->nErr==0 ){ @@ -1013,6 +1080,7 @@ static void codeReturningTrigger( int i; int nCol = pNew->nExpr; int reg = pParse->nMem+1; + sqlite3ProcessReturningSubqueries(pNew, pTab); pParse->nMem += nCol+2; pReturning->iRetReg = reg; for(i=0; i<nCol; i++){ @@ -325,6 +325,44 @@ void sqlite3DequoteExpr(Expr *p){ } /* +** Expression p is a QNUMBER (quoted number). Dequote the value in p->u.zToken +** and set the type to INTEGER or FLOAT. "Quoted" integers or floats are those +** that contain '_' characters that must be removed before further processing. +*/ +void sqlite3DequoteNumber(Parse *pParse, Expr *p){ + assert( p!=0 || pParse->db->mallocFailed ); + if( p ){ + const char *pIn = p->u.zToken; + char *pOut = p->u.zToken; + int bHex = (pIn[0]=='0' && (pIn[1]=='x' || pIn[1]=='X')); + int iValue; + assert( p->op==TK_QNUMBER ); + p->op = TK_INTEGER; + do { + if( *pIn!=SQLITE_DIGIT_SEPARATOR ){ + *pOut++ = *pIn; + if( *pIn=='e' || *pIn=='E' || *pIn=='.' ) p->op = TK_FLOAT; + }else{ + if( (bHex==0 && (!sqlite3Isdigit(pIn[-1]) || !sqlite3Isdigit(pIn[1]))) + || (bHex==1 && (!sqlite3Isxdigit(pIn[-1]) || !sqlite3Isxdigit(pIn[1]))) + ){ + sqlite3ErrorMsg(pParse, "unrecognized token: \"%s\"", p->u.zToken); + } + } + }while( *pIn++ ); + if( bHex ) p->op = TK_INTEGER; + + /* tag-20240227-a: If after dequoting, the number is an integer that + ** fits in 32 bits, then it must be converted into EP_IntValue. Other + ** parts of the code expect this. See also tag-20240227-b. */ + if( p->op==TK_INTEGER && sqlite3GetInt32(p->u.zToken, &iValue) ){ + p->u.iValue = iValue; + p->flags |= EP_IntValue; + } + } +} + +/* ** If the input token p is quoted, try to adjust the token to remove ** the quotes. This is not always possible: ** @@ -1129,7 +1129,7 @@ case OP_Return: { /* in1 */ ** ** See also: EndCoroutine */ -case OP_InitCoroutine: { /* jump */ +case OP_InitCoroutine: { /* jump0 */ assert( pOp->p1>0 && pOp->p1<=(p->nMem+1 - p->nCursor) ); assert( pOp->p2>=0 && pOp->p2<p->nOp ); assert( pOp->p3>=0 && pOp->p3<p->nOp ); @@ -1152,7 +1152,9 @@ jump_to_p2: ** ** The instruction at the address in register P1 is a Yield. ** Jump to the P2 parameter of that Yield. -** After the jump, register P1 becomes undefined. +** After the jump, the value register P1 is left with a value +** such that subsequent OP_Yields go back to the this same +** OP_EndCoroutine instruction. ** ** See also: InitCoroutine */ @@ -1164,8 +1166,8 @@ case OP_EndCoroutine: { /* in1 */ pCaller = &aOp[pIn1->u.i]; assert( pCaller->opcode==OP_Yield ); assert( pCaller->p2>=0 && pCaller->p2<p->nOp ); + pIn1->u.i = (int)(pOp - p->aOp) - 1; pOp = &aOp[pCaller->p2 - 1]; - pIn1->flags = MEM_Undefined; break; } @@ -1182,7 +1184,7 @@ case OP_EndCoroutine: { /* in1 */ ** ** See also: InitCoroutine */ -case OP_Yield: { /* in1, jump */ +case OP_Yield: { /* in1, jump0 */ int pcDest; pIn1 = &aMem[pOp->p1]; assert( VdbeMemDynamic(pIn1)==0 ); @@ -1512,19 +1514,15 @@ case OP_Blob: { /* out2 */ break; } -/* Opcode: Variable P1 P2 * P4 * -** Synopsis: r[P2]=parameter(P1,P4) +/* Opcode: Variable P1 P2 * * * +** Synopsis: r[P2]=parameter(P1) ** ** Transfer the values of bound parameter P1 into register P2 -** -** If the parameter is named, then its name appears in P4. -** The P4 value is used by sqlite3_bind_parameter_name(). */ case OP_Variable: { /* out2 */ Mem *pVar; /* Value being transferred */ assert( pOp->p1>0 && pOp->p1<=p->nVar ); - assert( pOp->p4.z==0 || pOp->p4.z==sqlite3VListNumToName(p->pVList,pOp->p1) ); pVar = &p->aVar[pOp->p1 - 1]; if( sqlite3VdbeMemTooBig(pVar) ){ goto too_big; @@ -2045,7 +2043,7 @@ case OP_AddImm: { /* in1 */ ** without data loss, then jump immediately to P2, or if P2==0 ** raise an SQLITE_MISMATCH exception. */ -case OP_MustBeInt: { /* jump, in1 */ +case OP_MustBeInt: { /* jump0, in1 */ pIn1 = &aMem[pOp->p1]; if( (pIn1->flags & MEM_Int)==0 ){ applyAffinity(pIn1, SQLITE_AFF_NUMERIC, encoding); @@ -2086,7 +2084,7 @@ case OP_RealAffinity: { /* in1 */ } #endif -#ifndef SQLITE_OMIT_CAST +#if !defined(SQLITE_OMIT_CAST) && !defined(SQLITE_OMIT_ANALYZE) /* Opcode: Cast P1 P2 * * * ** Synopsis: affinity(r[P1]) ** @@ -3658,11 +3656,16 @@ case OP_MakeRecord: { switch( len ){ default: zPayload[7] = (u8)(v&0xff); v >>= 8; zPayload[6] = (u8)(v&0xff); v >>= 8; + /* no break */ deliberate_fall_through case 6: zPayload[5] = (u8)(v&0xff); v >>= 8; zPayload[4] = (u8)(v&0xff); v >>= 8; + /* no break */ deliberate_fall_through case 4: zPayload[3] = (u8)(v&0xff); v >>= 8; + /* no break */ deliberate_fall_through case 3: zPayload[2] = (u8)(v&0xff); v >>= 8; + /* no break */ deliberate_fall_through case 2: zPayload[1] = (u8)(v&0xff); v >>= 8; + /* no break */ deliberate_fall_through case 1: zPayload[0] = (u8)(v&0xff); } zPayload += len; @@ -4581,7 +4584,8 @@ case OP_SequenceTest: { ** is the only cursor opcode that works with a pseudo-table. ** ** P3 is the number of fields in the records that will be stored by -** the pseudo-table. +** the pseudo-table. If P2 is 0 or negative then the pseudo-cursor +** will return NULL for every column. */ case OP_OpenPseudo: { VdbeCursor *pCx; @@ -4724,10 +4728,10 @@ case OP_ColumnsUsed: { ** ** See also: Found, NotFound, SeekGt, SeekGe, SeekLt */ -case OP_SeekLT: /* jump, in3, group, ncycle */ -case OP_SeekLE: /* jump, in3, group, ncycle */ -case OP_SeekGE: /* jump, in3, group, ncycle */ -case OP_SeekGT: { /* jump, in3, group, ncycle */ +case OP_SeekLT: /* jump0, in3, group, ncycle */ +case OP_SeekLE: /* jump0, in3, group, ncycle */ +case OP_SeekGE: /* jump0, in3, group, ncycle */ +case OP_SeekGT: { /* jump0, in3, group, ncycle */ int res; /* Comparison result */ int oc; /* Opcode */ VdbeCursor *pC; /* The cursor to seek */ @@ -5394,7 +5398,7 @@ case OP_Found: { /* jump, in3, ncycle */ ** ** See also: Found, NotFound, NoConflict, SeekRowid */ -case OP_SeekRowid: { /* jump, in3, ncycle */ +case OP_SeekRowid: { /* jump0, in3, ncycle */ VdbeCursor *pC; BtCursor *pCrsr; int res; @@ -6153,7 +6157,7 @@ case OP_NullRow: { ** configured to use Prev, not Next. */ case OP_SeekEnd: /* ncycle */ -case OP_Last: { /* jump, ncycle */ +case OP_Last: { /* jump0, ncycle */ VdbeCursor *pC; BtCursor *pCrsr; int res; @@ -6187,28 +6191,38 @@ case OP_Last: { /* jump, ncycle */ break; } -/* Opcode: IfSmaller P1 P2 P3 * * +/* Opcode: IfSizeBetween P1 P2 P3 P4 * +** +** Let N be the approximate number of rows in the table or index +** with cursor P1 and let X be 10*log2(N) if N is positive or -1 +** if N is zero. ** -** Estimate the number of rows in the table P1. Jump to P2 if that -** estimate is less than approximately 2**(0.1*P3). +** Jump to P2 if X is in between P3 and P4, inclusive. */ -case OP_IfSmaller: { /* jump */ +case OP_IfSizeBetween: { /* jump */ VdbeCursor *pC; BtCursor *pCrsr; int res; i64 sz; assert( pOp->p1>=0 && pOp->p1<p->nCursor ); + assert( pOp->p4type==P4_INT32 ); + assert( pOp->p3>=-1 && pOp->p3<=640*2 ); + assert( pOp->p4.i>=-1 && pOp->p4.i<=640*2 ); pC = p->apCsr[pOp->p1]; assert( pC!=0 ); pCrsr = pC->uc.pCursor; assert( pCrsr ); rc = sqlite3BtreeFirst(pCrsr, &res); if( rc ) goto abort_due_to_error; - if( res==0 ){ + if( res!=0 ){ + sz = -1; /* -Infinity encoding */ + }else{ sz = sqlite3BtreeRowCountEst(pCrsr); - if( ALWAYS(sz>=0) && sqlite3LogEst((u64)sz)<pOp->p3 ) res = 1; + assert( sz>0 ); + sz = sqlite3LogEst((u64)sz); } + res = sz>=pOp->p3 && sz<=pOp->p4.i; VdbeBranchTaken(res!=0,2); if( res ) goto jump_to_p2; break; @@ -6261,7 +6275,7 @@ case OP_Sort: { /* jump ncycle */ ** from the beginning toward the end. In other words, the cursor is ** configured to use Next, not Prev. */ -case OP_Rewind: { /* jump, ncycle */ +case OP_Rewind: { /* jump0, ncycle */ VdbeCursor *pC; BtCursor *pCrsr; int res; @@ -6908,11 +6922,18 @@ case OP_CreateBtree: { /* out2 */ break; } -/* Opcode: SqlExec * * * P4 * +/* Opcode: SqlExec P1 P2 * P4 * ** ** Run the SQL statement or statements specified in the P4 string. -** Disable Auth and Trace callbacks while those statements are running if -** P1 is true. +** +** The P1 parameter is a bitmask of options: +** +** 0x0001 Disable Auth and Trace callbacks while the statements +** in P4 are running. +** +** 0x0002 Set db->nAnalysisLimit to P2 while the statements in +** P4 are running. +** */ case OP_SqlExec: { char *zErr; @@ -6920,6 +6941,7 @@ case OP_SqlExec: { sqlite3_xauth xAuth; #endif u8 mTrace; + int savedAnalysisLimit; sqlite3VdbeIncrWriteCounter(p, 0); db->nSqlExec++; @@ -6928,18 +6950,23 @@ case OP_SqlExec: { xAuth = db->xAuth; #endif mTrace = db->mTrace; - if( pOp->p1 ){ + savedAnalysisLimit = db->nAnalysisLimit; + if( pOp->p1 & 0x0001 ){ #ifndef SQLITE_OMIT_AUTHORIZATION db->xAuth = 0; #endif db->mTrace = 0; } + if( pOp->p1 & 0x0002 ){ + db->nAnalysisLimit = pOp->p2; + } rc = sqlite3_exec(db, pOp->p4.z, 0, 0, &zErr); db->nSqlExec--; #ifndef SQLITE_OMIT_AUTHORIZATION db->xAuth = xAuth; #endif db->mTrace = mTrace; + db->nAnalysisLimit = savedAnalysisLimit; if( zErr || rc ){ sqlite3VdbeError(p, "%s", zErr); sqlite3_free(zErr); @@ -7091,11 +7118,11 @@ case OP_DropTrigger: { /* Opcode: IntegrityCk P1 P2 P3 P4 P5 ** ** Do an analysis of the currently open database. Store in -** register P1 the text of an error message describing any problems. -** If no problems are found, store a NULL in register P1. +** register (P1+1) the text of an error message describing any problems. +** If no problems are found, store a NULL in register (P1+1). ** -** The register P3 contains one less than the maximum number of allowed errors. -** At most reg(P3) errors will be reported. +** The register (P1) contains one less than the maximum number of allowed +** errors. At most reg(P1) errors will be reported. ** In other words, the analysis stops as soon as reg(P1) errors are ** seen. Reg(P1) is updated with the number of errors remaining. ** @@ -7115,19 +7142,21 @@ case OP_IntegrityCk: { Mem *pnErr; /* Register keeping track of errors remaining */ assert( p->bIsReader ); + assert( pOp->p4type==P4_INTARRAY ); nRoot = pOp->p2; aRoot = pOp->p4.ai; assert( nRoot>0 ); + assert( aRoot!=0 ); assert( aRoot[0]==(Pgno)nRoot ); - assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) ); - pnErr = &aMem[pOp->p3]; + assert( pOp->p1>0 && (pOp->p1+1)<=(p->nMem+1 - p->nCursor) ); + pnErr = &aMem[pOp->p1]; assert( (pnErr->flags & MEM_Int)!=0 ); assert( (pnErr->flags & (MEM_Str|MEM_Blob))==0 ); - pIn1 = &aMem[pOp->p1]; + pIn1 = &aMem[pOp->p1+1]; assert( pOp->p5<db->nDb ); assert( DbMaskTest(p->btreeMask, pOp->p5) ); - rc = sqlite3BtreeIntegrityCheck(db, db->aDb[pOp->p5].pBt, &aRoot[1], nRoot, - (int)pnErr->u.i+1, &nErr, &z); + rc = sqlite3BtreeIntegrityCheck(db, db->aDb[pOp->p5].pBt, &aRoot[1], + &aMem[pOp->p3], nRoot, (int)pnErr->u.i+1, &nErr, &z); sqlite3VdbeMemSetNull(pIn1); if( nErr==0 ){ assert( z==0 ); @@ -7254,7 +7283,9 @@ case OP_RowSetTest: { /* jump, in1, in3 */ ** P1 contains the address of the memory cell that contains the first memory ** cell in an array of values used as arguments to the sub-program. P2 ** contains the address to jump to if the sub-program throws an IGNORE -** exception using the RAISE() function. Register P3 contains the address +** exception using the RAISE() function. P2 might be zero, if there is +** no possibility that an IGNORE exception will be raised. +** Register P3 contains the address ** of a memory cell in this (the parent) VM that is used to allocate the ** memory required by the sub-vdbe at runtime. ** @@ -7262,7 +7293,7 @@ case OP_RowSetTest: { /* jump, in1, in3 */ ** ** If P5 is non-zero, then recursive program invocation is enabled. */ -case OP_Program: { /* jump */ +case OP_Program: { /* jump0 */ int nMem; /* Number of memory registers for sub-program */ int nByte; /* Bytes of runtime space required for sub-program */ Mem *pRt; /* Register to allocate runtime space */ @@ -8811,7 +8842,7 @@ case OP_Filter: { /* jump */ ** error is encountered. */ case OP_Trace: -case OP_Init: { /* jump */ +case OP_Init: { /* jump0 */ int i; #ifndef SQLITE_OMIT_TRACE char *zTrace; @@ -296,6 +296,8 @@ RecordCompare sqlite3VdbeFindCompare(UnpackedRecord*); void sqlite3VdbeLinkSubProgram(Vdbe *, SubProgram *); int sqlite3VdbeHasSubProgram(Vdbe*); +void sqlite3MemSetArrayInt64(sqlite3_value *aMem, int iIdx, i64 val); + int sqlite3NotPureFunc(sqlite3_context*); #ifdef SQLITE_ENABLE_BYTECODE_VTAB int sqlite3VdbeBytecodeVtabInit(sqlite3*); diff --git a/src/vdbeapi.c b/src/vdbeapi.c index 14c6091..3182e40 100644 --- a/src/vdbeapi.c +++ b/src/vdbeapi.c @@ -2404,7 +2404,6 @@ int sqlite3_stmt_scanstatus_v2( } if( flags & SQLITE_SCANSTAT_COMPLEX ){ idx = iScan; - pScan = &p->aScan[idx]; }else{ /* If the COMPLEX flag is clear, then this function must ignore any ** ScanStatus structures with ScanStatus.addrLoop set to 0. */ @@ -2417,6 +2416,8 @@ int sqlite3_stmt_scanstatus_v2( } } if( idx>=p->nScan ) return 1; + assert( pScan==0 || pScan==&p->aScan[idx] ); + pScan = &p->aScan[idx]; switch( iScanStatusOp ){ case SQLITE_SCANSTAT_NLOOP: { diff --git a/src/vdbeaux.c b/src/vdbeaux.c index fe0dbd6..e4c174e 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -939,6 +939,15 @@ static void resolveP2Values(Vdbe *p, int *pMaxFuncArgs){ assert( aLabel!=0 ); /* True because of tag-20230419-1 */ pOp->p2 = aLabel[ADDR(pOp->p2)]; } + + /* OPFLG_JUMP opcodes never have P2==0, though OPFLG_JUMP0 opcodes + ** might */ + assert( pOp->p2>0 + || (sqlite3OpcodeProperty[pOp->opcode] & OPFLG_JUMP0)!=0 ); + + /* Jumps never go off the end of the bytecode array */ + assert( pOp->p2<p->nOp + || (sqlite3OpcodeProperty[pOp->opcode] & OPFLG_JUMP)==0 ); break; } } @@ -3346,9 +3355,9 @@ int sqlite3VdbeHalt(Vdbe *p){ /* Check for immediate foreign key violations. */ if( p->rc==SQLITE_OK || (p->errorAction==OE_Fail && !isSpecialError) ){ - sqlite3VdbeCheckFk(p, 0); + (void)sqlite3VdbeCheckFk(p, 0); } - + /* If the auto-commit flag is set and this is the only active writer ** VM, then we do either a commit or rollback of the current transaction. ** @@ -4516,17 +4525,15 @@ int sqlite3IntFloatCompare(i64 i, double r){ return (x<r) ? -1 : (x>r); }else{ i64 y; - double s; if( r<-9223372036854775808.0 ) return +1; if( r>=9223372036854775808.0 ) return -1; y = (i64)r; if( i<y ) return -1; if( i>y ) return +1; - s = (double)i; - testcase( doubleLt(s,r) ); - testcase( doubleLt(r,s) ); - testcase( doubleEq(r,s) ); - return (s<r) ? -1 : (s>r); + testcase( doubleLt(((double)i),r) ); + testcase( doubleLt(r,((double)i)) ); + testcase( doubleEq(r,((double)i)) ); + return (((double)i)<r) ? -1 : (((double)i)>r); } } diff --git a/src/vdbemem.c b/src/vdbemem.c index d527164..8e2aa4a 100644 --- a/src/vdbemem.c +++ b/src/vdbemem.c @@ -943,6 +943,13 @@ void sqlite3VdbeMemSetInt64(Mem *pMem, i64 val){ } } +/* +** Set the iIdx'th entry of array aMem[] to contain integer value val. +*/ +void sqlite3MemSetArrayInt64(sqlite3_value *aMem, int iIdx, i64 val){ + sqlite3VdbeMemSetInt64(&aMem[iIdx], val); +} + /* A no-op destructor */ void sqlite3NoopDestructor(void *p){ UNUSED_PARAMETER(p); } @@ -1631,14 +1638,20 @@ static int valueFromExpr( } /* Handle negative integers in a single step. This is needed in the - ** case when the value is -9223372036854775808. - */ - if( op==TK_UMINUS - && (pExpr->pLeft->op==TK_INTEGER || pExpr->pLeft->op==TK_FLOAT) ){ - pExpr = pExpr->pLeft; - op = pExpr->op; - negInt = -1; - zNeg = "-"; + ** case when the value is -9223372036854775808. Except - do not do this + ** for hexadecimal literals. */ + if( op==TK_UMINUS ){ + Expr *pLeft = pExpr->pLeft; + if( (pLeft->op==TK_INTEGER || pLeft->op==TK_FLOAT) ){ + if( ExprHasProperty(pLeft, EP_IntValue) + || pLeft->u.zToken[0]!='0' || (pLeft->u.zToken[1] & ~0x20)!='X' + ){ + pExpr = pLeft; + op = pExpr->op; + negInt = -1; + zNeg = "-"; + } + } } if( op==TK_STRING || op==TK_FLOAT || op==TK_INTEGER ){ @@ -1647,12 +1660,26 @@ static int valueFromExpr( if( ExprHasProperty(pExpr, EP_IntValue) ){ sqlite3VdbeMemSetInt64(pVal, (i64)pExpr->u.iValue*negInt); }else{ - zVal = sqlite3MPrintf(db, "%s%s", zNeg, pExpr->u.zToken); - if( zVal==0 ) goto no_mem; - sqlite3ValueSetStr(pVal, -1, zVal, SQLITE_UTF8, SQLITE_DYNAMIC); + i64 iVal; + if( op==TK_INTEGER && 0==sqlite3DecOrHexToI64(pExpr->u.zToken, &iVal) ){ + sqlite3VdbeMemSetInt64(pVal, iVal*negInt); + }else{ + zVal = sqlite3MPrintf(db, "%s%s", zNeg, pExpr->u.zToken); + if( zVal==0 ) goto no_mem; + sqlite3ValueSetStr(pVal, -1, zVal, SQLITE_UTF8, SQLITE_DYNAMIC); + } } - if( (op==TK_INTEGER || op==TK_FLOAT ) && affinity==SQLITE_AFF_BLOB ){ - sqlite3ValueApplyAffinity(pVal, SQLITE_AFF_NUMERIC, SQLITE_UTF8); + if( affinity==SQLITE_AFF_BLOB ){ + if( op==TK_FLOAT ){ + assert( pVal && pVal->z && pVal->flags==(MEM_Str|MEM_Term) ); + sqlite3AtoF(pVal->z, &pVal->u.r, pVal->n, SQLITE_UTF8); + pVal->flags = MEM_Real; + }else if( op==TK_INTEGER ){ + /* This case is required by -9223372036854775808 and other strings + ** that look like integers but cannot be handled by the + ** sqlite3DecOrHexToI64() call above. */ + sqlite3ValueApplyAffinity(pVal, SQLITE_AFF_NUMERIC, SQLITE_UTF8); + } }else{ sqlite3ValueApplyAffinity(pVal, affinity, SQLITE_UTF8); } @@ -1922,17 +1949,17 @@ int sqlite3Stat4Column( sqlite3_value **ppVal /* OUT: Extracted value */ ){ u32 t = 0; /* a column type code */ - int nHdr; /* Size of the header in the record */ - int iHdr; /* Next unread header byte */ - int iField; /* Next unread data byte */ - int szField = 0; /* Size of the current data field */ + u32 nHdr; /* Size of the header in the record */ + u32 iHdr; /* Next unread header byte */ + i64 iField; /* Next unread data byte */ + u32 szField = 0; /* Size of the current data field */ int i; /* Column index */ u8 *a = (u8*)pRec; /* Typecast byte array */ Mem *pMem = *ppVal; /* Write result into this Mem object */ assert( iCol>0 ); iHdr = getVarint32(a, nHdr); - if( nHdr>nRec || iHdr>=nHdr ) return SQLITE_CORRUPT_BKPT; + if( nHdr>(u32)nRec || iHdr>=nHdr ) return SQLITE_CORRUPT_BKPT; iField = nHdr; for(i=0; i<=iCol; i++){ iHdr += getVarint32(&a[iHdr], t); diff --git a/src/vdbevtab.c b/src/vdbevtab.c index b295dff..1c9909a 100644 --- a/src/vdbevtab.c +++ b/src/vdbevtab.c @@ -286,10 +286,10 @@ static int bytecodevtabColumn( #ifdef SQLITE_ENABLE_STMT_SCANSTATUS case 9: /* nexec */ - sqlite3_result_int(ctx, pOp->nExec); + sqlite3_result_int64(ctx, pOp->nExec); break; case 10: /* ncycle */ - sqlite3_result_int(ctx, pOp->nCycle); + sqlite3_result_int64(ctx, pOp->nCycle); break; #else case 9: /* nexec */ @@ -611,6 +611,8 @@ static int vtabCallConstructor( db->pVtabCtx = &sCtx; pTab->nTabRef++; rc = xConstruct(db, pMod->pAux, nArg, azArg, &pVTable->pVtab, &zErr); + assert( pTab!=0 ); + assert( pTab->nTabRef>1 || rc!=SQLITE_OK ); sqlite3DeleteTable(db, pTab); db->pVtabCtx = sCtx.pPrior; if( rc==SQLITE_NOMEM ) sqlite3OomFault(db); @@ -633,7 +635,7 @@ static int vtabCallConstructor( pVTable->nRef = 1; if( sCtx.bDeclared==0 ){ const char *zFormat = "vtable constructor did not declare schema: %s"; - *pzErr = sqlite3MPrintf(db, zFormat, pTab->zName); + *pzErr = sqlite3MPrintf(db, zFormat, zModuleName); sqlite3VtabUnlock(pVTable); rc = SQLITE_ERROR; }else{ @@ -811,12 +813,30 @@ int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){ Table *pTab; Parse sParse; int initBusy; + int i; + const unsigned char *z; + static const u8 aKeyword[] = { TK_CREATE, TK_TABLE, 0 }; #ifdef SQLITE_ENABLE_API_ARMOR if( !sqlite3SafetyCheckOk(db) || zCreateTable==0 ){ return SQLITE_MISUSE_BKPT; } #endif + + /* Verify that the first two keywords in the CREATE TABLE statement + ** really are "CREATE" and "TABLE". If this is not the case, then + ** sqlite3_declare_vtab() is being misused. + */ + z = (const unsigned char*)zCreateTable; + for(i=0; aKeyword[i]; i++){ + int tokenType = 0; + do{ z += sqlite3GetToken(z, &tokenType); }while( tokenType==TK_SPACE ); + if( tokenType!=aKeyword[i] ){ + sqlite3ErrorWithMsg(db, SQLITE_ERROR, "syntax error"); + return SQLITE_ERROR; + } + } + sqlite3_mutex_enter(db->mutex); pCtx = db->pVtabCtx; if( !pCtx || pCtx->bDeclared ){ @@ -824,6 +844,7 @@ int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){ sqlite3_mutex_leave(db->mutex); return SQLITE_MISUSE_BKPT; } + pTab = pCtx->pTab; assert( IsVirtual(pTab) ); @@ -837,11 +858,10 @@ int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){ initBusy = db->init.busy; db->init.busy = 0; sParse.nQueryLoop = 1; - if( SQLITE_OK==sqlite3RunParser(&sParse, zCreateTable) - && ALWAYS(sParse.pNewTable!=0) - && ALWAYS(!db->mallocFailed) - && IsOrdinaryTable(sParse.pNewTable) - ){ + if( SQLITE_OK==sqlite3RunParser(&sParse, zCreateTable) ){ + assert( sParse.pNewTable!=0 ); + assert( !db->mallocFailed ); + assert( IsOrdinaryTable(sParse.pNewTable) ); assert( sParse.zErrMsg==0 ); if( !pTab->aCol ){ Table *pNew = sParse.pNewTable; diff --git a/src/where.c b/src/where.c index 8e7b112..fac0f6c 100644 --- a/src/where.c +++ b/src/where.c @@ -303,6 +303,42 @@ static Expr *whereRightSubexprIsColumn(Expr *p){ } /* +** Term pTerm is guaranteed to be a WO_IN term. It may be a component term +** of a vector IN expression of the form "(x, y, ...) IN (SELECT ...)". +** This function checks to see if the term is compatible with an index +** column with affinity idxaff (one of the SQLITE_AFF_XYZ values). If so, +** it returns a pointer to the name of the collation sequence (e.g. "BINARY" +** or "NOCASE") used by the comparison in pTerm. If it is not compatible +** with affinity idxaff, NULL is returned. +*/ +static SQLITE_NOINLINE const char *indexInAffinityOk( + Parse *pParse, + WhereTerm *pTerm, + u8 idxaff +){ + Expr *pX = pTerm->pExpr; + Expr inexpr; + + assert( pTerm->eOperator & WO_IN ); + + if( sqlite3ExprIsVector(pX->pLeft) ){ + int iField = pTerm->u.x.iField - 1; + inexpr.flags = 0; + inexpr.op = TK_EQ; + inexpr.pLeft = pX->pLeft->x.pList->a[iField].pExpr; + assert( ExprUseXSelect(pX) ); + inexpr.pRight = pX->x.pSelect->pEList->a[iField].pExpr; + pX = &inexpr; + } + + if( sqlite3IndexAffinityOk(pX, idxaff) ){ + CollSeq *pRet = sqlite3ExprCompareCollSeq(pParse, pX); + return pRet ? pRet->zName : sqlite3StrBINARY; + } + return 0; +} + +/* ** Advance to the next WhereTerm that matches according to the criteria ** established when the pScan object was initialized by whereScanInit(). ** Return NULL if there are no more matching WhereTerms. @@ -352,16 +388,24 @@ static WhereTerm *whereScanNext(WhereScan *pScan){ if( (pTerm->eOperator & pScan->opMask)!=0 ){ /* Verify the affinity and collating sequence match */ if( pScan->zCollName && (pTerm->eOperator & WO_ISNULL)==0 ){ - CollSeq *pColl; + const char *zCollName; Parse *pParse = pWC->pWInfo->pParse; pX = pTerm->pExpr; - if( !sqlite3IndexAffinityOk(pX, pScan->idxaff) ){ - continue; + + if( (pTerm->eOperator & WO_IN) ){ + zCollName = indexInAffinityOk(pParse, pTerm, pScan->idxaff); + if( !zCollName ) continue; + }else{ + CollSeq *pColl; + if( !sqlite3IndexAffinityOk(pX, pScan->idxaff) ){ + continue; + } + assert(pX->pLeft); + pColl = sqlite3ExprCompareCollSeq(pParse, pX); + zCollName = pColl ? pColl->zName : sqlite3StrBINARY; } - assert(pX->pLeft); - pColl = sqlite3ExprCompareCollSeq(pParse, pX); - if( pColl==0 ) pColl = pParse->db->pDfltColl; - if( sqlite3StrICmp(pColl->zName, pScan->zCollName) ){ + + if( sqlite3StrICmp(zCollName, pScan->zCollName) ){ continue; } } @@ -713,9 +757,13 @@ static void translateColumnToCopy( ** are no-ops. */ #if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(WHERETRACE_ENABLED) -static void whereTraceIndexInfoInputs(sqlite3_index_info *p){ +static void whereTraceIndexInfoInputs( + sqlite3_index_info *p, /* The IndexInfo object */ + Table *pTab /* The TABLE that is the virtual table */ +){ int i; if( (sqlite3WhereTrace & 0x10)==0 ) return; + sqlite3DebugPrintf("sqlite3_index_info inputs for %s:\n", pTab->zName); for(i=0; i<p->nConstraint; i++){ sqlite3DebugPrintf( " constraint[%d]: col=%d termid=%d op=%d usabled=%d collseq=%s\n", @@ -733,9 +781,13 @@ static void whereTraceIndexInfoInputs(sqlite3_index_info *p){ p->aOrderBy[i].desc); } } -static void whereTraceIndexInfoOutputs(sqlite3_index_info *p){ +static void whereTraceIndexInfoOutputs( + sqlite3_index_info *p, /* The IndexInfo object */ + Table *pTab /* The TABLE that is the virtual table */ +){ int i; if( (sqlite3WhereTrace & 0x10)==0 ) return; + sqlite3DebugPrintf("sqlite3_index_info outputs for %s:\n", pTab->zName); for(i=0; i<p->nConstraint; i++){ sqlite3DebugPrintf(" usage[%d]: argvIdx=%d omit=%d\n", i, @@ -749,8 +801,8 @@ static void whereTraceIndexInfoOutputs(sqlite3_index_info *p){ sqlite3DebugPrintf(" estimatedRows=%lld\n", p->estimatedRows); } #else -#define whereTraceIndexInfoInputs(A) -#define whereTraceIndexInfoOutputs(A) +#define whereTraceIndexInfoInputs(A,B) +#define whereTraceIndexInfoOutputs(A,B) #endif /* @@ -934,7 +986,7 @@ static SQLITE_NOINLINE void constructAutomaticIndex( ** WHERE clause (or the ON clause of a LEFT join) that constrain which ** rows of the target table (pSrc) that can be used. */ if( (pTerm->wtFlags & TERM_VIRTUAL)==0 - && sqlite3ExprIsSingleTableConstraint(pExpr, pTabList, pLevel->iFrom) + && sqlite3ExprIsSingleTableConstraint(pExpr, pTabList, pLevel->iFrom, 0) ){ pPartial = sqlite3ExprAnd(pParse, pPartial, sqlite3ExprDup(pParse->db, pExpr, 0)); @@ -976,7 +1028,7 @@ static SQLITE_NOINLINE void constructAutomaticIndex( ** if they go out of sync. */ if( IsView(pTable) ){ - extraCols = ALLBITS; + extraCols = ALLBITS & ~idxCols; }else{ extraCols = pSrc->colUsed & (~idxCols | MASKBIT(BMS-1)); } @@ -1203,7 +1255,7 @@ static SQLITE_NOINLINE void sqlite3ConstructBloomFilter( for(pTerm=pWInfo->sWC.a; pTerm<pWCEnd; pTerm++){ Expr *pExpr = pTerm->pExpr; if( (pTerm->wtFlags & TERM_VIRTUAL)==0 - && sqlite3ExprIsSingleTableConstraint(pExpr, pTabList, iSrc) + && sqlite3ExprIsSingleTableConstraint(pExpr, pTabList, iSrc, 0) ){ sqlite3ExprIfFalse(pParse, pTerm->pExpr, addrCont, SQLITE_JUMPIFNULL); } @@ -1329,7 +1381,7 @@ static sqlite3_index_info *allocateIndexInfo( Expr *pE2; /* Skip over constant terms in the ORDER BY clause */ - if( sqlite3ExprIsConstant(pExpr) ){ + if( sqlite3ExprIsConstant(0, pExpr) ){ continue; } @@ -1364,7 +1416,7 @@ static sqlite3_index_info *allocateIndexInfo( } if( i==n ){ nOrderBy = n; - if( (pWInfo->wctrlFlags & WHERE_DISTINCTBY) ){ + if( (pWInfo->wctrlFlags & WHERE_DISTINCTBY) && !pSrc->fg.rowidUsed ){ eDistinct = 2 + ((pWInfo->wctrlFlags & WHERE_SORTBYGROUP)!=0); }else if( pWInfo->wctrlFlags & WHERE_GROUPBY ){ eDistinct = 1; @@ -1441,7 +1493,7 @@ static sqlite3_index_info *allocateIndexInfo( pIdxInfo->nConstraint = j; for(i=j=0; i<nOrderBy; i++){ Expr *pExpr = pOrderBy->a[i].pExpr; - if( sqlite3ExprIsConstant(pExpr) ) continue; + if( sqlite3ExprIsConstant(0, pExpr) ) continue; assert( pExpr->op==TK_COLUMN || (pExpr->op==TK_COLLATE && pExpr->pLeft->op==TK_COLUMN && pExpr->iColumn==pExpr->pLeft->iColumn) ); @@ -1493,11 +1545,11 @@ static int vtabBestIndex(Parse *pParse, Table *pTab, sqlite3_index_info *p){ sqlite3_vtab *pVtab = sqlite3GetVTable(pParse->db, pTab)->pVtab; int rc; - whereTraceIndexInfoInputs(p); + whereTraceIndexInfoInputs(p, pTab); pParse->db->nSchemaLock++; rc = pVtab->pModule->xBestIndex(pVtab, p); pParse->db->nSchemaLock--; - whereTraceIndexInfoOutputs(p); + whereTraceIndexInfoOutputs(p, pTab); if( rc!=SQLITE_OK && rc!=SQLITE_CONSTRAINT ){ if( rc==SQLITE_NOMEM ){ @@ -2975,7 +3027,9 @@ static int whereLoopAddBtreeIndex( } if( pProbe->bUnordered || pProbe->bLowQual ){ if( pProbe->bUnordered ) opMask &= ~(WO_GT|WO_GE|WO_LT|WO_LE); - if( pProbe->bLowQual ) opMask &= ~(WO_EQ|WO_IN|WO_IS); + if( pProbe->bLowQual && pSrc->fg.isIndexedBy==0 ){ + opMask &= ~(WO_EQ|WO_IN|WO_IS); + } } assert( pNew->u.btree.nEq<pProbe->nColumn ); @@ -3242,10 +3296,13 @@ static int whereLoopAddBtreeIndex( } } - /* Set rCostIdx to the cost of visiting selected rows in index. Add - ** it to pNew->rRun, which is currently set to the cost of the index - ** seek only. Then, if this is a non-covering index, add the cost of - ** visiting the rows in the main table. */ + /* Set rCostIdx to the estimated cost of visiting selected rows in the + ** index. The estimate is the sum of two values: + ** 1. The cost of doing one search-by-key to find the first matching + ** entry + ** 2. Stepping forward in the index pNew->nOut times to find all + ** additional matching entries. + */ assert( pSrc->pTab->szTabRow>0 ); if( pProbe->idxType==SQLITE_IDXTYPE_IPK ){ /* The pProbe->szIdxRow is low for an IPK table since the interior @@ -3256,7 +3313,15 @@ static int whereLoopAddBtreeIndex( }else{ rCostIdx = pNew->nOut + 1 + (15*pProbe->szIdxRow)/pSrc->pTab->szTabRow; } - pNew->rRun = sqlite3LogEstAdd(rLogSize, rCostIdx); + rCostIdx = sqlite3LogEstAdd(rLogSize, rCostIdx); + + /* Estimate the cost of running the loop. If all data is coming + ** from the index, then this is just the cost of doing the index + ** lookup and scan. But if some data is coming out of the main table, + ** we also have to add in the cost of doing pNew->nOut searches to + ** locate the row in the main table that corresponds to the index entry. + */ + pNew->rRun = rCostIdx; if( (pNew->wsFlags & (WHERE_IDX_ONLY|WHERE_IPK|WHERE_EXPRIDX))==0 ){ pNew->rRun = sqlite3LogEstAdd(pNew->rRun, pNew->nOut + 16); } @@ -3362,7 +3427,9 @@ static int indexMightHelpWithOrderBy( for(ii=0; ii<pOB->nExpr; ii++){ Expr *pExpr = sqlite3ExprSkipCollateAndLikely(pOB->a[ii].pExpr); if( NEVER(pExpr==0) ) continue; - if( pExpr->op==TK_COLUMN && pExpr->iTable==iCursor ){ + if( (pExpr->op==TK_COLUMN || pExpr->op==TK_AGG_COLUMN) + && pExpr->iTable==iCursor + ){ if( pExpr->iColumn<0 ) return 1; for(jj=0; jj<pIndex->nKeyCol; jj++){ if( pExpr->iColumn==pIndex->aiColumn[jj] ) return 1; @@ -3619,7 +3686,7 @@ static void wherePartIdxExpr( u8 aff; if( pLeft->op!=TK_COLUMN ) return; - if( !sqlite3ExprIsConstant(pRight) ) return; + if( !sqlite3ExprIsConstant(0, pRight) ) return; if( !sqlite3IsBinary(sqlite3ExprCompareCollSeq(pParse, pPart)) ) return; if( pLeft->iColumn<0 ) return; aff = pIdx->pTable->aCol[pLeft->iColumn].affinity; @@ -3968,7 +4035,7 @@ static int whereLoopAddBtree( ** unique index is used (making the index functionally non-unique) ** then the sqlite_stat1 data becomes important for scoring the ** plan */ - pTab->tabFlags |= TF_StatsUsed; + pTab->tabFlags |= TF_MaybeReanalyze; } #ifdef SQLITE_ENABLE_STAT4 sqlite3Stat4ProbeFree(pBuilder->pRec); @@ -3991,6 +4058,21 @@ static int isLimitTerm(WhereTerm *pTerm){ } /* +** Return true if the first nCons constraints in the pUsage array are +** marked as in-use (have argvIndex>0). False otherwise. +*/ +static int allConstraintsUsed( + struct sqlite3_index_constraint_usage *aUsage, + int nCons +){ + int ii; + for(ii=0; ii<nCons; ii++){ + if( aUsage[ii].argvIndex<=0 ) return 0; + } + return 1; +} + +/* ** Argument pIdxInfo is already populated with all constraints that may ** be used by the virtual table identified by pBuilder->pNew->iTab. This ** function marks a subset of those constraints usable, invokes the @@ -4130,13 +4212,20 @@ static int whereLoopAddVirtualOne( *pbIn = 1; assert( (mExclude & WO_IN)==0 ); } + /* Unless pbRetryLimit is non-NULL, there should be no LIMIT/OFFSET + ** terms. And if there are any, they should follow all other terms. */ assert( pbRetryLimit || !isLimitTerm(pTerm) ); - if( isLimitTerm(pTerm) && *pbIn ){ + assert( !isLimitTerm(pTerm) || i>=nConstraint-2 ); + assert( !isLimitTerm(pTerm) || i==nConstraint-1 || isLimitTerm(pTerm+1) ); + + if( isLimitTerm(pTerm) && (*pbIn || !allConstraintsUsed(pUsage, i)) ){ /* If there is an IN(...) term handled as an == (separate call to ** xFilter for each value on the RHS of the IN) and a LIMIT or - ** OFFSET term handled as well, the plan is unusable. Set output - ** variable *pbRetryLimit to true to tell the caller to retry with - ** LIMIT and OFFSET disabled. */ + ** OFFSET term handled as well, the plan is unusable. Similarly, + ** if there is a LIMIT/OFFSET and there are other unused terms, + ** the plan cannot be used. In these cases set variable *pbRetryLimit + ** to true to tell the caller to retry with LIMIT and OFFSET + ** disabled. */ if( pIdxInfo->needToFreeIdxStr ){ sqlite3_free(pIdxInfo->idxStr); pIdxInfo->idxStr = 0; @@ -4993,7 +5082,7 @@ static i8 wherePathSatisfiesOrderBy( if( MASKBIT(i) & obSat ) continue; p = pOrderBy->a[i].pExpr; mTerm = sqlite3WhereExprUsage(&pWInfo->sMaskSet,p); - if( mTerm==0 && !sqlite3ExprIsConstant(p) ) continue; + if( mTerm==0 && !sqlite3ExprIsConstant(0,p) ) continue; if( (mTerm&~orderDistinctMask)==0 ){ obSat |= MASKBIT(i); } @@ -5462,10 +5551,9 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){ if( pFrom->isOrdered==pWInfo->pOrderBy->nExpr ){ pWInfo->eDistinct = WHERE_DISTINCT_ORDERED; } - if( pWInfo->pSelect->pOrderBy - && pWInfo->nOBSat > pWInfo->pSelect->pOrderBy->nExpr ){ - pWInfo->nOBSat = pWInfo->pSelect->pOrderBy->nExpr; - } + /* vvv--- See check-in [12ad822d9b827777] on 2023-03-16 ---vvv */ + assert( pWInfo->pSelect->pOrderBy==0 + || pWInfo->nOBSat <= pWInfo->pSelect->pOrderBy->nExpr ); }else{ pWInfo->revMask = pFrom->revLoop; if( pWInfo->nOBSat<=0 ){ @@ -5508,7 +5596,6 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){ } } - pWInfo->nRowOut = pFrom->nRow; /* Free temporary memory and return success */ @@ -5517,6 +5604,83 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){ } /* +** This routine implements a heuristic designed to improve query planning. +** This routine is called in between the first and second call to +** wherePathSolver(). Hence the name "Interstage" "Heuristic". +** +** The first call to wherePathSolver() (hereafter just "solver()") computes +** the best path without regard to the order of the outputs. The second call +** to the solver() builds upon the first call to try to find an alternative +** path that satisfies the ORDER BY clause. +** +** This routine looks at the results of the first solver() run, and for +** every FROM clause term in the resulting query plan that uses an equality +** constraint against an index, disable other WhereLoops for that same +** FROM clause term that would try to do a full-table scan. This prevents +** an index search from being converted into a full-table scan in order to +** satisfy an ORDER BY clause, since even though we might get slightly better +** performance using the full-scan without sorting if the output size +** estimates are very precise, we might also get severe performance +** degradation using the full-scan if the output size estimate is too large. +** It is better to err on the side of caution. +** +** Except, if the first solver() call generated a full-table scan in an outer +** loop then stop this analysis at the first full-scan, since the second +** solver() run might try to swap that full-scan for another in order to +** get the output into the correct order. In other words, we allow a +** rewrite like this: +** +** First Solver() Second Solver() +** |-- SCAN t1 |-- SCAN t2 +** |-- SEARCH t2 `-- SEARCH t1 +** `-- SORT USING B-TREE +** +** The purpose of this routine is to disallow rewrites such as: +** +** First Solver() Second Solver() +** |-- SEARCH t1 |-- SCAN t2 <--- bad! +** |-- SEARCH t2 `-- SEARCH t1 +** `-- SORT USING B-TREE +** +** See test cases in test/whereN.test for the real-world query that +** originally provoked this heuristic. +*/ +static SQLITE_NOINLINE void whereInterstageHeuristic(WhereInfo *pWInfo){ + int i; +#ifdef WHERETRACE_ENABLED + int once = 0; +#endif + for(i=0; i<pWInfo->nLevel; i++){ + WhereLoop *p = pWInfo->a[i].pWLoop; + if( p==0 ) break; + if( (p->wsFlags & WHERE_VIRTUALTABLE)!=0 ) continue; + if( (p->wsFlags & (WHERE_COLUMN_EQ|WHERE_COLUMN_NULL|WHERE_COLUMN_IN))!=0 ){ + u8 iTab = p->iTab; + WhereLoop *pLoop; + for(pLoop=pWInfo->pLoops; pLoop; pLoop=pLoop->pNextLoop){ + if( pLoop->iTab!=iTab ) continue; + if( (pLoop->wsFlags & (WHERE_CONSTRAINT|WHERE_AUTO_INDEX))!=0 ){ + /* Auto-index and index-constrained loops allowed to remain */ + continue; + } +#ifdef WHERETRACE_ENABLED + if( sqlite3WhereTrace & 0x80 ){ + if( once==0 ){ + sqlite3DebugPrintf("Loops disabled by interstage heuristic:\n"); + once = 1; + } + sqlite3WhereLoopPrint(pLoop, &pWInfo->sWC); + } +#endif /* WHERETRACE_ENABLED */ + pLoop->prereq = ALLBITS; /* Prevent 2nd solver() from using this one */ + } + }else{ + break; + } + } +} + +/* ** Most queries use only a single table (they are not joins) and have ** simple == constraints against indexed fields. This routine attempts ** to plan those simple cases using much less ceremony than the @@ -5804,7 +5968,7 @@ static SQLITE_NOINLINE void whereCheckIfBloomFilterIsUseful( SrcItem *pItem = &pWInfo->pTabList->a[pLoop->iTab]; Table *pTab = pItem->pTab; if( (pTab->tabFlags & TF_HasStat1)==0 ) break; - pTab->tabFlags |= TF_StatsUsed; + pTab->tabFlags |= TF_MaybeReanalyze; if( i>=1 && (pLoop->wsFlags & reqFlags)==reqFlags /* vvvvvv--- Always the case if WHERE_COLUMN_EQ is defined */ @@ -5826,6 +5990,58 @@ static SQLITE_NOINLINE void whereCheckIfBloomFilterIsUseful( } /* +** Expression Node callback for sqlite3ExprCanReturnSubtype(). +** +** Only a function call is able to return a subtype. So if the node +** is not a function call, return WRC_Prune immediately. +** +** A function call is able to return a subtype if it has the +** SQLITE_RESULT_SUBTYPE property. +** +** Assume that every function is able to pass-through a subtype from +** one of its argument (using sqlite3_result_value()). Most functions +** are not this way, but we don't have a mechanism to distinguish those +** that are from those that are not, so assume they all work this way. +** That means that if one of its arguments is another function and that +** other function is able to return a subtype, then this function is +** able to return a subtype. +*/ +static int exprNodeCanReturnSubtype(Walker *pWalker, Expr *pExpr){ + int n; + FuncDef *pDef; + sqlite3 *db; + if( pExpr->op!=TK_FUNCTION ){ + return WRC_Prune; + } + assert( ExprUseXList(pExpr) ); + db = pWalker->pParse->db; + n = pExpr->x.pList ? pExpr->x.pList->nExpr : 0; + pDef = sqlite3FindFunction(db, pExpr->u.zToken, n, ENC(db), 0); + if( pDef==0 || (pDef->funcFlags & SQLITE_RESULT_SUBTYPE)!=0 ){ + pWalker->eCode = 1; + return WRC_Prune; + } + return WRC_Continue; +} + +/* +** Return TRUE if expression pExpr is able to return a subtype. +** +** A TRUE return does not guarantee that a subtype will be returned. +** It only indicates that a subtype return is possible. False positives +** are acceptable as they only disable an optimization. False negatives, +** on the other hand, can lead to incorrect answers. +*/ +static int sqlite3ExprCanReturnSubtype(Parse *pParse, Expr *pExpr){ + Walker w; + memset(&w, 0, sizeof(w)); + w.pParse = pParse; + w.xExprCallback = exprNodeCanReturnSubtype; + sqlite3WalkExpr(&w, pExpr); + return w.eCode; +} + +/* ** The index pIdx is used by a query and contains one or more expressions. ** In other words pIdx is an index on an expression. iIdxCur is the cursor ** number for the index and iDataCur is the cursor number for the corresponding @@ -5857,20 +6073,12 @@ static SQLITE_NOINLINE void whereAddIndexedExpr( }else{ continue; } - if( sqlite3ExprIsConstant(pExpr) ) continue; - if( pExpr->op==TK_FUNCTION ){ + if( sqlite3ExprIsConstant(0,pExpr) ) continue; + if( pExpr->op==TK_FUNCTION && sqlite3ExprCanReturnSubtype(pParse,pExpr) ){ /* Functions that might set a subtype should not be replaced by the ** value taken from an expression index since the index omits the ** subtype. https://sqlite.org/forum/forumpost/68d284c86b082c3e */ - int n; - FuncDef *pDef; - sqlite3 *db = pParse->db; - assert( ExprUseXList(pExpr) ); - n = pExpr->x.pList ? pExpr->x.pList->nExpr : 0; - pDef = sqlite3FindFunction(db, pExpr->u.zToken, n, ENC(db), 0); - if( pDef==0 || (pDef->funcFlags & SQLITE_RESULT_SUBTYPE)!=0 ){ - continue; - } + continue; } p = sqlite3DbMallocRaw(pParse->db, sizeof(IndexedExpr)); if( p==0 ) break; @@ -6135,7 +6343,11 @@ WhereInfo *sqlite3WhereBegin( ){ pWInfo->eDistinct = WHERE_DISTINCT_UNIQUE; } - ExplainQueryPlan((pParse, 0, "SCAN CONSTANT ROW")); + if( ALWAYS(pWInfo->pSelect) + && (pWInfo->pSelect->selFlags & SF_MultiValue)==0 + ){ + ExplainQueryPlan((pParse, 0, "SCAN CONSTANT ROW")); + } }else{ /* Assign a bit from the bitmask to every term in the FROM clause. ** @@ -6288,6 +6500,7 @@ WhereInfo *sqlite3WhereBegin( wherePathSolver(pWInfo, 0); if( db->mallocFailed ) goto whereBeginError; if( pWInfo->pOrderBy ){ + whereInterstageHeuristic(pWInfo); wherePathSolver(pWInfo, pWInfo->nRowOut+1); if( db->mallocFailed ) goto whereBeginError; } @@ -6837,7 +7050,15 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){ addr = sqlite3VdbeAddOp1(v, OP_IfPos, pLevel->iLeftJoin); VdbeCoverage(v); assert( (ws & WHERE_IDX_ONLY)==0 || (ws & WHERE_INDEXED)!=0 ); if( (ws & WHERE_IDX_ONLY)==0 ){ - assert( pLevel->iTabCur==pTabList->a[pLevel->iFrom].iCursor ); + SrcItem *pSrc = &pTabList->a[pLevel->iFrom]; + assert( pLevel->iTabCur==pSrc->iCursor ); + if( pSrc->fg.viaCoroutine ){ + int m, n; + n = pSrc->regResult; + assert( pSrc->pTab!=0 ); + m = pSrc->pTab->nCol; + sqlite3VdbeAddOp3(v, OP_Null, 0, n, n+m-1); + } sqlite3VdbeAddOp1(v, OP_NullRow, pLevel->iTabCur); } if( (ws & WHERE_INDEXED) @@ -6887,6 +7108,7 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){ */ if( pTabItem->fg.viaCoroutine ){ testcase( pParse->db->mallocFailed ); + assert( pTabItem->regResult>=0 ); translateColumnToCopy(pParse, pLevel->addrBody, pLevel->iTabCur, pTabItem->regResult, 0); continue; diff --git a/src/wherecode.c b/src/wherecode.c index 47ce36c..a620a5a 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -1338,6 +1338,27 @@ static SQLITE_NOINLINE void filterPullDown( } /* +** Loop pLoop is a WHERE_INDEXED level that uses at least one IN(...) +** operator. Return true if level pLoop is guaranteed to visit only one +** row for each key generated for the index. +*/ +static int whereLoopIsOneRow(WhereLoop *pLoop){ + if( pLoop->u.btree.pIndex->onError + && pLoop->nSkip==0 + && pLoop->u.btree.nEq==pLoop->u.btree.pIndex->nKeyCol + ){ + int ii; + for(ii=0; ii<pLoop->u.btree.nEq; ii++){ + if( pLoop->aLTerm[ii]->eOperator & (WO_IS|WO_ISNULL) ){ + return 0; + } + } + return 1; + } + return 0; +} + +/* ** Generate code for the start of the iLevel-th loop in the WHERE clause ** implementation described by pWInfo. */ @@ -1415,7 +1436,7 @@ Bitmask sqlite3WhereCodeOneLoopStart( if( pLevel->iFrom>0 && (pTabItem[0].fg.jointype & JT_LEFT)!=0 ){ pLevel->iLeftJoin = ++pParse->nMem; sqlite3VdbeAddOp2(v, OP_Integer, 0, pLevel->iLeftJoin); - VdbeComment((v, "init LEFT JOIN no-match flag")); + VdbeComment((v, "init LEFT JOIN match flag")); } /* Compute a safe address to jump to if we discover that the table for @@ -2084,7 +2105,9 @@ Bitmask sqlite3WhereCodeOneLoopStart( } /* Record the instruction used to terminate the loop. */ - if( pLoop->wsFlags & WHERE_ONEROW ){ + if( (pLoop->wsFlags & WHERE_ONEROW) + || (pLevel->u.in.nIn && regBignull==0 && whereLoopIsOneRow(pLoop)) + ){ pLevel->op = OP_Noop; }else if( bRev ){ pLevel->op = OP_Prev; @@ -2474,6 +2497,12 @@ Bitmask sqlite3WhereCodeOneLoopStart( ** iLoop==3: Code all remaining expressions. ** ** An effort is made to skip unnecessary iterations of the loop. + ** + ** This optimization of causing simple query restrictions to occur before + ** more complex one is call the "push-down" optimization in MySQL. Here + ** in SQLite, the name is "MySQL push-down", since there is also another + ** totally unrelated optimization called "WHERE-clause push-down". + ** Sometimes the qualifier is omitted, resulting in an ambiguity, so beware. */ iLoop = (pIdx ? 1 : 2); do{ @@ -2724,7 +2753,16 @@ SQLITE_NOINLINE void sqlite3WhereRightJoinLoop( pRJ->regReturn); for(k=0; k<iLevel; k++){ int iIdxCur; + SrcItem *pRight; + assert( pWInfo->a[k].pWLoop->iTab == pWInfo->a[k].iFrom ); + pRight = &pWInfo->pTabList->a[pWInfo->a[k].iFrom]; mAll |= pWInfo->a[k].pWLoop->maskSelf; + if( pRight->fg.viaCoroutine ){ + sqlite3VdbeAddOp3( + v, OP_Null, 0, pRight->regResult, + pRight->regResult + pRight->pSelect->pEList->nExpr-1 + ); + } sqlite3VdbeAddOp1(v, OP_NullRow, pWInfo->a[k].iTabCur); iIdxCur = pWInfo->a[k].iIdxCur; if( iIdxCur ){ diff --git a/src/whereexpr.c b/src/whereexpr.c index daf3d5d..5465dc9 100644 --- a/src/whereexpr.c +++ b/src/whereexpr.c @@ -989,7 +989,7 @@ static SQLITE_NOINLINE int exprMightBeIndexed2( if( pIdx->aiColumn[i]!=XN_EXPR ) continue; assert( pIdx->bHasExpr ); if( sqlite3ExprCompareSkip(pExpr,pIdx->aColExpr->a[i].pExpr,iCur)==0 - && pExpr->op!=TK_STRING + && !sqlite3ExprIsConstant(0,pIdx->aColExpr->a[i].pExpr) ){ aiCurCol[0] = iCur; aiCurCol[1] = XN_EXPR; @@ -1638,6 +1638,7 @@ void SQLITE_NOINLINE sqlite3WhereAddLimit(WhereClause *pWC, Select *p){ continue; } if( pWC->a[ii].leftCursor!=iCsr ) return; + if( pWC->a[ii].prereqRight!=0 ) return; } /* Check condition (5). Return early if it is not met. */ @@ -1652,12 +1653,14 @@ void SQLITE_NOINLINE sqlite3WhereAddLimit(WhereClause *pWC, Select *p){ /* All conditions are met. Add the terms to the where-clause object. */ assert( p->pLimit->op==TK_LIMIT ); - whereAddLimitExpr(pWC, p->iLimit, p->pLimit->pLeft, - iCsr, SQLITE_INDEX_CONSTRAINT_LIMIT); - if( p->iOffset>0 ){ + if( p->iOffset!=0 && (p->selFlags & SF_Compound)==0 ){ whereAddLimitExpr(pWC, p->iOffset, p->pLimit->pRight, iCsr, SQLITE_INDEX_CONSTRAINT_OFFSET); } + if( p->iOffset==0 || (p->selFlags & SF_Compound)==0 ){ + whereAddLimitExpr(pWC, p->iLimit, p->pLimit->pLeft, + iCsr, SQLITE_INDEX_CONSTRAINT_LIMIT); + } } } diff --git a/src/window.c b/src/window.c index 62df349..bcee65d 100644 --- a/src/window.c +++ b/src/window.c @@ -1164,7 +1164,7 @@ void sqlite3WindowListDelete(sqlite3 *db, Window *p){ ** variable values in the expression tree. */ static Expr *sqlite3WindowOffsetExpr(Parse *pParse, Expr *pExpr){ - if( 0==sqlite3ExprIsConstant(pExpr) ){ + if( 0==sqlite3ExprIsConstant(0,pExpr) ){ if( IN_RENAME_OBJECT ) sqlite3RenameExprUnmap(pParse, pExpr); sqlite3ExprDelete(pParse->db, pExpr); pExpr = sqlite3ExprAlloc(pParse->db, TK_NULL, 0, 0); diff --git a/test/alter2.test b/test/alter2.test index aae0061..20b75b5 100644 --- a/test/alter2.test +++ b/test/alter2.test @@ -371,7 +371,7 @@ do_test alter2-7.5 { execsql { SELECT a, typeof(a), b, typeof(b), c, typeof(c) FROM t1 LIMIT 1; } -} {1 integer -123 integer 5 text} +} {1 integer -123.0 real 5 text} #----------------------------------------------------------------------- # Test that UPDATE trigger tables work with default values, and that when @@ -397,11 +397,11 @@ do_test alter2-8.2 { UPDATE t1 SET c = 10 WHERE a = 1; SELECT a, typeof(a), b, typeof(b), c, typeof(c) FROM t1 LIMIT 1; } -} {1 integer -123 integer 10 text} +} {1 integer -123.0 real 10 text} ifcapable trigger { do_test alter2-8.3 { set ::val - } {-123 integer 5 text -123 integer 10 text} + } {-123.0 real 5 text -123.0 real 10 text} } #----------------------------------------------------------------------- @@ -425,7 +425,7 @@ ifcapable trigger { DELETE FROM t1 WHERE a = 2; } set ::val - } {-123 integer 5 text} + } {-123.0 real 5 text} } #----------------------------------------------------------------------- diff --git a/test/altertab2.test b/test/altertab2.test index def9e56..576dc49 100644 --- a/test/altertab2.test +++ b/test/altertab2.test @@ -360,4 +360,26 @@ do_catchsql_test 8.6 { SELECT sql FROM sqlite_master WHERE name='i0'; } {1 {error in index i0: second argument to likelihood() must be a constant between 0.0 and 1.0}} + +reset_db + +do_execsql_test 9.0 { + CREATE TABLE t1(a,b,c,d); + CREATE TABLE t2(a,b,c,d,x); + + CREATE TRIGGER AFTER INSERT ON t2 BEGIN + + SELECT group_conct( + 123 ORDER BY ( + SELECT 1 FROM ( VALUES(a, 'b'), ('c') ) + )) + FROM t1; + + END; +} + +do_catchsql_test 9.1 { + ALTER TABLE t2 RENAME TO newname; +} {1 {error in trigger AFTER: all VALUES must have the same number of terms}} + finish_test diff --git a/test/altertab3.test b/test/altertab3.test index 5fd17f3..5f5c11b 100644 --- a/test/altertab3.test +++ b/test/altertab3.test @@ -736,4 +736,54 @@ do_execsql_test 29.7 { END} } +#------------------------------------------------------------------------- +reset_db +do_execsql_test 30.0 { + CREATE TABLE t1(a, b); + CREATE VIEW v1 AS + SELECT ( VALUES(a), (b) ) FROM ( + SELECT a, b FROM t1 + ) + ; +} + +do_execsql_test 30.1 { + SELECT * FROM v1 +} + +do_execsql_test 30.1 { + ALTER TABLE t1 RENAME TO t2; +} +do_execsql_test 30.2 { + SELECT sql FROM sqlite_schema WHERE type='view' +} { + {CREATE VIEW v1 AS + SELECT ( VALUES(a), (b) ) FROM ( + SELECT a, b FROM "t2" + )} +} + +#------------------------------------------------------------------------- +reset_db +do_execsql_test 31.0 { + CREATE TABLE t1(ii INTEGER PRIMARY KEY, tt INTEGER, rr REAL); + WITH s(i) AS ( + SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<50000 + ) + INSERT INTO t1 SELECT NULL, i, 5.0 FROM s; +} + +do_test 31.1 { + set pg [db one {PRAGMA page_count}] + execsql { + ALTER TABLE t1 DROP COLUMN tt; + } + set pg2 [db one {PRAGMA page_count}] + expr $pg==$pg2 +} {1} + +do_execsql_test 31.2 { + SELECT rr FROM t1 LIMIT 1 +} {5.0} + finish_test diff --git a/test/avfs.test b/test/avfs.test index 2ebd608..ffd6b30 100644 --- a/test/avfs.test +++ b/test/avfs.test @@ -8,6 +8,7 @@ # May you share freely, never taking more than you give. # #*********************************************************************** +# TESTRUNNER: shell # # This file implements tests for the appendvfs extension. # diff --git a/test/bestindex8.test b/test/bestindex8.test index e95c3c6..3ed7f67 100644 --- a/test/bestindex8.test +++ b/test/bestindex8.test @@ -158,7 +158,7 @@ do_test 2.2 { set ::lFilterArgs [list] execsql { SELECT * FROM vt1 LIMIT 5 OFFSET 50 } set ::lFilterArgs -} {{5 50}} +} {{50 5}} do_test 2.3 { set ::lFilterArgs [list] diff --git a/test/bestindexC.test b/test/bestindexC.test new file mode 100644 index 0000000..c6ddf30 --- /dev/null +++ b/test/bestindexC.test @@ -0,0 +1,213 @@ +# 2024-04-26 +# +# 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. +# +#*********************************************************************** +# +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set testprefix bestindexC + +ifcapable !vtab { + finish_test + return +} + +register_tcl_module db + +proc vtab_command {lVal method args} { + switch -- $method { + xConnect { + return "CREATE TABLE t1(a)" + } + + xBestIndex { + set hdl [lindex $args 0] + set clist [$hdl constraints] + set orderby [$hdl orderby] + + set idxstr [list] + set res [list] + + set idx 0 + foreach c $clist { + array set a $c + if {$a(usable)==0} continue + if {$a(op)=="limit" && ![info exists ::do_not_use_limit]} { + lappend idxstr limit + lappend res omit $idx + } + if {$a(op)=="offset" && ![info exists ::do_not_use_offset]} { + lappend idxstr offset + lappend res omit $idx + } + incr idx + } + + return "cost 1000000 rows 1000000 idxnum 0 idxstr {$idxstr} $res" + } + + xFilter { + set idxstr [lindex $args 1] + set LIMIT "" + foreach a $idxstr b [lindex $args 2] { + set x($a) $b + } + + if {![info exists x(limit)]} { set x(limit) -1 } + if {![info exists x(offset)]} { set x(offset) -1 } + set LIMIT " LIMIT $x(limit) OFFSET $x(offset)" + + set idx 1 + foreach v $lVal { + lappend lRow "($idx, '$v')" + incr idx + } + + return [list sql " + SELECT * FROM ( VALUES [join $lRow ,]) $LIMIT + "] + } + } + + return {} +} + +do_execsql_test 1.0 { + CREATE VIRTUAL TABLE x1 USING tcl(vtab_command "a b c d e f"); + CREATE VIRTUAL TABLE x2 USING tcl(vtab_command "A B C D E F a b"); +} {} + +do_execsql_test 1.1 { + CREATE TEMP TABLE t_unionall AS + SELECT * FROM x1 UNION ALL SELECT * FROM x2; + + CREATE TEMP TABLE t_intersect AS + SELECT * FROM x1 INTERSECT SELECT * FROM x2; + + CREATE TEMP TABLE t_union AS + SELECT * FROM x1 UNION SELECT * FROM x2; + + CREATE TEMP TABLE t_except AS + SELECT * FROM x1 EXCEPT SELECT * FROM x2; +} + +foreach {tn limit} { + 1 "LIMIT 8" + 2 "LIMIT 4" + 3 "LIMIT 4 OFFSET 2" + 4 "LIMIT 8 OFFSET 4" +} { + + foreach {op tbl} { + "UNION ALL" t_unionall + "UNION" t_union + "INTERSECT" t_intersect + "EXCEPT" t_except + } { + + set expect [execsql "SELECT * FROM $tbl $limit"] + do_execsql_test 1.2.$tbl.$tn "SELECT * FROM ( + SELECT * FROM x1 $op SELECT * FROM x2 + ) $limit" $expect + + } + +} + +#------------------------------------------------------------------------- +reset_db +register_tcl_module db + +do_execsql_test 2.0 { + CREATE VIRTUAL TABLE x1 USING tcl(vtab_command "a b c d e f"); + CREATE VIRTUAL TABLE x2 USING tcl(vtab_command "a b e f"); +} {} + +do_execsql_test 2.1 { + SELECT * FROM x1 + EXCEPT + SELECT * FROM x2 + LIMIT 3 +} {c d} + +#------------------------------------------------------------------------- +reset_db +register_tcl_module db +do_execsql_test 3.0 { + CREATE VIRTUAL TABLE y1 USING tcl(vtab_command "1 2 3 4 5 6 7 8 9 10"); +} {} + +do_execsql_test 3.1 { + SELECT * FROM y1 WHERE a = COALESCE('8', a) LIMIT 3 +} {8} + +do_execsql_test 3.2 { + SELECT * FROM y1 WHERE a = '2' LIMIT 3 +} {2} + +load_static_extension db series +do_execsql_test 3.3 { + SELECT * FROM generate_series(1, 5) WHERE value = (value & 14) LIMIT 3 +} {2 4} + +do_execsql_test 3.4 { + SELECT value FROM generate_series(1,10) WHERE value>2 LIMIT 4 OFFSET 1; +} {4 5 6 7} + +set ::do_not_use_limit 1 +do_execsql_test 3.5 { + SELECT * FROM y1 LIMIT 5 OFFSET 3 +} {4 5 6 7 8} +unset ::do_not_use_limit +set ::do_not_use_offset 1 +do_execsql_test 3.6 { + SELECT * FROM y1 LIMIT 5 OFFSET 3 +} {4 5 6 7 8} +unset ::do_not_use_offset + +#------------------------------------------------------------------------- +reset_db +proc vtab_command {lVal method args} { + switch -- $method { + xConnect { error "not happy!" } + } + + return {} +} + +register_tcl_module db +do_catchsql_test 4.0 { + CREATE VIRTUAL TABLE y1 USING tcl(vtab_command 1); +} {1 {not happy!}} +do_test 4.1 { + sqlite3_errcode db +} SQLITE_ERROR + +proc vtab_command {lVal method args} { + switch -- $method { + xConnect { + return $lVal + } + } + return {} +} + +do_catchsql_test 4.2 { + CREATE VIRTUAL TABLE y1 USING tcl(vtab_command "PRAGMA page_size=1024"); +} {1 {declare_vtab: syntax error}} +do_catchsql_test 4.3 { + CREATE VIRTUAL TABLE y1 USING tcl(vtab_command "CREATE TABLE x1("); +} {1 {declare_vtab: incomplete input}} +do_catchsql_test 4.4 { + CREATE VIRTUAL TABLE y1 USING tcl(vtab_command "CREATE TABLE x1(insert)"); +} {1 {declare_vtab: near "insert": syntax error}} + +finish_test diff --git a/test/busy.test b/test/busy.test index be0515b..896c7fa 100644 --- a/test/busy.test +++ b/test/busy.test @@ -106,7 +106,7 @@ do_test 3.4 { proc busy_handler {n} { return 1 } do_test 3.5 { catchsql { PRAGMA optimize } -} {0 {}} +} {1 {database is locked}} do_test 3.6 { execsql { COMMIT } db2 diff --git a/test/capi3.test b/test/capi3.test index 40d87ac..e65f90e 100644 --- a/test/capi3.test +++ b/test/capi3.test @@ -181,7 +181,7 @@ do_test capi3-3.4 { do_test capi3-3.5 { list [sqlite3_system_errno $db2] [sqlite3_close $db2] } [list $::capi3_errno SQLITE_OK] -if {[clang_sanitize_address]==0} { +if {[clang_sanitize_address]==0 && 0} { do_test capi3-3.6.1-misuse { sqlite3_close $db2 } {SQLITE_MISUSE} diff --git a/test/cksumvfs.test b/test/cksumvfs.test new file mode 100644 index 0000000..8c7bcf5 --- /dev/null +++ b/test/cksumvfs.test @@ -0,0 +1,33 @@ +# 2024 March 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. +# +#*********************************************************************** +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set testprefix cksumvfs + +sqlite3_register_cksumvfs +db close +sqlite3 db test.db +file_control_reservebytes db 8 + +set text [db one "SELECT hex(randomblob(5000))"] + +do_execsql_test 1.0 { + CREATE TABLE t1(a INTEGER PRIMARY KEY, b); + INSERT INTO t1 VALUES(1, $text); +} + +do_execsql_test 1.1 { + SELECT * FROM t1; +} [list 1 $text] + +finish_test diff --git a/test/corruptC.test b/test/corruptC.test index f5733a8..bf324c1 100644 --- a/test/corruptC.test +++ b/test/corruptC.test @@ -98,7 +98,7 @@ do_test corruptC-2.1 { sqlite3 db test.db catchsql {PRAGMA integrity_check} } {0 {{*** in database main *** -Tree 3 page 3: free space corruption}}} +Tree 3 page 3: free space corruption} {wrong # of entries in index t1i1}}} # test that a corrupt content offset size is handled (seed 5649) # diff --git a/test/corruptD.test b/test/corruptD.test index c35388a..381e52c 100644 --- a/test/corruptD.test +++ b/test/corruptD.test @@ -113,7 +113,7 @@ do_test corruptD-1.1.1 { hexio_write test.db [expr 1024+1] FFFF catchsql { PRAGMA quick_check } } {0 {{*** in database main *** -Tree 2 page 2: free space corruption}}} +Tree 2 page 2: free space corruption} {wrong # of entries in index i1}}} do_test corruptD-1.1.2 { incr_change_counter hexio_write test.db [expr 1024+1] [hexio_render_int32 1021] diff --git a/test/corruptL.test b/test/corruptL.test index cf38764..52adf6f 100644 --- a/test/corruptL.test +++ b/test/corruptL.test @@ -1505,4 +1505,89 @@ do_catchsql_test 19.4 { PRAGMA integrity_check; } {1 {database disk image is malformed}} +#------------------------------------------------------------------------- +reset_db +do_test 18.0 { + sqlite3 db {} + db deserialize [decode_hexdb { +.open --hexdb +| size 20480 pagesize 4096 filename crash-a4150b729051e4.db +| page 1 offset 0 +| 0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00 SQLite format 3. +| 16: 10 00 01 01 00 40 20 20 00 00 00 00 00 00 00 05 .....@ ........ +| 32: 00 00 00 00 00 00 00 00 00 00 00 04 00 00 00 04 ................ +| 48: 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00 ................ +| 64: 00 00 00 00 00 00 00 00 00 00 ff f0 00 00 00 00 ................ +| 96: 00 00 00 00 0d 00 00 00 04 0e e5 00 0f c2 0f 75 ...............u +| 112: 0f 19 0e e5 00 00 00 00 00 00 00 01 00 00 00 00 ................ +| 3808: 00 00 00 00 00 32 04 06 17 17 11 01 4b 69 6e 64 .....2......Kind +| 3824: 65 78 74 31 61 62 63 74 31 05 43 52 45 41 54 45 ext1abct1.CREATE +| 3840: 20 49 4e 44 45 58 20 74 31 61 62 63 20 4f 4e 20 INDEX t1abc ON +| 3856: 74 31 28 61 2c 62 2c 63 29 5a 03 06 17 25 25 01 t1(a,b,c)Z...%%. +| 3872: 79 74 61 62 6c 65 73 71 6c 69 74 65 5f 73 74 61 ytablesqlite_sta +| 3888: 74 34 73 71 6c 69 74 65 5f 73 74 61 74 34 04 43 t4sqlite_stat4.C +| 3904: 52 45 41 54 45 20 54 41 42 4c 45 20 73 71 6c 69 REATE TABLE sqli +| 3920: 74 65 5f 73 74 61 74 34 28 74 62 6c 2c 69 64 78 te_stat4(tbl,idx +| 3936: 2c 6e 65 71 2c 6e 6c 74 2c 6e 64 6c 74 2c 73 61 ,neq,nlt,ndlt,sa +| 3952: 6d 70 6c 65 29 4b 02 06 17 25 25 01 5b 74 61 62 mple)K...%%.[tab +| 3968: 6c 65 73 71 6c 69 74 65 5f 73 74 61 74 31 73 71 lesqlite_stat1sq +| 3984: 6c 69 74 65 5f 73 74 61 74 31 03 43 52 45 41 54 lite_stat1.CREAT +| 4000: 45 20 54 41 42 4c 45 20 73 71 6c 69 74 65 5f 73 E TABLE sqlite_s +| 4016: 74 61 74 31 28 74 62 6c 2c 69 64 78 2c 73 74 61 tat1(tbl,idx,sta +| 4032: 74 29 3c 01 06 17 11 11 01 65 74 61 62 6c 65 74 t)<......etablet +| 4048: 31 74 31 02 43 52 45 41 54 45 20 54 41 42 4c 45 1t1.CREATE TABLE +| 4064: 20 74 31 28 61 20 54 45 58 54 2c 20 62 20 49 4e t1(a TEXT, b IN +| 4080: 54 2c 20 63 20 49 4e 54 2c 20 64 20 49 4e 54 29 T, c INT, d INT) +| page 2 offset 4096 +| 0: 0d 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ +| 4000: 0b 07 05 13 01 01 01 62 63 64 64 06 0b 0c 06 05 .......bcdd..... +| 4016: 13 02 01 01 64 65 66 01 59 09 0a 0c 05 05 13 03 ....def.Y....... +| 4032: 01 01 64 65 66 02 6f 08 09 0c 04 05 13 02 01 01 ..def.o......... +| 4048: 61 62 63 01 59 07 08 0c 03 05 13 02 01 01 87 62 abc.Y..........b +| 4064: 63 00 ea 06 07 0c 02 05 13 02 01 01 61 62 63 00 c...........abc. +| 4080: ea 06 06 0b 01 05 13 01 01 01 61 62 63 7b 04 04 ..........abc... +| page 3 offset 8192 +| 0: 0d 00 00 00 01 0f e0 00 0f e1 00 00 00 00 00 00 ................ +| 4064: 00 1d 01 04 11 17 31 74 31 74 31 61 62 63 31 30 ......1t1t1abc10 +| 4080: 30 30 30 20 35 30 30 30 20 32 30 30 30 20 31 30 000 5000 2000 10 +| page 4 offset 12288 +| 0: 0d 00 00 00 07 0e ac 00 0f d1 0f a0 0f 6f 0f 3e .............o.> +| 16: 0f 0e 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ +| 3744: 00 00 00 00 00 00 00 00 00 00 00 00 2f 07 07 11 ............/... +| 3760: 17 1b 1b 1b 24 74 31 74 31 61 62 63 32 20 31 20 ....$t1t1abc2 1 +| 3776: 31 20 31 35 20 36 20 36 20 36 32 20 35 20 36 20 1 15 6 6 62 5 6 +| 3792: 36 05 13 02 01 01 64 65 66 02 37 08 05 2f 06 07 6.....def.7../.. +| 3808: 11 17 1b 1b 1b 24 74 41 74 31 61 62 63 32 20 31 .....$tAt1abc2 1 +| 3824: 20 31 20 31 35 20 35 20 55 20 35 32 20 34 20 35 1 15 5 U 52 4 5 +| 3840: 20 35 05 13 02 01 01 64 65 66 01 59 09 06 2e 05 5.....def.Y.... +| 3856: 07 11 17 1b 1b 1b 22 74 31 74 31 61 62 63 31 20 .......t1t1abc1 +| 3872: 31 20 31 20 31 34 20 34 20 34 20 34 31 20 33 20 1 1 14 4 4 41 3 +| 3888: 34 20 34 08 b3 cd f0 f1 62 63 64 64 06 07 2f 05 4 4.....bcdd../. +| 3904: 07 11 17 1b 1b 1b 24 74 37 74 31 61 62 63 34 20 ......$t7t1abc4 +| 3920: 31 20 31 20 31 30 20 33 20 33 20 33 30 20 32 20 1 1 10 3 3 30 2 +| 3936: 33 20 33 05 13 02 01 01 61 62 63 01 59 07 04 2f 3 3.....abc.Y../ +| 3952: 03 07 11 17 1b 1b 1b 24 74 31 74 31 61 62 63 34 .......$t1t1abc4 +| 3968: 20 32 20 31 20 31 30 20 31 20 32 20 32 30 20 31 2 1 10 1 2 20 1 +| 3984: 20 32 20 32 05 13 02 01 01 61 62 63 00 ea 06 03 2 2.....abc.... +| 4000: 2f 02 07 11 17 1b 1b 1b 24 74 31 74 31 61 62 63 /.......$t1t1abc +| 4016: 34 20 32 20 31 20 31 30 20 31 20 31 20 31 30 20 4 2 1 10 1 1 10 +| 4032: 31 20 31 20 31 05 13 02 01 01 61 62 63 00 ea 05 1 1 1.....abc... +| 4048: 02 2d 01 07 11 17 1b 1b 1b 20 74 31 74 31 61 62 .-....... t1t1ab +| 4064: 63 34 20 31 20 31 20 31 30 20 30 20 30 1f 30 30 c4 1 1 10 0 0.00 +| 4080: 20 30 20 30 20 30 05 13 01 01 09 61 62 63 7b 04 0 0 0.....abc.. +| page 5 offset 16384 +| 0: 0a 00 00 00 07 0f a8 00 0f f5 00 00 00 00 00 00 ................ +| 4000: 00 00 00 00 00 00 00 00 0c 05 13 02 01 01 64 65 ..............de +| 4016: 66 02 37 08 05 0c 05 13 02 01 01 64 65 66 01 59 f.7........def.Y +| 4032: 09 06 0b 05 12 01 01 01 62 63 64 64 06 07 0c 05 ........bcdd.... +| 4048: 13 02 01 01 61 62 63 01 59 07 01 2c 05 13 02 01 ....abc.Y..,.... +| 4064: 01 61 62 63 00 ea 06 03 0c 05 13 02 01 01 61 62 .abc..........ab +| 4080: 63 00 ea 05 00 00 00 00 00 00 00 00 00 00 00 00 c............... +| end crash-a4150b729051e4.db +}]} {} + +do_catchsql_test 18.1 { + SELECT a FROM t1 WHERE b GLOB b AND b GLOB '0^x]␅6␚xz]'; +} {1 {database disk image is malformed}} + finish_test diff --git a/test/cost.test b/test/cost.test index 5684177..6106cab 100644 --- a/test/cost.test +++ b/test/cost.test @@ -103,7 +103,7 @@ do_eqp_test 5.2 { } { QUERY PLAN |--SCAN t2 USING INDEX t2i1 - `--USE TEMP B-TREE FOR RIGHT PART OF ORDER BY + `--USE TEMP B-TREE FOR LAST TERM OF ORDER BY } do_eqp_test 5.3 { diff --git a/test/date.test b/test/date.test index 19cecc2..d22b652 100644 --- a/test/date.test +++ b/test/date.test @@ -209,8 +209,8 @@ datetest 3.16 "strftime('[repeat 200 %Y]','2003-10-31')" [repeat 200 2003] datetest 3.17 "strftime('[repeat 200 abc%m123]','2003-10-31')" \ [repeat 200 abc10123] -foreach c {a b c g h i n o q r t v x y z - A B C D E G K L N O Q V Z +foreach c {a b c h i n o q r t v x y z + A B C D E K L N O Q Z 0 1 2 3 4 5 6 6 7 9 _} { datetest 3.18.$c "strftime('%$c','2003-10-31')" NULL } @@ -262,7 +262,7 @@ datetest 5.15 {datetime('1994-04-16 14:00:00 +05:00 Z')} NULL # localtime->utc and utc->localtime conversions. # # Use SQLITE_TESTCTRL_LOCALTIME_FAULT=2 to set an alternative localtime_r() -# implementation that is not locale-dependent. This testing localtime_r() +# implementation that is not locale-dependent. The testing localtime_r() # operates as follows: # # (1) Localtime is 30 minutes earlier than (west of) UTC on @@ -321,6 +321,38 @@ utc_to_local 6.22 {1800-10-29 12:30:00} {1800-10-29 12:00:00} local_to_utc 6.23 {3000-10-30 12:00:00} {3000-10-30 11:30:00} utc_to_local 6.24 {3000-10-30 11:30:00} {3000-10-30 12:00:00} +# If the time is specified to be ZULU, or if it has an explicit +# timezone extension, then the time will already be UTC and subsequent +# 'utc' modifiers are no-ops. +# +do_execsql_test date-6.25 { + SELECT datetime('2000-10-29 12:00Z','utc','utc'); +} {{2000-10-29 12:00:00}} +do_execsql_test date-6.26 { + SELECT datetime('2000-10-29 12:00:00+05:00'); +} {{2000-10-29 07:00:00}} +do_execsql_test date-6.27 { + SELECT datetime('2000-10-29 12:00:00+05:00', 'utc'); +} {{2000-10-29 07:00:00}} + +# Multiple back-and-forth UTC to LOCAL to UTC... +do_execsql_test date-6.28 { + SELECT datetime('2000-10-29 12:00:00Z', 'localtime'); +} {{2000-10-29 12:30:00}} +do_execsql_test date-6.29 { + SELECT datetime('2000-10-29 12:00:00Z', 'utc', 'localtime'); +} {{2000-10-29 12:30:00}} +do_execsql_test date-6.30 { + SELECT datetime('2000-10-29 12:00:00Z', 'utc', 'localtime', 'utc'); +} {{2000-10-29 12:00:00}} +do_execsql_test date-6.31 { + SELECT datetime('2000-10-29 12:00:00Z', 'utc','localtime','utc','localtime'); +} {{2000-10-29 12:30:00}} +do_execsql_test date-6.32 { + SELECT datetime('2000-10-29 12:00:00Z', 'localtime','localtime'); +} {{2000-10-29 12:30:00}} + + # Restore the use of the OS localtime_r() before going on... sqlite3_test_control SQLITE_TESTCTRL_LOCALTIME_FAULT 0 @@ -573,4 +605,51 @@ datetest 18.2 {unixepoch('1970-01-01T00:00:00.1', 'subsec')} {0.1} datetest 18.3 {unixepoch('1970-01-01T00:00:00.2', 'subsecond')} {0.2} datetest 18.4 {julianday('-4713-11-24 13:40:48.864', 'subsec')} {0.07001} datetest 18.5 {typeof(unixepoch('now', 'subsecond'))} {real} + +# 2024-03-03 the 'ceiling' and 'floor' operators. +# +datetest 19.1 {date('2000-01-31','floor')} {2000-01-31} +datetest 19.2a {date('2000-02-31','floor')} {2000-02-29} +datetest 19.2b {date('1999-02-31','floor')} {1999-02-28} +datetest 19.2c {date('1900-02-31','floor')} {1900-02-28} +datetest 19.3 {date('2000-03-31','floor')} {2000-03-31} +datetest 19.4 {date('2000-04-31','floor')} {2000-04-30} +datetest 19.5 {date('2000-05-31','floor')} {2000-05-31} +datetest 19.6 {date('2000-06-31','floor')} {2000-06-30} +datetest 19.7 {date('2000-07-31','floor')} {2000-07-31} +datetest 19.8 {date('2000-08-31','floor')} {2000-08-31} +datetest 19.9 {date('2000-09-31','floor')} {2000-09-30} +datetest 19.10 {date('2000-10-31','floor')} {2000-10-31} +datetest 19.11 {date('2000-11-31','floor')} {2000-11-30} +datetest 19.12 {date('2000-12-31','floor')} {2000-12-31} +datetest 19.21 {date('2000-01-31','ceiling')} {2000-01-31} +datetest 19.22a {date('2000-02-31','ceiling')} {2000-03-02} +datetest 19.22b {date('1999-02-31','ceiling')} {1999-03-03} +datetest 19.22c {date('1900-02-31','ceiling')} {1900-03-03} +datetest 19.23 {date('2000-03-31','ceiling')} {2000-03-31} +datetest 19.24 {date('2000-04-31','ceiling')} {2000-05-01} +datetest 19.25 {date('2000-05-31','ceiling')} {2000-05-31} +datetest 19.26 {date('2000-06-31','ceiling')} {2000-07-01} +datetest 19.27 {date('2000-07-31','ceiling')} {2000-07-31} +datetest 19.28 {date('2000-08-31','ceiling')} {2000-08-31} +datetest 19.29 {date('2000-09-31','ceiling')} {2000-10-01} +datetest 19.30 {date('2000-10-31','ceiling')} {2000-10-31} +datetest 19.31 {date('2000-11-31','ceiling')} {2000-12-01} +datetest 19.32 {date('2000-12-31','ceiling')} {2000-12-31} +datetest 19.40 {date('2024-01-31','+1 month','ceiling')} {2024-03-02} +datetest 19.41 {date('2024-01-31','+1 month','floor')} {2024-02-29} +datetest 19.42 {date('2023-01-31','+1 month','ceiling')} {2023-03-03} +datetest 19.43 {date('2023-01-31','+1 month','floor')} {2023-02-28} +datetest 19.44 {date('2024-02-29','+1 year','ceiling')} {2025-03-01} +datetest 19.45 {date('2024-02-29','+1 year','floor')} {2025-02-28} +datetest 19.46 {date('2024-02-29','-110 years','ceiling')} {1914-03-01} +datetest 19.47 {date('2024-02-29','-110 years','floor')} {1914-02-28} +datetest 19.48 {date('2024-02-29','-0110-00-00','floor')} {1914-02-28} +datetest 19.49 {date('2024-02-29','-0110-00-00','ceiling')} {1914-03-01} +datetest 19.50 {date('2000-08-31','+0023-06-00','floor')} {2024-02-29} +datetest 19.51 {date('2000-08-31','+0022-06-00','floor')} {2023-02-28} +datetest 19.52 {date('2000-08-31','+0023-06-00','ceiling')} {2024-03-02} +datetest 19.53 {date('2000-08-31','+0022-06-00','ceiling')} {2023-03-03} + + finish_test diff --git a/test/date4.test b/test/date4.test index 0d820a0..56a9090 100644 --- a/test/date4.test +++ b/test/date4.test @@ -24,12 +24,12 @@ ifcapable {!datetime} { } if {$tcl_platform(os)=="Linux"} { - set FMT {%d,%e,%F,%H,%k,%I,%l,%j,%m,%M,%u,%w,%W,%Y,%%,%P,%p} + set FMT {%d,%e,%F,%H,%k,%I,%l,%j,%m,%M,%u,%w,%W,%Y,%%,%P,%p,%U,%V,%G,%g} } else { set FMT {%d,%e,%F,%H,%I,%j,%p,%R,%u,%w,%W,%%} } -for {set i 0} {$i<=24854} {incr i} { - set TS [expr {$i*86401}] +for {set i 0} {$i<=24858} {incr i} { + set TS [expr {$i*86390}] do_execsql_test date4-$i { SELECT strftime($::FMT,$::TS,'unixepoch'); } [list [strftime $FMT $TS]] diff --git a/test/default.test b/test/default.test index de67f64..192b3d2 100644 --- a/test/default.test +++ b/test/default.test @@ -135,10 +135,10 @@ reset_db do_catchsql_test default-5.1 { CREATE TABLE t1 (a,b DEFAULT(random() NOTNULL IN (RAISE(IGNORE),2,3))); INSERT INTO t1(a) VALUES(1); -} {1 {RAISE() may only be used within a trigger-program}} +} {1 {default value of column [b] is not constant}} do_catchsql_test default-5.2 { CREATE TABLE Table0 (Col0 DEFAULT (RAISE(IGNORE) ) ) ; INSERT INTO Table0 DEFAULT VALUES ; -} {1 {RAISE() may only be used within a trigger-program}} +} {1 {default value of column [Col0] is not constant}} finish_test diff --git a/test/distinctagg.test b/test/distinctagg.test index 199ca06..9eedd35 100644 --- a/test/distinctagg.test +++ b/test/distinctagg.test @@ -95,7 +95,7 @@ foreach {tn use_eph sql res} { 7 0 "SELECT count(DISTINCT a) FROM t2, t1" 5 8 1 "SELECT count(DISTINCT a+b) FROM t1, t2, t2, t2" 6 9 0 "SELECT count(DISTINCT c) FROM t1 WHERE c=2" 1 - 10 1 "SELECT count(DISTINCT t1.rowid) FROM t1, t2" 10 + 10 0 "SELECT count(DISTINCT t1.rowid) FROM t1, t2" 10 } { do_test 3.$tn.1 { set prg [db eval "EXPLAIN $sql"] @@ -148,6 +148,10 @@ do_execsql_test 3.0 { CREATE TABLE t3(x, y, z); INSERT INTO t3 VALUES(1,1,1); INSERT INTO t3 VALUES(2,2,2); + + CREATE TABLE t4(a); + CREATE INDEX t4a ON t4(a); + INSERT INTO t4 VALUES(1), (2), (2), (3), (1); } foreach {tn use_eph sql res} { @@ -158,6 +162,9 @@ foreach {tn use_eph sql res} { 4 0 "SELECT count(DISTINCT f) FROM t2 GROUP BY d, e" {1 2 2 3} 5 1 "SELECT count(DISTINCT f) FROM t2 GROUP BY d" {2 3} 6 0 "SELECT count(DISTINCT f) FROM t2 WHERE d IS 1 GROUP BY e" {1 2 2} + + 7 0 "SELECT count(DISTINCT a) FROM t1" {4} + 8 0 "SELECT count(DISTINCT a) FROM t4" {3} } { do_test 4.$tn.1 { set prg [db eval "EXPLAIN $sql"] diff --git a/test/e_reindex.test b/test/e_reindex.test index 00291b7..50d2e7d 100644 --- a/test/e_reindex.test +++ b/test/e_reindex.test @@ -73,12 +73,12 @@ sqlite3 db test.db do_execsql_test e_reindex-1.3 { PRAGMA integrity_check; } [list \ + {wrong # of entries in index i2} \ + {wrong # of entries in index i1} \ {row 3 missing from index i2} \ {row 3 missing from index i1} \ {row 4 missing from index i2} \ - {row 4 missing from index i1} \ - {wrong # of entries in index i2} \ - {wrong # of entries in index i1} + {row 4 missing from index i1} ] do_execsql_test e_reindex-1.4 { diff --git a/test/eqp.test b/test/eqp.test index 61fd617..cd441c2 100644 --- a/test/eqp.test +++ b/test/eqp.test @@ -413,7 +413,7 @@ do_eqp_test 4.2.3 { | `--USE TEMP B-TREE FOR ORDER BY `--RIGHT |--SCAN t2 USING INDEX t2i1 - `--USE TEMP B-TREE FOR RIGHT PART OF ORDER BY + `--USE TEMP B-TREE FOR LAST 2 TERMS OF ORDER BY } do_eqp_test 4.2.4 { SELECT * FROM t1 INTERSECT SELECT * FROM t2 ORDER BY 1 @@ -425,7 +425,7 @@ do_eqp_test 4.2.4 { | `--USE TEMP B-TREE FOR ORDER BY `--RIGHT |--SCAN t2 USING INDEX t2i1 - `--USE TEMP B-TREE FOR RIGHT PART OF ORDER BY + `--USE TEMP B-TREE FOR LAST 2 TERMS OF ORDER BY } do_eqp_test 4.2.5 { SELECT * FROM t1 EXCEPT SELECT * FROM t2 ORDER BY 1 @@ -437,7 +437,7 @@ do_eqp_test 4.2.5 { | `--USE TEMP B-TREE FOR ORDER BY `--RIGHT |--SCAN t2 USING INDEX t2i1 - `--USE TEMP B-TREE FOR RIGHT PART OF ORDER BY + `--USE TEMP B-TREE FOR LAST 2 TERMS OF ORDER BY } do_eqp_test 4.3.1 { diff --git a/test/eqp2.test b/test/eqp2.test new file mode 100644 index 0000000..3c634fc --- /dev/null +++ b/test/eqp2.test @@ -0,0 +1,49 @@ +# 2024 March 20 +# +# 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. +# +#*********************************************************************** +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl + +set testprefix eqp2 + +do_execsql_test 1.0 { + CREATE TABLE t1(a, b, c, d); + CREATE INDEX i1 ON t1(a, b, c); +} + +do_eqp_test 1.1 { + SELECT * FROM t1 ORDER BY a, b, c +} { + QUERY PLAN + `--SCAN t1 USING INDEX i1 +} + + +do_eqp_test 1.2 { + SELECT * FROM t1 ORDER BY a, b, +c +} { + QUERY PLAN + |--SCAN t1 USING INDEX i1 + `--USE TEMP B-TREE FOR LAST TERM OF ORDER BY +} + +do_eqp_test 1.3 { + SELECT * FROM t1 ORDER BY a, +b, +c +} { + QUERY PLAN + |--SCAN t1 USING INDEX i1 + `--USE TEMP B-TREE FOR LAST 2 TERMS OF ORDER BY +} + +finish_test + + diff --git a/test/exprfault2.test b/test/exprfault2.test new file mode 100644 index 0000000..acbead5 --- /dev/null +++ b/test/exprfault2.test @@ -0,0 +1,35 @@ +# 2024-05-11 +# +# 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. +# +#*********************************************************************** +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set testprefix exprfault2 + +do_execsql_test 1.0 { + CREATE TABLE t1(a,b,c,d,f,PRIMARY KEY(b,b)); + CREATE TABLE t2(x INT PRIMARY KEY, y, z); + CREATE TABLE t3(a,b,c,d,e,PRIMARY KEY(a,b))WITHOUT ROWID; +} +faultsim_save_and_close + + +do_faultsim_test 1 -faults oom-t* -prep { + faultsim_restore_and_reopen +} -body { + execsql { + UPDATE t3 SET (d,d,d,d, a )=(SELECT EXISTS(SELECT 1 NOT IN(SELECT EXISTS(SELECT 1 IN(SELECT max( 1 IN(SELECT x ORDER BY 1)) OVER(PARTITION BY sum((SELECT y FROM t2 UNION SELECT (SELECT max( 1 IN(SELECT x NOT IN(SELECT 1 NOT IN(SELECT EXISTS(SELECT 1 IN(SELECT max( 1 IN(SELECT x ORDER BY 1)) OVER(PARTITION BY sum((SELECT y FROM t2 UNION SELECT (SELECT max( (SELECT x NOT IN(SELECT 1 NOT IN(SELECT EXISTS(SELECT 1 IN(SELECT max( 1 IN(SELECT x ORDER BY 1)) OVER(PARTITION BY sum((SELECT y FROM t2 UNION SELECT (SELECT max( 1 IN(SELECT x ORDER BY 1)) OVER(PARTITION BY sum((SELECT y FROM t2 UNION SELECT x ORDER BY 1)))INTERSECT SELECT (SELECT 1 FROM t2 UNION SELECT d ORDER BY 1) ORDER BY 1) ORDERa)| (SELECT 1 x ORDER BY 1)))INTERSECT SELECT EXISTS(SELECT 1 FROM t2 UNION SELECT d ORDER BY 1) ORDER BY 1) a)| (SELECT 1 IN(SELECT max( 1 IN(SELECT x ORDER BY 1)) OVER(ORDER BY sum((SELECT DISTINCT y FROM t2 UNION SELECT x ORDER BY 1)))INTERSECT SELECT EXISTS(SELECT 1 FROM t2 UNION SELECT x ORDER BY 1) ORDER BY 1) z)|9 AS blob) IN(SELECT max( 1 IN(SELECT x ORDER BY 1)) OVER(PARTITION BY sum((SELECT DISTINCT y FROM t2 UNION SELECT x ORDER BY 1)))EXCEPT SELECT EXISTS(SELECT 1 FROM t2 UNION SELECT d ORDER BY 1) ORDER BY 1) z) ORDER BY 1) IN(SELECT x ORDER BY 1)) OVER(PARTITION BY sum((SELECT DISTINCT y FROM t2 UNION SELECT x ORDER BY 1)))INTERSECT SELECT (SELECT 1 FROM t2 UNION SELECT d ORDER BY 1) ORDER BY 1) ORDERa)| (SELECT 1 x ORDER BY 1)))EXCEPT SELECT EXISTS(SELECT 1 FROM t2 UNION SELECT d ORDER BY 1) ORDER BY 1) a)| (SELECT 1 IN(SELECT max( 1 IN(SELECT x ORDER BY 1)) OVER(PARTITION BY sum((SELECT DISTINCT y FROM t2 UNION SELECT x ORDER BY 1)))INTERSECT SELECT EXISTS(SELECT 1 FROM t2 UNION SELECT x ORDER BY 1) ORDER BY 1) z)|9 AS blob) IN(SELECT max( 1 IN(SELECT x ORDER BY 1)) OVER(PARTITION BY sum((SELECT DISTINCT y FROM t2 UNION SELECT x ORDER BY 1)))EXCEPT SELECT EXISTS(SELECT 1 FROM t2 UNION SELECT d ORDER BY 1) ORDER BY 1) z) ORDER BY 1)) OVER(PARTITION BY sum((SELECT y FROM t2 UNION SELECT x ORDER BY 1)))INTERSECT SELECT EXISTS(SELECT 1 FROM t2 UNION SELECT d ORDER BY 1) ORDER BY 1) ORDERa)| (SELECT 1 x ORDER BY 1)))INTERSECT SELECT EXISTS(SELECT 5 FROM t2 UNION SELECT d ORDER BY 1) ORDER BY 1) ORDERa)| (SELECT 1 IN(SELECT max( 1 IN(SELECT x ORDER BY 1)) OVER(ORDER BY sum((SELECT DISTINCT y FROM t2 UNION SELECT x ORDER BY 1)))INTERSECT SELECT EXISTS(SELECT 1 FROM t2 UNION SELECT x ORDER BY 1) ORDER BY 1) z)| 1 AS blob) IN(SELECT max( 1 IN(SELECT x ORDER BY 1)) OVER(PARTITION BY sum((SELECT DISTINCT y FROM t2 UNION SELECT x ORDER BY 1)))INTERSECT SELECT EXISTS(SELECT 1 FROM t2 UNION SELECT d ORDER BY 1) ORDER BY 1) z)| (SELECT 1 IN(SELECT max( 1 IN(SELECT c ORDER BY 1)) OVER(PARTITION BY sum((SELECT y FROM t2 UNION SELECT x ORDER BY 1)))INTERSECT SELECT (SELECT 1 FROM t2 UNION SELECT x ORDER BY 1) ORDER BY 1) e)|9 AS blob) FROM t2 WHERE a<x), e= BY 1) FROM t2 UNION SELECT 1 ORDER BY 1) ORDER BY 1)) a) FILTER (GROUP BY 1 HAVING b<= OVER(ORDER BY (SELECT max(x INPARTITION BY sum((SELECT y FROM t2 UNION SELECT x IN(SELECT 1 ORDER BY 1) ORDER 1)))INTERSECT SELECT EXISTS(SELECT 1 FROM t2 WHERE xBY 1) ORDER BY 1)) FROM77; + } +} -test { + faultsim_test_result {1 {near ")": syntax error}} +} + +finish_test diff --git a/test/fts3fault3.test b/test/fts3fault3.test index 6e1c0cd..ae20471 100644 --- a/test/fts3fault3.test +++ b/test/fts3fault3.test @@ -50,5 +50,33 @@ do_faultsim_test 1 -faults oom* -prep { faultsim_test_result {0 {}} } +#------------------------------------------------------------------- +reset_db + +do_execsql_test 2.0 { + BEGIN; + CREATE VIRTUAL TABLE t1 USING fts3(a); + WITH s(i) AS ( + SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<50 + ) + INSERT INTO t1 SELECT 'abc def ghi jkl mno pqr' FROM s; + COMMIT; +} + +faultsim_save_and_close +do_faultsim_test 2 -faults oom-t* -prep { + faultsim_restore_and_reopen + execsql { + BEGIN; + CREATE TABLE x1(a PRIMARY KEY); + } +} -body { + execsql { + PRAGMA integrity_check; + } +} -test { + faultsim_test_result {0 ok} $::TMPDBERROR +} + finish_test diff --git a/test/fts3snippet2.test b/test/fts3snippet2.test index 607b01e..f55a5f2 100644 --- a/test/fts3snippet2.test +++ b/test/fts3snippet2.test @@ -55,5 +55,16 @@ do_execsql_test 2.2 { '(def AND (one NEAR abc)) OR one' } {<b>one</b>} +#------------------------------------------------------------------------- + +do_execsql_test 3.0 { +CREATE VIRTUAL TABLE f USING fts3(a,b); +INSERT INTO f VALUES (101,x'056522650565056505650d051e056505650565286505650565056505056505650565056505650565056505650565056505650565056505656505650565056505650d05650505656505650565ef65056505844c746e65650565056505650565056505650565056505650565058405800565056505650565056505651e650565056505650565056505650d056505056565056505650565056505840580056505650565056f05650565056505650565056505650565050565056505640565056505650565056505651e05650565056505650565056505650505656565056505650565056505651e0565056505650565056505650565052265056505650569056505650565056505650565056505650565056505650500406505650565056505650565056505000101e5c501014b010101c501c5c501010101f5010201010101014101017373737373737373737373737373737373737373737373737373737330737373737373737373737373737365056505650d051e05650565056528056505650d05650505656505650565650565056505650565056505e505650565056505656505650565056505650d05650505656505650565ef65056505844c746e65650565056505650565056505650565056505650565058405800565056505650565056505651e650565056505650565056505650d056505056565056505650565056505840580056505650565286505c705650565050565059494949494949494949494949494949494949494949494949494949494949494949494650565056505650565056505650565056505650565056505656505650565056505650d05650505656505650565ef650565058405056505650565056505650565056505650565056505650565058405800565056505650565056505651e650565056505650565056505650d056505056565056505650565056505840580056505650565056505650565056505650505650565056505650565056505650565056500000000000000000000000000000000000000000000000000000000000000000565056505656505650565056505650d056500000000000000000000000000000000000000000000000000000000000000000100000000000000ed0000000000ffffffffffffffffffffff0007ffffff0001c5c50001c5c50001c5c50001c5c50001c5c50001c5c50001e5c50001c5c50001c5c50001c5c50001c5c50001c5c5000100000014720000000000000016dac5c50001c5c50001c5c50001c5c50001c5c50001c5c50d0505656505650565ef650565058405056505650565056505650565056505650565056505650565058405800465056505650565056505651e650565056505650565056505650d05650505656505650565050565650584058005650565056505650565056505650565056522650565056505650d051e056505650561286505c70565056505056505650565056505650565056505650565056505650565056505656505650565056505650d05650505656505650565ef650565058405056505650565056505650565056505650565056505650565058405800565056505650565056505651e650565056505650565056505650d056505056565056505650565056505840580056505650565056505650565056505650565226505737373737373737373737373737373737373737373737373737373737373737373737373737373737373737373737373733a73737373737373737373737373737373737373737373737373737373737373737373737373737373737c7373737365056505650d051e05650565056528650565056505650505650565056505650565056505650565056505e505650565056505656505650565056505650d05650505656505650565ef65056505'); +} + +do_execsql_test 3.1 { + SELECT length(snippet(f)) FROM f WHERE b MATCH x'0565056505650565056505650565056505650565058405800565056505650565056505651e650565056505650565056505650d056505056565056505650565056505840580056505650565056505650565056505650565056505650565050565056505640565056505650565056505651e05650565056522650565056505650d051e056505650565286505650565056505056505650565056505650565056505650565056505650565056505656505650565056505650d05650505656505650565ef65056505844c746e65650565056505650565056505650565056505650565058405800565056505650565056505651e650565056505650565056505650d056505056565056505650565056505840580056505650565056f05650565056505650565056505650565050565056505640565056505650565056505651e05650565056505650565056505650505656565056505650565056505651e0565056505650565056505650565052265056505650569056505650565056505650565056505650565056505650500406505650565056505650565056505000101e5c501014b010101c501c5c501010101f50102010101010141010141010001017bf15905000000000017'; +} {192} + set sqlite_fts3_enable_parentheses 0 finish_test diff --git a/test/func2.test b/test/func2.test index 08ad857..a7c7ec3 100644 --- a/test/func2.test +++ b/test/func2.test @@ -508,4 +508,27 @@ do_test func2-3.9.2 { bin_to_hex [lindex $blob 0] } "12" +#------------------------------------------------------------------------- +# At one point this was extremely slow to compile. +# +do_test func2-3.10 { + set tm [time { + execsql { + SELECT '' IN (zerobloB(zerobloB(zerobloB(zerobloB(zerobloB( + zerobloB(zerobloB(zerobloB(zerobloB(zerobloB(zerobloB(zerobloB( + zerobloB(zerobloB(zerobloB(zerobloB(zerobloB(zerobloB(zerobloB( + zerobloB(zerobloB(zerobloB(zerobloB(zerobloB(zerobloB(zerobloB( + zerobloB(zerobloB(zerobloB(zerobloB(zerobloB(zerobloB(zerobloB( + zerobloB(zerobloB(zerobloB(zerobloB(zerobloB(zerobloB(zerobloB( + zerobloB(zerobloB(zerobloB(zerobloB(zerobloB(zerobloB(zerobloB( + zerobloB(zerobloB(zerobloB(zerobloB(zerobloB(zerobloB(zerobloB( + zerobloB(zerobloB(zerobloB(zerobloB(zerobloB(zerobloB(zerobloB(1) + ))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) + } + }] + + set tm [lindex $tm 0] + expr $tm<2000000 +} {1} + finish_test diff --git a/test/func4.test b/test/func4.test index 64c7a11..56cc906 100644 --- a/test/func4.test +++ b/test/func4.test @@ -1,4 +1,4 @@ -# 2013 March 10 +# 2023-03-10 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: @@ -9,7 +9,10 @@ # #*********************************************************************** # This file implements regression tests for SQLite library. The focus of -# this file is testing the tointeger() and toreal() functions. +# this file is testing the tointeger() and toreal() functions that are +# part of the "totype.c" extension. This file does not test the core +# SQLite library. Failures of tests in this file are related to the +# ext/misc/totype.c extension. # # Several of the toreal() tests are disabled on platforms where floating # point precision is not high enough to represent their constant integer @@ -23,6 +26,20 @@ load_static_extension db totype set highPrecision(1) [expr \ {[db eval {SELECT tointeger(9223372036854775807 + 1);}] eq {{}}}] +set highPrecision(2) [expr \ + {[db eval {SELECT toreal(-9223372036854775808 + 1);}] eq {{}}}] + +# highPrecision(3) is only known to be false on i586 with gcc-13 and -O2. +# It is true on the exact same platform with -O0. Both results seem +# reasonable, so we'll just very the expectation accordingly. +# +set highPrecision(3) [expr \ + {[db eval {SELECT toreal(9007199254740992 + 1);}] eq {{}}}] + +if {!$highPrecision(1) || !$highPrecision(2) || !$highPrecision(3)} { + puts "NOTICE: use_long_double: [use_long_double] \ + highPrecision: $highPrecision(1) $highPrecision(2) $highPrecision(3)" +} do_execsql_test func4-1.1 { SELECT tointeger(NULL); @@ -195,8 +212,6 @@ do_execsql_test func4-1.55 { } {{}} ifcapable floatingpoint { - set highPrecision(2) [expr \ - {[db eval {SELECT toreal(-9223372036854775808 + 1);}] eq {{}}}] do_execsql_test func4-2.1 { SELECT toreal(NULL); @@ -341,10 +356,14 @@ ifcapable floatingpoint { do_execsql_test func4-2.45 { SELECT toreal(9007199254740992); } {9007199254740992.0} - if {$highPrecision(2)} { + if {$highPrecision(3)} { do_execsql_test func4-2.46 { SELECT toreal(9007199254740992 + 1); } {{}} + } else { + do_execsql_test func4-2.46 { + SELECT toreal(9007199254740992 + 1); + } {9007199254740992.0} } do_execsql_test func4-2.47 { SELECT toreal(9007199254740992 + 2); @@ -626,10 +645,14 @@ ifcapable floatingpoint { do_execsql_test func4-5.22 { SELECT tointeger(toreal(9007199254740992)); } {9007199254740992} - if {$highPrecision(2)} { + if {$highPrecision(3)} { do_execsql_test func4-5.23 { SELECT tointeger(toreal(9007199254740992 + 1)); } {{}} + } else { + do_execsql_test func4-5.23 { + SELECT tointeger(toreal(9007199254740992 + 1)); + } {9007199254740992} } do_execsql_test func4-5.24 { SELECT tointeger(toreal(9007199254740992 + 2)); diff --git a/test/fuzzcheck.c b/test/fuzzcheck.c index e4ad1c1..6cae348 100644 --- a/test/fuzzcheck.c +++ b/test/fuzzcheck.c @@ -979,7 +979,8 @@ extern int fuzz_invariant( int iRow, /* The row number for pStmt */ int nRow, /* Total number of output rows */ int *pbCorrupt, /* IN/OUT: Flag indicating a corrupt database file */ - int eVerbosity /* How much debugging output */ + int eVerbosity, /* How much debugging output */ + unsigned int dbOpt /* Default optimization flags */ ); /* Implementation of sqlite_dbdata and sqlite_dbptr */ @@ -1031,7 +1032,12 @@ static int recoverDatabase(sqlite3 *db){ /* ** Run the SQL text */ -static int runDbSql(sqlite3 *db, const char *zSql, unsigned int *pBtsFlags){ +static int runDbSql( + sqlite3 *db, /* Run SQL on this database connection */ + const char *zSql, /* The SQL to be run */ + unsigned int *pBtsFlags, + unsigned int dbOpt /* Default optimization flags */ +){ int rc; sqlite3_stmt *pStmt; int bCorrupt = 0; @@ -1107,7 +1113,7 @@ static int runDbSql(sqlite3 *db, const char *zSql, unsigned int *pBtsFlags){ iRow++; for(iCnt=0; iCnt<99999; iCnt++){ rc = fuzz_invariant(db, pStmt, iCnt, iRow, nRow, - &bCorrupt, eVerbosity); + &bCorrupt, eVerbosity, dbOpt); if( rc==SQLITE_DONE ) break; if( rc!=SQLITE_ERROR ) g.nInvariant++; if( eVerbosity>0 ){ @@ -1330,7 +1336,7 @@ int runCombinedDbSqlInput( char cSaved = zSql[i+1]; zSql[i+1] = 0; if( sqlite3_complete(zSql+j) ){ - rc = runDbSql(cx.db, zSql+j, &btsFlags); + rc = runDbSql(cx.db, zSql+j, &btsFlags, dbOpt); j = i+1; } zSql[i+1] = cSaved; @@ -1340,7 +1346,7 @@ int runCombinedDbSqlInput( } } if( j<i ){ - runDbSql(cx.db, zSql+j, &btsFlags); + runDbSql(cx.db, zSql+j, &btsFlags, dbOpt); } } testrun_finished: diff --git a/test/fuzzinvariants.c b/test/fuzzinvariants.c index 00b2c11..80eb4ae 100644 --- a/test/fuzzinvariants.c +++ b/test/fuzzinvariants.c @@ -30,7 +30,13 @@ /* Forward references */ static char *fuzz_invariant_sql(sqlite3_stmt*, int); static int sameValue(sqlite3_stmt*,int,sqlite3_stmt*,int,sqlite3_stmt*); -static void reportInvariantFailed(sqlite3_stmt*,sqlite3_stmt*,int); +static void reportInvariantFailed( + sqlite3_stmt *pOrig, /* The original query */ + sqlite3_stmt *pTest, /* The alternative test query with a missing row */ + int iRow, /* Row number in pOrig */ + unsigned int dbOpt, /* Optimization flags on pOrig */ + int noOpt /* True if opt flags inverted for pTest */ +); /* ** Do an invariant check on pStmt. iCnt determines which invariant check to @@ -68,7 +74,8 @@ int fuzz_invariant( int iRow, /* Current row number */ int nRow, /* Number of output rows from pStmt */ int *pbCorrupt, /* IN/OUT: Flag indicating a corrupt database file */ - int eVerbosity /* How much debugging output */ + int eVerbosity, /* How much debugging output */ + unsigned int dbOpt /* Default optimization flags */ ){ char *zTest; sqlite3_stmt *pTestStmt = 0; @@ -76,13 +83,20 @@ int fuzz_invariant( int i; int nCol; int nParam; + int noOpt = (iCnt%3)==0; if( *pbCorrupt ) return SQLITE_DONE; nParam = sqlite3_bind_parameter_count(pStmt); if( nParam>100 ) return SQLITE_DONE; zTest = fuzz_invariant_sql(pStmt, iCnt); if( zTest==0 ) return SQLITE_DONE; + if( noOpt ){ + sqlite3_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS, db, ~dbOpt); + } rc = sqlite3_prepare_v2(db, zTest, -1, &pTestStmt, 0); + if( noOpt ){ + sqlite3_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS, db, dbOpt); + } if( rc ){ if( eVerbosity ){ printf("invariant compile failed: %s\n%s\n", @@ -212,7 +226,7 @@ int fuzz_invariant( } sqlite3_finalize(pCk); if( rc==SQLITE_DONE ){ - reportInvariantFailed(pStmt, pTestStmt, iRow); + reportInvariantFailed(pStmt, pTestStmt, iRow, dbOpt, noOpt); return SQLITE_INTERNAL; }else if( eVerbosity>0 ){ printf("invariant-error ignored due to the use of virtual tables\n"); @@ -223,7 +237,6 @@ not_a_fault: return SQLITE_OK; } - /* ** Generate SQL used to test a statement invariant. ** @@ -296,14 +309,6 @@ static char *fuzz_invariant_sql(sqlite3_stmt *pStmt, int iCnt){ ** WHERE clause. */ continue; } -#ifdef SQLITE_ALLOW_ROWID_IN_VIEW - if( sqlite3_strlike("%rowid%",zColName,0)==0 - || sqlite3_strlike("%oid%",zColName,0)==0 - ){ - /* ROWID values are unreliable if SQLITE_ALLOW_ROWID_IN_VIEW is used */ - continue; - } -#endif for(j=0; j<i; j++){ const char *zPrior = sqlite3_column_name(pBase, j); if( sqlite3_stricmp(zPrior, zColName)==0 ) break; @@ -497,13 +502,17 @@ static void printRow(sqlite3_stmt *pStmt, int iRow){ static void reportInvariantFailed( sqlite3_stmt *pOrig, /* The original query */ sqlite3_stmt *pTest, /* The alternative test query with a missing row */ - int iRow /* Row number in pOrig */ + int iRow, /* Row number in pOrig */ + unsigned int dbOpt, /* Optimization flags on pOrig */ + int noOpt /* True if opt flags inverted for pTest */ ){ int iTestRow = 0; printf("Invariant check failed on row %d.\n", iRow); - printf("Original query --------------------------------------------------\n"); + printf("Original query (opt-flags: 0x%08x) --------------------------\n", + dbOpt); printf("%s\n", sqlite3_expanded_sql(pOrig)); - printf("Alternative query -----------------------------------------------\n"); + printf("Alternative query (opt-flags: 0x%08x) -----------------------\n", + noOpt ? ~dbOpt : dbOpt); printf("%s\n", sqlite3_expanded_sql(pTest)); printf("Result row that is missing from the alternative -----------------\n"); printRow(pOrig, iRow); diff --git a/test/icu.test b/test/icu.test index 644cbb1..c1b5653 100644 --- a/test/icu.test +++ b/test/icu.test @@ -149,7 +149,7 @@ ifcapable icu { # 2020-03-19 # The ESCAPE clause on LIKE takes precedence over wildcards # -do_execsql_test idu-6.0 { +do_execsql_test icu-6.0 { DROP TABLE IF EXISTS t1; CREATE TABLE t1(id INTEGER PRIMARY KEY, x TEXT); INSERT INTO t1 VALUES @@ -164,4 +164,20 @@ do_execsql_test icu-6.1 { SELECT id FROM t1 WHERE x LIKE 'abc__' ESCAPE '_'; } {2} +# 2024-04-02 +# Optional 3rd argument to icu_load_collation() that specifies +# the "strength" of comparison. +# +reset_db +do_catchsql_test icu-7.1 { + SELECT icu_load_collation('en_US','error','xyzzy'); +} {1 {unknown collation strength "xyzzy" - should be one of: PRIMARY SECONDARY TERTIARY DEFAULT QUARTERNARY IDENTICAL}} +do_execsql_test icu-7.2 { + SELECT icu_load_collation('en_US','prim','PRIMARY'), + icu_load_collation('en_US','dflt','DEFAULT'); +} {{} {}} +do_execsql_test icu-7.3 { + SELECT char(0x100)=='a', char(0x100)=='a' COLLATE dflt, char(0x100)=='a' COLLATE prim; +} {0 0 1} + finish_test diff --git a/test/in4.test b/test/in4.test index a3fe22e..71993e7 100644 --- a/test/in4.test +++ b/test/in4.test @@ -458,14 +458,14 @@ do_execsql_test 11.0 { do_execsql_test 11.1 { SELECT * FROM t1 WHERE b IN (345, (SELECT 1 FROM t1 - WHERE b IN (345 NOT GLOB 510) + WHERE b IN (coalesce(1,random())) AND c GLOB 'abc*xyz')) AND c BETWEEN 'abc' AND 'xyz'; } {xyz 1 abcdefxyz 99} do_execsql_test 11.2 { EXPLAIN SELECT * FROM t1 WHERE b IN (345, (SELECT 1 FROM t1 - WHERE b IN (345 NOT GLOB 510) + WHERE b IN (coalesce(1,random())) AND c GLOB 'abc*xyz')) AND c BETWEEN 'abc' AND 'xyz'; } {/ SeekScan /} diff --git a/test/in5.test b/test/in5.test index 6680641..933eb90 100644 --- a/test/in5.test +++ b/test/in5.test @@ -266,4 +266,26 @@ do_execsql_test 9.2 { SELECT lower('1e500') FROM t0 WHERE rowid != lower('1e500'); } {1e500} +#------------------------------------------------------------------------- +# +reset_db + +do_execsql_test 10.0 { + CREATE TABLE t1(a, b TEXT COLLATE NOCASE); + INSERT INTO t1 VALUES('abc', 'def'); + INSERT INTO t1 VALUES('ghi', 'jkl'); +} + +do_execsql_test 10.1 { + SELECT rowid FROM t1 WHERE (a, b) IN ( VALUES('abc', 'def'), ('ghi', 'JKL') ); +} {1 2} + +do_execsql_test 10.2 { + CREATE INDEX i1 ON t1(a, b COLLATE BINARY); +} + +do_execsql_test 10.3 { + SELECT rowid FROM t1 WHERE (a, b) IN ( VALUES('abc', 'def'), ('ghi', 'JKL') ); +} {1 2} + finish_test diff --git a/test/in7.test b/test/in7.test new file mode 100644 index 0000000..099f75c --- /dev/null +++ b/test/in7.test @@ -0,0 +1,141 @@ +# 2024-05-01 +# +# 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. +# +#*********************************************************************** +# +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set testprefix in7 + +do_execsql_test 1.0 { + CREATE TABLE t1(a, b, c PRIMARY KEY); + CREATE TABLE t2(x, y, z); +} + +foreach {tn nNext idx sql} { + 1 1 { + CREATE INDEX i1 ON t1(a, b); + } { + SELECT * FROM t1 WHERE (a, b) IN (SELECT x, y FROM t2) + } + + 2 0 { + CREATE UNIQUE INDEX i1 ON t1(a, b); + } { + SELECT * FROM t1 WHERE (a, b) IN (SELECT x, y FROM t2) + } + + 3 0 { + CREATE UNIQUE INDEX i1 ON t1(a, b); + } { + SELECT * FROM t1 WHERE a = ? AND b = ? + } + + 3 1 { + CREATE UNIQUE INDEX i1 ON t1(a, b); + } { + SELECT * FROM t1 WHERE a = ? AND b IS ? + } + + 4 0 { + CREATE UNIQUE INDEX i1 ON t1(a, b); + } { + SELECT * FROM t1 WHERE a = ? AND b IN (?, ?, ?); + } + + 5 1 { + CREATE UNIQUE INDEX i1 ON t1(a, b, c); + } { + SELECT * FROM t1 WHERE a = ? AND b = ? + } + + 6 0 { + } { + SELECT * FROM t1 WHERE c IN (SELECT z FROM t2) + } + + 7 0 { + } { + SELECT * FROM t1 WHERE (a, c) IN (SELECT z, x FROM t2) + } + + 8 1 { + } { + SELECT * FROM t1 WHERE a IN (SELECT z FROM t2) + } + + 9 1 { + CREATE UNIQUE INDEX i1 ON t1(a, b); + } { + SELECT * FROM t1 WHERE a IN (SELECT z FROM t2) AND b IS ? + } + 10 0 { + CREATE UNIQUE INDEX i1 ON t1(a, b); + } { + SELECT * FROM t1 WHERE a IN (SELECT z FROM t2) AND b = ? + } + 11 1 { + CREATE UNIQUE INDEX i1 ON t1(a, b); + } { + SELECT * FROM t1 WHERE a IS NULL AND b IN (SELECT z FROM t2) + } + 12 0 { + CREATE UNIQUE INDEX i1 ON t1(a, b); + } { + SELECT * FROM t1 WHERE a = ? AND b IN (SELECT z FROM t2) + } +} { + do_test 1.1.$tn { + execsql BEGIN + execsql $idx + + catch { array unset root_to_tbl } + catch { array unset csr_to_root } + + db eval {SELECT rootpage, tbl_name FROM sqlite_schema} { + set root_to_tbl($rootpage) $tbl_name + } + + set nSeen 0 + db eval "explain $sql" { + if {$opcode=="OpenRead"} { + set csr_to_root($p1) $p2 + } + if {$opcode=="Next"} { + catch { + set root $csr_to_root($p1) + set tbl $root_to_tbl($root) + if {$tbl=="t1"} {incr nSeen} + } + } + } + + execsql ROLLBACK + + set nSeen + } $nNext +} + +#------------------------------------------------------------------------- +reset_db +do_execsql_test 2.0 { + CREATE TABLE t1(a TEXT PRIMARY KEY, b TEXT) WITHOUT ROWID; + INSERT INTO t1 VALUES('1', 'one'); + INSERT INTO t1 VALUES('2', NULL); + INSERT INTO t1 VALUES('3', 'three'); +} + +do_execsql_test 2.1 { + SELECT b FROM t1 WHERE a IN (1,2,3) ORDER BY b ASC NULLS LAST; +} {one three {}} + + +finish_test diff --git a/test/indexexpr1.test b/test/indexexpr1.test index 0316ee9..3ba5944 100644 --- a/test/indexexpr1.test +++ b/test/indexexpr1.test @@ -615,6 +615,58 @@ do_execsql_test indexexpr1-2200 { GROUP BY t2.type, t1.tag ) v ON v.type = 0 AND v.tag = u.tag; } {7 100 8 101} +do_execsql_test indexexpr1-2210 { + DROP TABLE t1; + CREATE TABLE t1(x INT, y TEXT); + INSERT INTO t1(x,y) VALUES(1,'{b:5}'); + SELECT json_insert('{}', '$.a', coalesce(null,json(y)))->>'$.a.b' FROM t1; +} {5} +db null NULL +do_execsql_test indexexpr1-2211 { + CREATE INDEX t1j ON t1(coalesce(null,json(y))); + SELECT json_insert('{}', '$.a', coalesce(null,json(y)))->>'$.a.b' FROM t1; +} {5} +do_execsql_test indexexpr1-2220 { + DROP INDEX t1j; + SELECT json_insert('{}', '$.a', iif(1,json(y),123))->>'$.a.b' FROM t1; +} {5} +do_execsql_test indexexpr1-2221 { + CREATE INDEX t1j ON t1(iif(1,json(y),123)); + SELECT json_insert('{}', '$.a', iif(1,json(y),123))->>'$.a.b' FROM t1; +} {5} +do_execsql_test indexexpr1-2230 { + DROP INDEX t1j; + SELECT json_insert('{}', '$.a', ifnull(NULL,json(y)))->>'$.a.b' FROM t1; +} {5} +do_execsql_test indexexpr1-2231 { + CREATE INDEX t1j ON t1(ifnull(NULL,json(y))); + SELECT json_insert('{}', '$.a', ifnull(NULL,json(y)))->>'$.a.b' FROM t1; +} {5} +do_execsql_test indexexpr1-2240 { + DROP INDEX t1j; + SELECT json_insert('{}', '$.a', nullif(json(y),8))->>'$.a.b' FROM t1; +} {5} +do_execsql_test indexexpr1-2241 { + CREATE INDEX t1j ON t1(nullif(json(y),8)); + SELECT json_insert('{}', '$.a', nullif(json(y),8))->>'$.a.b' FROM t1; +} {5} +do_execsql_test indexexpr1-2250 { + DROP INDEX t1j; + SELECT json_insert('{}', '$.a', min('~',json(y)))->>'$.a.b' FROM t1; +} {5} +do_execsql_test indexexpr1-2251 { + CREATE INDEX t1j ON t1(min('~',json(y))); + SELECT json_insert('{}', '$.a', min('~',json(y)))->>'$.a.b' FROM t1; +} {5} +do_execsql_test indexexpr1-2260 { + DROP INDEX t1j; + SELECT json_insert('{}', '$.a', max('...',json(y)))->>'$.a.b' FROM t1; +} {5} +do_execsql_test indexexpr1-2261 { + CREATE INDEX t1j ON t1(max('...',json(y))); + SELECT json_insert('{}', '$.a', max('...',json(y)))->>'$.a.b' FROM t1; +} {5} + # 2023-11-08 Forum post https://sqlite.org/forum/forumpost/68d284c86b082c3e # diff --git a/test/json102.test b/test/json102.test index 15a54b4..1a00cb6 100644 --- a/test/json102.test +++ b/test/json102.test @@ -764,4 +764,35 @@ do_execsql_test json102-1720 { SELECT * FROM t1; } {ok 2023-08-03 876 5 {{"x":77,"y":6}}} +# 2024-05-21 https://sqlite.org/forum/forumpost/9e52cdfe15c3926e +# What if the RHS of the -> or ->> operator is a string that looks +# like a number? PostgreSQL treats it as a string. +# +do_execsql_test json102-1800 { + SELECT '{"1":"one","2":"two","3":"three"}'->>'2'; +} two +db null NULL +do_execsql_test json102-1801 { + SELECT '{"1":"one","2":"two","3":"three"}'->>2; +} NULL +do_execsql_test json102-1810 { + SELECT '["zero","one","two"]'->>'1'; +} NULL +do_execsql_test json102-1811 { + SELECT '["zero","one","two"]'->>1; +} one +do_execsql_test json102-1820 { + SELECT '{"1":"one","2":"two","3":"three"}'->'2'; +} {{"two"}} +do_execsql_test json102-1821 { + SELECT '{"1":"one","2":"two","3":"three"}'->2; +} {NULL} +do_execsql_test json102-1830 { + SELECT '["zero","one","two"]'->'1'; +} {NULL} +do_execsql_test json102-1831 { + SELECT '["zero","one","two"]'->1; +} {{"one"}} + + finish_test diff --git a/test/json106.test b/test/json106.test index 23fa028..06859a1 100644 --- a/test/json106.test +++ b/test/json106.test @@ -67,6 +67,12 @@ for {set ii 1} {$ii<=5000} {incr ii} { FROM t1, kv WHERE p->>key IS NOT val } 0 + do_execsql_test $ii.8 { + SELECT j0 FROM t1 WHERE json(j0)!=json(json_pretty(j0)); + } {} + do_execsql_test $ii.9 { + SELECT j5 FROM t1 WHERE json(j5)!=json(json_pretty(j5)); + } {} } diff --git a/test/json108.test b/test/json108.test new file mode 100644 index 0000000..71f3814 --- /dev/null +++ b/test/json108.test @@ -0,0 +1,45 @@ +# 2024-03-06 +# +# 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. +# +#*********************************************************************** +# Invariant tests for JSON built around the randomjson extension +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set testprefix json108 + +# These tests require virtual table "json_tree" to run. +ifcapable !vtab { finish_test ; return } + +load_static_extension db randomjson +db eval { + CREATE TEMP TABLE t1(j0,j5); + WITH RECURSIVE c(n) AS (VALUES(0) UNION ALL SELECT n+1 FROM c WHERE n<9) + INSERT INTO t1 SELECT random_json(n), random_json5(n) FROM c; +} + +do_execsql_test 1.1 { + SELECT count(*) FROM t1 WHERE json(j0)==json(json_pretty(j0,NULL)); +} 10 +do_execsql_test 1.2 { + SELECT count(*) FROM t1 WHERE json(j0)==json(json_pretty(j0,NULL)); +} 10 +do_execsql_test 1.3 { + SELECT count(*) FROM t1 WHERE json(j0)==json(json_pretty(j0,'')); +} 10 +do_execsql_test 1.4 { + SELECT count(*) FROM t1 WHERE json(j0)==json(json_pretty(j0,char(9))); +} 10 +do_execsql_test 1.5 { + SELECT count(*) FROM t1 WHERE json(j0)==json(json_pretty(j0,'/*hello*/')); +} 10 + + +finish_test diff --git a/test/json501.test b/test/json501.test index 40b3b56..bfd2105 100644 --- a/test/json501.test +++ b/test/json501.test @@ -306,4 +306,31 @@ do_execsql_test 13.1 { SELECT json('{x:''a "b" c''}'); } {{{"x":"a \"b\" c"}}} +# 2024-01-31 +# Allow control characters within JSON5 string literals. +# +for {set c 1} {$c<=0x1f} {incr c} { + do_execsql_test 14.$c.1 { + SELECT json_valid('"abc' || char($c) || 'xyz"'); + } {0} + do_execsql_test 14.$c.2 { + SELECT json_valid('"abc' || char($c) || 'xyz"', 2); + } {1} + switch $c { + 8 {set e "\\b"} + 9 {set e "\\t"} + 10 {set e "\\n"} + 12 {set e "\\f"} + 13 {set e "\\r"} + default {set e [format "\\u00%02x" $c]} + } + do_execsql_test 14.$c.3 { + SELECT json('{label:"abc' || char($c) || 'xyz"}'); + } "{{\"label\":\"abc${e}xyz\"}}" + do_execsql_test 14.$c.4 { + SELECT jsonb('{label:"abc' || char($c) || 'xyz"}') -> '$'; + } "{{\"label\":\"abc${e}xyz\"}}" +} + + finish_test diff --git a/test/lemon-test01.y b/test/lemon-test01.y index 0fd514f..67890c6 100644 --- a/test/lemon-test01.y +++ b/test/lemon-test01.y @@ -2,6 +2,11 @@ // // lemon lemon-test01.y && gcc -g lemon-test01.c && ./a.out // +// This testcase was made obsolete by check-in 7cca80808cef192f on +// 2021-08-17 (associated with Forum Thread +// https://sqlite.org/forum/forumpost/bd91fd965c9803c4) and no longer +// works. It is retained for historical reference only. +// %token_prefix TK_ %token_type int %default_type int @@ -28,7 +33,7 @@ all ::= error B. #include "lemon-test01.h" static int nTest = 0; static int nErr = 0; - static int testCase(int testId, int shouldBe, int actual){ + static void testCase(int testId, int shouldBe, int actual){ nTest++; if( shouldBe==actual ){ printf("test %d: ok\n", testId); diff --git a/test/literal.test b/test/literal.test new file mode 100644 index 0000000..5aa331e --- /dev/null +++ b/test/literal.test @@ -0,0 +1,103 @@ +# 2024-01-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 tests for SQL literals + + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set ::testprefix literal + +proc test_literal {tn lit type val} { + do_execsql_test $tn.1 "SELECT typeof( $lit ), $lit" [list $type $val] + + ifcapable altertable { + do_execsql_test $tn.2 " + DROP TABLE IF EXISTS x1; + CREATE TABLE x1(a); + INSERT INTO x1 VALUES(123); + ALTER TABLE x1 ADD COLUMN b DEFAULT $lit ; + SELECT typeof(b), b FROM x1; + " [list $type $val] + } + + do_execsql_test $tn.3 " + DROP TABLE IF EXISTS x1; + CREATE TABLE x1(a DEFAULT $lit); + INSERT INTO x1 DEFAULT VALUES; + SELECT typeof(a), a FROM x1; + " [list $type $val] +} + +proc test_literal_error {tn lit unrec} { + do_catchsql_test $tn "SELECT $lit" "1 {unrecognized token: \"$unrec\"}" +} + + +test_literal 1.0 45 integer 45 +test_literal 1.1 0xFF integer 255 +test_literal 1.2 0xFFFFFFFF integer [expr 0xFFFFFFFF] +test_literal 1.3 0x123FFFFFFFF integer [expr 0x123FFFFFFFF] +test_literal 1.4 -0x123FFFFFFFF integer [expr -1 * 0x123FFFFFFFF] +test_literal 1.5 0xFFFFFFFFFFFFFFFF integer -1 +test_literal 1.7 0x7FFFFFFFFFFFFFFF integer [expr 0x7FFFFFFFFFFFFFFF] +test_literal 1.8 -0x7FFFFFFFFFFFFFFF integer [expr -0x7FFFFFFFFFFFFFFF] +test_literal 1.9 +0x7FFFFFFFFFFFFFFF integer [expr +0x7FFFFFFFFFFFFFFF] +test_literal 1.10 -45 integer -45 +test_literal 1.11 '0xFF' text 0xFF +test_literal 1.12 '-0xFF' text -0xFF +test_literal 1.13 -'0xFF' integer 0 +test_literal 1.14 -9223372036854775808 integer -9223372036854775808 + +test_literal 2.1 1e12 real 1000000000000.0 +test_literal 2.2 1.0 real 1.0 +test_literal 2.3 1e1000 real Inf +test_literal 2.4 -1e1000 real -Inf + +test_literal 3.1 1_000 integer 1000 +test_literal 3.2 1.1_1 real 1.11 +test_literal 3.3 1_0.1_1 real 10.11 +test_literal 3.4 1e1_000 real Inf +test_literal 3.5 12_3_456.7_8_9 real 123456.789 +test_literal 3.6 9_223_372_036_854_775_807 integer 9223372036854775807 +test_literal 3.7 9_223_372_036_854_775_808 real 9.22337203685478e+18 +test_literal 3.8 -9_223_372_036_854_775_808 integer -9223372036854775808 + +foreach {tn lit unrec} { + 0 123a456 123a456 + 1 1_ 1_ + 2 1_.4 1_.4 + 3 1e_4 1e_4 + 4 1_e4 1_e4 + 5 1.4_e4 1.4_e4 + 6 1.4e+_4 1.4e + 7 1.4e-_4 1.4e + 8 1.4e4_ 1.4e4_ + 9 1.4_e4 1.4_e4 + 10 1.4e_4 1.4e_4 + 11 12__34 12__34 + 12 1234_ 1234_ + 13 12._34 12._34 + 14 12_.34 12_.34 + 15 12.34_ 12.34_ + 16 1.0e1_______2 1.0e1_______2 +} { + test_literal_error 4.$tn $lit $unrec +} + +# dbsqlfuzz e3186a9e7826e9cd7f4085aa4452f8696485f9e1 +# See tag-20240224-a and -b +# +do_catchsql_test 5.1 { + SELECT 1 ORDER BY 2_3; +} {1 {1st ORDER BY term out of range - should be between 1 and 1}} + +finish_test diff --git a/test/literal2.tcl b/test/literal2.tcl new file mode 100644 index 0000000..e14a035 --- /dev/null +++ b/test/literal2.tcl @@ -0,0 +1,40 @@ +# 2018 May 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. +# +#*********************************************************************** +# + +source [file join [file dirname $argv0] pg_common.tcl] + +#========================================================================= + + +start_test literal2 "2024 Jan 23" + +execsql_test 1.0 { SELECT 123_456 } +errorsql_test 1.1 { SELECT 123__456 } + +execsql_float_test 2.1 { SELECT 1.0e1_2 } + + +execsql_test 3.0.0 { SELECT 0xFF_FF } +execsql_test 3.0.1 { SELECT 0xFF_EF } +errorsql_test 3.0.2 { SELECT 0xFF__EF } +# errorsql_test 3.0.3 { SELECT 0x_FFEF } +errorsql_test 3.0.4 { SELECT 0xFFEF_ } + +execsql_test 3.1.0 { SELECT 0XFF_FF } +execsql_test 3.1.1 { SELECT 0XFF_EF } +errorsql_test 3.1.2 { SELECT 0XFF__EF } +# errorsql_test 3.1.3 { SELECT 0X_FFEF } +errorsql_test 3.1.4 { SELECT 0XFFEF_ } + +finish_test + + diff --git a/test/literal2.test b/test/literal2.test new file mode 100644 index 0000000..ed177ca --- /dev/null +++ b/test/literal2.test @@ -0,0 +1,84 @@ +# 2024 Jan 23 +# +# 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. +# + +#################################################### +# DO NOT EDIT! THIS FILE IS AUTOMATICALLY GENERATED! +#################################################### + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set testprefix literal2 + +do_execsql_test 1.0 { + SELECT 123_456 +} {123456} + +# PG says ERROR: trailing junk after numeric literal at or near "123_" +do_test 1.1 { catch { execsql { + SELECT 123__456 +} } } 1 + + +do_test 2.1 { + set myres {} + foreach r [db eval {SELECT 1.0e1_2}] { + lappend myres [format %.4f [set r]] + } + set res2 {1000000000000.0000} + set i 0 + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + incr i + } + set {} {} +} {} + +do_execsql_test 3.0.0 { + SELECT 0xFF_FF +} {65535} + +do_execsql_test 3.0.1 { + SELECT 0xFF_EF +} {65519} + +# PG says ERROR: trailing junk after numeric literal at or near "0xFF_" +do_test 3.0.2 { catch { execsql { + SELECT 0xFF__EF +} } } 1 + +# PG says ERROR: trailing junk after numeric literal at or near "0xFFEF_" +do_test 3.0.4 { catch { execsql { + SELECT 0xFFEF_ +} } } 1 + +do_execsql_test 3.1.0 { + SELECT 0XFF_FF +} {65535} + +do_execsql_test 3.1.1 { + SELECT 0XFF_EF +} {65519} + +# PG says ERROR: trailing junk after numeric literal at or near "0XFF_" +do_test 3.1.2 { catch { execsql { + SELECT 0XFF__EF +} } } 1 + +# PG says ERROR: trailing junk after numeric literal at or near "0XFFEF_" +do_test 3.1.4 { catch { execsql { + SELECT 0XFFEF_ +} } } 1 + +finish_test diff --git a/test/misc1.test b/test/misc1.test index 83acc75..8110d38 100644 --- a/test/misc1.test +++ b/test/misc1.test @@ -654,7 +654,7 @@ do_catchsql_test misc1-21.1 { } {1 {near "#0": syntax error}} do_catchsql_test misc1-21.2 { VALUES(0,0x0MATCH#0; -} {1 {near ";": syntax error}} +} {1 {unrecognized token: "0x0MATCH"}} # 2015-04-15 do_execsql_test misc1-22.1 { diff --git a/test/misc5.test b/test/misc5.test index f7c6048..84aa958 100644 --- a/test/misc5.test +++ b/test/misc5.test @@ -569,11 +569,11 @@ ifcapable subquery&&compound { } # Overflow the lemon parser stack by providing an overly complex -# expression. Make sure that the overflow is detected and reported. +# expression. Make sure that the overflow is detected and the +# stack is grown automatically such that the application calling +# SQLite never notices. # -# This test fails when building with -DYYSTACKDEPTH=0 -# -do_test misc5-7.1 { +do_test misc5-7.1.1 { execsql {CREATE TABLE t1(x)} set sql "INSERT INTO t1 VALUES(" set tail "" @@ -581,9 +581,21 @@ do_test misc5-7.1 { append sql "(1+" append tail ")" } - append sql 2$tail + append sql "0$tail); SELECT * FROM t1;" + catchsql $sql +} {0 200} +do_test misc5-7.1.2 { + execsql {DELETE FROM t1} + set sql "INSERT INTO t1 VALUES(" + set tail "" + for {set i 0} {$i<900} {incr i} { + append sql "(1+" + append tail ")" + } + append sql "0$tail); SELECT * FROM t1;" catchsql $sql -} {1 {parser stack overflow}} +} {0 900} + # Parser stack overflow is silently ignored when it occurs while parsing the # schema and PRAGMA writable_schema is turned on. diff --git a/test/mmapcorrupt.test b/test/mmapcorrupt.test index 70dbe84..d434ec1 100644 --- a/test/mmapcorrupt.test +++ b/test/mmapcorrupt.test @@ -16,6 +16,10 @@ set testdir [file dirname $argv0] source $testdir/tester.tcl set testprefix mmapcorrupt +ifcapable !mmap { + finish_test + return +} database_may_be_corrupt db close diff --git a/test/orderby1.test b/test/orderby1.test index 7432b54..41444a4 100644 --- a/test/orderby1.test +++ b/test/orderby1.test @@ -520,7 +520,7 @@ do_eqp_test 8.1 { } { QUERY PLAN |--SCAN t1 USING INDEX i1 - `--USE TEMP B-TREE FOR RIGHT PART OF ORDER BY + `--USE TEMP B-TREE FOR LAST TERM OF ORDER BY } do_execsql_test 8.2 { diff --git a/test/permutations.test b/test/permutations.test index 25aa7de..c26d6ea 100644 --- a/test/permutations.test +++ b/test/permutations.test @@ -95,6 +95,7 @@ foreach f [glob -nocomplain \ $testdir/../ext/lsm1/test/*.test \ $testdir/../ext/recover/*.test \ $testdir/../ext/rbu/*.test \ + $testdir/../ext/intck/*.test \ ] { lappend alltests $f } diff --git a/test/pragma.test b/test/pragma.test index 8f78a7e..e823a67 100644 --- a/test/pragma.test +++ b/test/pragma.test @@ -372,27 +372,30 @@ ifcapable attach { db close sqlite3 db test.db execsql {PRAGMA integrity_check} - } {{row 1 missing from index i2} {row 2 missing from index i2} {wrong # of entries in index i2}} + } {{wrong # of entries in index i2} {row 1 missing from index i2} {row 2 missing from index i2}} do_test pragma-3.3 { execsql {PRAGMA integrity_check=1} - } {{row 1 missing from index i2}} + } {{wrong # of entries in index i2}} do_test pragma-3.4 { execsql { ATTACH DATABASE 'test.db' AS t2; PRAGMA integrity_check } - } {{row 1 missing from index i2} {row 2 missing from index i2} {wrong # of entries in index i2} {row 1 missing from index i2} {row 2 missing from index i2} {wrong # of entries in index i2}} + } {{wrong # of entries in index i2} {row 1 missing from index i2} {row 2 missing from index i2} {wrong # of entries in index i2} {row 1 missing from index i2} {row 2 missing from index i2}} do_test pragma-3.5 { execsql { PRAGMA integrity_check=4 } - } {{row 1 missing from index i2} {row 2 missing from index i2} {wrong # of entries in index i2} {row 1 missing from index i2}} + } {{wrong # of entries in index i2} {row 1 missing from index i2} {row 2 missing from index i2} {wrong # of entries in index i2}} + do_catchsql_test pragma-3.5.2 { + PRAGMA integrity_check='4' + } {1 {no such table: 4}} do_catchsql_test pragma-3.6 { PRAGMA integrity_check=xyz } {1 {no such table: xyz}} do_catchsql_test pragma-3.6b { PRAGMA integrity_check=t2 - } {0 {{row 1 missing from index i2} {row 2 missing from index i2} {wrong # of entries in index i2}}} + } {0 {{wrong # of entries in index i2} {row 1 missing from index i2} {row 2 missing from index i2}}} do_catchsql_test pragma-3.6c { PRAGMA integrity_check=sqlite_schema } {0 ok} @@ -400,7 +403,7 @@ ifcapable attach { execsql { PRAGMA integrity_check=0 } - } {{row 1 missing from index i2} {row 2 missing from index i2} {wrong # of entries in index i2} {row 1 missing from index i2} {row 2 missing from index i2} {wrong # of entries in index i2}} + } {{wrong # of entries in index i2} {row 1 missing from index i2} {row 2 missing from index i2} {wrong # of entries in index i2} {row 1 missing from index i2} {row 2 missing from index i2}} # Add additional corruption by appending unused pages to the end of # the database file testerr.db @@ -435,10 +438,10 @@ ifcapable attach { } {{*** in database t2 *** Page 4: never used Page 5: never used -Page 6: never used} {row 1 missing from index i2} {row 2 missing from index i2} {wrong # of entries in index i2}} +Page 6: never used} {wrong # of entries in index i2} {row 1 missing from index i2} {row 2 missing from index i2}} do_execsql_test pragma-3.9b { PRAGMA t2.integrity_check=t2; - } {{row 1 missing from index i2} {row 2 missing from index i2} {wrong # of entries in index i2}} + } {{wrong # of entries in index i2} {row 1 missing from index i2} {row 2 missing from index i2}} do_execsql_test pragma-3.9c { PRAGMA t2.integrity_check=sqlite_schema; } {ok} @@ -455,7 +458,7 @@ Page 4: never used}} } {{*** in database t2 *** Page 4: never used Page 5: never used -Page 6: never used} {row 1 missing from index i2} {row 2 missing from index i2}} +Page 6: never used} {wrong # of entries in index i2} {row 1 missing from index i2}} do_test pragma-3.12 { execsql { PRAGMA integrity_check=4 @@ -463,7 +466,7 @@ Page 6: never used} {row 1 missing from index i2} {row 2 missing from index i2}} } {{*** in database t2 *** Page 4: never used Page 5: never used -Page 6: never used} {row 1 missing from index i2}} +Page 6: never used} {wrong # of entries in index i2}} do_test pragma-3.13 { execsql { PRAGMA integrity_check=3 @@ -487,10 +490,10 @@ Page 5: never used}} } {{*** in database t2 *** Page 4: never used Page 5: never used -Page 6: never used} {row 1 missing from index i2} {row 2 missing from index i2} {wrong # of entries in index i2} {*** in database t3 *** +Page 6: never used} {wrong # of entries in index i2} {row 1 missing from index i2} {row 2 missing from index i2} {*** in database t3 *** Page 4: never used Page 5: never used -Page 6: never used} {row 1 missing from index i2} {row 2 missing from index i2} {wrong # of entries in index i2}} +Page 6: never used} {wrong # of entries in index i2} {row 1 missing from index i2} {row 2 missing from index i2}} do_test pragma-3.16 { execsql { PRAGMA integrity_check(10) @@ -498,10 +501,10 @@ Page 6: never used} {row 1 missing from index i2} {row 2 missing from index i2} } {{*** in database t2 *** Page 4: never used Page 5: never used -Page 6: never used} {row 1 missing from index i2} {row 2 missing from index i2} {wrong # of entries in index i2} {*** in database t3 *** +Page 6: never used} {wrong # of entries in index i2} {row 1 missing from index i2} {row 2 missing from index i2} {*** in database t3 *** Page 4: never used Page 5: never used -Page 6: never used} {row 1 missing from index i2}} +Page 6: never used} {wrong # of entries in index i2}} do_test pragma-3.17 { execsql { PRAGMA integrity_check=8 @@ -509,7 +512,7 @@ Page 6: never used} {row 1 missing from index i2}} } {{*** in database t2 *** Page 4: never used Page 5: never used -Page 6: never used} {row 1 missing from index i2} {row 2 missing from index i2} {wrong # of entries in index i2} {*** in database t3 *** +Page 6: never used} {wrong # of entries in index i2} {row 1 missing from index i2} {row 2 missing from index i2} {*** in database t3 *** Page 4: never used Page 5: never used}} do_test pragma-3.18 { @@ -519,7 +522,7 @@ Page 5: never used}} } {{*** in database t2 *** Page 4: never used Page 5: never used -Page 6: never used} {row 1 missing from index i2}} +Page 6: never used} {wrong # of entries in index i2}} } do_test pragma-3.19 { catch {db close} diff --git a/test/pragma4.test b/test/pragma4.test index 97c6226..5360fba 100644 --- a/test/pragma4.test +++ b/test/pragma4.test @@ -97,7 +97,7 @@ do_test pragma4-2.100 { } string map {\[ x \] x \173 {} \175 {}} \ [db eval {EXPLAIN PRAGMA integrity_check}] -} {/ IntegrityCk 2 2 1 x[0-9]+,1x /} +} {/ IntegrityCk 1 2 8 x[0-9]+,1x /} #-------------------------------------------------------------------------- @@ -271,6 +271,8 @@ catch {db3 close} ifcapable vtab { reset_db do_execsql_test 6.0 { + DROP TABLE IF EXISTS t1; + DROP TABLE IF EXISTS t2; CREATE TABLE t1(a INT PRIMARY KEY, b INT); CREATE TABLE t2(c INT PRIMARY KEY, d INT REFERENCES t1); SELECT t.name, f."table", f."from", i.name, i.pk @@ -281,4 +283,32 @@ ifcapable vtab { } {t2 t1 d a 1} } +# 2024-05-08 https://sqlite.org/forum/forumpost/cf29a33e94 +# +ifcapable vtab { + do_execsql_test 7.0 { + CREATE TABLE t3 ("a" TEXT, "b" TEXT); + CREATE TABLE t4 ("a" TEXT, "b" TEXT, "c" TEXT); + } + + do_execsql_test 7.1 { + CREATE TABLE pragma_t3 AS SELECT * FROM pragma_table_info('t3'); + CREATE TABLE pragma_t4 AS SELECT * FROM pragma_table_info('t4'); + } + + do_execsql_test 7.2 { + SELECT pragma_t4.name, pragma_t3.name + FROM pragma_t4 RIGHT JOIN pragma_t3 ON (pragma_t4.name=pragma_t3.name); + } {a a b b} + + do_execsql_test 7.3 { + SELECT t4.name, t3.name + FROM pragma_table_info('t4') t4 + RIGHT JOIN pragma_table_info('t3') t3 ON (t4.name=t3.name); + } {a a b b} +} + + + + finish_test diff --git a/test/pragma6.test b/test/pragma6.test new file mode 100644 index 0000000..fc5566a --- /dev/null +++ b/test/pragma6.test @@ -0,0 +1,74 @@ +# 2024 February 27 +# +# 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 tests for PRAGMAs quick_check and integrity_check. +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set testprefix pragma6 + +database_may_be_corrupt + +#------------------------------------------------------------------------- +# +do_test 1.0 { + sqlite3 db {} + db deserialize [decode_hexdb { + .open --hexdb + | size 12288 pagesize 4096 filename crash-540f4c1eb1e7ac.db + | page 1 offset 0 + | 0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00 SQLite format 3. + | 16: 10 00 01 01 00 40 20 20 00 00 00 00 00 00 00 03 .....@ ........ + | 32: 00 bb 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ + | 96: 00 00 00 00 0d 00 00 00 02 0f 7f 00 0f c3 0f 7f ................ + | 3952: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 42 ...............B + | 3968: 02 06 17 11 11 01 71 74 61 62 6c 65 74 32 74 32 ......qtablet2t2 + | 3984: 03 43 52 45 41 54 45 20 54 41 42 4c 45 20 74 32 .CREATE TABLE t2 + | 4000: 28 61 20 49 4e 54 2c 20 62 20 41 53 20 28 61 2a (a INT, b AS (a* + | 4016: 32 29 20 53 54 4f 52 45 44 20 4e 4f 54 20 4e 55 2) STORED NOT NU + | 4032: 4c 4c 29 3b 01 06 17 11 11 01 63 74 61 62 6c 65 LL);......ctable + | 4048: 74 31 74 31 02 43 52 45 41 54 45 20 54 41 42 4c t1t1.CREATE TABL + | 4064: 45 20 74 31 28 61 20 49 4e 54 2c 20 62 20 41 53 E t1(a INT, b AS + | 4080: 20 28 61 2a 32 29 20 4e 4f 54 20 4e 55 4c 4c 29 (a*2) NOT NULL) + | page 2 offset 4096 + | 0: 0d 00 00 00 05 0f e7 00 00 00 00 00 00 00 00 00 ................ + | 4064: 00 00 00 00 00 00 00 00 03 05 02 01 05 03 04 02 ................ + | 4080: 01 04 03 03 02 01 03 03 02 02 01 02 02 01 02 09 ................ + | page 3 offset 8192 + | 0: 0d 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ + | 4048: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 05 05 ................ + | 4064: 03 01 01 05 0a 05 04 03 01 01 04 08 05 03 03 01 ................ + | 4080: 01 03 06 05 02 03 00 00 00 00 00 00 00 00 00 00 ................ + | end crash-540f4c1eb1e7ac.db + }] +} {} + +do_test 1.1 { + execsql { + CREATE TEMP TABLE t2( + a t1 PRIMARY KEY default 27, + b default(current_timestamp), + d TEXT UNIQUE DEFAULT 'ch`arlie', + c TEXT UNIQUE DEFAULT 084, + UNIQUE(c,b,b,a,b) + ) WITHOUT ROWID; + } + catchsql { INSERT INTO t1(a) VALUES(zeroblob(40000)) } + set {} {} +} {} + +do_test 1.2 { + execsql { PRAGMA integrity_check; } + execsql { PRAGMA quick_check; } + set {} {} +} {} + +finish_test diff --git a/test/pushdown.test b/test/pushdown.test index 1fbe6f3..5c3e818 100644 --- a/test/pushdown.test +++ b/test/pushdown.test @@ -1,4 +1,4 @@ -# 2017 April 29 +# 2017-04-29 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: @@ -8,6 +8,26 @@ # May you share freely, never taking more than you give. # #*********************************************************************** +# +# Test cases for the push-down optimizations. +# +# +# There are two different meanings for "push-down optimization". +# +# (1) "MySQL push-down" means that WHERE clause terms that can be +# evaluated using only the index and without reference to the +# table are run first, so that if they are false, unnecessary table +# seeks are avoided. See https://sqlite.org/src/info/d7bb79ed3a40419d +# from 2017-04-29. +# +# (2) "WHERE-clause pushdown" means to push WHERE clause terms in +# outer queries down into subqueries. See +# https://sqlite.org/src/info/6df18e949d367629 from 2015-06-02. +# +# This module started out as tests for MySQL push-down only. But because +# of naming ambiguity, it has picked up test cases for WHERE-clause push-down +# over the years. +# set testdir [file dirname $argv0] source $testdir/tester.tcl @@ -87,8 +107,8 @@ do_test 2.2 { } {three} # 2022-11-25 dbsqlfuzz crash-3a548de406a50e896c1bf7142692d35d339d697f -# Disable the push-down optimization for compound subqueries if any -# arm of the compound has an incompatible affinity. +# Disable the WHERE-clause push-down optimization for compound subqueries +# if any arm of the compound has an incompatible affinity. # reset_db do_execsql_test 3.1 { @@ -185,7 +205,7 @@ do_eqp_test 3.8 { # SELECT (SELECT count(*) FROM t1)+(SELECT count(*) FROM t2) # 2023-05-09 https://sqlite.org/forum/forumpost/a7d4be7fb6 -# Restriction (9) on the push-down optimization. +# Restriction (9) on the WHERE-clause push-down optimization. # reset_db db null - @@ -227,4 +247,89 @@ do_execsql_test 5.0 { WHERE e>0; } {- - 3 4 5} + +# 2024-04-05 +# Allow push-down of operators of the form "expr IN table". +# +reset_db +do_execsql_test 6.0 { + CREATE TABLE t01(w,x,y,z); + CREATE TABLE t02(w,x,y,z); + CREATE VIEW t0(w,x,y,z) AS + SELECT w,x,y,z FROM t01 UNION ALL SELECT w,x,y,z FROM t02; + CREATE INDEX t01x ON t01(w,x,y); + CREATE INDEX t02x ON t02(w,x,y); + CREATE VIEW v1(k) AS VALUES(77),(88),(99); + CREATE TABLE k1(k); + INSERT INTO k1 SELECT * FROM v1; +} +do_eqp_test 6.1 { + WITH k(n) AS (VALUES(77),(88),(99)) + SELECT max(z) FROM t0 WHERE w=123 AND x IN k AND y BETWEEN 44 AND 55; +} { + QUERY PLAN + |--CO-ROUTINE t0 + | `--COMPOUND QUERY + | |--LEFT-MOST SUBQUERY + | | |--SEARCH t01 USING INDEX t01x (w=? AND x=? AND y>? AND y<?) + | | `--LIST SUBQUERY xxxxxx + | | |--MATERIALIZE k + | | | `--SCAN 3 CONSTANT ROWS + | | `--SCAN k + | `--UNION ALL + | |--SEARCH t02 USING INDEX t02x (w=? AND x=? AND y>? AND y<?) + | `--LIST SUBQUERY xxxxxx + | `--SCAN k + |--SEARCH t0 + `--LIST SUBQUERY xxxxxx + `--SCAN k +} +# ^^^^--- The key feature above is that the SEARCH for each subquery +# uses all three fields of the index w, x, and y. Prior to the push-down +# of "expr IN table", only the w term of the index would be used. Similar +# for the following tests: +# +do_eqp_test 6.2 { + SELECT max(z) FROM t0 WHERE w=123 AND x IN v1 AND y BETWEEN 44 AND 55; +} { + QUERY PLAN + |--CO-ROUTINE t0 + | `--COMPOUND QUERY + | |--LEFT-MOST SUBQUERY + | | |--SEARCH t01 USING INDEX t01x (w=? AND x=? AND y>? AND y<?) + | | `--LIST SUBQUERY xxxxxx + | | |--CO-ROUTINE v1 + | | | `--SCAN 3 CONSTANT ROWS + | | `--SCAN v1 + | `--UNION ALL + | |--SEARCH t02 USING INDEX t02x (w=? AND x=? AND y>? AND y<?) + | `--LIST SUBQUERY xxxxxx + | |--CO-ROUTINE v1 + | | `--SCAN 3 CONSTANT ROWS + | `--SCAN v1 + |--SEARCH t0 + `--LIST SUBQUERY xxxxxx + |--CO-ROUTINE v1 + | `--SCAN 3 CONSTANT ROWS + `--SCAN v1 +} +do_eqp_test 6.3 { + SELECT max(z) FROM t0 WHERE w=123 AND x IN k1 AND y BETWEEN 44 AND 55; +} { + QUERY PLAN + |--CO-ROUTINE t0 + | `--COMPOUND QUERY + | |--LEFT-MOST SUBQUERY + | | |--SEARCH t01 USING INDEX t01x (w=? AND x=? AND y>? AND y<?) + | | `--LIST SUBQUERY xxxxxx + | | `--SCAN k1 + | `--UNION ALL + | |--SEARCH t02 USING INDEX t02x (w=? AND x=? AND y>? AND y<?) + | `--LIST SUBQUERY xxxxxx + | `--SCAN k1 + |--SEARCH t0 + `--LIST SUBQUERY xxxxxx + `--SCAN k1 +} + finish_test diff --git a/test/quote.test b/test/quote.test index 6d7b317..4e40a9e 100644 --- a/test/quote.test +++ b/test/quote.test @@ -103,7 +103,7 @@ foreach {tn sql errname} { 3 { CREATE INDEX i3 ON t1("w") } w 4 { CREATE INDEX i4 ON t1(x) WHERE z="w" } w } { - do_catchsql_test 2.1.$tn $sql [list 1 "no such column: $errname"] + do_catchsql_test 2.1.$tn $sql [list 1 "no such column: \"$errname\" - should this be a string literal in single-quotes?"] } do_execsql_test 2.2 { @@ -147,19 +147,19 @@ ifcapable altertable { CREATE TABLE t1(a,b); CREATE INDEX x1 on t1("b"); ALTER TABLE t1 DROP COLUMN b; - } {1 {error in index x1 after drop column: no such column: b}} + } {1 {error in index x1 after drop column: no such column: "b" - should this be a string literal in single-quotes?}} do_catchsql_test 3.1 { DROP TABLE t1; CREATE TABLE t1(a,"b"); CREATE INDEX x1 on t1("b"); ALTER TABLE t1 DROP COLUMN b; - } {1 {error in index x1 after drop column: no such column: b}} + } {1 {error in index x1 after drop column: no such column: "b" - should this be a string literal in single-quotes?}} do_catchsql_test 3.2 { DROP TABLE t1; CREATE TABLE t1(a,'b'); CREATE INDEX x1 on t1("b"); ALTER TABLE t1 DROP COLUMN b; - } {1 {error in index x1 after drop column: no such column: b}} + } {1 {error in index x1 after drop column: no such column: "b" - should this be a string literal in single-quotes?}} do_catchsql_test 3.3 { DROP TABLE t1; CREATE TABLE t1(a,"b"); @@ -172,7 +172,7 @@ ifcapable altertable { CREATE INDEX x1 ON t1("a"||"b"); INSERT INTO t1 VALUES(1,2,3),(1,4,5); ALTER TABLE t1 DROP COLUMN b; - } {1 {error in index x1 after drop column: no such column: b}} + } {1 {error in index x1 after drop column: no such column: "b" - should this be a string literal in single-quotes?}} sqlite3_db_config db SQLITE_DBCONFIG_DQS_DDL 1 do_catchsql_test 3.5 { DROP TABLE t1; diff --git a/test/readonly.test b/test/readonly.test new file mode 100644 index 0000000..1ccbcee --- /dev/null +++ b/test/readonly.test @@ -0,0 +1,55 @@ +# 2024 March 21 +# +# 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 contains tests for using databases in read-only mode on +# unix. +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +if {$tcl_platform(platform)=="windows"} finish_test +source $testdir/lock_common.tcl +source $testdir/wal_common.tcl +set ::testprefix readonly + +do_execsql_test 1.0 { + CREATE TABLE t1(a, b); + INSERT INTO t1 VALUES(1, 2), (3, 4), (5, 6); +} + +db close +file attributes test.db -permissions r--r--r-- + +sqlite3 db test.db + +do_catchsql_test 1.1 { + INSERT INTO t1 VALUES(7, 8); +} {1 {attempt to write a readonly database}} + +do_execsql_test 1.2 { + BEGIN; + SELECT * FROM t1; +} {1 2 3 4 5 6} + +# The following attempts to open a read/write fd on the database 20,000 +# times. And each time instead opens a read-only fd. At one point this +# was failing to reuse cached fds, causing a "too many open file-descriptors" +# error. +do_test 1.3 { + for {set ii 0} {$ii < 20000} {incr ii} { + sqlite3 db2 test.db + db2 close + } + set {} {} +} {} + + +finish_test diff --git a/test/recover.test b/test/recover.test index 8d9ad01..5495b7a 100644 --- a/test/recover.test +++ b/test/recover.test @@ -8,6 +8,7 @@ # May you share freely, never taking more than you give. # #*********************************************************************** +# TESTRUNNER: shell # # Test the shell tool ".ar" command. # diff --git a/test/returning1.test b/test/returning1.test index 2403249..05bd445 100644 --- a/test/returning1.test +++ b/test/returning1.test @@ -227,21 +227,21 @@ ifcapable !allow_rowid_in_view { } else { # Note: The values returned by the RETURNING clauses of the following # two statements are the rowid columns of views. These values are not - # well defined, so the INSERT returns -1, and the UPDATE returns 1, 2 - # and 3. These match the values used for new.rowid expressions, but - # not much else. + # well defined, so the INSERT returns -1, and the UPDATE returns NULL. + # These match the values used for new.rowid expressions, but not much + # else. do_catchsql_test 10.3a { INSERT INTO t1(a, b) VALUES(1234, 5678) RETURNING rowid; } {0 -1} do_catchsql_test 10.3b { UPDATE t1 SET a='z' WHERE b='y' RETURNING rowid; - } {0 {1 2 3}} + } {0 {{} {} {}}} do_execsql_test 10.4 { SELECT * FROM log; } { - insert -1 1234 5678 update 1 z y update 2 z y update 3 z y + insert -1 1234 5678 update {} z y update {} z y update {} z y } } @@ -460,4 +460,75 @@ do_catchsql_test 19.1 { END; } {0 {}} +# 2024-04-24 +# https://sqlite.org/forum/forumpost/2c83569ce8945d39 +# +# If the RETURNING clause includes subqueries that reference the +# table being modified, make sure that the subqueries are identified +# as correlated so that the results are recomputed after each step +# instead of being computed once and reused. +# +reset_db +db null N +do_execsql_test 20.1 { + CREATE TABLE t1(a INTEGER PRIMARY KEY, b INT); + INSERT INTO t1 VALUES(1,10),(2,20),(3,30),(4,40),(6,60),(8,80); + BEGIN; + DELETE FROM t1 WHERE a<>3 + RETURNING a, + (SELECT min(a) FROM t1), + (SELECT max(a) FROM t1), + (SELECT round(avg(a),2) FROM t1); + ROLLBACK; +} { + 1 2 8 4.6 + 2 3 8 5.25 + 4 3 8 5.67 + 6 3 8 5.5 + 8 3 3 3.0 +} +do_execsql_test 20.2 { + BEGIN; + DELETE FROM t1 + RETURNING a, + (SELECT min(a) FROM t1), + (SELECT max(a) FROM t1), + (SELECT round(avg(a),2) FROM t1); + ROLLBACK; +} { + 1 2 8 4.6 + 2 3 8 5.25 + 3 4 8 6.0 + 4 6 8 7.0 + 6 8 8 8.0 + 8 N N N +} +do_execsql_test 20.3 { + BEGIN; + DELETE FROM t1 + RETURNING a, + (SELECT min(t2.a)+t1.a*100 FROM t1 AS t2), + (SELECT max(t2.a)+t1.a*100 FROM t1 AS t2), + (SELECT round(avg(t2.a),2)+t1.a*100 FROM t1 AS t2); + ROLLBACK; +} { + 1 102 108 104.6 + 2 203 208 205.25 + 3 304 308 306.0 + 4 406 408 407.0 + 6 608 608 608.0 + 8 N N N +} + +#------------------------------------------------------------------------- +reset_db +do_execsql_test 21.0 { + PRAGMA writable_schema=ON; + INSERT INTO sqlite_schema DEFAULT VALUES RETURNING sqlite_schema.name; +} {{}} + +do_execsql_test 21.1 { + INSERT INTO sqlite_temp_schema DEFAULT VALUES RETURNING sqlite_temp_schema.name; +} {{}} + finish_test diff --git a/test/scanstatus2.test b/test/scanstatus2.test index ca3a42f..7f107cd 100644 --- a/test/scanstatus2.test +++ b/test/scanstatus2.test @@ -247,7 +247,7 @@ QUERY (nCycle=nnn) ----SCAN rt2 (nCycle=nnn) ----USE TEMP B-TREE FOR GROUP BY (nCycle=nnn) --SCAN rt1 (nCycle=nnn) ---CREATE AUTOMATIC INDEX ON v1(x1, cnt, x1) (nCycle=nnn) +--CREATE AUTOMATIC INDEX ON v1(x1, cnt) (nCycle=nnn) --BLOOM FILTER ON v1 (x1=?) --SEARCH v1 USING AUTOMATIC COVERING INDEX (x1=?) (nCycle=nnn) } @@ -328,6 +328,17 @@ QUERY (nCycle=nnn) --SCAN xy2 (nCycle=nnn) } +#------------------------------------------------------------------------- +reset_db + +# Check that an OOB parameter (45) does not cause asan or valgrind errors. +# +do_test 7.0 { + db eval {SELECT * FROM sqlite_schema} + set stmt [db version -last-stmt-ptr] + sqlite3_stmt_scanstatus -flags complex $stmt 1000000 +} {} + #explain_i { SELECT (a % 2), group_concat(b) FROM t1 GROUP BY 1 } #puts_debug_info { SELECT (a % 2), group_concat(b) FROM t1 GROUP BY 1 } diff --git a/test/selectA.test b/test/selectA.test index 7d72bb3..91b1548 100644 --- a/test/selectA.test +++ b/test/selectA.test @@ -1340,10 +1340,10 @@ do_eqp_test 4.1.2 { `--MERGE (UNION ALL) |--LEFT | |--SCAN t5 USING INDEX i2 - | `--USE TEMP B-TREE FOR RIGHT PART OF ORDER BY + | `--USE TEMP B-TREE FOR LAST TERM OF ORDER BY `--RIGHT |--SCAN t4 USING INDEX i1 - `--USE TEMP B-TREE FOR RIGHT PART OF ORDER BY + `--USE TEMP B-TREE FOR LAST TERM OF ORDER BY } do_execsql_test 4.1.3 { diff --git a/test/sessionfuzz.c b/test/sessionfuzz.c index 093c2b0..c389a5e 100644 --- a/test/sessionfuzz.c +++ b/test/sessionfuzz.c @@ -60,6 +60,7 @@ #define SQLITE_DEBUG 1 #define SQLITE_THREADSAFE 0 +#undef SQLITE_OMIT_LOAD_EXTENSION #define SQLITE_OMIT_LOAD_EXTENSION 0 #define SQLITE_ENABLE_SESSION 1 #define SQLITE_ENABLE_PREUPDATE_HOOK 1 diff --git a/test/shell1.test b/test/shell1.test index 5d4243f..206fb0a 100644 --- a/test/shell1.test +++ b/test/shell1.test @@ -11,6 +11,7 @@ # # The focus of this file is testing the CLI shell tool. # +# TESTRUNNER: shell # # Test plan: diff --git a/test/shell2.test b/test/shell2.test index 16ed33c..c6c27d2 100644 --- a/test/shell2.test +++ b/test/shell2.test @@ -8,6 +8,7 @@ # May you share freely, never taking more than you give. # #*********************************************************************** +# TESTRUNNER: shell # # The focus of this file is testing the CLI shell tool. # diff --git a/test/shell3.test b/test/shell3.test index f8d6994..c1ea9f6 100644 --- a/test/shell3.test +++ b/test/shell3.test @@ -8,6 +8,7 @@ # May you share freely, never taking more than you give. # #*********************************************************************** +# TESTRUNNER: shell # # The focus of this file is testing the CLI shell tool. # diff --git a/test/shell4.test b/test/shell4.test index eee59b0..4b7e9b8 100644 --- a/test/shell4.test +++ b/test/shell4.test @@ -8,6 +8,7 @@ # May you share freely, never taking more than you give. # #*********************************************************************** +# TESTRUNNER: shell # # The focus of this file is testing the CLI shell tool. # These tests are specific to the .stats command. diff --git a/test/shell5.test b/test/shell5.test index 20f2ba2..877676d 100644 --- a/test/shell5.test +++ b/test/shell5.test @@ -8,6 +8,7 @@ # May you share freely, never taking more than you give. # #*********************************************************************** +# TESTRUNNER: shell # # The focus of this file is testing the CLI shell tool. # These tests are specific to the .import command. diff --git a/test/shell6.test b/test/shell6.test index 49b4cc3..4841d6c 100644 --- a/test/shell6.test +++ b/test/shell6.test @@ -8,6 +8,7 @@ # May you share freely, never taking more than you give. # #*********************************************************************** +# TESTRUNNER: shell # # Test the shell tool ".lint fkey-indexes" command. # diff --git a/test/shell7.test b/test/shell7.test index 898018d..dfd9e47 100644 --- a/test/shell7.test +++ b/test/shell7.test @@ -8,6 +8,7 @@ # May you share freely, never taking more than you give. # #*********************************************************************** +# TESTRUNNER: shell # # Test the readfile() function built into the shell tool. Specifically, # that it does not truncate the blob read at the first embedded 0x00 diff --git a/test/shell8.test b/test/shell8.test index bee6039..ca37598 100644 --- a/test/shell8.test +++ b/test/shell8.test @@ -8,6 +8,7 @@ # May you share freely, never taking more than you give. # #*********************************************************************** +# TESTRUNNER: shell # # Test the shell tool ".ar" command. # @@ -164,7 +165,7 @@ foreach {tn tcl} { # # Because it is slow, only do this for $tn==1. if {$tn==1} { - do_test 1.$tn.1 { + do_test 1.$tn.4 { catchcmd test_ar.db $c1 file delete -force ar1 after 2000 @@ -193,4 +194,29 @@ do_test 2.1.1 { regsub -all {ar4} [dir_content ar4] ar2 } {ar2/file1 ar2/file2 ar2/junk1} +# Test symbolic links. +# +if {$tcl_platform(platform)=="unix"} { + populate_dir ar2 { + file1 "1234" + file2 "3456" + } + file link ar2/link1 file1 + + forcedelete shell8.db + forcedelete link1 + + do_test 3.1 { + catchcmd shell8.db {.ar -C ar2 -c file2 link1 } + } {0 {}} + + do_test 3.2 { + catchcmd shell8.db {.ar -x} + } {0 {}} + + do_test 3.3 { + catchcmd shell8.db {.ar -x} + } {0 {}} +} + finish_test diff --git a/test/shell9.test b/test/shell9.test index 34c9d8c..869cb07 100644 --- a/test/shell9.test +++ b/test/shell9.test @@ -8,6 +8,7 @@ # May you share freely, never taking more than you give. # #*********************************************************************** +# TESTRUNNER: shell # # The focus of this file is testing the CLI shell tool. Specifically, # testing that it is possible to run a ".dump" script that creates diff --git a/test/speedtest1.c b/test/speedtest1.c index 4f32580..5709423 100644 --- a/test/speedtest1.c +++ b/test/speedtest1.c @@ -2150,6 +2150,50 @@ void testset_debug1(void){ } } +/* +** This testset focuses on the speed of parsing numeric literals (integers +** and real numbers). This was added to test the impact of allowing "_" +** characters to appear in numeric SQL literals to make them easier to read. +** For example, "SELECT 1_000_000;" instead of "SELECT 1000000;". +*/ +void testset_parsenumber(void){ + const char *zSql1 = "SELECT 1, 12, 123, 1234, 12345, 123456"; + const char *zSql2 = "SELECT 8227256643844975616, 7932208612563860480, " + "2010730661871032832, 9138463067404021760, " + "2557616153664746496, 2557616153664746496"; + const char *zSql3 = "SELECT 1.0, 1.2, 1.23, 123.4, 1.2345, 1.23456"; + const char *zSql4 = "SELECT 8.227256643844975616, 7.932208612563860480, " + "2.010730661871032832, 9.138463067404021760, " + "2.557616153664746496, 2.557616153664746496"; + + const int NROW = 100*g.szTest; + int ii; + + speedtest1_begin_test(100, "parsing small integers"); + for(ii=0; ii<NROW; ii++){ + sqlite3_exec(g.db, zSql1, 0, 0, 0); + } + speedtest1_end_test(); + + speedtest1_begin_test(110, "parsing large integers"); + for(ii=0; ii<NROW; ii++){ + sqlite3_exec(g.db, zSql2, 0, 0, 0); + } + speedtest1_end_test(); + + speedtest1_begin_test(200, "parsing small reals"); + for(ii=0; ii<NROW; ii++){ + sqlite3_exec(g.db, zSql3, 0, 0, 0); + } + speedtest1_end_test(); + + speedtest1_begin_test(210, "parsing large reals"); + for(ii=0; ii<NROW; ii++){ + sqlite3_exec(g.db, zSql4, 0, 0, 0); + } + speedtest1_end_test(); +} + #ifdef __linux__ #include <sys/types.h> #include <unistd.h> @@ -2557,6 +2601,8 @@ int main(int argc, char **argv){ testset_fp(); }else if( strcmp(zThisTest,"trigger")==0 ){ testset_trigger(); + }else if( strcmp(zThisTest,"parsenumber")==0 ){ + testset_parsenumber(); }else if( strcmp(zThisTest,"rtree")==0 ){ #ifdef SQLITE_ENABLE_RTREE testset_rtree(6, 147); diff --git a/test/sqllimits1.test b/test/sqllimits1.test index f16208f..14d39e6 100644 --- a/test/sqllimits1.test +++ b/test/sqllimits1.test @@ -707,6 +707,7 @@ if {$SQLITE_MAX_EXPR_DEPTH==0} { }] } "1 {Expression tree is too large (maximum depth $::SQLITE_MAX_EXPR_DEPTH)}" +if 0 { # Attempting to beat the expression depth limit using nested SELECT # queries causes a parser stack overflow. do_test sqllimits1-9.2 { @@ -718,7 +719,6 @@ if {$SQLITE_MAX_EXPR_DEPTH==0} { catchsql [subst { $expr }] } "1 {parser stack overflow}" -if 0 { do_test sqllimits1-9.3 { execsql { PRAGMA max_page_count = 1000000; -- 1 GB @@ -922,7 +922,7 @@ do_catchsql_test sqllimits1-18.1 { do_catchsql_test sqllimits1-18.2 { INSERT INTO b1 VALUES(1), (2), (3), (4), (5), (6), (7), (8), (9), (10) UNION VALUES(11); -} {1 {too many terms in compound SELECT}} +} {0 {}} #------------------------------------------------------------------------- # diff --git a/test/subquery.test b/test/subquery.test index c51edba..17061d4 100644 --- a/test/subquery.test +++ b/test/subquery.test @@ -651,5 +651,64 @@ do_eqp_test subquery-10.2 { # `--SEARCH t1 USING INDEX x12 (aa=?) # +#----------------------------------------------------------------------------- +# 2024-04-25 Column affinities for columns of compound subqueries +# +reset_db +sqlite3_test_control SQLITE_TESTCTRL_INTERNAL_FUNCTIONS db +do_execsql_test subquery-11.1 { + CREATE TABLE t1(ix INT, rx REAL, bx BLOB, tx TEXT, ax); + INSERT INTO t1 VALUES(1,1.0,x'31','x',NULL); + WITH c(a) AS (SELECT 'y' UNION SELECT tx FROM t1) SELECT affinity(a) FROM c; + WITH c(a) AS (SELECT tx FROM t1 UNION SELECT 'y') SELECT affinity(a) FROM c; +} {text text text text} +do_execsql_test subquery-11.2 { + WITH c(a) AS (SELECT 2 UNION SELECT tx FROM t1) SELECT affinity(a) FROM c; + WITH c(a) AS (SELECT tx FROM t1 UNION SELECT 2) SELECT affinity(a) FROM c; +} {blob blob blob blob} +do_execsql_test subquery-11.3 { + WITH c(a) AS (SELECT 2.0 UNION SELECT tx FROM t1) SELECT affinity(a) FROM c; + WITH c(a) AS (SELECT tx FROM t1 UNION SELECT 2.0) SELECT affinity(a) FROM c; +} {blob blob blob blob} +do_execsql_test subquery-11.4 { + WITH c(a) AS (SELECT null UNION SELECT tx FROM t1) SELECT affinity(a) FROM c; + WITH c(a) AS (SELECT tx FROM t1 UNION SELECT null) SELECT affinity(a) FROM c; +} {text text text text} +do_execsql_test subquery-11.5 { + WITH c(a) AS (SELECT x'32' UNION SELECT tx FROM t1) SELECT affinity(a) FROM c; + WITH c(a) AS (SELECT tx FROM t1 UNION SELECT x'32') SELECT affinity(a) FROM c; +} {text text text text} +do_execsql_test subquery-11.6 { + WITH c(a) AS (SELECT 3 UNION SELECT ix FROM t1) SELECT affinity(a) FROM c; + WITH c(a) AS (SELECT ix FROM t1 UNION SELECT 3) SELECT affinity(a) FROM c; +} {integer integer integer integer} +do_execsql_test subquery-11.7 { + WITH c(a) AS (SELECT 3.0 UNION SELECT ix FROM t1) SELECT affinity(a) FROM c; + WITH c(a) AS (SELECT ix FROM t1 UNION SELECT 3.0) SELECT affinity(a) FROM c; +} {integer integer integer integer} +do_execsql_test subquery-11.8 { + WITH c(a) AS (SELECT '3' UNION SELECT ix FROM t1) SELECT affinity(a) FROM c; + WITH c(a) AS (SELECT ix FROM t1 UNION SELECT '3') SELECT affinity(a) FROM c; +} {blob blob blob blob} +do_execsql_test subquery-11.10 { + WITH c(a) AS (SELECT x'32' UNION SELECT ix FROM t1) SELECT affinity(a) FROM c; + WITH c(a) AS (SELECT ix FROM t1 UNION SELECT x'32') SELECT affinity(a) FROM c; +} {integer integer integer integer} +do_execsql_test subquery-11.11 { + WITH c(a) AS (SELECT 4 UNION SELECT rx FROM t1) SELECT affinity(a) FROM c; + WITH c(a) AS (SELECT rx FROM t1 UNION SELECT 4) SELECT affinity(a) FROM c; +} {real real real real} +do_execsql_test subquery-11.12 { + WITH c(a) AS (SELECT '4' UNION SELECT rx FROM t1) SELECT affinity(a) FROM c; + WITH c(a) AS (SELECT rx FROM t1 UNION SELECT '4') SELECT affinity(a) FROM c; +} {blob blob blob blob} +do_execsql_test subquery-11.13 { + WITH c(a) AS (SELECT null UNION SELECT rx FROM t1) SELECT affinity(a) FROM c; + WITH c(a) AS (SELECT rx FROM t1 UNION SELECT null) SELECT affinity(a) FROM c; +} {real real real real} +do_execsql_test subquery-11.14 { + WITH c(a) AS (SELECT x'b4' UNION SELECT rx FROM t1) SELECT affinity(a) FROM c; + WITH c(a) AS (SELECT rx FROM t1 UNION SELECT x'b4') SELECT affinity(a) FROM c; +} {real real real real} finish_test diff --git a/test/tabfunc01.test b/test/tabfunc01.test index 8e90c54..3a62b81 100644 --- a/test/tabfunc01.test +++ b/test/tabfunc01.test @@ -322,6 +322,32 @@ ifcapable altertable { } {1 {table pragma_compile_options may not be altered}} } +#----------------------------------------------------------------------------- +# 2024-04-26 LIMIT and OFFSET passed into virtual tables +# https://sqlite.org/forum/forumpost/c243b8f856 +# +do_execsql_test tabfunc01-900 { + SELECT * FROM ( + SELECT * FROM generate_series(1,10) + UNION ALL + SELECT * FROM generate_series(101,104) + ) LIMIT 10 OFFSET 5; +} {6 7 8 9 10 101 102 103 104} +do_execsql_test tabfunc01-910 { + SELECT * FROM ( + SELECT * FROM generate_series(1,10) + UNION ALL + SELECT * FROM generate_series(101,104) + ) LIMIT -1 OFFSET 5; +} {6 7 8 9 10 101 102 103 104} +do_execsql_test tabfunc01-920 { + SELECT * FROM ( + SELECT * FROM generate_series(1,10) + UNION ALL + SELECT * FROM generate_series(101,104) + ) LIMIT -1 OFFSET 0; +} {1 2 3 4 5 6 7 8 9 10 101 102 103 104} + # Free up memory allocations intarray_addr diff --git a/test/testrunner.tcl b/test/testrunner.tcl index 0c704da..fd82716 100644 --- a/test/testrunner.tcl +++ b/test/testrunner.tcl @@ -54,22 +54,35 @@ proc usage {} { Usage: $a0 ?SWITCHES? ?PERMUTATION? ?PATTERNS? $a0 PERMUTATION FILE + $a0 help $a0 njob ?NJOB? + $a0 script ?-msvc? CONFIG $a0 status where SWITCHES are: - --buildonly - --dryrun - --jobs NUMBER-OF-JOBS - --zipvfs ZIPVFS-SOURCE-DIR + --buildonly Build test exes but do not run tests + --config CONFIGS Only use configs on comma-separate list CONFIGS + --dryrun Write what would have happened to testrunner.log + --explain Write summary to stdout + --jobs NUM Run tests using NUM separate processes + --omit CONFIGS Omit configs on comma-separated list CONFIGS + --stop-on-coredump Stop running if any test segfaults + --stop-on-error Stop running after any reported error + --zipvfs ZIPVFSDIR ZIPVFS source directory + +Special values for PERMUTATION that work with plain tclsh: + + list - show all allowed PERMUTATION arguments. + mdevtest - tests recommended prior to normal development check-ins. + release - full release test with various builds. + sdevtest - like mdevtest but using ASAN and UBSAN. -Interesting values for PERMUTATION are: +Other PERMUTATION arguments must be run using testfixture, not tclsh: - veryquick - a fast subset of the tcl test scripts. This is the default. - full - all tcl test scripts. all - all tcl test scripts, plus a subset of test scripts rerun with various permutations. - release - full release test with various builds. + full - all tcl test scripts. + veryquick - a fast subset of the tcl test scripts. This is the default. If no PATTERN arguments are present, all tests specified by the PERMUTATION are run. Otherwise, each pattern is interpreted as a glob pattern. Only @@ -89,6 +102,12 @@ directory as a running testrunner.tcl script that is running tests. The "status" command prints a report describing the current state and progress of the tests. The "njob" command may be used to query or modify the number of sub-processes the test script uses to run tests. + +The "script" command outputs the script used to build a configuration. +Add the "-msvc" option for a Windows-compatible script. For a list of +available configurations enter "$a0 script help". + +Full documentation here: https://sqlite.org/src/doc/trunk/doc/testrunner.md }]] exit 1 @@ -126,6 +145,10 @@ proc guess_number_of_cores {} { } proc default_njob {} { + global env + if {[info exists env(NJOB)] && $env(NJOB)>=1} { + return $env(NJOB) + } set nCore [guess_number_of_cores] if {$nCore<=2} { set nHelper 1 @@ -151,7 +174,12 @@ set TRG(reporttime) 2000 set TRG(fuzztest) 0 ;# is the fuzztest option present. set TRG(zipvfs) "" ;# -zipvfs option, if any set TRG(buildonly) 0 ;# True if --buildonly option +set TRG(config) {} ;# Only build the named configurations +set TRG(omitconfig) {} ;# Do not build these configurations set TRG(dryrun) 0 ;# True if --dryrun option +set TRG(explain) 0 ;# True for the --explain option +set TRG(stopOnError) 0 ;# Stop running at first failure +set TRG(stopOnCore) 0 ;# Stop on a core-dump switch -nocase -glob -- $tcl_platform(os) { *darwin* { @@ -159,6 +187,7 @@ switch -nocase -glob -- $tcl_platform(os) { set TRG(make) make.sh set TRG(makecmd) "bash make.sh" set TRG(testfixture) testfixture + set TRG(shell) sqlite3 set TRG(run) run.sh set TRG(runcmd) "bash run.sh" } @@ -167,14 +196,16 @@ switch -nocase -glob -- $tcl_platform(os) { set TRG(make) make.sh set TRG(makecmd) "bash make.sh" set TRG(testfixture) testfixture + set TRG(shell) sqlite3 set TRG(run) run.sh set TRG(runcmd) "bash run.sh" } *win* { set TRG(platform) win set TRG(make) make.bat - set TRG(makecmd) make.bat + set TRG(makecmd) "call make.bat" set TRG(testfixture) testfixture.exe + set TRG(shell) sqlite3.exe set TRG(run) run.bat set TRG(runcmd) "run.bat" } @@ -239,7 +270,7 @@ set TRG(schema) { /* Fields updated as jobs run */ starttime INTEGER, endtime INTEGER, - state TEXT CHECK( state IN ('', 'ready', 'running', 'done', 'failed') ), + state TEXT CHECK( state IN ('','ready','running','done','failed','omit') ), output TEXT ); @@ -327,6 +358,14 @@ if {([llength $argv]==2 || [llength $argv]==1) #-------------------------------------------------------------------------- #-------------------------------------------------------------------------- +# Check if this is the "help" command: +# +if {[string compare -nocase help [lindex $argv 0]]==0} { + usage +} +#-------------------------------------------------------------------------- + +#-------------------------------------------------------------------------- # Check if this is the "script" command: # if {[string compare -nocase script [lindex $argv 0]]==0} { @@ -408,6 +447,10 @@ if {[llength $argv]==1 } job { display_job [array get job] } + set nOmit [db one {SELECT count(*) FROM jobs WHERE state='omit'}] + if {$nOmit} { + puts "$nOmit jobs omitted due to failures" + } } mydb close @@ -433,8 +476,20 @@ for {set ii 0} {$ii < [llength $argv]} {incr ii} { if {$isLast} { usage } } elseif {($n>2 && [string match "$a*" --buildonly]) || $a=="-b"} { set TRG(buildonly) 1 + } elseif {($n>2 && [string match "$a*" --config]) || $a=="-c"} { + incr ii + set TRG(config) [lindex $argv $ii] } elseif {($n>2 && [string match "$a*" --dryrun]) || $a=="-d"} { set TRG(dryrun) 1 + } elseif {($n>2 && [string match "$a*" --explain]) || $a=="-e"} { + set TRG(explain) 1 + } elseif {($n>2 && [string match "$a*" --omit]) || $a=="-c"} { + incr ii + set TRG(omitconfig) [lindex $argv $ii] + } elseif {[string match "$a*" --stop-on-error]} { + set TRG(stopOnError) 1 + } elseif {[string match "$a*" --stop-on-coredump]} { + set TRG(stopOnCore) 1 } else { usage } @@ -444,8 +499,6 @@ for {set ii 0} {$ii < [llength $argv]} {incr ii} { } set argv [list] - - # This script runs individual tests - tcl scripts or [make xyz] commands - # in directories named "testdir$N", where $N is an integer. This variable # contains a list of integers indicating the directories in use. @@ -617,7 +670,16 @@ proc add_job {args} { trdb last_insert_rowid } -proc add_tcl_jobs {build config patternlist} { +# Argument $build is either an empty string, or else a list of length 3 +# describing the job to build testfixture. In the usual form: +# +# {ID DIRNAME DISPLAYNAME} +# +# e.g +# +# {1 /home/user/sqlite/test/testrunner_bld_xyz All-Debug} +# +proc add_tcl_jobs {build config patternlist {shelldepid ""}} { global TRG set topdir [file dirname $::testdir] @@ -666,34 +728,59 @@ proc add_tcl_jobs {build config patternlist} { if {[lsearch $lProp slow]>=0} { set priority 2 } if {[lsearch $lProp superslow]>=0} { set priority 4 } + set depid [lindex $build 0] + if {$shelldepid!="" && [lsearch $lProp shell]>=0} { set depid $shelldepid } + add_job \ -displaytype tcl \ -displayname $displayname \ -cmd $cmd \ - -depid [lindex $build 0] \ + -depid $depid \ -priority $priority - } } -proc add_build_job {buildname target} { +proc add_build_job {buildname target {postcmd ""} {depid ""}} { global TRG set dirname "[string tolower [string map {- _} $buildname]]_$target" set dirname "testrunner_bld_$dirname" + set cmd "$TRG(makecmd) $target" + if {$postcmd!=""} { + append cmd "\n" + append cmd $postcmd + } + set id [add_job \ -displaytype bld \ -displayname "Build $buildname ($target)" \ -dirname $dirname \ -build $buildname \ - -cmd "$TRG(makecmd) $target" \ + -cmd $cmd \ + -depid $depid \ -priority 3 ] list $id [file normalize $dirname] $buildname } +proc add_shell_build_job {buildname dirname depid} { + global TRG + + if {$TRG(platform)=="win"} { + set path [string map {/ \\} "$dirname/"] + set copycmd "xcopy $TRG(shell) $path" + } else { + set copycmd "cp $TRG(shell) $dirname/" + } + + return [ + add_build_job $buildname $TRG(shell) $copycmd $depid + ] +} + + proc add_make_job {bld target} { global TRG @@ -767,10 +854,30 @@ proc add_devtest_jobs {lBld patternlist} { foreach b $lBld { set bld [add_build_job $b $TRG(testfixture)] - add_tcl_jobs $bld veryquick $patternlist + add_tcl_jobs $bld veryquick $patternlist SHELL if {$patternlist==""} { add_fuzztest_jobs $b } + + if {[trdb one "SELECT EXISTS (SELECT 1 FROM jobs WHERE depid='SHELL')"]} { + set sbld [add_shell_build_job $b [lindex $bld 1] [lindex $bld 0]] + set sbldid [lindex $sbld 0] + trdb eval { + UPDATE jobs SET depid=$sbldid WHERE depid='SHELL' + } + } + + } +} + +# Check to ensure that the interpreter is a full-blown "testfixture" +# build and not just a "tclsh". If this is not the case, issue an +# error message and exit. +# +proc must_be_testfixture {} { + if {[lsearch [info commands] sqlite3_soft_heap_limit]<0} { + puts "Use testfixture, not tclsh, for these arguments." + exit 1 } } @@ -789,6 +896,7 @@ proc add_jobs_from_cmdline {patternlist} { set first [lindex $patternlist 0] switch -- $first { all { + must_be_testfixture set patternlist [lrange $patternlist 1 end] set clist [trd_all_configs] foreach c $clist { @@ -797,16 +905,26 @@ proc add_jobs_from_cmdline {patternlist} { } mdevtest { - add_devtest_jobs {All-O0 All-Debug} [lrange $patternlist 1 end] + set config_set { + All-O0 + All-Debug + } + add_devtest_jobs $config_set [lrange $patternlist 1 end] } sdevtest { - add_devtest_jobs {All-Sanitize All-Debug} [lrange $patternlist 1 end] + set config_set { + All-Sanitize + All-Debug + } + add_devtest_jobs $config_set [lrange $patternlist 1 end] } release { set patternlist [lrange $patternlist 1 end] foreach b [trd_builds $TRG(platform)] { + if {$TRG(config)!="" && ![regexp "\\y$b\\y" $TRG(config)]} continue + if {[regexp "\\y$b\\y" $TRG(omitconfig)]} continue set bld [add_build_job $b $TRG(testfixture)] foreach c [trd_configs $TRG(platform) $b] { add_tcl_jobs $bld $c $patternlist @@ -824,7 +942,15 @@ proc add_jobs_from_cmdline {patternlist} { } } + list { + set allperm [array names ::testspec] + lappend allperm all mdevtest sdevtest release list + puts "Allowed values for the PERMUTATION argument: [lsort $allperm]" + exit 0 + } + default { + must_be_testfixture if {[info exists ::testspec($first)]} { add_tcl_jobs "" $first [lrange $patternlist 1 end] } else { @@ -853,11 +979,16 @@ proc make_new_testset {} { proc mark_job_as_finished {jobid output state endtm} { r_write_db { + if {$state=="failed"} { + set childstate omit + } else { + set childstate ready + } trdb eval { UPDATE jobs SET output=$output, state=$state, endtime=$endtm WHERE jobid=$jobid; - UPDATE jobs SET state='ready' WHERE depid=$jobid; + UPDATE jobs SET state=$childstate WHERE depid=$jobid; } } } @@ -888,6 +1019,14 @@ proc script_input_ready {fd iJob jobid} { } puts "FAILED: $job(displayname) ($iJob)" set state "failed" + if {$TRG(stopOnError)} { + puts "OUTPUT: $O($iJob)" + exit 1 + } + if {$TRG(stopOnCore) && [string first {core dumped} $O($iJob)]>0} { + puts "OUTPUT: $O($iJob)" + exit 1 + } } set tm [clock_milliseconds] @@ -948,6 +1087,16 @@ proc launch_another_job {iJob} { close $fd } + # Add a batch/shell file command to set the directory used for temp + # files to the test's working directory. Otherwise, tests that use + # large numbers of temp files (e.g. zipvfs), might generate temp + # filename collisions. + if {$TRG(platform)=="win"} { + set set_tmp_dir "SET SQLITE_TMPDIR=[file normalize $dir]" + } else { + set set_tmp_dir "export SQLITE_TMPDIR=\"[file normalize $dir]\"" + } + if { $TRG(dryrun) } { mark_job_as_finished $job(jobid) "" done 0 @@ -962,7 +1111,8 @@ proc launch_another_job {iJob} { set pwd [pwd] cd $dir set fd [open $TRG(run) w] - puts $fd $job(cmd) + puts $fd $set_tmp_dir + puts $fd $job(cmd) close $fd set fd [open "|$TRG(runcmd) 2>@1" r] cd $pwd @@ -1061,6 +1211,10 @@ proc run_testset {} { puts "FAILED: $displayname" } } + set nOmit [trdb one {SELECT count(*) FROM jobs WHERE state='omit'}] + if {$nOmit>0} { + puts "$nOmit jobs skipped due to prior failures" + } } puts "\nTest database is $TRG(dbname)" @@ -1078,15 +1232,42 @@ proc handle_buildonly {} { } } +# Handle the --explain option. Provide a human-readable +# explanation of all the tests that are in the trdb database jobs +# table. +# +proc explain_layer {indent depid} { + global TRG + if {$TRG(buildonly)} { + set showtests 0 + } else { + set showtests 1 + } + trdb eval {SELECT jobid, displayname, displaytype, dirname + FROM jobs WHERE depid=$depid ORDER BY displayname} { + if {$displaytype=="bld"} { + puts "${indent}$displayname in $dirname" + explain_layer "${indent} " $jobid + } elseif {$showtests} { + puts "${indent}[lindex $displayname end]" + } + } +} +proc explain_tests {} { + explain_layer "" "" +} + sqlite3 trdb $TRG(dbname) trdb timeout $TRG(timeout) set tm [lindex [time { make_new_testset }] 0] -if {$TRG(nJob)>1} { - puts "splitting work across $TRG(nJob) jobs" +if {$TRG(explain)} { + explain_tests +} else { + if {$TRG(nJob)>1} { + puts "splitting work across $TRG(nJob) jobs" + } + puts "built testset in [expr $tm/1000]ms.." + handle_buildonly + run_testset } -puts "built testset in [expr $tm/1000]ms.." - -handle_buildonly -run_testset trdb close -#puts [pwd] diff --git a/test/testrunner_data.tcl b/test/testrunner_data.tcl index 984c6d8..f8f12d9 100644 --- a/test/testrunner_data.tcl +++ b/test/testrunner_data.tcl @@ -23,6 +23,7 @@ namespace eval trd { set tcltest(linux.No-lookaside) veryquick set tcltest(linux.Devkit) veryquick set tcltest(linux.Apple) veryquick + set tcltest(linux.Android) veryquick set tcltest(linux.Sanitize) veryquick set tcltest(linux.Device-One) all set tcltest(linux.Default) all_plus_autovacuum_crash @@ -53,6 +54,7 @@ namespace eval trd { set extra(linux.Device-Two) {fuzztest sourcetest threadtest} set extra(linux.No-lookaside) {fuzztest sourcetest} set extra(linux.Devkit) {fuzztest sourcetest} + set extra(linux.Android) {fuzztest sourcetest} set extra(linux.Apple) {fuzztest sourcetest} set extra(linux.Sanitize) {fuzztest sourcetest} set extra(linux.Default) {fuzztest sourcetest threadtest} @@ -108,6 +110,7 @@ namespace eval trd { -DSQLITE_ENABLE_STAT4 -DSQLITE_OMIT_LOOKASIDE=1 -DCONFIG_SLOWDOWN_FACTOR=5.0 + -DSQLITE_ENABLE_RBU --enable-debug --enable-all } @@ -245,6 +248,40 @@ namespace eval trd { -O2 -DSQLITE_ENABLE_LOCKING_STYLE=1 } + set build(Android) { + -Os + -DHAVE_USLEEP=1 + -DSQLITE_HAVE_ISNAN + -DSQLITE_POWERSAFE_OVERWRITE=1 + -DSQLITE_DEFAULT_FILE_FORMAT=4 + -DSQLITE_DEFAULT_AUTOVACUUM=1 + -DSQLITE_ENABLE_MEMORY_MANAGEMENT=1 + -DSQLITE_ENABLE_FTS3 + -DSQLITE_ENABLE_FTS3_BACKWARDS + -DSQLITE_ENABLE_FTS4 + -DSQLITE_SECURE_DELETE + -DSQLITE_ENABLE_BATCH_ATOMIC_WRITE + -DBIONIC_IOCTL_NO_SIGNEDNESS_OVERLOAD + -DSQLITE_ALLOW_ROWID_IN_VIEW + -DSQLITE_ENABLE_BYTECODE_VTAB + -Wno-unused-parameter + -Werror + -DUSE_PREAD64 + -Dfdatasync=fdatasync + -DHAVE_MALLOC_H=1 + -DHAVE_MALLOC_USABLE_SIZE + -DSQLITE_ENABLE_DBSTAT_VTAB + } + # Compile-options used by Android but omitted from these + # tests: + # -DNDEBUG=1 + # -DSQLITE_DEFAULT_LEGACY_ALTER_TABLE + # -DSQLITE_DEFAULT_JOURNAL_SIZE_LIMIT=1048576 + # -DSQLITE_DEFAULT_FILE_PERMISSIONS=0600 + # -DSQLITE_OMIT_BUILTIN_TEST + # -DSQLITE_OMIT_LOAD_EXTENSION + # -DSQLITE_OMIT_COMPILEOPTION_DIAGS + # set build(Apple) { -Os -DHAVE_GMTIME_R=1 @@ -598,7 +635,12 @@ proc trd_buildscript {config srcdir bMsvc} { # Ensure that the named configuration exists. if {![info exists build($config)]} { - error "No such build config: $config" + if {$config!="help"} { + puts "No such build config: $config" + } + puts "Available configurations: [lsort [array names build]]" + flush stdout + exit 1 } # Generate and return the script. @@ -637,4 +679,3 @@ proc trd_test_script_properties {path} { set trd_test_script_properties_cache($path) } - diff --git a/test/tkt-8454a207b9.test b/test/tkt-8454a207b9.test index 20e1420..42b95c8 100644 --- a/test/tkt-8454a207b9.test +++ b/test/tkt-8454a207b9.test @@ -49,7 +49,7 @@ do_test tkt-8454a207b9.4 { ALTER TABLE t1 ADD COLUMN e DEFAULT -123.0; SELECT e, typeof(e) FROM t1; } -} {-123 integer} +} {-123.0 real} do_test tkt-8454a207b9.5 { db eval { ALTER TABLE t1 ADD COLUMN f DEFAULT -123.5; diff --git a/test/tkt-bd484a090c.test b/test/tkt-bd484a090c.test index 3d2b599..7867c8d 100644 --- a/test/tkt-bd484a090c.test +++ b/test/tkt-bd484a090c.test @@ -30,7 +30,7 @@ do_test 2.1 { catchsql { SELECT datetime('now', 'localtime') } } {1 {local time unavailable}} do_test 2.2 { - catchsql { SELECT datetime('now', 'utc') } + catchsql { SELECT datetime('2000-01-01', 'utc') } } {1 {local time unavailable}} sqlite3_test_control SQLITE_TESTCTRL_LOCALTIME_FAULT 0 diff --git a/test/upsert1.test b/test/upsert1.test index 7818311..8af273a 100644 --- a/test/upsert1.test +++ b/test/upsert1.test @@ -268,4 +268,28 @@ do_catchsql_test upsert1-1210 { INSERT INTO t1(a,b) VALUES(1,2) ON CONFLICT(b+?1) DO NOTHING; } {1 {ON CONFLICT clause does not match any PRIMARY KEY or UNIQUE constraint}} +# 2024-04-11 https://sqlite.org/forum/forumpost/284955a3cd454a15 +# Incorrect value passed into a trigger that fires as the result of +# an upsert. +# +reset_db +do_execsql_test upsert1-1300 { + CREATE TABLE t1(x INT, y TEXT); + INSERT INTO t1 VALUES + (11, printf('%.9000c','a')), + (11, printf('%.9000c','a')), + (33, printf('%.9000c','b')), + (33, printf('%.9000c','b')); + CREATE TABLE t2(x INT UNIQUE, y TEXT); + CREATE TRIGGER r1 BEFORE UPDATE ON t2 BEGIN + SELECT raise(ABORT,'Incorrect old.y value passed to trigger!') + WHERE old.y != new.y; + /* ^^^ This trigger will fire and cause the ABORT if the problem has + ** not been fixed, or if there is a regression. */ + END; + INSERT INTO t2(x, y) SELECT x, y FROM t1 + WHERE true + ON CONFLICT (x) DO UPDATE SET y = excluded.y; +} {} + finish_test diff --git a/test/values.test b/test/values.test new file mode 100644 index 0000000..fed2c5c --- /dev/null +++ b/test/values.test @@ -0,0 +1,715 @@ +# 2024 March 3 +# +# 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. +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set testprefix values + + +do_execsql_test 1.0 { + CREATE TABLE x1(a, b, c); +} + + +explain_i { + INSERT INTO x1(a, b, c) VALUES(1, 1, 1), (2, 2, 2), (3, 3, 3), (4, 4, 4); +} +do_execsql_test 1.1.1 { + INSERT INTO x1 VALUES(1, 1, 1), (2, 2, 2), (3, 3, 3), (4, 4, 4); +} +do_execsql_test 1.1.2 { + SELECT * FROM x1; +} { + 1 1 1 + 2 2 2 + 3 3 3 + 4 4 4 +} + +do_execsql_test 1.2.0 { + DELETE FROM x1 +} +do_execsql_test 1.2.1 { + INSERT INTO x1 VALUES(1, 1, 1), (2, 2, 2), (3, 3, 3) UNION ALL SELECT 4, 4, 4; + SELECT * FROM x1; +} {1 1 1 2 2 2 3 3 3 4 4 4} + +sqlite3_limit db SQLITE_LIMIT_COMPOUND_SELECT 4 + +do_execsql_test 1.2.2 { + DELETE FROM x1; + INSERT INTO x1 + VALUES(1, 1, 1), (2, 2, 2), (3, 3, 3), (4, 4, 4), (5, 5, 5) + UNION ALL SELECT 6, 6, 6; + SELECT * FROM x1; +} {1 1 1 2 2 2 3 3 3 4 4 4 5 5 5 6 6 6} + +do_execsql_test 1.2.3 { + DELETE FROM x1; + INSERT INTO x1 + VALUES(1, 1, 1), (2, 2, 2), (3, 3, 3), (4, 4, 4) + UNION ALL SELECT 6, 6, 6; + SELECT * FROM x1; +} {1 1 1 2 2 2 3 3 3 4 4 4 6 6 6} + +do_execsql_test 1.2.4 { + DELETE FROM x1; + INSERT INTO x1 VALUES(1, 1, 1), (2, 2, 2), (3, 3, 3) UNION ALL SELECT 6, 6, 6; + SELECT * FROM x1; +} { + 1 1 1 + 2 2 2 + 3 3 3 + 6 6 6 +} + +set a 4 +set b 5 +set c 6 +do_execsql_test 1.2.5 { + DELETE FROM x1; + INSERT INTO x1 + VALUES(1, 1, 1), (2, 2, 2), (3, 3, 3), + (4, 4, $a), (5, 5, $b), (6, 6, $c) +} + +do_execsql_test 1.2.6 { + SELECT * FROM x1; +} { + 1 1 1 + 2 2 2 + 3 3 3 + 4 4 4 + 5 5 5 + 6 6 6 +} + +#------------------------------------------------------------------------- +# SQLITE_LIMIT_COMPOUND_SELECT set to 0. +# +reset_db + +do_execsql_test 2.0 { + CREATE TABLE x1(a, b, c); +} + +sqlite3_limit db SQLITE_LIMIT_COMPOUND_SELECT 3 + +do_catchsql_test 2.1.1 { + INSERT INTO x1 VALUES + (1, 1, 1), + (2, 2, 2), + (3, 3, 3), + (4, 4, 4), + (5, 5, 5), + (6, 6, 6), + (7, 7, 7), + (8, 8, 8), + (9, 9, 9), + (10, 10, 10, 10) +} {1 {all VALUES must have the same number of terms}} + +do_catchsql_test 2.1.2 { + INSERT INTO x1 VALUES + (1, 1, 1), + (2, 2, 2, 2), + (3, 3, 3), + (4, 4, 4), + (5, 5, 5), + (6, 6, 6), + (7, 7, 7), + (8, 8, 8), + (9, 9, 9), + (10, 10, 10) +} {1 {all VALUES must have the same number of terms}} + +sqlite3_limit db SQLITE_LIMIT_COMPOUND_SELECT 0 + +do_execsql_test 2.2 { + INSERT INTO x1 VALUES + (1, 1, 1), + (2, 2, 2), + (3, 3, 3), + (4, 4, 4), + (5, 5, 5), + (6, 6, 6), + (7, 7, 7), + (8, 8, 8), + (9, 9, 9), + (10, 10, 10) +} {} +do_execsql_test 2.3 { + INSERT INTO x1 VALUES + (1, 1, 1), + (2, 2, 2), + (3, 3, 3), + (4, 4, 4), + (5, 5, 5), + (6, 6, 6), + (7, 7, 7), + (8, 8, 8), + (9, 9, 9), + (10, 10, 10) + UNION ALL + SELECT 5, 12, 12 + ORDER BY 1 +} {} + +#------------------------------------------------------------------------- +reset_db + +do_execsql_test 3.0 { + CREATE TABLE y1(x, y); +} + +do_execsql_test 3.1.1 { + DELETE FROM y1; + INSERT INTO y1 VALUES(1, 2), (3, 4), (row_number() OVER (), 5); +} +do_execsql_test 3.1.2 { + SELECT * FROM y1; +} {1 2 3 4 1 5} +do_execsql_test 3.2.1 { + DELETE FROM y1; + INSERT INTO y1 VALUES(1, 2), (3, 4), (row_number() OVER (), 6) + , (row_number() OVER (), 7) +} +do_execsql_test 3.1.2 { + SELECT * FROM y1; +} {1 2 3 4 1 6 1 7} + +#------------------------------------------------------------------------- +reset_db + +do_execsql_test 4.0 { + CREATE TABLE x1(a PRIMARY KEY, b) WITHOUT ROWID; +} + +foreach {tn iLimit} {1 0 2 3} { + sqlite3_limit db SQLITE_LIMIT_COMPOUND_SELECT $iLimit + + do_execsql_test 4.1.1 { + DELETE FROM x1; + INSERT INTO x1 VALUES + (1, 1), + (2, (SELECT * FROM (VALUES('a'), ('b'), ('c'), ('d')) )) + } + do_execsql_test 4.1.2 { + SELECT * FROM x1 + } {1 1 2 a} + + do_execsql_test 4.2.1 { + DELETE FROM x1; + INSERT INTO x1 VALUES + (1, 1), + (2, 2), + (3, 3), + (4, 4), + (5, (SELECT * FROM (VALUES('a'), ('b'), ('c'), ('d')) )) + } + do_execsql_test 4.2.2 { + SELECT * FROM x1 + } {1 1 2 2 3 3 4 4 5 a} + + do_execsql_test 4.3.1 { + DELETE FROM x1; + INSERT INTO x1 VALUES + (1, (SELECT * FROM (VALUES('a'), ('b'), ('c'), ('d'), ('e')) )) + } + do_execsql_test 4.3.2 { + SELECT * FROM x1 + } {1 a} +} + +#------------------------------------------------------------------------ +reset_db + +do_execsql_test 5.0 { + CREATE VIEW v1 AS VALUES(1, 2, 3), (4, 5, 6), (7, 8, 9); +} +do_execsql_test 5.1 { + SELECT * FROM v1 +} {1 2 3 4 5 6 7 8 9} + +#------------------------------------------------------------------------- +reset_db +do_execsql_test 6.0 { + CREATE TABLE t1(x); + INSERT INTO t1 VALUES(1), (2); +} + +do_execsql_test 6.1 { + SELECT ( VALUES( x ), ( x ) ) FROM t1; +} {1 2} + +#------------------------------------------------------------------------- +reset_db +do_execsql_test 6.0 { + CREATE TABLE t1(x); + INSERT INTO t1 VALUES('x'), ('y'); +} + +do_execsql_test 6.1 { + SELECT * FROM t1, (VALUES(1), (2)) +} {x 1 x 2 y 1 y 2} + +do_execsql_test 6.2 { + VALUES(CAST(44 AS REAL)),(55); +} {44.0 55} + +#------------------------------------------------------------------------ +do_execsql_test 7.1 { + WITH x1(a, b) AS ( + VALUES(1, 2), ('a', 'b') + ) + SELECT * FROM x1 one, x1 two +} { + 1 2 1 2 + 1 2 a b + a b 1 2 + a b a b +} + +#------------------------------------------------------------------------- +reset_db + +set VVV { + ( VALUES('a', 'b'), ('c', 'd'), (123, NULL) ) +} +set VVV2 { + ( + SELECT 'a' AS column1, 'b' AS column2 + UNION ALL SELECT 'c', 'd' UNION ALL SELECT 123, NULL + ) +} + +do_execsql_test 8.0 { + CREATE TABLE t1(x); + INSERT INTO t1 VALUES('d'), (NULL), (123) +} +foreach {tn q res} { + 1 "SELECT * FROM t1 LEFT JOIN VVV" { + d a b d c d d 123 {} + {} a b {} c d {} 123 {} + 123 a b 123 c d 123 123 {} + } + + 2 "SELECT * FROM t1 LEFT JOIN VVV ON (column1=x)" { + d {} {} + {} {} {} + 123 123 {} + } + + 3 "SELECT * FROM t1 RIGHT JOIN VVV" { + d a b d c d d 123 {} + {} a b {} c d {} 123 {} + 123 a b 123 c d 123 123 {} + } + + 4 "SELECT * FROM t1 RIGHT JOIN VVV ON (column1=x)" { + 123 123 {} + {} a b + {} c d + } + + 5 "SELECT * FROM t1 FULL OUTER JOIN VVV ON (column1=x)" { + d {} {} + {} {} {} + 123 123 {} + {} a b + {} c d + } + + 6 "SELECT count(*) FROM VVV" { 3 } + + 7 "SELECT (SELECT column1 FROM VVV)" { a } + + 8 "SELECT * FROM VVV UNION ALL SELECT * FROM VVV" { + a b c d 123 {} + a b c d 123 {} + } + + 9 "SELECT * FROM VVV INTERSECT SELECT * FROM VVV" { + 123 {} a b c d + } + + 10 "SELECT * FROM VVV eXCEPT SELECT * FROM VVV" { } + + 11 "SELECT * FROM VVV eXCEPT SELECT 'a', 'b'" { 123 {} c d } + +} { + set q1 [string map [list VVV $VVV] $q] + set q2 [string map [list VVV $VVV2] $q] + set q3 "WITH VVV AS $VVV $q" + + do_execsql_test 8.1.$tn.1 $q1 $res + do_execsql_test 8.1.$tn.2 $q2 $res + do_execsql_test 8.1.$tn.3 $q3 $res +} + +#------------------------------------------------------------------------- +reset_db + +do_execsql_test 9.1 { + VALUES(456), (123), (NULL) UNION ALL SELECT 122 ORDER BY 1 +} { {} 122 123 456 } + +do_execsql_test 9.2 { + VALUES (1, 2), (3, 4), ( + ( SELECT column1 FROM ( VALUES (5, 6), (7, 8) ) ), + ( SELECT max(column2) FROM ( VALUES (5, 1), (7, 6) ) ) + ) +} { 1 2 3 4 5 6 } + +do_execsql_test 10.1 { + CREATE TABLE a2(a, b, c DEFAULT 'xyz'); +} +do_execsql_test 10.2 { + INSERT INTO a2(a) VALUES(3),(4); +} + +#------------------------------------------------------------------------- +reset_db +ifcapable fts5 { + do_execsql_test 11.0 { + CREATE VIRTUAL TABLE ft USING fts3(x); + } + do_execsql_test 11.1 { + INSERT INTO ft VALUES('one'), ('two'); + } +} + +#------------------------------------------------------------------------- +reset_db +do_execsql_test 12.0 { + CREATE TABLE t1(a, b); +} +do_execsql_test 12.1 { + INSERT INTO t1 SELECT 1, 2 UNION ALL VALUES(3, 4), (5, 6); +} +do_execsql_test 12.2 { + SELECT * FROM t1 +} {1 2 3 4 5 6} + +#------------------------------------------------------------------------- +reset_db +do_execsql_test 13.0 { + CREATE TABLE t1(x); + INSERT INTO t1 VALUES('xyz'); + + SELECT ( + VALUES( (max(substr('abc', 1, 1), x)) ), + (123), + (456) + ) + FROM t1; +} {xyz} + +do_catchsql_test 13.1 { + VALUES(300), (zeroblob(300) OVER win); +} {1 {zeroblob() may not be used as a window function}} + +#-------------------------------------------------------------------------- +reset_db +do_execsql_test 14.1 { + PRAGMA encoding = utf16; + CREATE TABLE t1(a, b); +} {} + +db close +sqlite3 db test.db + +do_execsql_test 14.2 { + INSERT INTO t1 VALUES + (17, 'craft'), + (16, 'urtlek' IN(1,2,3)); +} + +#-------------------------------------------------------------------------- +# +reset_db +do_eqp_test 15.1 { + VALUES(1),(2),(3),(4),(5); +} { + QUERY PLAN + `--SCAN 5-ROW VALUES CLAUSE +} +do_execsql_test 15.2 { + CREATE TABLE t1(a,b); +} +do_eqp_test 15.3 { + INSERT INTO t1 VALUES + (1,2),(3,4),(7,8); +} { + QUERY PLAN + `--SCAN 3-ROW VALUES CLAUSE +} +do_eqp_test 15.4 { + INSERT INTO t1 VALUES + (1,2),(3,4),(7,8), + (5,row_number()OVER()); +} { + QUERY PLAN + `--COMPOUND QUERY + |--LEFT-MOST SUBQUERY + | `--SCAN 3-ROW VALUES CLAUSE + `--UNION ALL + |--CO-ROUTINE (subquery-xxxxxx) + | `--SCAN CONSTANT ROW + `--SCAN (subquery-xxxxxx) +} +do_eqp_test 15.5 { + SELECT * FROM (VALUES(1),(2),(3),(4),(5),(6)), (VALUES('a'),('b'),('c')); +} { + QUERY PLAN + |--SCAN 6-ROW VALUES CLAUSE + `--SCAN 3-ROW VALUES CLAUSE +} +do_execsql_test 15.6 { + CREATE TABLE t2(x,y); +} +do_eqp_test 15.7 { + SELECT * FROM t2 UNION ALL VALUES(1,2),(3,4),(5,6),(7,8); +} { + QUERY PLAN + `--COMPOUND QUERY + |--LEFT-MOST SUBQUERY + | `--SCAN t2 + `--UNION ALL + `--SCAN 4-ROW VALUES CLAUSE +} + +#-------------------------------------------------------------------------- +# The VALUES-as-coroutine optimization can be applied to later rows of +# a VALUES clause even if earlier rows do not qualify. +# +reset_db +do_execsql_test 16.1 { + CREATE TABLE t1(a,b); +} +do_execsql_test 16.2 { + BEGIN; + INSERT INTO t1 VALUES(1,2),(3,4),(5,6), + (7,row_number()OVER()), + (9,10), (11,12), (13,14), (15,16); + SELECT * FROM t1 ORDER BY a, b; + ROLLBACK; +} {1 2 3 4 5 6 7 1 9 10 11 12 13 14 15 16} +do_eqp_test 16.3 { + INSERT INTO t1 VALUES(1,2),(3,4),(5,6), + (7,row_number()OVER()), + (9,10), (11,12), (13,14), (15,16); +} { + QUERY PLAN + `--COMPOUND QUERY + |--LEFT-MOST SUBQUERY + | `--SCAN 3-ROW VALUES CLAUSE + |--UNION ALL + | |--CO-ROUTINE (subquery-xxxxxx) + | | `--SCAN CONSTANT ROW + | `--SCAN (subquery-xxxxxx) + `--UNION ALL + `--SCAN 4-ROW VALUES CLAUSE +} +do_execsql_test 16.4 { + BEGIN; + INSERT INTO t1 VALUES + (1,row_number()OVER()), + (2,3), (4,5), (6,7); + SELECT * FROM t1 ORDER BY a, b; + ROLLBACK; +} {1 1 2 3 4 5 6 7} +do_eqp_test 16.5 { + INSERT INTO t1 VALUES + (1,row_number()OVER()), + (2,3), (4,5), (6,7); +} { + QUERY PLAN + `--COMPOUND QUERY + |--LEFT-MOST SUBQUERY + | |--CO-ROUTINE (subquery-xxxxxx) + | | `--SCAN CONSTANT ROW + | `--SCAN (subquery-xxxxxx) + `--UNION ALL + `--SCAN 3-ROW VALUES CLAUSE +} +do_execsql_test 16.6 { + BEGIN; + INSERT INTO t1 VALUES + (1,2),(3,4), + (5,row_number()OVER()), + (7,8),(9,10),(11,12), + (13,row_number()OVER()), + (15,16),(17,18),(19,20),(21,22); + SELECT * FROM t1 ORDER BY a, b; + ROLLBACK; +} { 1 2 3 4 5 1 7 8 9 10 11 12 13 1 15 16 17 18 19 20 21 22} +do_eqp_test 16.7 { + INSERT INTO t1 VALUES + (1,2),(3,4), + (5,row_number()OVER()), + (7,8),(9,10),(11,12), + (13,row_number()OVER()), + (15,16),(17,18),(19,20),(21,22); +} { + QUERY PLAN + `--COMPOUND QUERY + |--LEFT-MOST SUBQUERY + | `--SCAN 2-ROW VALUES CLAUSE + |--UNION ALL + | |--CO-ROUTINE (subquery-xxxxxx) + | | `--SCAN CONSTANT ROW + | `--SCAN (subquery-xxxxxx) + |--UNION ALL + | `--SCAN 3-ROW VALUES CLAUSE + |--UNION ALL + | |--CO-ROUTINE (subquery-xxxxxx) + | | `--SCAN CONSTANT ROW + | `--SCAN (subquery-xxxxxx) + `--UNION ALL + `--SCAN 4-ROW VALUES CLAUSE +} + +#-------------------------------------------------------------------------- +# 2024-03-23 dbsqlfuzz crash-c2c5e7e08b7e489d270a26d895077a03f678c33b +# +do_execsql_test 17.1 { + DROP TABLE IF EXISTS t1; + CREATE TABLE t1 AS SELECT * FROM (VALUES(1,2), (3,4 IN (1,2,3))); +} + +do_execsql_test 17.2 { + SELECT * FROM t1 +} {1 2 3 0} + +# 2024-03-25 dbsqlfuzz crash-74cf7c9904360322a6c917e4934b127543d1cd51 +# +do_catchsql_test 18.1 { + DROP TABLE t1; + CREATE TABLE t1(x INTEGER PRIMARY KEY); + INSERT INTO t1 VALUES(RAISE(IGNORE)),(0); +} {1 {RAISE() may only be used within a trigger-program}} +do_catchsql_test 18.2 { + DROP TABLE t1; + CREATE TABLE t1(x INTEGER PRIMARY KEY, y, z); + CREATE TRIGGER r2 AFTER INSERT ON t1 BEGIN + INSERT INTO t1(y) VALUES(RAISE(IGNORE)),(0); + END; + INSERT INTO t1 VALUES(1,2,3); + SELECT * FROM t1; +} {0 {1 2 3}} +do_catchsql_test 18.3.1 { + DROP TABLE t1; + CREATE TABLE t1(x INTEGER PRIMARY KEY, y, z); + CREATE TRIGGER r2 AFTER INSERT ON t1 BEGIN + INSERT INTO t1(y) VALUES(RAISE(ABORT,'error 18.3')),(0); + END; + INSERT INTO t1 VALUES(1,2,3); +} {1 {error 18.3}} +do_execsql_test 18.3.2 { + SELECT * FROM t1; +} {} +do_catchsql_test 18.4.1 { + DROP TABLE t1; + CREATE TABLE t1(x INTEGER PRIMARY KEY, y, z); + CREATE TRIGGER r2 AFTER INSERT ON t1 BEGIN + INSERT INTO t1(y) VALUES(1),(RAISE(ABORT,'error 18.4')),(0); + END; + INSERT INTO t1 VALUES(1,2,3); +} {1 {error 18.4}} +do_execsql_test 18.4.2 { + SELECT * FROM t1; +} {} +do_catchsql_test 18.5.1 { + DROP TABLE t1; + CREATE TABLE t1(x INTEGER PRIMARY KEY, y, z); + CREATE TRIGGER r2 AFTER INSERT ON t1 BEGIN + INSERT INTO t1(y) VALUES(1), + (CASE WHEN new.z>7 THEN RAISE(ABORT,'error 18.5') ELSE 2 END); + END; + INSERT INTO t1 VALUES(1,2,3); + SELECT * FROM t1; +} {0 {1 2 3 2 1 {} 3 2 {}}} +do_catchsql_test 18.5.2 { + DELETE FROM t1; + INSERT INTO t1 VALUES(1,2,13); +} {1 {error 18.5}} +do_catchsql_test 18.5.3 { + SELECT * FROM t1; +} {0 {}} + +# 2024-04-18 dbsqlfuzz crash-bde3bf80aedf25afa56e2997a0545a314765d3f8 +# Verify that the VALUES expressions used as an argument to an outer +# join work correctly. +# +reset_db +db null NULL +do_execsql_test 19.1 { + CREATE TABLE t1(a INT, b INT); + INSERT INTO t1 VALUES(11,22); + SELECT * FROM t1 LEFT JOIN (VALUES(33,44),(55,66)) AS t2 ON a=b; +} {11 22 NULL NULL} +do_execsql_test 19.2 { + SELECT * FROM (VALUES(33,44),(55,66)) AS t2 RIGHT JOIN t1 ON a=b; +} {NULL NULL 11 22} +do_execsql_test 19.3 { + SELECT *, '|' FROM t1 FULL JOIN (VALUES(33,44),(55,66)) AS t2 ON a=b + ORDER BY +column1 +} {11 22 NULL NULL | NULL NULL 33 44 | NULL NULL 55 66 |} +do_execsql_test 19.4 { + SELECT *, '|' FROM (VALUES(33,44),(55,66)) AS t2 FULL JOIN t1 ON a=b + ORDER BY +column1 +} {NULL NULL 11 22 | 33 44 NULL NULL | 55 66 NULL NULL |} + +# 2024-04-21 dbsqlfuzz 6fd1ff3a64bef4a6c092e8d757548e95698b0df5 +# A continuation of the 2024-04-18 problem above. We have to create +# Pseudo-cursor that is always NULL on the viaCoroutine loop in case +# there are OP_Columns generated against it by the sub-WHERE clause. +# +db null N +do_execsql_test 19.5 { + DROP TABLE IF EXISTS t1; + DROP TABLE IF EXISTS t2; + DROP TABLE IF EXISTS t3; + CREATE TABLE t1(a,b); INSERT INTO t1 VALUES(1,2); + CREATE TABLE t2(column1,column2); INSERT INTO t2 VALUES(11,22),(33,44); + CREATE TABLE t3(d,e); INSERT INTO t3 VALUES(3,4); +} +do_execsql_test 19.6 { + -- output verify using PG 14.2 + SELECT * + FROM t1 CROSS JOIN t2 FULL JOIN t3 ON a=d + ORDER BY +d, +column1; +} {1 2 11 22 N N + 1 2 33 44 N N + N N N N 3 4} +do_execsql_test 19.7 { + SELECT * + FROM t1 CROSS JOIN (VALUES(11,22),(33,44)) FULL JOIN t3 ON a=d + ORDER BY +d, +column1; +} {1 2 11 22 N N + 1 2 33 44 N N + N N N N 3 4} +do_execsql_test 19.8 { + -- output verified using PG 14.2 + SELECT * + FROM t1 CROSS JOIN t2 FULL JOIN t3 ON a=d + WHERE column1 IS NULL; +} {N N N N 3 4} +do_execsql_test 19.9 { + SELECT * + FROM t1 CROSS JOIN (VALUES(11,22),(33,44)) FULL JOIN t3 ON a=d + WHERE column1 IS NULL; +} {N N N N 3 4} + +finish_test diff --git a/test/valuesfault.test b/test/valuesfault.test new file mode 100644 index 0000000..bc5dddf --- /dev/null +++ b/test/valuesfault.test @@ -0,0 +1,37 @@ +# 2024 March 3 +# +# 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. +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set testprefix valuesfault +source $testdir/malloc_common.tcl + + +do_execsql_test 1.0 { + CREATE TABLE x1(a, b, c); +} +faultsim_save_and_close + +do_faultsim_test 1 -prep { + faultsim_restore_and_reopen + sqlite3_limit db SQLITE_LIMIT_COMPOUND_SELECT 2 +} -body { + execsql { + INSERT INTO x1 VALUES(1, 1, 1), (2, 2, 2), (3, 3, 3), (4, 4, 4); + } +} -test { + faultsim_test_result {0 {}} +} + + +finish_test diff --git a/test/view.test b/test/view.test index 90c9c99..2417420 100644 --- a/test/view.test +++ b/test/view.test @@ -801,4 +801,27 @@ ifcapable schema_pragmas { } { 0 a INT 0 {} 0 1 b BLOB 0 {} 0 } } +#----------------------------------------------------------------------- +# 2024-04-25 Trying to make type information on compound subqueries +# more predictable and rational. +# +reset_db +do_execsql_test view-31.1 { + CREATE TABLE x2(b TEXT); + CREATE TABLE x1(a TEXT); + INSERT INTO x1 VALUES('123'); + -- Two queries get the same result even though the order of terms + -- in the CTE is reversed + WITH c(x) AS ( SELECT b FROM x2 UNION SELECT 123 ) + SELECT count(*) FROM x1 WHERE a IN c; + WITH c(x) AS ( SELECT 123 UNION SELECT b FROM x2 ) + SELECT count(*) FROM x1 WHERE a IN c; +} {0 0} +do_execsql_test view-31.2 { + CREATE TABLE t3(a INTEGER, b TEXT); + INSERT INTO t3 VALUES(123, 123); + WITH s AS ( VALUES(123), (456) ) SELECT * FROM t3 WHERE b IN s; +} {123 123} + + finish_test diff --git a/test/vtabL.test b/test/vtabL.test new file mode 100644 index 0000000..45528ed --- /dev/null +++ b/test/vtabL.test @@ -0,0 +1,75 @@ +# 2024-03-26 +# +# 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. +# +#*********************************************************************** +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set testprefix vtabL + +ifcapable !vtab { + finish_test + return +} + +register_tcl_module db + +proc vtab_command {method args} { + switch -- $method { + xConnect { + return $::create_table_sql + } + } + + return {} +} + +foreach {tn cts} { + 1 {SELECT 123} + 2 {SELECT 123, 456} + 3 {INSERT INTO t1 VALUES(5, 6)} + 4 {CREATE INDEX i1 ON t1(a)} + 5 {CREATE TRIGGER tr1 AFTER INSERT ON t1 BEGIN SELECT 1; END;} + 6 {DROP TABLE nosuchtable} + 7 {DROP TABLE x1} + 8 {DROP TABLE t1} +} { + set ::create_table_sql $cts + do_catchsql_test 1.$tn { + CREATE VIRTUAL TABLE x1 USING tcl(vtab_command); + } {1 {declare_vtab: syntax error}} +} + +foreach {tn cts} { + 9 {CREATE TABLE xyz AS SELECT * FROM sqlite_schema} + 10 {CREATE TABLE xyz AS SELECT 1 AS 'col'} +} { + set ::create_table_sql $cts + do_catchsql_test 1.$tn { + CREATE VIRTUAL TABLE x1 USING tcl(vtab_command); + } {1 {declare_vtab: SQL logic error}} +} + +foreach {tn cts} { + 1 {CREATE TABLE IF NOT EXISTS t1(a, b)} + 2 {CREATE TABLE ""(a, b PRIMARY KEY) WITHOUT ROWID} +} { + set ::create_table_sql $cts + execsql { DROP TABLE IF EXISTS x1 } + do_execsql_test 2.$tn.1 { + CREATE VIRTUAL TABLE x1 USING tcl(vtab_command); + } + do_execsql_test 2.$tn.2 { + SELECT a, b FROM x1 + } +} + +finish_test + diff --git a/test/whereL.test b/test/whereL.test index c3bdcb8..2e9ae21 100644 --- a/test/whereL.test +++ b/test/whereL.test @@ -49,6 +49,33 @@ do_eqp_test 120 { |--SEARCH t2 USING INDEX sqlite_autoindex_t2_1 (a=?) `--SCAN t3 } +do_eqp_test 121 { + SELECT * FROM t1, t2, t3 + WHERE t1.a=t2.a AND t2.a=t3.j AND t3.j=abs(5) + ORDER BY t1.a; +} { + QUERY PLAN + |--SEARCH t1 USING INDEX sqlite_autoindex_t1_1 (a=?) + |--SEARCH t2 USING INDEX sqlite_autoindex_t2_1 (a=?) + `--SCAN t3 +} + +# The sqlite3ExprIsConstant() routine does not believe that +# the expression "coalesce(5,random())" is constant. So the +# optimization does not apply in this case. +# +sqlite3_create_function db +do_eqp_test 122 { + SELECT * FROM t1, t2, t3 + WHERE t1.a=t2.a AND t2.a=t3.j AND t3.j=coalesce(5,random()) + ORDER BY t1.a; +} { + QUERY PLAN + |--SCAN t3 + |--SEARCH t1 USING INDEX sqlite_autoindex_t1_1 (a=?) + |--SEARCH t2 USING INDEX sqlite_autoindex_t2_1 (a=?) + `--USE TEMP B-TREE FOR ORDER BY +} # Constant propagation in the face of collating sequences: # @@ -209,4 +236,22 @@ do_eqp_test 710 { `--SEARCH t1 USING INDEX idx (<expr>=?) } +# 2024-03-07 https://sqlite.org/forum/forumpost/ecdfc02339 +# A refinement is needed to the enhancements tested by the prior test case +# to avoid another problem with indexes on constant expressions. +# +reset_db +db null NULL +do_execsql_test 800 { + CREATE TABLE t0(c0, c1); + CREATE TABLE t1(c2); + CREATE INDEX i0 ON t1(NULL); + INSERT INTO t1(c2) VALUES (0.2); + CREATE VIEW v0(c3) AS SELECT DISTINCT c2 FROM t1; + SELECT * FROM v0 LEFT JOIN t0 ON c3<NULL LEFT JOIN t1 ON 1; +} {0.2 NULL NULL 0.2} +do_execsql_test 810 { + SELECT * FROM v0 LEFT JOIN t0 ON c3<NULL LEFT JOIN t1 ON 1 WHERE c2/0.1; +} {0.2 NULL NULL 0.2} + finish_test diff --git a/test/whereN.test b/test/whereN.test new file mode 100644 index 0000000..b9b889f --- /dev/null +++ b/test/whereN.test @@ -0,0 +1,103 @@ +# 2024-04-02 +# +# 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. +# +#*********************************************************************** +# Tests for the whereInterstageHeuristic() routine in the query planner. +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set testprefix whereN + +# The following is a simplified and "sanitized" version of the original +# real-world query that brought the problem to light. +# +# The issue is a slow query. The answer is correct, but it was taking too +# much time, because it was doing a full table scan rather than an indexed +# lookup. +# +# The problem was that the query planner was overestimating the number of +# output rows. The estimated number of output rows is accurate if the +# DSNAME parameter is "ds-one". In that case, a large fraction of the rows +# in "violation" end up being output. The query planner correctly deduces +# that it is faster to do a full table scan of the large "violation" table +# to avoid the after-query sort that implements the ORDER BY clause. However, +# if the DSNAME is "ds-two", then only a few rows (about 6) are generated, +# and it is much much faster to do an indexed lookup of "violation" followed +# by a sort operation to implement ORDER BY +# +# The problem, of course, is that the query planner has no way of knowing +# in advance how many rows will be generated. The query planner tries to +# estimate a worst case, which is a large number of output rows, and it picks +# the best plan for that case. However, the plan choosen is very inefficient +# when the number of output rows is small. +# +# The whereInterstageHeuristic() routine in the query planner attempts to +# correct this by adjusting the query plan such that it avoids the very bad +# query plan for a small number of rows, at the expense of a slightly less +# efficient plan for a large number of rows. The large number of rows case +# is perhaps 5% slower with the revised plan, but the small number of +# rows case is around 100 times faster. That seems like a good tradeoff. +# +do_execsql_test 1.0 { + CREATE TABLE datasource(dsid INT, name TEXT); + INSERT INTO datasource VALUES(1,'ds-one'),(2,'ds-two'),(3,'ds-three'); + CREATE INDEX ds1 ON datasource(name, dsid); + + CREATE TABLE rule(rid INT, team_id INT, dsid INT); + WITH RECURSIVE c(n) AS (VALUES(1) UNION ALL SELECT n+1 FROM c WHERE n<9) + INSERT INTO rule(rid,team_id,dsid) SELECT n, 1, 1 FROM c; + WITH RECURSIVE c(n) AS (VALUES(10) UNION ALL SELECT n+1 FROM c WHERE n<24) + INSERT INTO rule(rid,team_id,dsid) SELECT n, 2, 2 FROM c; + CREATE INDEX rule2 ON rule(dsid, rid); + + CREATE TABLE violation(vid INT, rid INT, vx BLOB); + /*** Uncomment to insert actual data + WITH src(rid, cnt) AS (VALUES(1,3586),(2,1343),(3,6505),(5,76230), + (6,740),(7,287794),(8,457),(12,1), + (14,1),(16,1),(17,1),(18,1),(19,1)) + INSERT INTO violation(vid, rid, vx) + SELECT rid*1000000+value, rid, randomblob(15) + FROM src, generate_series(1,cnt); + ***/ + CREATE INDEX v1 ON violation(rid, vid); + CREATE INDEX v2 ON violation(vid); + ANALYZE; + DELETE FROM sqlite_stat1; + DROP TABLE IF EXISTS sqlite_stat4; + INSERT INTO sqlite_stat1 VALUES + ('violation','v2','376661 1'), + ('violation','v1','376661 28974 1'), + ('rule','rule2','24 12 1'), + ('datasource','ds1','3 1 1'); + ANALYZE sqlite_schema; +} +set DSNAME ds-two ;# Only a few rows. Change to "ds-one" for many rows. +do_eqp_test 1.1 { + SELECT count(*), length(group_concat(vx)) FROM ( + SELECT V.* + FROM datasource DS, rule R, violation V + WHERE V.rid=R.rid + AND R.dsid=DS.dsid + AND DS.name=$DSNAME + ORDER BY V.vid desc + ); +} { + QUERY PLAN + |--CO-ROUTINE (subquery-xxxxxx) + | |--SEARCH DS USING COVERING INDEX ds1 (name=?) + | |--SEARCH R USING COVERING INDEX rule2 (dsid=?) + | |--SEARCH V USING INDEX v1 (rid=?) + | `--USE TEMP B-TREE FOR ORDER BY + `--SCAN (subquery-xxxxxx) +} +# ^^^^---- We want to see three SEARCH terms. No SCAN terms. +# The ORDER BY is implemented by a separate sorter pass. + +finish_test diff --git a/tool/lemon.c b/tool/lemon.c index 7804837..06b9109 100644 --- a/tool/lemon.c +++ b/tool/lemon.c @@ -60,6 +60,82 @@ static char *msort(char*,char**,int(*)(const char*,const char*)); #define lemonStrlen(X) ((int)strlen(X)) /* +** Header on the linked list of memory allocations. +*/ +typedef struct MemChunk MemChunk; +struct MemChunk { + MemChunk *pNext; + size_t sz; + /* Actually memory follows */ +}; + +/* +** Global linked list of all memory allocations. +*/ +static MemChunk *memChunkList = 0; + +/* +** Wrappers around malloc(), calloc(), realloc() and free(). +** +** All memory allocations are kept on a doubly-linked list. The +** lemon_free_all() function can be called prior to exit to clean +** up any memory leaks. +** +** This is not necessary. But compilers and getting increasingly +** fussy about memory leaks, even in command-line programs like Lemon +** where they do not matter. So this code is provided to hush the +** warnings. +*/ +static void *lemon_malloc(size_t nByte){ + MemChunk *p; + if( nByte<0 ) return 0; + p = malloc( nByte + sizeof(MemChunk) ); + if( p==0 ){ + fprintf(stderr, "Out of memory. Failed to allocate %lld bytes.\n", + (long long int)nByte); + exit(1); + } + p->pNext = memChunkList; + p->sz = nByte; + memChunkList = p; + return (void*)&p[1]; +} +static void *lemon_calloc(size_t nElem, size_t sz){ + void *p = lemon_malloc(nElem*sz); + memset(p, 0, nElem*sz); + return p; +} +static void lemon_free(void *pOld){ + if( pOld ){ + MemChunk *p = (MemChunk*)pOld; + p--; + memset(pOld, 0, p->sz); + } +} +static void *lemon_realloc(void *pOld, size_t nNew){ + void *pNew; + MemChunk *p; + if( pOld==0 ) return lemon_malloc(nNew); + p = (MemChunk*)pOld; + p--; + if( p->sz>=nNew ) return pOld; + pNew = lemon_malloc( nNew ); + memcpy(pNew, pOld, p->sz); + return pNew; +} + +/* Free all outstanding memory allocations. +** Do this right before exiting. +*/ +static void lemon_free_all(void){ + while( memChunkList ){ + MemChunk *pNext = memChunkList->pNext; + free( memChunkList ); + memChunkList = pNext; + } +} + +/* ** Compilers are starting to complain about the use of sprintf() and strcpy(), ** saying they are unsafe. So we define our own versions of those routines too. ** @@ -418,6 +494,8 @@ struct lemon { char *filename; /* Name of the input file */ char *outname; /* Name of the current output file */ char *tokenprefix; /* A prefix added to token names in the .h file */ + char *reallocFunc; /* Function to use to allocate stack space */ + char *freeFunc; /* Function to use to free stack space */ int nconflict; /* Number of parsing conflicts */ int nactiontab; /* Number of entries in the yy_action[] table */ int nlookaheadtab; /* Number of entries in yy_lookahead[] */ @@ -495,7 +573,7 @@ static struct action *Action_new(void){ if( actionfreelist==0 ){ int i; int amt = 100; - actionfreelist = (struct action *)calloc(amt, sizeof(struct action)); + actionfreelist = (struct action *)lemon_calloc(amt, sizeof(struct action)); if( actionfreelist==0 ){ fprintf(stderr,"Unable to allocate memory for a new parser action."); exit(1); @@ -614,14 +692,14 @@ struct acttab { /* Free all memory associated with the given acttab */ void acttab_free(acttab *p){ - free( p->aAction ); - free( p->aLookahead ); - free( p ); + lemon_free( p->aAction ); + lemon_free( p->aLookahead ); + lemon_free( p ); } /* Allocate a new acttab structure */ acttab *acttab_alloc(int nsymbol, int nterminal){ - acttab *p = (acttab *) calloc( 1, sizeof(*p) ); + acttab *p = (acttab *) lemon_calloc( 1, sizeof(*p) ); if( p==0 ){ fprintf(stderr,"Unable to allocate memory for a new acttab."); exit(1); @@ -640,7 +718,7 @@ acttab *acttab_alloc(int nsymbol, int nterminal){ void acttab_action(acttab *p, int lookahead, int action){ if( p->nLookahead>=p->nLookaheadAlloc ){ p->nLookaheadAlloc += 25; - p->aLookahead = (struct lookahead_action *) realloc( p->aLookahead, + p->aLookahead = (struct lookahead_action *) lemon_realloc( p->aLookahead, sizeof(p->aLookahead[0])*p->nLookaheadAlloc ); if( p->aLookahead==0 ){ fprintf(stderr,"malloc failed\n"); @@ -690,7 +768,7 @@ int acttab_insert(acttab *p, int makeItSafe){ if( p->nAction + n >= p->nActionAlloc ){ int oldAlloc = p->nActionAlloc; p->nActionAlloc = p->nAction + n + p->nActionAlloc + 20; - p->aAction = (struct lookahead_action *) realloc( p->aAction, + p->aAction = (struct lookahead_action *) lemon_realloc( p->aAction, sizeof(p->aAction[0])*p->nActionAlloc); if( p->aAction==0 ){ fprintf(stderr,"malloc failed\n"); @@ -1312,7 +1390,7 @@ static struct config **basisend = 0; /* End of list of basis configs */ /* Return a pointer to a new configuration */ PRIVATE struct config *newconfig(void){ - return (struct config*)calloc(1, sizeof(struct config)); + return (struct config*)lemon_calloc(1, sizeof(struct config)); } /* The configuration "old" is no longer used */ @@ -1528,19 +1606,19 @@ static char *bDefineUsed = 0; /* True for every -D macro actually used */ static void handle_D_option(char *z){ char **paz; nDefine++; - azDefine = (char **) realloc(azDefine, sizeof(azDefine[0])*nDefine); + azDefine = (char **) lemon_realloc(azDefine, sizeof(azDefine[0])*nDefine); if( azDefine==0 ){ fprintf(stderr,"out of memory\n"); exit(1); } - bDefineUsed = (char*)realloc(bDefineUsed, nDefine); + bDefineUsed = (char*)lemon_realloc(bDefineUsed, nDefine); if( bDefineUsed==0 ){ fprintf(stderr,"out of memory\n"); exit(1); } bDefineUsed[nDefine-1] = 0; paz = &azDefine[nDefine-1]; - *paz = (char *) malloc( lemonStrlen(z)+1 ); + *paz = (char *) lemon_malloc( lemonStrlen(z)+1 ); if( *paz==0 ){ fprintf(stderr,"out of memory\n"); exit(1); @@ -1554,7 +1632,7 @@ static void handle_D_option(char *z){ */ static char *outputDir = NULL; static void handle_d_option(char *z){ - outputDir = (char *) malloc( lemonStrlen(z)+1 ); + outputDir = (char *) lemon_malloc( lemonStrlen(z)+1 ); if( outputDir==0 ){ fprintf(stderr,"out of memory\n"); exit(1); @@ -1564,7 +1642,7 @@ static void handle_d_option(char *z){ static char *user_templatename = NULL; static void handle_T_option(char *z){ - user_templatename = (char *) malloc( lemonStrlen(z)+1 ); + user_templatename = (char *) lemon_malloc( lemonStrlen(z)+1 ); if( user_templatename==0 ){ memory_error(); } @@ -1801,6 +1879,7 @@ int main(int argc, char **argv){ /* return 0 on success, 1 on failure. */ exitcode = ((lem.errorcnt > 0) || (lem.nconflict > 0)) ? 1 : 0; + lemon_free_all(); exit(exitcode); return (exitcode); } @@ -2389,7 +2468,7 @@ static void parseonetoken(struct pstate *psp) case IN_RHS: if( x[0]=='.' ){ struct rule *rp; - rp = (struct rule *)calloc( sizeof(struct rule) + + rp = (struct rule *)lemon_calloc( sizeof(struct rule) + sizeof(struct symbol*)*psp->nrhs + sizeof(char*)*psp->nrhs, 1); if( rp==0 ){ ErrorMsg(psp->filename,psp->tokenlineno, @@ -2441,17 +2520,17 @@ static void parseonetoken(struct pstate *psp) struct symbol *msp = psp->rhs[psp->nrhs-1]; if( msp->type!=MULTITERMINAL ){ struct symbol *origsp = msp; - msp = (struct symbol *) calloc(1,sizeof(*msp)); + msp = (struct symbol *) lemon_calloc(1,sizeof(*msp)); memset(msp, 0, sizeof(*msp)); msp->type = MULTITERMINAL; msp->nsubsym = 1; - msp->subsym = (struct symbol **) calloc(1,sizeof(struct symbol*)); + msp->subsym = (struct symbol**)lemon_calloc(1,sizeof(struct symbol*)); msp->subsym[0] = origsp; msp->name = origsp->name; psp->rhs[psp->nrhs-1] = msp; } msp->nsubsym++; - msp->subsym = (struct symbol **) realloc(msp->subsym, + msp->subsym = (struct symbol **) lemon_realloc(msp->subsym, sizeof(struct symbol*)*msp->nsubsym); msp->subsym[msp->nsubsym-1] = Symbol_new(&x[1]); if( ISLOWER(x[1]) || ISLOWER(msp->subsym[0]->name[0]) ){ @@ -2531,6 +2610,12 @@ static void parseonetoken(struct pstate *psp) }else if( strcmp(x,"default_type")==0 ){ psp->declargslot = &(psp->gp->vartype); psp->insertLineMacro = 0; + }else if( strcmp(x,"realloc")==0 ){ + psp->declargslot = &(psp->gp->reallocFunc); + psp->insertLineMacro = 0; + }else if( strcmp(x,"free")==0 ){ + psp->declargslot = &(psp->gp->freeFunc); + psp->insertLineMacro = 0; }else if( strcmp(x,"stack_size")==0 ){ psp->declargslot = &(psp->gp->stacksize); psp->insertLineMacro = 0; @@ -2661,7 +2746,7 @@ static void parseonetoken(struct pstate *psp) nLine = lemonStrlen(zLine); n += nLine + lemonStrlen(psp->filename) + nBack; } - *psp->declargslot = (char *) realloc(*psp->declargslot, n); + *psp->declargslot = (char *) lemon_realloc(*psp->declargslot, n); zBuf = *psp->declargslot + nOld; if( addLineMacro ){ if( nOld && zBuf[-1]!='\n' ){ @@ -2775,7 +2860,7 @@ static void parseonetoken(struct pstate *psp) }else if( ISUPPER(x[0]) || ((x[0]=='|' || x[0]=='/') && ISUPPER(x[1])) ){ struct symbol *msp = psp->tkclass; msp->nsubsym++; - msp->subsym = (struct symbol **) realloc(msp->subsym, + msp->subsym = (struct symbol **) lemon_realloc(msp->subsym, sizeof(struct symbol*)*msp->nsubsym); if( !ISUPPER(x[0]) ) x++; msp->subsym[msp->nsubsym-1] = Symbol_new(x); @@ -2990,10 +3075,10 @@ void Parse(struct lemon *gp) fseek(fp,0,2); filesize = ftell(fp); rewind(fp); - filebuf = (char *)malloc( filesize+1 ); + filebuf = (char *)lemon_malloc( filesize+1 ); if( filesize>100000000 || filebuf==0 ){ ErrorMsg(ps.filename,0,"Input file too large."); - free(filebuf); + lemon_free(filebuf); gp->errorcnt++; fclose(fp); return; @@ -3001,7 +3086,7 @@ void Parse(struct lemon *gp) if( fread(filebuf,1,filesize,fp)!=filesize ){ ErrorMsg(ps.filename,0,"Can't read in all %d bytes of this file.", filesize); - free(filebuf); + lemon_free(filebuf); gp->errorcnt++; fclose(fp); return; @@ -3113,7 +3198,7 @@ void Parse(struct lemon *gp) *cp = (char)c; /* Restore the buffer */ cp = nextcp; } - free(filebuf); /* Release the buffer after parsing */ + lemon_free(filebuf); /* Release the buffer after parsing */ gp->rule = ps.firstrule; gp->errorcnt = ps.errorcnt; } @@ -3131,7 +3216,7 @@ struct plink *Plink_new(void){ if( plink_freelist==0 ){ int i; int amt = 100; - plink_freelist = (struct plink *)calloc( amt, sizeof(struct plink) ); + plink_freelist = (struct plink *)lemon_calloc( amt, sizeof(struct plink) ); if( plink_freelist==0 ){ fprintf(stderr, "Unable to allocate memory for a new follow-set propagation link.\n"); @@ -3184,9 +3269,7 @@ void Plink_delete(struct plink *plp) ** Procedures for generating reports and tables in the LEMON parser generator. */ -/* Generate a filename with the given suffix. Space to hold the -** name comes from malloc() and must be freed by the calling -** function. +/* Generate a filename with the given suffix. */ PRIVATE char *file_makename(struct lemon *lemp, const char *suffix) { @@ -3203,7 +3286,7 @@ PRIVATE char *file_makename(struct lemon *lemp, const char *suffix) sz += lemonStrlen(suffix); if( outputDir ) sz += lemonStrlen(outputDir) + 1; sz += 5; - name = (char*)malloc( sz ); + name = (char*)lemon_malloc( sz ); if( name==0 ){ fprintf(stderr,"Can't allocate space for a filename.\n"); exit(1); @@ -3230,7 +3313,7 @@ PRIVATE FILE *file_open( ){ FILE *fp; - if( lemp->outname ) free(lemp->outname); + if( lemp->outname ) lemon_free(lemp->outname); lemp->outname = file_makename(lemp, suffix); fp = fopen(lemp->outname,mode); if( fp==0 && *mode=='w' ){ @@ -3546,14 +3629,14 @@ PRIVATE char *pathsearch(char *argv0, char *name, int modemask) if( cp ){ c = *cp; *cp = 0; - path = (char *)malloc( lemonStrlen(argv0) + lemonStrlen(name) + 2 ); + path = (char *)lemon_malloc( lemonStrlen(argv0) + lemonStrlen(name) + 2 ); if( path ) lemon_sprintf(path,"%s/%s",argv0,name); *cp = c; }else{ pathlist = getenv("PATH"); if( pathlist==0 ) pathlist = ".:/bin:/usr/bin"; - pathbuf = (char *) malloc( lemonStrlen(pathlist) + 1 ); - path = (char *)malloc( lemonStrlen(pathlist)+lemonStrlen(name)+2 ); + pathbuf = (char *) lemon_malloc( lemonStrlen(pathlist) + 1 ); + path = (char *)lemon_malloc( lemonStrlen(pathlist)+lemonStrlen(name)+2 ); if( (pathbuf != 0) && (path!=0) ){ pathbufptr = pathbuf; lemon_strcpy(pathbuf, pathlist); @@ -3569,7 +3652,7 @@ PRIVATE char *pathsearch(char *argv0, char *name, int modemask) if( access(path,modemask)==0 ) break; } } - free(pathbufptr); + lemon_free(pathbufptr); } return path; } @@ -3700,7 +3783,7 @@ PRIVATE FILE *tplt_open(struct lemon *lemp) fprintf(stderr,"Can't open the template file \"%s\".\n",tpltname); lemp->errorcnt++; } - free(toFree); + lemon_free(toFree); return in; } @@ -3829,7 +3912,7 @@ PRIVATE char *append_str(const char *zText, int n, int p1, int p2){ } if( (int) (n+sizeof(zInt)*2+used) >= alloced ){ alloced = n + sizeof(zInt)*2 + used + 200; - z = (char *) realloc(z, alloced); + z = (char *) lemon_realloc(z, alloced); } if( z==0 ) return empty; while( n-- > 0 ){ @@ -4119,7 +4202,7 @@ void print_stack_union( /* Allocate and initialize types[] and allocate stddt[] */ arraysize = lemp->nsymbol * 2; - types = (char**)calloc( arraysize, sizeof(char*) ); + types = (char**)lemon_calloc( arraysize, sizeof(char*) ); if( types==0 ){ fprintf(stderr,"Out of memory.\n"); exit(1); @@ -4136,7 +4219,7 @@ void print_stack_union( len = lemonStrlen(sp->datatype); if( len>maxdtlength ) maxdtlength = len; } - stddt = (char*)malloc( maxdtlength*2 + 1 ); + stddt = (char*)lemon_malloc( maxdtlength*2 + 1 ); if( stddt==0 ){ fprintf(stderr,"Out of memory.\n"); exit(1); @@ -4185,7 +4268,7 @@ void print_stack_union( } if( types[hash]==0 ){ sp->dtnum = hash + 1; - types[hash] = (char*)malloc( lemonStrlen(stddt)+1 ); + types[hash] = (char*)lemon_malloc( lemonStrlen(stddt)+1 ); if( types[hash]==0 ){ fprintf(stderr,"Out of memory.\n"); exit(1); @@ -4207,13 +4290,13 @@ void print_stack_union( for(i=0; i<arraysize; i++){ if( types[i]==0 ) continue; fprintf(out," %s yy%d;\n",types[i],i+1); lineno++; - free(types[i]); + lemon_free(types[i]); } if( lemp->errsym && lemp->errsym->useCnt ){ fprintf(out," int yy%d;\n",lemp->errsym->dtnum); lineno++; } - free(stddt); - free(types); + lemon_free(stddt); + lemon_free(types); fprintf(out,"} YYMINORTYPE;\n"); lineno++; *plineno = lineno; } @@ -4309,7 +4392,7 @@ void ReportTable( struct action *ap; struct rule *rp; struct acttab *pActtab; - int i, j, n, sz; + int i, j, n, sz, mn, mx; int nLookAhead; int szActionType; /* sizeof(YYACTIONTYPE) */ int szCodeType; /* sizeof(YYCODETYPE) */ @@ -4442,7 +4525,7 @@ void ReportTable( if( mhflag ){ char *incName = file_makename(lemp, ".h"); fprintf(out,"#include \"%s\"\n", incName); lineno++; - free(incName); + lemon_free(incName); } tplt_xfer(lemp->name,in,out,&lineno); @@ -4501,6 +4584,21 @@ void ReportTable( fprintf(out,"#define %sARG_FETCH\n",name); lineno++; fprintf(out,"#define %sARG_STORE\n",name); lineno++; } + if( lemp->reallocFunc ){ + fprintf(out,"#define YYREALLOC %s\n", lemp->reallocFunc); lineno++; + }else{ + fprintf(out,"#define YYREALLOC realloc\n"); lineno++; + } + if( lemp->freeFunc ){ + fprintf(out,"#define YYFREE %s\n", lemp->freeFunc); lineno++; + }else{ + fprintf(out,"#define YYFREE free\n"); lineno++; + } + if( lemp->reallocFunc && lemp->freeFunc ){ + fprintf(out,"#define YYDYNSTACK 1\n"); lineno++; + }else{ + fprintf(out,"#define YYDYNSTACK 0\n"); lineno++; + } if( lemp->ctx && lemp->ctx[0] ){ i = lemonStrlen(lemp->ctx); while( i>=1 && ISSPACE(lemp->ctx[i-1]) ) i--; @@ -4534,7 +4632,7 @@ void ReportTable( ** table must be computed before generating the YYNSTATE macro because ** we need to know how many states can be eliminated. */ - ax = (struct axset *) calloc(lemp->nxstate*2, sizeof(ax[0])); + ax = (struct axset *) lemon_calloc(lemp->nxstate*2, sizeof(ax[0])); if( ax==0 ){ fprintf(stderr,"malloc failed\n"); exit(1); @@ -4592,7 +4690,7 @@ void ReportTable( } #endif } - free(ax); + lemon_free(ax); /* Mark rules that are actually used for reduce actions after all ** optimizations have been applied @@ -4624,6 +4722,22 @@ void ReportTable( fprintf(out,"#define YY_MIN_REDUCE %d\n", lemp->minReduce); lineno++; i = lemp->minReduce + lemp->nrule; fprintf(out,"#define YY_MAX_REDUCE %d\n", i-1); lineno++; + + /* Minimum and maximum token values that have a destructor */ + mn = mx = 0; + for(i=0; i<lemp->nsymbol; i++){ + struct symbol *sp = lemp->symbols[i]; + + if( sp && sp->type!=TERMINAL && sp->destructor ){ + if( mn==0 || sp->index<mn ) mn = sp->index; + if( sp->index>mx ) mx = sp->index; + } + } + if( lemp->tokendest ) mn = 0; + if( lemp->vardest ) mx = lemp->nsymbol-1; + fprintf(out,"#define YY_MIN_DSTRCTR %d\n", mn); lineno++; + fprintf(out,"#define YY_MAX_DSTRCTR %d\n", mx); lineno++; + tplt_xfer(lemp->name,in,out,&lineno); /* Now output the action table and its associates: @@ -4767,7 +4881,7 @@ void ReportTable( /* Generate the table of fallback tokens. */ if( lemp->has_fallback ){ - int mx = lemp->nterminal - 1; + mx = lemp->nterminal - 1; /* 2019-08-28: Generate fallback entries for every token to avoid ** having to do a range check on the index */ /* while( mx>0 && lemp->symbols[mx]->fallback==0 ){ mx--; } */ @@ -5202,7 +5316,7 @@ void SetSize(int n) /* Allocate a new set */ char *SetNew(void){ char *s; - s = (char*)calloc( size, 1); + s = (char*)lemon_calloc( size, 1); if( s==0 ){ memory_error(); } @@ -5212,7 +5326,7 @@ char *SetNew(void){ /* Deallocate a set */ void SetFree(char *s) { - free(s); + lemon_free(s); } /* Add a new element to the set. Return TRUE if the element was added @@ -5271,7 +5385,7 @@ const char *Strsafe(const char *y) if( y==0 ) return 0; z = Strsafe_find(y); - if( z==0 && (cpy=(char *)malloc( lemonStrlen(y)+1 ))!=0 ){ + if( z==0 && (cpy=(char *)lemon_malloc( lemonStrlen(y)+1 ))!=0 ){ lemon_strcpy(cpy,y); z = cpy; Strsafe_insert(z); @@ -5307,13 +5421,13 @@ static struct s_x1 *x1a; /* Allocate a new associative array */ void Strsafe_init(void){ if( x1a ) return; - x1a = (struct s_x1*)malloc( sizeof(struct s_x1) ); + x1a = (struct s_x1*)lemon_malloc( sizeof(struct s_x1) ); if( x1a ){ x1a->size = 1024; x1a->count = 0; - x1a->tbl = (x1node*)calloc(1024, sizeof(x1node) + sizeof(x1node*)); + x1a->tbl = (x1node*)lemon_calloc(1024, sizeof(x1node) + sizeof(x1node*)); if( x1a->tbl==0 ){ - free(x1a); + lemon_free(x1a); x1a = 0; }else{ int i; @@ -5348,7 +5462,7 @@ int Strsafe_insert(const char *data) struct s_x1 array; array.size = arrSize = x1a->size*2; array.count = x1a->count; - array.tbl = (x1node*)calloc(arrSize, sizeof(x1node) + sizeof(x1node*)); + array.tbl = (x1node*)lemon_calloc(arrSize, sizeof(x1node)+sizeof(x1node*)); if( array.tbl==0 ) return 0; /* Fail due to malloc failure */ array.ht = (x1node**)&(array.tbl[arrSize]); for(i=0; i<arrSize; i++) array.ht[i] = 0; @@ -5363,7 +5477,7 @@ int Strsafe_insert(const char *data) newnp->from = &(array.ht[h]); array.ht[h] = newnp; } - /* free(x1a->tbl); // This program was originally for 16-bit machines. + /* lemon_free(x1a->tbl); // This program was originally for 16-bit machines. ** Don't worry about freeing memory on modern platforms. */ *x1a = array; } @@ -5404,7 +5518,7 @@ struct symbol *Symbol_new(const char *x) sp = Symbol_find(x); if( sp==0 ){ - sp = (struct symbol *)calloc(1, sizeof(struct symbol) ); + sp = (struct symbol *)lemon_calloc(1, sizeof(struct symbol) ); MemoryCheck(sp); sp->name = Strsafe(x); sp->type = ISUPPER(*x) ? TERMINAL : NONTERMINAL; @@ -5475,13 +5589,13 @@ static struct s_x2 *x2a; /* Allocate a new associative array */ void Symbol_init(void){ if( x2a ) return; - x2a = (struct s_x2*)malloc( sizeof(struct s_x2) ); + x2a = (struct s_x2*)lemon_malloc( sizeof(struct s_x2) ); if( x2a ){ x2a->size = 128; x2a->count = 0; - x2a->tbl = (x2node*)calloc(128, sizeof(x2node) + sizeof(x2node*)); + x2a->tbl = (x2node*)lemon_calloc(128, sizeof(x2node) + sizeof(x2node*)); if( x2a->tbl==0 ){ - free(x2a); + lemon_free(x2a); x2a = 0; }else{ int i; @@ -5516,7 +5630,7 @@ int Symbol_insert(struct symbol *data, const char *key) struct s_x2 array; array.size = arrSize = x2a->size*2; array.count = x2a->count; - array.tbl = (x2node*)calloc(arrSize, sizeof(x2node) + sizeof(x2node*)); + array.tbl = (x2node*)lemon_calloc(arrSize, sizeof(x2node)+sizeof(x2node*)); if( array.tbl==0 ) return 0; /* Fail due to malloc failure */ array.ht = (x2node**)&(array.tbl[arrSize]); for(i=0; i<arrSize; i++) array.ht[i] = 0; @@ -5532,7 +5646,7 @@ int Symbol_insert(struct symbol *data, const char *key) newnp->from = &(array.ht[h]); array.ht[h] = newnp; } - /* free(x2a->tbl); // This program was originally written for 16-bit + /* lemon_free(x2a->tbl); // This program was originally written for 16-bit ** machines. Don't worry about freeing this trivial amount of memory ** on modern platforms. Just leak it. */ *x2a = array; @@ -5593,7 +5707,7 @@ struct symbol **Symbol_arrayof() int i,arrSize; if( x2a==0 ) return 0; arrSize = x2a->count; - array = (struct symbol **)calloc(arrSize, sizeof(struct symbol *)); + array = (struct symbol **)lemon_calloc(arrSize, sizeof(struct symbol *)); if( array ){ for(i=0; i<arrSize; i++) array[i] = x2a->tbl[i].data; } @@ -5641,7 +5755,7 @@ PRIVATE unsigned statehash(struct config *a) struct state *State_new() { struct state *newstate; - newstate = (struct state *)calloc(1, sizeof(struct state) ); + newstate = (struct state *)lemon_calloc(1, sizeof(struct state) ); MemoryCheck(newstate); return newstate; } @@ -5674,13 +5788,13 @@ static struct s_x3 *x3a; /* Allocate a new associative array */ void State_init(void){ if( x3a ) return; - x3a = (struct s_x3*)malloc( sizeof(struct s_x3) ); + x3a = (struct s_x3*)lemon_malloc( sizeof(struct s_x3) ); if( x3a ){ x3a->size = 128; x3a->count = 0; - x3a->tbl = (x3node*)calloc(128, sizeof(x3node) + sizeof(x3node*)); + x3a->tbl = (x3node*)lemon_calloc(128, sizeof(x3node) + sizeof(x3node*)); if( x3a->tbl==0 ){ - free(x3a); + lemon_free(x3a); x3a = 0; }else{ int i; @@ -5715,7 +5829,7 @@ int State_insert(struct state *data, struct config *key) struct s_x3 array; array.size = arrSize = x3a->size*2; array.count = x3a->count; - array.tbl = (x3node*)calloc(arrSize, sizeof(x3node) + sizeof(x3node*)); + array.tbl = (x3node*)lemon_calloc(arrSize, sizeof(x3node)+sizeof(x3node*)); if( array.tbl==0 ) return 0; /* Fail due to malloc failure */ array.ht = (x3node**)&(array.tbl[arrSize]); for(i=0; i<arrSize; i++) array.ht[i] = 0; @@ -5731,7 +5845,7 @@ int State_insert(struct state *data, struct config *key) newnp->from = &(array.ht[h]); array.ht[h] = newnp; } - free(x3a->tbl); + lemon_free(x3a->tbl); *x3a = array; } /* Insert the new data */ @@ -5772,7 +5886,7 @@ struct state **State_arrayof(void) int i,arrSize; if( x3a==0 ) return 0; arrSize = x3a->count; - array = (struct state **)calloc(arrSize, sizeof(struct state *)); + array = (struct state **)lemon_calloc(arrSize, sizeof(struct state *)); if( array ){ for(i=0; i<arrSize; i++) array[i] = x3a->tbl[i].data; } @@ -5814,13 +5928,13 @@ static struct s_x4 *x4a; /* Allocate a new associative array */ void Configtable_init(void){ if( x4a ) return; - x4a = (struct s_x4*)malloc( sizeof(struct s_x4) ); + x4a = (struct s_x4*)lemon_malloc( sizeof(struct s_x4) ); if( x4a ){ x4a->size = 64; x4a->count = 0; - x4a->tbl = (x4node*)calloc(64, sizeof(x4node) + sizeof(x4node*)); + x4a->tbl = (x4node*)lemon_calloc(64, sizeof(x4node) + sizeof(x4node*)); if( x4a->tbl==0 ){ - free(x4a); + lemon_free(x4a); x4a = 0; }else{ int i; @@ -5855,7 +5969,8 @@ int Configtable_insert(struct config *data) struct s_x4 array; array.size = arrSize = x4a->size*2; array.count = x4a->count; - array.tbl = (x4node*)calloc(arrSize, sizeof(x4node) + sizeof(x4node*)); + array.tbl = (x4node*)lemon_calloc(arrSize, + sizeof(x4node) + sizeof(x4node*)); if( array.tbl==0 ) return 0; /* Fail due to malloc failure */ array.ht = (x4node**)&(array.tbl[arrSize]); for(i=0; i<arrSize; i++) array.ht[i] = 0; @@ -5870,9 +5985,6 @@ int Configtable_insert(struct config *data) newnp->from = &(array.ht[h]); array.ht[h] = newnp; } - /* free(x4a->tbl); // This code was originall written for 16-bit machines. - ** on modern machines, don't worry about freeing this trival amount of - ** memory. */ *x4a = array; } /* Insert the new data */ diff --git a/tool/lempar.c b/tool/lempar.c index 8cc5789..851a0e2 100644 --- a/tool/lempar.c +++ b/tool/lempar.c @@ -67,6 +67,9 @@ ** ParseARG_STORE Code to store %extra_argument into yypParser ** ParseARG_FETCH Code to extract %extra_argument from yypParser ** ParseCTX_* As ParseARG_ except for %extra_context +** YYREALLOC Name of the realloc() function to use +** YYFREE Name of the free() function to use +** YYDYNSTACK True if stack space should be extended on heap ** YYERRORSYMBOL is the code number of the error symbol. If not ** defined, then do no error processing. ** YYNSTATE the combined number of states. @@ -80,6 +83,8 @@ ** YY_NO_ACTION The yy_action[] code for no-op ** YY_MIN_REDUCE Minimum value for reduce actions ** YY_MAX_REDUCE Maximum value for reduce actions +** YY_MIN_DSTRCTR Minimum symbol value that has a destructor +** YY_MAX_DSTRCTR Maximum symbol value that has a destructor */ #ifndef INTERFACE # define INTERFACE 1 @@ -101,6 +106,22 @@ # define yytestcase(X) #endif +/* Macro to determine if stack space has the ability to grow using +** heap memory. +*/ +#if YYSTACKDEPTH<=0 || YYDYNSTACK +# define YYGROWABLESTACK 1 +#else +# define YYGROWABLESTACK 0 +#endif + +/* Guarantee a minimum number of initial stack slots. +*/ +#if YYSTACKDEPTH<=0 +# undef YYSTACKDEPTH +# define YYSTACKDEPTH 2 /* Need a minimum stack size */ +#endif + /* Next are the tables used to determine what action to take based on the ** current state and lookahead token. These tables are used to implement @@ -212,14 +233,9 @@ struct yyParser { #endif ParseARG_SDECL /* A place to hold %extra_argument */ ParseCTX_SDECL /* A place to hold %extra_context */ -#if YYSTACKDEPTH<=0 - int yystksz; /* Current side of the stack */ - yyStackEntry *yystack; /* The parser's stack */ - yyStackEntry yystk0; /* First stack entry */ -#else - yyStackEntry yystack[YYSTACKDEPTH]; /* The parser's stack */ - yyStackEntry *yystackEnd; /* Last entry in the stack */ -#endif + yyStackEntry *yystackEnd; /* Last entry in the stack */ + yyStackEntry *yystack; /* The parser stack */ + yyStackEntry yystk0[YYSTACKDEPTH]; /* Initial stack space */ }; typedef struct yyParser yyParser; @@ -273,37 +289,45 @@ static const char *const yyRuleName[] = { #endif /* NDEBUG */ -#if YYSTACKDEPTH<=0 +#if YYGROWABLESTACK /* ** Try to increase the size of the parser stack. Return the number ** of errors. Return 0 on success. */ static int yyGrowStack(yyParser *p){ + int oldSize = 1 + (int)(p->yystackEnd - p->yystack); int newSize; int idx; yyStackEntry *pNew; - newSize = p->yystksz*2 + 100; - idx = p->yytos ? (int)(p->yytos - p->yystack) : 0; - if( p->yystack==&p->yystk0 ){ - pNew = malloc(newSize*sizeof(pNew[0])); - if( pNew ) pNew[0] = p->yystk0; + newSize = oldSize*2 + 100; + idx = (int)(p->yytos - p->yystack); + if( p->yystack==p->yystk0 ){ + pNew = YYREALLOC(0, newSize*sizeof(pNew[0])); + if( pNew==0 ) return 1; + memcpy(pNew, p->yystack, oldSize*sizeof(pNew[0])); }else{ - pNew = realloc(p->yystack, newSize*sizeof(pNew[0])); + pNew = YYREALLOC(p->yystack, newSize*sizeof(pNew[0])); + if( pNew==0 ) return 1; } - if( pNew ){ - p->yystack = pNew; - p->yytos = &p->yystack[idx]; + p->yystack = pNew; + p->yytos = &p->yystack[idx]; #ifndef NDEBUG - if( yyTraceFILE ){ - fprintf(yyTraceFILE,"%sStack grows from %d to %d entries.\n", - yyTracePrompt, p->yystksz, newSize); - } -#endif - p->yystksz = newSize; + if( yyTraceFILE ){ + fprintf(yyTraceFILE,"%sStack grows from %d to %d entries.\n", + yyTracePrompt, oldSize, newSize); } - return pNew==0; +#endif + p->yystackEnd = &p->yystack[newSize-1]; + return 0; } +#endif /* YYGROWABLESTACK */ + +#if !YYGROWABLESTACK +/* For builds that do no have a growable stack, yyGrowStack always +** returns an error. +*/ +# define yyGrowStack(X) 1 #endif /* Datatype of the argument to the memory allocated passed as the @@ -323,24 +347,14 @@ void ParseInit(void *yypRawParser ParseCTX_PDECL){ #ifdef YYTRACKMAXSTACKDEPTH yypParser->yyhwm = 0; #endif -#if YYSTACKDEPTH<=0 - yypParser->yytos = NULL; - yypParser->yystack = NULL; - yypParser->yystksz = 0; - if( yyGrowStack(yypParser) ){ - yypParser->yystack = &yypParser->yystk0; - yypParser->yystksz = 1; - } -#endif + yypParser->yystack = yypParser->yystk0; + yypParser->yystackEnd = &yypParser->yystack[YYSTACKDEPTH-1]; #ifndef YYNOERRORRECOVERY yypParser->yyerrcnt = -1; #endif yypParser->yytos = yypParser->yystack; yypParser->yystack[0].stateno = 0; yypParser->yystack[0].major = 0; -#if YYSTACKDEPTH>0 - yypParser->yystackEnd = &yypParser->yystack[YYSTACKDEPTH-1]; -#endif } #ifndef Parse_ENGINEALWAYSONSTACK @@ -426,9 +440,26 @@ static void yy_pop_parser_stack(yyParser *pParser){ */ void ParseFinalize(void *p){ yyParser *pParser = (yyParser*)p; - while( pParser->yytos>pParser->yystack ) yy_pop_parser_stack(pParser); -#if YYSTACKDEPTH<=0 - if( pParser->yystack!=&pParser->yystk0 ) free(pParser->yystack); + + /* In-lined version of calling yy_pop_parser_stack() for each + ** element left in the stack */ + yyStackEntry *yytos = pParser->yytos; + while( yytos>pParser->yystack ){ +#ifndef NDEBUG + if( yyTraceFILE ){ + fprintf(yyTraceFILE,"%sPopping %s\n", + yyTracePrompt, + yyTokenName[yytos->major]); + } +#endif + if( yytos->major>=YY_MIN_DSTRCTR ){ + yy_destructor(pParser, yytos->major, &yytos->minor); + } + yytos--; + } + +#if YYGROWABLESTACK + if( pParser->yystack!=pParser->yystk0 ) YYFREE(pParser->yystack); #endif } @@ -654,25 +685,19 @@ static void yy_shift( assert( yypParser->yyhwm == (int)(yypParser->yytos - yypParser->yystack) ); } #endif -#if YYSTACKDEPTH>0 - if( yypParser->yytos>yypParser->yystackEnd ){ - yypParser->yytos--; - yyStackOverflow(yypParser); - return; - } -#else - if( yypParser->yytos>=&yypParser->yystack[yypParser->yystksz] ){ + yytos = yypParser->yytos; + if( yytos>yypParser->yystackEnd ){ if( yyGrowStack(yypParser) ){ yypParser->yytos--; yyStackOverflow(yypParser); return; } + yytos = yypParser->yytos; + assert( yytos <= yypParser->yystackEnd ); } -#endif if( yyNewState > YY_MAX_SHIFT ){ yyNewState += YY_MIN_REDUCE - YY_MIN_SHIFTREDUCE; } - yytos = yypParser->yytos; yytos->stateno = yyNewState; yytos->major = yyMajor; yytos->minor.yy0 = yyMinor; @@ -911,19 +936,12 @@ void Parse( (int)(yypParser->yytos - yypParser->yystack)); } #endif -#if YYSTACKDEPTH>0 if( yypParser->yytos>=yypParser->yystackEnd ){ - yyStackOverflow(yypParser); - break; - } -#else - if( yypParser->yytos>=&yypParser->yystack[yypParser->yystksz-1] ){ if( yyGrowStack(yypParser) ){ yyStackOverflow(yypParser); break; } } -#endif } yyact = yy_reduce(yypParser,yyruleno,yymajor,yyminor ParseCTX_PARAM); }else if( yyact <= YY_MAX_SHIFTREDUCE ){ diff --git a/tool/mkopcodeh.tcl b/tool/mkopcodeh.tcl index 6fb3b75..18fe1a2 100644 --- a/tool/mkopcodeh.tcl +++ b/tool/mkopcodeh.tcl @@ -81,6 +81,7 @@ while {![eof $in]} { set op($name) -1 set group($name) 0 set jump($name) 0 + set jump0($name) 0 set in1($name) 0 set in2($name) 0 set in3($name) 0 @@ -109,6 +110,7 @@ while {![eof $in]} { out2 {set out2($name) 1} out3 {set out3($name) 1} ncycle {set ncycle($name) 1} + jump0 {set jump($name) 1; set jump0($name) 1;} } } if {$group($name)} { @@ -137,6 +139,7 @@ puts "/* Automatically generated. Do not edit */" puts "/* See the tool/mkopcodeh.tcl script for details */" foreach name {OP_Noop OP_Explain OP_Abortable} { set jump($name) 0 + set jump0($name) 0 set in1($name) 0 set in2($name) 0 set in3($name) 0 @@ -256,7 +259,9 @@ for {set i 0} {$i<=$max} {incr i} { set name $def($i) puts -nonewline [format {#define %-16s %3d} $name $i] set com {} - if {[info exists jump($name)] && $jump($name)} { + if {[info exists jump0($name)] && $jump0($name)} { + lappend com "jump0" + } elseif {[info exists jump($name)] && $jump($name)} { lappend com "jump" } if {[info exists sameas($i)]} { @@ -289,6 +294,7 @@ for {set i 0} {$i<=$max} {incr i} { if {$out2($name)} {incr x 16} if {$out3($name)} {incr x 32} if {$ncycle($name)} {incr x 64} + if {$jump0($name)} {incr x 128} } set bv($i) $x } @@ -304,6 +310,7 @@ puts "#define OPFLG_IN3 0x08 /* in3: P3 is an input */" puts "#define OPFLG_OUT2 0x10 /* out2: P2 is an output */" puts "#define OPFLG_OUT3 0x20 /* out3: P3 is an output */" puts "#define OPFLG_NCYCLE 0x40 /* ncycle:Cycles count against P1 */" +puts "#define OPFLG_JUMP0 0x80 /* jump0: P2 might be zero */" puts "#define OPFLG_INITIALIZER \173\\" for {set i 0} {$i<=$max} {incr i} { if {$i%8==0} { diff --git a/tool/mksqlite3c.tcl b/tool/mksqlite3c.tcl index 53fa59a..ef8353d 100644 --- a/tool/mksqlite3c.tcl +++ b/tool/mksqlite3c.tcl @@ -17,7 +17,7 @@ # After the "tsrc" directory has been created and populated, run # this script: # -# tclsh mksqlite3c.tcl +# tclsh mksqlite3c.tcl [flags] [extra source files] # # The amalgamated SQLite code will be written into sqlite3.c # @@ -42,6 +42,7 @@ set linemacros 0 set useapicall 0 set enable_recover 0 set srcdir tsrc +set extrasrc [list] for {set i 0} {$i<[llength $argv]} {incr i} { set x [lindex $argv $i] @@ -63,8 +64,10 @@ for {set i 0} {$i<[llength $argv]} {incr i} { } elseif {[regexp {^-?-((help)|\?)$} $x]} { puts $help exit 0 - } else { + } elseif {[regexp {^-?-} $x]} { error "unknown command-line option: $x" + } else { + lappend extrasrc $x } } set in [open $srcdir/sqlite3.h] @@ -349,6 +352,21 @@ proc copy_file {filename} { section_comment "End of $tail" } +# Read the source file named $filename and write it into the +# sqlite3.c output file. The only transformation is the trimming +# of EOL whitespace. +# +proc copy_file_verbatim {filename} { + global out + set in [open $filename r] + set tail [file tail $filename] + section_comment "Begin EXTRA_SRC file $tail" + while {![eof $in]} { + set line [string trimright [gets $in]] + puts $out $line + } + section_comment "End of EXTRA_SRC $tail" +} # Process the source files. Process files containing commonly # used subroutines first in order to help the compiler find @@ -470,13 +488,16 @@ set flist { sqlite3session.c fts5.c stmt.c -} +} if {$enable_recover} { lappend flist sqlite3recover.c dbdata.c } foreach file $flist { copy_file $srcdir/$file } +foreach file $extrasrc { + copy_file_verbatim $file +} puts $out \ "/* Return the source-id for this library */ diff --git a/tool/speed-check.sh b/tool/speed-check.sh index 4cc2579..5d425c3 100644 --- a/tool/speed-check.sh +++ b/tool/speed-check.sh @@ -161,6 +161,9 @@ while test "$1" != ""; do --fp) SPEEDTEST_OPTS="$SPEEDTEST_OPTS --testset fp" ;; + --parsenumber) + SPEEDTEST_OPTS="$SPEEDTEST_OPTS --testset parsenumber" + ;; --stmtscanstatus) SPEEDTEST_OPTS="$SPEEDTEST_OPTS --stmtscanstatus" ;; diff --git a/www/appfunc.html b/www/appfunc.html index 998bcd0..b3167a5 100644 --- a/www/appfunc.html +++ b/www/appfunc.html @@ -524,7 +524,7 @@ where an attacker might be able to surreptiously invoke them by modifying a database schema: </p><ul> <li> In VIEWs. -</li><li> In TRIGGERSs. +</li><li> In TRIGGERs. </li><li> In CHECK constraints of a table definition. </li><li> In DEFAULT constraints of a table definition. </li><li> In the definitions of generated columns. @@ -562,5 +562,5 @@ unless you really need to and you have checked the implementation closely and are certain that it can do no harm even if it falls under the control of an attacker. </p></li></ol> -<p align="center"><small><i>This page last modified on <a href="https://sqlite.org/docsrc/honeypot" id="mtimelink" data-href="https://sqlite.org/docsrc/finfo/pages/appfunc.in?m=da7fbd0b40">2023-02-27 02:07:35</a> UTC </small></i></p> +<p align="center"><small><i>This page last modified on <a href="https://sqlite.org/docsrc/honeypot" id="mtimelink" data-href="https://sqlite.org/docsrc/finfo/pages/appfunc.in?m=fe78d4d736">2024-04-16 17:22:18</a> UTC </small></i></p> diff --git a/www/c3ref/c_source_id.html b/www/c3ref/c_source_id.html index 672f75f..82e7547 100644 --- a/www/c3ref/c_source_id.html +++ b/www/c3ref/c_source_id.html @@ -121,9 +121,9 @@ antiRobotDefense(); <h2>Compile-Time Library Version Numbers</h2> </div> <blockquote><pre> -#define SQLITE_VERSION "3.45.3" -#define SQLITE_VERSION_NUMBER 3045003 -#define SQLITE_SOURCE_ID "2024-04-15 13:34:05 8653b758870e6ef0c98d46b3ace27849054af85da891eb121e9aaa537f1e8355" +#define SQLITE_VERSION "3.46.0" +#define SQLITE_VERSION_NUMBER 3046000 +#define SQLITE_SOURCE_ID "2024-05-23 13:25:27 96c92aba00c8375bc32fafcdf12429c58bd8aabfcadab6683e35bbb9cdebf19e" </pre></blockquote> <p> The <a href="../c3ref/c_source_id.html">SQLITE_VERSION</a> C preprocessor macro in the sqlite3.h header diff --git a/www/c3ref/funclist.html b/www/c3ref/funclist.html index eedbe37..5642032 100644 --- a/www/c3ref/funclist.html +++ b/www/c3ref/funclist.html @@ -121,8 +121,8 @@ antiRobotDefense(); <p>Note: Functions marked with "<small><i>(exp)</i></small>" are <a href="../c3ref/experimental.html">experimental</a> and functions whose names are <s>struck through</s> are <a href="../c3ref/experimental.html">deprecated</a>.</p> -<!-- number of functions: 290 --> -<!-- number of deprecated functions: 7 --> +<!-- number of functions: 288 --> +<!-- number of deprecated functions: 9 --> <!-- number of experimental functions: 0 --> <div class='columns' style='columns: 15em auto;'> <ul style='padding-top:0;'> @@ -291,7 +291,7 @@ are <a href="../c3ref/experimental.html">experimental</a> and functions whose na <li><a href='../c3ref/preupdate_blobwrite.html'>sqlite3_preupdate_hook</a></li> <li><a href='../c3ref/preupdate_blobwrite.html'>sqlite3_preupdate_new</a></li> <li><a href='../c3ref/preupdate_blobwrite.html'>sqlite3_preupdate_old</a></li> -<li><a href='../c3ref/profile.html'>sqlite3_profile</a></li> +<li><s>sqlite3_profile</s></li> <li><a href='../c3ref/progress_handler.html'>sqlite3_progress_handler</a></li> <li><a href='../c3ref/randomness.html'>sqlite3_randomness</a></li> <li><a href='../c3ref/free.html'>sqlite3_realloc</a></li> @@ -371,7 +371,7 @@ are <a href="../c3ref/experimental.html">experimental</a> and functions whose na <li><a href='../c3ref/threadsafe.html'>sqlite3_threadsafe</a></li> <li><a href='../c3ref/total_changes.html'>sqlite3_total_changes</a></li> <li><a href='../c3ref/total_changes.html'>sqlite3_total_changes64</a></li> -<li><a href='../c3ref/profile.html'>sqlite3_trace</a></li> +<li><s>sqlite3_trace</s></li> <li><a href='../c3ref/trace_v2.html'>sqlite3_trace_v2</a></li> <li><s>sqlite3_transfer_bindings</s></li> <li><a href='../c3ref/txn_state.html'>sqlite3_txn_state</a></li> diff --git a/www/c3ref/io_methods.html b/www/c3ref/io_methods.html index 67ddcd0..033a806 100644 --- a/www/c3ref/io_methods.html +++ b/www/c3ref/io_methods.html @@ -178,10 +178,11 @@ and not its inode needs to be synced.</p> </ul> xLock() upgrades the database file lock. In other words, xLock() moves the database file lock in the direction NONE toward EXCLUSIVE. The argument to -xLock() is always on of SHARED, RESERVED, PENDING, or EXCLUSIVE, never +xLock() is always one of SHARED, RESERVED, PENDING, or EXCLUSIVE, never SQLITE_LOCK_NONE. If the database file lock is already at or above the requested lock, then the call to xLock() is a no-op. xUnlock() downgrades the database file lock to either SHARED or NONE. +If the lock is already at or below the requested lock state, then the call to xUnlock() is a no-op. The xCheckReservedLock() method checks whether any database connection, either in this process or in some other process, is holding a RESERVED, diff --git a/www/c3ref/keyword_check.html b/www/c3ref/keyword_check.html index 0492f5f..f3f4d89 100644 --- a/www/c3ref/keyword_check.html +++ b/www/c3ref/keyword_check.html @@ -134,7 +134,7 @@ by enclosing in double-quotes) so as not to confuse the parser.</p> <p>The sqlite3_keyword_count() interface returns the number of distinct keywords understood by SQLite.</p> -<p>The sqlite3_keyword_name(N,Z,L) interface finds the N-th keyword and +<p>The sqlite3_keyword_name(N,Z,L) interface finds the 0-based N-th keyword and makes *Z point to that keyword expressed as UTF8 and writes the number of bytes in the keyword into *L. The string that *Z points to is not zero-terminated. The sqlite3_keyword_name(N,Z,L) routine returns diff --git a/www/c3ref/profile.html b/www/c3ref/profile.html index e92fc14..53d0efb 100644 --- a/www/c3ref/profile.html +++ b/www/c3ref/profile.html @@ -3,7 +3,7 @@ <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> <link href="../sqlite.css" rel="stylesheet"> -<title>Tracing And Profiling Functions</title> +<title>Deprecated Tracing And Profiling Functions</title> <!-- path=../ --> </head> <body> @@ -118,7 +118,7 @@ antiRobotDefense(); <!-- keywords: sqlite3_profile sqlite3_trace --> <div class=nosearch> <a href="../c3ref/intro.html"><h2>SQLite C Interface</h2></a> -<h2>Tracing And Profiling Functions</h2> +<h2>Deprecated Tracing And Profiling Functions</h2> </div> <blockquote><pre> void *sqlite3_trace(sqlite3*, diff --git a/www/c3ref/sqlite3.html b/www/c3ref/sqlite3.html index b8d2725..88a3dbf 100644 --- a/www/c3ref/sqlite3.html +++ b/www/c3ref/sqlite3.html @@ -140,7 +140,7 @@ sqlite3 object. <p>2 Destructors using this object: <a href="../c3ref/close.html">sqlite3_close()</a>, <a href="../c3ref/close.html">sqlite3_close_v2()</a></p> -<p>79 Methods using this object: +<p>77 Methods using this object: <div class='columns' style='columns: 17em auto;'> <ul style='padding-top:0;'> <li><a href='../c3ref/autovacuum_pages.html'>sqlite3_autovacuum_pages</a></li> @@ -203,7 +203,6 @@ sqlite3 object. <li><a href='../c3ref/preupdate_blobwrite.html'>sqlite3_preupdate_hook</a></li> <li><a href='../c3ref/preupdate_blobwrite.html'>sqlite3_preupdate_new</a></li> <li><a href='../c3ref/preupdate_blobwrite.html'>sqlite3_preupdate_old</a></li> -<li><a href='../c3ref/profile.html'>sqlite3_profile</a></li> <li><a href='../c3ref/progress_handler.html'>sqlite3_progress_handler</a></li> <li><a href='../c3ref/commit_hook.html'>sqlite3_rollback_hook</a></li> <li><a href='../c3ref/set_authorizer.html'>sqlite3_set_authorizer</a></li> @@ -213,7 +212,6 @@ sqlite3 object. <li><a href='../c3ref/table_column_metadata.html'>sqlite3_table_column_metadata</a></li> <li><a href='../c3ref/total_changes.html'>sqlite3_total_changes</a></li> <li><a href='../c3ref/total_changes.html'>sqlite3_total_changes64</a></li> -<li><a href='../c3ref/profile.html'>sqlite3_trace</a></li> <li><a href='../c3ref/trace_v2.html'>sqlite3_trace_v2</a></li> <li><a href='../c3ref/txn_state.html'>sqlite3_txn_state</a></li> <li><a href='../c3ref/unlock_notify.html'>sqlite3_unlock_notify</a></li> diff --git a/www/c3ref/update_hook.html b/www/c3ref/update_hook.html index 88b8e81..3df764a 100644 --- a/www/c3ref/update_hook.html +++ b/www/c3ref/update_hook.html @@ -158,6 +158,12 @@ invoked when rows are deleted using the <a href="../lang_delete.html#truncateopt The exceptions defined in this paragraph might change in a future release of SQLite.</p> +<p>Whether the update hook is invoked before or after the +corresponding change is currently unspecified and may differ +depending on the type of change. Do not rely on the order of the +hook call with regards to the final result of the operation which +triggers the hook.</p> + <p>The update hook implementation must not do anything that will modify the database connection that invoked the update hook. Any actions to modify the database connection must be deferred until after the diff --git a/www/c3ref/vtab_distinct.html b/www/c3ref/vtab_distinct.html index 16420a1..5cfef1c 100644 --- a/www/c3ref/vtab_distinct.html +++ b/www/c3ref/vtab_distinct.html @@ -152,24 +152,45 @@ is doing a GROUP BY. <li value="2"><p> If the sqlite3_vtab_distinct() interface returns 2, that means that the query planner does not need the rows returned in any particular -order, as long as rows with the same values in all "aOrderBy" columns -are adjacent. Furthermore, only a single row for each particular -combination of values in the columns identified by the "aOrderBy" field -needs to be returned. It is always ok for two or more rows with the same -values in all "aOrderBy" columns to be returned, as long as all such rows -are adjacent. The virtual table may, if it chooses, omit extra rows -that have the same value for all columns identified by "aOrderBy". -However omitting the extra rows is optional. +order, as long as rows with the same values in all columns identified +by "aOrderBy" are adjacent. Furthermore, when two or more rows +contain the same values for all columns identified by "colUsed", all but +one such row may optionally be omitted from the result. +The virtual table is not required to omit rows that are duplicates +over the "colUsed" columns, but if the virtual table can do that without +too much extra effort, it could potentially help the query to run faster. This mode is used for a DISTINCT query. <li value="3"><p> -If the sqlite3_vtab_distinct() interface returns 3, that means -that the query planner needs only distinct rows but it does need the -rows to be sorted. The virtual table implementation is free to omit -rows that are identical in all aOrderBy columns, if it wants to, but -it is not required to omit any rows. This mode is used for queries +If the sqlite3_vtab_distinct() interface returns 3, that means the +virtual table must return rows in the order defined by "aOrderBy" as +if the sqlite3_vtab_distinct() interface had returned 0. However if +two or more rows in the result have the same values for all columns +identified by "colUsed", then all but one such row may optionally be +omitted. Like when the return value is 2, the virtual table +is not required to omit rows that are duplicates over the "colUsed" +columns, but if the virtual table can do that without +too much extra effort, it could potentially help the query to run faster. +This mode is used for queries that have both DISTINCT and ORDER BY clauses. </ol></p> +<p><p>The following table summarizes the conditions under which the +virtual table is allowed to set the "orderByConsumed" flag based on +the value returned by sqlite3_vtab_distinct(). This table is a +restatement of the previous four paragraphs:</p> + +<p><table border=1 cellspacing=0 cellpadding=10 width="90%"> +<tr> +<td valign="top">sqlite3_vtab_distinct() return value +<td valign="top">Rows are returned in aOrderBy order +<td valign="top">Rows with the same value in all aOrderBy columns are adjacent +<td valign="top">Duplicates over all colUsed columns may be omitted +<tr><td>0<td>yes<td>yes<td>no +<tr><td>1<td>no<td>yes<td>no +<tr><td>2<td>no<td>yes<td>yes +<tr><td>3<td>yes<td>yes<td>yes +</table></p> + <p>For the purposes of comparing virtual table output values to see if the values are same value for sorting purposes, two NULL values are considered to be the same. In other words, the comparison operator is "IS" diff --git a/www/capi3ref.html b/www/capi3ref.html index 43cecdb..54ae2b8 100644 --- a/www/capi3ref.html +++ b/www/capi3ref.html @@ -687,8 +687,8 @@ be removed in some future release.</li> <p>Note: Functions marked with "<small><i>(exp)</i></small>" are <a href="capi3ref.html">experimental</a> and functions whose names are <s>struck through</s> are <a href="capi3ref.html">deprecated</a>.</p> -<!-- number of functions: 290 --> -<!-- number of deprecated functions: 7 --> +<!-- number of functions: 288 --> +<!-- number of deprecated functions: 9 --> <!-- number of experimental functions: 0 --> <div class='columns' style='columns: 15em auto;'> <ul style='padding-top:0;'> @@ -857,7 +857,7 @@ are <a href="capi3ref.html">experimental</a> and functions whose names are <li><a href='#sqlite3_preupdate_blobwrite'>sqlite3_preupdate_hook</a></li> <li><a href='#sqlite3_preupdate_blobwrite'>sqlite3_preupdate_new</a></li> <li><a href='#sqlite3_preupdate_blobwrite'>sqlite3_preupdate_old</a></li> -<li><a href='#sqlite3_profile'>sqlite3_profile</a></li> +<li><s>sqlite3_profile</s></li> <li><a href='#sqlite3_progress_handler'>sqlite3_progress_handler</a></li> <li><a href='#sqlite3_randomness'>sqlite3_randomness</a></li> <li><a href='#sqlite3_free'>sqlite3_realloc</a></li> @@ -937,7 +937,7 @@ are <a href="capi3ref.html">experimental</a> and functions whose names are <li><a href='#sqlite3_threadsafe'>sqlite3_threadsafe</a></li> <li><a href='#sqlite3_total_changes'>sqlite3_total_changes</a></li> <li><a href='#sqlite3_total_changes'>sqlite3_total_changes64</a></li> -<li><a href='#sqlite3_profile'>sqlite3_trace</a></li> +<li><s>sqlite3_trace</s></li> <li><a href='#sqlite3_trace_v2'>sqlite3_trace_v2</a></li> <li><s>sqlite3_transfer_bindings</s></li> <li><a href='#sqlite3_txn_state'>sqlite3_txn_state</a></li> @@ -1376,10 +1376,11 @@ and not its inode needs to be synced.</p> </ul> xLock() upgrades the database file lock. In other words, xLock() moves the database file lock in the direction NONE toward EXCLUSIVE. The argument to -xLock() is always on of SHARED, RESERVED, PENDING, or EXCLUSIVE, never +xLock() is always one of SHARED, RESERVED, PENDING, or EXCLUSIVE, never SQLITE_LOCK_NONE. If the database file lock is already at or above the requested lock, then the call to xLock() is a no-op. xUnlock() downgrades the database file lock to either SHARED or NONE. +If the lock is already at or below the requested lock state, then the call to xUnlock() is a no-op. The xCheckReservedLock() method checks whether any database connection, either in this process or in some other process, is holding a RESERVED, @@ -4307,6 +4308,12 @@ invoked when rows are deleted using the <a href="lang_delete.html#truncateopt">t The exceptions defined in this paragraph might change in a future release of SQLite.</p> +<p>Whether the update hook is invoked before or after the +corresponding change is currently unspecified and may differ +depending on the type of change. Do not rely on the order of the +hook call with regards to the final result of the operation which +triggers the hook.</p> + <p>The update hook implementation must not do anything that will modify the database connection that invoked the update hook. Any actions to modify the database connection must be deferred until after the @@ -4467,24 +4474,45 @@ is doing a GROUP BY. <li value="2"><p> If the sqlite3_vtab_distinct() interface returns 2, that means that the query planner does not need the rows returned in any particular -order, as long as rows with the same values in all "aOrderBy" columns -are adjacent. Furthermore, only a single row for each particular -combination of values in the columns identified by the "aOrderBy" field -needs to be returned. It is always ok for two or more rows with the same -values in all "aOrderBy" columns to be returned, as long as all such rows -are adjacent. The virtual table may, if it chooses, omit extra rows -that have the same value for all columns identified by "aOrderBy". -However omitting the extra rows is optional. +order, as long as rows with the same values in all columns identified +by "aOrderBy" are adjacent. Furthermore, when two or more rows +contain the same values for all columns identified by "colUsed", all but +one such row may optionally be omitted from the result. +The virtual table is not required to omit rows that are duplicates +over the "colUsed" columns, but if the virtual table can do that without +too much extra effort, it could potentially help the query to run faster. This mode is used for a DISTINCT query. <li value="3"><p> -If the sqlite3_vtab_distinct() interface returns 3, that means -that the query planner needs only distinct rows but it does need the -rows to be sorted. The virtual table implementation is free to omit -rows that are identical in all aOrderBy columns, if it wants to, but -it is not required to omit any rows. This mode is used for queries +If the sqlite3_vtab_distinct() interface returns 3, that means the +virtual table must return rows in the order defined by "aOrderBy" as +if the sqlite3_vtab_distinct() interface had returned 0. However if +two or more rows in the result have the same values for all columns +identified by "colUsed", then all but one such row may optionally be +omitted. Like when the return value is 2, the virtual table +is not required to omit rows that are duplicates over the "colUsed" +columns, but if the virtual table can do that without +too much extra effort, it could potentially help the query to run faster. +This mode is used for queries that have both DISTINCT and ORDER BY clauses. </ol></p> +<p><p>The following table summarizes the conditions under which the +virtual table is allowed to set the "orderByConsumed" flag based on +the value returned by sqlite3_vtab_distinct(). This table is a +restatement of the previous four paragraphs:</p> + +<p><table border=1 cellspacing=0 cellpadding=10 width="90%"> +<tr> +<td valign="top">sqlite3_vtab_distinct() return value +<td valign="top">Rows are returned in aOrderBy order +<td valign="top">Rows with the same value in all aOrderBy columns are adjacent +<td valign="top">Duplicates over all colUsed columns may be omitted +<tr><td>0<td>yes<td>yes<td>no +<tr><td>1<td>no<td>yes<td>no +<tr><td>2<td>no<td>yes<td>yes +<tr><td>3<td>yes<td>yes<td>yes +</table></p> + <p>For the purposes of comparing virtual table output values to see if the values are same value for sorting purposes, two NULL values are considered to be the same. In other words, the comparison operator is "IS" @@ -6884,9 +6912,9 @@ and EXCLUSIVE. <h2>Compile-Time Library Version Numbers</h2> </div> <blockquote><pre> -#define SQLITE_VERSION "3.45.3" -#define SQLITE_VERSION_NUMBER 3045003 -#define SQLITE_SOURCE_ID "2024-04-15 13:34:05 8653b758870e6ef0c98d46b3ace27849054af85da891eb121e9aaa537f1e8355" +#define SQLITE_VERSION "3.46.0" +#define SQLITE_VERSION_NUMBER 3046000 +#define SQLITE_SOURCE_ID "2024-05-23 13:25:27 96c92aba00c8375bc32fafcdf12429c58bd8aabfcadab6683e35bbb9cdebf19e" </pre></blockquote> <p> The <a href="#SQLITE_SOURCE_ID">SQLITE_VERSION</a> C preprocessor macro in the sqlite3.h header @@ -7779,7 +7807,7 @@ sqlite3 object. <p>2 Destructors using this object: <a href="#sqlite3_close">sqlite3_close()</a>, <a href="#sqlite3_close">sqlite3_close_v2()</a></p> -<p>79 Methods using this object: +<p>77 Methods using this object: <div class='columns' style='columns: 17em auto;'> <ul style='padding-top:0;'> <li><a href='#sqlite3_autovacuum_pages'>sqlite3_autovacuum_pages</a></li> @@ -7842,7 +7870,6 @@ sqlite3 object. <li><a href='#sqlite3_preupdate_blobwrite'>sqlite3_preupdate_hook</a></li> <li><a href='#sqlite3_preupdate_blobwrite'>sqlite3_preupdate_new</a></li> <li><a href='#sqlite3_preupdate_blobwrite'>sqlite3_preupdate_old</a></li> -<li><a href='#sqlite3_profile'>sqlite3_profile</a></li> <li><a href='#sqlite3_progress_handler'>sqlite3_progress_handler</a></li> <li><a href='#sqlite3_commit_hook'>sqlite3_rollback_hook</a></li> <li><a href='#sqlite3_set_authorizer'>sqlite3_set_authorizer</a></li> @@ -7852,7 +7879,6 @@ sqlite3 object. <li><a href='#sqlite3_table_column_metadata'>sqlite3_table_column_metadata</a></li> <li><a href='#sqlite3_total_changes'>sqlite3_total_changes</a></li> <li><a href='#sqlite3_total_changes'>sqlite3_total_changes64</a></li> -<li><a href='#sqlite3_profile'>sqlite3_trace</a></li> <li><a href='#sqlite3_trace_v2'>sqlite3_trace_v2</a></li> <li><a href='#sqlite3_txn_state'>sqlite3_txn_state</a></li> <li><a href='#sqlite3_unlock_notify'>sqlite3_unlock_notify</a></li> @@ -9701,7 +9727,7 @@ by enclosing in double-quotes) so as not to confuse the parser.</p> <p>The sqlite3_keyword_count() interface returns the number of distinct keywords understood by SQLite.</p> -<p>The sqlite3_keyword_name(N,Z,L) interface finds the N-th keyword and +<p>The sqlite3_keyword_name(N,Z,L) interface finds the 0-based N-th keyword and makes *Z point to that keyword expressed as UTF8 and writes the number of bytes in the keyword into *L. The string that *Z points to is not zero-terminated. The sqlite3_keyword_name(N,Z,L) routine returns @@ -10420,7 +10446,7 @@ regular DELETE, sqlite3_preupdate_blobwrite() returns -1.</p> <p>See also: <a href="#sqlite3_update_hook">sqlite3_update_hook()</a> </p><hr><a name="sqlite3_profile"></a> -<h2>Tracing And Profiling Functions</h2> +<h2>Deprecated Tracing And Profiling Functions</h2> </div> <blockquote><pre> void *sqlite3_trace(sqlite3*, diff --git a/www/changes.html b/www/changes.html index 8defc25..f7954ca 100644 --- a/www/changes.html +++ b/www/changes.html @@ -129,6 +129,56 @@ https://www.sqlite.org/src/timeline?t=release</a>. See the <a href="chronology.html">chronology</a> a succinct listing of releases. </p> +<a name="version_3_46_0"></a> +<h3>2024-05-23 (3.46.0)</h3><p><ol class='lessindent'> +<li> Enhance <a href="pragma.html#pragma_optimize">PRAGMA optimize</a> in multiple ways, to make it + <a href="lang_analyze.html#pragopt">simpler to use</a>: + <ol type="a"> + <li> PRAGMA optimize automatically implements a temporary + <a href="pragma.html#pragma_analysis_limit">analysis limit</a> to prevent excess runtime + on large databases. + <li> Added the new 0x10000 bitmask option to check for updates on all tables. + <li> Automatically re-analyze tables that do not have sqlite_stat1 entries. + </ol> +<li> Enhancements to the <a href="lang_datefunc.html">date and time functions</a>: + <ol type="a"> + <li> The <a href="lang_datefunc.html#strftm">strftime() SQL function</a> now supports %G, %g, %U, and %V. + <li> New modifiers 'ceiling' and 'floor' control the algorithm used to + resolve <a href="lang_datefunc.html#dtambg">ambiguous dates</a> when shifting a date by an integer number + of months and/or years. + <li> The <a href="lang_datefunc.html#localtime">'utc' and 'localtime' modifiers</a> are now no-ops if SQLite knows + that the time is already in UTC or in the localtime, respectively. + </ol> +<li> Add support for underscore ("_") characters between digits in + <a href="lang_expr.html#litvalue">numeric literals</a>. +<li> Add the <a href="json1.html#jpretty">json_pretty()</a> SQL function. +<li> Query planner improvements: + <ol type="a"> + <li> The "VALUES-as-coroutine" optimization enables INSERT statements with + thousands of rows in the VALUES clause to parse and run in about half + the time and using about half as much memory. + <li> Allow the use of an index for queries like "SELECT count(DISTINCT col) FROM ...", + even if the index records are not smaller than the table records. + <li> Improved recognition of cases where the value of an SQL function is + constant because all its arguments are constant. + <li> Enhance the <a href="optoverview.html#pushdown">WHERE-clause push-down optimization</a> so that it is able to + push down WHERE clause terms containing uncorrelated subqueries. + </ol> +<li> Allocate additional memory from the heap for the SQL parser stack if + that stack overflows, rather than reporting a "parser stack overflow" error. +<li> JSON changes: + <ol type="a"> + <li> Allow ASCII control characters within JSON5 string literals. + <li> Fix <a href="json1.html#jptr">the -> and ->> operators</a> so that when the right-hand side operand is a string + that looks like an integer it is still treated as a string, because that is what + PostgreSQL does. + </ol> +<li> Allow large hexadecimal literals to be used as the DEFAULT value to a table column. +<p><b>Hashes:</b> +<li>SQLITE_SOURCE_ID: 2024-05-23 13:25:27 96c92aba00c8375bc32fafcdf12429c58bd8aabfcadab6683e35bbb9cdebf19e +<li>SHA3-256 for sqlite3.c: 094429ea827fcd32275e767134bc6c7b9ea394a2c5a9e653dd0a0690b2c11358 + +</ol></p> <a name="version_3_45_3"></a> <h3>2024-04-15 (3.45.3)</h3><p><ol class='lessindent'> <li> Fix a long-standing bug (going back to <a href="#version_3_24_0">version 3.24.0</a>) @@ -402,7 +452,7 @@ See the <a href="chronology.html">chronology</a> a succinct listing of releases. <ol type="a"> <li> Enable the "count-of-view" optimization by default. <li> Avoid computing unused columns in subqueries. - <li> Improvements to the <a href="optoverview.html#pushdown">push-down optimization</a>. + <li> Improvements to the <a href="optoverview.html#pushdown">WHERE-clause push-down optimization</a>. </ol> <li> Enhancements to the <a href="cli.html">CLI</a>: <ol type="a"> @@ -2757,7 +2807,7 @@ with a home-baked pie.</center> the table has one or more indexes that are able to trigger the OR optimization, but none of the indexes reference any table columns other than the INTEGER PRIMARY KEY. Ticket <a href="https://www.sqlite.org/src/info/16c9801ceba49">16c9801ceba49</a>. -<li>When checking for the WHERE-clause push-down optimization, verify that all terms +<li>When checking for the <a href="optoverview.html#pushdown">WHERE-clause push-down optimization</a>, verify that all terms of the compound inner SELECT are non-aggregate, not just the last term. Fix for ticket <a href="https://www.sqlite.org/src/info/f7f8c97e97597">f7f8c97e97597</a>. <li>Fix a locking race condition in Windows that can occur when two or more processes @@ -3110,7 +3160,7 @@ with a home-baked pie.</center> <a href="c3ref/initialize.html">sqlite3_initialize()</a> to help ensure that it is thread-safe. <li>Fix the <a href="optoverview.html#or_opt">OR optimization</a> so that it always ignores subplans that do not use an index. -<li>Do not apply the WHERE-clause pushdown optimization on terms that originate +<li>Do not apply the <a href="optoverview.html#pushdown">WHERE-clause push-down optimization</a> on terms that originate in the ON or USING clause of a LEFT JOIN. Fix for ticket <a href="https://www.sqlite.org/src/info/c2a19d81652f40568c">c2a19d81652f40568c</a>. diff --git a/www/chronology.html b/www/chronology.html index 4c8e450..e638413 100644 --- a/www/chronology.html +++ b/www/chronology.html @@ -125,6 +125,8 @@ antiRobotDefense(); <tr><th class='sort desc'>Date<th class='sort none'>Version </thead> <tbody> +<tr><td width='100' align='center' data-sortkey='08681'><a href='https://www.sqlite.org/src/timeline?c=96c92aba00&y=ci'>2024-05-23</a></td> +<td width='100' align='center' data-sortkey='3460000'><a href="releaselog/3_46_0.html">3.46.0</a></td></tr> <tr><td width='100' align='center' data-sortkey='08643'><a href='https://www.sqlite.org/src/timeline?c=8653b75887&y=ci'>2024-04-15</a></td> <td width='100' align='center' data-sortkey='3450300'><a href="releaselog/3_45_3.html">3.45.3</a></td></tr> <tr><td width='100' align='center' data-sortkey='08609'><a href='https://www.sqlite.org/src/timeline?c=bd76ad2dc9&y=ci'>2024-03-12</a></td> @@ -243,6 +245,8 @@ antiRobotDefense(); <td width='100' align='center' data-sortkey='3250000'><a href="releaselog/3_25_0.html">3.25.0</a></td></tr> <tr><td width='100' align='center' data-sortkey='06501'><a href='https://www.sqlite.org/src/timeline?c=c7ee083322&y=ci'>2018-06-04</a></td> <td width='100' align='center' data-sortkey='3240000'><a href="releaselog/3_24_0.html">3.24.0</a></td></tr> +<tr><td width='100' align='center' data-sortkey='06475'><a href='https://www.sqlite.org/src/timeline?c=f139f6f07d&y=ci'>2018-05-09</a></td> +<td width='100' align='center' data-sortkey='3230200'>3.23.2</td></tr> <tr><td width='100' align='center' data-sortkey='06446'><a href='https://www.sqlite.org/src/timeline?c=4bb2294022&y=ci'>2018-04-10</a></td> <td width='100' align='center' data-sortkey='3230100'><a href="releaselog/3_23_1.html">3.23.1</a></td></tr> <tr><td width='100' align='center' data-sortkey='06438'><a href='https://www.sqlite.org/src/timeline?c=736b53f57f&y=ci'>2018-04-02</a></td> @@ -259,6 +263,8 @@ antiRobotDefense(); <td width='100' align='center' data-sortkey='3180200'><a href="releaselog/3_18_2.html">3.18.2</a></td></tr> <tr><td width='100' align='center' data-sortkey='06148'><a href='https://www.sqlite.org/src/timeline?c=77bb46233d&y=ci'>2017-06-16</a></td> <td width='100' align='center' data-sortkey='3180100'><a href="releaselog/3_18_1.html">3.18.1</a></td></tr> +<tr><td width='100' align='center' data-sortkey='06211'><a href='https://www.sqlite.org/src/timeline?c=605907e73a&y=ci'>2017-08-18</a></td> +<td width='100' align='center' data-sortkey='3190400'>3.19.4</td></tr> <tr><td width='100' align='center' data-sortkey='06140'><a href='https://www.sqlite.org/src/timeline?c=0ee482a1e0&y=ci'>2017-06-08</a></td> <td width='100' align='center' data-sortkey='3190300'><a href="releaselog/3_19_3.html">3.19.3</a></td></tr> <tr><td width='100' align='center' data-sortkey='06126'><a href='https://www.sqlite.org/src/timeline?c=edb4e819b0&y=ci'>2017-05-25</a></td> @@ -395,10 +401,6 @@ antiRobotDefense(); <td width='100' align='center' data-sortkey='3071300'><a href="releaselog/3_7_13.html">3.7.13</a></td></tr> <tr><td width='100' align='center' data-sortkey='04297'><a href='https://www.sqlite.org/src/timeline?c=6d326d44fd&y=ci'>2012-05-22</a></td> <td width='100' align='center' data-sortkey='3071201'><a href="releaselog/3_7_12_1.html">3.7.12.1</a></td></tr> -<tr><td width='100' align='center' data-sortkey='04289'><a href='https://www.sqlite.org/src/timeline?c=d9348b2a4e&y=ci'>2012-05-14</a></td> -<td width='100' align='center' data-sortkey='3071200'><a href="releaselog/3_7_12.html">3.7.12</a></td></tr> -<tr><td width='100' align='center' data-sortkey='04289'><a href='https://www.sqlite.org/src/timeline?c=be71d2f667&y=ci'>2012-05-14</a></td> -<td width='100' align='center' data-sortkey='3071200'><a href="releaselog/3_7_12.html">3.7.12</a></td></tr> <tr><td width='100' align='center' data-sortkey='04289'><a href='https://www.sqlite.org/src/timeline?c=8654aa9540&y=ci'>2012-05-14</a></td> <td width='100' align='center' data-sortkey='3071200'><a href="releaselog/3_7_12.html">3.7.12</a></td></tr> <tr><td width='100' align='center' data-sortkey='04234'><a href='https://www.sqlite.org/src/timeline?c=00bb9c9ce4&y=ci'>2012-03-20</a></td> @@ -945,8 +947,8 @@ var t = new SortableTable(document.getElementById("chrontab"),"nK",1); </script> <p> -<i>348 releases -over 23.7 years.</i> +<i>349 releases +over 23.8 years.</i> <p align="center"><small><i>This page last modified on <a href="https://sqlite.org/docsrc/honeypot" id="mtimelink" data-href="https://sqlite.org/docsrc/finfo/pages/chronology.in?m=5d8275493b">2023-03-03 01:19:02</a> UTC </small></i></p> diff --git a/www/cli.html b/www/cli.html index 6ed5de9..773c353 100644 --- a/www/cli.html +++ b/www/cli.html @@ -562,7 +562,7 @@ sqlite> <p>In "column" mode (and also in "box", "table", and "markdown" modes) the width of columns adjusts automatically. But you can override this, -providing a speicified width for each column using the ".width" command. +providing a specified width for each column using the ".width" command. The arguments to ".width" are integers which are the number of characters to devote to each column. Negative numbers mean right-justify. Thus:</p> @@ -2046,5 +2046,5 @@ provide a full-featured command-line shell: </li><li> <a href="compile.html#enable_fts4">-DSQLITE_ENABLE_FTS4</a> </li><li> <a href="compile.html#enable_fts5">-DSQLITE_ENABLE_FTS5</a> </li></ul> -<p align="center"><small><i>This page last modified on <a href="https://sqlite.org/docsrc/honeypot" id="mtimelink" data-href="https://sqlite.org/docsrc/finfo/pages/cli.in?m=ab1e42c23b">2023-12-05 14:43:20</a> UTC </small></i></p> +<p align="center"><small><i>This page last modified on <a href="https://sqlite.org/docsrc/honeypot" id="mtimelink" data-href="https://sqlite.org/docsrc/finfo/pages/cli.in?m=b6fcfaaa3a">2024-04-16 17:22:18</a> UTC </small></i></p> diff --git a/www/compile.html b/www/compile.html index 437ac3a..9d93392 100644 --- a/www/compile.html +++ b/www/compile.html @@ -293,15 +293,25 @@ the SQLite library will be approximately 3% smaller and use about 5% fewer CPU cycles. So these options do not make a huge difference. But in some design situations, every little bit helps. +</p><p>Library-level configuration options, such as those listed above, +may optionally be defined in a client-side header file. Defining +SQLITE_CUSTOM_INCLUDE=myconfig.h (with no quotes) will cause sqlite3.c +to include myconfig.h early on in the compilation process, enabling +the client to customize the flags without having to explicitly pass +all of them to the compiler. + <a name="osconfig"></a> </p><h1 id="_platform_configuration"><span>3. </span> Platform Configuration</h1> <a name="sqlite_config_h"></a> <p><b>_HAVE_SQLITE_CONFIG_H</b></p><blockquote><p> If the _HAVE_SQLITE_CONFIG_H macro is defined - then the SQLite source code will attempt to #include a file named "config.h". - The "config.h" file usually contains other configuration options, especially - "HAVE_<i>INTERFACE</i>" type options generated by autoconf scripts. + then the SQLite source code will attempt to #include a file named "sqlite_cfg.h". + The "sqlite_cfg.h" file usually contains other configuration options, especially + "HAVE_<i>INTERFACE</i>" type options generated by autoconf scripts. Note that this + header is intended only for use for platform-level configuration, not library-level + configuration. To set SQLite-level configuration flags in a custom header, define + SQLITE_CUSTOM_INCLUDE=myconfig.h, as described in the previous section. </p></blockquote><a name="fdatasync"></a> <p><b>HAVE_FDATASYNC</b></p><blockquote><p> If the HAVE_FDATASYNC compile-time option is true, then the default <a href="vfs.html">VFS</a> @@ -1024,7 +1034,7 @@ the available settings:</p> destroyed. When this option is enabled and an illegal API usage is detected, the interface will typically return SQLITE_MISUSE. <p> - The SQLITE_ENABLE_API_ARMOR option does not guarantee that all + The SQLITE_ENABLE_API_ARMOR option does not guarantee that all illegal API usages will be detected. Even when SQLITE_ENABLE_API_ARMOR is enabled, passing incorrect values into the C-language APIs can cause a process crash due to segmentation @@ -1032,15 +1042,15 @@ the available settings:</p> SQLITE_ENABLE_API_ARMOR compile-time option is intended as an aid for application testing and debugging option. Applications should not depend SQLITE_ENABLE_API_ARMOR for safety. - SQLITE_ENABLE_API_ARMORE is appropriate as a second line of + SQLITE_ENABLE_API_ARMOR is appropriate as a second line of defense against application bugs, but it should not be the only defense. If any SQLite interface returns SQLITE_MISUSE, that indicates that the application is using SQLite contrary to the spec and that the application contains a bug. The SQLITE_MISUSE return provides the application with the opportunity to respond - gracefully to that bug, rather than simply crashing the process, - but nothing more. Applications should not make use of nor depend - upon SQLITE_MISUSE for routine processing. + gracefully to that bug, rather than simply crashing the process or + invoking undefined behavior, but nothing more. Applications should + neither make use of nor depend upon SQLITE_MISUSE for routine processing. </p></blockquote><a name="enable_atomic_write"></a> <p><b>SQLITE_ENABLE_ATOMIC_WRITE</b></p><blockquote><p> If this C-preprocessor macro is defined and if the @@ -2129,5 +2139,5 @@ macros is included for completeness.</p> This macro may not be used in combination with any of <a href="compile.html#apicall">SQLITE_APICALL</a>, <a href="compile.html#callback">SQLITE_CALLBACK</a>, <a href="compile.html#cdecl">SQLITE_CDECL</a> or <a href="compile.html#sysapi">SQLITE_SYSAPI</a>. </p></blockquote> - +<p align="center"><small><i>This page last modified on <a href="https://sqlite.org/docsrc/honeypot" id="mtimelink" data-href="https://sqlite.org/docsrc/finfo/pages/compile.in?m=d1dca65e6b">2024-05-09 08:10:19</a> UTC </small></i></p> diff --git a/www/copyright.html b/www/copyright.html index aec24b5..b2e99fd 100644 --- a/www/copyright.html +++ b/www/copyright.html @@ -196,7 +196,7 @@ sources on the internet. <p> SQLite is in the public domain and does not require a license. Even so, some organizations want legal proof of their right to use -SQLite. Circumstances where this might occurs include the following: +SQLite. Circumstances where this might occur include the following: </p> <ul> @@ -221,7 +221,7 @@ all the developers of SQLite, will a Warranty of Title for SQLite</a>. A Warranty of Title is a legal document that asserts that the claimed authors of SQLite are the true authors, and that the authors -have the legal right to dedicate the SQLite to the public domain, and +have the legal right to dedicate the SQLite library into the public domain, and that Hwaci will vigorously defend against challenges to those claims. All proceeds from the sale of SQLite Warranties of Title are used to fund continuing improvement and support of SQLite. @@ -235,5 +235,5 @@ the project does not accept patches. If you would like to suggest a change and you include a patch as a proof-of-concept, that would be great. However, please do not be offended if we rewrite your patch from scratch. -<p align="center"><small><i>This page last modified on <a href="https://sqlite.org/docsrc/honeypot" id="mtimelink" data-href="https://sqlite.org/docsrc/finfo/pages/copyright.in?m=19090139cc">2022-04-18 02:55:50</a> UTC </small></i></p> +<p align="center"><small><i>This page last modified on <a href="https://sqlite.org/docsrc/honeypot" id="mtimelink" data-href="https://sqlite.org/docsrc/finfo/pages/copyright.in?m=8efc05353b">2024-05-05 15:23:53</a> UTC </small></i></p> diff --git a/www/crew.html b/www/crew.html index fa6704a..4dfad8c 100644 --- a/www/crew.html +++ b/www/crew.html @@ -158,11 +158,13 @@ Dan has been a key contributor to SQLite since 2002. <img src="images/joe1.jpg" align="left" hspace="25" vspace="0"> <p> <b>Joe Mistachkin</b> -(pronounced "miss-tash-kin") is a software engineer and one -of the maintainers of Tcl/Tk. He is also the author of the TclBridge -component and the Eagle scripting language. He has been working in the -software industry since 1994. +(pronounced "miss-tash-kin") is a software engineer, one of the +maintainers of <a href="https://www.tcl.tk/">Tcl/Tk</a>, and the founder +of <a href="https://www.mistachkin.com/">Mistachkin Systems</a>. He is +also the author of the TclBridge component and the <a href="https://eagle.to/">Eagle</a> +scripting language. He has been working in the software industry +since 1994. <br clear="both"> -</p><p align="center"><small><i>This page last modified on <a href="https://sqlite.org/docsrc/honeypot" id="mtimelink" data-href="https://sqlite.org/docsrc/finfo/pages/crew.in?m=520fe02caf">2022-01-08 05:02:57</a> UTC </small></i></p> +</p><p align="center"><small><i>This page last modified on <a href="https://sqlite.org/docsrc/honeypot" id="mtimelink" data-href="https://sqlite.org/docsrc/finfo/pages/crew.in?m=5a7597b66c">2024-05-09 21:15:44</a> UTC </small></i></p> diff --git a/www/different.html b/www/different.html index 64dee1b..c1edd8f 100644 --- a/www/different.html +++ b/www/different.html @@ -214,11 +214,10 @@ database engines. <p><b>Compact</b></p> <blockquote> When optimized for size, the whole SQLite library with everything enabled - is <a href="footprint.html">less than 500KiB in size</a> + is <a href="footprint.html">less than 1MiB in size</a> (as measured on an ix86 using the "size" utility from the GNU compiler suite.) Unneeded features can be disabled - at compile-time to further reduce the size of the library to under - 300KiB if desired. + at compile-time to further reduce the size of the library even further. <p> Most other SQL database engines are much larger than this. IBM boasts that its recently released CloudScape database engine is "only" a 2MiB @@ -354,5 +353,5 @@ database engines. and <a href="c3ref/create_collation.html">collating sequences</a>. </blockquote> -<p align="center"><small><i>This page last modified on <a href="https://sqlite.org/docsrc/honeypot" id="mtimelink" data-href="https://sqlite.org/docsrc/finfo/pages/different.in?m=95a3317bd2">2022-04-18 02:55:50</a> UTC </small></i></p> +<p align="center"><small><i>This page last modified on <a href="https://sqlite.org/docsrc/honeypot" id="mtimelink" data-href="https://sqlite.org/docsrc/finfo/pages/different.in?m=bd7c209359">2024-05-08 11:54:12</a> UTC </small></i></p> diff --git a/www/doc_backlink_crossref.html b/www/doc_backlink_crossref.html index 10a2e62..8abf1fd 100644 --- a/www/doc_backlink_crossref.html +++ b/www/doc_backlink_crossref.html @@ -367,6 +367,7 @@ antiRobotDefense(); <a href="lang_createtable.html#tablecoldef">lang_createtable.html#tablecoldef</a> <a href="lang_select.html#fromclause">lang_select.html#fromclause</a> <a href="oldnews.html">oldnews.html</a> + <a href="optoverview.html#flattening">optoverview.html#flattening</a> <a href="optoverview.html#like_opt">optoverview.html#like_opt</a> <a href="withoutrowid.html">withoutrowid.html</a> <li>affshort → <a href="appfileformat.html">appfileformat.html</a> @@ -411,7 +412,7 @@ antiRobotDefense(); <a href="fileformat2.html#serialtype">fileformat2.html#serialtype</a> <a href="foreignkeys.html#fk_actions">foreignkeys.html#fk_actions</a> <a href="lang.html">lang.html</a> - <a href="lang_analyze.html#req">lang_analyze.html#req</a> + <a href="lang_analyze.html#statanal">lang_analyze.html#statanal</a> <a href="lang_createtable.html#notnullconst">lang_createtable.html#notnullconst</a> <a href="lang_createtrigger.html">lang_createtrigger.html</a> <a href="lang_naming.html">lang_naming.html</a> @@ -513,12 +514,15 @@ antiRobotDefense(); <a href="howtocompile.html#cli">howtocompile.html#cli</a> <a href="releaselog/3_11_0.html">releaselog/3_11_0.html</a> <a href="releaselog/3_11_1.html">releaselog/3_11_1.html</a> +<li>ambiguous dates → <a href="changes.html#version_3_46_0">changes.html#version_3_46_0</a> + <a href="releaselog/3_46_0.html">releaselog/3_46_0.html</a> <li>American Fuzzy Lop fuzzer → <a href="changes.html#version_3_8_10">changes.html#version_3_8_10</a> <a href="releaselog/3_8_10.html">releaselog/3_8_10.html</a> <a href="releaselog/3_8_10_1.html">releaselog/3_8_10_1.html</a> <a href="releaselog/3_8_10_2.html">releaselog/3_8_10_2.html</a> <li>analysis_limit → <a href="lang_analyze.html#approx">lang_analyze.html#approx</a> -<li>analysis_limit pragma → <a href="lang_analyze.html#req">lang_analyze.html#req</a> +<li>analysis_limit pragma → <a href="changes.html#version_3_46_0">changes.html#version_3_46_0</a> + <a href="releaselog/3_46_0.html">releaselog/3_46_0.html</a> <li>ANALYZE → <a href="appfileformat.html">appfileformat.html</a> <a href="c3ref/stmt_scanstatus.html">c3ref/stmt_scanstatus.html</a> <a href="capi3ref.html#sqlite3_stmt_scanstatus">capi3ref.html#sqlite3_stmt_scanstatus</a> @@ -543,12 +547,12 @@ antiRobotDefense(); <a href="news.html">news.html</a> <a href="oldnews.html">oldnews.html</a> <a href="optoverview.html#autoindex">optoverview.html#autoindex</a> + <a href="optoverview.html#joins">optoverview.html#joins</a> <a href="optoverview.html#manctrl">optoverview.html#manctrl</a> <a href="optoverview.html#multi_index">optoverview.html#multi_index</a> <a href="optoverview.html#option2">optoverview.html#option2</a> <a href="optoverview.html#rangequery">optoverview.html#rangequery</a> <a href="optoverview.html#skipscan">optoverview.html#skipscan</a> - <a href="optoverview.html#table_order">optoverview.html#table_order</a> <a href="pragma.html#pragma_analysis_limit">pragma.html#pragma_analysis_limit</a> <a href="pragma.html#pragma_optimize">pragma.html#pragma_optimize</a> <a href="queryplanner-ng.html#fossilcasestudy">queryplanner-ng.html#fossilcasestudy</a> @@ -657,6 +661,7 @@ antiRobotDefense(); <a href="releaselog/3_32_1.html">releaselog/3_32_1.html</a> <a href="releaselog/3_32_2.html">releaselog/3_32_2.html</a> <a href="releaselog/3_32_3.html">releaselog/3_32_3.html</a> +<li>Approximate ANALYZE For Large Databases → <a href="lang_analyze.html#pragopt">lang_analyze.html#pragopt</a> <li>asin → <a href="lang_mathfunc.html">lang_mathfunc.html</a> <li>asinh → <a href="lang_mathfunc.html">lang_mathfunc.html</a> <li>asynchronous I/O backend → <a href="oldnews.html">oldnews.html</a> @@ -751,6 +756,8 @@ antiRobotDefense(); <a href="releaselog/3_19_2.html">releaselog/3_19_2.html</a> <a href="releaselog/3_19_3.html">releaselog/3_19_3.html</a> <li>auto modifier → <a href="changes.html#version_3_38_0">changes.html#version_3_38_0</a> + <a href="lang_datefunc.html">lang_datefunc.html</a> + <a href="lang_datefunc.html#tmval">lang_datefunc.html#tmval</a> <a href="releaselog/3_38_0.html">releaselog/3_38_0.html</a> <a href="releaselog/3_38_1.html">releaselog/3_38_1.html</a> <a href="releaselog/3_38_2.html">releaselog/3_38_2.html</a> @@ -822,6 +829,7 @@ antiRobotDefense(); <a href="releaselog/3_9_3.html">releaselog/3_9_3.html</a> <a href="rescode.html#warning_autoindex">rescode.html#warning_autoindex</a> <li>automatic_index pragma → <a href="optoverview.html#autoindex">optoverview.html#autoindex</a> +<li>Automatically Running ANALYZE → <a href="lang_analyze.html#pragopt">lang_analyze.html#pragopt</a> <li>automerge command → <a href="changes.html#version_3_8_5">changes.html#version_3_8_5</a> <a href="releaselog/3_8_5.html">releaselog/3_8_5.html</a> <li>auxiliary columns → <a href="rtree.html#xshadow">rtree.html#xshadow</a> @@ -965,6 +973,7 @@ antiRobotDefense(); <a href="releaselog/3_37_2.html">releaselog/3_37_2.html</a> <a href="rowvalue.html#rvinop">rowvalue.html#rvinop</a> <a href="vtab.html#colUsed">vtab.html#colUsed</a> + <a href="whybytecode.html">whybytecode.html</a> <li>bytecode and tables_used virtual tables → <a href="compile.html#enable_bytecode_vtab">compile.html#enable_bytecode_vtab</a> <li>bytecode engine → <a href="changes.html#version_3_35_3">changes.html#version_3_35_3</a> <a href="changes.html#version_3_45_1">changes.html#version_3_45_1</a> @@ -1309,6 +1318,7 @@ antiRobotDefense(); <a href="releaselog/3_45_1.html">releaselog/3_45_1.html</a> <a href="releaselog/3_45_2.html">releaselog/3_45_2.html</a> <a href="releaselog/3_45_3.html">releaselog/3_45_3.html</a> + <a href="releaselog/3_46_0.html">releaselog/3_46_0.html</a> <a href="releaselog/3_4_0.html">releaselog/3_4_0.html</a> <a href="releaselog/3_4_1.html">releaselog/3_4_1.html</a> <a href="releaselog/3_4_2.html">releaselog/3_4_2.html</a> @@ -1633,6 +1643,7 @@ antiRobotDefense(); <a href="releaselog/3_6_21.html">releaselog/3_6_21.html</a> <a href="releaselog/3_6_23.html">releaselog/3_6_23.html</a> <li>command-line interface → <a href="features.html">features.html</a> + <a href="lang_analyze.html#statanal">lang_analyze.html#statanal</a> <li>command-line shell → <a href="changes.html#version_3_10_0">changes.html#version_3_10_0</a> <a href="changes.html#version_3_11_0">changes.html#version_3_11_0</a> <a href="changes.html#version_3_12_0">changes.html#version_3_12_0</a> @@ -1982,6 +1993,7 @@ antiRobotDefense(); <a href="releaselog/3_45_1.html">releaselog/3_45_1.html</a> <a href="releaselog/3_45_2.html">releaselog/3_45_2.html</a> <a href="releaselog/3_45_3.html">releaselog/3_45_3.html</a> + <a href="releaselog/3_46_0.html">releaselog/3_46_0.html</a> <a href="releaselog/3_4_0.html">releaselog/3_4_0.html</a> <a href="releaselog/3_4_1.html">releaselog/3_4_1.html</a> <a href="releaselog/3_4_2.html">releaselog/3_4_2.html</a> @@ -2230,6 +2242,7 @@ antiRobotDefense(); <a href="fullsql.html">fullsql.html</a> <a href="lang.html">lang.html</a> <a href="lang_altertable.html#otheralter">lang_altertable.html#otheralter</a> + <a href="lang_analyze.html#pragopt">lang_analyze.html#pragopt</a> <a href="lang_dropindex.html">lang_dropindex.html</a> <a href="limits.html#max_page_count">limits.html#max_page_count</a> <a href="oldnews.html">oldnews.html</a> @@ -2240,6 +2253,7 @@ antiRobotDefense(); <a href="pragma.html#pragma_index_xinfo">pragma.html#pragma_index_xinfo</a> <a href="pragma.html#pragma_journal_mode">pragma.html#pragma_journal_mode</a> <a href="pragma.html#pragma_legacy_alter_table">pragma.html#pragma_legacy_alter_table</a> + <a href="pragma.html#pragma_optimize">pragma.html#pragma_optimize</a> <a href="releaselog/3_7_8.html">releaselog/3_7_8.html</a> <a href="releaselog/3_8_10.html">releaselog/3_8_10.html</a> <a href="releaselog/3_8_10_1.html">releaselog/3_8_10_1.html</a> @@ -2513,7 +2527,6 @@ antiRobotDefense(); <a href="pragma.html#pragma_journal_mode">pragma.html#pragma_journal_mode</a> <a href="pragma.html#pragma_legacy_alter_table">pragma.html#pragma_legacy_alter_table</a> <a href="pragma.html#pragma_mmap_size">pragma.html#pragma_mmap_size</a> - <a href="pragma.html#pragma_optimize">pragma.html#pragma_optimize</a> <a href="releaselog/3_5_8.html">releaselog/3_5_8.html</a> <a href="releaselog/3_6_1.html">releaselog/3_6_1.html</a> <a href="releaselog/3_7_17.html">releaselog/3_7_17.html</a> @@ -2588,11 +2601,13 @@ antiRobotDefense(); <a href="changes.html#version_3_38_1">changes.html#version_3_38_1</a> <a href="changes.html#version_3_42_0">changes.html#version_3_42_0</a> <a href="changes.html#version_3_43_0">changes.html#version_3_43_0</a> + <a href="changes.html#version_3_46_0">changes.html#version_3_46_0</a> <a href="compile.html#gmtime_r">compile.html#gmtime_r</a> <a href="compile.html#localtime_r">compile.html#localtime_r</a> <a href="compile.html#localtime_s">compile.html#localtime_s</a> <a href="datatype3.html#datetime">datatype3.html#datetime</a> <a href="deterministic.html#dtexception">deterministic.html#dtexception</a> + <a href="news.html">news.html</a> <a href="quirks.html">quirks.html</a> <a href="releaselog/3_10_0.html">releaselog/3_10_0.html</a> <a href="releaselog/3_10_1.html">releaselog/3_10_1.html</a> @@ -2615,6 +2630,7 @@ antiRobotDefense(); <a href="releaselog/3_43_0.html">releaselog/3_43_0.html</a> <a href="releaselog/3_43_1.html">releaselog/3_43_1.html</a> <a href="releaselog/3_43_2.html">releaselog/3_43_2.html</a> + <a href="releaselog/3_46_0.html">releaselog/3_46_0.html</a> <li>date/time special case → <a href="changes.html#version_3_20_0">changes.html#version_3_20_0</a> <a href="releaselog/3_20_0.html">releaselog/3_20_0.html</a> <a href="releaselog/3_20_1.html">releaselog/3_20_1.html</a> @@ -2708,7 +2724,7 @@ antiRobotDefense(); <a href="fullsql.html">fullsql.html</a> <a href="isolation.html">isolation.html</a> <a href="lang.html">lang.html</a> - <a href="lang_analyze.html#req">lang_analyze.html#req</a> + <a href="lang_analyze.html#statanal">lang_analyze.html#statanal</a> <a href="lang_createtable.html#notnullconst">lang_createtable.html#notnullconst</a> <a href="lang_createtrigger.html">lang_createtrigger.html</a> <a href="lang_createview.html">lang_createview.html</a> @@ -2822,7 +2838,7 @@ antiRobotDefense(); <a href="fts3.html#fts4">fts3.html#fts4</a> <a href="lang.html">lang.html</a> <a href="lang_altertable.html#otheralter">lang_altertable.html#otheralter</a> - <a href="lang_analyze.html#req">lang_analyze.html#req</a> + <a href="lang_analyze.html#statanal">lang_analyze.html#statanal</a> <a href="lang_createtable.html">lang_createtable.html</a> <a href="lang_createtrigger.html">lang_createtrigger.html</a> <a href="lang_createvtab.html">lang_createvtab.html</a> @@ -3181,6 +3197,7 @@ antiRobotDefense(); <a href="intern-v-extern-blob.html">intern-v-extern-blob.html</a> <a href="whentouse.html#appfileformat">whentouse.html#appfileformat</a> <a href="whentouse.html#container">whentouse.html#container</a> + <a href="whybytecode.html">whybytecode.html</a> <li>file control → <a href="c3ref/snapshot_recover.html">c3ref/snapshot_recover.html</a> <a href="c3ref/total_changes.html">c3ref/total_changes.html</a> <a href="capi3ref.html#sqlite3_snapshot_recover">capi3ref.html#sqlite3_snapshot_recover</a> @@ -3249,6 +3266,7 @@ antiRobotDefense(); <a href="windowfunctions.html#wexcls">windowfunctions.html#wexcls</a> <li>flattened → <a href="changes.html#version_3_35_0">changes.html#version_3_35_0</a> <a href="lang_with.html#mathint">lang_with.html#mathint</a> + <a href="optoverview.html#coroutines">optoverview.html#coroutines</a> <a href="optoverview.html#pushdown">optoverview.html#pushdown</a> <a href="releaselog/3_35_0.html">releaselog/3_35_0.html</a> <a href="releaselog/3_35_1.html">releaselog/3_35_1.html</a> @@ -3870,7 +3888,7 @@ antiRobotDefense(); <li>http://en.wikipedia.org/wiki/ACID → <a href="about.html">about.html</a> <a href="transactional.html">transactional.html</a> <li>http://en.wikipedia.org/wiki/Charlotte,_North_Carolina → <a href="crew.html">crew.html</a> -<li>http://en.wikipedia.org/wiki/Coordinated_Universal_Time → <a href="lang_datefunc.html#tmdif">lang_datefunc.html#tmdif</a> +<li>http://en.wikipedia.org/wiki/Coordinated_Universal_Time → <a href="lang_datefunc.html#tmval">lang_datefunc.html#tmval</a> <li>http://en.wikipedia.org/wiki/Endianness → <a href="about.html">about.html</a> <a href="onefile.html">onefile.html</a> <li>http://en.wikipedia.org/wiki/Fuzz_testing → <a href="testing.html#fuzztesting">testing.html#fuzztesting</a> @@ -3878,7 +3896,7 @@ antiRobotDefense(); <li>http://en.wikipedia.org/wiki/ISO_8601 → <a href="lang_datefunc.html">lang_datefunc.html</a> <li>http://en.wikipedia.org/wiki/Julian_day → <a href="lang_datefunc.html">lang_datefunc.html</a> <a href="lang_datefunc.html#jlndy">lang_datefunc.html#jlndy</a> - <a href="lang_datefunc.html#tmdif">lang_datefunc.html#tmdif</a> + <a href="lang_datefunc.html#tmval">lang_datefunc.html#tmval</a> <li>http://en.wikipedia.org/wiki/Kibibyte → <a href="oldnews.html">oldnews.html</a> <li>http://en.wikipedia.org/wiki/Modified_Condition/Decision_Coverage → <a href="testing.html#mcdc">testing.html#mcdc</a> <li>http://en.wikipedia.org/wiki/OpenDocument → <a href="affcase1.html">affcase1.html</a> @@ -3887,7 +3905,7 @@ antiRobotDefense(); <li>http://en.wikipedia.org/wiki/R-tree → <a href="rtree.html">rtree.html</a> <li>http://en.wikipedia.org/wiki/Serializability → <a href="transactional.html">transactional.html</a> <li>http://en.wikipedia.org/wiki/Syslog → <a href="errlog.html">errlog.html</a> -<li>http://en.wikipedia.org/wiki/Unix_time → <a href="lang_datefunc.html#tmshf">lang_datefunc.html#tmshf</a> +<li>http://en.wikipedia.org/wiki/Unix_time → <a href="lang_datefunc.html#jdmod">lang_datefunc.html#jdmod</a> <li>http://en.wikipedia.org/wiki/UUID → <a href="changes.html#version_3_3_13">changes.html#version_3_3_13</a> <a href="releaselog/3_3_13.html">releaselog/3_3_13.html</a> <li>http://en.wikipedia.org/wiki/Zip_%28file_format%29 → <a href="affcase1.html">affcase1.html</a> @@ -4013,7 +4031,7 @@ antiRobotDefense(); <li>http://www.tcl.tk/ → <a href="sqlanalyze.html">sqlanalyze.html</a> <a href="th3.html">th3.html</a> <li>http://www.valgrind.org/ → <a href="qmplan.html">qmplan.html</a> -<li>http://www.w3c.org/TR/NOTE-datetime → <a href="lang_datefunc.html#tmdif">lang_datefunc.html#tmdif</a> +<li>http://www.w3c.org/TR/NOTE-datetime → <a href="lang_datefunc.html#tmval">lang_datefunc.html#tmval</a> <li>http://www.xojo.com/ → <a href="famous.html">famous.html</a> <li>http://zlib.net/ → <a href="sqlar.html">sqlar.html</a> <li>https://airsdk.harman.com → <a href="famous.html">famous.html</a> @@ -4026,7 +4044,9 @@ antiRobotDefense(); <li>https://developers.google.com/open-source/osa#2005-google-oreilly-open-source-award-winners → <a href="oldnews.html">oldnews.html</a> <li>https://digitalocean.com → <a href="qmplan.html">qmplan.html</a> <li>https://docs.microsoft.com/en-us/azure/cosmos-db/serverless-computing-database → <a href="serverless.html">serverless.html</a> +<li>https://eagle.to/ → <a href="crew.html#dan">crew.html#dan</a> <li>https://en.wikipedia.org/wiki/Abstract_syntax_tree → <a href="howitworks.html">howitworks.html</a> + <a href="whybytecode.html">whybytecode.html</a> <li>https://en.wikipedia.org/wiki/Artificial_intelligence → <a href="queryplanner.html">queryplanner.html</a> <li>https://en.wikipedia.org/wiki/Assert.h → <a href="assert.html">assert.html</a> <li>https://en.wikipedia.org/wiki/Berkeley_DB → <a href="howitworks.html">howitworks.html</a> @@ -4036,6 +4056,7 @@ antiRobotDefense(); <a href="releaselog/3_10_2.html">releaselog/3_10_2.html</a> <li>https://en.wikipedia.org/wiki/Database_index#Clustered → <a href="withoutrowid.html">withoutrowid.html</a> <li>https://en.wikipedia.org/wiki/Database_transaction → <a href="howitworks.html">howitworks.html</a> +<li>https://en.wikipedia.org/wiki/Dataflow_programming → <a href="whybytecode.html">whybytecode.html</a> <li>https://en.wikipedia.org/wiki/Declarative_programming → <a href="howitworks.html">howitworks.html</a> <li>https://en.wikipedia.org/wiki/DO-178B → <a href="hirely.html">hirely.html</a> <a href="qmplan.html">qmplan.html</a> @@ -4048,12 +4069,16 @@ antiRobotDefense(); <li>https://en.wikipedia.org/wiki/Hash_join → <a href="optoverview.html#hashjoin">optoverview.html#hashjoin</a> <li>https://en.wikipedia.org/wiki/Imperative_programming → <a href="howitworks.html">howitworks.html</a> <li>https://en.wikipedia.org/wiki/Information_schema → <a href="pragma.html#pragfunc">pragma.html#pragfunc</a> +<li>https://en.wikipedia.org/wiki/Java_virtual_machine → <a href="whybytecode.html">whybytecode.html</a> <li>https://en.wikipedia.org/wiki/Julian_day → <a href="quirks.html">quirks.html</a> <li>https://en.wikipedia.org/wiki/LALR_parser → <a href="howitworks.html">howitworks.html</a> + <a href="whybytecode.html">whybytecode.html</a> <li>https://en.wikipedia.org/wiki/Library_(computing) → <a href="howitworks.html">howitworks.html</a> <li>https://en.wikipedia.org/wiki/Linus%27s_law → <a href="testing.html#3pfuzz">testing.html#3pfuzz</a> <li>https://en.wikipedia.org/wiki/Modified_condition/decision_coverage → <a href="th3.html">th3.html</a> <li>https://en.wikipedia.org/wiki/Mutation_testing → <a href="testing.html#mutationtests">testing.html#mutationtests</a> +<li>https://en.wikipedia.org/wiki/Online_analytical_processing → <a href="whybytecode.html">whybytecode.html</a> +<li>https://en.wikipedia.org/wiki/Online_transaction_processing → <a href="whybytecode.html">whybytecode.html</a> <li>https://en.wikipedia.org/wiki/Patch_(Unix) → <a href="sessionintro.html">sessionintro.html</a> <li>https://en.wikipedia.org/wiki/Recursive_descent_parser → <a href="compile.html#json_max_depth">compile.html#json_max_depth</a> <li>https://en.wikipedia.org/wiki/Robustness_principle → <a href="lang_select.html#nonstd">lang_select.html#nonstd</a> @@ -4071,7 +4096,9 @@ antiRobotDefense(); <a href="th3.html">th3.html</a> <li>https://en.wikipedia.org/wiki/Tar_(computing) → <a href="sqlar.html">sqlar.html</a> <li>https://en.wikipedia.org/wiki/Tcl → <a href="vtablist.html">vtablist.html</a> +<li>https://en.wikipedia.org/wiki/Unix_time → <a href="lang_datefunc.html">lang_datefunc.html</a> <li>https://en.wikipedia.org/wiki/Web_SQL_Database → <a href="bindptr.html">bindptr.html</a> +<li>https://en.wikipedia.org/wiki/WebAssembly → <a href="whybytecode.html">whybytecode.html</a> <li>https://en.wikipedia.org/wiki/Yacc → <a href="lemon.html">lemon.html</a> <li>https://en.wikipedia.org/wiki/Zip_%28file_format%29 → <a href="zipfile.html">zipfile.html</a> <li>https://en.wikipedia.org/wiki/Zip_(file_format) → <a href="changes.html#version_3_22_0">changes.html#version_3_22_0</a> @@ -4153,6 +4180,10 @@ antiRobotDefense(); <a href="json1.html#json5">json1.html#json5</a> <li>https://spec.json5.org/#introduction → <a href="json1.html#json5">json1.html#json5</a> <li>https://sqlite.org/docsrc/finfo/pages/whynotgit.in → <a href="whynotgit.html">whynotgit.html</a> +<li>https://sqlite.org/forum → <a href="optoverview.html#option2">optoverview.html#option2</a> + <a href="optoverview.html#uplus">optoverview.html#uplus</a> + <a href="queryplanner-ng.html#howtofix">queryplanner-ng.html#howtofix</a> + <a href="whybytecode.html">whybytecode.html</a> <li>https://sqlite.org/forum/about → <a href="cves.html#cvetab">cves.html#cvetab</a> <li>https://sqlite.org/forum/forum → <a href="flextypegood.html">flextypegood.html</a> <a href="quirks.html">quirks.html</a> @@ -4532,6 +4563,7 @@ antiRobotDefense(); <li>https://www.loc.gov/preservation/resources/rfs/data.html → <a href="locrsf.html">locrsf.html</a> <li>https://www.microsoft.com/en-us/research/people/gray/ → <a href="fasterthanfs.html">fasterthanfs.html</a> <li>https://www.microsoft.com/en-us/research/publication/to-blob-or-not-to-blob-large-object-storage-in-a-database-or-a-filesystem/ → <a href="fasterthanfs.html">fasterthanfs.html</a> +<li>https://www.mistachkin.com/ → <a href="crew.html#dan">crew.html#dan</a> <li>https://www.neooffice.org/neojava/en/index.php → <a href="affcase1.html">affcase1.html</a> <li>https://www.postgresql.org → <a href="lang_returning.html">lang_returning.html</a> <li>https://www.reddit.com/r/programming/comments/84fzoc/why_is_sqlite_coded_in_c/ → <a href="whyc.html">whyc.html</a> @@ -5166,6 +5198,7 @@ antiRobotDefense(); <li>https://www.sqlite.org/src/vdiff?from=e4ab094f8afce0817f4074e823fabe59fc29ebb4&to=83afe23e553e802c0947c80d0ffdd120423e7c52&sbs=1 → <a href="oldnews.html">oldnews.html</a> <li>https://www.sqlite.org/src/vpatch?from=version-3.9.0&to=version-3.9.1 → <a href="oldnews.html">oldnews.html</a> <li>https://www.sqlite.org/th3 → <a href="qmplan.html">qmplan.html</a> +<li>https://www.tcl.tk/ → <a href="crew.html#dan">crew.html#dan</a> <li>https://www.tcl.tk/man/tcl8.3/UserCmd/tclsh.htm → <a href="cli.html#compiling">cli.html#compiling</a> <li>https://www2.eecs.berkeley.edu/Pubs/TechRpts/2006/EECS-2006-1.html → <a href="faq.html#q6">faq.html#q6</a> <li>https://www2.sqlite.org → <a href="qmplan.html">qmplan.html</a> @@ -5343,7 +5376,7 @@ antiRobotDefense(); <a href="fullsql.html">fullsql.html</a> <a href="isolation.html">isolation.html</a> <a href="lang.html">lang.html</a> - <a href="lang_analyze.html#req">lang_analyze.html#req</a> + <a href="lang_analyze.html#statanal">lang_analyze.html#statanal</a> <a href="lang_conflict.html">lang_conflict.html</a> <a href="lang_createtable.html#dfltval">lang_createtable.html#dfltval</a> <a href="lang_createtable.html#notnullconst">lang_createtable.html#notnullconst</a> @@ -5427,7 +5460,7 @@ antiRobotDefense(); <li>internal schema objects → <a href="fileformat2.html#ffschema">fileformat2.html#ffschema</a> <li>internal table → <a href="autoinc.html">autoinc.html</a> <li>internal tables → <a href="lang_analyze.html">lang_analyze.html</a> - <a href="lang_analyze.html#req">lang_analyze.html#req</a> + <a href="lang_analyze.html#statanal">lang_analyze.html#statanal</a> <li>Internal Versus External BLOBs → <a href="aff_short.html">aff_short.html</a> <a href="appfileformat.html">appfileformat.html</a> <a href="fasterthanfs.html">fasterthanfs.html</a> @@ -5460,6 +5493,7 @@ antiRobotDefense(); <a href="releaselog/3_45_2.html">releaselog/3_45_2.html</a> <a href="releaselog/3_45_3.html">releaselog/3_45_3.html</a> <li>join order → <a href="eqp.html">eqp.html</a> + <a href="optoverview.html">optoverview.html</a> <li>join-clause → <a href="lang_aggfunc.html">lang_aggfunc.html</a> <a href="lang_altertable.html">lang_altertable.html</a> <a href="lang_attach.html">lang_attach.html</a> @@ -5552,6 +5586,7 @@ antiRobotDefense(); <li>json → <a href="changes.html#version_3_10_0">changes.html#version_3_10_0</a> <a href="json1.html#jarray">json1.html#jarray</a> <a href="json1.html#jobj">json1.html#jobj</a> + <a href="json1.html#jpretty">json1.html#jpretty</a> <a href="json1.html#jset">json1.html#jset</a> <a href="json1.html#json5">json1.html#json5</a> <a href="json1.html#varg">json1.html#varg</a> @@ -5587,6 +5622,7 @@ antiRobotDefense(); <a href="changes.html#version_3_43_0">changes.html#version_3_43_0</a> <a href="features.html">features.html</a> <a href="fullsql.html">fullsql.html</a> + <a href="lang.html">lang.html</a> <a href="lang_corefunc.html">lang_corefunc.html</a> <a href="lang_expr.html#*funcinexpr">lang_expr.html#*funcinexpr</a> <a href="news.html">news.html</a> @@ -5650,6 +5686,9 @@ antiRobotDefense(); <a href="releaselog/3_18_0.html">releaselog/3_18_0.html</a> <a href="releaselog/3_18_1.html">releaselog/3_18_1.html</a> <a href="releaselog/3_18_2.html">releaselog/3_18_2.html</a> +<li>json_pretty → <a href="changes.html#version_3_46_0">changes.html#version_3_46_0</a> + <a href="news.html">news.html</a> + <a href="releaselog/3_46_0.html">releaselog/3_46_0.html</a> <li>json_quote → <a href="changes.html#version_3_14">changes.html#version_3_14</a> <a href="json1.html#howtocompile">json1.html#howtocompile</a> <a href="releaselog/3_14.html">releaselog/3_14.html</a> @@ -5989,7 +6028,7 @@ antiRobotDefense(); <li>ltrim → <a href="lang_corefunc.html">lang_corefunc.html</a> <li>mailing lists → <a href="bindptr.html">bindptr.html</a> <a href="qmplan.html">qmplan.html</a> -<li>Manual Control Of Query Plans Using SQLITE_STAT Tables → <a href="lang_analyze.html#req">lang_analyze.html#req</a> +<li>Manual Control Of Query Plans Using SQLITE_STAT Tables → <a href="lang_analyze.html#statanal">lang_analyze.html#statanal</a> <li>master journal → <a href="changes.html#version_3_12_0">changes.html#version_3_12_0</a> <a href="releaselog/3_12_0.html">releaselog/3_12_0.html</a> <a href="releaselog/3_12_1.html">releaselog/3_12_1.html</a> @@ -6034,7 +6073,8 @@ antiRobotDefense(); <a href="releaselog/3_35_4.html">releaselog/3_35_4.html</a> <a href="releaselog/3_35_5.html">releaselog/3_35_5.html</a> <li>math functions → <a href="lang_expr.html#*funcinexpr">lang_expr.html#*funcinexpr</a> -<li>mathfunc → <a href="lang_corefunc.html">lang_corefunc.html</a> +<li>mathfunc → <a href="lang.html">lang.html</a> + <a href="lang_corefunc.html">lang_corefunc.html</a> <li>max → <a href="lang_corefunc.html">lang_corefunc.html</a> <li>max_agg → <a href="lang_aggfunc.html#aggfunclist">lang_aggfunc.html#aggfunclist</a> <a href="lang_corefunc.html#max_scalar">lang_corefunc.html#max_scalar</a> @@ -6100,6 +6140,7 @@ antiRobotDefense(); <a href="releaselog/3_15_0.html">releaselog/3_15_0.html</a> <a href="releaselog/3_15_1.html">releaselog/3_15_1.html</a> <a href="releaselog/3_15_2.html">releaselog/3_15_2.html</a> +<li>modifiers → <a href="lang_datefunc.html">lang_datefunc.html</a> <li>most used → <a href="index.html">index.html</a> <li>most widely deployed → <a href="about.html">about.html</a> <a href="appfileformat.html">appfileformat.html</a> @@ -6125,10 +6166,10 @@ antiRobotDefense(); <a href="versionnumbers.html">versionnumbers.html</a> <li>Next Generation Query Planner → <a href="howitworks.html">howitworks.html</a> <a href="optoverview.html">optoverview.html</a> + <a href="optoverview.html#joins">optoverview.html#joins</a> <li>NGQP → <a href="changes.html#version_3_8_0">changes.html#version_3_8_0</a> <a href="limits.html#max_sql_length">limits.html#max_sql_length</a> <a href="oldnews.html">oldnews.html</a> - <a href="optoverview.html">optoverview.html</a> <a href="releaselog/3_8_0.html">releaselog/3_8_0.html</a> <a href="releaselog/3_8_0_1.html">releaselog/3_8_0_1.html</a> <a href="releaselog/3_8_0_2.html">releaselog/3_8_0_2.html</a> @@ -6168,6 +6209,8 @@ antiRobotDefense(); <li>NULLS LAST → <a href="changes.html#version_3_30_0">changes.html#version_3_30_0</a> <a href="releaselog/3_30_0.html">releaselog/3_30_0.html</a> <a href="releaselog/3_30_1.html">releaselog/3_30_1.html</a> +<li>numeric literals → <a href="changes.html#version_3_46_0">changes.html#version_3_46_0</a> + <a href="releaselog/3_46_0.html">releaselog/3_46_0.html</a> <li>numeric-literal → <a href="lang_expr.html#litvalue">lang_expr.html#litvalue</a> <li>object resolution → <a href="lang_dropview.html">lang_dropview.html</a> <li>octet_length → <a href="changes.html#version_3_43_0">changes.html#version_3_43_0</a> @@ -6226,7 +6269,6 @@ antiRobotDefense(); <a href="releaselog/3_31_1.html">releaselog/3_31_1.html</a> <li>OpenOffice case study → <a href="appfileformat.html">appfileformat.html</a> <li>optimize command → <a href="fts3.html#fts4">fts3.html#fts4</a> -<li>optimize pragma → <a href="lang_analyze.html#req">lang_analyze.html#req</a> <li>optimizer → <a href="eqp.html">eqp.html</a> <li>OR optimization → <a href="changes.html#version_3_11_0">changes.html#version_3_11_0</a> <a href="changes.html#version_3_14">changes.html#version_3_14</a> @@ -6496,9 +6538,9 @@ antiRobotDefense(); <a href="vtablist.html">vtablist.html</a> <li>PRAGMA analysis_limit → <a href="changes.html#version_3_32_0">changes.html#version_3_32_0</a> <a href="lang_analyze.html#approx">lang_analyze.html#approx</a> + <a href="lang_analyze.html#pragopt">lang_analyze.html#pragopt</a> <a href="pragma.html#pragma_optimize">pragma.html#pragma_optimize</a> <a href="pragma.html#toc">pragma.html#toc</a> - <a href="queryplanner-ng.html#fossilcasestudy">queryplanner-ng.html#fossilcasestudy</a> <a href="releaselog/3_32_0.html">releaselog/3_32_0.html</a> <a href="releaselog/3_32_1.html">releaselog/3_32_1.html</a> <a href="releaselog/3_32_2.html">releaselog/3_32_2.html</a> @@ -6801,16 +6843,21 @@ antiRobotDefense(); <a href="releaselog/3_30_0.html">releaselog/3_30_0.html</a> <a href="releaselog/3_30_1.html">releaselog/3_30_1.html</a> <li>PRAGMA optimize → <a href="changes.html#version_3_18_0">changes.html#version_3_18_0</a> + <a href="changes.html#version_3_46_0">changes.html#version_3_46_0</a> <a href="lang_analyze.html#approx">lang_analyze.html#approx</a> <a href="lang_analyze.html#autoanalyze">lang_analyze.html#autoanalyze</a> + <a href="lang_analyze.html#pragopt">lang_analyze.html#pragopt</a> <a href="news.html">news.html</a> + <a href="optoverview.html#option2">optoverview.html#option2</a> <a href="pragma.html#pragma_analysis_limit">pragma.html#pragma_analysis_limit</a> <a href="pragma.html#toc">pragma.html#toc</a> <a href="queryplanner-ng.html#fossilcasestudy">queryplanner-ng.html#fossilcasestudy</a> <a href="queryplanner-ng.html#howtofix">queryplanner-ng.html#howtofix</a> + <a href="queryplanner-ng.html#qpstab">queryplanner-ng.html#qpstab</a> <a href="releaselog/3_18_0.html">releaselog/3_18_0.html</a> <a href="releaselog/3_18_1.html">releaselog/3_18_1.html</a> <a href="releaselog/3_18_2.html">releaselog/3_18_2.html</a> + <a href="releaselog/3_46_0.html">releaselog/3_46_0.html</a> <li>PRAGMA page_count → <a href="changes.html#version_3_6_1">changes.html#version_3_6_1</a> <a href="pragma.html#toc">pragma.html#toc</a> <a href="releaselog/3_6_0.html">releaselog/3_6_0.html</a> @@ -6995,6 +7042,7 @@ antiRobotDefense(); <a href="releaselog/3_27_0.html">releaselog/3_27_0.html</a> <a href="releaselog/3_27_1.html">releaselog/3_27_1.html</a> <a href="releaselog/3_27_2.html">releaselog/3_27_2.html</a> + <a href="whybytecode.html">whybytecode.html</a> <li>PRAGMA wal_autocheckpoint → <a href="pragma.html#toc">pragma.html#toc</a> <li>PRAGMA wal_checkpoint → <a href="c3ref/wal_checkpoint_v2.html">c3ref/wal_checkpoint_v2.html</a> <a href="capi3ref.html#sqlite3_wal_checkpoint_v2">capi3ref.html#sqlite3_wal_checkpoint_v2</a> @@ -7117,6 +7165,7 @@ antiRobotDefense(); <a href="threadsafe.html">threadsafe.html</a> <a href="vfs.html">vfs.html</a> <a href="vtablist.html">vtablist.html</a> + <a href="whybytecode.html">whybytecode.html</a> <li>prepared statements → <a href="35to36.html">35to36.html</a> <a href="bytecodevtab.html">bytecodevtab.html</a> <a href="c3ref/c_config_covering_index_scan.html#sqliteconfigmultithread">c3ref/c_config_covering_index_scan.html#sqliteconfigmultithread</a> @@ -7189,7 +7238,6 @@ antiRobotDefense(); <li>push-down optimization → <a href="changes.html#version_3_23_0">changes.html#version_3_23_0</a> <a href="changes.html#version_3_35_0">changes.html#version_3_35_0</a> <a href="changes.html#version_3_35_4">changes.html#version_3_35_4</a> - <a href="changes.html#version_3_42_0">changes.html#version_3_42_0</a> <a href="lang_with.html#mathint">lang_with.html#mathint</a> <a href="releaselog/3_23_0.html">releaselog/3_23_0.html</a> <a href="releaselog/3_23_1.html">releaselog/3_23_1.html</a> @@ -7199,7 +7247,6 @@ antiRobotDefense(); <a href="releaselog/3_35_3.html">releaselog/3_35_3.html</a> <a href="releaselog/3_35_4.html">releaselog/3_35_4.html</a> <a href="releaselog/3_35_5.html">releaselog/3_35_5.html</a> - <a href="releaselog/3_42_0.html">releaselog/3_42_0.html</a> <li>Q → <a href="c3ref/mprintf.html">c3ref/mprintf.html</a> <a href="capi3ref.html#sqlite3_mprintf">capi3ref.html#sqlite3_mprintf</a> <a href="printf.html">printf.html</a> @@ -7250,9 +7297,11 @@ antiRobotDefense(); <a href="changes.html#version_3_20_0">changes.html#version_3_20_0</a> <a href="compile.html#enable_qpsg">compile.html#enable_qpsg</a> <a href="compile.html#enable_stat4">compile.html#enable_stat4</a> + <a href="lang_analyze.html#statanal">lang_analyze.html#statanal</a> <a href="oldnews.html">oldnews.html</a> <a href="releaselog/3_20_0.html">releaselog/3_20_0.html</a> <a href="releaselog/3_20_1.html">releaselog/3_20_1.html</a> +<li>query-time index → <a href="optoverview.html#flattening">optoverview.html#flattening</a> <li>query_only pragma → <a href="changes.html#version_3_8_0">changes.html#version_3_8_0</a> <a href="releaselog/3_8_0.html">releaselog/3_8_0.html</a> <a href="releaselog/3_8_0_1.html">releaselog/3_8_0_1.html</a> @@ -7372,6 +7421,7 @@ antiRobotDefense(); <a href="lang_altertable.html#altertableishard">lang_altertable.html#altertableishard</a> <a href="lts.html">lts.html</a> <a href="onefile.html">onefile.html</a> +<li>Recommended usage patterns for ANALYZE → <a href="queryplanner-ng.html#qpstab">queryplanner-ng.html#qpstab</a> <li>record format → <a href="changes.html#version_3_21_0">changes.html#version_3_21_0</a> <a href="fileformat2.html#stat4tab">fileformat2.html#stat4tab</a> <a href="opcode.html#codes">opcode.html#codes</a> @@ -7700,6 +7750,8 @@ antiRobotDefense(); <li>rtrim → <a href="lang_corefunc.html">lang_corefunc.html</a> <li>rules for determining column affinity → <a href="lang_expr.html#castexpr">lang_expr.html#castexpr</a> <li>Run-Time Loadable Extensions → <a href="cli.html#dotload">cli.html#dotload</a> +<li>running ANALYZE via PRAGMA optimize → <a href="changes.html#version_3_46_0">changes.html#version_3_46_0</a> + <a href="releaselog/3_46_0.html">releaselog/3_46_0.html</a> <li>safe command-line option → <a href="changes.html#version_3_40_1">changes.html#version_3_40_1</a> <a href="news.html">news.html</a> <a href="releaselog/3_40_1.html">releaselog/3_40_1.html</a> @@ -7776,7 +7828,7 @@ antiRobotDefense(); <a href="fts3.html#simple_fts_queries">fts3.html#simple_fts_queries</a> <a href="isolation.html">isolation.html</a> <a href="lang.html">lang.html</a> - <a href="lang_analyze.html#req">lang_analyze.html#req</a> + <a href="lang_analyze.html#statanal">lang_analyze.html#statanal</a> <a href="lang_createview.html">lang_createview.html</a> <a href="lang_expr.html#cosub">lang_expr.html#cosub</a> <a href="lang_expr.html#subq">lang_expr.html#subq</a> @@ -9673,7 +9725,6 @@ antiRobotDefense(); <a href="changes.html#version_3_16_0">changes.html#version_3_16_0</a> <a href="changes.html#version_3_31_0">changes.html#version_3_31_0</a> <a href="changes.html#version_3_41_0">changes.html#version_3_41_0</a> - <a href="pragma.html#pragma_optimize">pragma.html#pragma_optimize</a> <a href="releaselog/3_16_0.html">releaselog/3_16_0.html</a> <a href="releaselog/3_16_1.html">releaselog/3_16_1.html</a> <a href="releaselog/3_16_2.html">releaselog/3_16_2.html</a> @@ -10326,6 +10377,7 @@ antiRobotDefense(); <a href="vtab.html#obc">vtab.html#obc</a> <a href="vtab.html#xbestindex">vtab.html#xbestindex</a> <a href="vtab.html#xfindfunction">vtab.html#xfindfunction</a> + <a href="whybytecode.html">whybytecode.html</a> <li>sqlite3_prepare16 → <a href="c3ref/bind_parameter_name.html">c3ref/bind_parameter_name.html</a> <a href="c3ref/funclist.html">c3ref/funclist.html</a> <a href="c3ref/set_authorizer.html">c3ref/set_authorizer.html</a> @@ -10513,11 +10565,7 @@ antiRobotDefense(); <a href="capi3ref.html#sqlite3">capi3ref.html#sqlite3</a> <a href="capi3ref.html#sqlite3_preupdate_blobwrite">capi3ref.html#sqlite3_preupdate_blobwrite</a> <li>sqlite3_profile → <a href="c3ref/c_trace.html#sqlitetraceprofile">c3ref/c_trace.html#sqlitetraceprofile</a> - <a href="c3ref/funclist.html">c3ref/funclist.html</a> - <a href="c3ref/sqlite3.html">c3ref/sqlite3.html</a> <a href="c3ref/trace_v2.html">c3ref/trace_v2.html</a> - <a href="capi3ref.html">capi3ref.html</a> - <a href="capi3ref.html#sqlite3">capi3ref.html#sqlite3</a> <a href="capi3ref.html#sqlite3_trace_v2">capi3ref.html#sqlite3_trace_v2</a> <a href="capi3ref.html#sqlitetraceprofile">capi3ref.html#sqlitetraceprofile</a> <a href="changes.html#version_3_14">changes.html#version_3_14</a> @@ -11094,7 +11142,7 @@ antiRobotDefense(); <a href="lang_corefunc.html#likelihood">lang_corefunc.html#likelihood</a> <a href="lang_corefunc.html#likely">lang_corefunc.html#likely</a> <a href="lang_corefunc.html#unlikely">lang_corefunc.html#unlikely</a> - <a href="lang_datefunc.html#tmdif">lang_datefunc.html#tmdif</a> + <a href="lang_datefunc.html#tmval">lang_datefunc.html#tmval</a> <a href="lang_explain.html">lang_explain.html</a> <a href="lang_returning.html">lang_returning.html</a> <a href="malloc.html#lookaside">malloc.html#lookaside</a> @@ -11125,6 +11173,7 @@ antiRobotDefense(); <a href="cintro.html">cintro.html</a> <a href="tclsqlite.html#trace_v2">tclsqlite.html#trace_v2</a> <a href="unlock_notify.html">unlock_notify.html</a> + <a href="whybytecode.html">whybytecode.html</a> <li>sqlite3_stmt_busy → <a href="c3ref/funclist.html">c3ref/funclist.html</a> <a href="c3ref/stmt.html">c3ref/stmt.html</a> <a href="capi3ref.html">capi3ref.html</a> @@ -11427,12 +11476,8 @@ antiRobotDefense(); <a href="releaselog/3_37_1.html">releaselog/3_37_1.html</a> <a href="releaselog/3_37_2.html">releaselog/3_37_2.html</a> <li>sqlite3_trace → <a href="c3ref/c_trace.html#sqlitetracestmt">c3ref/c_trace.html#sqlitetracestmt</a> - <a href="c3ref/funclist.html">c3ref/funclist.html</a> <a href="c3ref/profile.html">c3ref/profile.html</a> - <a href="c3ref/sqlite3.html">c3ref/sqlite3.html</a> <a href="c3ref/trace_v2.html">c3ref/trace_v2.html</a> - <a href="capi3ref.html">capi3ref.html</a> - <a href="capi3ref.html#sqlite3">capi3ref.html#sqlite3</a> <a href="capi3ref.html#sqlite3_profile">capi3ref.html#sqlite3_profile</a> <a href="capi3ref.html#sqlite3_trace_v2">capi3ref.html#sqlite3_trace_v2</a> <a href="capi3ref.html#sqlitetracestmt">capi3ref.html#sqlitetracestmt</a> @@ -11757,7 +11802,7 @@ antiRobotDefense(); <a href="compile.html#os_other">compile.html#os_other</a> <a href="custombuild.html">custombuild.html</a> <a href="howtocorrupt.html#posix_close_bug">howtocorrupt.html#posix_close_bug</a> - <a href="lang_datefunc.html#tmdif">lang_datefunc.html#tmdif</a> + <a href="lang_datefunc.html#tmval">lang_datefunc.html#tmval</a> <a href="loadext.html#persist">loadext.html#persist</a> <a href="loadext.html#statext">loadext.html#statext</a> <a href="oldnews.html">oldnews.html</a> @@ -12009,6 +12054,12 @@ antiRobotDefense(); <a href="capi3ref.html#sqlite3_win32_set_directory">capi3ref.html#sqlite3_win32_set_directory</a> <li>sqlite3changegroup_add → <a href="session.html">session.html</a> <a href="session.html#sqlite3_changegroup">session.html#sqlite3_changegroup</a> + <a href="session.html#sqlite3changegroup_add_change">session.html#sqlite3changegroup_add_change</a> + <a href="session/changegroup.html">session/changegroup.html</a> + <a href="session/funclist.html">session/funclist.html</a> + <a href="session/sqlite3changegroup_add_change.html">session/sqlite3changegroup_add_change.html</a> +<li>sqlite3changegroup_add_change → <a href="session.html">session.html</a> + <a href="session.html#sqlite3_changegroup">session.html#sqlite3_changegroup</a> <a href="session/changegroup.html">session/changegroup.html</a> <a href="session/funclist.html">session/funclist.html</a> <li>sqlite3changegroup_add_strm → <a href="session.html">session.html</a> @@ -13292,7 +13343,7 @@ antiRobotDefense(); <a href="changes.html#version_3_6_20">changes.html#version_3_6_20</a> <a href="changes.html#version_3_7_6">changes.html#version_3_7_6</a> <a href="changes.html#version_3_7_9">changes.html#version_3_7_9</a> - <a href="lang_analyze.html#req">lang_analyze.html#req</a> + <a href="lang_analyze.html#statanal">lang_analyze.html#statanal</a> <a href="oldnews.html">oldnews.html</a> <a href="releaselog/3_6_18.html">releaselog/3_6_18.html</a> <a href="releaselog/3_6_20.html">releaselog/3_6_20.html</a> @@ -13304,7 +13355,7 @@ antiRobotDefense(); <a href="compile.html#enable_stat2">compile.html#enable_stat2</a> <a href="compile.html#enable_stat4">compile.html#enable_stat4</a> <a href="fileformat2.html#stat3tab">fileformat2.html#stat3tab</a> - <a href="lang_analyze.html#req">lang_analyze.html#req</a> + <a href="lang_analyze.html#statanal">lang_analyze.html#statanal</a> <a href="oldnews.html">oldnews.html</a> <a href="optoverview.html#rangequery">optoverview.html#rangequery</a> <a href="releaselog/3_30_0.html">releaselog/3_30_0.html</a> @@ -13322,7 +13373,7 @@ antiRobotDefense(); <a href="compile.html#enable_stat3">compile.html#enable_stat3</a> <a href="fileformat2.html#stat3tab">fileformat2.html#stat3tab</a> <a href="fileformat2.html#stat4tab">fileformat2.html#stat4tab</a> - <a href="lang_analyze.html#req">lang_analyze.html#req</a> + <a href="lang_analyze.html#statanal">lang_analyze.html#statanal</a> <a href="oldnews.html">oldnews.html</a> <a href="optoverview.html#rangequery">optoverview.html#rangequery</a> <a href="releaselog/3_41_2.html">releaselog/3_41_2.html</a> @@ -14889,6 +14940,7 @@ antiRobotDefense(); <a href="security.html">security.html</a> <a href="sharedcache.html#dontuse">sharedcache.html#dontuse</a> <a href="unlock_notify.html">unlock_notify.html</a> + <a href="whybytecode.html">whybytecode.html</a> <li>SQLITE_SECURE_DELETE → <a href="changes.html#version_3_6_21">changes.html#version_3_6_21</a> <a href="faq.html#q20">faq.html#q20</a> <a href="pragma.html#pragma_secure_delete">pragma.html#pragma_secure_delete</a> @@ -14951,11 +15003,11 @@ antiRobotDefense(); <li>sqlite_stat1 → <a href="changes.html#version_3_13_0">changes.html#version_3_13_0</a> <a href="changes.html#version_3_33_0">changes.html#version_3_33_0</a> <a href="changes.html#version_3_8_1">changes.html#version_3_8_1</a> - <a href="lang_analyze.html#req">lang_analyze.html#req</a> + <a href="lang_analyze.html#pragopt">lang_analyze.html#pragopt</a> + <a href="lang_analyze.html#statanal">lang_analyze.html#statanal</a> <a href="oldnews.html">oldnews.html</a> <a href="optoverview.html#manctrl">optoverview.html#manctrl</a> <a href="optoverview.html#multi_index">optoverview.html#multi_index</a> - <a href="pragma.html#pragma_optimize">pragma.html#pragma_optimize</a> <a href="queryplanner-ng.html#fossilcasestudy">queryplanner-ng.html#fossilcasestudy</a> <a href="queryplanner-ng.html#howtofix">queryplanner-ng.html#howtofix</a> <a href="releaselog/3_13_0.html">releaselog/3_13_0.html</a> @@ -14964,15 +15016,13 @@ antiRobotDefense(); <li>SQLITE_STAT1 → <a href="queryplanner-ng.html#fossilcasestudy">queryplanner-ng.html#fossilcasestudy</a> <a href="queryplanner-ng.html#hazards">queryplanner-ng.html#hazards</a> <a href="queryplanner-ng.html#howtofix">queryplanner-ng.html#howtofix</a> -<li>sqlite_stat2 → <a href="lang_analyze.html#req">lang_analyze.html#req</a> -<li>sqlite_stat3 → <a href="lang_analyze.html#req">lang_analyze.html#req</a> - <a href="optoverview.html#manctrl">optoverview.html#manctrl</a> +<li>sqlite_stat2 → <a href="lang_analyze.html#statanal">lang_analyze.html#statanal</a> +<li>sqlite_stat3 → <a href="lang_analyze.html#statanal">lang_analyze.html#statanal</a> <a href="optoverview.html#rangequery">optoverview.html#rangequery</a> <li>sqlite_stat4 → <a href="changes.html#version_3_8_6">changes.html#version_3_8_6</a> <a href="changes.html#version_3_8_7">changes.html#version_3_8_7</a> <a href="compile.html#enable_stat4">compile.html#enable_stat4</a> - <a href="lang_analyze.html#req">lang_analyze.html#req</a> - <a href="optoverview.html#manctrl">optoverview.html#manctrl</a> + <a href="lang_analyze.html#statanal">lang_analyze.html#statanal</a> <a href="optoverview.html#rangequery">optoverview.html#rangequery</a> <a href="releaselog/3_8_6.html">releaselog/3_8_6.html</a> <a href="releaselog/3_8_7.html">releaselog/3_8_7.html</a> @@ -15431,9 +15481,11 @@ antiRobotDefense(); <li>strategies → <a href="eqp.html">eqp.html</a> <li>strftime → <a href="lang_datefunc.html#subsec">lang_datefunc.html#subsec</a> <li>strftime SQL function → <a href="changes.html#version_3_44_0">changes.html#version_3_44_0</a> + <a href="changes.html#version_3_46_0">changes.html#version_3_46_0</a> <a href="releaselog/3_44_0.html">releaselog/3_44_0.html</a> <a href="releaselog/3_44_1.html">releaselog/3_44_1.html</a> <a href="releaselog/3_44_2.html">releaselog/3_44_2.html</a> + <a href="releaselog/3_46_0.html">releaselog/3_46_0.html</a> <li>STRICT → <a href="datatype3.html#affname">datatype3.html#affname</a> <a href="lang_createtable.html#primkeyconst">lang_createtable.html#primkeyconst</a> <li>STRICT table → <a href="pragma.html#pragma_table_list">pragma.html#pragma_table_list</a> @@ -15454,7 +15506,8 @@ antiRobotDefense(); <a href="releaselog/3_44_2.html">releaselog/3_44_2.html</a> <li>subprograms → <a href="opcode.html">opcode.html</a> <li>Subqueries → <a href="fullsql.html">fullsql.html</a> -<li>subsec modifier → <a href="lang_datefunc.html#uepch">lang_datefunc.html#uepch</a> +<li>subsec modifier → <a href="lang_datefunc.html#dttm">lang_datefunc.html#dttm</a> + <a href="lang_datefunc.html#uepch">lang_datefunc.html#uepch</a> <li>subsecond modifier → <a href="changes.html#version_3_42_0">changes.html#version_3_42_0</a> <a href="releaselog/3_42_0.html">releaselog/3_42_0.html</a> <li>substr → <a href="arch.html">arch.html</a> @@ -15635,6 +15688,7 @@ antiRobotDefense(); <a href="testing.html#stmtvbr">testing.html#stmtvbr</a> <a href="testing.html#tcl">testing.html#tcl</a> <li>the - and - operators → <a href="changes.html#version_3_38_0">changes.html#version_3_38_0</a> + <a href="changes.html#version_3_46_0">changes.html#version_3_46_0</a> <a href="lang_expr.html#collateop">lang_expr.html#collateop</a> <a href="lang_expr.html#extract">lang_expr.html#extract</a> <a href="releaselog/3_38_0.html">releaselog/3_38_0.html</a> @@ -15643,6 +15697,7 @@ antiRobotDefense(); <a href="releaselog/3_38_3.html">releaselog/3_38_3.html</a> <a href="releaselog/3_38_4.html">releaselog/3_38_4.html</a> <a href="releaselog/3_38_5.html">releaselog/3_38_5.html</a> + <a href="releaselog/3_46_0.html">releaselog/3_46_0.html</a> <li>the - operator → <a href="json1.html#jobj">json1.html#jobj</a> <a href="json1.html#jset">json1.html#jset</a> <a href="json1.html#varg">json1.html#varg</a> @@ -15686,6 +15741,8 @@ antiRobotDefense(); <a href="releaselog/3_43_0.html">releaselog/3_43_0.html</a> <a href="releaselog/3_43_1.html">releaselog/3_43_1.html</a> <a href="releaselog/3_43_2.html">releaselog/3_43_2.html</a> +<li>time-value → <a href="lang_datefunc.html">lang_datefunc.html</a> +<li>time-values → <a href="lang_datefunc.html">lang_datefunc.html</a> <li>timediff SQL function → <a href="changes.html#version_3_43_0">changes.html#version_3_43_0</a> <a href="releaselog/3_43_0.html">releaselog/3_43_0.html</a> <a href="releaselog/3_43_1.html">releaselog/3_43_1.html</a> @@ -15702,7 +15759,7 @@ antiRobotDefense(); <li>transaction state → <a href="c3ref/txn_state.html">c3ref/txn_state.html</a> <a href="capi3ref.html#sqlite3_txn_state">capi3ref.html#sqlite3_txn_state</a> <li>transactional → <a href="fasterthanfs.html">fasterthanfs.html</a> -<li>treats the CROSS JOIN operator specially → <a href="optoverview.html#table_order">optoverview.html#table_order</a> +<li>treats the CROSS JOIN operator specially → <a href="optoverview.html#joins">optoverview.html#joins</a> <a href="queryplanner-ng.html#howtofix">queryplanner-ng.html#howtofix</a> <li>trigger → <a href="changes.html#version_3_45_3">changes.html#version_3_45_3</a> <a href="news.html">news.html</a> @@ -15808,6 +15865,8 @@ antiRobotDefense(); <a href="releaselog/3_38_3.html">releaselog/3_38_3.html</a> <a href="releaselog/3_38_4.html">releaselog/3_38_4.html</a> <a href="releaselog/3_38_5.html">releaselog/3_38_5.html</a> +<li>unixepoch modifier → <a href="lang_datefunc.html">lang_datefunc.html</a> + <a href="lang_datefunc.html#tmval">lang_datefunc.html#tmval</a> <li>unlikely → <a href="changes.html#version_3_8_1">changes.html#version_3_8_1</a> <a href="changes.html#version_3_8_8">changes.html#version_3_8_8</a> <a href="lang_corefunc.html">lang_corefunc.html</a> @@ -15852,7 +15911,7 @@ antiRobotDefense(); <a href="isolation.html">isolation.html</a> <a href="lang.html">lang.html</a> <a href="lang_altertable.html#caution">lang_altertable.html#caution</a> - <a href="lang_analyze.html#req">lang_analyze.html#req</a> + <a href="lang_analyze.html#statanal">lang_analyze.html#statanal</a> <a href="lang_createtable.html#notnullconst">lang_createtable.html#notnullconst</a> <a href="lang_createtable.html#primkeyconst">lang_createtable.html#primkeyconst</a> <a href="lang_createtrigger.html">lang_createtrigger.html</a> @@ -15977,6 +16036,8 @@ antiRobotDefense(); <li>Using the SQLite Unlock Notification Feature → <a href="c3ref/unlock_notify.html">c3ref/unlock_notify.html</a> <a href="capi3ref.html#sqlite3_unlock_notify">capi3ref.html#sqlite3_unlock_notify</a> <a href="compile.html#enable_unlock_notify">compile.html#enable_unlock_notify</a> +<li>utc and localtime modifiers → <a href="changes.html#version_3_46_0">changes.html#version_3_46_0</a> + <a href="releaselog/3_46_0.html">releaselog/3_46_0.html</a> <li>utc modifier → <a href="changes.html#version_3_10_0">changes.html#version_3_10_0</a> <a href="deterministic.html#dtexception">deterministic.html#dtexception</a> <a href="releaselog/3_10_0.html">releaselog/3_10_0.html</a> @@ -16345,6 +16406,7 @@ antiRobotDefense(); <li>version 3.45.1 → <a href="chronology.html">chronology.html</a> <li>version 3.45.2 → <a href="chronology.html">chronology.html</a> <li>version 3.45.3 → <a href="chronology.html">chronology.html</a> +<li>version 3.46.0 → <a href="chronology.html">chronology.html</a> <li>version 3.5.0 → <a href="35to36.html">35to36.html</a> <a href="c3ref/enable_shared_cache.html">c3ref/enable_shared_cache.html</a> <a href="c3ref/vfs.html">c3ref/vfs.html</a> @@ -17089,11 +17151,24 @@ antiRobotDefense(); <a href="releaselog/3_7_6.html">releaselog/3_7_6.html</a> <a href="wal.html#fast">wal.html#fast</a> <li>WHERE clause → <a href="lang_select.html#simpleselect">lang_select.html#simpleselect</a> +<li>WHERE-clause push-down optimization → <a href="changes.html#version_3_13_0">changes.html#version_3_13_0</a> + <a href="changes.html#version_3_42_0">changes.html#version_3_42_0</a> + <a href="changes.html#version_3_46_0">changes.html#version_3_46_0</a> + <a href="changes.html#version_3_9_0">changes.html#version_3_9_0</a> + <a href="releaselog/3_13_0.html">releaselog/3_13_0.html</a> + <a href="releaselog/3_42_0.html">releaselog/3_42_0.html</a> + <a href="releaselog/3_46_0.html">releaselog/3_46_0.html</a> + <a href="releaselog/3_9_0.html">releaselog/3_9_0.html</a> + <a href="releaselog/3_9_1.html">releaselog/3_9_1.html</a> + <a href="releaselog/3_9_2.html">releaselog/3_9_2.html</a> + <a href="releaselog/3_9_3.html">releaselog/3_9_3.html</a> +<li>Why SQLite Uses Bytecode → <a href="opcode.html">opcode.html</a> <li>window chaining → <a href="changes.html#version_3_28_0">changes.html#version_3_28_0</a> <a href="releaselog/3_28_0.html">releaselog/3_28_0.html</a> <li>window function → <a href="appfunc.html">appfunc.html</a> <a href="changes.html#version_3_27_2">changes.html#version_3_27_2</a> <a href="news.html">news.html</a> + <a href="optoverview.html#flattening">optoverview.html#flattening</a> <a href="releaselog/3_27_2.html">releaselog/3_27_2.html</a> <li>Window functions → <a href="appfunc.html">appfunc.html</a> <li>window functions → <a href="appfunc.html">appfunc.html</a> @@ -17142,6 +17217,7 @@ antiRobotDefense(); <a href="windowfunctions.html#wexcls">windowfunctions.html#wexcls</a> <li>window-function-invocation → <a href="lang_expr.html#*funcinexpr">lang_expr.html#*funcinexpr</a> <a href="windowfunctions.html">windowfunctions.html</a> +<li>winfunc → <a href="lang.html">lang.html</a> <li>WITH → <a href="fullsql.html">fullsql.html</a> <a href="lang_select.html">lang_select.html</a> <li>WITH clause → <a href="changes.html#version_3_23_0">changes.html#version_3_23_0</a> diff --git a/www/doc_keyword_crossref.html b/www/doc_keyword_crossref.html index d01682b..4177a3b 100644 --- a/www/doc_keyword_crossref.html +++ b/www/doc_keyword_crossref.html @@ -115,5 +115,5 @@ antiRobotGo(); } antiRobotDefense(); </script> -<ul><li>--insert option - <a href="cli.html#arinsup">cli.html#arinsup</a></li><li>--safe command-line option - <a href="cli.html#safemode">cli.html#safemode</a></li><li>--unsafe-testing command-line option - <a href="cli.html#testing_mode">cli.html#testing_mode</a></li><li>--update option - <a href="cli.html#arinsup">cli.html#arinsup</a></li><li>-DHAVE_FDATASYNC - <a href="compile.html#fdatasync">compile.html#fdatasync</a></li><li>-DHAVE_GMTIME_R - <a href="compile.html#gmtime_r">compile.html#gmtime_r</a></li><li>-DHAVE_ISNAN - <a href="compile.html#isnan">compile.html#isnan</a></li><li>-DHAVE_LOCALTIME_R - <a href="compile.html#localtime_r">compile.html#localtime_r</a></li><li>-DHAVE_LOCALTIME_S - <a href="compile.html#localtime_s">compile.html#localtime_s</a></li><li>-DHAVE_MALLOC_USABLE_SIZE - <a href="compile.html#malloc_usable_size">compile.html#malloc_usable_size</a></li><li>-DHAVE_SQLITE_CONFIG_H - <a href="compile.html#sqlite_config_h">compile.html#sqlite_config_h</a></li><li>-DHAVE_STRCHRNUL - <a href="compile.html#strchrnul">compile.html#strchrnul</a></li><li>-DHAVE_UTIME - <a href="compile.html#utime">compile.html#utime</a></li><li>-DSQLITE_4_BYTE_ALIGNED_MALLOC - <a href="compile.html#4_byte_aligned_malloc">compile.html#4_byte_aligned_malloc</a></li><li>-DSQLITE_ALLOW_COVERING_INDEX_SCAN - <a href="compile.html#allow_covering_index_scan">compile.html#allow_covering_index_scan</a></li><li>-DSQLITE_ALLOW_URI_AUTHORITY - <a href="compile.html#allow_uri_authority">compile.html#allow_uri_authority</a></li><li>-DSQLITE_API - <a href="compile.html#api">compile.html#api</a></li><li>-DSQLITE_APICALL - <a href="compile.html#apicall">compile.html#apicall</a></li><li>-DSQLITE_BYTEORDER - <a href="compile.html#byteorder">compile.html#byteorder</a></li><li>-DSQLITE_CALLBACK - <a href="compile.html#callback">compile.html#callback</a></li><li>-DSQLITE_CASE_SENSITIVE_LIKE - <a href="compile.html#case_sensitive_like">compile.html#case_sensitive_like</a></li><li>-DSQLITE_CDECL - <a href="compile.html#cdecl">compile.html#cdecl</a></li><li>-DSQLITE_DEBUG - <a href="compile.html#debug">compile.html#debug</a></li><li>-DSQLITE_DEFAULT_AUTOMATIC_INDEX - <a href="compile.html#default_automatic_index">compile.html#default_automatic_index</a></li><li>-DSQLITE_DEFAULT_AUTOVACUUM - <a href="compile.html#default_autovacuum">compile.html#default_autovacuum</a></li><li>-DSQLITE_DEFAULT_CACHE_SIZE - <a href="compile.html#default_cache_size">compile.html#default_cache_size</a></li><li>-DSQLITE_DEFAULT_FILE_FORMAT - <a href="compile.html#default_file_format">compile.html#default_file_format</a></li><li>-DSQLITE_DEFAULT_FILE_PERMISSIONS - <a href="compile.html#default_file_permissions">compile.html#default_file_permissions</a></li><li>-DSQLITE_DEFAULT_FOREIGN_KEYS - <a href="compile.html#default_foreign_keys">compile.html#default_foreign_keys</a></li><li>-DSQLITE_DEFAULT_JOURNAL_SIZE_LIMIT - <a href="compile.html#default_journal_size_limit">compile.html#default_journal_size_limit</a></li><li>-DSQLITE_DEFAULT_LOCKING_MODE - <a href="compile.html#default_locking_mode">compile.html#default_locking_mode</a></li><li>-DSQLITE_DEFAULT_LOOKASIDE - <a href="compile.html#default_lookaside">compile.html#default_lookaside</a></li><li>-DSQLITE_DEFAULT_MEMSTATUS - <a href="compile.html#default_memstatus">compile.html#default_memstatus</a></li><li>-DSQLITE_DEFAULT_MMAP_SIZE - <a href="compile.html#default_mmap_size">compile.html#default_mmap_size</a></li><li>-DSQLITE_DEFAULT_PAGE_SIZE - <a href="compile.html#default_page_size">compile.html#default_page_size</a></li><li>-DSQLITE_DEFAULT_PCACHE_INITSZ - <a href="compile.html#default_pcache_initsz">compile.html#default_pcache_initsz</a></li><li>-DSQLITE_DEFAULT_SYNCHRONOUS - <a href="compile.html#default_synchronous">compile.html#default_synchronous</a></li><li>-DSQLITE_DEFAULT_WAL_AUTOCHECKPOINT - <a href="compile.html#default_wal_autocheckpoint">compile.html#default_wal_autocheckpoint</a></li><li>-DSQLITE_DEFAULT_WAL_SYNCHRONOUS - <a href="compile.html#default_wal_synchronous">compile.html#default_wal_synchronous</a></li><li>-DSQLITE_DEFAULT_WORKER_THREADS - <a href="compile.html#default_worker_threads">compile.html#default_worker_threads</a></li><li>-DSQLITE_DIRECT_OVERFLOW_READ - <a href="compile.html#direct_overflow_read">compile.html#direct_overflow_read</a></li><li>-DSQLITE_DISABLE_DIRSYNC - <a href="compile.html#disable_dirsync">compile.html#disable_dirsync</a></li><li>-DSQLITE_DISABLE_FTS3_UNICODE - <a href="compile.html#disable_fts3_unicode">compile.html#disable_fts3_unicode</a></li><li>-DSQLITE_DISABLE_FTS4_DEFERRED - <a href="compile.html#disable_fts4_deferred">compile.html#disable_fts4_deferred</a></li><li>-DSQLITE_DISABLE_INTRINSIC - <a href="compile.html#disable_intrinsic">compile.html#disable_intrinsic</a></li><li>-DSQLITE_DISABLE_LFS - <a href="compile.html#disable_lfs">compile.html#disable_lfs</a></li><li>-DSQLITE_DISABLE_PAGECACHE_OVERFLOW_STATS - <a href="compile.html#disable_pagecache_overflow_stats">compile.html#disable_pagecache_overflow_stats</a></li><li>-DSQLITE_DQS - <a href="compile.html#dqs">compile.html#dqs</a></li><li>-DSQLITE_ENABLE_8_3_NAMES - <a href="compile.html#enable_8_3_names">compile.html#enable_8_3_names</a></li><li>-DSQLITE_ENABLE_API_ARMOR - <a href="compile.html#enable_api_armor">compile.html#enable_api_armor</a></li><li>-DSQLITE_ENABLE_ATOMIC_WRITE - <a href="compile.html#enable_atomic_write">compile.html#enable_atomic_write</a></li><li>-DSQLITE_ENABLE_BATCH_ATOMIC_WRITE - <a href="compile.html#enable_batch_atomic_write">compile.html#enable_batch_atomic_write</a></li><li>-DSQLITE_ENABLE_BYTECODE_VTAB - <a href="compile.html#enable_bytecode_vtab">compile.html#enable_bytecode_vtab</a></li><li>-DSQLITE_ENABLE_COLUMN_METADATA - <a href="compile.html#enable_column_metadata">compile.html#enable_column_metadata</a></li><li>-DSQLITE_ENABLE_DBPAGE_VTAB - <a href="compile.html#enable_dbpage_vtab">compile.html#enable_dbpage_vtab</a></li><li>-DSQLITE_ENABLE_DBSTAT_VTAB - <a href="compile.html#enable_dbstat_vtab">compile.html#enable_dbstat_vtab</a></li><li>-DSQLITE_ENABLE_DESERIALIZE - <a href="compile.html#enable_deserialize">compile.html#enable_deserialize</a></li><li>-DSQLITE_ENABLE_EXPLAIN_COMMENTS - <a href="compile.html#enable_explain_comments">compile.html#enable_explain_comments</a></li><li>-DSQLITE_ENABLE_FTS3 - <a href="compile.html#enable_fts3">compile.html#enable_fts3</a></li><li>-DSQLITE_ENABLE_FTS3_PARENTHESIS - <a href="compile.html#enable_fts3_parenthesis">compile.html#enable_fts3_parenthesis</a></li><li>-DSQLITE_ENABLE_FTS3_TOKENIZER - <a href="compile.html#enable_fts3_tokenizer">compile.html#enable_fts3_tokenizer</a></li><li>-DSQLITE_ENABLE_FTS4 - <a href="compile.html#enable_fts4">compile.html#enable_fts4</a></li><li>-DSQLITE_ENABLE_FTS5 - <a href="compile.html#enable_fts5">compile.html#enable_fts5</a></li><li>-DSQLITE_ENABLE_GEOPOLY - <a href="compile.html#enable_geopoly">compile.html#enable_geopoly</a></li><li>-DSQLITE_ENABLE_HIDDEN_COLUMNS - <a href="compile.html#enable_hidden_columns">compile.html#enable_hidden_columns</a></li><li>-DSQLITE_ENABLE_ICU - <a href="compile.html#enable_icu">compile.html#enable_icu</a></li><li>-DSQLITE_ENABLE_IOTRACE - <a href="compile.html#enable_iotrace">compile.html#enable_iotrace</a></li><li>-DSQLITE_ENABLE_JSON1 - <a href="compile.html#enable_json1">compile.html#enable_json1</a></li><li>-DSQLITE_ENABLE_LOCKING_STYLE - <a href="compile.html#enable_locking_style">compile.html#enable_locking_style</a></li><li>-DSQLITE_ENABLE_MATH_FUNCTIONS - <a href="compile.html#enable_math_functions">compile.html#enable_math_functions</a></li><li>-DSQLITE_ENABLE_MEMORY_MANAGEMENT - <a href="compile.html#enable_memory_management">compile.html#enable_memory_management</a></li><li>-DSQLITE_ENABLE_MEMSYS3 - <a href="compile.html#enable_memsys3">compile.html#enable_memsys3</a></li><li>-DSQLITE_ENABLE_MEMSYS5 - <a href="compile.html#enable_memsys5">compile.html#enable_memsys5</a></li><li>-DSQLITE_ENABLE_NORMALIZE - <a href="compile.html#enable_normalize">compile.html#enable_normalize</a></li><li>-DSQLITE_ENABLE_NULL_TRIM - <a href="compile.html#enable_null_trim">compile.html#enable_null_trim</a></li><li>-DSQLITE_ENABLE_OFFSET_SQL_FUNC - <a href="compile.html#enable_offset_sql_func">compile.html#enable_offset_sql_func</a></li><li>-DSQLITE_ENABLE_PREUPDATE_HOOK - <a href="compile.html#enable_preupdate_hook">compile.html#enable_preupdate_hook</a></li><li>-DSQLITE_ENABLE_QPSG - <a href="compile.html#enable_qpsg">compile.html#enable_qpsg</a></li><li>-DSQLITE_ENABLE_RBU - <a href="compile.html#enable_rbu">compile.html#enable_rbu</a></li><li>-DSQLITE_ENABLE_RTREE - <a href="compile.html#enable_rtree">compile.html#enable_rtree</a></li><li>-DSQLITE_ENABLE_SESSION - <a href="compile.html#enable_session">compile.html#enable_session</a></li><li>-DSQLITE_ENABLE_SNAPSHOT - <a href="compile.html#enable_snapshot">compile.html#enable_snapshot</a></li><li>-DSQLITE_ENABLE_SORTER_REFERENCES - <a href="compile.html#enable_sorter_references">compile.html#enable_sorter_references</a></li><li>-DSQLITE_ENABLE_SQLLOG - <a href="compile.html#enable_sqllog">compile.html#enable_sqllog</a></li><li>-DSQLITE_ENABLE_STAT2 - <a href="compile.html#enable_stat2">compile.html#enable_stat2</a></li><li>-DSQLITE_ENABLE_STAT3 - <a href="compile.html#enable_stat3">compile.html#enable_stat3</a></li><li>-DSQLITE_ENABLE_STAT4 - <a href="compile.html#enable_stat4">compile.html#enable_stat4</a></li><li>-DSQLITE_ENABLE_STMT_SCANSTATUS - <a href="compile.html#enable_stmt_scanstatus">compile.html#enable_stmt_scanstatus</a></li><li>-DSQLITE_ENABLE_STMTVTAB - <a href="compile.html#enable_stmtvtab">compile.html#enable_stmtvtab</a></li><li>-DSQLITE_ENABLE_TREE_EXPLAIN - <a href="compile.html#enable_tree_explain">compile.html#enable_tree_explain</a></li><li>-DSQLITE_ENABLE_UNKNOWN_SQL_FUNCTION - <a href="compile.html#enable_unknown_sql_function">compile.html#enable_unknown_sql_function</a></li><li>-DSQLITE_ENABLE_UNLOCK_NOTIFY - <a href="compile.html#enable_unlock_notify">compile.html#enable_unlock_notify</a></li><li>-DSQLITE_ENABLE_UPDATE_DELETE_LIMIT - <a href="compile.html#enable_update_delete_limit">compile.html#enable_update_delete_limit</a></li><li>-DSQLITE_EXTERN - <a href="compile.html#extern">compile.html#extern</a></li><li>-DSQLITE_EXTRA_DURABLE - <a href="compile.html#extra_durable">compile.html#extra_durable</a></li><li>-DSQLITE_FTS3_MAX_EXPR_DEPTH - <a href="compile.html#fts3_max_expr_depth">compile.html#fts3_max_expr_depth</a></li><li>-DSQLITE_HAVE_ISNAN - <a href="compile.html#have_isnan">compile.html#have_isnan</a></li><li>-DSQLITE_HAVE_ZLIB - <a href="compile.html#have_zlib">compile.html#have_zlib</a></li><li>-DSQLITE_INTROSPECTION_PRAGMAS - <a href="compile.html#introspection_pragmas">compile.html#introspection_pragmas</a></li><li>-DSQLITE_JSON_MAX_DEPTH - <a href="compile.html#json_max_depth">compile.html#json_max_depth</a></li><li>-DSQLITE_LIKE_DOESNT_MATCH_BLOBS - <a href="compile.html#like_doesnt_match_blobs">compile.html#like_doesnt_match_blobs</a></li><li>-DSQLITE_MAX_ALLOCATION_SIZE - <a href="compile.html#max_allocation_size">compile.html#max_allocation_size</a></li><li>-DSQLITE_MAX_MEMORY - <a href="compile.html#max_memory">compile.html#max_memory</a></li><li>-DSQLITE_MAX_MMAP_SIZE - <a href="compile.html#max_mmap_size">compile.html#max_mmap_size</a></li><li>-DSQLITE_MAX_SCHEMA_RETRY - <a href="compile.html#max_schema_retry">compile.html#max_schema_retry</a></li><li>-DSQLITE_MAX_WORKER_THREADS - <a href="compile.html#max_worker_threads">compile.html#max_worker_threads</a></li><li>-DSQLITE_MEMDB_DEFAULT_MAXSIZE - <a href="compile.html#memdb_default_maxsize">compile.html#memdb_default_maxsize</a></li><li>-DSQLITE_MEMDEBUG - <a href="compile.html#memdebug">compile.html#memdebug</a></li><li>-DSQLITE_MINIMUM_FILE_DESCRIPTOR - <a href="compile.html#minimum_file_descriptor">compile.html#minimum_file_descriptor</a></li><li>-DSQLITE_OMIT_ALTERTABLE - <a href="compile.html#omit_altertable">compile.html#omit_altertable</a></li><li>-DSQLITE_OMIT_ANALYZE - <a href="compile.html#omit_analyze">compile.html#omit_analyze</a></li><li>-DSQLITE_OMIT_ATTACH - <a href="compile.html#omit_attach">compile.html#omit_attach</a></li><li>-DSQLITE_OMIT_AUTHORIZATION - <a href="compile.html#omit_authorization">compile.html#omit_authorization</a></li><li>-DSQLITE_OMIT_AUTOINCREMENT - <a href="compile.html#omit_autoincrement">compile.html#omit_autoincrement</a></li><li>-DSQLITE_OMIT_AUTOINIT - <a href="compile.html#omit_autoinit">compile.html#omit_autoinit</a></li><li>-DSQLITE_OMIT_AUTOMATIC_INDEX - <a href="compile.html#omit_automatic_index">compile.html#omit_automatic_index</a></li><li>-DSQLITE_OMIT_AUTORESET - <a href="compile.html#omit_autoreset">compile.html#omit_autoreset</a></li><li>-DSQLITE_OMIT_AUTOVACUUM - <a href="compile.html#omit_autovacuum">compile.html#omit_autovacuum</a></li><li>-DSQLITE_OMIT_BETWEEN_OPTIMIZATION - <a href="compile.html#omit_between_optimization">compile.html#omit_between_optimization</a></li><li>-DSQLITE_OMIT_BLOB_LITERAL - <a href="compile.html#omit_blob_literal">compile.html#omit_blob_literal</a></li><li>-DSQLITE_OMIT_BTREECOUNT - <a href="compile.html#omit_btreecount">compile.html#omit_btreecount</a></li><li>-DSQLITE_OMIT_BUILTIN_TEST - <a href="compile.html#omit_builtin_test">compile.html#omit_builtin_test</a></li><li>-DSQLITE_OMIT_CASE_SENSITIVE_LIKE_PRAGMA - <a href="compile.html#omit_case_sensitive_like_pragma">compile.html#omit_case_sensitive_like_pragma</a></li><li>-DSQLITE_OMIT_CAST - <a href="compile.html#omit_cast">compile.html#omit_cast</a></li><li>-DSQLITE_OMIT_CHECK - <a href="compile.html#omit_check">compile.html#omit_check</a></li><li>-DSQLITE_OMIT_COMPILEOPTION_DIAGS - <a href="compile.html#omit_compileoption_diags">compile.html#omit_compileoption_diags</a></li><li>-DSQLITE_OMIT_COMPLETE - <a href="compile.html#omit_complete">compile.html#omit_complete</a></li><li>-DSQLITE_OMIT_COMPOUND_SELECT - <a href="compile.html#omit_compound_select">compile.html#omit_compound_select</a></li><li>-DSQLITE_OMIT_CTE - <a href="compile.html#omit_cte">compile.html#omit_cte</a></li><li>-DSQLITE_OMIT_DATETIME_FUNCS - <a href="compile.html#omit_datetime_funcs">compile.html#omit_datetime_funcs</a></li><li>-DSQLITE_OMIT_DECLTYPE - <a href="compile.html#omit_decltype">compile.html#omit_decltype</a></li><li>-DSQLITE_OMIT_DEPRECATED - <a href="compile.html#omit_deprecated">compile.html#omit_deprecated</a></li><li>-DSQLITE_OMIT_DESERIALIZE - <a href="compile.html#omit_deserialize">compile.html#omit_deserialize</a></li><li>-DSQLITE_OMIT_DISKIO - <a href="compile.html#omit_diskio">compile.html#omit_diskio</a></li><li>-DSQLITE_OMIT_EXPLAIN - <a href="compile.html#omit_explain">compile.html#omit_explain</a></li><li>-DSQLITE_OMIT_FLAG_PRAGMAS - <a href="compile.html#omit_flag_pragmas">compile.html#omit_flag_pragmas</a></li><li>-DSQLITE_OMIT_FLOATING_POINT - <a href="compile.html#omit_floating_point">compile.html#omit_floating_point</a></li><li>-DSQLITE_OMIT_FOREIGN_KEY - <a href="compile.html#omit_foreign_key">compile.html#omit_foreign_key</a></li><li>-DSQLITE_OMIT_GENERATED_COLUMNS - <a href="compile.html#omit_generated_columns">compile.html#omit_generated_columns</a></li><li>-DSQLITE_OMIT_GET_TABLE - <a href="compile.html#omit_get_table">compile.html#omit_get_table</a></li><li>-DSQLITE_OMIT_HEX_INTEGER - <a href="compile.html#omit_hex_integer">compile.html#omit_hex_integer</a></li><li>-DSQLITE_OMIT_INCRBLOB - <a href="compile.html#omit_incrblob">compile.html#omit_incrblob</a></li><li>-DSQLITE_OMIT_INTEGRITY_CHECK - <a href="compile.html#omit_integrity_check">compile.html#omit_integrity_check</a></li><li>-DSQLITE_OMIT_INTROSPECTION_PRAGMAS - <a href="compile.html#omit_introspection_pragmas">compile.html#omit_introspection_pragmas</a></li><li>-DSQLITE_OMIT_JSON - <a href="compile.html#omit_json">compile.html#omit_json</a></li><li>-DSQLITE_OMIT_LIKE_OPTIMIZATION - <a href="compile.html#omit_like_optimization">compile.html#omit_like_optimization</a></li><li>-DSQLITE_OMIT_LOAD_EXTENSION - <a href="compile.html#omit_load_extension">compile.html#omit_load_extension</a></li><li>-DSQLITE_OMIT_LOCALTIME - <a href="compile.html#omit_localtime">compile.html#omit_localtime</a></li><li>-DSQLITE_OMIT_LOOKASIDE - <a href="compile.html#omit_lookaside">compile.html#omit_lookaside</a></li><li>-DSQLITE_OMIT_MEMORYDB - <a href="compile.html#omit_memorydb">compile.html#omit_memorydb</a></li><li>-DSQLITE_OMIT_OR_OPTIMIZATION - <a href="compile.html#omit_or_optimization">compile.html#omit_or_optimization</a></li><li>-DSQLITE_OMIT_PAGER_PRAGMAS - <a href="compile.html#omit_pager_pragmas">compile.html#omit_pager_pragmas</a></li><li>-DSQLITE_OMIT_PRAGMA - <a href="compile.html#omit_pragma">compile.html#omit_pragma</a></li><li>-DSQLITE_OMIT_PROGRESS_CALLBACK - <a href="compile.html#omit_progress_callback">compile.html#omit_progress_callback</a></li><li>-DSQLITE_OMIT_QUICKBALANCE - <a href="compile.html#omit_quickbalance">compile.html#omit_quickbalance</a></li><li>-DSQLITE_OMIT_REINDEX - <a href="compile.html#omit_reindex">compile.html#omit_reindex</a></li><li>-DSQLITE_OMIT_SCHEMA_PRAGMAS - <a href="compile.html#omit_schema_pragmas">compile.html#omit_schema_pragmas</a></li><li>-DSQLITE_OMIT_SCHEMA_VERSION_PRAGMAS - <a href="compile.html#omit_schema_version_pragmas">compile.html#omit_schema_version_pragmas</a></li><li>-DSQLITE_OMIT_SHARED_CACHE - <a href="compile.html#omit_shared_cache">compile.html#omit_shared_cache</a></li><li>-DSQLITE_OMIT_SUBQUERY - <a href="compile.html#omit_subquery">compile.html#omit_subquery</a></li><li>-DSQLITE_OMIT_TCL_VARIABLE - <a href="compile.html#omit_tcl_variable">compile.html#omit_tcl_variable</a></li><li>-DSQLITE_OMIT_TEMPDB - <a href="compile.html#omit_tempdb">compile.html#omit_tempdb</a></li><li>-DSQLITE_OMIT_TRACE - <a href="compile.html#omit_trace">compile.html#omit_trace</a></li><li>-DSQLITE_OMIT_TRIGGER - <a href="compile.html#omit_trigger">compile.html#omit_trigger</a></li><li>-DSQLITE_OMIT_TRUNCATE_OPTIMIZATION - <a href="compile.html#omit_truncate_optimization">compile.html#omit_truncate_optimization</a></li><li>-DSQLITE_OMIT_UTF16 - <a href="compile.html#omit_utf16">compile.html#omit_utf16</a></li><li>-DSQLITE_OMIT_VACUUM - <a href="compile.html#omit_vacuum">compile.html#omit_vacuum</a></li><li>-DSQLITE_OMIT_VIEW - <a href="compile.html#omit_view">compile.html#omit_view</a></li><li>-DSQLITE_OMIT_VIRTUALTABLE - <a href="compile.html#omit_virtualtable">compile.html#omit_virtualtable</a></li><li>-DSQLITE_OMIT_WAL - <a href="compile.html#omit_wal">compile.html#omit_wal</a></li><li>-DSQLITE_OMIT_WINDOWFUNC - <a href="compile.html#omit_windowfunc">compile.html#omit_windowfunc</a></li><li>-DSQLITE_OMIT_WSD - <a href="compile.html#omit_wsd">compile.html#omit_wsd</a></li><li>-DSQLITE_OMIT_XFER_OPT - <a href="compile.html#omit_xfer_opt">compile.html#omit_xfer_opt</a></li><li>-DSQLITE_OS_OTHER - <a href="compile.html#os_other">compile.html#os_other</a></li><li>-DSQLITE_POWERSAFE_OVERWRITE - <a href="compile.html#powersafe_overwrite">compile.html#powersafe_overwrite</a></li><li>-DSQLITE_PRINTF_PRECISION_LIMIT - <a href="compile.html#printf_precision_limit">compile.html#printf_precision_limit</a></li><li>-DSQLITE_QUERY_PLANNER_LIMIT - <a href="compile.html#query_planner_limit">compile.html#query_planner_limit</a></li><li>-DSQLITE_QUERY_PLANNER_LIMIT_INCR - <a href="compile.html#query_planner_limit_incr">compile.html#query_planner_limit_incr</a></li><li>-DSQLITE_REVERSE_UNORDERED_SELECTS - <a href="compile.html#reverse_unordered_selects">compile.html#reverse_unordered_selects</a></li><li>-DSQLITE_RTREE_INT_ONLY - <a href="compile.html#rtree_int_only">compile.html#rtree_int_only</a></li><li>-DSQLITE_SECURE_DELETE - <a href="compile.html#secure_delete">compile.html#secure_delete</a></li><li>-DSQLITE_SORTER_PMASZ - <a href="compile.html#sorter_pmasz">compile.html#sorter_pmasz</a></li><li>-DSQLITE_SOUNDEX - <a href="compile.html#soundex">compile.html#soundex</a></li><li>-DSQLITE_STDCALL - <a href="compile.html#stdcall">compile.html#stdcall</a></li><li>-DSQLITE_STMTJRNL_SPILL - <a href="compile.html#stmtjrnl_spill">compile.html#stmtjrnl_spill</a></li><li>-DSQLITE_STRICT_SUBTYPE - <a href="compile.html#strict_subtype">compile.html#strict_subtype</a></li><li>-DSQLITE_SYSAPI - <a href="compile.html#sysapi">compile.html#sysapi</a></li><li>-DSQLITE_TCLAPI - <a href="compile.html#tclapi">compile.html#tclapi</a></li><li>-DSQLITE_TEMP_STORE - <a href="compile.html#temp_store">compile.html#temp_store</a></li><li>-DSQLITE_THREADSAFE - <a href="compile.html#threadsafe">compile.html#threadsafe</a></li><li>-DSQLITE_TRACE_SIZE_LIMIT - <a href="compile.html#trace_size_limit">compile.html#trace_size_limit</a></li><li>-DSQLITE_TRUSTED_SCHEMA - <a href="compile.html#trusted_schema">compile.html#trusted_schema</a></li><li>-DSQLITE_UNTESTABLE - <a href="compile.html#untestable">compile.html#untestable</a></li><li>-DSQLITE_USE_ALLOCA - <a href="compile.html#use_alloca">compile.html#use_alloca</a></li><li>-DSQLITE_USE_FCNTL_TRACE - <a href="compile.html#use_fcntl_trace">compile.html#use_fcntl_trace</a></li><li>-DSQLITE_USE_SEH - <a href="compile.html#use_seh">compile.html#use_seh</a></li><li>-DSQLITE_USE_URI - <a href="compile.html#use_uri">compile.html#use_uri</a></li><li>-DSQLITE_WIN32_HEAP_CREATE - <a href="compile.html#win32_heap_create">compile.html#win32_heap_create</a></li><li>-DSQLITE_WIN32_MALLOC - <a href="compile.html#win32_malloc">compile.html#win32_malloc</a></li><li>-DSQLITE_WIN32_MALLOC_VALIDATE - <a href="compile.html#win32_malloc_validate">compile.html#win32_malloc_validate</a></li><li>-DSQLITE_ZERO_MALLOC - <a href="compile.html#zero_malloc">compile.html#zero_malloc</a></li><li>.archive command - <a href="cli.html#sqlar">cli.html#sqlar</a></li><li>.connection - <a href="cli.html#dotconn">cli.html#dotconn</a></li><li>.databases - <a href="cli.html#dotdatabases">cli.html#dotdatabases</a></li><li>.databases command - <a href="cli.html#dotdatabases">cli.html#dotdatabases</a></li><li>.dump - <a href="cli.html#dump">cli.html#dump</a></li><li>.excel - <a href="cli.html#dotexcel">cli.html#dotexcel</a></li><li>.expert command - <a href="cli.html#expert">cli.html#expert</a></li><li>.fullschema - <a href="cli.html#fullschema">cli.html#fullschema</a></li><li>.import - <a href="cli.html#csv">cli.html#csv</a></li><li>.import command - <a href="cli.html#csv">cli.html#csv</a></li><li>.imposter dot-command - <a href="imposter.html#dotimposter">imposter.html#dotimposter</a></li><li>.load command - <a href="cli.html#dotload">cli.html#dotload</a></li><li>.mode - <a href="cli.html#dotmode">cli.html#dotmode</a></li><li>.mode quote - <a href="cli.html#dotmodequote">cli.html#dotmodequote</a></li><li>.once - <a href="cli.html#dotoutput">cli.html#dotoutput</a></li><li>.open - <a href="cli.html#dotopen">cli.html#dotopen</a></li><li>.open command - <a href="cli.html#dotopen">cli.html#dotopen</a></li><li>.output - <a href="cli.html#dotoutput">cli.html#dotoutput</a></li><li>.parameter command - <a href="cli.html#param">cli.html#param</a></li><li>.read - <a href="cli.html#dotread">cli.html#dotread</a></li><li>.recover dot-command - <a href="cli.html#recover">cli.html#recover</a></li><li>.schema - <a href="cli.html#dschema">cli.html#dschema</a></li><li>.selftest dot-command - <a href="cli.html#selftest">cli.html#selftest</a></li><li>.sha3sum dot-command - <a href="cli.html#sha3sum">cli.html#sha3sum</a></li><li>.tables - <a href="cli.html#dtables">cli.html#dtables</a></li><li>3rd-party fuzzers - <a href="testing.html#3pfuzz">testing.html#3pfuzz</a></li><li>34to35 - <a href="34to35.html">34to35.html</a></li><li>35 Faster Than The Filesystem - <a href="fasterthanfs.html">fasterthanfs.html</a></li><li>35to36 - <a href="35to36.html">35to36.html</a></li><li>about 200 SQL statements per webpage - <a href="np1queryprob.html">np1queryprob.html</a></li><li>abs - <a href="lang_corefunc.html#abs">lang_corefunc.html#abs</a></li><li>abs SQL function - <a href="lang_corefunc.html#abs">lang_corefunc.html#abs</a></li><li>ACID - <a href="transactional.html">transactional.html</a></li><li>acos - <a href="lang_mathfunc.html#acos">lang_mathfunc.html#acos</a></li><li>acos SQL function - <a href="lang_mathfunc.html#acos">lang_mathfunc.html#acos</a></li><li>acosh - <a href="lang_mathfunc.html#acosh">lang_mathfunc.html#acosh</a></li><li>acosh SQL function - <a href="lang_mathfunc.html#acosh">lang_mathfunc.html#acosh</a></li><li>add column - <a href="lang_altertable.html#altertabaddcol">lang_altertable.html#altertabaddcol</a></li><li>Adding to Zip - <a href="zipfile.html#adding_entries_to_a_zip_archive">zipfile.html#adding_entries_to_a_zip_archive</a></li><li>advanced - <a href="swarmvtab.html#advanced_usage">swarmvtab.html#advanced_usage</a></li><li>advantages of WAL-mode - <a href="wal.html#advantages">wal.html#advantages</a></li><li>affinities - <a href="datatype3.html#affinity">datatype3.html#affinity</a></li><li>affinity - <a href="datatype3.html#affinity">datatype3.html#affinity</a></li><li>affinity in compound VIEWs - <a href="datatype3.html#affcompoundview">datatype3.html#affcompoundview</a></li><li>Affinity Of Expressions - <a href="datatype3.html#expraff">datatype3.html#expraff</a></li><li>affshort - <a href="aff_short.html">aff_short.html</a></li><li>AFL - <a href="testing.html#aflfuzz">testing.html#aflfuzz</a></li><li>aggfunc - <a href="lang_aggfunc.html">lang_aggfunc.html</a></li><li>Aggregate Functions - <a href="lang_aggfunc.html">lang_aggfunc.html</a></li><li>Aggregate functions - <a href="lang_aggfunc.html">lang_aggfunc.html</a></li><li>aggregate functions - <a href="lang_aggfunc.html">lang_aggfunc.html</a></li><li>aggregate JSON SQL functions - <a href="json1.html#jgroupobjectb">json1.html#jgroupobjectb</a></li><li>aggregate SQL functions - <a href="lang_aggfunc.html">lang_aggfunc.html</a></li><li>aggregate window functions - <a href="windowfunctions.html#aggwinfunc">windowfunctions.html#aggwinfunc</a></li><li>aggregate-function-invocation - <a href="syntax/aggregate-function-invocation.html">syntax/aggregate-function-invocation.html</a></li><li>aggregate-function-invocation syntax diagram - <a href="syntax/aggregate-function-invocation.html">syntax/aggregate-function-invocation.html</a></li><li>alphabetical listing of documents - <a href="doclist.html">doclist.html</a></li><li>ALTER - <a href="lang_altertable.html">lang_altertable.html</a></li><li>ALTER TABLE - <a href="lang_altertable.html">lang_altertable.html</a></li><li>ALTER TABLE ADD COLUMN - <a href="lang_altertable.html#altertabaddcol">lang_altertable.html#altertabaddcol</a></li><li>ALTER TABLE DROP COLUMN - <a href="lang_altertable.html#altertabdropcol">lang_altertable.html#altertabdropcol</a></li><li>ALTER TABLE RENAME - <a href="lang_altertable.html#altertabrename">lang_altertable.html#altertabrename</a></li><li>ALTER TABLE RENAME COLUMN - <a href="lang_altertable.html#altertabmvcol">lang_altertable.html#altertabmvcol</a></li><li>ALTER TABLE RENAME documentation - <a href="lang_altertable.html#altertabrename">lang_altertable.html#altertabrename</a></li><li>alter-table-stmt - <a href="syntax/alter-table-stmt.html">syntax/alter-table-stmt.html</a></li><li>alter-table-stmt syntax diagram - <a href="syntax/alter-table-stmt.html">syntax/alter-table-stmt.html</a></li><li>altertable - <a href="lang_altertable.html">lang_altertable.html</a></li><li>amalgamation - <a href="amalgamation.html">amalgamation.html</a></li><li>amalgamation tarball - <a href="download.html">download.html</a></li><li>American Fuzzy Lop fuzzer - <a href="testing.html#aflfuzz">testing.html#aflfuzz</a></li><li>analysis_limit - <a href="pragma.html#pragma_analysis_limit">pragma.html#pragma_analysis_limit</a></li><li>analysis_limit pragma - <a href="pragma.html#pragma_analysis_limit">pragma.html#pragma_analysis_limit</a></li><li>ANALYZE - <a href="lang_analyze.html">lang_analyze.html</a></li><li>analyze - <a href="lang_analyze.html">lang_analyze.html</a></li><li>analyze-stmt - <a href="syntax/analyze-stmt.html">syntax/analyze-stmt.html</a></li><li>analyze-stmt syntax diagram - <a href="syntax/analyze-stmt.html">syntax/analyze-stmt.html</a></li><li>appformat - <a href="appfileformat.html">appfileformat.html</a></li><li>Application File Format - <a href="appfileformat.html">appfileformat.html</a></li><li>application file format - <a href="appfileformat.html">appfileformat.html</a></li><li>application file-format - <a href="appfileformat.html">appfileformat.html</a></li><li>Application ID - <a href="fileformat2.html#appid">fileformat2.html#appid</a></li><li>application-defined function attacks - <a href="appfunc.html#sec">appfunc.html#sec</a></li><li>application-defined SQL function - <a href="appfunc.html">appfunc.html</a></li><li>application-defined SQL functions - <a href="appfunc.html">appfunc.html</a></li><li>application-defined window functions - <a href="windowfunctions.html#udfwinfunc">windowfunctions.html#udfwinfunc</a></li><li>application_id - <a href="pragma.html#pragma_application_id">pragma.html#pragma_application_id</a></li><li>application_id pragma - <a href="pragma.html#pragma_application_id">pragma.html#pragma_application_id</a></li><li>appreciate the freedom - <a href="flextypegood.html">flextypegood.html</a></li><li>Appropriate Uses For SQLite - <a href="whentouse.html">whentouse.html</a></li><li>approximate ANALYZE - <a href="lang_analyze.html#approx">lang_analyze.html#approx</a></li><li>asin - <a href="lang_mathfunc.html#asin">lang_mathfunc.html#asin</a></li><li>asin SQL function - <a href="lang_mathfunc.html#asin">lang_mathfunc.html#asin</a></li><li>asinh - <a href="lang_mathfunc.html#asinh">lang_mathfunc.html#asinh</a></li><li>asinh SQL function - <a href="lang_mathfunc.html#asinh">lang_mathfunc.html#asinh</a></li><li>asynchronous I/O backend - <a href="asyncvfs.html">asyncvfs.html</a></li><li>asynchronous VFS - <a href="asyncvfs.html">asyncvfs.html</a></li><li>atan - <a href="lang_mathfunc.html#atan">lang_mathfunc.html#atan</a></li><li>atan SQL function - <a href="lang_mathfunc.html#atan">lang_mathfunc.html#atan</a></li><li>atan2 - <a href="lang_mathfunc.html#atan2">lang_mathfunc.html#atan2</a></li><li>atan2 SQL function - <a href="lang_mathfunc.html#atan2">lang_mathfunc.html#atan2</a></li><li>atanh - <a href="lang_mathfunc.html#atanh">lang_mathfunc.html#atanh</a></li><li>atanh SQL function - <a href="lang_mathfunc.html#atanh">lang_mathfunc.html#atanh</a></li><li>Atomic Commit - <a href="atomiccommit.html">atomiccommit.html</a></li><li>atomic commit - <a href="atomiccommit.html">atomiccommit.html</a></li><li>ATTACH - <a href="lang_attach.html">lang_attach.html</a></li><li>attach - <a href="lang_attach.html">lang_attach.html</a></li><li>ATTACH DATABASE - <a href="lang_attach.html">lang_attach.html</a></li><li>attach-stmt - <a href="syntax/attach-stmt.html">syntax/attach-stmt.html</a></li><li>attach-stmt syntax diagram - <a href="syntax/attach-stmt.html">syntax/attach-stmt.html</a></li><li>attached - <a href="lang_attach.html">lang_attach.html</a></li><li>attack resistance - <a href="security.html">security.html</a></li><li>authorizer callback - <a href="c3ref/set_authorizer.html">c3ref/set_authorizer.html</a></li><li>authorizer method - <a href="tclsqlite.html#authorizer">tclsqlite.html#authorizer</a></li><li>auto modifier - <a href="lang_datefunc.html#automod">lang_datefunc.html#automod</a></li><li>auto_vacuum - <a href="pragma.html#pragma_auto_vacuum">pragma.html#pragma_auto_vacuum</a></li><li>auto_vacuum pragma - <a href="pragma.html#pragma_auto_vacuum">pragma.html#pragma_auto_vacuum</a></li><li>autocommit mode - <a href="c3ref/get_autocommit.html">c3ref/get_autocommit.html</a></li><li>AUTOINCREMENT - <a href="autoinc.html">autoinc.html</a></li><li>automated undo/redo stack - <a href="undoredo.html">undoredo.html</a></li><li>automatic indexes - <a href="optoverview.html#autoindex">optoverview.html#autoindex</a></li><li>Automatic indexing - <a href="optoverview.html#autoindex">optoverview.html#autoindex</a></li><li>automatic indexing - <a href="optoverview.html#autoindex">optoverview.html#autoindex</a></li><li>automatic_index - <a href="pragma.html#pragma_automatic_index">pragma.html#pragma_automatic_index</a></li><li>automatic_index pragma - <a href="pragma.html#pragma_automatic_index">pragma.html#pragma_automatic_index</a></li><li>automatically running ANALYZE - <a href="lang_analyze.html#autoanalyze">lang_analyze.html#autoanalyze</a></li><li>automerge command - <a href="fts3.html#*fts4automergecmd">fts3.html#*fts4automergecmd</a></li><li>auxiliary columns - <a href="rtree.html#auxcol">rtree.html#auxcol</a></li><li>auxiliary columns in r-tree tables - <a href="rtree.html#auxcol">rtree.html#auxcol</a></li><li>auxiliary function mapping - <a href="fts5.html#sorting_by_auxiliary_function_results">fts5.html#sorting_by_auxiliary_function_results</a></li><li>avg - <a href="lang_aggfunc.html#avg">lang_aggfunc.html#avg</a></li><li>avg aggregate function - <a href="lang_aggfunc.html#avg">lang_aggfunc.html#avg</a></li><li>avoiding large WAL files - <a href="wal.html#bigwal">wal.html#bigwal</a></li><li>B-tree - <a href="fileformat2.html#btree">fileformat2.html#btree</a></li><li>B-Trees - <a href="fileformat2.html#btree">fileformat2.html#btree</a></li><li>backup API - <a href="backup.html">backup.html</a></li><li>backup method - <a href="tclsqlite.html#backup">tclsqlite.html#backup</a></li><li>bare aggregate terms - <a href="lang_select.html#bareagg">lang_select.html#bareagg</a></li><li>base64 SQL function - <a href="cli.html#base64">cli.html#base64</a></li><li>base85 SQL function - <a href="cli.html#base85">cli.html#base85</a></li><li>bcvtab - <a href="bytecodevtab.html">bytecodevtab.html</a></li><li>BEGIN - <a href="lang_transaction.html">lang_transaction.html</a></li><li>BEGIN EXCLUSIVE - <a href="lang_transaction.html#immediate">lang_transaction.html#immediate</a></li><li>BEGIN IMMEDIATE - <a href="lang_transaction.html#immediate">lang_transaction.html#immediate</a></li><li>begin-stmt - <a href="syntax/begin-stmt.html">syntax/begin-stmt.html</a></li><li>begin-stmt syntax diagram - <a href="syntax/begin-stmt.html">syntax/begin-stmt.html</a></li><li>benefits of using WITHOUT ROWID - <a href="withoutrowid.html#bene">withoutrowid.html#bene</a></li><li>BETWEEN - <a href="lang_expr.html#between">lang_expr.html#between</a></li><li>BINARY - <a href="datatype3.html#collation">datatype3.html#collation</a></li><li>BINARY collating function - <a href="datatype3.html#collation">datatype3.html#collation</a></li><li>binary operators - <a href="lang_expr.html#binaryops">lang_expr.html#binaryops</a></li><li>bind_fallback method - <a href="tclsqlite.html#bind_fallback">tclsqlite.html#bind_fallback</a></li><li>BLOB handle - <a href="c3ref/blob.html">c3ref/blob.html</a></li><li>BLOB handles - <a href="c3ref/blob.html">c3ref/blob.html</a></li><li>BLOB I/O performance - <a href="intern-v-extern-blob.html">intern-v-extern-blob.html</a></li><li>block sorting - <a href="queryplanner.html#partialsort">queryplanner.html#partialsort</a></li><li>books about SQLite - <a href="books.html">books.html</a></li><li>boolean datatype - <a href="datatype3.html#boolean">datatype3.html#boolean</a></li><li>boolean expression - <a href="lang_expr.html#booleanexpr">lang_expr.html#booleanexpr</a></li><li>bound parameter - <a href="lang_expr.html#varparam">lang_expr.html#varparam</a></li><li>bound parameters - <a href="lang_expr.html#varparam">lang_expr.html#varparam</a></li><li>bugs - <a href="fts3.html#limitations">fts3.html#limitations</a></li><li>build product names - <a href="download.html#encoding">download.html#encoding</a></li><li>building a DLL - <a href="howtocompile.html#dll">howtocompile.html#dll</a></li><li>building the amalgamation - <a href="howtocompile.html#amal">howtocompile.html#amal</a></li><li>built-in memory allocators - <a href="malloc.html#altalloc">malloc.html#altalloc</a></li><li>built-in printf - <a href="printf.html">printf.html</a></li><li>built-in SQL math functions - <a href="lang_mathfunc.html">lang_mathfunc.html</a></li><li>built-in window functions - <a href="windowfunctions.html#builtins">windowfunctions.html#builtins</a></li><li>built-ins - <a href="windowfunctions.html#builtins">windowfunctions.html#builtins</a></li><li>builtin window functions - <a href="windowfunctions.html#biwinfunc">windowfunctions.html#biwinfunc</a></li><li>busy handler - <a href="c3ref/busy_handler.html">c3ref/busy_handler.html</a></li><li>busy method - <a href="tclsqlite.html#busy">tclsqlite.html#busy</a></li><li>busy-handler callback - <a href="c3ref/busy_handler.html">c3ref/busy_handler.html</a></li><li>busy_timeout - <a href="pragma.html#pragma_busy_timeout">pragma.html#pragma_busy_timeout</a></li><li>busy_timeout pragma - <a href="pragma.html#pragma_busy_timeout">pragma.html#pragma_busy_timeout</a></li><li>byte-order determination rules - <a href="c3ref/bind_blob.html#byteorderdeterminationrules">c3ref/bind_blob.html#byteorderdeterminationrules</a></li><li>bytecode - <a href="opcode.html">opcode.html</a></li><li>bytecode and tables_used virtual tables - <a href="bytecodevtab.html">bytecodevtab.html</a></li><li>bytecode engine - <a href="opcode.html">opcode.html</a></li><li>bytecode virtual table - <a href="bytecodevtab.html">bytecodevtab.html</a></li><li>bytecodes - <a href="opcode.html">opcode.html</a></li><li>C-API function list - <a href="c3ref/funclist.html">c3ref/funclist.html</a></li><li>C-language Interface - <a href="c3ref/intro.html">c3ref/intro.html</a></li><li>cache method - <a href="tclsqlite.html#cache">tclsqlite.html#cache</a></li><li>cache query parameter - <a href="uri.html#uricache">uri.html#uricache</a></li><li>cache_size - <a href="pragma.html#pragma_cache_size">pragma.html#pragma_cache_size</a></li><li>cache_size pragma - <a href="pragma.html#pragma_cache_size">pragma.html#pragma_cache_size</a></li><li>cache_spill - <a href="pragma.html#pragma_cache_spill">pragma.html#pragma_cache_spill</a></li><li>cache_spill pragma - <a href="pragma.html#pragma_cache_spill">pragma.html#pragma_cache_spill</a></li><li>canonical source code - <a href="getthecode.html">getthecode.html</a></li><li>capi3ref - <a href="c3ref/intro.html">c3ref/intro.html</a></li><li>capi3ref_funclist - <a href="c3ref/funclist.html">c3ref/funclist.html</a></li><li>carray - <a href="carray.html">carray.html</a></li><li>carray table-valued function - <a href="carray.html">carray.html</a></li><li>CASE expression - <a href="lang_expr.html#case">lang_expr.html#case</a></li><li>case_sensitive_like - <a href="pragma.html#pragma_case_sensitive_like">pragma.html#pragma_case_sensitive_like</a></li><li>case_sensitive_like pragma - <a href="pragma.html#pragma_case_sensitive_like">pragma.html#pragma_case_sensitive_like</a></li><li>CAST - <a href="lang_expr.html#castexpr">lang_expr.html#castexpr</a></li><li>cast - <a href="lang_expr.html#castexpr">lang_expr.html#castexpr</a></li><li>CAST expression - <a href="lang_expr.html#castexpr">lang_expr.html#castexpr</a></li><li>CAST operator - <a href="lang_expr.html#castexpr">lang_expr.html#castexpr</a></li><li>categorical listing of SQLite documents - <a href="docs.html">docs.html</a></li><li>ceil - <a href="lang_mathfunc.html#ceil">lang_mathfunc.html#ceil</a></li><li>ceiling - <a href="lang_mathfunc.html#ceil">lang_mathfunc.html#ceil</a></li><li>cell format summary - <a href="fileformat2.html#cellformat">fileformat2.html#cellformat</a></li><li>cell payload - <a href="fileformat2.html#cell_payload">fileformat2.html#cell_payload</a></li><li>cell_size_check - <a href="pragma.html#pragma_cell_size_check">pragma.html#pragma_cell_size_check</a></li><li>cell_size_check pragma - <a href="pragma.html#pragma_cell_size_check">pragma.html#pragma_cell_size_check</a></li><li>cfgerrors - <a href="howtocorrupt.html#cfgerr">howtocorrupt.html#cfgerr</a></li><li>change counter - <a href="fileformat2.html#chngctr">fileformat2.html#chngctr</a></li><li>changes - <a href="lang_corefunc.html#changes">lang_corefunc.html#changes</a></li><li>changes method - <a href="tclsqlite.html#changes">tclsqlite.html#changes</a></li><li>changes SQL function - <a href="lang_corefunc.html#changes">lang_corefunc.html#changes</a></li><li>changeset - <a href="sessionintro.html#changeset">sessionintro.html#changeset</a></li><li>changesets - <a href="sessionintro.html#changeset">sessionintro.html#changeset</a></li><li>char - <a href="lang_corefunc.html#char">lang_corefunc.html#char</a></li><li>char SQL function - <a href="lang_corefunc.html#char">lang_corefunc.html#char</a></li><li>CHECK - <a href="lang_createtable.html#ckconst">lang_createtable.html#ckconst</a></li><li>CHECK constraint - <a href="lang_createtable.html#ckconst">lang_createtable.html#ckconst</a></li><li>CHECK constraints - <a href="lang_createtable.html#ckconst">lang_createtable.html#ckconst</a></li><li>checklist - <a href="testing.html#cklist">testing.html#cklist</a></li><li>checkpoint - <a href="wal.html#ckpt">wal.html#ckpt</a></li><li>checkpoint mode - <a href="c3ref/c_checkpoint_full.html">c3ref/c_checkpoint_full.html</a></li><li>checkpoint_fullfsync - <a href="pragma.html#pragma_checkpoint_fullfsync">pragma.html#pragma_checkpoint_fullfsync</a></li><li>checkpoint_fullfsync pragma - <a href="pragma.html#pragma_checkpoint_fullfsync">pragma.html#pragma_checkpoint_fullfsync</a></li><li>checkpointed - <a href="wal.html#ckpt">wal.html#ckpt</a></li><li>checkpointing - <a href="wal.html#ckpt">wal.html#ckpt</a></li><li>checksum VFS - <a href="cksumvfs.html">cksumvfs.html</a></li><li>checksum VFS shim - <a href="cksumvfs.html">cksumvfs.html</a></li><li>child key - <a href="foreignkeys.html#parentchild">foreignkeys.html#parentchild</a></li><li>child table - <a href="foreignkeys.html#parentchild">foreignkeys.html#parentchild</a></li><li>chronology - <a href="chronology.html">chronology.html</a></li><li>cintro - <a href="cintro.html">cintro.html</a></li><li>cksumvfs - <a href="cksumvfs.html">cksumvfs.html</a></li><li>CLI - <a href="cli.html">cli.html</a></li><li>clone the entire repository - <a href="getthecode.html#clone">getthecode.html#clone</a></li><li>close method - <a href="tclsqlite.html#close">tclsqlite.html#close</a></li><li>Clustered indexes - <a href="withoutrowid.html">withoutrowid.html</a></li><li>co-routines - <a href="optoverview.html#coroutines">optoverview.html#coroutines</a></li><li>coalesce - <a href="lang_corefunc.html#coalesce">lang_corefunc.html#coalesce</a></li><li>coalesce SQL function - <a href="lang_corefunc.html#coalesce">lang_corefunc.html#coalesce</a></li><li>Code of Conduct - <a href="codeofconduct.html">codeofconduct.html</a></li><li>Code of Ethics - <a href="codeofethics.html">codeofethics.html</a></li><li>Code of Ethics of the Project Founder - <a href="codeofethics.html">codeofethics.html</a></li><li>code repositories - <a href="download.html#srctree">download.html#srctree</a></li><li>COLLATE - <a href="lang_createindex.html#collidx">lang_createindex.html#collidx</a></li><li>COLLATE clause - <a href="lang_createtable.html#collateclause">lang_createtable.html#collateclause</a></li><li>COLLATE clauses - <a href="lang_createtable.html#collateclause">lang_createtable.html#collateclause</a></li><li>COLLATE constraint - <a href="lang_createtable.html#collateclause">lang_createtable.html#collateclause</a></li><li>collate method - <a href="tclsqlite.html#collate">tclsqlite.html#collate</a></li><li>COLLATE operator - <a href="lang_expr.html#collateop">lang_expr.html#collateop</a></li><li>collating function - <a href="datatype3.html#collation">datatype3.html#collation</a></li><li>collating sequence - <a href="datatype3.html#collation">datatype3.html#collation</a></li><li>collating sequences - <a href="datatype3.html#collation">datatype3.html#collation</a></li><li>collation - <a href="datatype3.html#collation">datatype3.html#collation</a></li><li>collation_list - <a href="pragma.html#pragma_collation_list">pragma.html#pragma_collation_list</a></li><li>collation_list pragma - <a href="pragma.html#pragma_collation_list">pragma.html#pragma_collation_list</a></li><li>collation_needed method - <a href="tclsqlite.html#collation_needed">tclsqlite.html#collation_needed</a></li><li>column access functions - <a href="c3ref/column_blob.html">c3ref/column_blob.html</a></li><li>column affinity - <a href="datatype3.html#affinity">datatype3.html#affinity</a></li><li>column definition - <a href="lang_createtable.html#tablecoldef">lang_createtable.html#tablecoldef</a></li><li>column definitions - <a href="lang_createtable.html#tablecoldef">lang_createtable.html#tablecoldef</a></li><li>column-constraint - <a href="syntax/column-constraint.html">syntax/column-constraint.html</a></li><li>column-constraint syntax diagram - <a href="syntax/column-constraint.html">syntax/column-constraint.html</a></li><li>column-def - <a href="syntax/column-def.html">syntax/column-def.html</a></li><li>column-def syntax diagram - <a href="syntax/column-def.html">syntax/column-def.html</a></li><li>column-name-list - <a href="syntax/column-name-list.html">syntax/column-name-list.html</a></li><li>column-name-list syntax diagram - <a href="syntax/column-name-list.html">syntax/column-name-list.html</a></li><li>Columnar output modes - <a href="cli.html#clmnr">cli.html#clmnr</a></li><li>columnar output modes - <a href="cli.html#clmnr">cli.html#clmnr</a></li><li>colUsed field - <a href="vtab.html#colUsed">vtab.html#colUsed</a></li><li>comma option - <a href="printf.html#comma">printf.html#comma</a></li><li>Command Line Interface - <a href="cli.html">cli.html</a></li><li>command-line interface - <a href="cli.html">cli.html</a></li><li>command-line options - <a href="cli.html#clopts">cli.html#clopts</a></li><li>command-line shell - <a href="cli.html">cli.html</a></li><li>commands - <a href="fts3.html#commands">fts3.html#commands</a></li><li>comment - <a href="lang_comment.html">lang_comment.html</a></li><li>comment-syntax - <a href="syntax/comment-syntax.html">syntax/comment-syntax.html</a></li><li>comment-syntax syntax diagram - <a href="syntax/comment-syntax.html">syntax/comment-syntax.html</a></li><li>comments - <a href="lang_comment.html">lang_comment.html</a></li><li>COMMIT - <a href="lang_transaction.html">lang_transaction.html</a></li><li>commit-stmt - <a href="syntax/commit-stmt.html">syntax/commit-stmt.html</a></li><li>commit-stmt syntax diagram - <a href="syntax/commit-stmt.html">syntax/commit-stmt.html</a></li><li>commit_hook method - <a href="tclsqlite.html#commit_hook">tclsqlite.html#commit_hook</a></li><li>common table expressions - <a href="lang_with.html">lang_with.html</a></li><li>common-table-expression - <a href="syntax/common-table-expression.html">syntax/common-table-expression.html</a></li><li>common-table-expression syntax diagram - <a href="syntax/common-table-expression.html">syntax/common-table-expression.html</a></li><li>comparison affinity rules - <a href="datatype3.html#compaff">datatype3.html#compaff</a></li><li>comparison expressions - <a href="datatype3.html#comparisons">datatype3.html#comparisons</a></li><li>comparison with fts4 - <a href="fts5.html#appendix_a">fts5.html#appendix_a</a></li><li>compilation - <a href="swarmvtab.html#compiling_and_using_swarmvtab">swarmvtab.html#compiling_and_using_swarmvtab</a></li><li>compile fts - <a href="fts3.html#compiling_and_enabling_fts3_and_fts4">fts3.html#compiling_and_enabling_fts3_and_fts4</a></li><li>compile loadable extensions - <a href="loadext.html#build">loadext.html#build</a></li><li>compile-time options - <a href="compile.html">compile.html</a></li><li>compile_options - <a href="pragma.html#pragma_compile_options">pragma.html#pragma_compile_options</a></li><li>compile_options pragma - <a href="pragma.html#pragma_compile_options">pragma.html#pragma_compile_options</a></li><li>Compiling Loadable Extensions - <a href="loadext.html#build">loadext.html#build</a></li><li>compiling the CLI - <a href="howtocompile.html#cli">howtocompile.html#cli</a></li><li>compiling the TCL interface - <a href="howtocompile.html#tcl">howtocompile.html#tcl</a></li><li>complete list of SQLite releases - <a href="changes.html">changes.html</a></li><li>complete method - <a href="tclsqlite.html#complete">tclsqlite.html#complete</a></li><li>COMPLETION - <a href="completion.html">completion.html</a></li><li>COMPLETION extension - <a href="completion.html">completion.html</a></li><li>COMPLETION table-valued function - <a href="completion.html">completion.html</a></li><li>compound query - <a href="lang_select.html#compound">lang_select.html#compound</a></li><li>compound SELECT - <a href="lang_select.html#compound">lang_select.html#compound</a></li><li>compound select - <a href="lang_select.html#compound">lang_select.html#compound</a></li><li>compound SELECTs - <a href="lang_select.html#compound">lang_select.html#compound</a></li><li>compound-operator - <a href="syntax/compound-operator.html">syntax/compound-operator.html</a></li><li>compound-operator syntax diagram - <a href="syntax/compound-operator.html">syntax/compound-operator.html</a></li><li>compound-select-stmt - <a href="syntax/compound-select-stmt.html">syntax/compound-select-stmt.html</a></li><li>compound-select-stmt syntax diagram - <a href="syntax/compound-select-stmt.html">syntax/compound-select-stmt.html</a></li><li>compressed FTS4 content - <a href="fts3.html#*fts4compression">fts3.html#*fts4compression</a></li><li>compute the Mandelbrot set - <a href="lang_with.html#mandelbrot">lang_with.html#mandelbrot</a></li><li>computed columns - <a href="gencol.html">gencol.html</a></li><li>concat - <a href="lang_corefunc.html#concat">lang_corefunc.html#concat</a></li><li>concat SQL function - <a href="lang_corefunc.html#concat">lang_corefunc.html#concat</a></li><li>concat_ws - <a href="lang_corefunc.html#concat_ws">lang_corefunc.html#concat_ws</a></li><li>concat_ws SQL function - <a href="lang_corefunc.html#concat_ws">lang_corefunc.html#concat_ws</a></li><li>config method - <a href="tclsqlite.html#config">tclsqlite.html#config</a></li><li>configurable edit distances - <a href="spellfix1.html#configeditdist">spellfix1.html#configeditdist</a></li><li>configuration option - <a href="c3ref/c_config_covering_index_scan.html">c3ref/c_config_covering_index_scan.html</a></li><li>conflict - <a href="lang_conflict.html">lang_conflict.html</a></li><li>conflict clause - <a href="lang_conflict.html">lang_conflict.html</a></li><li>conflict resolution algorithm - <a href="lang_conflict.html">lang_conflict.html</a></li><li>conflict resolution mode - <a href="c3ref/c_fail.html">c3ref/c_fail.html</a></li><li>conflict-clause - <a href="syntax/conflict-clause.html">syntax/conflict-clause.html</a></li><li>conflict-clause syntax diagram - <a href="syntax/conflict-clause.html">syntax/conflict-clause.html</a></li><li>constant-propagation optimization - <a href="optoverview.html#constprop">optoverview.html#constprop</a></li><li>contentless fts4 tables - <a href="fts3.html#_contentless_fts4_tables_">fts3.html#_contentless_fts4_tables_</a></li><li>contentless-delete - <a href="fts5.html#clssdeltab">fts5.html#clssdeltab</a></li><li>copy method - <a href="tclsqlite.html#copy">tclsqlite.html#copy</a></li><li>copyright - <a href="copyright.html">copyright.html</a></li><li>Core Functions - <a href="lang_corefunc.html">lang_corefunc.html</a></li><li>core URI query parameters - <a href="c3ref/open.html#coreuriqueryparameters">c3ref/open.html#coreuriqueryparameters</a></li><li>corefunc - <a href="lang_corefunc.html">lang_corefunc.html</a></li><li>coreqp - <a href="uri.html#coreqp">uri.html#coreqp</a></li><li>correlated subqueries - <a href="lang_expr.html#cosub">lang_expr.html#cosub</a></li><li>cos - <a href="lang_mathfunc.html#cos">lang_mathfunc.html#cos</a></li><li>cos SQL function - <a href="lang_mathfunc.html#cos">lang_mathfunc.html#cos</a></li><li>cosh - <a href="lang_mathfunc.html#cosh">lang_mathfunc.html#cosh</a></li><li>cosh SQL function - <a href="lang_mathfunc.html#cosh">lang_mathfunc.html#cosh</a></li><li>count - <a href="lang_aggfunc.html#count">lang_aggfunc.html#count</a></li><li>count aggregate function - <a href="lang_aggfunc.html#count">lang_aggfunc.html#count</a></li><li>count_changes - <a href="pragma.html#pragma_count_changes">pragma.html#pragma_count_changes</a></li><li>count_changes pragma - <a href="pragma.html#pragma_count_changes">pragma.html#pragma_count_changes</a></li><li>coverage testing vs. fuzz testing - <a href="testing.html#tension">testing.html#tension</a></li><li>covering index - <a href="queryplanner.html#covidx">queryplanner.html#covidx</a></li><li>covering indexes - <a href="queryplanner.html#covidx">queryplanner.html#covidx</a></li><li>covering indices - <a href="queryplanner.html#covidx">queryplanner.html#covidx</a></li><li>CPU cycles used - <a href="cpu.html">cpu.html</a></li><li>CPU performance measurement - <a href="cpu.html">cpu.html</a></li><li>CREATE INDEX - <a href="lang_createindex.html">lang_createindex.html</a></li><li>CREATE TABLE - <a href="lang_createtable.html">lang_createtable.html</a></li><li>CREATE TABLE AS - <a href="lang_createtable.html#createtabas">lang_createtable.html#createtabas</a></li><li>CREATE TRIGGER - <a href="lang_createtrigger.html">lang_createtrigger.html</a></li><li>CREATE VIEW - <a href="lang_createview.html">lang_createview.html</a></li><li>CREATE VIRTUAL TABLE - <a href="lang_createvtab.html">lang_createvtab.html</a></li><li>create-index-stmt - <a href="syntax/create-index-stmt.html">syntax/create-index-stmt.html</a></li><li>create-index-stmt syntax diagram - <a href="syntax/create-index-stmt.html">syntax/create-index-stmt.html</a></li><li>create-table-stmt - <a href="syntax/create-table-stmt.html">syntax/create-table-stmt.html</a></li><li>create-table-stmt syntax diagram - <a href="syntax/create-table-stmt.html">syntax/create-table-stmt.html</a></li><li>create-trigger-stmt - <a href="syntax/create-trigger-stmt.html">syntax/create-trigger-stmt.html</a></li><li>create-trigger-stmt syntax diagram - <a href="syntax/create-trigger-stmt.html">syntax/create-trigger-stmt.html</a></li><li>create-view-stmt - <a href="syntax/create-view-stmt.html">syntax/create-view-stmt.html</a></li><li>create-view-stmt syntax diagram - <a href="syntax/create-view-stmt.html">syntax/create-view-stmt.html</a></li><li>create-virtual-table-stmt - <a href="syntax/create-virtual-table-stmt.html">syntax/create-virtual-table-stmt.html</a></li><li>create-virtual-table-stmt syntax diagram - <a href="syntax/create-virtual-table-stmt.html">syntax/create-virtual-table-stmt.html</a></li><li>createindex - <a href="lang_createindex.html">lang_createindex.html</a></li><li>createtable - <a href="lang_createtable.html">lang_createtable.html</a></li><li>createtrigger - <a href="lang_createtrigger.html">lang_createtrigger.html</a></li><li>createview - <a href="lang_createview.html">lang_createview.html</a></li><li>createvtab - <a href="lang_createvtab.html">lang_createvtab.html</a></li><li>crew - <a href="crew.html">crew.html</a></li><li>CROSS JOIN - <a href="optoverview.html#crossjoin">optoverview.html#crossjoin</a></li><li>csv - <a href="csv.html">csv.html</a></li><li>CSV export - <a href="cli.html#csvout">cli.html#csvout</a></li><li>CSV import - <a href="cli.html#csv">cli.html#csv</a></li><li>CSV virtual table - <a href="csv.html">csv.html</a></li><li>cte-table-name - <a href="syntax/cte-table-name.html">syntax/cte-table-name.html</a></li><li>cte-table-name syntax diagram - <a href="syntax/cte-table-name.html">syntax/cte-table-name.html</a></li><li>custom auxiliary functions - <a href="fts5.html#_custom_auxiliary_functions_api_reference_">fts5.html#_custom_auxiliary_functions_api_reference_</a></li><li>custom builds - <a href="custombuild.html">custombuild.html</a></li><li>custom r-tree queries - <a href="rtree.html#customquery">rtree.html#customquery</a></li><li>custom SQL function - <a href="appfunc.html">appfunc.html</a></li><li>custom SQL functions - <a href="appfunc.html">appfunc.html</a></li><li>custom tokenizers - <a href="fts5.html#custom_tokenizers">fts5.html#custom_tokenizers</a></li><li>custom virtual tables - <a href="vtab.html#customvtab">vtab.html#customvtab</a></li><li>CVEs - <a href="cves.html">cves.html</a></li><li>Dan Kennedy - <a href="crew.html#dan">crew.html#dan</a></li><li>data container - <a href="whentouse.html#container">whentouse.html#container</a></li><li>data transfer format - <a href="whentouse.html#wireproto">whentouse.html#wireproto</a></li><li>data_store_directory - <a href="pragma.html#pragma_data_store_directory">pragma.html#pragma_data_store_directory</a></li><li>data_store_directory pragma - <a href="pragma.html#pragma_data_store_directory">pragma.html#pragma_data_store_directory</a></li><li>data_version - <a href="pragma.html#pragma_data_version">pragma.html#pragma_data_version</a></li><li>data_version pragma - <a href="pragma.html#pragma_data_version">pragma.html#pragma_data_version</a></li><li>database as container object - <a href="sqlar.html#dbasobj">sqlar.html#dbasobj</a></li><li>database as object - <a href="sqlar.html#dbasobj">sqlar.html#dbasobj</a></li><li>database connection - <a href="c3ref/sqlite3.html">c3ref/sqlite3.html</a></li><li>database connections - <a href="c3ref/sqlite3.html">c3ref/sqlite3.html</a></li><li>database corruption caused by inconsistent use of 83 filenames - <a href="shortnames.html#db83corrupt">shortnames.html#db83corrupt</a></li><li>database filename aliasing - <a href="howtocorrupt.html#alias">howtocorrupt.html#alias</a></li><li>database header - <a href="fileformat2.html#database_header">fileformat2.html#database_header</a></li><li>database_list - <a href="pragma.html#pragma_database_list">pragma.html#pragma_database_list</a></li><li>database_list pragma - <a href="pragma.html#pragma_database_list">pragma.html#pragma_database_list</a></li><li>datatype - <a href="datatype3.html">datatype3.html</a></li><li>date - <a href="lang_datefunc.html#dttm">lang_datefunc.html#dttm</a></li><li>date and time datatype - <a href="datatype3.html#datetime">datatype3.html#datetime</a></li><li>Date And Time Functions - <a href="lang_datefunc.html">lang_datefunc.html</a></li><li>date and time functions - <a href="lang_datefunc.html">lang_datefunc.html</a></li><li>date SQL function - <a href="lang_datefunc.html#dttm">lang_datefunc.html#dttm</a></li><li>date/time modifiers - <a href="lang_datefunc.html#dtmods">lang_datefunc.html#dtmods</a></li><li>date/time special case - <a href="deterministic.html#dtexception">deterministic.html#dtexception</a></li><li>datefunc - <a href="lang_datefunc.html">lang_datefunc.html</a></li><li>datetime - <a href="lang_datefunc.html#dttm">lang_datefunc.html#dttm</a></li><li>datetime SQL function - <a href="lang_datefunc.html#dttm">lang_datefunc.html#dttm</a></li><li>dbghints - <a href="debugging.html">debugging.html</a></li><li>dbhash - <a href="dbhash.html">dbhash.html</a></li><li>dbhash.exe - <a href="dbhash.html">dbhash.html</a></li><li>dbsqlfuzz - <a href="testing.html#dbsqlfuzz">testing.html#dbsqlfuzz</a></li><li>dbstat - <a href="dbstat.html">dbstat.html</a></li><li>DBSTAT aggregated mode - <a href="dbstat.html#dbstatagg">dbstat.html#dbstatagg</a></li><li>DBSTAT virtual table - <a href="dbstat.html">dbstat.html</a></li><li>dbstat virtual table - <a href="dbstat.html">dbstat.html</a></li><li>debugging hints - <a href="debugging.html">debugging.html</a></li><li>debugging memory allocator - <a href="malloc.html#memdebug">malloc.html#memdebug</a></li><li>decimal extension - <a href="floatingpoint.html#decext">floatingpoint.html#decext</a></li><li>decision checklist - <a href="whentouse.html#dbcklst">whentouse.html#dbcklst</a></li><li>DEFAULT clauses - <a href="lang_createtable.html#dfltval">lang_createtable.html#dfltval</a></li><li>default column value - <a href="lang_createtable.html#dfltval">lang_createtable.html#dfltval</a></li><li>default memory allocator - <a href="malloc.html#defaultalloc">malloc.html#defaultalloc</a></li><li>default value - <a href="lang_createtable.html#dfltval">lang_createtable.html#dfltval</a></li><li>default_cache_size - <a href="pragma.html#pragma_default_cache_size">pragma.html#pragma_default_cache_size</a></li><li>default_cache_size pragma - <a href="pragma.html#pragma_default_cache_size">pragma.html#pragma_default_cache_size</a></li><li>defense against dark arts - <a href="security.html">security.html</a></li><li>defense against the dark arts - <a href="security.html">security.html</a></li><li>defensive code - <a href="testing.html#defcode">testing.html#defcode</a></li><li>defer_foreign_keys - <a href="pragma.html#pragma_defer_foreign_keys">pragma.html#pragma_defer_foreign_keys</a></li><li>defer_foreign_keys pragma - <a href="pragma.html#pragma_defer_foreign_keys">pragma.html#pragma_defer_foreign_keys</a></li><li>degrees - <a href="lang_mathfunc.html#degrees">lang_mathfunc.html#degrees</a></li><li>degrees SQL function - <a href="lang_mathfunc.html#degrees">lang_mathfunc.html#degrees</a></li><li>DELETE - <a href="lang_delete.html">lang_delete.html</a></li><li>delete - <a href="lang_delete.html">lang_delete.html</a></li><li>delete-stmt - <a href="syntax/delete-stmt.html">syntax/delete-stmt.html</a></li><li>delete-stmt syntax diagram - <a href="syntax/delete-stmt.html">syntax/delete-stmt.html</a></li><li>delete-stmt-limited - <a href="syntax/delete-stmt-limited.html">syntax/delete-stmt-limited.html</a></li><li>delete-stmt-limited syntax diagram - <a href="syntax/delete-stmt-limited.html">syntax/delete-stmt-limited.html</a></li><li>deletemerge - <a href="fts5.html#the_deletemerge_configuration_option">fts5.html#the_deletemerge_configuration_option</a></li><li>DELETEs - <a href="lang_delete.html">lang_delete.html</a></li><li>deleting a hot journal - <a href="howtocorrupt.html#delhotjrnl">howtocorrupt.html#delhotjrnl</a></li><li>deprecated - <a href="c3ref/experimental.html">c3ref/experimental.html</a></li><li>DESC - <a href="lang_createindex.html#descidx">lang_createindex.html#descidx</a></li><li>descending index - <a href="lang_createindex.html#descidx">lang_createindex.html#descidx</a></li><li>descending indexes - <a href="lang_createindex.html#descidx">lang_createindex.html#descidx</a></li><li>descending indices - <a href="lang_createindex.html#descidx">lang_createindex.html#descidx</a></li><li>deserialize method - <a href="tclsqlite.html#deserialize">tclsqlite.html#deserialize</a></li><li>DETACH - <a href="lang_detach.html">lang_detach.html</a></li><li>detach - <a href="lang_detach.html">lang_detach.html</a></li><li>DETACH DATABASE - <a href="lang_detach.html">lang_detach.html</a></li><li>detach-stmt - <a href="syntax/detach-stmt.html">syntax/detach-stmt.html</a></li><li>detach-stmt syntax diagram - <a href="syntax/detach-stmt.html">syntax/detach-stmt.html</a></li><li>deterministic function - <a href="deterministic.html">deterministic.html</a></li><li>deterministic functions - <a href="deterministic.html">deterministic.html</a></li><li>deterministic SQL functions - <a href="deterministic.html">deterministic.html</a></li><li>DISTINCT - <a href="lang_select.html#distinct">lang_select.html#distinct</a></li><li>doclist - <a href="doclist.html">doclist.html</a></li><li>documents by category - <a href="docs.html">docs.html</a></li><li>dot-commands - <a href="cli.html#dotcmd">cli.html#dotcmd</a></li><li>double-quoted string literal - <a href="quirks.html#dblquote">quirks.html#dblquote</a></li><li>double-quoted string misfeature - <a href="quirks.html#dblquote">quirks.html#dblquote</a></li><li>download page - <a href="download.html">download.html</a></li><li>drop column - <a href="lang_altertable.html#altertabdropcol">lang_altertable.html#altertabdropcol</a></li><li>DROP INDEX - <a href="lang_dropindex.html">lang_dropindex.html</a></li><li>DROP TABLE - <a href="lang_droptable.html">lang_droptable.html</a></li><li>DROP TRIGGER - <a href="lang_droptrigger.html">lang_droptrigger.html</a></li><li>DROP VIEW - <a href="lang_dropview.html">lang_dropview.html</a></li><li>drop-index-stmt - <a href="syntax/drop-index-stmt.html">syntax/drop-index-stmt.html</a></li><li>drop-index-stmt syntax diagram - <a href="syntax/drop-index-stmt.html">syntax/drop-index-stmt.html</a></li><li>drop-table-stmt - <a href="syntax/drop-table-stmt.html">syntax/drop-table-stmt.html</a></li><li>drop-table-stmt syntax diagram - <a href="syntax/drop-table-stmt.html">syntax/drop-table-stmt.html</a></li><li>drop-trigger-stmt - <a href="syntax/drop-trigger-stmt.html">syntax/drop-trigger-stmt.html</a></li><li>drop-trigger-stmt syntax diagram - <a href="syntax/drop-trigger-stmt.html">syntax/drop-trigger-stmt.html</a></li><li>drop-view-stmt - <a href="syntax/drop-view-stmt.html">syntax/drop-view-stmt.html</a></li><li>drop-view-stmt syntax diagram - <a href="syntax/drop-view-stmt.html">syntax/drop-view-stmt.html</a></li><li>dropindex - <a href="lang_dropindex.html">lang_dropindex.html</a></li><li>droptable - <a href="lang_droptable.html">lang_droptable.html</a></li><li>droptrigger - <a href="lang_droptrigger.html">lang_droptrigger.html</a></li><li>dropview - <a href="lang_dropview.html">lang_dropview.html</a></li><li>dynamic string - <a href="c3ref/str.html">c3ref/str.html</a></li><li>dynamic typing - <a href="datatype3.html">datatype3.html</a></li><li>edit SQL function - <a href="cli.html#editfunc">cli.html#editfunc</a></li><li>editdist3 - <a href="spellfix1.html#editdist3">spellfix1.html#editdist3</a></li><li>embedded - <a href="serverless.html">serverless.html</a></li><li>empty_result_callbacks - <a href="pragma.html#pragma_empty_result_callbacks">pragma.html#pragma_empty_result_callbacks</a></li><li>empty_result_callbacks pragma - <a href="pragma.html#pragma_empty_result_callbacks">pragma.html#pragma_empty_result_callbacks</a></li><li>enable_load_extension method - <a href="tclsqlite.html#enable_load_extension">tclsqlite.html#enable_load_extension</a></li><li>encoding - <a href="pragma.html#pragma_encoding">pragma.html#pragma_encoding</a></li><li>encoding pragma - <a href="pragma.html#pragma_encoding">pragma.html#pragma_encoding</a></li><li>enhanced query syntax - <a href="fts3.html#_set_operations_using_the_enhanced_query_syntax">fts3.html#_set_operations_using_the_enhanced_query_syntax</a></li><li>eponymous virtual table - <a href="vtab.html#epovtab">vtab.html#epovtab</a></li><li>eponymous virtual tables - <a href="vtab.html#epovtab">vtab.html#epovtab</a></li><li>eponymous-only virtual table - <a href="vtab.html#epoonlyvtab">vtab.html#epoonlyvtab</a></li><li>eponymous-only virtual tables - <a href="vtab.html#epoonlyvtab">vtab.html#epoonlyvtab</a></li><li>eqp-or-opt - <a href="eqp.html#or-opt">eqp.html#or-opt</a></li><li>errlog - <a href="errlog.html">errlog.html</a></li><li>error code - <a href="rescode.html">rescode.html</a></li><li>error codes - <a href="rescode.html">rescode.html</a></li><li>error log - <a href="errlog.html">errlog.html</a></li><li>errorcode method - <a href="tclsqlite.html#errorcode">tclsqlite.html#errorcode</a></li><li>ESCAPE - <a href="lang_expr.html#like">lang_expr.html#like</a></li><li>eval method - <a href="tclsqlite.html#eval">tclsqlite.html#eval</a></li><li>EXCLUDE clause - <a href="windowfunctions.html#wexcls">windowfunctions.html#wexcls</a></li><li>exclude clause - <a href="windowfunctions.html#wexcls">windowfunctions.html#wexcls</a></li><li>EXCLUSIVE - <a href="lockingv3.html#excl_lock">lockingv3.html#excl_lock</a></li><li>EXCLUSIVE lock - <a href="lockingv3.html#excl_lock">lockingv3.html#excl_lock</a></li><li>exclusive lock - <a href="lockingv3.html#excl_lock">lockingv3.html#excl_lock</a></li><li>EXCLUSIVE locking mode - <a href="pragma.html#pragma_locking_mode">pragma.html#pragma_locking_mode</a></li><li>exclusive locking mode - <a href="pragma.html#pragma_locking_mode">pragma.html#pragma_locking_mode</a></li><li>exists method - <a href="tclsqlite.html#exists">tclsqlite.html#exists</a></li><li>EXISTS operator - <a href="lang_expr.html#exists_op">lang_expr.html#exists_op</a></li><li>exp - <a href="lang_mathfunc.html#exp">lang_mathfunc.html#exp</a></li><li>exp SQL function - <a href="lang_mathfunc.html#exp">lang_mathfunc.html#exp</a></li><li>experimental - <a href="c3ref/experimental.html">c3ref/experimental.html</a></li><li>experimental memory allocators - <a href="malloc.html#memsysx">malloc.html#memsysx</a></li><li>EXPLAIN - <a href="lang_explain.html">lang_explain.html</a></li><li>explain - <a href="lang_explain.html">lang_explain.html</a></li><li>EXPLAIN QUERY PLAN - <a href="eqp.html">eqp.html</a></li><li>explain query plan - <a href="eqp.html">eqp.html</a></li><li>export to excel - <a href="cli.html#exexcel*">cli.html#exexcel*</a></li><li>export to TSV - <a href="cli.html#extsv*">cli.html#extsv*</a></li><li>expr - <a href="syntax/expr.html">syntax/expr.html</a></li><li>expr syntax diagram - <a href="syntax/expr.html">syntax/expr.html</a></li><li>expression - <a href="lang_expr.html">lang_expr.html</a></li><li>expression affinity - <a href="datatype3.html#expraff">datatype3.html#expraff</a></li><li>expression index - <a href="expridx.html">expridx.html</a></li><li>expression indexes - <a href="expridx.html">expridx.html</a></li><li>expression syntax - <a href="lang_expr.html">lang_expr.html</a></li><li>ext-v-prim - <a href="rescode.html#pve">rescode.html#pve</a></li><li>extended error code - <a href="rescode.html#extrc">rescode.html#extrc</a></li><li>extended error codes - <a href="rescode.html#extrc">rescode.html#extrc</a></li><li>extended result code - <a href="rescode.html#extrc">rescode.html#extrc</a></li><li>extended result code definitions - <a href="c3ref/c_abort_rollback.html">c3ref/c_abort_rollback.html</a></li><li>extended result codes - <a href="rescode.html#extrc">rescode.html#extrc</a></li><li>Extending FTS5 - <a href="fts5.html#extending_fts5">fts5.html#extending_fts5</a></li><li>extension loading - <a href="loadext.html">loadext.html</a></li><li>external content fts4 tables - <a href="fts3.html#_external_content_fts4_tables_">fts3.html#_external_content_fts4_tables_</a></li><li>extract - <a href="lang_expr.html#extract">lang_expr.html#extract</a></li><li>factored-select-stmt - <a href="syntax/factored-select-stmt.html">syntax/factored-select-stmt.html</a></li><li>factored-select-stmt syntax diagram - <a href="syntax/factored-select-stmt.html">syntax/factored-select-stmt.html</a></li><li>faster than the filesystem - <a href="fasterthanfs.html">fasterthanfs.html</a></li><li>file control - <a href="c3ref/file_control.html">c3ref/file_control.html</a></li><li>file control opcode - <a href="c3ref/c_fcntl_begin_atomic_write.html">c3ref/c_fcntl_begin_atomic_write.html</a></li><li>file control opcodes - <a href="c3ref/c_fcntl_begin_atomic_write.html">c3ref/c_fcntl_begin_atomic_write.html</a></li><li>file format - <a href="fileformat2.html">fileformat2.html</a></li><li>file format version numbers - <a href="fileformat2.html#vnums">fileformat2.html#vnums</a></li><li>file I/O functions - <a href="cli.html#fileio">cli.html#fileio</a></li><li>file locking and concurrency control - <a href="lockingv3.html">lockingv3.html</a></li><li>file locking states - <a href="lockingv3.html#locking">lockingv3.html#locking</a></li><li>file-format benefits - <a href="aff_short.html">aff_short.html</a></li><li>filesystem corruption - <a href="howtocorrupt.html#fscorruption">howtocorrupt.html#fscorruption</a></li><li>FILTER clause on aggregate functions - <a href="lang_aggfunc.html#aggfilter">lang_aggfunc.html#aggfilter</a></li><li>filter-clause - <a href="syntax/filter-clause.html">syntax/filter-clause.html</a></li><li>filter-clause syntax diagram - <a href="syntax/filter-clause.html">syntax/filter-clause.html</a></li><li>flattened - <a href="optoverview.html#flattening">optoverview.html#flattening</a></li><li>flattening optimization - <a href="optoverview.html#flattening">optoverview.html#flattening</a></li><li>flexible type system - <a href="datatype3.html">datatype3.html</a></li><li>Flexible typing is a feature - <a href="flextypegood.html">flextypegood.html</a></li><li>floor - <a href="lang_mathfunc.html#floor">lang_mathfunc.html#floor</a></li><li>floor SQL function - <a href="lang_mathfunc.html#floor">lang_mathfunc.html#floor</a></li><li>footprint - <a href="footprint.html">footprint.html</a></li><li>foreign key actions - <a href="foreignkeys.html#fk_actions">foreignkeys.html#fk_actions</a></li><li>foreign key constraint - <a href="foreignkeys.html">foreignkeys.html</a></li><li>FOREIGN KEY constraints - <a href="foreignkeys.html">foreignkeys.html</a></li><li>foreign key constraints - <a href="foreignkeys.html">foreignkeys.html</a></li><li>foreign key constraints are enabled - <a href="foreignkeys.html#fk_enable">foreignkeys.html#fk_enable</a></li><li>foreign-key-clause - <a href="syntax/foreign-key-clause.html">syntax/foreign-key-clause.html</a></li><li>foreign-key-clause syntax diagram - <a href="syntax/foreign-key-clause.html">syntax/foreign-key-clause.html</a></li><li>foreign_key_check - <a href="pragma.html#pragma_foreign_key_check">pragma.html#pragma_foreign_key_check</a></li><li>foreign_key_check pragma - <a href="pragma.html#pragma_foreign_key_check">pragma.html#pragma_foreign_key_check</a></li><li>foreign_key_list - <a href="pragma.html#pragma_foreign_key_list">pragma.html#pragma_foreign_key_list</a></li><li>foreign_key_list pragma - <a href="pragma.html#pragma_foreign_key_list">pragma.html#pragma_foreign_key_list</a></li><li>foreign_keys - <a href="pragma.html#pragma_foreign_keys">pragma.html#pragma_foreign_keys</a></li><li>foreign_keys pragma - <a href="pragma.html#pragma_foreign_keys">pragma.html#pragma_foreign_keys</a></li><li>format - <a href="lang_corefunc.html#format">lang_corefunc.html#format</a></li><li>format SQL function - <a href="lang_corefunc.html#format">lang_corefunc.html#format</a></li><li>forum - <a href="support.html#fx">support.html#fx</a></li><li>frame boundary - <a href="windowfunctions.html#frameboundary">windowfunctions.html#frameboundary</a></li><li>frame specification - <a href="windowfunctions.html#framespec">windowfunctions.html#framespec</a></li><li>frame type - <a href="windowfunctions.html#frametype">windowfunctions.html#frametype</a></li><li>frame-spec - <a href="syntax/frame-spec.html">syntax/frame-spec.html</a></li><li>frame-spec syntax diagram - <a href="syntax/frame-spec.html">syntax/frame-spec.html</a></li><li>frames - <a href="windowfunctions.html#framespec">windowfunctions.html#framespec</a></li><li>free-page list - <a href="fileformat2.html#freelist">fileformat2.html#freelist</a></li><li>freelist - <a href="fileformat2.html#freelist">fileformat2.html#freelist</a></li><li>freelist_count - <a href="pragma.html#pragma_freelist_count">pragma.html#pragma_freelist_count</a></li><li>freelist_count pragma - <a href="pragma.html#pragma_freelist_count">pragma.html#pragma_freelist_count</a></li><li>FROM clause - <a href="lang_select.html#fromclause">lang_select.html#fromclause</a></li><li>FTS auxiliary functions - <a href="fts3.html#snippet">fts3.html#snippet</a></li><li>FTS hidden column - <a href="fts3.html#hiddencol">fts3.html#hiddencol</a></li><li>FTS MATCH - <a href="fts3.html#full_text_index_queries">fts3.html#full_text_index_queries</a></li><li>FTS shadow tables - <a href="fts3.html#*shadowtab">fts3.html#*shadowtab</a></li><li>FTS3 - <a href="fts3.html">fts3.html</a></li><li>fts3 - <a href="fts3.html">fts3.html</a></li><li>fts3_tokenizer - <a href="fts3.html#f3tknzr">fts3.html#f3tknzr</a></li><li>fts3tokenize - <a href="fts3.html#fts3tok">fts3.html#fts3tok</a></li><li>fts3tokenize virtual table - <a href="fts3.html#fts3tok">fts3.html#fts3tok</a></li><li>FTS4 - <a href="fts3.html#fts4">fts3.html#fts4</a></li><li>FTS4 automerge command - <a href="fts3.html#*fts4automergecmd">fts3.html#*fts4automergecmd</a></li><li>FTS4 commands - <a href="fts3.html#*cmds">fts3.html#*cmds</a></li><li>fts4 compress option - <a href="fts3.html#the_compress_and_uncompress_options">fts3.html#the_compress_and_uncompress_options</a></li><li>FTS4 content option - <a href="fts3.html#*fts4content">fts3.html#*fts4content</a></li><li>fts4 content option - <a href="fts3.html#the_content_option_">fts3.html#the_content_option_</a></li><li>FTS4 integrity-check command - <a href="fts3.html#*fts4ickcmd">fts3.html#*fts4ickcmd</a></li><li>FTS4 languageid option - <a href="fts3.html#*fts4languageid">fts3.html#*fts4languageid</a></li><li>fts4 languageid option - <a href="fts3.html#the_languageid_option">fts3.html#the_languageid_option</a></li><li>FTS4 matchinfo option - <a href="fts3.html#fts4matchinfo">fts3.html#fts4matchinfo</a></li><li>fts4 matchinfo option - <a href="fts3.html#the_matchinfo_option">fts3.html#the_matchinfo_option</a></li><li>FTS4 merge command - <a href="fts3.html#*fts4mergecmd">fts3.html#*fts4mergecmd</a></li><li>FTS4 notindexed option - <a href="fts3.html#fts4notindexed">fts3.html#fts4notindexed</a></li><li>fts4 notindexed option - <a href="fts3.html#the_notindexed_option">fts3.html#the_notindexed_option</a></li><li>FTS4 optimize command - <a href="fts3.html#*fts4optcmd">fts3.html#*fts4optcmd</a></li><li>FTS4 options - <a href="fts3.html#fts4_options">fts3.html#fts4_options</a></li><li>FTS4 order option - <a href="fts3.html#fts4order">fts3.html#fts4order</a></li><li>FTS4 prefix option - <a href="fts3.html#fts4prefix">fts3.html#fts4prefix</a></li><li>fts4 prefix option - <a href="fts3.html#the_prefix_option">fts3.html#the_prefix_option</a></li><li>FTS4 rebuild command - <a href="fts3.html#*fts4rebuidcmd">fts3.html#*fts4rebuidcmd</a></li><li>fts4aux - <a href="fts3.html#fts4aux">fts3.html#fts4aux</a></li><li>fts4aux languageid column - <a href="fts3.html#f4alid">fts3.html#f4alid</a></li><li>FTS5 - <a href="fts5.html">fts5.html</a></li><li>fts5 - <a href="fts5.html">fts5.html</a></li><li>FTS5 automerge option - <a href="fts5.html#the_automerge_configuration_option">fts5.html#the_automerge_configuration_option</a></li><li>FTS5 auxiliary functions - <a href="fts5.html#_auxiliary_functions_">fts5.html#_auxiliary_functions_</a></li><li>FTS5 bm25 - <a href="fts5.html#the_bm25_function">fts5.html#the_bm25_function</a></li><li>FTS5 boolean operators - <a href="fts5.html#fts5_boolean_operators">fts5.html#fts5_boolean_operators</a></li><li>FTS5 building - <a href="fts5.html#compiling_and_using_fts5">fts5.html#compiling_and_using_fts5</a></li><li>FTS5 column filters - <a href="fts5.html#fts5_column_filters">fts5.html#fts5_column_filters</a></li><li>FTS5 columnsize option - <a href="fts5.html#the_columnsize_option">fts5.html#the_columnsize_option</a></li><li>FTS5 content option - <a href="fts5.html#external_content_and_contentless_tables">fts5.html#external_content_and_contentless_tables</a></li><li>FTS5 contentless tables - <a href="fts5.html#contentless_tables">fts5.html#contentless_tables</a></li><li>FTS5 contentless-delete tables - <a href="fts5.html#contentless_delete_tables">fts5.html#contentless_delete_tables</a></li><li>FTS5 CREATE TABLE Options - <a href="fts5.html#fts5_table_creation_and_initialization">fts5.html#fts5_table_creation_and_initialization</a></li><li>FTS5 custom auxiliary functions - <a href="fts5.html#custom_auxiliary_functions">fts5.html#custom_auxiliary_functions</a></li><li>FTS5 delete command - <a href="fts5.html#the_delete_command">fts5.html#the_delete_command</a></li><li>FTS5 delete-all command - <a href="fts5.html#the_delete_all_command">fts5.html#the_delete_all_command</a></li><li>FTS5 detail option - <a href="fts5.html#the_detail_option">fts5.html#the_detail_option</a></li><li>FTS5 external content pitfalls - <a href="fts5.html#external_content_table_pitfalls">fts5.html#external_content_table_pitfalls</a></li><li>FTS5 external content tables - <a href="fts5.html#external_content_tables">fts5.html#external_content_tables</a></li><li>FTS5 highlight - <a href="fts5.html#the_highlight_function">fts5.html#the_highlight_function</a></li><li>FTS5 initial token - <a href="fts5.html#carrotq">fts5.html#carrotq</a></li><li>FTS5 initial token queries - <a href="fts5.html#fts5_initial_token_queries">fts5.html#fts5_initial_token_queries</a></li><li>FTS5 merge command - <a href="fts5.html#the_merge_command">fts5.html#the_merge_command</a></li><li>FTS5 NEAR queries - <a href="fts5.html#fts5_near_queries">fts5.html#fts5_near_queries</a></li><li>FTS5 optimize command - <a href="fts5.html#the_optimize_command">fts5.html#the_optimize_command</a></li><li>FTS5 pgsz option - <a href="fts5.html#the_pgsz_configuration_option">fts5.html#the_pgsz_configuration_option</a></li><li>FTS5 Phrases - <a href="fts5.html#fts5_phrases">fts5.html#fts5_phrases</a></li><li>FTS5 prefix indexes - <a href="fts5.html#prefix_indexes">fts5.html#prefix_indexes</a></li><li>FTS5 prefix queries - <a href="fts5.html#fts5_prefix_queries">fts5.html#fts5_prefix_queries</a></li><li>FTS5 query syntax - <a href="fts5.html#full_text_query_syntax">fts5.html#full_text_query_syntax</a></li><li>FTS5 rank configuration option - <a href="fts5.html#the_rank_configuration_option">fts5.html#the_rank_configuration_option</a></li><li>FTS5 rebuild command - <a href="fts5.html#the_rebuild_command">fts5.html#the_rebuild_command</a></li><li>FTS5 secure-delete command - <a href="fts5.html#the_secure_delete_configuration_option">fts5.html#the_secure_delete_configuration_option</a></li><li>fts5 shadow tables - <a href="fts5.html#fts5shadowtables">fts5.html#fts5shadowtables</a></li><li>FTS5 snippet - <a href="fts5.html#the_snippet_function">fts5.html#the_snippet_function</a></li><li>FTS5 Strings - <a href="fts5.html#fts5_strings">fts5.html#fts5_strings</a></li><li>fts5 technical differences - <a href="fts5.html#_summary_of_technical_differences_">fts5.html#_summary_of_technical_differences_</a></li><li>FTS5 tokendata option - <a href="fts5.html#the_tokendata_option">fts5.html#the_tokendata_option</a></li><li>FTS5 tokenizers - <a href="fts5.html#tokenizers">fts5.html#tokenizers</a></li><li>FTS5 usermerge option - <a href="fts5.html#the_usermerge_configuration_option">fts5.html#the_usermerge_configuration_option</a></li><li>fts5vocab - <a href="fts5.html#the_fts5vocab_virtual_table_module">fts5.html#the_fts5vocab_virtual_table_module</a></li><li>FULL JOIN - <a href="lang_select.html#fulljoin">lang_select.html#fulljoin</a></li><li>FULL OUTER JOIN - <a href="lang_select.html#fulljoin">lang_select.html#fulljoin</a></li><li>Full-featured SQL - <a href="fullsql.html">fullsql.html</a></li><li>full-featured SQL - <a href="fullsql.html">fullsql.html</a></li><li>full-text search - <a href="fts3.html">fts3.html</a></li><li>full_column_names - <a href="pragma.html#pragma_full_column_names">pragma.html#pragma_full_column_names</a></li><li>full_column_names pragma - <a href="pragma.html#pragma_full_column_names">pragma.html#pragma_full_column_names</a></li><li>fullfsync - <a href="pragma.html#pragma_fullfsync">pragma.html#pragma_fullfsync</a></li><li>fullfsync pragma - <a href="pragma.html#pragma_fullfsync">pragma.html#pragma_fullfsync</a></li><li>function creation routines - <a href="c3ref/create_function.html">c3ref/create_function.html</a></li><li>function method - <a href="tclsqlite.html#function">tclsqlite.html#function</a></li><li>function-arguments - <a href="syntax/function-arguments.html">syntax/function-arguments.html</a></li><li>function-arguments syntax diagram - <a href="syntax/function-arguments.html">syntax/function-arguments.html</a></li><li>function_list - <a href="pragma.html#pragma_function_list">pragma.html#pragma_function_list</a></li><li>function_list pragma - <a href="pragma.html#pragma_function_list">pragma.html#pragma_function_list</a></li><li>functions within expressions - <a href="lang_expr.html#*funcinexpr">lang_expr.html#*funcinexpr</a></li><li>fuzz testing - <a href="testing.html#fuzztesting">testing.html#fuzztesting</a></li><li>fuzzcheck - <a href="testing.html#fuzzcheck">testing.html#fuzzcheck</a></li><li>generalized ALTER TABLE procedure - <a href="lang_altertable.html#otheralter">lang_altertable.html#otheralter</a></li><li>generate_series - <a href="series.html">series.html</a></li><li>generated column - <a href="gencol.html">gencol.html</a></li><li>Generated columns - <a href="gencol.html">gencol.html</a></li><li>generated columns - <a href="gencol.html">gencol.html</a></li><li>GEOPOLY - <a href="geopoly.html">geopoly.html</a></li><li>geopoly - <a href="geopoly.html">geopoly.html</a></li><li>Geopoly extension - <a href="geopoly.html">geopoly.html</a></li><li>Geopoly module - <a href="geopoly.html">geopoly.html</a></li><li>geopoly_area - <a href="geopoly.html#garea">geopoly.html#garea</a></li><li>geopoly_bbox - <a href="geopoly.html#gbbox">geopoly.html#gbbox</a></li><li>geopoly_blob - <a href="geopoly.html#gblob">geopoly.html#gblob</a></li><li>geopoly_ccw - <a href="geopoly.html#ccw">geopoly.html#ccw</a></li><li>geopoly_contains_point - <a href="geopoly.html#gpoint">geopoly.html#gpoint</a></li><li>geopoly_group_bbox - <a href="geopoly.html#gbbox">geopoly.html#gbbox</a></li><li>geopoly_json - <a href="geopoly.html#gjson">geopoly.html#gjson</a></li><li>geopoly_overlap - <a href="geopoly.html#goverlap">geopoly.html#goverlap</a></li><li>geopoly_regular - <a href="geopoly.html#regpoly">geopoly.html#regpoly</a></li><li>geopoly_svg - <a href="geopoly.html#gsvg">geopoly.html#gsvg</a></li><li>geopoly_within - <a href="geopoly.html#gwithin">geopoly.html#gwithin</a></li><li>geopoly_xform - <a href="geopoly.html#xform">geopoly.html#xform</a></li><li>get the canonical source code - <a href="getthecode.html">getthecode.html</a></li><li>GLOB - <a href="lang_expr.html#glob">lang_expr.html#glob</a></li><li>glob - <a href="lang_corefunc.html#glob">lang_corefunc.html#glob</a></li><li>glob SQL function - <a href="lang_corefunc.html#glob">lang_corefunc.html#glob</a></li><li>GROUP BY - <a href="lang_select.html#resultset">lang_select.html#resultset</a></li><li>GROUP BY clause - <a href="lang_select.html#resultset">lang_select.html#resultset</a></li><li>group_concat - <a href="lang_aggfunc.html#group_concat">lang_aggfunc.html#group_concat</a></li><li>group_concat aggregate function - <a href="lang_aggfunc.html#group_concat">lang_aggfunc.html#group_concat</a></li><li>GROUPS frames - <a href="windowfunctions.html#grouptype">windowfunctions.html#grouptype</a></li><li>hard_heap_limit - <a href="pragma.html#pragma_hard_heap_limit">pragma.html#pragma_hard_heap_limit</a></li><li>hard_heap_limit pragma - <a href="pragma.html#pragma_hard_heap_limit">pragma.html#pragma_hard_heap_limit</a></li><li>hash join - <a href="optoverview.html#hashjoin">optoverview.html#hashjoin</a></li><li>HAVE_FDATASYNC - <a href="compile.html#fdatasync">compile.html#fdatasync</a></li><li>HAVE_GMTIME_R - <a href="compile.html#gmtime_r">compile.html#gmtime_r</a></li><li>HAVE_ISNAN - <a href="compile.html#isnan">compile.html#isnan</a></li><li>HAVE_LOCALTIME_R - <a href="compile.html#localtime_r">compile.html#localtime_r</a></li><li>HAVE_LOCALTIME_S - <a href="compile.html#localtime_s">compile.html#localtime_s</a></li><li>HAVE_MALLOC_USABLE_SIZE - <a href="compile.html#malloc_usable_size">compile.html#malloc_usable_size</a></li><li>HAVE_SQLITE_CONFIG_H - <a href="compile.html#sqlite_config_h">compile.html#sqlite_config_h</a></li><li>HAVE_STRCHRNUL - <a href="compile.html#strchrnul">compile.html#strchrnul</a></li><li>HAVE_UTIME - <a href="compile.html#utime">compile.html#utime</a></li><li>HAVING - <a href="lang_select.html#resultset">lang_select.html#resultset</a></li><li>HAVING clause - <a href="lang_select.html#resultset">lang_select.html#resultset</a></li><li>hazards of upgrading to the NGQP - <a href="queryplanner-ng.html#hazards">queryplanner-ng.html#hazards</a></li><li>hex - <a href="lang_corefunc.html#hex">lang_corefunc.html#hex</a></li><li>hex SQL function - <a href="lang_corefunc.html#hex">lang_corefunc.html#hex</a></li><li>hexadecimal integer literals - <a href="lang_expr.html#hexint">lang_expr.html#hexint</a></li><li>hexadecimal integers - <a href="lang_expr.html#hexint">lang_expr.html#hexint</a></li><li>hidden column - <a href="vtab.html#hiddencol">vtab.html#hiddencol</a></li><li>hidden columns - <a href="vtab.html#hiddencol">vtab.html#hiddencol</a></li><li>high-reliability - <a href="hirely.html">hirely.html</a></li><li>Hipp - <a href="crew.html">crew.html</a></li><li>host parameter - <a href="c3ref/bind_blob.html">c3ref/bind_blob.html</a></li><li>host parameter name - <a href="c3ref/bind_blob.html">c3ref/bind_blob.html</a></li><li>host parameters - <a href="c3ref/bind_blob.html">c3ref/bind_blob.html</a></li><li>hot journal - <a href="fileformat2.html#hotjrnl">fileformat2.html#hotjrnl</a></li><li>hot journal files - <a href="fileformat2.html#hotjrnl">fileformat2.html#hotjrnl</a></li><li>how collation is determined - <a href="datatype3.html#colrules">datatype3.html#colrules</a></li><li>How SQL Works - <a href="howitworks.html">howitworks.html</a></li><li>How SQLite Works - <a href="howitworks.html">howitworks.html</a></li><li>how to compile - <a href="howtocompile.html">howtocompile.html</a></li><li>How To Compile SQLite - <a href="howtocompile.html">howtocompile.html</a></li><li>how to corrupt - <a href="howtocorrupt.html">howtocorrupt.html</a></li><li>how to corrupt a database - <a href="useovernet.html">useovernet.html</a></li><li>How To Corrupt Your Database Files - <a href="lockingv3.html#how_to_corrupt">lockingv3.html#how_to_corrupt</a></li><li>how vacuum works - <a href="lang_vacuum.html#howvacuumworks">lang_vacuum.html#howvacuumworks</a></li><li>IEEE 754 floating point values are approximations - <a href="floatingpoint.html#fpapprox">floatingpoint.html#fpapprox</a></li><li>ieee754 extension - <a href="floatingpoint.html#ieee754ext">floatingpoint.html#ieee754ext</a></li><li>ieee754 function - <a href="floatingpoint.html#ieee754">floatingpoint.html#ieee754</a></li><li>ieee754_exponent function - <a href="floatingpoint.html#ieee754m">floatingpoint.html#ieee754m</a></li><li>ieee754_from_blob function - <a href="floatingpoint.html#ieee754b">floatingpoint.html#ieee754b</a></li><li>ieee754_mantissa function - <a href="floatingpoint.html#ieee754m">floatingpoint.html#ieee754m</a></li><li>ieee754_to_blob function - <a href="floatingpoint.html#ieee754b">floatingpoint.html#ieee754b</a></li><li>ifnull - <a href="lang_corefunc.html#ifnull">lang_corefunc.html#ifnull</a></li><li>ifnull SQL function - <a href="lang_corefunc.html#ifnull">lang_corefunc.html#ifnull</a></li><li>ignore_check_constraints - <a href="pragma.html#pragma_ignore_check_constraints">pragma.html#pragma_ignore_check_constraints</a></li><li>ignore_check_constraints pragma - <a href="pragma.html#pragma_ignore_check_constraints">pragma.html#pragma_ignore_check_constraints</a></li><li>iif - <a href="lang_corefunc.html#iif">lang_corefunc.html#iif</a></li><li>iif SQL function - <a href="lang_corefunc.html#iif">lang_corefunc.html#iif</a></li><li>immutable query parameter - <a href="uri.html#uriimmutable">uri.html#uriimmutable</a></li><li>imposter tables - <a href="imposter.html">imposter.html</a></li><li>IN operator - <a href="lang_expr.html#in_op">lang_expr.html#in_op</a></li><li>in-header database size - <a href="fileformat2.html#filesize">fileformat2.html#filesize</a></li><li>in-memory database - <a href="inmemorydb.html">inmemorydb.html</a></li><li>in-memory databases - <a href="inmemorydb.html">inmemorydb.html</a></li><li>in-memory shared cache database - <a href="inmemorydb.html#sharedmemdb">inmemorydb.html#sharedmemdb</a></li><li>in-memory shared-cache - <a href="sharedcache.html#inmemsharedcache">sharedcache.html#inmemsharedcache</a></li><li>incrblob method - <a href="tclsqlite.html#incrblob">tclsqlite.html#incrblob</a></li><li>increase in the default page size - <a href="pgszchng2016.html">pgszchng2016.html</a></li><li>incremental_vacuum - <a href="pragma.html#pragma_incremental_vacuum">pragma.html#pragma_incremental_vacuum</a></li><li>incremental_vacuum pragma - <a href="pragma.html#pragma_incremental_vacuum">pragma.html#pragma_incremental_vacuum</a></li><li>index b-tree - <a href="fileformat2.html#btypes">fileformat2.html#btypes</a></li><li>index_info - <a href="pragma.html#pragma_index_info">pragma.html#pragma_index_info</a></li><li>index_info pragma - <a href="pragma.html#pragma_index_info">pragma.html#pragma_index_info</a></li><li>index_list - <a href="pragma.html#pragma_index_list">pragma.html#pragma_index_list</a></li><li>index_list pragma - <a href="pragma.html#pragma_index_list">pragma.html#pragma_index_list</a></li><li>index_xinfo - <a href="pragma.html#pragma_index_xinfo">pragma.html#pragma_index_xinfo</a></li><li>index_xinfo pragma - <a href="pragma.html#pragma_index_xinfo">pragma.html#pragma_index_xinfo</a></li><li>INDEXED BY - <a href="lang_indexedby.html">lang_indexedby.html</a></li><li>indexed expression - <a href="expridx.html">expridx.html</a></li><li>indexed expressions - <a href="expridx.html">expridx.html</a></li><li>indexed-column - <a href="syntax/indexed-column.html">syntax/indexed-column.html</a></li><li>indexed-column syntax diagram - <a href="syntax/indexed-column.html">syntax/indexed-column.html</a></li><li>Indexes - <a href="lang_createindex.html">lang_createindex.html</a></li><li>Indexes On Expressions - <a href="expridx.html">expridx.html</a></li><li>indexes on expressions - <a href="expridx.html">expridx.html</a></li><li>indexing - <a href="queryplanner.html">queryplanner.html</a></li><li>indexing tutorial - <a href="queryplanner.html">queryplanner.html</a></li><li>INSERT - <a href="lang_insert.html">lang_insert.html</a></li><li>insert - <a href="lang_insert.html">lang_insert.html</a></li><li>insert-stmt - <a href="syntax/insert-stmt.html">syntax/insert-stmt.html</a></li><li>insert-stmt syntax diagram - <a href="syntax/insert-stmt.html">syntax/insert-stmt.html</a></li><li>INSERTs - <a href="lang_insert.html">lang_insert.html</a></li><li>INSTEAD OF - <a href="lang_createtrigger.html#instead_of_trigger">lang_createtrigger.html#instead_of_trigger</a></li><li>INSTEAD OF trigger - <a href="lang_createtrigger.html#instead_of_trigger">lang_createtrigger.html#instead_of_trigger</a></li><li>instr - <a href="lang_corefunc.html#instr">lang_corefunc.html#instr</a></li><li>instr SQL function - <a href="lang_corefunc.html#instr">lang_corefunc.html#instr</a></li><li>INTEGER PRIMARY KEY - <a href="lang_createtable.html#rowid">lang_createtable.html#rowid</a></li><li>integer-valued r-trees - <a href="rtree.html#intrtree">rtree.html#intrtree</a></li><li>integrity_check - <a href="pragma.html#pragma_integrity_check">pragma.html#pragma_integrity_check</a></li><li>integrity_check pragma - <a href="pragma.html#pragma_integrity_check">pragma.html#pragma_integrity_check</a></li><li>internal index - <a href="fileformat2.html#intschema">fileformat2.html#intschema</a></li><li>internal indexes - <a href="fileformat2.html#intschema">fileformat2.html#intschema</a></li><li>internal schema object - <a href="fileformat2.html#intschema">fileformat2.html#intschema</a></li><li>internal schema objects - <a href="fileformat2.html#intschema">fileformat2.html#intschema</a></li><li>internal table - <a href="fileformat2.html#intschema">fileformat2.html#intschema</a></li><li>internal tables - <a href="fileformat2.html#intschema">fileformat2.html#intschema</a></li><li>Internal Versus External BLOBs - <a href="intern-v-extern-blob.html">intern-v-extern-blob.html</a></li><li>interrupt method - <a href="tclsqlite.html#interrupt">tclsqlite.html#interrupt</a></li><li>invalid UTF - <a href="invalidutf.html">invalidutf.html</a></li><li>IS DISTINCT FROM - <a href="lang_expr.html#isdf">lang_expr.html#isdf</a></li><li>IS NOT DISTINCT FROM - <a href="lang_expr.html#isdf">lang_expr.html#isdf</a></li><li>IS NOT operator - <a href="lang_expr.html#isisnot">lang_expr.html#isisnot</a></li><li>IS operator - <a href="lang_expr.html#isisnot">lang_expr.html#isisnot</a></li><li>isolation - <a href="isolation.html">isolation.html</a></li><li>jfuzz - <a href="testing.html#dbsqlfuzz">testing.html#dbsqlfuzz</a></li><li>join order - <a href="optoverview.html#table_order">optoverview.html#table_order</a></li><li>join-clause - <a href="syntax/join-clause.html">syntax/join-clause.html</a></li><li>join-clause syntax diagram - <a href="syntax/join-clause.html">syntax/join-clause.html</a></li><li>join-constraint - <a href="syntax/join-constraint.html">syntax/join-constraint.html</a></li><li>join-constraint syntax diagram - <a href="syntax/join-constraint.html">syntax/join-constraint.html</a></li><li>join-operator - <a href="syntax/join-operator.html">syntax/join-operator.html</a></li><li>join-operator syntax diagram - <a href="syntax/join-operator.html">syntax/join-operator.html</a></li><li>journal_mode - <a href="pragma.html#pragma_journal_mode">pragma.html#pragma_journal_mode</a></li><li>journal_mode pragma - <a href="pragma.html#pragma_journal_mode">pragma.html#pragma_journal_mode</a></li><li>journal_size_limit - <a href="pragma.html#pragma_journal_size_limit">pragma.html#pragma_journal_size_limit</a></li><li>journal_size_limit pragma - <a href="pragma.html#pragma_journal_size_limit">pragma.html#pragma_journal_size_limit</a></li><li>json - <a href="json1.html#jmini">json1.html#jmini</a></li><li>JSON BLOB input bug - <a href="json1.html#jblobbug">json1.html#jblobbug</a></li><li>JSON function path arguments - <a href="json1.html#jsonpath">json1.html#jsonpath</a></li><li>JSON paths - <a href="json1.html#jsonpath">json1.html#jsonpath</a></li><li>json SQL function - <a href="json1.html#jmini">json1.html#jmini</a></li><li>JSON SQL functions - <a href="json1.html">json1.html</a></li><li>json1 - <a href="json1.html">json1.html</a></li><li>JSON5 - <a href="json1.html#json5">json1.html#json5</a></li><li>JSON5 extensions - <a href="json1.html#json5">json1.html#json5</a></li><li>json_array - <a href="json1.html#jarray">json1.html#jarray</a></li><li>json_array SQL function - <a href="json1.html#jarray">json1.html#jarray</a></li><li>json_array_length - <a href="json1.html#jarraylen">json1.html#jarraylen</a></li><li>json_array_length SQL function - <a href="json1.html#jarraylen">json1.html#jarraylen</a></li><li>json_each - <a href="json1.html#jeach">json1.html#jeach</a></li><li>json_each table-valued function - <a href="json1.html#jeach">json1.html#jeach</a></li><li>json_error_position - <a href="json1.html#jerr">json1.html#jerr</a></li><li>json_error_position SQL function - <a href="json1.html#jerr">json1.html#jerr</a></li><li>json_extract - <a href="json1.html#jex">json1.html#jex</a></li><li>json_extract SQL function - <a href="json1.html#jex">json1.html#jex</a></li><li>json_group_array - <a href="json1.html#jgrouparray">json1.html#jgrouparray</a></li><li>json_group_array SQL function - <a href="json1.html#jgrouparray">json1.html#jgrouparray</a></li><li>json_group_object - <a href="json1.html#jgroupobject">json1.html#jgroupobject</a></li><li>json_group_object SQL function - <a href="json1.html#jgroupobject">json1.html#jgroupobject</a></li><li>json_insert - <a href="json1.html#jins">json1.html#jins</a></li><li>json_insert SQL function - <a href="json1.html#jins">json1.html#jins</a></li><li>json_object - <a href="json1.html#jobj">json1.html#jobj</a></li><li>json_object SQL function - <a href="json1.html#jobj">json1.html#jobj</a></li><li>json_patch - <a href="json1.html#jpatch">json1.html#jpatch</a></li><li>json_patch SQL function - <a href="json1.html#jpatch">json1.html#jpatch</a></li><li>json_quote - <a href="json1.html#jquote">json1.html#jquote</a></li><li>json_quote SQL function - <a href="json1.html#jquote">json1.html#jquote</a></li><li>json_remove - <a href="json1.html#jrm">json1.html#jrm</a></li><li>json_remove SQL function - <a href="json1.html#jrm">json1.html#jrm</a></li><li>json_replace - <a href="json1.html#jrepl">json1.html#jrepl</a></li><li>json_replace SQL function - <a href="json1.html#jrepl">json1.html#jrepl</a></li><li>json_set - <a href="json1.html#jset">json1.html#jset</a></li><li>json_set SQL function - <a href="json1.html#jset">json1.html#jset</a></li><li>json_tree - <a href="json1.html#jtree">json1.html#jtree</a></li><li>json_tree table-valued function - <a href="json1.html#jtree">json1.html#jtree</a></li><li>json_type - <a href="json1.html#jtype">json1.html#jtype</a></li><li>json_type SQL function - <a href="json1.html#jtype">json1.html#jtype</a></li><li>json_valid - <a href="json1.html#jvalid">json1.html#jvalid</a></li><li>json_valid SQL function - <a href="json1.html#jvalid">json1.html#jvalid</a></li><li>JSONB - <a href="json1.html#jsonbx">json1.html#jsonbx</a></li><li>jsonb - <a href="json1.html#jminib">json1.html#jminib</a></li><li>jsonb SQL function - <a href="json1.html#jminib">json1.html#jminib</a></li><li>jsonb_array - <a href="json1.html#jarrayb">json1.html#jarrayb</a></li><li>jsonb_array SQL function - <a href="json1.html#jarrayb">json1.html#jarrayb</a></li><li>jsonb_extract - <a href="json1.html#jexb">json1.html#jexb</a></li><li>jsonb_extract SQL function - <a href="json1.html#jexb">json1.html#jexb</a></li><li>jsonb_group_array - <a href="json1.html#jgrouparrayb">json1.html#jgrouparrayb</a></li><li>jsonb_group_array SQL function - <a href="json1.html#jgrouparrayb">json1.html#jgrouparrayb</a></li><li>jsonb_group_object - <a href="json1.html#jgroupobjectb">json1.html#jgroupobjectb</a></li><li>jsonb_group_object SQL function - <a href="json1.html#jgroupobjectb">json1.html#jgroupobjectb</a></li><li>jsonb_insert - <a href="json1.html#jinsb">json1.html#jinsb</a></li><li>jsonb_insert SQL function - <a href="json1.html#jinsb">json1.html#jinsb</a></li><li>jsonb_object - <a href="json1.html#jobjb">json1.html#jobjb</a></li><li>jsonb_object SQL function - <a href="json1.html#jobjb">json1.html#jobjb</a></li><li>jsonb_patch - <a href="json1.html#jpatchb">json1.html#jpatchb</a></li><li>jsonb_patch SQL function - <a href="json1.html#jpatchb">json1.html#jpatchb</a></li><li>jsonb_remove - <a href="json1.html#jrmb">json1.html#jrmb</a></li><li>jsonb_remove SQL function - <a href="json1.html#jrmb">json1.html#jrmb</a></li><li>jsonb_replace - <a href="json1.html#jreplb">json1.html#jreplb</a></li><li>jsonb_replace SQL function - <a href="json1.html#jreplb">json1.html#jreplb</a></li><li>jsonb_set - <a href="json1.html#jsetb">json1.html#jsetb</a></li><li>jsonb_set SQL function - <a href="json1.html#jsetb">json1.html#jsetb</a></li><li>julianday - <a href="lang_datefunc.html#jlndy">lang_datefunc.html#jlndy</a></li><li>julianday modifier - <a href="lang_datefunc.html#jdmod">lang_datefunc.html#jdmod</a></li><li>julianday SQL function - <a href="lang_datefunc.html#jlndy">lang_datefunc.html#jlndy</a></li><li>Kennedy - <a href="crew.html">crew.html</a></li><li>keyword index - <a href="keyword_index.html">keyword_index.html</a></li><li>keywords - <a href="lang_keywords.html">lang_keywords.html</a></li><li>langexpr - <a href="lang_expr.html">lang_expr.html</a></li><li>langindexedby - <a href="lang_indexedby.html">lang_indexedby.html</a></li><li>langkeywords - <a href="lang_keywords.html">lang_keywords.html</a></li><li>langreplace - <a href="lang_replace.html">lang_replace.html</a></li><li>languageid - <a href="fts3.html#*fts4languageid">fts3.html#*fts4languageid</a></li><li>langupdate - <a href="lang_update.html">lang_update.html</a></li><li>langvacuum - <a href="lang_vacuum.html">lang_vacuum.html</a></li><li>large WAL files - <a href="wal.html#bigwal">wal.html#bigwal</a></li><li>last_insert_rowid - <a href="lang_corefunc.html#last_insert_rowid">lang_corefunc.html#last_insert_rowid</a></li><li>last_insert_rowid method - <a href="tclsqlite.html#last_insert_rowid">tclsqlite.html#last_insert_rowid</a></li><li>last_insert_rowid SQL function - <a href="lang_corefunc.html#last_insert_rowid">lang_corefunc.html#last_insert_rowid</a></li><li>LEFT JOIN strength reduction optimization - <a href="optoverview.html#leftjoinreduction">optoverview.html#leftjoinreduction</a></li><li>legacy_alter_table - <a href="pragma.html#pragma_legacy_alter_table">pragma.html#pragma_legacy_alter_table</a></li><li>legacy_alter_table pragma - <a href="pragma.html#pragma_legacy_alter_table">pragma.html#pragma_legacy_alter_table</a></li><li>legacy_file_format - <a href="pragma.html#pragma_legacy_file_format">pragma.html#pragma_legacy_file_format</a></li><li>legacy_file_format pragma - <a href="pragma.html#pragma_legacy_file_format">pragma.html#pragma_legacy_file_format</a></li><li>Lemon - <a href="lemon.html">lemon.html</a></li><li>Lemon LALR parser generator - <a href="lemon.html">lemon.html</a></li><li>Lemon parser generator - <a href="lemon.html">lemon.html</a></li><li>length - <a href="lang_corefunc.html#length">lang_corefunc.html#length</a></li><li>length SQL function - <a href="lang_corefunc.html#length">lang_corefunc.html#length</a></li><li>library size - <a href="footprint.html">footprint.html</a></li><li>license - <a href="copyright.html">copyright.html</a></li><li>LIKE - <a href="lang_expr.html#like">lang_expr.html#like</a></li><li>like - <a href="lang_corefunc.html#like">lang_corefunc.html#like</a></li><li>LIKE optimization - <a href="optoverview.html#like_opt">optoverview.html#like_opt</a></li><li>like SQL function - <a href="lang_corefunc.html#like">lang_corefunc.html#like</a></li><li>likelihood - <a href="lang_corefunc.html#likelihood">lang_corefunc.html#likelihood</a></li><li>likelihood SQL function - <a href="lang_corefunc.html#likelihood">lang_corefunc.html#likelihood</a></li><li>likely - <a href="lang_corefunc.html#likely">lang_corefunc.html#likely</a></li><li>likely SQL function - <a href="lang_corefunc.html#likely">lang_corefunc.html#likely</a></li><li>LIMIT - <a href="lang_select.html#limitoffset">lang_select.html#limitoffset</a></li><li>limit categories - <a href="c3ref/c_limit_attached.html">c3ref/c_limit_attached.html</a></li><li>limit category - <a href="c3ref/c_limit_attached.html">c3ref/c_limit_attached.html</a></li><li>limits - <a href="limits.html">limits.html</a></li><li>list of current bytecodes - <a href="opcode.html#codes">opcode.html#codes</a></li><li>list of virtual tables - <a href="vtablist.html">vtablist.html</a></li><li>literal value - <a href="lang_expr.html#litvalue">lang_expr.html#litvalue</a></li><li>literal-value - <a href="syntax/literal-value.html">syntax/literal-value.html</a></li><li>literal-value syntax diagram - <a href="syntax/literal-value.html">syntax/literal-value.html</a></li><li>ln - <a href="lang_mathfunc.html#ln">lang_mathfunc.html#ln</a></li><li>ln SQL function - <a href="lang_mathfunc.html#ln">lang_mathfunc.html#ln</a></li><li>load_extension - <a href="lang_corefunc.html#load_extension">lang_corefunc.html#load_extension</a></li><li>load_extension SQL function - <a href="lang_corefunc.html#load_extension">lang_corefunc.html#load_extension</a></li><li>loadable extension - <a href="loadext.html">loadext.html</a></li><li>loadable extensions - <a href="loadext.html">loadext.html</a></li><li>loadext - <a href="loadext.html">loadext.html</a></li><li>localtime modifier - <a href="lang_datefunc.html#localtime">lang_datefunc.html#localtime</a></li><li>lock-byte page - <a href="fileformat2.html#lockbyte">fileformat2.html#lockbyte</a></li><li>locking_mode - <a href="pragma.html#pragma_locking_mode">pragma.html#pragma_locking_mode</a></li><li>locking_mode pragma - <a href="pragma.html#pragma_locking_mode">pragma.html#pragma_locking_mode</a></li><li>log - <a href="lang_mathfunc.html#log">lang_mathfunc.html#log</a></li><li>log2 - <a href="lang_mathfunc.html#log2">lang_mathfunc.html#log2</a></li><li>log2 SQL function - <a href="lang_mathfunc.html#log2">lang_mathfunc.html#log2</a></li><li>log10 - <a href="lang_mathfunc.html#log">lang_mathfunc.html#log</a></li><li>long term support - <a href="lts.html">lts.html</a></li><li>lookaside - <a href="malloc.html#lookaside">malloc.html#lookaside</a></li><li>lookaside buffer - <a href="malloc.html#lookaside">malloc.html#lookaside</a></li><li>lookaside memory - <a href="malloc.html#lookaside">malloc.html#lookaside</a></li><li>lookaside memory allocator - <a href="malloc.html#lookaside">malloc.html#lookaside</a></li><li>low-dependency - <a href="selfcontained.html">selfcontained.html</a></li><li>lower - <a href="lang_corefunc.html#lower">lang_corefunc.html#lower</a></li><li>lower SQL function - <a href="lang_corefunc.html#lower">lang_corefunc.html#lower</a></li><li>ltrim - <a href="lang_corefunc.html#ltrim">lang_corefunc.html#ltrim</a></li><li>ltrim SQL function - <a href="lang_corefunc.html#ltrim">lang_corefunc.html#ltrim</a></li><li>mailing lists - <a href="support.html#mailinglists">support.html#mailinglists</a></li><li>managing SQLite Archives from the command-line - <a href="sqlar.html#cltools">sqlar.html#cltools</a></li><li>Manual Control Of Query Plans Using CROSS JOIN - <a href="optoverview.html#crossjoin">optoverview.html#crossjoin</a></li><li>Manual Control Of Query Plans Using SQLITE_STAT Tables - <a href="optoverview.html#manctrl">optoverview.html#manctrl</a></li><li>master journal - <a href="tempfiles.html#superjrnl">tempfiles.html#superjrnl</a></li><li>MATCH - <a href="lang_expr.html#match">lang_expr.html#match</a></li><li>matchinfo - <a href="fts3.html#matchinfo">fts3.html#matchinfo</a></li><li>matchinfo b flag - <a href="fts3.html#matchinfo-b">fts3.html#matchinfo-b</a></li><li>matchinfo x flag - <a href="fts3.html#matchinfo-x">fts3.html#matchinfo-x</a></li><li>matchinfo y flag - <a href="fts3.html#matchinfo-y">fts3.html#matchinfo-y</a></li><li>materialization hints - <a href="lang_with.html#mathint">lang_with.html#mathint</a></li><li>MATERIALIZED - <a href="lang_with.html#mathint">lang_with.html#mathint</a></li><li>Math Functions - <a href="lang_mathfunc.html">lang_mathfunc.html</a></li><li>math functions - <a href="lang_mathfunc.html">lang_mathfunc.html</a></li><li>mathfunc - <a href="lang_mathfunc.html">lang_mathfunc.html</a></li><li>max - <a href="lang_corefunc.html#max_scalar">lang_corefunc.html#max_scalar</a></li><li>max aggregate function - <a href="lang_aggfunc.html#max_agg">lang_aggfunc.html#max_agg</a></li><li>max SQL function - <a href="lang_corefunc.html#max_scalar">lang_corefunc.html#max_scalar</a></li><li>max_agg - <a href="lang_aggfunc.html#max_agg">lang_aggfunc.html#max_agg</a></li><li>max_page_count - <a href="pragma.html#pragma_max_page_count">pragma.html#pragma_max_page_count</a></li><li>max_page_count pragma - <a href="pragma.html#pragma_max_page_count">pragma.html#pragma_max_page_count</a></li><li>max_scalar - <a href="lang_corefunc.html#max_scalar">lang_corefunc.html#max_scalar</a></li><li>maxopen parameter - <a href="swarmvtab.html#the_maxopen_parameter">swarmvtab.html#the_maxopen_parameter</a></li><li>MC/DC - <a href="testing.html#mcdc">testing.html#mcdc</a></li><li>MC/DC testing - <a href="testing.html#mcdc">testing.html#mcdc</a></li><li>memory - <a href="inmemorydb.html">inmemorydb.html</a></li><li>memory allocation - <a href="malloc.html">malloc.html</a></li><li>memory statistics - <a href="malloc.html#memstatus">malloc.html#memstatus</a></li><li>memory-mapped I/O - <a href="mmap.html">mmap.html</a></li><li>memsys2 - <a href="malloc.html#memdebug">malloc.html#memdebug</a></li><li>memsys5 - <a href="malloc.html#memsys5">malloc.html#memsys5</a></li><li>merge command - <a href="fts3.html#*fts4mergecmd">fts3.html#*fts4mergecmd</a></li><li>microoptimizations - <a href="cpu.html#microopt">cpu.html#microopt</a></li><li>min - <a href="lang_corefunc.html#min_scalar">lang_corefunc.html#min_scalar</a></li><li>min aggregate function - <a href="lang_aggfunc.html#min_agg">lang_aggfunc.html#min_agg</a></li><li>min SQL function - <a href="lang_corefunc.html#min_scalar">lang_corefunc.html#min_scalar</a></li><li>min/max optimization - <a href="optoverview.html#minmax">optoverview.html#minmax</a></li><li>min_agg - <a href="lang_aggfunc.html#min_agg">lang_aggfunc.html#min_agg</a></li><li>min_scalar - <a href="lang_corefunc.html#min_scalar">lang_corefunc.html#min_scalar</a></li><li>missing callback - <a href="swarmvtab.html#the_missing_callback">swarmvtab.html#the_missing_callback</a></li><li>mmap - <a href="mmap.html">mmap.html</a></li><li>mmap_size - <a href="pragma.html#pragma_mmap_size">pragma.html#pragma_mmap_size</a></li><li>mmap_size pragma - <a href="pragma.html#pragma_mmap_size">pragma.html#pragma_mmap_size</a></li><li>mod - <a href="lang_mathfunc.html#mod">lang_mathfunc.html#mod</a></li><li>mod SQL function - <a href="lang_mathfunc.html#mod">lang_mathfunc.html#mod</a></li><li>mode query parameter - <a href="uri.html#urimode">uri.html#urimode</a></li><li>modeof - <a href="uri.html#urimodeof">uri.html#urimodeof</a></li><li>modeof query parameter - <a href="uri.html#urimodeof">uri.html#urimodeof</a></li><li>modifiers - <a href="lang_datefunc.html#dtmods">lang_datefunc.html#dtmods</a></li><li>module_list - <a href="pragma.html#pragma_module_list">pragma.html#pragma_module_list</a></li><li>module_list pragma - <a href="pragma.html#pragma_module_list">pragma.html#pragma_module_list</a></li><li>most used - <a href="mostdeployed.html">mostdeployed.html</a></li><li>most widely deployed - <a href="mostdeployed.html">mostdeployed.html</a></li><li>most widely used - <a href="mostdeployed.html">mostdeployed.html</a></li><li>mutation test script - <a href="th3.html#muttest">th3.html#muttest</a></li><li>mutation testing - <a href="testing.html#mutationtests">testing.html#mutationtests</a></li><li>mxFrame - <a href="walformat.html#mxframe">walformat.html#mxframe</a></li><li>naming - <a href="lang_naming.html">lang_naming.html</a></li><li>nBackfill - <a href="walformat.html#nbackfill">walformat.html#nbackfill</a></li><li>NEAR queries - <a href="fts3.html#near">fts3.html#near</a></li><li>network filesystem use - <a href="useovernet.html">useovernet.html</a></li><li>Next Generation Query Planner - <a href="queryplanner-ng.html">queryplanner-ng.html</a></li><li>next generation query planner - <a href="queryplanner-ng.html">queryplanner-ng.html</a></li><li>NGQP - <a href="queryplanner-ng.html">queryplanner-ng.html</a></li><li>NOCASE - <a href="datatype3.html#collation">datatype3.html#collation</a></li><li>NOCASE collating function - <a href="datatype3.html#collation">datatype3.html#collation</a></li><li>nolock query parameter - <a href="uri.html#urinolock">uri.html#urinolock</a></li><li>non-deterministic functions - <a href="deterministic.html">deterministic.html</a></li><li>non-standard SELECT syntax - <a href="lang_select.html#nonstd">lang_select.html#nonstd</a></li><li>NOT EXISTS operator - <a href="lang_expr.html#exists_op">lang_expr.html#exists_op</a></li><li>NOT IN operator - <a href="lang_expr.html#in_op">lang_expr.html#in_op</a></li><li>NOT INDEXED - <a href="lang_indexedby.html">lang_indexedby.html</a></li><li>NOT MATERIALIZED - <a href="lang_with.html#mathint">lang_with.html#mathint</a></li><li>NOT NULL - <a href="lang_createtable.html#notnullconst">lang_createtable.html#notnullconst</a></li><li>NOT NULL constraint - <a href="lang_createtable.html#notnullconst">lang_createtable.html#notnullconst</a></li><li>NOT NULL constraints - <a href="lang_createtable.html#notnullconst">lang_createtable.html#notnullconst</a></li><li>not open-contributin - <a href="copyright.html#notopencontrib">copyright.html#notopencontrib</a></li><li>NUL characters in strings - <a href="nulinstr.html">nulinstr.html</a></li><li>nullif - <a href="lang_corefunc.html#nullif">lang_corefunc.html#nullif</a></li><li>nullif SQL function - <a href="lang_corefunc.html#nullif">lang_corefunc.html#nullif</a></li><li>NULLS FIRST - <a href="lang_select.html#nullslast">lang_select.html#nullslast</a></li><li>NULLS LAST - <a href="lang_select.html#nullslast">lang_select.html#nullslast</a></li><li>nullvalue method - <a href="tclsqlite.html#nullvalue">tclsqlite.html#nullvalue</a></li><li>numeric-literal - <a href="syntax/numeric-literal.html">syntax/numeric-literal.html</a></li><li>numeric-literal syntax diagram - <a href="syntax/numeric-literal.html">syntax/numeric-literal.html</a></li><li>object resolution - <a href="lang_naming.html">lang_naming.html</a></li><li>octet_length - <a href="lang_corefunc.html#octet_length">lang_corefunc.html#octet_length</a></li><li>octet_length SQL function - <a href="lang_corefunc.html#octet_length">lang_corefunc.html#octet_length</a></li><li>OFFSET - <a href="lang_select.html#limitoffset">lang_select.html#limitoffset</a></li><li>offsets - <a href="fts3.html#offsets">fts3.html#offsets</a></li><li>omit-left-join optimization - <a href="optoverview.html#omitnoopjoin">optoverview.html#omitnoopjoin</a></li><li>omit-outer-join optimization - <a href="optoverview.html#omitnoopjoin">optoverview.html#omitnoopjoin</a></li><li>omitfeatures - <a href="compile.html#omitfeatures">compile.html#omitfeatures</a></li><li>ON CONFLICT - <a href="lang_conflict.html">lang_conflict.html</a></li><li>ON CONFLICT clause - <a href="lang_conflict.html">lang_conflict.html</a></li><li>ON CONFLICT clauses - <a href="lang_conflict.html">lang_conflict.html</a></li><li>on-disk format - <a href="fileformat2.html">fileformat2.html</a></li><li>onecolumn method - <a href="tclsqlite.html#onecolumn">tclsqlite.html#onecolumn</a></li><li>opcode definitions - <a href="opcode.html#codes">opcode.html#codes</a></li><li>opcodes - <a href="opcode.html">opcode.html</a></li><li>OPEN_EXRESCODE - <a href="c3ref/open.html#openexrescode">c3ref/open.html#openexrescode</a></li><li>OPEN_NOFOLLOW - <a href="c3ref/open.html#opennofollow">c3ref/open.html#opennofollow</a></li><li>openclose callback - <a href="swarmvtab.html#the_openclose_callback">swarmvtab.html#the_openclose_callback</a></li><li>OpenOffice case study - <a href="affcase1.html">affcase1.html</a></li><li>optimize - <a href="pragma.html#pragma_optimize">pragma.html#pragma_optimize</a></li><li>optimize command - <a href="fts3.html#*fts4optcmd">fts3.html#*fts4optcmd</a></li><li>optimize pragma - <a href="pragma.html#pragma_optimize">pragma.html#pragma_optimize</a></li><li>optimizer - <a href="optoverview.html">optoverview.html</a></li><li>OR optimization - <a href="optoverview.html#or_opt">optoverview.html#or_opt</a></li><li>or optimization - <a href="optoverview.html#or_opt">optoverview.html#or_opt</a></li><li>or-connected-terms - <a href="queryplanner.html#or_in_where">queryplanner.html#or_in_where</a></li><li>ORDER BY - <a href="lang_select.html#orderby">lang_select.html#orderby</a></li><li>order by - <a href="lang_select.html#orderby">lang_select.html#orderby</a></li><li>ORDER BY clause in aggregate functions - <a href="lang_aggfunc.html#aggorderby">lang_aggfunc.html#aggorderby</a></li><li>orderByConsumed - <a href="vtab.html#obc">vtab.html#obc</a></li><li>ordering-term - <a href="syntax/ordering-term.html">syntax/ordering-term.html</a></li><li>ordering-term syntax diagram - <a href="syntax/ordering-term.html">syntax/ordering-term.html</a></li><li>ordinary common table expressions - <a href="lang_with.html#ordinarycte">lang_with.html#ordinarycte</a></li><li>OS backend - <a href="vfs.html">vfs.html</a></li><li>OSS Fuzz - <a href="testing.html#ossfuzz">testing.html#ossfuzz</a></li><li>OUTER JOIN strength reduction - <a href="optoverview.html#leftjoinreduction">optoverview.html#leftjoinreduction</a></li><li>OUTER JOIN strength reduction optimization - <a href="optoverview.html#leftjoinreduction">optoverview.html#leftjoinreduction</a></li><li>output mode - <a href="cli.html#dotmode">cli.html#dotmode</a></li><li>over-clause - <a href="syntax/over-clause.html">syntax/over-clause.html</a></li><li>over-clause syntax diagram - <a href="syntax/over-clause.html">syntax/over-clause.html</a></li><li>overflow page - <a href="fileformat2.html#ovflpgs">fileformat2.html#ovflpgs</a></li><li>overflow pages - <a href="fileformat2.html#ovflpgs">fileformat2.html#ovflpgs</a></li><li>page cache - <a href="c3ref/pcache_methods2.html">c3ref/pcache_methods2.html</a></li><li>page_count - <a href="pragma.html#pragma_page_count">pragma.html#pragma_page_count</a></li><li>page_count pragma - <a href="pragma.html#pragma_page_count">pragma.html#pragma_page_count</a></li><li>page_size - <a href="pragma.html#pragma_page_size">pragma.html#pragma_page_size</a></li><li>page_size pragma - <a href="pragma.html#pragma_page_size">pragma.html#pragma_page_size</a></li><li>pagecache memory allocator - <a href="malloc.html#pagecache">malloc.html#pagecache</a></li><li>parameter - <a href="lang_expr.html#varparam">lang_expr.html#varparam</a></li><li>parameter binding - <a href="c3ref/bind_blob.html">c3ref/bind_blob.html</a></li><li>parameters - <a href="lang_expr.html#varparam">lang_expr.html#varparam</a></li><li>parent key - <a href="foreignkeys.html#parentchild">foreignkeys.html#parentchild</a></li><li>parent table - <a href="foreignkeys.html#parentchild">foreignkeys.html#parentchild</a></li><li>parser_trace - <a href="pragma.html#pragma_parser_trace">pragma.html#pragma_parser_trace</a></li><li>parser_trace pragma - <a href="pragma.html#pragma_parser_trace">pragma.html#pragma_parser_trace</a></li><li>partial index - <a href="partialindex.html">partialindex.html</a></li><li>partial indexes - <a href="partialindex.html">partialindex.html</a></li><li>partial indices - <a href="partialindex.html">partialindex.html</a></li><li>partial sorting by index - <a href="queryplanner.html#partialsort">queryplanner.html#partialsort</a></li><li>partition - <a href="windowfunctions.html#ptxn">windowfunctions.html#ptxn</a></li><li>patchset - <a href="sessionintro.html#changeset">sessionintro.html#changeset</a></li><li>patchsets - <a href="sessionintro.html#changeset">sessionintro.html#changeset</a></li><li>PENDING - <a href="lockingv3.html#pending_lock">lockingv3.html#pending_lock</a></li><li>PENDING lock - <a href="lockingv3.html#pending_lock">lockingv3.html#pending_lock</a></li><li>pending lock - <a href="lockingv3.html#pending_lock">lockingv3.html#pending_lock</a></li><li>permuted index - <a href="sitemap.html">sitemap.html</a></li><li>persistent journal mode - <a href="pragma.html#pragma_journal_mode">pragma.html#pragma_journal_mode</a></li><li>persistent loadable extensions - <a href="loadext.html#persist">loadext.html#persist</a></li><li>phrase queries - <a href="fts3.html#phrase">fts3.html#phrase</a></li><li>pi - <a href="lang_mathfunc.html#pi">lang_mathfunc.html#pi</a></li><li>pi SQL function - <a href="lang_mathfunc.html#pi">lang_mathfunc.html#pi</a></li><li>pointer leak - <a href="bindptr.html#ptrleak">bindptr.html#ptrleak</a></li><li>pointer leaks - <a href="bindptr.html#ptrleak">bindptr.html#ptrleak</a></li><li>pointer passing interface - <a href="bindptr.html">bindptr.html</a></li><li>pointer passing interfaces - <a href="bindptr.html">bindptr.html</a></li><li>pointer types - <a href="bindptr.html#ptrtyp">bindptr.html#ptrtyp</a></li><li>pointer value - <a href="bindptr.html">bindptr.html</a></li><li>porting SQLite - <a href="custombuild.html">custombuild.html</a></li><li>pow - <a href="lang_mathfunc.html#pow">lang_mathfunc.html#pow</a></li><li>pow SQL function - <a href="lang_mathfunc.html#pow">lang_mathfunc.html#pow</a></li><li>power-safe - <a href="transactional.html">transactional.html</a></li><li>power-safe transactions - <a href="transactional.html">transactional.html</a></li><li>powersafe overwrite - <a href="psow.html">psow.html</a></li><li>PRAGMA - <a href="pragma.html#syntax">pragma.html#syntax</a></li><li>PRAGMA analysis_limit - <a href="pragma.html#pragma_analysis_limit">pragma.html#pragma_analysis_limit</a></li><li>PRAGMA application_id - <a href="pragma.html#pragma_application_id">pragma.html#pragma_application_id</a></li><li>PRAGMA auto_vacuum - <a href="pragma.html#pragma_auto_vacuum">pragma.html#pragma_auto_vacuum</a></li><li>PRAGMA automatic_index - <a href="pragma.html#pragma_automatic_index">pragma.html#pragma_automatic_index</a></li><li>PRAGMA busy_timeout - <a href="pragma.html#pragma_busy_timeout">pragma.html#pragma_busy_timeout</a></li><li>PRAGMA cache_size - <a href="pragma.html#pragma_cache_size">pragma.html#pragma_cache_size</a></li><li>PRAGMA cache_spill - <a href="pragma.html#pragma_cache_spill">pragma.html#pragma_cache_spill</a></li><li>PRAGMA case_sensitive_like - <a href="pragma.html#pragma_case_sensitive_like">pragma.html#pragma_case_sensitive_like</a></li><li>PRAGMA cell_size_check - <a href="pragma.html#pragma_cell_size_check">pragma.html#pragma_cell_size_check</a></li><li>PRAGMA checkpoint_fullfsync - <a href="pragma.html#pragma_checkpoint_fullfsync">pragma.html#pragma_checkpoint_fullfsync</a></li><li>PRAGMA collation_list - <a href="pragma.html#pragma_collation_list">pragma.html#pragma_collation_list</a></li><li>PRAGMA compile_options - <a href="pragma.html#pragma_compile_options">pragma.html#pragma_compile_options</a></li><li>PRAGMA count_changes - <a href="pragma.html#pragma_count_changes">pragma.html#pragma_count_changes</a></li><li>PRAGMA data_store_directory - <a href="pragma.html#pragma_data_store_directory">pragma.html#pragma_data_store_directory</a></li><li>PRAGMA data_version - <a href="pragma.html#pragma_data_version">pragma.html#pragma_data_version</a></li><li>PRAGMA database_list - <a href="pragma.html#pragma_database_list">pragma.html#pragma_database_list</a></li><li>PRAGMA default_cache_size - <a href="pragma.html#pragma_default_cache_size">pragma.html#pragma_default_cache_size</a></li><li>PRAGMA defer_foreign_keys - <a href="pragma.html#pragma_defer_foreign_keys">pragma.html#pragma_defer_foreign_keys</a></li><li>PRAGMA empty_result_callbacks - <a href="pragma.html#pragma_empty_result_callbacks">pragma.html#pragma_empty_result_callbacks</a></li><li>PRAGMA encoding - <a href="pragma.html#pragma_encoding">pragma.html#pragma_encoding</a></li><li>PRAGMA foreign_key_check - <a href="pragma.html#pragma_foreign_key_check">pragma.html#pragma_foreign_key_check</a></li><li>PRAGMA foreign_key_list - <a href="pragma.html#pragma_foreign_key_list">pragma.html#pragma_foreign_key_list</a></li><li>PRAGMA foreign_keys - <a href="pragma.html#pragma_foreign_keys">pragma.html#pragma_foreign_keys</a></li><li>PRAGMA freelist_count - <a href="pragma.html#pragma_freelist_count">pragma.html#pragma_freelist_count</a></li><li>PRAGMA full_column_names - <a href="pragma.html#pragma_full_column_names">pragma.html#pragma_full_column_names</a></li><li>PRAGMA fullfsync - <a href="pragma.html#pragma_fullfsync">pragma.html#pragma_fullfsync</a></li><li>PRAGMA function - <a href="pragma.html#pragfunc">pragma.html#pragfunc</a></li><li>PRAGMA function_list - <a href="pragma.html#pragma_function_list">pragma.html#pragma_function_list</a></li><li>PRAGMA functions - <a href="pragma.html#pragfunc">pragma.html#pragfunc</a></li><li>PRAGMA hard_heap_limit - <a href="pragma.html#pragma_hard_heap_limit">pragma.html#pragma_hard_heap_limit</a></li><li>PRAGMA ignore_check_constraints - <a href="pragma.html#pragma_ignore_check_constraints">pragma.html#pragma_ignore_check_constraints</a></li><li>PRAGMA incremental_vacuum - <a href="pragma.html#pragma_incremental_vacuum">pragma.html#pragma_incremental_vacuum</a></li><li>PRAGMA index_info - <a href="pragma.html#pragma_index_info">pragma.html#pragma_index_info</a></li><li>PRAGMA index_list - <a href="pragma.html#pragma_index_list">pragma.html#pragma_index_list</a></li><li>PRAGMA index_xinfo - <a href="pragma.html#pragma_index_xinfo">pragma.html#pragma_index_xinfo</a></li><li>PRAGMA integrity_check - <a href="pragma.html#pragma_integrity_check">pragma.html#pragma_integrity_check</a></li><li>PRAGMA journal_mode - <a href="pragma.html#pragma_journal_mode">pragma.html#pragma_journal_mode</a></li><li>PRAGMA journal_size_limit - <a href="pragma.html#pragma_journal_size_limit">pragma.html#pragma_journal_size_limit</a></li><li>PRAGMA legacy_alter_table - <a href="pragma.html#pragma_legacy_alter_table">pragma.html#pragma_legacy_alter_table</a></li><li>PRAGMA legacy_file_format - <a href="pragma.html#pragma_legacy_file_format">pragma.html#pragma_legacy_file_format</a></li><li>pragma list - <a href="pragma.html#toc">pragma.html#toc</a></li><li>PRAGMA locking_mode - <a href="pragma.html#pragma_locking_mode">pragma.html#pragma_locking_mode</a></li><li>PRAGMA max_page_count - <a href="pragma.html#pragma_max_page_count">pragma.html#pragma_max_page_count</a></li><li>PRAGMA mmap_size - <a href="pragma.html#pragma_mmap_size">pragma.html#pragma_mmap_size</a></li><li>PRAGMA module_list - <a href="pragma.html#pragma_module_list">pragma.html#pragma_module_list</a></li><li>PRAGMA optimize - <a href="pragma.html#pragma_optimize">pragma.html#pragma_optimize</a></li><li>PRAGMA page_count - <a href="pragma.html#pragma_page_count">pragma.html#pragma_page_count</a></li><li>PRAGMA page_size - <a href="pragma.html#pragma_page_size">pragma.html#pragma_page_size</a></li><li>PRAGMA parser_trace - <a href="pragma.html#pragma_parser_trace">pragma.html#pragma_parser_trace</a></li><li>PRAGMA pragma_list - <a href="pragma.html#pragma_pragma_list">pragma.html#pragma_pragma_list</a></li><li>PRAGMA query_only - <a href="pragma.html#pragma_query_only">pragma.html#pragma_query_only</a></li><li>PRAGMA quick_check - <a href="pragma.html#pragma_quick_check">pragma.html#pragma_quick_check</a></li><li>PRAGMA read_uncommitted - <a href="pragma.html#pragma_read_uncommitted">pragma.html#pragma_read_uncommitted</a></li><li>PRAGMA recursive_triggers - <a href="pragma.html#pragma_recursive_triggers">pragma.html#pragma_recursive_triggers</a></li><li>PRAGMA reverse_unordered_selects - <a href="pragma.html#pragma_reverse_unordered_selects">pragma.html#pragma_reverse_unordered_selects</a></li><li>PRAGMA schema_version - <a href="pragma.html#pragma_schema_version">pragma.html#pragma_schema_version</a></li><li>PRAGMA secure_delete - <a href="pragma.html#pragma_secure_delete">pragma.html#pragma_secure_delete</a></li><li>PRAGMA short_column_names - <a href="pragma.html#pragma_short_column_names">pragma.html#pragma_short_column_names</a></li><li>PRAGMA shrink_memory - <a href="pragma.html#pragma_shrink_memory">pragma.html#pragma_shrink_memory</a></li><li>PRAGMA soft_heap_limit - <a href="pragma.html#pragma_soft_heap_limit">pragma.html#pragma_soft_heap_limit</a></li><li>PRAGMA stats - <a href="pragma.html#pragma_stats">pragma.html#pragma_stats</a></li><li>PRAGMA synchronous - <a href="pragma.html#pragma_synchronous">pragma.html#pragma_synchronous</a></li><li>PRAGMA table_info - <a href="pragma.html#pragma_table_info">pragma.html#pragma_table_info</a></li><li>PRAGMA table_list - <a href="pragma.html#pragma_table_list">pragma.html#pragma_table_list</a></li><li>PRAGMA table_xinfo - <a href="pragma.html#pragma_table_xinfo">pragma.html#pragma_table_xinfo</a></li><li>PRAGMA temp_store - <a href="pragma.html#pragma_temp_store">pragma.html#pragma_temp_store</a></li><li>PRAGMA temp_store_directory - <a href="pragma.html#pragma_temp_store_directory">pragma.html#pragma_temp_store_directory</a></li><li>PRAGMA threads - <a href="pragma.html#pragma_threads">pragma.html#pragma_threads</a></li><li>PRAGMA trusted_schema - <a href="pragma.html#pragma_trusted_schema">pragma.html#pragma_trusted_schema</a></li><li>PRAGMA user_version - <a href="pragma.html#pragma_user_version">pragma.html#pragma_user_version</a></li><li>PRAGMA vdbe_addoptrace - <a href="pragma.html#pragma_vdbe_addoptrace">pragma.html#pragma_vdbe_addoptrace</a></li><li>PRAGMA vdbe_debug - <a href="pragma.html#pragma_vdbe_debug">pragma.html#pragma_vdbe_debug</a></li><li>PRAGMA vdbe_listing - <a href="pragma.html#pragma_vdbe_listing">pragma.html#pragma_vdbe_listing</a></li><li>PRAGMA vdbe_trace - <a href="pragma.html#pragma_vdbe_trace">pragma.html#pragma_vdbe_trace</a></li><li>PRAGMA wal_autocheckpoint - <a href="pragma.html#pragma_wal_autocheckpoint">pragma.html#pragma_wal_autocheckpoint</a></li><li>PRAGMA wal_checkpoint - <a href="pragma.html#pragma_wal_checkpoint">pragma.html#pragma_wal_checkpoint</a></li><li>PRAGMA writable_schema - <a href="pragma.html#pragma_writable_schema">pragma.html#pragma_writable_schema</a></li><li>pragma-stmt - <a href="syntax/pragma-stmt.html">syntax/pragma-stmt.html</a></li><li>pragma-stmt syntax diagram - <a href="syntax/pragma-stmt.html">syntax/pragma-stmt.html</a></li><li>pragma-value - <a href="syntax/pragma-value.html">syntax/pragma-value.html</a></li><li>pragma-value syntax diagram - <a href="syntax/pragma-value.html">syntax/pragma-value.html</a></li><li>pragma_list - <a href="pragma.html#pragma_pragma_list">pragma.html#pragma_pragma_list</a></li><li>pragma_list pragma - <a href="pragma.html#pragma_pragma_list">pragma.html#pragma_pragma_list</a></li><li>precompiled amalgamation tarballs - <a href="amalgamation.html#amalgtarball">amalgamation.html#amalgtarball</a></li><li>prefix queries - <a href="fts3.html#termprefix">fts3.html#termprefix</a></li><li>prefix query - <a href="fts3.html#termprefix">fts3.html#termprefix</a></li><li>prepared statement - <a href="c3ref/stmt.html">c3ref/stmt.html</a></li><li>prepared statements - <a href="c3ref/stmt.html">c3ref/stmt.html</a></li><li>preupdate method - <a href="tclsqlite.html#preupdate">tclsqlite.html#preupdate</a></li><li>PRIMARY KEY - <a href="lang_createtable.html#primkeyconst">lang_createtable.html#primkeyconst</a></li><li>PRIMARY KEY constraint - <a href="lang_createtable.html#primkeyconst">lang_createtable.html#primkeyconst</a></li><li>primary versus extended result codes - <a href="rescode.html#pve">rescode.html#pve</a></li><li>printf - <a href="lang_corefunc.html#printf">lang_corefunc.html#printf</a></li><li>printf SQL function - <a href="lang_corefunc.html#printf">lang_corefunc.html#printf</a></li><li>prior releases - <a href="chronology.html">chronology.html</a></li><li>private branches - <a href="privatebranch.html">privatebranch.html</a></li><li>professional support - <a href="prosupport.html">prosupport.html</a></li><li>profile method - <a href="tclsqlite.html#profile">tclsqlite.html#profile</a></li><li>Programming Loadable Extensions - <a href="loadext.html#write">loadext.html#write</a></li><li>progress method - <a href="tclsqlite.html#progress">tclsqlite.html#progress</a></li><li>protected sqlite3_value - <a href="c3ref/value.html">c3ref/value.html</a></li><li>PSOW - <a href="psow.html">psow.html</a></li><li>psow query parameter - <a href="uri.html#uripsow">uri.html#uripsow</a></li><li>public-domain - <a href="copyright.html">copyright.html</a></li><li>push-down optimization - <a href="optoverview.html#pushdown">optoverview.html#pushdown</a></li><li>Q - <a href="printf.html#percentq">printf.html#percentq</a></li><li>q - <a href="printf.html#percentq">printf.html#percentq</a></li><li>qbox - <a href="cli.html#qbox">cli.html#qbox</a></li><li>qbox output mode - <a href="cli.html#qbox">cli.html#qbox</a></li><li>QPSG - <a href="queryplanner-ng.html#qpstab">queryplanner-ng.html#qpstab</a></li><li>qualified-table-name - <a href="syntax/qualified-table-name.html">syntax/qualified-table-name.html</a></li><li>qualified-table-name syntax diagram - <a href="syntax/qualified-table-name.html">syntax/qualified-table-name.html</a></li><li>queries against graphs - <a href="lang_with.html#rcex3">lang_with.html#rcex3</a></li><li>query flattener - <a href="optoverview.html#flattening">optoverview.html#flattening</a></li><li>query parameters with special meaning to SQLite - <a href="uri.html#coreqp">uri.html#coreqp</a></li><li>query planner - <a href="optoverview.html">optoverview.html</a></li><li>query planner checklist - <a href="queryplanner-ng.html#howtofix">queryplanner-ng.html#howtofix</a></li><li>query planner stability guarantee - <a href="queryplanner-ng.html#qpstab">queryplanner-ng.html#qpstab</a></li><li>query_only - <a href="pragma.html#pragma_query_only">pragma.html#pragma_query_only</a></li><li>query_only pragma - <a href="pragma.html#pragma_query_only">pragma.html#pragma_query_only</a></li><li>Quick Start Guide - <a href="quickstart.html">quickstart.html</a></li><li>quick_check - <a href="pragma.html#pragma_quick_check">pragma.html#pragma_quick_check</a></li><li>quick_check pragma - <a href="pragma.html#pragma_quick_check">pragma.html#pragma_quick_check</a></li><li>quickstart - <a href="quickstart.html">quickstart.html</a></li><li>Quirks - <a href="quirks.html">quirks.html</a></li><li>quote - <a href="lang_corefunc.html#quote">lang_corefunc.html#quote</a></li><li>quote SQL function - <a href="lang_corefunc.html#quote">lang_corefunc.html#quote</a></li><li>R-Tree extension - <a href="rtree.html">rtree.html</a></li><li>R-Trees - <a href="rtree.html">rtree.html</a></li><li>radians - <a href="lang_mathfunc.html#radians">lang_mathfunc.html#radians</a></li><li>radians SQL function - <a href="lang_mathfunc.html#radians">lang_mathfunc.html#radians</a></li><li>RAISE function - <a href="lang_createtrigger.html#raise">lang_createtrigger.html#raise</a></li><li>raise-function - <a href="syntax/raise-function.html">syntax/raise-function.html</a></li><li>raise-function syntax diagram - <a href="syntax/raise-function.html">syntax/raise-function.html</a></li><li>random - <a href="lang_corefunc.html#random">lang_corefunc.html#random</a></li><li>random SQL function - <a href="lang_corefunc.html#random">lang_corefunc.html#random</a></li><li>randomblob - <a href="lang_corefunc.html#randomblob">lang_corefunc.html#randomblob</a></li><li>randomblob SQL function - <a href="lang_corefunc.html#randomblob">lang_corefunc.html#randomblob</a></li><li>RANGE frames - <a href="windowfunctions.html#rangetype">windowfunctions.html#rangetype</a></li><li>RANGE n FOLLOWING - <a href="windowfunctions.html#exprrange">windowfunctions.html#exprrange</a></li><li>RANGE n PRECEDING - <a href="windowfunctions.html#exprrange">windowfunctions.html#exprrange</a></li><li>range query optimization - <a href="optoverview.html#rangequery">optoverview.html#rangequery</a></li><li>RBU - <a href="rbu.html">rbu.html</a></li><li>RBU Database Contents - <a href="rbu.html#database_contents">rbu.html#database_contents</a></li><li>RBU Database Tables - <a href="rbu.html#database_tables">rbu.html#database_tables</a></li><li>RBU extension - <a href="rbu.html">rbu.html</a></li><li>RBU FTS3/4 Tables - <a href="rbu.html#fts4_tables">rbu.html#fts4_tables</a></li><li>RBU Update - <a href="rbu.html#rbu_updates">rbu.html#rbu_updates</a></li><li>RBU Vacuum - <a href="rbu.html#rbu_vacuum">rbu.html#rbu_vacuum</a></li><li>read-only WAL databases - <a href="wal.html#readonly">wal.html#readonly</a></li><li>read_uncommitted - <a href="pragma.html#pragma_read_uncommitted">pragma.html#pragma_read_uncommitted</a></li><li>read_uncommitted pragma - <a href="pragma.html#pragma_read_uncommitted">pragma.html#pragma_read_uncommitted</a></li><li>reading and writing an rtree at the same time - <a href="rtree.html#readwrite">rtree.html#readwrite</a></li><li>rebuild command - <a href="fts3.html#*fts4rebuidcmd">fts3.html#*fts4rebuidcmd</a></li><li>recent CVEs - <a href="cves.html#cvetab">cves.html#cvetab</a></li><li>recommended ANALYZE usage pattern - <a href="lang_analyze.html#req">lang_analyze.html#req</a></li><li>recommended by the US Library of Congress - <a href="locrsf.html">locrsf.html</a></li><li>recommended compile-time option - <a href="compile.html#rcmd">compile.html#rcmd</a></li><li>recommended compile-time options - <a href="compile.html#rcmd">compile.html#rcmd</a></li><li>recommended storage format - <a href="locrsf.html">locrsf.html</a></li><li>record format - <a href="fileformat2.html#record_format">fileformat2.html#record_format</a></li><li>recovery - <a href="walformat.html#recovery">walformat.html#recovery</a></li><li>recovery extension - <a href="recovery.html">recovery.html</a></li><li>recursive common table expression - <a href="lang_with.html#recursivecte">lang_with.html#recursivecte</a></li><li>recursive common table expressions - <a href="lang_with.html#recursivecte">lang_with.html#recursivecte</a></li><li>recursive query - <a href="lang_with.html#recursivecte">lang_with.html#recursivecte</a></li><li>recursive-cte - <a href="syntax/recursive-cte.html">syntax/recursive-cte.html</a></li><li>recursive-cte syntax diagram - <a href="syntax/recursive-cte.html">syntax/recursive-cte.html</a></li><li>recursive_triggers - <a href="pragma.html#pragma_recursive_triggers">pragma.html#pragma_recursive_triggers</a></li><li>recursive_triggers pragma - <a href="pragma.html#pragma_recursive_triggers">pragma.html#pragma_recursive_triggers</a></li><li>REGEXP - <a href="lang_expr.html#regexp">lang_expr.html#regexp</a></li><li>REINDEX - <a href="lang_reindex.html">lang_reindex.html</a></li><li>reindex - <a href="lang_reindex.html">lang_reindex.html</a></li><li>reindex-stmt - <a href="syntax/reindex-stmt.html">syntax/reindex-stmt.html</a></li><li>reindex-stmt syntax diagram - <a href="syntax/reindex-stmt.html">syntax/reindex-stmt.html</a></li><li>RELEASE - <a href="lang_savepoint.html">lang_savepoint.html</a></li><li>release history - <a href="changes.html">changes.html</a></li><li>release testing checklists - <a href="testing.html#cklist">testing.html#cklist</a></li><li>release-stmt - <a href="syntax/release-stmt.html">syntax/release-stmt.html</a></li><li>release-stmt syntax diagram - <a href="syntax/release-stmt.html">syntax/release-stmt.html</a></li><li>relfootprint - <a href="footprint.html">footprint.html</a></li><li>rename column - <a href="lang_altertable.html#altertabmvcol">lang_altertable.html#altertabmvcol</a></li><li>rename table - <a href="lang_altertable.html#altertabrename">lang_altertable.html#altertabrename</a></li><li>REPLACE - <a href="lang_replace.html">lang_replace.html</a></li><li>replace - <a href="lang_corefunc.html#replace">lang_corefunc.html#replace</a></li><li>replace SQL function - <a href="lang_corefunc.html#replace">lang_corefunc.html#replace</a></li><li>reported vulnerabilities - <a href="cves.html">cves.html</a></li><li>requirements - <a href="requirements.html">requirements.html</a></li><li>reserve bytes - <a href="fileformat2.html#resbyte">fileformat2.html#resbyte</a></li><li>RESERVED - <a href="lockingv3.html#reserved_lock">lockingv3.html#reserved_lock</a></li><li>RESERVED lock - <a href="lockingv3.html#reserved_lock">lockingv3.html#reserved_lock</a></li><li>reserved lock - <a href="lockingv3.html#reserved_lock">lockingv3.html#reserved_lock</a></li><li>reset the WAL - <a href="fileformat2.html#walreset">fileformat2.html#walreset</a></li><li>restore method - <a href="tclsqlite.html#restore">tclsqlite.html#restore</a></li><li>result code - <a href="rescode.html">rescode.html</a></li><li>result code definitions - <a href="c3ref/c_abort.html">c3ref/c_abort.html</a></li><li>result codes - <a href="rescode.html">rescode.html</a></li><li>result-column - <a href="syntax/result-column.html">syntax/result-column.html</a></li><li>result-column syntax diagram - <a href="syntax/result-column.html">syntax/result-column.html</a></li><li>result-set expressions - <a href="lang_select.html#resultset">lang_select.html#resultset</a></li><li>RETURNING - <a href="lang_returning.html">lang_returning.html</a></li><li>returning - <a href="lang_returning.html">lang_returning.html</a></li><li>RETURNING clause - <a href="lang_returning.html">lang_returning.html</a></li><li>returning-clause - <a href="syntax/returning-clause.html">syntax/returning-clause.html</a></li><li>returning-clause syntax diagram - <a href="syntax/returning-clause.html">syntax/returning-clause.html</a></li><li>reverse_unordered_selects - <a href="pragma.html#pragma_reverse_unordered_selects">pragma.html#pragma_reverse_unordered_selects</a></li><li>reverse_unordered_selects pragma - <a href="pragma.html#pragma_reverse_unordered_selects">pragma.html#pragma_reverse_unordered_selects</a></li><li>RIGHT and FULL OUTER JOIN - <a href="lang_select.html#rjoin">lang_select.html#rjoin</a></li><li>RIGHT JOIN - <a href="lang_select.html#rjoin">lang_select.html#rjoin</a></li><li>Robson proof - <a href="malloc.html#nofrag">malloc.html#nofrag</a></li><li>ROLLBACK - <a href="lang_transaction.html">lang_transaction.html</a></li><li>rollback journal - <a href="lockingv3.html#rollback">lockingv3.html#rollback</a></li><li>rollback journal format - <a href="fileformat2.html#rollbackjournal">fileformat2.html#rollbackjournal</a></li><li>rollback-stmt - <a href="syntax/rollback-stmt.html">syntax/rollback-stmt.html</a></li><li>rollback-stmt syntax diagram - <a href="syntax/rollback-stmt.html">syntax/rollback-stmt.html</a></li><li>rollback_hook method - <a href="tclsqlite.html#rollback_hook">tclsqlite.html#rollback_hook</a></li><li>round - <a href="lang_corefunc.html#round">lang_corefunc.html#round</a></li><li>round SQL function - <a href="lang_corefunc.html#round">lang_corefunc.html#round</a></li><li>row value - <a href="rowvalue.html">rowvalue.html</a></li><li>row value IN operator - <a href="rowvalue.html#rvinop">rowvalue.html#rvinop</a></li><li>row values - <a href="rowvalue.html">rowvalue.html</a></li><li>ROWID - <a href="lang_createtable.html#rowid">lang_createtable.html#rowid</a></li><li>rowid - <a href="lang_createtable.html#rowid">lang_createtable.html#rowid</a></li><li>rowid table - <a href="rowidtable.html">rowidtable.html</a></li><li>rowid tables - <a href="rowidtable.html">rowidtable.html</a></li><li>rowvalue - <a href="rowvalue.html">rowvalue.html</a></li><li>RTREE - <a href="rtree.html">rtree.html</a></li><li>rtree - <a href="rtree.html">rtree.html</a></li><li>rtree shadow tables - <a href="rtree.html#xshadow">rtree.html#xshadow</a></li><li>rtreecheck - <a href="rtree.html#rtreecheck">rtree.html#rtreecheck</a></li><li>RTRIM - <a href="datatype3.html#collation">datatype3.html#collation</a></li><li>rtrim - <a href="lang_corefunc.html#rtrim">lang_corefunc.html#rtrim</a></li><li>RTRIM collating function - <a href="datatype3.html#collation">datatype3.html#collation</a></li><li>rtrim SQL function - <a href="lang_corefunc.html#rtrim">lang_corefunc.html#rtrim</a></li><li>rules for determining column affinity - <a href="datatype3.html#affname">datatype3.html#affname</a></li><li>rules for determining column affinity in VIEWs - <a href="datatype3.html#affview">datatype3.html#affview</a></li><li>Run-Time Loadable Extensions - <a href="loadext.html">loadext.html</a></li><li>safe command-line option - <a href="cli.html#safemode">cli.html#safemode</a></li><li>SAVEPOINT - <a href="lang_savepoint.html">lang_savepoint.html</a></li><li>savepoint - <a href="lang_savepoint.html">lang_savepoint.html</a></li><li>SAVEPOINT bug - <a href="howtocorrupt.html#svptbug">howtocorrupt.html#svptbug</a></li><li>savepoint-stmt - <a href="syntax/savepoint-stmt.html">syntax/savepoint-stmt.html</a></li><li>savepoint-stmt syntax diagram - <a href="syntax/savepoint-stmt.html">syntax/savepoint-stmt.html</a></li><li>Scalar Functions - <a href="lang_corefunc.html">lang_corefunc.html</a></li><li>scalar functions - <a href="lang_corefunc.html">lang_corefunc.html</a></li><li>scan status flags - <a href="c3ref/c_scanstat_complex.html">c3ref/c_scanstat_complex.html</a></li><li>scanstatus options - <a href="c3ref/c_scanstat_est.html">c3ref/c_scanstat_est.html</a></li><li>schema format - <a href="fileformat2.html#schemaformat">fileformat2.html#schemaformat</a></li><li>schema format number - <a href="fileformat2.html#schemaformat">fileformat2.html#schemaformat</a></li><li>schema storage - <a href="fileformat2.html#ffschema">fileformat2.html#ffschema</a></li><li>schema_version - <a href="pragma.html#pragma_schema_version">pragma.html#pragma_schema_version</a></li><li>schema_version pragma - <a href="pragma.html#pragma_schema_version">pragma.html#pragma_schema_version</a></li><li>search application tips - <a href="fts3.html#appendix_a">fts3.html#appendix_a</a></li><li>second edition file format document - <a href="fileformat2.html">fileformat2.html</a></li><li>secure_delete - <a href="pragma.html#pragma_secure_delete">pragma.html#pragma_secure_delete</a></li><li>secure_delete pragma - <a href="pragma.html#pragma_secure_delete">pragma.html#pragma_secure_delete</a></li><li>security - <a href="security.html">security.html</a></li><li>segment btree - <a href="fts3.html#data_structures">fts3.html#data_structures</a></li><li>SELECT - <a href="lang_select.html">lang_select.html</a></li><li>select - <a href="lang_select.html">lang_select.html</a></li><li>SELECT query - <a href="lang_select.html">lang_select.html</a></li><li>SELECT statement - <a href="lang_select.html">lang_select.html</a></li><li>select-core - <a href="syntax/select-core.html">syntax/select-core.html</a></li><li>select-core syntax diagram - <a href="syntax/select-core.html">syntax/select-core.html</a></li><li>select-stmt - <a href="syntax/select-stmt.html">syntax/select-stmt.html</a></li><li>select-stmt syntax diagram - <a href="syntax/select-stmt.html">syntax/select-stmt.html</a></li><li>self-contained - <a href="selfcontained.html">selfcontained.html</a></li><li>separating a database from its journal - <a href="howtocorrupt.html#roguejrnl">howtocorrupt.html#roguejrnl</a></li><li>serial type - <a href="fileformat2.html#serialtype">fileformat2.html#serialtype</a></li><li>serial types - <a href="fileformat2.html#serialtype">fileformat2.html#serialtype</a></li><li>serialize method - <a href="tclsqlite.html#serialize">tclsqlite.html#serialize</a></li><li>series - <a href="series.html">series.html</a></li><li>server-side database - <a href="whentouse.html#serversidedb">whentouse.html#serversidedb</a></li><li>serverless - <a href="serverless.html">serverless.html</a></li><li>session - <a href="sessionintro.html">sessionintro.html</a></li><li>session extension - <a href="sessionintro.html">sessionintro.html</a></li><li>Session Extension C-language Interface - <a href="session/intro.html">session/intro.html</a></li><li>Session Module C-API function list - <a href="session/funclist.html">session/funclist.html</a></li><li>session-capi - <a href="session/intro.html">session/intro.html</a></li><li>session_funclist - <a href="session/funclist.html">session/funclist.html</a></li><li>shadow table - <a href="vtab.html#xshadowname">vtab.html#xshadowname</a></li><li>shadow tables - <a href="vtab.html#xshadowname">vtab.html#xshadowname</a></li><li>shadowtabs - <a href="fts3.html#shadow_tables">fts3.html#shadow_tables</a></li><li>SHARED - <a href="lockingv3.html#shared_lock">lockingv3.html#shared_lock</a></li><li>shared cache - <a href="sharedcache.html">sharedcache.html</a></li><li>shared cache mode - <a href="sharedcache.html">sharedcache.html</a></li><li>SHARED lock - <a href="lockingv3.html#shared_lock">lockingv3.html#shared_lock</a></li><li>shared lock - <a href="lockingv3.html#shared_lock">lockingv3.html#shared_lock</a></li><li>shims - <a href="vfs.html#shim">vfs.html#shim</a></li><li>shm file - <a href="walformat.html#shm">walformat.html#shm</a></li><li>short filenames - <a href="shortnames.html">shortnames.html</a></li><li>short_column_names - <a href="pragma.html#pragma_short_column_names">pragma.html#pragma_short_column_names</a></li><li>short_column_names pragma - <a href="pragma.html#pragma_short_column_names">pragma.html#pragma_short_column_names</a></li><li>shrink_memory - <a href="pragma.html#pragma_shrink_memory">pragma.html#pragma_shrink_memory</a></li><li>shrink_memory pragma - <a href="pragma.html#pragma_shrink_memory">pragma.html#pragma_shrink_memory</a></li><li>sign - <a href="lang_corefunc.html#sign">lang_corefunc.html#sign</a></li><li>sign SQL function - <a href="lang_corefunc.html#sign">lang_corefunc.html#sign</a></li><li>signed-number - <a href="syntax/signed-number.html">syntax/signed-number.html</a></li><li>signed-number syntax diagram - <a href="syntax/signed-number.html">syntax/signed-number.html</a></li><li>simple fts queries - <a href="fts3.html#simple_fts_queries">fts3.html#simple_fts_queries</a></li><li>simple SELECT - <a href="lang_select.html#simpleselect">lang_select.html#simpleselect</a></li><li>simple-function-invocation - <a href="syntax/simple-function-invocation.html">syntax/simple-function-invocation.html</a></li><li>simple-function-invocation syntax diagram - <a href="syntax/simple-function-invocation.html">syntax/simple-function-invocation.html</a></li><li>simple-select-stmt - <a href="syntax/simple-select-stmt.html">syntax/simple-select-stmt.html</a></li><li>simple-select-stmt syntax diagram - <a href="syntax/simple-select-stmt.html">syntax/simple-select-stmt.html</a></li><li>sin - <a href="lang_mathfunc.html#sin">lang_mathfunc.html#sin</a></li><li>sin SQL function - <a href="lang_mathfunc.html#sin">lang_mathfunc.html#sin</a></li><li>single-argument carray - <a href="carray.html#onearg">carray.html#onearg</a></li><li>sinh - <a href="lang_mathfunc.html#sinh">lang_mathfunc.html#sinh</a></li><li>sinh SQL function - <a href="lang_mathfunc.html#sinh">lang_mathfunc.html#sinh</a></li><li>skip-scan - <a href="optoverview.html#skipscan">optoverview.html#skipscan</a></li><li>skip-scan optimization - <a href="optoverview.html#skipscan">optoverview.html#skipscan</a></li><li>SLT - <a href="testing.html#slt">testing.html#slt</a></li><li>snapshot - <a href="c3ref/snapshot.html">c3ref/snapshot.html</a></li><li>snippet - <a href="fts3.html#snippet">fts3.html#snippet</a></li><li>soft_heap_limit - <a href="pragma.html#pragma_soft_heap_limit">pragma.html#pragma_soft_heap_limit</a></li><li>soft_heap_limit pragma - <a href="pragma.html#pragma_soft_heap_limit">pragma.html#pragma_soft_heap_limit</a></li><li>solve Sudoku puzzles - <a href="lang_with.html#sudoku">lang_with.html#sudoku</a></li><li>sort order - <a href="datatype3.html#sortorder">datatype3.html#sortorder</a></li><li>sorting - <a href="queryplanner.html#sorting">queryplanner.html#sorting</a></li><li>sorting subsets of the result - <a href="optoverview.html#partsort">optoverview.html#partsort</a></li><li>soundex - <a href="lang_corefunc.html#soundex">lang_corefunc.html#soundex</a></li><li>soundex SQL function - <a href="lang_corefunc.html#soundex">lang_corefunc.html#soundex</a></li><li>spellfix1 - <a href="spellfix1.html">spellfix1.html</a></li><li>split amalgamation - <a href="amalgamation.html#amal32k">amalgamation.html#amal32k</a></li><li>SQL Archive - <a href="sqlar.html">sqlar.html</a></li><li>SQL fuzzing - <a href="testing.html#fuzztesting">testing.html#fuzztesting</a></li><li>SQL keyword - <a href="lang_keywords.html">lang_keywords.html</a></li><li>SQL keywords - <a href="lang_keywords.html">lang_keywords.html</a></li><li>SQL Logic Tests - <a href="testing.html#slt">testing.html#slt</a></li><li>SQL parameter - <a href="c3ref/bind_blob.html">c3ref/bind_blob.html</a></li><li>SQL parameters - <a href="c3ref/bind_blob.html">c3ref/bind_blob.html</a></li><li>sql parameters - <a href="swarmvtab.html#sql_parameters">swarmvtab.html#sql_parameters</a></li><li>SQL statement compiler - <a href="c3ref/prepare.html">c3ref/prepare.html</a></li><li>sql-stmt - <a href="syntax/sql-stmt.html">syntax/sql-stmt.html</a></li><li>sql-stmt syntax diagram - <a href="syntax/sql-stmt.html">syntax/sql-stmt.html</a></li><li>sql-stmt-list - <a href="syntax/sql-stmt-list.html">syntax/sql-stmt-list.html</a></li><li>sql-stmt-list syntax diagram - <a href="syntax/sql-stmt-list.html">syntax/sql-stmt-list.html</a></li><li>SQLAR - <a href="sqlar.html">sqlar.html</a></li><li>sqldiff - <a href="sqldiff.html">sqldiff.html</a></li><li>sqldiff --rbu - <a href="rbu.html#sqldiff">rbu.html#sqldiff</a></li><li>sqldiff.exe - <a href="sqldiff.html">sqldiff.html</a></li><li>SQLite amalgamation source file - <a href="amalgamation.html">amalgamation.html</a></li><li>SQLite Archive - <a href="sqlar.html">sqlar.html</a></li><li>SQLite Archive files - <a href="sqlar.html">sqlar.html</a></li><li>SQLite Archive format - <a href="sqlar.html">sqlar.html</a></li><li>SQLite Archive smaller than ZIP - <a href="affcase1.html#smaller">affcase1.html#smaller</a></li><li>SQLite Consortium - <a href="consortium.html">consortium.html</a></li><li>SQLite database file format - <a href="fileformat2.html">fileformat2.html</a></li><li>SQLite extension - <a href="loadext.html">loadext.html</a></li><li>SQLite extensions - <a href="loadext.html">loadext.html</a></li><li>SQLite Keywords - <a href="lang_keywords.html">lang_keywords.html</a></li><li>SQLite query planner - <a href="optoverview.html">optoverview.html</a></li><li>SQLite Shared-Cache Mode - <a href="sharedcache.html">sharedcache.html</a></li><li>SQLite source code repositories - <a href="download.html#srctree">download.html#srctree</a></li><li>sqlite3 - <a href="c3ref/sqlite3.html">c3ref/sqlite3.html</a></li><li>sqlite3.exe - <a href="cli.html">cli.html</a></li><li>sqlite3.exe command-line shell - <a href="cli.html">cli.html</a></li><li>sqlite3_aggregate_context - <a href="c3ref/aggregate_context.html">c3ref/aggregate_context.html</a></li><li>sqlite3_aggregate_count - <a href="c3ref/aggregate_count.html">c3ref/aggregate_count.html</a></li><li>sqlite3_analyzer - <a href="sqlanalyze.html">sqlanalyze.html</a></li><li>sqlite3_analyzer.exe - <a href="sqlanalyze.html">sqlanalyze.html</a></li><li>sqlite3_api_routines - <a href="c3ref/api_routines.html">c3ref/api_routines.html</a></li><li>sqlite3_auto_extension - <a href="c3ref/auto_extension.html">c3ref/auto_extension.html</a></li><li>sqlite3_autovacuum_pages - <a href="c3ref/autovacuum_pages.html">c3ref/autovacuum_pages.html</a></li><li>sqlite3_backup - <a href="c3ref/backup.html">c3ref/backup.html</a></li><li>sqlite3_backup_finish - <a href="c3ref/backup_finish.html#sqlite3backupfinish">c3ref/backup_finish.html#sqlite3backupfinish</a></li><li>sqlite3_backup_init - <a href="c3ref/backup_finish.html#sqlite3backupinit">c3ref/backup_finish.html#sqlite3backupinit</a></li><li>sqlite3_backup_pagecount - <a href="c3ref/backup_finish.html#sqlite3backuppagecount">c3ref/backup_finish.html#sqlite3backuppagecount</a></li><li>sqlite3_backup_remaining - <a href="c3ref/backup_finish.html#sqlite3backupremaining">c3ref/backup_finish.html#sqlite3backupremaining</a></li><li>sqlite3_backup_step - <a href="c3ref/backup_finish.html#sqlite3backupstep">c3ref/backup_finish.html#sqlite3backupstep</a></li><li>sqlite3_bind_blob - <a href="c3ref/bind_blob.html">c3ref/bind_blob.html</a></li><li>sqlite3_bind_blob64 - <a href="c3ref/bind_blob.html">c3ref/bind_blob.html</a></li><li>sqlite3_bind_double - <a href="c3ref/bind_blob.html">c3ref/bind_blob.html</a></li><li>sqlite3_bind_int - <a href="c3ref/bind_blob.html">c3ref/bind_blob.html</a></li><li>sqlite3_bind_int64 - <a href="c3ref/bind_blob.html">c3ref/bind_blob.html</a></li><li>sqlite3_bind_null - <a href="c3ref/bind_blob.html">c3ref/bind_blob.html</a></li><li>sqlite3_bind_parameter_count - <a href="c3ref/bind_parameter_count.html">c3ref/bind_parameter_count.html</a></li><li>sqlite3_bind_parameter_index - <a href="c3ref/bind_parameter_index.html">c3ref/bind_parameter_index.html</a></li><li>sqlite3_bind_parameter_name - <a href="c3ref/bind_parameter_name.html">c3ref/bind_parameter_name.html</a></li><li>sqlite3_bind_pointer - <a href="c3ref/bind_blob.html">c3ref/bind_blob.html</a></li><li>sqlite3_bind_text - <a href="c3ref/bind_blob.html">c3ref/bind_blob.html</a></li><li>sqlite3_bind_text16 - <a href="c3ref/bind_blob.html">c3ref/bind_blob.html</a></li><li>sqlite3_bind_text64 - <a href="c3ref/bind_blob.html">c3ref/bind_blob.html</a></li><li>sqlite3_bind_value - <a href="c3ref/bind_blob.html">c3ref/bind_blob.html</a></li><li>sqlite3_bind_zeroblob - <a href="c3ref/bind_blob.html">c3ref/bind_blob.html</a></li><li>sqlite3_bind_zeroblob64 - <a href="c3ref/bind_blob.html">c3ref/bind_blob.html</a></li><li>sqlite3_blob - <a href="c3ref/blob.html">c3ref/blob.html</a></li><li>sqlite3_blob_bytes - <a href="c3ref/blob_bytes.html">c3ref/blob_bytes.html</a></li><li>sqlite3_blob_close - <a href="c3ref/blob_close.html">c3ref/blob_close.html</a></li><li>sqlite3_blob_open - <a href="c3ref/blob_open.html">c3ref/blob_open.html</a></li><li>sqlite3_blob_read - <a href="c3ref/blob_read.html">c3ref/blob_read.html</a></li><li>sqlite3_blob_reopen - <a href="c3ref/blob_reopen.html">c3ref/blob_reopen.html</a></li><li>sqlite3_blob_write - <a href="c3ref/blob_write.html">c3ref/blob_write.html</a></li><li>sqlite3_busy_handler - <a href="c3ref/busy_handler.html">c3ref/busy_handler.html</a></li><li>sqlite3_busy_timeout - <a href="c3ref/busy_timeout.html">c3ref/busy_timeout.html</a></li><li>sqlite3_cancel_auto_extension - <a href="c3ref/cancel_auto_extension.html">c3ref/cancel_auto_extension.html</a></li><li>sqlite3_carray_bind - <a href="carray.html#onearg">carray.html#onearg</a></li><li>sqlite3_changegroup - <a href="session/changegroup.html">session/changegroup.html</a></li><li>sqlite3_changes - <a href="c3ref/changes.html">c3ref/changes.html</a></li><li>sqlite3_changes64 - <a href="c3ref/changes.html">c3ref/changes.html</a></li><li>sqlite3_changeset_iter - <a href="session/changeset_iter.html">session/changeset_iter.html</a></li><li>sqlite3_clear_bindings - <a href="c3ref/clear_bindings.html">c3ref/clear_bindings.html</a></li><li>sqlite3_close - <a href="c3ref/close.html">c3ref/close.html</a></li><li>sqlite3_close_v2 - <a href="c3ref/close.html">c3ref/close.html</a></li><li>sqlite3_collation_needed - <a href="c3ref/collation_needed.html">c3ref/collation_needed.html</a></li><li>sqlite3_collation_needed16 - <a href="c3ref/collation_needed.html">c3ref/collation_needed.html</a></li><li>sqlite3_column_blob - <a href="c3ref/column_blob.html">c3ref/column_blob.html</a></li><li>sqlite3_column_bytes - <a href="c3ref/column_blob.html">c3ref/column_blob.html</a></li><li>sqlite3_column_bytes16 - <a href="c3ref/column_blob.html">c3ref/column_blob.html</a></li><li>sqlite3_column_count - <a href="c3ref/column_count.html">c3ref/column_count.html</a></li><li>sqlite3_column_database_name - <a href="c3ref/column_database_name.html">c3ref/column_database_name.html</a></li><li>sqlite3_column_database_name16 - <a href="c3ref/column_database_name.html">c3ref/column_database_name.html</a></li><li>sqlite3_column_decltype - <a href="c3ref/column_decltype.html">c3ref/column_decltype.html</a></li><li>sqlite3_column_decltype16 - <a href="c3ref/column_decltype.html">c3ref/column_decltype.html</a></li><li>sqlite3_column_double - <a href="c3ref/column_blob.html">c3ref/column_blob.html</a></li><li>sqlite3_column_int - <a href="c3ref/column_blob.html">c3ref/column_blob.html</a></li><li>sqlite3_column_int64 - <a href="c3ref/column_blob.html">c3ref/column_blob.html</a></li><li>sqlite3_column_name - <a href="c3ref/column_name.html">c3ref/column_name.html</a></li><li>sqlite3_column_name16 - <a href="c3ref/column_name.html">c3ref/column_name.html</a></li><li>sqlite3_column_origin_name - <a href="c3ref/column_database_name.html">c3ref/column_database_name.html</a></li><li>sqlite3_column_origin_name16 - <a href="c3ref/column_database_name.html">c3ref/column_database_name.html</a></li><li>sqlite3_column_table_name - <a href="c3ref/column_database_name.html">c3ref/column_database_name.html</a></li><li>sqlite3_column_table_name16 - <a href="c3ref/column_database_name.html">c3ref/column_database_name.html</a></li><li>sqlite3_column_text - <a href="c3ref/column_blob.html">c3ref/column_blob.html</a></li><li>sqlite3_column_text16 - <a href="c3ref/column_blob.html">c3ref/column_blob.html</a></li><li>sqlite3_column_type - <a href="c3ref/column_blob.html">c3ref/column_blob.html</a></li><li>sqlite3_column_value - <a href="c3ref/column_blob.html">c3ref/column_blob.html</a></li><li>sqlite3_commit_hook - <a href="c3ref/commit_hook.html">c3ref/commit_hook.html</a></li><li>sqlite3_compileoption_get - <a href="c3ref/compileoption_get.html">c3ref/compileoption_get.html</a></li><li>sqlite3_compileoption_used - <a href="c3ref/compileoption_get.html">c3ref/compileoption_get.html</a></li><li>sqlite3_complete - <a href="c3ref/complete.html">c3ref/complete.html</a></li><li>sqlite3_complete16 - <a href="c3ref/complete.html">c3ref/complete.html</a></li><li>sqlite3_config - <a href="c3ref/config.html">c3ref/config.html</a></li><li>sqlite3_context - <a href="c3ref/context.html">c3ref/context.html</a></li><li>sqlite3_context_db_handle - <a href="c3ref/context_db_handle.html">c3ref/context_db_handle.html</a></li><li>sqlite3_create_collation - <a href="c3ref/create_collation.html">c3ref/create_collation.html</a></li><li>sqlite3_create_collation16 - <a href="c3ref/create_collation.html">c3ref/create_collation.html</a></li><li>sqlite3_create_collation_v2 - <a href="c3ref/create_collation.html">c3ref/create_collation.html</a></li><li>sqlite3_create_filename - <a href="c3ref/create_filename.html">c3ref/create_filename.html</a></li><li>sqlite3_create_function - <a href="c3ref/create_function.html">c3ref/create_function.html</a></li><li>sqlite3_create_function16 - <a href="c3ref/create_function.html">c3ref/create_function.html</a></li><li>sqlite3_create_function_v2 - <a href="c3ref/create_function.html">c3ref/create_function.html</a></li><li>sqlite3_create_module - <a href="c3ref/create_module.html">c3ref/create_module.html</a></li><li>sqlite3_create_module_v2 - <a href="c3ref/create_module.html">c3ref/create_module.html</a></li><li>sqlite3_create_window_function - <a href="c3ref/create_function.html">c3ref/create_function.html</a></li><li>sqlite3_data_count - <a href="c3ref/data_count.html">c3ref/data_count.html</a></li><li>sqlite3_data_directory - <a href="c3ref/data_directory.html">c3ref/data_directory.html</a></li><li>sqlite3_database_file_object - <a href="c3ref/database_file_object.html">c3ref/database_file_object.html</a></li><li>sqlite3_db_cacheflush - <a href="c3ref/db_cacheflush.html">c3ref/db_cacheflush.html</a></li><li>sqlite3_db_config - <a href="c3ref/db_config.html">c3ref/db_config.html</a></li><li>sqlite3_db_filename - <a href="c3ref/db_filename.html">c3ref/db_filename.html</a></li><li>sqlite3_db_handle - <a href="c3ref/db_handle.html">c3ref/db_handle.html</a></li><li>sqlite3_db_mutex - <a href="c3ref/db_mutex.html">c3ref/db_mutex.html</a></li><li>sqlite3_db_name - <a href="c3ref/db_name.html">c3ref/db_name.html</a></li><li>sqlite3_db_readonly - <a href="c3ref/db_readonly.html">c3ref/db_readonly.html</a></li><li>sqlite3_db_release_memory - <a href="c3ref/db_release_memory.html">c3ref/db_release_memory.html</a></li><li>sqlite3_db_status - <a href="c3ref/db_status.html">c3ref/db_status.html</a></li><li>sqlite3_declare_vtab - <a href="c3ref/declare_vtab.html">c3ref/declare_vtab.html</a></li><li>sqlite3_deserialize - <a href="c3ref/deserialize.html">c3ref/deserialize.html</a></li><li>sqlite3_drop_modules - <a href="c3ref/drop_modules.html">c3ref/drop_modules.html</a></li><li>sqlite3_enable_load_extension - <a href="c3ref/enable_load_extension.html">c3ref/enable_load_extension.html</a></li><li>sqlite3_enable_shared_cache - <a href="c3ref/enable_shared_cache.html">c3ref/enable_shared_cache.html</a></li><li>sqlite3_errcode - <a href="c3ref/errcode.html">c3ref/errcode.html</a></li><li>sqlite3_errmsg - <a href="c3ref/errcode.html">c3ref/errcode.html</a></li><li>sqlite3_errmsg16 - <a href="c3ref/errcode.html">c3ref/errcode.html</a></li><li>sqlite3_error_offset - <a href="c3ref/errcode.html">c3ref/errcode.html</a></li><li>sqlite3_errstr - <a href="c3ref/errcode.html">c3ref/errcode.html</a></li><li>sqlite3_exec - <a href="c3ref/exec.html">c3ref/exec.html</a></li><li>sqlite3_expanded_sql - <a href="c3ref/expanded_sql.html">c3ref/expanded_sql.html</a></li><li>sqlite3_expired - <a href="c3ref/aggregate_count.html">c3ref/aggregate_count.html</a></li><li>sqlite3_extended_errcode - <a href="c3ref/errcode.html">c3ref/errcode.html</a></li><li>sqlite3_extended_result_codes - <a href="c3ref/extended_result_codes.html">c3ref/extended_result_codes.html</a></li><li>sqlite3_file - <a href="c3ref/file.html">c3ref/file.html</a></li><li>sqlite3_file_control - <a href="c3ref/file_control.html">c3ref/file_control.html</a></li><li>sqlite3_filename - <a href="c3ref/filename.html">c3ref/filename.html</a></li><li>sqlite3_filename_database - <a href="c3ref/filename_database.html">c3ref/filename_database.html</a></li><li>sqlite3_filename_journal - <a href="c3ref/filename_database.html">c3ref/filename_database.html</a></li><li>sqlite3_filename_wal - <a href="c3ref/filename_database.html">c3ref/filename_database.html</a></li><li>sqlite3_finalize - <a href="c3ref/finalize.html">c3ref/finalize.html</a></li><li>sqlite3_free - <a href="c3ref/free.html">c3ref/free.html</a></li><li>sqlite3_free_filename - <a href="c3ref/create_filename.html">c3ref/create_filename.html</a></li><li>sqlite3_free_table - <a href="c3ref/free_table.html">c3ref/free_table.html</a></li><li>sqlite3_get_autocommit - <a href="c3ref/get_autocommit.html">c3ref/get_autocommit.html</a></li><li>sqlite3_get_auxdata - <a href="c3ref/get_auxdata.html">c3ref/get_auxdata.html</a></li><li>sqlite3_get_clientdata - <a href="c3ref/get_clientdata.html">c3ref/get_clientdata.html</a></li><li>sqlite3_get_table - <a href="c3ref/free_table.html">c3ref/free_table.html</a></li><li>sqlite3_global_recover - <a href="c3ref/aggregate_count.html">c3ref/aggregate_count.html</a></li><li>sqlite3_hard_heap_limit64 - <a href="c3ref/hard_heap_limit64.html">c3ref/hard_heap_limit64.html</a></li><li>sqlite3_index_info - <a href="c3ref/index_info.html">c3ref/index_info.html</a></li><li>sqlite3_initialize - <a href="c3ref/initialize.html">c3ref/initialize.html</a></li><li>sqlite3_int64 - <a href="c3ref/int64.html">c3ref/int64.html</a></li><li>sqlite3_interrupt - <a href="c3ref/interrupt.html">c3ref/interrupt.html</a></li><li>sqlite3_io_methods - <a href="c3ref/io_methods.html">c3ref/io_methods.html</a></li><li>sqlite3_is_interrupted - <a href="c3ref/interrupt.html">c3ref/interrupt.html</a></li><li>sqlite3_keyword_check - <a href="c3ref/keyword_check.html">c3ref/keyword_check.html</a></li><li>sqlite3_keyword_count - <a href="c3ref/keyword_check.html">c3ref/keyword_check.html</a></li><li>sqlite3_keyword_name - <a href="c3ref/keyword_check.html">c3ref/keyword_check.html</a></li><li>sqlite3_last_insert_rowid - <a href="c3ref/last_insert_rowid.html">c3ref/last_insert_rowid.html</a></li><li>sqlite3_libversion - <a href="c3ref/libversion.html">c3ref/libversion.html</a></li><li>sqlite3_libversion_number - <a href="c3ref/libversion.html">c3ref/libversion.html</a></li><li>sqlite3_limit - <a href="c3ref/limit.html">c3ref/limit.html</a></li><li>sqlite3_load_extension - <a href="c3ref/load_extension.html">c3ref/load_extension.html</a></li><li>sqlite3_log - <a href="c3ref/log.html">c3ref/log.html</a></li><li>sqlite3_malloc - <a href="c3ref/free.html">c3ref/free.html</a></li><li>sqlite3_malloc64 - <a href="c3ref/free.html">c3ref/free.html</a></li><li>sqlite3_mem_methods - <a href="c3ref/mem_methods.html">c3ref/mem_methods.html</a></li><li>sqlite3_memory_alarm - <a href="c3ref/aggregate_count.html">c3ref/aggregate_count.html</a></li><li>sqlite3_memory_highwater - <a href="c3ref/memory_highwater.html">c3ref/memory_highwater.html</a></li><li>sqlite3_memory_used - <a href="c3ref/memory_highwater.html">c3ref/memory_highwater.html</a></li><li>sqlite3_module - <a href="c3ref/module.html">c3ref/module.html</a></li><li>sqlite3_module.xBegin - <a href="vtab.html#xBegin">vtab.html#xBegin</a></li><li>sqlite3_module.xBestIndex - <a href="vtab.html#xbestindex">vtab.html#xbestindex</a></li><li>sqlite3_module.xClose - <a href="vtab.html#xclose">vtab.html#xclose</a></li><li>sqlite3_module.xColumn - <a href="vtab.html#xcolumn">vtab.html#xcolumn</a></li><li>sqlite3_module.xCommit - <a href="vtab.html#xcommit">vtab.html#xcommit</a></li><li>sqlite3_module.xConnect - <a href="vtab.html#xconnect">vtab.html#xconnect</a></li><li>sqlite3_module.xCreate - <a href="vtab.html#xcreate">vtab.html#xcreate</a></li><li>sqlite3_module.xDisconnect - <a href="vtab.html#xdisconnect">vtab.html#xdisconnect</a></li><li>sqlite3_module.xEof - <a href="vtab.html#xeof">vtab.html#xeof</a></li><li>sqlite3_module.xFilter - <a href="vtab.html#xfilter">vtab.html#xfilter</a></li><li>sqlite3_module.xFindFunction - <a href="vtab.html#xfindfunction">vtab.html#xfindfunction</a></li><li>sqlite3_module.xIntegrity - <a href="vtab.html#xintegrity">vtab.html#xintegrity</a></li><li>sqlite3_module.xNext - <a href="vtab.html#xnext">vtab.html#xnext</a></li><li>sqlite3_module.xOpen - <a href="vtab.html#xopen">vtab.html#xopen</a></li><li>sqlite3_module.xRename - <a href="vtab.html#xrename">vtab.html#xrename</a></li><li>sqlite3_module.xRollback - <a href="vtab.html#xrollback">vtab.html#xrollback</a></li><li>sqlite3_module.xRowid - <a href="vtab.html#xrowid">vtab.html#xrowid</a></li><li>sqlite3_module.xSavepoint - <a href="vtab.html#xsavepoint">vtab.html#xsavepoint</a></li><li>sqlite3_module.xShadowName - <a href="vtab.html#xshadowname">vtab.html#xshadowname</a></li><li>sqlite3_module.xSync - <a href="vtab.html#xsync">vtab.html#xsync</a></li><li>sqlite3_module.xUpdate - <a href="vtab.html#xupdate">vtab.html#xupdate</a></li><li>sqlite3_mprintf - <a href="c3ref/mprintf.html">c3ref/mprintf.html</a></li><li>sqlite3_msize - <a href="c3ref/free.html">c3ref/free.html</a></li><li>sqlite3_mutex - <a href="c3ref/mutex.html">c3ref/mutex.html</a></li><li>sqlite3_mutex_alloc - <a href="c3ref/mutex_alloc.html">c3ref/mutex_alloc.html</a></li><li>sqlite3_mutex_enter - <a href="c3ref/mutex_alloc.html">c3ref/mutex_alloc.html</a></li><li>sqlite3_mutex_free - <a href="c3ref/mutex_alloc.html">c3ref/mutex_alloc.html</a></li><li>sqlite3_mutex_held - <a href="c3ref/mutex_held.html">c3ref/mutex_held.html</a></li><li>sqlite3_mutex_leave - <a href="c3ref/mutex_alloc.html">c3ref/mutex_alloc.html</a></li><li>sqlite3_mutex_methods - <a href="c3ref/mutex_methods.html">c3ref/mutex_methods.html</a></li><li>sqlite3_mutex_notheld - <a href="c3ref/mutex_held.html">c3ref/mutex_held.html</a></li><li>sqlite3_mutex_try - <a href="c3ref/mutex_alloc.html">c3ref/mutex_alloc.html</a></li><li>sqlite3_next_stmt - <a href="c3ref/next_stmt.html">c3ref/next_stmt.html</a></li><li>sqlite3_normalized_sql - <a href="c3ref/expanded_sql.html">c3ref/expanded_sql.html</a></li><li>sqlite3_open - <a href="c3ref/open.html">c3ref/open.html</a></li><li>sqlite3_open16 - <a href="c3ref/open.html">c3ref/open.html</a></li><li>sqlite3_open_v2 - <a href="c3ref/open.html">c3ref/open.html</a></li><li>sqlite3_os_end - <a href="c3ref/initialize.html">c3ref/initialize.html</a></li><li>sqlite3_os_init - <a href="c3ref/initialize.html">c3ref/initialize.html</a></li><li>sqlite3_overload_function - <a href="c3ref/overload_function.html">c3ref/overload_function.html</a></li><li>sqlite3_pcache - <a href="c3ref/pcache.html">c3ref/pcache.html</a></li><li>sqlite3_pcache_methods2 - <a href="c3ref/pcache_methods2.html">c3ref/pcache_methods2.html</a></li><li>sqlite3_pcache_page - <a href="c3ref/pcache_page.html">c3ref/pcache_page.html</a></li><li>sqlite3_prepare - <a href="c3ref/prepare.html">c3ref/prepare.html</a></li><li>sqlite3_prepare16 - <a href="c3ref/prepare.html">c3ref/prepare.html</a></li><li>sqlite3_prepare16_v2 - <a href="c3ref/prepare.html">c3ref/prepare.html</a></li><li>sqlite3_prepare16_v3 - <a href="c3ref/prepare.html">c3ref/prepare.html</a></li><li>sqlite3_prepare_v2 - <a href="c3ref/prepare.html">c3ref/prepare.html</a></li><li>sqlite3_prepare_v3 - <a href="c3ref/prepare.html">c3ref/prepare.html</a></li><li>sqlite3_preupdate_blobwrite - <a href="c3ref/preupdate_blobwrite.html">c3ref/preupdate_blobwrite.html</a></li><li>sqlite3_preupdate_count - <a href="c3ref/preupdate_blobwrite.html">c3ref/preupdate_blobwrite.html</a></li><li>sqlite3_preupdate_depth - <a href="c3ref/preupdate_blobwrite.html">c3ref/preupdate_blobwrite.html</a></li><li>sqlite3_preupdate_hook - <a href="c3ref/preupdate_blobwrite.html">c3ref/preupdate_blobwrite.html</a></li><li>sqlite3_preupdate_new - <a href="c3ref/preupdate_blobwrite.html">c3ref/preupdate_blobwrite.html</a></li><li>sqlite3_preupdate_old - <a href="c3ref/preupdate_blobwrite.html">c3ref/preupdate_blobwrite.html</a></li><li>sqlite3_profile - <a href="c3ref/profile.html">c3ref/profile.html</a></li><li>sqlite3_progress_handler - <a href="c3ref/progress_handler.html">c3ref/progress_handler.html</a></li><li>sqlite3_randomness - <a href="c3ref/randomness.html">c3ref/randomness.html</a></li><li>sqlite3_realloc - <a href="c3ref/free.html">c3ref/free.html</a></li><li>sqlite3_realloc64 - <a href="c3ref/free.html">c3ref/free.html</a></li><li>sqlite3_rebaser - <a href="session/rebaser.html">session/rebaser.html</a></li><li>sqlite3_release_memory - <a href="c3ref/release_memory.html">c3ref/release_memory.html</a></li><li>sqlite3_reset - <a href="c3ref/reset.html">c3ref/reset.html</a></li><li>sqlite3_reset_auto_extension - <a href="c3ref/reset_auto_extension.html">c3ref/reset_auto_extension.html</a></li><li>sqlite3_result_blob - <a href="c3ref/result_blob.html">c3ref/result_blob.html</a></li><li>sqlite3_result_blob64 - <a href="c3ref/result_blob.html">c3ref/result_blob.html</a></li><li>sqlite3_result_double - <a href="c3ref/result_blob.html">c3ref/result_blob.html</a></li><li>sqlite3_result_error - <a href="c3ref/result_blob.html">c3ref/result_blob.html</a></li><li>sqlite3_result_error16 - <a href="c3ref/result_blob.html">c3ref/result_blob.html</a></li><li>sqlite3_result_error_code - <a href="c3ref/result_blob.html">c3ref/result_blob.html</a></li><li>sqlite3_result_error_nomem - <a href="c3ref/result_blob.html">c3ref/result_blob.html</a></li><li>sqlite3_result_error_toobig - <a href="c3ref/result_blob.html">c3ref/result_blob.html</a></li><li>sqlite3_result_int - <a href="c3ref/result_blob.html">c3ref/result_blob.html</a></li><li>sqlite3_result_int64 - <a href="c3ref/result_blob.html">c3ref/result_blob.html</a></li><li>sqlite3_result_null - <a href="c3ref/result_blob.html">c3ref/result_blob.html</a></li><li>sqlite3_result_pointer - <a href="c3ref/result_blob.html">c3ref/result_blob.html</a></li><li>sqlite3_result_subtype - <a href="c3ref/result_subtype.html">c3ref/result_subtype.html</a></li><li>sqlite3_result_text - <a href="c3ref/result_blob.html">c3ref/result_blob.html</a></li><li>sqlite3_result_text16 - <a href="c3ref/result_blob.html">c3ref/result_blob.html</a></li><li>sqlite3_result_text16be - <a href="c3ref/result_blob.html">c3ref/result_blob.html</a></li><li>sqlite3_result_text16le - <a href="c3ref/result_blob.html">c3ref/result_blob.html</a></li><li>sqlite3_result_text64 - <a href="c3ref/result_blob.html">c3ref/result_blob.html</a></li><li>sqlite3_result_value - <a href="c3ref/result_blob.html">c3ref/result_blob.html</a></li><li>sqlite3_result_zeroblob - <a href="c3ref/result_blob.html">c3ref/result_blob.html</a></li><li>sqlite3_result_zeroblob64 - <a href="c3ref/result_blob.html">c3ref/result_blob.html</a></li><li>sqlite3_rollback_hook - <a href="c3ref/commit_hook.html">c3ref/commit_hook.html</a></li><li>sqlite3_rtree_query_callback - <a href="rtree.html#xquery">rtree.html#xquery</a></li><li>sqlite3_serialize - <a href="c3ref/serialize.html">c3ref/serialize.html</a></li><li>sqlite3_session - <a href="session/session.html">session/session.html</a></li><li>sqlite3_set_authorizer - <a href="c3ref/set_authorizer.html">c3ref/set_authorizer.html</a></li><li>sqlite3_set_auxdata - <a href="c3ref/get_auxdata.html">c3ref/get_auxdata.html</a></li><li>sqlite3_set_clientdata - <a href="c3ref/get_clientdata.html">c3ref/get_clientdata.html</a></li><li>sqlite3_set_last_insert_rowid - <a href="c3ref/set_last_insert_rowid.html">c3ref/set_last_insert_rowid.html</a></li><li>sqlite3_shutdown - <a href="c3ref/initialize.html">c3ref/initialize.html</a></li><li>sqlite3_sleep - <a href="c3ref/sleep.html">c3ref/sleep.html</a></li><li>sqlite3_snapshot - <a href="c3ref/snapshot.html">c3ref/snapshot.html</a></li><li>sqlite3_snapshot_cmp - <a href="c3ref/snapshot_cmp.html">c3ref/snapshot_cmp.html</a></li><li>sqlite3_snapshot_free - <a href="c3ref/snapshot_free.html">c3ref/snapshot_free.html</a></li><li>sqlite3_snapshot_get - <a href="c3ref/snapshot_get.html">c3ref/snapshot_get.html</a></li><li>sqlite3_snapshot_open - <a href="c3ref/snapshot_open.html">c3ref/snapshot_open.html</a></li><li>sqlite3_snapshot_recover - <a href="c3ref/snapshot_recover.html">c3ref/snapshot_recover.html</a></li><li>sqlite3_snprintf - <a href="c3ref/mprintf.html">c3ref/mprintf.html</a></li><li>sqlite3_soft_heap_limit - <a href="c3ref/soft_heap_limit.html">c3ref/soft_heap_limit.html</a></li><li>sqlite3_soft_heap_limit64 - <a href="c3ref/hard_heap_limit64.html">c3ref/hard_heap_limit64.html</a></li><li>sqlite3_sourceid - <a href="c3ref/libversion.html">c3ref/libversion.html</a></li><li>sqlite3_sql - <a href="c3ref/expanded_sql.html">c3ref/expanded_sql.html</a></li><li>sqlite3_status - <a href="c3ref/status.html">c3ref/status.html</a></li><li>sqlite3_status64 - <a href="c3ref/status.html">c3ref/status.html</a></li><li>sqlite3_step - <a href="c3ref/step.html">c3ref/step.html</a></li><li>sqlite3_stmt - <a href="c3ref/stmt.html">c3ref/stmt.html</a></li><li>sqlite3_stmt_busy - <a href="c3ref/stmt_busy.html">c3ref/stmt_busy.html</a></li><li>sqlite3_stmt_explain - <a href="c3ref/stmt_explain.html">c3ref/stmt_explain.html</a></li><li>sqlite3_stmt_isexplain - <a href="c3ref/stmt_isexplain.html">c3ref/stmt_isexplain.html</a></li><li>sqlite3_stmt_readonly - <a href="c3ref/stmt_readonly.html">c3ref/stmt_readonly.html</a></li><li>sqlite3_stmt_scanstatus - <a href="c3ref/stmt_scanstatus.html">c3ref/stmt_scanstatus.html</a></li><li>sqlite3_stmt_scanstatus_reset - <a href="c3ref/stmt_scanstatus_reset.html">c3ref/stmt_scanstatus_reset.html</a></li><li>sqlite3_stmt_scanstatus_v2 - <a href="c3ref/stmt_scanstatus.html">c3ref/stmt_scanstatus.html</a></li><li>sqlite3_stmt_status - <a href="c3ref/stmt_status.html">c3ref/stmt_status.html</a></li><li>sqlite3_str - <a href="c3ref/str.html">c3ref/str.html</a></li><li>sqlite3_str_append - <a href="c3ref/str_append.html">c3ref/str_append.html</a></li><li>sqlite3_str_appendall - <a href="c3ref/str_append.html">c3ref/str_append.html</a></li><li>sqlite3_str_appendchar - <a href="c3ref/str_append.html">c3ref/str_append.html</a></li><li>sqlite3_str_appendf - <a href="c3ref/str_append.html">c3ref/str_append.html</a></li><li>sqlite3_str_errcode - <a href="c3ref/str_errcode.html">c3ref/str_errcode.html</a></li><li>sqlite3_str_finish - <a href="c3ref/str_finish.html">c3ref/str_finish.html</a></li><li>sqlite3_str_length - <a href="c3ref/str_errcode.html">c3ref/str_errcode.html</a></li><li>sqlite3_str_new - <a href="c3ref/str_new.html">c3ref/str_new.html</a></li><li>sqlite3_str_reset - <a href="c3ref/str_append.html">c3ref/str_append.html</a></li><li>sqlite3_str_value - <a href="c3ref/str_errcode.html">c3ref/str_errcode.html</a></li><li>sqlite3_str_vappendf - <a href="c3ref/str_append.html">c3ref/str_append.html</a></li><li>sqlite3_strglob - <a href="c3ref/strglob.html">c3ref/strglob.html</a></li><li>sqlite3_stricmp - <a href="c3ref/stricmp.html">c3ref/stricmp.html</a></li><li>sqlite3_strlike - <a href="c3ref/strlike.html">c3ref/strlike.html</a></li><li>sqlite3_strnicmp - <a href="c3ref/stricmp.html">c3ref/stricmp.html</a></li><li>sqlite3_system_errno - <a href="c3ref/system_errno.html">c3ref/system_errno.html</a></li><li>sqlite3_table_column_metadata - <a href="c3ref/table_column_metadata.html">c3ref/table_column_metadata.html</a></li><li>sqlite3_temp_directory - <a href="c3ref/temp_directory.html">c3ref/temp_directory.html</a></li><li>sqlite3_test_control - <a href="c3ref/test_control.html">c3ref/test_control.html</a></li><li>sqlite3_thread_cleanup - <a href="c3ref/aggregate_count.html">c3ref/aggregate_count.html</a></li><li>sqlite3_threadsafe - <a href="c3ref/threadsafe.html">c3ref/threadsafe.html</a></li><li>sqlite3_total_changes - <a href="c3ref/total_changes.html">c3ref/total_changes.html</a></li><li>sqlite3_total_changes64 - <a href="c3ref/total_changes.html">c3ref/total_changes.html</a></li><li>sqlite3_trace - <a href="c3ref/profile.html">c3ref/profile.html</a></li><li>sqlite3_trace_v2 - <a href="c3ref/trace_v2.html">c3ref/trace_v2.html</a></li><li>sqlite3_transfer_bindings - <a href="c3ref/aggregate_count.html">c3ref/aggregate_count.html</a></li><li>sqlite3_txn_state - <a href="c3ref/txn_state.html">c3ref/txn_state.html</a></li><li>sqlite3_uint64 - <a href="c3ref/int64.html">c3ref/int64.html</a></li><li>sqlite3_unlock_notify - <a href="c3ref/unlock_notify.html">c3ref/unlock_notify.html</a></li><li>sqlite3_update_hook - <a href="c3ref/update_hook.html">c3ref/update_hook.html</a></li><li>sqlite3_uri_boolean - <a href="c3ref/uri_boolean.html">c3ref/uri_boolean.html</a></li><li>sqlite3_uri_int64 - <a href="c3ref/uri_boolean.html">c3ref/uri_boolean.html</a></li><li>sqlite3_uri_key - <a href="c3ref/uri_boolean.html">c3ref/uri_boolean.html</a></li><li>sqlite3_uri_parameter - <a href="c3ref/uri_boolean.html">c3ref/uri_boolean.html</a></li><li>sqlite3_user_data - <a href="c3ref/user_data.html">c3ref/user_data.html</a></li><li>sqlite3_value - <a href="c3ref/value.html">c3ref/value.html</a></li><li>sqlite3_value_blob - <a href="c3ref/value_blob.html">c3ref/value_blob.html</a></li><li>sqlite3_value_bytes - <a href="c3ref/value_blob.html">c3ref/value_blob.html</a></li><li>sqlite3_value_bytes16 - <a href="c3ref/value_blob.html">c3ref/value_blob.html</a></li><li>sqlite3_value_double - <a href="c3ref/value_blob.html">c3ref/value_blob.html</a></li><li>sqlite3_value_dup - <a href="c3ref/value_dup.html">c3ref/value_dup.html</a></li><li>sqlite3_value_encoding - <a href="c3ref/value_encoding.html">c3ref/value_encoding.html</a></li><li>sqlite3_value_free - <a href="c3ref/value_dup.html">c3ref/value_dup.html</a></li><li>sqlite3_value_frombind - <a href="c3ref/value_blob.html">c3ref/value_blob.html</a></li><li>sqlite3_value_int - <a href="c3ref/value_blob.html">c3ref/value_blob.html</a></li><li>sqlite3_value_int64 - <a href="c3ref/value_blob.html">c3ref/value_blob.html</a></li><li>sqlite3_value_nochange - <a href="c3ref/value_blob.html">c3ref/value_blob.html</a></li><li>sqlite3_value_numeric_type - <a href="c3ref/value_blob.html">c3ref/value_blob.html</a></li><li>sqlite3_value_pointer - <a href="c3ref/value_blob.html">c3ref/value_blob.html</a></li><li>sqlite3_value_subtype - <a href="c3ref/value_subtype.html">c3ref/value_subtype.html</a></li><li>sqlite3_value_text - <a href="c3ref/value_blob.html">c3ref/value_blob.html</a></li><li>sqlite3_value_text16 - <a href="c3ref/value_blob.html">c3ref/value_blob.html</a></li><li>sqlite3_value_text16be - <a href="c3ref/value_blob.html">c3ref/value_blob.html</a></li><li>sqlite3_value_text16le - <a href="c3ref/value_blob.html">c3ref/value_blob.html</a></li><li>sqlite3_value_type - <a href="c3ref/value_blob.html">c3ref/value_blob.html</a></li><li>sqlite3_version - <a href="c3ref/libversion.html">c3ref/libversion.html</a></li><li>sqlite3_vfs - <a href="c3ref/vfs.html">c3ref/vfs.html</a></li><li>sqlite3_vfs.xAccess - <a href="c3ref/vfs.html#sqlite3vfsxaccess">c3ref/vfs.html#sqlite3vfsxaccess</a></li><li>sqlite3_vfs.xOpen - <a href="c3ref/vfs.html#sqlite3vfsxopen">c3ref/vfs.html#sqlite3vfsxopen</a></li><li>sqlite3_vfs_find - <a href="c3ref/vfs_find.html">c3ref/vfs_find.html</a></li><li>sqlite3_vfs_register - <a href="c3ref/vfs_find.html">c3ref/vfs_find.html</a></li><li>sqlite3_vfs_unregister - <a href="c3ref/vfs_find.html">c3ref/vfs_find.html</a></li><li>sqlite3_vmprintf - <a href="c3ref/mprintf.html">c3ref/mprintf.html</a></li><li>sqlite3_vsnprintf - <a href="c3ref/mprintf.html">c3ref/mprintf.html</a></li><li>sqlite3_vtab - <a href="c3ref/vtab.html">c3ref/vtab.html</a></li><li>sqlite3_vtab_collation - <a href="c3ref/vtab_collation.html">c3ref/vtab_collation.html</a></li><li>sqlite3_vtab_config - <a href="c3ref/vtab_config.html">c3ref/vtab_config.html</a></li><li>sqlite3_vtab_cursor - <a href="c3ref/vtab_cursor.html">c3ref/vtab_cursor.html</a></li><li>sqlite3_vtab_distinct - <a href="c3ref/vtab_distinct.html">c3ref/vtab_distinct.html</a></li><li>sqlite3_vtab_in - <a href="c3ref/vtab_in.html">c3ref/vtab_in.html</a></li><li>sqlite3_vtab_in_first - <a href="c3ref/vtab_in_first.html">c3ref/vtab_in_first.html</a></li><li>sqlite3_vtab_in_next - <a href="c3ref/vtab_in_first.html">c3ref/vtab_in_first.html</a></li><li>sqlite3_vtab_nochange - <a href="c3ref/vtab_nochange.html">c3ref/vtab_nochange.html</a></li><li>sqlite3_vtab_on_conflict - <a href="c3ref/vtab_on_conflict.html">c3ref/vtab_on_conflict.html</a></li><li>sqlite3_vtab_rhs_value - <a href="c3ref/vtab_rhs_value.html">c3ref/vtab_rhs_value.html</a></li><li>sqlite3_wal_autocheckpoint - <a href="c3ref/wal_autocheckpoint.html">c3ref/wal_autocheckpoint.html</a></li><li>sqlite3_wal_checkpoint - <a href="c3ref/wal_checkpoint.html">c3ref/wal_checkpoint.html</a></li><li>sqlite3_wal_checkpoint_v2 - <a href="c3ref/wal_checkpoint_v2.html">c3ref/wal_checkpoint_v2.html</a></li><li>sqlite3_wal_hook - <a href="c3ref/wal_hook.html">c3ref/wal_hook.html</a></li><li>sqlite3_win32_set_directory - <a href="c3ref/win32_set_directory.html">c3ref/win32_set_directory.html</a></li><li>sqlite3_win32_set_directory8 - <a href="c3ref/win32_set_directory.html">c3ref/win32_set_directory.html</a></li><li>sqlite3_win32_set_directory16 - <a href="c3ref/win32_set_directory.html">c3ref/win32_set_directory.html</a></li><li>sqlite3changegroup_add - <a href="session/sqlite3changegroup_add.html">session/sqlite3changegroup_add.html</a></li><li>sqlite3changegroup_add_strm - <a href="session/sqlite3changegroup_add_strm.html">session/sqlite3changegroup_add_strm.html</a></li><li>sqlite3changegroup_delete - <a href="session/sqlite3changegroup_delete.html">session/sqlite3changegroup_delete.html</a></li><li>sqlite3changegroup_new - <a href="session/sqlite3changegroup_new.html">session/sqlite3changegroup_new.html</a></li><li>sqlite3changegroup_output - <a href="session/sqlite3changegroup_output.html">session/sqlite3changegroup_output.html</a></li><li>sqlite3changegroup_output_strm - <a href="session/sqlite3changegroup_add_strm.html">session/sqlite3changegroup_add_strm.html</a></li><li>sqlite3changegroup_schema - <a href="session/sqlite3changegroup_schema.html">session/sqlite3changegroup_schema.html</a></li><li>sqlite3changeset_apply - <a href="session/sqlite3changeset_apply.html">session/sqlite3changeset_apply.html</a></li><li>sqlite3changeset_apply_strm - <a href="session/sqlite3changegroup_add_strm.html">session/sqlite3changegroup_add_strm.html</a></li><li>sqlite3changeset_apply_v2 - <a href="session/sqlite3changeset_apply.html">session/sqlite3changeset_apply.html</a></li><li>sqlite3changeset_apply_v2_strm - <a href="session/sqlite3changegroup_add_strm.html">session/sqlite3changegroup_add_strm.html</a></li><li>sqlite3changeset_concat - <a href="session/sqlite3changeset_concat.html">session/sqlite3changeset_concat.html</a></li><li>sqlite3changeset_concat_strm - <a href="session/sqlite3changegroup_add_strm.html">session/sqlite3changegroup_add_strm.html</a></li><li>sqlite3changeset_conflict - <a href="session/sqlite3changeset_conflict.html">session/sqlite3changeset_conflict.html</a></li><li>sqlite3changeset_finalize - <a href="session/sqlite3changeset_finalize.html">session/sqlite3changeset_finalize.html</a></li><li>sqlite3changeset_fk_conflicts - <a href="session/sqlite3changeset_fk_conflicts.html">session/sqlite3changeset_fk_conflicts.html</a></li><li>sqlite3changeset_invert - <a href="session/sqlite3changeset_invert.html">session/sqlite3changeset_invert.html</a></li><li>sqlite3changeset_invert_strm - <a href="session/sqlite3changegroup_add_strm.html">session/sqlite3changegroup_add_strm.html</a></li><li>sqlite3changeset_new - <a href="session/sqlite3changeset_new.html">session/sqlite3changeset_new.html</a></li><li>sqlite3changeset_next - <a href="session/sqlite3changeset_next.html">session/sqlite3changeset_next.html</a></li><li>sqlite3changeset_old - <a href="session/sqlite3changeset_old.html">session/sqlite3changeset_old.html</a></li><li>sqlite3changeset_op - <a href="session/sqlite3changeset_op.html">session/sqlite3changeset_op.html</a></li><li>sqlite3changeset_pk - <a href="session/sqlite3changeset_pk.html">session/sqlite3changeset_pk.html</a></li><li>sqlite3changeset_start - <a href="session/sqlite3changeset_start.html">session/sqlite3changeset_start.html</a></li><li>sqlite3changeset_start_strm - <a href="session/sqlite3changegroup_add_strm.html">session/sqlite3changegroup_add_strm.html</a></li><li>sqlite3changeset_start_v2 - <a href="session/sqlite3changeset_start.html">session/sqlite3changeset_start.html</a></li><li>sqlite3changeset_start_v2_strm - <a href="session/sqlite3changegroup_add_strm.html">session/sqlite3changegroup_add_strm.html</a></li><li>sqlite3changeset_upgrade - <a href="session/sqlite3changeset_upgrade.html">session/sqlite3changeset_upgrade.html</a></li><li>sqlite3rebaser_configure - <a href="session/sqlite3rebaser_configure.html">session/sqlite3rebaser_configure.html</a></li><li>sqlite3rebaser_create - <a href="session/sqlite3rebaser_create.html">session/sqlite3rebaser_create.html</a></li><li>sqlite3rebaser_delete - <a href="session/sqlite3rebaser_delete.html">session/sqlite3rebaser_delete.html</a></li><li>sqlite3rebaser_rebase - <a href="session/sqlite3rebaser_rebase.html">session/sqlite3rebaser_rebase.html</a></li><li>sqlite3rebaser_rebase_strm - <a href="session/sqlite3changegroup_add_strm.html">session/sqlite3changegroup_add_strm.html</a></li><li>sqlite3session_attach - <a href="session/sqlite3session_attach.html">session/sqlite3session_attach.html</a></li><li>sqlite3session_changeset - <a href="session/sqlite3session_changeset.html">session/sqlite3session_changeset.html</a></li><li>sqlite3session_changeset_size - <a href="session/sqlite3session_changeset_size.html">session/sqlite3session_changeset_size.html</a></li><li>sqlite3session_changeset_strm - <a href="session/sqlite3changegroup_add_strm.html">session/sqlite3changegroup_add_strm.html</a></li><li>sqlite3session_config - <a href="session/sqlite3session_config.html">session/sqlite3session_config.html</a></li><li>sqlite3session_create - <a href="session/sqlite3session_create.html">session/sqlite3session_create.html</a></li><li>sqlite3session_delete - <a href="session/sqlite3session_delete.html">session/sqlite3session_delete.html</a></li><li>sqlite3session_diff - <a href="session/sqlite3session_diff.html">session/sqlite3session_diff.html</a></li><li>sqlite3session_enable - <a href="session/sqlite3session_enable.html">session/sqlite3session_enable.html</a></li><li>sqlite3session_indirect - <a href="session/sqlite3session_indirect.html">session/sqlite3session_indirect.html</a></li><li>sqlite3session_isempty - <a href="session/sqlite3session_isempty.html">session/sqlite3session_isempty.html</a></li><li>sqlite3session_memory_used - <a href="session/sqlite3session_memory_used.html">session/sqlite3session_memory_used.html</a></li><li>sqlite3session_object_config - <a href="session/sqlite3session_object_config.html">session/sqlite3session_object_config.html</a></li><li>sqlite3session_patchset - <a href="session/sqlite3session_patchset.html">session/sqlite3session_patchset.html</a></li><li>sqlite3session_patchset_strm - <a href="session/sqlite3changegroup_add_strm.html">session/sqlite3changegroup_add_strm.html</a></li><li>sqlite3session_table_filter - <a href="session/sqlite3session_table_filter.html">session/sqlite3session_table_filter.html</a></li><li>SQLITE_4_BYTE_ALIGNED_MALLOC - <a href="compile.html#4_byte_aligned_malloc">compile.html#4_byte_aligned_malloc</a></li><li>SQLITE_ABORT - <a href="rescode.html#abort">rescode.html#abort</a></li><li>SQLITE_ABORT_ROLLBACK - <a href="rescode.html#abort_rollback">rescode.html#abort_rollback</a></li><li>SQLITE_ACCESS_EXISTS - <a href="c3ref/c_access_exists.html">c3ref/c_access_exists.html</a></li><li>SQLITE_ACCESS_READ - <a href="c3ref/c_access_exists.html">c3ref/c_access_exists.html</a></li><li>SQLITE_ACCESS_READWRITE - <a href="c3ref/c_access_exists.html">c3ref/c_access_exists.html</a></li><li>SQLITE_ALLOW_COVERING_INDEX_SCAN - <a href="compile.html#allow_covering_index_scan">compile.html#allow_covering_index_scan</a></li><li>SQLITE_ALLOW_URI_AUTHORITY - <a href="compile.html#allow_uri_authority">compile.html#allow_uri_authority</a></li><li>SQLITE_ALTER_TABLE - <a href="c3ref/c_alter_table.html">c3ref/c_alter_table.html</a></li><li>SQLITE_ANALYZE - <a href="c3ref/c_alter_table.html">c3ref/c_alter_table.html</a></li><li>SQLITE_ANY - <a href="c3ref/c_any.html">c3ref/c_any.html</a></li><li>SQLITE_API - <a href="compile.html#api">compile.html#api</a></li><li>SQLITE_APICALL - <a href="compile.html#apicall">compile.html#apicall</a></li><li>SQLITE_ATTACH - <a href="c3ref/c_alter_table.html">c3ref/c_alter_table.html</a></li><li>SQLITE_AUTH - <a href="rescode.html#auth">rescode.html#auth</a></li><li>SQLITE_AUTH_USER - <a href="rescode.html#auth_user">rescode.html#auth_user</a></li><li>SQLITE_BLOB - <a href="c3ref/c_blob.html">c3ref/c_blob.html</a></li><li>SQLITE_BUSY - <a href="rescode.html#busy">rescode.html#busy</a></li><li>SQLITE_BUSY_RECOVERY - <a href="rescode.html#busy_recovery">rescode.html#busy_recovery</a></li><li>SQLITE_BUSY_SNAPSHOT - <a href="rescode.html#busy_snapshot">rescode.html#busy_snapshot</a></li><li>SQLITE_BUSY_TIMEOUT - <a href="rescode.html#busy_timeout">rescode.html#busy_timeout</a></li><li>SQLITE_BYTEORDER - <a href="compile.html#byteorder">compile.html#byteorder</a></li><li>SQLITE_CALLBACK - <a href="compile.html#callback">compile.html#callback</a></li><li>SQLITE_CANTOPEN - <a href="rescode.html#cantopen">rescode.html#cantopen</a></li><li>SQLITE_CANTOPEN_CONVPATH - <a href="rescode.html#cantopen_convpath">rescode.html#cantopen_convpath</a></li><li>SQLITE_CANTOPEN_DIRTYWAL - <a href="rescode.html#cantopen_dirtywal">rescode.html#cantopen_dirtywal</a></li><li>SQLITE_CANTOPEN_FULLPATH - <a href="rescode.html#cantopen_fullpath">rescode.html#cantopen_fullpath</a></li><li>SQLITE_CANTOPEN_ISDIR - <a href="rescode.html#cantopen_isdir">rescode.html#cantopen_isdir</a></li><li>SQLITE_CANTOPEN_NOTEMPDIR - <a href="rescode.html#cantopen_notempdir">rescode.html#cantopen_notempdir</a></li><li>SQLITE_CANTOPEN_SYMLINK - <a href="rescode.html#cantopen_symlink">rescode.html#cantopen_symlink</a></li><li>SQLITE_CASE_SENSITIVE_LIKE - <a href="compile.html#case_sensitive_like">compile.html#case_sensitive_like</a></li><li>SQLITE_CDECL - <a href="compile.html#cdecl">compile.html#cdecl</a></li><li>SQLITE_CHANGESET_ABORT - <a href="session/c_changeset_abort.html">session/c_changeset_abort.html</a></li><li>SQLITE_CHANGESET_CONFLICT - <a href="session/c_changeset_conflict.html">session/c_changeset_conflict.html</a></li><li>SQLITE_CHANGESET_CONSTRAINT - <a href="session/c_changeset_conflict.html">session/c_changeset_conflict.html</a></li><li>SQLITE_CHANGESET_DATA - <a href="session/c_changeset_conflict.html">session/c_changeset_conflict.html</a></li><li>SQLITE_CHANGESET_FOREIGN_KEY - <a href="session/c_changeset_conflict.html">session/c_changeset_conflict.html</a></li><li>SQLITE_CHANGESET_NOTFOUND - <a href="session/c_changeset_conflict.html">session/c_changeset_conflict.html</a></li><li>SQLITE_CHANGESET_OMIT - <a href="session/c_changeset_abort.html">session/c_changeset_abort.html</a></li><li>SQLITE_CHANGESET_REPLACE - <a href="session/c_changeset_abort.html">session/c_changeset_abort.html</a></li><li>SQLITE_CHANGESETAPPLY_FKNOACTION - <a href="session/c_changesetapply_fknoaction.html">session/c_changesetapply_fknoaction.html</a></li><li>SQLITE_CHANGESETAPPLY_IGNORENOOP - <a href="session/c_changesetapply_fknoaction.html">session/c_changesetapply_fknoaction.html</a></li><li>SQLITE_CHANGESETAPPLY_INVERT - <a href="session/c_changesetapply_fknoaction.html">session/c_changesetapply_fknoaction.html</a></li><li>SQLITE_CHANGESETAPPLY_NOSAVEPOINT - <a href="session/c_changesetapply_fknoaction.html">session/c_changesetapply_fknoaction.html</a></li><li>SQLITE_CHANGESETSTART_INVERT - <a href="session/c_changesetstart_invert.html">session/c_changesetstart_invert.html</a></li><li>SQLITE_CHECKPOINT_FULL - <a href="c3ref/c_checkpoint_full.html">c3ref/c_checkpoint_full.html</a></li><li>SQLITE_CHECKPOINT_PASSIVE - <a href="c3ref/c_checkpoint_full.html">c3ref/c_checkpoint_full.html</a></li><li>SQLITE_CHECKPOINT_RESTART - <a href="c3ref/c_checkpoint_full.html">c3ref/c_checkpoint_full.html</a></li><li>SQLITE_CHECKPOINT_TRUNCATE - <a href="c3ref/c_checkpoint_full.html">c3ref/c_checkpoint_full.html</a></li><li>sqlite_compileoption_get - <a href="lang_corefunc.html#sqlite_compileoption_get">lang_corefunc.html#sqlite_compileoption_get</a></li><li>sqlite_compileoption_get SQL function - <a href="lang_corefunc.html#sqlite_compileoption_get">lang_corefunc.html#sqlite_compileoption_get</a></li><li>sqlite_compileoption_used - <a href="lang_corefunc.html#sqlite_compileoption_used">lang_corefunc.html#sqlite_compileoption_used</a></li><li>sqlite_compileoption_used SQL function - <a href="lang_corefunc.html#sqlite_compileoption_used">lang_corefunc.html#sqlite_compileoption_used</a></li><li>SQLITE_CONFIG_COVERING_INDEX_SCAN - <a href="c3ref/c_config_covering_index_scan.html#sqliteconfigcoveringindexscan">c3ref/c_config_covering_index_scan.html#sqliteconfigcoveringindexscan</a></li><li>SQLITE_CONFIG_GETMALLOC - <a href="c3ref/c_config_covering_index_scan.html#sqliteconfiggetmalloc">c3ref/c_config_covering_index_scan.html#sqliteconfiggetmalloc</a></li><li>SQLITE_CONFIG_GETMUTEX - <a href="c3ref/c_config_covering_index_scan.html#sqliteconfiggetmutex">c3ref/c_config_covering_index_scan.html#sqliteconfiggetmutex</a></li><li>SQLITE_CONFIG_GETPCACHE - <a href="c3ref/c_config_covering_index_scan.html#sqliteconfiggetpcache">c3ref/c_config_covering_index_scan.html#sqliteconfiggetpcache</a></li><li>SQLITE_CONFIG_GETPCACHE2 - <a href="c3ref/c_config_covering_index_scan.html#sqliteconfiggetpcache2">c3ref/c_config_covering_index_scan.html#sqliteconfiggetpcache2</a></li><li>SQLITE_CONFIG_HEAP - <a href="c3ref/c_config_covering_index_scan.html#sqliteconfigheap">c3ref/c_config_covering_index_scan.html#sqliteconfigheap</a></li><li>SQLITE_CONFIG_LOG - <a href="c3ref/c_config_covering_index_scan.html#sqliteconfiglog">c3ref/c_config_covering_index_scan.html#sqliteconfiglog</a></li><li>SQLITE_CONFIG_LOOKASIDE - <a href="c3ref/c_config_covering_index_scan.html#sqliteconfiglookaside">c3ref/c_config_covering_index_scan.html#sqliteconfiglookaside</a></li><li>SQLITE_CONFIG_MALLOC - <a href="c3ref/c_config_covering_index_scan.html#sqliteconfigmalloc">c3ref/c_config_covering_index_scan.html#sqliteconfigmalloc</a></li><li>SQLITE_CONFIG_MEMDB_MAXSIZE - <a href="c3ref/c_config_covering_index_scan.html#sqliteconfigmemdbmaxsize">c3ref/c_config_covering_index_scan.html#sqliteconfigmemdbmaxsize</a></li><li>SQLITE_CONFIG_MEMSTATUS - <a href="c3ref/c_config_covering_index_scan.html#sqliteconfigmemstatus">c3ref/c_config_covering_index_scan.html#sqliteconfigmemstatus</a></li><li>SQLITE_CONFIG_MMAP_SIZE - <a href="c3ref/c_config_covering_index_scan.html#sqliteconfigmmapsize">c3ref/c_config_covering_index_scan.html#sqliteconfigmmapsize</a></li><li>SQLITE_CONFIG_MULTITHREAD - <a href="c3ref/c_config_covering_index_scan.html#sqliteconfigmultithread">c3ref/c_config_covering_index_scan.html#sqliteconfigmultithread</a></li><li>SQLITE_CONFIG_MUTEX - <a href="c3ref/c_config_covering_index_scan.html#sqliteconfigmutex">c3ref/c_config_covering_index_scan.html#sqliteconfigmutex</a></li><li>SQLITE_CONFIG_PAGECACHE - <a href="c3ref/c_config_covering_index_scan.html#sqliteconfigpagecache">c3ref/c_config_covering_index_scan.html#sqliteconfigpagecache</a></li><li>SQLITE_CONFIG_PCACHE - <a href="c3ref/c_config_covering_index_scan.html#sqliteconfigpcache">c3ref/c_config_covering_index_scan.html#sqliteconfigpcache</a></li><li>SQLITE_CONFIG_PCACHE2 - <a href="c3ref/c_config_covering_index_scan.html#sqliteconfigpcache2">c3ref/c_config_covering_index_scan.html#sqliteconfigpcache2</a></li><li>SQLITE_CONFIG_PCACHE_HDRSZ - <a href="c3ref/c_config_covering_index_scan.html#sqliteconfigpcachehdrsz">c3ref/c_config_covering_index_scan.html#sqliteconfigpcachehdrsz</a></li><li>SQLITE_CONFIG_PMASZ - <a href="c3ref/c_config_covering_index_scan.html#sqliteconfigpmasz">c3ref/c_config_covering_index_scan.html#sqliteconfigpmasz</a></li><li>SQLITE_CONFIG_ROWID_IN_VIEW - <a href="c3ref/c_config_covering_index_scan.html#sqliteconfigrowidinview">c3ref/c_config_covering_index_scan.html#sqliteconfigrowidinview</a></li><li>SQLITE_CONFIG_SCRATCH - <a href="c3ref/c_config_covering_index_scan.html#sqliteconfigscratch">c3ref/c_config_covering_index_scan.html#sqliteconfigscratch</a></li><li>SQLITE_CONFIG_SERIALIZED - <a href="c3ref/c_config_covering_index_scan.html#sqliteconfigserialized">c3ref/c_config_covering_index_scan.html#sqliteconfigserialized</a></li><li>SQLITE_CONFIG_SINGLETHREAD - <a href="c3ref/c_config_covering_index_scan.html#sqliteconfigsinglethread">c3ref/c_config_covering_index_scan.html#sqliteconfigsinglethread</a></li><li>SQLITE_CONFIG_SMALL_MALLOC - <a href="c3ref/c_config_covering_index_scan.html#sqliteconfigsmallmalloc">c3ref/c_config_covering_index_scan.html#sqliteconfigsmallmalloc</a></li><li>SQLITE_CONFIG_SORTERREF_SIZE - <a href="c3ref/c_config_covering_index_scan.html#sqliteconfigsorterrefsize">c3ref/c_config_covering_index_scan.html#sqliteconfigsorterrefsize</a></li><li>SQLITE_CONFIG_SQLLOG - <a href="c3ref/c_config_covering_index_scan.html#sqliteconfigsqllog">c3ref/c_config_covering_index_scan.html#sqliteconfigsqllog</a></li><li>SQLITE_CONFIG_STMTJRNL_SPILL - <a href="c3ref/c_config_covering_index_scan.html#sqliteconfigstmtjrnlspill">c3ref/c_config_covering_index_scan.html#sqliteconfigstmtjrnlspill</a></li><li>SQLITE_CONFIG_URI - <a href="c3ref/c_config_covering_index_scan.html#sqliteconfiguri">c3ref/c_config_covering_index_scan.html#sqliteconfiguri</a></li><li>SQLITE_CONFIG_WIN32_HEAPSIZE - <a href="c3ref/c_config_covering_index_scan.html#sqliteconfigwin32heapsize">c3ref/c_config_covering_index_scan.html#sqliteconfigwin32heapsize</a></li><li>SQLITE_CONSTRAINT - <a href="rescode.html#constraint">rescode.html#constraint</a></li><li>SQLITE_CONSTRAINT_CHECK - <a href="rescode.html#constraint_check">rescode.html#constraint_check</a></li><li>SQLITE_CONSTRAINT_COMMITHOOK - <a href="rescode.html#constraint_commithook">rescode.html#constraint_commithook</a></li><li>SQLITE_CONSTRAINT_DATATYPE - <a href="rescode.html#constraint_datatype">rescode.html#constraint_datatype</a></li><li>SQLITE_CONSTRAINT_FOREIGNKEY - <a href="rescode.html#constraint_foreignkey">rescode.html#constraint_foreignkey</a></li><li>SQLITE_CONSTRAINT_FUNCTION - <a href="rescode.html#constraint_function">rescode.html#constraint_function</a></li><li>SQLITE_CONSTRAINT_NOTNULL - <a href="rescode.html#constraint_notnull">rescode.html#constraint_notnull</a></li><li>SQLITE_CONSTRAINT_PINNED - <a href="rescode.html#constraint_pinned">rescode.html#constraint_pinned</a></li><li>SQLITE_CONSTRAINT_PRIMARYKEY - <a href="rescode.html#constraint_primarykey">rescode.html#constraint_primarykey</a></li><li>SQLITE_CONSTRAINT_ROWID - <a href="rescode.html#constraint_rowid">rescode.html#constraint_rowid</a></li><li>SQLITE_CONSTRAINT_TRIGGER - <a href="rescode.html#constraint_trigger">rescode.html#constraint_trigger</a></li><li>SQLITE_CONSTRAINT_UNIQUE - <a href="rescode.html#constraint_unique">rescode.html#constraint_unique</a></li><li>SQLITE_CONSTRAINT_VTAB - <a href="rescode.html#constraint_vtab">rescode.html#constraint_vtab</a></li><li>SQLITE_COPY - <a href="c3ref/c_alter_table.html">c3ref/c_alter_table.html</a></li><li>SQLITE_CORRUPT - <a href="rescode.html#corrupt">rescode.html#corrupt</a></li><li>SQLITE_CORRUPT_INDEX - <a href="rescode.html#corrupt_index">rescode.html#corrupt_index</a></li><li>SQLITE_CORRUPT_SEQUENCE - <a href="rescode.html#corrupt_sequence">rescode.html#corrupt_sequence</a></li><li>SQLITE_CORRUPT_VTAB - <a href="rescode.html#corrupt_vtab">rescode.html#corrupt_vtab</a></li><li>SQLITE_CREATE_INDEX - <a href="c3ref/c_alter_table.html">c3ref/c_alter_table.html</a></li><li>SQLITE_CREATE_TABLE - <a href="c3ref/c_alter_table.html">c3ref/c_alter_table.html</a></li><li>SQLITE_CREATE_TEMP_INDEX - <a href="c3ref/c_alter_table.html">c3ref/c_alter_table.html</a></li><li>SQLITE_CREATE_TEMP_TABLE - <a href="c3ref/c_alter_table.html">c3ref/c_alter_table.html</a></li><li>SQLITE_CREATE_TEMP_TRIGGER - <a href="c3ref/c_alter_table.html">c3ref/c_alter_table.html</a></li><li>SQLITE_CREATE_TEMP_VIEW - <a href="c3ref/c_alter_table.html">c3ref/c_alter_table.html</a></li><li>SQLITE_CREATE_TRIGGER - <a href="c3ref/c_alter_table.html">c3ref/c_alter_table.html</a></li><li>SQLITE_CREATE_VIEW - <a href="c3ref/c_alter_table.html">c3ref/c_alter_table.html</a></li><li>SQLITE_CREATE_VTABLE - <a href="c3ref/c_alter_table.html">c3ref/c_alter_table.html</a></li><li>SQLITE_DBCONFIG_DEFENSIVE - <a href="c3ref/c_dbconfig_defensive.html#sqlitedbconfigdefensive">c3ref/c_dbconfig_defensive.html#sqlitedbconfigdefensive</a></li><li>SQLITE_DBCONFIG_DQS_DDL - <a href="c3ref/c_dbconfig_defensive.html#sqlitedbconfigdqsddl">c3ref/c_dbconfig_defensive.html#sqlitedbconfigdqsddl</a></li><li>SQLITE_DBCONFIG_DQS_DML - <a href="c3ref/c_dbconfig_defensive.html#sqlitedbconfigdqsdml">c3ref/c_dbconfig_defensive.html#sqlitedbconfigdqsdml</a></li><li>SQLITE_DBCONFIG_ENABLE_FKEY - <a href="c3ref/c_dbconfig_defensive.html#sqlitedbconfigenablefkey">c3ref/c_dbconfig_defensive.html#sqlitedbconfigenablefkey</a></li><li>SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER - <a href="c3ref/c_dbconfig_defensive.html#sqlitedbconfigenablefts3tokenizer">c3ref/c_dbconfig_defensive.html#sqlitedbconfigenablefts3tokenizer</a></li><li>SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION - <a href="c3ref/c_dbconfig_defensive.html#sqlitedbconfigenableloadextension">c3ref/c_dbconfig_defensive.html#sqlitedbconfigenableloadextension</a></li><li>SQLITE_DBCONFIG_ENABLE_QPSG - <a href="c3ref/c_dbconfig_defensive.html#sqlitedbconfigenableqpsg">c3ref/c_dbconfig_defensive.html#sqlitedbconfigenableqpsg</a></li><li>SQLITE_DBCONFIG_ENABLE_TRIGGER - <a href="c3ref/c_dbconfig_defensive.html#sqlitedbconfigenabletrigger">c3ref/c_dbconfig_defensive.html#sqlitedbconfigenabletrigger</a></li><li>SQLITE_DBCONFIG_ENABLE_VIEW - <a href="c3ref/c_dbconfig_defensive.html#sqlitedbconfigenableview">c3ref/c_dbconfig_defensive.html#sqlitedbconfigenableview</a></li><li>SQLITE_DBCONFIG_LEGACY_ALTER_TABLE - <a href="c3ref/c_dbconfig_defensive.html#sqlitedbconfiglegacyaltertable">c3ref/c_dbconfig_defensive.html#sqlitedbconfiglegacyaltertable</a></li><li>SQLITE_DBCONFIG_LEGACY_FILE_FORMAT - <a href="c3ref/c_dbconfig_defensive.html#sqlitedbconfiglegacyfileformat">c3ref/c_dbconfig_defensive.html#sqlitedbconfiglegacyfileformat</a></li><li>SQLITE_DBCONFIG_LOOKASIDE - <a href="c3ref/c_dbconfig_defensive.html#sqlitedbconfiglookaside">c3ref/c_dbconfig_defensive.html#sqlitedbconfiglookaside</a></li><li>SQLITE_DBCONFIG_MAINDBNAME - <a href="c3ref/c_dbconfig_defensive.html#sqlitedbconfigmaindbname">c3ref/c_dbconfig_defensive.html#sqlitedbconfigmaindbname</a></li><li>SQLITE_DBCONFIG_MAX - <a href="c3ref/c_dbconfig_defensive.html">c3ref/c_dbconfig_defensive.html</a></li><li>SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE - <a href="c3ref/c_dbconfig_defensive.html#sqlitedbconfignockptonclose">c3ref/c_dbconfig_defensive.html#sqlitedbconfignockptonclose</a></li><li>SQLITE_DBCONFIG_RESET_DATABASE - <a href="c3ref/c_dbconfig_defensive.html#sqlitedbconfigresetdatabase">c3ref/c_dbconfig_defensive.html#sqlitedbconfigresetdatabase</a></li><li>SQLITE_DBCONFIG_REVERSE_SCANORDER - <a href="c3ref/c_dbconfig_defensive.html#sqlitedbconfigreversescanorder">c3ref/c_dbconfig_defensive.html#sqlitedbconfigreversescanorder</a></li><li>SQLITE_DBCONFIG_STMT_SCANSTATUS - <a href="c3ref/c_dbconfig_defensive.html#sqlitedbconfigstmtscanstatus">c3ref/c_dbconfig_defensive.html#sqlitedbconfigstmtscanstatus</a></li><li>SQLITE_DBCONFIG_TRIGGER_EQP - <a href="c3ref/c_dbconfig_defensive.html#sqlitedbconfigtriggereqp">c3ref/c_dbconfig_defensive.html#sqlitedbconfigtriggereqp</a></li><li>SQLITE_DBCONFIG_TRUSTED_SCHEMA - <a href="c3ref/c_dbconfig_defensive.html#sqlitedbconfigtrustedschema">c3ref/c_dbconfig_defensive.html#sqlitedbconfigtrustedschema</a></li><li>SQLITE_DBCONFIG_WRITABLE_SCHEMA - <a href="c3ref/c_dbconfig_defensive.html#sqlitedbconfigwritableschema">c3ref/c_dbconfig_defensive.html#sqlitedbconfigwritableschema</a></li><li>sqlite_dbpage - <a href="dbpage.html">dbpage.html</a></li><li>SQLITE_DBPAGE virtual table - <a href="dbpage.html">dbpage.html</a></li><li>SQLITE_DBSTATUS options - <a href="c3ref/c_dbstatus_options.html">c3ref/c_dbstatus_options.html</a></li><li>SQLITE_DBSTATUS_CACHE_HIT - <a href="c3ref/c_dbstatus_options.html#sqlitedbstatuscachehit">c3ref/c_dbstatus_options.html#sqlitedbstatuscachehit</a></li><li>SQLITE_DBSTATUS_CACHE_MISS - <a href="c3ref/c_dbstatus_options.html#sqlitedbstatuscachemiss">c3ref/c_dbstatus_options.html#sqlitedbstatuscachemiss</a></li><li>SQLITE_DBSTATUS_CACHE_SPILL - <a href="c3ref/c_dbstatus_options.html#sqlitedbstatuscachespill">c3ref/c_dbstatus_options.html#sqlitedbstatuscachespill</a></li><li>SQLITE_DBSTATUS_CACHE_USED - <a href="c3ref/c_dbstatus_options.html#sqlitedbstatuscacheused">c3ref/c_dbstatus_options.html#sqlitedbstatuscacheused</a></li><li>SQLITE_DBSTATUS_CACHE_USED_SHARED - <a href="c3ref/c_dbstatus_options.html#sqlitedbstatuscacheusedshared">c3ref/c_dbstatus_options.html#sqlitedbstatuscacheusedshared</a></li><li>SQLITE_DBSTATUS_CACHE_WRITE - <a href="c3ref/c_dbstatus_options.html#sqlitedbstatuscachewrite">c3ref/c_dbstatus_options.html#sqlitedbstatuscachewrite</a></li><li>SQLITE_DBSTATUS_DEFERRED_FKS - <a href="c3ref/c_dbstatus_options.html#sqlitedbstatusdeferredfks">c3ref/c_dbstatus_options.html#sqlitedbstatusdeferredfks</a></li><li>SQLITE_DBSTATUS_LOOKASIDE_HIT - <a href="c3ref/c_dbstatus_options.html#sqlitedbstatuslookasidehit">c3ref/c_dbstatus_options.html#sqlitedbstatuslookasidehit</a></li><li>SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL - <a href="c3ref/c_dbstatus_options.html#sqlitedbstatuslookasidemissfull">c3ref/c_dbstatus_options.html#sqlitedbstatuslookasidemissfull</a></li><li>SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE - <a href="c3ref/c_dbstatus_options.html#sqlitedbstatuslookasidemisssize">c3ref/c_dbstatus_options.html#sqlitedbstatuslookasidemisssize</a></li><li>SQLITE_DBSTATUS_LOOKASIDE_USED - <a href="c3ref/c_dbstatus_options.html#sqlitedbstatuslookasideused">c3ref/c_dbstatus_options.html#sqlitedbstatuslookasideused</a></li><li>SQLITE_DBSTATUS_MAX - <a href="c3ref/c_dbstatus_options.html">c3ref/c_dbstatus_options.html</a></li><li>SQLITE_DBSTATUS_SCHEMA_USED - <a href="c3ref/c_dbstatus_options.html#sqlitedbstatusschemaused">c3ref/c_dbstatus_options.html#sqlitedbstatusschemaused</a></li><li>SQLITE_DBSTATUS_STMT_USED - <a href="c3ref/c_dbstatus_options.html#sqlitedbstatusstmtused">c3ref/c_dbstatus_options.html#sqlitedbstatusstmtused</a></li><li>SQLITE_DEBUG - <a href="compile.html#debug">compile.html#debug</a></li><li>SQLITE_DEFAULT_AUTOMATIC_INDEX - <a href="compile.html#default_automatic_index">compile.html#default_automatic_index</a></li><li>SQLITE_DEFAULT_AUTOVACUUM - <a href="compile.html#default_autovacuum">compile.html#default_autovacuum</a></li><li>SQLITE_DEFAULT_CACHE_SIZE - <a href="compile.html#default_cache_size">compile.html#default_cache_size</a></li><li>SQLITE_DEFAULT_FILE_FORMAT - <a href="compile.html#default_file_format">compile.html#default_file_format</a></li><li>SQLITE_DEFAULT_FILE_PERMISSIONS - <a href="compile.html#default_file_permissions">compile.html#default_file_permissions</a></li><li>SQLITE_DEFAULT_FOREIGN_KEYS - <a href="compile.html#default_foreign_keys">compile.html#default_foreign_keys</a></li><li>SQLITE_DEFAULT_JOURNAL_SIZE_LIMIT - <a href="compile.html#default_journal_size_limit">compile.html#default_journal_size_limit</a></li><li>SQLITE_DEFAULT_LOCKING_MODE - <a href="compile.html#default_locking_mode">compile.html#default_locking_mode</a></li><li>SQLITE_DEFAULT_LOOKASIDE - <a href="compile.html#default_lookaside">compile.html#default_lookaside</a></li><li>SQLITE_DEFAULT_MEMSTATUS - <a href="compile.html#default_memstatus">compile.html#default_memstatus</a></li><li>SQLITE_DEFAULT_MMAP_SIZE - <a href="compile.html#default_mmap_size">compile.html#default_mmap_size</a></li><li>SQLITE_DEFAULT_PAGE_SIZE - <a href="compile.html#default_page_size">compile.html#default_page_size</a></li><li>SQLITE_DEFAULT_PCACHE_INITSZ - <a href="compile.html#default_pcache_initsz">compile.html#default_pcache_initsz</a></li><li>SQLITE_DEFAULT_SYNCHRONOUS - <a href="compile.html#default_synchronous">compile.html#default_synchronous</a></li><li>SQLITE_DEFAULT_WAL_AUTOCHECKPOINT - <a href="compile.html#default_wal_autocheckpoint">compile.html#default_wal_autocheckpoint</a></li><li>SQLITE_DEFAULT_WAL_SYNCHRONOUS - <a href="compile.html#default_wal_synchronous">compile.html#default_wal_synchronous</a></li><li>SQLITE_DEFAULT_WORKER_THREADS - <a href="compile.html#default_worker_threads">compile.html#default_worker_threads</a></li><li>SQLITE_DELETE - <a href="c3ref/c_alter_table.html">c3ref/c_alter_table.html</a></li><li>SQLITE_DENY - <a href="c3ref/c_deny.html">c3ref/c_deny.html</a></li><li>SQLITE_DESERIALIZE_FREEONCLOSE - <a href="c3ref/c_deserialize_freeonclose.html">c3ref/c_deserialize_freeonclose.html</a></li><li>SQLITE_DESERIALIZE_READONLY - <a href="c3ref/c_deserialize_freeonclose.html">c3ref/c_deserialize_freeonclose.html</a></li><li>SQLITE_DESERIALIZE_RESIZEABLE - <a href="c3ref/c_deserialize_freeonclose.html">c3ref/c_deserialize_freeonclose.html</a></li><li>SQLITE_DETACH - <a href="c3ref/c_alter_table.html">c3ref/c_alter_table.html</a></li><li>SQLITE_DETERMINISTIC - <a href="c3ref/c_deterministic.html#sqlitedeterministic">c3ref/c_deterministic.html#sqlitedeterministic</a></li><li>SQLITE_DIRECT_OVERFLOW_READ - <a href="compile.html#direct_overflow_read">compile.html#direct_overflow_read</a></li><li>SQLITE_DIRECTONLY - <a href="c3ref/c_deterministic.html#sqlitedirectonly">c3ref/c_deterministic.html#sqlitedirectonly</a></li><li>SQLITE_DISABLE_DIRSYNC - <a href="compile.html#disable_dirsync">compile.html#disable_dirsync</a></li><li>SQLITE_DISABLE_FTS3_UNICODE - <a href="compile.html#disable_fts3_unicode">compile.html#disable_fts3_unicode</a></li><li>SQLITE_DISABLE_FTS4_DEFERRED - <a href="compile.html#disable_fts4_deferred">compile.html#disable_fts4_deferred</a></li><li>SQLITE_DISABLE_INTRINSIC - <a href="compile.html#disable_intrinsic">compile.html#disable_intrinsic</a></li><li>SQLITE_DISABLE_LFS - <a href="compile.html#disable_lfs">compile.html#disable_lfs</a></li><li>SQLITE_DISABLE_PAGECACHE_OVERFLOW_STATS - <a href="compile.html#disable_pagecache_overflow_stats">compile.html#disable_pagecache_overflow_stats</a></li><li>SQLITE_DONE - <a href="rescode.html#done">rescode.html#done</a></li><li>SQLITE_DQS - <a href="compile.html#dqs">compile.html#dqs</a></li><li>SQLITE_DROP_INDEX - <a href="c3ref/c_alter_table.html">c3ref/c_alter_table.html</a></li><li>SQLITE_DROP_TABLE - <a href="c3ref/c_alter_table.html">c3ref/c_alter_table.html</a></li><li>SQLITE_DROP_TEMP_INDEX - <a href="c3ref/c_alter_table.html">c3ref/c_alter_table.html</a></li><li>SQLITE_DROP_TEMP_TABLE - <a href="c3ref/c_alter_table.html">c3ref/c_alter_table.html</a></li><li>SQLITE_DROP_TEMP_TRIGGER - <a href="c3ref/c_alter_table.html">c3ref/c_alter_table.html</a></li><li>SQLITE_DROP_TEMP_VIEW - <a href="c3ref/c_alter_table.html">c3ref/c_alter_table.html</a></li><li>SQLITE_DROP_TRIGGER - <a href="c3ref/c_alter_table.html">c3ref/c_alter_table.html</a></li><li>SQLITE_DROP_VIEW - <a href="c3ref/c_alter_table.html">c3ref/c_alter_table.html</a></li><li>SQLITE_DROP_VTABLE - <a href="c3ref/c_alter_table.html">c3ref/c_alter_table.html</a></li><li>SQLITE_EMPTY - <a href="rescode.html#empty">rescode.html#empty</a></li><li>SQLITE_ENABLE_8_3_NAMES - <a href="compile.html#enable_8_3_names">compile.html#enable_8_3_names</a></li><li>SQLITE_ENABLE_API_ARMOR - <a href="compile.html#enable_api_armor">compile.html#enable_api_armor</a></li><li>SQLITE_ENABLE_ATOMIC_WRITE - <a href="compile.html#enable_atomic_write">compile.html#enable_atomic_write</a></li><li>SQLITE_ENABLE_BATCH_ATOMIC_WRITE - <a href="compile.html#enable_batch_atomic_write">compile.html#enable_batch_atomic_write</a></li><li>SQLITE_ENABLE_BYTECODE_VTAB - <a href="compile.html#enable_bytecode_vtab">compile.html#enable_bytecode_vtab</a></li><li>SQLITE_ENABLE_COLUMN_METADATA - <a href="compile.html#enable_column_metadata">compile.html#enable_column_metadata</a></li><li>SQLITE_ENABLE_DBPAGE_VTAB - <a href="compile.html#enable_dbpage_vtab">compile.html#enable_dbpage_vtab</a></li><li>SQLITE_ENABLE_DBSTAT_VTAB - <a href="compile.html#enable_dbstat_vtab">compile.html#enable_dbstat_vtab</a></li><li>SQLITE_ENABLE_DESERIALIZE - <a href="compile.html#enable_deserialize">compile.html#enable_deserialize</a></li><li>SQLITE_ENABLE_EXPLAIN_COMMENTS - <a href="compile.html#enable_explain_comments">compile.html#enable_explain_comments</a></li><li>SQLITE_ENABLE_FTS3 - <a href="compile.html#enable_fts3">compile.html#enable_fts3</a></li><li>SQLITE_ENABLE_FTS3_PARENTHESIS - <a href="compile.html#enable_fts3_parenthesis">compile.html#enable_fts3_parenthesis</a></li><li>SQLITE_ENABLE_FTS3_TOKENIZER - <a href="compile.html#enable_fts3_tokenizer">compile.html#enable_fts3_tokenizer</a></li><li>SQLITE_ENABLE_FTS4 - <a href="compile.html#enable_fts4">compile.html#enable_fts4</a></li><li>SQLITE_ENABLE_FTS5 - <a href="compile.html#enable_fts5">compile.html#enable_fts5</a></li><li>SQLITE_ENABLE_GEOPOLY - <a href="compile.html#enable_geopoly">compile.html#enable_geopoly</a></li><li>SQLITE_ENABLE_HIDDEN_COLUMNS - <a href="compile.html#enable_hidden_columns">compile.html#enable_hidden_columns</a></li><li>SQLITE_ENABLE_ICU - <a href="compile.html#enable_icu">compile.html#enable_icu</a></li><li>SQLITE_ENABLE_IOTRACE - <a href="compile.html#enable_iotrace">compile.html#enable_iotrace</a></li><li>SQLITE_ENABLE_JSON1 - <a href="compile.html#enable_json1">compile.html#enable_json1</a></li><li>SQLITE_ENABLE_LOCKING_STYLE - <a href="compile.html#enable_locking_style">compile.html#enable_locking_style</a></li><li>SQLITE_ENABLE_MATH_FUNCTIONS - <a href="compile.html#enable_math_functions">compile.html#enable_math_functions</a></li><li>SQLITE_ENABLE_MEMORY_MANAGEMENT - <a href="compile.html#enable_memory_management">compile.html#enable_memory_management</a></li><li>SQLITE_ENABLE_MEMSYS3 - <a href="compile.html#enable_memsys3">compile.html#enable_memsys3</a></li><li>SQLITE_ENABLE_MEMSYS5 - <a href="compile.html#enable_memsys5">compile.html#enable_memsys5</a></li><li>SQLITE_ENABLE_NORMALIZE - <a href="compile.html#enable_normalize">compile.html#enable_normalize</a></li><li>SQLITE_ENABLE_NULL_TRIM - <a href="compile.html#enable_null_trim">compile.html#enable_null_trim</a></li><li>SQLITE_ENABLE_OFFSET_SQL_FUNC - <a href="compile.html#enable_offset_sql_func">compile.html#enable_offset_sql_func</a></li><li>SQLITE_ENABLE_PREUPDATE_HOOK - <a href="compile.html#enable_preupdate_hook">compile.html#enable_preupdate_hook</a></li><li>SQLITE_ENABLE_QPSG - <a href="compile.html#enable_qpsg">compile.html#enable_qpsg</a></li><li>SQLITE_ENABLE_RBU - <a href="compile.html#enable_rbu">compile.html#enable_rbu</a></li><li>SQLITE_ENABLE_RTREE - <a href="compile.html#enable_rtree">compile.html#enable_rtree</a></li><li>SQLITE_ENABLE_SESSION - <a href="compile.html#enable_session">compile.html#enable_session</a></li><li>SQLITE_ENABLE_SNAPSHOT - <a href="compile.html#enable_snapshot">compile.html#enable_snapshot</a></li><li>SQLITE_ENABLE_SORTER_REFERENCES - <a href="compile.html#enable_sorter_references">compile.html#enable_sorter_references</a></li><li>SQLITE_ENABLE_SQLLOG - <a href="compile.html#enable_sqllog">compile.html#enable_sqllog</a></li><li>SQLITE_ENABLE_STAT2 - <a href="compile.html#enable_stat2">compile.html#enable_stat2</a></li><li>SQLITE_ENABLE_STAT3 - <a href="compile.html#enable_stat3">compile.html#enable_stat3</a></li><li>SQLITE_ENABLE_STAT4 - <a href="compile.html#enable_stat4">compile.html#enable_stat4</a></li><li>SQLITE_ENABLE_STMT_SCANSTATUS - <a href="compile.html#enable_stmt_scanstatus">compile.html#enable_stmt_scanstatus</a></li><li>SQLITE_ENABLE_STMTVTAB - <a href="compile.html#enable_stmtvtab">compile.html#enable_stmtvtab</a></li><li>SQLITE_ENABLE_TREE_EXPLAIN - <a href="compile.html#enable_tree_explain">compile.html#enable_tree_explain</a></li><li>SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION - <a href="compile.html#enable_unknown_sql_function">compile.html#enable_unknown_sql_function</a></li><li>SQLITE_ENABLE_UNLOCK_NOTIFY - <a href="compile.html#enable_unlock_notify">compile.html#enable_unlock_notify</a></li><li>SQLITE_ENABLE_UPDATE_DELETE_LIMIT - <a href="compile.html#enable_update_delete_limit">compile.html#enable_update_delete_limit</a></li><li>SQLITE_ERROR - <a href="rescode.html#error">rescode.html#error</a></li><li>SQLITE_ERROR_MISSING_COLLSEQ - <a href="rescode.html#error_missing_collseq">rescode.html#error_missing_collseq</a></li><li>SQLITE_ERROR_RETRY - <a href="rescode.html#error_retry">rescode.html#error_retry</a></li><li>SQLITE_ERROR_SNAPSHOT - <a href="rescode.html#error_snapshot">rescode.html#error_snapshot</a></li><li>SQLITE_EXTERN - <a href="compile.html#extern">compile.html#extern</a></li><li>SQLITE_EXTRA_DURABLE - <a href="compile.html#extra_durable">compile.html#extra_durable</a></li><li>SQLITE_FAIL - <a href="c3ref/c_fail.html">c3ref/c_fail.html</a></li><li>SQLITE_FCNTL_BEGIN_ATOMIC_WRITE - <a href="c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntlbeginatomicwrite">c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntlbeginatomicwrite</a></li><li>SQLITE_FCNTL_BUSYHANDLER - <a href="c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntlbusyhandler">c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntlbusyhandler</a></li><li>SQLITE_FCNTL_CHUNK_SIZE - <a href="c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntlchunksize">c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntlchunksize</a></li><li>SQLITE_FCNTL_CKPT_DONE - <a href="c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntlckptdone">c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntlckptdone</a></li><li>SQLITE_FCNTL_CKPT_START - <a href="c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntlckptstart">c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntlckptstart</a></li><li>SQLITE_FCNTL_CKSM_FILE - <a href="c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntlcksmfile">c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntlcksmfile</a></li><li>SQLITE_FCNTL_COMMIT_ATOMIC_WRITE - <a href="c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntlcommitatomicwrite">c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntlcommitatomicwrite</a></li><li>SQLITE_FCNTL_COMMIT_PHASETWO - <a href="c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntlcommitphasetwo">c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntlcommitphasetwo</a></li><li>SQLITE_FCNTL_DATA_VERSION - <a href="c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntldataversion">c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntldataversion</a></li><li>SQLITE_FCNTL_EXTERNAL_READER - <a href="c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntlexternalreader">c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntlexternalreader</a></li><li>SQLITE_FCNTL_FILE_POINTER - <a href="c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntlfilepointer">c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntlfilepointer</a></li><li>SQLITE_FCNTL_GET_LOCKPROXYFILE - <a href="c3ref/c_fcntl_begin_atomic_write.html">c3ref/c_fcntl_begin_atomic_write.html</a></li><li>SQLITE_FCNTL_HAS_MOVED - <a href="c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntlhasmoved">c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntlhasmoved</a></li><li>SQLITE_FCNTL_JOURNAL_POINTER - <a href="c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntljournalpointer">c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntljournalpointer</a></li><li>SQLITE_FCNTL_LAST_ERRNO - <a href="c3ref/c_fcntl_begin_atomic_write.html">c3ref/c_fcntl_begin_atomic_write.html</a></li><li>SQLITE_FCNTL_LOCK_TIMEOUT - <a href="c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntllocktimeout">c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntllocktimeout</a></li><li>SQLITE_FCNTL_LOCKSTATE - <a href="c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntllockstate">c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntllockstate</a></li><li>SQLITE_FCNTL_MMAP_SIZE - <a href="c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntlmmapsize">c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntlmmapsize</a></li><li>SQLITE_FCNTL_OVERWRITE - <a href="c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntloverwrite">c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntloverwrite</a></li><li>SQLITE_FCNTL_PDB - <a href="c3ref/c_fcntl_begin_atomic_write.html">c3ref/c_fcntl_begin_atomic_write.html</a></li><li>SQLITE_FCNTL_PERSIST_WAL - <a href="c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntlpersistwal">c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntlpersistwal</a></li><li>SQLITE_FCNTL_POWERSAFE_OVERWRITE - <a href="c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntlpowersafeoverwrite">c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntlpowersafeoverwrite</a></li><li>SQLITE_FCNTL_PRAGMA - <a href="c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntlpragma">c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntlpragma</a></li><li>SQLITE_FCNTL_RBU - <a href="c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntlrbu">c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntlrbu</a></li><li>SQLITE_FCNTL_RESERVE_BYTES - <a href="c3ref/c_fcntl_begin_atomic_write.html">c3ref/c_fcntl_begin_atomic_write.html</a></li><li>SQLITE_FCNTL_RESET_CACHE - <a href="c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntlresetcache">c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntlresetcache</a></li><li>SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE - <a href="c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntlrollbackatomicwrite">c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntlrollbackatomicwrite</a></li><li>SQLITE_FCNTL_SET_LOCKPROXYFILE - <a href="c3ref/c_fcntl_begin_atomic_write.html">c3ref/c_fcntl_begin_atomic_write.html</a></li><li>SQLITE_FCNTL_SIZE_HINT - <a href="c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntlsizehint">c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntlsizehint</a></li><li>SQLITE_FCNTL_SIZE_LIMIT - <a href="c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntlsizelimit">c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntlsizelimit</a></li><li>SQLITE_FCNTL_SYNC - <a href="c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntlsync">c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntlsync</a></li><li>SQLITE_FCNTL_SYNC_OMITTED - <a href="c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntlsyncomitted">c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntlsyncomitted</a></li><li>SQLITE_FCNTL_TEMPFILENAME - <a href="c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntltempfilename">c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntltempfilename</a></li><li>SQLITE_FCNTL_TRACE - <a href="c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntltrace">c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntltrace</a></li><li>SQLITE_FCNTL_VFS_POINTER - <a href="c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntlvfspointer">c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntlvfspointer</a></li><li>SQLITE_FCNTL_VFSNAME - <a href="c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntlvfsname">c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntlvfsname</a></li><li>SQLITE_FCNTL_WAL_BLOCK - <a href="c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntlwalblock">c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntlwalblock</a></li><li>SQLITE_FCNTL_WIN32_AV_RETRY - <a href="c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntlwin32avretry">c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntlwin32avretry</a></li><li>SQLITE_FCNTL_WIN32_GET_HANDLE - <a href="c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntlwin32gethandle">c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntlwin32gethandle</a></li><li>SQLITE_FCNTL_WIN32_SET_HANDLE - <a href="c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntlwin32sethandle">c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntlwin32sethandle</a></li><li>SQLITE_FCNTL_ZIPVFS - <a href="c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntlzipvfs">c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntlzipvfs</a></li><li>SQLITE_FLOAT - <a href="c3ref/c_blob.html">c3ref/c_blob.html</a></li><li>SQLITE_FORMAT - <a href="rescode.html#format">rescode.html#format</a></li><li>SQLITE_FTS3_MAX_EXPR_DEPTH - <a href="compile.html#fts3_max_expr_depth">compile.html#fts3_max_expr_depth</a></li><li>SQLITE_FULL - <a href="rescode.html#full">rescode.html#full</a></li><li>SQLITE_FUNCTION - <a href="c3ref/c_alter_table.html">c3ref/c_alter_table.html</a></li><li>SQLITE_HAVE_ISNAN - <a href="compile.html#have_isnan">compile.html#have_isnan</a></li><li>SQLITE_HAVE_ZLIB - <a href="compile.html#have_zlib">compile.html#have_zlib</a></li><li>SQLITE_IGNORE - <a href="c3ref/c_deny.html">c3ref/c_deny.html</a></li><li>SQLITE_INDEX_CONSTRAINT_EQ - <a href="c3ref/c_index_constraint_eq.html">c3ref/c_index_constraint_eq.html</a></li><li>SQLITE_INDEX_CONSTRAINT_FUNCTION - <a href="c3ref/c_index_constraint_eq.html">c3ref/c_index_constraint_eq.html</a></li><li>SQLITE_INDEX_CONSTRAINT_GE - <a href="c3ref/c_index_constraint_eq.html">c3ref/c_index_constraint_eq.html</a></li><li>SQLITE_INDEX_CONSTRAINT_GLOB - <a href="c3ref/c_index_constraint_eq.html">c3ref/c_index_constraint_eq.html</a></li><li>SQLITE_INDEX_CONSTRAINT_GT - <a href="c3ref/c_index_constraint_eq.html">c3ref/c_index_constraint_eq.html</a></li><li>SQLITE_INDEX_CONSTRAINT_IS - <a href="c3ref/c_index_constraint_eq.html">c3ref/c_index_constraint_eq.html</a></li><li>SQLITE_INDEX_CONSTRAINT_ISNOT - <a href="c3ref/c_index_constraint_eq.html">c3ref/c_index_constraint_eq.html</a></li><li>SQLITE_INDEX_CONSTRAINT_ISNOTNULL - <a href="c3ref/c_index_constraint_eq.html">c3ref/c_index_constraint_eq.html</a></li><li>SQLITE_INDEX_CONSTRAINT_ISNULL - <a href="c3ref/c_index_constraint_eq.html">c3ref/c_index_constraint_eq.html</a></li><li>SQLITE_INDEX_CONSTRAINT_LE - <a href="c3ref/c_index_constraint_eq.html">c3ref/c_index_constraint_eq.html</a></li><li>SQLITE_INDEX_CONSTRAINT_LIKE - <a href="c3ref/c_index_constraint_eq.html">c3ref/c_index_constraint_eq.html</a></li><li>SQLITE_INDEX_CONSTRAINT_LIMIT - <a href="c3ref/c_index_constraint_eq.html">c3ref/c_index_constraint_eq.html</a></li><li>SQLITE_INDEX_CONSTRAINT_LT - <a href="c3ref/c_index_constraint_eq.html">c3ref/c_index_constraint_eq.html</a></li><li>SQLITE_INDEX_CONSTRAINT_MATCH - <a href="c3ref/c_index_constraint_eq.html">c3ref/c_index_constraint_eq.html</a></li><li>SQLITE_INDEX_CONSTRAINT_NE - <a href="c3ref/c_index_constraint_eq.html">c3ref/c_index_constraint_eq.html</a></li><li>SQLITE_INDEX_CONSTRAINT_OFFSET - <a href="c3ref/c_index_constraint_eq.html">c3ref/c_index_constraint_eq.html</a></li><li>SQLITE_INDEX_CONSTRAINT_REGEXP - <a href="c3ref/c_index_constraint_eq.html">c3ref/c_index_constraint_eq.html</a></li><li>SQLITE_INDEX_SCAN_UNIQUE - <a href="c3ref/c_index_scan_unique.html">c3ref/c_index_scan_unique.html</a></li><li>SQLITE_INNOCUOUS - <a href="c3ref/c_deterministic.html#sqliteinnocuous">c3ref/c_deterministic.html#sqliteinnocuous</a></li><li>SQLITE_INSERT - <a href="c3ref/c_alter_table.html">c3ref/c_alter_table.html</a></li><li>sqlite_int64 - <a href="c3ref/int64.html">c3ref/int64.html</a></li><li>SQLITE_INTEGER - <a href="c3ref/c_blob.html">c3ref/c_blob.html</a></li><li>SQLITE_INTERNAL - <a href="rescode.html#internal">rescode.html#internal</a></li><li>SQLITE_INTERRUPT - <a href="rescode.html#interrupt">rescode.html#interrupt</a></li><li>SQLITE_INTROSPECTION_PRAGMAS - <a href="compile.html#introspection_pragmas">compile.html#introspection_pragmas</a></li><li>SQLITE_IOCAP_ATOMIC - <a href="c3ref/c_iocap_atomic.html">c3ref/c_iocap_atomic.html</a></li><li>SQLITE_IOCAP_ATOMIC1K - <a href="c3ref/c_iocap_atomic.html">c3ref/c_iocap_atomic.html</a></li><li>SQLITE_IOCAP_ATOMIC2K - <a href="c3ref/c_iocap_atomic.html">c3ref/c_iocap_atomic.html</a></li><li>SQLITE_IOCAP_ATOMIC4K - <a href="c3ref/c_iocap_atomic.html">c3ref/c_iocap_atomic.html</a></li><li>SQLITE_IOCAP_ATOMIC8K - <a href="c3ref/c_iocap_atomic.html">c3ref/c_iocap_atomic.html</a></li><li>SQLITE_IOCAP_ATOMIC16K - <a href="c3ref/c_iocap_atomic.html">c3ref/c_iocap_atomic.html</a></li><li>SQLITE_IOCAP_ATOMIC32K - <a href="c3ref/c_iocap_atomic.html">c3ref/c_iocap_atomic.html</a></li><li>SQLITE_IOCAP_ATOMIC64K - <a href="c3ref/c_iocap_atomic.html">c3ref/c_iocap_atomic.html</a></li><li>SQLITE_IOCAP_ATOMIC512 - <a href="c3ref/c_iocap_atomic.html">c3ref/c_iocap_atomic.html</a></li><li>SQLITE_IOCAP_BATCH_ATOMIC - <a href="c3ref/c_iocap_atomic.html">c3ref/c_iocap_atomic.html</a></li><li>SQLITE_IOCAP_IMMUTABLE - <a href="c3ref/c_iocap_atomic.html">c3ref/c_iocap_atomic.html</a></li><li>SQLITE_IOCAP_POWERSAFE_OVERWRITE - <a href="c3ref/c_iocap_atomic.html">c3ref/c_iocap_atomic.html</a></li><li>SQLITE_IOCAP_SAFE_APPEND - <a href="c3ref/c_iocap_atomic.html">c3ref/c_iocap_atomic.html</a></li><li>SQLITE_IOCAP_SEQUENTIAL - <a href="c3ref/c_iocap_atomic.html">c3ref/c_iocap_atomic.html</a></li><li>SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN - <a href="c3ref/c_iocap_atomic.html">c3ref/c_iocap_atomic.html</a></li><li>SQLITE_IOERR - <a href="rescode.html#ioerr">rescode.html#ioerr</a></li><li>SQLITE_IOERR_ACCESS - <a href="rescode.html#ioerr_access">rescode.html#ioerr_access</a></li><li>SQLITE_IOERR_AUTH - <a href="rescode.html#ioerr_auth">rescode.html#ioerr_auth</a></li><li>SQLITE_IOERR_BEGIN_ATOMIC - <a href="rescode.html#ioerr_begin_atomic">rescode.html#ioerr_begin_atomic</a></li><li>SQLITE_IOERR_BLOCKED - <a href="rescode.html#ioerr_blocked">rescode.html#ioerr_blocked</a></li><li>SQLITE_IOERR_CHECKRESERVEDLOCK - <a href="rescode.html#ioerr_checkreservedlock">rescode.html#ioerr_checkreservedlock</a></li><li>SQLITE_IOERR_CLOSE - <a href="rescode.html#ioerr_close">rescode.html#ioerr_close</a></li><li>SQLITE_IOERR_COMMIT_ATOMIC - <a href="rescode.html#ioerr_commit_atomic">rescode.html#ioerr_commit_atomic</a></li><li>SQLITE_IOERR_CONVPATH - <a href="rescode.html#ioerr_convpath">rescode.html#ioerr_convpath</a></li><li>SQLITE_IOERR_CORRUPTFS - <a href="rescode.html#ioerr_corruptfs">rescode.html#ioerr_corruptfs</a></li><li>SQLITE_IOERR_DATA - <a href="rescode.html#ioerr_data">rescode.html#ioerr_data</a></li><li>SQLITE_IOERR_DELETE - <a href="rescode.html#ioerr_delete">rescode.html#ioerr_delete</a></li><li>SQLITE_IOERR_DELETE_NOENT - <a href="rescode.html#ioerr_delete_noent">rescode.html#ioerr_delete_noent</a></li><li>SQLITE_IOERR_DIR_CLOSE - <a href="rescode.html#ioerr_dir_close">rescode.html#ioerr_dir_close</a></li><li>SQLITE_IOERR_DIR_FSYNC - <a href="rescode.html#ioerr_dir_fsync">rescode.html#ioerr_dir_fsync</a></li><li>SQLITE_IOERR_FSTAT - <a href="rescode.html#ioerr_fstat">rescode.html#ioerr_fstat</a></li><li>SQLITE_IOERR_FSYNC - <a href="rescode.html#ioerr_fsync">rescode.html#ioerr_fsync</a></li><li>SQLITE_IOERR_GETTEMPPATH - <a href="rescode.html#ioerr_gettemppath">rescode.html#ioerr_gettemppath</a></li><li>SQLITE_IOERR_IN_PAGE - <a href="c3ref/c_abort_rollback.html">c3ref/c_abort_rollback.html</a></li><li>SQLITE_IOERR_LOCK - <a href="rescode.html#ioerr_lock">rescode.html#ioerr_lock</a></li><li>SQLITE_IOERR_MMAP - <a href="rescode.html#ioerr_mmap">rescode.html#ioerr_mmap</a></li><li>SQLITE_IOERR_NOMEM - <a href="rescode.html#ioerr_nomem">rescode.html#ioerr_nomem</a></li><li>SQLITE_IOERR_RDLOCK - <a href="rescode.html#ioerr_rdlock">rescode.html#ioerr_rdlock</a></li><li>SQLITE_IOERR_READ - <a href="rescode.html#ioerr_read">rescode.html#ioerr_read</a></li><li>SQLITE_IOERR_ROLLBACK_ATOMIC - <a href="rescode.html#ioerr_rollback_atomic">rescode.html#ioerr_rollback_atomic</a></li><li>SQLITE_IOERR_SEEK - <a href="rescode.html#ioerr_seek">rescode.html#ioerr_seek</a></li><li>SQLITE_IOERR_SHMLOCK - <a href="rescode.html#ioerr_shmlock">rescode.html#ioerr_shmlock</a></li><li>SQLITE_IOERR_SHMMAP - <a href="rescode.html#ioerr_shmmap">rescode.html#ioerr_shmmap</a></li><li>SQLITE_IOERR_SHMOPEN - <a href="rescode.html#ioerr_shmopen">rescode.html#ioerr_shmopen</a></li><li>SQLITE_IOERR_SHMSIZE - <a href="rescode.html#ioerr_shmsize">rescode.html#ioerr_shmsize</a></li><li>SQLITE_IOERR_SHORT_READ - <a href="rescode.html#ioerr_short_read">rescode.html#ioerr_short_read</a></li><li>SQLITE_IOERR_TRUNCATE - <a href="rescode.html#ioerr_truncate">rescode.html#ioerr_truncate</a></li><li>SQLITE_IOERR_UNLOCK - <a href="rescode.html#ioerr_unlock">rescode.html#ioerr_unlock</a></li><li>SQLITE_IOERR_VNODE - <a href="rescode.html#ioerr_vnode">rescode.html#ioerr_vnode</a></li><li>SQLITE_IOERR_WRITE - <a href="rescode.html#ioerr_write">rescode.html#ioerr_write</a></li><li>SQLITE_JSON_MAX_DEPTH - <a href="compile.html#json_max_depth">compile.html#json_max_depth</a></li><li>SQLITE_LIKE_DOESNT_MATCH_BLOBS - <a href="compile.html#like_doesnt_match_blobs">compile.html#like_doesnt_match_blobs</a></li><li>SQLITE_LIMIT_ATTACHED - <a href="c3ref/c_limit_attached.html#sqlitelimitattached">c3ref/c_limit_attached.html#sqlitelimitattached</a></li><li>SQLITE_LIMIT_COLUMN - <a href="c3ref/c_limit_attached.html#sqlitelimitcolumn">c3ref/c_limit_attached.html#sqlitelimitcolumn</a></li><li>SQLITE_LIMIT_COMPOUND_SELECT - <a href="c3ref/c_limit_attached.html#sqlitelimitcompoundselect">c3ref/c_limit_attached.html#sqlitelimitcompoundselect</a></li><li>SQLITE_LIMIT_EXPR_DEPTH - <a href="c3ref/c_limit_attached.html#sqlitelimitexprdepth">c3ref/c_limit_attached.html#sqlitelimitexprdepth</a></li><li>SQLITE_LIMIT_FUNCTION_ARG - <a href="c3ref/c_limit_attached.html#sqlitelimitfunctionarg">c3ref/c_limit_attached.html#sqlitelimitfunctionarg</a></li><li>SQLITE_LIMIT_LENGTH - <a href="c3ref/c_limit_attached.html#sqlitelimitlength">c3ref/c_limit_attached.html#sqlitelimitlength</a></li><li>SQLITE_LIMIT_LIKE_PATTERN_LENGTH - <a href="c3ref/c_limit_attached.html#sqlitelimitlikepatternlength">c3ref/c_limit_attached.html#sqlitelimitlikepatternlength</a></li><li>SQLITE_LIMIT_SQL_LENGTH - <a href="c3ref/c_limit_attached.html#sqlitelimitsqllength">c3ref/c_limit_attached.html#sqlitelimitsqllength</a></li><li>SQLITE_LIMIT_TRIGGER_DEPTH - <a href="c3ref/c_limit_attached.html#sqlitelimittriggerdepth">c3ref/c_limit_attached.html#sqlitelimittriggerdepth</a></li><li>SQLITE_LIMIT_VARIABLE_NUMBER - <a href="c3ref/c_limit_attached.html#sqlitelimitvariablenumber">c3ref/c_limit_attached.html#sqlitelimitvariablenumber</a></li><li>SQLITE_LIMIT_VDBE_OP - <a href="c3ref/c_limit_attached.html#sqlitelimitvdbeop">c3ref/c_limit_attached.html#sqlitelimitvdbeop</a></li><li>SQLITE_LIMIT_WORKER_THREADS - <a href="c3ref/c_limit_attached.html#sqlitelimitworkerthreads">c3ref/c_limit_attached.html#sqlitelimitworkerthreads</a></li><li>SQLITE_LOCK_EXCLUSIVE - <a href="c3ref/c_lock_exclusive.html">c3ref/c_lock_exclusive.html</a></li><li>SQLITE_LOCK_NONE - <a href="c3ref/c_lock_exclusive.html">c3ref/c_lock_exclusive.html</a></li><li>SQLITE_LOCK_PENDING - <a href="c3ref/c_lock_exclusive.html">c3ref/c_lock_exclusive.html</a></li><li>SQLITE_LOCK_RESERVED - <a href="c3ref/c_lock_exclusive.html">c3ref/c_lock_exclusive.html</a></li><li>SQLITE_LOCK_SHARED - <a href="c3ref/c_lock_exclusive.html">c3ref/c_lock_exclusive.html</a></li><li>SQLITE_LOCKED - <a href="rescode.html#locked">rescode.html#locked</a></li><li>SQLITE_LOCKED_SHAREDCACHE - <a href="rescode.html#locked_sharedcache">rescode.html#locked_sharedcache</a></li><li>SQLITE_LOCKED_VTAB - <a href="rescode.html#locked_vtab">rescode.html#locked_vtab</a></li><li>sqlite_master table - <a href="schematab.html">schematab.html</a></li><li>SQLITE_MAX_ALLOCATION_SIZE - <a href="compile.html#max_allocation_size">compile.html#max_allocation_size</a></li><li>SQLITE_MAX_ATTACHED - <a href="limits.html#max_attached">limits.html#max_attached</a></li><li>SQLITE_MAX_COLUMN - <a href="limits.html#max_column">limits.html#max_column</a></li><li>SQLITE_MAX_COMPOUND_SELECT - <a href="limits.html#max_compound_select">limits.html#max_compound_select</a></li><li>SQLITE_MAX_EXPR_DEPTH - <a href="limits.html#max_expr_depth">limits.html#max_expr_depth</a></li><li>SQLITE_MAX_FUNCTION_ARG - <a href="limits.html#max_function_arg">limits.html#max_function_arg</a></li><li>SQLITE_MAX_LENGTH - <a href="limits.html#max_length">limits.html#max_length</a></li><li>SQLITE_MAX_LIKE_PATTERN_LENGTH - <a href="limits.html#max_like_pattern_length">limits.html#max_like_pattern_length</a></li><li>SQLITE_MAX_MEMORY - <a href="compile.html#max_memory">compile.html#max_memory</a></li><li>SQLITE_MAX_MMAP_SIZE - <a href="compile.html#max_mmap_size">compile.html#max_mmap_size</a></li><li>SQLITE_MAX_PAGE_COUNT - <a href="limits.html#max_page_count">limits.html#max_page_count</a></li><li>SQLITE_MAX_SCHEMA_RETRY - <a href="compile.html#max_schema_retry">compile.html#max_schema_retry</a></li><li>SQLITE_MAX_SQL_LENGTH - <a href="limits.html#max_sql_length">limits.html#max_sql_length</a></li><li>SQLITE_MAX_TRIGGER_DEPTH - <a href="limits.html#max_trigger_depth">limits.html#max_trigger_depth</a></li><li>SQLITE_MAX_VARIABLE_NUMBER - <a href="limits.html#max_variable_number">limits.html#max_variable_number</a></li><li>SQLITE_MAX_WORKER_THREADS - <a href="compile.html#max_worker_threads">compile.html#max_worker_threads</a></li><li>SQLITE_MEMDB_DEFAULT_MAXSIZE - <a href="compile.html#memdb_default_maxsize">compile.html#memdb_default_maxsize</a></li><li>SQLITE_MEMDEBUG - <a href="compile.html#memdebug">compile.html#memdebug</a></li><li>sqlite_memstat - <a href="memstat.html">memstat.html</a></li><li>SQLITE_MEMSTAT virtual table - <a href="memstat.html">memstat.html</a></li><li>SQLITE_MINIMUM_FILE_DESCRIPTOR - <a href="compile.html#minimum_file_descriptor">compile.html#minimum_file_descriptor</a></li><li>SQLITE_MISMATCH - <a href="rescode.html#mismatch">rescode.html#mismatch</a></li><li>SQLITE_MISUSE - <a href="rescode.html#misuse">rescode.html#misuse</a></li><li>SQLITE_MUTEX_FAST - <a href="c3ref/c_mutex_fast.html">c3ref/c_mutex_fast.html</a></li><li>SQLITE_MUTEX_RECURSIVE - <a href="c3ref/c_mutex_fast.html">c3ref/c_mutex_fast.html</a></li><li>SQLITE_MUTEX_STATIC_APP1 - <a href="c3ref/c_mutex_fast.html">c3ref/c_mutex_fast.html</a></li><li>SQLITE_MUTEX_STATIC_APP2 - <a href="c3ref/c_mutex_fast.html">c3ref/c_mutex_fast.html</a></li><li>SQLITE_MUTEX_STATIC_APP3 - <a href="c3ref/c_mutex_fast.html">c3ref/c_mutex_fast.html</a></li><li>SQLITE_MUTEX_STATIC_LRU - <a href="c3ref/c_mutex_fast.html">c3ref/c_mutex_fast.html</a></li><li>SQLITE_MUTEX_STATIC_LRU2 - <a href="c3ref/c_mutex_fast.html">c3ref/c_mutex_fast.html</a></li><li>SQLITE_MUTEX_STATIC_MAIN - <a href="c3ref/c_mutex_fast.html">c3ref/c_mutex_fast.html</a></li><li>SQLITE_MUTEX_STATIC_MEM - <a href="c3ref/c_mutex_fast.html">c3ref/c_mutex_fast.html</a></li><li>SQLITE_MUTEX_STATIC_MEM2 - <a href="c3ref/c_mutex_fast.html">c3ref/c_mutex_fast.html</a></li><li>SQLITE_MUTEX_STATIC_OPEN - <a href="c3ref/c_mutex_fast.html">c3ref/c_mutex_fast.html</a></li><li>SQLITE_MUTEX_STATIC_PMEM - <a href="c3ref/c_mutex_fast.html">c3ref/c_mutex_fast.html</a></li><li>SQLITE_MUTEX_STATIC_PRNG - <a href="c3ref/c_mutex_fast.html">c3ref/c_mutex_fast.html</a></li><li>SQLITE_MUTEX_STATIC_VFS1 - <a href="c3ref/c_mutex_fast.html">c3ref/c_mutex_fast.html</a></li><li>SQLITE_MUTEX_STATIC_VFS2 - <a href="c3ref/c_mutex_fast.html">c3ref/c_mutex_fast.html</a></li><li>SQLITE_MUTEX_STATIC_VFS3 - <a href="c3ref/c_mutex_fast.html">c3ref/c_mutex_fast.html</a></li><li>SQLITE_NOLFS - <a href="rescode.html#nolfs">rescode.html#nolfs</a></li><li>SQLITE_NOMEM - <a href="rescode.html#nomem">rescode.html#nomem</a></li><li>SQLITE_NOTADB - <a href="rescode.html#notadb">rescode.html#notadb</a></li><li>SQLITE_NOTFOUND - <a href="rescode.html#notfound">rescode.html#notfound</a></li><li>SQLITE_NOTICE - <a href="rescode.html#notice">rescode.html#notice</a></li><li>SQLITE_NOTICE_RBU - <a href="c3ref/c_abort_rollback.html">c3ref/c_abort_rollback.html</a></li><li>SQLITE_NOTICE_RECOVER_ROLLBACK - <a href="rescode.html#notice_recover_rollback">rescode.html#notice_recover_rollback</a></li><li>SQLITE_NOTICE_RECOVER_WAL - <a href="rescode.html#notice_recover_wal">rescode.html#notice_recover_wal</a></li><li>SQLITE_NULL - <a href="c3ref/c_blob.html">c3ref/c_blob.html</a></li><li>sqlite_offset - <a href="lang_corefunc.html#sqlite_offset">lang_corefunc.html#sqlite_offset</a></li><li>sqlite_offset SQL function - <a href="lang_corefunc.html#sqlite_offset">lang_corefunc.html#sqlite_offset</a></li><li>SQLITE_OK - <a href="rescode.html#ok">rescode.html#ok</a></li><li>SQLITE_OK_LOAD_PERMANENTLY - <a href="rescode.html#ok_load_permanently">rescode.html#ok_load_permanently</a></li><li>SQLITE_OK_SYMLINK - <a href="c3ref/c_abort_rollback.html">c3ref/c_abort_rollback.html</a></li><li>SQLITE_OMIT_ALTERTABLE - <a href="compile.html#omit_altertable">compile.html#omit_altertable</a></li><li>SQLITE_OMIT_ANALYZE - <a href="compile.html#omit_analyze">compile.html#omit_analyze</a></li><li>SQLITE_OMIT_ATTACH - <a href="compile.html#omit_attach">compile.html#omit_attach</a></li><li>SQLITE_OMIT_AUTHORIZATION - <a href="compile.html#omit_authorization">compile.html#omit_authorization</a></li><li>SQLITE_OMIT_AUTOINCREMENT - <a href="compile.html#omit_autoincrement">compile.html#omit_autoincrement</a></li><li>SQLITE_OMIT_AUTOINIT - <a href="compile.html#omit_autoinit">compile.html#omit_autoinit</a></li><li>SQLITE_OMIT_AUTOMATIC_INDEX - <a href="compile.html#omit_automatic_index">compile.html#omit_automatic_index</a></li><li>SQLITE_OMIT_AUTORESET - <a href="compile.html#omit_autoreset">compile.html#omit_autoreset</a></li><li>SQLITE_OMIT_AUTOVACUUM - <a href="compile.html#omit_autovacuum">compile.html#omit_autovacuum</a></li><li>SQLITE_OMIT_BETWEEN_OPTIMIZATION - <a href="compile.html#omit_between_optimization">compile.html#omit_between_optimization</a></li><li>SQLITE_OMIT_BLOB_LITERAL - <a href="compile.html#omit_blob_literal">compile.html#omit_blob_literal</a></li><li>SQLITE_OMIT_BTREECOUNT - <a href="compile.html#omit_btreecount">compile.html#omit_btreecount</a></li><li>SQLITE_OMIT_BUILTIN_TEST - <a href="compile.html#omit_builtin_test">compile.html#omit_builtin_test</a></li><li>SQLITE_OMIT_CASE_SENSITIVE_LIKE_PRAGMA - <a href="compile.html#omit_case_sensitive_like_pragma">compile.html#omit_case_sensitive_like_pragma</a></li><li>SQLITE_OMIT_CAST - <a href="compile.html#omit_cast">compile.html#omit_cast</a></li><li>SQLITE_OMIT_CHECK - <a href="compile.html#omit_check">compile.html#omit_check</a></li><li>SQLITE_OMIT_COMPILEOPTION_DIAGS - <a href="compile.html#omit_compileoption_diags">compile.html#omit_compileoption_diags</a></li><li>SQLITE_OMIT_COMPLETE - <a href="compile.html#omit_complete">compile.html#omit_complete</a></li><li>SQLITE_OMIT_COMPOUND_SELECT - <a href="compile.html#omit_compound_select">compile.html#omit_compound_select</a></li><li>SQLITE_OMIT_CTE - <a href="compile.html#omit_cte">compile.html#omit_cte</a></li><li>SQLITE_OMIT_DATETIME_FUNCS - <a href="compile.html#omit_datetime_funcs">compile.html#omit_datetime_funcs</a></li><li>SQLITE_OMIT_DECLTYPE - <a href="compile.html#omit_decltype">compile.html#omit_decltype</a></li><li>SQLITE_OMIT_DEPRECATED - <a href="compile.html#omit_deprecated">compile.html#omit_deprecated</a></li><li>SQLITE_OMIT_DESERIALIZE - <a href="compile.html#omit_deserialize">compile.html#omit_deserialize</a></li><li>SQLITE_OMIT_DISKIO - <a href="compile.html#omit_diskio">compile.html#omit_diskio</a></li><li>SQLITE_OMIT_EXPLAIN - <a href="compile.html#omit_explain">compile.html#omit_explain</a></li><li>SQLITE_OMIT_FLAG_PRAGMAS - <a href="compile.html#omit_flag_pragmas">compile.html#omit_flag_pragmas</a></li><li>SQLITE_OMIT_FLOATING_POINT - <a href="compile.html#omit_floating_point">compile.html#omit_floating_point</a></li><li>SQLITE_OMIT_FOREIGN_KEY - <a href="compile.html#omit_foreign_key">compile.html#omit_foreign_key</a></li><li>SQLITE_OMIT_GENERATED_COLUMNS - <a href="compile.html#omit_generated_columns">compile.html#omit_generated_columns</a></li><li>SQLITE_OMIT_GET_TABLE - <a href="compile.html#omit_get_table">compile.html#omit_get_table</a></li><li>SQLITE_OMIT_HEX_INTEGER - <a href="compile.html#omit_hex_integer">compile.html#omit_hex_integer</a></li><li>SQLITE_OMIT_INCRBLOB - <a href="compile.html#omit_incrblob">compile.html#omit_incrblob</a></li><li>SQLITE_OMIT_INTEGRITY_CHECK - <a href="compile.html#omit_integrity_check">compile.html#omit_integrity_check</a></li><li>SQLITE_OMIT_INTROSPECTION_PRAGMAS - <a href="compile.html#omit_introspection_pragmas">compile.html#omit_introspection_pragmas</a></li><li>SQLITE_OMIT_JSON - <a href="compile.html#omit_json">compile.html#omit_json</a></li><li>SQLITE_OMIT_LIKE_OPTIMIZATION - <a href="compile.html#omit_like_optimization">compile.html#omit_like_optimization</a></li><li>SQLITE_OMIT_LOAD_EXTENSION - <a href="compile.html#omit_load_extension">compile.html#omit_load_extension</a></li><li>SQLITE_OMIT_LOCALTIME - <a href="compile.html#omit_localtime">compile.html#omit_localtime</a></li><li>SQLITE_OMIT_LOOKASIDE - <a href="compile.html#omit_lookaside">compile.html#omit_lookaside</a></li><li>SQLITE_OMIT_MEMORYDB - <a href="compile.html#omit_memorydb">compile.html#omit_memorydb</a></li><li>SQLITE_OMIT_OR_OPTIMIZATION - <a href="compile.html#omit_or_optimization">compile.html#omit_or_optimization</a></li><li>SQLITE_OMIT_PAGER_PRAGMAS - <a href="compile.html#omit_pager_pragmas">compile.html#omit_pager_pragmas</a></li><li>SQLITE_OMIT_PRAGMA - <a href="compile.html#omit_pragma">compile.html#omit_pragma</a></li><li>SQLITE_OMIT_PROGRESS_CALLBACK - <a href="compile.html#omit_progress_callback">compile.html#omit_progress_callback</a></li><li>SQLITE_OMIT_QUICKBALANCE - <a href="compile.html#omit_quickbalance">compile.html#omit_quickbalance</a></li><li>SQLITE_OMIT_REINDEX - <a href="compile.html#omit_reindex">compile.html#omit_reindex</a></li><li>SQLITE_OMIT_SCHEMA_PRAGMAS - <a href="compile.html#omit_schema_pragmas">compile.html#omit_schema_pragmas</a></li><li>SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS - <a href="compile.html#omit_schema_version_pragmas">compile.html#omit_schema_version_pragmas</a></li><li>SQLITE_OMIT_SHARED_CACHE - <a href="compile.html#omit_shared_cache">compile.html#omit_shared_cache</a></li><li>SQLITE_OMIT_SUBQUERY - <a href="compile.html#omit_subquery">compile.html#omit_subquery</a></li><li>SQLITE_OMIT_TCL_VARIABLE - <a href="compile.html#omit_tcl_variable">compile.html#omit_tcl_variable</a></li><li>SQLITE_OMIT_TEMPDB - <a href="compile.html#omit_tempdb">compile.html#omit_tempdb</a></li><li>SQLITE_OMIT_TRACE - <a href="compile.html#omit_trace">compile.html#omit_trace</a></li><li>SQLITE_OMIT_TRIGGER - <a href="compile.html#omit_trigger">compile.html#omit_trigger</a></li><li>SQLITE_OMIT_TRUNCATE_OPTIMIZATION - <a href="compile.html#omit_truncate_optimization">compile.html#omit_truncate_optimization</a></li><li>SQLITE_OMIT_UTF16 - <a href="compile.html#omit_utf16">compile.html#omit_utf16</a></li><li>SQLITE_OMIT_VACUUM - <a href="compile.html#omit_vacuum">compile.html#omit_vacuum</a></li><li>SQLITE_OMIT_VIEW - <a href="compile.html#omit_view">compile.html#omit_view</a></li><li>SQLITE_OMIT_VIRTUALTABLE - <a href="compile.html#omit_virtualtable">compile.html#omit_virtualtable</a></li><li>SQLITE_OMIT_WAL - <a href="compile.html#omit_wal">compile.html#omit_wal</a></li><li>SQLITE_OMIT_WINDOWFUNC - <a href="compile.html#omit_windowfunc">compile.html#omit_windowfunc</a></li><li>SQLITE_OMIT_WSD - <a href="compile.html#omit_wsd">compile.html#omit_wsd</a></li><li>SQLITE_OMIT_XFER_OPT - <a href="compile.html#omit_xfer_opt">compile.html#omit_xfer_opt</a></li><li>SQLITE_OPEN_AUTOPROXY - <a href="c3ref/c_open_autoproxy.html">c3ref/c_open_autoproxy.html</a></li><li>SQLITE_OPEN_CREATE - <a href="c3ref/c_open_autoproxy.html">c3ref/c_open_autoproxy.html</a></li><li>SQLITE_OPEN_DELETEONCLOSE - <a href="c3ref/c_open_autoproxy.html">c3ref/c_open_autoproxy.html</a></li><li>SQLITE_OPEN_EXCLUSIVE - <a href="c3ref/c_open_autoproxy.html">c3ref/c_open_autoproxy.html</a></li><li>SQLITE_OPEN_EXRESCODE - <a href="c3ref/c_open_autoproxy.html">c3ref/c_open_autoproxy.html</a></li><li>SQLITE_OPEN_FULLMUTEX - <a href="c3ref/c_open_autoproxy.html">c3ref/c_open_autoproxy.html</a></li><li>SQLITE_OPEN_MAIN_DB - <a href="c3ref/c_open_autoproxy.html">c3ref/c_open_autoproxy.html</a></li><li>SQLITE_OPEN_MAIN_JOURNAL - <a href="c3ref/c_open_autoproxy.html">c3ref/c_open_autoproxy.html</a></li><li>SQLITE_OPEN_MEMORY - <a href="c3ref/c_open_autoproxy.html">c3ref/c_open_autoproxy.html</a></li><li>SQLITE_OPEN_NOFOLLOW - <a href="c3ref/c_open_autoproxy.html">c3ref/c_open_autoproxy.html</a></li><li>SQLITE_OPEN_NOMUTEX - <a href="c3ref/c_open_autoproxy.html">c3ref/c_open_autoproxy.html</a></li><li>SQLITE_OPEN_PRIVATECACHE - <a href="c3ref/c_open_autoproxy.html">c3ref/c_open_autoproxy.html</a></li><li>SQLITE_OPEN_READONLY - <a href="c3ref/c_open_autoproxy.html">c3ref/c_open_autoproxy.html</a></li><li>SQLITE_OPEN_READWRITE - <a href="c3ref/c_open_autoproxy.html">c3ref/c_open_autoproxy.html</a></li><li>SQLITE_OPEN_SHAREDCACHE - <a href="c3ref/c_open_autoproxy.html">c3ref/c_open_autoproxy.html</a></li><li>SQLITE_OPEN_SUBJOURNAL - <a href="c3ref/c_open_autoproxy.html">c3ref/c_open_autoproxy.html</a></li><li>SQLITE_OPEN_SUPER_JOURNAL - <a href="c3ref/c_open_autoproxy.html">c3ref/c_open_autoproxy.html</a></li><li>SQLITE_OPEN_TEMP_DB - <a href="c3ref/c_open_autoproxy.html">c3ref/c_open_autoproxy.html</a></li><li>SQLITE_OPEN_TEMP_JOURNAL - <a href="c3ref/c_open_autoproxy.html">c3ref/c_open_autoproxy.html</a></li><li>SQLITE_OPEN_TRANSIENT_DB - <a href="c3ref/c_open_autoproxy.html">c3ref/c_open_autoproxy.html</a></li><li>SQLITE_OPEN_URI - <a href="c3ref/c_open_autoproxy.html">c3ref/c_open_autoproxy.html</a></li><li>SQLITE_OPEN_WAL - <a href="c3ref/c_open_autoproxy.html">c3ref/c_open_autoproxy.html</a></li><li>SQLITE_OS_OTHER - <a href="compile.html#os_other">compile.html#os_other</a></li><li>SQLITE_PERM - <a href="rescode.html#perm">rescode.html#perm</a></li><li>SQLITE_POWERSAFE_OVERWRITE - <a href="compile.html#powersafe_overwrite">compile.html#powersafe_overwrite</a></li><li>SQLITE_PRAGMA - <a href="c3ref/c_alter_table.html">c3ref/c_alter_table.html</a></li><li>SQLITE_PREPARE_NO_VTAB - <a href="c3ref/c_prepare_normalize.html#sqlitepreparenovtab">c3ref/c_prepare_normalize.html#sqlitepreparenovtab</a></li><li>SQLITE_PREPARE_NORMALIZE - <a href="c3ref/c_prepare_normalize.html#sqlitepreparenormalize">c3ref/c_prepare_normalize.html#sqlitepreparenormalize</a></li><li>SQLITE_PREPARE_PERSISTENT - <a href="c3ref/c_prepare_normalize.html#sqlitepreparepersistent">c3ref/c_prepare_normalize.html#sqlitepreparepersistent</a></li><li>SQLITE_PRINTF_PRECISION_LIMIT - <a href="compile.html#printf_precision_limit">compile.html#printf_precision_limit</a></li><li>SQLITE_PROTOCOL - <a href="rescode.html#protocol">rescode.html#protocol</a></li><li>SQLITE_QUERY_PLANNER_LIMIT - <a href="compile.html#query_planner_limit">compile.html#query_planner_limit</a></li><li>SQLITE_QUERY_PLANNER_LIMIT_INCR - <a href="compile.html#query_planner_limit_incr">compile.html#query_planner_limit_incr</a></li><li>SQLITE_RANGE - <a href="rescode.html#range">rescode.html#range</a></li><li>SQLITE_READ - <a href="c3ref/c_alter_table.html">c3ref/c_alter_table.html</a></li><li>SQLITE_READONLY - <a href="rescode.html#readonly">rescode.html#readonly</a></li><li>SQLITE_READONLY_CANTINIT - <a href="rescode.html#readonly_cantinit">rescode.html#readonly_cantinit</a></li><li>SQLITE_READONLY_CANTLOCK - <a href="rescode.html#readonly_cantlock">rescode.html#readonly_cantlock</a></li><li>SQLITE_READONLY_DBMOVED - <a href="rescode.html#readonly_dbmoved">rescode.html#readonly_dbmoved</a></li><li>SQLITE_READONLY_DIRECTORY - <a href="rescode.html#readonly_directory">rescode.html#readonly_directory</a></li><li>SQLITE_READONLY_RECOVERY - <a href="rescode.html#readonly_recovery">rescode.html#readonly_recovery</a></li><li>SQLITE_READONLY_ROLLBACK - <a href="rescode.html#readonly_rollback">rescode.html#readonly_rollback</a></li><li>SQLITE_RECURSIVE - <a href="c3ref/c_alter_table.html">c3ref/c_alter_table.html</a></li><li>SQLITE_REINDEX - <a href="c3ref/c_alter_table.html">c3ref/c_alter_table.html</a></li><li>SQLITE_REPLACE - <a href="c3ref/c_fail.html">c3ref/c_fail.html</a></li><li>SQLITE_RESULT_SUBTYPE - <a href="c3ref/c_deterministic.html#sqliteresultsubtype">c3ref/c_deterministic.html#sqliteresultsubtype</a></li><li>SQLITE_REVERSE_UNORDERED_SELECTS - <a href="compile.html#reverse_unordered_selects">compile.html#reverse_unordered_selects</a></li><li>SQLITE_ROLLBACK - <a href="c3ref/c_fail.html">c3ref/c_fail.html</a></li><li>SQLITE_ROW - <a href="rescode.html#row">rescode.html#row</a></li><li>SQLITE_RTREE_INT_ONLY - <a href="compile.html#rtree_int_only">compile.html#rtree_int_only</a></li><li>SQLITE_SAVEPOINT - <a href="c3ref/c_alter_table.html">c3ref/c_alter_table.html</a></li><li>SQLITE_SCANSTAT_COMPLEX - <a href="c3ref/c_scanstat_complex.html">c3ref/c_scanstat_complex.html</a></li><li>SQLITE_SCANSTAT_EST - <a href="c3ref/c_scanstat_est.html#sqlitescanstatest">c3ref/c_scanstat_est.html#sqlitescanstatest</a></li><li>SQLITE_SCANSTAT_EXPLAIN - <a href="c3ref/c_scanstat_est.html#sqlitescanstatexplain">c3ref/c_scanstat_est.html#sqlitescanstatexplain</a></li><li>SQLITE_SCANSTAT_NAME - <a href="c3ref/c_scanstat_est.html#sqlitescanstatname">c3ref/c_scanstat_est.html#sqlitescanstatname</a></li><li>SQLITE_SCANSTAT_NCYCLE - <a href="c3ref/c_scanstat_est.html#sqlitescanstatncycle">c3ref/c_scanstat_est.html#sqlitescanstatncycle</a></li><li>SQLITE_SCANSTAT_NLOOP - <a href="c3ref/c_scanstat_est.html#sqlitescanstatnloop">c3ref/c_scanstat_est.html#sqlitescanstatnloop</a></li><li>SQLITE_SCANSTAT_NVISIT - <a href="c3ref/c_scanstat_est.html#sqlitescanstatnvisit">c3ref/c_scanstat_est.html#sqlitescanstatnvisit</a></li><li>SQLITE_SCANSTAT_PARENTID - <a href="c3ref/c_scanstat_est.html#sqlitescanstatparentid">c3ref/c_scanstat_est.html#sqlitescanstatparentid</a></li><li>SQLITE_SCANSTAT_SELECTID - <a href="c3ref/c_scanstat_est.html#sqlitescanstatselectid">c3ref/c_scanstat_est.html#sqlitescanstatselectid</a></li><li>SQLITE_SCHEMA - <a href="rescode.html#schema">rescode.html#schema</a></li><li>sqlite_schema - <a href="schematab.html">schematab.html</a></li><li>sqlite_schema table - <a href="schematab.html">schematab.html</a></li><li>SQLITE_SECURE_DELETE - <a href="compile.html#secure_delete">compile.html#secure_delete</a></li><li>SQLITE_SELECT - <a href="c3ref/c_alter_table.html">c3ref/c_alter_table.html</a></li><li>sqlite_sequence - <a href="fileformat2.html#seqtab">fileformat2.html#seqtab</a></li><li>SQLITE_SERIALIZE_NOCOPY - <a href="c3ref/c_serialize_nocopy.html">c3ref/c_serialize_nocopy.html</a></li><li>SQLITE_SESSION_CONFIG_STRMSIZE - <a href="session/c_session_config_strmsize.html">session/c_session_config_strmsize.html</a></li><li>SQLITE_SESSION_OBJCONFIG_ROWID - <a href="session/c_session_objconfig_rowid.html">session/c_session_objconfig_rowid.html</a></li><li>SQLITE_SESSION_OBJCONFIG_SIZE - <a href="session/c_session_objconfig_rowid.html">session/c_session_objconfig_rowid.html</a></li><li>SQLITE_SHM_EXCLUSIVE - <a href="c3ref/c_shm_exclusive.html">c3ref/c_shm_exclusive.html</a></li><li>SQLITE_SHM_LOCK - <a href="c3ref/c_shm_exclusive.html">c3ref/c_shm_exclusive.html</a></li><li>SQLITE_SHM_NLOCK - <a href="c3ref/c_shm_nlock.html">c3ref/c_shm_nlock.html</a></li><li>SQLITE_SHM_SHARED - <a href="c3ref/c_shm_exclusive.html">c3ref/c_shm_exclusive.html</a></li><li>SQLITE_SHM_UNLOCK - <a href="c3ref/c_shm_exclusive.html">c3ref/c_shm_exclusive.html</a></li><li>SQLITE_SORTER_PMASZ - <a href="compile.html#sorter_pmasz">compile.html#sorter_pmasz</a></li><li>SQLITE_SOUNDEX - <a href="compile.html#soundex">compile.html#soundex</a></li><li>SQLITE_SOURCE_ID - <a href="c3ref/c_source_id.html">c3ref/c_source_id.html</a></li><li>sqlite_source_id - <a href="lang_corefunc.html#sqlite_source_id">lang_corefunc.html#sqlite_source_id</a></li><li>sqlite_source_id SQL function - <a href="lang_corefunc.html#sqlite_source_id">lang_corefunc.html#sqlite_source_id</a></li><li>SQLITE_STAT1 - <a href="fileformat2.html#stat1tab">fileformat2.html#stat1tab</a></li><li>sqlite_stat1 - <a href="fileformat2.html#stat1tab">fileformat2.html#stat1tab</a></li><li>sqlite_stat2 - <a href="fileformat2.html#stat2tab">fileformat2.html#stat2tab</a></li><li>SQLITE_STAT3 - <a href="fileformat2.html#stat3tab">fileformat2.html#stat3tab</a></li><li>sqlite_stat3 - <a href="fileformat2.html#stat3tab">fileformat2.html#stat3tab</a></li><li>SQLITE_STAT4 - <a href="fileformat2.html#stat4tab">fileformat2.html#stat4tab</a></li><li>sqlite_stat4 - <a href="fileformat2.html#stat4tab">fileformat2.html#stat4tab</a></li><li>SQLITE_STATIC - <a href="c3ref/c_static.html">c3ref/c_static.html</a></li><li>SQLITE_STATUS_MALLOC_COUNT - <a href="c3ref/c_status_malloc_count.html#sqlitestatusmalloccount">c3ref/c_status_malloc_count.html#sqlitestatusmalloccount</a></li><li>SQLITE_STATUS_MALLOC_SIZE - <a href="c3ref/c_status_malloc_count.html#sqlitestatusmallocsize">c3ref/c_status_malloc_count.html#sqlitestatusmallocsize</a></li><li>SQLITE_STATUS_MEMORY_USED - <a href="c3ref/c_status_malloc_count.html#sqlitestatusmemoryused">c3ref/c_status_malloc_count.html#sqlitestatusmemoryused</a></li><li>SQLITE_STATUS_PAGECACHE_OVERFLOW - <a href="c3ref/c_status_malloc_count.html#sqlitestatuspagecacheoverflow">c3ref/c_status_malloc_count.html#sqlitestatuspagecacheoverflow</a></li><li>SQLITE_STATUS_PAGECACHE_SIZE - <a href="c3ref/c_status_malloc_count.html#sqlitestatuspagecachesize">c3ref/c_status_malloc_count.html#sqlitestatuspagecachesize</a></li><li>SQLITE_STATUS_PAGECACHE_USED - <a href="c3ref/c_status_malloc_count.html#sqlitestatuspagecacheused">c3ref/c_status_malloc_count.html#sqlitestatuspagecacheused</a></li><li>SQLITE_STATUS_PARSER_STACK - <a href="c3ref/c_status_malloc_count.html#sqlitestatusparserstack">c3ref/c_status_malloc_count.html#sqlitestatusparserstack</a></li><li>SQLITE_STATUS_SCRATCH_OVERFLOW - <a href="c3ref/c_status_malloc_count.html#sqlitestatusscratchoverflow">c3ref/c_status_malloc_count.html#sqlitestatusscratchoverflow</a></li><li>SQLITE_STATUS_SCRATCH_SIZE - <a href="c3ref/c_status_malloc_count.html#sqlitestatusscratchsize">c3ref/c_status_malloc_count.html#sqlitestatusscratchsize</a></li><li>SQLITE_STATUS_SCRATCH_USED - <a href="c3ref/c_status_malloc_count.html#sqlitestatusscratchused">c3ref/c_status_malloc_count.html#sqlitestatusscratchused</a></li><li>SQLITE_STDCALL - <a href="compile.html#stdcall">compile.html#stdcall</a></li><li>sqlite_stmt - <a href="stmt.html">stmt.html</a></li><li>SQLITE_STMT virtual table - <a href="stmt.html">stmt.html</a></li><li>SQLITE_STMTJRNL_SPILL - <a href="compile.html#stmtjrnl_spill">compile.html#stmtjrnl_spill</a></li><li>SQLITE_STMTSTATUS counter - <a href="c3ref/c_stmtstatus_counter.html">c3ref/c_stmtstatus_counter.html</a></li><li>SQLITE_STMTSTATUS counters - <a href="c3ref/c_stmtstatus_counter.html">c3ref/c_stmtstatus_counter.html</a></li><li>SQLITE_STMTSTATUS_AUTOINDEX - <a href="c3ref/c_stmtstatus_counter.html#sqlitestmtstatusautoindex">c3ref/c_stmtstatus_counter.html#sqlitestmtstatusautoindex</a></li><li>SQLITE_STMTSTATUS_FILTER HIT - <a href="c3ref/c_stmtstatus_counter.html#sqlitestmtstatusfilterhit">c3ref/c_stmtstatus_counter.html#sqlitestmtstatusfilterhit</a></li><li>SQLITE_STMTSTATUS_FILTER_HIT - <a href="c3ref/c_stmtstatus_counter.html">c3ref/c_stmtstatus_counter.html</a></li><li>SQLITE_STMTSTATUS_FILTER_MISS - <a href="c3ref/c_stmtstatus_counter.html#sqlitestmtstatusfiltermiss">c3ref/c_stmtstatus_counter.html#sqlitestmtstatusfiltermiss</a></li><li>SQLITE_STMTSTATUS_FULLSCAN_STEP - <a href="c3ref/c_stmtstatus_counter.html#sqlitestmtstatusfullscanstep">c3ref/c_stmtstatus_counter.html#sqlitestmtstatusfullscanstep</a></li><li>SQLITE_STMTSTATUS_MEMUSED - <a href="c3ref/c_stmtstatus_counter.html#sqlitestmtstatusmemused">c3ref/c_stmtstatus_counter.html#sqlitestmtstatusmemused</a></li><li>SQLITE_STMTSTATUS_REPREPARE - <a href="c3ref/c_stmtstatus_counter.html#sqlitestmtstatusreprepare">c3ref/c_stmtstatus_counter.html#sqlitestmtstatusreprepare</a></li><li>SQLITE_STMTSTATUS_RUN - <a href="c3ref/c_stmtstatus_counter.html#sqlitestmtstatusrun">c3ref/c_stmtstatus_counter.html#sqlitestmtstatusrun</a></li><li>SQLITE_STMTSTATUS_SORT - <a href="c3ref/c_stmtstatus_counter.html#sqlitestmtstatussort">c3ref/c_stmtstatus_counter.html#sqlitestmtstatussort</a></li><li>SQLITE_STMTSTATUS_VM_STEP - <a href="c3ref/c_stmtstatus_counter.html#sqlitestmtstatusvmstep">c3ref/c_stmtstatus_counter.html#sqlitestmtstatusvmstep</a></li><li>SQLITE_STRICT_SUBTYPE - <a href="compile.html#strict_subtype">compile.html#strict_subtype</a></li><li>SQLITE_SUBTYPE - <a href="c3ref/c_deterministic.html#sqlitesubtype">c3ref/c_deterministic.html#sqlitesubtype</a></li><li>SQLITE_SYNC_DATAONLY - <a href="c3ref/c_sync_dataonly.html">c3ref/c_sync_dataonly.html</a></li><li>SQLITE_SYNC_FULL - <a href="c3ref/c_sync_dataonly.html">c3ref/c_sync_dataonly.html</a></li><li>SQLITE_SYNC_NORMAL - <a href="c3ref/c_sync_dataonly.html">c3ref/c_sync_dataonly.html</a></li><li>SQLITE_SYSAPI - <a href="compile.html#sysapi">compile.html#sysapi</a></li><li>SQLITE_TCLAPI - <a href="compile.html#tclapi">compile.html#tclapi</a></li><li>sqlite_temp_schema - <a href="schematab.html">schematab.html</a></li><li>SQLITE_TEMP_STORE - <a href="compile.html#temp_store">compile.html#temp_store</a></li><li>SQLITE_TESTCTRL_ALWAYS - <a href="c3ref/c_testctrl_always.html">c3ref/c_testctrl_always.html</a></li><li>SQLITE_TESTCTRL_ASSERT - <a href="c3ref/c_testctrl_always.html">c3ref/c_testctrl_always.html</a></li><li>SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS - <a href="c3ref/c_testctrl_always.html">c3ref/c_testctrl_always.html</a></li><li>SQLITE_TESTCTRL_BITVEC_TEST - <a href="c3ref/c_testctrl_always.html">c3ref/c_testctrl_always.html</a></li><li>SQLITE_TESTCTRL_BYTEORDER - <a href="c3ref/c_testctrl_always.html">c3ref/c_testctrl_always.html</a></li><li>SQLITE_TESTCTRL_EXPLAIN_STMT - <a href="c3ref/c_testctrl_always.html">c3ref/c_testctrl_always.html</a></li><li>SQLITE_TESTCTRL_EXTRA_SCHEMA_CHECKS - <a href="c3ref/c_testctrl_always.html">c3ref/c_testctrl_always.html</a></li><li>SQLITE_TESTCTRL_FAULT_INSTALL - <a href="c3ref/c_testctrl_always.html">c3ref/c_testctrl_always.html</a></li><li>SQLITE_TESTCTRL_FIRST - <a href="c3ref/c_testctrl_always.html">c3ref/c_testctrl_always.html</a></li><li>SQLITE_TESTCTRL_FK_NO_ACTION - <a href="c3ref/c_testctrl_always.html">c3ref/c_testctrl_always.html</a></li><li>SQLITE_TESTCTRL_IMPOSTER - <a href="c3ref/c_testctrl_always.html">c3ref/c_testctrl_always.html</a></li><li>SQLITE_TESTCTRL_INTERNAL_FUNCTIONS - <a href="c3ref/c_testctrl_always.html">c3ref/c_testctrl_always.html</a></li><li>SQLITE_TESTCTRL_ISINIT - <a href="c3ref/c_testctrl_always.html">c3ref/c_testctrl_always.html</a></li><li>SQLITE_TESTCTRL_ISKEYWORD - <a href="c3ref/c_testctrl_always.html">c3ref/c_testctrl_always.html</a></li><li>SQLITE_TESTCTRL_JSON_SELFCHECK - <a href="c3ref/c_testctrl_always.html">c3ref/c_testctrl_always.html</a></li><li>SQLITE_TESTCTRL_LAST - <a href="c3ref/c_testctrl_always.html">c3ref/c_testctrl_always.html</a></li><li>SQLITE_TESTCTRL_LOCALTIME_FAULT - <a href="c3ref/c_testctrl_always.html">c3ref/c_testctrl_always.html</a></li><li>SQLITE_TESTCTRL_LOGEST - <a href="c3ref/c_testctrl_always.html">c3ref/c_testctrl_always.html</a></li><li>SQLITE_TESTCTRL_NEVER_CORRUPT - <a href="c3ref/c_testctrl_always.html">c3ref/c_testctrl_always.html</a></li><li>SQLITE_TESTCTRL_ONCE_RESET_THRESHOLD - <a href="c3ref/c_testctrl_always.html">c3ref/c_testctrl_always.html</a></li><li>SQLITE_TESTCTRL_OPTIMIZATIONS - <a href="c3ref/c_testctrl_always.html">c3ref/c_testctrl_always.html</a></li><li>SQLITE_TESTCTRL_PARSER_COVERAGE - <a href="c3ref/c_testctrl_always.html">c3ref/c_testctrl_always.html</a></li><li>SQLITE_TESTCTRL_PENDING_BYTE - <a href="c3ref/c_testctrl_always.html">c3ref/c_testctrl_always.html</a></li><li>SQLITE_TESTCTRL_PRNG_RESET - <a href="c3ref/c_testctrl_always.html">c3ref/c_testctrl_always.html</a></li><li>SQLITE_TESTCTRL_PRNG_RESTORE - <a href="c3ref/c_testctrl_always.html">c3ref/c_testctrl_always.html</a></li><li>SQLITE_TESTCTRL_PRNG_SAVE - <a href="c3ref/c_testctrl_always.html">c3ref/c_testctrl_always.html</a></li><li>SQLITE_TESTCTRL_PRNG_SEED - <a href="c3ref/c_testctrl_always.html">c3ref/c_testctrl_always.html</a></li><li>SQLITE_TESTCTRL_RESERVE - <a href="c3ref/c_testctrl_always.html">c3ref/c_testctrl_always.html</a></li><li>SQLITE_TESTCTRL_RESULT_INTREAL - <a href="c3ref/c_testctrl_always.html">c3ref/c_testctrl_always.html</a></li><li>SQLITE_TESTCTRL_SCRATCHMALLOC - <a href="c3ref/c_testctrl_always.html">c3ref/c_testctrl_always.html</a></li><li>SQLITE_TESTCTRL_SEEK_COUNT - <a href="c3ref/c_testctrl_always.html">c3ref/c_testctrl_always.html</a></li><li>SQLITE_TESTCTRL_SORTER_MMAP - <a href="c3ref/c_testctrl_always.html">c3ref/c_testctrl_always.html</a></li><li>SQLITE_TESTCTRL_TRACEFLAGS - <a href="c3ref/c_testctrl_always.html">c3ref/c_testctrl_always.html</a></li><li>SQLITE_TESTCTRL_TUNE - <a href="c3ref/c_testctrl_always.html">c3ref/c_testctrl_always.html</a></li><li>SQLITE_TESTCTRL_USELONGDOUBLE - <a href="c3ref/c_testctrl_always.html">c3ref/c_testctrl_always.html</a></li><li>SQLITE_TESTCTRL_VDBE_COVERAGE - <a href="c3ref/c_testctrl_always.html">c3ref/c_testctrl_always.html</a></li><li>SQLITE_TEXT - <a href="c3ref/c_blob.html">c3ref/c_blob.html</a></li><li>SQLITE_THREADSAFE - <a href="compile.html#threadsafe">compile.html#threadsafe</a></li><li>SQLITE_TOOBIG - <a href="rescode.html#toobig">rescode.html#toobig</a></li><li>SQLITE_TRACE - <a href="c3ref/c_trace.html">c3ref/c_trace.html</a></li><li>SQLITE_TRACE_CLOSE - <a href="c3ref/c_trace.html#sqlitetraceclose">c3ref/c_trace.html#sqlitetraceclose</a></li><li>SQLITE_TRACE_PROFILE - <a href="c3ref/c_trace.html#sqlitetraceprofile">c3ref/c_trace.html#sqlitetraceprofile</a></li><li>SQLITE_TRACE_ROW - <a href="c3ref/c_trace.html#sqlitetracerow">c3ref/c_trace.html#sqlitetracerow</a></li><li>SQLITE_TRACE_SIZE_LIMIT - <a href="compile.html#trace_size_limit">compile.html#trace_size_limit</a></li><li>SQLITE_TRACE_STMT - <a href="c3ref/c_trace.html#sqlitetracestmt">c3ref/c_trace.html#sqlitetracestmt</a></li><li>SQLITE_TRANSACTION - <a href="c3ref/c_alter_table.html">c3ref/c_alter_table.html</a></li><li>SQLITE_TRANSIENT - <a href="c3ref/c_static.html">c3ref/c_static.html</a></li><li>SQLITE_TRUSTED_SCHEMA - <a href="compile.html#trusted_schema">compile.html#trusted_schema</a></li><li>SQLITE_TXN_NONE - <a href="c3ref/c_txn_none.html#sqlitetxnnone">c3ref/c_txn_none.html#sqlitetxnnone</a></li><li>SQLITE_TXN_READ - <a href="c3ref/c_txn_none.html#sqlitetxnread">c3ref/c_txn_none.html#sqlitetxnread</a></li><li>SQLITE_TXN_WRITE - <a href="c3ref/c_txn_none.html#sqlitetxnwrite">c3ref/c_txn_none.html#sqlitetxnwrite</a></li><li>sqlite_uint64 - <a href="c3ref/int64.html">c3ref/int64.html</a></li><li>SQLITE_UNTESTABLE - <a href="compile.html#untestable">compile.html#untestable</a></li><li>SQLITE_UPDATE - <a href="c3ref/c_alter_table.html">c3ref/c_alter_table.html</a></li><li>SQLITE_USE_ALLOCA - <a href="compile.html#use_alloca">compile.html#use_alloca</a></li><li>SQLITE_USE_FCNTL_TRACE - <a href="compile.html#use_fcntl_trace">compile.html#use_fcntl_trace</a></li><li>SQLITE_USE_SEH - <a href="compile.html#use_seh">compile.html#use_seh</a></li><li>SQLITE_USE_URI - <a href="compile.html#use_uri">compile.html#use_uri</a></li><li>SQLITE_UTF8 - <a href="c3ref/c_any.html">c3ref/c_any.html</a></li><li>SQLITE_UTF16 - <a href="c3ref/c_any.html">c3ref/c_any.html</a></li><li>SQLITE_UTF16_ALIGNED - <a href="c3ref/c_any.html">c3ref/c_any.html</a></li><li>SQLITE_UTF16BE - <a href="c3ref/c_any.html">c3ref/c_any.html</a></li><li>SQLITE_UTF16LE - <a href="c3ref/c_any.html">c3ref/c_any.html</a></li><li>SQLITE_VERSION - <a href="c3ref/c_source_id.html">c3ref/c_source_id.html</a></li><li>sqlite_version - <a href="lang_corefunc.html#sqlite_version">lang_corefunc.html#sqlite_version</a></li><li>sqlite_version SQL function - <a href="lang_corefunc.html#sqlite_version">lang_corefunc.html#sqlite_version</a></li><li>SQLITE_VERSION_NUMBER - <a href="c3ref/c_source_id.html">c3ref/c_source_id.html</a></li><li>SQLITE_VTAB_CONSTRAINT_SUPPORT - <a href="c3ref/c_vtab_constraint_support.html#sqlitevtabconstraintsupport">c3ref/c_vtab_constraint_support.html#sqlitevtabconstraintsupport</a></li><li>SQLITE_VTAB_DIRECTONLY - <a href="c3ref/c_vtab_constraint_support.html#sqlitevtabdirectonly">c3ref/c_vtab_constraint_support.html#sqlitevtabdirectonly</a></li><li>SQLITE_VTAB_INNOCUOUS - <a href="c3ref/c_vtab_constraint_support.html#sqlitevtabinnocuous">c3ref/c_vtab_constraint_support.html#sqlitevtabinnocuous</a></li><li>SQLITE_VTAB_USES_ALL_SCHEMAS - <a href="c3ref/c_vtab_constraint_support.html#sqlitevtabusesallschemas">c3ref/c_vtab_constraint_support.html#sqlitevtabusesallschemas</a></li><li>SQLITE_WARNING - <a href="rescode.html#warning">rescode.html#warning</a></li><li>SQLITE_WARNING_AUTOINDEX - <a href="rescode.html#warning_autoindex">rescode.html#warning_autoindex</a></li><li>SQLITE_WIN32_DATA_DIRECTORY_TYPE - <a href="c3ref/c_win32_data_directory_type.html">c3ref/c_win32_data_directory_type.html</a></li><li>SQLITE_WIN32_HEAP_CREATE - <a href="compile.html#win32_heap_create">compile.html#win32_heap_create</a></li><li>SQLITE_WIN32_MALLOC - <a href="compile.html#win32_malloc">compile.html#win32_malloc</a></li><li>SQLITE_WIN32_MALLOC_VALIDATE - <a href="compile.html#win32_malloc_validate">compile.html#win32_malloc_validate</a></li><li>SQLITE_WIN32_TEMP_DIRECTORY_TYPE - <a href="c3ref/c_win32_data_directory_type.html">c3ref/c_win32_data_directory_type.html</a></li><li>SQLITE_ZERO_MALLOC - <a href="compile.html#zero_malloc">compile.html#zero_malloc</a></li><li>sqrt - <a href="lang_mathfunc.html#sqrt">lang_mathfunc.html#sqrt</a></li><li>sqrt SQL function - <a href="lang_mathfunc.html#sqrt">lang_mathfunc.html#sqrt</a></li><li>stale file descriptor - <a href="howtocorrupt.html#stalefd">howtocorrupt.html#stalefd</a></li><li>standard query parameters - <a href="uri.html#coreqp">uri.html#coreqp</a></li><li>statement journal - <a href="tempfiles.html#stmtjrnl">tempfiles.html#stmtjrnl</a></li><li>Statement journals - <a href="tempfiles.html#stmtjrnl">tempfiles.html#stmtjrnl</a></li><li>statement journals - <a href="tempfiles.html#stmtjrnl">tempfiles.html#stmtjrnl</a></li><li>statically linked extensions - <a href="loadext.html#statext">loadext.html#statext</a></li><li>stats - <a href="pragma.html#pragma_stats">pragma.html#pragma_stats</a></li><li>stats pragma - <a href="pragma.html#pragma_stats">pragma.html#pragma_stats</a></li><li>status method - <a href="tclsqlite.html#status">tclsqlite.html#status</a></li><li>status parameters - <a href="c3ref/c_status_malloc_count.html">c3ref/c_status_malloc_count.html</a></li><li>storage class - <a href="datatype3.html#storageclasses">datatype3.html#storageclasses</a></li><li>strategies - <a href="queryplanner.html#searching">queryplanner.html#searching</a></li><li>strftime - <a href="lang_datefunc.html#strftm">lang_datefunc.html#strftm</a></li><li>strftime SQL function - <a href="lang_datefunc.html#strftm">lang_datefunc.html#strftm</a></li><li>STRICT - <a href="stricttables.html">stricttables.html</a></li><li>STRICT table - <a href="stricttables.html">stricttables.html</a></li><li>STRICT tables - <a href="stricttables.html">stricttables.html</a></li><li>strict type checking - <a href="stricttables.html">stricttables.html</a></li><li>string_agg - <a href="lang_aggfunc.html#group_concat">lang_aggfunc.html#group_concat</a></li><li>string_agg aggregate function - <a href="lang_aggfunc.html#group_concat">lang_aggfunc.html#group_concat</a></li><li>subprograms - <a href="opcode.html#subprog">opcode.html#subprog</a></li><li>Subqueries - <a href="lang_expr.html#subq">lang_expr.html#subq</a></li><li>subquery co-routines - <a href="optoverview.html#coroutines">optoverview.html#coroutines</a></li><li>subsec modifier - <a href="lang_datefunc.html#subsec">lang_datefunc.html#subsec</a></li><li>subsecond modifier - <a href="lang_datefunc.html#subsec">lang_datefunc.html#subsec</a></li><li>substr - <a href="lang_corefunc.html#substr">lang_corefunc.html#substr</a></li><li>substr SQL function - <a href="lang_corefunc.html#substr">lang_corefunc.html#substr</a></li><li>sum - <a href="lang_aggfunc.html#sumunc">lang_aggfunc.html#sumunc</a></li><li>sum aggregate function - <a href="lang_aggfunc.html#sumunc">lang_aggfunc.html#sumunc</a></li><li>sumFunc - <a href="lang_aggfunc.html#sumunc">lang_aggfunc.html#sumunc</a></li><li>super-journal - <a href="tempfiles.html#superjrnl">tempfiles.html#superjrnl</a></li><li>swarmvtab - <a href="swarmvtab.html#overview">swarmvtab.html#overview</a></li><li>swarmvtab context - <a href="swarmvtab.html#component_table_context_values">swarmvtab.html#component_table_context_values</a></li><li>synchronous - <a href="pragma.html#pragma_synchronous">pragma.html#pragma_synchronous</a></li><li>synchronous pragma - <a href="pragma.html#pragma_synchronous">pragma.html#pragma_synchronous</a></li><li>syntax diagrams - <a href="syntaxdiagrams.html">syntaxdiagrams.html</a></li><li>table b-tree - <a href="fileformat2.html#btypes">fileformat2.html#btypes</a></li><li>table data format - <a href="fileformat2.html##sqltab">fileformat2.html##sqltab</a></li><li>table-constraint - <a href="syntax/table-constraint.html">syntax/table-constraint.html</a></li><li>table-constraint syntax diagram - <a href="syntax/table-constraint.html">syntax/table-constraint.html</a></li><li>table-options - <a href="syntax/table-options.html">syntax/table-options.html</a></li><li>table-options syntax diagram - <a href="syntax/table-options.html">syntax/table-options.html</a></li><li>table-or-subquery - <a href="syntax/table-or-subquery.html">syntax/table-or-subquery.html</a></li><li>table-or-subquery syntax diagram - <a href="syntax/table-or-subquery.html">syntax/table-or-subquery.html</a></li><li>table-valued function - <a href="vtab.html#tabfunc2">vtab.html#tabfunc2</a></li><li>table-valued functions - <a href="vtab.html#tabfunc2">vtab.html#tabfunc2</a></li><li>table-valued functions in the FROM clause - <a href="lang_select.html#tabfunc1">lang_select.html#tabfunc1</a></li><li>table_info - <a href="pragma.html#pragma_table_info">pragma.html#pragma_table_info</a></li><li>table_info pragma - <a href="pragma.html#pragma_table_info">pragma.html#pragma_table_info</a></li><li>table_list - <a href="pragma.html#pragma_table_list">pragma.html#pragma_table_list</a></li><li>table_list pragma - <a href="pragma.html#pragma_table_list">pragma.html#pragma_table_list</a></li><li>table_xinfo - <a href="pragma.html#pragma_table_xinfo">pragma.html#pragma_table_xinfo</a></li><li>table_xinfo pragma - <a href="pragma.html#pragma_table_xinfo">pragma.html#pragma_table_xinfo</a></li><li>tables_used virtual table - <a href="bytecodevtab.html">bytecodevtab.html</a></li><li>tan - <a href="lang_mathfunc.html#tan">lang_mathfunc.html#tan</a></li><li>tan SQL function - <a href="lang_mathfunc.html#tan">lang_mathfunc.html#tan</a></li><li>tanh - <a href="lang_mathfunc.html#tanh">lang_mathfunc.html#tanh</a></li><li>tanh SQL function - <a href="lang_mathfunc.html#tanh">lang_mathfunc.html#tanh</a></li><li>Tcl extension - <a href="tclsqlite.html">tclsqlite.html</a></li><li>TCL Interface - <a href="tclsqlite.html">tclsqlite.html</a></li><li>TCL interface authorizer method - <a href="tclsqlite.html#authorizer">tclsqlite.html#authorizer</a></li><li>TCL interface backup method - <a href="tclsqlite.html#backup">tclsqlite.html#backup</a></li><li>TCL interface bind_fallback method - <a href="tclsqlite.html#bind_fallback">tclsqlite.html#bind_fallback</a></li><li>TCL interface busy method - <a href="tclsqlite.html#busy">tclsqlite.html#busy</a></li><li>TCL interface cache method - <a href="tclsqlite.html#cache">tclsqlite.html#cache</a></li><li>TCL interface changes method - <a href="tclsqlite.html#changes">tclsqlite.html#changes</a></li><li>TCL interface close method - <a href="tclsqlite.html#close">tclsqlite.html#close</a></li><li>TCL interface collate method - <a href="tclsqlite.html#collate">tclsqlite.html#collate</a></li><li>TCL interface collation_needed method - <a href="tclsqlite.html#collation_needed">tclsqlite.html#collation_needed</a></li><li>TCL interface commit_hook method - <a href="tclsqlite.html#commit_hook">tclsqlite.html#commit_hook</a></li><li>TCL interface complete method - <a href="tclsqlite.html#complete">tclsqlite.html#complete</a></li><li>TCL interface config method - <a href="tclsqlite.html#config">tclsqlite.html#config</a></li><li>TCL interface copy method - <a href="tclsqlite.html#copy">tclsqlite.html#copy</a></li><li>TCL interface deserialize method - <a href="tclsqlite.html#deserialize">tclsqlite.html#deserialize</a></li><li>TCL interface enable_load_extension method - <a href="tclsqlite.html#enable_load_extension">tclsqlite.html#enable_load_extension</a></li><li>TCL interface errorcode method - <a href="tclsqlite.html#errorcode">tclsqlite.html#errorcode</a></li><li>TCL interface eval method - <a href="tclsqlite.html#eval">tclsqlite.html#eval</a></li><li>TCL interface exists method - <a href="tclsqlite.html#exists">tclsqlite.html#exists</a></li><li>TCL interface function method - <a href="tclsqlite.html#function">tclsqlite.html#function</a></li><li>TCL interface incrblob method - <a href="tclsqlite.html#incrblob">tclsqlite.html#incrblob</a></li><li>TCL interface interrupt method - <a href="tclsqlite.html#interrupt">tclsqlite.html#interrupt</a></li><li>TCL interface last_insert_rowid method - <a href="tclsqlite.html#last_insert_rowid">tclsqlite.html#last_insert_rowid</a></li><li>TCL interface nullvalue method - <a href="tclsqlite.html#nullvalue">tclsqlite.html#nullvalue</a></li><li>TCL interface onecolumn method - <a href="tclsqlite.html#onecolumn">tclsqlite.html#onecolumn</a></li><li>TCL interface preupdate method - <a href="tclsqlite.html#preupdate">tclsqlite.html#preupdate</a></li><li>TCL interface profile method - <a href="tclsqlite.html#profile">tclsqlite.html#profile</a></li><li>TCL interface progress method - <a href="tclsqlite.html#progress">tclsqlite.html#progress</a></li><li>TCL interface restore method - <a href="tclsqlite.html#restore">tclsqlite.html#restore</a></li><li>TCL interface rollback_hook method - <a href="tclsqlite.html#rollback_hook">tclsqlite.html#rollback_hook</a></li><li>TCL interface serialize method - <a href="tclsqlite.html#serialize">tclsqlite.html#serialize</a></li><li>TCL interface status method - <a href="tclsqlite.html#status">tclsqlite.html#status</a></li><li>TCL interface timeout method - <a href="tclsqlite.html#timeout">tclsqlite.html#timeout</a></li><li>TCL interface total_changes method - <a href="tclsqlite.html#total_changes">tclsqlite.html#total_changes</a></li><li>TCL interface trace method - <a href="tclsqlite.html#trace">tclsqlite.html#trace</a></li><li>TCL interface trace_v2 method - <a href="tclsqlite.html#trace_v2">tclsqlite.html#trace_v2</a></li><li>TCL interface transaction method - <a href="tclsqlite.html#transaction">tclsqlite.html#transaction</a></li><li>TCL interface unlock_notify method - <a href="tclsqlite.html#unlock_notify">tclsqlite.html#unlock_notify</a></li><li>TCL interface update_hook method - <a href="tclsqlite.html#update_hook">tclsqlite.html#update_hook</a></li><li>TCL interface version method - <a href="tclsqlite.html#version">tclsqlite.html#version</a></li><li>TCL interface wal_hook method - <a href="tclsqlite.html#wal_hook">tclsqlite.html#wal_hook</a></li><li>TCL test suite - <a href="testing.html#tcl">testing.html#tcl</a></li><li>TCL variable substitution - <a href="tclsqlite.html#varsubst">tclsqlite.html#varsubst</a></li><li>TEA tarball - <a href="download.html">download.html</a></li><li>TEMP triggers on non-TEMP tables - <a href="lang_createtrigger.html#temptrig">lang_createtrigger.html#temptrig</a></li><li>temp_store - <a href="pragma.html#pragma_temp_store">pragma.html#pragma_temp_store</a></li><li>temp_store pragma - <a href="pragma.html#pragma_temp_store">pragma.html#pragma_temp_store</a></li><li>temp_store_directory - <a href="pragma.html#pragma_temp_store_directory">pragma.html#pragma_temp_store_directory</a></li><li>temp_store_directory pragma - <a href="pragma.html#pragma_temp_store_directory">pragma.html#pragma_temp_store_directory</a></li><li>temporary databases - <a href="inmemorydb.html#temp_db">inmemorydb.html#temp_db</a></li><li>temporary directory search algorithm - <a href="tempfiles.html#tempdir">tempfiles.html#tempdir</a></li><li>temporary disk files - <a href="tempfiles.html">tempfiles.html</a></li><li>temporary tables - <a href="inmemorydb.html#temp_db">inmemorydb.html#temp_db</a></li><li>tempstore - <a href="tempfiles.html#tempstore">tempfiles.html#tempstore</a></li><li>test coverage - <a href="testing.html#coverage">testing.html#coverage</a></li><li>test harness - <a href="testing.html#harnesses">testing.html#harnesses</a></li><li>test suite - <a href="testing.html">testing.html</a></li><li>testcase macros - <a href="testing.html#testcase">testing.html#testcase</a></li><li>tested - <a href="testing.html">testing.html</a></li><li>testing - <a href="testing.html">testing.html</a></li><li>text encoding - <a href="fileformat2.html#enc">fileformat2.html#enc</a></li><li>TH3 - <a href="th3.html">th3.html</a></li><li>the - and - operators - <a href="json1.html#jptr">json1.html#jptr</a></li><li>the - operator - <a href="json1.html#jptr">json1.html#jptr</a></li><li>the .fullschema dot-command - <a href="cli.html#fullschema">cli.html#fullschema</a></li><li>the amalgamation - <a href="amalgamation.html">amalgamation.html</a></li><li>the ext3 barrier problem - <a href="lockingv3.html#ext3-barrier-problem">lockingv3.html#ext3-barrier-problem</a></li><li>The Fossil NGQP Upgrade Case Study - <a href="queryplanner-ng.html#fossilcasestudy">queryplanner-ng.html#fossilcasestudy</a></li><li>the json1 extension - <a href="json1.html">json1.html</a></li><li>the SQLITE_DBPAGE extension - <a href="dbpage.html">dbpage.html</a></li><li>the SQLITE_MEMSTAT extension - <a href="memstat.html">memstat.html</a></li><li>the SQLITE_STMT extension - <a href="stmt.html">stmt.html</a></li><li>The Use Of assert In SQLite - <a href="assert.html">assert.html</a></li><li>the xCachesize page cache method - <a href="c3ref/pcache_methods2.html#thexcachesizepagecachemethod">c3ref/pcache_methods2.html#thexcachesizepagecachemethod</a></li><li>the xCreate page cache methods - <a href="c3ref/pcache_methods2.html#thexcreatepagecachemethods">c3ref/pcache_methods2.html#thexcreatepagecachemethods</a></li><li>the xDestroy page cache method - <a href="c3ref/pcache_methods2.html#thexdestroypagecachemethod">c3ref/pcache_methods2.html#thexdestroypagecachemethod</a></li><li>the xFetch page cache methods - <a href="c3ref/pcache_methods2.html#thexfetchpagecachemethods">c3ref/pcache_methods2.html#thexfetchpagecachemethods</a></li><li>the xInit page cache method - <a href="c3ref/pcache_methods2.html#thexinitpagecachemethod">c3ref/pcache_methods2.html#thexinitpagecachemethod</a></li><li>the xPagecount page cache methods - <a href="c3ref/pcache_methods2.html#thexpagecountpagecachemethods">c3ref/pcache_methods2.html#thexpagecountpagecachemethods</a></li><li>the xRekey page cache methods - <a href="c3ref/pcache_methods2.html#thexrekeypagecachemethods">c3ref/pcache_methods2.html#thexrekeypagecachemethods</a></li><li>the xShrink page cache method - <a href="c3ref/pcache_methods2.html#thexshrinkpagecachemethod">c3ref/pcache_methods2.html#thexshrinkpagecachemethod</a></li><li>the xShutdown page cache method - <a href="c3ref/pcache_methods2.html#thexshutdownpagecachemethod">c3ref/pcache_methods2.html#thexshutdownpagecachemethod</a></li><li>the xUnpin page cache method - <a href="c3ref/pcache_methods2.html#thexunpinpagecachemethod">c3ref/pcache_methods2.html#thexunpinpagecachemethod</a></li><li>Things That Can Go Wrong - <a href="atomiccommit.html#sect_9_0">atomiccommit.html#sect_9_0</a></li><li>threading mode - <a href="threadsafe.html">threadsafe.html</a></li><li>threads - <a href="pragma.html#pragma_threads">pragma.html#pragma_threads</a></li><li>threads pragma - <a href="pragma.html#pragma_threads">pragma.html#pragma_threads</a></li><li>three test harnesses - <a href="testing.html#harnesses">testing.html#harnesses</a></li><li>time - <a href="lang_datefunc.html#dttm">lang_datefunc.html#dttm</a></li><li>time shift modifiers - <a href="lang_datefunc.html#tmshf">lang_datefunc.html#tmshf</a></li><li>time SQL function - <a href="lang_datefunc.html#dttm">lang_datefunc.html#dttm</a></li><li>timediff - <a href="lang_datefunc.html#tmdif">lang_datefunc.html#tmdif</a></li><li>timediff SQL function - <a href="lang_datefunc.html#tmdif">lang_datefunc.html#tmdif</a></li><li>timeout method - <a href="tclsqlite.html#timeout">tclsqlite.html#timeout</a></li><li>tokenizer - <a href="fts3.html#tokenizer">fts3.html#tokenizer</a></li><li>torn page - <a href="psow.html#tornpage">psow.html#tornpage</a></li><li>total - <a href="lang_aggfunc.html#sumunc">lang_aggfunc.html#sumunc</a></li><li>total aggregate function - <a href="lang_aggfunc.html#sumunc">lang_aggfunc.html#sumunc</a></li><li>total_changes - <a href="lang_corefunc.html#total_changes">lang_corefunc.html#total_changes</a></li><li>total_changes method - <a href="tclsqlite.html#total_changes">tclsqlite.html#total_changes</a></li><li>total_changes SQL function - <a href="lang_corefunc.html#total_changes">lang_corefunc.html#total_changes</a></li><li>trace method - <a href="tclsqlite.html#trace">tclsqlite.html#trace</a></li><li>trace_v2 method - <a href="tclsqlite.html#trace_v2">tclsqlite.html#trace_v2</a></li><li>transaction - <a href="lang_transaction.html">lang_transaction.html</a></li><li>transaction method - <a href="tclsqlite.html#transaction">tclsqlite.html#transaction</a></li><li>transaction state - <a href="c3ref/c_txn_none.html">c3ref/c_txn_none.html</a></li><li>transactional - <a href="transactional.html">transactional.html</a></li><li>treats the CROSS JOIN operator specially - <a href="lang_select.html#crossjoin">lang_select.html#crossjoin</a></li><li>trigger - <a href="lang_createtrigger.html">lang_createtrigger.html</a></li><li>triggers - <a href="lang_createtrigger.html">lang_createtrigger.html</a></li><li>trigram indexes - <a href="fts5.html#trigramidx">fts5.html#trigramidx</a></li><li>trigram tokenizer - <a href="fts5.html#trigramidx">fts5.html#trigramidx</a></li><li>trim - <a href="lang_corefunc.html#trim">lang_corefunc.html#trim</a></li><li>trim SQL function - <a href="lang_corefunc.html#trim">lang_corefunc.html#trim</a></li><li>trunc - <a href="lang_mathfunc.html#trunc">lang_mathfunc.html#trunc</a></li><li>trunc SQL function - <a href="lang_mathfunc.html#trunc">lang_mathfunc.html#trunc</a></li><li>truncate optimization - <a href="lang_delete.html#truncateopt">lang_delete.html#truncateopt</a></li><li>trusted_schema - <a href="pragma.html#pragma_trusted_schema">pragma.html#pragma_trusted_schema</a></li><li>trusted_schema pragma - <a href="pragma.html#pragma_trusted_schema">pragma.html#pragma_trusted_schema</a></li><li>type affinity - <a href="datatype3.html#affinity">datatype3.html#affinity</a></li><li>type-name - <a href="syntax/type-name.html">syntax/type-name.html</a></li><li>type-name syntax diagram - <a href="syntax/type-name.html">syntax/type-name.html</a></li><li>typeof - <a href="lang_corefunc.html#typeof">lang_corefunc.html#typeof</a></li><li>typeof SQL function - <a href="lang_corefunc.html#typeof">lang_corefunc.html#typeof</a></li><li>UINT - <a href="uintcseq.html">uintcseq.html</a></li><li>UINT collating sequence - <a href="uintcseq.html">uintcseq.html</a></li><li>undefined BEFORE trigger behavior - <a href="lang_createtrigger.html#undef_before">lang_createtrigger.html#undef_before</a></li><li>undo/redo - <a href="undoredo.html">undoredo.html</a></li><li>undoredo - <a href="undoredo.html">undoredo.html</a></li><li>unhex - <a href="lang_corefunc.html#unhex">lang_corefunc.html#unhex</a></li><li>unhex SQL function - <a href="lang_corefunc.html#unhex">lang_corefunc.html#unhex</a></li><li>unicode - <a href="lang_corefunc.html#unicode">lang_corefunc.html#unicode</a></li><li>unicode SQL function - <a href="lang_corefunc.html#unicode">lang_corefunc.html#unicode</a></li><li>unicode61 - <a href="fts3.html#unicode61">fts3.html#unicode61</a></li><li>Uniform Resource Identifier - <a href="uri.html">uri.html</a></li><li>unindexed - <a href="fts5.html#the_unindexed_column_option">fts5.html#the_unindexed_column_option</a></li><li>UNION virtual table - <a href="unionvtab.html">unionvtab.html</a></li><li>union-vtab - <a href="unionvtab.html">unionvtab.html</a></li><li>unionvtab - <a href="unionvtab.html">unionvtab.html</a></li><li>UNIQUE - <a href="lang_createtable.html#uniqueconst">lang_createtable.html#uniqueconst</a></li><li>UNIQUE constraint - <a href="lang_createtable.html#uniqueconst">lang_createtable.html#uniqueconst</a></li><li>unique constraint - <a href="lang_createtable.html#uniqueconst">lang_createtable.html#uniqueconst</a></li><li>UNIQUE constraints - <a href="lang_createtable.html#uniqueconst">lang_createtable.html#uniqueconst</a></li><li>unique index - <a href="lang_createindex.html#uniqueidx">lang_createindex.html#uniqueidx</a></li><li>unixepoch - <a href="lang_datefunc.html#uepch">lang_datefunc.html#uepch</a></li><li>unixepoch function - <a href="lang_datefunc.html#uepch">lang_datefunc.html#uepch</a></li><li>unixepoch SQL function - <a href="lang_datefunc.html#uepch">lang_datefunc.html#uepch</a></li><li>unlikely - <a href="lang_corefunc.html#unlikely">lang_corefunc.html#unlikely</a></li><li>unlikely SQL function - <a href="lang_corefunc.html#unlikely">lang_corefunc.html#unlikely</a></li><li>unlink corruption - <a href="howtocorrupt.html#unlink">howtocorrupt.html#unlink</a></li><li>unlinked database files - <a href="howtocorrupt.html#unlink">howtocorrupt.html#unlink</a></li><li>unlock_notify method - <a href="tclsqlite.html#unlock_notify">tclsqlite.html#unlock_notify</a></li><li>unprotected sqlite3_value - <a href="c3ref/value.html">c3ref/value.html</a></li><li>unsafe-testing command-line option - <a href="cli.html#testing_mode">cli.html#testing_mode</a></li><li>untrusted database files - <a href="security.html#baddb">security.html#baddb</a></li><li>UPDATE - <a href="lang_update.html">lang_update.html</a></li><li>UPDATE FROM - <a href="lang_update.html#upfrom">lang_update.html#upfrom</a></li><li>UPDATE trigger - <a href="lang_createtrigger.html">lang_createtrigger.html</a></li><li>update-stmt - <a href="syntax/update-stmt.html">syntax/update-stmt.html</a></li><li>update-stmt syntax diagram - <a href="syntax/update-stmt.html">syntax/update-stmt.html</a></li><li>update-stmt-limited - <a href="syntax/update-stmt-limited.html">syntax/update-stmt-limited.html</a></li><li>update-stmt-limited syntax diagram - <a href="syntax/update-stmt-limited.html">syntax/update-stmt-limited.html</a></li><li>update_hook method - <a href="tclsqlite.html#update_hook">tclsqlite.html#update_hook</a></li><li>UPDATEs - <a href="lang_update.html">lang_update.html</a></li><li>upluscontrol - <a href="optoverview.html#uplus">optoverview.html#uplus</a></li><li>upper - <a href="lang_corefunc.html#upper">lang_corefunc.html#upper</a></li><li>upper SQL function - <a href="lang_corefunc.html#upper">lang_corefunc.html#upper</a></li><li>UPSERT - <a href="lang_upsert.html">lang_upsert.html</a></li><li>upsert - <a href="lang_upsert.html">lang_upsert.html</a></li><li>upsert clause - <a href="lang_upsert.html">lang_upsert.html</a></li><li>UPSERT parsing ambiguity - <a href="lang_upsert.html#parseambig">lang_upsert.html#parseambig</a></li><li>upsert-clause - <a href="syntax/upsert-clause.html">syntax/upsert-clause.html</a></li><li>upsert-clause syntax diagram - <a href="syntax/upsert-clause.html">syntax/upsert-clause.html</a></li><li>URI - <a href="uri.html">uri.html</a></li><li>URI filename - <a href="uri.html">uri.html</a></li><li>URI filename examples - <a href="c3ref/open.html#urifilenameexamples">c3ref/open.html#urifilenameexamples</a></li><li>URI filenames - <a href="uri.html">uri.html</a></li><li>URI filenames in sqlite3_open - <a href="c3ref/open.html#urifilenamesinsqlite3open">c3ref/open.html#urifilenamesinsqlite3open</a></li><li>URI query parameters - <a href="uri.html#coreqp">uri.html#coreqp</a></li><li>usable size - <a href="fileformat2.html#usable_size">fileformat2.html#usable_size</a></li><li>use of shared cache mode is discouraged - <a href="sharedcache.html#dontuse">sharedcache.html#dontuse</a></li><li>user-defined window functions - <a href="windowfunctions.html#udfwinfunc">windowfunctions.html#udfwinfunc</a></li><li>user_version - <a href="pragma.html#pragma_user_version">pragma.html#pragma_user_version</a></li><li>user_version pragma - <a href="pragma.html#pragma_user_version">pragma.html#pragma_user_version</a></li><li>using SQLite for websites - <a href="whentouse.html#website">whentouse.html#website</a></li><li>Using the SQLite Online Backup API - <a href="backup.html">backup.html</a></li><li>Using the SQLite Unlock Notification Feature - <a href="unlock_notify.html">unlock_notify.html</a></li><li>utc modifier - <a href="lang_datefunc.html#localtime">lang_datefunc.html#localtime</a></li><li>VACUUM - <a href="lang_vacuum.html">lang_vacuum.html</a></li><li>vacuum - <a href="lang_vacuum.html">lang_vacuum.html</a></li><li>VACUUM INTO - <a href="lang_vacuum.html#vacuuminto">lang_vacuum.html#vacuuminto</a></li><li>vacuum-stmt - <a href="syntax/vacuum-stmt.html">syntax/vacuum-stmt.html</a></li><li>vacuum-stmt syntax diagram - <a href="syntax/vacuum-stmt.html">syntax/vacuum-stmt.html</a></li><li>value argument - <a href="json1.html#varg">json1.html#varg</a></li><li>VALUES - <a href="lang_select.html#values">lang_select.html#values</a></li><li>VALUES clause - <a href="lang_select.html#values">lang_select.html#values</a></li><li>variable-length integer - <a href="fileformat2.html#varint">fileformat2.html#varint</a></li><li>varint - <a href="fileformat2.html#varint">fileformat2.html#varint</a></li><li>VDBE - <a href="opcode.html">opcode.html</a></li><li>vdbe_addoptrace - <a href="pragma.html#pragma_vdbe_addoptrace">pragma.html#pragma_vdbe_addoptrace</a></li><li>vdbe_addoptrace pragma - <a href="pragma.html#pragma_vdbe_addoptrace">pragma.html#pragma_vdbe_addoptrace</a></li><li>vdbe_debug - <a href="pragma.html#pragma_vdbe_debug">pragma.html#pragma_vdbe_debug</a></li><li>vdbe_debug pragma - <a href="pragma.html#pragma_vdbe_debug">pragma.html#pragma_vdbe_debug</a></li><li>vdbe_listing - <a href="pragma.html#pragma_vdbe_listing">pragma.html#pragma_vdbe_listing</a></li><li>vdbe_listing pragma - <a href="pragma.html#pragma_vdbe_listing">pragma.html#pragma_vdbe_listing</a></li><li>vdbe_trace - <a href="pragma.html#pragma_vdbe_trace">pragma.html#pragma_vdbe_trace</a></li><li>vdbe_trace pragma - <a href="pragma.html#pragma_vdbe_trace">pragma.html#pragma_vdbe_trace</a></li><li>vectors - <a href="rowvalue.html">rowvalue.html</a></li><li>Version 3.0.0 - <a href="releaselog/3_0_0.html">releaselog/3_0_0.html</a></li><li>version 3.0.0 - <a href="releaselog/3_0_0.html">releaselog/3_0_0.html</a></li><li>Version 3.0.1 - <a href="releaselog/3_0_1.html">releaselog/3_0_1.html</a></li><li>version 3.0.1 - <a href="releaselog/3_0_1.html">releaselog/3_0_1.html</a></li><li>Version 3.0.2 - <a href="releaselog/3_0_2.html">releaselog/3_0_2.html</a></li><li>version 3.0.2 - <a href="releaselog/3_0_2.html">releaselog/3_0_2.html</a></li><li>Version 3.0.3 - <a href="releaselog/3_0_3.html">releaselog/3_0_3.html</a></li><li>version 3.0.3 - <a href="releaselog/3_0_3.html">releaselog/3_0_3.html</a></li><li>Version 3.0.4 - <a href="releaselog/3_0_4.html">releaselog/3_0_4.html</a></li><li>version 3.0.4 - <a href="releaselog/3_0_4.html">releaselog/3_0_4.html</a></li><li>Version 3.0.5 - <a href="releaselog/3_0_5.html">releaselog/3_0_5.html</a></li><li>version 3.0.5 - <a href="releaselog/3_0_5.html">releaselog/3_0_5.html</a></li><li>Version 3.0.6 - <a href="releaselog/3_0_6.html">releaselog/3_0_6.html</a></li><li>version 3.0.6 - <a href="releaselog/3_0_6.html">releaselog/3_0_6.html</a></li><li>Version 3.0.7 - <a href="releaselog/3_0_7.html">releaselog/3_0_7.html</a></li><li>version 3.0.7 - <a href="releaselog/3_0_7.html">releaselog/3_0_7.html</a></li><li>Version 3.0.8 - <a href="releaselog/3_0_8.html">releaselog/3_0_8.html</a></li><li>version 3.0.8 - <a href="releaselog/3_0_8.html">releaselog/3_0_8.html</a></li><li>Version 3.1.0 - <a href="releaselog/3_1_0.html">releaselog/3_1_0.html</a></li><li>version 3.1.0 - <a href="releaselog/3_1_0.html">releaselog/3_1_0.html</a></li><li>Version 3.1.1 - <a href="releaselog/3_1_1.html">releaselog/3_1_1.html</a></li><li>version 3.1.1 - <a href="releaselog/3_1_1.html">releaselog/3_1_1.html</a></li><li>Version 3.1.2 - <a href="releaselog/3_1_2.html">releaselog/3_1_2.html</a></li><li>version 3.1.2 - <a href="releaselog/3_1_2.html">releaselog/3_1_2.html</a></li><li>Version 3.1.3 - <a href="releaselog/3_1_3.html">releaselog/3_1_3.html</a></li><li>version 3.1.3 - <a href="releaselog/3_1_3.html">releaselog/3_1_3.html</a></li><li>Version 3.1.4 - <a href="releaselog/3_1_4.html">releaselog/3_1_4.html</a></li><li>version 3.1.4 - <a href="releaselog/3_1_4.html">releaselog/3_1_4.html</a></li><li>Version 3.1.5 - <a href="releaselog/3_1_5.html">releaselog/3_1_5.html</a></li><li>version 3.1.5 - <a href="releaselog/3_1_5.html">releaselog/3_1_5.html</a></li><li>Version 3.1.6 - <a href="releaselog/3_1_6.html">releaselog/3_1_6.html</a></li><li>version 3.1.6 - <a href="releaselog/3_1_6.html">releaselog/3_1_6.html</a></li><li>Version 3.2.0 - <a href="releaselog/3_2_0.html">releaselog/3_2_0.html</a></li><li>version 3.2.0 - <a href="releaselog/3_2_0.html">releaselog/3_2_0.html</a></li><li>Version 3.2.1 - <a href="releaselog/3_2_1.html">releaselog/3_2_1.html</a></li><li>version 3.2.1 - <a href="releaselog/3_2_1.html">releaselog/3_2_1.html</a></li><li>Version 3.2.2 - <a href="releaselog/3_2_2.html">releaselog/3_2_2.html</a></li><li>version 3.2.2 - <a href="releaselog/3_2_2.html">releaselog/3_2_2.html</a></li><li>Version 3.2.3 - <a href="releaselog/3_2_3.html">releaselog/3_2_3.html</a></li><li>version 3.2.3 - <a href="releaselog/3_2_3.html">releaselog/3_2_3.html</a></li><li>Version 3.2.4 - <a href="releaselog/3_2_4.html">releaselog/3_2_4.html</a></li><li>version 3.2.4 - <a href="releaselog/3_2_4.html">releaselog/3_2_4.html</a></li><li>Version 3.2.5 - <a href="releaselog/3_2_5.html">releaselog/3_2_5.html</a></li><li>version 3.2.5 - <a href="releaselog/3_2_5.html">releaselog/3_2_5.html</a></li><li>Version 3.2.6 - <a href="releaselog/3_2_6.html">releaselog/3_2_6.html</a></li><li>version 3.2.6 - <a href="releaselog/3_2_6.html">releaselog/3_2_6.html</a></li><li>Version 3.2.7 - <a href="releaselog/3_2_7.html">releaselog/3_2_7.html</a></li><li>version 3.2.7 - <a href="releaselog/3_2_7.html">releaselog/3_2_7.html</a></li><li>Version 3.2.8 - <a href="releaselog/3_2_8.html">releaselog/3_2_8.html</a></li><li>version 3.2.8 - <a href="releaselog/3_2_8.html">releaselog/3_2_8.html</a></li><li>Version 3.3.0 - <a href="releaselog/3_3_0.html">releaselog/3_3_0.html</a></li><li>version 3.3.0 - <a href="releaselog/3_3_0.html">releaselog/3_3_0.html</a></li><li>Version 3.3.0.0 - <a href="releaselog/3_3_0.html">releaselog/3_3_0.html</a></li><li>version 3.3.0.0 - <a href="releaselog/3_3_0.html">releaselog/3_3_0.html</a></li><li>Version 3.3.1 - <a href="releaselog/3_3_1.html">releaselog/3_3_1.html</a></li><li>version 3.3.1 - <a href="releaselog/3_3_1.html">releaselog/3_3_1.html</a></li><li>Version 3.3.1.0 - <a href="releaselog/3_3_1.html">releaselog/3_3_1.html</a></li><li>version 3.3.1.0 - <a href="releaselog/3_3_1.html">releaselog/3_3_1.html</a></li><li>Version 3.3.2 - <a href="releaselog/3_3_2.html">releaselog/3_3_2.html</a></li><li>version 3.3.2 - <a href="releaselog/3_3_2.html">releaselog/3_3_2.html</a></li><li>Version 3.3.2.0 - <a href="releaselog/3_3_2.html">releaselog/3_3_2.html</a></li><li>version 3.3.2.0 - <a href="releaselog/3_3_2.html">releaselog/3_3_2.html</a></li><li>Version 3.3.3 - <a href="releaselog/3_3_3.html">releaselog/3_3_3.html</a></li><li>version 3.3.3 - <a href="releaselog/3_3_3.html">releaselog/3_3_3.html</a></li><li>Version 3.3.3.0 - <a href="releaselog/3_3_3.html">releaselog/3_3_3.html</a></li><li>version 3.3.3.0 - <a href="releaselog/3_3_3.html">releaselog/3_3_3.html</a></li><li>Version 3.3.4 - <a href="releaselog/3_3_4.html">releaselog/3_3_4.html</a></li><li>version 3.3.4 - <a href="releaselog/3_3_4.html">releaselog/3_3_4.html</a></li><li>Version 3.3.4.0 - <a href="releaselog/3_3_4.html">releaselog/3_3_4.html</a></li><li>version 3.3.4.0 - <a href="releaselog/3_3_4.html">releaselog/3_3_4.html</a></li><li>Version 3.3.5 - <a href="releaselog/3_3_5.html">releaselog/3_3_5.html</a></li><li>version 3.3.5 - <a href="releaselog/3_3_5.html">releaselog/3_3_5.html</a></li><li>Version 3.3.5.0 - <a href="releaselog/3_3_5.html">releaselog/3_3_5.html</a></li><li>version 3.3.5.0 - <a href="releaselog/3_3_5.html">releaselog/3_3_5.html</a></li><li>Version 3.3.6 - <a href="releaselog/3_3_6.html">releaselog/3_3_6.html</a></li><li>version 3.3.6 - <a href="releaselog/3_3_6.html">releaselog/3_3_6.html</a></li><li>Version 3.3.6.0 - <a href="releaselog/3_3_6.html">releaselog/3_3_6.html</a></li><li>version 3.3.6.0 - <a href="releaselog/3_3_6.html">releaselog/3_3_6.html</a></li><li>Version 3.3.7 - <a href="releaselog/3_3_7.html">releaselog/3_3_7.html</a></li><li>version 3.3.7 - <a href="releaselog/3_3_7.html">releaselog/3_3_7.html</a></li><li>Version 3.3.7.0 - <a href="releaselog/3_3_7.html">releaselog/3_3_7.html</a></li><li>version 3.3.7.0 - <a href="releaselog/3_3_7.html">releaselog/3_3_7.html</a></li><li>Version 3.3.8 - <a href="releaselog/3_3_8.html">releaselog/3_3_8.html</a></li><li>version 3.3.8 - <a href="releaselog/3_3_8.html">releaselog/3_3_8.html</a></li><li>Version 3.3.8.0 - <a href="releaselog/3_3_8.html">releaselog/3_3_8.html</a></li><li>version 3.3.8.0 - <a href="releaselog/3_3_8.html">releaselog/3_3_8.html</a></li><li>Version 3.3.9 - <a href="releaselog/3_3_9.html">releaselog/3_3_9.html</a></li><li>version 3.3.9 - <a href="releaselog/3_3_9.html">releaselog/3_3_9.html</a></li><li>Version 3.3.9.0 - <a href="releaselog/3_3_9.html">releaselog/3_3_9.html</a></li><li>version 3.3.9.0 - <a href="releaselog/3_3_9.html">releaselog/3_3_9.html</a></li><li>Version 3.3.10 - <a href="releaselog/3_3_10.html">releaselog/3_3_10.html</a></li><li>version 3.3.10 - <a href="releaselog/3_3_10.html">releaselog/3_3_10.html</a></li><li>Version 3.3.10.0 - <a href="releaselog/3_3_10.html">releaselog/3_3_10.html</a></li><li>version 3.3.10.0 - <a href="releaselog/3_3_10.html">releaselog/3_3_10.html</a></li><li>Version 3.3.11 - <a href="releaselog/3_3_11.html">releaselog/3_3_11.html</a></li><li>version 3.3.11 - <a href="releaselog/3_3_11.html">releaselog/3_3_11.html</a></li><li>Version 3.3.11.0 - <a href="releaselog/3_3_11.html">releaselog/3_3_11.html</a></li><li>version 3.3.11.0 - <a href="releaselog/3_3_11.html">releaselog/3_3_11.html</a></li><li>Version 3.3.12 - <a href="releaselog/3_3_12.html">releaselog/3_3_12.html</a></li><li>version 3.3.12 - <a href="releaselog/3_3_12.html">releaselog/3_3_12.html</a></li><li>Version 3.3.12.0 - <a href="releaselog/3_3_12.html">releaselog/3_3_12.html</a></li><li>version 3.3.12.0 - <a href="releaselog/3_3_12.html">releaselog/3_3_12.html</a></li><li>Version 3.3.13 - <a href="releaselog/3_3_13.html">releaselog/3_3_13.html</a></li><li>version 3.3.13 - <a href="releaselog/3_3_13.html">releaselog/3_3_13.html</a></li><li>Version 3.3.13.0 - <a href="releaselog/3_3_13.html">releaselog/3_3_13.html</a></li><li>version 3.3.13.0 - <a href="releaselog/3_3_13.html">releaselog/3_3_13.html</a></li><li>Version 3.3.14 - <a href="releaselog/3_3_14.html">releaselog/3_3_14.html</a></li><li>version 3.3.14 - <a href="releaselog/3_3_14.html">releaselog/3_3_14.html</a></li><li>Version 3.3.14.0 - <a href="releaselog/3_3_14.html">releaselog/3_3_14.html</a></li><li>version 3.3.14.0 - <a href="releaselog/3_3_14.html">releaselog/3_3_14.html</a></li><li>Version 3.3.15 - <a href="releaselog/3_3_15.html">releaselog/3_3_15.html</a></li><li>version 3.3.15 - <a href="releaselog/3_3_15.html">releaselog/3_3_15.html</a></li><li>Version 3.3.15.0 - <a href="releaselog/3_3_15.html">releaselog/3_3_15.html</a></li><li>version 3.3.15.0 - <a href="releaselog/3_3_15.html">releaselog/3_3_15.html</a></li><li>Version 3.3.16 - <a href="releaselog/3_3_16.html">releaselog/3_3_16.html</a></li><li>version 3.3.16 - <a href="releaselog/3_3_16.html">releaselog/3_3_16.html</a></li><li>Version 3.3.16.0 - <a href="releaselog/3_3_16.html">releaselog/3_3_16.html</a></li><li>version 3.3.16.0 - <a href="releaselog/3_3_16.html">releaselog/3_3_16.html</a></li><li>Version 3.3.17 - <a href="releaselog/3_3_17.html">releaselog/3_3_17.html</a></li><li>version 3.3.17 - <a href="releaselog/3_3_17.html">releaselog/3_3_17.html</a></li><li>Version 3.3.17.0 - <a href="releaselog/3_3_17.html">releaselog/3_3_17.html</a></li><li>version 3.3.17.0 - <a href="releaselog/3_3_17.html">releaselog/3_3_17.html</a></li><li>Version 3.4.0 - <a href="releaselog/3_4_0.html">releaselog/3_4_0.html</a></li><li>version 3.4.0 - <a href="releaselog/3_4_0.html">releaselog/3_4_0.html</a></li><li>Version 3.4.1 - <a href="releaselog/3_4_1.html">releaselog/3_4_1.html</a></li><li>version 3.4.1 - <a href="releaselog/3_4_1.html">releaselog/3_4_1.html</a></li><li>Version 3.4.2 - <a href="releaselog/3_4_2.html">releaselog/3_4_2.html</a></li><li>version 3.4.2 - <a href="releaselog/3_4_2.html">releaselog/3_4_2.html</a></li><li>Version 3.5.0 - <a href="releaselog/3_5_0.html">releaselog/3_5_0.html</a></li><li>version 3.5.0 - <a href="releaselog/3_5_0.html">releaselog/3_5_0.html</a></li><li>Version 3.5.1 - <a href="releaselog/3_5_1.html">releaselog/3_5_1.html</a></li><li>version 3.5.1 - <a href="releaselog/3_5_1.html">releaselog/3_5_1.html</a></li><li>Version 3.5.2 - <a href="releaselog/3_5_2.html">releaselog/3_5_2.html</a></li><li>version 3.5.2 - <a href="releaselog/3_5_2.html">releaselog/3_5_2.html</a></li><li>Version 3.5.3 - <a href="releaselog/3_5_3.html">releaselog/3_5_3.html</a></li><li>version 3.5.3 - <a href="releaselog/3_5_3.html">releaselog/3_5_3.html</a></li><li>Version 3.5.4 - <a href="releaselog/3_5_4.html">releaselog/3_5_4.html</a></li><li>version 3.5.4 - <a href="releaselog/3_5_4.html">releaselog/3_5_4.html</a></li><li>Version 3.5.5 - <a href="releaselog/3_5_5.html">releaselog/3_5_5.html</a></li><li>version 3.5.5 - <a href="releaselog/3_5_5.html">releaselog/3_5_5.html</a></li><li>Version 3.5.6 - <a href="releaselog/3_5_6.html">releaselog/3_5_6.html</a></li><li>version 3.5.6 - <a href="releaselog/3_5_6.html">releaselog/3_5_6.html</a></li><li>Version 3.5.7 - <a href="releaselog/3_5_7.html">releaselog/3_5_7.html</a></li><li>version 3.5.7 - <a href="releaselog/3_5_7.html">releaselog/3_5_7.html</a></li><li>Version 3.5.8 - <a href="releaselog/3_5_8.html">releaselog/3_5_8.html</a></li><li>version 3.5.8 - <a href="releaselog/3_5_8.html">releaselog/3_5_8.html</a></li><li>Version 3.5.9 - <a href="releaselog/3_5_9.html">releaselog/3_5_9.html</a></li><li>version 3.5.9 - <a href="releaselog/3_5_9.html">releaselog/3_5_9.html</a></li><li>Version 3.6.0 - <a href="releaselog/3_6_0.html">releaselog/3_6_0.html</a></li><li>version 3.6.0 - <a href="releaselog/3_6_0.html">releaselog/3_6_0.html</a></li><li>Version 3.6.1 - <a href="releaselog/3_6_1.html">releaselog/3_6_1.html</a></li><li>version 3.6.1 - <a href="releaselog/3_6_1.html">releaselog/3_6_1.html</a></li><li>Version 3.6.2 - <a href="releaselog/3_6_2.html">releaselog/3_6_2.html</a></li><li>version 3.6.2 - <a href="releaselog/3_6_2.html">releaselog/3_6_2.html</a></li><li>Version 3.6.3 - <a href="releaselog/3_6_3.html">releaselog/3_6_3.html</a></li><li>version 3.6.3 - <a href="releaselog/3_6_3.html">releaselog/3_6_3.html</a></li><li>Version 3.6.4 - <a href="releaselog/3_6_4.html">releaselog/3_6_4.html</a></li><li>version 3.6.4 - <a href="releaselog/3_6_4.html">releaselog/3_6_4.html</a></li><li>Version 3.6.5 - <a href="releaselog/3_6_5.html">releaselog/3_6_5.html</a></li><li>version 3.6.5 - <a href="releaselog/3_6_5.html">releaselog/3_6_5.html</a></li><li>Version 3.6.6 - <a href="releaselog/3_6_6.html">releaselog/3_6_6.html</a></li><li>version 3.6.6 - <a href="releaselog/3_6_6.html">releaselog/3_6_6.html</a></li><li>Version 3.6.6.1 - <a href="releaselog/3_6_6_1.html">releaselog/3_6_6_1.html</a></li><li>version 3.6.6.1 - <a href="releaselog/3_6_6_1.html">releaselog/3_6_6_1.html</a></li><li>Version 3.6.6.2 - <a href="releaselog/3_6_6_2.html">releaselog/3_6_6_2.html</a></li><li>version 3.6.6.2 - <a href="releaselog/3_6_6_2.html">releaselog/3_6_6_2.html</a></li><li>Version 3.6.7 - <a href="releaselog/3_6_7.html">releaselog/3_6_7.html</a></li><li>version 3.6.7 - <a href="releaselog/3_6_7.html">releaselog/3_6_7.html</a></li><li>Version 3.6.8 - <a href="releaselog/3_6_8.html">releaselog/3_6_8.html</a></li><li>version 3.6.8 - <a href="releaselog/3_6_8.html">releaselog/3_6_8.html</a></li><li>Version 3.6.9 - <a href="releaselog/3_6_9.html">releaselog/3_6_9.html</a></li><li>version 3.6.9 - <a href="releaselog/3_6_9.html">releaselog/3_6_9.html</a></li><li>Version 3.6.10 - <a href="releaselog/3_6_10.html">releaselog/3_6_10.html</a></li><li>version 3.6.10 - <a href="releaselog/3_6_10.html">releaselog/3_6_10.html</a></li><li>Version 3.6.11 - <a href="releaselog/3_6_11.html">releaselog/3_6_11.html</a></li><li>version 3.6.11 - <a href="releaselog/3_6_11.html">releaselog/3_6_11.html</a></li><li>Version 3.6.12 - <a href="releaselog/3_6_12.html">releaselog/3_6_12.html</a></li><li>version 3.6.12 - <a href="releaselog/3_6_12.html">releaselog/3_6_12.html</a></li><li>Version 3.6.13 - <a href="releaselog/3_6_13.html">releaselog/3_6_13.html</a></li><li>version 3.6.13 - <a href="releaselog/3_6_13.html">releaselog/3_6_13.html</a></li><li>Version 3.6.14 - <a href="releaselog/3_6_14.html">releaselog/3_6_14.html</a></li><li>version 3.6.14 - <a href="releaselog/3_6_14.html">releaselog/3_6_14.html</a></li><li>Version 3.6.14.1 - <a href="releaselog/3_6_14_1.html">releaselog/3_6_14_1.html</a></li><li>version 3.6.14.1 - <a href="releaselog/3_6_14_1.html">releaselog/3_6_14_1.html</a></li><li>Version 3.6.14.2 - <a href="releaselog/3_6_14_2.html">releaselog/3_6_14_2.html</a></li><li>version 3.6.14.2 - <a href="releaselog/3_6_14_2.html">releaselog/3_6_14_2.html</a></li><li>Version 3.6.15 - <a href="releaselog/3_6_15.html">releaselog/3_6_15.html</a></li><li>version 3.6.15 - <a href="releaselog/3_6_15.html">releaselog/3_6_15.html</a></li><li>Version 3.6.16 - <a href="releaselog/3_6_16.html">releaselog/3_6_16.html</a></li><li>version 3.6.16 - <a href="releaselog/3_6_16.html">releaselog/3_6_16.html</a></li><li>Version 3.6.16.1 - <a href="releaselog/3_6_16_1.html">releaselog/3_6_16_1.html</a></li><li>version 3.6.16.1 - <a href="releaselog/3_6_16_1.html">releaselog/3_6_16_1.html</a></li><li>Version 3.6.17 - <a href="releaselog/3_6_17.html">releaselog/3_6_17.html</a></li><li>version 3.6.17 - <a href="releaselog/3_6_17.html">releaselog/3_6_17.html</a></li><li>Version 3.6.18 - <a href="releaselog/3_6_18.html">releaselog/3_6_18.html</a></li><li>version 3.6.18 - <a href="releaselog/3_6_18.html">releaselog/3_6_18.html</a></li><li>Version 3.6.19 - <a href="releaselog/3_6_19.html">releaselog/3_6_19.html</a></li><li>version 3.6.19 - <a href="releaselog/3_6_19.html">releaselog/3_6_19.html</a></li><li>Version 3.6.20 - <a href="releaselog/3_6_20.html">releaselog/3_6_20.html</a></li><li>version 3.6.20 - <a href="releaselog/3_6_20.html">releaselog/3_6_20.html</a></li><li>Version 3.6.21 - <a href="releaselog/3_6_21.html">releaselog/3_6_21.html</a></li><li>version 3.6.21 - <a href="releaselog/3_6_21.html">releaselog/3_6_21.html</a></li><li>Version 3.6.22 - <a href="releaselog/3_6_22.html">releaselog/3_6_22.html</a></li><li>version 3.6.22 - <a href="releaselog/3_6_22.html">releaselog/3_6_22.html</a></li><li>Version 3.6.23 - <a href="releaselog/3_6_23.html">releaselog/3_6_23.html</a></li><li>version 3.6.23 - <a href="releaselog/3_6_23.html">releaselog/3_6_23.html</a></li><li>Version 3.6.23.1 - <a href="releaselog/3_6_23_1.html">releaselog/3_6_23_1.html</a></li><li>version 3.6.23.1 - <a href="releaselog/3_6_23_1.html">releaselog/3_6_23_1.html</a></li><li>Version 3.6.23.1.0 - <a href="releaselog/3_6_23_1.html">releaselog/3_6_23_1.html</a></li><li>version 3.6.23.1.0 - <a href="releaselog/3_6_23_1.html">releaselog/3_6_23_1.html</a></li><li>Version 3.7.0 - <a href="releaselog/3_7_0.html">releaselog/3_7_0.html</a></li><li>version 3.7.0 - <a href="releaselog/3_7_0.html">releaselog/3_7_0.html</a></li><li>Version 3.7.0.1 - <a href="releaselog/3_7_0_1.html">releaselog/3_7_0_1.html</a></li><li>version 3.7.0.1 - <a href="releaselog/3_7_0_1.html">releaselog/3_7_0_1.html</a></li><li>Version 3.7.1 - <a href="releaselog/3_7_1.html">releaselog/3_7_1.html</a></li><li>version 3.7.1 - <a href="releaselog/3_7_1.html">releaselog/3_7_1.html</a></li><li>Version 3.7.2 - <a href="releaselog/3_7_2.html">releaselog/3_7_2.html</a></li><li>version 3.7.2 - <a href="releaselog/3_7_2.html">releaselog/3_7_2.html</a></li><li>Version 3.7.3 - <a href="releaselog/3_7_3.html">releaselog/3_7_3.html</a></li><li>version 3.7.3 - <a href="releaselog/3_7_3.html">releaselog/3_7_3.html</a></li><li>Version 3.7.4 - <a href="releaselog/3_7_4.html">releaselog/3_7_4.html</a></li><li>version 3.7.4 - <a href="releaselog/3_7_4.html">releaselog/3_7_4.html</a></li><li>Version 3.7.5 - <a href="releaselog/3_7_5.html">releaselog/3_7_5.html</a></li><li>version 3.7.5 - <a href="releaselog/3_7_5.html">releaselog/3_7_5.html</a></li><li>Version 3.7.6 - <a href="releaselog/3_7_6.html">releaselog/3_7_6.html</a></li><li>version 3.7.6 - <a href="releaselog/3_7_6.html">releaselog/3_7_6.html</a></li><li>Version 3.7.6.1 - <a href="releaselog/3_7_6_1.html">releaselog/3_7_6_1.html</a></li><li>version 3.7.6.1 - <a href="releaselog/3_7_6_1.html">releaselog/3_7_6_1.html</a></li><li>Version 3.7.6.2 - <a href="releaselog/3_7_6_2.html">releaselog/3_7_6_2.html</a></li><li>version 3.7.6.2 - <a href="releaselog/3_7_6_2.html">releaselog/3_7_6_2.html</a></li><li>Version 3.7.6.3 - <a href="releaselog/3_7_6_3.html">releaselog/3_7_6_3.html</a></li><li>version 3.7.6.3 - <a href="releaselog/3_7_6_3.html">releaselog/3_7_6_3.html</a></li><li>Version 3.7.7 - <a href="releaselog/3_7_7.html">releaselog/3_7_7.html</a></li><li>version 3.7.7 - <a href="releaselog/3_7_7.html">releaselog/3_7_7.html</a></li><li>Version 3.7.7.1 - <a href="releaselog/3_7_7_1.html">releaselog/3_7_7_1.html</a></li><li>version 3.7.7.1 - <a href="releaselog/3_7_7_1.html">releaselog/3_7_7_1.html</a></li><li>Version 3.7.8 - <a href="releaselog/3_7_8.html">releaselog/3_7_8.html</a></li><li>version 3.7.8 - <a href="releaselog/3_7_8.html">releaselog/3_7_8.html</a></li><li>Version 3.7.9 - <a href="releaselog/3_7_9.html">releaselog/3_7_9.html</a></li><li>version 3.7.9 - <a href="releaselog/3_7_9.html">releaselog/3_7_9.html</a></li><li>Version 3.7.10 - <a href="releaselog/3_7_10.html">releaselog/3_7_10.html</a></li><li>version 3.7.10 - <a href="releaselog/3_7_10.html">releaselog/3_7_10.html</a></li><li>Version 3.7.11 - <a href="releaselog/3_7_11.html">releaselog/3_7_11.html</a></li><li>version 3.7.11 - <a href="releaselog/3_7_11.html">releaselog/3_7_11.html</a></li><li>Version 3.7.12 - <a href="releaselog/3_7_12.html">releaselog/3_7_12.html</a></li><li>version 3.7.12 - <a href="releaselog/3_7_12.html">releaselog/3_7_12.html</a></li><li>Version 3.7.12.1 - <a href="releaselog/3_7_12_1.html">releaselog/3_7_12_1.html</a></li><li>version 3.7.12.1 - <a href="releaselog/3_7_12_1.html">releaselog/3_7_12_1.html</a></li><li>Version 3.7.13 - <a href="releaselog/3_7_13.html">releaselog/3_7_13.html</a></li><li>version 3.7.13 - <a href="releaselog/3_7_13.html">releaselog/3_7_13.html</a></li><li>Version 3.7.14 - <a href="releaselog/3_7_14.html">releaselog/3_7_14.html</a></li><li>version 3.7.14 - <a href="releaselog/3_7_14.html">releaselog/3_7_14.html</a></li><li>Version 3.7.14.1 - <a href="releaselog/3_7_14_1.html">releaselog/3_7_14_1.html</a></li><li>version 3.7.14.1 - <a href="releaselog/3_7_14_1.html">releaselog/3_7_14_1.html</a></li><li>Version 3.7.15 - <a href="releaselog/3_7_15.html">releaselog/3_7_15.html</a></li><li>version 3.7.15 - <a href="releaselog/3_7_15.html">releaselog/3_7_15.html</a></li><li>Version 3.7.15.1 - <a href="releaselog/3_7_15_1.html">releaselog/3_7_15_1.html</a></li><li>version 3.7.15.1 - <a href="releaselog/3_7_15_1.html">releaselog/3_7_15_1.html</a></li><li>Version 3.7.15.2 - <a href="releaselog/3_7_15_2.html">releaselog/3_7_15_2.html</a></li><li>version 3.7.15.2 - <a href="releaselog/3_7_15_2.html">releaselog/3_7_15_2.html</a></li><li>Version 3.7.16 - <a href="releaselog/3_7_16.html">releaselog/3_7_16.html</a></li><li>version 3.7.16 - <a href="releaselog/3_7_16.html">releaselog/3_7_16.html</a></li><li>Version 3.7.16.1 - <a href="releaselog/3_7_16_1.html">releaselog/3_7_16_1.html</a></li><li>version 3.7.16.1 - <a href="releaselog/3_7_16_1.html">releaselog/3_7_16_1.html</a></li><li>Version 3.7.16.2 - <a href="releaselog/3_7_16_2.html">releaselog/3_7_16_2.html</a></li><li>version 3.7.16.2 - <a href="releaselog/3_7_16_2.html">releaselog/3_7_16_2.html</a></li><li>Version 3.7.17 - <a href="releaselog/3_7_17.html">releaselog/3_7_17.html</a></li><li>version 3.7.17 - <a href="releaselog/3_7_17.html">releaselog/3_7_17.html</a></li><li>Version 3.8.0 - <a href="releaselog/3_8_0.html">releaselog/3_8_0.html</a></li><li>version 3.8.0 - <a href="releaselog/3_8_0.html">releaselog/3_8_0.html</a></li><li>Version 3.8.0.1 - <a href="releaselog/3_8_0_1.html">releaselog/3_8_0_1.html</a></li><li>version 3.8.0.1 - <a href="releaselog/3_8_0_1.html">releaselog/3_8_0_1.html</a></li><li>Version 3.8.0.2 - <a href="releaselog/3_8_0_2.html">releaselog/3_8_0_2.html</a></li><li>version 3.8.0.2 - <a href="releaselog/3_8_0_2.html">releaselog/3_8_0_2.html</a></li><li>Version 3.8.1 - <a href="releaselog/3_8_1.html">releaselog/3_8_1.html</a></li><li>version 3.8.1 - <a href="releaselog/3_8_1.html">releaselog/3_8_1.html</a></li><li>Version 3.8.2 - <a href="releaselog/3_8_2.html">releaselog/3_8_2.html</a></li><li>version 3.8.2 - <a href="releaselog/3_8_2.html">releaselog/3_8_2.html</a></li><li>Version 3.8.3 - <a href="releaselog/3_8_3.html">releaselog/3_8_3.html</a></li><li>version 3.8.3 - <a href="releaselog/3_8_3.html">releaselog/3_8_3.html</a></li><li>Version 3.8.3.1 - <a href="releaselog/3_8_3_1.html">releaselog/3_8_3_1.html</a></li><li>version 3.8.3.1 - <a href="releaselog/3_8_3_1.html">releaselog/3_8_3_1.html</a></li><li>Version 3.8.3.1.0 - <a href="releaselog/3_8_3_1.html">releaselog/3_8_3_1.html</a></li><li>version 3.8.3.1.0 - <a href="releaselog/3_8_3_1.html">releaselog/3_8_3_1.html</a></li><li>Version 3.8.4 - <a href="releaselog/3_8_4.html">releaselog/3_8_4.html</a></li><li>version 3.8.4 - <a href="releaselog/3_8_4.html">releaselog/3_8_4.html</a></li><li>Version 3.8.4.1 - <a href="releaselog/3_8_4_1.html">releaselog/3_8_4_1.html</a></li><li>version 3.8.4.1 - <a href="releaselog/3_8_4_1.html">releaselog/3_8_4_1.html</a></li><li>Version 3.8.4.2 - <a href="releaselog/3_8_4_2.html">releaselog/3_8_4_2.html</a></li><li>version 3.8.4.2 - <a href="releaselog/3_8_4_2.html">releaselog/3_8_4_2.html</a></li><li>Version 3.8.4.3 - <a href="releaselog/3_8_4_3.html">releaselog/3_8_4_3.html</a></li><li>version 3.8.4.3 - <a href="releaselog/3_8_4_3.html">releaselog/3_8_4_3.html</a></li><li>Version 3.8.5 - <a href="releaselog/3_8_5.html">releaselog/3_8_5.html</a></li><li>version 3.8.5 - <a href="releaselog/3_8_5.html">releaselog/3_8_5.html</a></li><li>Version 3.8.6 - <a href="releaselog/3_8_6.html">releaselog/3_8_6.html</a></li><li>version 3.8.6 - <a href="releaselog/3_8_6.html">releaselog/3_8_6.html</a></li><li>Version 3.8.7 - <a href="releaselog/3_8_7.html">releaselog/3_8_7.html</a></li><li>version 3.8.7 - <a href="releaselog/3_8_7.html">releaselog/3_8_7.html</a></li><li>Version 3.8.7.1 - <a href="releaselog/3_8_7_1.html">releaselog/3_8_7_1.html</a></li><li>version 3.8.7.1 - <a href="releaselog/3_8_7_1.html">releaselog/3_8_7_1.html</a></li><li>Version 3.8.7.2 - <a href="releaselog/3_8_7_2.html">releaselog/3_8_7_2.html</a></li><li>version 3.8.7.2 - <a href="releaselog/3_8_7_2.html">releaselog/3_8_7_2.html</a></li><li>Version 3.8.7.3 - <a href="releaselog/3_8_7_3.html">releaselog/3_8_7_3.html</a></li><li>version 3.8.7.3 - <a href="releaselog/3_8_7_3.html">releaselog/3_8_7_3.html</a></li><li>Version 3.8.7.4 - <a href="releaselog/3_8_7_4.html">releaselog/3_8_7_4.html</a></li><li>version 3.8.7.4 - <a href="releaselog/3_8_7_4.html">releaselog/3_8_7_4.html</a></li><li>Version 3.8.8 - <a href="releaselog/3_8_8.html">releaselog/3_8_8.html</a></li><li>version 3.8.8 - <a href="releaselog/3_8_8.html">releaselog/3_8_8.html</a></li><li>Version 3.8.8.1 - <a href="releaselog/3_8_8_1.html">releaselog/3_8_8_1.html</a></li><li>version 3.8.8.1 - <a href="releaselog/3_8_8_1.html">releaselog/3_8_8_1.html</a></li><li>Version 3.8.8.2 - <a href="releaselog/3_8_8_2.html">releaselog/3_8_8_2.html</a></li><li>version 3.8.8.2 - <a href="releaselog/3_8_8_2.html">releaselog/3_8_8_2.html</a></li><li>Version 3.8.8.3 - <a href="releaselog/3_8_8_3.html">releaselog/3_8_8_3.html</a></li><li>version 3.8.8.3 - <a href="releaselog/3_8_8_3.html">releaselog/3_8_8_3.html</a></li><li>Version 3.8.9 - <a href="releaselog/3_8_9.html">releaselog/3_8_9.html</a></li><li>version 3.8.9 - <a href="releaselog/3_8_9.html">releaselog/3_8_9.html</a></li><li>Version 3.8.10 - <a href="releaselog/3_8_10.html">releaselog/3_8_10.html</a></li><li>version 3.8.10 - <a href="releaselog/3_8_10.html">releaselog/3_8_10.html</a></li><li>Version 3.8.10.1 - <a href="releaselog/3_8_10_1.html">releaselog/3_8_10_1.html</a></li><li>version 3.8.10.1 - <a href="releaselog/3_8_10_1.html">releaselog/3_8_10_1.html</a></li><li>Version 3.8.10.2 - <a href="releaselog/3_8_10_2.html">releaselog/3_8_10_2.html</a></li><li>version 3.8.10.2 - <a href="releaselog/3_8_10_2.html">releaselog/3_8_10_2.html</a></li><li>Version 3.8.11 - <a href="releaselog/3_8_11.html">releaselog/3_8_11.html</a></li><li>version 3.8.11 - <a href="releaselog/3_8_11.html">releaselog/3_8_11.html</a></li><li>Version 3.8.11.1 - <a href="releaselog/3_8_11_1.html">releaselog/3_8_11_1.html</a></li><li>version 3.8.11.1 - <a href="releaselog/3_8_11_1.html">releaselog/3_8_11_1.html</a></li><li>Version 3.9.0 - <a href="releaselog/3_9_0.html">releaselog/3_9_0.html</a></li><li>version 3.9.0 - <a href="releaselog/3_9_0.html">releaselog/3_9_0.html</a></li><li>Version 3.9.1 - <a href="releaselog/3_9_1.html">releaselog/3_9_1.html</a></li><li>version 3.9.1 - <a href="releaselog/3_9_1.html">releaselog/3_9_1.html</a></li><li>Version 3.9.2 - <a href="releaselog/3_9_2.html">releaselog/3_9_2.html</a></li><li>version 3.9.2 - <a href="releaselog/3_9_2.html">releaselog/3_9_2.html</a></li><li>Version 3.9.3 - <a href="releaselog/3_9_3.html">releaselog/3_9_3.html</a></li><li>version 3.9.3 - <a href="releaselog/3_9_3.html">releaselog/3_9_3.html</a></li><li>Version 3.10.0 - <a href="releaselog/3_10_0.html">releaselog/3_10_0.html</a></li><li>version 3.10.0 - <a href="releaselog/3_10_0.html">releaselog/3_10_0.html</a></li><li>Version 3.10.1 - <a href="releaselog/3_10_1.html">releaselog/3_10_1.html</a></li><li>version 3.10.1 - <a href="releaselog/3_10_1.html">releaselog/3_10_1.html</a></li><li>Version 3.10.2 - <a href="releaselog/3_10_2.html">releaselog/3_10_2.html</a></li><li>version 3.10.2 - <a href="releaselog/3_10_2.html">releaselog/3_10_2.html</a></li><li>Version 3.11.0 - <a href="releaselog/3_11_0.html">releaselog/3_11_0.html</a></li><li>version 3.11.0 - <a href="releaselog/3_11_0.html">releaselog/3_11_0.html</a></li><li>Version 3.11.1 - <a href="releaselog/3_11_1.html">releaselog/3_11_1.html</a></li><li>version 3.11.1 - <a href="releaselog/3_11_1.html">releaselog/3_11_1.html</a></li><li>Version 3.12.0 - <a href="releaselog/3_12_0.html">releaselog/3_12_0.html</a></li><li>version 3.12.0 - <a href="releaselog/3_12_0.html">releaselog/3_12_0.html</a></li><li>version 3.12.0 page size change - <a href="pgszchng2016.html">pgszchng2016.html</a></li><li>Version 3.12.1 - <a href="releaselog/3_12_1.html">releaselog/3_12_1.html</a></li><li>version 3.12.1 - <a href="releaselog/3_12_1.html">releaselog/3_12_1.html</a></li><li>Version 3.12.2 - <a href="releaselog/3_12_2.html">releaselog/3_12_2.html</a></li><li>version 3.12.2 - <a href="releaselog/3_12_2.html">releaselog/3_12_2.html</a></li><li>Version 3.13.0 - <a href="releaselog/3_13_0.html">releaselog/3_13_0.html</a></li><li>version 3.13.0 - <a href="releaselog/3_13_0.html">releaselog/3_13_0.html</a></li><li>Version 3.13.0.0 - <a href="releaselog/3_13_0.html">releaselog/3_13_0.html</a></li><li>version 3.13.0.0 - <a href="releaselog/3_13_0.html">releaselog/3_13_0.html</a></li><li>Version 3.14 - <a href="releaselog/3_14.html">releaselog/3_14.html</a></li><li>version 3.14 - <a href="releaselog/3_14.html">releaselog/3_14.html</a></li><li>Version 3.14.0 - <a href="releaselog/3_14.html">releaselog/3_14.html</a></li><li>version 3.14.0 - <a href="releaselog/3_14.html">releaselog/3_14.html</a></li><li>Version 3.14.1 - <a href="releaselog/3_14_1.html">releaselog/3_14_1.html</a></li><li>version 3.14.1 - <a href="releaselog/3_14_1.html">releaselog/3_14_1.html</a></li><li>Version 3.14.2 - <a href="releaselog/3_14_2.html">releaselog/3_14_2.html</a></li><li>version 3.14.2 - <a href="releaselog/3_14_2.html">releaselog/3_14_2.html</a></li><li>Version 3.15.0 - <a href="releaselog/3_15_0.html">releaselog/3_15_0.html</a></li><li>version 3.15.0 - <a href="releaselog/3_15_0.html">releaselog/3_15_0.html</a></li><li>Version 3.15.1 - <a href="releaselog/3_15_1.html">releaselog/3_15_1.html</a></li><li>version 3.15.1 - <a href="releaselog/3_15_1.html">releaselog/3_15_1.html</a></li><li>Version 3.15.2 - <a href="releaselog/3_15_2.html">releaselog/3_15_2.html</a></li><li>version 3.15.2 - <a href="releaselog/3_15_2.html">releaselog/3_15_2.html</a></li><li>Version 3.16.0 - <a href="releaselog/3_16_0.html">releaselog/3_16_0.html</a></li><li>version 3.16.0 - <a href="releaselog/3_16_0.html">releaselog/3_16_0.html</a></li><li>Version 3.16.1 - <a href="releaselog/3_16_1.html">releaselog/3_16_1.html</a></li><li>version 3.16.1 - <a href="releaselog/3_16_1.html">releaselog/3_16_1.html</a></li><li>Version 3.16.2 - <a href="releaselog/3_16_2.html">releaselog/3_16_2.html</a></li><li>version 3.16.2 - <a href="releaselog/3_16_2.html">releaselog/3_16_2.html</a></li><li>Version 3.17.0 - <a href="releaselog/3_17_0.html">releaselog/3_17_0.html</a></li><li>version 3.17.0 - <a href="releaselog/3_17_0.html">releaselog/3_17_0.html</a></li><li>Version 3.18.0 - <a href="releaselog/3_18_0.html">releaselog/3_18_0.html</a></li><li>version 3.18.0 - <a href="releaselog/3_18_0.html">releaselog/3_18_0.html</a></li><li>Version 3.18.1 - <a href="releaselog/3_18_1.html">releaselog/3_18_1.html</a></li><li>version 3.18.1 - <a href="releaselog/3_18_1.html">releaselog/3_18_1.html</a></li><li>Version 3.18.2 - <a href="releaselog/3_18_2.html">releaselog/3_18_2.html</a></li><li>version 3.18.2 - <a href="releaselog/3_18_2.html">releaselog/3_18_2.html</a></li><li>Version 3.19.0 - <a href="releaselog/3_19_0.html">releaselog/3_19_0.html</a></li><li>version 3.19.0 - <a href="releaselog/3_19_0.html">releaselog/3_19_0.html</a></li><li>Version 3.19.1 - <a href="releaselog/3_19_1.html">releaselog/3_19_1.html</a></li><li>version 3.19.1 - <a href="releaselog/3_19_1.html">releaselog/3_19_1.html</a></li><li>Version 3.19.2 - <a href="releaselog/3_19_2.html">releaselog/3_19_2.html</a></li><li>version 3.19.2 - <a href="releaselog/3_19_2.html">releaselog/3_19_2.html</a></li><li>Version 3.19.3 - <a href="releaselog/3_19_3.html">releaselog/3_19_3.html</a></li><li>version 3.19.3 - <a href="releaselog/3_19_3.html">releaselog/3_19_3.html</a></li><li>Version 3.20.0 - <a href="releaselog/3_20_0.html">releaselog/3_20_0.html</a></li><li>version 3.20.0 - <a href="releaselog/3_20_0.html">releaselog/3_20_0.html</a></li><li>Version 3.20.1 - <a href="releaselog/3_20_1.html">releaselog/3_20_1.html</a></li><li>version 3.20.1 - <a href="releaselog/3_20_1.html">releaselog/3_20_1.html</a></li><li>Version 3.21.0 - <a href="releaselog/3_21_0.html">releaselog/3_21_0.html</a></li><li>version 3.21.0 - <a href="releaselog/3_21_0.html">releaselog/3_21_0.html</a></li><li>Version 3.22.0 - <a href="releaselog/3_22_0.html">releaselog/3_22_0.html</a></li><li>version 3.22.0 - <a href="releaselog/3_22_0.html">releaselog/3_22_0.html</a></li><li>Version 3.23.0 - <a href="releaselog/3_23_0.html">releaselog/3_23_0.html</a></li><li>version 3.23.0 - <a href="releaselog/3_23_0.html">releaselog/3_23_0.html</a></li><li>Version 3.23.0.0 - <a href="releaselog/3_23_0.html">releaselog/3_23_0.html</a></li><li>version 3.23.0.0 - <a href="releaselog/3_23_0.html">releaselog/3_23_0.html</a></li><li>Version 3.23.1 - <a href="releaselog/3_23_1.html">releaselog/3_23_1.html</a></li><li>version 3.23.1 - <a href="releaselog/3_23_1.html">releaselog/3_23_1.html</a></li><li>Version 3.23.1.0 - <a href="releaselog/3_23_1.html">releaselog/3_23_1.html</a></li><li>version 3.23.1.0 - <a href="releaselog/3_23_1.html">releaselog/3_23_1.html</a></li><li>Version 3.24.0 - <a href="releaselog/3_24_0.html">releaselog/3_24_0.html</a></li><li>version 3.24.0 - <a href="releaselog/3_24_0.html">releaselog/3_24_0.html</a></li><li>Version 3.25.0 - <a href="releaselog/3_25_0.html">releaselog/3_25_0.html</a></li><li>version 3.25.0 - <a href="releaselog/3_25_0.html">releaselog/3_25_0.html</a></li><li>Version 3.25.1 - <a href="releaselog/3_25_1.html">releaselog/3_25_1.html</a></li><li>version 3.25.1 - <a href="releaselog/3_25_1.html">releaselog/3_25_1.html</a></li><li>Version 3.25.2 - <a href="releaselog/3_25_2.html">releaselog/3_25_2.html</a></li><li>version 3.25.2 - <a href="releaselog/3_25_2.html">releaselog/3_25_2.html</a></li><li>Version 3.25.3 - <a href="releaselog/3_25_3.html">releaselog/3_25_3.html</a></li><li>version 3.25.3 - <a href="releaselog/3_25_3.html">releaselog/3_25_3.html</a></li><li>Version 3.26.0 - <a href="releaselog/3_26_0.html">releaselog/3_26_0.html</a></li><li>version 3.26.0 - <a href="releaselog/3_26_0.html">releaselog/3_26_0.html</a></li><li>Version 3.27.0 - <a href="releaselog/3_27_0.html">releaselog/3_27_0.html</a></li><li>version 3.27.0 - <a href="releaselog/3_27_0.html">releaselog/3_27_0.html</a></li><li>Version 3.27.1 - <a href="releaselog/3_27_1.html">releaselog/3_27_1.html</a></li><li>version 3.27.1 - <a href="releaselog/3_27_1.html">releaselog/3_27_1.html</a></li><li>Version 3.27.2 - <a href="releaselog/3_27_2.html">releaselog/3_27_2.html</a></li><li>version 3.27.2 - <a href="releaselog/3_27_2.html">releaselog/3_27_2.html</a></li><li>Version 3.28.0 - <a href="releaselog/3_28_0.html">releaselog/3_28_0.html</a></li><li>version 3.28.0 - <a href="releaselog/3_28_0.html">releaselog/3_28_0.html</a></li><li>Version 3.29.0 - <a href="releaselog/3_29_0.html">releaselog/3_29_0.html</a></li><li>version 3.29.0 - <a href="releaselog/3_29_0.html">releaselog/3_29_0.html</a></li><li>Version 3.30.0 - <a href="releaselog/3_30_0.html">releaselog/3_30_0.html</a></li><li>version 3.30.0 - <a href="releaselog/3_30_0.html">releaselog/3_30_0.html</a></li><li>Version 3.30.1 - <a href="releaselog/3_30_1.html">releaselog/3_30_1.html</a></li><li>version 3.30.1 - <a href="releaselog/3_30_1.html">releaselog/3_30_1.html</a></li><li>Version 3.31.0 - <a href="releaselog/3_31_0.html">releaselog/3_31_0.html</a></li><li>version 3.31.0 - <a href="releaselog/3_31_0.html">releaselog/3_31_0.html</a></li><li>Version 3.31.1 - <a href="releaselog/3_31_1.html">releaselog/3_31_1.html</a></li><li>version 3.31.1 - <a href="releaselog/3_31_1.html">releaselog/3_31_1.html</a></li><li>Version 3.32.0 - <a href="releaselog/3_32_0.html">releaselog/3_32_0.html</a></li><li>version 3.32.0 - <a href="releaselog/3_32_0.html">releaselog/3_32_0.html</a></li><li>Version 3.32.1 - <a href="releaselog/3_32_1.html">releaselog/3_32_1.html</a></li><li>version 3.32.1 - <a href="releaselog/3_32_1.html">releaselog/3_32_1.html</a></li><li>Version 3.32.2 - <a href="releaselog/3_32_2.html">releaselog/3_32_2.html</a></li><li>version 3.32.2 - <a href="releaselog/3_32_2.html">releaselog/3_32_2.html</a></li><li>Version 3.32.3 - <a href="releaselog/3_32_3.html">releaselog/3_32_3.html</a></li><li>version 3.32.3 - <a href="releaselog/3_32_3.html">releaselog/3_32_3.html</a></li><li>Version 3.33.0 - <a href="releaselog/3_33_0.html">releaselog/3_33_0.html</a></li><li>version 3.33.0 - <a href="releaselog/3_33_0.html">releaselog/3_33_0.html</a></li><li>Version 3.33.0.0 - <a href="releaselog/3_33_0.html">releaselog/3_33_0.html</a></li><li>version 3.33.0.0 - <a href="releaselog/3_33_0.html">releaselog/3_33_0.html</a></li><li>Version 3.34.0 - <a href="releaselog/3_34_0.html">releaselog/3_34_0.html</a></li><li>version 3.34.0 - <a href="releaselog/3_34_0.html">releaselog/3_34_0.html</a></li><li>Version 3.34.1 - <a href="releaselog/3_34_1.html">releaselog/3_34_1.html</a></li><li>version 3.34.1 - <a href="releaselog/3_34_1.html">releaselog/3_34_1.html</a></li><li>Version 3.35.0 - <a href="releaselog/3_35_0.html">releaselog/3_35_0.html</a></li><li>version 3.35.0 - <a href="releaselog/3_35_0.html">releaselog/3_35_0.html</a></li><li>Version 3.35.1 - <a href="releaselog/3_35_1.html">releaselog/3_35_1.html</a></li><li>version 3.35.1 - <a href="releaselog/3_35_1.html">releaselog/3_35_1.html</a></li><li>Version 3.35.2 - <a href="releaselog/3_35_2.html">releaselog/3_35_2.html</a></li><li>version 3.35.2 - <a href="releaselog/3_35_2.html">releaselog/3_35_2.html</a></li><li>Version 3.35.3 - <a href="releaselog/3_35_3.html">releaselog/3_35_3.html</a></li><li>version 3.35.3 - <a href="releaselog/3_35_3.html">releaselog/3_35_3.html</a></li><li>Version 3.35.4 - <a href="releaselog/3_35_4.html">releaselog/3_35_4.html</a></li><li>version 3.35.4 - <a href="releaselog/3_35_4.html">releaselog/3_35_4.html</a></li><li>Version 3.35.5 - <a href="releaselog/3_35_5.html">releaselog/3_35_5.html</a></li><li>version 3.35.5 - <a href="releaselog/3_35_5.html">releaselog/3_35_5.html</a></li><li>Version 3.36.0 - <a href="releaselog/3_36_0.html">releaselog/3_36_0.html</a></li><li>version 3.36.0 - <a href="releaselog/3_36_0.html">releaselog/3_36_0.html</a></li><li>Version 3.37.0 - <a href="releaselog/3_37_0.html">releaselog/3_37_0.html</a></li><li>version 3.37.0 - <a href="releaselog/3_37_0.html">releaselog/3_37_0.html</a></li><li>Version 3.37.1 - <a href="releaselog/3_37_1.html">releaselog/3_37_1.html</a></li><li>version 3.37.1 - <a href="releaselog/3_37_1.html">releaselog/3_37_1.html</a></li><li>Version 3.37.2 - <a href="releaselog/3_37_2.html">releaselog/3_37_2.html</a></li><li>version 3.37.2 - <a href="releaselog/3_37_2.html">releaselog/3_37_2.html</a></li><li>Version 3.38.0 - <a href="releaselog/3_38_0.html">releaselog/3_38_0.html</a></li><li>version 3.38.0 - <a href="releaselog/3_38_0.html">releaselog/3_38_0.html</a></li><li>Version 3.38.1 - <a href="releaselog/3_38_1.html">releaselog/3_38_1.html</a></li><li>version 3.38.1 - <a href="releaselog/3_38_1.html">releaselog/3_38_1.html</a></li><li>Version 3.38.2 - <a href="releaselog/3_38_2.html">releaselog/3_38_2.html</a></li><li>version 3.38.2 - <a href="releaselog/3_38_2.html">releaselog/3_38_2.html</a></li><li>Version 3.38.3 - <a href="releaselog/3_38_3.html">releaselog/3_38_3.html</a></li><li>version 3.38.3 - <a href="releaselog/3_38_3.html">releaselog/3_38_3.html</a></li><li>Version 3.38.4 - <a href="releaselog/3_38_4.html">releaselog/3_38_4.html</a></li><li>version 3.38.4 - <a href="releaselog/3_38_4.html">releaselog/3_38_4.html</a></li><li>Version 3.38.5 - <a href="releaselog/3_38_5.html">releaselog/3_38_5.html</a></li><li>version 3.38.5 - <a href="releaselog/3_38_5.html">releaselog/3_38_5.html</a></li><li>Version 3.39.0 - <a href="releaselog/3_39_0.html">releaselog/3_39_0.html</a></li><li>version 3.39.0 - <a href="releaselog/3_39_0.html">releaselog/3_39_0.html</a></li><li>Version 3.39.1 - <a href="releaselog/3_39_1.html">releaselog/3_39_1.html</a></li><li>version 3.39.1 - <a href="releaselog/3_39_1.html">releaselog/3_39_1.html</a></li><li>Version 3.39.2 - <a href="releaselog/3_39_2.html">releaselog/3_39_2.html</a></li><li>version 3.39.2 - <a href="releaselog/3_39_2.html">releaselog/3_39_2.html</a></li><li>Version 3.39.3 - <a href="releaselog/3_39_3.html">releaselog/3_39_3.html</a></li><li>version 3.39.3 - <a href="releaselog/3_39_3.html">releaselog/3_39_3.html</a></li><li>Version 3.39.4 - <a href="releaselog/3_39_4.html">releaselog/3_39_4.html</a></li><li>version 3.39.4 - <a href="releaselog/3_39_4.html">releaselog/3_39_4.html</a></li><li>Version 3.40.0 - <a href="releaselog/3_40_0.html">releaselog/3_40_0.html</a></li><li>version 3.40.0 - <a href="releaselog/3_40_0.html">releaselog/3_40_0.html</a></li><li>Version 3.40.1 - <a href="releaselog/3_40_1.html">releaselog/3_40_1.html</a></li><li>version 3.40.1 - <a href="releaselog/3_40_1.html">releaselog/3_40_1.html</a></li><li>Version 3.41.0 - <a href="releaselog/3_41_0.html">releaselog/3_41_0.html</a></li><li>version 3.41.0 - <a href="releaselog/3_41_0.html">releaselog/3_41_0.html</a></li><li>Version 3.41.1 - <a href="releaselog/3_41_1.html">releaselog/3_41_1.html</a></li><li>version 3.41.1 - <a href="releaselog/3_41_1.html">releaselog/3_41_1.html</a></li><li>Version 3.41.2 - <a href="releaselog/3_41_2.html">releaselog/3_41_2.html</a></li><li>version 3.41.2 - <a href="releaselog/3_41_2.html">releaselog/3_41_2.html</a></li><li>Version 3.42.0 - <a href="releaselog/3_42_0.html">releaselog/3_42_0.html</a></li><li>version 3.42.0 - <a href="releaselog/3_42_0.html">releaselog/3_42_0.html</a></li><li>Version 3.43.0 - <a href="releaselog/3_43_0.html">releaselog/3_43_0.html</a></li><li>version 3.43.0 - <a href="releaselog/3_43_0.html">releaselog/3_43_0.html</a></li><li>Version 3.43.0.0 - <a href="releaselog/3_43_0.html">releaselog/3_43_0.html</a></li><li>version 3.43.0.0 - <a href="releaselog/3_43_0.html">releaselog/3_43_0.html</a></li><li>Version 3.43.1 - <a href="releaselog/3_43_1.html">releaselog/3_43_1.html</a></li><li>version 3.43.1 - <a href="releaselog/3_43_1.html">releaselog/3_43_1.html</a></li><li>Version 3.43.1.0 - <a href="releaselog/3_43_1.html">releaselog/3_43_1.html</a></li><li>version 3.43.1.0 - <a href="releaselog/3_43_1.html">releaselog/3_43_1.html</a></li><li>Version 3.43.2 - <a href="releaselog/3_43_2.html">releaselog/3_43_2.html</a></li><li>version 3.43.2 - <a href="releaselog/3_43_2.html">releaselog/3_43_2.html</a></li><li>Version 3.43.2.0 - <a href="releaselog/3_43_2.html">releaselog/3_43_2.html</a></li><li>version 3.43.2.0 - <a href="releaselog/3_43_2.html">releaselog/3_43_2.html</a></li><li>Version 3.44.0 - <a href="releaselog/3_44_0.html">releaselog/3_44_0.html</a></li><li>version 3.44.0 - <a href="releaselog/3_44_0.html">releaselog/3_44_0.html</a></li><li>Version 3.44.1 - <a href="releaselog/3_44_1.html">releaselog/3_44_1.html</a></li><li>version 3.44.1 - <a href="releaselog/3_44_1.html">releaselog/3_44_1.html</a></li><li>Version 3.44.2 - <a href="releaselog/3_44_2.html">releaselog/3_44_2.html</a></li><li>version 3.44.2 - <a href="releaselog/3_44_2.html">releaselog/3_44_2.html</a></li><li>Version 3.45.0 - <a href="releaselog/3_45_0.html">releaselog/3_45_0.html</a></li><li>version 3.45.0 - <a href="releaselog/3_45_0.html">releaselog/3_45_0.html</a></li><li>Version 3.45.1 - <a href="releaselog/3_45_1.html">releaselog/3_45_1.html</a></li><li>version 3.45.1 - <a href="releaselog/3_45_1.html">releaselog/3_45_1.html</a></li><li>Version 3.45.2 - <a href="releaselog/3_45_2.html">releaselog/3_45_2.html</a></li><li>version 3.45.2 - <a href="releaselog/3_45_2.html">releaselog/3_45_2.html</a></li><li>Version 3.45.3 - <a href="releaselog/3_45_3.html">releaselog/3_45_3.html</a></li><li>version 3.45.3 - <a href="releaselog/3_45_3.html">releaselog/3_45_3.html</a></li><li>version method - <a href="tclsqlite.html#version">tclsqlite.html#version</a></li><li>version numbering conventions - <a href="versionnumbers.html">versionnumbers.html</a></li><li>version-valid-for number - <a href="fileformat2.html#validfor">fileformat2.html#validfor</a></li><li>VFS - <a href="vfs.html">vfs.html</a></li><li>vfs query parameter - <a href="uri.html#urivfs">uri.html#urivfs</a></li><li>VFS shim - <a href="vfs.html#shim">vfs.html#shim</a></li><li>VFS shims - <a href="vfs.html#shim">vfs.html#shim</a></li><li>VFSes - <a href="vfs.html">vfs.html</a></li><li>VIEW - <a href="lang_createview.html">lang_createview.html</a></li><li>view - <a href="lang_createview.html">lang_createview.html</a></li><li>views - <a href="lang_createview.html">lang_createview.html</a></li><li>virtual machine - <a href="opcode.html">opcode.html</a></li><li>virtual machine instructions - <a href="opcode.html">opcode.html</a></li><li>virtual table - <a href="vtab.html">vtab.html</a></li><li>virtual table configuration option - <a href="c3ref/c_vtab_constraint_support.html">c3ref/c_vtab_constraint_support.html</a></li><li>virtual table configuration options - <a href="c3ref/c_vtab_constraint_support.html">c3ref/c_vtab_constraint_support.html</a></li><li>virtual table cursor - <a href="c3ref/vtab_cursor.html">c3ref/vtab_cursor.html</a></li><li>virtual table list - <a href="vtablist.html">vtablist.html</a></li><li>virtual table module - <a href="c3ref/module.html">c3ref/module.html</a></li><li>virtual tables - <a href="vtab.html">vtab.html</a></li><li>vulnerabilities - <a href="cves.html">cves.html</a></li><li>w - <a href="printf.html#percentw">printf.html#percentw</a></li><li>WAL - <a href="wal.html">wal.html</a></li><li>WAL backwards compatibility - <a href="wal.html#bkwrds">wal.html#bkwrds</a></li><li>WAL checksum algorithm - <a href="fileformat2.html#walcksm">fileformat2.html#walcksm</a></li><li>WAL concurrency - <a href="wal.html#concurrency">wal.html#concurrency</a></li><li>WAL file - <a href="wal.html#walfile">wal.html#walfile</a></li><li>WAL file format - <a href="fileformat2.html#walformat">fileformat2.html#walformat</a></li><li>WAL format - <a href="fileformat2.html#walformat">fileformat2.html#walformat</a></li><li>WAL mode - <a href="wal.html">wal.html</a></li><li>WAL read algorithm - <a href="fileformat2.html#walread">fileformat2.html#walread</a></li><li>WAL reset - <a href="fileformat2.html#walreset">fileformat2.html#walreset</a></li><li>WAL without shared memory - <a href="wal.html#noshm">wal.html#noshm</a></li><li>wal-index - <a href="walformat.html#shm">walformat.html#shm</a></li><li>WAL-index File Format - <a href="walformat.html#walidxfmt">walformat.html#walidxfmt</a></li><li>WAL-index format - <a href="walformat.html#walidxfmt">walformat.html#walidxfmt</a></li><li>WAL-mode crash recovery - <a href="walformat.html#recovery">walformat.html#recovery</a></li><li>WAL-mode File Format - <a href="walformat.html">walformat.html</a></li><li>WAL-mode locks - <a href="walformat.html#locks">walformat.html#locks</a></li><li>WAL-mode read blocking - <a href="wal.html#busy">wal.html#busy</a></li><li>wal_autocheckpoint - <a href="pragma.html#pragma_wal_autocheckpoint">pragma.html#pragma_wal_autocheckpoint</a></li><li>wal_autocheckpoint pragma - <a href="pragma.html#pragma_wal_autocheckpoint">pragma.html#pragma_wal_autocheckpoint</a></li><li>wal_checkpoint - <a href="pragma.html#pragma_wal_checkpoint">pragma.html#pragma_wal_checkpoint</a></li><li>wal_checkpoint pragma - <a href="pragma.html#pragma_wal_checkpoint">pragma.html#pragma_wal_checkpoint</a></li><li>wal_hook method - <a href="tclsqlite.html#wal_hook">tclsqlite.html#wal_hook</a></li><li>Warranty of Title - <a href="copyright.html#warrantyoftitle">copyright.html#warrantyoftitle</a></li><li>What If OpenOffice Used SQLite - <a href="affcase1.html">affcase1.html</a></li><li>when to use WITHOUT ROWID - <a href="withoutrowid.html#wtu">withoutrowid.html#wtu</a></li><li>WHERE clause - <a href="lang_select.html#whereclause">lang_select.html#whereclause</a></li><li>why ALTER TABLE is so difficult - <a href="lang_altertable.html#altertableishard">lang_altertable.html#altertableishard</a></li><li>Win32 native memory allocator - <a href="malloc.html#win32heap">malloc.html#win32heap</a></li><li>window chaining - <a href="windowfunctions.html#wchaining">windowfunctions.html#wchaining</a></li><li>window function - <a href="windowfunctions.html">windowfunctions.html</a></li><li>Window functions - <a href="windowfunctions.html">windowfunctions.html</a></li><li>window functions - <a href="windowfunctions.html">windowfunctions.html</a></li><li>window-defn - <a href="syntax/window-defn.html">syntax/window-defn.html</a></li><li>window-defn syntax diagram - <a href="syntax/window-defn.html">syntax/window-defn.html</a></li><li>window-function-invocation - <a href="syntax/window-function-invocation.html">syntax/window-function-invocation.html</a></li><li>window-function-invocation syntax diagram - <a href="syntax/window-function-invocation.html">syntax/window-function-invocation.html</a></li><li>WITH - <a href="lang_with.html">lang_with.html</a></li><li>with - <a href="lang_with.html">lang_with.html</a></li><li>WITH clause - <a href="lang_with.html">lang_with.html</a></li><li>with-clause - <a href="syntax/with-clause.html">syntax/with-clause.html</a></li><li>with-clause syntax diagram - <a href="syntax/with-clause.html">syntax/with-clause.html</a></li><li>WITHOUT ROWID - <a href="withoutrowid.html">withoutrowid.html</a></li><li>WITHOUT rowid - <a href="withoutrowid.html">withoutrowid.html</a></li><li>WITHOUT ROWID virtual table - <a href="vtab.html#worid">vtab.html#worid</a></li><li>WITHOUT ROWID virtual tables - <a href="vtab.html#worid">vtab.html#worid</a></li><li>wrapping text - <a href="cli.html#wrap1">cli.html#wrap1</a></li><li>writable_schema - <a href="pragma.html#pragma_writable_schema">pragma.html#pragma_writable_schema</a></li><li>writable_schema pragma - <a href="pragma.html#pragma_writable_schema">pragma.html#pragma_writable_schema</a></li><li>write-ahead log - <a href="wal.html">wal.html</a></li><li>writer starvation - <a href="lockingv3.html#writer_starvation">lockingv3.html#writer_starvation</a></li><li>xBegin - <a href="vtab.html#xBegin">vtab.html#xBegin</a></li><li>xBestIndex - <a href="vtab.html#xbestindex">vtab.html#xbestindex</a></li><li>xColumn - <a href="vtab.html#xcolumn">vtab.html#xcolumn</a></li><li>xCommit - <a href="vtab.html#xcommit">vtab.html#xcommit</a></li><li>xConnect - <a href="vtab.html#xconnect">vtab.html#xconnect</a></li><li>xCreate - <a href="vtab.html#xcreate">vtab.html#xcreate</a></li><li>xDestroy - <a href="vtab.html#sqlite3_module.xDestroy">vtab.html#sqlite3_module.xDestroy</a></li><li>xDisconnect - <a href="vtab.html#xdisconnect">vtab.html#xdisconnect</a></li><li>xEof - <a href="vtab.html#xeof">vtab.html#xeof</a></li><li>xFilter - <a href="vtab.html#xfilter">vtab.html#xfilter</a></li><li>xFindFunction - <a href="vtab.html#xfindfunction">vtab.html#xfindfunction</a></li><li>xIntegrity - <a href="vtab.html#xintegrity">vtab.html#xintegrity</a></li><li>xIntegrity method - <a href="vtab.html#xintegrity">vtab.html#xintegrity</a></li><li>xNext - <a href="vtab.html#xnext">vtab.html#xnext</a></li><li>xQueryFunc RTree callback - <a href="rtree.html#xquery">rtree.html#xquery</a></li><li>xRelease - <a href="vtab.html#xsavepoint">vtab.html#xsavepoint</a></li><li>xRename - <a href="vtab.html#xrename">vtab.html#xrename</a></li><li>xRollback - <a href="vtab.html#xrollback">vtab.html#xrollback</a></li><li>xRollbackTo - <a href="vtab.html#xsavepoint">vtab.html#xsavepoint</a></li><li>xRowid - <a href="vtab.html#xrowid">vtab.html#xrowid</a></li><li>xSavepoint - <a href="vtab.html#xsavepoint">vtab.html#xsavepoint</a></li><li>xShadowName - <a href="vtab.html#xshadowname">vtab.html#xshadowname</a></li><li>xUpdate - <a href="vtab.html#xupdate">vtab.html#xupdate</a></li><li>YYSTACKDEPTH - <a href="compile.html#yystackdepth">compile.html#yystackdepth</a></li><li>YYTRACKMAXSTACKDEPTH - <a href="compile.html#yytrackmaxstackdepth">compile.html#yytrackmaxstackdepth</a></li><li>z - <a href="printf.html#percentz">printf.html#percentz</a></li><li>zero-configuration - <a href="zeroconf.html">zeroconf.html</a></li><li>zero-malloc memory allocator - <a href="malloc.html#memsys5">malloc.html#memsys5</a></li><li>zeroblob - <a href="lang_corefunc.html#zeroblob">lang_corefunc.html#zeroblob</a></li><li>zeroblob SQL function - <a href="lang_corefunc.html#zeroblob">lang_corefunc.html#zeroblob</a></li><li>ZIP file as database - <a href="cli.html#zipdb">cli.html#zipdb</a></li><li>zipfile - <a href="zipfile.html">zipfile.html</a></li><li>Zipfile virtual table - <a href="zipfile.html">zipfile.html</a></li></ul><p align="center"><small><i>This page last modified on <a href="https://sqlite.org/docsrc/honeypot" id="mtimelink" data-href="https://sqlite.org/docsrc/finfo/wrap.tcl?m=08af34fe24">2023-03-31 19:57:15</a> UTC </small></i></p> +<ul><li>--insert option - <a href="cli.html#arinsup">cli.html#arinsup</a></li><li>--safe command-line option - <a href="cli.html#safemode">cli.html#safemode</a></li><li>--unsafe-testing command-line option - <a href="cli.html#testing_mode">cli.html#testing_mode</a></li><li>--update option - <a href="cli.html#arinsup">cli.html#arinsup</a></li><li>-DHAVE_FDATASYNC - <a href="compile.html#fdatasync">compile.html#fdatasync</a></li><li>-DHAVE_GMTIME_R - <a href="compile.html#gmtime_r">compile.html#gmtime_r</a></li><li>-DHAVE_ISNAN - <a href="compile.html#isnan">compile.html#isnan</a></li><li>-DHAVE_LOCALTIME_R - <a href="compile.html#localtime_r">compile.html#localtime_r</a></li><li>-DHAVE_LOCALTIME_S - <a href="compile.html#localtime_s">compile.html#localtime_s</a></li><li>-DHAVE_MALLOC_USABLE_SIZE - <a href="compile.html#malloc_usable_size">compile.html#malloc_usable_size</a></li><li>-DHAVE_SQLITE_CONFIG_H - <a href="compile.html#sqlite_config_h">compile.html#sqlite_config_h</a></li><li>-DHAVE_STRCHRNUL - <a href="compile.html#strchrnul">compile.html#strchrnul</a></li><li>-DHAVE_UTIME - <a href="compile.html#utime">compile.html#utime</a></li><li>-DSQLITE_4_BYTE_ALIGNED_MALLOC - <a href="compile.html#4_byte_aligned_malloc">compile.html#4_byte_aligned_malloc</a></li><li>-DSQLITE_ALLOW_COVERING_INDEX_SCAN - <a href="compile.html#allow_covering_index_scan">compile.html#allow_covering_index_scan</a></li><li>-DSQLITE_ALLOW_URI_AUTHORITY - <a href="compile.html#allow_uri_authority">compile.html#allow_uri_authority</a></li><li>-DSQLITE_API - <a href="compile.html#api">compile.html#api</a></li><li>-DSQLITE_APICALL - <a href="compile.html#apicall">compile.html#apicall</a></li><li>-DSQLITE_BYTEORDER - <a href="compile.html#byteorder">compile.html#byteorder</a></li><li>-DSQLITE_CALLBACK - <a href="compile.html#callback">compile.html#callback</a></li><li>-DSQLITE_CASE_SENSITIVE_LIKE - <a href="compile.html#case_sensitive_like">compile.html#case_sensitive_like</a></li><li>-DSQLITE_CDECL - <a href="compile.html#cdecl">compile.html#cdecl</a></li><li>-DSQLITE_DEBUG - <a href="compile.html#debug">compile.html#debug</a></li><li>-DSQLITE_DEFAULT_AUTOMATIC_INDEX - <a href="compile.html#default_automatic_index">compile.html#default_automatic_index</a></li><li>-DSQLITE_DEFAULT_AUTOVACUUM - <a href="compile.html#default_autovacuum">compile.html#default_autovacuum</a></li><li>-DSQLITE_DEFAULT_CACHE_SIZE - <a href="compile.html#default_cache_size">compile.html#default_cache_size</a></li><li>-DSQLITE_DEFAULT_FILE_FORMAT - <a href="compile.html#default_file_format">compile.html#default_file_format</a></li><li>-DSQLITE_DEFAULT_FILE_PERMISSIONS - <a href="compile.html#default_file_permissions">compile.html#default_file_permissions</a></li><li>-DSQLITE_DEFAULT_FOREIGN_KEYS - <a href="compile.html#default_foreign_keys">compile.html#default_foreign_keys</a></li><li>-DSQLITE_DEFAULT_JOURNAL_SIZE_LIMIT - <a href="compile.html#default_journal_size_limit">compile.html#default_journal_size_limit</a></li><li>-DSQLITE_DEFAULT_LOCKING_MODE - <a href="compile.html#default_locking_mode">compile.html#default_locking_mode</a></li><li>-DSQLITE_DEFAULT_LOOKASIDE - <a href="compile.html#default_lookaside">compile.html#default_lookaside</a></li><li>-DSQLITE_DEFAULT_MEMSTATUS - <a href="compile.html#default_memstatus">compile.html#default_memstatus</a></li><li>-DSQLITE_DEFAULT_MMAP_SIZE - <a href="compile.html#default_mmap_size">compile.html#default_mmap_size</a></li><li>-DSQLITE_DEFAULT_PAGE_SIZE - <a href="compile.html#default_page_size">compile.html#default_page_size</a></li><li>-DSQLITE_DEFAULT_PCACHE_INITSZ - <a href="compile.html#default_pcache_initsz">compile.html#default_pcache_initsz</a></li><li>-DSQLITE_DEFAULT_SYNCHRONOUS - <a href="compile.html#default_synchronous">compile.html#default_synchronous</a></li><li>-DSQLITE_DEFAULT_WAL_AUTOCHECKPOINT - <a href="compile.html#default_wal_autocheckpoint">compile.html#default_wal_autocheckpoint</a></li><li>-DSQLITE_DEFAULT_WAL_SYNCHRONOUS - <a href="compile.html#default_wal_synchronous">compile.html#default_wal_synchronous</a></li><li>-DSQLITE_DEFAULT_WORKER_THREADS - <a href="compile.html#default_worker_threads">compile.html#default_worker_threads</a></li><li>-DSQLITE_DIRECT_OVERFLOW_READ - <a href="compile.html#direct_overflow_read">compile.html#direct_overflow_read</a></li><li>-DSQLITE_DISABLE_DIRSYNC - <a href="compile.html#disable_dirsync">compile.html#disable_dirsync</a></li><li>-DSQLITE_DISABLE_FTS3_UNICODE - <a href="compile.html#disable_fts3_unicode">compile.html#disable_fts3_unicode</a></li><li>-DSQLITE_DISABLE_FTS4_DEFERRED - <a href="compile.html#disable_fts4_deferred">compile.html#disable_fts4_deferred</a></li><li>-DSQLITE_DISABLE_INTRINSIC - <a href="compile.html#disable_intrinsic">compile.html#disable_intrinsic</a></li><li>-DSQLITE_DISABLE_LFS - <a href="compile.html#disable_lfs">compile.html#disable_lfs</a></li><li>-DSQLITE_DISABLE_PAGECACHE_OVERFLOW_STATS - <a href="compile.html#disable_pagecache_overflow_stats">compile.html#disable_pagecache_overflow_stats</a></li><li>-DSQLITE_DQS - <a href="compile.html#dqs">compile.html#dqs</a></li><li>-DSQLITE_ENABLE_8_3_NAMES - <a href="compile.html#enable_8_3_names">compile.html#enable_8_3_names</a></li><li>-DSQLITE_ENABLE_API_ARMOR - <a href="compile.html#enable_api_armor">compile.html#enable_api_armor</a></li><li>-DSQLITE_ENABLE_ATOMIC_WRITE - <a href="compile.html#enable_atomic_write">compile.html#enable_atomic_write</a></li><li>-DSQLITE_ENABLE_BATCH_ATOMIC_WRITE - <a href="compile.html#enable_batch_atomic_write">compile.html#enable_batch_atomic_write</a></li><li>-DSQLITE_ENABLE_BYTECODE_VTAB - <a href="compile.html#enable_bytecode_vtab">compile.html#enable_bytecode_vtab</a></li><li>-DSQLITE_ENABLE_COLUMN_METADATA - <a href="compile.html#enable_column_metadata">compile.html#enable_column_metadata</a></li><li>-DSQLITE_ENABLE_DBPAGE_VTAB - <a href="compile.html#enable_dbpage_vtab">compile.html#enable_dbpage_vtab</a></li><li>-DSQLITE_ENABLE_DBSTAT_VTAB - <a href="compile.html#enable_dbstat_vtab">compile.html#enable_dbstat_vtab</a></li><li>-DSQLITE_ENABLE_DESERIALIZE - <a href="compile.html#enable_deserialize">compile.html#enable_deserialize</a></li><li>-DSQLITE_ENABLE_EXPLAIN_COMMENTS - <a href="compile.html#enable_explain_comments">compile.html#enable_explain_comments</a></li><li>-DSQLITE_ENABLE_FTS3 - <a href="compile.html#enable_fts3">compile.html#enable_fts3</a></li><li>-DSQLITE_ENABLE_FTS3_PARENTHESIS - <a href="compile.html#enable_fts3_parenthesis">compile.html#enable_fts3_parenthesis</a></li><li>-DSQLITE_ENABLE_FTS3_TOKENIZER - <a href="compile.html#enable_fts3_tokenizer">compile.html#enable_fts3_tokenizer</a></li><li>-DSQLITE_ENABLE_FTS4 - <a href="compile.html#enable_fts4">compile.html#enable_fts4</a></li><li>-DSQLITE_ENABLE_FTS5 - <a href="compile.html#enable_fts5">compile.html#enable_fts5</a></li><li>-DSQLITE_ENABLE_GEOPOLY - <a href="compile.html#enable_geopoly">compile.html#enable_geopoly</a></li><li>-DSQLITE_ENABLE_HIDDEN_COLUMNS - <a href="compile.html#enable_hidden_columns">compile.html#enable_hidden_columns</a></li><li>-DSQLITE_ENABLE_ICU - <a href="compile.html#enable_icu">compile.html#enable_icu</a></li><li>-DSQLITE_ENABLE_IOTRACE - <a href="compile.html#enable_iotrace">compile.html#enable_iotrace</a></li><li>-DSQLITE_ENABLE_JSON1 - <a href="compile.html#enable_json1">compile.html#enable_json1</a></li><li>-DSQLITE_ENABLE_LOCKING_STYLE - <a href="compile.html#enable_locking_style">compile.html#enable_locking_style</a></li><li>-DSQLITE_ENABLE_MATH_FUNCTIONS - <a href="compile.html#enable_math_functions">compile.html#enable_math_functions</a></li><li>-DSQLITE_ENABLE_MEMORY_MANAGEMENT - <a href="compile.html#enable_memory_management">compile.html#enable_memory_management</a></li><li>-DSQLITE_ENABLE_MEMSYS3 - <a href="compile.html#enable_memsys3">compile.html#enable_memsys3</a></li><li>-DSQLITE_ENABLE_MEMSYS5 - <a href="compile.html#enable_memsys5">compile.html#enable_memsys5</a></li><li>-DSQLITE_ENABLE_NORMALIZE - <a href="compile.html#enable_normalize">compile.html#enable_normalize</a></li><li>-DSQLITE_ENABLE_NULL_TRIM - <a href="compile.html#enable_null_trim">compile.html#enable_null_trim</a></li><li>-DSQLITE_ENABLE_OFFSET_SQL_FUNC - <a href="compile.html#enable_offset_sql_func">compile.html#enable_offset_sql_func</a></li><li>-DSQLITE_ENABLE_PREUPDATE_HOOK - <a href="compile.html#enable_preupdate_hook">compile.html#enable_preupdate_hook</a></li><li>-DSQLITE_ENABLE_QPSG - <a href="compile.html#enable_qpsg">compile.html#enable_qpsg</a></li><li>-DSQLITE_ENABLE_RBU - <a href="compile.html#enable_rbu">compile.html#enable_rbu</a></li><li>-DSQLITE_ENABLE_RTREE - <a href="compile.html#enable_rtree">compile.html#enable_rtree</a></li><li>-DSQLITE_ENABLE_SESSION - <a href="compile.html#enable_session">compile.html#enable_session</a></li><li>-DSQLITE_ENABLE_SNAPSHOT - <a href="compile.html#enable_snapshot">compile.html#enable_snapshot</a></li><li>-DSQLITE_ENABLE_SORTER_REFERENCES - <a href="compile.html#enable_sorter_references">compile.html#enable_sorter_references</a></li><li>-DSQLITE_ENABLE_SQLLOG - <a href="compile.html#enable_sqllog">compile.html#enable_sqllog</a></li><li>-DSQLITE_ENABLE_STAT2 - <a href="compile.html#enable_stat2">compile.html#enable_stat2</a></li><li>-DSQLITE_ENABLE_STAT3 - <a href="compile.html#enable_stat3">compile.html#enable_stat3</a></li><li>-DSQLITE_ENABLE_STAT4 - <a href="compile.html#enable_stat4">compile.html#enable_stat4</a></li><li>-DSQLITE_ENABLE_STMT_SCANSTATUS - <a href="compile.html#enable_stmt_scanstatus">compile.html#enable_stmt_scanstatus</a></li><li>-DSQLITE_ENABLE_STMTVTAB - <a href="compile.html#enable_stmtvtab">compile.html#enable_stmtvtab</a></li><li>-DSQLITE_ENABLE_TREE_EXPLAIN - <a href="compile.html#enable_tree_explain">compile.html#enable_tree_explain</a></li><li>-DSQLITE_ENABLE_UNKNOWN_SQL_FUNCTION - <a href="compile.html#enable_unknown_sql_function">compile.html#enable_unknown_sql_function</a></li><li>-DSQLITE_ENABLE_UNLOCK_NOTIFY - <a href="compile.html#enable_unlock_notify">compile.html#enable_unlock_notify</a></li><li>-DSQLITE_ENABLE_UPDATE_DELETE_LIMIT - <a href="compile.html#enable_update_delete_limit">compile.html#enable_update_delete_limit</a></li><li>-DSQLITE_EXTERN - <a href="compile.html#extern">compile.html#extern</a></li><li>-DSQLITE_EXTRA_DURABLE - <a href="compile.html#extra_durable">compile.html#extra_durable</a></li><li>-DSQLITE_FTS3_MAX_EXPR_DEPTH - <a href="compile.html#fts3_max_expr_depth">compile.html#fts3_max_expr_depth</a></li><li>-DSQLITE_HAVE_ISNAN - <a href="compile.html#have_isnan">compile.html#have_isnan</a></li><li>-DSQLITE_HAVE_ZLIB - <a href="compile.html#have_zlib">compile.html#have_zlib</a></li><li>-DSQLITE_INTROSPECTION_PRAGMAS - <a href="compile.html#introspection_pragmas">compile.html#introspection_pragmas</a></li><li>-DSQLITE_JSON_MAX_DEPTH - <a href="compile.html#json_max_depth">compile.html#json_max_depth</a></li><li>-DSQLITE_LIKE_DOESNT_MATCH_BLOBS - <a href="compile.html#like_doesnt_match_blobs">compile.html#like_doesnt_match_blobs</a></li><li>-DSQLITE_MAX_ALLOCATION_SIZE - <a href="compile.html#max_allocation_size">compile.html#max_allocation_size</a></li><li>-DSQLITE_MAX_MEMORY - <a href="compile.html#max_memory">compile.html#max_memory</a></li><li>-DSQLITE_MAX_MMAP_SIZE - <a href="compile.html#max_mmap_size">compile.html#max_mmap_size</a></li><li>-DSQLITE_MAX_SCHEMA_RETRY - <a href="compile.html#max_schema_retry">compile.html#max_schema_retry</a></li><li>-DSQLITE_MAX_WORKER_THREADS - <a href="compile.html#max_worker_threads">compile.html#max_worker_threads</a></li><li>-DSQLITE_MEMDB_DEFAULT_MAXSIZE - <a href="compile.html#memdb_default_maxsize">compile.html#memdb_default_maxsize</a></li><li>-DSQLITE_MEMDEBUG - <a href="compile.html#memdebug">compile.html#memdebug</a></li><li>-DSQLITE_MINIMUM_FILE_DESCRIPTOR - <a href="compile.html#minimum_file_descriptor">compile.html#minimum_file_descriptor</a></li><li>-DSQLITE_OMIT_ALTERTABLE - <a href="compile.html#omit_altertable">compile.html#omit_altertable</a></li><li>-DSQLITE_OMIT_ANALYZE - <a href="compile.html#omit_analyze">compile.html#omit_analyze</a></li><li>-DSQLITE_OMIT_ATTACH - <a href="compile.html#omit_attach">compile.html#omit_attach</a></li><li>-DSQLITE_OMIT_AUTHORIZATION - <a href="compile.html#omit_authorization">compile.html#omit_authorization</a></li><li>-DSQLITE_OMIT_AUTOINCREMENT - <a href="compile.html#omit_autoincrement">compile.html#omit_autoincrement</a></li><li>-DSQLITE_OMIT_AUTOINIT - <a href="compile.html#omit_autoinit">compile.html#omit_autoinit</a></li><li>-DSQLITE_OMIT_AUTOMATIC_INDEX - <a href="compile.html#omit_automatic_index">compile.html#omit_automatic_index</a></li><li>-DSQLITE_OMIT_AUTORESET - <a href="compile.html#omit_autoreset">compile.html#omit_autoreset</a></li><li>-DSQLITE_OMIT_AUTOVACUUM - <a href="compile.html#omit_autovacuum">compile.html#omit_autovacuum</a></li><li>-DSQLITE_OMIT_BETWEEN_OPTIMIZATION - <a href="compile.html#omit_between_optimization">compile.html#omit_between_optimization</a></li><li>-DSQLITE_OMIT_BLOB_LITERAL - <a href="compile.html#omit_blob_literal">compile.html#omit_blob_literal</a></li><li>-DSQLITE_OMIT_BTREECOUNT - <a href="compile.html#omit_btreecount">compile.html#omit_btreecount</a></li><li>-DSQLITE_OMIT_BUILTIN_TEST - <a href="compile.html#omit_builtin_test">compile.html#omit_builtin_test</a></li><li>-DSQLITE_OMIT_CASE_SENSITIVE_LIKE_PRAGMA - <a href="compile.html#omit_case_sensitive_like_pragma">compile.html#omit_case_sensitive_like_pragma</a></li><li>-DSQLITE_OMIT_CAST - <a href="compile.html#omit_cast">compile.html#omit_cast</a></li><li>-DSQLITE_OMIT_CHECK - <a href="compile.html#omit_check">compile.html#omit_check</a></li><li>-DSQLITE_OMIT_COMPILEOPTION_DIAGS - <a href="compile.html#omit_compileoption_diags">compile.html#omit_compileoption_diags</a></li><li>-DSQLITE_OMIT_COMPLETE - <a href="compile.html#omit_complete">compile.html#omit_complete</a></li><li>-DSQLITE_OMIT_COMPOUND_SELECT - <a href="compile.html#omit_compound_select">compile.html#omit_compound_select</a></li><li>-DSQLITE_OMIT_CTE - <a href="compile.html#omit_cte">compile.html#omit_cte</a></li><li>-DSQLITE_OMIT_DATETIME_FUNCS - <a href="compile.html#omit_datetime_funcs">compile.html#omit_datetime_funcs</a></li><li>-DSQLITE_OMIT_DECLTYPE - <a href="compile.html#omit_decltype">compile.html#omit_decltype</a></li><li>-DSQLITE_OMIT_DEPRECATED - <a href="compile.html#omit_deprecated">compile.html#omit_deprecated</a></li><li>-DSQLITE_OMIT_DESERIALIZE - <a href="compile.html#omit_deserialize">compile.html#omit_deserialize</a></li><li>-DSQLITE_OMIT_DISKIO - <a href="compile.html#omit_diskio">compile.html#omit_diskio</a></li><li>-DSQLITE_OMIT_EXPLAIN - <a href="compile.html#omit_explain">compile.html#omit_explain</a></li><li>-DSQLITE_OMIT_FLAG_PRAGMAS - <a href="compile.html#omit_flag_pragmas">compile.html#omit_flag_pragmas</a></li><li>-DSQLITE_OMIT_FLOATING_POINT - <a href="compile.html#omit_floating_point">compile.html#omit_floating_point</a></li><li>-DSQLITE_OMIT_FOREIGN_KEY - <a href="compile.html#omit_foreign_key">compile.html#omit_foreign_key</a></li><li>-DSQLITE_OMIT_GENERATED_COLUMNS - <a href="compile.html#omit_generated_columns">compile.html#omit_generated_columns</a></li><li>-DSQLITE_OMIT_GET_TABLE - <a href="compile.html#omit_get_table">compile.html#omit_get_table</a></li><li>-DSQLITE_OMIT_HEX_INTEGER - <a href="compile.html#omit_hex_integer">compile.html#omit_hex_integer</a></li><li>-DSQLITE_OMIT_INCRBLOB - <a href="compile.html#omit_incrblob">compile.html#omit_incrblob</a></li><li>-DSQLITE_OMIT_INTEGRITY_CHECK - <a href="compile.html#omit_integrity_check">compile.html#omit_integrity_check</a></li><li>-DSQLITE_OMIT_INTROSPECTION_PRAGMAS - <a href="compile.html#omit_introspection_pragmas">compile.html#omit_introspection_pragmas</a></li><li>-DSQLITE_OMIT_JSON - <a href="compile.html#omit_json">compile.html#omit_json</a></li><li>-DSQLITE_OMIT_LIKE_OPTIMIZATION - <a href="compile.html#omit_like_optimization">compile.html#omit_like_optimization</a></li><li>-DSQLITE_OMIT_LOAD_EXTENSION - <a href="compile.html#omit_load_extension">compile.html#omit_load_extension</a></li><li>-DSQLITE_OMIT_LOCALTIME - <a href="compile.html#omit_localtime">compile.html#omit_localtime</a></li><li>-DSQLITE_OMIT_LOOKASIDE - <a href="compile.html#omit_lookaside">compile.html#omit_lookaside</a></li><li>-DSQLITE_OMIT_MEMORYDB - <a href="compile.html#omit_memorydb">compile.html#omit_memorydb</a></li><li>-DSQLITE_OMIT_OR_OPTIMIZATION - <a href="compile.html#omit_or_optimization">compile.html#omit_or_optimization</a></li><li>-DSQLITE_OMIT_PAGER_PRAGMAS - <a href="compile.html#omit_pager_pragmas">compile.html#omit_pager_pragmas</a></li><li>-DSQLITE_OMIT_PRAGMA - <a href="compile.html#omit_pragma">compile.html#omit_pragma</a></li><li>-DSQLITE_OMIT_PROGRESS_CALLBACK - <a href="compile.html#omit_progress_callback">compile.html#omit_progress_callback</a></li><li>-DSQLITE_OMIT_QUICKBALANCE - <a href="compile.html#omit_quickbalance">compile.html#omit_quickbalance</a></li><li>-DSQLITE_OMIT_REINDEX - <a href="compile.html#omit_reindex">compile.html#omit_reindex</a></li><li>-DSQLITE_OMIT_SCHEMA_PRAGMAS - <a href="compile.html#omit_schema_pragmas">compile.html#omit_schema_pragmas</a></li><li>-DSQLITE_OMIT_SCHEMA_VERSION_PRAGMAS - <a href="compile.html#omit_schema_version_pragmas">compile.html#omit_schema_version_pragmas</a></li><li>-DSQLITE_OMIT_SHARED_CACHE - <a href="compile.html#omit_shared_cache">compile.html#omit_shared_cache</a></li><li>-DSQLITE_OMIT_SUBQUERY - <a href="compile.html#omit_subquery">compile.html#omit_subquery</a></li><li>-DSQLITE_OMIT_TCL_VARIABLE - <a href="compile.html#omit_tcl_variable">compile.html#omit_tcl_variable</a></li><li>-DSQLITE_OMIT_TEMPDB - <a href="compile.html#omit_tempdb">compile.html#omit_tempdb</a></li><li>-DSQLITE_OMIT_TRACE - <a href="compile.html#omit_trace">compile.html#omit_trace</a></li><li>-DSQLITE_OMIT_TRIGGER - <a href="compile.html#omit_trigger">compile.html#omit_trigger</a></li><li>-DSQLITE_OMIT_TRUNCATE_OPTIMIZATION - <a href="compile.html#omit_truncate_optimization">compile.html#omit_truncate_optimization</a></li><li>-DSQLITE_OMIT_UTF16 - <a href="compile.html#omit_utf16">compile.html#omit_utf16</a></li><li>-DSQLITE_OMIT_VACUUM - <a href="compile.html#omit_vacuum">compile.html#omit_vacuum</a></li><li>-DSQLITE_OMIT_VIEW - <a href="compile.html#omit_view">compile.html#omit_view</a></li><li>-DSQLITE_OMIT_VIRTUALTABLE - <a href="compile.html#omit_virtualtable">compile.html#omit_virtualtable</a></li><li>-DSQLITE_OMIT_WAL - <a href="compile.html#omit_wal">compile.html#omit_wal</a></li><li>-DSQLITE_OMIT_WINDOWFUNC - <a href="compile.html#omit_windowfunc">compile.html#omit_windowfunc</a></li><li>-DSQLITE_OMIT_WSD - <a href="compile.html#omit_wsd">compile.html#omit_wsd</a></li><li>-DSQLITE_OMIT_XFER_OPT - <a href="compile.html#omit_xfer_opt">compile.html#omit_xfer_opt</a></li><li>-DSQLITE_OS_OTHER - <a href="compile.html#os_other">compile.html#os_other</a></li><li>-DSQLITE_POWERSAFE_OVERWRITE - <a href="compile.html#powersafe_overwrite">compile.html#powersafe_overwrite</a></li><li>-DSQLITE_PRINTF_PRECISION_LIMIT - <a href="compile.html#printf_precision_limit">compile.html#printf_precision_limit</a></li><li>-DSQLITE_QUERY_PLANNER_LIMIT - <a href="compile.html#query_planner_limit">compile.html#query_planner_limit</a></li><li>-DSQLITE_QUERY_PLANNER_LIMIT_INCR - <a href="compile.html#query_planner_limit_incr">compile.html#query_planner_limit_incr</a></li><li>-DSQLITE_REVERSE_UNORDERED_SELECTS - <a href="compile.html#reverse_unordered_selects">compile.html#reverse_unordered_selects</a></li><li>-DSQLITE_RTREE_INT_ONLY - <a href="compile.html#rtree_int_only">compile.html#rtree_int_only</a></li><li>-DSQLITE_SECURE_DELETE - <a href="compile.html#secure_delete">compile.html#secure_delete</a></li><li>-DSQLITE_SORTER_PMASZ - <a href="compile.html#sorter_pmasz">compile.html#sorter_pmasz</a></li><li>-DSQLITE_SOUNDEX - <a href="compile.html#soundex">compile.html#soundex</a></li><li>-DSQLITE_STDCALL - <a href="compile.html#stdcall">compile.html#stdcall</a></li><li>-DSQLITE_STMTJRNL_SPILL - <a href="compile.html#stmtjrnl_spill">compile.html#stmtjrnl_spill</a></li><li>-DSQLITE_STRICT_SUBTYPE - <a href="compile.html#strict_subtype">compile.html#strict_subtype</a></li><li>-DSQLITE_SYSAPI - <a href="compile.html#sysapi">compile.html#sysapi</a></li><li>-DSQLITE_TCLAPI - <a href="compile.html#tclapi">compile.html#tclapi</a></li><li>-DSQLITE_TEMP_STORE - <a href="compile.html#temp_store">compile.html#temp_store</a></li><li>-DSQLITE_THREADSAFE - <a href="compile.html#threadsafe">compile.html#threadsafe</a></li><li>-DSQLITE_TRACE_SIZE_LIMIT - <a href="compile.html#trace_size_limit">compile.html#trace_size_limit</a></li><li>-DSQLITE_TRUSTED_SCHEMA - <a href="compile.html#trusted_schema">compile.html#trusted_schema</a></li><li>-DSQLITE_UNTESTABLE - <a href="compile.html#untestable">compile.html#untestable</a></li><li>-DSQLITE_USE_ALLOCA - <a href="compile.html#use_alloca">compile.html#use_alloca</a></li><li>-DSQLITE_USE_FCNTL_TRACE - <a href="compile.html#use_fcntl_trace">compile.html#use_fcntl_trace</a></li><li>-DSQLITE_USE_SEH - <a href="compile.html#use_seh">compile.html#use_seh</a></li><li>-DSQLITE_USE_URI - <a href="compile.html#use_uri">compile.html#use_uri</a></li><li>-DSQLITE_WIN32_HEAP_CREATE - <a href="compile.html#win32_heap_create">compile.html#win32_heap_create</a></li><li>-DSQLITE_WIN32_MALLOC - <a href="compile.html#win32_malloc">compile.html#win32_malloc</a></li><li>-DSQLITE_WIN32_MALLOC_VALIDATE - <a href="compile.html#win32_malloc_validate">compile.html#win32_malloc_validate</a></li><li>-DSQLITE_ZERO_MALLOC - <a href="compile.html#zero_malloc">compile.html#zero_malloc</a></li><li>.archive command - <a href="cli.html#sqlar">cli.html#sqlar</a></li><li>.connection - <a href="cli.html#dotconn">cli.html#dotconn</a></li><li>.databases - <a href="cli.html#dotdatabases">cli.html#dotdatabases</a></li><li>.databases command - <a href="cli.html#dotdatabases">cli.html#dotdatabases</a></li><li>.dump - <a href="cli.html#dump">cli.html#dump</a></li><li>.excel - <a href="cli.html#dotexcel">cli.html#dotexcel</a></li><li>.expert command - <a href="cli.html#expert">cli.html#expert</a></li><li>.fullschema - <a href="cli.html#fullschema">cli.html#fullschema</a></li><li>.import - <a href="cli.html#csv">cli.html#csv</a></li><li>.import command - <a href="cli.html#csv">cli.html#csv</a></li><li>.imposter dot-command - <a href="imposter.html#dotimposter">imposter.html#dotimposter</a></li><li>.load command - <a href="cli.html#dotload">cli.html#dotload</a></li><li>.mode - <a href="cli.html#dotmode">cli.html#dotmode</a></li><li>.mode quote - <a href="cli.html#dotmodequote">cli.html#dotmodequote</a></li><li>.once - <a href="cli.html#dotoutput">cli.html#dotoutput</a></li><li>.open - <a href="cli.html#dotopen">cli.html#dotopen</a></li><li>.open command - <a href="cli.html#dotopen">cli.html#dotopen</a></li><li>.output - <a href="cli.html#dotoutput">cli.html#dotoutput</a></li><li>.parameter command - <a href="cli.html#param">cli.html#param</a></li><li>.read - <a href="cli.html#dotread">cli.html#dotread</a></li><li>.recover dot-command - <a href="cli.html#recover">cli.html#recover</a></li><li>.schema - <a href="cli.html#dschema">cli.html#dschema</a></li><li>.selftest dot-command - <a href="cli.html#selftest">cli.html#selftest</a></li><li>.sha3sum dot-command - <a href="cli.html#sha3sum">cli.html#sha3sum</a></li><li>.tables - <a href="cli.html#dtables">cli.html#dtables</a></li><li>3rd-party fuzzers - <a href="testing.html#3pfuzz">testing.html#3pfuzz</a></li><li>34to35 - <a href="34to35.html">34to35.html</a></li><li>35 Faster Than The Filesystem - <a href="fasterthanfs.html">fasterthanfs.html</a></li><li>35to36 - <a href="35to36.html">35to36.html</a></li><li>about 200 SQL statements per webpage - <a href="np1queryprob.html">np1queryprob.html</a></li><li>abs - <a href="lang_corefunc.html#abs">lang_corefunc.html#abs</a></li><li>abs SQL function - <a href="lang_corefunc.html#abs">lang_corefunc.html#abs</a></li><li>ACID - <a href="transactional.html">transactional.html</a></li><li>acos - <a href="lang_mathfunc.html#acos">lang_mathfunc.html#acos</a></li><li>acos SQL function - <a href="lang_mathfunc.html#acos">lang_mathfunc.html#acos</a></li><li>acosh - <a href="lang_mathfunc.html#acosh">lang_mathfunc.html#acosh</a></li><li>acosh SQL function - <a href="lang_mathfunc.html#acosh">lang_mathfunc.html#acosh</a></li><li>add column - <a href="lang_altertable.html#altertabaddcol">lang_altertable.html#altertabaddcol</a></li><li>Adding to Zip - <a href="zipfile.html#adding_entries_to_a_zip_archive">zipfile.html#adding_entries_to_a_zip_archive</a></li><li>advanced - <a href="swarmvtab.html#advanced_usage">swarmvtab.html#advanced_usage</a></li><li>advantages of WAL-mode - <a href="wal.html#advantages">wal.html#advantages</a></li><li>affinities - <a href="datatype3.html#affinity">datatype3.html#affinity</a></li><li>affinity - <a href="datatype3.html#affinity">datatype3.html#affinity</a></li><li>affinity in compound VIEWs - <a href="datatype3.html#affcompoundview">datatype3.html#affcompoundview</a></li><li>Affinity Of Expressions - <a href="datatype3.html#expraff">datatype3.html#expraff</a></li><li>affshort - <a href="aff_short.html">aff_short.html</a></li><li>AFL - <a href="testing.html#aflfuzz">testing.html#aflfuzz</a></li><li>aggfunc - <a href="lang_aggfunc.html">lang_aggfunc.html</a></li><li>Aggregate Functions - <a href="lang_aggfunc.html">lang_aggfunc.html</a></li><li>Aggregate functions - <a href="lang_aggfunc.html">lang_aggfunc.html</a></li><li>aggregate functions - <a href="lang_aggfunc.html">lang_aggfunc.html</a></li><li>aggregate JSON SQL functions - <a href="json1.html#jgroupobjectb">json1.html#jgroupobjectb</a></li><li>aggregate SQL functions - <a href="lang_aggfunc.html">lang_aggfunc.html</a></li><li>aggregate window functions - <a href="windowfunctions.html#aggwinfunc">windowfunctions.html#aggwinfunc</a></li><li>aggregate-function-invocation - <a href="syntax/aggregate-function-invocation.html">syntax/aggregate-function-invocation.html</a></li><li>aggregate-function-invocation syntax diagram - <a href="syntax/aggregate-function-invocation.html">syntax/aggregate-function-invocation.html</a></li><li>alphabetical listing of documents - <a href="doclist.html">doclist.html</a></li><li>ALTER - <a href="lang_altertable.html">lang_altertable.html</a></li><li>ALTER TABLE - <a href="lang_altertable.html">lang_altertable.html</a></li><li>ALTER TABLE ADD COLUMN - <a href="lang_altertable.html#altertabaddcol">lang_altertable.html#altertabaddcol</a></li><li>ALTER TABLE DROP COLUMN - <a href="lang_altertable.html#altertabdropcol">lang_altertable.html#altertabdropcol</a></li><li>ALTER TABLE RENAME - <a href="lang_altertable.html#altertabrename">lang_altertable.html#altertabrename</a></li><li>ALTER TABLE RENAME COLUMN - <a href="lang_altertable.html#altertabmvcol">lang_altertable.html#altertabmvcol</a></li><li>ALTER TABLE RENAME documentation - <a href="lang_altertable.html#altertabrename">lang_altertable.html#altertabrename</a></li><li>alter-table-stmt - <a href="syntax/alter-table-stmt.html">syntax/alter-table-stmt.html</a></li><li>alter-table-stmt syntax diagram - <a href="syntax/alter-table-stmt.html">syntax/alter-table-stmt.html</a></li><li>altertable - <a href="lang_altertable.html">lang_altertable.html</a></li><li>amalgamation - <a href="amalgamation.html">amalgamation.html</a></li><li>amalgamation tarball - <a href="download.html">download.html</a></li><li>ambiguous dates - <a href="lang_datefunc.html#dtambg">lang_datefunc.html#dtambg</a></li><li>American Fuzzy Lop fuzzer - <a href="testing.html#aflfuzz">testing.html#aflfuzz</a></li><li>analysis_limit - <a href="pragma.html#pragma_analysis_limit">pragma.html#pragma_analysis_limit</a></li><li>analysis_limit pragma - <a href="pragma.html#pragma_analysis_limit">pragma.html#pragma_analysis_limit</a></li><li>ANALYZE - <a href="lang_analyze.html">lang_analyze.html</a></li><li>analyze - <a href="lang_analyze.html">lang_analyze.html</a></li><li>analyze-stmt - <a href="syntax/analyze-stmt.html">syntax/analyze-stmt.html</a></li><li>analyze-stmt syntax diagram - <a href="syntax/analyze-stmt.html">syntax/analyze-stmt.html</a></li><li>appformat - <a href="appfileformat.html">appfileformat.html</a></li><li>Application File Format - <a href="appfileformat.html">appfileformat.html</a></li><li>application file format - <a href="appfileformat.html">appfileformat.html</a></li><li>application file-format - <a href="appfileformat.html">appfileformat.html</a></li><li>Application ID - <a href="fileformat2.html#appid">fileformat2.html#appid</a></li><li>application-defined function attacks - <a href="appfunc.html#sec">appfunc.html#sec</a></li><li>application-defined SQL function - <a href="appfunc.html">appfunc.html</a></li><li>application-defined SQL functions - <a href="appfunc.html">appfunc.html</a></li><li>application-defined window functions - <a href="windowfunctions.html#udfwinfunc">windowfunctions.html#udfwinfunc</a></li><li>application_id - <a href="pragma.html#pragma_application_id">pragma.html#pragma_application_id</a></li><li>application_id pragma - <a href="pragma.html#pragma_application_id">pragma.html#pragma_application_id</a></li><li>appreciate the freedom - <a href="flextypegood.html">flextypegood.html</a></li><li>Appropriate Uses For SQLite - <a href="whentouse.html">whentouse.html</a></li><li>approximate ANALYZE - <a href="lang_analyze.html#approx">lang_analyze.html#approx</a></li><li>Approximate ANALYZE For Large Databases - <a href="lang_analyze.html#approx">lang_analyze.html#approx</a></li><li>asin - <a href="lang_mathfunc.html#asin">lang_mathfunc.html#asin</a></li><li>asin SQL function - <a href="lang_mathfunc.html#asin">lang_mathfunc.html#asin</a></li><li>asinh - <a href="lang_mathfunc.html#asinh">lang_mathfunc.html#asinh</a></li><li>asinh SQL function - <a href="lang_mathfunc.html#asinh">lang_mathfunc.html#asinh</a></li><li>asynchronous I/O backend - <a href="asyncvfs.html">asyncvfs.html</a></li><li>asynchronous VFS - <a href="asyncvfs.html">asyncvfs.html</a></li><li>atan - <a href="lang_mathfunc.html#atan">lang_mathfunc.html#atan</a></li><li>atan SQL function - <a href="lang_mathfunc.html#atan">lang_mathfunc.html#atan</a></li><li>atan2 - <a href="lang_mathfunc.html#atan2">lang_mathfunc.html#atan2</a></li><li>atan2 SQL function - <a href="lang_mathfunc.html#atan2">lang_mathfunc.html#atan2</a></li><li>atanh - <a href="lang_mathfunc.html#atanh">lang_mathfunc.html#atanh</a></li><li>atanh SQL function - <a href="lang_mathfunc.html#atanh">lang_mathfunc.html#atanh</a></li><li>Atomic Commit - <a href="atomiccommit.html">atomiccommit.html</a></li><li>atomic commit - <a href="atomiccommit.html">atomiccommit.html</a></li><li>ATTACH - <a href="lang_attach.html">lang_attach.html</a></li><li>attach - <a href="lang_attach.html">lang_attach.html</a></li><li>ATTACH DATABASE - <a href="lang_attach.html">lang_attach.html</a></li><li>attach-stmt - <a href="syntax/attach-stmt.html">syntax/attach-stmt.html</a></li><li>attach-stmt syntax diagram - <a href="syntax/attach-stmt.html">syntax/attach-stmt.html</a></li><li>attached - <a href="lang_attach.html">lang_attach.html</a></li><li>attack resistance - <a href="security.html">security.html</a></li><li>authorizer callback - <a href="c3ref/set_authorizer.html">c3ref/set_authorizer.html</a></li><li>authorizer method - <a href="tclsqlite.html#authorizer">tclsqlite.html#authorizer</a></li><li>auto modifier - <a href="lang_datefunc.html#automod">lang_datefunc.html#automod</a></li><li>auto_vacuum - <a href="pragma.html#pragma_auto_vacuum">pragma.html#pragma_auto_vacuum</a></li><li>auto_vacuum pragma - <a href="pragma.html#pragma_auto_vacuum">pragma.html#pragma_auto_vacuum</a></li><li>autocommit mode - <a href="c3ref/get_autocommit.html">c3ref/get_autocommit.html</a></li><li>AUTOINCREMENT - <a href="autoinc.html">autoinc.html</a></li><li>automated undo/redo stack - <a href="undoredo.html">undoredo.html</a></li><li>automatic indexes - <a href="optoverview.html#autoindex">optoverview.html#autoindex</a></li><li>Automatic indexing - <a href="optoverview.html#autoindex">optoverview.html#autoindex</a></li><li>automatic indexing - <a href="optoverview.html#autoindex">optoverview.html#autoindex</a></li><li>automatic_index - <a href="pragma.html#pragma_automatic_index">pragma.html#pragma_automatic_index</a></li><li>automatic_index pragma - <a href="pragma.html#pragma_automatic_index">pragma.html#pragma_automatic_index</a></li><li>Automatically Running ANALYZE - <a href="lang_analyze.html#autoanalyze">lang_analyze.html#autoanalyze</a></li><li>automatically running ANALYZE - <a href="lang_analyze.html#autoanalyze">lang_analyze.html#autoanalyze</a></li><li>automerge command - <a href="fts3.html#*fts4automergecmd">fts3.html#*fts4automergecmd</a></li><li>auxiliary columns - <a href="rtree.html#auxcol">rtree.html#auxcol</a></li><li>auxiliary columns in r-tree tables - <a href="rtree.html#auxcol">rtree.html#auxcol</a></li><li>auxiliary function mapping - <a href="fts5.html#sorting_by_auxiliary_function_results">fts5.html#sorting_by_auxiliary_function_results</a></li><li>avg - <a href="lang_aggfunc.html#avg">lang_aggfunc.html#avg</a></li><li>avg aggregate function - <a href="lang_aggfunc.html#avg">lang_aggfunc.html#avg</a></li><li>avoiding large WAL files - <a href="wal.html#bigwal">wal.html#bigwal</a></li><li>B-tree - <a href="fileformat2.html#btree">fileformat2.html#btree</a></li><li>B-Trees - <a href="fileformat2.html#btree">fileformat2.html#btree</a></li><li>backup API - <a href="backup.html">backup.html</a></li><li>backup method - <a href="tclsqlite.html#backup">tclsqlite.html#backup</a></li><li>bare aggregate terms - <a href="lang_select.html#bareagg">lang_select.html#bareagg</a></li><li>base64 SQL function - <a href="cli.html#base64">cli.html#base64</a></li><li>base85 SQL function - <a href="cli.html#base85">cli.html#base85</a></li><li>bcvtab - <a href="bytecodevtab.html">bytecodevtab.html</a></li><li>BEGIN - <a href="lang_transaction.html">lang_transaction.html</a></li><li>BEGIN EXCLUSIVE - <a href="lang_transaction.html#immediate">lang_transaction.html#immediate</a></li><li>BEGIN IMMEDIATE - <a href="lang_transaction.html#immediate">lang_transaction.html#immediate</a></li><li>begin-stmt - <a href="syntax/begin-stmt.html">syntax/begin-stmt.html</a></li><li>begin-stmt syntax diagram - <a href="syntax/begin-stmt.html">syntax/begin-stmt.html</a></li><li>benefits of using WITHOUT ROWID - <a href="withoutrowid.html#bene">withoutrowid.html#bene</a></li><li>BETWEEN - <a href="lang_expr.html#between">lang_expr.html#between</a></li><li>BINARY - <a href="datatype3.html#collation">datatype3.html#collation</a></li><li>BINARY collating function - <a href="datatype3.html#collation">datatype3.html#collation</a></li><li>binary operators - <a href="lang_expr.html#binaryops">lang_expr.html#binaryops</a></li><li>bind_fallback method - <a href="tclsqlite.html#bind_fallback">tclsqlite.html#bind_fallback</a></li><li>BLOB handle - <a href="c3ref/blob.html">c3ref/blob.html</a></li><li>BLOB handles - <a href="c3ref/blob.html">c3ref/blob.html</a></li><li>BLOB I/O performance - <a href="intern-v-extern-blob.html">intern-v-extern-blob.html</a></li><li>block sorting - <a href="queryplanner.html#partialsort">queryplanner.html#partialsort</a></li><li>books about SQLite - <a href="books.html">books.html</a></li><li>boolean datatype - <a href="datatype3.html#boolean">datatype3.html#boolean</a></li><li>boolean expression - <a href="lang_expr.html#booleanexpr">lang_expr.html#booleanexpr</a></li><li>bound parameter - <a href="lang_expr.html#varparam">lang_expr.html#varparam</a></li><li>bound parameters - <a href="lang_expr.html#varparam">lang_expr.html#varparam</a></li><li>bugs - <a href="fts3.html#limitations">fts3.html#limitations</a></li><li>build product names - <a href="download.html#encoding">download.html#encoding</a></li><li>building a DLL - <a href="howtocompile.html#dll">howtocompile.html#dll</a></li><li>building the amalgamation - <a href="howtocompile.html#amal">howtocompile.html#amal</a></li><li>built-in memory allocators - <a href="malloc.html#altalloc">malloc.html#altalloc</a></li><li>built-in printf - <a href="printf.html">printf.html</a></li><li>built-in SQL math functions - <a href="lang_mathfunc.html">lang_mathfunc.html</a></li><li>built-in window functions - <a href="windowfunctions.html#builtins">windowfunctions.html#builtins</a></li><li>built-ins - <a href="windowfunctions.html#builtins">windowfunctions.html#builtins</a></li><li>builtin window functions - <a href="windowfunctions.html#biwinfunc">windowfunctions.html#biwinfunc</a></li><li>busy handler - <a href="c3ref/busy_handler.html">c3ref/busy_handler.html</a></li><li>busy method - <a href="tclsqlite.html#busy">tclsqlite.html#busy</a></li><li>busy-handler callback - <a href="c3ref/busy_handler.html">c3ref/busy_handler.html</a></li><li>busy_timeout - <a href="pragma.html#pragma_busy_timeout">pragma.html#pragma_busy_timeout</a></li><li>busy_timeout pragma - <a href="pragma.html#pragma_busy_timeout">pragma.html#pragma_busy_timeout</a></li><li>byte-order determination rules - <a href="c3ref/bind_blob.html#byteorderdeterminationrules">c3ref/bind_blob.html#byteorderdeterminationrules</a></li><li>bytecode - <a href="opcode.html">opcode.html</a></li><li>bytecode and tables_used virtual tables - <a href="bytecodevtab.html">bytecodevtab.html</a></li><li>bytecode engine - <a href="opcode.html">opcode.html</a></li><li>bytecode virtual table - <a href="bytecodevtab.html">bytecodevtab.html</a></li><li>bytecodes - <a href="opcode.html">opcode.html</a></li><li>C-API function list - <a href="c3ref/funclist.html">c3ref/funclist.html</a></li><li>C-language Interface - <a href="c3ref/intro.html">c3ref/intro.html</a></li><li>cache method - <a href="tclsqlite.html#cache">tclsqlite.html#cache</a></li><li>cache query parameter - <a href="uri.html#uricache">uri.html#uricache</a></li><li>cache_size - <a href="pragma.html#pragma_cache_size">pragma.html#pragma_cache_size</a></li><li>cache_size pragma - <a href="pragma.html#pragma_cache_size">pragma.html#pragma_cache_size</a></li><li>cache_spill - <a href="pragma.html#pragma_cache_spill">pragma.html#pragma_cache_spill</a></li><li>cache_spill pragma - <a href="pragma.html#pragma_cache_spill">pragma.html#pragma_cache_spill</a></li><li>canonical source code - <a href="getthecode.html">getthecode.html</a></li><li>capi3ref - <a href="c3ref/intro.html">c3ref/intro.html</a></li><li>capi3ref_funclist - <a href="c3ref/funclist.html">c3ref/funclist.html</a></li><li>carray - <a href="carray.html">carray.html</a></li><li>carray table-valued function - <a href="carray.html">carray.html</a></li><li>CASE expression - <a href="lang_expr.html#case">lang_expr.html#case</a></li><li>case_sensitive_like - <a href="pragma.html#pragma_case_sensitive_like">pragma.html#pragma_case_sensitive_like</a></li><li>case_sensitive_like pragma - <a href="pragma.html#pragma_case_sensitive_like">pragma.html#pragma_case_sensitive_like</a></li><li>CAST - <a href="lang_expr.html#castexpr">lang_expr.html#castexpr</a></li><li>cast - <a href="lang_expr.html#castexpr">lang_expr.html#castexpr</a></li><li>CAST expression - <a href="lang_expr.html#castexpr">lang_expr.html#castexpr</a></li><li>CAST operator - <a href="lang_expr.html#castexpr">lang_expr.html#castexpr</a></li><li>categorical listing of SQLite documents - <a href="docs.html">docs.html</a></li><li>ceil - <a href="lang_mathfunc.html#ceil">lang_mathfunc.html#ceil</a></li><li>ceiling - <a href="lang_mathfunc.html#ceil">lang_mathfunc.html#ceil</a></li><li>cell format summary - <a href="fileformat2.html#cellformat">fileformat2.html#cellformat</a></li><li>cell payload - <a href="fileformat2.html#cell_payload">fileformat2.html#cell_payload</a></li><li>cell_size_check - <a href="pragma.html#pragma_cell_size_check">pragma.html#pragma_cell_size_check</a></li><li>cell_size_check pragma - <a href="pragma.html#pragma_cell_size_check">pragma.html#pragma_cell_size_check</a></li><li>cfgerrors - <a href="howtocorrupt.html#cfgerr">howtocorrupt.html#cfgerr</a></li><li>change counter - <a href="fileformat2.html#chngctr">fileformat2.html#chngctr</a></li><li>changes - <a href="lang_corefunc.html#changes">lang_corefunc.html#changes</a></li><li>changes method - <a href="tclsqlite.html#changes">tclsqlite.html#changes</a></li><li>changes SQL function - <a href="lang_corefunc.html#changes">lang_corefunc.html#changes</a></li><li>changeset - <a href="sessionintro.html#changeset">sessionintro.html#changeset</a></li><li>changesets - <a href="sessionintro.html#changeset">sessionintro.html#changeset</a></li><li>char - <a href="lang_corefunc.html#char">lang_corefunc.html#char</a></li><li>char SQL function - <a href="lang_corefunc.html#char">lang_corefunc.html#char</a></li><li>CHECK - <a href="lang_createtable.html#ckconst">lang_createtable.html#ckconst</a></li><li>CHECK constraint - <a href="lang_createtable.html#ckconst">lang_createtable.html#ckconst</a></li><li>CHECK constraints - <a href="lang_createtable.html#ckconst">lang_createtable.html#ckconst</a></li><li>checklist - <a href="testing.html#cklist">testing.html#cklist</a></li><li>checkpoint - <a href="wal.html#ckpt">wal.html#ckpt</a></li><li>checkpoint mode - <a href="c3ref/c_checkpoint_full.html">c3ref/c_checkpoint_full.html</a></li><li>checkpoint_fullfsync - <a href="pragma.html#pragma_checkpoint_fullfsync">pragma.html#pragma_checkpoint_fullfsync</a></li><li>checkpoint_fullfsync pragma - <a href="pragma.html#pragma_checkpoint_fullfsync">pragma.html#pragma_checkpoint_fullfsync</a></li><li>checkpointed - <a href="wal.html#ckpt">wal.html#ckpt</a></li><li>checkpointing - <a href="wal.html#ckpt">wal.html#ckpt</a></li><li>checksum VFS - <a href="cksumvfs.html">cksumvfs.html</a></li><li>checksum VFS shim - <a href="cksumvfs.html">cksumvfs.html</a></li><li>child key - <a href="foreignkeys.html#parentchild">foreignkeys.html#parentchild</a></li><li>child table - <a href="foreignkeys.html#parentchild">foreignkeys.html#parentchild</a></li><li>chronology - <a href="chronology.html">chronology.html</a></li><li>cintro - <a href="cintro.html">cintro.html</a></li><li>cksumvfs - <a href="cksumvfs.html">cksumvfs.html</a></li><li>CLI - <a href="cli.html">cli.html</a></li><li>clone the entire repository - <a href="getthecode.html#clone">getthecode.html#clone</a></li><li>close method - <a href="tclsqlite.html#close">tclsqlite.html#close</a></li><li>Clustered indexes - <a href="withoutrowid.html">withoutrowid.html</a></li><li>co-routines - <a href="optoverview.html#coroutines">optoverview.html#coroutines</a></li><li>coalesce - <a href="lang_corefunc.html#coalesce">lang_corefunc.html#coalesce</a></li><li>coalesce SQL function - <a href="lang_corefunc.html#coalesce">lang_corefunc.html#coalesce</a></li><li>Code of Conduct - <a href="codeofconduct.html">codeofconduct.html</a></li><li>Code of Ethics - <a href="codeofethics.html">codeofethics.html</a></li><li>Code of Ethics of the Project Founder - <a href="codeofethics.html">codeofethics.html</a></li><li>code repositories - <a href="download.html#srctree">download.html#srctree</a></li><li>COLLATE - <a href="lang_createindex.html#collidx">lang_createindex.html#collidx</a></li><li>COLLATE clause - <a href="lang_createtable.html#collateclause">lang_createtable.html#collateclause</a></li><li>COLLATE clauses - <a href="lang_createtable.html#collateclause">lang_createtable.html#collateclause</a></li><li>COLLATE constraint - <a href="lang_createtable.html#collateclause">lang_createtable.html#collateclause</a></li><li>collate method - <a href="tclsqlite.html#collate">tclsqlite.html#collate</a></li><li>COLLATE operator - <a href="lang_expr.html#collateop">lang_expr.html#collateop</a></li><li>collating function - <a href="datatype3.html#collation">datatype3.html#collation</a></li><li>collating sequence - <a href="datatype3.html#collation">datatype3.html#collation</a></li><li>collating sequences - <a href="datatype3.html#collation">datatype3.html#collation</a></li><li>collation - <a href="datatype3.html#collation">datatype3.html#collation</a></li><li>collation_list - <a href="pragma.html#pragma_collation_list">pragma.html#pragma_collation_list</a></li><li>collation_list pragma - <a href="pragma.html#pragma_collation_list">pragma.html#pragma_collation_list</a></li><li>collation_needed method - <a href="tclsqlite.html#collation_needed">tclsqlite.html#collation_needed</a></li><li>column access functions - <a href="c3ref/column_blob.html">c3ref/column_blob.html</a></li><li>column affinity - <a href="datatype3.html#affinity">datatype3.html#affinity</a></li><li>column definition - <a href="lang_createtable.html#tablecoldef">lang_createtable.html#tablecoldef</a></li><li>column definitions - <a href="lang_createtable.html#tablecoldef">lang_createtable.html#tablecoldef</a></li><li>column-constraint - <a href="syntax/column-constraint.html">syntax/column-constraint.html</a></li><li>column-constraint syntax diagram - <a href="syntax/column-constraint.html">syntax/column-constraint.html</a></li><li>column-def - <a href="syntax/column-def.html">syntax/column-def.html</a></li><li>column-def syntax diagram - <a href="syntax/column-def.html">syntax/column-def.html</a></li><li>column-name-list - <a href="syntax/column-name-list.html">syntax/column-name-list.html</a></li><li>column-name-list syntax diagram - <a href="syntax/column-name-list.html">syntax/column-name-list.html</a></li><li>Columnar output modes - <a href="cli.html#clmnr">cli.html#clmnr</a></li><li>columnar output modes - <a href="cli.html#clmnr">cli.html#clmnr</a></li><li>colUsed field - <a href="vtab.html#colUsed">vtab.html#colUsed</a></li><li>comma option - <a href="printf.html#comma">printf.html#comma</a></li><li>Command Line Interface - <a href="cli.html">cli.html</a></li><li>command-line interface - <a href="cli.html">cli.html</a></li><li>command-line options - <a href="cli.html#clopts">cli.html#clopts</a></li><li>command-line shell - <a href="cli.html">cli.html</a></li><li>commands - <a href="fts3.html#commands">fts3.html#commands</a></li><li>comment - <a href="lang_comment.html">lang_comment.html</a></li><li>comment-syntax - <a href="syntax/comment-syntax.html">syntax/comment-syntax.html</a></li><li>comment-syntax syntax diagram - <a href="syntax/comment-syntax.html">syntax/comment-syntax.html</a></li><li>comments - <a href="lang_comment.html">lang_comment.html</a></li><li>COMMIT - <a href="lang_transaction.html">lang_transaction.html</a></li><li>commit-stmt - <a href="syntax/commit-stmt.html">syntax/commit-stmt.html</a></li><li>commit-stmt syntax diagram - <a href="syntax/commit-stmt.html">syntax/commit-stmt.html</a></li><li>commit_hook method - <a href="tclsqlite.html#commit_hook">tclsqlite.html#commit_hook</a></li><li>common table expressions - <a href="lang_with.html">lang_with.html</a></li><li>common-table-expression - <a href="syntax/common-table-expression.html">syntax/common-table-expression.html</a></li><li>common-table-expression syntax diagram - <a href="syntax/common-table-expression.html">syntax/common-table-expression.html</a></li><li>comparison affinity rules - <a href="datatype3.html#compaff">datatype3.html#compaff</a></li><li>comparison expressions - <a href="datatype3.html#comparisons">datatype3.html#comparisons</a></li><li>comparison with fts4 - <a href="fts5.html#appendix_a">fts5.html#appendix_a</a></li><li>compilation - <a href="swarmvtab.html#compiling_and_using_swarmvtab">swarmvtab.html#compiling_and_using_swarmvtab</a></li><li>compile fts - <a href="fts3.html#compiling_and_enabling_fts3_and_fts4">fts3.html#compiling_and_enabling_fts3_and_fts4</a></li><li>compile loadable extensions - <a href="loadext.html#build">loadext.html#build</a></li><li>compile-time options - <a href="compile.html">compile.html</a></li><li>compile_options - <a href="pragma.html#pragma_compile_options">pragma.html#pragma_compile_options</a></li><li>compile_options pragma - <a href="pragma.html#pragma_compile_options">pragma.html#pragma_compile_options</a></li><li>Compiling Loadable Extensions - <a href="loadext.html#build">loadext.html#build</a></li><li>compiling the CLI - <a href="howtocompile.html#cli">howtocompile.html#cli</a></li><li>compiling the TCL interface - <a href="howtocompile.html#tcl">howtocompile.html#tcl</a></li><li>complete list of SQLite releases - <a href="changes.html">changes.html</a></li><li>complete method - <a href="tclsqlite.html#complete">tclsqlite.html#complete</a></li><li>COMPLETION - <a href="completion.html">completion.html</a></li><li>COMPLETION extension - <a href="completion.html">completion.html</a></li><li>COMPLETION table-valued function - <a href="completion.html">completion.html</a></li><li>compound query - <a href="lang_select.html#compound">lang_select.html#compound</a></li><li>compound SELECT - <a href="lang_select.html#compound">lang_select.html#compound</a></li><li>compound select - <a href="lang_select.html#compound">lang_select.html#compound</a></li><li>compound SELECTs - <a href="lang_select.html#compound">lang_select.html#compound</a></li><li>compound-operator - <a href="syntax/compound-operator.html">syntax/compound-operator.html</a></li><li>compound-operator syntax diagram - <a href="syntax/compound-operator.html">syntax/compound-operator.html</a></li><li>compound-select-stmt - <a href="syntax/compound-select-stmt.html">syntax/compound-select-stmt.html</a></li><li>compound-select-stmt syntax diagram - <a href="syntax/compound-select-stmt.html">syntax/compound-select-stmt.html</a></li><li>compressed FTS4 content - <a href="fts3.html#*fts4compression">fts3.html#*fts4compression</a></li><li>compute the Mandelbrot set - <a href="lang_with.html#mandelbrot">lang_with.html#mandelbrot</a></li><li>computed columns - <a href="gencol.html">gencol.html</a></li><li>concat - <a href="lang_corefunc.html#concat">lang_corefunc.html#concat</a></li><li>concat SQL function - <a href="lang_corefunc.html#concat">lang_corefunc.html#concat</a></li><li>concat_ws - <a href="lang_corefunc.html#concat_ws">lang_corefunc.html#concat_ws</a></li><li>concat_ws SQL function - <a href="lang_corefunc.html#concat_ws">lang_corefunc.html#concat_ws</a></li><li>config method - <a href="tclsqlite.html#config">tclsqlite.html#config</a></li><li>configurable edit distances - <a href="spellfix1.html#configeditdist">spellfix1.html#configeditdist</a></li><li>configuration option - <a href="c3ref/c_config_covering_index_scan.html">c3ref/c_config_covering_index_scan.html</a></li><li>conflict - <a href="lang_conflict.html">lang_conflict.html</a></li><li>conflict clause - <a href="lang_conflict.html">lang_conflict.html</a></li><li>conflict resolution algorithm - <a href="lang_conflict.html">lang_conflict.html</a></li><li>conflict resolution mode - <a href="c3ref/c_fail.html">c3ref/c_fail.html</a></li><li>conflict-clause - <a href="syntax/conflict-clause.html">syntax/conflict-clause.html</a></li><li>conflict-clause syntax diagram - <a href="syntax/conflict-clause.html">syntax/conflict-clause.html</a></li><li>constant-propagation optimization - <a href="optoverview.html#constprop">optoverview.html#constprop</a></li><li>contentless fts4 tables - <a href="fts3.html#_contentless_fts4_tables_">fts3.html#_contentless_fts4_tables_</a></li><li>contentless-delete - <a href="fts5.html#clssdeltab">fts5.html#clssdeltab</a></li><li>copy method - <a href="tclsqlite.html#copy">tclsqlite.html#copy</a></li><li>copyright - <a href="copyright.html">copyright.html</a></li><li>Core Functions - <a href="lang_corefunc.html">lang_corefunc.html</a></li><li>core URI query parameters - <a href="c3ref/open.html#coreuriqueryparameters">c3ref/open.html#coreuriqueryparameters</a></li><li>corefunc - <a href="lang_corefunc.html">lang_corefunc.html</a></li><li>coreqp - <a href="uri.html#coreqp">uri.html#coreqp</a></li><li>correlated subqueries - <a href="lang_expr.html#cosub">lang_expr.html#cosub</a></li><li>cos - <a href="lang_mathfunc.html#cos">lang_mathfunc.html#cos</a></li><li>cos SQL function - <a href="lang_mathfunc.html#cos">lang_mathfunc.html#cos</a></li><li>cosh - <a href="lang_mathfunc.html#cosh">lang_mathfunc.html#cosh</a></li><li>cosh SQL function - <a href="lang_mathfunc.html#cosh">lang_mathfunc.html#cosh</a></li><li>count - <a href="lang_aggfunc.html#count">lang_aggfunc.html#count</a></li><li>count aggregate function - <a href="lang_aggfunc.html#count">lang_aggfunc.html#count</a></li><li>count_changes - <a href="pragma.html#pragma_count_changes">pragma.html#pragma_count_changes</a></li><li>count_changes pragma - <a href="pragma.html#pragma_count_changes">pragma.html#pragma_count_changes</a></li><li>coverage testing vs. fuzz testing - <a href="testing.html#tension">testing.html#tension</a></li><li>covering index - <a href="queryplanner.html#covidx">queryplanner.html#covidx</a></li><li>covering indexes - <a href="queryplanner.html#covidx">queryplanner.html#covidx</a></li><li>covering indices - <a href="queryplanner.html#covidx">queryplanner.html#covidx</a></li><li>CPU cycles used - <a href="cpu.html">cpu.html</a></li><li>CPU performance measurement - <a href="cpu.html">cpu.html</a></li><li>CREATE INDEX - <a href="lang_createindex.html">lang_createindex.html</a></li><li>CREATE TABLE - <a href="lang_createtable.html">lang_createtable.html</a></li><li>CREATE TABLE AS - <a href="lang_createtable.html#createtabas">lang_createtable.html#createtabas</a></li><li>CREATE TRIGGER - <a href="lang_createtrigger.html">lang_createtrigger.html</a></li><li>CREATE VIEW - <a href="lang_createview.html">lang_createview.html</a></li><li>CREATE VIRTUAL TABLE - <a href="lang_createvtab.html">lang_createvtab.html</a></li><li>create-index-stmt - <a href="syntax/create-index-stmt.html">syntax/create-index-stmt.html</a></li><li>create-index-stmt syntax diagram - <a href="syntax/create-index-stmt.html">syntax/create-index-stmt.html</a></li><li>create-table-stmt - <a href="syntax/create-table-stmt.html">syntax/create-table-stmt.html</a></li><li>create-table-stmt syntax diagram - <a href="syntax/create-table-stmt.html">syntax/create-table-stmt.html</a></li><li>create-trigger-stmt - <a href="syntax/create-trigger-stmt.html">syntax/create-trigger-stmt.html</a></li><li>create-trigger-stmt syntax diagram - <a href="syntax/create-trigger-stmt.html">syntax/create-trigger-stmt.html</a></li><li>create-view-stmt - <a href="syntax/create-view-stmt.html">syntax/create-view-stmt.html</a></li><li>create-view-stmt syntax diagram - <a href="syntax/create-view-stmt.html">syntax/create-view-stmt.html</a></li><li>create-virtual-table-stmt - <a href="syntax/create-virtual-table-stmt.html">syntax/create-virtual-table-stmt.html</a></li><li>create-virtual-table-stmt syntax diagram - <a href="syntax/create-virtual-table-stmt.html">syntax/create-virtual-table-stmt.html</a></li><li>createindex - <a href="lang_createindex.html">lang_createindex.html</a></li><li>createtable - <a href="lang_createtable.html">lang_createtable.html</a></li><li>createtrigger - <a href="lang_createtrigger.html">lang_createtrigger.html</a></li><li>createview - <a href="lang_createview.html">lang_createview.html</a></li><li>createvtab - <a href="lang_createvtab.html">lang_createvtab.html</a></li><li>crew - <a href="crew.html">crew.html</a></li><li>CROSS JOIN - <a href="optoverview.html#crossjoin">optoverview.html#crossjoin</a></li><li>csv - <a href="csv.html">csv.html</a></li><li>CSV export - <a href="cli.html#csvout">cli.html#csvout</a></li><li>CSV import - <a href="cli.html#csv">cli.html#csv</a></li><li>CSV virtual table - <a href="csv.html">csv.html</a></li><li>cte-table-name - <a href="syntax/cte-table-name.html">syntax/cte-table-name.html</a></li><li>cte-table-name syntax diagram - <a href="syntax/cte-table-name.html">syntax/cte-table-name.html</a></li><li>custom auxiliary functions - <a href="fts5.html#custom_auxiliary_functions_api_reference">fts5.html#custom_auxiliary_functions_api_reference</a></li><li>custom auxiliary overview - <a href="fts5.html#custom_auxiliary_functions_api_overview">fts5.html#custom_auxiliary_functions_api_overview</a></li><li>custom builds - <a href="custombuild.html">custombuild.html</a></li><li>custom r-tree queries - <a href="rtree.html#customquery">rtree.html#customquery</a></li><li>custom SQL function - <a href="appfunc.html">appfunc.html</a></li><li>custom SQL functions - <a href="appfunc.html">appfunc.html</a></li><li>custom tokenizers - <a href="fts5.html#custom_tokenizers">fts5.html#custom_tokenizers</a></li><li>custom virtual tables - <a href="vtab.html#customvtab">vtab.html#customvtab</a></li><li>CVEs - <a href="cves.html">cves.html</a></li><li>Dan Kennedy - <a href="crew.html#dan">crew.html#dan</a></li><li>data container - <a href="whentouse.html#container">whentouse.html#container</a></li><li>data transfer format - <a href="whentouse.html#wireproto">whentouse.html#wireproto</a></li><li>data_store_directory - <a href="pragma.html#pragma_data_store_directory">pragma.html#pragma_data_store_directory</a></li><li>data_store_directory pragma - <a href="pragma.html#pragma_data_store_directory">pragma.html#pragma_data_store_directory</a></li><li>data_version - <a href="pragma.html#pragma_data_version">pragma.html#pragma_data_version</a></li><li>data_version pragma - <a href="pragma.html#pragma_data_version">pragma.html#pragma_data_version</a></li><li>database as container object - <a href="sqlar.html#dbasobj">sqlar.html#dbasobj</a></li><li>database as object - <a href="sqlar.html#dbasobj">sqlar.html#dbasobj</a></li><li>database connection - <a href="c3ref/sqlite3.html">c3ref/sqlite3.html</a></li><li>database connections - <a href="c3ref/sqlite3.html">c3ref/sqlite3.html</a></li><li>database corruption caused by inconsistent use of 83 filenames - <a href="shortnames.html#db83corrupt">shortnames.html#db83corrupt</a></li><li>database filename aliasing - <a href="howtocorrupt.html#alias">howtocorrupt.html#alias</a></li><li>database header - <a href="fileformat2.html#database_header">fileformat2.html#database_header</a></li><li>database_list - <a href="pragma.html#pragma_database_list">pragma.html#pragma_database_list</a></li><li>database_list pragma - <a href="pragma.html#pragma_database_list">pragma.html#pragma_database_list</a></li><li>datatype - <a href="datatype3.html">datatype3.html</a></li><li>date - <a href="lang_datefunc.html#dttm">lang_datefunc.html#dttm</a></li><li>date and time datatype - <a href="datatype3.html#datetime">datatype3.html#datetime</a></li><li>Date And Time Functions - <a href="lang_datefunc.html">lang_datefunc.html</a></li><li>date and time functions - <a href="lang_datefunc.html">lang_datefunc.html</a></li><li>date SQL function - <a href="lang_datefunc.html#dttm">lang_datefunc.html#dttm</a></li><li>date/time modifiers - <a href="lang_datefunc.html#dtmods">lang_datefunc.html#dtmods</a></li><li>date/time special case - <a href="deterministic.html#dtexception">deterministic.html#dtexception</a></li><li>datefunc - <a href="lang_datefunc.html">lang_datefunc.html</a></li><li>datetime - <a href="lang_datefunc.html#dttm">lang_datefunc.html#dttm</a></li><li>datetime SQL function - <a href="lang_datefunc.html#dttm">lang_datefunc.html#dttm</a></li><li>dbghints - <a href="debugging.html">debugging.html</a></li><li>dbhash - <a href="dbhash.html">dbhash.html</a></li><li>dbhash.exe - <a href="dbhash.html">dbhash.html</a></li><li>dbsqlfuzz - <a href="testing.html#dbsqlfuzz">testing.html#dbsqlfuzz</a></li><li>dbstat - <a href="dbstat.html">dbstat.html</a></li><li>DBSTAT aggregated mode - <a href="dbstat.html#dbstatagg">dbstat.html#dbstatagg</a></li><li>DBSTAT virtual table - <a href="dbstat.html">dbstat.html</a></li><li>dbstat virtual table - <a href="dbstat.html">dbstat.html</a></li><li>debugging hints - <a href="debugging.html">debugging.html</a></li><li>debugging memory allocator - <a href="malloc.html#memdebug">malloc.html#memdebug</a></li><li>decimal extension - <a href="floatingpoint.html#decext">floatingpoint.html#decext</a></li><li>decision checklist - <a href="whentouse.html#dbcklst">whentouse.html#dbcklst</a></li><li>DEFAULT clauses - <a href="lang_createtable.html#dfltval">lang_createtable.html#dfltval</a></li><li>default column value - <a href="lang_createtable.html#dfltval">lang_createtable.html#dfltval</a></li><li>default memory allocator - <a href="malloc.html#defaultalloc">malloc.html#defaultalloc</a></li><li>default value - <a href="lang_createtable.html#dfltval">lang_createtable.html#dfltval</a></li><li>default_cache_size - <a href="pragma.html#pragma_default_cache_size">pragma.html#pragma_default_cache_size</a></li><li>default_cache_size pragma - <a href="pragma.html#pragma_default_cache_size">pragma.html#pragma_default_cache_size</a></li><li>defense against dark arts - <a href="security.html">security.html</a></li><li>defense against the dark arts - <a href="security.html">security.html</a></li><li>defensive code - <a href="testing.html#defcode">testing.html#defcode</a></li><li>defer_foreign_keys - <a href="pragma.html#pragma_defer_foreign_keys">pragma.html#pragma_defer_foreign_keys</a></li><li>defer_foreign_keys pragma - <a href="pragma.html#pragma_defer_foreign_keys">pragma.html#pragma_defer_foreign_keys</a></li><li>degrees - <a href="lang_mathfunc.html#degrees">lang_mathfunc.html#degrees</a></li><li>degrees SQL function - <a href="lang_mathfunc.html#degrees">lang_mathfunc.html#degrees</a></li><li>DELETE - <a href="lang_delete.html">lang_delete.html</a></li><li>delete - <a href="lang_delete.html">lang_delete.html</a></li><li>delete-stmt - <a href="syntax/delete-stmt.html">syntax/delete-stmt.html</a></li><li>delete-stmt syntax diagram - <a href="syntax/delete-stmt.html">syntax/delete-stmt.html</a></li><li>delete-stmt-limited - <a href="syntax/delete-stmt-limited.html">syntax/delete-stmt-limited.html</a></li><li>delete-stmt-limited syntax diagram - <a href="syntax/delete-stmt-limited.html">syntax/delete-stmt-limited.html</a></li><li>deletemerge - <a href="fts5.html#the_deletemerge_configuration_option">fts5.html#the_deletemerge_configuration_option</a></li><li>DELETEs - <a href="lang_delete.html">lang_delete.html</a></li><li>deleting a hot journal - <a href="howtocorrupt.html#delhotjrnl">howtocorrupt.html#delhotjrnl</a></li><li>deprecated - <a href="c3ref/experimental.html">c3ref/experimental.html</a></li><li>DESC - <a href="lang_createindex.html#descidx">lang_createindex.html#descidx</a></li><li>descending index - <a href="lang_createindex.html#descidx">lang_createindex.html#descidx</a></li><li>descending indexes - <a href="lang_createindex.html#descidx">lang_createindex.html#descidx</a></li><li>descending indices - <a href="lang_createindex.html#descidx">lang_createindex.html#descidx</a></li><li>deserialize method - <a href="tclsqlite.html#deserialize">tclsqlite.html#deserialize</a></li><li>DETACH - <a href="lang_detach.html">lang_detach.html</a></li><li>detach - <a href="lang_detach.html">lang_detach.html</a></li><li>DETACH DATABASE - <a href="lang_detach.html">lang_detach.html</a></li><li>detach-stmt - <a href="syntax/detach-stmt.html">syntax/detach-stmt.html</a></li><li>detach-stmt syntax diagram - <a href="syntax/detach-stmt.html">syntax/detach-stmt.html</a></li><li>deterministic function - <a href="deterministic.html">deterministic.html</a></li><li>deterministic functions - <a href="deterministic.html">deterministic.html</a></li><li>deterministic SQL functions - <a href="deterministic.html">deterministic.html</a></li><li>DISTINCT - <a href="lang_select.html#distinct">lang_select.html#distinct</a></li><li>doclist - <a href="doclist.html">doclist.html</a></li><li>documents by category - <a href="docs.html">docs.html</a></li><li>dot-commands - <a href="cli.html#dotcmd">cli.html#dotcmd</a></li><li>double-quoted string literal - <a href="quirks.html#dblquote">quirks.html#dblquote</a></li><li>double-quoted string misfeature - <a href="quirks.html#dblquote">quirks.html#dblquote</a></li><li>download page - <a href="download.html">download.html</a></li><li>drop column - <a href="lang_altertable.html#altertabdropcol">lang_altertable.html#altertabdropcol</a></li><li>DROP INDEX - <a href="lang_dropindex.html">lang_dropindex.html</a></li><li>DROP TABLE - <a href="lang_droptable.html">lang_droptable.html</a></li><li>DROP TRIGGER - <a href="lang_droptrigger.html">lang_droptrigger.html</a></li><li>DROP VIEW - <a href="lang_dropview.html">lang_dropview.html</a></li><li>drop-index-stmt - <a href="syntax/drop-index-stmt.html">syntax/drop-index-stmt.html</a></li><li>drop-index-stmt syntax diagram - <a href="syntax/drop-index-stmt.html">syntax/drop-index-stmt.html</a></li><li>drop-table-stmt - <a href="syntax/drop-table-stmt.html">syntax/drop-table-stmt.html</a></li><li>drop-table-stmt syntax diagram - <a href="syntax/drop-table-stmt.html">syntax/drop-table-stmt.html</a></li><li>drop-trigger-stmt - <a href="syntax/drop-trigger-stmt.html">syntax/drop-trigger-stmt.html</a></li><li>drop-trigger-stmt syntax diagram - <a href="syntax/drop-trigger-stmt.html">syntax/drop-trigger-stmt.html</a></li><li>drop-view-stmt - <a href="syntax/drop-view-stmt.html">syntax/drop-view-stmt.html</a></li><li>drop-view-stmt syntax diagram - <a href="syntax/drop-view-stmt.html">syntax/drop-view-stmt.html</a></li><li>dropindex - <a href="lang_dropindex.html">lang_dropindex.html</a></li><li>droptable - <a href="lang_droptable.html">lang_droptable.html</a></li><li>droptrigger - <a href="lang_droptrigger.html">lang_droptrigger.html</a></li><li>dropview - <a href="lang_dropview.html">lang_dropview.html</a></li><li>dynamic string - <a href="c3ref/str.html">c3ref/str.html</a></li><li>dynamic typing - <a href="datatype3.html">datatype3.html</a></li><li>edit SQL function - <a href="cli.html#editfunc">cli.html#editfunc</a></li><li>editdist3 - <a href="spellfix1.html#editdist3">spellfix1.html#editdist3</a></li><li>embedded - <a href="serverless.html">serverless.html</a></li><li>empty_result_callbacks - <a href="pragma.html#pragma_empty_result_callbacks">pragma.html#pragma_empty_result_callbacks</a></li><li>empty_result_callbacks pragma - <a href="pragma.html#pragma_empty_result_callbacks">pragma.html#pragma_empty_result_callbacks</a></li><li>enable_load_extension method - <a href="tclsqlite.html#enable_load_extension">tclsqlite.html#enable_load_extension</a></li><li>encoding - <a href="pragma.html#pragma_encoding">pragma.html#pragma_encoding</a></li><li>encoding pragma - <a href="pragma.html#pragma_encoding">pragma.html#pragma_encoding</a></li><li>enhanced query syntax - <a href="fts3.html#_set_operations_using_the_enhanced_query_syntax">fts3.html#_set_operations_using_the_enhanced_query_syntax</a></li><li>eponymous virtual table - <a href="vtab.html#epovtab">vtab.html#epovtab</a></li><li>eponymous virtual tables - <a href="vtab.html#epovtab">vtab.html#epovtab</a></li><li>eponymous-only virtual table - <a href="vtab.html#epoonlyvtab">vtab.html#epoonlyvtab</a></li><li>eponymous-only virtual tables - <a href="vtab.html#epoonlyvtab">vtab.html#epoonlyvtab</a></li><li>eqp-or-opt - <a href="eqp.html#or-opt">eqp.html#or-opt</a></li><li>errlog - <a href="errlog.html">errlog.html</a></li><li>error code - <a href="rescode.html">rescode.html</a></li><li>error codes - <a href="rescode.html">rescode.html</a></li><li>error log - <a href="errlog.html">errlog.html</a></li><li>errorcode method - <a href="tclsqlite.html#errorcode">tclsqlite.html#errorcode</a></li><li>ESCAPE - <a href="lang_expr.html#like">lang_expr.html#like</a></li><li>eval method - <a href="tclsqlite.html#eval">tclsqlite.html#eval</a></li><li>EXCLUDE clause - <a href="windowfunctions.html#wexcls">windowfunctions.html#wexcls</a></li><li>exclude clause - <a href="windowfunctions.html#wexcls">windowfunctions.html#wexcls</a></li><li>EXCLUSIVE - <a href="lockingv3.html#excl_lock">lockingv3.html#excl_lock</a></li><li>EXCLUSIVE lock - <a href="lockingv3.html#excl_lock">lockingv3.html#excl_lock</a></li><li>exclusive lock - <a href="lockingv3.html#excl_lock">lockingv3.html#excl_lock</a></li><li>EXCLUSIVE locking mode - <a href="pragma.html#pragma_locking_mode">pragma.html#pragma_locking_mode</a></li><li>exclusive locking mode - <a href="pragma.html#pragma_locking_mode">pragma.html#pragma_locking_mode</a></li><li>exists method - <a href="tclsqlite.html#exists">tclsqlite.html#exists</a></li><li>EXISTS operator - <a href="lang_expr.html#exists_op">lang_expr.html#exists_op</a></li><li>exp - <a href="lang_mathfunc.html#exp">lang_mathfunc.html#exp</a></li><li>exp SQL function - <a href="lang_mathfunc.html#exp">lang_mathfunc.html#exp</a></li><li>experimental - <a href="c3ref/experimental.html">c3ref/experimental.html</a></li><li>experimental memory allocators - <a href="malloc.html#memsysx">malloc.html#memsysx</a></li><li>EXPLAIN - <a href="lang_explain.html">lang_explain.html</a></li><li>explain - <a href="lang_explain.html">lang_explain.html</a></li><li>EXPLAIN QUERY PLAN - <a href="eqp.html">eqp.html</a></li><li>explain query plan - <a href="eqp.html">eqp.html</a></li><li>export to excel - <a href="cli.html#exexcel*">cli.html#exexcel*</a></li><li>export to TSV - <a href="cli.html#extsv*">cli.html#extsv*</a></li><li>expr - <a href="syntax/expr.html">syntax/expr.html</a></li><li>expr syntax diagram - <a href="syntax/expr.html">syntax/expr.html</a></li><li>expression - <a href="lang_expr.html">lang_expr.html</a></li><li>expression affinity - <a href="datatype3.html#expraff">datatype3.html#expraff</a></li><li>expression index - <a href="expridx.html">expridx.html</a></li><li>expression indexes - <a href="expridx.html">expridx.html</a></li><li>expression syntax - <a href="lang_expr.html">lang_expr.html</a></li><li>ext-v-prim - <a href="rescode.html#pve">rescode.html#pve</a></li><li>extended error code - <a href="rescode.html#extrc">rescode.html#extrc</a></li><li>extended error codes - <a href="rescode.html#extrc">rescode.html#extrc</a></li><li>extended result code - <a href="rescode.html#extrc">rescode.html#extrc</a></li><li>extended result code definitions - <a href="c3ref/c_abort_rollback.html">c3ref/c_abort_rollback.html</a></li><li>extended result codes - <a href="rescode.html#extrc">rescode.html#extrc</a></li><li>Extending FTS5 - <a href="fts5.html#extending_fts5">fts5.html#extending_fts5</a></li><li>extension loading - <a href="loadext.html">loadext.html</a></li><li>external content fts4 tables - <a href="fts3.html#_external_content_fts4_tables_">fts3.html#_external_content_fts4_tables_</a></li><li>extract - <a href="lang_expr.html#extract">lang_expr.html#extract</a></li><li>factored-select-stmt - <a href="syntax/factored-select-stmt.html">syntax/factored-select-stmt.html</a></li><li>factored-select-stmt syntax diagram - <a href="syntax/factored-select-stmt.html">syntax/factored-select-stmt.html</a></li><li>faster than the filesystem - <a href="fasterthanfs.html">fasterthanfs.html</a></li><li>file control - <a href="c3ref/file_control.html">c3ref/file_control.html</a></li><li>file control opcode - <a href="c3ref/c_fcntl_begin_atomic_write.html">c3ref/c_fcntl_begin_atomic_write.html</a></li><li>file control opcodes - <a href="c3ref/c_fcntl_begin_atomic_write.html">c3ref/c_fcntl_begin_atomic_write.html</a></li><li>file format - <a href="fileformat2.html">fileformat2.html</a></li><li>file format version numbers - <a href="fileformat2.html#vnums">fileformat2.html#vnums</a></li><li>file I/O functions - <a href="cli.html#fileio">cli.html#fileio</a></li><li>file locking and concurrency control - <a href="lockingv3.html">lockingv3.html</a></li><li>file locking states - <a href="lockingv3.html#locking">lockingv3.html#locking</a></li><li>file-format benefits - <a href="aff_short.html">aff_short.html</a></li><li>filesystem corruption - <a href="howtocorrupt.html#fscorruption">howtocorrupt.html#fscorruption</a></li><li>FILTER clause on aggregate functions - <a href="lang_aggfunc.html#aggfilter">lang_aggfunc.html#aggfilter</a></li><li>filter-clause - <a href="syntax/filter-clause.html">syntax/filter-clause.html</a></li><li>filter-clause syntax diagram - <a href="syntax/filter-clause.html">syntax/filter-clause.html</a></li><li>flattened - <a href="optoverview.html#flattening">optoverview.html#flattening</a></li><li>flattening optimization - <a href="optoverview.html#flattening">optoverview.html#flattening</a></li><li>flexible type system - <a href="datatype3.html">datatype3.html</a></li><li>Flexible typing is a feature - <a href="flextypegood.html">flextypegood.html</a></li><li>floor - <a href="lang_mathfunc.html#floor">lang_mathfunc.html#floor</a></li><li>floor SQL function - <a href="lang_mathfunc.html#floor">lang_mathfunc.html#floor</a></li><li>footprint - <a href="footprint.html">footprint.html</a></li><li>foreign key actions - <a href="foreignkeys.html#fk_actions">foreignkeys.html#fk_actions</a></li><li>foreign key constraint - <a href="foreignkeys.html">foreignkeys.html</a></li><li>FOREIGN KEY constraints - <a href="foreignkeys.html">foreignkeys.html</a></li><li>foreign key constraints - <a href="foreignkeys.html">foreignkeys.html</a></li><li>foreign key constraints are enabled - <a href="foreignkeys.html#fk_enable">foreignkeys.html#fk_enable</a></li><li>foreign-key-clause - <a href="syntax/foreign-key-clause.html">syntax/foreign-key-clause.html</a></li><li>foreign-key-clause syntax diagram - <a href="syntax/foreign-key-clause.html">syntax/foreign-key-clause.html</a></li><li>foreign_key_check - <a href="pragma.html#pragma_foreign_key_check">pragma.html#pragma_foreign_key_check</a></li><li>foreign_key_check pragma - <a href="pragma.html#pragma_foreign_key_check">pragma.html#pragma_foreign_key_check</a></li><li>foreign_key_list - <a href="pragma.html#pragma_foreign_key_list">pragma.html#pragma_foreign_key_list</a></li><li>foreign_key_list pragma - <a href="pragma.html#pragma_foreign_key_list">pragma.html#pragma_foreign_key_list</a></li><li>foreign_keys - <a href="pragma.html#pragma_foreign_keys">pragma.html#pragma_foreign_keys</a></li><li>foreign_keys pragma - <a href="pragma.html#pragma_foreign_keys">pragma.html#pragma_foreign_keys</a></li><li>format - <a href="lang_corefunc.html#format">lang_corefunc.html#format</a></li><li>format SQL function - <a href="lang_corefunc.html#format">lang_corefunc.html#format</a></li><li>forum - <a href="support.html#fx">support.html#fx</a></li><li>frame boundary - <a href="windowfunctions.html#frameboundary">windowfunctions.html#frameboundary</a></li><li>frame specification - <a href="windowfunctions.html#framespec">windowfunctions.html#framespec</a></li><li>frame type - <a href="windowfunctions.html#frametype">windowfunctions.html#frametype</a></li><li>frame-spec - <a href="syntax/frame-spec.html">syntax/frame-spec.html</a></li><li>frame-spec syntax diagram - <a href="syntax/frame-spec.html">syntax/frame-spec.html</a></li><li>frames - <a href="windowfunctions.html#framespec">windowfunctions.html#framespec</a></li><li>free-page list - <a href="fileformat2.html#freelist">fileformat2.html#freelist</a></li><li>freelist - <a href="fileformat2.html#freelist">fileformat2.html#freelist</a></li><li>freelist_count - <a href="pragma.html#pragma_freelist_count">pragma.html#pragma_freelist_count</a></li><li>freelist_count pragma - <a href="pragma.html#pragma_freelist_count">pragma.html#pragma_freelist_count</a></li><li>FROM clause - <a href="lang_select.html#fromclause">lang_select.html#fromclause</a></li><li>FTS auxiliary functions - <a href="fts3.html#snippet">fts3.html#snippet</a></li><li>FTS hidden column - <a href="fts3.html#hiddencol">fts3.html#hiddencol</a></li><li>FTS MATCH - <a href="fts3.html#full_text_index_queries">fts3.html#full_text_index_queries</a></li><li>FTS shadow tables - <a href="fts3.html#*shadowtab">fts3.html#*shadowtab</a></li><li>FTS3 - <a href="fts3.html">fts3.html</a></li><li>fts3 - <a href="fts3.html">fts3.html</a></li><li>fts3_tokenizer - <a href="fts3.html#f3tknzr">fts3.html#f3tknzr</a></li><li>fts3tokenize - <a href="fts3.html#fts3tok">fts3.html#fts3tok</a></li><li>fts3tokenize virtual table - <a href="fts3.html#fts3tok">fts3.html#fts3tok</a></li><li>FTS4 - <a href="fts3.html#fts4">fts3.html#fts4</a></li><li>FTS4 automerge command - <a href="fts3.html#*fts4automergecmd">fts3.html#*fts4automergecmd</a></li><li>FTS4 commands - <a href="fts3.html#*cmds">fts3.html#*cmds</a></li><li>fts4 compress option - <a href="fts3.html#the_compress_and_uncompress_options">fts3.html#the_compress_and_uncompress_options</a></li><li>FTS4 content option - <a href="fts3.html#*fts4content">fts3.html#*fts4content</a></li><li>fts4 content option - <a href="fts3.html#the_content_option_">fts3.html#the_content_option_</a></li><li>FTS4 integrity-check command - <a href="fts3.html#*fts4ickcmd">fts3.html#*fts4ickcmd</a></li><li>FTS4 languageid option - <a href="fts3.html#*fts4languageid">fts3.html#*fts4languageid</a></li><li>fts4 languageid option - <a href="fts3.html#the_languageid_option">fts3.html#the_languageid_option</a></li><li>FTS4 matchinfo option - <a href="fts3.html#fts4matchinfo">fts3.html#fts4matchinfo</a></li><li>fts4 matchinfo option - <a href="fts3.html#the_matchinfo_option">fts3.html#the_matchinfo_option</a></li><li>FTS4 merge command - <a href="fts3.html#*fts4mergecmd">fts3.html#*fts4mergecmd</a></li><li>FTS4 notindexed option - <a href="fts3.html#fts4notindexed">fts3.html#fts4notindexed</a></li><li>fts4 notindexed option - <a href="fts3.html#the_notindexed_option">fts3.html#the_notindexed_option</a></li><li>FTS4 optimize command - <a href="fts3.html#*fts4optcmd">fts3.html#*fts4optcmd</a></li><li>FTS4 options - <a href="fts3.html#fts4_options">fts3.html#fts4_options</a></li><li>FTS4 order option - <a href="fts3.html#fts4order">fts3.html#fts4order</a></li><li>FTS4 prefix option - <a href="fts3.html#fts4prefix">fts3.html#fts4prefix</a></li><li>fts4 prefix option - <a href="fts3.html#the_prefix_option">fts3.html#the_prefix_option</a></li><li>FTS4 rebuild command - <a href="fts3.html#*fts4rebuidcmd">fts3.html#*fts4rebuidcmd</a></li><li>fts4aux - <a href="fts3.html#fts4aux">fts3.html#fts4aux</a></li><li>fts4aux languageid column - <a href="fts3.html#f4alid">fts3.html#f4alid</a></li><li>FTS5 - <a href="fts5.html">fts5.html</a></li><li>fts5 - <a href="fts5.html">fts5.html</a></li><li>FTS5 automerge option - <a href="fts5.html#the_automerge_configuration_option">fts5.html#the_automerge_configuration_option</a></li><li>FTS5 auxiliary functions - <a href="fts5.html#_auxiliary_functions_">fts5.html#_auxiliary_functions_</a></li><li>FTS5 bm25 - <a href="fts5.html#the_bm25_function">fts5.html#the_bm25_function</a></li><li>FTS5 boolean operators - <a href="fts5.html#fts5_boolean_operators">fts5.html#fts5_boolean_operators</a></li><li>FTS5 building - <a href="fts5.html#compiling_and_using_fts5">fts5.html#compiling_and_using_fts5</a></li><li>FTS5 column filters - <a href="fts5.html#fts5_column_filters">fts5.html#fts5_column_filters</a></li><li>FTS5 columnsize option - <a href="fts5.html#the_columnsize_option">fts5.html#the_columnsize_option</a></li><li>FTS5 content option - <a href="fts5.html#external_content_and_contentless_tables">fts5.html#external_content_and_contentless_tables</a></li><li>FTS5 contentless tables - <a href="fts5.html#contentless_tables">fts5.html#contentless_tables</a></li><li>FTS5 contentless-delete tables - <a href="fts5.html#contentless_delete_tables">fts5.html#contentless_delete_tables</a></li><li>FTS5 CREATE TABLE Options - <a href="fts5.html#fts5_table_creation_and_initialization">fts5.html#fts5_table_creation_and_initialization</a></li><li>FTS5 custom auxiliary functions - <a href="fts5.html#custom_auxiliary_functions">fts5.html#custom_auxiliary_functions</a></li><li>FTS5 delete command - <a href="fts5.html#the_delete_command">fts5.html#the_delete_command</a></li><li>FTS5 delete-all command - <a href="fts5.html#the_delete_all_command">fts5.html#the_delete_all_command</a></li><li>FTS5 detail option - <a href="fts5.html#the_detail_option">fts5.html#the_detail_option</a></li><li>FTS5 external content pitfalls - <a href="fts5.html#external_content_table_pitfalls">fts5.html#external_content_table_pitfalls</a></li><li>FTS5 external content tables - <a href="fts5.html#external_content_tables">fts5.html#external_content_tables</a></li><li>FTS5 highlight - <a href="fts5.html#the_highlight_function">fts5.html#the_highlight_function</a></li><li>FTS5 initial token - <a href="fts5.html#carrotq">fts5.html#carrotq</a></li><li>FTS5 initial token queries - <a href="fts5.html#fts5_initial_token_queries">fts5.html#fts5_initial_token_queries</a></li><li>FTS5 merge command - <a href="fts5.html#the_merge_command">fts5.html#the_merge_command</a></li><li>FTS5 NEAR queries - <a href="fts5.html#fts5_near_queries">fts5.html#fts5_near_queries</a></li><li>FTS5 optimize command - <a href="fts5.html#the_optimize_command">fts5.html#the_optimize_command</a></li><li>FTS5 pgsz option - <a href="fts5.html#the_pgsz_configuration_option">fts5.html#the_pgsz_configuration_option</a></li><li>FTS5 Phrases - <a href="fts5.html#fts5_phrases">fts5.html#fts5_phrases</a></li><li>FTS5 prefix indexes - <a href="fts5.html#prefix_indexes">fts5.html#prefix_indexes</a></li><li>FTS5 prefix queries - <a href="fts5.html#fts5_prefix_queries">fts5.html#fts5_prefix_queries</a></li><li>FTS5 query syntax - <a href="fts5.html#full_text_query_syntax">fts5.html#full_text_query_syntax</a></li><li>FTS5 rank configuration option - <a href="fts5.html#the_rank_configuration_option">fts5.html#the_rank_configuration_option</a></li><li>FTS5 rebuild command - <a href="fts5.html#the_rebuild_command">fts5.html#the_rebuild_command</a></li><li>FTS5 secure-delete command - <a href="fts5.html#the_secure_delete_configuration_option">fts5.html#the_secure_delete_configuration_option</a></li><li>fts5 shadow tables - <a href="fts5.html#fts5shadowtables">fts5.html#fts5shadowtables</a></li><li>FTS5 snippet - <a href="fts5.html#the_snippet_function">fts5.html#the_snippet_function</a></li><li>FTS5 Strings - <a href="fts5.html#fts5_strings">fts5.html#fts5_strings</a></li><li>fts5 technical differences - <a href="fts5.html#_summary_of_technical_differences_">fts5.html#_summary_of_technical_differences_</a></li><li>FTS5 tokendata option - <a href="fts5.html#the_tokendata_option">fts5.html#the_tokendata_option</a></li><li>FTS5 tokenizers - <a href="fts5.html#tokenizers">fts5.html#tokenizers</a></li><li>FTS5 usermerge option - <a href="fts5.html#the_usermerge_configuration_option">fts5.html#the_usermerge_configuration_option</a></li><li>fts5vocab - <a href="fts5.html#the_fts5vocab_virtual_table_module">fts5.html#the_fts5vocab_virtual_table_module</a></li><li>FULL JOIN - <a href="lang_select.html#fulljoin">lang_select.html#fulljoin</a></li><li>FULL OUTER JOIN - <a href="lang_select.html#fulljoin">lang_select.html#fulljoin</a></li><li>Full-featured SQL - <a href="fullsql.html">fullsql.html</a></li><li>full-featured SQL - <a href="fullsql.html">fullsql.html</a></li><li>full-text search - <a href="fts3.html">fts3.html</a></li><li>full_column_names - <a href="pragma.html#pragma_full_column_names">pragma.html#pragma_full_column_names</a></li><li>full_column_names pragma - <a href="pragma.html#pragma_full_column_names">pragma.html#pragma_full_column_names</a></li><li>fullfsync - <a href="pragma.html#pragma_fullfsync">pragma.html#pragma_fullfsync</a></li><li>fullfsync pragma - <a href="pragma.html#pragma_fullfsync">pragma.html#pragma_fullfsync</a></li><li>function creation routines - <a href="c3ref/create_function.html">c3ref/create_function.html</a></li><li>function method - <a href="tclsqlite.html#function">tclsqlite.html#function</a></li><li>function-arguments - <a href="syntax/function-arguments.html">syntax/function-arguments.html</a></li><li>function-arguments syntax diagram - <a href="syntax/function-arguments.html">syntax/function-arguments.html</a></li><li>function_list - <a href="pragma.html#pragma_function_list">pragma.html#pragma_function_list</a></li><li>function_list pragma - <a href="pragma.html#pragma_function_list">pragma.html#pragma_function_list</a></li><li>functions within expressions - <a href="lang_expr.html#*funcinexpr">lang_expr.html#*funcinexpr</a></li><li>fuzz testing - <a href="testing.html#fuzztesting">testing.html#fuzztesting</a></li><li>fuzzcheck - <a href="testing.html#fuzzcheck">testing.html#fuzzcheck</a></li><li>generalized ALTER TABLE procedure - <a href="lang_altertable.html#otheralter">lang_altertable.html#otheralter</a></li><li>generate_series - <a href="series.html">series.html</a></li><li>generated column - <a href="gencol.html">gencol.html</a></li><li>Generated columns - <a href="gencol.html">gencol.html</a></li><li>generated columns - <a href="gencol.html">gencol.html</a></li><li>GEOPOLY - <a href="geopoly.html">geopoly.html</a></li><li>geopoly - <a href="geopoly.html">geopoly.html</a></li><li>Geopoly extension - <a href="geopoly.html">geopoly.html</a></li><li>Geopoly module - <a href="geopoly.html">geopoly.html</a></li><li>geopoly_area - <a href="geopoly.html#garea">geopoly.html#garea</a></li><li>geopoly_bbox - <a href="geopoly.html#gbbox">geopoly.html#gbbox</a></li><li>geopoly_blob - <a href="geopoly.html#gblob">geopoly.html#gblob</a></li><li>geopoly_ccw - <a href="geopoly.html#ccw">geopoly.html#ccw</a></li><li>geopoly_contains_point - <a href="geopoly.html#gpoint">geopoly.html#gpoint</a></li><li>geopoly_group_bbox - <a href="geopoly.html#gbbox">geopoly.html#gbbox</a></li><li>geopoly_json - <a href="geopoly.html#gjson">geopoly.html#gjson</a></li><li>geopoly_overlap - <a href="geopoly.html#goverlap">geopoly.html#goverlap</a></li><li>geopoly_regular - <a href="geopoly.html#regpoly">geopoly.html#regpoly</a></li><li>geopoly_svg - <a href="geopoly.html#gsvg">geopoly.html#gsvg</a></li><li>geopoly_within - <a href="geopoly.html#gwithin">geopoly.html#gwithin</a></li><li>geopoly_xform - <a href="geopoly.html#xform">geopoly.html#xform</a></li><li>get the canonical source code - <a href="getthecode.html">getthecode.html</a></li><li>GLOB - <a href="lang_expr.html#glob">lang_expr.html#glob</a></li><li>glob - <a href="lang_corefunc.html#glob">lang_corefunc.html#glob</a></li><li>glob SQL function - <a href="lang_corefunc.html#glob">lang_corefunc.html#glob</a></li><li>GROUP BY - <a href="lang_select.html#resultset">lang_select.html#resultset</a></li><li>GROUP BY clause - <a href="lang_select.html#resultset">lang_select.html#resultset</a></li><li>group_concat - <a href="lang_aggfunc.html#group_concat">lang_aggfunc.html#group_concat</a></li><li>group_concat aggregate function - <a href="lang_aggfunc.html#group_concat">lang_aggfunc.html#group_concat</a></li><li>GROUPS frames - <a href="windowfunctions.html#grouptype">windowfunctions.html#grouptype</a></li><li>hard_heap_limit - <a href="pragma.html#pragma_hard_heap_limit">pragma.html#pragma_hard_heap_limit</a></li><li>hard_heap_limit pragma - <a href="pragma.html#pragma_hard_heap_limit">pragma.html#pragma_hard_heap_limit</a></li><li>hash join - <a href="optoverview.html#hashjoin">optoverview.html#hashjoin</a></li><li>HAVE_FDATASYNC - <a href="compile.html#fdatasync">compile.html#fdatasync</a></li><li>HAVE_GMTIME_R - <a href="compile.html#gmtime_r">compile.html#gmtime_r</a></li><li>HAVE_ISNAN - <a href="compile.html#isnan">compile.html#isnan</a></li><li>HAVE_LOCALTIME_R - <a href="compile.html#localtime_r">compile.html#localtime_r</a></li><li>HAVE_LOCALTIME_S - <a href="compile.html#localtime_s">compile.html#localtime_s</a></li><li>HAVE_MALLOC_USABLE_SIZE - <a href="compile.html#malloc_usable_size">compile.html#malloc_usable_size</a></li><li>HAVE_SQLITE_CONFIG_H - <a href="compile.html#sqlite_config_h">compile.html#sqlite_config_h</a></li><li>HAVE_STRCHRNUL - <a href="compile.html#strchrnul">compile.html#strchrnul</a></li><li>HAVE_UTIME - <a href="compile.html#utime">compile.html#utime</a></li><li>HAVING - <a href="lang_select.html#resultset">lang_select.html#resultset</a></li><li>HAVING clause - <a href="lang_select.html#resultset">lang_select.html#resultset</a></li><li>hazards of upgrading to the NGQP - <a href="queryplanner-ng.html#hazards">queryplanner-ng.html#hazards</a></li><li>hex - <a href="lang_corefunc.html#hex">lang_corefunc.html#hex</a></li><li>hex SQL function - <a href="lang_corefunc.html#hex">lang_corefunc.html#hex</a></li><li>hexadecimal integer literals - <a href="lang_expr.html#hexint">lang_expr.html#hexint</a></li><li>hexadecimal integers - <a href="lang_expr.html#hexint">lang_expr.html#hexint</a></li><li>hidden column - <a href="vtab.html#hiddencol">vtab.html#hiddencol</a></li><li>hidden columns - <a href="vtab.html#hiddencol">vtab.html#hiddencol</a></li><li>high-reliability - <a href="hirely.html">hirely.html</a></li><li>Hipp - <a href="crew.html">crew.html</a></li><li>host parameter - <a href="c3ref/bind_blob.html">c3ref/bind_blob.html</a></li><li>host parameter name - <a href="c3ref/bind_blob.html">c3ref/bind_blob.html</a></li><li>host parameters - <a href="c3ref/bind_blob.html">c3ref/bind_blob.html</a></li><li>hot journal - <a href="fileformat2.html#hotjrnl">fileformat2.html#hotjrnl</a></li><li>hot journal files - <a href="fileformat2.html#hotjrnl">fileformat2.html#hotjrnl</a></li><li>how collation is determined - <a href="datatype3.html#colrules">datatype3.html#colrules</a></li><li>How SQL Works - <a href="howitworks.html">howitworks.html</a></li><li>How SQLite Works - <a href="howitworks.html">howitworks.html</a></li><li>how to compile - <a href="howtocompile.html">howtocompile.html</a></li><li>How To Compile SQLite - <a href="howtocompile.html">howtocompile.html</a></li><li>how to corrupt - <a href="howtocorrupt.html">howtocorrupt.html</a></li><li>how to corrupt a database - <a href="useovernet.html">useovernet.html</a></li><li>How To Corrupt Your Database Files - <a href="lockingv3.html#how_to_corrupt">lockingv3.html#how_to_corrupt</a></li><li>how vacuum works - <a href="lang_vacuum.html#howvacuumworks">lang_vacuum.html#howvacuumworks</a></li><li>IEEE 754 floating point values are approximations - <a href="floatingpoint.html#fpapprox">floatingpoint.html#fpapprox</a></li><li>ieee754 extension - <a href="floatingpoint.html#ieee754ext">floatingpoint.html#ieee754ext</a></li><li>ieee754 function - <a href="floatingpoint.html#ieee754">floatingpoint.html#ieee754</a></li><li>ieee754_exponent function - <a href="floatingpoint.html#ieee754m">floatingpoint.html#ieee754m</a></li><li>ieee754_from_blob function - <a href="floatingpoint.html#ieee754b">floatingpoint.html#ieee754b</a></li><li>ieee754_mantissa function - <a href="floatingpoint.html#ieee754m">floatingpoint.html#ieee754m</a></li><li>ieee754_to_blob function - <a href="floatingpoint.html#ieee754b">floatingpoint.html#ieee754b</a></li><li>ifnull - <a href="lang_corefunc.html#ifnull">lang_corefunc.html#ifnull</a></li><li>ifnull SQL function - <a href="lang_corefunc.html#ifnull">lang_corefunc.html#ifnull</a></li><li>ignore_check_constraints - <a href="pragma.html#pragma_ignore_check_constraints">pragma.html#pragma_ignore_check_constraints</a></li><li>ignore_check_constraints pragma - <a href="pragma.html#pragma_ignore_check_constraints">pragma.html#pragma_ignore_check_constraints</a></li><li>iif - <a href="lang_corefunc.html#iif">lang_corefunc.html#iif</a></li><li>iif SQL function - <a href="lang_corefunc.html#iif">lang_corefunc.html#iif</a></li><li>immutable query parameter - <a href="uri.html#uriimmutable">uri.html#uriimmutable</a></li><li>imposter tables - <a href="imposter.html">imposter.html</a></li><li>IN operator - <a href="lang_expr.html#in_op">lang_expr.html#in_op</a></li><li>in-header database size - <a href="fileformat2.html#filesize">fileformat2.html#filesize</a></li><li>in-memory database - <a href="inmemorydb.html">inmemorydb.html</a></li><li>in-memory databases - <a href="inmemorydb.html">inmemorydb.html</a></li><li>in-memory shared cache database - <a href="inmemorydb.html#sharedmemdb">inmemorydb.html#sharedmemdb</a></li><li>in-memory shared-cache - <a href="sharedcache.html#inmemsharedcache">sharedcache.html#inmemsharedcache</a></li><li>incrblob method - <a href="tclsqlite.html#incrblob">tclsqlite.html#incrblob</a></li><li>increase in the default page size - <a href="pgszchng2016.html">pgszchng2016.html</a></li><li>incremental_vacuum - <a href="pragma.html#pragma_incremental_vacuum">pragma.html#pragma_incremental_vacuum</a></li><li>incremental_vacuum pragma - <a href="pragma.html#pragma_incremental_vacuum">pragma.html#pragma_incremental_vacuum</a></li><li>index b-tree - <a href="fileformat2.html#btypes">fileformat2.html#btypes</a></li><li>index_info - <a href="pragma.html#pragma_index_info">pragma.html#pragma_index_info</a></li><li>index_info pragma - <a href="pragma.html#pragma_index_info">pragma.html#pragma_index_info</a></li><li>index_list - <a href="pragma.html#pragma_index_list">pragma.html#pragma_index_list</a></li><li>index_list pragma - <a href="pragma.html#pragma_index_list">pragma.html#pragma_index_list</a></li><li>index_xinfo - <a href="pragma.html#pragma_index_xinfo">pragma.html#pragma_index_xinfo</a></li><li>index_xinfo pragma - <a href="pragma.html#pragma_index_xinfo">pragma.html#pragma_index_xinfo</a></li><li>INDEXED BY - <a href="lang_indexedby.html">lang_indexedby.html</a></li><li>indexed expression - <a href="expridx.html">expridx.html</a></li><li>indexed expressions - <a href="expridx.html">expridx.html</a></li><li>indexed-column - <a href="syntax/indexed-column.html">syntax/indexed-column.html</a></li><li>indexed-column syntax diagram - <a href="syntax/indexed-column.html">syntax/indexed-column.html</a></li><li>Indexes - <a href="lang_createindex.html">lang_createindex.html</a></li><li>Indexes On Expressions - <a href="expridx.html">expridx.html</a></li><li>indexes on expressions - <a href="expridx.html">expridx.html</a></li><li>indexing - <a href="queryplanner.html">queryplanner.html</a></li><li>indexing tutorial - <a href="queryplanner.html">queryplanner.html</a></li><li>INSERT - <a href="lang_insert.html">lang_insert.html</a></li><li>insert - <a href="lang_insert.html">lang_insert.html</a></li><li>insert-stmt - <a href="syntax/insert-stmt.html">syntax/insert-stmt.html</a></li><li>insert-stmt syntax diagram - <a href="syntax/insert-stmt.html">syntax/insert-stmt.html</a></li><li>INSERTs - <a href="lang_insert.html">lang_insert.html</a></li><li>INSTEAD OF - <a href="lang_createtrigger.html#instead_of_trigger">lang_createtrigger.html#instead_of_trigger</a></li><li>INSTEAD OF trigger - <a href="lang_createtrigger.html#instead_of_trigger">lang_createtrigger.html#instead_of_trigger</a></li><li>instr - <a href="lang_corefunc.html#instr">lang_corefunc.html#instr</a></li><li>instr SQL function - <a href="lang_corefunc.html#instr">lang_corefunc.html#instr</a></li><li>INTEGER PRIMARY KEY - <a href="lang_createtable.html#rowid">lang_createtable.html#rowid</a></li><li>integer-valued r-trees - <a href="rtree.html#intrtree">rtree.html#intrtree</a></li><li>integrity_check - <a href="pragma.html#pragma_integrity_check">pragma.html#pragma_integrity_check</a></li><li>integrity_check pragma - <a href="pragma.html#pragma_integrity_check">pragma.html#pragma_integrity_check</a></li><li>internal index - <a href="fileformat2.html#intschema">fileformat2.html#intschema</a></li><li>internal indexes - <a href="fileformat2.html#intschema">fileformat2.html#intschema</a></li><li>internal schema object - <a href="fileformat2.html#intschema">fileformat2.html#intschema</a></li><li>internal schema objects - <a href="fileformat2.html#intschema">fileformat2.html#intschema</a></li><li>internal table - <a href="fileformat2.html#intschema">fileformat2.html#intschema</a></li><li>internal tables - <a href="fileformat2.html#intschema">fileformat2.html#intschema</a></li><li>Internal Versus External BLOBs - <a href="intern-v-extern-blob.html">intern-v-extern-blob.html</a></li><li>interrupt method - <a href="tclsqlite.html#interrupt">tclsqlite.html#interrupt</a></li><li>invalid UTF - <a href="invalidutf.html">invalidutf.html</a></li><li>IS DISTINCT FROM - <a href="lang_expr.html#isdf">lang_expr.html#isdf</a></li><li>IS NOT DISTINCT FROM - <a href="lang_expr.html#isdf">lang_expr.html#isdf</a></li><li>IS NOT operator - <a href="lang_expr.html#isisnot">lang_expr.html#isisnot</a></li><li>IS operator - <a href="lang_expr.html#isisnot">lang_expr.html#isisnot</a></li><li>isolation - <a href="isolation.html">isolation.html</a></li><li>jfuzz - <a href="testing.html#dbsqlfuzz">testing.html#dbsqlfuzz</a></li><li>join order - <a href="optoverview.html#joins">optoverview.html#joins</a></li><li>join-clause - <a href="syntax/join-clause.html">syntax/join-clause.html</a></li><li>join-clause syntax diagram - <a href="syntax/join-clause.html">syntax/join-clause.html</a></li><li>join-constraint - <a href="syntax/join-constraint.html">syntax/join-constraint.html</a></li><li>join-constraint syntax diagram - <a href="syntax/join-constraint.html">syntax/join-constraint.html</a></li><li>join-operator - <a href="syntax/join-operator.html">syntax/join-operator.html</a></li><li>join-operator syntax diagram - <a href="syntax/join-operator.html">syntax/join-operator.html</a></li><li>journal_mode - <a href="pragma.html#pragma_journal_mode">pragma.html#pragma_journal_mode</a></li><li>journal_mode pragma - <a href="pragma.html#pragma_journal_mode">pragma.html#pragma_journal_mode</a></li><li>journal_size_limit - <a href="pragma.html#pragma_journal_size_limit">pragma.html#pragma_journal_size_limit</a></li><li>journal_size_limit pragma - <a href="pragma.html#pragma_journal_size_limit">pragma.html#pragma_journal_size_limit</a></li><li>json - <a href="json1.html#jmini">json1.html#jmini</a></li><li>JSON BLOB input bug - <a href="json1.html#jblobbug">json1.html#jblobbug</a></li><li>JSON function path arguments - <a href="json1.html#jsonpath">json1.html#jsonpath</a></li><li>JSON paths - <a href="json1.html#jsonpath">json1.html#jsonpath</a></li><li>json SQL function - <a href="json1.html#jmini">json1.html#jmini</a></li><li>JSON SQL functions - <a href="json1.html">json1.html</a></li><li>json1 - <a href="json1.html">json1.html</a></li><li>JSON5 - <a href="json1.html#json5">json1.html#json5</a></li><li>JSON5 extensions - <a href="json1.html#json5">json1.html#json5</a></li><li>json_array - <a href="json1.html#jarray">json1.html#jarray</a></li><li>json_array SQL function - <a href="json1.html#jarray">json1.html#jarray</a></li><li>json_array_length - <a href="json1.html#jarraylen">json1.html#jarraylen</a></li><li>json_array_length SQL function - <a href="json1.html#jarraylen">json1.html#jarraylen</a></li><li>json_each - <a href="json1.html#jeach">json1.html#jeach</a></li><li>json_each table-valued function - <a href="json1.html#jeach">json1.html#jeach</a></li><li>json_error_position - <a href="json1.html#jerr">json1.html#jerr</a></li><li>json_error_position SQL function - <a href="json1.html#jerr">json1.html#jerr</a></li><li>json_extract - <a href="json1.html#jex">json1.html#jex</a></li><li>json_extract SQL function - <a href="json1.html#jex">json1.html#jex</a></li><li>json_group_array - <a href="json1.html#jgrouparray">json1.html#jgrouparray</a></li><li>json_group_array SQL function - <a href="json1.html#jgrouparray">json1.html#jgrouparray</a></li><li>json_group_object - <a href="json1.html#jgroupobject">json1.html#jgroupobject</a></li><li>json_group_object SQL function - <a href="json1.html#jgroupobject">json1.html#jgroupobject</a></li><li>json_insert - <a href="json1.html#jins">json1.html#jins</a></li><li>json_insert SQL function - <a href="json1.html#jins">json1.html#jins</a></li><li>json_object - <a href="json1.html#jobj">json1.html#jobj</a></li><li>json_object SQL function - <a href="json1.html#jobj">json1.html#jobj</a></li><li>json_patch - <a href="json1.html#jpatch">json1.html#jpatch</a></li><li>json_patch SQL function - <a href="json1.html#jpatch">json1.html#jpatch</a></li><li>json_pretty - <a href="json1.html#jpretty">json1.html#jpretty</a></li><li>json_pretty SQL function - <a href="json1.html#jpretty">json1.html#jpretty</a></li><li>json_quote - <a href="json1.html#jquote">json1.html#jquote</a></li><li>json_quote SQL function - <a href="json1.html#jquote">json1.html#jquote</a></li><li>json_remove - <a href="json1.html#jrm">json1.html#jrm</a></li><li>json_remove SQL function - <a href="json1.html#jrm">json1.html#jrm</a></li><li>json_replace - <a href="json1.html#jrepl">json1.html#jrepl</a></li><li>json_replace SQL function - <a href="json1.html#jrepl">json1.html#jrepl</a></li><li>json_set - <a href="json1.html#jset">json1.html#jset</a></li><li>json_set SQL function - <a href="json1.html#jset">json1.html#jset</a></li><li>json_tree - <a href="json1.html#jtree">json1.html#jtree</a></li><li>json_tree table-valued function - <a href="json1.html#jtree">json1.html#jtree</a></li><li>json_type - <a href="json1.html#jtype">json1.html#jtype</a></li><li>json_type SQL function - <a href="json1.html#jtype">json1.html#jtype</a></li><li>json_valid - <a href="json1.html#jvalid">json1.html#jvalid</a></li><li>json_valid SQL function - <a href="json1.html#jvalid">json1.html#jvalid</a></li><li>JSONB - <a href="json1.html#jsonbx">json1.html#jsonbx</a></li><li>jsonb - <a href="json1.html#jminib">json1.html#jminib</a></li><li>jsonb SQL function - <a href="json1.html#jminib">json1.html#jminib</a></li><li>jsonb_array - <a href="json1.html#jarrayb">json1.html#jarrayb</a></li><li>jsonb_array SQL function - <a href="json1.html#jarrayb">json1.html#jarrayb</a></li><li>jsonb_extract - <a href="json1.html#jexb">json1.html#jexb</a></li><li>jsonb_extract SQL function - <a href="json1.html#jexb">json1.html#jexb</a></li><li>jsonb_group_array - <a href="json1.html#jgrouparrayb">json1.html#jgrouparrayb</a></li><li>jsonb_group_array SQL function - <a href="json1.html#jgrouparrayb">json1.html#jgrouparrayb</a></li><li>jsonb_group_object - <a href="json1.html#jgroupobjectb">json1.html#jgroupobjectb</a></li><li>jsonb_group_object SQL function - <a href="json1.html#jgroupobjectb">json1.html#jgroupobjectb</a></li><li>jsonb_insert - <a href="json1.html#jinsb">json1.html#jinsb</a></li><li>jsonb_insert SQL function - <a href="json1.html#jinsb">json1.html#jinsb</a></li><li>jsonb_object - <a href="json1.html#jobjb">json1.html#jobjb</a></li><li>jsonb_object SQL function - <a href="json1.html#jobjb">json1.html#jobjb</a></li><li>jsonb_patch - <a href="json1.html#jpatchb">json1.html#jpatchb</a></li><li>jsonb_patch SQL function - <a href="json1.html#jpatchb">json1.html#jpatchb</a></li><li>jsonb_remove - <a href="json1.html#jrmb">json1.html#jrmb</a></li><li>jsonb_remove SQL function - <a href="json1.html#jrmb">json1.html#jrmb</a></li><li>jsonb_replace - <a href="json1.html#jreplb">json1.html#jreplb</a></li><li>jsonb_replace SQL function - <a href="json1.html#jreplb">json1.html#jreplb</a></li><li>jsonb_set - <a href="json1.html#jsetb">json1.html#jsetb</a></li><li>jsonb_set SQL function - <a href="json1.html#jsetb">json1.html#jsetb</a></li><li>julianday - <a href="lang_datefunc.html#jlndy">lang_datefunc.html#jlndy</a></li><li>julianday modifier - <a href="lang_datefunc.html#jdmod">lang_datefunc.html#jdmod</a></li><li>julianday SQL function - <a href="lang_datefunc.html#jlndy">lang_datefunc.html#jlndy</a></li><li>Kennedy - <a href="crew.html">crew.html</a></li><li>keyword index - <a href="keyword_index.html">keyword_index.html</a></li><li>keywords - <a href="lang_keywords.html">lang_keywords.html</a></li><li>langexpr - <a href="lang_expr.html">lang_expr.html</a></li><li>langindexedby - <a href="lang_indexedby.html">lang_indexedby.html</a></li><li>langkeywords - <a href="lang_keywords.html">lang_keywords.html</a></li><li>langreplace - <a href="lang_replace.html">lang_replace.html</a></li><li>languageid - <a href="fts3.html#*fts4languageid">fts3.html#*fts4languageid</a></li><li>langupdate - <a href="lang_update.html">lang_update.html</a></li><li>langvacuum - <a href="lang_vacuum.html">lang_vacuum.html</a></li><li>large WAL files - <a href="wal.html#bigwal">wal.html#bigwal</a></li><li>last_insert_rowid - <a href="lang_corefunc.html#last_insert_rowid">lang_corefunc.html#last_insert_rowid</a></li><li>last_insert_rowid method - <a href="tclsqlite.html#last_insert_rowid">tclsqlite.html#last_insert_rowid</a></li><li>last_insert_rowid SQL function - <a href="lang_corefunc.html#last_insert_rowid">lang_corefunc.html#last_insert_rowid</a></li><li>LEFT JOIN strength reduction optimization - <a href="optoverview.html#leftjoinreduction">optoverview.html#leftjoinreduction</a></li><li>legacy_alter_table - <a href="pragma.html#pragma_legacy_alter_table">pragma.html#pragma_legacy_alter_table</a></li><li>legacy_alter_table pragma - <a href="pragma.html#pragma_legacy_alter_table">pragma.html#pragma_legacy_alter_table</a></li><li>legacy_file_format - <a href="pragma.html#pragma_legacy_file_format">pragma.html#pragma_legacy_file_format</a></li><li>legacy_file_format pragma - <a href="pragma.html#pragma_legacy_file_format">pragma.html#pragma_legacy_file_format</a></li><li>Lemon - <a href="lemon.html">lemon.html</a></li><li>Lemon LALR parser generator - <a href="lemon.html">lemon.html</a></li><li>Lemon parser generator - <a href="lemon.html">lemon.html</a></li><li>length - <a href="lang_corefunc.html#length">lang_corefunc.html#length</a></li><li>length SQL function - <a href="lang_corefunc.html#length">lang_corefunc.html#length</a></li><li>library size - <a href="footprint.html">footprint.html</a></li><li>license - <a href="copyright.html">copyright.html</a></li><li>LIKE - <a href="lang_expr.html#like">lang_expr.html#like</a></li><li>like - <a href="lang_corefunc.html#like">lang_corefunc.html#like</a></li><li>LIKE optimization - <a href="optoverview.html#like_opt">optoverview.html#like_opt</a></li><li>like SQL function - <a href="lang_corefunc.html#like">lang_corefunc.html#like</a></li><li>likelihood - <a href="lang_corefunc.html#likelihood">lang_corefunc.html#likelihood</a></li><li>likelihood SQL function - <a href="lang_corefunc.html#likelihood">lang_corefunc.html#likelihood</a></li><li>likely - <a href="lang_corefunc.html#likely">lang_corefunc.html#likely</a></li><li>likely SQL function - <a href="lang_corefunc.html#likely">lang_corefunc.html#likely</a></li><li>LIMIT - <a href="lang_select.html#limitoffset">lang_select.html#limitoffset</a></li><li>limit categories - <a href="c3ref/c_limit_attached.html">c3ref/c_limit_attached.html</a></li><li>limit category - <a href="c3ref/c_limit_attached.html">c3ref/c_limit_attached.html</a></li><li>limits - <a href="limits.html">limits.html</a></li><li>list of current bytecodes - <a href="opcode.html#codes">opcode.html#codes</a></li><li>list of virtual tables - <a href="vtablist.html">vtablist.html</a></li><li>literal value - <a href="lang_expr.html#litvalue">lang_expr.html#litvalue</a></li><li>literal-value - <a href="syntax/literal-value.html">syntax/literal-value.html</a></li><li>literal-value syntax diagram - <a href="syntax/literal-value.html">syntax/literal-value.html</a></li><li>ln - <a href="lang_mathfunc.html#ln">lang_mathfunc.html#ln</a></li><li>ln SQL function - <a href="lang_mathfunc.html#ln">lang_mathfunc.html#ln</a></li><li>load_extension - <a href="lang_corefunc.html#load_extension">lang_corefunc.html#load_extension</a></li><li>load_extension SQL function - <a href="lang_corefunc.html#load_extension">lang_corefunc.html#load_extension</a></li><li>loadable extension - <a href="loadext.html">loadext.html</a></li><li>loadable extensions - <a href="loadext.html">loadext.html</a></li><li>loadext - <a href="loadext.html">loadext.html</a></li><li>localtime modifier - <a href="lang_datefunc.html#localtime">lang_datefunc.html#localtime</a></li><li>lock-byte page - <a href="fileformat2.html#lockbyte">fileformat2.html#lockbyte</a></li><li>locking_mode - <a href="pragma.html#pragma_locking_mode">pragma.html#pragma_locking_mode</a></li><li>locking_mode pragma - <a href="pragma.html#pragma_locking_mode">pragma.html#pragma_locking_mode</a></li><li>log - <a href="lang_mathfunc.html#log">lang_mathfunc.html#log</a></li><li>log2 - <a href="lang_mathfunc.html#log2">lang_mathfunc.html#log2</a></li><li>log2 SQL function - <a href="lang_mathfunc.html#log2">lang_mathfunc.html#log2</a></li><li>log10 - <a href="lang_mathfunc.html#log">lang_mathfunc.html#log</a></li><li>long term support - <a href="lts.html">lts.html</a></li><li>lookaside - <a href="malloc.html#lookaside">malloc.html#lookaside</a></li><li>lookaside buffer - <a href="malloc.html#lookaside">malloc.html#lookaside</a></li><li>lookaside memory - <a href="malloc.html#lookaside">malloc.html#lookaside</a></li><li>lookaside memory allocator - <a href="malloc.html#lookaside">malloc.html#lookaside</a></li><li>low-dependency - <a href="selfcontained.html">selfcontained.html</a></li><li>lower - <a href="lang_corefunc.html#lower">lang_corefunc.html#lower</a></li><li>lower SQL function - <a href="lang_corefunc.html#lower">lang_corefunc.html#lower</a></li><li>ltrim - <a href="lang_corefunc.html#ltrim">lang_corefunc.html#ltrim</a></li><li>ltrim SQL function - <a href="lang_corefunc.html#ltrim">lang_corefunc.html#ltrim</a></li><li>mailing lists - <a href="support.html#mailinglists">support.html#mailinglists</a></li><li>managing SQLite Archives from the command-line - <a href="sqlar.html#cltools">sqlar.html#cltools</a></li><li>Manual Control Of Query Plans Using CROSS JOIN - <a href="optoverview.html#crossjoin">optoverview.html#crossjoin</a></li><li>Manual Control Of Query Plans Using SQLITE_STAT Tables - <a href="optoverview.html#manctrl">optoverview.html#manctrl</a></li><li>master journal - <a href="tempfiles.html#superjrnl">tempfiles.html#superjrnl</a></li><li>MATCH - <a href="lang_expr.html#match">lang_expr.html#match</a></li><li>matchinfo - <a href="fts3.html#matchinfo">fts3.html#matchinfo</a></li><li>matchinfo b flag - <a href="fts3.html#matchinfo-b">fts3.html#matchinfo-b</a></li><li>matchinfo x flag - <a href="fts3.html#matchinfo-x">fts3.html#matchinfo-x</a></li><li>matchinfo y flag - <a href="fts3.html#matchinfo-y">fts3.html#matchinfo-y</a></li><li>materialization hints - <a href="lang_with.html#mathint">lang_with.html#mathint</a></li><li>MATERIALIZED - <a href="lang_with.html#mathint">lang_with.html#mathint</a></li><li>Math Functions - <a href="lang_mathfunc.html">lang_mathfunc.html</a></li><li>math functions - <a href="lang_mathfunc.html">lang_mathfunc.html</a></li><li>mathfunc - <a href="lang_mathfunc.html">lang_mathfunc.html</a></li><li>max - <a href="lang_corefunc.html#max_scalar">lang_corefunc.html#max_scalar</a></li><li>max aggregate function - <a href="lang_aggfunc.html#max_agg">lang_aggfunc.html#max_agg</a></li><li>max SQL function - <a href="lang_corefunc.html#max_scalar">lang_corefunc.html#max_scalar</a></li><li>max_agg - <a href="lang_aggfunc.html#max_agg">lang_aggfunc.html#max_agg</a></li><li>max_page_count - <a href="pragma.html#pragma_max_page_count">pragma.html#pragma_max_page_count</a></li><li>max_page_count pragma - <a href="pragma.html#pragma_max_page_count">pragma.html#pragma_max_page_count</a></li><li>max_scalar - <a href="lang_corefunc.html#max_scalar">lang_corefunc.html#max_scalar</a></li><li>maxopen parameter - <a href="swarmvtab.html#the_maxopen_parameter">swarmvtab.html#the_maxopen_parameter</a></li><li>MC/DC - <a href="testing.html#mcdc">testing.html#mcdc</a></li><li>MC/DC testing - <a href="testing.html#mcdc">testing.html#mcdc</a></li><li>memory - <a href="inmemorydb.html">inmemorydb.html</a></li><li>memory allocation - <a href="malloc.html">malloc.html</a></li><li>memory statistics - <a href="malloc.html#memstatus">malloc.html#memstatus</a></li><li>memory-mapped I/O - <a href="mmap.html">mmap.html</a></li><li>memsys2 - <a href="malloc.html#memdebug">malloc.html#memdebug</a></li><li>memsys5 - <a href="malloc.html#memsys5">malloc.html#memsys5</a></li><li>merge command - <a href="fts3.html#*fts4mergecmd">fts3.html#*fts4mergecmd</a></li><li>microoptimizations - <a href="cpu.html#microopt">cpu.html#microopt</a></li><li>min - <a href="lang_corefunc.html#min_scalar">lang_corefunc.html#min_scalar</a></li><li>min aggregate function - <a href="lang_aggfunc.html#min_agg">lang_aggfunc.html#min_agg</a></li><li>min SQL function - <a href="lang_corefunc.html#min_scalar">lang_corefunc.html#min_scalar</a></li><li>min/max optimization - <a href="optoverview.html#minmax">optoverview.html#minmax</a></li><li>min_agg - <a href="lang_aggfunc.html#min_agg">lang_aggfunc.html#min_agg</a></li><li>min_scalar - <a href="lang_corefunc.html#min_scalar">lang_corefunc.html#min_scalar</a></li><li>missing callback - <a href="swarmvtab.html#the_missing_callback">swarmvtab.html#the_missing_callback</a></li><li>mmap - <a href="mmap.html">mmap.html</a></li><li>mmap_size - <a href="pragma.html#pragma_mmap_size">pragma.html#pragma_mmap_size</a></li><li>mmap_size pragma - <a href="pragma.html#pragma_mmap_size">pragma.html#pragma_mmap_size</a></li><li>mod - <a href="lang_mathfunc.html#mod">lang_mathfunc.html#mod</a></li><li>mod SQL function - <a href="lang_mathfunc.html#mod">lang_mathfunc.html#mod</a></li><li>mode query parameter - <a href="uri.html#urimode">uri.html#urimode</a></li><li>modeof - <a href="uri.html#urimodeof">uri.html#urimodeof</a></li><li>modeof query parameter - <a href="uri.html#urimodeof">uri.html#urimodeof</a></li><li>modifiers - <a href="lang_datefunc.html#dtmods">lang_datefunc.html#dtmods</a></li><li>module_list - <a href="pragma.html#pragma_module_list">pragma.html#pragma_module_list</a></li><li>module_list pragma - <a href="pragma.html#pragma_module_list">pragma.html#pragma_module_list</a></li><li>most used - <a href="mostdeployed.html">mostdeployed.html</a></li><li>most widely deployed - <a href="mostdeployed.html">mostdeployed.html</a></li><li>most widely used - <a href="mostdeployed.html">mostdeployed.html</a></li><li>mutation test script - <a href="th3.html#muttest">th3.html#muttest</a></li><li>mutation testing - <a href="testing.html#mutationtests">testing.html#mutationtests</a></li><li>mxFrame - <a href="walformat.html#mxframe">walformat.html#mxframe</a></li><li>naming - <a href="lang_naming.html">lang_naming.html</a></li><li>nBackfill - <a href="walformat.html#nbackfill">walformat.html#nbackfill</a></li><li>NEAR queries - <a href="fts3.html#near">fts3.html#near</a></li><li>network filesystem use - <a href="useovernet.html">useovernet.html</a></li><li>Next Generation Query Planner - <a href="queryplanner-ng.html">queryplanner-ng.html</a></li><li>next generation query planner - <a href="queryplanner-ng.html">queryplanner-ng.html</a></li><li>NGQP - <a href="queryplanner-ng.html">queryplanner-ng.html</a></li><li>NOCASE - <a href="datatype3.html#collation">datatype3.html#collation</a></li><li>NOCASE collating function - <a href="datatype3.html#collation">datatype3.html#collation</a></li><li>nolock query parameter - <a href="uri.html#urinolock">uri.html#urinolock</a></li><li>non-deterministic functions - <a href="deterministic.html">deterministic.html</a></li><li>non-standard SELECT syntax - <a href="lang_select.html#nonstd">lang_select.html#nonstd</a></li><li>NOT EXISTS operator - <a href="lang_expr.html#exists_op">lang_expr.html#exists_op</a></li><li>NOT IN operator - <a href="lang_expr.html#in_op">lang_expr.html#in_op</a></li><li>NOT INDEXED - <a href="lang_indexedby.html">lang_indexedby.html</a></li><li>NOT MATERIALIZED - <a href="lang_with.html#mathint">lang_with.html#mathint</a></li><li>NOT NULL - <a href="lang_createtable.html#notnullconst">lang_createtable.html#notnullconst</a></li><li>NOT NULL constraint - <a href="lang_createtable.html#notnullconst">lang_createtable.html#notnullconst</a></li><li>NOT NULL constraints - <a href="lang_createtable.html#notnullconst">lang_createtable.html#notnullconst</a></li><li>not open-contributin - <a href="copyright.html#notopencontrib">copyright.html#notopencontrib</a></li><li>NUL characters in strings - <a href="nulinstr.html">nulinstr.html</a></li><li>nullif - <a href="lang_corefunc.html#nullif">lang_corefunc.html#nullif</a></li><li>nullif SQL function - <a href="lang_corefunc.html#nullif">lang_corefunc.html#nullif</a></li><li>NULLS FIRST - <a href="lang_select.html#nullslast">lang_select.html#nullslast</a></li><li>NULLS LAST - <a href="lang_select.html#nullslast">lang_select.html#nullslast</a></li><li>nullvalue method - <a href="tclsqlite.html#nullvalue">tclsqlite.html#nullvalue</a></li><li>numeric literals - <a href="lang_expr.html#litvalue">lang_expr.html#litvalue</a></li><li>numeric-literal - <a href="syntax/numeric-literal.html">syntax/numeric-literal.html</a></li><li>numeric-literal syntax diagram - <a href="syntax/numeric-literal.html">syntax/numeric-literal.html</a></li><li>object resolution - <a href="lang_naming.html">lang_naming.html</a></li><li>octet_length - <a href="lang_corefunc.html#octet_length">lang_corefunc.html#octet_length</a></li><li>octet_length SQL function - <a href="lang_corefunc.html#octet_length">lang_corefunc.html#octet_length</a></li><li>OFFSET - <a href="lang_select.html#limitoffset">lang_select.html#limitoffset</a></li><li>offsets - <a href="fts3.html#offsets">fts3.html#offsets</a></li><li>omit-left-join optimization - <a href="optoverview.html#omitnoopjoin">optoverview.html#omitnoopjoin</a></li><li>omit-outer-join optimization - <a href="optoverview.html#omitnoopjoin">optoverview.html#omitnoopjoin</a></li><li>omitfeatures - <a href="compile.html#omitfeatures">compile.html#omitfeatures</a></li><li>ON CONFLICT - <a href="lang_conflict.html">lang_conflict.html</a></li><li>ON CONFLICT clause - <a href="lang_conflict.html">lang_conflict.html</a></li><li>ON CONFLICT clauses - <a href="lang_conflict.html">lang_conflict.html</a></li><li>on-disk format - <a href="fileformat2.html">fileformat2.html</a></li><li>onecolumn method - <a href="tclsqlite.html#onecolumn">tclsqlite.html#onecolumn</a></li><li>opcode definitions - <a href="opcode.html#codes">opcode.html#codes</a></li><li>opcodes - <a href="opcode.html">opcode.html</a></li><li>OPEN_EXRESCODE - <a href="c3ref/open.html#openexrescode">c3ref/open.html#openexrescode</a></li><li>OPEN_NOFOLLOW - <a href="c3ref/open.html#opennofollow">c3ref/open.html#opennofollow</a></li><li>openclose callback - <a href="swarmvtab.html#the_openclose_callback">swarmvtab.html#the_openclose_callback</a></li><li>OpenOffice case study - <a href="affcase1.html">affcase1.html</a></li><li>optimize - <a href="pragma.html#pragma_optimize">pragma.html#pragma_optimize</a></li><li>optimize command - <a href="fts3.html#*fts4optcmd">fts3.html#*fts4optcmd</a></li><li>optimize pragma - <a href="pragma.html#pragma_optimize">pragma.html#pragma_optimize</a></li><li>optimizer - <a href="optoverview.html">optoverview.html</a></li><li>OR optimization - <a href="optoverview.html#or_opt">optoverview.html#or_opt</a></li><li>or optimization - <a href="optoverview.html#or_opt">optoverview.html#or_opt</a></li><li>or-connected-terms - <a href="queryplanner.html#or_in_where">queryplanner.html#or_in_where</a></li><li>ORDER BY - <a href="lang_select.html#orderby">lang_select.html#orderby</a></li><li>order by - <a href="lang_select.html#orderby">lang_select.html#orderby</a></li><li>ORDER BY clause in aggregate functions - <a href="lang_aggfunc.html#aggorderby">lang_aggfunc.html#aggorderby</a></li><li>orderByConsumed - <a href="vtab.html#obc">vtab.html#obc</a></li><li>ordering-term - <a href="syntax/ordering-term.html">syntax/ordering-term.html</a></li><li>ordering-term syntax diagram - <a href="syntax/ordering-term.html">syntax/ordering-term.html</a></li><li>ordinary common table expressions - <a href="lang_with.html#ordinarycte">lang_with.html#ordinarycte</a></li><li>OS backend - <a href="vfs.html">vfs.html</a></li><li>OSS Fuzz - <a href="testing.html#ossfuzz">testing.html#ossfuzz</a></li><li>OUTER JOIN strength reduction - <a href="optoverview.html#leftjoinreduction">optoverview.html#leftjoinreduction</a></li><li>OUTER JOIN strength reduction optimization - <a href="optoverview.html#leftjoinreduction">optoverview.html#leftjoinreduction</a></li><li>output mode - <a href="cli.html#dotmode">cli.html#dotmode</a></li><li>over-clause - <a href="syntax/over-clause.html">syntax/over-clause.html</a></li><li>over-clause syntax diagram - <a href="syntax/over-clause.html">syntax/over-clause.html</a></li><li>overflow page - <a href="fileformat2.html#ovflpgs">fileformat2.html#ovflpgs</a></li><li>overflow pages - <a href="fileformat2.html#ovflpgs">fileformat2.html#ovflpgs</a></li><li>page cache - <a href="c3ref/pcache_methods2.html">c3ref/pcache_methods2.html</a></li><li>page_count - <a href="pragma.html#pragma_page_count">pragma.html#pragma_page_count</a></li><li>page_count pragma - <a href="pragma.html#pragma_page_count">pragma.html#pragma_page_count</a></li><li>page_size - <a href="pragma.html#pragma_page_size">pragma.html#pragma_page_size</a></li><li>page_size pragma - <a href="pragma.html#pragma_page_size">pragma.html#pragma_page_size</a></li><li>pagecache memory allocator - <a href="malloc.html#pagecache">malloc.html#pagecache</a></li><li>parameter - <a href="lang_expr.html#varparam">lang_expr.html#varparam</a></li><li>parameter binding - <a href="c3ref/bind_blob.html">c3ref/bind_blob.html</a></li><li>parameters - <a href="lang_expr.html#varparam">lang_expr.html#varparam</a></li><li>parent key - <a href="foreignkeys.html#parentchild">foreignkeys.html#parentchild</a></li><li>parent table - <a href="foreignkeys.html#parentchild">foreignkeys.html#parentchild</a></li><li>parser_trace - <a href="pragma.html#pragma_parser_trace">pragma.html#pragma_parser_trace</a></li><li>parser_trace pragma - <a href="pragma.html#pragma_parser_trace">pragma.html#pragma_parser_trace</a></li><li>partial index - <a href="partialindex.html">partialindex.html</a></li><li>partial indexes - <a href="partialindex.html">partialindex.html</a></li><li>partial indices - <a href="partialindex.html">partialindex.html</a></li><li>partial sorting by index - <a href="queryplanner.html#partialsort">queryplanner.html#partialsort</a></li><li>partition - <a href="windowfunctions.html#ptxn">windowfunctions.html#ptxn</a></li><li>patchset - <a href="sessionintro.html#changeset">sessionintro.html#changeset</a></li><li>patchsets - <a href="sessionintro.html#changeset">sessionintro.html#changeset</a></li><li>PENDING - <a href="lockingv3.html#pending_lock">lockingv3.html#pending_lock</a></li><li>PENDING lock - <a href="lockingv3.html#pending_lock">lockingv3.html#pending_lock</a></li><li>pending lock - <a href="lockingv3.html#pending_lock">lockingv3.html#pending_lock</a></li><li>permuted index - <a href="sitemap.html">sitemap.html</a></li><li>persistent journal mode - <a href="pragma.html#pragma_journal_mode">pragma.html#pragma_journal_mode</a></li><li>persistent loadable extensions - <a href="loadext.html#persist">loadext.html#persist</a></li><li>phrase queries - <a href="fts3.html#phrase">fts3.html#phrase</a></li><li>pi - <a href="lang_mathfunc.html#pi">lang_mathfunc.html#pi</a></li><li>pi SQL function - <a href="lang_mathfunc.html#pi">lang_mathfunc.html#pi</a></li><li>pointer leak - <a href="bindptr.html#ptrleak">bindptr.html#ptrleak</a></li><li>pointer leaks - <a href="bindptr.html#ptrleak">bindptr.html#ptrleak</a></li><li>pointer passing interface - <a href="bindptr.html">bindptr.html</a></li><li>pointer passing interfaces - <a href="bindptr.html">bindptr.html</a></li><li>pointer types - <a href="bindptr.html#ptrtyp">bindptr.html#ptrtyp</a></li><li>pointer value - <a href="bindptr.html">bindptr.html</a></li><li>porting SQLite - <a href="custombuild.html">custombuild.html</a></li><li>pow - <a href="lang_mathfunc.html#pow">lang_mathfunc.html#pow</a></li><li>pow SQL function - <a href="lang_mathfunc.html#pow">lang_mathfunc.html#pow</a></li><li>power-safe - <a href="transactional.html">transactional.html</a></li><li>power-safe transactions - <a href="transactional.html">transactional.html</a></li><li>powersafe overwrite - <a href="psow.html">psow.html</a></li><li>PRAGMA - <a href="pragma.html#syntax">pragma.html#syntax</a></li><li>PRAGMA analysis_limit - <a href="pragma.html#pragma_analysis_limit">pragma.html#pragma_analysis_limit</a></li><li>PRAGMA application_id - <a href="pragma.html#pragma_application_id">pragma.html#pragma_application_id</a></li><li>PRAGMA auto_vacuum - <a href="pragma.html#pragma_auto_vacuum">pragma.html#pragma_auto_vacuum</a></li><li>PRAGMA automatic_index - <a href="pragma.html#pragma_automatic_index">pragma.html#pragma_automatic_index</a></li><li>PRAGMA busy_timeout - <a href="pragma.html#pragma_busy_timeout">pragma.html#pragma_busy_timeout</a></li><li>PRAGMA cache_size - <a href="pragma.html#pragma_cache_size">pragma.html#pragma_cache_size</a></li><li>PRAGMA cache_spill - <a href="pragma.html#pragma_cache_spill">pragma.html#pragma_cache_spill</a></li><li>PRAGMA case_sensitive_like - <a href="pragma.html#pragma_case_sensitive_like">pragma.html#pragma_case_sensitive_like</a></li><li>PRAGMA cell_size_check - <a href="pragma.html#pragma_cell_size_check">pragma.html#pragma_cell_size_check</a></li><li>PRAGMA checkpoint_fullfsync - <a href="pragma.html#pragma_checkpoint_fullfsync">pragma.html#pragma_checkpoint_fullfsync</a></li><li>PRAGMA collation_list - <a href="pragma.html#pragma_collation_list">pragma.html#pragma_collation_list</a></li><li>PRAGMA compile_options - <a href="pragma.html#pragma_compile_options">pragma.html#pragma_compile_options</a></li><li>PRAGMA count_changes - <a href="pragma.html#pragma_count_changes">pragma.html#pragma_count_changes</a></li><li>PRAGMA data_store_directory - <a href="pragma.html#pragma_data_store_directory">pragma.html#pragma_data_store_directory</a></li><li>PRAGMA data_version - <a href="pragma.html#pragma_data_version">pragma.html#pragma_data_version</a></li><li>PRAGMA database_list - <a href="pragma.html#pragma_database_list">pragma.html#pragma_database_list</a></li><li>PRAGMA default_cache_size - <a href="pragma.html#pragma_default_cache_size">pragma.html#pragma_default_cache_size</a></li><li>PRAGMA defer_foreign_keys - <a href="pragma.html#pragma_defer_foreign_keys">pragma.html#pragma_defer_foreign_keys</a></li><li>PRAGMA empty_result_callbacks - <a href="pragma.html#pragma_empty_result_callbacks">pragma.html#pragma_empty_result_callbacks</a></li><li>PRAGMA encoding - <a href="pragma.html#pragma_encoding">pragma.html#pragma_encoding</a></li><li>PRAGMA foreign_key_check - <a href="pragma.html#pragma_foreign_key_check">pragma.html#pragma_foreign_key_check</a></li><li>PRAGMA foreign_key_list - <a href="pragma.html#pragma_foreign_key_list">pragma.html#pragma_foreign_key_list</a></li><li>PRAGMA foreign_keys - <a href="pragma.html#pragma_foreign_keys">pragma.html#pragma_foreign_keys</a></li><li>PRAGMA freelist_count - <a href="pragma.html#pragma_freelist_count">pragma.html#pragma_freelist_count</a></li><li>PRAGMA full_column_names - <a href="pragma.html#pragma_full_column_names">pragma.html#pragma_full_column_names</a></li><li>PRAGMA fullfsync - <a href="pragma.html#pragma_fullfsync">pragma.html#pragma_fullfsync</a></li><li>PRAGMA function - <a href="pragma.html#pragfunc">pragma.html#pragfunc</a></li><li>PRAGMA function_list - <a href="pragma.html#pragma_function_list">pragma.html#pragma_function_list</a></li><li>PRAGMA functions - <a href="pragma.html#pragfunc">pragma.html#pragfunc</a></li><li>PRAGMA hard_heap_limit - <a href="pragma.html#pragma_hard_heap_limit">pragma.html#pragma_hard_heap_limit</a></li><li>PRAGMA ignore_check_constraints - <a href="pragma.html#pragma_ignore_check_constraints">pragma.html#pragma_ignore_check_constraints</a></li><li>PRAGMA incremental_vacuum - <a href="pragma.html#pragma_incremental_vacuum">pragma.html#pragma_incremental_vacuum</a></li><li>PRAGMA index_info - <a href="pragma.html#pragma_index_info">pragma.html#pragma_index_info</a></li><li>PRAGMA index_list - <a href="pragma.html#pragma_index_list">pragma.html#pragma_index_list</a></li><li>PRAGMA index_xinfo - <a href="pragma.html#pragma_index_xinfo">pragma.html#pragma_index_xinfo</a></li><li>PRAGMA integrity_check - <a href="pragma.html#pragma_integrity_check">pragma.html#pragma_integrity_check</a></li><li>PRAGMA journal_mode - <a href="pragma.html#pragma_journal_mode">pragma.html#pragma_journal_mode</a></li><li>PRAGMA journal_size_limit - <a href="pragma.html#pragma_journal_size_limit">pragma.html#pragma_journal_size_limit</a></li><li>PRAGMA legacy_alter_table - <a href="pragma.html#pragma_legacy_alter_table">pragma.html#pragma_legacy_alter_table</a></li><li>PRAGMA legacy_file_format - <a href="pragma.html#pragma_legacy_file_format">pragma.html#pragma_legacy_file_format</a></li><li>pragma list - <a href="pragma.html#toc">pragma.html#toc</a></li><li>PRAGMA locking_mode - <a href="pragma.html#pragma_locking_mode">pragma.html#pragma_locking_mode</a></li><li>PRAGMA max_page_count - <a href="pragma.html#pragma_max_page_count">pragma.html#pragma_max_page_count</a></li><li>PRAGMA mmap_size - <a href="pragma.html#pragma_mmap_size">pragma.html#pragma_mmap_size</a></li><li>PRAGMA module_list - <a href="pragma.html#pragma_module_list">pragma.html#pragma_module_list</a></li><li>PRAGMA optimize - <a href="pragma.html#pragma_optimize">pragma.html#pragma_optimize</a></li><li>PRAGMA page_count - <a href="pragma.html#pragma_page_count">pragma.html#pragma_page_count</a></li><li>PRAGMA page_size - <a href="pragma.html#pragma_page_size">pragma.html#pragma_page_size</a></li><li>PRAGMA parser_trace - <a href="pragma.html#pragma_parser_trace">pragma.html#pragma_parser_trace</a></li><li>PRAGMA pragma_list - <a href="pragma.html#pragma_pragma_list">pragma.html#pragma_pragma_list</a></li><li>PRAGMA query_only - <a href="pragma.html#pragma_query_only">pragma.html#pragma_query_only</a></li><li>PRAGMA quick_check - <a href="pragma.html#pragma_quick_check">pragma.html#pragma_quick_check</a></li><li>PRAGMA read_uncommitted - <a href="pragma.html#pragma_read_uncommitted">pragma.html#pragma_read_uncommitted</a></li><li>PRAGMA recursive_triggers - <a href="pragma.html#pragma_recursive_triggers">pragma.html#pragma_recursive_triggers</a></li><li>PRAGMA reverse_unordered_selects - <a href="pragma.html#pragma_reverse_unordered_selects">pragma.html#pragma_reverse_unordered_selects</a></li><li>PRAGMA schema_version - <a href="pragma.html#pragma_schema_version">pragma.html#pragma_schema_version</a></li><li>PRAGMA secure_delete - <a href="pragma.html#pragma_secure_delete">pragma.html#pragma_secure_delete</a></li><li>PRAGMA short_column_names - <a href="pragma.html#pragma_short_column_names">pragma.html#pragma_short_column_names</a></li><li>PRAGMA shrink_memory - <a href="pragma.html#pragma_shrink_memory">pragma.html#pragma_shrink_memory</a></li><li>PRAGMA soft_heap_limit - <a href="pragma.html#pragma_soft_heap_limit">pragma.html#pragma_soft_heap_limit</a></li><li>PRAGMA stats - <a href="pragma.html#pragma_stats">pragma.html#pragma_stats</a></li><li>PRAGMA synchronous - <a href="pragma.html#pragma_synchronous">pragma.html#pragma_synchronous</a></li><li>PRAGMA table_info - <a href="pragma.html#pragma_table_info">pragma.html#pragma_table_info</a></li><li>PRAGMA table_list - <a href="pragma.html#pragma_table_list">pragma.html#pragma_table_list</a></li><li>PRAGMA table_xinfo - <a href="pragma.html#pragma_table_xinfo">pragma.html#pragma_table_xinfo</a></li><li>PRAGMA temp_store - <a href="pragma.html#pragma_temp_store">pragma.html#pragma_temp_store</a></li><li>PRAGMA temp_store_directory - <a href="pragma.html#pragma_temp_store_directory">pragma.html#pragma_temp_store_directory</a></li><li>PRAGMA threads - <a href="pragma.html#pragma_threads">pragma.html#pragma_threads</a></li><li>PRAGMA trusted_schema - <a href="pragma.html#pragma_trusted_schema">pragma.html#pragma_trusted_schema</a></li><li>PRAGMA user_version - <a href="pragma.html#pragma_user_version">pragma.html#pragma_user_version</a></li><li>PRAGMA vdbe_addoptrace - <a href="pragma.html#pragma_vdbe_addoptrace">pragma.html#pragma_vdbe_addoptrace</a></li><li>PRAGMA vdbe_debug - <a href="pragma.html#pragma_vdbe_debug">pragma.html#pragma_vdbe_debug</a></li><li>PRAGMA vdbe_listing - <a href="pragma.html#pragma_vdbe_listing">pragma.html#pragma_vdbe_listing</a></li><li>PRAGMA vdbe_trace - <a href="pragma.html#pragma_vdbe_trace">pragma.html#pragma_vdbe_trace</a></li><li>PRAGMA wal_autocheckpoint - <a href="pragma.html#pragma_wal_autocheckpoint">pragma.html#pragma_wal_autocheckpoint</a></li><li>PRAGMA wal_checkpoint - <a href="pragma.html#pragma_wal_checkpoint">pragma.html#pragma_wal_checkpoint</a></li><li>PRAGMA writable_schema - <a href="pragma.html#pragma_writable_schema">pragma.html#pragma_writable_schema</a></li><li>pragma-stmt - <a href="syntax/pragma-stmt.html">syntax/pragma-stmt.html</a></li><li>pragma-stmt syntax diagram - <a href="syntax/pragma-stmt.html">syntax/pragma-stmt.html</a></li><li>pragma-value - <a href="syntax/pragma-value.html">syntax/pragma-value.html</a></li><li>pragma-value syntax diagram - <a href="syntax/pragma-value.html">syntax/pragma-value.html</a></li><li>pragma_list - <a href="pragma.html#pragma_pragma_list">pragma.html#pragma_pragma_list</a></li><li>pragma_list pragma - <a href="pragma.html#pragma_pragma_list">pragma.html#pragma_pragma_list</a></li><li>precompiled amalgamation tarballs - <a href="amalgamation.html#amalgtarball">amalgamation.html#amalgtarball</a></li><li>prefix queries - <a href="fts3.html#termprefix">fts3.html#termprefix</a></li><li>prefix query - <a href="fts3.html#termprefix">fts3.html#termprefix</a></li><li>prepared statement - <a href="c3ref/stmt.html">c3ref/stmt.html</a></li><li>prepared statements - <a href="c3ref/stmt.html">c3ref/stmt.html</a></li><li>preupdate method - <a href="tclsqlite.html#preupdate">tclsqlite.html#preupdate</a></li><li>PRIMARY KEY - <a href="lang_createtable.html#primkeyconst">lang_createtable.html#primkeyconst</a></li><li>PRIMARY KEY constraint - <a href="lang_createtable.html#primkeyconst">lang_createtable.html#primkeyconst</a></li><li>primary versus extended result codes - <a href="rescode.html#pve">rescode.html#pve</a></li><li>printf - <a href="lang_corefunc.html#printf">lang_corefunc.html#printf</a></li><li>printf SQL function - <a href="lang_corefunc.html#printf">lang_corefunc.html#printf</a></li><li>prior releases - <a href="chronology.html">chronology.html</a></li><li>private branches - <a href="privatebranch.html">privatebranch.html</a></li><li>professional support - <a href="prosupport.html">prosupport.html</a></li><li>profile method - <a href="tclsqlite.html#profile">tclsqlite.html#profile</a></li><li>Programming Loadable Extensions - <a href="loadext.html#write">loadext.html#write</a></li><li>progress method - <a href="tclsqlite.html#progress">tclsqlite.html#progress</a></li><li>protected sqlite3_value - <a href="c3ref/value.html">c3ref/value.html</a></li><li>PSOW - <a href="psow.html">psow.html</a></li><li>psow query parameter - <a href="uri.html#uripsow">uri.html#uripsow</a></li><li>public-domain - <a href="copyright.html">copyright.html</a></li><li>push-down optimization - <a href="optoverview.html#pushdown">optoverview.html#pushdown</a></li><li>Q - <a href="printf.html#percentq">printf.html#percentq</a></li><li>q - <a href="printf.html#percentq">printf.html#percentq</a></li><li>qbox - <a href="cli.html#qbox">cli.html#qbox</a></li><li>qbox output mode - <a href="cli.html#qbox">cli.html#qbox</a></li><li>QPSG - <a href="queryplanner-ng.html#qpstab">queryplanner-ng.html#qpstab</a></li><li>qualified-table-name - <a href="syntax/qualified-table-name.html">syntax/qualified-table-name.html</a></li><li>qualified-table-name syntax diagram - <a href="syntax/qualified-table-name.html">syntax/qualified-table-name.html</a></li><li>queries against graphs - <a href="lang_with.html#rcex3">lang_with.html#rcex3</a></li><li>query flattener - <a href="optoverview.html#flattening">optoverview.html#flattening</a></li><li>query parameters with special meaning to SQLite - <a href="uri.html#coreqp">uri.html#coreqp</a></li><li>query planner - <a href="optoverview.html">optoverview.html</a></li><li>query planner checklist - <a href="queryplanner-ng.html#howtofix">queryplanner-ng.html#howtofix</a></li><li>query planner stability guarantee - <a href="queryplanner-ng.html#qpstab">queryplanner-ng.html#qpstab</a></li><li>query-time index - <a href="optoverview.html#autoindex">optoverview.html#autoindex</a></li><li>Query-time indexes - <a href="optoverview.html#autoindex">optoverview.html#autoindex</a></li><li>Query-time indexing - <a href="optoverview.html#autoindex">optoverview.html#autoindex</a></li><li>query-time indexing - <a href="optoverview.html#autoindex">optoverview.html#autoindex</a></li><li>query_only - <a href="pragma.html#pragma_query_only">pragma.html#pragma_query_only</a></li><li>query_only pragma - <a href="pragma.html#pragma_query_only">pragma.html#pragma_query_only</a></li><li>Quick Start Guide - <a href="quickstart.html">quickstart.html</a></li><li>quick_check - <a href="pragma.html#pragma_quick_check">pragma.html#pragma_quick_check</a></li><li>quick_check pragma - <a href="pragma.html#pragma_quick_check">pragma.html#pragma_quick_check</a></li><li>quickstart - <a href="quickstart.html">quickstart.html</a></li><li>Quirks - <a href="quirks.html">quirks.html</a></li><li>quote - <a href="lang_corefunc.html#quote">lang_corefunc.html#quote</a></li><li>quote SQL function - <a href="lang_corefunc.html#quote">lang_corefunc.html#quote</a></li><li>R-Tree extension - <a href="rtree.html">rtree.html</a></li><li>R-Trees - <a href="rtree.html">rtree.html</a></li><li>radians - <a href="lang_mathfunc.html#radians">lang_mathfunc.html#radians</a></li><li>radians SQL function - <a href="lang_mathfunc.html#radians">lang_mathfunc.html#radians</a></li><li>RAISE function - <a href="lang_createtrigger.html#raise">lang_createtrigger.html#raise</a></li><li>raise-function - <a href="syntax/raise-function.html">syntax/raise-function.html</a></li><li>raise-function syntax diagram - <a href="syntax/raise-function.html">syntax/raise-function.html</a></li><li>random - <a href="lang_corefunc.html#random">lang_corefunc.html#random</a></li><li>random SQL function - <a href="lang_corefunc.html#random">lang_corefunc.html#random</a></li><li>randomblob - <a href="lang_corefunc.html#randomblob">lang_corefunc.html#randomblob</a></li><li>randomblob SQL function - <a href="lang_corefunc.html#randomblob">lang_corefunc.html#randomblob</a></li><li>RANGE frames - <a href="windowfunctions.html#rangetype">windowfunctions.html#rangetype</a></li><li>RANGE n FOLLOWING - <a href="windowfunctions.html#exprrange">windowfunctions.html#exprrange</a></li><li>RANGE n PRECEDING - <a href="windowfunctions.html#exprrange">windowfunctions.html#exprrange</a></li><li>range query optimization - <a href="optoverview.html#rangequery">optoverview.html#rangequery</a></li><li>RBU - <a href="rbu.html">rbu.html</a></li><li>RBU Database Contents - <a href="rbu.html#database_contents">rbu.html#database_contents</a></li><li>RBU Database Tables - <a href="rbu.html#database_tables">rbu.html#database_tables</a></li><li>RBU extension - <a href="rbu.html">rbu.html</a></li><li>RBU FTS3/4 Tables - <a href="rbu.html#fts4_tables">rbu.html#fts4_tables</a></li><li>RBU Update - <a href="rbu.html#rbu_updates">rbu.html#rbu_updates</a></li><li>RBU Vacuum - <a href="rbu.html#rbu_vacuum">rbu.html#rbu_vacuum</a></li><li>read-only WAL databases - <a href="wal.html#readonly">wal.html#readonly</a></li><li>read_uncommitted - <a href="pragma.html#pragma_read_uncommitted">pragma.html#pragma_read_uncommitted</a></li><li>read_uncommitted pragma - <a href="pragma.html#pragma_read_uncommitted">pragma.html#pragma_read_uncommitted</a></li><li>reading and writing an rtree at the same time - <a href="rtree.html#readwrite">rtree.html#readwrite</a></li><li>rebuild command - <a href="fts3.html#*fts4rebuidcmd">fts3.html#*fts4rebuidcmd</a></li><li>recent CVEs - <a href="cves.html#cvetab">cves.html#cvetab</a></li><li>recommended by the US Library of Congress - <a href="locrsf.html">locrsf.html</a></li><li>recommended compile-time option - <a href="compile.html#rcmd">compile.html#rcmd</a></li><li>recommended compile-time options - <a href="compile.html#rcmd">compile.html#rcmd</a></li><li>recommended storage format - <a href="locrsf.html">locrsf.html</a></li><li>Recommended usage patterns for ANALYZE - <a href="lang_analyze.html#req">lang_analyze.html#req</a></li><li>record format - <a href="fileformat2.html#record_format">fileformat2.html#record_format</a></li><li>recovery - <a href="walformat.html#recovery">walformat.html#recovery</a></li><li>recovery extension - <a href="recovery.html">recovery.html</a></li><li>recursive common table expression - <a href="lang_with.html#recursivecte">lang_with.html#recursivecte</a></li><li>recursive common table expressions - <a href="lang_with.html#recursivecte">lang_with.html#recursivecte</a></li><li>recursive query - <a href="lang_with.html#recursivecte">lang_with.html#recursivecte</a></li><li>recursive-cte - <a href="syntax/recursive-cte.html">syntax/recursive-cte.html</a></li><li>recursive-cte syntax diagram - <a href="syntax/recursive-cte.html">syntax/recursive-cte.html</a></li><li>recursive_triggers - <a href="pragma.html#pragma_recursive_triggers">pragma.html#pragma_recursive_triggers</a></li><li>recursive_triggers pragma - <a href="pragma.html#pragma_recursive_triggers">pragma.html#pragma_recursive_triggers</a></li><li>REGEXP - <a href="lang_expr.html#regexp">lang_expr.html#regexp</a></li><li>REINDEX - <a href="lang_reindex.html">lang_reindex.html</a></li><li>reindex - <a href="lang_reindex.html">lang_reindex.html</a></li><li>reindex-stmt - <a href="syntax/reindex-stmt.html">syntax/reindex-stmt.html</a></li><li>reindex-stmt syntax diagram - <a href="syntax/reindex-stmt.html">syntax/reindex-stmt.html</a></li><li>RELEASE - <a href="lang_savepoint.html">lang_savepoint.html</a></li><li>release history - <a href="changes.html">changes.html</a></li><li>release testing checklists - <a href="testing.html#cklist">testing.html#cklist</a></li><li>release-stmt - <a href="syntax/release-stmt.html">syntax/release-stmt.html</a></li><li>release-stmt syntax diagram - <a href="syntax/release-stmt.html">syntax/release-stmt.html</a></li><li>relfootprint - <a href="footprint.html">footprint.html</a></li><li>rename column - <a href="lang_altertable.html#altertabmvcol">lang_altertable.html#altertabmvcol</a></li><li>rename table - <a href="lang_altertable.html#altertabrename">lang_altertable.html#altertabrename</a></li><li>REPLACE - <a href="lang_replace.html">lang_replace.html</a></li><li>replace - <a href="lang_corefunc.html#replace">lang_corefunc.html#replace</a></li><li>replace SQL function - <a href="lang_corefunc.html#replace">lang_corefunc.html#replace</a></li><li>reported vulnerabilities - <a href="cves.html">cves.html</a></li><li>requirements - <a href="requirements.html">requirements.html</a></li><li>reserve bytes - <a href="fileformat2.html#resbyte">fileformat2.html#resbyte</a></li><li>RESERVED - <a href="lockingv3.html#reserved_lock">lockingv3.html#reserved_lock</a></li><li>RESERVED lock - <a href="lockingv3.html#reserved_lock">lockingv3.html#reserved_lock</a></li><li>reserved lock - <a href="lockingv3.html#reserved_lock">lockingv3.html#reserved_lock</a></li><li>reset the WAL - <a href="fileformat2.html#walreset">fileformat2.html#walreset</a></li><li>restore method - <a href="tclsqlite.html#restore">tclsqlite.html#restore</a></li><li>result code - <a href="rescode.html">rescode.html</a></li><li>result code definitions - <a href="c3ref/c_abort.html">c3ref/c_abort.html</a></li><li>result codes - <a href="rescode.html">rescode.html</a></li><li>result-column - <a href="syntax/result-column.html">syntax/result-column.html</a></li><li>result-column syntax diagram - <a href="syntax/result-column.html">syntax/result-column.html</a></li><li>result-set expressions - <a href="lang_select.html#resultset">lang_select.html#resultset</a></li><li>RETURNING - <a href="lang_returning.html">lang_returning.html</a></li><li>returning - <a href="lang_returning.html">lang_returning.html</a></li><li>RETURNING clause - <a href="lang_returning.html">lang_returning.html</a></li><li>returning-clause - <a href="syntax/returning-clause.html">syntax/returning-clause.html</a></li><li>returning-clause syntax diagram - <a href="syntax/returning-clause.html">syntax/returning-clause.html</a></li><li>reverse_unordered_selects - <a href="pragma.html#pragma_reverse_unordered_selects">pragma.html#pragma_reverse_unordered_selects</a></li><li>reverse_unordered_selects pragma - <a href="pragma.html#pragma_reverse_unordered_selects">pragma.html#pragma_reverse_unordered_selects</a></li><li>RIGHT and FULL OUTER JOIN - <a href="lang_select.html#rjoin">lang_select.html#rjoin</a></li><li>RIGHT JOIN - <a href="lang_select.html#rjoin">lang_select.html#rjoin</a></li><li>Robson proof - <a href="malloc.html#nofrag">malloc.html#nofrag</a></li><li>ROLLBACK - <a href="lang_transaction.html">lang_transaction.html</a></li><li>rollback journal - <a href="lockingv3.html#rollback">lockingv3.html#rollback</a></li><li>rollback journal format - <a href="fileformat2.html#rollbackjournal">fileformat2.html#rollbackjournal</a></li><li>rollback-stmt - <a href="syntax/rollback-stmt.html">syntax/rollback-stmt.html</a></li><li>rollback-stmt syntax diagram - <a href="syntax/rollback-stmt.html">syntax/rollback-stmt.html</a></li><li>rollback_hook method - <a href="tclsqlite.html#rollback_hook">tclsqlite.html#rollback_hook</a></li><li>round - <a href="lang_corefunc.html#round">lang_corefunc.html#round</a></li><li>round SQL function - <a href="lang_corefunc.html#round">lang_corefunc.html#round</a></li><li>row value - <a href="rowvalue.html">rowvalue.html</a></li><li>row value IN operator - <a href="rowvalue.html#rvinop">rowvalue.html#rvinop</a></li><li>row values - <a href="rowvalue.html">rowvalue.html</a></li><li>ROWID - <a href="lang_createtable.html#rowid">lang_createtable.html#rowid</a></li><li>rowid - <a href="lang_createtable.html#rowid">lang_createtable.html#rowid</a></li><li>rowid table - <a href="rowidtable.html">rowidtable.html</a></li><li>rowid tables - <a href="rowidtable.html">rowidtable.html</a></li><li>rowvalue - <a href="rowvalue.html">rowvalue.html</a></li><li>RTREE - <a href="rtree.html">rtree.html</a></li><li>rtree - <a href="rtree.html">rtree.html</a></li><li>rtree shadow tables - <a href="rtree.html#xshadow">rtree.html#xshadow</a></li><li>rtreecheck - <a href="rtree.html#rtreecheck">rtree.html#rtreecheck</a></li><li>RTRIM - <a href="datatype3.html#collation">datatype3.html#collation</a></li><li>rtrim - <a href="lang_corefunc.html#rtrim">lang_corefunc.html#rtrim</a></li><li>RTRIM collating function - <a href="datatype3.html#collation">datatype3.html#collation</a></li><li>rtrim SQL function - <a href="lang_corefunc.html#rtrim">lang_corefunc.html#rtrim</a></li><li>rules for determining column affinity - <a href="datatype3.html#affname">datatype3.html#affname</a></li><li>rules for determining column affinity in VIEWs - <a href="datatype3.html#affview">datatype3.html#affview</a></li><li>Run-Time Loadable Extensions - <a href="loadext.html">loadext.html</a></li><li>running ANALYZE via PRAGMA optimize - <a href="lang_analyze.html#pragopt">lang_analyze.html#pragopt</a></li><li>safe command-line option - <a href="cli.html#safemode">cli.html#safemode</a></li><li>SAVEPOINT - <a href="lang_savepoint.html">lang_savepoint.html</a></li><li>savepoint - <a href="lang_savepoint.html">lang_savepoint.html</a></li><li>SAVEPOINT bug - <a href="howtocorrupt.html#svptbug">howtocorrupt.html#svptbug</a></li><li>savepoint-stmt - <a href="syntax/savepoint-stmt.html">syntax/savepoint-stmt.html</a></li><li>savepoint-stmt syntax diagram - <a href="syntax/savepoint-stmt.html">syntax/savepoint-stmt.html</a></li><li>Scalar Functions - <a href="lang_corefunc.html">lang_corefunc.html</a></li><li>scalar functions - <a href="lang_corefunc.html">lang_corefunc.html</a></li><li>scan status flags - <a href="c3ref/c_scanstat_complex.html">c3ref/c_scanstat_complex.html</a></li><li>scanstatus options - <a href="c3ref/c_scanstat_est.html">c3ref/c_scanstat_est.html</a></li><li>schema format - <a href="fileformat2.html#schemaformat">fileformat2.html#schemaformat</a></li><li>schema format number - <a href="fileformat2.html#schemaformat">fileformat2.html#schemaformat</a></li><li>schema storage - <a href="fileformat2.html#ffschema">fileformat2.html#ffschema</a></li><li>schema_version - <a href="pragma.html#pragma_schema_version">pragma.html#pragma_schema_version</a></li><li>schema_version pragma - <a href="pragma.html#pragma_schema_version">pragma.html#pragma_schema_version</a></li><li>search application tips - <a href="fts3.html#appendix_a">fts3.html#appendix_a</a></li><li>second edition file format document - <a href="fileformat2.html">fileformat2.html</a></li><li>secure_delete - <a href="pragma.html#pragma_secure_delete">pragma.html#pragma_secure_delete</a></li><li>secure_delete pragma - <a href="pragma.html#pragma_secure_delete">pragma.html#pragma_secure_delete</a></li><li>security - <a href="security.html">security.html</a></li><li>segment btree - <a href="fts3.html#data_structures">fts3.html#data_structures</a></li><li>SELECT - <a href="lang_select.html">lang_select.html</a></li><li>select - <a href="lang_select.html">lang_select.html</a></li><li>SELECT query - <a href="lang_select.html">lang_select.html</a></li><li>SELECT statement - <a href="lang_select.html">lang_select.html</a></li><li>select-core - <a href="syntax/select-core.html">syntax/select-core.html</a></li><li>select-core syntax diagram - <a href="syntax/select-core.html">syntax/select-core.html</a></li><li>select-stmt - <a href="syntax/select-stmt.html">syntax/select-stmt.html</a></li><li>select-stmt syntax diagram - <a href="syntax/select-stmt.html">syntax/select-stmt.html</a></li><li>self-contained - <a href="selfcontained.html">selfcontained.html</a></li><li>separating a database from its journal - <a href="howtocorrupt.html#roguejrnl">howtocorrupt.html#roguejrnl</a></li><li>serial type - <a href="fileformat2.html#serialtype">fileformat2.html#serialtype</a></li><li>serial types - <a href="fileformat2.html#serialtype">fileformat2.html#serialtype</a></li><li>serialize method - <a href="tclsqlite.html#serialize">tclsqlite.html#serialize</a></li><li>series - <a href="series.html">series.html</a></li><li>server-side database - <a href="whentouse.html#serversidedb">whentouse.html#serversidedb</a></li><li>serverless - <a href="serverless.html">serverless.html</a></li><li>session - <a href="sessionintro.html">sessionintro.html</a></li><li>session extension - <a href="sessionintro.html">sessionintro.html</a></li><li>Session Extension C-language Interface - <a href="session/intro.html">session/intro.html</a></li><li>Session Module C-API function list - <a href="session/funclist.html">session/funclist.html</a></li><li>session-capi - <a href="session/intro.html">session/intro.html</a></li><li>session_funclist - <a href="session/funclist.html">session/funclist.html</a></li><li>shadow table - <a href="vtab.html#xshadowname">vtab.html#xshadowname</a></li><li>shadow tables - <a href="vtab.html#xshadowname">vtab.html#xshadowname</a></li><li>shadowtabs - <a href="fts3.html#shadow_tables">fts3.html#shadow_tables</a></li><li>SHARED - <a href="lockingv3.html#shared_lock">lockingv3.html#shared_lock</a></li><li>shared cache - <a href="sharedcache.html">sharedcache.html</a></li><li>shared cache mode - <a href="sharedcache.html">sharedcache.html</a></li><li>SHARED lock - <a href="lockingv3.html#shared_lock">lockingv3.html#shared_lock</a></li><li>shared lock - <a href="lockingv3.html#shared_lock">lockingv3.html#shared_lock</a></li><li>shims - <a href="vfs.html#shim">vfs.html#shim</a></li><li>shm file - <a href="walformat.html#shm">walformat.html#shm</a></li><li>short filenames - <a href="shortnames.html">shortnames.html</a></li><li>short_column_names - <a href="pragma.html#pragma_short_column_names">pragma.html#pragma_short_column_names</a></li><li>short_column_names pragma - <a href="pragma.html#pragma_short_column_names">pragma.html#pragma_short_column_names</a></li><li>shrink_memory - <a href="pragma.html#pragma_shrink_memory">pragma.html#pragma_shrink_memory</a></li><li>shrink_memory pragma - <a href="pragma.html#pragma_shrink_memory">pragma.html#pragma_shrink_memory</a></li><li>sign - <a href="lang_corefunc.html#sign">lang_corefunc.html#sign</a></li><li>sign SQL function - <a href="lang_corefunc.html#sign">lang_corefunc.html#sign</a></li><li>signed-number - <a href="syntax/signed-number.html">syntax/signed-number.html</a></li><li>signed-number syntax diagram - <a href="syntax/signed-number.html">syntax/signed-number.html</a></li><li>simple fts queries - <a href="fts3.html#simple_fts_queries">fts3.html#simple_fts_queries</a></li><li>simple SELECT - <a href="lang_select.html#simpleselect">lang_select.html#simpleselect</a></li><li>simple-function-invocation - <a href="syntax/simple-function-invocation.html">syntax/simple-function-invocation.html</a></li><li>simple-function-invocation syntax diagram - <a href="syntax/simple-function-invocation.html">syntax/simple-function-invocation.html</a></li><li>simple-select-stmt - <a href="syntax/simple-select-stmt.html">syntax/simple-select-stmt.html</a></li><li>simple-select-stmt syntax diagram - <a href="syntax/simple-select-stmt.html">syntax/simple-select-stmt.html</a></li><li>sin - <a href="lang_mathfunc.html#sin">lang_mathfunc.html#sin</a></li><li>sin SQL function - <a href="lang_mathfunc.html#sin">lang_mathfunc.html#sin</a></li><li>single-argument carray - <a href="carray.html#onearg">carray.html#onearg</a></li><li>sinh - <a href="lang_mathfunc.html#sinh">lang_mathfunc.html#sinh</a></li><li>sinh SQL function - <a href="lang_mathfunc.html#sinh">lang_mathfunc.html#sinh</a></li><li>skip-scan - <a href="optoverview.html#skipscan">optoverview.html#skipscan</a></li><li>skip-scan optimization - <a href="optoverview.html#skipscan">optoverview.html#skipscan</a></li><li>SLT - <a href="testing.html#slt">testing.html#slt</a></li><li>snapshot - <a href="c3ref/snapshot.html">c3ref/snapshot.html</a></li><li>snippet - <a href="fts3.html#snippet">fts3.html#snippet</a></li><li>soft_heap_limit - <a href="pragma.html#pragma_soft_heap_limit">pragma.html#pragma_soft_heap_limit</a></li><li>soft_heap_limit pragma - <a href="pragma.html#pragma_soft_heap_limit">pragma.html#pragma_soft_heap_limit</a></li><li>solve Sudoku puzzles - <a href="lang_with.html#sudoku">lang_with.html#sudoku</a></li><li>sort order - <a href="datatype3.html#sortorder">datatype3.html#sortorder</a></li><li>sorting - <a href="queryplanner.html#sorting">queryplanner.html#sorting</a></li><li>sorting subsets of the result - <a href="optoverview.html#partsort">optoverview.html#partsort</a></li><li>soundex - <a href="lang_corefunc.html#soundex">lang_corefunc.html#soundex</a></li><li>soundex SQL function - <a href="lang_corefunc.html#soundex">lang_corefunc.html#soundex</a></li><li>spellfix1 - <a href="spellfix1.html">spellfix1.html</a></li><li>split amalgamation - <a href="amalgamation.html#amal32k">amalgamation.html#amal32k</a></li><li>SQL Archive - <a href="sqlar.html">sqlar.html</a></li><li>SQL fuzzing - <a href="testing.html#fuzztesting">testing.html#fuzztesting</a></li><li>SQL keyword - <a href="lang_keywords.html">lang_keywords.html</a></li><li>SQL keywords - <a href="lang_keywords.html">lang_keywords.html</a></li><li>SQL Logic Tests - <a href="testing.html#slt">testing.html#slt</a></li><li>SQL parameter - <a href="c3ref/bind_blob.html">c3ref/bind_blob.html</a></li><li>SQL parameters - <a href="c3ref/bind_blob.html">c3ref/bind_blob.html</a></li><li>sql parameters - <a href="swarmvtab.html#sql_parameters">swarmvtab.html#sql_parameters</a></li><li>SQL statement compiler - <a href="c3ref/prepare.html">c3ref/prepare.html</a></li><li>sql-stmt - <a href="syntax/sql-stmt.html">syntax/sql-stmt.html</a></li><li>sql-stmt syntax diagram - <a href="syntax/sql-stmt.html">syntax/sql-stmt.html</a></li><li>sql-stmt-list - <a href="syntax/sql-stmt-list.html">syntax/sql-stmt-list.html</a></li><li>sql-stmt-list syntax diagram - <a href="syntax/sql-stmt-list.html">syntax/sql-stmt-list.html</a></li><li>SQLAR - <a href="sqlar.html">sqlar.html</a></li><li>sqldiff - <a href="sqldiff.html">sqldiff.html</a></li><li>sqldiff --rbu - <a href="rbu.html#sqldiff">rbu.html#sqldiff</a></li><li>sqldiff.exe - <a href="sqldiff.html">sqldiff.html</a></li><li>SQLite amalgamation source file - <a href="amalgamation.html">amalgamation.html</a></li><li>SQLite Archive - <a href="sqlar.html">sqlar.html</a></li><li>SQLite Archive files - <a href="sqlar.html">sqlar.html</a></li><li>SQLite Archive format - <a href="sqlar.html">sqlar.html</a></li><li>SQLite Archive smaller than ZIP - <a href="affcase1.html#smaller">affcase1.html#smaller</a></li><li>SQLite Consortium - <a href="consortium.html">consortium.html</a></li><li>SQLite database file format - <a href="fileformat2.html">fileformat2.html</a></li><li>SQLite extension - <a href="loadext.html">loadext.html</a></li><li>SQLite extensions - <a href="loadext.html">loadext.html</a></li><li>SQLite Keywords - <a href="lang_keywords.html">lang_keywords.html</a></li><li>SQLite query planner - <a href="optoverview.html">optoverview.html</a></li><li>SQLite Shared-Cache Mode - <a href="sharedcache.html">sharedcache.html</a></li><li>SQLite source code repositories - <a href="download.html#srctree">download.html#srctree</a></li><li>sqlite3 - <a href="c3ref/sqlite3.html">c3ref/sqlite3.html</a></li><li>sqlite3.exe - <a href="cli.html">cli.html</a></li><li>sqlite3.exe command-line shell - <a href="cli.html">cli.html</a></li><li>sqlite3_aggregate_context - <a href="c3ref/aggregate_context.html">c3ref/aggregate_context.html</a></li><li>sqlite3_aggregate_count - <a href="c3ref/aggregate_count.html">c3ref/aggregate_count.html</a></li><li>sqlite3_analyzer - <a href="sqlanalyze.html">sqlanalyze.html</a></li><li>sqlite3_analyzer.exe - <a href="sqlanalyze.html">sqlanalyze.html</a></li><li>sqlite3_api_routines - <a href="c3ref/api_routines.html">c3ref/api_routines.html</a></li><li>sqlite3_auto_extension - <a href="c3ref/auto_extension.html">c3ref/auto_extension.html</a></li><li>sqlite3_autovacuum_pages - <a href="c3ref/autovacuum_pages.html">c3ref/autovacuum_pages.html</a></li><li>sqlite3_backup - <a href="c3ref/backup.html">c3ref/backup.html</a></li><li>sqlite3_backup_finish - <a href="c3ref/backup_finish.html#sqlite3backupfinish">c3ref/backup_finish.html#sqlite3backupfinish</a></li><li>sqlite3_backup_init - <a href="c3ref/backup_finish.html#sqlite3backupinit">c3ref/backup_finish.html#sqlite3backupinit</a></li><li>sqlite3_backup_pagecount - <a href="c3ref/backup_finish.html#sqlite3backuppagecount">c3ref/backup_finish.html#sqlite3backuppagecount</a></li><li>sqlite3_backup_remaining - <a href="c3ref/backup_finish.html#sqlite3backupremaining">c3ref/backup_finish.html#sqlite3backupremaining</a></li><li>sqlite3_backup_step - <a href="c3ref/backup_finish.html#sqlite3backupstep">c3ref/backup_finish.html#sqlite3backupstep</a></li><li>sqlite3_bind_blob - <a href="c3ref/bind_blob.html">c3ref/bind_blob.html</a></li><li>sqlite3_bind_blob64 - <a href="c3ref/bind_blob.html">c3ref/bind_blob.html</a></li><li>sqlite3_bind_double - <a href="c3ref/bind_blob.html">c3ref/bind_blob.html</a></li><li>sqlite3_bind_int - <a href="c3ref/bind_blob.html">c3ref/bind_blob.html</a></li><li>sqlite3_bind_int64 - <a href="c3ref/bind_blob.html">c3ref/bind_blob.html</a></li><li>sqlite3_bind_null - <a href="c3ref/bind_blob.html">c3ref/bind_blob.html</a></li><li>sqlite3_bind_parameter_count - <a href="c3ref/bind_parameter_count.html">c3ref/bind_parameter_count.html</a></li><li>sqlite3_bind_parameter_index - <a href="c3ref/bind_parameter_index.html">c3ref/bind_parameter_index.html</a></li><li>sqlite3_bind_parameter_name - <a href="c3ref/bind_parameter_name.html">c3ref/bind_parameter_name.html</a></li><li>sqlite3_bind_pointer - <a href="c3ref/bind_blob.html">c3ref/bind_blob.html</a></li><li>sqlite3_bind_text - <a href="c3ref/bind_blob.html">c3ref/bind_blob.html</a></li><li>sqlite3_bind_text16 - <a href="c3ref/bind_blob.html">c3ref/bind_blob.html</a></li><li>sqlite3_bind_text64 - <a href="c3ref/bind_blob.html">c3ref/bind_blob.html</a></li><li>sqlite3_bind_value - <a href="c3ref/bind_blob.html">c3ref/bind_blob.html</a></li><li>sqlite3_bind_zeroblob - <a href="c3ref/bind_blob.html">c3ref/bind_blob.html</a></li><li>sqlite3_bind_zeroblob64 - <a href="c3ref/bind_blob.html">c3ref/bind_blob.html</a></li><li>sqlite3_blob - <a href="c3ref/blob.html">c3ref/blob.html</a></li><li>sqlite3_blob_bytes - <a href="c3ref/blob_bytes.html">c3ref/blob_bytes.html</a></li><li>sqlite3_blob_close - <a href="c3ref/blob_close.html">c3ref/blob_close.html</a></li><li>sqlite3_blob_open - <a href="c3ref/blob_open.html">c3ref/blob_open.html</a></li><li>sqlite3_blob_read - <a href="c3ref/blob_read.html">c3ref/blob_read.html</a></li><li>sqlite3_blob_reopen - <a href="c3ref/blob_reopen.html">c3ref/blob_reopen.html</a></li><li>sqlite3_blob_write - <a href="c3ref/blob_write.html">c3ref/blob_write.html</a></li><li>sqlite3_busy_handler - <a href="c3ref/busy_handler.html">c3ref/busy_handler.html</a></li><li>sqlite3_busy_timeout - <a href="c3ref/busy_timeout.html">c3ref/busy_timeout.html</a></li><li>sqlite3_cancel_auto_extension - <a href="c3ref/cancel_auto_extension.html">c3ref/cancel_auto_extension.html</a></li><li>sqlite3_carray_bind - <a href="carray.html#onearg">carray.html#onearg</a></li><li>sqlite3_changegroup - <a href="session/changegroup.html">session/changegroup.html</a></li><li>sqlite3_changes - <a href="c3ref/changes.html">c3ref/changes.html</a></li><li>sqlite3_changes64 - <a href="c3ref/changes.html">c3ref/changes.html</a></li><li>sqlite3_changeset_iter - <a href="session/changeset_iter.html">session/changeset_iter.html</a></li><li>sqlite3_clear_bindings - <a href="c3ref/clear_bindings.html">c3ref/clear_bindings.html</a></li><li>sqlite3_close - <a href="c3ref/close.html">c3ref/close.html</a></li><li>sqlite3_close_v2 - <a href="c3ref/close.html">c3ref/close.html</a></li><li>sqlite3_collation_needed - <a href="c3ref/collation_needed.html">c3ref/collation_needed.html</a></li><li>sqlite3_collation_needed16 - <a href="c3ref/collation_needed.html">c3ref/collation_needed.html</a></li><li>sqlite3_column_blob - <a href="c3ref/column_blob.html">c3ref/column_blob.html</a></li><li>sqlite3_column_bytes - <a href="c3ref/column_blob.html">c3ref/column_blob.html</a></li><li>sqlite3_column_bytes16 - <a href="c3ref/column_blob.html">c3ref/column_blob.html</a></li><li>sqlite3_column_count - <a href="c3ref/column_count.html">c3ref/column_count.html</a></li><li>sqlite3_column_database_name - <a href="c3ref/column_database_name.html">c3ref/column_database_name.html</a></li><li>sqlite3_column_database_name16 - <a href="c3ref/column_database_name.html">c3ref/column_database_name.html</a></li><li>sqlite3_column_decltype - <a href="c3ref/column_decltype.html">c3ref/column_decltype.html</a></li><li>sqlite3_column_decltype16 - <a href="c3ref/column_decltype.html">c3ref/column_decltype.html</a></li><li>sqlite3_column_double - <a href="c3ref/column_blob.html">c3ref/column_blob.html</a></li><li>sqlite3_column_int - <a href="c3ref/column_blob.html">c3ref/column_blob.html</a></li><li>sqlite3_column_int64 - <a href="c3ref/column_blob.html">c3ref/column_blob.html</a></li><li>sqlite3_column_name - <a href="c3ref/column_name.html">c3ref/column_name.html</a></li><li>sqlite3_column_name16 - <a href="c3ref/column_name.html">c3ref/column_name.html</a></li><li>sqlite3_column_origin_name - <a href="c3ref/column_database_name.html">c3ref/column_database_name.html</a></li><li>sqlite3_column_origin_name16 - <a href="c3ref/column_database_name.html">c3ref/column_database_name.html</a></li><li>sqlite3_column_table_name - <a href="c3ref/column_database_name.html">c3ref/column_database_name.html</a></li><li>sqlite3_column_table_name16 - <a href="c3ref/column_database_name.html">c3ref/column_database_name.html</a></li><li>sqlite3_column_text - <a href="c3ref/column_blob.html">c3ref/column_blob.html</a></li><li>sqlite3_column_text16 - <a href="c3ref/column_blob.html">c3ref/column_blob.html</a></li><li>sqlite3_column_type - <a href="c3ref/column_blob.html">c3ref/column_blob.html</a></li><li>sqlite3_column_value - <a href="c3ref/column_blob.html">c3ref/column_blob.html</a></li><li>sqlite3_commit_hook - <a href="c3ref/commit_hook.html">c3ref/commit_hook.html</a></li><li>sqlite3_compileoption_get - <a href="c3ref/compileoption_get.html">c3ref/compileoption_get.html</a></li><li>sqlite3_compileoption_used - <a href="c3ref/compileoption_get.html">c3ref/compileoption_get.html</a></li><li>sqlite3_complete - <a href="c3ref/complete.html">c3ref/complete.html</a></li><li>sqlite3_complete16 - <a href="c3ref/complete.html">c3ref/complete.html</a></li><li>sqlite3_config - <a href="c3ref/config.html">c3ref/config.html</a></li><li>sqlite3_context - <a href="c3ref/context.html">c3ref/context.html</a></li><li>sqlite3_context_db_handle - <a href="c3ref/context_db_handle.html">c3ref/context_db_handle.html</a></li><li>sqlite3_create_collation - <a href="c3ref/create_collation.html">c3ref/create_collation.html</a></li><li>sqlite3_create_collation16 - <a href="c3ref/create_collation.html">c3ref/create_collation.html</a></li><li>sqlite3_create_collation_v2 - <a href="c3ref/create_collation.html">c3ref/create_collation.html</a></li><li>sqlite3_create_filename - <a href="c3ref/create_filename.html">c3ref/create_filename.html</a></li><li>sqlite3_create_function - <a href="c3ref/create_function.html">c3ref/create_function.html</a></li><li>sqlite3_create_function16 - <a href="c3ref/create_function.html">c3ref/create_function.html</a></li><li>sqlite3_create_function_v2 - <a href="c3ref/create_function.html">c3ref/create_function.html</a></li><li>sqlite3_create_module - <a href="c3ref/create_module.html">c3ref/create_module.html</a></li><li>sqlite3_create_module_v2 - <a href="c3ref/create_module.html">c3ref/create_module.html</a></li><li>sqlite3_create_window_function - <a href="c3ref/create_function.html">c3ref/create_function.html</a></li><li>sqlite3_data_count - <a href="c3ref/data_count.html">c3ref/data_count.html</a></li><li>sqlite3_data_directory - <a href="c3ref/data_directory.html">c3ref/data_directory.html</a></li><li>sqlite3_database_file_object - <a href="c3ref/database_file_object.html">c3ref/database_file_object.html</a></li><li>sqlite3_db_cacheflush - <a href="c3ref/db_cacheflush.html">c3ref/db_cacheflush.html</a></li><li>sqlite3_db_config - <a href="c3ref/db_config.html">c3ref/db_config.html</a></li><li>sqlite3_db_filename - <a href="c3ref/db_filename.html">c3ref/db_filename.html</a></li><li>sqlite3_db_handle - <a href="c3ref/db_handle.html">c3ref/db_handle.html</a></li><li>sqlite3_db_mutex - <a href="c3ref/db_mutex.html">c3ref/db_mutex.html</a></li><li>sqlite3_db_name - <a href="c3ref/db_name.html">c3ref/db_name.html</a></li><li>sqlite3_db_readonly - <a href="c3ref/db_readonly.html">c3ref/db_readonly.html</a></li><li>sqlite3_db_release_memory - <a href="c3ref/db_release_memory.html">c3ref/db_release_memory.html</a></li><li>sqlite3_db_status - <a href="c3ref/db_status.html">c3ref/db_status.html</a></li><li>sqlite3_declare_vtab - <a href="c3ref/declare_vtab.html">c3ref/declare_vtab.html</a></li><li>sqlite3_deserialize - <a href="c3ref/deserialize.html">c3ref/deserialize.html</a></li><li>sqlite3_drop_modules - <a href="c3ref/drop_modules.html">c3ref/drop_modules.html</a></li><li>sqlite3_enable_load_extension - <a href="c3ref/enable_load_extension.html">c3ref/enable_load_extension.html</a></li><li>sqlite3_enable_shared_cache - <a href="c3ref/enable_shared_cache.html">c3ref/enable_shared_cache.html</a></li><li>sqlite3_errcode - <a href="c3ref/errcode.html">c3ref/errcode.html</a></li><li>sqlite3_errmsg - <a href="c3ref/errcode.html">c3ref/errcode.html</a></li><li>sqlite3_errmsg16 - <a href="c3ref/errcode.html">c3ref/errcode.html</a></li><li>sqlite3_error_offset - <a href="c3ref/errcode.html">c3ref/errcode.html</a></li><li>sqlite3_errstr - <a href="c3ref/errcode.html">c3ref/errcode.html</a></li><li>sqlite3_exec - <a href="c3ref/exec.html">c3ref/exec.html</a></li><li>sqlite3_expanded_sql - <a href="c3ref/expanded_sql.html">c3ref/expanded_sql.html</a></li><li>sqlite3_expired - <a href="c3ref/aggregate_count.html">c3ref/aggregate_count.html</a></li><li>sqlite3_extended_errcode - <a href="c3ref/errcode.html">c3ref/errcode.html</a></li><li>sqlite3_extended_result_codes - <a href="c3ref/extended_result_codes.html">c3ref/extended_result_codes.html</a></li><li>sqlite3_file - <a href="c3ref/file.html">c3ref/file.html</a></li><li>sqlite3_file_control - <a href="c3ref/file_control.html">c3ref/file_control.html</a></li><li>sqlite3_filename - <a href="c3ref/filename.html">c3ref/filename.html</a></li><li>sqlite3_filename_database - <a href="c3ref/filename_database.html">c3ref/filename_database.html</a></li><li>sqlite3_filename_journal - <a href="c3ref/filename_database.html">c3ref/filename_database.html</a></li><li>sqlite3_filename_wal - <a href="c3ref/filename_database.html">c3ref/filename_database.html</a></li><li>sqlite3_finalize - <a href="c3ref/finalize.html">c3ref/finalize.html</a></li><li>sqlite3_free - <a href="c3ref/free.html">c3ref/free.html</a></li><li>sqlite3_free_filename - <a href="c3ref/create_filename.html">c3ref/create_filename.html</a></li><li>sqlite3_free_table - <a href="c3ref/free_table.html">c3ref/free_table.html</a></li><li>sqlite3_get_autocommit - <a href="c3ref/get_autocommit.html">c3ref/get_autocommit.html</a></li><li>sqlite3_get_auxdata - <a href="c3ref/get_auxdata.html">c3ref/get_auxdata.html</a></li><li>sqlite3_get_clientdata - <a href="c3ref/get_clientdata.html">c3ref/get_clientdata.html</a></li><li>sqlite3_get_table - <a href="c3ref/free_table.html">c3ref/free_table.html</a></li><li>sqlite3_global_recover - <a href="c3ref/aggregate_count.html">c3ref/aggregate_count.html</a></li><li>sqlite3_hard_heap_limit64 - <a href="c3ref/hard_heap_limit64.html">c3ref/hard_heap_limit64.html</a></li><li>sqlite3_index_info - <a href="c3ref/index_info.html">c3ref/index_info.html</a></li><li>sqlite3_initialize - <a href="c3ref/initialize.html">c3ref/initialize.html</a></li><li>sqlite3_int64 - <a href="c3ref/int64.html">c3ref/int64.html</a></li><li>sqlite3_interrupt - <a href="c3ref/interrupt.html">c3ref/interrupt.html</a></li><li>sqlite3_io_methods - <a href="c3ref/io_methods.html">c3ref/io_methods.html</a></li><li>sqlite3_is_interrupted - <a href="c3ref/interrupt.html">c3ref/interrupt.html</a></li><li>sqlite3_keyword_check - <a href="c3ref/keyword_check.html">c3ref/keyword_check.html</a></li><li>sqlite3_keyword_count - <a href="c3ref/keyword_check.html">c3ref/keyword_check.html</a></li><li>sqlite3_keyword_name - <a href="c3ref/keyword_check.html">c3ref/keyword_check.html</a></li><li>sqlite3_last_insert_rowid - <a href="c3ref/last_insert_rowid.html">c3ref/last_insert_rowid.html</a></li><li>sqlite3_libversion - <a href="c3ref/libversion.html">c3ref/libversion.html</a></li><li>sqlite3_libversion_number - <a href="c3ref/libversion.html">c3ref/libversion.html</a></li><li>sqlite3_limit - <a href="c3ref/limit.html">c3ref/limit.html</a></li><li>sqlite3_load_extension - <a href="c3ref/load_extension.html">c3ref/load_extension.html</a></li><li>sqlite3_log - <a href="c3ref/log.html">c3ref/log.html</a></li><li>sqlite3_malloc - <a href="c3ref/free.html">c3ref/free.html</a></li><li>sqlite3_malloc64 - <a href="c3ref/free.html">c3ref/free.html</a></li><li>sqlite3_mem_methods - <a href="c3ref/mem_methods.html">c3ref/mem_methods.html</a></li><li>sqlite3_memory_alarm - <a href="c3ref/aggregate_count.html">c3ref/aggregate_count.html</a></li><li>sqlite3_memory_highwater - <a href="c3ref/memory_highwater.html">c3ref/memory_highwater.html</a></li><li>sqlite3_memory_used - <a href="c3ref/memory_highwater.html">c3ref/memory_highwater.html</a></li><li>sqlite3_module - <a href="c3ref/module.html">c3ref/module.html</a></li><li>sqlite3_module.xBegin - <a href="vtab.html#xBegin">vtab.html#xBegin</a></li><li>sqlite3_module.xBestIndex - <a href="vtab.html#xbestindex">vtab.html#xbestindex</a></li><li>sqlite3_module.xClose - <a href="vtab.html#xclose">vtab.html#xclose</a></li><li>sqlite3_module.xColumn - <a href="vtab.html#xcolumn">vtab.html#xcolumn</a></li><li>sqlite3_module.xCommit - <a href="vtab.html#xcommit">vtab.html#xcommit</a></li><li>sqlite3_module.xConnect - <a href="vtab.html#xconnect">vtab.html#xconnect</a></li><li>sqlite3_module.xCreate - <a href="vtab.html#xcreate">vtab.html#xcreate</a></li><li>sqlite3_module.xDisconnect - <a href="vtab.html#xdisconnect">vtab.html#xdisconnect</a></li><li>sqlite3_module.xEof - <a href="vtab.html#xeof">vtab.html#xeof</a></li><li>sqlite3_module.xFilter - <a href="vtab.html#xfilter">vtab.html#xfilter</a></li><li>sqlite3_module.xFindFunction - <a href="vtab.html#xfindfunction">vtab.html#xfindfunction</a></li><li>sqlite3_module.xIntegrity - <a href="vtab.html#xintegrity">vtab.html#xintegrity</a></li><li>sqlite3_module.xNext - <a href="vtab.html#xnext">vtab.html#xnext</a></li><li>sqlite3_module.xOpen - <a href="vtab.html#xopen">vtab.html#xopen</a></li><li>sqlite3_module.xRename - <a href="vtab.html#xrename">vtab.html#xrename</a></li><li>sqlite3_module.xRollback - <a href="vtab.html#xrollback">vtab.html#xrollback</a></li><li>sqlite3_module.xRowid - <a href="vtab.html#xrowid">vtab.html#xrowid</a></li><li>sqlite3_module.xSavepoint - <a href="vtab.html#xsavepoint">vtab.html#xsavepoint</a></li><li>sqlite3_module.xShadowName - <a href="vtab.html#xshadowname">vtab.html#xshadowname</a></li><li>sqlite3_module.xSync - <a href="vtab.html#xsync">vtab.html#xsync</a></li><li>sqlite3_module.xUpdate - <a href="vtab.html#xupdate">vtab.html#xupdate</a></li><li>sqlite3_mprintf - <a href="c3ref/mprintf.html">c3ref/mprintf.html</a></li><li>sqlite3_msize - <a href="c3ref/free.html">c3ref/free.html</a></li><li>sqlite3_mutex - <a href="c3ref/mutex.html">c3ref/mutex.html</a></li><li>sqlite3_mutex_alloc - <a href="c3ref/mutex_alloc.html">c3ref/mutex_alloc.html</a></li><li>sqlite3_mutex_enter - <a href="c3ref/mutex_alloc.html">c3ref/mutex_alloc.html</a></li><li>sqlite3_mutex_free - <a href="c3ref/mutex_alloc.html">c3ref/mutex_alloc.html</a></li><li>sqlite3_mutex_held - <a href="c3ref/mutex_held.html">c3ref/mutex_held.html</a></li><li>sqlite3_mutex_leave - <a href="c3ref/mutex_alloc.html">c3ref/mutex_alloc.html</a></li><li>sqlite3_mutex_methods - <a href="c3ref/mutex_methods.html">c3ref/mutex_methods.html</a></li><li>sqlite3_mutex_notheld - <a href="c3ref/mutex_held.html">c3ref/mutex_held.html</a></li><li>sqlite3_mutex_try - <a href="c3ref/mutex_alloc.html">c3ref/mutex_alloc.html</a></li><li>sqlite3_next_stmt - <a href="c3ref/next_stmt.html">c3ref/next_stmt.html</a></li><li>sqlite3_normalized_sql - <a href="c3ref/expanded_sql.html">c3ref/expanded_sql.html</a></li><li>sqlite3_open - <a href="c3ref/open.html">c3ref/open.html</a></li><li>sqlite3_open16 - <a href="c3ref/open.html">c3ref/open.html</a></li><li>sqlite3_open_v2 - <a href="c3ref/open.html">c3ref/open.html</a></li><li>sqlite3_os_end - <a href="c3ref/initialize.html">c3ref/initialize.html</a></li><li>sqlite3_os_init - <a href="c3ref/initialize.html">c3ref/initialize.html</a></li><li>sqlite3_overload_function - <a href="c3ref/overload_function.html">c3ref/overload_function.html</a></li><li>sqlite3_pcache - <a href="c3ref/pcache.html">c3ref/pcache.html</a></li><li>sqlite3_pcache_methods2 - <a href="c3ref/pcache_methods2.html">c3ref/pcache_methods2.html</a></li><li>sqlite3_pcache_page - <a href="c3ref/pcache_page.html">c3ref/pcache_page.html</a></li><li>sqlite3_prepare - <a href="c3ref/prepare.html">c3ref/prepare.html</a></li><li>sqlite3_prepare16 - <a href="c3ref/prepare.html">c3ref/prepare.html</a></li><li>sqlite3_prepare16_v2 - <a href="c3ref/prepare.html">c3ref/prepare.html</a></li><li>sqlite3_prepare16_v3 - <a href="c3ref/prepare.html">c3ref/prepare.html</a></li><li>sqlite3_prepare_v2 - <a href="c3ref/prepare.html">c3ref/prepare.html</a></li><li>sqlite3_prepare_v3 - <a href="c3ref/prepare.html">c3ref/prepare.html</a></li><li>sqlite3_preupdate_blobwrite - <a href="c3ref/preupdate_blobwrite.html">c3ref/preupdate_blobwrite.html</a></li><li>sqlite3_preupdate_count - <a href="c3ref/preupdate_blobwrite.html">c3ref/preupdate_blobwrite.html</a></li><li>sqlite3_preupdate_depth - <a href="c3ref/preupdate_blobwrite.html">c3ref/preupdate_blobwrite.html</a></li><li>sqlite3_preupdate_hook - <a href="c3ref/preupdate_blobwrite.html">c3ref/preupdate_blobwrite.html</a></li><li>sqlite3_preupdate_new - <a href="c3ref/preupdate_blobwrite.html">c3ref/preupdate_blobwrite.html</a></li><li>sqlite3_preupdate_old - <a href="c3ref/preupdate_blobwrite.html">c3ref/preupdate_blobwrite.html</a></li><li>sqlite3_profile - <a href="c3ref/profile.html">c3ref/profile.html</a></li><li>sqlite3_progress_handler - <a href="c3ref/progress_handler.html">c3ref/progress_handler.html</a></li><li>sqlite3_randomness - <a href="c3ref/randomness.html">c3ref/randomness.html</a></li><li>sqlite3_realloc - <a href="c3ref/free.html">c3ref/free.html</a></li><li>sqlite3_realloc64 - <a href="c3ref/free.html">c3ref/free.html</a></li><li>sqlite3_rebaser - <a href="session/rebaser.html">session/rebaser.html</a></li><li>sqlite3_release_memory - <a href="c3ref/release_memory.html">c3ref/release_memory.html</a></li><li>sqlite3_reset - <a href="c3ref/reset.html">c3ref/reset.html</a></li><li>sqlite3_reset_auto_extension - <a href="c3ref/reset_auto_extension.html">c3ref/reset_auto_extension.html</a></li><li>sqlite3_result_blob - <a href="c3ref/result_blob.html">c3ref/result_blob.html</a></li><li>sqlite3_result_blob64 - <a href="c3ref/result_blob.html">c3ref/result_blob.html</a></li><li>sqlite3_result_double - <a href="c3ref/result_blob.html">c3ref/result_blob.html</a></li><li>sqlite3_result_error - <a href="c3ref/result_blob.html">c3ref/result_blob.html</a></li><li>sqlite3_result_error16 - <a href="c3ref/result_blob.html">c3ref/result_blob.html</a></li><li>sqlite3_result_error_code - <a href="c3ref/result_blob.html">c3ref/result_blob.html</a></li><li>sqlite3_result_error_nomem - <a href="c3ref/result_blob.html">c3ref/result_blob.html</a></li><li>sqlite3_result_error_toobig - <a href="c3ref/result_blob.html">c3ref/result_blob.html</a></li><li>sqlite3_result_int - <a href="c3ref/result_blob.html">c3ref/result_blob.html</a></li><li>sqlite3_result_int64 - <a href="c3ref/result_blob.html">c3ref/result_blob.html</a></li><li>sqlite3_result_null - <a href="c3ref/result_blob.html">c3ref/result_blob.html</a></li><li>sqlite3_result_pointer - <a href="c3ref/result_blob.html">c3ref/result_blob.html</a></li><li>sqlite3_result_subtype - <a href="c3ref/result_subtype.html">c3ref/result_subtype.html</a></li><li>sqlite3_result_text - <a href="c3ref/result_blob.html">c3ref/result_blob.html</a></li><li>sqlite3_result_text16 - <a href="c3ref/result_blob.html">c3ref/result_blob.html</a></li><li>sqlite3_result_text16be - <a href="c3ref/result_blob.html">c3ref/result_blob.html</a></li><li>sqlite3_result_text16le - <a href="c3ref/result_blob.html">c3ref/result_blob.html</a></li><li>sqlite3_result_text64 - <a href="c3ref/result_blob.html">c3ref/result_blob.html</a></li><li>sqlite3_result_value - <a href="c3ref/result_blob.html">c3ref/result_blob.html</a></li><li>sqlite3_result_zeroblob - <a href="c3ref/result_blob.html">c3ref/result_blob.html</a></li><li>sqlite3_result_zeroblob64 - <a href="c3ref/result_blob.html">c3ref/result_blob.html</a></li><li>sqlite3_rollback_hook - <a href="c3ref/commit_hook.html">c3ref/commit_hook.html</a></li><li>sqlite3_rtree_query_callback - <a href="rtree.html#xquery">rtree.html#xquery</a></li><li>sqlite3_serialize - <a href="c3ref/serialize.html">c3ref/serialize.html</a></li><li>sqlite3_session - <a href="session/session.html">session/session.html</a></li><li>sqlite3_set_authorizer - <a href="c3ref/set_authorizer.html">c3ref/set_authorizer.html</a></li><li>sqlite3_set_auxdata - <a href="c3ref/get_auxdata.html">c3ref/get_auxdata.html</a></li><li>sqlite3_set_clientdata - <a href="c3ref/get_clientdata.html">c3ref/get_clientdata.html</a></li><li>sqlite3_set_last_insert_rowid - <a href="c3ref/set_last_insert_rowid.html">c3ref/set_last_insert_rowid.html</a></li><li>sqlite3_shutdown - <a href="c3ref/initialize.html">c3ref/initialize.html</a></li><li>sqlite3_sleep - <a href="c3ref/sleep.html">c3ref/sleep.html</a></li><li>sqlite3_snapshot - <a href="c3ref/snapshot.html">c3ref/snapshot.html</a></li><li>sqlite3_snapshot_cmp - <a href="c3ref/snapshot_cmp.html">c3ref/snapshot_cmp.html</a></li><li>sqlite3_snapshot_free - <a href="c3ref/snapshot_free.html">c3ref/snapshot_free.html</a></li><li>sqlite3_snapshot_get - <a href="c3ref/snapshot_get.html">c3ref/snapshot_get.html</a></li><li>sqlite3_snapshot_open - <a href="c3ref/snapshot_open.html">c3ref/snapshot_open.html</a></li><li>sqlite3_snapshot_recover - <a href="c3ref/snapshot_recover.html">c3ref/snapshot_recover.html</a></li><li>sqlite3_snprintf - <a href="c3ref/mprintf.html">c3ref/mprintf.html</a></li><li>sqlite3_soft_heap_limit - <a href="c3ref/soft_heap_limit.html">c3ref/soft_heap_limit.html</a></li><li>sqlite3_soft_heap_limit64 - <a href="c3ref/hard_heap_limit64.html">c3ref/hard_heap_limit64.html</a></li><li>sqlite3_sourceid - <a href="c3ref/libversion.html">c3ref/libversion.html</a></li><li>sqlite3_sql - <a href="c3ref/expanded_sql.html">c3ref/expanded_sql.html</a></li><li>sqlite3_status - <a href="c3ref/status.html">c3ref/status.html</a></li><li>sqlite3_status64 - <a href="c3ref/status.html">c3ref/status.html</a></li><li>sqlite3_step - <a href="c3ref/step.html">c3ref/step.html</a></li><li>sqlite3_stmt - <a href="c3ref/stmt.html">c3ref/stmt.html</a></li><li>sqlite3_stmt_busy - <a href="c3ref/stmt_busy.html">c3ref/stmt_busy.html</a></li><li>sqlite3_stmt_explain - <a href="c3ref/stmt_explain.html">c3ref/stmt_explain.html</a></li><li>sqlite3_stmt_isexplain - <a href="c3ref/stmt_isexplain.html">c3ref/stmt_isexplain.html</a></li><li>sqlite3_stmt_readonly - <a href="c3ref/stmt_readonly.html">c3ref/stmt_readonly.html</a></li><li>sqlite3_stmt_scanstatus - <a href="c3ref/stmt_scanstatus.html">c3ref/stmt_scanstatus.html</a></li><li>sqlite3_stmt_scanstatus_reset - <a href="c3ref/stmt_scanstatus_reset.html">c3ref/stmt_scanstatus_reset.html</a></li><li>sqlite3_stmt_scanstatus_v2 - <a href="c3ref/stmt_scanstatus.html">c3ref/stmt_scanstatus.html</a></li><li>sqlite3_stmt_status - <a href="c3ref/stmt_status.html">c3ref/stmt_status.html</a></li><li>sqlite3_str - <a href="c3ref/str.html">c3ref/str.html</a></li><li>sqlite3_str_append - <a href="c3ref/str_append.html">c3ref/str_append.html</a></li><li>sqlite3_str_appendall - <a href="c3ref/str_append.html">c3ref/str_append.html</a></li><li>sqlite3_str_appendchar - <a href="c3ref/str_append.html">c3ref/str_append.html</a></li><li>sqlite3_str_appendf - <a href="c3ref/str_append.html">c3ref/str_append.html</a></li><li>sqlite3_str_errcode - <a href="c3ref/str_errcode.html">c3ref/str_errcode.html</a></li><li>sqlite3_str_finish - <a href="c3ref/str_finish.html">c3ref/str_finish.html</a></li><li>sqlite3_str_length - <a href="c3ref/str_errcode.html">c3ref/str_errcode.html</a></li><li>sqlite3_str_new - <a href="c3ref/str_new.html">c3ref/str_new.html</a></li><li>sqlite3_str_reset - <a href="c3ref/str_append.html">c3ref/str_append.html</a></li><li>sqlite3_str_value - <a href="c3ref/str_errcode.html">c3ref/str_errcode.html</a></li><li>sqlite3_str_vappendf - <a href="c3ref/str_append.html">c3ref/str_append.html</a></li><li>sqlite3_strglob - <a href="c3ref/strglob.html">c3ref/strglob.html</a></li><li>sqlite3_stricmp - <a href="c3ref/stricmp.html">c3ref/stricmp.html</a></li><li>sqlite3_strlike - <a href="c3ref/strlike.html">c3ref/strlike.html</a></li><li>sqlite3_strnicmp - <a href="c3ref/stricmp.html">c3ref/stricmp.html</a></li><li>sqlite3_system_errno - <a href="c3ref/system_errno.html">c3ref/system_errno.html</a></li><li>sqlite3_table_column_metadata - <a href="c3ref/table_column_metadata.html">c3ref/table_column_metadata.html</a></li><li>sqlite3_temp_directory - <a href="c3ref/temp_directory.html">c3ref/temp_directory.html</a></li><li>sqlite3_test_control - <a href="c3ref/test_control.html">c3ref/test_control.html</a></li><li>sqlite3_thread_cleanup - <a href="c3ref/aggregate_count.html">c3ref/aggregate_count.html</a></li><li>sqlite3_threadsafe - <a href="c3ref/threadsafe.html">c3ref/threadsafe.html</a></li><li>sqlite3_total_changes - <a href="c3ref/total_changes.html">c3ref/total_changes.html</a></li><li>sqlite3_total_changes64 - <a href="c3ref/total_changes.html">c3ref/total_changes.html</a></li><li>sqlite3_trace - <a href="c3ref/profile.html">c3ref/profile.html</a></li><li>sqlite3_trace_v2 - <a href="c3ref/trace_v2.html">c3ref/trace_v2.html</a></li><li>sqlite3_transfer_bindings - <a href="c3ref/aggregate_count.html">c3ref/aggregate_count.html</a></li><li>sqlite3_txn_state - <a href="c3ref/txn_state.html">c3ref/txn_state.html</a></li><li>sqlite3_uint64 - <a href="c3ref/int64.html">c3ref/int64.html</a></li><li>sqlite3_unlock_notify - <a href="c3ref/unlock_notify.html">c3ref/unlock_notify.html</a></li><li>sqlite3_update_hook - <a href="c3ref/update_hook.html">c3ref/update_hook.html</a></li><li>sqlite3_uri_boolean - <a href="c3ref/uri_boolean.html">c3ref/uri_boolean.html</a></li><li>sqlite3_uri_int64 - <a href="c3ref/uri_boolean.html">c3ref/uri_boolean.html</a></li><li>sqlite3_uri_key - <a href="c3ref/uri_boolean.html">c3ref/uri_boolean.html</a></li><li>sqlite3_uri_parameter - <a href="c3ref/uri_boolean.html">c3ref/uri_boolean.html</a></li><li>sqlite3_user_data - <a href="c3ref/user_data.html">c3ref/user_data.html</a></li><li>sqlite3_value - <a href="c3ref/value.html">c3ref/value.html</a></li><li>sqlite3_value_blob - <a href="c3ref/value_blob.html">c3ref/value_blob.html</a></li><li>sqlite3_value_bytes - <a href="c3ref/value_blob.html">c3ref/value_blob.html</a></li><li>sqlite3_value_bytes16 - <a href="c3ref/value_blob.html">c3ref/value_blob.html</a></li><li>sqlite3_value_double - <a href="c3ref/value_blob.html">c3ref/value_blob.html</a></li><li>sqlite3_value_dup - <a href="c3ref/value_dup.html">c3ref/value_dup.html</a></li><li>sqlite3_value_encoding - <a href="c3ref/value_encoding.html">c3ref/value_encoding.html</a></li><li>sqlite3_value_free - <a href="c3ref/value_dup.html">c3ref/value_dup.html</a></li><li>sqlite3_value_frombind - <a href="c3ref/value_blob.html">c3ref/value_blob.html</a></li><li>sqlite3_value_int - <a href="c3ref/value_blob.html">c3ref/value_blob.html</a></li><li>sqlite3_value_int64 - <a href="c3ref/value_blob.html">c3ref/value_blob.html</a></li><li>sqlite3_value_nochange - <a href="c3ref/value_blob.html">c3ref/value_blob.html</a></li><li>sqlite3_value_numeric_type - <a href="c3ref/value_blob.html">c3ref/value_blob.html</a></li><li>sqlite3_value_pointer - <a href="c3ref/value_blob.html">c3ref/value_blob.html</a></li><li>sqlite3_value_subtype - <a href="c3ref/value_subtype.html">c3ref/value_subtype.html</a></li><li>sqlite3_value_text - <a href="c3ref/value_blob.html">c3ref/value_blob.html</a></li><li>sqlite3_value_text16 - <a href="c3ref/value_blob.html">c3ref/value_blob.html</a></li><li>sqlite3_value_text16be - <a href="c3ref/value_blob.html">c3ref/value_blob.html</a></li><li>sqlite3_value_text16le - <a href="c3ref/value_blob.html">c3ref/value_blob.html</a></li><li>sqlite3_value_type - <a href="c3ref/value_blob.html">c3ref/value_blob.html</a></li><li>sqlite3_version - <a href="c3ref/libversion.html">c3ref/libversion.html</a></li><li>sqlite3_vfs - <a href="c3ref/vfs.html">c3ref/vfs.html</a></li><li>sqlite3_vfs.xAccess - <a href="c3ref/vfs.html#sqlite3vfsxaccess">c3ref/vfs.html#sqlite3vfsxaccess</a></li><li>sqlite3_vfs.xOpen - <a href="c3ref/vfs.html#sqlite3vfsxopen">c3ref/vfs.html#sqlite3vfsxopen</a></li><li>sqlite3_vfs_find - <a href="c3ref/vfs_find.html">c3ref/vfs_find.html</a></li><li>sqlite3_vfs_register - <a href="c3ref/vfs_find.html">c3ref/vfs_find.html</a></li><li>sqlite3_vfs_unregister - <a href="c3ref/vfs_find.html">c3ref/vfs_find.html</a></li><li>sqlite3_vmprintf - <a href="c3ref/mprintf.html">c3ref/mprintf.html</a></li><li>sqlite3_vsnprintf - <a href="c3ref/mprintf.html">c3ref/mprintf.html</a></li><li>sqlite3_vtab - <a href="c3ref/vtab.html">c3ref/vtab.html</a></li><li>sqlite3_vtab_collation - <a href="c3ref/vtab_collation.html">c3ref/vtab_collation.html</a></li><li>sqlite3_vtab_config - <a href="c3ref/vtab_config.html">c3ref/vtab_config.html</a></li><li>sqlite3_vtab_cursor - <a href="c3ref/vtab_cursor.html">c3ref/vtab_cursor.html</a></li><li>sqlite3_vtab_distinct - <a href="c3ref/vtab_distinct.html">c3ref/vtab_distinct.html</a></li><li>sqlite3_vtab_in - <a href="c3ref/vtab_in.html">c3ref/vtab_in.html</a></li><li>sqlite3_vtab_in_first - <a href="c3ref/vtab_in_first.html">c3ref/vtab_in_first.html</a></li><li>sqlite3_vtab_in_next - <a href="c3ref/vtab_in_first.html">c3ref/vtab_in_first.html</a></li><li>sqlite3_vtab_nochange - <a href="c3ref/vtab_nochange.html">c3ref/vtab_nochange.html</a></li><li>sqlite3_vtab_on_conflict - <a href="c3ref/vtab_on_conflict.html">c3ref/vtab_on_conflict.html</a></li><li>sqlite3_vtab_rhs_value - <a href="c3ref/vtab_rhs_value.html">c3ref/vtab_rhs_value.html</a></li><li>sqlite3_wal_autocheckpoint - <a href="c3ref/wal_autocheckpoint.html">c3ref/wal_autocheckpoint.html</a></li><li>sqlite3_wal_checkpoint - <a href="c3ref/wal_checkpoint.html">c3ref/wal_checkpoint.html</a></li><li>sqlite3_wal_checkpoint_v2 - <a href="c3ref/wal_checkpoint_v2.html">c3ref/wal_checkpoint_v2.html</a></li><li>sqlite3_wal_hook - <a href="c3ref/wal_hook.html">c3ref/wal_hook.html</a></li><li>sqlite3_win32_set_directory - <a href="c3ref/win32_set_directory.html">c3ref/win32_set_directory.html</a></li><li>sqlite3_win32_set_directory8 - <a href="c3ref/win32_set_directory.html">c3ref/win32_set_directory.html</a></li><li>sqlite3_win32_set_directory16 - <a href="c3ref/win32_set_directory.html">c3ref/win32_set_directory.html</a></li><li>sqlite3changegroup_add - <a href="session/sqlite3changegroup_add.html">session/sqlite3changegroup_add.html</a></li><li>sqlite3changegroup_add_change - <a href="session/sqlite3changegroup_add_change.html">session/sqlite3changegroup_add_change.html</a></li><li>sqlite3changegroup_add_strm - <a href="session/sqlite3changegroup_add_strm.html">session/sqlite3changegroup_add_strm.html</a></li><li>sqlite3changegroup_delete - <a href="session/sqlite3changegroup_delete.html">session/sqlite3changegroup_delete.html</a></li><li>sqlite3changegroup_new - <a href="session/sqlite3changegroup_new.html">session/sqlite3changegroup_new.html</a></li><li>sqlite3changegroup_output - <a href="session/sqlite3changegroup_output.html">session/sqlite3changegroup_output.html</a></li><li>sqlite3changegroup_output_strm - <a href="session/sqlite3changegroup_add_strm.html">session/sqlite3changegroup_add_strm.html</a></li><li>sqlite3changegroup_schema - <a href="session/sqlite3changegroup_schema.html">session/sqlite3changegroup_schema.html</a></li><li>sqlite3changeset_apply - <a href="session/sqlite3changeset_apply.html">session/sqlite3changeset_apply.html</a></li><li>sqlite3changeset_apply_strm - <a href="session/sqlite3changegroup_add_strm.html">session/sqlite3changegroup_add_strm.html</a></li><li>sqlite3changeset_apply_v2 - <a href="session/sqlite3changeset_apply.html">session/sqlite3changeset_apply.html</a></li><li>sqlite3changeset_apply_v2_strm - <a href="session/sqlite3changegroup_add_strm.html">session/sqlite3changegroup_add_strm.html</a></li><li>sqlite3changeset_concat - <a href="session/sqlite3changeset_concat.html">session/sqlite3changeset_concat.html</a></li><li>sqlite3changeset_concat_strm - <a href="session/sqlite3changegroup_add_strm.html">session/sqlite3changegroup_add_strm.html</a></li><li>sqlite3changeset_conflict - <a href="session/sqlite3changeset_conflict.html">session/sqlite3changeset_conflict.html</a></li><li>sqlite3changeset_finalize - <a href="session/sqlite3changeset_finalize.html">session/sqlite3changeset_finalize.html</a></li><li>sqlite3changeset_fk_conflicts - <a href="session/sqlite3changeset_fk_conflicts.html">session/sqlite3changeset_fk_conflicts.html</a></li><li>sqlite3changeset_invert - <a href="session/sqlite3changeset_invert.html">session/sqlite3changeset_invert.html</a></li><li>sqlite3changeset_invert_strm - <a href="session/sqlite3changegroup_add_strm.html">session/sqlite3changegroup_add_strm.html</a></li><li>sqlite3changeset_new - <a href="session/sqlite3changeset_new.html">session/sqlite3changeset_new.html</a></li><li>sqlite3changeset_next - <a href="session/sqlite3changeset_next.html">session/sqlite3changeset_next.html</a></li><li>sqlite3changeset_old - <a href="session/sqlite3changeset_old.html">session/sqlite3changeset_old.html</a></li><li>sqlite3changeset_op - <a href="session/sqlite3changeset_op.html">session/sqlite3changeset_op.html</a></li><li>sqlite3changeset_pk - <a href="session/sqlite3changeset_pk.html">session/sqlite3changeset_pk.html</a></li><li>sqlite3changeset_start - <a href="session/sqlite3changeset_start.html">session/sqlite3changeset_start.html</a></li><li>sqlite3changeset_start_strm - <a href="session/sqlite3changegroup_add_strm.html">session/sqlite3changegroup_add_strm.html</a></li><li>sqlite3changeset_start_v2 - <a href="session/sqlite3changeset_start.html">session/sqlite3changeset_start.html</a></li><li>sqlite3changeset_start_v2_strm - <a href="session/sqlite3changegroup_add_strm.html">session/sqlite3changegroup_add_strm.html</a></li><li>sqlite3changeset_upgrade - <a href="session/sqlite3changeset_upgrade.html">session/sqlite3changeset_upgrade.html</a></li><li>sqlite3rebaser_configure - <a href="session/sqlite3rebaser_configure.html">session/sqlite3rebaser_configure.html</a></li><li>sqlite3rebaser_create - <a href="session/sqlite3rebaser_create.html">session/sqlite3rebaser_create.html</a></li><li>sqlite3rebaser_delete - <a href="session/sqlite3rebaser_delete.html">session/sqlite3rebaser_delete.html</a></li><li>sqlite3rebaser_rebase - <a href="session/sqlite3rebaser_rebase.html">session/sqlite3rebaser_rebase.html</a></li><li>sqlite3rebaser_rebase_strm - <a href="session/sqlite3changegroup_add_strm.html">session/sqlite3changegroup_add_strm.html</a></li><li>sqlite3session_attach - <a href="session/sqlite3session_attach.html">session/sqlite3session_attach.html</a></li><li>sqlite3session_changeset - <a href="session/sqlite3session_changeset.html">session/sqlite3session_changeset.html</a></li><li>sqlite3session_changeset_size - <a href="session/sqlite3session_changeset_size.html">session/sqlite3session_changeset_size.html</a></li><li>sqlite3session_changeset_strm - <a href="session/sqlite3changegroup_add_strm.html">session/sqlite3changegroup_add_strm.html</a></li><li>sqlite3session_config - <a href="session/sqlite3session_config.html">session/sqlite3session_config.html</a></li><li>sqlite3session_create - <a href="session/sqlite3session_create.html">session/sqlite3session_create.html</a></li><li>sqlite3session_delete - <a href="session/sqlite3session_delete.html">session/sqlite3session_delete.html</a></li><li>sqlite3session_diff - <a href="session/sqlite3session_diff.html">session/sqlite3session_diff.html</a></li><li>sqlite3session_enable - <a href="session/sqlite3session_enable.html">session/sqlite3session_enable.html</a></li><li>sqlite3session_indirect - <a href="session/sqlite3session_indirect.html">session/sqlite3session_indirect.html</a></li><li>sqlite3session_isempty - <a href="session/sqlite3session_isempty.html">session/sqlite3session_isempty.html</a></li><li>sqlite3session_memory_used - <a href="session/sqlite3session_memory_used.html">session/sqlite3session_memory_used.html</a></li><li>sqlite3session_object_config - <a href="session/sqlite3session_object_config.html">session/sqlite3session_object_config.html</a></li><li>sqlite3session_patchset - <a href="session/sqlite3session_patchset.html">session/sqlite3session_patchset.html</a></li><li>sqlite3session_patchset_strm - <a href="session/sqlite3changegroup_add_strm.html">session/sqlite3changegroup_add_strm.html</a></li><li>sqlite3session_table_filter - <a href="session/sqlite3session_table_filter.html">session/sqlite3session_table_filter.html</a></li><li>SQLITE_4_BYTE_ALIGNED_MALLOC - <a href="compile.html#4_byte_aligned_malloc">compile.html#4_byte_aligned_malloc</a></li><li>SQLITE_ABORT - <a href="rescode.html#abort">rescode.html#abort</a></li><li>SQLITE_ABORT_ROLLBACK - <a href="rescode.html#abort_rollback">rescode.html#abort_rollback</a></li><li>SQLITE_ACCESS_EXISTS - <a href="c3ref/c_access_exists.html">c3ref/c_access_exists.html</a></li><li>SQLITE_ACCESS_READ - <a href="c3ref/c_access_exists.html">c3ref/c_access_exists.html</a></li><li>SQLITE_ACCESS_READWRITE - <a href="c3ref/c_access_exists.html">c3ref/c_access_exists.html</a></li><li>SQLITE_ALLOW_COVERING_INDEX_SCAN - <a href="compile.html#allow_covering_index_scan">compile.html#allow_covering_index_scan</a></li><li>SQLITE_ALLOW_URI_AUTHORITY - <a href="compile.html#allow_uri_authority">compile.html#allow_uri_authority</a></li><li>SQLITE_ALTER_TABLE - <a href="c3ref/c_alter_table.html">c3ref/c_alter_table.html</a></li><li>SQLITE_ANALYZE - <a href="c3ref/c_alter_table.html">c3ref/c_alter_table.html</a></li><li>SQLITE_ANY - <a href="c3ref/c_any.html">c3ref/c_any.html</a></li><li>SQLITE_API - <a href="compile.html#api">compile.html#api</a></li><li>SQLITE_APICALL - <a href="compile.html#apicall">compile.html#apicall</a></li><li>SQLITE_ATTACH - <a href="c3ref/c_alter_table.html">c3ref/c_alter_table.html</a></li><li>SQLITE_AUTH - <a href="rescode.html#auth">rescode.html#auth</a></li><li>SQLITE_AUTH_USER - <a href="rescode.html#auth_user">rescode.html#auth_user</a></li><li>SQLITE_BLOB - <a href="c3ref/c_blob.html">c3ref/c_blob.html</a></li><li>SQLITE_BUSY - <a href="rescode.html#busy">rescode.html#busy</a></li><li>SQLITE_BUSY_RECOVERY - <a href="rescode.html#busy_recovery">rescode.html#busy_recovery</a></li><li>SQLITE_BUSY_SNAPSHOT - <a href="rescode.html#busy_snapshot">rescode.html#busy_snapshot</a></li><li>SQLITE_BUSY_TIMEOUT - <a href="rescode.html#busy_timeout">rescode.html#busy_timeout</a></li><li>SQLITE_BYTEORDER - <a href="compile.html#byteorder">compile.html#byteorder</a></li><li>SQLITE_CALLBACK - <a href="compile.html#callback">compile.html#callback</a></li><li>SQLITE_CANTOPEN - <a href="rescode.html#cantopen">rescode.html#cantopen</a></li><li>SQLITE_CANTOPEN_CONVPATH - <a href="rescode.html#cantopen_convpath">rescode.html#cantopen_convpath</a></li><li>SQLITE_CANTOPEN_DIRTYWAL - <a href="rescode.html#cantopen_dirtywal">rescode.html#cantopen_dirtywal</a></li><li>SQLITE_CANTOPEN_FULLPATH - <a href="rescode.html#cantopen_fullpath">rescode.html#cantopen_fullpath</a></li><li>SQLITE_CANTOPEN_ISDIR - <a href="rescode.html#cantopen_isdir">rescode.html#cantopen_isdir</a></li><li>SQLITE_CANTOPEN_NOTEMPDIR - <a href="rescode.html#cantopen_notempdir">rescode.html#cantopen_notempdir</a></li><li>SQLITE_CANTOPEN_SYMLINK - <a href="rescode.html#cantopen_symlink">rescode.html#cantopen_symlink</a></li><li>SQLITE_CASE_SENSITIVE_LIKE - <a href="compile.html#case_sensitive_like">compile.html#case_sensitive_like</a></li><li>SQLITE_CDECL - <a href="compile.html#cdecl">compile.html#cdecl</a></li><li>SQLITE_CHANGESET_ABORT - <a href="session/c_changeset_abort.html">session/c_changeset_abort.html</a></li><li>SQLITE_CHANGESET_CONFLICT - <a href="session/c_changeset_conflict.html">session/c_changeset_conflict.html</a></li><li>SQLITE_CHANGESET_CONSTRAINT - <a href="session/c_changeset_conflict.html">session/c_changeset_conflict.html</a></li><li>SQLITE_CHANGESET_DATA - <a href="session/c_changeset_conflict.html">session/c_changeset_conflict.html</a></li><li>SQLITE_CHANGESET_FOREIGN_KEY - <a href="session/c_changeset_conflict.html">session/c_changeset_conflict.html</a></li><li>SQLITE_CHANGESET_NOTFOUND - <a href="session/c_changeset_conflict.html">session/c_changeset_conflict.html</a></li><li>SQLITE_CHANGESET_OMIT - <a href="session/c_changeset_abort.html">session/c_changeset_abort.html</a></li><li>SQLITE_CHANGESET_REPLACE - <a href="session/c_changeset_abort.html">session/c_changeset_abort.html</a></li><li>SQLITE_CHANGESETAPPLY_FKNOACTION - <a href="session/c_changesetapply_fknoaction.html">session/c_changesetapply_fknoaction.html</a></li><li>SQLITE_CHANGESETAPPLY_IGNORENOOP - <a href="session/c_changesetapply_fknoaction.html">session/c_changesetapply_fknoaction.html</a></li><li>SQLITE_CHANGESETAPPLY_INVERT - <a href="session/c_changesetapply_fknoaction.html">session/c_changesetapply_fknoaction.html</a></li><li>SQLITE_CHANGESETAPPLY_NOSAVEPOINT - <a href="session/c_changesetapply_fknoaction.html">session/c_changesetapply_fknoaction.html</a></li><li>SQLITE_CHANGESETSTART_INVERT - <a href="session/c_changesetstart_invert.html">session/c_changesetstart_invert.html</a></li><li>SQLITE_CHECKPOINT_FULL - <a href="c3ref/c_checkpoint_full.html">c3ref/c_checkpoint_full.html</a></li><li>SQLITE_CHECKPOINT_PASSIVE - <a href="c3ref/c_checkpoint_full.html">c3ref/c_checkpoint_full.html</a></li><li>SQLITE_CHECKPOINT_RESTART - <a href="c3ref/c_checkpoint_full.html">c3ref/c_checkpoint_full.html</a></li><li>SQLITE_CHECKPOINT_TRUNCATE - <a href="c3ref/c_checkpoint_full.html">c3ref/c_checkpoint_full.html</a></li><li>sqlite_compileoption_get - <a href="lang_corefunc.html#sqlite_compileoption_get">lang_corefunc.html#sqlite_compileoption_get</a></li><li>sqlite_compileoption_get SQL function - <a href="lang_corefunc.html#sqlite_compileoption_get">lang_corefunc.html#sqlite_compileoption_get</a></li><li>sqlite_compileoption_used - <a href="lang_corefunc.html#sqlite_compileoption_used">lang_corefunc.html#sqlite_compileoption_used</a></li><li>sqlite_compileoption_used SQL function - <a href="lang_corefunc.html#sqlite_compileoption_used">lang_corefunc.html#sqlite_compileoption_used</a></li><li>SQLITE_CONFIG_COVERING_INDEX_SCAN - <a href="c3ref/c_config_covering_index_scan.html#sqliteconfigcoveringindexscan">c3ref/c_config_covering_index_scan.html#sqliteconfigcoveringindexscan</a></li><li>SQLITE_CONFIG_GETMALLOC - <a href="c3ref/c_config_covering_index_scan.html#sqliteconfiggetmalloc">c3ref/c_config_covering_index_scan.html#sqliteconfiggetmalloc</a></li><li>SQLITE_CONFIG_GETMUTEX - <a href="c3ref/c_config_covering_index_scan.html#sqliteconfiggetmutex">c3ref/c_config_covering_index_scan.html#sqliteconfiggetmutex</a></li><li>SQLITE_CONFIG_GETPCACHE - <a href="c3ref/c_config_covering_index_scan.html#sqliteconfiggetpcache">c3ref/c_config_covering_index_scan.html#sqliteconfiggetpcache</a></li><li>SQLITE_CONFIG_GETPCACHE2 - <a href="c3ref/c_config_covering_index_scan.html#sqliteconfiggetpcache2">c3ref/c_config_covering_index_scan.html#sqliteconfiggetpcache2</a></li><li>SQLITE_CONFIG_HEAP - <a href="c3ref/c_config_covering_index_scan.html#sqliteconfigheap">c3ref/c_config_covering_index_scan.html#sqliteconfigheap</a></li><li>SQLITE_CONFIG_LOG - <a href="c3ref/c_config_covering_index_scan.html#sqliteconfiglog">c3ref/c_config_covering_index_scan.html#sqliteconfiglog</a></li><li>SQLITE_CONFIG_LOOKASIDE - <a href="c3ref/c_config_covering_index_scan.html#sqliteconfiglookaside">c3ref/c_config_covering_index_scan.html#sqliteconfiglookaside</a></li><li>SQLITE_CONFIG_MALLOC - <a href="c3ref/c_config_covering_index_scan.html#sqliteconfigmalloc">c3ref/c_config_covering_index_scan.html#sqliteconfigmalloc</a></li><li>SQLITE_CONFIG_MEMDB_MAXSIZE - <a href="c3ref/c_config_covering_index_scan.html#sqliteconfigmemdbmaxsize">c3ref/c_config_covering_index_scan.html#sqliteconfigmemdbmaxsize</a></li><li>SQLITE_CONFIG_MEMSTATUS - <a href="c3ref/c_config_covering_index_scan.html#sqliteconfigmemstatus">c3ref/c_config_covering_index_scan.html#sqliteconfigmemstatus</a></li><li>SQLITE_CONFIG_MMAP_SIZE - <a href="c3ref/c_config_covering_index_scan.html#sqliteconfigmmapsize">c3ref/c_config_covering_index_scan.html#sqliteconfigmmapsize</a></li><li>SQLITE_CONFIG_MULTITHREAD - <a href="c3ref/c_config_covering_index_scan.html#sqliteconfigmultithread">c3ref/c_config_covering_index_scan.html#sqliteconfigmultithread</a></li><li>SQLITE_CONFIG_MUTEX - <a href="c3ref/c_config_covering_index_scan.html#sqliteconfigmutex">c3ref/c_config_covering_index_scan.html#sqliteconfigmutex</a></li><li>SQLITE_CONFIG_PAGECACHE - <a href="c3ref/c_config_covering_index_scan.html#sqliteconfigpagecache">c3ref/c_config_covering_index_scan.html#sqliteconfigpagecache</a></li><li>SQLITE_CONFIG_PCACHE - <a href="c3ref/c_config_covering_index_scan.html#sqliteconfigpcache">c3ref/c_config_covering_index_scan.html#sqliteconfigpcache</a></li><li>SQLITE_CONFIG_PCACHE2 - <a href="c3ref/c_config_covering_index_scan.html#sqliteconfigpcache2">c3ref/c_config_covering_index_scan.html#sqliteconfigpcache2</a></li><li>SQLITE_CONFIG_PCACHE_HDRSZ - <a href="c3ref/c_config_covering_index_scan.html#sqliteconfigpcachehdrsz">c3ref/c_config_covering_index_scan.html#sqliteconfigpcachehdrsz</a></li><li>SQLITE_CONFIG_PMASZ - <a href="c3ref/c_config_covering_index_scan.html#sqliteconfigpmasz">c3ref/c_config_covering_index_scan.html#sqliteconfigpmasz</a></li><li>SQLITE_CONFIG_ROWID_IN_VIEW - <a href="c3ref/c_config_covering_index_scan.html#sqliteconfigrowidinview">c3ref/c_config_covering_index_scan.html#sqliteconfigrowidinview</a></li><li>SQLITE_CONFIG_SCRATCH - <a href="c3ref/c_config_covering_index_scan.html#sqliteconfigscratch">c3ref/c_config_covering_index_scan.html#sqliteconfigscratch</a></li><li>SQLITE_CONFIG_SERIALIZED - <a href="c3ref/c_config_covering_index_scan.html#sqliteconfigserialized">c3ref/c_config_covering_index_scan.html#sqliteconfigserialized</a></li><li>SQLITE_CONFIG_SINGLETHREAD - <a href="c3ref/c_config_covering_index_scan.html#sqliteconfigsinglethread">c3ref/c_config_covering_index_scan.html#sqliteconfigsinglethread</a></li><li>SQLITE_CONFIG_SMALL_MALLOC - <a href="c3ref/c_config_covering_index_scan.html#sqliteconfigsmallmalloc">c3ref/c_config_covering_index_scan.html#sqliteconfigsmallmalloc</a></li><li>SQLITE_CONFIG_SORTERREF_SIZE - <a href="c3ref/c_config_covering_index_scan.html#sqliteconfigsorterrefsize">c3ref/c_config_covering_index_scan.html#sqliteconfigsorterrefsize</a></li><li>SQLITE_CONFIG_SQLLOG - <a href="c3ref/c_config_covering_index_scan.html#sqliteconfigsqllog">c3ref/c_config_covering_index_scan.html#sqliteconfigsqllog</a></li><li>SQLITE_CONFIG_STMTJRNL_SPILL - <a href="c3ref/c_config_covering_index_scan.html#sqliteconfigstmtjrnlspill">c3ref/c_config_covering_index_scan.html#sqliteconfigstmtjrnlspill</a></li><li>SQLITE_CONFIG_URI - <a href="c3ref/c_config_covering_index_scan.html#sqliteconfiguri">c3ref/c_config_covering_index_scan.html#sqliteconfiguri</a></li><li>SQLITE_CONFIG_WIN32_HEAPSIZE - <a href="c3ref/c_config_covering_index_scan.html#sqliteconfigwin32heapsize">c3ref/c_config_covering_index_scan.html#sqliteconfigwin32heapsize</a></li><li>SQLITE_CONSTRAINT - <a href="rescode.html#constraint">rescode.html#constraint</a></li><li>SQLITE_CONSTRAINT_CHECK - <a href="rescode.html#constraint_check">rescode.html#constraint_check</a></li><li>SQLITE_CONSTRAINT_COMMITHOOK - <a href="rescode.html#constraint_commithook">rescode.html#constraint_commithook</a></li><li>SQLITE_CONSTRAINT_DATATYPE - <a href="rescode.html#constraint_datatype">rescode.html#constraint_datatype</a></li><li>SQLITE_CONSTRAINT_FOREIGNKEY - <a href="rescode.html#constraint_foreignkey">rescode.html#constraint_foreignkey</a></li><li>SQLITE_CONSTRAINT_FUNCTION - <a href="rescode.html#constraint_function">rescode.html#constraint_function</a></li><li>SQLITE_CONSTRAINT_NOTNULL - <a href="rescode.html#constraint_notnull">rescode.html#constraint_notnull</a></li><li>SQLITE_CONSTRAINT_PINNED - <a href="rescode.html#constraint_pinned">rescode.html#constraint_pinned</a></li><li>SQLITE_CONSTRAINT_PRIMARYKEY - <a href="rescode.html#constraint_primarykey">rescode.html#constraint_primarykey</a></li><li>SQLITE_CONSTRAINT_ROWID - <a href="rescode.html#constraint_rowid">rescode.html#constraint_rowid</a></li><li>SQLITE_CONSTRAINT_TRIGGER - <a href="rescode.html#constraint_trigger">rescode.html#constraint_trigger</a></li><li>SQLITE_CONSTRAINT_UNIQUE - <a href="rescode.html#constraint_unique">rescode.html#constraint_unique</a></li><li>SQLITE_CONSTRAINT_VTAB - <a href="rescode.html#constraint_vtab">rescode.html#constraint_vtab</a></li><li>SQLITE_COPY - <a href="c3ref/c_alter_table.html">c3ref/c_alter_table.html</a></li><li>SQLITE_CORRUPT - <a href="rescode.html#corrupt">rescode.html#corrupt</a></li><li>SQLITE_CORRUPT_INDEX - <a href="rescode.html#corrupt_index">rescode.html#corrupt_index</a></li><li>SQLITE_CORRUPT_SEQUENCE - <a href="rescode.html#corrupt_sequence">rescode.html#corrupt_sequence</a></li><li>SQLITE_CORRUPT_VTAB - <a href="rescode.html#corrupt_vtab">rescode.html#corrupt_vtab</a></li><li>SQLITE_CREATE_INDEX - <a href="c3ref/c_alter_table.html">c3ref/c_alter_table.html</a></li><li>SQLITE_CREATE_TABLE - <a href="c3ref/c_alter_table.html">c3ref/c_alter_table.html</a></li><li>SQLITE_CREATE_TEMP_INDEX - <a href="c3ref/c_alter_table.html">c3ref/c_alter_table.html</a></li><li>SQLITE_CREATE_TEMP_TABLE - <a href="c3ref/c_alter_table.html">c3ref/c_alter_table.html</a></li><li>SQLITE_CREATE_TEMP_TRIGGER - <a href="c3ref/c_alter_table.html">c3ref/c_alter_table.html</a></li><li>SQLITE_CREATE_TEMP_VIEW - <a href="c3ref/c_alter_table.html">c3ref/c_alter_table.html</a></li><li>SQLITE_CREATE_TRIGGER - <a href="c3ref/c_alter_table.html">c3ref/c_alter_table.html</a></li><li>SQLITE_CREATE_VIEW - <a href="c3ref/c_alter_table.html">c3ref/c_alter_table.html</a></li><li>SQLITE_CREATE_VTABLE - <a href="c3ref/c_alter_table.html">c3ref/c_alter_table.html</a></li><li>SQLITE_DBCONFIG_DEFENSIVE - <a href="c3ref/c_dbconfig_defensive.html#sqlitedbconfigdefensive">c3ref/c_dbconfig_defensive.html#sqlitedbconfigdefensive</a></li><li>SQLITE_DBCONFIG_DQS_DDL - <a href="c3ref/c_dbconfig_defensive.html#sqlitedbconfigdqsddl">c3ref/c_dbconfig_defensive.html#sqlitedbconfigdqsddl</a></li><li>SQLITE_DBCONFIG_DQS_DML - <a href="c3ref/c_dbconfig_defensive.html#sqlitedbconfigdqsdml">c3ref/c_dbconfig_defensive.html#sqlitedbconfigdqsdml</a></li><li>SQLITE_DBCONFIG_ENABLE_FKEY - <a href="c3ref/c_dbconfig_defensive.html#sqlitedbconfigenablefkey">c3ref/c_dbconfig_defensive.html#sqlitedbconfigenablefkey</a></li><li>SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER - <a href="c3ref/c_dbconfig_defensive.html#sqlitedbconfigenablefts3tokenizer">c3ref/c_dbconfig_defensive.html#sqlitedbconfigenablefts3tokenizer</a></li><li>SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION - <a href="c3ref/c_dbconfig_defensive.html#sqlitedbconfigenableloadextension">c3ref/c_dbconfig_defensive.html#sqlitedbconfigenableloadextension</a></li><li>SQLITE_DBCONFIG_ENABLE_QPSG - <a href="c3ref/c_dbconfig_defensive.html#sqlitedbconfigenableqpsg">c3ref/c_dbconfig_defensive.html#sqlitedbconfigenableqpsg</a></li><li>SQLITE_DBCONFIG_ENABLE_TRIGGER - <a href="c3ref/c_dbconfig_defensive.html#sqlitedbconfigenabletrigger">c3ref/c_dbconfig_defensive.html#sqlitedbconfigenabletrigger</a></li><li>SQLITE_DBCONFIG_ENABLE_VIEW - <a href="c3ref/c_dbconfig_defensive.html#sqlitedbconfigenableview">c3ref/c_dbconfig_defensive.html#sqlitedbconfigenableview</a></li><li>SQLITE_DBCONFIG_LEGACY_ALTER_TABLE - <a href="c3ref/c_dbconfig_defensive.html#sqlitedbconfiglegacyaltertable">c3ref/c_dbconfig_defensive.html#sqlitedbconfiglegacyaltertable</a></li><li>SQLITE_DBCONFIG_LEGACY_FILE_FORMAT - <a href="c3ref/c_dbconfig_defensive.html#sqlitedbconfiglegacyfileformat">c3ref/c_dbconfig_defensive.html#sqlitedbconfiglegacyfileformat</a></li><li>SQLITE_DBCONFIG_LOOKASIDE - <a href="c3ref/c_dbconfig_defensive.html#sqlitedbconfiglookaside">c3ref/c_dbconfig_defensive.html#sqlitedbconfiglookaside</a></li><li>SQLITE_DBCONFIG_MAINDBNAME - <a href="c3ref/c_dbconfig_defensive.html#sqlitedbconfigmaindbname">c3ref/c_dbconfig_defensive.html#sqlitedbconfigmaindbname</a></li><li>SQLITE_DBCONFIG_MAX - <a href="c3ref/c_dbconfig_defensive.html">c3ref/c_dbconfig_defensive.html</a></li><li>SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE - <a href="c3ref/c_dbconfig_defensive.html#sqlitedbconfignockptonclose">c3ref/c_dbconfig_defensive.html#sqlitedbconfignockptonclose</a></li><li>SQLITE_DBCONFIG_RESET_DATABASE - <a href="c3ref/c_dbconfig_defensive.html#sqlitedbconfigresetdatabase">c3ref/c_dbconfig_defensive.html#sqlitedbconfigresetdatabase</a></li><li>SQLITE_DBCONFIG_REVERSE_SCANORDER - <a href="c3ref/c_dbconfig_defensive.html#sqlitedbconfigreversescanorder">c3ref/c_dbconfig_defensive.html#sqlitedbconfigreversescanorder</a></li><li>SQLITE_DBCONFIG_STMT_SCANSTATUS - <a href="c3ref/c_dbconfig_defensive.html#sqlitedbconfigstmtscanstatus">c3ref/c_dbconfig_defensive.html#sqlitedbconfigstmtscanstatus</a></li><li>SQLITE_DBCONFIG_TRIGGER_EQP - <a href="c3ref/c_dbconfig_defensive.html#sqlitedbconfigtriggereqp">c3ref/c_dbconfig_defensive.html#sqlitedbconfigtriggereqp</a></li><li>SQLITE_DBCONFIG_TRUSTED_SCHEMA - <a href="c3ref/c_dbconfig_defensive.html#sqlitedbconfigtrustedschema">c3ref/c_dbconfig_defensive.html#sqlitedbconfigtrustedschema</a></li><li>SQLITE_DBCONFIG_WRITABLE_SCHEMA - <a href="c3ref/c_dbconfig_defensive.html#sqlitedbconfigwritableschema">c3ref/c_dbconfig_defensive.html#sqlitedbconfigwritableschema</a></li><li>sqlite_dbpage - <a href="dbpage.html">dbpage.html</a></li><li>SQLITE_DBPAGE virtual table - <a href="dbpage.html">dbpage.html</a></li><li>SQLITE_DBSTATUS options - <a href="c3ref/c_dbstatus_options.html">c3ref/c_dbstatus_options.html</a></li><li>SQLITE_DBSTATUS_CACHE_HIT - <a href="c3ref/c_dbstatus_options.html#sqlitedbstatuscachehit">c3ref/c_dbstatus_options.html#sqlitedbstatuscachehit</a></li><li>SQLITE_DBSTATUS_CACHE_MISS - <a href="c3ref/c_dbstatus_options.html#sqlitedbstatuscachemiss">c3ref/c_dbstatus_options.html#sqlitedbstatuscachemiss</a></li><li>SQLITE_DBSTATUS_CACHE_SPILL - <a href="c3ref/c_dbstatus_options.html#sqlitedbstatuscachespill">c3ref/c_dbstatus_options.html#sqlitedbstatuscachespill</a></li><li>SQLITE_DBSTATUS_CACHE_USED - <a href="c3ref/c_dbstatus_options.html#sqlitedbstatuscacheused">c3ref/c_dbstatus_options.html#sqlitedbstatuscacheused</a></li><li>SQLITE_DBSTATUS_CACHE_USED_SHARED - <a href="c3ref/c_dbstatus_options.html#sqlitedbstatuscacheusedshared">c3ref/c_dbstatus_options.html#sqlitedbstatuscacheusedshared</a></li><li>SQLITE_DBSTATUS_CACHE_WRITE - <a href="c3ref/c_dbstatus_options.html#sqlitedbstatuscachewrite">c3ref/c_dbstatus_options.html#sqlitedbstatuscachewrite</a></li><li>SQLITE_DBSTATUS_DEFERRED_FKS - <a href="c3ref/c_dbstatus_options.html#sqlitedbstatusdeferredfks">c3ref/c_dbstatus_options.html#sqlitedbstatusdeferredfks</a></li><li>SQLITE_DBSTATUS_LOOKASIDE_HIT - <a href="c3ref/c_dbstatus_options.html#sqlitedbstatuslookasidehit">c3ref/c_dbstatus_options.html#sqlitedbstatuslookasidehit</a></li><li>SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL - <a href="c3ref/c_dbstatus_options.html#sqlitedbstatuslookasidemissfull">c3ref/c_dbstatus_options.html#sqlitedbstatuslookasidemissfull</a></li><li>SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE - <a href="c3ref/c_dbstatus_options.html#sqlitedbstatuslookasidemisssize">c3ref/c_dbstatus_options.html#sqlitedbstatuslookasidemisssize</a></li><li>SQLITE_DBSTATUS_LOOKASIDE_USED - <a href="c3ref/c_dbstatus_options.html#sqlitedbstatuslookasideused">c3ref/c_dbstatus_options.html#sqlitedbstatuslookasideused</a></li><li>SQLITE_DBSTATUS_MAX - <a href="c3ref/c_dbstatus_options.html">c3ref/c_dbstatus_options.html</a></li><li>SQLITE_DBSTATUS_SCHEMA_USED - <a href="c3ref/c_dbstatus_options.html#sqlitedbstatusschemaused">c3ref/c_dbstatus_options.html#sqlitedbstatusschemaused</a></li><li>SQLITE_DBSTATUS_STMT_USED - <a href="c3ref/c_dbstatus_options.html#sqlitedbstatusstmtused">c3ref/c_dbstatus_options.html#sqlitedbstatusstmtused</a></li><li>SQLITE_DEBUG - <a href="compile.html#debug">compile.html#debug</a></li><li>SQLITE_DEFAULT_AUTOMATIC_INDEX - <a href="compile.html#default_automatic_index">compile.html#default_automatic_index</a></li><li>SQLITE_DEFAULT_AUTOVACUUM - <a href="compile.html#default_autovacuum">compile.html#default_autovacuum</a></li><li>SQLITE_DEFAULT_CACHE_SIZE - <a href="compile.html#default_cache_size">compile.html#default_cache_size</a></li><li>SQLITE_DEFAULT_FILE_FORMAT - <a href="compile.html#default_file_format">compile.html#default_file_format</a></li><li>SQLITE_DEFAULT_FILE_PERMISSIONS - <a href="compile.html#default_file_permissions">compile.html#default_file_permissions</a></li><li>SQLITE_DEFAULT_FOREIGN_KEYS - <a href="compile.html#default_foreign_keys">compile.html#default_foreign_keys</a></li><li>SQLITE_DEFAULT_JOURNAL_SIZE_LIMIT - <a href="compile.html#default_journal_size_limit">compile.html#default_journal_size_limit</a></li><li>SQLITE_DEFAULT_LOCKING_MODE - <a href="compile.html#default_locking_mode">compile.html#default_locking_mode</a></li><li>SQLITE_DEFAULT_LOOKASIDE - <a href="compile.html#default_lookaside">compile.html#default_lookaside</a></li><li>SQLITE_DEFAULT_MEMSTATUS - <a href="compile.html#default_memstatus">compile.html#default_memstatus</a></li><li>SQLITE_DEFAULT_MMAP_SIZE - <a href="compile.html#default_mmap_size">compile.html#default_mmap_size</a></li><li>SQLITE_DEFAULT_PAGE_SIZE - <a href="compile.html#default_page_size">compile.html#default_page_size</a></li><li>SQLITE_DEFAULT_PCACHE_INITSZ - <a href="compile.html#default_pcache_initsz">compile.html#default_pcache_initsz</a></li><li>SQLITE_DEFAULT_SYNCHRONOUS - <a href="compile.html#default_synchronous">compile.html#default_synchronous</a></li><li>SQLITE_DEFAULT_WAL_AUTOCHECKPOINT - <a href="compile.html#default_wal_autocheckpoint">compile.html#default_wal_autocheckpoint</a></li><li>SQLITE_DEFAULT_WAL_SYNCHRONOUS - <a href="compile.html#default_wal_synchronous">compile.html#default_wal_synchronous</a></li><li>SQLITE_DEFAULT_WORKER_THREADS - <a href="compile.html#default_worker_threads">compile.html#default_worker_threads</a></li><li>SQLITE_DELETE - <a href="c3ref/c_alter_table.html">c3ref/c_alter_table.html</a></li><li>SQLITE_DENY - <a href="c3ref/c_deny.html">c3ref/c_deny.html</a></li><li>SQLITE_DESERIALIZE_FREEONCLOSE - <a href="c3ref/c_deserialize_freeonclose.html">c3ref/c_deserialize_freeonclose.html</a></li><li>SQLITE_DESERIALIZE_READONLY - <a href="c3ref/c_deserialize_freeonclose.html">c3ref/c_deserialize_freeonclose.html</a></li><li>SQLITE_DESERIALIZE_RESIZEABLE - <a href="c3ref/c_deserialize_freeonclose.html">c3ref/c_deserialize_freeonclose.html</a></li><li>SQLITE_DETACH - <a href="c3ref/c_alter_table.html">c3ref/c_alter_table.html</a></li><li>SQLITE_DETERMINISTIC - <a href="c3ref/c_deterministic.html#sqlitedeterministic">c3ref/c_deterministic.html#sqlitedeterministic</a></li><li>SQLITE_DIRECT_OVERFLOW_READ - <a href="compile.html#direct_overflow_read">compile.html#direct_overflow_read</a></li><li>SQLITE_DIRECTONLY - <a href="c3ref/c_deterministic.html#sqlitedirectonly">c3ref/c_deterministic.html#sqlitedirectonly</a></li><li>SQLITE_DISABLE_DIRSYNC - <a href="compile.html#disable_dirsync">compile.html#disable_dirsync</a></li><li>SQLITE_DISABLE_FTS3_UNICODE - <a href="compile.html#disable_fts3_unicode">compile.html#disable_fts3_unicode</a></li><li>SQLITE_DISABLE_FTS4_DEFERRED - <a href="compile.html#disable_fts4_deferred">compile.html#disable_fts4_deferred</a></li><li>SQLITE_DISABLE_INTRINSIC - <a href="compile.html#disable_intrinsic">compile.html#disable_intrinsic</a></li><li>SQLITE_DISABLE_LFS - <a href="compile.html#disable_lfs">compile.html#disable_lfs</a></li><li>SQLITE_DISABLE_PAGECACHE_OVERFLOW_STATS - <a href="compile.html#disable_pagecache_overflow_stats">compile.html#disable_pagecache_overflow_stats</a></li><li>SQLITE_DONE - <a href="rescode.html#done">rescode.html#done</a></li><li>SQLITE_DQS - <a href="compile.html#dqs">compile.html#dqs</a></li><li>SQLITE_DROP_INDEX - <a href="c3ref/c_alter_table.html">c3ref/c_alter_table.html</a></li><li>SQLITE_DROP_TABLE - <a href="c3ref/c_alter_table.html">c3ref/c_alter_table.html</a></li><li>SQLITE_DROP_TEMP_INDEX - <a href="c3ref/c_alter_table.html">c3ref/c_alter_table.html</a></li><li>SQLITE_DROP_TEMP_TABLE - <a href="c3ref/c_alter_table.html">c3ref/c_alter_table.html</a></li><li>SQLITE_DROP_TEMP_TRIGGER - <a href="c3ref/c_alter_table.html">c3ref/c_alter_table.html</a></li><li>SQLITE_DROP_TEMP_VIEW - <a href="c3ref/c_alter_table.html">c3ref/c_alter_table.html</a></li><li>SQLITE_DROP_TRIGGER - <a href="c3ref/c_alter_table.html">c3ref/c_alter_table.html</a></li><li>SQLITE_DROP_VIEW - <a href="c3ref/c_alter_table.html">c3ref/c_alter_table.html</a></li><li>SQLITE_DROP_VTABLE - <a href="c3ref/c_alter_table.html">c3ref/c_alter_table.html</a></li><li>SQLITE_EMPTY - <a href="rescode.html#empty">rescode.html#empty</a></li><li>SQLITE_ENABLE_8_3_NAMES - <a href="compile.html#enable_8_3_names">compile.html#enable_8_3_names</a></li><li>SQLITE_ENABLE_API_ARMOR - <a href="compile.html#enable_api_armor">compile.html#enable_api_armor</a></li><li>SQLITE_ENABLE_ATOMIC_WRITE - <a href="compile.html#enable_atomic_write">compile.html#enable_atomic_write</a></li><li>SQLITE_ENABLE_BATCH_ATOMIC_WRITE - <a href="compile.html#enable_batch_atomic_write">compile.html#enable_batch_atomic_write</a></li><li>SQLITE_ENABLE_BYTECODE_VTAB - <a href="compile.html#enable_bytecode_vtab">compile.html#enable_bytecode_vtab</a></li><li>SQLITE_ENABLE_COLUMN_METADATA - <a href="compile.html#enable_column_metadata">compile.html#enable_column_metadata</a></li><li>SQLITE_ENABLE_DBPAGE_VTAB - <a href="compile.html#enable_dbpage_vtab">compile.html#enable_dbpage_vtab</a></li><li>SQLITE_ENABLE_DBSTAT_VTAB - <a href="compile.html#enable_dbstat_vtab">compile.html#enable_dbstat_vtab</a></li><li>SQLITE_ENABLE_DESERIALIZE - <a href="compile.html#enable_deserialize">compile.html#enable_deserialize</a></li><li>SQLITE_ENABLE_EXPLAIN_COMMENTS - <a href="compile.html#enable_explain_comments">compile.html#enable_explain_comments</a></li><li>SQLITE_ENABLE_FTS3 - <a href="compile.html#enable_fts3">compile.html#enable_fts3</a></li><li>SQLITE_ENABLE_FTS3_PARENTHESIS - <a href="compile.html#enable_fts3_parenthesis">compile.html#enable_fts3_parenthesis</a></li><li>SQLITE_ENABLE_FTS3_TOKENIZER - <a href="compile.html#enable_fts3_tokenizer">compile.html#enable_fts3_tokenizer</a></li><li>SQLITE_ENABLE_FTS4 - <a href="compile.html#enable_fts4">compile.html#enable_fts4</a></li><li>SQLITE_ENABLE_FTS5 - <a href="compile.html#enable_fts5">compile.html#enable_fts5</a></li><li>SQLITE_ENABLE_GEOPOLY - <a href="compile.html#enable_geopoly">compile.html#enable_geopoly</a></li><li>SQLITE_ENABLE_HIDDEN_COLUMNS - <a href="compile.html#enable_hidden_columns">compile.html#enable_hidden_columns</a></li><li>SQLITE_ENABLE_ICU - <a href="compile.html#enable_icu">compile.html#enable_icu</a></li><li>SQLITE_ENABLE_IOTRACE - <a href="compile.html#enable_iotrace">compile.html#enable_iotrace</a></li><li>SQLITE_ENABLE_JSON1 - <a href="compile.html#enable_json1">compile.html#enable_json1</a></li><li>SQLITE_ENABLE_LOCKING_STYLE - <a href="compile.html#enable_locking_style">compile.html#enable_locking_style</a></li><li>SQLITE_ENABLE_MATH_FUNCTIONS - <a href="compile.html#enable_math_functions">compile.html#enable_math_functions</a></li><li>SQLITE_ENABLE_MEMORY_MANAGEMENT - <a href="compile.html#enable_memory_management">compile.html#enable_memory_management</a></li><li>SQLITE_ENABLE_MEMSYS3 - <a href="compile.html#enable_memsys3">compile.html#enable_memsys3</a></li><li>SQLITE_ENABLE_MEMSYS5 - <a href="compile.html#enable_memsys5">compile.html#enable_memsys5</a></li><li>SQLITE_ENABLE_NORMALIZE - <a href="compile.html#enable_normalize">compile.html#enable_normalize</a></li><li>SQLITE_ENABLE_NULL_TRIM - <a href="compile.html#enable_null_trim">compile.html#enable_null_trim</a></li><li>SQLITE_ENABLE_OFFSET_SQL_FUNC - <a href="compile.html#enable_offset_sql_func">compile.html#enable_offset_sql_func</a></li><li>SQLITE_ENABLE_PREUPDATE_HOOK - <a href="compile.html#enable_preupdate_hook">compile.html#enable_preupdate_hook</a></li><li>SQLITE_ENABLE_QPSG - <a href="compile.html#enable_qpsg">compile.html#enable_qpsg</a></li><li>SQLITE_ENABLE_RBU - <a href="compile.html#enable_rbu">compile.html#enable_rbu</a></li><li>SQLITE_ENABLE_RTREE - <a href="compile.html#enable_rtree">compile.html#enable_rtree</a></li><li>SQLITE_ENABLE_SESSION - <a href="compile.html#enable_session">compile.html#enable_session</a></li><li>SQLITE_ENABLE_SNAPSHOT - <a href="compile.html#enable_snapshot">compile.html#enable_snapshot</a></li><li>SQLITE_ENABLE_SORTER_REFERENCES - <a href="compile.html#enable_sorter_references">compile.html#enable_sorter_references</a></li><li>SQLITE_ENABLE_SQLLOG - <a href="compile.html#enable_sqllog">compile.html#enable_sqllog</a></li><li>SQLITE_ENABLE_STAT2 - <a href="compile.html#enable_stat2">compile.html#enable_stat2</a></li><li>SQLITE_ENABLE_STAT3 - <a href="compile.html#enable_stat3">compile.html#enable_stat3</a></li><li>SQLITE_ENABLE_STAT4 - <a href="compile.html#enable_stat4">compile.html#enable_stat4</a></li><li>SQLITE_ENABLE_STMT_SCANSTATUS - <a href="compile.html#enable_stmt_scanstatus">compile.html#enable_stmt_scanstatus</a></li><li>SQLITE_ENABLE_STMTVTAB - <a href="compile.html#enable_stmtvtab">compile.html#enable_stmtvtab</a></li><li>SQLITE_ENABLE_TREE_EXPLAIN - <a href="compile.html#enable_tree_explain">compile.html#enable_tree_explain</a></li><li>SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION - <a href="compile.html#enable_unknown_sql_function">compile.html#enable_unknown_sql_function</a></li><li>SQLITE_ENABLE_UNLOCK_NOTIFY - <a href="compile.html#enable_unlock_notify">compile.html#enable_unlock_notify</a></li><li>SQLITE_ENABLE_UPDATE_DELETE_LIMIT - <a href="compile.html#enable_update_delete_limit">compile.html#enable_update_delete_limit</a></li><li>SQLITE_ERROR - <a href="rescode.html#error">rescode.html#error</a></li><li>SQLITE_ERROR_MISSING_COLLSEQ - <a href="rescode.html#error_missing_collseq">rescode.html#error_missing_collseq</a></li><li>SQLITE_ERROR_RETRY - <a href="rescode.html#error_retry">rescode.html#error_retry</a></li><li>SQLITE_ERROR_SNAPSHOT - <a href="rescode.html#error_snapshot">rescode.html#error_snapshot</a></li><li>SQLITE_EXTERN - <a href="compile.html#extern">compile.html#extern</a></li><li>SQLITE_EXTRA_DURABLE - <a href="compile.html#extra_durable">compile.html#extra_durable</a></li><li>SQLITE_FAIL - <a href="c3ref/c_fail.html">c3ref/c_fail.html</a></li><li>SQLITE_FCNTL_BEGIN_ATOMIC_WRITE - <a href="c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntlbeginatomicwrite">c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntlbeginatomicwrite</a></li><li>SQLITE_FCNTL_BUSYHANDLER - <a href="c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntlbusyhandler">c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntlbusyhandler</a></li><li>SQLITE_FCNTL_CHUNK_SIZE - <a href="c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntlchunksize">c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntlchunksize</a></li><li>SQLITE_FCNTL_CKPT_DONE - <a href="c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntlckptdone">c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntlckptdone</a></li><li>SQLITE_FCNTL_CKPT_START - <a href="c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntlckptstart">c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntlckptstart</a></li><li>SQLITE_FCNTL_CKSM_FILE - <a href="c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntlcksmfile">c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntlcksmfile</a></li><li>SQLITE_FCNTL_COMMIT_ATOMIC_WRITE - <a href="c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntlcommitatomicwrite">c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntlcommitatomicwrite</a></li><li>SQLITE_FCNTL_COMMIT_PHASETWO - <a href="c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntlcommitphasetwo">c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntlcommitphasetwo</a></li><li>SQLITE_FCNTL_DATA_VERSION - <a href="c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntldataversion">c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntldataversion</a></li><li>SQLITE_FCNTL_EXTERNAL_READER - <a href="c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntlexternalreader">c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntlexternalreader</a></li><li>SQLITE_FCNTL_FILE_POINTER - <a href="c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntlfilepointer">c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntlfilepointer</a></li><li>SQLITE_FCNTL_GET_LOCKPROXYFILE - <a href="c3ref/c_fcntl_begin_atomic_write.html">c3ref/c_fcntl_begin_atomic_write.html</a></li><li>SQLITE_FCNTL_HAS_MOVED - <a href="c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntlhasmoved">c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntlhasmoved</a></li><li>SQLITE_FCNTL_JOURNAL_POINTER - <a href="c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntljournalpointer">c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntljournalpointer</a></li><li>SQLITE_FCNTL_LAST_ERRNO - <a href="c3ref/c_fcntl_begin_atomic_write.html">c3ref/c_fcntl_begin_atomic_write.html</a></li><li>SQLITE_FCNTL_LOCK_TIMEOUT - <a href="c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntllocktimeout">c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntllocktimeout</a></li><li>SQLITE_FCNTL_LOCKSTATE - <a href="c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntllockstate">c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntllockstate</a></li><li>SQLITE_FCNTL_MMAP_SIZE - <a href="c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntlmmapsize">c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntlmmapsize</a></li><li>SQLITE_FCNTL_OVERWRITE - <a href="c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntloverwrite">c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntloverwrite</a></li><li>SQLITE_FCNTL_PDB - <a href="c3ref/c_fcntl_begin_atomic_write.html">c3ref/c_fcntl_begin_atomic_write.html</a></li><li>SQLITE_FCNTL_PERSIST_WAL - <a href="c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntlpersistwal">c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntlpersistwal</a></li><li>SQLITE_FCNTL_POWERSAFE_OVERWRITE - <a href="c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntlpowersafeoverwrite">c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntlpowersafeoverwrite</a></li><li>SQLITE_FCNTL_PRAGMA - <a href="c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntlpragma">c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntlpragma</a></li><li>SQLITE_FCNTL_RBU - <a href="c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntlrbu">c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntlrbu</a></li><li>SQLITE_FCNTL_RESERVE_BYTES - <a href="c3ref/c_fcntl_begin_atomic_write.html">c3ref/c_fcntl_begin_atomic_write.html</a></li><li>SQLITE_FCNTL_RESET_CACHE - <a href="c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntlresetcache">c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntlresetcache</a></li><li>SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE - <a href="c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntlrollbackatomicwrite">c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntlrollbackatomicwrite</a></li><li>SQLITE_FCNTL_SET_LOCKPROXYFILE - <a href="c3ref/c_fcntl_begin_atomic_write.html">c3ref/c_fcntl_begin_atomic_write.html</a></li><li>SQLITE_FCNTL_SIZE_HINT - <a href="c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntlsizehint">c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntlsizehint</a></li><li>SQLITE_FCNTL_SIZE_LIMIT - <a href="c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntlsizelimit">c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntlsizelimit</a></li><li>SQLITE_FCNTL_SYNC - <a href="c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntlsync">c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntlsync</a></li><li>SQLITE_FCNTL_SYNC_OMITTED - <a href="c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntlsyncomitted">c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntlsyncomitted</a></li><li>SQLITE_FCNTL_TEMPFILENAME - <a href="c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntltempfilename">c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntltempfilename</a></li><li>SQLITE_FCNTL_TRACE - <a href="c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntltrace">c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntltrace</a></li><li>SQLITE_FCNTL_VFS_POINTER - <a href="c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntlvfspointer">c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntlvfspointer</a></li><li>SQLITE_FCNTL_VFSNAME - <a href="c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntlvfsname">c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntlvfsname</a></li><li>SQLITE_FCNTL_WAL_BLOCK - <a href="c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntlwalblock">c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntlwalblock</a></li><li>SQLITE_FCNTL_WIN32_AV_RETRY - <a href="c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntlwin32avretry">c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntlwin32avretry</a></li><li>SQLITE_FCNTL_WIN32_GET_HANDLE - <a href="c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntlwin32gethandle">c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntlwin32gethandle</a></li><li>SQLITE_FCNTL_WIN32_SET_HANDLE - <a href="c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntlwin32sethandle">c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntlwin32sethandle</a></li><li>SQLITE_FCNTL_ZIPVFS - <a href="c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntlzipvfs">c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntlzipvfs</a></li><li>SQLITE_FLOAT - <a href="c3ref/c_blob.html">c3ref/c_blob.html</a></li><li>SQLITE_FORMAT - <a href="rescode.html#format">rescode.html#format</a></li><li>SQLITE_FTS3_MAX_EXPR_DEPTH - <a href="compile.html#fts3_max_expr_depth">compile.html#fts3_max_expr_depth</a></li><li>SQLITE_FULL - <a href="rescode.html#full">rescode.html#full</a></li><li>SQLITE_FUNCTION - <a href="c3ref/c_alter_table.html">c3ref/c_alter_table.html</a></li><li>SQLITE_HAVE_ISNAN - <a href="compile.html#have_isnan">compile.html#have_isnan</a></li><li>SQLITE_HAVE_ZLIB - <a href="compile.html#have_zlib">compile.html#have_zlib</a></li><li>SQLITE_IGNORE - <a href="c3ref/c_deny.html">c3ref/c_deny.html</a></li><li>SQLITE_INDEX_CONSTRAINT_EQ - <a href="c3ref/c_index_constraint_eq.html">c3ref/c_index_constraint_eq.html</a></li><li>SQLITE_INDEX_CONSTRAINT_FUNCTION - <a href="c3ref/c_index_constraint_eq.html">c3ref/c_index_constraint_eq.html</a></li><li>SQLITE_INDEX_CONSTRAINT_GE - <a href="c3ref/c_index_constraint_eq.html">c3ref/c_index_constraint_eq.html</a></li><li>SQLITE_INDEX_CONSTRAINT_GLOB - <a href="c3ref/c_index_constraint_eq.html">c3ref/c_index_constraint_eq.html</a></li><li>SQLITE_INDEX_CONSTRAINT_GT - <a href="c3ref/c_index_constraint_eq.html">c3ref/c_index_constraint_eq.html</a></li><li>SQLITE_INDEX_CONSTRAINT_IS - <a href="c3ref/c_index_constraint_eq.html">c3ref/c_index_constraint_eq.html</a></li><li>SQLITE_INDEX_CONSTRAINT_ISNOT - <a href="c3ref/c_index_constraint_eq.html">c3ref/c_index_constraint_eq.html</a></li><li>SQLITE_INDEX_CONSTRAINT_ISNOTNULL - <a href="c3ref/c_index_constraint_eq.html">c3ref/c_index_constraint_eq.html</a></li><li>SQLITE_INDEX_CONSTRAINT_ISNULL - <a href="c3ref/c_index_constraint_eq.html">c3ref/c_index_constraint_eq.html</a></li><li>SQLITE_INDEX_CONSTRAINT_LE - <a href="c3ref/c_index_constraint_eq.html">c3ref/c_index_constraint_eq.html</a></li><li>SQLITE_INDEX_CONSTRAINT_LIKE - <a href="c3ref/c_index_constraint_eq.html">c3ref/c_index_constraint_eq.html</a></li><li>SQLITE_INDEX_CONSTRAINT_LIMIT - <a href="c3ref/c_index_constraint_eq.html">c3ref/c_index_constraint_eq.html</a></li><li>SQLITE_INDEX_CONSTRAINT_LT - <a href="c3ref/c_index_constraint_eq.html">c3ref/c_index_constraint_eq.html</a></li><li>SQLITE_INDEX_CONSTRAINT_MATCH - <a href="c3ref/c_index_constraint_eq.html">c3ref/c_index_constraint_eq.html</a></li><li>SQLITE_INDEX_CONSTRAINT_NE - <a href="c3ref/c_index_constraint_eq.html">c3ref/c_index_constraint_eq.html</a></li><li>SQLITE_INDEX_CONSTRAINT_OFFSET - <a href="c3ref/c_index_constraint_eq.html">c3ref/c_index_constraint_eq.html</a></li><li>SQLITE_INDEX_CONSTRAINT_REGEXP - <a href="c3ref/c_index_constraint_eq.html">c3ref/c_index_constraint_eq.html</a></li><li>SQLITE_INDEX_SCAN_UNIQUE - <a href="c3ref/c_index_scan_unique.html">c3ref/c_index_scan_unique.html</a></li><li>SQLITE_INNOCUOUS - <a href="c3ref/c_deterministic.html#sqliteinnocuous">c3ref/c_deterministic.html#sqliteinnocuous</a></li><li>SQLITE_INSERT - <a href="c3ref/c_alter_table.html">c3ref/c_alter_table.html</a></li><li>sqlite_int64 - <a href="c3ref/int64.html">c3ref/int64.html</a></li><li>SQLITE_INTEGER - <a href="c3ref/c_blob.html">c3ref/c_blob.html</a></li><li>SQLITE_INTERNAL - <a href="rescode.html#internal">rescode.html#internal</a></li><li>SQLITE_INTERRUPT - <a href="rescode.html#interrupt">rescode.html#interrupt</a></li><li>SQLITE_INTROSPECTION_PRAGMAS - <a href="compile.html#introspection_pragmas">compile.html#introspection_pragmas</a></li><li>SQLITE_IOCAP_ATOMIC - <a href="c3ref/c_iocap_atomic.html">c3ref/c_iocap_atomic.html</a></li><li>SQLITE_IOCAP_ATOMIC1K - <a href="c3ref/c_iocap_atomic.html">c3ref/c_iocap_atomic.html</a></li><li>SQLITE_IOCAP_ATOMIC2K - <a href="c3ref/c_iocap_atomic.html">c3ref/c_iocap_atomic.html</a></li><li>SQLITE_IOCAP_ATOMIC4K - <a href="c3ref/c_iocap_atomic.html">c3ref/c_iocap_atomic.html</a></li><li>SQLITE_IOCAP_ATOMIC8K - <a href="c3ref/c_iocap_atomic.html">c3ref/c_iocap_atomic.html</a></li><li>SQLITE_IOCAP_ATOMIC16K - <a href="c3ref/c_iocap_atomic.html">c3ref/c_iocap_atomic.html</a></li><li>SQLITE_IOCAP_ATOMIC32K - <a href="c3ref/c_iocap_atomic.html">c3ref/c_iocap_atomic.html</a></li><li>SQLITE_IOCAP_ATOMIC64K - <a href="c3ref/c_iocap_atomic.html">c3ref/c_iocap_atomic.html</a></li><li>SQLITE_IOCAP_ATOMIC512 - <a href="c3ref/c_iocap_atomic.html">c3ref/c_iocap_atomic.html</a></li><li>SQLITE_IOCAP_BATCH_ATOMIC - <a href="c3ref/c_iocap_atomic.html">c3ref/c_iocap_atomic.html</a></li><li>SQLITE_IOCAP_IMMUTABLE - <a href="c3ref/c_iocap_atomic.html">c3ref/c_iocap_atomic.html</a></li><li>SQLITE_IOCAP_POWERSAFE_OVERWRITE - <a href="c3ref/c_iocap_atomic.html">c3ref/c_iocap_atomic.html</a></li><li>SQLITE_IOCAP_SAFE_APPEND - <a href="c3ref/c_iocap_atomic.html">c3ref/c_iocap_atomic.html</a></li><li>SQLITE_IOCAP_SEQUENTIAL - <a href="c3ref/c_iocap_atomic.html">c3ref/c_iocap_atomic.html</a></li><li>SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN - <a href="c3ref/c_iocap_atomic.html">c3ref/c_iocap_atomic.html</a></li><li>SQLITE_IOERR - <a href="rescode.html#ioerr">rescode.html#ioerr</a></li><li>SQLITE_IOERR_ACCESS - <a href="rescode.html#ioerr_access">rescode.html#ioerr_access</a></li><li>SQLITE_IOERR_AUTH - <a href="rescode.html#ioerr_auth">rescode.html#ioerr_auth</a></li><li>SQLITE_IOERR_BEGIN_ATOMIC - <a href="rescode.html#ioerr_begin_atomic">rescode.html#ioerr_begin_atomic</a></li><li>SQLITE_IOERR_BLOCKED - <a href="rescode.html#ioerr_blocked">rescode.html#ioerr_blocked</a></li><li>SQLITE_IOERR_CHECKRESERVEDLOCK - <a href="rescode.html#ioerr_checkreservedlock">rescode.html#ioerr_checkreservedlock</a></li><li>SQLITE_IOERR_CLOSE - <a href="rescode.html#ioerr_close">rescode.html#ioerr_close</a></li><li>SQLITE_IOERR_COMMIT_ATOMIC - <a href="rescode.html#ioerr_commit_atomic">rescode.html#ioerr_commit_atomic</a></li><li>SQLITE_IOERR_CONVPATH - <a href="rescode.html#ioerr_convpath">rescode.html#ioerr_convpath</a></li><li>SQLITE_IOERR_CORRUPTFS - <a href="rescode.html#ioerr_corruptfs">rescode.html#ioerr_corruptfs</a></li><li>SQLITE_IOERR_DATA - <a href="rescode.html#ioerr_data">rescode.html#ioerr_data</a></li><li>SQLITE_IOERR_DELETE - <a href="rescode.html#ioerr_delete">rescode.html#ioerr_delete</a></li><li>SQLITE_IOERR_DELETE_NOENT - <a href="rescode.html#ioerr_delete_noent">rescode.html#ioerr_delete_noent</a></li><li>SQLITE_IOERR_DIR_CLOSE - <a href="rescode.html#ioerr_dir_close">rescode.html#ioerr_dir_close</a></li><li>SQLITE_IOERR_DIR_FSYNC - <a href="rescode.html#ioerr_dir_fsync">rescode.html#ioerr_dir_fsync</a></li><li>SQLITE_IOERR_FSTAT - <a href="rescode.html#ioerr_fstat">rescode.html#ioerr_fstat</a></li><li>SQLITE_IOERR_FSYNC - <a href="rescode.html#ioerr_fsync">rescode.html#ioerr_fsync</a></li><li>SQLITE_IOERR_GETTEMPPATH - <a href="rescode.html#ioerr_gettemppath">rescode.html#ioerr_gettemppath</a></li><li>SQLITE_IOERR_IN_PAGE - <a href="c3ref/c_abort_rollback.html">c3ref/c_abort_rollback.html</a></li><li>SQLITE_IOERR_LOCK - <a href="rescode.html#ioerr_lock">rescode.html#ioerr_lock</a></li><li>SQLITE_IOERR_MMAP - <a href="rescode.html#ioerr_mmap">rescode.html#ioerr_mmap</a></li><li>SQLITE_IOERR_NOMEM - <a href="rescode.html#ioerr_nomem">rescode.html#ioerr_nomem</a></li><li>SQLITE_IOERR_RDLOCK - <a href="rescode.html#ioerr_rdlock">rescode.html#ioerr_rdlock</a></li><li>SQLITE_IOERR_READ - <a href="rescode.html#ioerr_read">rescode.html#ioerr_read</a></li><li>SQLITE_IOERR_ROLLBACK_ATOMIC - <a href="rescode.html#ioerr_rollback_atomic">rescode.html#ioerr_rollback_atomic</a></li><li>SQLITE_IOERR_SEEK - <a href="rescode.html#ioerr_seek">rescode.html#ioerr_seek</a></li><li>SQLITE_IOERR_SHMLOCK - <a href="rescode.html#ioerr_shmlock">rescode.html#ioerr_shmlock</a></li><li>SQLITE_IOERR_SHMMAP - <a href="rescode.html#ioerr_shmmap">rescode.html#ioerr_shmmap</a></li><li>SQLITE_IOERR_SHMOPEN - <a href="rescode.html#ioerr_shmopen">rescode.html#ioerr_shmopen</a></li><li>SQLITE_IOERR_SHMSIZE - <a href="rescode.html#ioerr_shmsize">rescode.html#ioerr_shmsize</a></li><li>SQLITE_IOERR_SHORT_READ - <a href="rescode.html#ioerr_short_read">rescode.html#ioerr_short_read</a></li><li>SQLITE_IOERR_TRUNCATE - <a href="rescode.html#ioerr_truncate">rescode.html#ioerr_truncate</a></li><li>SQLITE_IOERR_UNLOCK - <a href="rescode.html#ioerr_unlock">rescode.html#ioerr_unlock</a></li><li>SQLITE_IOERR_VNODE - <a href="rescode.html#ioerr_vnode">rescode.html#ioerr_vnode</a></li><li>SQLITE_IOERR_WRITE - <a href="rescode.html#ioerr_write">rescode.html#ioerr_write</a></li><li>SQLITE_JSON_MAX_DEPTH - <a href="compile.html#json_max_depth">compile.html#json_max_depth</a></li><li>SQLITE_LIKE_DOESNT_MATCH_BLOBS - <a href="compile.html#like_doesnt_match_blobs">compile.html#like_doesnt_match_blobs</a></li><li>SQLITE_LIMIT_ATTACHED - <a href="c3ref/c_limit_attached.html#sqlitelimitattached">c3ref/c_limit_attached.html#sqlitelimitattached</a></li><li>SQLITE_LIMIT_COLUMN - <a href="c3ref/c_limit_attached.html#sqlitelimitcolumn">c3ref/c_limit_attached.html#sqlitelimitcolumn</a></li><li>SQLITE_LIMIT_COMPOUND_SELECT - <a href="c3ref/c_limit_attached.html#sqlitelimitcompoundselect">c3ref/c_limit_attached.html#sqlitelimitcompoundselect</a></li><li>SQLITE_LIMIT_EXPR_DEPTH - <a href="c3ref/c_limit_attached.html#sqlitelimitexprdepth">c3ref/c_limit_attached.html#sqlitelimitexprdepth</a></li><li>SQLITE_LIMIT_FUNCTION_ARG - <a href="c3ref/c_limit_attached.html#sqlitelimitfunctionarg">c3ref/c_limit_attached.html#sqlitelimitfunctionarg</a></li><li>SQLITE_LIMIT_LENGTH - <a href="c3ref/c_limit_attached.html#sqlitelimitlength">c3ref/c_limit_attached.html#sqlitelimitlength</a></li><li>SQLITE_LIMIT_LIKE_PATTERN_LENGTH - <a href="c3ref/c_limit_attached.html#sqlitelimitlikepatternlength">c3ref/c_limit_attached.html#sqlitelimitlikepatternlength</a></li><li>SQLITE_LIMIT_SQL_LENGTH - <a href="c3ref/c_limit_attached.html#sqlitelimitsqllength">c3ref/c_limit_attached.html#sqlitelimitsqllength</a></li><li>SQLITE_LIMIT_TRIGGER_DEPTH - <a href="c3ref/c_limit_attached.html#sqlitelimittriggerdepth">c3ref/c_limit_attached.html#sqlitelimittriggerdepth</a></li><li>SQLITE_LIMIT_VARIABLE_NUMBER - <a href="c3ref/c_limit_attached.html#sqlitelimitvariablenumber">c3ref/c_limit_attached.html#sqlitelimitvariablenumber</a></li><li>SQLITE_LIMIT_VDBE_OP - <a href="c3ref/c_limit_attached.html#sqlitelimitvdbeop">c3ref/c_limit_attached.html#sqlitelimitvdbeop</a></li><li>SQLITE_LIMIT_WORKER_THREADS - <a href="c3ref/c_limit_attached.html#sqlitelimitworkerthreads">c3ref/c_limit_attached.html#sqlitelimitworkerthreads</a></li><li>SQLITE_LOCK_EXCLUSIVE - <a href="c3ref/c_lock_exclusive.html">c3ref/c_lock_exclusive.html</a></li><li>SQLITE_LOCK_NONE - <a href="c3ref/c_lock_exclusive.html">c3ref/c_lock_exclusive.html</a></li><li>SQLITE_LOCK_PENDING - <a href="c3ref/c_lock_exclusive.html">c3ref/c_lock_exclusive.html</a></li><li>SQLITE_LOCK_RESERVED - <a href="c3ref/c_lock_exclusive.html">c3ref/c_lock_exclusive.html</a></li><li>SQLITE_LOCK_SHARED - <a href="c3ref/c_lock_exclusive.html">c3ref/c_lock_exclusive.html</a></li><li>SQLITE_LOCKED - <a href="rescode.html#locked">rescode.html#locked</a></li><li>SQLITE_LOCKED_SHAREDCACHE - <a href="rescode.html#locked_sharedcache">rescode.html#locked_sharedcache</a></li><li>SQLITE_LOCKED_VTAB - <a href="rescode.html#locked_vtab">rescode.html#locked_vtab</a></li><li>sqlite_master table - <a href="schematab.html">schematab.html</a></li><li>SQLITE_MAX_ALLOCATION_SIZE - <a href="compile.html#max_allocation_size">compile.html#max_allocation_size</a></li><li>SQLITE_MAX_ATTACHED - <a href="limits.html#max_attached">limits.html#max_attached</a></li><li>SQLITE_MAX_COLUMN - <a href="limits.html#max_column">limits.html#max_column</a></li><li>SQLITE_MAX_COMPOUND_SELECT - <a href="limits.html#max_compound_select">limits.html#max_compound_select</a></li><li>SQLITE_MAX_EXPR_DEPTH - <a href="limits.html#max_expr_depth">limits.html#max_expr_depth</a></li><li>SQLITE_MAX_FUNCTION_ARG - <a href="limits.html#max_function_arg">limits.html#max_function_arg</a></li><li>SQLITE_MAX_LENGTH - <a href="limits.html#max_length">limits.html#max_length</a></li><li>SQLITE_MAX_LIKE_PATTERN_LENGTH - <a href="limits.html#max_like_pattern_length">limits.html#max_like_pattern_length</a></li><li>SQLITE_MAX_MEMORY - <a href="compile.html#max_memory">compile.html#max_memory</a></li><li>SQLITE_MAX_MMAP_SIZE - <a href="compile.html#max_mmap_size">compile.html#max_mmap_size</a></li><li>SQLITE_MAX_PAGE_COUNT - <a href="limits.html#max_page_count">limits.html#max_page_count</a></li><li>SQLITE_MAX_SCHEMA_RETRY - <a href="compile.html#max_schema_retry">compile.html#max_schema_retry</a></li><li>SQLITE_MAX_SQL_LENGTH - <a href="limits.html#max_sql_length">limits.html#max_sql_length</a></li><li>SQLITE_MAX_TRIGGER_DEPTH - <a href="limits.html#max_trigger_depth">limits.html#max_trigger_depth</a></li><li>SQLITE_MAX_VARIABLE_NUMBER - <a href="limits.html#max_variable_number">limits.html#max_variable_number</a></li><li>SQLITE_MAX_WORKER_THREADS - <a href="compile.html#max_worker_threads">compile.html#max_worker_threads</a></li><li>SQLITE_MEMDB_DEFAULT_MAXSIZE - <a href="compile.html#memdb_default_maxsize">compile.html#memdb_default_maxsize</a></li><li>SQLITE_MEMDEBUG - <a href="compile.html#memdebug">compile.html#memdebug</a></li><li>sqlite_memstat - <a href="memstat.html">memstat.html</a></li><li>SQLITE_MEMSTAT virtual table - <a href="memstat.html">memstat.html</a></li><li>SQLITE_MINIMUM_FILE_DESCRIPTOR - <a href="compile.html#minimum_file_descriptor">compile.html#minimum_file_descriptor</a></li><li>SQLITE_MISMATCH - <a href="rescode.html#mismatch">rescode.html#mismatch</a></li><li>SQLITE_MISUSE - <a href="rescode.html#misuse">rescode.html#misuse</a></li><li>SQLITE_MUTEX_FAST - <a href="c3ref/c_mutex_fast.html">c3ref/c_mutex_fast.html</a></li><li>SQLITE_MUTEX_RECURSIVE - <a href="c3ref/c_mutex_fast.html">c3ref/c_mutex_fast.html</a></li><li>SQLITE_MUTEX_STATIC_APP1 - <a href="c3ref/c_mutex_fast.html">c3ref/c_mutex_fast.html</a></li><li>SQLITE_MUTEX_STATIC_APP2 - <a href="c3ref/c_mutex_fast.html">c3ref/c_mutex_fast.html</a></li><li>SQLITE_MUTEX_STATIC_APP3 - <a href="c3ref/c_mutex_fast.html">c3ref/c_mutex_fast.html</a></li><li>SQLITE_MUTEX_STATIC_LRU - <a href="c3ref/c_mutex_fast.html">c3ref/c_mutex_fast.html</a></li><li>SQLITE_MUTEX_STATIC_LRU2 - <a href="c3ref/c_mutex_fast.html">c3ref/c_mutex_fast.html</a></li><li>SQLITE_MUTEX_STATIC_MAIN - <a href="c3ref/c_mutex_fast.html">c3ref/c_mutex_fast.html</a></li><li>SQLITE_MUTEX_STATIC_MEM - <a href="c3ref/c_mutex_fast.html">c3ref/c_mutex_fast.html</a></li><li>SQLITE_MUTEX_STATIC_MEM2 - <a href="c3ref/c_mutex_fast.html">c3ref/c_mutex_fast.html</a></li><li>SQLITE_MUTEX_STATIC_OPEN - <a href="c3ref/c_mutex_fast.html">c3ref/c_mutex_fast.html</a></li><li>SQLITE_MUTEX_STATIC_PMEM - <a href="c3ref/c_mutex_fast.html">c3ref/c_mutex_fast.html</a></li><li>SQLITE_MUTEX_STATIC_PRNG - <a href="c3ref/c_mutex_fast.html">c3ref/c_mutex_fast.html</a></li><li>SQLITE_MUTEX_STATIC_VFS1 - <a href="c3ref/c_mutex_fast.html">c3ref/c_mutex_fast.html</a></li><li>SQLITE_MUTEX_STATIC_VFS2 - <a href="c3ref/c_mutex_fast.html">c3ref/c_mutex_fast.html</a></li><li>SQLITE_MUTEX_STATIC_VFS3 - <a href="c3ref/c_mutex_fast.html">c3ref/c_mutex_fast.html</a></li><li>SQLITE_NOLFS - <a href="rescode.html#nolfs">rescode.html#nolfs</a></li><li>SQLITE_NOMEM - <a href="rescode.html#nomem">rescode.html#nomem</a></li><li>SQLITE_NOTADB - <a href="rescode.html#notadb">rescode.html#notadb</a></li><li>SQLITE_NOTFOUND - <a href="rescode.html#notfound">rescode.html#notfound</a></li><li>SQLITE_NOTICE - <a href="rescode.html#notice">rescode.html#notice</a></li><li>SQLITE_NOTICE_RBU - <a href="c3ref/c_abort_rollback.html">c3ref/c_abort_rollback.html</a></li><li>SQLITE_NOTICE_RECOVER_ROLLBACK - <a href="rescode.html#notice_recover_rollback">rescode.html#notice_recover_rollback</a></li><li>SQLITE_NOTICE_RECOVER_WAL - <a href="rescode.html#notice_recover_wal">rescode.html#notice_recover_wal</a></li><li>SQLITE_NULL - <a href="c3ref/c_blob.html">c3ref/c_blob.html</a></li><li>sqlite_offset - <a href="lang_corefunc.html#sqlite_offset">lang_corefunc.html#sqlite_offset</a></li><li>sqlite_offset SQL function - <a href="lang_corefunc.html#sqlite_offset">lang_corefunc.html#sqlite_offset</a></li><li>SQLITE_OK - <a href="rescode.html#ok">rescode.html#ok</a></li><li>SQLITE_OK_LOAD_PERMANENTLY - <a href="rescode.html#ok_load_permanently">rescode.html#ok_load_permanently</a></li><li>SQLITE_OK_SYMLINK - <a href="c3ref/c_abort_rollback.html">c3ref/c_abort_rollback.html</a></li><li>SQLITE_OMIT_ALTERTABLE - <a href="compile.html#omit_altertable">compile.html#omit_altertable</a></li><li>SQLITE_OMIT_ANALYZE - <a href="compile.html#omit_analyze">compile.html#omit_analyze</a></li><li>SQLITE_OMIT_ATTACH - <a href="compile.html#omit_attach">compile.html#omit_attach</a></li><li>SQLITE_OMIT_AUTHORIZATION - <a href="compile.html#omit_authorization">compile.html#omit_authorization</a></li><li>SQLITE_OMIT_AUTOINCREMENT - <a href="compile.html#omit_autoincrement">compile.html#omit_autoincrement</a></li><li>SQLITE_OMIT_AUTOINIT - <a href="compile.html#omit_autoinit">compile.html#omit_autoinit</a></li><li>SQLITE_OMIT_AUTOMATIC_INDEX - <a href="compile.html#omit_automatic_index">compile.html#omit_automatic_index</a></li><li>SQLITE_OMIT_AUTORESET - <a href="compile.html#omit_autoreset">compile.html#omit_autoreset</a></li><li>SQLITE_OMIT_AUTOVACUUM - <a href="compile.html#omit_autovacuum">compile.html#omit_autovacuum</a></li><li>SQLITE_OMIT_BETWEEN_OPTIMIZATION - <a href="compile.html#omit_between_optimization">compile.html#omit_between_optimization</a></li><li>SQLITE_OMIT_BLOB_LITERAL - <a href="compile.html#omit_blob_literal">compile.html#omit_blob_literal</a></li><li>SQLITE_OMIT_BTREECOUNT - <a href="compile.html#omit_btreecount">compile.html#omit_btreecount</a></li><li>SQLITE_OMIT_BUILTIN_TEST - <a href="compile.html#omit_builtin_test">compile.html#omit_builtin_test</a></li><li>SQLITE_OMIT_CASE_SENSITIVE_LIKE_PRAGMA - <a href="compile.html#omit_case_sensitive_like_pragma">compile.html#omit_case_sensitive_like_pragma</a></li><li>SQLITE_OMIT_CAST - <a href="compile.html#omit_cast">compile.html#omit_cast</a></li><li>SQLITE_OMIT_CHECK - <a href="compile.html#omit_check">compile.html#omit_check</a></li><li>SQLITE_OMIT_COMPILEOPTION_DIAGS - <a href="compile.html#omit_compileoption_diags">compile.html#omit_compileoption_diags</a></li><li>SQLITE_OMIT_COMPLETE - <a href="compile.html#omit_complete">compile.html#omit_complete</a></li><li>SQLITE_OMIT_COMPOUND_SELECT - <a href="compile.html#omit_compound_select">compile.html#omit_compound_select</a></li><li>SQLITE_OMIT_CTE - <a href="compile.html#omit_cte">compile.html#omit_cte</a></li><li>SQLITE_OMIT_DATETIME_FUNCS - <a href="compile.html#omit_datetime_funcs">compile.html#omit_datetime_funcs</a></li><li>SQLITE_OMIT_DECLTYPE - <a href="compile.html#omit_decltype">compile.html#omit_decltype</a></li><li>SQLITE_OMIT_DEPRECATED - <a href="compile.html#omit_deprecated">compile.html#omit_deprecated</a></li><li>SQLITE_OMIT_DESERIALIZE - <a href="compile.html#omit_deserialize">compile.html#omit_deserialize</a></li><li>SQLITE_OMIT_DISKIO - <a href="compile.html#omit_diskio">compile.html#omit_diskio</a></li><li>SQLITE_OMIT_EXPLAIN - <a href="compile.html#omit_explain">compile.html#omit_explain</a></li><li>SQLITE_OMIT_FLAG_PRAGMAS - <a href="compile.html#omit_flag_pragmas">compile.html#omit_flag_pragmas</a></li><li>SQLITE_OMIT_FLOATING_POINT - <a href="compile.html#omit_floating_point">compile.html#omit_floating_point</a></li><li>SQLITE_OMIT_FOREIGN_KEY - <a href="compile.html#omit_foreign_key">compile.html#omit_foreign_key</a></li><li>SQLITE_OMIT_GENERATED_COLUMNS - <a href="compile.html#omit_generated_columns">compile.html#omit_generated_columns</a></li><li>SQLITE_OMIT_GET_TABLE - <a href="compile.html#omit_get_table">compile.html#omit_get_table</a></li><li>SQLITE_OMIT_HEX_INTEGER - <a href="compile.html#omit_hex_integer">compile.html#omit_hex_integer</a></li><li>SQLITE_OMIT_INCRBLOB - <a href="compile.html#omit_incrblob">compile.html#omit_incrblob</a></li><li>SQLITE_OMIT_INTEGRITY_CHECK - <a href="compile.html#omit_integrity_check">compile.html#omit_integrity_check</a></li><li>SQLITE_OMIT_INTROSPECTION_PRAGMAS - <a href="compile.html#omit_introspection_pragmas">compile.html#omit_introspection_pragmas</a></li><li>SQLITE_OMIT_JSON - <a href="compile.html#omit_json">compile.html#omit_json</a></li><li>SQLITE_OMIT_LIKE_OPTIMIZATION - <a href="compile.html#omit_like_optimization">compile.html#omit_like_optimization</a></li><li>SQLITE_OMIT_LOAD_EXTENSION - <a href="compile.html#omit_load_extension">compile.html#omit_load_extension</a></li><li>SQLITE_OMIT_LOCALTIME - <a href="compile.html#omit_localtime">compile.html#omit_localtime</a></li><li>SQLITE_OMIT_LOOKASIDE - <a href="compile.html#omit_lookaside">compile.html#omit_lookaside</a></li><li>SQLITE_OMIT_MEMORYDB - <a href="compile.html#omit_memorydb">compile.html#omit_memorydb</a></li><li>SQLITE_OMIT_OR_OPTIMIZATION - <a href="compile.html#omit_or_optimization">compile.html#omit_or_optimization</a></li><li>SQLITE_OMIT_PAGER_PRAGMAS - <a href="compile.html#omit_pager_pragmas">compile.html#omit_pager_pragmas</a></li><li>SQLITE_OMIT_PRAGMA - <a href="compile.html#omit_pragma">compile.html#omit_pragma</a></li><li>SQLITE_OMIT_PROGRESS_CALLBACK - <a href="compile.html#omit_progress_callback">compile.html#omit_progress_callback</a></li><li>SQLITE_OMIT_QUICKBALANCE - <a href="compile.html#omit_quickbalance">compile.html#omit_quickbalance</a></li><li>SQLITE_OMIT_REINDEX - <a href="compile.html#omit_reindex">compile.html#omit_reindex</a></li><li>SQLITE_OMIT_SCHEMA_PRAGMAS - <a href="compile.html#omit_schema_pragmas">compile.html#omit_schema_pragmas</a></li><li>SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS - <a href="compile.html#omit_schema_version_pragmas">compile.html#omit_schema_version_pragmas</a></li><li>SQLITE_OMIT_SHARED_CACHE - <a href="compile.html#omit_shared_cache">compile.html#omit_shared_cache</a></li><li>SQLITE_OMIT_SUBQUERY - <a href="compile.html#omit_subquery">compile.html#omit_subquery</a></li><li>SQLITE_OMIT_TCL_VARIABLE - <a href="compile.html#omit_tcl_variable">compile.html#omit_tcl_variable</a></li><li>SQLITE_OMIT_TEMPDB - <a href="compile.html#omit_tempdb">compile.html#omit_tempdb</a></li><li>SQLITE_OMIT_TRACE - <a href="compile.html#omit_trace">compile.html#omit_trace</a></li><li>SQLITE_OMIT_TRIGGER - <a href="compile.html#omit_trigger">compile.html#omit_trigger</a></li><li>SQLITE_OMIT_TRUNCATE_OPTIMIZATION - <a href="compile.html#omit_truncate_optimization">compile.html#omit_truncate_optimization</a></li><li>SQLITE_OMIT_UTF16 - <a href="compile.html#omit_utf16">compile.html#omit_utf16</a></li><li>SQLITE_OMIT_VACUUM - <a href="compile.html#omit_vacuum">compile.html#omit_vacuum</a></li><li>SQLITE_OMIT_VIEW - <a href="compile.html#omit_view">compile.html#omit_view</a></li><li>SQLITE_OMIT_VIRTUALTABLE - <a href="compile.html#omit_virtualtable">compile.html#omit_virtualtable</a></li><li>SQLITE_OMIT_WAL - <a href="compile.html#omit_wal">compile.html#omit_wal</a></li><li>SQLITE_OMIT_WINDOWFUNC - <a href="compile.html#omit_windowfunc">compile.html#omit_windowfunc</a></li><li>SQLITE_OMIT_WSD - <a href="compile.html#omit_wsd">compile.html#omit_wsd</a></li><li>SQLITE_OMIT_XFER_OPT - <a href="compile.html#omit_xfer_opt">compile.html#omit_xfer_opt</a></li><li>SQLITE_OPEN_AUTOPROXY - <a href="c3ref/c_open_autoproxy.html">c3ref/c_open_autoproxy.html</a></li><li>SQLITE_OPEN_CREATE - <a href="c3ref/c_open_autoproxy.html">c3ref/c_open_autoproxy.html</a></li><li>SQLITE_OPEN_DELETEONCLOSE - <a href="c3ref/c_open_autoproxy.html">c3ref/c_open_autoproxy.html</a></li><li>SQLITE_OPEN_EXCLUSIVE - <a href="c3ref/c_open_autoproxy.html">c3ref/c_open_autoproxy.html</a></li><li>SQLITE_OPEN_EXRESCODE - <a href="c3ref/c_open_autoproxy.html">c3ref/c_open_autoproxy.html</a></li><li>SQLITE_OPEN_FULLMUTEX - <a href="c3ref/c_open_autoproxy.html">c3ref/c_open_autoproxy.html</a></li><li>SQLITE_OPEN_MAIN_DB - <a href="c3ref/c_open_autoproxy.html">c3ref/c_open_autoproxy.html</a></li><li>SQLITE_OPEN_MAIN_JOURNAL - <a href="c3ref/c_open_autoproxy.html">c3ref/c_open_autoproxy.html</a></li><li>SQLITE_OPEN_MEMORY - <a href="c3ref/c_open_autoproxy.html">c3ref/c_open_autoproxy.html</a></li><li>SQLITE_OPEN_NOFOLLOW - <a href="c3ref/c_open_autoproxy.html">c3ref/c_open_autoproxy.html</a></li><li>SQLITE_OPEN_NOMUTEX - <a href="c3ref/c_open_autoproxy.html">c3ref/c_open_autoproxy.html</a></li><li>SQLITE_OPEN_PRIVATECACHE - <a href="c3ref/c_open_autoproxy.html">c3ref/c_open_autoproxy.html</a></li><li>SQLITE_OPEN_READONLY - <a href="c3ref/c_open_autoproxy.html">c3ref/c_open_autoproxy.html</a></li><li>SQLITE_OPEN_READWRITE - <a href="c3ref/c_open_autoproxy.html">c3ref/c_open_autoproxy.html</a></li><li>SQLITE_OPEN_SHAREDCACHE - <a href="c3ref/c_open_autoproxy.html">c3ref/c_open_autoproxy.html</a></li><li>SQLITE_OPEN_SUBJOURNAL - <a href="c3ref/c_open_autoproxy.html">c3ref/c_open_autoproxy.html</a></li><li>SQLITE_OPEN_SUPER_JOURNAL - <a href="c3ref/c_open_autoproxy.html">c3ref/c_open_autoproxy.html</a></li><li>SQLITE_OPEN_TEMP_DB - <a href="c3ref/c_open_autoproxy.html">c3ref/c_open_autoproxy.html</a></li><li>SQLITE_OPEN_TEMP_JOURNAL - <a href="c3ref/c_open_autoproxy.html">c3ref/c_open_autoproxy.html</a></li><li>SQLITE_OPEN_TRANSIENT_DB - <a href="c3ref/c_open_autoproxy.html">c3ref/c_open_autoproxy.html</a></li><li>SQLITE_OPEN_URI - <a href="c3ref/c_open_autoproxy.html">c3ref/c_open_autoproxy.html</a></li><li>SQLITE_OPEN_WAL - <a href="c3ref/c_open_autoproxy.html">c3ref/c_open_autoproxy.html</a></li><li>SQLITE_OS_OTHER - <a href="compile.html#os_other">compile.html#os_other</a></li><li>SQLITE_PERM - <a href="rescode.html#perm">rescode.html#perm</a></li><li>SQLITE_POWERSAFE_OVERWRITE - <a href="compile.html#powersafe_overwrite">compile.html#powersafe_overwrite</a></li><li>SQLITE_PRAGMA - <a href="c3ref/c_alter_table.html">c3ref/c_alter_table.html</a></li><li>SQLITE_PREPARE_NO_VTAB - <a href="c3ref/c_prepare_normalize.html#sqlitepreparenovtab">c3ref/c_prepare_normalize.html#sqlitepreparenovtab</a></li><li>SQLITE_PREPARE_NORMALIZE - <a href="c3ref/c_prepare_normalize.html#sqlitepreparenormalize">c3ref/c_prepare_normalize.html#sqlitepreparenormalize</a></li><li>SQLITE_PREPARE_PERSISTENT - <a href="c3ref/c_prepare_normalize.html#sqlitepreparepersistent">c3ref/c_prepare_normalize.html#sqlitepreparepersistent</a></li><li>SQLITE_PRINTF_PRECISION_LIMIT - <a href="compile.html#printf_precision_limit">compile.html#printf_precision_limit</a></li><li>SQLITE_PROTOCOL - <a href="rescode.html#protocol">rescode.html#protocol</a></li><li>SQLITE_QUERY_PLANNER_LIMIT - <a href="compile.html#query_planner_limit">compile.html#query_planner_limit</a></li><li>SQLITE_QUERY_PLANNER_LIMIT_INCR - <a href="compile.html#query_planner_limit_incr">compile.html#query_planner_limit_incr</a></li><li>SQLITE_RANGE - <a href="rescode.html#range">rescode.html#range</a></li><li>SQLITE_READ - <a href="c3ref/c_alter_table.html">c3ref/c_alter_table.html</a></li><li>SQLITE_READONLY - <a href="rescode.html#readonly">rescode.html#readonly</a></li><li>SQLITE_READONLY_CANTINIT - <a href="rescode.html#readonly_cantinit">rescode.html#readonly_cantinit</a></li><li>SQLITE_READONLY_CANTLOCK - <a href="rescode.html#readonly_cantlock">rescode.html#readonly_cantlock</a></li><li>SQLITE_READONLY_DBMOVED - <a href="rescode.html#readonly_dbmoved">rescode.html#readonly_dbmoved</a></li><li>SQLITE_READONLY_DIRECTORY - <a href="rescode.html#readonly_directory">rescode.html#readonly_directory</a></li><li>SQLITE_READONLY_RECOVERY - <a href="rescode.html#readonly_recovery">rescode.html#readonly_recovery</a></li><li>SQLITE_READONLY_ROLLBACK - <a href="rescode.html#readonly_rollback">rescode.html#readonly_rollback</a></li><li>SQLITE_RECURSIVE - <a href="c3ref/c_alter_table.html">c3ref/c_alter_table.html</a></li><li>SQLITE_REINDEX - <a href="c3ref/c_alter_table.html">c3ref/c_alter_table.html</a></li><li>SQLITE_REPLACE - <a href="c3ref/c_fail.html">c3ref/c_fail.html</a></li><li>SQLITE_RESULT_SUBTYPE - <a href="c3ref/c_deterministic.html#sqliteresultsubtype">c3ref/c_deterministic.html#sqliteresultsubtype</a></li><li>SQLITE_REVERSE_UNORDERED_SELECTS - <a href="compile.html#reverse_unordered_selects">compile.html#reverse_unordered_selects</a></li><li>SQLITE_ROLLBACK - <a href="c3ref/c_fail.html">c3ref/c_fail.html</a></li><li>SQLITE_ROW - <a href="rescode.html#row">rescode.html#row</a></li><li>SQLITE_RTREE_INT_ONLY - <a href="compile.html#rtree_int_only">compile.html#rtree_int_only</a></li><li>SQLITE_SAVEPOINT - <a href="c3ref/c_alter_table.html">c3ref/c_alter_table.html</a></li><li>SQLITE_SCANSTAT_COMPLEX - <a href="c3ref/c_scanstat_complex.html">c3ref/c_scanstat_complex.html</a></li><li>SQLITE_SCANSTAT_EST - <a href="c3ref/c_scanstat_est.html#sqlitescanstatest">c3ref/c_scanstat_est.html#sqlitescanstatest</a></li><li>SQLITE_SCANSTAT_EXPLAIN - <a href="c3ref/c_scanstat_est.html#sqlitescanstatexplain">c3ref/c_scanstat_est.html#sqlitescanstatexplain</a></li><li>SQLITE_SCANSTAT_NAME - <a href="c3ref/c_scanstat_est.html#sqlitescanstatname">c3ref/c_scanstat_est.html#sqlitescanstatname</a></li><li>SQLITE_SCANSTAT_NCYCLE - <a href="c3ref/c_scanstat_est.html#sqlitescanstatncycle">c3ref/c_scanstat_est.html#sqlitescanstatncycle</a></li><li>SQLITE_SCANSTAT_NLOOP - <a href="c3ref/c_scanstat_est.html#sqlitescanstatnloop">c3ref/c_scanstat_est.html#sqlitescanstatnloop</a></li><li>SQLITE_SCANSTAT_NVISIT - <a href="c3ref/c_scanstat_est.html#sqlitescanstatnvisit">c3ref/c_scanstat_est.html#sqlitescanstatnvisit</a></li><li>SQLITE_SCANSTAT_PARENTID - <a href="c3ref/c_scanstat_est.html#sqlitescanstatparentid">c3ref/c_scanstat_est.html#sqlitescanstatparentid</a></li><li>SQLITE_SCANSTAT_SELECTID - <a href="c3ref/c_scanstat_est.html#sqlitescanstatselectid">c3ref/c_scanstat_est.html#sqlitescanstatselectid</a></li><li>SQLITE_SCHEMA - <a href="rescode.html#schema">rescode.html#schema</a></li><li>sqlite_schema - <a href="schematab.html">schematab.html</a></li><li>sqlite_schema table - <a href="schematab.html">schematab.html</a></li><li>SQLITE_SECURE_DELETE - <a href="compile.html#secure_delete">compile.html#secure_delete</a></li><li>SQLITE_SELECT - <a href="c3ref/c_alter_table.html">c3ref/c_alter_table.html</a></li><li>sqlite_sequence - <a href="fileformat2.html#seqtab">fileformat2.html#seqtab</a></li><li>SQLITE_SERIALIZE_NOCOPY - <a href="c3ref/c_serialize_nocopy.html">c3ref/c_serialize_nocopy.html</a></li><li>SQLITE_SESSION_CONFIG_STRMSIZE - <a href="session/c_session_config_strmsize.html">session/c_session_config_strmsize.html</a></li><li>SQLITE_SESSION_OBJCONFIG_ROWID - <a href="session/c_session_objconfig_rowid.html">session/c_session_objconfig_rowid.html</a></li><li>SQLITE_SESSION_OBJCONFIG_SIZE - <a href="session/c_session_objconfig_rowid.html">session/c_session_objconfig_rowid.html</a></li><li>SQLITE_SHM_EXCLUSIVE - <a href="c3ref/c_shm_exclusive.html">c3ref/c_shm_exclusive.html</a></li><li>SQLITE_SHM_LOCK - <a href="c3ref/c_shm_exclusive.html">c3ref/c_shm_exclusive.html</a></li><li>SQLITE_SHM_NLOCK - <a href="c3ref/c_shm_nlock.html">c3ref/c_shm_nlock.html</a></li><li>SQLITE_SHM_SHARED - <a href="c3ref/c_shm_exclusive.html">c3ref/c_shm_exclusive.html</a></li><li>SQLITE_SHM_UNLOCK - <a href="c3ref/c_shm_exclusive.html">c3ref/c_shm_exclusive.html</a></li><li>SQLITE_SORTER_PMASZ - <a href="compile.html#sorter_pmasz">compile.html#sorter_pmasz</a></li><li>SQLITE_SOUNDEX - <a href="compile.html#soundex">compile.html#soundex</a></li><li>SQLITE_SOURCE_ID - <a href="c3ref/c_source_id.html">c3ref/c_source_id.html</a></li><li>sqlite_source_id - <a href="lang_corefunc.html#sqlite_source_id">lang_corefunc.html#sqlite_source_id</a></li><li>sqlite_source_id SQL function - <a href="lang_corefunc.html#sqlite_source_id">lang_corefunc.html#sqlite_source_id</a></li><li>SQLITE_STAT1 - <a href="fileformat2.html#stat1tab">fileformat2.html#stat1tab</a></li><li>sqlite_stat1 - <a href="fileformat2.html#stat1tab">fileformat2.html#stat1tab</a></li><li>sqlite_stat2 - <a href="fileformat2.html#stat2tab">fileformat2.html#stat2tab</a></li><li>SQLITE_STAT3 - <a href="fileformat2.html#stat3tab">fileformat2.html#stat3tab</a></li><li>sqlite_stat3 - <a href="fileformat2.html#stat3tab">fileformat2.html#stat3tab</a></li><li>SQLITE_STAT4 - <a href="fileformat2.html#stat4tab">fileformat2.html#stat4tab</a></li><li>sqlite_stat4 - <a href="fileformat2.html#stat4tab">fileformat2.html#stat4tab</a></li><li>SQLITE_STATIC - <a href="c3ref/c_static.html">c3ref/c_static.html</a></li><li>SQLITE_STATUS_MALLOC_COUNT - <a href="c3ref/c_status_malloc_count.html#sqlitestatusmalloccount">c3ref/c_status_malloc_count.html#sqlitestatusmalloccount</a></li><li>SQLITE_STATUS_MALLOC_SIZE - <a href="c3ref/c_status_malloc_count.html#sqlitestatusmallocsize">c3ref/c_status_malloc_count.html#sqlitestatusmallocsize</a></li><li>SQLITE_STATUS_MEMORY_USED - <a href="c3ref/c_status_malloc_count.html#sqlitestatusmemoryused">c3ref/c_status_malloc_count.html#sqlitestatusmemoryused</a></li><li>SQLITE_STATUS_PAGECACHE_OVERFLOW - <a href="c3ref/c_status_malloc_count.html#sqlitestatuspagecacheoverflow">c3ref/c_status_malloc_count.html#sqlitestatuspagecacheoverflow</a></li><li>SQLITE_STATUS_PAGECACHE_SIZE - <a href="c3ref/c_status_malloc_count.html#sqlitestatuspagecachesize">c3ref/c_status_malloc_count.html#sqlitestatuspagecachesize</a></li><li>SQLITE_STATUS_PAGECACHE_USED - <a href="c3ref/c_status_malloc_count.html#sqlitestatuspagecacheused">c3ref/c_status_malloc_count.html#sqlitestatuspagecacheused</a></li><li>SQLITE_STATUS_PARSER_STACK - <a href="c3ref/c_status_malloc_count.html#sqlitestatusparserstack">c3ref/c_status_malloc_count.html#sqlitestatusparserstack</a></li><li>SQLITE_STATUS_SCRATCH_OVERFLOW - <a href="c3ref/c_status_malloc_count.html#sqlitestatusscratchoverflow">c3ref/c_status_malloc_count.html#sqlitestatusscratchoverflow</a></li><li>SQLITE_STATUS_SCRATCH_SIZE - <a href="c3ref/c_status_malloc_count.html#sqlitestatusscratchsize">c3ref/c_status_malloc_count.html#sqlitestatusscratchsize</a></li><li>SQLITE_STATUS_SCRATCH_USED - <a href="c3ref/c_status_malloc_count.html#sqlitestatusscratchused">c3ref/c_status_malloc_count.html#sqlitestatusscratchused</a></li><li>SQLITE_STDCALL - <a href="compile.html#stdcall">compile.html#stdcall</a></li><li>sqlite_stmt - <a href="stmt.html">stmt.html</a></li><li>SQLITE_STMT virtual table - <a href="stmt.html">stmt.html</a></li><li>SQLITE_STMTJRNL_SPILL - <a href="compile.html#stmtjrnl_spill">compile.html#stmtjrnl_spill</a></li><li>SQLITE_STMTSTATUS counter - <a href="c3ref/c_stmtstatus_counter.html">c3ref/c_stmtstatus_counter.html</a></li><li>SQLITE_STMTSTATUS counters - <a href="c3ref/c_stmtstatus_counter.html">c3ref/c_stmtstatus_counter.html</a></li><li>SQLITE_STMTSTATUS_AUTOINDEX - <a href="c3ref/c_stmtstatus_counter.html#sqlitestmtstatusautoindex">c3ref/c_stmtstatus_counter.html#sqlitestmtstatusautoindex</a></li><li>SQLITE_STMTSTATUS_FILTER HIT - <a href="c3ref/c_stmtstatus_counter.html#sqlitestmtstatusfilterhit">c3ref/c_stmtstatus_counter.html#sqlitestmtstatusfilterhit</a></li><li>SQLITE_STMTSTATUS_FILTER_HIT - <a href="c3ref/c_stmtstatus_counter.html">c3ref/c_stmtstatus_counter.html</a></li><li>SQLITE_STMTSTATUS_FILTER_MISS - <a href="c3ref/c_stmtstatus_counter.html#sqlitestmtstatusfiltermiss">c3ref/c_stmtstatus_counter.html#sqlitestmtstatusfiltermiss</a></li><li>SQLITE_STMTSTATUS_FULLSCAN_STEP - <a href="c3ref/c_stmtstatus_counter.html#sqlitestmtstatusfullscanstep">c3ref/c_stmtstatus_counter.html#sqlitestmtstatusfullscanstep</a></li><li>SQLITE_STMTSTATUS_MEMUSED - <a href="c3ref/c_stmtstatus_counter.html#sqlitestmtstatusmemused">c3ref/c_stmtstatus_counter.html#sqlitestmtstatusmemused</a></li><li>SQLITE_STMTSTATUS_REPREPARE - <a href="c3ref/c_stmtstatus_counter.html#sqlitestmtstatusreprepare">c3ref/c_stmtstatus_counter.html#sqlitestmtstatusreprepare</a></li><li>SQLITE_STMTSTATUS_RUN - <a href="c3ref/c_stmtstatus_counter.html#sqlitestmtstatusrun">c3ref/c_stmtstatus_counter.html#sqlitestmtstatusrun</a></li><li>SQLITE_STMTSTATUS_SORT - <a href="c3ref/c_stmtstatus_counter.html#sqlitestmtstatussort">c3ref/c_stmtstatus_counter.html#sqlitestmtstatussort</a></li><li>SQLITE_STMTSTATUS_VM_STEP - <a href="c3ref/c_stmtstatus_counter.html#sqlitestmtstatusvmstep">c3ref/c_stmtstatus_counter.html#sqlitestmtstatusvmstep</a></li><li>SQLITE_STRICT_SUBTYPE - <a href="compile.html#strict_subtype">compile.html#strict_subtype</a></li><li>SQLITE_SUBTYPE - <a href="c3ref/c_deterministic.html#sqlitesubtype">c3ref/c_deterministic.html#sqlitesubtype</a></li><li>SQLITE_SYNC_DATAONLY - <a href="c3ref/c_sync_dataonly.html">c3ref/c_sync_dataonly.html</a></li><li>SQLITE_SYNC_FULL - <a href="c3ref/c_sync_dataonly.html">c3ref/c_sync_dataonly.html</a></li><li>SQLITE_SYNC_NORMAL - <a href="c3ref/c_sync_dataonly.html">c3ref/c_sync_dataonly.html</a></li><li>SQLITE_SYSAPI - <a href="compile.html#sysapi">compile.html#sysapi</a></li><li>SQLITE_TCLAPI - <a href="compile.html#tclapi">compile.html#tclapi</a></li><li>sqlite_temp_schema - <a href="schematab.html">schematab.html</a></li><li>SQLITE_TEMP_STORE - <a href="compile.html#temp_store">compile.html#temp_store</a></li><li>SQLITE_TESTCTRL_ALWAYS - <a href="c3ref/c_testctrl_always.html">c3ref/c_testctrl_always.html</a></li><li>SQLITE_TESTCTRL_ASSERT - <a href="c3ref/c_testctrl_always.html">c3ref/c_testctrl_always.html</a></li><li>SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS - <a href="c3ref/c_testctrl_always.html">c3ref/c_testctrl_always.html</a></li><li>SQLITE_TESTCTRL_BITVEC_TEST - <a href="c3ref/c_testctrl_always.html">c3ref/c_testctrl_always.html</a></li><li>SQLITE_TESTCTRL_BYTEORDER - <a href="c3ref/c_testctrl_always.html">c3ref/c_testctrl_always.html</a></li><li>SQLITE_TESTCTRL_EXPLAIN_STMT - <a href="c3ref/c_testctrl_always.html">c3ref/c_testctrl_always.html</a></li><li>SQLITE_TESTCTRL_EXTRA_SCHEMA_CHECKS - <a href="c3ref/c_testctrl_always.html">c3ref/c_testctrl_always.html</a></li><li>SQLITE_TESTCTRL_FAULT_INSTALL - <a href="c3ref/c_testctrl_always.html">c3ref/c_testctrl_always.html</a></li><li>SQLITE_TESTCTRL_FIRST - <a href="c3ref/c_testctrl_always.html">c3ref/c_testctrl_always.html</a></li><li>SQLITE_TESTCTRL_FK_NO_ACTION - <a href="c3ref/c_testctrl_always.html">c3ref/c_testctrl_always.html</a></li><li>SQLITE_TESTCTRL_IMPOSTER - <a href="c3ref/c_testctrl_always.html">c3ref/c_testctrl_always.html</a></li><li>SQLITE_TESTCTRL_INTERNAL_FUNCTIONS - <a href="c3ref/c_testctrl_always.html">c3ref/c_testctrl_always.html</a></li><li>SQLITE_TESTCTRL_ISINIT - <a href="c3ref/c_testctrl_always.html">c3ref/c_testctrl_always.html</a></li><li>SQLITE_TESTCTRL_ISKEYWORD - <a href="c3ref/c_testctrl_always.html">c3ref/c_testctrl_always.html</a></li><li>SQLITE_TESTCTRL_JSON_SELFCHECK - <a href="c3ref/c_testctrl_always.html">c3ref/c_testctrl_always.html</a></li><li>SQLITE_TESTCTRL_LAST - <a href="c3ref/c_testctrl_always.html">c3ref/c_testctrl_always.html</a></li><li>SQLITE_TESTCTRL_LOCALTIME_FAULT - <a href="c3ref/c_testctrl_always.html">c3ref/c_testctrl_always.html</a></li><li>SQLITE_TESTCTRL_LOGEST - <a href="c3ref/c_testctrl_always.html">c3ref/c_testctrl_always.html</a></li><li>SQLITE_TESTCTRL_NEVER_CORRUPT - <a href="c3ref/c_testctrl_always.html">c3ref/c_testctrl_always.html</a></li><li>SQLITE_TESTCTRL_ONCE_RESET_THRESHOLD - <a href="c3ref/c_testctrl_always.html">c3ref/c_testctrl_always.html</a></li><li>SQLITE_TESTCTRL_OPTIMIZATIONS - <a href="c3ref/c_testctrl_always.html">c3ref/c_testctrl_always.html</a></li><li>SQLITE_TESTCTRL_PARSER_COVERAGE - <a href="c3ref/c_testctrl_always.html">c3ref/c_testctrl_always.html</a></li><li>SQLITE_TESTCTRL_PENDING_BYTE - <a href="c3ref/c_testctrl_always.html">c3ref/c_testctrl_always.html</a></li><li>SQLITE_TESTCTRL_PRNG_RESET - <a href="c3ref/c_testctrl_always.html">c3ref/c_testctrl_always.html</a></li><li>SQLITE_TESTCTRL_PRNG_RESTORE - <a href="c3ref/c_testctrl_always.html">c3ref/c_testctrl_always.html</a></li><li>SQLITE_TESTCTRL_PRNG_SAVE - <a href="c3ref/c_testctrl_always.html">c3ref/c_testctrl_always.html</a></li><li>SQLITE_TESTCTRL_PRNG_SEED - <a href="c3ref/c_testctrl_always.html">c3ref/c_testctrl_always.html</a></li><li>SQLITE_TESTCTRL_RESERVE - <a href="c3ref/c_testctrl_always.html">c3ref/c_testctrl_always.html</a></li><li>SQLITE_TESTCTRL_RESULT_INTREAL - <a href="c3ref/c_testctrl_always.html">c3ref/c_testctrl_always.html</a></li><li>SQLITE_TESTCTRL_SCRATCHMALLOC - <a href="c3ref/c_testctrl_always.html">c3ref/c_testctrl_always.html</a></li><li>SQLITE_TESTCTRL_SEEK_COUNT - <a href="c3ref/c_testctrl_always.html">c3ref/c_testctrl_always.html</a></li><li>SQLITE_TESTCTRL_SORTER_MMAP - <a href="c3ref/c_testctrl_always.html">c3ref/c_testctrl_always.html</a></li><li>SQLITE_TESTCTRL_TRACEFLAGS - <a href="c3ref/c_testctrl_always.html">c3ref/c_testctrl_always.html</a></li><li>SQLITE_TESTCTRL_TUNE - <a href="c3ref/c_testctrl_always.html">c3ref/c_testctrl_always.html</a></li><li>SQLITE_TESTCTRL_USELONGDOUBLE - <a href="c3ref/c_testctrl_always.html">c3ref/c_testctrl_always.html</a></li><li>SQLITE_TESTCTRL_VDBE_COVERAGE - <a href="c3ref/c_testctrl_always.html">c3ref/c_testctrl_always.html</a></li><li>SQLITE_TEXT - <a href="c3ref/c_blob.html">c3ref/c_blob.html</a></li><li>SQLITE_THREADSAFE - <a href="compile.html#threadsafe">compile.html#threadsafe</a></li><li>SQLITE_TOOBIG - <a href="rescode.html#toobig">rescode.html#toobig</a></li><li>SQLITE_TRACE - <a href="c3ref/c_trace.html">c3ref/c_trace.html</a></li><li>SQLITE_TRACE_CLOSE - <a href="c3ref/c_trace.html#sqlitetraceclose">c3ref/c_trace.html#sqlitetraceclose</a></li><li>SQLITE_TRACE_PROFILE - <a href="c3ref/c_trace.html#sqlitetraceprofile">c3ref/c_trace.html#sqlitetraceprofile</a></li><li>SQLITE_TRACE_ROW - <a href="c3ref/c_trace.html#sqlitetracerow">c3ref/c_trace.html#sqlitetracerow</a></li><li>SQLITE_TRACE_SIZE_LIMIT - <a href="compile.html#trace_size_limit">compile.html#trace_size_limit</a></li><li>SQLITE_TRACE_STMT - <a href="c3ref/c_trace.html#sqlitetracestmt">c3ref/c_trace.html#sqlitetracestmt</a></li><li>SQLITE_TRANSACTION - <a href="c3ref/c_alter_table.html">c3ref/c_alter_table.html</a></li><li>SQLITE_TRANSIENT - <a href="c3ref/c_static.html">c3ref/c_static.html</a></li><li>SQLITE_TRUSTED_SCHEMA - <a href="compile.html#trusted_schema">compile.html#trusted_schema</a></li><li>SQLITE_TXN_NONE - <a href="c3ref/c_txn_none.html#sqlitetxnnone">c3ref/c_txn_none.html#sqlitetxnnone</a></li><li>SQLITE_TXN_READ - <a href="c3ref/c_txn_none.html#sqlitetxnread">c3ref/c_txn_none.html#sqlitetxnread</a></li><li>SQLITE_TXN_WRITE - <a href="c3ref/c_txn_none.html#sqlitetxnwrite">c3ref/c_txn_none.html#sqlitetxnwrite</a></li><li>sqlite_uint64 - <a href="c3ref/int64.html">c3ref/int64.html</a></li><li>SQLITE_UNTESTABLE - <a href="compile.html#untestable">compile.html#untestable</a></li><li>SQLITE_UPDATE - <a href="c3ref/c_alter_table.html">c3ref/c_alter_table.html</a></li><li>SQLITE_USE_ALLOCA - <a href="compile.html#use_alloca">compile.html#use_alloca</a></li><li>SQLITE_USE_FCNTL_TRACE - <a href="compile.html#use_fcntl_trace">compile.html#use_fcntl_trace</a></li><li>SQLITE_USE_SEH - <a href="compile.html#use_seh">compile.html#use_seh</a></li><li>SQLITE_USE_URI - <a href="compile.html#use_uri">compile.html#use_uri</a></li><li>SQLITE_UTF8 - <a href="c3ref/c_any.html">c3ref/c_any.html</a></li><li>SQLITE_UTF16 - <a href="c3ref/c_any.html">c3ref/c_any.html</a></li><li>SQLITE_UTF16_ALIGNED - <a href="c3ref/c_any.html">c3ref/c_any.html</a></li><li>SQLITE_UTF16BE - <a href="c3ref/c_any.html">c3ref/c_any.html</a></li><li>SQLITE_UTF16LE - <a href="c3ref/c_any.html">c3ref/c_any.html</a></li><li>SQLITE_VERSION - <a href="c3ref/c_source_id.html">c3ref/c_source_id.html</a></li><li>sqlite_version - <a href="lang_corefunc.html#sqlite_version">lang_corefunc.html#sqlite_version</a></li><li>sqlite_version SQL function - <a href="lang_corefunc.html#sqlite_version">lang_corefunc.html#sqlite_version</a></li><li>SQLITE_VERSION_NUMBER - <a href="c3ref/c_source_id.html">c3ref/c_source_id.html</a></li><li>SQLITE_VTAB_CONSTRAINT_SUPPORT - <a href="c3ref/c_vtab_constraint_support.html#sqlitevtabconstraintsupport">c3ref/c_vtab_constraint_support.html#sqlitevtabconstraintsupport</a></li><li>SQLITE_VTAB_DIRECTONLY - <a href="c3ref/c_vtab_constraint_support.html#sqlitevtabdirectonly">c3ref/c_vtab_constraint_support.html#sqlitevtabdirectonly</a></li><li>SQLITE_VTAB_INNOCUOUS - <a href="c3ref/c_vtab_constraint_support.html#sqlitevtabinnocuous">c3ref/c_vtab_constraint_support.html#sqlitevtabinnocuous</a></li><li>SQLITE_VTAB_USES_ALL_SCHEMAS - <a href="c3ref/c_vtab_constraint_support.html#sqlitevtabusesallschemas">c3ref/c_vtab_constraint_support.html#sqlitevtabusesallschemas</a></li><li>SQLITE_WARNING - <a href="rescode.html#warning">rescode.html#warning</a></li><li>SQLITE_WARNING_AUTOINDEX - <a href="rescode.html#warning_autoindex">rescode.html#warning_autoindex</a></li><li>SQLITE_WIN32_DATA_DIRECTORY_TYPE - <a href="c3ref/c_win32_data_directory_type.html">c3ref/c_win32_data_directory_type.html</a></li><li>SQLITE_WIN32_HEAP_CREATE - <a href="compile.html#win32_heap_create">compile.html#win32_heap_create</a></li><li>SQLITE_WIN32_MALLOC - <a href="compile.html#win32_malloc">compile.html#win32_malloc</a></li><li>SQLITE_WIN32_MALLOC_VALIDATE - <a href="compile.html#win32_malloc_validate">compile.html#win32_malloc_validate</a></li><li>SQLITE_WIN32_TEMP_DIRECTORY_TYPE - <a href="c3ref/c_win32_data_directory_type.html">c3ref/c_win32_data_directory_type.html</a></li><li>SQLITE_ZERO_MALLOC - <a href="compile.html#zero_malloc">compile.html#zero_malloc</a></li><li>sqrt - <a href="lang_mathfunc.html#sqrt">lang_mathfunc.html#sqrt</a></li><li>sqrt SQL function - <a href="lang_mathfunc.html#sqrt">lang_mathfunc.html#sqrt</a></li><li>stale file descriptor - <a href="howtocorrupt.html#stalefd">howtocorrupt.html#stalefd</a></li><li>standard query parameters - <a href="uri.html#coreqp">uri.html#coreqp</a></li><li>statement journal - <a href="tempfiles.html#stmtjrnl">tempfiles.html#stmtjrnl</a></li><li>Statement journals - <a href="tempfiles.html#stmtjrnl">tempfiles.html#stmtjrnl</a></li><li>statement journals - <a href="tempfiles.html#stmtjrnl">tempfiles.html#stmtjrnl</a></li><li>static ANALYZE results - <a href="lang_analyze.html#statanal">lang_analyze.html#statanal</a></li><li>statically linked extensions - <a href="loadext.html#statext">loadext.html#statext</a></li><li>stats - <a href="pragma.html#pragma_stats">pragma.html#pragma_stats</a></li><li>stats pragma - <a href="pragma.html#pragma_stats">pragma.html#pragma_stats</a></li><li>status method - <a href="tclsqlite.html#status">tclsqlite.html#status</a></li><li>status parameters - <a href="c3ref/c_status_malloc_count.html">c3ref/c_status_malloc_count.html</a></li><li>storage class - <a href="datatype3.html#storageclasses">datatype3.html#storageclasses</a></li><li>strategies - <a href="queryplanner.html#searching">queryplanner.html#searching</a></li><li>strftime - <a href="lang_datefunc.html#strftm">lang_datefunc.html#strftm</a></li><li>strftime SQL function - <a href="lang_datefunc.html#strftm">lang_datefunc.html#strftm</a></li><li>STRICT - <a href="stricttables.html">stricttables.html</a></li><li>STRICT table - <a href="stricttables.html">stricttables.html</a></li><li>STRICT tables - <a href="stricttables.html">stricttables.html</a></li><li>strict type checking - <a href="stricttables.html">stricttables.html</a></li><li>string_agg - <a href="lang_aggfunc.html#group_concat">lang_aggfunc.html#group_concat</a></li><li>string_agg aggregate function - <a href="lang_aggfunc.html#group_concat">lang_aggfunc.html#group_concat</a></li><li>subprograms - <a href="opcode.html#subprog">opcode.html#subprog</a></li><li>Subqueries - <a href="lang_expr.html#subq">lang_expr.html#subq</a></li><li>subquery co-routines - <a href="optoverview.html#coroutines">optoverview.html#coroutines</a></li><li>subsec modifier - <a href="lang_datefunc.html#subsec">lang_datefunc.html#subsec</a></li><li>subsecond modifier - <a href="lang_datefunc.html#subsec">lang_datefunc.html#subsec</a></li><li>substr - <a href="lang_corefunc.html#substr">lang_corefunc.html#substr</a></li><li>substr SQL function - <a href="lang_corefunc.html#substr">lang_corefunc.html#substr</a></li><li>sum - <a href="lang_aggfunc.html#sumunc">lang_aggfunc.html#sumunc</a></li><li>sum aggregate function - <a href="lang_aggfunc.html#sumunc">lang_aggfunc.html#sumunc</a></li><li>sumFunc - <a href="lang_aggfunc.html#sumunc">lang_aggfunc.html#sumunc</a></li><li>super-journal - <a href="tempfiles.html#superjrnl">tempfiles.html#superjrnl</a></li><li>swarmvtab - <a href="swarmvtab.html#overview">swarmvtab.html#overview</a></li><li>swarmvtab context - <a href="swarmvtab.html#component_table_context_values">swarmvtab.html#component_table_context_values</a></li><li>synchronous - <a href="pragma.html#pragma_synchronous">pragma.html#pragma_synchronous</a></li><li>synchronous pragma - <a href="pragma.html#pragma_synchronous">pragma.html#pragma_synchronous</a></li><li>syntax diagrams - <a href="syntaxdiagrams.html">syntaxdiagrams.html</a></li><li>table b-tree - <a href="fileformat2.html#btypes">fileformat2.html#btypes</a></li><li>table data format - <a href="fileformat2.html##sqltab">fileformat2.html##sqltab</a></li><li>table-constraint - <a href="syntax/table-constraint.html">syntax/table-constraint.html</a></li><li>table-constraint syntax diagram - <a href="syntax/table-constraint.html">syntax/table-constraint.html</a></li><li>table-options - <a href="syntax/table-options.html">syntax/table-options.html</a></li><li>table-options syntax diagram - <a href="syntax/table-options.html">syntax/table-options.html</a></li><li>table-or-subquery - <a href="syntax/table-or-subquery.html">syntax/table-or-subquery.html</a></li><li>table-or-subquery syntax diagram - <a href="syntax/table-or-subquery.html">syntax/table-or-subquery.html</a></li><li>table-valued function - <a href="vtab.html#tabfunc2">vtab.html#tabfunc2</a></li><li>table-valued functions - <a href="vtab.html#tabfunc2">vtab.html#tabfunc2</a></li><li>table-valued functions in the FROM clause - <a href="lang_select.html#tabfunc1">lang_select.html#tabfunc1</a></li><li>table_info - <a href="pragma.html#pragma_table_info">pragma.html#pragma_table_info</a></li><li>table_info pragma - <a href="pragma.html#pragma_table_info">pragma.html#pragma_table_info</a></li><li>table_list - <a href="pragma.html#pragma_table_list">pragma.html#pragma_table_list</a></li><li>table_list pragma - <a href="pragma.html#pragma_table_list">pragma.html#pragma_table_list</a></li><li>table_xinfo - <a href="pragma.html#pragma_table_xinfo">pragma.html#pragma_table_xinfo</a></li><li>table_xinfo pragma - <a href="pragma.html#pragma_table_xinfo">pragma.html#pragma_table_xinfo</a></li><li>tables_used virtual table - <a href="bytecodevtab.html">bytecodevtab.html</a></li><li>tan - <a href="lang_mathfunc.html#tan">lang_mathfunc.html#tan</a></li><li>tan SQL function - <a href="lang_mathfunc.html#tan">lang_mathfunc.html#tan</a></li><li>tanh - <a href="lang_mathfunc.html#tanh">lang_mathfunc.html#tanh</a></li><li>tanh SQL function - <a href="lang_mathfunc.html#tanh">lang_mathfunc.html#tanh</a></li><li>Tcl extension - <a href="tclsqlite.html">tclsqlite.html</a></li><li>TCL Interface - <a href="tclsqlite.html">tclsqlite.html</a></li><li>TCL interface authorizer method - <a href="tclsqlite.html#authorizer">tclsqlite.html#authorizer</a></li><li>TCL interface backup method - <a href="tclsqlite.html#backup">tclsqlite.html#backup</a></li><li>TCL interface bind_fallback method - <a href="tclsqlite.html#bind_fallback">tclsqlite.html#bind_fallback</a></li><li>TCL interface busy method - <a href="tclsqlite.html#busy">tclsqlite.html#busy</a></li><li>TCL interface cache method - <a href="tclsqlite.html#cache">tclsqlite.html#cache</a></li><li>TCL interface changes method - <a href="tclsqlite.html#changes">tclsqlite.html#changes</a></li><li>TCL interface close method - <a href="tclsqlite.html#close">tclsqlite.html#close</a></li><li>TCL interface collate method - <a href="tclsqlite.html#collate">tclsqlite.html#collate</a></li><li>TCL interface collation_needed method - <a href="tclsqlite.html#collation_needed">tclsqlite.html#collation_needed</a></li><li>TCL interface commit_hook method - <a href="tclsqlite.html#commit_hook">tclsqlite.html#commit_hook</a></li><li>TCL interface complete method - <a href="tclsqlite.html#complete">tclsqlite.html#complete</a></li><li>TCL interface config method - <a href="tclsqlite.html#config">tclsqlite.html#config</a></li><li>TCL interface copy method - <a href="tclsqlite.html#copy">tclsqlite.html#copy</a></li><li>TCL interface deserialize method - <a href="tclsqlite.html#deserialize">tclsqlite.html#deserialize</a></li><li>TCL interface enable_load_extension method - <a href="tclsqlite.html#enable_load_extension">tclsqlite.html#enable_load_extension</a></li><li>TCL interface errorcode method - <a href="tclsqlite.html#errorcode">tclsqlite.html#errorcode</a></li><li>TCL interface eval method - <a href="tclsqlite.html#eval">tclsqlite.html#eval</a></li><li>TCL interface exists method - <a href="tclsqlite.html#exists">tclsqlite.html#exists</a></li><li>TCL interface function method - <a href="tclsqlite.html#function">tclsqlite.html#function</a></li><li>TCL interface incrblob method - <a href="tclsqlite.html#incrblob">tclsqlite.html#incrblob</a></li><li>TCL interface interrupt method - <a href="tclsqlite.html#interrupt">tclsqlite.html#interrupt</a></li><li>TCL interface last_insert_rowid method - <a href="tclsqlite.html#last_insert_rowid">tclsqlite.html#last_insert_rowid</a></li><li>TCL interface nullvalue method - <a href="tclsqlite.html#nullvalue">tclsqlite.html#nullvalue</a></li><li>TCL interface onecolumn method - <a href="tclsqlite.html#onecolumn">tclsqlite.html#onecolumn</a></li><li>TCL interface preupdate method - <a href="tclsqlite.html#preupdate">tclsqlite.html#preupdate</a></li><li>TCL interface profile method - <a href="tclsqlite.html#profile">tclsqlite.html#profile</a></li><li>TCL interface progress method - <a href="tclsqlite.html#progress">tclsqlite.html#progress</a></li><li>TCL interface restore method - <a href="tclsqlite.html#restore">tclsqlite.html#restore</a></li><li>TCL interface rollback_hook method - <a href="tclsqlite.html#rollback_hook">tclsqlite.html#rollback_hook</a></li><li>TCL interface serialize method - <a href="tclsqlite.html#serialize">tclsqlite.html#serialize</a></li><li>TCL interface status method - <a href="tclsqlite.html#status">tclsqlite.html#status</a></li><li>TCL interface timeout method - <a href="tclsqlite.html#timeout">tclsqlite.html#timeout</a></li><li>TCL interface total_changes method - <a href="tclsqlite.html#total_changes">tclsqlite.html#total_changes</a></li><li>TCL interface trace method - <a href="tclsqlite.html#trace">tclsqlite.html#trace</a></li><li>TCL interface trace_v2 method - <a href="tclsqlite.html#trace_v2">tclsqlite.html#trace_v2</a></li><li>TCL interface transaction method - <a href="tclsqlite.html#transaction">tclsqlite.html#transaction</a></li><li>TCL interface unlock_notify method - <a href="tclsqlite.html#unlock_notify">tclsqlite.html#unlock_notify</a></li><li>TCL interface update_hook method - <a href="tclsqlite.html#update_hook">tclsqlite.html#update_hook</a></li><li>TCL interface version method - <a href="tclsqlite.html#version">tclsqlite.html#version</a></li><li>TCL interface wal_hook method - <a href="tclsqlite.html#wal_hook">tclsqlite.html#wal_hook</a></li><li>TCL test suite - <a href="testing.html#tcl">testing.html#tcl</a></li><li>TCL variable substitution - <a href="tclsqlite.html#varsubst">tclsqlite.html#varsubst</a></li><li>TEA tarball - <a href="download.html">download.html</a></li><li>TEMP triggers on non-TEMP tables - <a href="lang_createtrigger.html#temptrig">lang_createtrigger.html#temptrig</a></li><li>temp_store - <a href="pragma.html#pragma_temp_store">pragma.html#pragma_temp_store</a></li><li>temp_store pragma - <a href="pragma.html#pragma_temp_store">pragma.html#pragma_temp_store</a></li><li>temp_store_directory - <a href="pragma.html#pragma_temp_store_directory">pragma.html#pragma_temp_store_directory</a></li><li>temp_store_directory pragma - <a href="pragma.html#pragma_temp_store_directory">pragma.html#pragma_temp_store_directory</a></li><li>temporary databases - <a href="inmemorydb.html#temp_db">inmemorydb.html#temp_db</a></li><li>temporary directory search algorithm - <a href="tempfiles.html#tempdir">tempfiles.html#tempdir</a></li><li>temporary disk files - <a href="tempfiles.html">tempfiles.html</a></li><li>temporary tables - <a href="inmemorydb.html#temp_db">inmemorydb.html#temp_db</a></li><li>tempstore - <a href="tempfiles.html#tempstore">tempfiles.html#tempstore</a></li><li>test coverage - <a href="testing.html#coverage">testing.html#coverage</a></li><li>test harness - <a href="testing.html#harnesses">testing.html#harnesses</a></li><li>test suite - <a href="testing.html">testing.html</a></li><li>testcase macros - <a href="testing.html#testcase">testing.html#testcase</a></li><li>tested - <a href="testing.html">testing.html</a></li><li>testing - <a href="testing.html">testing.html</a></li><li>text encoding - <a href="fileformat2.html#enc">fileformat2.html#enc</a></li><li>TH3 - <a href="th3.html">th3.html</a></li><li>the - and - operators - <a href="json1.html#jptr">json1.html#jptr</a></li><li>the - operator - <a href="json1.html#jptr">json1.html#jptr</a></li><li>the .fullschema dot-command - <a href="cli.html#fullschema">cli.html#fullschema</a></li><li>the amalgamation - <a href="amalgamation.html">amalgamation.html</a></li><li>the ext3 barrier problem - <a href="lockingv3.html#ext3-barrier-problem">lockingv3.html#ext3-barrier-problem</a></li><li>The Fossil NGQP Upgrade Case Study - <a href="queryplanner-ng.html#fossilcasestudy">queryplanner-ng.html#fossilcasestudy</a></li><li>the json1 extension - <a href="json1.html">json1.html</a></li><li>the SQLITE_DBPAGE extension - <a href="dbpage.html">dbpage.html</a></li><li>the SQLITE_MEMSTAT extension - <a href="memstat.html">memstat.html</a></li><li>the SQLITE_STMT extension - <a href="stmt.html">stmt.html</a></li><li>The Use Of assert In SQLite - <a href="assert.html">assert.html</a></li><li>the xCachesize page cache method - <a href="c3ref/pcache_methods2.html#thexcachesizepagecachemethod">c3ref/pcache_methods2.html#thexcachesizepagecachemethod</a></li><li>the xCreate page cache methods - <a href="c3ref/pcache_methods2.html#thexcreatepagecachemethods">c3ref/pcache_methods2.html#thexcreatepagecachemethods</a></li><li>the xDestroy page cache method - <a href="c3ref/pcache_methods2.html#thexdestroypagecachemethod">c3ref/pcache_methods2.html#thexdestroypagecachemethod</a></li><li>the xFetch page cache methods - <a href="c3ref/pcache_methods2.html#thexfetchpagecachemethods">c3ref/pcache_methods2.html#thexfetchpagecachemethods</a></li><li>the xInit page cache method - <a href="c3ref/pcache_methods2.html#thexinitpagecachemethod">c3ref/pcache_methods2.html#thexinitpagecachemethod</a></li><li>the xPagecount page cache methods - <a href="c3ref/pcache_methods2.html#thexpagecountpagecachemethods">c3ref/pcache_methods2.html#thexpagecountpagecachemethods</a></li><li>the xRekey page cache methods - <a href="c3ref/pcache_methods2.html#thexrekeypagecachemethods">c3ref/pcache_methods2.html#thexrekeypagecachemethods</a></li><li>the xShrink page cache method - <a href="c3ref/pcache_methods2.html#thexshrinkpagecachemethod">c3ref/pcache_methods2.html#thexshrinkpagecachemethod</a></li><li>the xShutdown page cache method - <a href="c3ref/pcache_methods2.html#thexshutdownpagecachemethod">c3ref/pcache_methods2.html#thexshutdownpagecachemethod</a></li><li>the xUnpin page cache method - <a href="c3ref/pcache_methods2.html#thexunpinpagecachemethod">c3ref/pcache_methods2.html#thexunpinpagecachemethod</a></li><li>Things That Can Go Wrong - <a href="atomiccommit.html#sect_9_0">atomiccommit.html#sect_9_0</a></li><li>threading mode - <a href="threadsafe.html">threadsafe.html</a></li><li>threads - <a href="pragma.html#pragma_threads">pragma.html#pragma_threads</a></li><li>threads pragma - <a href="pragma.html#pragma_threads">pragma.html#pragma_threads</a></li><li>three test harnesses - <a href="testing.html#harnesses">testing.html#harnesses</a></li><li>time - <a href="lang_datefunc.html#dttm">lang_datefunc.html#dttm</a></li><li>time shift modifiers - <a href="lang_datefunc.html#tmshf">lang_datefunc.html#tmshf</a></li><li>time SQL function - <a href="lang_datefunc.html#dttm">lang_datefunc.html#dttm</a></li><li>time value - <a href="lang_datefunc.html#tmval">lang_datefunc.html#tmval</a></li><li>time values - <a href="lang_datefunc.html#tmval">lang_datefunc.html#tmval</a></li><li>time-value - <a href="lang_datefunc.html#tmval">lang_datefunc.html#tmval</a></li><li>time-values - <a href="lang_datefunc.html#tmval">lang_datefunc.html#tmval</a></li><li>timediff - <a href="lang_datefunc.html#tmdif">lang_datefunc.html#tmdif</a></li><li>timediff SQL function - <a href="lang_datefunc.html#tmdif">lang_datefunc.html#tmdif</a></li><li>timeout method - <a href="tclsqlite.html#timeout">tclsqlite.html#timeout</a></li><li>tokenizer - <a href="fts3.html#tokenizer">fts3.html#tokenizer</a></li><li>torn page - <a href="psow.html#tornpage">psow.html#tornpage</a></li><li>total - <a href="lang_aggfunc.html#sumunc">lang_aggfunc.html#sumunc</a></li><li>total aggregate function - <a href="lang_aggfunc.html#sumunc">lang_aggfunc.html#sumunc</a></li><li>total_changes - <a href="lang_corefunc.html#total_changes">lang_corefunc.html#total_changes</a></li><li>total_changes method - <a href="tclsqlite.html#total_changes">tclsqlite.html#total_changes</a></li><li>total_changes SQL function - <a href="lang_corefunc.html#total_changes">lang_corefunc.html#total_changes</a></li><li>trace method - <a href="tclsqlite.html#trace">tclsqlite.html#trace</a></li><li>trace_v2 method - <a href="tclsqlite.html#trace_v2">tclsqlite.html#trace_v2</a></li><li>transaction - <a href="lang_transaction.html">lang_transaction.html</a></li><li>transaction method - <a href="tclsqlite.html#transaction">tclsqlite.html#transaction</a></li><li>transaction state - <a href="c3ref/c_txn_none.html">c3ref/c_txn_none.html</a></li><li>transactional - <a href="transactional.html">transactional.html</a></li><li>treats the CROSS JOIN operator specially - <a href="lang_select.html#crossjoin">lang_select.html#crossjoin</a></li><li>trigger - <a href="lang_createtrigger.html">lang_createtrigger.html</a></li><li>triggers - <a href="lang_createtrigger.html">lang_createtrigger.html</a></li><li>trigram indexes - <a href="fts5.html#trigramidx">fts5.html#trigramidx</a></li><li>trigram tokenizer - <a href="fts5.html#trigramidx">fts5.html#trigramidx</a></li><li>trim - <a href="lang_corefunc.html#trim">lang_corefunc.html#trim</a></li><li>trim SQL function - <a href="lang_corefunc.html#trim">lang_corefunc.html#trim</a></li><li>trunc - <a href="lang_mathfunc.html#trunc">lang_mathfunc.html#trunc</a></li><li>trunc SQL function - <a href="lang_mathfunc.html#trunc">lang_mathfunc.html#trunc</a></li><li>truncate optimization - <a href="lang_delete.html#truncateopt">lang_delete.html#truncateopt</a></li><li>trusted_schema - <a href="pragma.html#pragma_trusted_schema">pragma.html#pragma_trusted_schema</a></li><li>trusted_schema pragma - <a href="pragma.html#pragma_trusted_schema">pragma.html#pragma_trusted_schema</a></li><li>type affinity - <a href="datatype3.html#affinity">datatype3.html#affinity</a></li><li>type-name - <a href="syntax/type-name.html">syntax/type-name.html</a></li><li>type-name syntax diagram - <a href="syntax/type-name.html">syntax/type-name.html</a></li><li>typeof - <a href="lang_corefunc.html#typeof">lang_corefunc.html#typeof</a></li><li>typeof SQL function - <a href="lang_corefunc.html#typeof">lang_corefunc.html#typeof</a></li><li>UINT - <a href="uintcseq.html">uintcseq.html</a></li><li>UINT collating sequence - <a href="uintcseq.html">uintcseq.html</a></li><li>undefined BEFORE trigger behavior - <a href="lang_createtrigger.html#undef_before">lang_createtrigger.html#undef_before</a></li><li>undo/redo - <a href="undoredo.html">undoredo.html</a></li><li>undoredo - <a href="undoredo.html">undoredo.html</a></li><li>unhex - <a href="lang_corefunc.html#unhex">lang_corefunc.html#unhex</a></li><li>unhex SQL function - <a href="lang_corefunc.html#unhex">lang_corefunc.html#unhex</a></li><li>unicode - <a href="lang_corefunc.html#unicode">lang_corefunc.html#unicode</a></li><li>unicode SQL function - <a href="lang_corefunc.html#unicode">lang_corefunc.html#unicode</a></li><li>unicode61 - <a href="fts3.html#unicode61">fts3.html#unicode61</a></li><li>Uniform Resource Identifier - <a href="uri.html">uri.html</a></li><li>unindexed - <a href="fts5.html#the_unindexed_column_option">fts5.html#the_unindexed_column_option</a></li><li>UNION virtual table - <a href="unionvtab.html">unionvtab.html</a></li><li>union-vtab - <a href="unionvtab.html">unionvtab.html</a></li><li>unionvtab - <a href="unionvtab.html">unionvtab.html</a></li><li>UNIQUE - <a href="lang_createtable.html#uniqueconst">lang_createtable.html#uniqueconst</a></li><li>UNIQUE constraint - <a href="lang_createtable.html#uniqueconst">lang_createtable.html#uniqueconst</a></li><li>unique constraint - <a href="lang_createtable.html#uniqueconst">lang_createtable.html#uniqueconst</a></li><li>UNIQUE constraints - <a href="lang_createtable.html#uniqueconst">lang_createtable.html#uniqueconst</a></li><li>unique index - <a href="lang_createindex.html#uniqueidx">lang_createindex.html#uniqueidx</a></li><li>unixepoch - <a href="lang_datefunc.html#uepch">lang_datefunc.html#uepch</a></li><li>unixepoch function - <a href="lang_datefunc.html#uepch">lang_datefunc.html#uepch</a></li><li>unixepoch modifier - <a href="lang_datefunc.html#jdmod">lang_datefunc.html#jdmod</a></li><li>unixepoch SQL function - <a href="lang_datefunc.html#uepch">lang_datefunc.html#uepch</a></li><li>unlikely - <a href="lang_corefunc.html#unlikely">lang_corefunc.html#unlikely</a></li><li>unlikely SQL function - <a href="lang_corefunc.html#unlikely">lang_corefunc.html#unlikely</a></li><li>unlink corruption - <a href="howtocorrupt.html#unlink">howtocorrupt.html#unlink</a></li><li>unlinked database files - <a href="howtocorrupt.html#unlink">howtocorrupt.html#unlink</a></li><li>unlock_notify method - <a href="tclsqlite.html#unlock_notify">tclsqlite.html#unlock_notify</a></li><li>unprotected sqlite3_value - <a href="c3ref/value.html">c3ref/value.html</a></li><li>unsafe-testing command-line option - <a href="cli.html#testing_mode">cli.html#testing_mode</a></li><li>untrusted database files - <a href="security.html#baddb">security.html#baddb</a></li><li>UPDATE - <a href="lang_update.html">lang_update.html</a></li><li>UPDATE FROM - <a href="lang_update.html#upfrom">lang_update.html#upfrom</a></li><li>UPDATE trigger - <a href="lang_createtrigger.html">lang_createtrigger.html</a></li><li>update-stmt - <a href="syntax/update-stmt.html">syntax/update-stmt.html</a></li><li>update-stmt syntax diagram - <a href="syntax/update-stmt.html">syntax/update-stmt.html</a></li><li>update-stmt-limited - <a href="syntax/update-stmt-limited.html">syntax/update-stmt-limited.html</a></li><li>update-stmt-limited syntax diagram - <a href="syntax/update-stmt-limited.html">syntax/update-stmt-limited.html</a></li><li>update_hook method - <a href="tclsqlite.html#update_hook">tclsqlite.html#update_hook</a></li><li>UPDATEs - <a href="lang_update.html">lang_update.html</a></li><li>upluscontrol - <a href="optoverview.html#uplus">optoverview.html#uplus</a></li><li>upper - <a href="lang_corefunc.html#upper">lang_corefunc.html#upper</a></li><li>upper SQL function - <a href="lang_corefunc.html#upper">lang_corefunc.html#upper</a></li><li>UPSERT - <a href="lang_upsert.html">lang_upsert.html</a></li><li>upsert - <a href="lang_upsert.html">lang_upsert.html</a></li><li>upsert clause - <a href="lang_upsert.html">lang_upsert.html</a></li><li>UPSERT parsing ambiguity - <a href="lang_upsert.html#parseambig">lang_upsert.html#parseambig</a></li><li>upsert-clause - <a href="syntax/upsert-clause.html">syntax/upsert-clause.html</a></li><li>upsert-clause syntax diagram - <a href="syntax/upsert-clause.html">syntax/upsert-clause.html</a></li><li>URI - <a href="uri.html">uri.html</a></li><li>URI filename - <a href="uri.html">uri.html</a></li><li>URI filename examples - <a href="c3ref/open.html#urifilenameexamples">c3ref/open.html#urifilenameexamples</a></li><li>URI filenames - <a href="uri.html">uri.html</a></li><li>URI filenames in sqlite3_open - <a href="c3ref/open.html#urifilenamesinsqlite3open">c3ref/open.html#urifilenamesinsqlite3open</a></li><li>URI query parameters - <a href="uri.html#coreqp">uri.html#coreqp</a></li><li>usable size - <a href="fileformat2.html#usable_size">fileformat2.html#usable_size</a></li><li>use of shared cache mode is discouraged - <a href="sharedcache.html#dontuse">sharedcache.html#dontuse</a></li><li>user-defined window functions - <a href="windowfunctions.html#udfwinfunc">windowfunctions.html#udfwinfunc</a></li><li>user_version - <a href="pragma.html#pragma_user_version">pragma.html#pragma_user_version</a></li><li>user_version pragma - <a href="pragma.html#pragma_user_version">pragma.html#pragma_user_version</a></li><li>using SQLite for websites - <a href="whentouse.html#website">whentouse.html#website</a></li><li>Using the SQLite Online Backup API - <a href="backup.html">backup.html</a></li><li>Using the SQLite Unlock Notification Feature - <a href="unlock_notify.html">unlock_notify.html</a></li><li>utc and localtime modifiers - <a href="lang_datefunc.html#localtime">lang_datefunc.html#localtime</a></li><li>utc modifier - <a href="lang_datefunc.html#localtime">lang_datefunc.html#localtime</a></li><li>VACUUM - <a href="lang_vacuum.html">lang_vacuum.html</a></li><li>vacuum - <a href="lang_vacuum.html">lang_vacuum.html</a></li><li>VACUUM INTO - <a href="lang_vacuum.html#vacuuminto">lang_vacuum.html#vacuuminto</a></li><li>vacuum-stmt - <a href="syntax/vacuum-stmt.html">syntax/vacuum-stmt.html</a></li><li>vacuum-stmt syntax diagram - <a href="syntax/vacuum-stmt.html">syntax/vacuum-stmt.html</a></li><li>value argument - <a href="json1.html#varg">json1.html#varg</a></li><li>VALUES - <a href="lang_select.html#values">lang_select.html#values</a></li><li>VALUES clause - <a href="lang_select.html#values">lang_select.html#values</a></li><li>variable-length integer - <a href="fileformat2.html#varint">fileformat2.html#varint</a></li><li>varint - <a href="fileformat2.html#varint">fileformat2.html#varint</a></li><li>VDBE - <a href="opcode.html">opcode.html</a></li><li>vdbe_addoptrace - <a href="pragma.html#pragma_vdbe_addoptrace">pragma.html#pragma_vdbe_addoptrace</a></li><li>vdbe_addoptrace pragma - <a href="pragma.html#pragma_vdbe_addoptrace">pragma.html#pragma_vdbe_addoptrace</a></li><li>vdbe_debug - <a href="pragma.html#pragma_vdbe_debug">pragma.html#pragma_vdbe_debug</a></li><li>vdbe_debug pragma - <a href="pragma.html#pragma_vdbe_debug">pragma.html#pragma_vdbe_debug</a></li><li>vdbe_listing - <a href="pragma.html#pragma_vdbe_listing">pragma.html#pragma_vdbe_listing</a></li><li>vdbe_listing pragma - <a href="pragma.html#pragma_vdbe_listing">pragma.html#pragma_vdbe_listing</a></li><li>vdbe_trace - <a href="pragma.html#pragma_vdbe_trace">pragma.html#pragma_vdbe_trace</a></li><li>vdbe_trace pragma - <a href="pragma.html#pragma_vdbe_trace">pragma.html#pragma_vdbe_trace</a></li><li>vectors - <a href="rowvalue.html">rowvalue.html</a></li><li>Version 3.0.0 - <a href="releaselog/3_0_0.html">releaselog/3_0_0.html</a></li><li>version 3.0.0 - <a href="releaselog/3_0_0.html">releaselog/3_0_0.html</a></li><li>Version 3.0.1 - <a href="releaselog/3_0_1.html">releaselog/3_0_1.html</a></li><li>version 3.0.1 - <a href="releaselog/3_0_1.html">releaselog/3_0_1.html</a></li><li>Version 3.0.2 - <a href="releaselog/3_0_2.html">releaselog/3_0_2.html</a></li><li>version 3.0.2 - <a href="releaselog/3_0_2.html">releaselog/3_0_2.html</a></li><li>Version 3.0.3 - <a href="releaselog/3_0_3.html">releaselog/3_0_3.html</a></li><li>version 3.0.3 - <a href="releaselog/3_0_3.html">releaselog/3_0_3.html</a></li><li>Version 3.0.4 - <a href="releaselog/3_0_4.html">releaselog/3_0_4.html</a></li><li>version 3.0.4 - <a href="releaselog/3_0_4.html">releaselog/3_0_4.html</a></li><li>Version 3.0.5 - <a href="releaselog/3_0_5.html">releaselog/3_0_5.html</a></li><li>version 3.0.5 - <a href="releaselog/3_0_5.html">releaselog/3_0_5.html</a></li><li>Version 3.0.6 - <a href="releaselog/3_0_6.html">releaselog/3_0_6.html</a></li><li>version 3.0.6 - <a href="releaselog/3_0_6.html">releaselog/3_0_6.html</a></li><li>Version 3.0.7 - <a href="releaselog/3_0_7.html">releaselog/3_0_7.html</a></li><li>version 3.0.7 - <a href="releaselog/3_0_7.html">releaselog/3_0_7.html</a></li><li>Version 3.0.8 - <a href="releaselog/3_0_8.html">releaselog/3_0_8.html</a></li><li>version 3.0.8 - <a href="releaselog/3_0_8.html">releaselog/3_0_8.html</a></li><li>Version 3.1.0 - <a href="releaselog/3_1_0.html">releaselog/3_1_0.html</a></li><li>version 3.1.0 - <a href="releaselog/3_1_0.html">releaselog/3_1_0.html</a></li><li>Version 3.1.1 - <a href="releaselog/3_1_1.html">releaselog/3_1_1.html</a></li><li>version 3.1.1 - <a href="releaselog/3_1_1.html">releaselog/3_1_1.html</a></li><li>Version 3.1.2 - <a href="releaselog/3_1_2.html">releaselog/3_1_2.html</a></li><li>version 3.1.2 - <a href="releaselog/3_1_2.html">releaselog/3_1_2.html</a></li><li>Version 3.1.3 - <a href="releaselog/3_1_3.html">releaselog/3_1_3.html</a></li><li>version 3.1.3 - <a href="releaselog/3_1_3.html">releaselog/3_1_3.html</a></li><li>Version 3.1.4 - <a href="releaselog/3_1_4.html">releaselog/3_1_4.html</a></li><li>version 3.1.4 - <a href="releaselog/3_1_4.html">releaselog/3_1_4.html</a></li><li>Version 3.1.5 - <a href="releaselog/3_1_5.html">releaselog/3_1_5.html</a></li><li>version 3.1.5 - <a href="releaselog/3_1_5.html">releaselog/3_1_5.html</a></li><li>Version 3.1.6 - <a href="releaselog/3_1_6.html">releaselog/3_1_6.html</a></li><li>version 3.1.6 - <a href="releaselog/3_1_6.html">releaselog/3_1_6.html</a></li><li>Version 3.2.0 - <a href="releaselog/3_2_0.html">releaselog/3_2_0.html</a></li><li>version 3.2.0 - <a href="releaselog/3_2_0.html">releaselog/3_2_0.html</a></li><li>Version 3.2.1 - <a href="releaselog/3_2_1.html">releaselog/3_2_1.html</a></li><li>version 3.2.1 - <a href="releaselog/3_2_1.html">releaselog/3_2_1.html</a></li><li>Version 3.2.2 - <a href="releaselog/3_2_2.html">releaselog/3_2_2.html</a></li><li>version 3.2.2 - <a href="releaselog/3_2_2.html">releaselog/3_2_2.html</a></li><li>Version 3.2.3 - <a href="releaselog/3_2_3.html">releaselog/3_2_3.html</a></li><li>version 3.2.3 - <a href="releaselog/3_2_3.html">releaselog/3_2_3.html</a></li><li>Version 3.2.4 - <a href="releaselog/3_2_4.html">releaselog/3_2_4.html</a></li><li>version 3.2.4 - <a href="releaselog/3_2_4.html">releaselog/3_2_4.html</a></li><li>Version 3.2.5 - <a href="releaselog/3_2_5.html">releaselog/3_2_5.html</a></li><li>version 3.2.5 - <a href="releaselog/3_2_5.html">releaselog/3_2_5.html</a></li><li>Version 3.2.6 - <a href="releaselog/3_2_6.html">releaselog/3_2_6.html</a></li><li>version 3.2.6 - <a href="releaselog/3_2_6.html">releaselog/3_2_6.html</a></li><li>Version 3.2.7 - <a href="releaselog/3_2_7.html">releaselog/3_2_7.html</a></li><li>version 3.2.7 - <a href="releaselog/3_2_7.html">releaselog/3_2_7.html</a></li><li>Version 3.2.8 - <a href="releaselog/3_2_8.html">releaselog/3_2_8.html</a></li><li>version 3.2.8 - <a href="releaselog/3_2_8.html">releaselog/3_2_8.html</a></li><li>Version 3.3.0 - <a href="releaselog/3_3_0.html">releaselog/3_3_0.html</a></li><li>version 3.3.0 - <a href="releaselog/3_3_0.html">releaselog/3_3_0.html</a></li><li>Version 3.3.0.0 - <a href="releaselog/3_3_0.html">releaselog/3_3_0.html</a></li><li>version 3.3.0.0 - <a href="releaselog/3_3_0.html">releaselog/3_3_0.html</a></li><li>Version 3.3.1 - <a href="releaselog/3_3_1.html">releaselog/3_3_1.html</a></li><li>version 3.3.1 - <a href="releaselog/3_3_1.html">releaselog/3_3_1.html</a></li><li>Version 3.3.1.0 - <a href="releaselog/3_3_1.html">releaselog/3_3_1.html</a></li><li>version 3.3.1.0 - <a href="releaselog/3_3_1.html">releaselog/3_3_1.html</a></li><li>Version 3.3.2 - <a href="releaselog/3_3_2.html">releaselog/3_3_2.html</a></li><li>version 3.3.2 - <a href="releaselog/3_3_2.html">releaselog/3_3_2.html</a></li><li>Version 3.3.2.0 - <a href="releaselog/3_3_2.html">releaselog/3_3_2.html</a></li><li>version 3.3.2.0 - <a href="releaselog/3_3_2.html">releaselog/3_3_2.html</a></li><li>Version 3.3.3 - <a href="releaselog/3_3_3.html">releaselog/3_3_3.html</a></li><li>version 3.3.3 - <a href="releaselog/3_3_3.html">releaselog/3_3_3.html</a></li><li>Version 3.3.3.0 - <a href="releaselog/3_3_3.html">releaselog/3_3_3.html</a></li><li>version 3.3.3.0 - <a href="releaselog/3_3_3.html">releaselog/3_3_3.html</a></li><li>Version 3.3.4 - <a href="releaselog/3_3_4.html">releaselog/3_3_4.html</a></li><li>version 3.3.4 - <a href="releaselog/3_3_4.html">releaselog/3_3_4.html</a></li><li>Version 3.3.4.0 - <a href="releaselog/3_3_4.html">releaselog/3_3_4.html</a></li><li>version 3.3.4.0 - <a href="releaselog/3_3_4.html">releaselog/3_3_4.html</a></li><li>Version 3.3.5 - <a href="releaselog/3_3_5.html">releaselog/3_3_5.html</a></li><li>version 3.3.5 - <a href="releaselog/3_3_5.html">releaselog/3_3_5.html</a></li><li>Version 3.3.5.0 - <a href="releaselog/3_3_5.html">releaselog/3_3_5.html</a></li><li>version 3.3.5.0 - <a href="releaselog/3_3_5.html">releaselog/3_3_5.html</a></li><li>Version 3.3.6 - <a href="releaselog/3_3_6.html">releaselog/3_3_6.html</a></li><li>version 3.3.6 - <a href="releaselog/3_3_6.html">releaselog/3_3_6.html</a></li><li>Version 3.3.6.0 - <a href="releaselog/3_3_6.html">releaselog/3_3_6.html</a></li><li>version 3.3.6.0 - <a href="releaselog/3_3_6.html">releaselog/3_3_6.html</a></li><li>Version 3.3.7 - <a href="releaselog/3_3_7.html">releaselog/3_3_7.html</a></li><li>version 3.3.7 - <a href="releaselog/3_3_7.html">releaselog/3_3_7.html</a></li><li>Version 3.3.7.0 - <a href="releaselog/3_3_7.html">releaselog/3_3_7.html</a></li><li>version 3.3.7.0 - <a href="releaselog/3_3_7.html">releaselog/3_3_7.html</a></li><li>Version 3.3.8 - <a href="releaselog/3_3_8.html">releaselog/3_3_8.html</a></li><li>version 3.3.8 - <a href="releaselog/3_3_8.html">releaselog/3_3_8.html</a></li><li>Version 3.3.8.0 - <a href="releaselog/3_3_8.html">releaselog/3_3_8.html</a></li><li>version 3.3.8.0 - <a href="releaselog/3_3_8.html">releaselog/3_3_8.html</a></li><li>Version 3.3.9 - <a href="releaselog/3_3_9.html">releaselog/3_3_9.html</a></li><li>version 3.3.9 - <a href="releaselog/3_3_9.html">releaselog/3_3_9.html</a></li><li>Version 3.3.9.0 - <a href="releaselog/3_3_9.html">releaselog/3_3_9.html</a></li><li>version 3.3.9.0 - <a href="releaselog/3_3_9.html">releaselog/3_3_9.html</a></li><li>Version 3.3.10 - <a href="releaselog/3_3_10.html">releaselog/3_3_10.html</a></li><li>version 3.3.10 - <a href="releaselog/3_3_10.html">releaselog/3_3_10.html</a></li><li>Version 3.3.10.0 - <a href="releaselog/3_3_10.html">releaselog/3_3_10.html</a></li><li>version 3.3.10.0 - <a href="releaselog/3_3_10.html">releaselog/3_3_10.html</a></li><li>Version 3.3.11 - <a href="releaselog/3_3_11.html">releaselog/3_3_11.html</a></li><li>version 3.3.11 - <a href="releaselog/3_3_11.html">releaselog/3_3_11.html</a></li><li>Version 3.3.11.0 - <a href="releaselog/3_3_11.html">releaselog/3_3_11.html</a></li><li>version 3.3.11.0 - <a href="releaselog/3_3_11.html">releaselog/3_3_11.html</a></li><li>Version 3.3.12 - <a href="releaselog/3_3_12.html">releaselog/3_3_12.html</a></li><li>version 3.3.12 - <a href="releaselog/3_3_12.html">releaselog/3_3_12.html</a></li><li>Version 3.3.12.0 - <a href="releaselog/3_3_12.html">releaselog/3_3_12.html</a></li><li>version 3.3.12.0 - <a href="releaselog/3_3_12.html">releaselog/3_3_12.html</a></li><li>Version 3.3.13 - <a href="releaselog/3_3_13.html">releaselog/3_3_13.html</a></li><li>version 3.3.13 - <a href="releaselog/3_3_13.html">releaselog/3_3_13.html</a></li><li>Version 3.3.13.0 - <a href="releaselog/3_3_13.html">releaselog/3_3_13.html</a></li><li>version 3.3.13.0 - <a href="releaselog/3_3_13.html">releaselog/3_3_13.html</a></li><li>Version 3.3.14 - <a href="releaselog/3_3_14.html">releaselog/3_3_14.html</a></li><li>version 3.3.14 - <a href="releaselog/3_3_14.html">releaselog/3_3_14.html</a></li><li>Version 3.3.14.0 - <a href="releaselog/3_3_14.html">releaselog/3_3_14.html</a></li><li>version 3.3.14.0 - <a href="releaselog/3_3_14.html">releaselog/3_3_14.html</a></li><li>Version 3.3.15 - <a href="releaselog/3_3_15.html">releaselog/3_3_15.html</a></li><li>version 3.3.15 - <a href="releaselog/3_3_15.html">releaselog/3_3_15.html</a></li><li>Version 3.3.15.0 - <a href="releaselog/3_3_15.html">releaselog/3_3_15.html</a></li><li>version 3.3.15.0 - <a href="releaselog/3_3_15.html">releaselog/3_3_15.html</a></li><li>Version 3.3.16 - <a href="releaselog/3_3_16.html">releaselog/3_3_16.html</a></li><li>version 3.3.16 - <a href="releaselog/3_3_16.html">releaselog/3_3_16.html</a></li><li>Version 3.3.16.0 - <a href="releaselog/3_3_16.html">releaselog/3_3_16.html</a></li><li>version 3.3.16.0 - <a href="releaselog/3_3_16.html">releaselog/3_3_16.html</a></li><li>Version 3.3.17 - <a href="releaselog/3_3_17.html">releaselog/3_3_17.html</a></li><li>version 3.3.17 - <a href="releaselog/3_3_17.html">releaselog/3_3_17.html</a></li><li>Version 3.3.17.0 - <a href="releaselog/3_3_17.html">releaselog/3_3_17.html</a></li><li>version 3.3.17.0 - <a href="releaselog/3_3_17.html">releaselog/3_3_17.html</a></li><li>Version 3.4.0 - <a href="releaselog/3_4_0.html">releaselog/3_4_0.html</a></li><li>version 3.4.0 - <a href="releaselog/3_4_0.html">releaselog/3_4_0.html</a></li><li>Version 3.4.1 - <a href="releaselog/3_4_1.html">releaselog/3_4_1.html</a></li><li>version 3.4.1 - <a href="releaselog/3_4_1.html">releaselog/3_4_1.html</a></li><li>Version 3.4.2 - <a href="releaselog/3_4_2.html">releaselog/3_4_2.html</a></li><li>version 3.4.2 - <a href="releaselog/3_4_2.html">releaselog/3_4_2.html</a></li><li>Version 3.5.0 - <a href="releaselog/3_5_0.html">releaselog/3_5_0.html</a></li><li>version 3.5.0 - <a href="releaselog/3_5_0.html">releaselog/3_5_0.html</a></li><li>Version 3.5.1 - <a href="releaselog/3_5_1.html">releaselog/3_5_1.html</a></li><li>version 3.5.1 - <a href="releaselog/3_5_1.html">releaselog/3_5_1.html</a></li><li>Version 3.5.2 - <a href="releaselog/3_5_2.html">releaselog/3_5_2.html</a></li><li>version 3.5.2 - <a href="releaselog/3_5_2.html">releaselog/3_5_2.html</a></li><li>Version 3.5.3 - <a href="releaselog/3_5_3.html">releaselog/3_5_3.html</a></li><li>version 3.5.3 - <a href="releaselog/3_5_3.html">releaselog/3_5_3.html</a></li><li>Version 3.5.4 - <a href="releaselog/3_5_4.html">releaselog/3_5_4.html</a></li><li>version 3.5.4 - <a href="releaselog/3_5_4.html">releaselog/3_5_4.html</a></li><li>Version 3.5.5 - <a href="releaselog/3_5_5.html">releaselog/3_5_5.html</a></li><li>version 3.5.5 - <a href="releaselog/3_5_5.html">releaselog/3_5_5.html</a></li><li>Version 3.5.6 - <a href="releaselog/3_5_6.html">releaselog/3_5_6.html</a></li><li>version 3.5.6 - <a href="releaselog/3_5_6.html">releaselog/3_5_6.html</a></li><li>Version 3.5.7 - <a href="releaselog/3_5_7.html">releaselog/3_5_7.html</a></li><li>version 3.5.7 - <a href="releaselog/3_5_7.html">releaselog/3_5_7.html</a></li><li>Version 3.5.8 - <a href="releaselog/3_5_8.html">releaselog/3_5_8.html</a></li><li>version 3.5.8 - <a href="releaselog/3_5_8.html">releaselog/3_5_8.html</a></li><li>Version 3.5.9 - <a href="releaselog/3_5_9.html">releaselog/3_5_9.html</a></li><li>version 3.5.9 - <a href="releaselog/3_5_9.html">releaselog/3_5_9.html</a></li><li>Version 3.6.0 - <a href="releaselog/3_6_0.html">releaselog/3_6_0.html</a></li><li>version 3.6.0 - <a href="releaselog/3_6_0.html">releaselog/3_6_0.html</a></li><li>Version 3.6.1 - <a href="releaselog/3_6_1.html">releaselog/3_6_1.html</a></li><li>version 3.6.1 - <a href="releaselog/3_6_1.html">releaselog/3_6_1.html</a></li><li>Version 3.6.2 - <a href="releaselog/3_6_2.html">releaselog/3_6_2.html</a></li><li>version 3.6.2 - <a href="releaselog/3_6_2.html">releaselog/3_6_2.html</a></li><li>Version 3.6.3 - <a href="releaselog/3_6_3.html">releaselog/3_6_3.html</a></li><li>version 3.6.3 - <a href="releaselog/3_6_3.html">releaselog/3_6_3.html</a></li><li>Version 3.6.4 - <a href="releaselog/3_6_4.html">releaselog/3_6_4.html</a></li><li>version 3.6.4 - <a href="releaselog/3_6_4.html">releaselog/3_6_4.html</a></li><li>Version 3.6.5 - <a href="releaselog/3_6_5.html">releaselog/3_6_5.html</a></li><li>version 3.6.5 - <a href="releaselog/3_6_5.html">releaselog/3_6_5.html</a></li><li>Version 3.6.6 - <a href="releaselog/3_6_6.html">releaselog/3_6_6.html</a></li><li>version 3.6.6 - <a href="releaselog/3_6_6.html">releaselog/3_6_6.html</a></li><li>Version 3.6.6.1 - <a href="releaselog/3_6_6_1.html">releaselog/3_6_6_1.html</a></li><li>version 3.6.6.1 - <a href="releaselog/3_6_6_1.html">releaselog/3_6_6_1.html</a></li><li>Version 3.6.6.2 - <a href="releaselog/3_6_6_2.html">releaselog/3_6_6_2.html</a></li><li>version 3.6.6.2 - <a href="releaselog/3_6_6_2.html">releaselog/3_6_6_2.html</a></li><li>Version 3.6.7 - <a href="releaselog/3_6_7.html">releaselog/3_6_7.html</a></li><li>version 3.6.7 - <a href="releaselog/3_6_7.html">releaselog/3_6_7.html</a></li><li>Version 3.6.8 - <a href="releaselog/3_6_8.html">releaselog/3_6_8.html</a></li><li>version 3.6.8 - <a href="releaselog/3_6_8.html">releaselog/3_6_8.html</a></li><li>Version 3.6.9 - <a href="releaselog/3_6_9.html">releaselog/3_6_9.html</a></li><li>version 3.6.9 - <a href="releaselog/3_6_9.html">releaselog/3_6_9.html</a></li><li>Version 3.6.10 - <a href="releaselog/3_6_10.html">releaselog/3_6_10.html</a></li><li>version 3.6.10 - <a href="releaselog/3_6_10.html">releaselog/3_6_10.html</a></li><li>Version 3.6.11 - <a href="releaselog/3_6_11.html">releaselog/3_6_11.html</a></li><li>version 3.6.11 - <a href="releaselog/3_6_11.html">releaselog/3_6_11.html</a></li><li>Version 3.6.12 - <a href="releaselog/3_6_12.html">releaselog/3_6_12.html</a></li><li>version 3.6.12 - <a href="releaselog/3_6_12.html">releaselog/3_6_12.html</a></li><li>Version 3.6.13 - <a href="releaselog/3_6_13.html">releaselog/3_6_13.html</a></li><li>version 3.6.13 - <a href="releaselog/3_6_13.html">releaselog/3_6_13.html</a></li><li>Version 3.6.14 - <a href="releaselog/3_6_14.html">releaselog/3_6_14.html</a></li><li>version 3.6.14 - <a href="releaselog/3_6_14.html">releaselog/3_6_14.html</a></li><li>Version 3.6.14.1 - <a href="releaselog/3_6_14_1.html">releaselog/3_6_14_1.html</a></li><li>version 3.6.14.1 - <a href="releaselog/3_6_14_1.html">releaselog/3_6_14_1.html</a></li><li>Version 3.6.14.2 - <a href="releaselog/3_6_14_2.html">releaselog/3_6_14_2.html</a></li><li>version 3.6.14.2 - <a href="releaselog/3_6_14_2.html">releaselog/3_6_14_2.html</a></li><li>Version 3.6.15 - <a href="releaselog/3_6_15.html">releaselog/3_6_15.html</a></li><li>version 3.6.15 - <a href="releaselog/3_6_15.html">releaselog/3_6_15.html</a></li><li>Version 3.6.16 - <a href="releaselog/3_6_16.html">releaselog/3_6_16.html</a></li><li>version 3.6.16 - <a href="releaselog/3_6_16.html">releaselog/3_6_16.html</a></li><li>Version 3.6.16.1 - <a href="releaselog/3_6_16_1.html">releaselog/3_6_16_1.html</a></li><li>version 3.6.16.1 - <a href="releaselog/3_6_16_1.html">releaselog/3_6_16_1.html</a></li><li>Version 3.6.17 - <a href="releaselog/3_6_17.html">releaselog/3_6_17.html</a></li><li>version 3.6.17 - <a href="releaselog/3_6_17.html">releaselog/3_6_17.html</a></li><li>Version 3.6.18 - <a href="releaselog/3_6_18.html">releaselog/3_6_18.html</a></li><li>version 3.6.18 - <a href="releaselog/3_6_18.html">releaselog/3_6_18.html</a></li><li>Version 3.6.19 - <a href="releaselog/3_6_19.html">releaselog/3_6_19.html</a></li><li>version 3.6.19 - <a href="releaselog/3_6_19.html">releaselog/3_6_19.html</a></li><li>Version 3.6.20 - <a href="releaselog/3_6_20.html">releaselog/3_6_20.html</a></li><li>version 3.6.20 - <a href="releaselog/3_6_20.html">releaselog/3_6_20.html</a></li><li>Version 3.6.21 - <a href="releaselog/3_6_21.html">releaselog/3_6_21.html</a></li><li>version 3.6.21 - <a href="releaselog/3_6_21.html">releaselog/3_6_21.html</a></li><li>Version 3.6.22 - <a href="releaselog/3_6_22.html">releaselog/3_6_22.html</a></li><li>version 3.6.22 - <a href="releaselog/3_6_22.html">releaselog/3_6_22.html</a></li><li>Version 3.6.23 - <a href="releaselog/3_6_23.html">releaselog/3_6_23.html</a></li><li>version 3.6.23 - <a href="releaselog/3_6_23.html">releaselog/3_6_23.html</a></li><li>Version 3.6.23.1 - <a href="releaselog/3_6_23_1.html">releaselog/3_6_23_1.html</a></li><li>version 3.6.23.1 - <a href="releaselog/3_6_23_1.html">releaselog/3_6_23_1.html</a></li><li>Version 3.6.23.1.0 - <a href="releaselog/3_6_23_1.html">releaselog/3_6_23_1.html</a></li><li>version 3.6.23.1.0 - <a href="releaselog/3_6_23_1.html">releaselog/3_6_23_1.html</a></li><li>Version 3.7.0 - <a href="releaselog/3_7_0.html">releaselog/3_7_0.html</a></li><li>version 3.7.0 - <a href="releaselog/3_7_0.html">releaselog/3_7_0.html</a></li><li>Version 3.7.0.1 - <a href="releaselog/3_7_0_1.html">releaselog/3_7_0_1.html</a></li><li>version 3.7.0.1 - <a href="releaselog/3_7_0_1.html">releaselog/3_7_0_1.html</a></li><li>Version 3.7.1 - <a href="releaselog/3_7_1.html">releaselog/3_7_1.html</a></li><li>version 3.7.1 - <a href="releaselog/3_7_1.html">releaselog/3_7_1.html</a></li><li>Version 3.7.2 - <a href="releaselog/3_7_2.html">releaselog/3_7_2.html</a></li><li>version 3.7.2 - <a href="releaselog/3_7_2.html">releaselog/3_7_2.html</a></li><li>Version 3.7.3 - <a href="releaselog/3_7_3.html">releaselog/3_7_3.html</a></li><li>version 3.7.3 - <a href="releaselog/3_7_3.html">releaselog/3_7_3.html</a></li><li>Version 3.7.4 - <a href="releaselog/3_7_4.html">releaselog/3_7_4.html</a></li><li>version 3.7.4 - <a href="releaselog/3_7_4.html">releaselog/3_7_4.html</a></li><li>Version 3.7.5 - <a href="releaselog/3_7_5.html">releaselog/3_7_5.html</a></li><li>version 3.7.5 - <a href="releaselog/3_7_5.html">releaselog/3_7_5.html</a></li><li>Version 3.7.6 - <a href="releaselog/3_7_6.html">releaselog/3_7_6.html</a></li><li>version 3.7.6 - <a href="releaselog/3_7_6.html">releaselog/3_7_6.html</a></li><li>Version 3.7.6.1 - <a href="releaselog/3_7_6_1.html">releaselog/3_7_6_1.html</a></li><li>version 3.7.6.1 - <a href="releaselog/3_7_6_1.html">releaselog/3_7_6_1.html</a></li><li>Version 3.7.6.2 - <a href="releaselog/3_7_6_2.html">releaselog/3_7_6_2.html</a></li><li>version 3.7.6.2 - <a href="releaselog/3_7_6_2.html">releaselog/3_7_6_2.html</a></li><li>Version 3.7.6.3 - <a href="releaselog/3_7_6_3.html">releaselog/3_7_6_3.html</a></li><li>version 3.7.6.3 - <a href="releaselog/3_7_6_3.html">releaselog/3_7_6_3.html</a></li><li>Version 3.7.7 - <a href="releaselog/3_7_7.html">releaselog/3_7_7.html</a></li><li>version 3.7.7 - <a href="releaselog/3_7_7.html">releaselog/3_7_7.html</a></li><li>Version 3.7.7.1 - <a href="releaselog/3_7_7_1.html">releaselog/3_7_7_1.html</a></li><li>version 3.7.7.1 - <a href="releaselog/3_7_7_1.html">releaselog/3_7_7_1.html</a></li><li>Version 3.7.8 - <a href="releaselog/3_7_8.html">releaselog/3_7_8.html</a></li><li>version 3.7.8 - <a href="releaselog/3_7_8.html">releaselog/3_7_8.html</a></li><li>Version 3.7.9 - <a href="releaselog/3_7_9.html">releaselog/3_7_9.html</a></li><li>version 3.7.9 - <a href="releaselog/3_7_9.html">releaselog/3_7_9.html</a></li><li>Version 3.7.10 - <a href="releaselog/3_7_10.html">releaselog/3_7_10.html</a></li><li>version 3.7.10 - <a href="releaselog/3_7_10.html">releaselog/3_7_10.html</a></li><li>Version 3.7.11 - <a href="releaselog/3_7_11.html">releaselog/3_7_11.html</a></li><li>version 3.7.11 - <a href="releaselog/3_7_11.html">releaselog/3_7_11.html</a></li><li>Version 3.7.12 - <a href="releaselog/3_7_12.html">releaselog/3_7_12.html</a></li><li>version 3.7.12 - <a href="releaselog/3_7_12.html">releaselog/3_7_12.html</a></li><li>Version 3.7.12.1 - <a href="releaselog/3_7_12_1.html">releaselog/3_7_12_1.html</a></li><li>version 3.7.12.1 - <a href="releaselog/3_7_12_1.html">releaselog/3_7_12_1.html</a></li><li>Version 3.7.13 - <a href="releaselog/3_7_13.html">releaselog/3_7_13.html</a></li><li>version 3.7.13 - <a href="releaselog/3_7_13.html">releaselog/3_7_13.html</a></li><li>Version 3.7.14 - <a href="releaselog/3_7_14.html">releaselog/3_7_14.html</a></li><li>version 3.7.14 - <a href="releaselog/3_7_14.html">releaselog/3_7_14.html</a></li><li>Version 3.7.14.1 - <a href="releaselog/3_7_14_1.html">releaselog/3_7_14_1.html</a></li><li>version 3.7.14.1 - <a href="releaselog/3_7_14_1.html">releaselog/3_7_14_1.html</a></li><li>Version 3.7.15 - <a href="releaselog/3_7_15.html">releaselog/3_7_15.html</a></li><li>version 3.7.15 - <a href="releaselog/3_7_15.html">releaselog/3_7_15.html</a></li><li>Version 3.7.15.1 - <a href="releaselog/3_7_15_1.html">releaselog/3_7_15_1.html</a></li><li>version 3.7.15.1 - <a href="releaselog/3_7_15_1.html">releaselog/3_7_15_1.html</a></li><li>Version 3.7.15.2 - <a href="releaselog/3_7_15_2.html">releaselog/3_7_15_2.html</a></li><li>version 3.7.15.2 - <a href="releaselog/3_7_15_2.html">releaselog/3_7_15_2.html</a></li><li>Version 3.7.16 - <a href="releaselog/3_7_16.html">releaselog/3_7_16.html</a></li><li>version 3.7.16 - <a href="releaselog/3_7_16.html">releaselog/3_7_16.html</a></li><li>Version 3.7.16.1 - <a href="releaselog/3_7_16_1.html">releaselog/3_7_16_1.html</a></li><li>version 3.7.16.1 - <a href="releaselog/3_7_16_1.html">releaselog/3_7_16_1.html</a></li><li>Version 3.7.16.2 - <a href="releaselog/3_7_16_2.html">releaselog/3_7_16_2.html</a></li><li>version 3.7.16.2 - <a href="releaselog/3_7_16_2.html">releaselog/3_7_16_2.html</a></li><li>Version 3.7.17 - <a href="releaselog/3_7_17.html">releaselog/3_7_17.html</a></li><li>version 3.7.17 - <a href="releaselog/3_7_17.html">releaselog/3_7_17.html</a></li><li>Version 3.8.0 - <a href="releaselog/3_8_0.html">releaselog/3_8_0.html</a></li><li>version 3.8.0 - <a href="releaselog/3_8_0.html">releaselog/3_8_0.html</a></li><li>Version 3.8.0.1 - <a href="releaselog/3_8_0_1.html">releaselog/3_8_0_1.html</a></li><li>version 3.8.0.1 - <a href="releaselog/3_8_0_1.html">releaselog/3_8_0_1.html</a></li><li>Version 3.8.0.2 - <a href="releaselog/3_8_0_2.html">releaselog/3_8_0_2.html</a></li><li>version 3.8.0.2 - <a href="releaselog/3_8_0_2.html">releaselog/3_8_0_2.html</a></li><li>Version 3.8.1 - <a href="releaselog/3_8_1.html">releaselog/3_8_1.html</a></li><li>version 3.8.1 - <a href="releaselog/3_8_1.html">releaselog/3_8_1.html</a></li><li>Version 3.8.2 - <a href="releaselog/3_8_2.html">releaselog/3_8_2.html</a></li><li>version 3.8.2 - <a href="releaselog/3_8_2.html">releaselog/3_8_2.html</a></li><li>Version 3.8.3 - <a href="releaselog/3_8_3.html">releaselog/3_8_3.html</a></li><li>version 3.8.3 - <a href="releaselog/3_8_3.html">releaselog/3_8_3.html</a></li><li>Version 3.8.3.1 - <a href="releaselog/3_8_3_1.html">releaselog/3_8_3_1.html</a></li><li>version 3.8.3.1 - <a href="releaselog/3_8_3_1.html">releaselog/3_8_3_1.html</a></li><li>Version 3.8.3.1.0 - <a href="releaselog/3_8_3_1.html">releaselog/3_8_3_1.html</a></li><li>version 3.8.3.1.0 - <a href="releaselog/3_8_3_1.html">releaselog/3_8_3_1.html</a></li><li>Version 3.8.4 - <a href="releaselog/3_8_4.html">releaselog/3_8_4.html</a></li><li>version 3.8.4 - <a href="releaselog/3_8_4.html">releaselog/3_8_4.html</a></li><li>Version 3.8.4.1 - <a href="releaselog/3_8_4_1.html">releaselog/3_8_4_1.html</a></li><li>version 3.8.4.1 - <a href="releaselog/3_8_4_1.html">releaselog/3_8_4_1.html</a></li><li>Version 3.8.4.2 - <a href="releaselog/3_8_4_2.html">releaselog/3_8_4_2.html</a></li><li>version 3.8.4.2 - <a href="releaselog/3_8_4_2.html">releaselog/3_8_4_2.html</a></li><li>Version 3.8.4.3 - <a href="releaselog/3_8_4_3.html">releaselog/3_8_4_3.html</a></li><li>version 3.8.4.3 - <a href="releaselog/3_8_4_3.html">releaselog/3_8_4_3.html</a></li><li>Version 3.8.5 - <a href="releaselog/3_8_5.html">releaselog/3_8_5.html</a></li><li>version 3.8.5 - <a href="releaselog/3_8_5.html">releaselog/3_8_5.html</a></li><li>Version 3.8.6 - <a href="releaselog/3_8_6.html">releaselog/3_8_6.html</a></li><li>version 3.8.6 - <a href="releaselog/3_8_6.html">releaselog/3_8_6.html</a></li><li>Version 3.8.7 - <a href="releaselog/3_8_7.html">releaselog/3_8_7.html</a></li><li>version 3.8.7 - <a href="releaselog/3_8_7.html">releaselog/3_8_7.html</a></li><li>Version 3.8.7.1 - <a href="releaselog/3_8_7_1.html">releaselog/3_8_7_1.html</a></li><li>version 3.8.7.1 - <a href="releaselog/3_8_7_1.html">releaselog/3_8_7_1.html</a></li><li>Version 3.8.7.2 - <a href="releaselog/3_8_7_2.html">releaselog/3_8_7_2.html</a></li><li>version 3.8.7.2 - <a href="releaselog/3_8_7_2.html">releaselog/3_8_7_2.html</a></li><li>Version 3.8.7.3 - <a href="releaselog/3_8_7_3.html">releaselog/3_8_7_3.html</a></li><li>version 3.8.7.3 - <a href="releaselog/3_8_7_3.html">releaselog/3_8_7_3.html</a></li><li>Version 3.8.7.4 - <a href="releaselog/3_8_7_4.html">releaselog/3_8_7_4.html</a></li><li>version 3.8.7.4 - <a href="releaselog/3_8_7_4.html">releaselog/3_8_7_4.html</a></li><li>Version 3.8.8 - <a href="releaselog/3_8_8.html">releaselog/3_8_8.html</a></li><li>version 3.8.8 - <a href="releaselog/3_8_8.html">releaselog/3_8_8.html</a></li><li>Version 3.8.8.1 - <a href="releaselog/3_8_8_1.html">releaselog/3_8_8_1.html</a></li><li>version 3.8.8.1 - <a href="releaselog/3_8_8_1.html">releaselog/3_8_8_1.html</a></li><li>Version 3.8.8.2 - <a href="releaselog/3_8_8_2.html">releaselog/3_8_8_2.html</a></li><li>version 3.8.8.2 - <a href="releaselog/3_8_8_2.html">releaselog/3_8_8_2.html</a></li><li>Version 3.8.8.3 - <a href="releaselog/3_8_8_3.html">releaselog/3_8_8_3.html</a></li><li>version 3.8.8.3 - <a href="releaselog/3_8_8_3.html">releaselog/3_8_8_3.html</a></li><li>Version 3.8.9 - <a href="releaselog/3_8_9.html">releaselog/3_8_9.html</a></li><li>version 3.8.9 - <a href="releaselog/3_8_9.html">releaselog/3_8_9.html</a></li><li>Version 3.8.10 - <a href="releaselog/3_8_10.html">releaselog/3_8_10.html</a></li><li>version 3.8.10 - <a href="releaselog/3_8_10.html">releaselog/3_8_10.html</a></li><li>Version 3.8.10.1 - <a href="releaselog/3_8_10_1.html">releaselog/3_8_10_1.html</a></li><li>version 3.8.10.1 - <a href="releaselog/3_8_10_1.html">releaselog/3_8_10_1.html</a></li><li>Version 3.8.10.2 - <a href="releaselog/3_8_10_2.html">releaselog/3_8_10_2.html</a></li><li>version 3.8.10.2 - <a href="releaselog/3_8_10_2.html">releaselog/3_8_10_2.html</a></li><li>Version 3.8.11 - <a href="releaselog/3_8_11.html">releaselog/3_8_11.html</a></li><li>version 3.8.11 - <a href="releaselog/3_8_11.html">releaselog/3_8_11.html</a></li><li>Version 3.8.11.1 - <a href="releaselog/3_8_11_1.html">releaselog/3_8_11_1.html</a></li><li>version 3.8.11.1 - <a href="releaselog/3_8_11_1.html">releaselog/3_8_11_1.html</a></li><li>Version 3.9.0 - <a href="releaselog/3_9_0.html">releaselog/3_9_0.html</a></li><li>version 3.9.0 - <a href="releaselog/3_9_0.html">releaselog/3_9_0.html</a></li><li>Version 3.9.1 - <a href="releaselog/3_9_1.html">releaselog/3_9_1.html</a></li><li>version 3.9.1 - <a href="releaselog/3_9_1.html">releaselog/3_9_1.html</a></li><li>Version 3.9.2 - <a href="releaselog/3_9_2.html">releaselog/3_9_2.html</a></li><li>version 3.9.2 - <a href="releaselog/3_9_2.html">releaselog/3_9_2.html</a></li><li>Version 3.9.3 - <a href="releaselog/3_9_3.html">releaselog/3_9_3.html</a></li><li>version 3.9.3 - <a href="releaselog/3_9_3.html">releaselog/3_9_3.html</a></li><li>Version 3.10.0 - <a href="releaselog/3_10_0.html">releaselog/3_10_0.html</a></li><li>version 3.10.0 - <a href="releaselog/3_10_0.html">releaselog/3_10_0.html</a></li><li>Version 3.10.1 - <a href="releaselog/3_10_1.html">releaselog/3_10_1.html</a></li><li>version 3.10.1 - <a href="releaselog/3_10_1.html">releaselog/3_10_1.html</a></li><li>Version 3.10.2 - <a href="releaselog/3_10_2.html">releaselog/3_10_2.html</a></li><li>version 3.10.2 - <a href="releaselog/3_10_2.html">releaselog/3_10_2.html</a></li><li>Version 3.11.0 - <a href="releaselog/3_11_0.html">releaselog/3_11_0.html</a></li><li>version 3.11.0 - <a href="releaselog/3_11_0.html">releaselog/3_11_0.html</a></li><li>Version 3.11.1 - <a href="releaselog/3_11_1.html">releaselog/3_11_1.html</a></li><li>version 3.11.1 - <a href="releaselog/3_11_1.html">releaselog/3_11_1.html</a></li><li>Version 3.12.0 - <a href="releaselog/3_12_0.html">releaselog/3_12_0.html</a></li><li>version 3.12.0 - <a href="releaselog/3_12_0.html">releaselog/3_12_0.html</a></li><li>version 3.12.0 page size change - <a href="pgszchng2016.html">pgszchng2016.html</a></li><li>Version 3.12.1 - <a href="releaselog/3_12_1.html">releaselog/3_12_1.html</a></li><li>version 3.12.1 - <a href="releaselog/3_12_1.html">releaselog/3_12_1.html</a></li><li>Version 3.12.2 - <a href="releaselog/3_12_2.html">releaselog/3_12_2.html</a></li><li>version 3.12.2 - <a href="releaselog/3_12_2.html">releaselog/3_12_2.html</a></li><li>Version 3.13.0 - <a href="releaselog/3_13_0.html">releaselog/3_13_0.html</a></li><li>version 3.13.0 - <a href="releaselog/3_13_0.html">releaselog/3_13_0.html</a></li><li>Version 3.13.0.0 - <a href="releaselog/3_13_0.html">releaselog/3_13_0.html</a></li><li>version 3.13.0.0 - <a href="releaselog/3_13_0.html">releaselog/3_13_0.html</a></li><li>Version 3.14 - <a href="releaselog/3_14.html">releaselog/3_14.html</a></li><li>version 3.14 - <a href="releaselog/3_14.html">releaselog/3_14.html</a></li><li>Version 3.14.0 - <a href="releaselog/3_14.html">releaselog/3_14.html</a></li><li>version 3.14.0 - <a href="releaselog/3_14.html">releaselog/3_14.html</a></li><li>Version 3.14.1 - <a href="releaselog/3_14_1.html">releaselog/3_14_1.html</a></li><li>version 3.14.1 - <a href="releaselog/3_14_1.html">releaselog/3_14_1.html</a></li><li>Version 3.14.2 - <a href="releaselog/3_14_2.html">releaselog/3_14_2.html</a></li><li>version 3.14.2 - <a href="releaselog/3_14_2.html">releaselog/3_14_2.html</a></li><li>Version 3.15.0 - <a href="releaselog/3_15_0.html">releaselog/3_15_0.html</a></li><li>version 3.15.0 - <a href="releaselog/3_15_0.html">releaselog/3_15_0.html</a></li><li>Version 3.15.1 - <a href="releaselog/3_15_1.html">releaselog/3_15_1.html</a></li><li>version 3.15.1 - <a href="releaselog/3_15_1.html">releaselog/3_15_1.html</a></li><li>Version 3.15.2 - <a href="releaselog/3_15_2.html">releaselog/3_15_2.html</a></li><li>version 3.15.2 - <a href="releaselog/3_15_2.html">releaselog/3_15_2.html</a></li><li>Version 3.16.0 - <a href="releaselog/3_16_0.html">releaselog/3_16_0.html</a></li><li>version 3.16.0 - <a href="releaselog/3_16_0.html">releaselog/3_16_0.html</a></li><li>Version 3.16.1 - <a href="releaselog/3_16_1.html">releaselog/3_16_1.html</a></li><li>version 3.16.1 - <a href="releaselog/3_16_1.html">releaselog/3_16_1.html</a></li><li>Version 3.16.2 - <a href="releaselog/3_16_2.html">releaselog/3_16_2.html</a></li><li>version 3.16.2 - <a href="releaselog/3_16_2.html">releaselog/3_16_2.html</a></li><li>Version 3.17.0 - <a href="releaselog/3_17_0.html">releaselog/3_17_0.html</a></li><li>version 3.17.0 - <a href="releaselog/3_17_0.html">releaselog/3_17_0.html</a></li><li>Version 3.18.0 - <a href="releaselog/3_18_0.html">releaselog/3_18_0.html</a></li><li>version 3.18.0 - <a href="releaselog/3_18_0.html">releaselog/3_18_0.html</a></li><li>Version 3.18.1 - <a href="releaselog/3_18_1.html">releaselog/3_18_1.html</a></li><li>version 3.18.1 - <a href="releaselog/3_18_1.html">releaselog/3_18_1.html</a></li><li>Version 3.18.2 - <a href="releaselog/3_18_2.html">releaselog/3_18_2.html</a></li><li>version 3.18.2 - <a href="releaselog/3_18_2.html">releaselog/3_18_2.html</a></li><li>Version 3.19.0 - <a href="releaselog/3_19_0.html">releaselog/3_19_0.html</a></li><li>version 3.19.0 - <a href="releaselog/3_19_0.html">releaselog/3_19_0.html</a></li><li>Version 3.19.1 - <a href="releaselog/3_19_1.html">releaselog/3_19_1.html</a></li><li>version 3.19.1 - <a href="releaselog/3_19_1.html">releaselog/3_19_1.html</a></li><li>Version 3.19.2 - <a href="releaselog/3_19_2.html">releaselog/3_19_2.html</a></li><li>version 3.19.2 - <a href="releaselog/3_19_2.html">releaselog/3_19_2.html</a></li><li>Version 3.19.3 - <a href="releaselog/3_19_3.html">releaselog/3_19_3.html</a></li><li>version 3.19.3 - <a href="releaselog/3_19_3.html">releaselog/3_19_3.html</a></li><li>Version 3.20.0 - <a href="releaselog/3_20_0.html">releaselog/3_20_0.html</a></li><li>version 3.20.0 - <a href="releaselog/3_20_0.html">releaselog/3_20_0.html</a></li><li>Version 3.20.1 - <a href="releaselog/3_20_1.html">releaselog/3_20_1.html</a></li><li>version 3.20.1 - <a href="releaselog/3_20_1.html">releaselog/3_20_1.html</a></li><li>Version 3.21.0 - <a href="releaselog/3_21_0.html">releaselog/3_21_0.html</a></li><li>version 3.21.0 - <a href="releaselog/3_21_0.html">releaselog/3_21_0.html</a></li><li>Version 3.22.0 - <a href="releaselog/3_22_0.html">releaselog/3_22_0.html</a></li><li>version 3.22.0 - <a href="releaselog/3_22_0.html">releaselog/3_22_0.html</a></li><li>Version 3.23.0 - <a href="releaselog/3_23_0.html">releaselog/3_23_0.html</a></li><li>version 3.23.0 - <a href="releaselog/3_23_0.html">releaselog/3_23_0.html</a></li><li>Version 3.23.0.0 - <a href="releaselog/3_23_0.html">releaselog/3_23_0.html</a></li><li>version 3.23.0.0 - <a href="releaselog/3_23_0.html">releaselog/3_23_0.html</a></li><li>Version 3.23.1 - <a href="releaselog/3_23_1.html">releaselog/3_23_1.html</a></li><li>version 3.23.1 - <a href="releaselog/3_23_1.html">releaselog/3_23_1.html</a></li><li>Version 3.23.1.0 - <a href="releaselog/3_23_1.html">releaselog/3_23_1.html</a></li><li>version 3.23.1.0 - <a href="releaselog/3_23_1.html">releaselog/3_23_1.html</a></li><li>Version 3.24.0 - <a href="releaselog/3_24_0.html">releaselog/3_24_0.html</a></li><li>version 3.24.0 - <a href="releaselog/3_24_0.html">releaselog/3_24_0.html</a></li><li>Version 3.25.0 - <a href="releaselog/3_25_0.html">releaselog/3_25_0.html</a></li><li>version 3.25.0 - <a href="releaselog/3_25_0.html">releaselog/3_25_0.html</a></li><li>Version 3.25.1 - <a href="releaselog/3_25_1.html">releaselog/3_25_1.html</a></li><li>version 3.25.1 - <a href="releaselog/3_25_1.html">releaselog/3_25_1.html</a></li><li>Version 3.25.2 - <a href="releaselog/3_25_2.html">releaselog/3_25_2.html</a></li><li>version 3.25.2 - <a href="releaselog/3_25_2.html">releaselog/3_25_2.html</a></li><li>Version 3.25.3 - <a href="releaselog/3_25_3.html">releaselog/3_25_3.html</a></li><li>version 3.25.3 - <a href="releaselog/3_25_3.html">releaselog/3_25_3.html</a></li><li>Version 3.26.0 - <a href="releaselog/3_26_0.html">releaselog/3_26_0.html</a></li><li>version 3.26.0 - <a href="releaselog/3_26_0.html">releaselog/3_26_0.html</a></li><li>Version 3.27.0 - <a href="releaselog/3_27_0.html">releaselog/3_27_0.html</a></li><li>version 3.27.0 - <a href="releaselog/3_27_0.html">releaselog/3_27_0.html</a></li><li>Version 3.27.1 - <a href="releaselog/3_27_1.html">releaselog/3_27_1.html</a></li><li>version 3.27.1 - <a href="releaselog/3_27_1.html">releaselog/3_27_1.html</a></li><li>Version 3.27.2 - <a href="releaselog/3_27_2.html">releaselog/3_27_2.html</a></li><li>version 3.27.2 - <a href="releaselog/3_27_2.html">releaselog/3_27_2.html</a></li><li>Version 3.28.0 - <a href="releaselog/3_28_0.html">releaselog/3_28_0.html</a></li><li>version 3.28.0 - <a href="releaselog/3_28_0.html">releaselog/3_28_0.html</a></li><li>Version 3.29.0 - <a href="releaselog/3_29_0.html">releaselog/3_29_0.html</a></li><li>version 3.29.0 - <a href="releaselog/3_29_0.html">releaselog/3_29_0.html</a></li><li>Version 3.30.0 - <a href="releaselog/3_30_0.html">releaselog/3_30_0.html</a></li><li>version 3.30.0 - <a href="releaselog/3_30_0.html">releaselog/3_30_0.html</a></li><li>Version 3.30.1 - <a href="releaselog/3_30_1.html">releaselog/3_30_1.html</a></li><li>version 3.30.1 - <a href="releaselog/3_30_1.html">releaselog/3_30_1.html</a></li><li>Version 3.31.0 - <a href="releaselog/3_31_0.html">releaselog/3_31_0.html</a></li><li>version 3.31.0 - <a href="releaselog/3_31_0.html">releaselog/3_31_0.html</a></li><li>Version 3.31.1 - <a href="releaselog/3_31_1.html">releaselog/3_31_1.html</a></li><li>version 3.31.1 - <a href="releaselog/3_31_1.html">releaselog/3_31_1.html</a></li><li>Version 3.32.0 - <a href="releaselog/3_32_0.html">releaselog/3_32_0.html</a></li><li>version 3.32.0 - <a href="releaselog/3_32_0.html">releaselog/3_32_0.html</a></li><li>Version 3.32.1 - <a href="releaselog/3_32_1.html">releaselog/3_32_1.html</a></li><li>version 3.32.1 - <a href="releaselog/3_32_1.html">releaselog/3_32_1.html</a></li><li>Version 3.32.2 - <a href="releaselog/3_32_2.html">releaselog/3_32_2.html</a></li><li>version 3.32.2 - <a href="releaselog/3_32_2.html">releaselog/3_32_2.html</a></li><li>Version 3.32.3 - <a href="releaselog/3_32_3.html">releaselog/3_32_3.html</a></li><li>version 3.32.3 - <a href="releaselog/3_32_3.html">releaselog/3_32_3.html</a></li><li>Version 3.33.0 - <a href="releaselog/3_33_0.html">releaselog/3_33_0.html</a></li><li>version 3.33.0 - <a href="releaselog/3_33_0.html">releaselog/3_33_0.html</a></li><li>Version 3.33.0.0 - <a href="releaselog/3_33_0.html">releaselog/3_33_0.html</a></li><li>version 3.33.0.0 - <a href="releaselog/3_33_0.html">releaselog/3_33_0.html</a></li><li>Version 3.34.0 - <a href="releaselog/3_34_0.html">releaselog/3_34_0.html</a></li><li>version 3.34.0 - <a href="releaselog/3_34_0.html">releaselog/3_34_0.html</a></li><li>Version 3.34.1 - <a href="releaselog/3_34_1.html">releaselog/3_34_1.html</a></li><li>version 3.34.1 - <a href="releaselog/3_34_1.html">releaselog/3_34_1.html</a></li><li>Version 3.35.0 - <a href="releaselog/3_35_0.html">releaselog/3_35_0.html</a></li><li>version 3.35.0 - <a href="releaselog/3_35_0.html">releaselog/3_35_0.html</a></li><li>Version 3.35.1 - <a href="releaselog/3_35_1.html">releaselog/3_35_1.html</a></li><li>version 3.35.1 - <a href="releaselog/3_35_1.html">releaselog/3_35_1.html</a></li><li>Version 3.35.2 - <a href="releaselog/3_35_2.html">releaselog/3_35_2.html</a></li><li>version 3.35.2 - <a href="releaselog/3_35_2.html">releaselog/3_35_2.html</a></li><li>Version 3.35.3 - <a href="releaselog/3_35_3.html">releaselog/3_35_3.html</a></li><li>version 3.35.3 - <a href="releaselog/3_35_3.html">releaselog/3_35_3.html</a></li><li>Version 3.35.4 - <a href="releaselog/3_35_4.html">releaselog/3_35_4.html</a></li><li>version 3.35.4 - <a href="releaselog/3_35_4.html">releaselog/3_35_4.html</a></li><li>Version 3.35.5 - <a href="releaselog/3_35_5.html">releaselog/3_35_5.html</a></li><li>version 3.35.5 - <a href="releaselog/3_35_5.html">releaselog/3_35_5.html</a></li><li>Version 3.36.0 - <a href="releaselog/3_36_0.html">releaselog/3_36_0.html</a></li><li>version 3.36.0 - <a href="releaselog/3_36_0.html">releaselog/3_36_0.html</a></li><li>Version 3.37.0 - <a href="releaselog/3_37_0.html">releaselog/3_37_0.html</a></li><li>version 3.37.0 - <a href="releaselog/3_37_0.html">releaselog/3_37_0.html</a></li><li>Version 3.37.1 - <a href="releaselog/3_37_1.html">releaselog/3_37_1.html</a></li><li>version 3.37.1 - <a href="releaselog/3_37_1.html">releaselog/3_37_1.html</a></li><li>Version 3.37.2 - <a href="releaselog/3_37_2.html">releaselog/3_37_2.html</a></li><li>version 3.37.2 - <a href="releaselog/3_37_2.html">releaselog/3_37_2.html</a></li><li>Version 3.38.0 - <a href="releaselog/3_38_0.html">releaselog/3_38_0.html</a></li><li>version 3.38.0 - <a href="releaselog/3_38_0.html">releaselog/3_38_0.html</a></li><li>Version 3.38.1 - <a href="releaselog/3_38_1.html">releaselog/3_38_1.html</a></li><li>version 3.38.1 - <a href="releaselog/3_38_1.html">releaselog/3_38_1.html</a></li><li>Version 3.38.2 - <a href="releaselog/3_38_2.html">releaselog/3_38_2.html</a></li><li>version 3.38.2 - <a href="releaselog/3_38_2.html">releaselog/3_38_2.html</a></li><li>Version 3.38.3 - <a href="releaselog/3_38_3.html">releaselog/3_38_3.html</a></li><li>version 3.38.3 - <a href="releaselog/3_38_3.html">releaselog/3_38_3.html</a></li><li>Version 3.38.4 - <a href="releaselog/3_38_4.html">releaselog/3_38_4.html</a></li><li>version 3.38.4 - <a href="releaselog/3_38_4.html">releaselog/3_38_4.html</a></li><li>Version 3.38.5 - <a href="releaselog/3_38_5.html">releaselog/3_38_5.html</a></li><li>version 3.38.5 - <a href="releaselog/3_38_5.html">releaselog/3_38_5.html</a></li><li>Version 3.39.0 - <a href="releaselog/3_39_0.html">releaselog/3_39_0.html</a></li><li>version 3.39.0 - <a href="releaselog/3_39_0.html">releaselog/3_39_0.html</a></li><li>Version 3.39.1 - <a href="releaselog/3_39_1.html">releaselog/3_39_1.html</a></li><li>version 3.39.1 - <a href="releaselog/3_39_1.html">releaselog/3_39_1.html</a></li><li>Version 3.39.2 - <a href="releaselog/3_39_2.html">releaselog/3_39_2.html</a></li><li>version 3.39.2 - <a href="releaselog/3_39_2.html">releaselog/3_39_2.html</a></li><li>Version 3.39.3 - <a href="releaselog/3_39_3.html">releaselog/3_39_3.html</a></li><li>version 3.39.3 - <a href="releaselog/3_39_3.html">releaselog/3_39_3.html</a></li><li>Version 3.39.4 - <a href="releaselog/3_39_4.html">releaselog/3_39_4.html</a></li><li>version 3.39.4 - <a href="releaselog/3_39_4.html">releaselog/3_39_4.html</a></li><li>Version 3.40.0 - <a href="releaselog/3_40_0.html">releaselog/3_40_0.html</a></li><li>version 3.40.0 - <a href="releaselog/3_40_0.html">releaselog/3_40_0.html</a></li><li>Version 3.40.1 - <a href="releaselog/3_40_1.html">releaselog/3_40_1.html</a></li><li>version 3.40.1 - <a href="releaselog/3_40_1.html">releaselog/3_40_1.html</a></li><li>Version 3.41.0 - <a href="releaselog/3_41_0.html">releaselog/3_41_0.html</a></li><li>version 3.41.0 - <a href="releaselog/3_41_0.html">releaselog/3_41_0.html</a></li><li>Version 3.41.1 - <a href="releaselog/3_41_1.html">releaselog/3_41_1.html</a></li><li>version 3.41.1 - <a href="releaselog/3_41_1.html">releaselog/3_41_1.html</a></li><li>Version 3.41.2 - <a href="releaselog/3_41_2.html">releaselog/3_41_2.html</a></li><li>version 3.41.2 - <a href="releaselog/3_41_2.html">releaselog/3_41_2.html</a></li><li>Version 3.42.0 - <a href="releaselog/3_42_0.html">releaselog/3_42_0.html</a></li><li>version 3.42.0 - <a href="releaselog/3_42_0.html">releaselog/3_42_0.html</a></li><li>Version 3.43.0 - <a href="releaselog/3_43_0.html">releaselog/3_43_0.html</a></li><li>version 3.43.0 - <a href="releaselog/3_43_0.html">releaselog/3_43_0.html</a></li><li>Version 3.43.0.0 - <a href="releaselog/3_43_0.html">releaselog/3_43_0.html</a></li><li>version 3.43.0.0 - <a href="releaselog/3_43_0.html">releaselog/3_43_0.html</a></li><li>Version 3.43.1 - <a href="releaselog/3_43_1.html">releaselog/3_43_1.html</a></li><li>version 3.43.1 - <a href="releaselog/3_43_1.html">releaselog/3_43_1.html</a></li><li>Version 3.43.1.0 - <a href="releaselog/3_43_1.html">releaselog/3_43_1.html</a></li><li>version 3.43.1.0 - <a href="releaselog/3_43_1.html">releaselog/3_43_1.html</a></li><li>Version 3.43.2 - <a href="releaselog/3_43_2.html">releaselog/3_43_2.html</a></li><li>version 3.43.2 - <a href="releaselog/3_43_2.html">releaselog/3_43_2.html</a></li><li>Version 3.43.2.0 - <a href="releaselog/3_43_2.html">releaselog/3_43_2.html</a></li><li>version 3.43.2.0 - <a href="releaselog/3_43_2.html">releaselog/3_43_2.html</a></li><li>Version 3.44.0 - <a href="releaselog/3_44_0.html">releaselog/3_44_0.html</a></li><li>version 3.44.0 - <a href="releaselog/3_44_0.html">releaselog/3_44_0.html</a></li><li>Version 3.44.1 - <a href="releaselog/3_44_1.html">releaselog/3_44_1.html</a></li><li>version 3.44.1 - <a href="releaselog/3_44_1.html">releaselog/3_44_1.html</a></li><li>Version 3.44.2 - <a href="releaselog/3_44_2.html">releaselog/3_44_2.html</a></li><li>version 3.44.2 - <a href="releaselog/3_44_2.html">releaselog/3_44_2.html</a></li><li>Version 3.45.0 - <a href="releaselog/3_45_0.html">releaselog/3_45_0.html</a></li><li>version 3.45.0 - <a href="releaselog/3_45_0.html">releaselog/3_45_0.html</a></li><li>Version 3.45.1 - <a href="releaselog/3_45_1.html">releaselog/3_45_1.html</a></li><li>version 3.45.1 - <a href="releaselog/3_45_1.html">releaselog/3_45_1.html</a></li><li>Version 3.45.2 - <a href="releaselog/3_45_2.html">releaselog/3_45_2.html</a></li><li>version 3.45.2 - <a href="releaselog/3_45_2.html">releaselog/3_45_2.html</a></li><li>Version 3.45.3 - <a href="releaselog/3_45_3.html">releaselog/3_45_3.html</a></li><li>version 3.45.3 - <a href="releaselog/3_45_3.html">releaselog/3_45_3.html</a></li><li>Version 3.46.0 - <a href="releaselog/3_46_0.html">releaselog/3_46_0.html</a></li><li>version 3.46.0 - <a href="releaselog/3_46_0.html">releaselog/3_46_0.html</a></li><li>version method - <a href="tclsqlite.html#version">tclsqlite.html#version</a></li><li>version numbering conventions - <a href="versionnumbers.html">versionnumbers.html</a></li><li>version-valid-for number - <a href="fileformat2.html#validfor">fileformat2.html#validfor</a></li><li>VFS - <a href="vfs.html">vfs.html</a></li><li>vfs query parameter - <a href="uri.html#urivfs">uri.html#urivfs</a></li><li>VFS shim - <a href="vfs.html#shim">vfs.html#shim</a></li><li>VFS shims - <a href="vfs.html#shim">vfs.html#shim</a></li><li>VFSes - <a href="vfs.html">vfs.html</a></li><li>VIEW - <a href="lang_createview.html">lang_createview.html</a></li><li>view - <a href="lang_createview.html">lang_createview.html</a></li><li>views - <a href="lang_createview.html">lang_createview.html</a></li><li>virtual machine - <a href="opcode.html">opcode.html</a></li><li>virtual machine instructions - <a href="opcode.html">opcode.html</a></li><li>virtual table - <a href="vtab.html">vtab.html</a></li><li>virtual table configuration option - <a href="c3ref/c_vtab_constraint_support.html">c3ref/c_vtab_constraint_support.html</a></li><li>virtual table configuration options - <a href="c3ref/c_vtab_constraint_support.html">c3ref/c_vtab_constraint_support.html</a></li><li>virtual table cursor - <a href="c3ref/vtab_cursor.html">c3ref/vtab_cursor.html</a></li><li>virtual table list - <a href="vtablist.html">vtablist.html</a></li><li>virtual table module - <a href="c3ref/module.html">c3ref/module.html</a></li><li>virtual tables - <a href="vtab.html">vtab.html</a></li><li>vulnerabilities - <a href="cves.html">cves.html</a></li><li>w - <a href="printf.html#percentw">printf.html#percentw</a></li><li>WAL - <a href="wal.html">wal.html</a></li><li>WAL backwards compatibility - <a href="wal.html#bkwrds">wal.html#bkwrds</a></li><li>WAL checksum algorithm - <a href="fileformat2.html#walcksm">fileformat2.html#walcksm</a></li><li>WAL concurrency - <a href="wal.html#concurrency">wal.html#concurrency</a></li><li>WAL file - <a href="wal.html#walfile">wal.html#walfile</a></li><li>WAL file format - <a href="fileformat2.html#walformat">fileformat2.html#walformat</a></li><li>WAL format - <a href="fileformat2.html#walformat">fileformat2.html#walformat</a></li><li>WAL mode - <a href="wal.html">wal.html</a></li><li>WAL read algorithm - <a href="fileformat2.html#walread">fileformat2.html#walread</a></li><li>WAL reset - <a href="fileformat2.html#walreset">fileformat2.html#walreset</a></li><li>WAL without shared memory - <a href="wal.html#noshm">wal.html#noshm</a></li><li>wal-index - <a href="walformat.html#shm">walformat.html#shm</a></li><li>WAL-index File Format - <a href="walformat.html#walidxfmt">walformat.html#walidxfmt</a></li><li>WAL-index format - <a href="walformat.html#walidxfmt">walformat.html#walidxfmt</a></li><li>WAL-mode crash recovery - <a href="walformat.html#recovery">walformat.html#recovery</a></li><li>WAL-mode File Format - <a href="walformat.html">walformat.html</a></li><li>WAL-mode locks - <a href="walformat.html#locks">walformat.html#locks</a></li><li>WAL-mode read blocking - <a href="wal.html#busy">wal.html#busy</a></li><li>wal_autocheckpoint - <a href="pragma.html#pragma_wal_autocheckpoint">pragma.html#pragma_wal_autocheckpoint</a></li><li>wal_autocheckpoint pragma - <a href="pragma.html#pragma_wal_autocheckpoint">pragma.html#pragma_wal_autocheckpoint</a></li><li>wal_checkpoint - <a href="pragma.html#pragma_wal_checkpoint">pragma.html#pragma_wal_checkpoint</a></li><li>wal_checkpoint pragma - <a href="pragma.html#pragma_wal_checkpoint">pragma.html#pragma_wal_checkpoint</a></li><li>wal_hook method - <a href="tclsqlite.html#wal_hook">tclsqlite.html#wal_hook</a></li><li>Warranty of Title - <a href="copyright.html#warrantyoftitle">copyright.html#warrantyoftitle</a></li><li>What If OpenOffice Used SQLite - <a href="affcase1.html">affcase1.html</a></li><li>when to use WITHOUT ROWID - <a href="withoutrowid.html#wtu">withoutrowid.html#wtu</a></li><li>WHERE clause - <a href="lang_select.html#whereclause">lang_select.html#whereclause</a></li><li>WHERE-clause push-down optimization - <a href="optoverview.html#pushdown">optoverview.html#pushdown</a></li><li>why ALTER TABLE is so difficult - <a href="lang_altertable.html#altertableishard">lang_altertable.html#altertableishard</a></li><li>Why SQLite Uses Bytecode - <a href="whybytecode.html">whybytecode.html</a></li><li>Win32 native memory allocator - <a href="malloc.html#win32heap">malloc.html#win32heap</a></li><li>window chaining - <a href="windowfunctions.html#wchaining">windowfunctions.html#wchaining</a></li><li>window function - <a href="windowfunctions.html">windowfunctions.html</a></li><li>Window functions - <a href="windowfunctions.html">windowfunctions.html</a></li><li>window functions - <a href="windowfunctions.html">windowfunctions.html</a></li><li>window-defn - <a href="syntax/window-defn.html">syntax/window-defn.html</a></li><li>window-defn syntax diagram - <a href="syntax/window-defn.html">syntax/window-defn.html</a></li><li>window-function-invocation - <a href="syntax/window-function-invocation.html">syntax/window-function-invocation.html</a></li><li>window-function-invocation syntax diagram - <a href="syntax/window-function-invocation.html">syntax/window-function-invocation.html</a></li><li>winfunc - <a href="windowfunctions.html">windowfunctions.html</a></li><li>WITH - <a href="lang_with.html">lang_with.html</a></li><li>with - <a href="lang_with.html">lang_with.html</a></li><li>WITH clause - <a href="lang_with.html">lang_with.html</a></li><li>with-clause - <a href="syntax/with-clause.html">syntax/with-clause.html</a></li><li>with-clause syntax diagram - <a href="syntax/with-clause.html">syntax/with-clause.html</a></li><li>WITHOUT ROWID - <a href="withoutrowid.html">withoutrowid.html</a></li><li>WITHOUT rowid - <a href="withoutrowid.html">withoutrowid.html</a></li><li>WITHOUT ROWID virtual table - <a href="vtab.html#worid">vtab.html#worid</a></li><li>WITHOUT ROWID virtual tables - <a href="vtab.html#worid">vtab.html#worid</a></li><li>wrapping text - <a href="cli.html#wrap1">cli.html#wrap1</a></li><li>writable_schema - <a href="pragma.html#pragma_writable_schema">pragma.html#pragma_writable_schema</a></li><li>writable_schema pragma - <a href="pragma.html#pragma_writable_schema">pragma.html#pragma_writable_schema</a></li><li>write-ahead log - <a href="wal.html">wal.html</a></li><li>writer starvation - <a href="lockingv3.html#writer_starvation">lockingv3.html#writer_starvation</a></li><li>xBegin - <a href="vtab.html#xBegin">vtab.html#xBegin</a></li><li>xBestIndex - <a href="vtab.html#xbestindex">vtab.html#xbestindex</a></li><li>xColumn - <a href="vtab.html#xcolumn">vtab.html#xcolumn</a></li><li>xCommit - <a href="vtab.html#xcommit">vtab.html#xcommit</a></li><li>xConnect - <a href="vtab.html#xconnect">vtab.html#xconnect</a></li><li>xCreate - <a href="vtab.html#xcreate">vtab.html#xcreate</a></li><li>xDestroy - <a href="vtab.html#sqlite3_module.xDestroy">vtab.html#sqlite3_module.xDestroy</a></li><li>xDisconnect - <a href="vtab.html#xdisconnect">vtab.html#xdisconnect</a></li><li>xEof - <a href="vtab.html#xeof">vtab.html#xeof</a></li><li>xFilter - <a href="vtab.html#xfilter">vtab.html#xfilter</a></li><li>xFindFunction - <a href="vtab.html#xfindfunction">vtab.html#xfindfunction</a></li><li>xIntegrity - <a href="vtab.html#xintegrity">vtab.html#xintegrity</a></li><li>xIntegrity method - <a href="vtab.html#xintegrity">vtab.html#xintegrity</a></li><li>xNext - <a href="vtab.html#xnext">vtab.html#xnext</a></li><li>xQueryFunc RTree callback - <a href="rtree.html#xquery">rtree.html#xquery</a></li><li>xRelease - <a href="vtab.html#xsavepoint">vtab.html#xsavepoint</a></li><li>xRename - <a href="vtab.html#xrename">vtab.html#xrename</a></li><li>xRollback - <a href="vtab.html#xrollback">vtab.html#xrollback</a></li><li>xRollbackTo - <a href="vtab.html#xsavepoint">vtab.html#xsavepoint</a></li><li>xRowid - <a href="vtab.html#xrowid">vtab.html#xrowid</a></li><li>xSavepoint - <a href="vtab.html#xsavepoint">vtab.html#xsavepoint</a></li><li>xShadowName - <a href="vtab.html#xshadowname">vtab.html#xshadowname</a></li><li>xUpdate - <a href="vtab.html#xupdate">vtab.html#xupdate</a></li><li>YYSTACKDEPTH - <a href="compile.html#yystackdepth">compile.html#yystackdepth</a></li><li>YYTRACKMAXSTACKDEPTH - <a href="compile.html#yytrackmaxstackdepth">compile.html#yytrackmaxstackdepth</a></li><li>z - <a href="printf.html#percentz">printf.html#percentz</a></li><li>zero-configuration - <a href="zeroconf.html">zeroconf.html</a></li><li>zero-malloc memory allocator - <a href="malloc.html#memsys5">malloc.html#memsys5</a></li><li>zeroblob - <a href="lang_corefunc.html#zeroblob">lang_corefunc.html#zeroblob</a></li><li>zeroblob SQL function - <a href="lang_corefunc.html#zeroblob">lang_corefunc.html#zeroblob</a></li><li>ZIP file as database - <a href="cli.html#zipdb">cli.html#zipdb</a></li><li>zipfile - <a href="zipfile.html">zipfile.html</a></li><li>Zipfile virtual table - <a href="zipfile.html">zipfile.html</a></li></ul><p align="center"><small><i>This page last modified on <a href="https://sqlite.org/docsrc/honeypot" id="mtimelink" data-href="https://sqlite.org/docsrc/finfo/wrap.tcl?m=08af34fe24">2023-03-31 19:57:15</a> UTC </small></i></p> diff --git a/www/doc_pagelink_crossref.html b/www/doc_pagelink_crossref.html index cb003a0..3208c37 100644 --- a/www/doc_pagelink_crossref.html +++ b/www/doc_pagelink_crossref.html @@ -376,7 +376,7 @@ antiRobotDefense(); <li><a href="c3ref/int64.html">c3ref/int64.html</a> → <a href="c3ref/c_config_covering_index_scan.html">c3ref/c_config_covering_index_scan.html</a> <a href="c3ref/c_fcntl_begin_atomic_write.html">c3ref/c_fcntl_begin_atomic_write.html</a> <a href="c3ref/c_scanstat_est.html">c3ref/c_scanstat_est.html</a> <a href="c3ref/objlist.html">c3ref/objlist.html</a> <a href="capi3ref.html">capi3ref.html</a> <a href="keyword_index.html">keyword_index.html</a> <a href="windowfunctions.html">windowfunctions.html</a> </li> <li><a href="c3ref/interrupt.html">c3ref/interrupt.html</a> → -<a href="arch.html">arch.html</a> <a href="c3ref/funclist.html">c3ref/funclist.html</a> <a href="c3ref/sqlite3.html">c3ref/sqlite3.html</a> <a href="capi3ref.html">capi3ref.html</a> <a href="keyword_index.html">keyword_index.html</a> <a href="pragma.html">pragma.html</a> <a href="rescode.html">rescode.html</a> <a href="security.html">security.html</a> <a href="tclsqlite.html">tclsqlite.html</a> </li> +<a href="arch.html">arch.html</a> <a href="c3ref/funclist.html">c3ref/funclist.html</a> <a href="c3ref/sqlite3.html">c3ref/sqlite3.html</a> <a href="capi3ref.html">capi3ref.html</a> <a href="keyword_index.html">keyword_index.html</a> <a href="rescode.html">rescode.html</a> <a href="security.html">security.html</a> <a href="tclsqlite.html">tclsqlite.html</a> </li> <li><a href="c3ref/intro.html">c3ref/intro.html</a> → <a href="about.html">about.html</a> <a href="arch.html">arch.html</a> <a href="c3ref/aggregate_context.html">c3ref/aggregate_context.html</a> <a href="c3ref/aggregate_count.html">c3ref/aggregate_count.html</a> <a href="c3ref/api_routines.html">c3ref/api_routines.html</a> <a href="c3ref/auto_extension.html">c3ref/auto_extension.html</a> <a href="c3ref/autovacuum_pages.html">c3ref/autovacuum_pages.html</a> <a href="c3ref/backup.html">c3ref/backup.html</a> <a href="c3ref/backup_finish.html">c3ref/backup_finish.html</a> <a href="c3ref/bind_blob.html">c3ref/bind_blob.html</a> <a href="c3ref/bind_parameter_count.html">c3ref/bind_parameter_count.html</a> <a href="c3ref/bind_parameter_index.html">c3ref/bind_parameter_index.html</a> <a href="c3ref/bind_parameter_name.html">c3ref/bind_parameter_name.html</a> <a href="c3ref/blob.html">c3ref/blob.html</a> <a href="c3ref/blob_bytes.html">c3ref/blob_bytes.html</a> <a href="c3ref/blob_close.html">c3ref/blob_close.html</a> <a href="c3ref/blob_open.html">c3ref/blob_open.html</a> <a href="c3ref/blob_read.html">c3ref/blob_read.html</a> <a href="c3ref/blob_reopen.html">c3ref/blob_reopen.html</a> <a href="c3ref/blob_write.html">c3ref/blob_write.html</a> <a href="c3ref/busy_handler.html">c3ref/busy_handler.html</a> <a href="c3ref/busy_timeout.html">c3ref/busy_timeout.html</a> <a href="c3ref/c_abort.html">c3ref/c_abort.html</a> <a href="c3ref/c_abort_rollback.html">c3ref/c_abort_rollback.html</a> <a href="c3ref/c_access_exists.html">c3ref/c_access_exists.html</a> <a href="c3ref/c_alter_table.html">c3ref/c_alter_table.html</a> <a href="c3ref/c_any.html">c3ref/c_any.html</a> <a href="c3ref/c_blob.html">c3ref/c_blob.html</a> <a href="c3ref/c_checkpoint_full.html">c3ref/c_checkpoint_full.html</a> <a href="c3ref/c_config_covering_index_scan.html">c3ref/c_config_covering_index_scan.html</a> <a href="c3ref/c_dbconfig_defensive.html">c3ref/c_dbconfig_defensive.html</a> <a href="c3ref/c_dbstatus_options.html">c3ref/c_dbstatus_options.html</a> <a href="c3ref/c_deny.html">c3ref/c_deny.html</a> <a href="c3ref/c_deserialize_freeonclose.html">c3ref/c_deserialize_freeonclose.html</a> <a href="c3ref/c_deterministic.html">c3ref/c_deterministic.html</a> <a href="c3ref/c_fail.html">c3ref/c_fail.html</a> <a href="c3ref/c_fcntl_begin_atomic_write.html">c3ref/c_fcntl_begin_atomic_write.html</a> <a href="c3ref/c_index_constraint_eq.html">c3ref/c_index_constraint_eq.html</a> <a href="c3ref/c_index_scan_unique.html">c3ref/c_index_scan_unique.html</a> <a href="c3ref/c_iocap_atomic.html">c3ref/c_iocap_atomic.html</a> <a href="c3ref/c_limit_attached.html">c3ref/c_limit_attached.html</a> <a href="c3ref/c_lock_exclusive.html">c3ref/c_lock_exclusive.html</a> <a href="c3ref/c_mutex_fast.html">c3ref/c_mutex_fast.html</a> <a href="c3ref/c_open_autoproxy.html">c3ref/c_open_autoproxy.html</a> <a href="c3ref/c_prepare_normalize.html">c3ref/c_prepare_normalize.html</a> <a href="c3ref/c_scanstat_complex.html">c3ref/c_scanstat_complex.html</a> <a href="c3ref/c_scanstat_est.html">c3ref/c_scanstat_est.html</a> <a href="c3ref/c_serialize_nocopy.html">c3ref/c_serialize_nocopy.html</a> <a href="c3ref/c_shm_exclusive.html">c3ref/c_shm_exclusive.html</a> <a href="c3ref/c_shm_nlock.html">c3ref/c_shm_nlock.html</a> <a href="c3ref/c_source_id.html">c3ref/c_source_id.html</a> <a href="c3ref/c_static.html">c3ref/c_static.html</a> <a href="c3ref/c_status_malloc_count.html">c3ref/c_status_malloc_count.html</a> <a href="c3ref/c_stmtstatus_counter.html">c3ref/c_stmtstatus_counter.html</a> <a href="c3ref/c_sync_dataonly.html">c3ref/c_sync_dataonly.html</a> <a href="c3ref/c_testctrl_always.html">c3ref/c_testctrl_always.html</a> <a href="c3ref/c_trace.html">c3ref/c_trace.html</a> <a href="c3ref/c_txn_none.html">c3ref/c_txn_none.html</a> <a href="c3ref/c_vtab_constraint_support.html">c3ref/c_vtab_constraint_support.html</a> <a href="c3ref/c_win32_data_directory_type.html">c3ref/c_win32_data_directory_type.html</a> <a href="c3ref/cancel_auto_extension.html">c3ref/cancel_auto_extension.html</a> <a href="c3ref/clear_bindings.html">c3ref/clear_bindings.html</a> <a href="c3ref/close.html">c3ref/close.html</a> <a href="c3ref/collation_needed.html">c3ref/collation_needed.html</a> <a href="c3ref/column_blob.html">c3ref/column_blob.html</a> <a href="c3ref/column_count.html">c3ref/column_count.html</a> <a href="c3ref/column_database_name.html">c3ref/column_database_name.html</a> <a href="c3ref/column_decltype.html">c3ref/column_decltype.html</a> <a href="c3ref/column_name.html">c3ref/column_name.html</a> <a href="c3ref/commit_hook.html">c3ref/commit_hook.html</a> <a href="c3ref/compileoption_get.html">c3ref/compileoption_get.html</a> <a href="c3ref/complete.html">c3ref/complete.html</a> <a href="c3ref/config.html">c3ref/config.html</a> <a href="c3ref/constlist.html">c3ref/constlist.html</a> <a href="c3ref/context.html">c3ref/context.html</a> <a href="c3ref/context_db_handle.html">c3ref/context_db_handle.html</a> <a href="c3ref/create_collation.html">c3ref/create_collation.html</a> <a href="c3ref/create_filename.html">c3ref/create_filename.html</a> <a href="c3ref/create_function.html">c3ref/create_function.html</a> <a href="c3ref/create_module.html">c3ref/create_module.html</a> <a href="c3ref/data_count.html">c3ref/data_count.html</a> <a href="c3ref/data_directory.html">c3ref/data_directory.html</a> <a href="c3ref/database_file_object.html">c3ref/database_file_object.html</a> <a href="c3ref/db_cacheflush.html">c3ref/db_cacheflush.html</a> <a href="c3ref/db_config.html">c3ref/db_config.html</a> <a href="c3ref/db_filename.html">c3ref/db_filename.html</a> <a href="c3ref/db_handle.html">c3ref/db_handle.html</a> <a href="c3ref/db_mutex.html">c3ref/db_mutex.html</a> <a href="c3ref/db_name.html">c3ref/db_name.html</a> <a href="c3ref/db_readonly.html">c3ref/db_readonly.html</a> <a href="c3ref/db_release_memory.html">c3ref/db_release_memory.html</a> <a href="c3ref/db_status.html">c3ref/db_status.html</a> <a href="c3ref/declare_vtab.html">c3ref/declare_vtab.html</a> <a href="c3ref/deserialize.html">c3ref/deserialize.html</a> <a href="c3ref/drop_modules.html">c3ref/drop_modules.html</a> <a href="c3ref/enable_load_extension.html">c3ref/enable_load_extension.html</a> <a href="c3ref/enable_shared_cache.html">c3ref/enable_shared_cache.html</a> <a href="c3ref/errcode.html">c3ref/errcode.html</a> <a href="c3ref/exec.html">c3ref/exec.html</a> <a href="c3ref/expanded_sql.html">c3ref/expanded_sql.html</a> <a href="c3ref/experimental.html">c3ref/experimental.html</a> <a href="c3ref/extended_result_codes.html">c3ref/extended_result_codes.html</a> <a href="c3ref/file.html">c3ref/file.html</a> <a href="c3ref/file_control.html">c3ref/file_control.html</a> <a href="c3ref/filename.html">c3ref/filename.html</a> <a href="c3ref/filename_database.html">c3ref/filename_database.html</a> <a href="c3ref/finalize.html">c3ref/finalize.html</a> <a href="c3ref/free.html">c3ref/free.html</a> <a href="c3ref/free_table.html">c3ref/free_table.html</a> <a href="c3ref/funclist.html">c3ref/funclist.html</a> <a href="c3ref/get_autocommit.html">c3ref/get_autocommit.html</a> <a href="c3ref/get_auxdata.html">c3ref/get_auxdata.html</a> <a href="c3ref/get_clientdata.html">c3ref/get_clientdata.html</a> <a href="c3ref/hard_heap_limit64.html">c3ref/hard_heap_limit64.html</a> <a href="c3ref/index_info.html">c3ref/index_info.html</a> <a href="c3ref/initialize.html">c3ref/initialize.html</a> <a href="c3ref/int64.html">c3ref/int64.html</a> <a href="c3ref/interrupt.html">c3ref/interrupt.html</a> <a href="c3ref/io_methods.html">c3ref/io_methods.html</a> <a href="c3ref/keyword_check.html">c3ref/keyword_check.html</a> <a href="c3ref/last_insert_rowid.html">c3ref/last_insert_rowid.html</a> <a href="c3ref/libversion.html">c3ref/libversion.html</a> <a href="c3ref/limit.html">c3ref/limit.html</a> <a href="c3ref/load_extension.html">c3ref/load_extension.html</a> <a href="c3ref/log.html">c3ref/log.html</a> <a href="c3ref/mem_methods.html">c3ref/mem_methods.html</a> <a href="c3ref/memory_highwater.html">c3ref/memory_highwater.html</a> <a href="c3ref/module.html">c3ref/module.html</a> <a href="c3ref/mprintf.html">c3ref/mprintf.html</a> <a href="c3ref/mutex.html">c3ref/mutex.html</a> <a href="c3ref/mutex_alloc.html">c3ref/mutex_alloc.html</a> <a href="c3ref/mutex_held.html">c3ref/mutex_held.html</a> <a href="c3ref/mutex_methods.html">c3ref/mutex_methods.html</a> <a href="c3ref/next_stmt.html">c3ref/next_stmt.html</a> <a href="c3ref/objlist.html">c3ref/objlist.html</a> <a href="c3ref/open.html">c3ref/open.html</a> <a href="c3ref/overload_function.html">c3ref/overload_function.html</a> <a href="c3ref/pcache.html">c3ref/pcache.html</a> <a href="c3ref/pcache_methods2.html">c3ref/pcache_methods2.html</a> <a href="c3ref/pcache_page.html">c3ref/pcache_page.html</a> <a href="c3ref/prepare.html">c3ref/prepare.html</a> <a href="c3ref/preupdate_blobwrite.html">c3ref/preupdate_blobwrite.html</a> <a href="c3ref/profile.html">c3ref/profile.html</a> <a href="c3ref/progress_handler.html">c3ref/progress_handler.html</a> <a href="c3ref/randomness.html">c3ref/randomness.html</a> <a href="c3ref/release_memory.html">c3ref/release_memory.html</a> <a href="c3ref/reset.html">c3ref/reset.html</a> <a href="c3ref/reset_auto_extension.html">c3ref/reset_auto_extension.html</a> <a href="c3ref/result_blob.html">c3ref/result_blob.html</a> <a href="c3ref/result_subtype.html">c3ref/result_subtype.html</a> <a href="c3ref/serialize.html">c3ref/serialize.html</a> <a href="c3ref/set_authorizer.html">c3ref/set_authorizer.html</a> <a href="c3ref/set_last_insert_rowid.html">c3ref/set_last_insert_rowid.html</a> <a href="c3ref/sleep.html">c3ref/sleep.html</a> <a href="c3ref/snapshot.html">c3ref/snapshot.html</a> <a href="c3ref/snapshot_cmp.html">c3ref/snapshot_cmp.html</a> <a href="c3ref/snapshot_free.html">c3ref/snapshot_free.html</a> <a href="c3ref/snapshot_get.html">c3ref/snapshot_get.html</a> <a href="c3ref/snapshot_open.html">c3ref/snapshot_open.html</a> <a href="c3ref/snapshot_recover.html">c3ref/snapshot_recover.html</a> <a href="c3ref/soft_heap_limit.html">c3ref/soft_heap_limit.html</a> <a href="c3ref/sqlite3.html">c3ref/sqlite3.html</a> <a href="c3ref/status.html">c3ref/status.html</a> <a href="c3ref/step.html">c3ref/step.html</a> <a href="c3ref/stmt.html">c3ref/stmt.html</a> <a href="c3ref/stmt_busy.html">c3ref/stmt_busy.html</a> <a href="c3ref/stmt_explain.html">c3ref/stmt_explain.html</a> <a href="c3ref/stmt_isexplain.html">c3ref/stmt_isexplain.html</a> <a href="c3ref/stmt_readonly.html">c3ref/stmt_readonly.html</a> <a href="c3ref/stmt_scanstatus.html">c3ref/stmt_scanstatus.html</a> <a href="c3ref/stmt_scanstatus_reset.html">c3ref/stmt_scanstatus_reset.html</a> <a href="c3ref/stmt_status.html">c3ref/stmt_status.html</a> <a href="c3ref/str.html">c3ref/str.html</a> <a href="c3ref/str_append.html">c3ref/str_append.html</a> <a href="c3ref/str_errcode.html">c3ref/str_errcode.html</a> <a href="c3ref/str_finish.html">c3ref/str_finish.html</a> <a href="c3ref/str_new.html">c3ref/str_new.html</a> <a href="c3ref/strglob.html">c3ref/strglob.html</a> <a href="c3ref/stricmp.html">c3ref/stricmp.html</a> <a href="c3ref/strlike.html">c3ref/strlike.html</a> <a href="c3ref/system_errno.html">c3ref/system_errno.html</a> <a href="c3ref/table_column_metadata.html">c3ref/table_column_metadata.html</a> <a href="c3ref/temp_directory.html">c3ref/temp_directory.html</a> <a href="c3ref/test_control.html">c3ref/test_control.html</a> <a href="c3ref/threadsafe.html">c3ref/threadsafe.html</a> <a href="c3ref/trace_v2.html">c3ref/trace_v2.html</a> <a href="c3ref/txn_state.html">c3ref/txn_state.html</a> <a href="c3ref/unlock_notify.html">c3ref/unlock_notify.html</a> <a href="c3ref/update_hook.html">c3ref/update_hook.html</a> <a href="c3ref/uri_boolean.html">c3ref/uri_boolean.html</a> <a href="c3ref/user_data.html">c3ref/user_data.html</a> <a href="c3ref/value.html">c3ref/value.html</a> <a href="c3ref/value_blob.html">c3ref/value_blob.html</a> <a href="c3ref/value_dup.html">c3ref/value_dup.html</a> <a href="c3ref/value_encoding.html">c3ref/value_encoding.html</a> <a href="c3ref/value_subtype.html">c3ref/value_subtype.html</a> <a href="c3ref/vfs.html">c3ref/vfs.html</a> <a href="c3ref/vfs_find.html">c3ref/vfs_find.html</a> <a href="c3ref/vtab.html">c3ref/vtab.html</a> <a href="c3ref/vtab_collation.html">c3ref/vtab_collation.html</a> <a href="c3ref/vtab_config.html">c3ref/vtab_config.html</a> <a href="c3ref/vtab_cursor.html">c3ref/vtab_cursor.html</a> <a href="c3ref/vtab_distinct.html">c3ref/vtab_distinct.html</a> <a href="c3ref/vtab_in.html">c3ref/vtab_in.html</a> <a href="c3ref/vtab_in_first.html">c3ref/vtab_in_first.html</a> <a href="c3ref/vtab_nochange.html">c3ref/vtab_nochange.html</a> <a href="c3ref/vtab_on_conflict.html">c3ref/vtab_on_conflict.html</a> <a href="c3ref/vtab_rhs_value.html">c3ref/vtab_rhs_value.html</a> <a href="c3ref/wal_autocheckpoint.html">c3ref/wal_autocheckpoint.html</a> <a href="c3ref/wal_checkpoint.html">c3ref/wal_checkpoint.html</a> <a href="c3ref/wal_checkpoint_v2.html">c3ref/wal_checkpoint_v2.html</a> <a href="c3ref/wal_hook.html">c3ref/wal_hook.html</a> <a href="c3ref/win32_set_directory.html">c3ref/win32_set_directory.html</a> <a href="capi3.html">capi3.html</a> <a href="capi3ref.html">capi3ref.html</a> <a href="cintro.html">cintro.html</a> <a href="docs.html">docs.html</a> <a href="index.html">index.html</a> <a href="keyword_index.html">keyword_index.html</a> <a href="quickstart.html">quickstart.html</a> <a href="rescode.html">rescode.html</a> </li> <li><a href="c3ref/io_methods.html">c3ref/io_methods.html</a> → @@ -424,11 +424,11 @@ antiRobotDefense(); <li><a href="c3ref/pcache_page.html">c3ref/pcache_page.html</a> → <a href="c3ref/objlist.html">c3ref/objlist.html</a> <a href="capi3ref.html">capi3ref.html</a> <a href="keyword_index.html">keyword_index.html</a> </li> <li><a href="c3ref/prepare.html">c3ref/prepare.html</a> → -<a href="arch.html">arch.html</a> <a href="c3ref/bind_blob.html">c3ref/bind_blob.html</a> <a href="c3ref/bind_parameter_index.html">c3ref/bind_parameter_index.html</a> <a href="c3ref/bind_parameter_name.html">c3ref/bind_parameter_name.html</a> <a href="c3ref/c_limit_attached.html">c3ref/c_limit_attached.html</a> <a href="c3ref/c_prepare_normalize.html">c3ref/c_prepare_normalize.html</a> <a href="c3ref/column_blob.html">c3ref/column_blob.html</a> <a href="c3ref/commit_hook.html">c3ref/commit_hook.html</a> <a href="c3ref/db_handle.html">c3ref/db_handle.html</a> <a href="c3ref/exec.html">c3ref/exec.html</a> <a href="c3ref/expanded_sql.html">c3ref/expanded_sql.html</a> <a href="c3ref/funclist.html">c3ref/funclist.html</a> <a href="c3ref/progress_handler.html">c3ref/progress_handler.html</a> <a href="c3ref/set_authorizer.html">c3ref/set_authorizer.html</a> <a href="c3ref/sqlite3.html">c3ref/sqlite3.html</a> <a href="c3ref/step.html">c3ref/step.html</a> <a href="c3ref/stmt.html">c3ref/stmt.html</a> <a href="c3ref/stmt_explain.html">c3ref/stmt_explain.html</a> <a href="c3ref/update_hook.html">c3ref/update_hook.html</a> <a href="capi3.html">capi3.html</a> <a href="capi3ref.html">capi3ref.html</a> <a href="cintro.html">cintro.html</a> <a href="cli.html">cli.html</a> <a href="compile.html">compile.html</a> <a href="errlog.html">errlog.html</a> <a href="faq.html">faq.html</a> <a href="keyword_index.html">keyword_index.html</a> <a href="lang.html">lang.html</a> <a href="lang_comment.html">lang_comment.html</a> <a href="lang_explain.html">lang_explain.html</a> <a href="limits.html">limits.html</a> <a href="malloc.html">malloc.html</a> <a href="opcode.html">opcode.html</a> <a href="optoverview.html">optoverview.html</a> <a href="pragma.html">pragma.html</a> <a href="queryplanner-ng.html">queryplanner-ng.html</a> <a href="rescode.html">rescode.html</a> <a href="stmt.html">stmt.html</a> <a href="tclsqlite.html">tclsqlite.html</a> <a href="unlock_notify.html">unlock_notify.html</a> <a href="vfs.html">vfs.html</a> <a href="vtab.html">vtab.html</a> </li> +<a href="arch.html">arch.html</a> <a href="c3ref/bind_blob.html">c3ref/bind_blob.html</a> <a href="c3ref/bind_parameter_index.html">c3ref/bind_parameter_index.html</a> <a href="c3ref/bind_parameter_name.html">c3ref/bind_parameter_name.html</a> <a href="c3ref/c_limit_attached.html">c3ref/c_limit_attached.html</a> <a href="c3ref/c_prepare_normalize.html">c3ref/c_prepare_normalize.html</a> <a href="c3ref/column_blob.html">c3ref/column_blob.html</a> <a href="c3ref/commit_hook.html">c3ref/commit_hook.html</a> <a href="c3ref/db_handle.html">c3ref/db_handle.html</a> <a href="c3ref/exec.html">c3ref/exec.html</a> <a href="c3ref/expanded_sql.html">c3ref/expanded_sql.html</a> <a href="c3ref/funclist.html">c3ref/funclist.html</a> <a href="c3ref/progress_handler.html">c3ref/progress_handler.html</a> <a href="c3ref/set_authorizer.html">c3ref/set_authorizer.html</a> <a href="c3ref/sqlite3.html">c3ref/sqlite3.html</a> <a href="c3ref/step.html">c3ref/step.html</a> <a href="c3ref/stmt.html">c3ref/stmt.html</a> <a href="c3ref/stmt_explain.html">c3ref/stmt_explain.html</a> <a href="c3ref/update_hook.html">c3ref/update_hook.html</a> <a href="capi3.html">capi3.html</a> <a href="capi3ref.html">capi3ref.html</a> <a href="cintro.html">cintro.html</a> <a href="cli.html">cli.html</a> <a href="compile.html">compile.html</a> <a href="errlog.html">errlog.html</a> <a href="faq.html">faq.html</a> <a href="keyword_index.html">keyword_index.html</a> <a href="lang.html">lang.html</a> <a href="lang_comment.html">lang_comment.html</a> <a href="lang_explain.html">lang_explain.html</a> <a href="limits.html">limits.html</a> <a href="malloc.html">malloc.html</a> <a href="opcode.html">opcode.html</a> <a href="optoverview.html">optoverview.html</a> <a href="pragma.html">pragma.html</a> <a href="queryplanner-ng.html">queryplanner-ng.html</a> <a href="rescode.html">rescode.html</a> <a href="stmt.html">stmt.html</a> <a href="tclsqlite.html">tclsqlite.html</a> <a href="unlock_notify.html">unlock_notify.html</a> <a href="vfs.html">vfs.html</a> <a href="vtab.html">vtab.html</a> <a href="whybytecode.html">whybytecode.html</a> </li> <li><a href="c3ref/preupdate_blobwrite.html">c3ref/preupdate_blobwrite.html</a> → <a href="c3ref/funclist.html">c3ref/funclist.html</a> <a href="c3ref/sqlite3.html">c3ref/sqlite3.html</a> <a href="c3ref/update_hook.html">c3ref/update_hook.html</a> <a href="capi3ref.html">capi3ref.html</a> <a href="compile.html">compile.html</a> <a href="keyword_index.html">keyword_index.html</a> <a href="session.html">session.html</a> <a href="session/sqlite3session_create.html">session/sqlite3session_create.html</a> </li> <li><a href="c3ref/profile.html">c3ref/profile.html</a> → -<a href="c3ref/c_trace.html">c3ref/c_trace.html</a> <a href="c3ref/funclist.html">c3ref/funclist.html</a> <a href="c3ref/sqlite3.html">c3ref/sqlite3.html</a> <a href="c3ref/trace_v2.html">c3ref/trace_v2.html</a> <a href="capi3ref.html">capi3ref.html</a> <a href="compile.html">compile.html</a> <a href="keyword_index.html">keyword_index.html</a> </li> +<a href="c3ref/c_trace.html">c3ref/c_trace.html</a> <a href="c3ref/trace_v2.html">c3ref/trace_v2.html</a> <a href="capi3ref.html">capi3ref.html</a> <a href="compile.html">compile.html</a> <a href="keyword_index.html">keyword_index.html</a> </li> <li><a href="c3ref/progress_handler.html">c3ref/progress_handler.html</a> → <a href="c3ref/funclist.html">c3ref/funclist.html</a> <a href="c3ref/sqlite3.html">c3ref/sqlite3.html</a> <a href="capi3ref.html">capi3ref.html</a> <a href="compile.html">compile.html</a> <a href="keyword_index.html">keyword_index.html</a> <a href="security.html">security.html</a> </li> <li><a href="c3ref/randomness.html">c3ref/randomness.html</a> → @@ -472,7 +472,7 @@ antiRobotDefense(); <li><a href="c3ref/step.html">c3ref/step.html</a> → <a href="arch.html">arch.html</a> <a href="backup.html">backup.html</a> <a href="c3ref/bind_blob.html">c3ref/bind_blob.html</a> <a href="c3ref/busy_timeout.html">c3ref/busy_timeout.html</a> <a href="c3ref/c_stmtstatus_counter.html">c3ref/c_stmtstatus_counter.html</a> <a href="c3ref/column_blob.html">c3ref/column_blob.html</a> <a href="c3ref/column_database_name.html">c3ref/column_database_name.html</a> <a href="c3ref/column_name.html">c3ref/column_name.html</a> <a href="c3ref/commit_hook.html">c3ref/commit_hook.html</a> <a href="c3ref/data_count.html">c3ref/data_count.html</a> <a href="c3ref/exec.html">c3ref/exec.html</a> <a href="c3ref/finalize.html">c3ref/finalize.html</a> <a href="c3ref/funclist.html">c3ref/funclist.html</a> <a href="c3ref/prepare.html">c3ref/prepare.html</a> <a href="c3ref/profile.html">c3ref/profile.html</a> <a href="c3ref/progress_handler.html">c3ref/progress_handler.html</a> <a href="c3ref/reset.html">c3ref/reset.html</a> <a href="c3ref/set_authorizer.html">c3ref/set_authorizer.html</a> <a href="c3ref/stmt.html">c3ref/stmt.html</a> <a href="c3ref/stmt_busy.html">c3ref/stmt_busy.html</a> <a href="c3ref/unlock_notify.html">c3ref/unlock_notify.html</a> <a href="c3ref/update_hook.html">c3ref/update_hook.html</a> <a href="capi3.html">capi3.html</a> <a href="capi3ref.html">capi3ref.html</a> <a href="cintro.html">cintro.html</a> <a href="compile.html">compile.html</a> <a href="eqp.html">eqp.html</a> <a href="errlog.html">errlog.html</a> <a href="faq.html">faq.html</a> <a href="isolation.html">isolation.html</a> <a href="keyword_index.html">keyword_index.html</a> <a href="lang_corefunc.html">lang_corefunc.html</a> <a href="lang_datefunc.html">lang_datefunc.html</a> <a href="lang_explain.html">lang_explain.html</a> <a href="lang_returning.html">lang_returning.html</a> <a href="malloc.html">malloc.html</a> <a href="opcode.html">opcode.html</a> <a href="optoverview.html">optoverview.html</a> <a href="pragma.html">pragma.html</a> <a href="rescode.html">rescode.html</a> <a href="stmt.html">stmt.html</a> <a href="unlock_notify.html">unlock_notify.html</a> <a href="vfs.html">vfs.html</a> </li> <li><a href="c3ref/stmt.html">c3ref/stmt.html</a> → -<a href="arch.html">arch.html</a> <a href="bytecodevtab.html">bytecodevtab.html</a> <a href="c3ref/bind_blob.html">c3ref/bind_blob.html</a> <a href="c3ref/bind_parameter_count.html">c3ref/bind_parameter_count.html</a> <a href="c3ref/bind_parameter_name.html">c3ref/bind_parameter_name.html</a> <a href="c3ref/busy_handler.html">c3ref/busy_handler.html</a> <a href="c3ref/c_config_covering_index_scan.html">c3ref/c_config_covering_index_scan.html</a> <a href="c3ref/c_limit_attached.html">c3ref/c_limit_attached.html</a> <a href="c3ref/c_trace.html">c3ref/c_trace.html</a> <a href="c3ref/clear_bindings.html">c3ref/clear_bindings.html</a> <a href="c3ref/close.html">c3ref/close.html</a> <a href="c3ref/column_blob.html">c3ref/column_blob.html</a> <a href="c3ref/column_count.html">c3ref/column_count.html</a> <a href="c3ref/column_database_name.html">c3ref/column_database_name.html</a> <a href="c3ref/column_decltype.html">c3ref/column_decltype.html</a> <a href="c3ref/column_name.html">c3ref/column_name.html</a> <a href="c3ref/data_count.html">c3ref/data_count.html</a> <a href="c3ref/db_handle.html">c3ref/db_handle.html</a> <a href="c3ref/expanded_sql.html">c3ref/expanded_sql.html</a> <a href="c3ref/finalize.html">c3ref/finalize.html</a> <a href="c3ref/intro.html">c3ref/intro.html</a> <a href="c3ref/next_stmt.html">c3ref/next_stmt.html</a> <a href="c3ref/objlist.html">c3ref/objlist.html</a> <a href="c3ref/prepare.html">c3ref/prepare.html</a> <a href="c3ref/reset.html">c3ref/reset.html</a> <a href="c3ref/set_authorizer.html">c3ref/set_authorizer.html</a> <a href="c3ref/step.html">c3ref/step.html</a> <a href="c3ref/stmt_busy.html">c3ref/stmt_busy.html</a> <a href="c3ref/stmt_explain.html">c3ref/stmt_explain.html</a> <a href="c3ref/stmt_readonly.html">c3ref/stmt_readonly.html</a> <a href="c3ref/stmt_status.html">c3ref/stmt_status.html</a> <a href="c3ref/value_blob.html">c3ref/value_blob.html</a> <a href="capi3ref.html">capi3ref.html</a> <a href="cintro.html">cintro.html</a> <a href="compile.html">compile.html</a> <a href="custombuild.html">custombuild.html</a> <a href="datatype3.html">datatype3.html</a> <a href="faq.html">faq.html</a> <a href="howitworks.html">howitworks.html</a> <a href="keyword_index.html">keyword_index.html</a> <a href="lang_explain.html">lang_explain.html</a> <a href="malloc.html">malloc.html</a> <a href="opcode.html">opcode.html</a> <a href="optoverview.html">optoverview.html</a> <a href="pragma.html">pragma.html</a> <a href="rescode.html">rescode.html</a> <a href="stmt.html">stmt.html</a> <a href="tclsqlite.html">tclsqlite.html</a> <a href="threadsafe.html">threadsafe.html</a> <a href="unlock_notify.html">unlock_notify.html</a> <a href="vfs.html">vfs.html</a> <a href="vtablist.html">vtablist.html</a> </li> +<a href="arch.html">arch.html</a> <a href="bytecodevtab.html">bytecodevtab.html</a> <a href="c3ref/bind_blob.html">c3ref/bind_blob.html</a> <a href="c3ref/bind_parameter_count.html">c3ref/bind_parameter_count.html</a> <a href="c3ref/bind_parameter_name.html">c3ref/bind_parameter_name.html</a> <a href="c3ref/busy_handler.html">c3ref/busy_handler.html</a> <a href="c3ref/c_config_covering_index_scan.html">c3ref/c_config_covering_index_scan.html</a> <a href="c3ref/c_limit_attached.html">c3ref/c_limit_attached.html</a> <a href="c3ref/c_trace.html">c3ref/c_trace.html</a> <a href="c3ref/clear_bindings.html">c3ref/clear_bindings.html</a> <a href="c3ref/close.html">c3ref/close.html</a> <a href="c3ref/column_blob.html">c3ref/column_blob.html</a> <a href="c3ref/column_count.html">c3ref/column_count.html</a> <a href="c3ref/column_database_name.html">c3ref/column_database_name.html</a> <a href="c3ref/column_decltype.html">c3ref/column_decltype.html</a> <a href="c3ref/column_name.html">c3ref/column_name.html</a> <a href="c3ref/data_count.html">c3ref/data_count.html</a> <a href="c3ref/db_handle.html">c3ref/db_handle.html</a> <a href="c3ref/expanded_sql.html">c3ref/expanded_sql.html</a> <a href="c3ref/finalize.html">c3ref/finalize.html</a> <a href="c3ref/intro.html">c3ref/intro.html</a> <a href="c3ref/next_stmt.html">c3ref/next_stmt.html</a> <a href="c3ref/objlist.html">c3ref/objlist.html</a> <a href="c3ref/prepare.html">c3ref/prepare.html</a> <a href="c3ref/reset.html">c3ref/reset.html</a> <a href="c3ref/set_authorizer.html">c3ref/set_authorizer.html</a> <a href="c3ref/step.html">c3ref/step.html</a> <a href="c3ref/stmt_busy.html">c3ref/stmt_busy.html</a> <a href="c3ref/stmt_explain.html">c3ref/stmt_explain.html</a> <a href="c3ref/stmt_readonly.html">c3ref/stmt_readonly.html</a> <a href="c3ref/stmt_status.html">c3ref/stmt_status.html</a> <a href="c3ref/value_blob.html">c3ref/value_blob.html</a> <a href="capi3ref.html">capi3ref.html</a> <a href="cintro.html">cintro.html</a> <a href="compile.html">compile.html</a> <a href="custombuild.html">custombuild.html</a> <a href="datatype3.html">datatype3.html</a> <a href="faq.html">faq.html</a> <a href="howitworks.html">howitworks.html</a> <a href="keyword_index.html">keyword_index.html</a> <a href="lang_explain.html">lang_explain.html</a> <a href="malloc.html">malloc.html</a> <a href="opcode.html">opcode.html</a> <a href="optoverview.html">optoverview.html</a> <a href="pragma.html">pragma.html</a> <a href="rescode.html">rescode.html</a> <a href="stmt.html">stmt.html</a> <a href="tclsqlite.html">tclsqlite.html</a> <a href="threadsafe.html">threadsafe.html</a> <a href="unlock_notify.html">unlock_notify.html</a> <a href="vfs.html">vfs.html</a> <a href="vtablist.html">vtablist.html</a> <a href="whybytecode.html">whybytecode.html</a> </li> <li><a href="c3ref/stmt_busy.html">c3ref/stmt_busy.html</a> → <a href="c3ref/funclist.html">c3ref/funclist.html</a> <a href="c3ref/stmt.html">c3ref/stmt.html</a> <a href="capi3ref.html">capi3ref.html</a> <a href="keyword_index.html">keyword_index.html</a> </li> <li><a href="c3ref/stmt_explain.html">c3ref/stmt_explain.html</a> → @@ -584,7 +584,7 @@ antiRobotDefense(); <li><a href="cksumvfs.html">cksumvfs.html</a> → <a href="c3ref/c_fcntl_begin_atomic_write.html">c3ref/c_fcntl_begin_atomic_write.html</a> <a href="capi3ref.html">capi3ref.html</a> <a href="doclist.html">doclist.html</a> <a href="keyword_index.html">keyword_index.html</a> <a href="rescode.html">rescode.html</a> <a href="sitemap.html">sitemap.html</a> </li> <li><a href="cli.html">cli.html</a> → -<a href="bytecodevtab.html">bytecodevtab.html</a> <a href="c3ref/c_deterministic.html">c3ref/c_deterministic.html</a> <a href="c_interface.html">c_interface.html</a> <a href="capi3ref.html">capi3ref.html</a> <a href="compile.html">compile.html</a> <a href="completion.html">completion.html</a> <a href="csv.html">csv.html</a> <a href="cves.html">cves.html</a> <a href="dbpage.html">dbpage.html</a> <a href="debugging.html">debugging.html</a> <a href="doclist.html">doclist.html</a> <a href="eqp.html">eqp.html</a> <a href="features.html">features.html</a> <a href="floatingpoint.html">floatingpoint.html</a> <a href="howtocompile.html">howtocompile.html</a> <a href="imposter.html">imposter.html</a> <a href="json1.html">json1.html</a> <a href="keyword_index.html">keyword_index.html</a> <a href="lang_with.html">lang_with.html</a> <a href="loadext.html">loadext.html</a> <a href="nulinstr.html">nulinstr.html</a> <a href="opcode.html">opcode.html</a> <a href="profile.html">profile.html</a> <a href="qmplan.html">qmplan.html</a> <a href="quickstart.html">quickstart.html</a> <a href="quirks.html">quirks.html</a> <a href="recovery.html">recovery.html</a> <a href="series.html">series.html</a> <a href="sitemap.html">sitemap.html</a> <a href="sqlanalyze.html">sqlanalyze.html</a> <a href="sqlar.html">sqlar.html</a> <a href="stmt.html">stmt.html</a> <a href="stricttables.html">stricttables.html</a> <a href="uintcseq.html">uintcseq.html</a> <a href="vfs.html">vfs.html</a> <a href="vtab.html">vtab.html</a> <a href="vtablist.html">vtablist.html</a> <a href="wal.html">wal.html</a> <a href="whentouse.html">whentouse.html</a> <a href="zipfile.html">zipfile.html</a> </li> +<a href="bytecodevtab.html">bytecodevtab.html</a> <a href="c3ref/c_deterministic.html">c3ref/c_deterministic.html</a> <a href="c_interface.html">c_interface.html</a> <a href="capi3ref.html">capi3ref.html</a> <a href="compile.html">compile.html</a> <a href="completion.html">completion.html</a> <a href="csv.html">csv.html</a> <a href="cves.html">cves.html</a> <a href="dbpage.html">dbpage.html</a> <a href="debugging.html">debugging.html</a> <a href="doclist.html">doclist.html</a> <a href="eqp.html">eqp.html</a> <a href="features.html">features.html</a> <a href="floatingpoint.html">floatingpoint.html</a> <a href="howtocompile.html">howtocompile.html</a> <a href="imposter.html">imposter.html</a> <a href="json1.html">json1.html</a> <a href="keyword_index.html">keyword_index.html</a> <a href="lang_analyze.html">lang_analyze.html</a> <a href="lang_with.html">lang_with.html</a> <a href="loadext.html">loadext.html</a> <a href="nulinstr.html">nulinstr.html</a> <a href="opcode.html">opcode.html</a> <a href="profile.html">profile.html</a> <a href="qmplan.html">qmplan.html</a> <a href="quickstart.html">quickstart.html</a> <a href="quirks.html">quirks.html</a> <a href="recovery.html">recovery.html</a> <a href="series.html">series.html</a> <a href="sitemap.html">sitemap.html</a> <a href="sqlanalyze.html">sqlanalyze.html</a> <a href="sqlar.html">sqlar.html</a> <a href="stmt.html">stmt.html</a> <a href="stricttables.html">stricttables.html</a> <a href="uintcseq.html">uintcseq.html</a> <a href="vfs.html">vfs.html</a> <a href="vtab.html">vtab.html</a> <a href="vtablist.html">vtablist.html</a> <a href="wal.html">wal.html</a> <a href="whentouse.html">whentouse.html</a> <a href="zipfile.html">zipfile.html</a> </li> <li><a href="codeofconduct.html">codeofconduct.html</a> → <a href="keyword_index.html">keyword_index.html</a> </li> <li><a href="codeofethics.html">codeofethics.html</a> → @@ -642,7 +642,7 @@ antiRobotDefense(); <li><a href="faq.html">faq.html</a> → <a href="doclist.html">doclist.html</a> <a href="docs.html">docs.html</a> <a href="index.html">index.html</a> <a href="sitemap.html">sitemap.html</a> </li> <li><a href="fasterthanfs.html">fasterthanfs.html</a> → -<a href="about.html">about.html</a> <a href="aff_short.html">aff_short.html</a> <a href="appfileformat.html">appfileformat.html</a> <a href="doclist.html">doclist.html</a> <a href="features.html">features.html</a> <a href="howitworks.html">howitworks.html</a> <a href="index.html">index.html</a> <a href="intern-v-extern-blob.html">intern-v-extern-blob.html</a> <a href="keyword_index.html">keyword_index.html</a> <a href="sitemap.html">sitemap.html</a> <a href="whentouse.html">whentouse.html</a> <a href="whyc.html">whyc.html</a> </li> +<a href="about.html">about.html</a> <a href="aff_short.html">aff_short.html</a> <a href="appfileformat.html">appfileformat.html</a> <a href="doclist.html">doclist.html</a> <a href="features.html">features.html</a> <a href="howitworks.html">howitworks.html</a> <a href="index.html">index.html</a> <a href="intern-v-extern-blob.html">intern-v-extern-blob.html</a> <a href="keyword_index.html">keyword_index.html</a> <a href="sitemap.html">sitemap.html</a> <a href="whentouse.html">whentouse.html</a> <a href="whybytecode.html">whybytecode.html</a> <a href="whyc.html">whyc.html</a> </li> <li><a href="features.html">features.html</a> → <a href="doclist.html">doclist.html</a> <a href="docs.html">docs.html</a> <a href="index.html">index.html</a> <a href="sitemap.html">sitemap.html</a> </li> <li><a href="fileformat.html">fileformat.html</a> → @@ -694,7 +694,7 @@ antiRobotDefense(); <li><a href="isolation.html">isolation.html</a> → <a href="doclist.html">doclist.html</a> <a href="keyword_index.html">keyword_index.html</a> <a href="sitemap.html">sitemap.html</a> <a href="useovernet.html">useovernet.html</a> </li> <li><a href="json1.html">json1.html</a> → -<a href="amalgamation.html">amalgamation.html</a> <a href="compile.html">compile.html</a> <a href="doclist.html">doclist.html</a> <a href="docs.html">docs.html</a> <a href="features.html">features.html</a> <a href="flextypegood.html">flextypegood.html</a> <a href="fullsql.html">fullsql.html</a> <a href="index.html">index.html</a> <a href="keyword_index.html">keyword_index.html</a> <a href="lang_aggfunc.html">lang_aggfunc.html</a> <a href="lang_corefunc.html">lang_corefunc.html</a> <a href="lang_expr.html">lang_expr.html</a> <a href="loadext.html">loadext.html</a> <a href="sitemap.html">sitemap.html</a> <a href="testing.html">testing.html</a> <a href="vtab.html">vtab.html</a> <a href="vtablist.html">vtablist.html</a> </li> +<a href="amalgamation.html">amalgamation.html</a> <a href="compile.html">compile.html</a> <a href="doclist.html">doclist.html</a> <a href="docs.html">docs.html</a> <a href="features.html">features.html</a> <a href="flextypegood.html">flextypegood.html</a> <a href="fullsql.html">fullsql.html</a> <a href="index.html">index.html</a> <a href="keyword_index.html">keyword_index.html</a> <a href="lang.html">lang.html</a> <a href="lang_aggfunc.html">lang_aggfunc.html</a> <a href="lang_corefunc.html">lang_corefunc.html</a> <a href="lang_expr.html">lang_expr.html</a> <a href="loadext.html">loadext.html</a> <a href="sitemap.html">sitemap.html</a> <a href="testing.html">testing.html</a> <a href="vtab.html">vtab.html</a> <a href="vtablist.html">vtablist.html</a> </li> <li><a href="keyword_index.html">keyword_index.html</a> → <a href="doclist.html">doclist.html</a> <a href="sitemap.html">sitemap.html</a> </li> <li><a href="lang.html">lang.html</a> → @@ -714,7 +714,7 @@ antiRobotDefense(); <li><a href="lang_corefunc.html">lang_corefunc.html</a> → <a href="arch.html">arch.html</a> <a href="bindptr.html">bindptr.html</a> <a href="c3ref/blob_open.html">c3ref/blob_open.html</a> <a href="c3ref/c_dbconfig_defensive.html">c3ref/c_dbconfig_defensive.html</a> <a href="c3ref/c_deterministic.html">c3ref/c_deterministic.html</a> <a href="c3ref/c_source_id.html">c3ref/c_source_id.html</a> <a href="c3ref/compileoption_get.html">c3ref/compileoption_get.html</a> <a href="c3ref/create_function.html">c3ref/create_function.html</a> <a href="c3ref/enable_load_extension.html">c3ref/enable_load_extension.html</a> <a href="c3ref/last_insert_rowid.html">c3ref/last_insert_rowid.html</a> <a href="c3ref/libversion.html">c3ref/libversion.html</a> <a href="c3ref/load_extension.html">c3ref/load_extension.html</a> <a href="c3ref/mprintf.html">c3ref/mprintf.html</a> <a href="capi3ref.html">capi3ref.html</a> <a href="cli.html">cli.html</a> <a href="compile.html">compile.html</a> <a href="deterministic.html">deterministic.html</a> <a href="doclist.html">doclist.html</a> <a href="docs.html">docs.html</a> <a href="expridx.html">expridx.html</a> <a href="faq.html">faq.html</a> <a href="fts3.html">fts3.html</a> <a href="fts5.html">fts5.html</a> <a href="fullsql.html">fullsql.html</a> <a href="howtocompile.html">howtocompile.html</a> <a href="index.html">index.html</a> <a href="invalidutf.html">invalidutf.html</a> <a href="keyword_index.html">keyword_index.html</a> <a href="lang.html">lang.html</a> <a href="lang_aggfunc.html">lang_aggfunc.html</a> <a href="lang_createindex.html">lang_createindex.html</a> <a href="lang_datefunc.html">lang_datefunc.html</a> <a href="lang_expr.html">lang_expr.html</a> <a href="lang_mathfunc.html">lang_mathfunc.html</a> <a href="loadext.html">loadext.html</a> <a href="nulinstr.html">nulinstr.html</a> <a href="optoverview.html">optoverview.html</a> <a href="pragma.html">pragma.html</a> <a href="printf.html">printf.html</a> <a href="queryplanner-ng.html">queryplanner-ng.html</a> <a href="security.html">security.html</a> <a href="sitemap.html">sitemap.html</a> <a href="syntaxdiagrams.html">syntaxdiagrams.html</a> <a href="tclsqlite.html">tclsqlite.html</a> <a href="undoredo.html">undoredo.html</a> <a href="windowfunctions.html">windowfunctions.html</a> <a href="withoutrowid.html">withoutrowid.html</a> </li> <li><a href="lang_createindex.html">lang_createindex.html</a> → -<a href="aff_short.html">aff_short.html</a> <a href="appfileformat.html">appfileformat.html</a> <a href="compile.html">compile.html</a> <a href="doclist.html">doclist.html</a> <a href="expridx.html">expridx.html</a> <a href="fileformat2.html">fileformat2.html</a> <a href="foreignkeys.html">foreignkeys.html</a> <a href="fullsql.html">fullsql.html</a> <a href="keyword_index.html">keyword_index.html</a> <a href="lang.html">lang.html</a> <a href="lang_altertable.html">lang_altertable.html</a> <a href="lang_dropindex.html">lang_dropindex.html</a> <a href="lang_upsert.html">lang_upsert.html</a> <a href="limits.html">limits.html</a> <a href="optoverview.html">optoverview.html</a> <a href="partialindex.html">partialindex.html</a> <a href="pragma.html">pragma.html</a> <a href="schematab.html">schematab.html</a> <a href="sitemap.html">sitemap.html</a> <a href="stricttables.html">stricttables.html</a> <a href="syntaxdiagrams.html">syntaxdiagrams.html</a> <a href="vtab.html">vtab.html</a> <a href="withoutrowid.html">withoutrowid.html</a> </li> +<a href="aff_short.html">aff_short.html</a> <a href="appfileformat.html">appfileformat.html</a> <a href="compile.html">compile.html</a> <a href="doclist.html">doclist.html</a> <a href="expridx.html">expridx.html</a> <a href="fileformat2.html">fileformat2.html</a> <a href="foreignkeys.html">foreignkeys.html</a> <a href="fullsql.html">fullsql.html</a> <a href="keyword_index.html">keyword_index.html</a> <a href="lang.html">lang.html</a> <a href="lang_altertable.html">lang_altertable.html</a> <a href="lang_analyze.html">lang_analyze.html</a> <a href="lang_dropindex.html">lang_dropindex.html</a> <a href="lang_upsert.html">lang_upsert.html</a> <a href="limits.html">limits.html</a> <a href="optoverview.html">optoverview.html</a> <a href="partialindex.html">partialindex.html</a> <a href="pragma.html">pragma.html</a> <a href="schematab.html">schematab.html</a> <a href="sitemap.html">sitemap.html</a> <a href="stricttables.html">stricttables.html</a> <a href="syntaxdiagrams.html">syntaxdiagrams.html</a> <a href="vtab.html">vtab.html</a> <a href="withoutrowid.html">withoutrowid.html</a> </li> <li><a href="lang_createtable.html">lang_createtable.html</a> → <a href="autoinc.html">autoinc.html</a> <a href="c3ref/blob_open.html">c3ref/blob_open.html</a> <a href="c3ref/c_deterministic.html">c3ref/c_deterministic.html</a> <a href="c3ref/last_insert_rowid.html">c3ref/last_insert_rowid.html</a> <a href="c3ref/preupdate_blobwrite.html">c3ref/preupdate_blobwrite.html</a> <a href="c3ref/randomness.html">c3ref/randomness.html</a> <a href="c3ref/table_column_metadata.html">c3ref/table_column_metadata.html</a> <a href="c3ref/update_hook.html">c3ref/update_hook.html</a> <a href="c3ref/vtab_collation.html">c3ref/vtab_collation.html</a> <a href="capi3ref.html">capi3ref.html</a> <a href="compile.html">compile.html</a> <a href="conflict.html">conflict.html</a> <a href="csv.html">csv.html</a> <a href="datatype3.html">datatype3.html</a> <a href="deterministic.html">deterministic.html</a> <a href="doclist.html">doclist.html</a> <a href="eqp.html">eqp.html</a> <a href="expridx.html">expridx.html</a> <a href="faq.html">faq.html</a> <a href="fileformat2.html">fileformat2.html</a> <a href="foreignkeys.html">foreignkeys.html</a> <a href="fts3.html">fts3.html</a> <a href="fts5.html">fts5.html</a> <a href="fullsql.html">fullsql.html</a> <a href="gencol.html">gencol.html</a> <a href="imposter.html">imposter.html</a> <a href="keyword_index.html">keyword_index.html</a> <a href="lang.html">lang.html</a> <a href="lang_altertable.html">lang_altertable.html</a> <a href="lang_conflict.html">lang_conflict.html</a> <a href="lang_corefunc.html">lang_corefunc.html</a> <a href="lang_createindex.html">lang_createindex.html</a> <a href="lang_createvtab.html">lang_createvtab.html</a> <a href="lang_droptable.html">lang_droptable.html</a> <a href="lang_expr.html">lang_expr.html</a> <a href="lang_indexedby.html">lang_indexedby.html</a> <a href="lang_insert.html">lang_insert.html</a> <a href="lang_vacuum.html">lang_vacuum.html</a> <a href="optoverview.html">optoverview.html</a> <a href="pragma.html">pragma.html</a> <a href="queryplanner.html">queryplanner.html</a> <a href="quirks.html">quirks.html</a> <a href="rbu.html">rbu.html</a> <a href="rescode.html">rescode.html</a> <a href="rowidtable.html">rowidtable.html</a> <a href="schematab.html">schematab.html</a> <a href="sitemap.html">sitemap.html</a> <a href="sqldiff.html">sqldiff.html</a> <a href="stricttables.html">stricttables.html</a> <a href="syntaxdiagrams.html">syntaxdiagrams.html</a> <a href="vtab.html">vtab.html</a> <a href="withoutrowid.html">withoutrowid.html</a> </li> <li><a href="lang_createtrigger.html">lang_createtrigger.html</a> → @@ -748,7 +748,7 @@ antiRobotDefense(); <li><a href="lang_keywords.html">lang_keywords.html</a> → <a href="doclist.html">doclist.html</a> <a href="keyword_index.html">keyword_index.html</a> <a href="lang.html">lang.html</a> <a href="sitemap.html">sitemap.html</a> </li> <li><a href="lang_mathfunc.html">lang_mathfunc.html</a> → -<a href="compile.html">compile.html</a> <a href="doclist.html">doclist.html</a> <a href="docs.html">docs.html</a> <a href="index.html">index.html</a> <a href="keyword_index.html">keyword_index.html</a> <a href="lang_corefunc.html">lang_corefunc.html</a> <a href="lang_expr.html">lang_expr.html</a> <a href="sitemap.html">sitemap.html</a> </li> +<a href="compile.html">compile.html</a> <a href="doclist.html">doclist.html</a> <a href="docs.html">docs.html</a> <a href="index.html">index.html</a> <a href="keyword_index.html">keyword_index.html</a> <a href="lang.html">lang.html</a> <a href="lang_corefunc.html">lang_corefunc.html</a> <a href="lang_expr.html">lang_expr.html</a> <a href="sitemap.html">sitemap.html</a> </li> <li><a href="lang_naming.html">lang_naming.html</a> → <a href="doclist.html">doclist.html</a> <a href="keyword_index.html">keyword_index.html</a> <a href="lang_dropview.html">lang_dropview.html</a> <a href="sitemap.html">sitemap.html</a> </li> <li><a href="lang_reindex.html">lang_reindex.html</a> → @@ -802,7 +802,7 @@ antiRobotDefense(); <li><a href="onefile.html">onefile.html</a> → <a href="doclist.html">doclist.html</a> <a href="features.html">features.html</a> <a href="sitemap.html">sitemap.html</a> </li> <li><a href="opcode.html">opcode.html</a> → -<a href="arch.html">arch.html</a> <a href="bytecodevtab.html">bytecodevtab.html</a> <a href="c3ref/progress_handler.html">c3ref/progress_handler.html</a> <a href="c3ref/vtab_distinct.html">c3ref/vtab_distinct.html</a> <a href="c3ref/vtab_in.html">c3ref/vtab_in.html</a> <a href="capi3ref.html">capi3ref.html</a> <a href="compile.html">compile.html</a> <a href="debugging.html">debugging.html</a> <a href="different.html">different.html</a> <a href="doclist.html">doclist.html</a> <a href="howitworks.html">howitworks.html</a> <a href="keyword_index.html">keyword_index.html</a> <a href="lang_corefunc.html">lang_corefunc.html</a> <a href="lang_explain.html">lang_explain.html</a> <a href="lts.html">lts.html</a> <a href="rowvalue.html">rowvalue.html</a> <a href="sitemap.html">sitemap.html</a> <a href="stmt.html">stmt.html</a> <a href="vdbe.html">vdbe.html</a> <a href="vtab.html">vtab.html</a> </li> +<a href="arch.html">arch.html</a> <a href="bytecodevtab.html">bytecodevtab.html</a> <a href="c3ref/progress_handler.html">c3ref/progress_handler.html</a> <a href="c3ref/vtab_distinct.html">c3ref/vtab_distinct.html</a> <a href="c3ref/vtab_in.html">c3ref/vtab_in.html</a> <a href="capi3ref.html">capi3ref.html</a> <a href="compile.html">compile.html</a> <a href="debugging.html">debugging.html</a> <a href="different.html">different.html</a> <a href="doclist.html">doclist.html</a> <a href="howitworks.html">howitworks.html</a> <a href="keyword_index.html">keyword_index.html</a> <a href="lang_corefunc.html">lang_corefunc.html</a> <a href="lang_explain.html">lang_explain.html</a> <a href="lts.html">lts.html</a> <a href="rowvalue.html">rowvalue.html</a> <a href="sitemap.html">sitemap.html</a> <a href="stmt.html">stmt.html</a> <a href="vdbe.html">vdbe.html</a> <a href="vtab.html">vtab.html</a> <a href="whybytecode.html">whybytecode.html</a> </li> <li><a href="optoverview.html">optoverview.html</a> → <a href="arch.html">arch.html</a> <a href="cli.html">cli.html</a> <a href="compile.html">compile.html</a> <a href="doclist.html">doclist.html</a> <a href="eqp.html">eqp.html</a> <a href="fileformat2.html">fileformat2.html</a> <a href="fts3.html">fts3.html</a> <a href="fullsql.html">fullsql.html</a> <a href="howitworks.html">howitworks.html</a> <a href="keyword_index.html">keyword_index.html</a> <a href="lang_analyze.html">lang_analyze.html</a> <a href="lang_indexedby.html">lang_indexedby.html</a> <a href="lang_select.html">lang_select.html</a> <a href="lang_with.html">lang_with.html</a> <a href="pragma.html">pragma.html</a> <a href="profile.html">profile.html</a> <a href="queryplanner-ng.html">queryplanner-ng.html</a> <a href="queryplanner.html">queryplanner.html</a> <a href="rescode.html">rescode.html</a> <a href="sitemap.html">sitemap.html</a> <a href="stmt.html">stmt.html</a> </li> <li><a href="partialindex.html">partialindex.html</a> → @@ -810,7 +810,7 @@ antiRobotDefense(); <li><a href="pgszchng2016.html">pgszchng2016.html</a> → <a href="doclist.html">doclist.html</a> <a href="keyword_index.html">keyword_index.html</a> <a href="sitemap.html">sitemap.html</a> </li> <li><a href="pragma.html">pragma.html</a> → -<a href="aff_short.html">aff_short.html</a> <a href="appfunc.html">appfunc.html</a> <a href="arch.html">arch.html</a> <a href="asyncvfs.html">asyncvfs.html</a> <a href="atomiccommit.html">atomiccommit.html</a> <a href="c3ref/busy_handler.html">c3ref/busy_handler.html</a> <a href="c3ref/busy_timeout.html">c3ref/busy_timeout.html</a> <a href="c3ref/c_access_exists.html">c3ref/c_access_exists.html</a> <a href="c3ref/c_config_covering_index_scan.html">c3ref/c_config_covering_index_scan.html</a> <a href="c3ref/c_dbconfig_defensive.html">c3ref/c_dbconfig_defensive.html</a> <a href="c3ref/c_deterministic.html">c3ref/c_deterministic.html</a> <a href="c3ref/c_fcntl_begin_atomic_write.html">c3ref/c_fcntl_begin_atomic_write.html</a> <a href="c3ref/c_sync_dataonly.html">c3ref/c_sync_dataonly.html</a> <a href="c3ref/compileoption_get.html">c3ref/compileoption_get.html</a> <a href="c3ref/data_count.html">c3ref/data_count.html</a> <a href="c3ref/data_directory.html">c3ref/data_directory.html</a> <a href="c3ref/hard_heap_limit64.html">c3ref/hard_heap_limit64.html</a> <a href="c3ref/limit.html">c3ref/limit.html</a> <a href="c3ref/pcache_methods2.html">c3ref/pcache_methods2.html</a> <a href="c3ref/set_authorizer.html">c3ref/set_authorizer.html</a> <a href="c3ref/snapshot_open.html">c3ref/snapshot_open.html</a> <a href="c3ref/temp_directory.html">c3ref/temp_directory.html</a> <a href="c3ref/wal_autocheckpoint.html">c3ref/wal_autocheckpoint.html</a> <a href="c3ref/wal_checkpoint_v2.html">c3ref/wal_checkpoint_v2.html</a> <a href="c3ref/wal_hook.html">c3ref/wal_hook.html</a> <a href="c_interface.html">c_interface.html</a> <a href="capi3ref.html">capi3ref.html</a> <a href="cli.html">cli.html</a> <a href="compile.html">compile.html</a> <a href="cves.html">cves.html</a> <a href="dbhash.html">dbhash.html</a> <a href="debugging.html">debugging.html</a> <a href="doclist.html">doclist.html</a> <a href="docs.html">docs.html</a> <a href="faq.html">faq.html</a> <a href="fasterthanfs.html">fasterthanfs.html</a> <a href="fileformat2.html">fileformat2.html</a> <a href="foreignkeys.html">foreignkeys.html</a> <a href="fts3.html">fts3.html</a> <a href="fts5.html">fts5.html</a> <a href="gencol.html">gencol.html</a> <a href="howtocorrupt.html">howtocorrupt.html</a> <a href="imposter.html">imposter.html</a> <a href="index.html">index.html</a> <a href="inmemorydb.html">inmemorydb.html</a> <a href="invalidutf.html">invalidutf.html</a> <a href="isolation.html">isolation.html</a> <a href="keyword_index.html">keyword_index.html</a> <a href="lang.html">lang.html</a> <a href="lang_altertable.html">lang_altertable.html</a> <a href="lang_analyze.html">lang_analyze.html</a> <a href="lang_attach.html">lang_attach.html</a> <a href="lang_conflict.html">lang_conflict.html</a> <a href="lang_corefunc.html">lang_corefunc.html</a> <a href="lang_createindex.html">lang_createindex.html</a> <a href="lang_createtable.html">lang_createtable.html</a> <a href="lang_createtrigger.html">lang_createtrigger.html</a> <a href="lang_delete.html">lang_delete.html</a> <a href="lang_explain.html">lang_explain.html</a> <a href="lang_expr.html">lang_expr.html</a> <a href="lang_transaction.html">lang_transaction.html</a> <a href="lang_vacuum.html">lang_vacuum.html</a> <a href="limits.html">limits.html</a> <a href="lockingv3.html">lockingv3.html</a> <a href="malloc.html">malloc.html</a> <a href="mmap.html">mmap.html</a> <a href="opcode.html">opcode.html</a> <a href="optoverview.html">optoverview.html</a> <a href="pgszchng2016.html">pgszchng2016.html</a> <a href="psow.html">psow.html</a> <a href="queryplanner-ng.html">queryplanner-ng.html</a> <a href="quirks.html">quirks.html</a> <a href="rescode.html">rescode.html</a> <a href="rtree.html">rtree.html</a> <a href="security.html">security.html</a> <a href="sharedcache.html">sharedcache.html</a> <a href="sitemap.html">sitemap.html</a> <a href="stricttables.html">stricttables.html</a> <a href="syntaxdiagrams.html">syntaxdiagrams.html</a> <a href="tclsqlite.html">tclsqlite.html</a> <a href="tempfiles.html">tempfiles.html</a> <a href="testing.html">testing.html</a> <a href="vdbe.html">vdbe.html</a> <a href="vtab.html">vtab.html</a> <a href="vtablist.html">vtablist.html</a> <a href="wal.html">wal.html</a> <a href="walformat.html">walformat.html</a> <a href="withoutrowid.html">withoutrowid.html</a> </li> +<a href="aff_short.html">aff_short.html</a> <a href="appfunc.html">appfunc.html</a> <a href="arch.html">arch.html</a> <a href="asyncvfs.html">asyncvfs.html</a> <a href="atomiccommit.html">atomiccommit.html</a> <a href="c3ref/busy_handler.html">c3ref/busy_handler.html</a> <a href="c3ref/busy_timeout.html">c3ref/busy_timeout.html</a> <a href="c3ref/c_access_exists.html">c3ref/c_access_exists.html</a> <a href="c3ref/c_config_covering_index_scan.html">c3ref/c_config_covering_index_scan.html</a> <a href="c3ref/c_dbconfig_defensive.html">c3ref/c_dbconfig_defensive.html</a> <a href="c3ref/c_deterministic.html">c3ref/c_deterministic.html</a> <a href="c3ref/c_fcntl_begin_atomic_write.html">c3ref/c_fcntl_begin_atomic_write.html</a> <a href="c3ref/c_sync_dataonly.html">c3ref/c_sync_dataonly.html</a> <a href="c3ref/compileoption_get.html">c3ref/compileoption_get.html</a> <a href="c3ref/data_count.html">c3ref/data_count.html</a> <a href="c3ref/data_directory.html">c3ref/data_directory.html</a> <a href="c3ref/hard_heap_limit64.html">c3ref/hard_heap_limit64.html</a> <a href="c3ref/limit.html">c3ref/limit.html</a> <a href="c3ref/pcache_methods2.html">c3ref/pcache_methods2.html</a> <a href="c3ref/set_authorizer.html">c3ref/set_authorizer.html</a> <a href="c3ref/snapshot_open.html">c3ref/snapshot_open.html</a> <a href="c3ref/temp_directory.html">c3ref/temp_directory.html</a> <a href="c3ref/wal_autocheckpoint.html">c3ref/wal_autocheckpoint.html</a> <a href="c3ref/wal_checkpoint_v2.html">c3ref/wal_checkpoint_v2.html</a> <a href="c3ref/wal_hook.html">c3ref/wal_hook.html</a> <a href="c_interface.html">c_interface.html</a> <a href="capi3ref.html">capi3ref.html</a> <a href="cli.html">cli.html</a> <a href="compile.html">compile.html</a> <a href="cves.html">cves.html</a> <a href="dbhash.html">dbhash.html</a> <a href="debugging.html">debugging.html</a> <a href="doclist.html">doclist.html</a> <a href="docs.html">docs.html</a> <a href="faq.html">faq.html</a> <a href="fasterthanfs.html">fasterthanfs.html</a> <a href="fileformat2.html">fileformat2.html</a> <a href="foreignkeys.html">foreignkeys.html</a> <a href="fts3.html">fts3.html</a> <a href="fts5.html">fts5.html</a> <a href="gencol.html">gencol.html</a> <a href="howtocorrupt.html">howtocorrupt.html</a> <a href="imposter.html">imposter.html</a> <a href="index.html">index.html</a> <a href="inmemorydb.html">inmemorydb.html</a> <a href="invalidutf.html">invalidutf.html</a> <a href="isolation.html">isolation.html</a> <a href="keyword_index.html">keyword_index.html</a> <a href="lang.html">lang.html</a> <a href="lang_altertable.html">lang_altertable.html</a> <a href="lang_analyze.html">lang_analyze.html</a> <a href="lang_attach.html">lang_attach.html</a> <a href="lang_conflict.html">lang_conflict.html</a> <a href="lang_corefunc.html">lang_corefunc.html</a> <a href="lang_createindex.html">lang_createindex.html</a> <a href="lang_createtable.html">lang_createtable.html</a> <a href="lang_createtrigger.html">lang_createtrigger.html</a> <a href="lang_delete.html">lang_delete.html</a> <a href="lang_explain.html">lang_explain.html</a> <a href="lang_expr.html">lang_expr.html</a> <a href="lang_transaction.html">lang_transaction.html</a> <a href="lang_vacuum.html">lang_vacuum.html</a> <a href="limits.html">limits.html</a> <a href="lockingv3.html">lockingv3.html</a> <a href="malloc.html">malloc.html</a> <a href="mmap.html">mmap.html</a> <a href="opcode.html">opcode.html</a> <a href="optoverview.html">optoverview.html</a> <a href="pgszchng2016.html">pgszchng2016.html</a> <a href="psow.html">psow.html</a> <a href="queryplanner-ng.html">queryplanner-ng.html</a> <a href="quirks.html">quirks.html</a> <a href="rescode.html">rescode.html</a> <a href="rtree.html">rtree.html</a> <a href="security.html">security.html</a> <a href="sharedcache.html">sharedcache.html</a> <a href="sitemap.html">sitemap.html</a> <a href="stricttables.html">stricttables.html</a> <a href="syntaxdiagrams.html">syntaxdiagrams.html</a> <a href="tclsqlite.html">tclsqlite.html</a> <a href="tempfiles.html">tempfiles.html</a> <a href="testing.html">testing.html</a> <a href="vdbe.html">vdbe.html</a> <a href="vtab.html">vtab.html</a> <a href="vtablist.html">vtablist.html</a> <a href="wal.html">wal.html</a> <a href="walformat.html">walformat.html</a> <a href="whybytecode.html">whybytecode.html</a> <a href="withoutrowid.html">withoutrowid.html</a> </li> <li><a href="printf.html">printf.html</a> → <a href="arch.html">arch.html</a> <a href="c3ref/mprintf.html">c3ref/mprintf.html</a> <a href="c3ref/str_append.html">c3ref/str_append.html</a> <a href="capi3ref.html">capi3ref.html</a> <a href="compile.html">compile.html</a> <a href="doclist.html">doclist.html</a> <a href="keyword_index.html">keyword_index.html</a> <a href="lang_corefunc.html">lang_corefunc.html</a> <a href="sitemap.html">sitemap.html</a> </li> <li><a href="privatebranch.html">privatebranch.html</a> → @@ -824,7 +824,7 @@ antiRobotDefense(); <li><a href="qmplan.html">qmplan.html</a> → <a href="doclist.html">doclist.html</a> <a href="sitemap.html">sitemap.html</a> </li> <li><a href="queryplanner-ng.html">queryplanner-ng.html</a> → -<a href="c3ref/c_dbconfig_defensive.html">c3ref/c_dbconfig_defensive.html</a> <a href="capi3ref.html">capi3ref.html</a> <a href="compile.html">compile.html</a> <a href="doclist.html">doclist.html</a> <a href="eqp.html">eqp.html</a> <a href="howitworks.html">howitworks.html</a> <a href="keyword_index.html">keyword_index.html</a> <a href="lang_indexedby.html">lang_indexedby.html</a> <a href="limits.html">limits.html</a> <a href="optoverview.html">optoverview.html</a> <a href="queryplanner.html">queryplanner.html</a> <a href="sitemap.html">sitemap.html</a> <a href="versionnumbers.html">versionnumbers.html</a> </li> +<a href="c3ref/c_dbconfig_defensive.html">c3ref/c_dbconfig_defensive.html</a> <a href="capi3ref.html">capi3ref.html</a> <a href="compile.html">compile.html</a> <a href="doclist.html">doclist.html</a> <a href="eqp.html">eqp.html</a> <a href="howitworks.html">howitworks.html</a> <a href="keyword_index.html">keyword_index.html</a> <a href="lang_analyze.html">lang_analyze.html</a> <a href="lang_indexedby.html">lang_indexedby.html</a> <a href="limits.html">limits.html</a> <a href="optoverview.html">optoverview.html</a> <a href="queryplanner.html">queryplanner.html</a> <a href="sitemap.html">sitemap.html</a> <a href="versionnumbers.html">versionnumbers.html</a> </li> <li><a href="queryplanner.html">queryplanner.html</a> → <a href="doclist.html">doclist.html</a> <a href="eqp.html">eqp.html</a> <a href="fullsql.html">fullsql.html</a> <a href="imposter.html">imposter.html</a> <a href="keyword_index.html">keyword_index.html</a> <a href="lts.html">lts.html</a> <a href="optoverview.html">optoverview.html</a> <a href="queryplanner-ng.html">queryplanner-ng.html</a> <a href="sitemap.html">sitemap.html</a> </li> <li><a href="quickstart.html">quickstart.html</a> → @@ -846,7 +846,7 @@ antiRobotDefense(); <li><a href="rtree.html">rtree.html</a> → <a href="aff_short.html">aff_short.html</a> <a href="amalgamation.html">amalgamation.html</a> <a href="compile.html">compile.html</a> <a href="doclist.html">doclist.html</a> <a href="floatingpoint.html">floatingpoint.html</a> <a href="fts5.html">fts5.html</a> <a href="fullsql.html">fullsql.html</a> <a href="geopoly.html">geopoly.html</a> <a href="howtocompile.html">howtocompile.html</a> <a href="keyword_index.html">keyword_index.html</a> <a href="rescode.html">rescode.html</a> <a href="sitemap.html">sitemap.html</a> <a href="sqldiff.html">sqldiff.html</a> <a href="th3.html">th3.html</a> <a href="vtab.html">vtab.html</a> <a href="vtablist.html">vtablist.html</a> </li> <li><a href="schematab.html">schematab.html</a> → -<a href="atomiccommit.html">atomiccommit.html</a> <a href="cli.html">cli.html</a> <a href="compile.html">compile.html</a> <a href="doclist.html">doclist.html</a> <a href="fileformat2.html">fileformat2.html</a> <a href="foreignkeys.html">foreignkeys.html</a> <a href="imposter.html">imposter.html</a> <a href="keyword_index.html">keyword_index.html</a> <a href="lang_altertable.html">lang_altertable.html</a> <a href="lang_droptrigger.html">lang_droptrigger.html</a> <a href="lemon.html">lemon.html</a> <a href="pragma.html">pragma.html</a> <a href="security.html">security.html</a> <a href="sharedcache.html">sharedcache.html</a> <a href="sitemap.html">sitemap.html</a> <a href="unlock_notify.html">unlock_notify.html</a> </li> +<a href="atomiccommit.html">atomiccommit.html</a> <a href="cli.html">cli.html</a> <a href="compile.html">compile.html</a> <a href="doclist.html">doclist.html</a> <a href="fileformat2.html">fileformat2.html</a> <a href="foreignkeys.html">foreignkeys.html</a> <a href="imposter.html">imposter.html</a> <a href="keyword_index.html">keyword_index.html</a> <a href="lang_altertable.html">lang_altertable.html</a> <a href="lang_droptrigger.html">lang_droptrigger.html</a> <a href="lemon.html">lemon.html</a> <a href="pragma.html">pragma.html</a> <a href="security.html">security.html</a> <a href="sharedcache.html">sharedcache.html</a> <a href="sitemap.html">sitemap.html</a> <a href="unlock_notify.html">unlock_notify.html</a> <a href="whybytecode.html">whybytecode.html</a> </li> <li><a href="security.html">security.html</a> → <a href="cves.html">cves.html</a> <a href="doclist.html">doclist.html</a> <a href="hirely.html">hirely.html</a> <a href="keyword_index.html">keyword_index.html</a> <a href="sitemap.html">sitemap.html</a> </li> <li><a href="selfcontained.html">selfcontained.html</a> → @@ -864,18 +864,20 @@ antiRobotDefense(); <li><a href="session/changegroup.html">session/changegroup.html</a> → <a href="keyword_index.html">keyword_index.html</a> <a href="session.html">session.html</a> <a href="session/objlist.html">session/objlist.html</a> <a href="sessionintro.html">sessionintro.html</a> </li> <li><a href="session/constlist.html">session/constlist.html</a> → -<a href="session/c_session_config_strmsize.html">session/c_session_config_strmsize.html</a> <a href="session/c_session_objconfig_rowid.html">session/c_session_objconfig_rowid.html</a> <a href="session/changegroup.html">session/changegroup.html</a> <a href="session/funclist.html">session/funclist.html</a> <a href="session/intro.html">session/intro.html</a> <a href="session/objlist.html">session/objlist.html</a> <a href="session/rebaser.html">session/rebaser.html</a> <a href="session/session.html">session/session.html</a> <a href="session/sqlite3changegroup_add.html">session/sqlite3changegroup_add.html</a> <a href="session/sqlite3changegroup_add_strm.html">session/sqlite3changegroup_add_strm.html</a> <a href="session/sqlite3changegroup_delete.html">session/sqlite3changegroup_delete.html</a> <a href="session/sqlite3changegroup_new.html">session/sqlite3changegroup_new.html</a> <a href="session/sqlite3changegroup_output.html">session/sqlite3changegroup_output.html</a> <a href="session/sqlite3changegroup_schema.html">session/sqlite3changegroup_schema.html</a> <a href="session/sqlite3rebaser_configure.html">session/sqlite3rebaser_configure.html</a> <a href="session/sqlite3rebaser_create.html">session/sqlite3rebaser_create.html</a> <a href="session/sqlite3rebaser_delete.html">session/sqlite3rebaser_delete.html</a> <a href="session/sqlite3rebaser_rebase.html">session/sqlite3rebaser_rebase.html</a> <a href="session/sqlite3session_attach.html">session/sqlite3session_attach.html</a> <a href="session/sqlite3session_config.html">session/sqlite3session_config.html</a> <a href="session/sqlite3session_create.html">session/sqlite3session_create.html</a> <a href="session/sqlite3session_delete.html">session/sqlite3session_delete.html</a> <a href="session/sqlite3session_diff.html">session/sqlite3session_diff.html</a> <a href="session/sqlite3session_enable.html">session/sqlite3session_enable.html</a> <a href="session/sqlite3session_indirect.html">session/sqlite3session_indirect.html</a> <a href="session/sqlite3session_isempty.html">session/sqlite3session_isempty.html</a> <a href="session/sqlite3session_memory_used.html">session/sqlite3session_memory_used.html</a> <a href="session/sqlite3session_object_config.html">session/sqlite3session_object_config.html</a> <a href="session/sqlite3session_patchset.html">session/sqlite3session_patchset.html</a> <a href="session/sqlite3session_table_filter.html">session/sqlite3session_table_filter.html</a> </li> +<a href="session/c_session_config_strmsize.html">session/c_session_config_strmsize.html</a> <a href="session/c_session_objconfig_rowid.html">session/c_session_objconfig_rowid.html</a> <a href="session/changegroup.html">session/changegroup.html</a> <a href="session/funclist.html">session/funclist.html</a> <a href="session/intro.html">session/intro.html</a> <a href="session/objlist.html">session/objlist.html</a> <a href="session/rebaser.html">session/rebaser.html</a> <a href="session/session.html">session/session.html</a> <a href="session/sqlite3changegroup_add.html">session/sqlite3changegroup_add.html</a> <a href="session/sqlite3changegroup_add_change.html">session/sqlite3changegroup_add_change.html</a> <a href="session/sqlite3changegroup_add_strm.html">session/sqlite3changegroup_add_strm.html</a> <a href="session/sqlite3changegroup_delete.html">session/sqlite3changegroup_delete.html</a> <a href="session/sqlite3changegroup_new.html">session/sqlite3changegroup_new.html</a> <a href="session/sqlite3changegroup_output.html">session/sqlite3changegroup_output.html</a> <a href="session/sqlite3changegroup_schema.html">session/sqlite3changegroup_schema.html</a> <a href="session/sqlite3rebaser_configure.html">session/sqlite3rebaser_configure.html</a> <a href="session/sqlite3rebaser_create.html">session/sqlite3rebaser_create.html</a> <a href="session/sqlite3rebaser_delete.html">session/sqlite3rebaser_delete.html</a> <a href="session/sqlite3rebaser_rebase.html">session/sqlite3rebaser_rebase.html</a> <a href="session/sqlite3session_attach.html">session/sqlite3session_attach.html</a> <a href="session/sqlite3session_config.html">session/sqlite3session_config.html</a> <a href="session/sqlite3session_create.html">session/sqlite3session_create.html</a> <a href="session/sqlite3session_delete.html">session/sqlite3session_delete.html</a> <a href="session/sqlite3session_diff.html">session/sqlite3session_diff.html</a> <a href="session/sqlite3session_enable.html">session/sqlite3session_enable.html</a> <a href="session/sqlite3session_indirect.html">session/sqlite3session_indirect.html</a> <a href="session/sqlite3session_isempty.html">session/sqlite3session_isempty.html</a> <a href="session/sqlite3session_memory_used.html">session/sqlite3session_memory_used.html</a> <a href="session/sqlite3session_object_config.html">session/sqlite3session_object_config.html</a> <a href="session/sqlite3session_patchset.html">session/sqlite3session_patchset.html</a> <a href="session/sqlite3session_table_filter.html">session/sqlite3session_table_filter.html</a> </li> <li><a href="session/funclist.html">session/funclist.html</a> → -<a href="keyword_index.html">keyword_index.html</a> <a href="session/c_session_config_strmsize.html">session/c_session_config_strmsize.html</a> <a href="session/c_session_objconfig_rowid.html">session/c_session_objconfig_rowid.html</a> <a href="session/changegroup.html">session/changegroup.html</a> <a href="session/constlist.html">session/constlist.html</a> <a href="session/intro.html">session/intro.html</a> <a href="session/objlist.html">session/objlist.html</a> <a href="session/rebaser.html">session/rebaser.html</a> <a href="session/session.html">session/session.html</a> <a href="session/sqlite3changegroup_add.html">session/sqlite3changegroup_add.html</a> <a href="session/sqlite3changegroup_add_strm.html">session/sqlite3changegroup_add_strm.html</a> <a href="session/sqlite3changegroup_delete.html">session/sqlite3changegroup_delete.html</a> <a href="session/sqlite3changegroup_new.html">session/sqlite3changegroup_new.html</a> <a href="session/sqlite3changegroup_output.html">session/sqlite3changegroup_output.html</a> <a href="session/sqlite3changegroup_schema.html">session/sqlite3changegroup_schema.html</a> <a href="session/sqlite3rebaser_configure.html">session/sqlite3rebaser_configure.html</a> <a href="session/sqlite3rebaser_create.html">session/sqlite3rebaser_create.html</a> <a href="session/sqlite3rebaser_delete.html">session/sqlite3rebaser_delete.html</a> <a href="session/sqlite3rebaser_rebase.html">session/sqlite3rebaser_rebase.html</a> <a href="session/sqlite3session_attach.html">session/sqlite3session_attach.html</a> <a href="session/sqlite3session_config.html">session/sqlite3session_config.html</a> <a href="session/sqlite3session_create.html">session/sqlite3session_create.html</a> <a href="session/sqlite3session_delete.html">session/sqlite3session_delete.html</a> <a href="session/sqlite3session_diff.html">session/sqlite3session_diff.html</a> <a href="session/sqlite3session_enable.html">session/sqlite3session_enable.html</a> <a href="session/sqlite3session_indirect.html">session/sqlite3session_indirect.html</a> <a href="session/sqlite3session_isempty.html">session/sqlite3session_isempty.html</a> <a href="session/sqlite3session_memory_used.html">session/sqlite3session_memory_used.html</a> <a href="session/sqlite3session_object_config.html">session/sqlite3session_object_config.html</a> <a href="session/sqlite3session_patchset.html">session/sqlite3session_patchset.html</a> <a href="session/sqlite3session_table_filter.html">session/sqlite3session_table_filter.html</a> </li> +<a href="keyword_index.html">keyword_index.html</a> <a href="session/c_session_config_strmsize.html">session/c_session_config_strmsize.html</a> <a href="session/c_session_objconfig_rowid.html">session/c_session_objconfig_rowid.html</a> <a href="session/changegroup.html">session/changegroup.html</a> <a href="session/constlist.html">session/constlist.html</a> <a href="session/intro.html">session/intro.html</a> <a href="session/objlist.html">session/objlist.html</a> <a href="session/rebaser.html">session/rebaser.html</a> <a href="session/session.html">session/session.html</a> <a href="session/sqlite3changegroup_add.html">session/sqlite3changegroup_add.html</a> <a href="session/sqlite3changegroup_add_change.html">session/sqlite3changegroup_add_change.html</a> <a href="session/sqlite3changegroup_add_strm.html">session/sqlite3changegroup_add_strm.html</a> <a href="session/sqlite3changegroup_delete.html">session/sqlite3changegroup_delete.html</a> <a href="session/sqlite3changegroup_new.html">session/sqlite3changegroup_new.html</a> <a href="session/sqlite3changegroup_output.html">session/sqlite3changegroup_output.html</a> <a href="session/sqlite3changegroup_schema.html">session/sqlite3changegroup_schema.html</a> <a href="session/sqlite3rebaser_configure.html">session/sqlite3rebaser_configure.html</a> <a href="session/sqlite3rebaser_create.html">session/sqlite3rebaser_create.html</a> <a href="session/sqlite3rebaser_delete.html">session/sqlite3rebaser_delete.html</a> <a href="session/sqlite3rebaser_rebase.html">session/sqlite3rebaser_rebase.html</a> <a href="session/sqlite3session_attach.html">session/sqlite3session_attach.html</a> <a href="session/sqlite3session_config.html">session/sqlite3session_config.html</a> <a href="session/sqlite3session_create.html">session/sqlite3session_create.html</a> <a href="session/sqlite3session_delete.html">session/sqlite3session_delete.html</a> <a href="session/sqlite3session_diff.html">session/sqlite3session_diff.html</a> <a href="session/sqlite3session_enable.html">session/sqlite3session_enable.html</a> <a href="session/sqlite3session_indirect.html">session/sqlite3session_indirect.html</a> <a href="session/sqlite3session_isempty.html">session/sqlite3session_isempty.html</a> <a href="session/sqlite3session_memory_used.html">session/sqlite3session_memory_used.html</a> <a href="session/sqlite3session_object_config.html">session/sqlite3session_object_config.html</a> <a href="session/sqlite3session_patchset.html">session/sqlite3session_patchset.html</a> <a href="session/sqlite3session_table_filter.html">session/sqlite3session_table_filter.html</a> </li> <li><a href="session/intro.html">session/intro.html</a> → -<a href="keyword_index.html">keyword_index.html</a> <a href="session.html">session.html</a> <a href="session/c_session_config_strmsize.html">session/c_session_config_strmsize.html</a> <a href="session/c_session_objconfig_rowid.html">session/c_session_objconfig_rowid.html</a> <a href="session/changegroup.html">session/changegroup.html</a> <a href="session/constlist.html">session/constlist.html</a> <a href="session/funclist.html">session/funclist.html</a> <a href="session/objlist.html">session/objlist.html</a> <a href="session/rebaser.html">session/rebaser.html</a> <a href="session/session.html">session/session.html</a> <a href="session/sqlite3changegroup_add.html">session/sqlite3changegroup_add.html</a> <a href="session/sqlite3changegroup_add_strm.html">session/sqlite3changegroup_add_strm.html</a> <a href="session/sqlite3changegroup_delete.html">session/sqlite3changegroup_delete.html</a> <a href="session/sqlite3changegroup_new.html">session/sqlite3changegroup_new.html</a> <a href="session/sqlite3changegroup_output.html">session/sqlite3changegroup_output.html</a> <a href="session/sqlite3changegroup_schema.html">session/sqlite3changegroup_schema.html</a> <a href="session/sqlite3rebaser_configure.html">session/sqlite3rebaser_configure.html</a> <a href="session/sqlite3rebaser_create.html">session/sqlite3rebaser_create.html</a> <a href="session/sqlite3rebaser_delete.html">session/sqlite3rebaser_delete.html</a> <a href="session/sqlite3rebaser_rebase.html">session/sqlite3rebaser_rebase.html</a> <a href="session/sqlite3session_attach.html">session/sqlite3session_attach.html</a> <a href="session/sqlite3session_config.html">session/sqlite3session_config.html</a> <a href="session/sqlite3session_create.html">session/sqlite3session_create.html</a> <a href="session/sqlite3session_delete.html">session/sqlite3session_delete.html</a> <a href="session/sqlite3session_diff.html">session/sqlite3session_diff.html</a> <a href="session/sqlite3session_enable.html">session/sqlite3session_enable.html</a> <a href="session/sqlite3session_indirect.html">session/sqlite3session_indirect.html</a> <a href="session/sqlite3session_isempty.html">session/sqlite3session_isempty.html</a> <a href="session/sqlite3session_memory_used.html">session/sqlite3session_memory_used.html</a> <a href="session/sqlite3session_object_config.html">session/sqlite3session_object_config.html</a> <a href="session/sqlite3session_patchset.html">session/sqlite3session_patchset.html</a> <a href="session/sqlite3session_table_filter.html">session/sqlite3session_table_filter.html</a> <a href="sessionintro.html">sessionintro.html</a> </li> +<a href="keyword_index.html">keyword_index.html</a> <a href="session.html">session.html</a> <a href="session/c_session_config_strmsize.html">session/c_session_config_strmsize.html</a> <a href="session/c_session_objconfig_rowid.html">session/c_session_objconfig_rowid.html</a> <a href="session/changegroup.html">session/changegroup.html</a> <a href="session/constlist.html">session/constlist.html</a> <a href="session/funclist.html">session/funclist.html</a> <a href="session/objlist.html">session/objlist.html</a> <a href="session/rebaser.html">session/rebaser.html</a> <a href="session/session.html">session/session.html</a> <a href="session/sqlite3changegroup_add.html">session/sqlite3changegroup_add.html</a> <a href="session/sqlite3changegroup_add_change.html">session/sqlite3changegroup_add_change.html</a> <a href="session/sqlite3changegroup_add_strm.html">session/sqlite3changegroup_add_strm.html</a> <a href="session/sqlite3changegroup_delete.html">session/sqlite3changegroup_delete.html</a> <a href="session/sqlite3changegroup_new.html">session/sqlite3changegroup_new.html</a> <a href="session/sqlite3changegroup_output.html">session/sqlite3changegroup_output.html</a> <a href="session/sqlite3changegroup_schema.html">session/sqlite3changegroup_schema.html</a> <a href="session/sqlite3rebaser_configure.html">session/sqlite3rebaser_configure.html</a> <a href="session/sqlite3rebaser_create.html">session/sqlite3rebaser_create.html</a> <a href="session/sqlite3rebaser_delete.html">session/sqlite3rebaser_delete.html</a> <a href="session/sqlite3rebaser_rebase.html">session/sqlite3rebaser_rebase.html</a> <a href="session/sqlite3session_attach.html">session/sqlite3session_attach.html</a> <a href="session/sqlite3session_config.html">session/sqlite3session_config.html</a> <a href="session/sqlite3session_create.html">session/sqlite3session_create.html</a> <a href="session/sqlite3session_delete.html">session/sqlite3session_delete.html</a> <a href="session/sqlite3session_diff.html">session/sqlite3session_diff.html</a> <a href="session/sqlite3session_enable.html">session/sqlite3session_enable.html</a> <a href="session/sqlite3session_indirect.html">session/sqlite3session_indirect.html</a> <a href="session/sqlite3session_isempty.html">session/sqlite3session_isempty.html</a> <a href="session/sqlite3session_memory_used.html">session/sqlite3session_memory_used.html</a> <a href="session/sqlite3session_object_config.html">session/sqlite3session_object_config.html</a> <a href="session/sqlite3session_patchset.html">session/sqlite3session_patchset.html</a> <a href="session/sqlite3session_table_filter.html">session/sqlite3session_table_filter.html</a> <a href="sessionintro.html">sessionintro.html</a> </li> <li><a href="session/objlist.html">session/objlist.html</a> → -<a href="session/c_session_config_strmsize.html">session/c_session_config_strmsize.html</a> <a href="session/c_session_objconfig_rowid.html">session/c_session_objconfig_rowid.html</a> <a href="session/changegroup.html">session/changegroup.html</a> <a href="session/constlist.html">session/constlist.html</a> <a href="session/funclist.html">session/funclist.html</a> <a href="session/intro.html">session/intro.html</a> <a href="session/rebaser.html">session/rebaser.html</a> <a href="session/session.html">session/session.html</a> <a href="session/sqlite3changegroup_add.html">session/sqlite3changegroup_add.html</a> <a href="session/sqlite3changegroup_add_strm.html">session/sqlite3changegroup_add_strm.html</a> <a href="session/sqlite3changegroup_delete.html">session/sqlite3changegroup_delete.html</a> <a href="session/sqlite3changegroup_new.html">session/sqlite3changegroup_new.html</a> <a href="session/sqlite3changegroup_output.html">session/sqlite3changegroup_output.html</a> <a href="session/sqlite3changegroup_schema.html">session/sqlite3changegroup_schema.html</a> <a href="session/sqlite3rebaser_configure.html">session/sqlite3rebaser_configure.html</a> <a href="session/sqlite3rebaser_create.html">session/sqlite3rebaser_create.html</a> <a href="session/sqlite3rebaser_delete.html">session/sqlite3rebaser_delete.html</a> <a href="session/sqlite3rebaser_rebase.html">session/sqlite3rebaser_rebase.html</a> <a href="session/sqlite3session_attach.html">session/sqlite3session_attach.html</a> <a href="session/sqlite3session_config.html">session/sqlite3session_config.html</a> <a href="session/sqlite3session_create.html">session/sqlite3session_create.html</a> <a href="session/sqlite3session_delete.html">session/sqlite3session_delete.html</a> <a href="session/sqlite3session_diff.html">session/sqlite3session_diff.html</a> <a href="session/sqlite3session_enable.html">session/sqlite3session_enable.html</a> <a href="session/sqlite3session_indirect.html">session/sqlite3session_indirect.html</a> <a href="session/sqlite3session_isempty.html">session/sqlite3session_isempty.html</a> <a href="session/sqlite3session_memory_used.html">session/sqlite3session_memory_used.html</a> <a href="session/sqlite3session_object_config.html">session/sqlite3session_object_config.html</a> <a href="session/sqlite3session_patchset.html">session/sqlite3session_patchset.html</a> <a href="session/sqlite3session_table_filter.html">session/sqlite3session_table_filter.html</a> </li> +<a href="session/c_session_config_strmsize.html">session/c_session_config_strmsize.html</a> <a href="session/c_session_objconfig_rowid.html">session/c_session_objconfig_rowid.html</a> <a href="session/changegroup.html">session/changegroup.html</a> <a href="session/constlist.html">session/constlist.html</a> <a href="session/funclist.html">session/funclist.html</a> <a href="session/intro.html">session/intro.html</a> <a href="session/rebaser.html">session/rebaser.html</a> <a href="session/session.html">session/session.html</a> <a href="session/sqlite3changegroup_add.html">session/sqlite3changegroup_add.html</a> <a href="session/sqlite3changegroup_add_change.html">session/sqlite3changegroup_add_change.html</a> <a href="session/sqlite3changegroup_add_strm.html">session/sqlite3changegroup_add_strm.html</a> <a href="session/sqlite3changegroup_delete.html">session/sqlite3changegroup_delete.html</a> <a href="session/sqlite3changegroup_new.html">session/sqlite3changegroup_new.html</a> <a href="session/sqlite3changegroup_output.html">session/sqlite3changegroup_output.html</a> <a href="session/sqlite3changegroup_schema.html">session/sqlite3changegroup_schema.html</a> <a href="session/sqlite3rebaser_configure.html">session/sqlite3rebaser_configure.html</a> <a href="session/sqlite3rebaser_create.html">session/sqlite3rebaser_create.html</a> <a href="session/sqlite3rebaser_delete.html">session/sqlite3rebaser_delete.html</a> <a href="session/sqlite3rebaser_rebase.html">session/sqlite3rebaser_rebase.html</a> <a href="session/sqlite3session_attach.html">session/sqlite3session_attach.html</a> <a href="session/sqlite3session_config.html">session/sqlite3session_config.html</a> <a href="session/sqlite3session_create.html">session/sqlite3session_create.html</a> <a href="session/sqlite3session_delete.html">session/sqlite3session_delete.html</a> <a href="session/sqlite3session_diff.html">session/sqlite3session_diff.html</a> <a href="session/sqlite3session_enable.html">session/sqlite3session_enable.html</a> <a href="session/sqlite3session_indirect.html">session/sqlite3session_indirect.html</a> <a href="session/sqlite3session_isempty.html">session/sqlite3session_isempty.html</a> <a href="session/sqlite3session_memory_used.html">session/sqlite3session_memory_used.html</a> <a href="session/sqlite3session_object_config.html">session/sqlite3session_object_config.html</a> <a href="session/sqlite3session_patchset.html">session/sqlite3session_patchset.html</a> <a href="session/sqlite3session_table_filter.html">session/sqlite3session_table_filter.html</a> </li> <li><a href="session/rebaser.html">session/rebaser.html</a> → <a href="keyword_index.html">keyword_index.html</a> <a href="session.html">session.html</a> <a href="session/objlist.html">session/objlist.html</a> </li> <li><a href="session/session.html">session/session.html</a> → <a href="keyword_index.html">keyword_index.html</a> <a href="session.html">session.html</a> <a href="session/objlist.html">session/objlist.html</a> </li> <li><a href="session/sqlite3changegroup_add.html">session/sqlite3changegroup_add.html</a> → +<a href="keyword_index.html">keyword_index.html</a> <a href="session.html">session.html</a> <a href="session/changegroup.html">session/changegroup.html</a> <a href="session/funclist.html">session/funclist.html</a> <a href="session/sqlite3changegroup_add_change.html">session/sqlite3changegroup_add_change.html</a> </li> +<li><a href="session/sqlite3changegroup_add_change.html">session/sqlite3changegroup_add_change.html</a> → <a href="keyword_index.html">keyword_index.html</a> <a href="session.html">session.html</a> <a href="session/changegroup.html">session/changegroup.html</a> <a href="session/funclist.html">session/funclist.html</a> </li> <li><a href="session/sqlite3changegroup_add_strm.html">session/sqlite3changegroup_add_strm.html</a> → <a href="keyword_index.html">keyword_index.html</a> <a href="session.html">session.html</a> <a href="session/funclist.html">session/funclist.html</a> </li> @@ -1133,12 +1135,14 @@ antiRobotDefense(); <a href="compile.html">compile.html</a> <a href="doclist.html">doclist.html</a> <a href="fileformat2.html">fileformat2.html</a> <a href="keyword_index.html">keyword_index.html</a> <a href="rescode.html">rescode.html</a> <a href="sitemap.html">sitemap.html</a> <a href="vfs.html">vfs.html</a> <a href="wal.html">wal.html</a> </li> <li><a href="whentouse.html">whentouse.html</a> → <a href="doclist.html">doclist.html</a> <a href="docs.html">docs.html</a> <a href="famous.html">famous.html</a> <a href="features.html">features.html</a> <a href="index.html">index.html</a> <a href="keyword_index.html">keyword_index.html</a> <a href="np1queryprob.html">np1queryprob.html</a> <a href="quirks.html">quirks.html</a> <a href="sitemap.html">sitemap.html</a> <a href="tempfiles.html">tempfiles.html</a> </li> +<li><a href="whybytecode.html">whybytecode.html</a> → +<a href="doclist.html">doclist.html</a> <a href="keyword_index.html">keyword_index.html</a> <a href="opcode.html">opcode.html</a> <a href="sitemap.html">sitemap.html</a> </li> <li><a href="whyc.html">whyc.html</a> → <a href="doclist.html">doclist.html</a> <a href="sitemap.html">sitemap.html</a> </li> <li><a href="whynotgit.html">whynotgit.html</a> → <a href="doclist.html">doclist.html</a> <a href="sitemap.html">sitemap.html</a> </li> <li><a href="windowfunctions.html">windowfunctions.html</a> → -<a href="appfunc.html">appfunc.html</a> <a href="c3ref/create_function.html">c3ref/create_function.html</a> <a href="capi3ref.html">capi3ref.html</a> <a href="compile.html">compile.html</a> <a href="doclist.html">doclist.html</a> <a href="docs.html">docs.html</a> <a href="features.html">features.html</a> <a href="fullsql.html">fullsql.html</a> <a href="index.html">index.html</a> <a href="keyword_index.html">keyword_index.html</a> <a href="lang_aggfunc.html">lang_aggfunc.html</a> <a href="lang_corefunc.html">lang_corefunc.html</a> <a href="lang_expr.html">lang_expr.html</a> <a href="lang_returning.html">lang_returning.html</a> <a href="lang_with.html">lang_with.html</a> <a href="sitemap.html">sitemap.html</a> </li> +<a href="appfunc.html">appfunc.html</a> <a href="c3ref/create_function.html">c3ref/create_function.html</a> <a href="capi3ref.html">capi3ref.html</a> <a href="compile.html">compile.html</a> <a href="doclist.html">doclist.html</a> <a href="docs.html">docs.html</a> <a href="features.html">features.html</a> <a href="fullsql.html">fullsql.html</a> <a href="index.html">index.html</a> <a href="keyword_index.html">keyword_index.html</a> <a href="lang.html">lang.html</a> <a href="lang_aggfunc.html">lang_aggfunc.html</a> <a href="lang_corefunc.html">lang_corefunc.html</a> <a href="lang_expr.html">lang_expr.html</a> <a href="lang_returning.html">lang_returning.html</a> <a href="lang_with.html">lang_with.html</a> <a href="optoverview.html">optoverview.html</a> <a href="sitemap.html">sitemap.html</a> </li> <li><a href="withoutrowid.html">withoutrowid.html</a> → <a href="autoinc.html">autoinc.html</a> <a href="c3ref/last_insert_rowid.html">c3ref/last_insert_rowid.html</a> <a href="c3ref/table_column_metadata.html">c3ref/table_column_metadata.html</a> <a href="c3ref/update_hook.html">c3ref/update_hook.html</a> <a href="capi3ref.html">capi3ref.html</a> <a href="doclist.html">doclist.html</a> <a href="fileformat2.html">fileformat2.html</a> <a href="fullsql.html">fullsql.html</a> <a href="imposter.html">imposter.html</a> <a href="keyword_index.html">keyword_index.html</a> <a href="lang_createtable.html">lang_createtable.html</a> <a href="lang_expr.html">lang_expr.html</a> <a href="optoverview.html">optoverview.html</a> <a href="pragma.html">pragma.html</a> <a href="queryplanner.html">queryplanner.html</a> <a href="quirks.html">quirks.html</a> <a href="rowidtable.html">rowidtable.html</a> <a href="schematab.html">schematab.html</a> <a href="sessionintro.html">sessionintro.html</a> <a href="sitemap.html">sitemap.html</a> <a href="sqldiff.html">sqldiff.html</a> <a href="stricttables.html">stricttables.html</a> <a href="vtab.html">vtab.html</a> </li> <li><a href="zeroconf.html">zeroconf.html</a> → diff --git a/www/doc_target_crossref.html b/www/doc_target_crossref.html index 736ee11..dfcbedd 100644 --- a/www/doc_target_crossref.html +++ b/www/doc_target_crossref.html @@ -916,7 +916,6 @@ antiRobotDefense(); <li><a href="fts3.html#unicode61">fts3.html#unicode61</a> → unicode61</li> <li><a href="fts5.html">fts5.html</a> → FTS5 fts5</li> <li><a href="fts5.html#_auxiliary_functions_">fts5.html#_auxiliary_functions_</a> → {FTS5 auxiliary functions}</li> -<li><a href="fts5.html#_custom_auxiliary_functions_api_reference_">fts5.html#_custom_auxiliary_functions_api_reference_</a> → {custom auxiliary functions}</li> <li><a href="fts5.html#_summary_of_technical_differences_">fts5.html#_summary_of_technical_differences_</a> → {fts5 technical differences}</li> <li><a href="fts5.html#appendix_a">fts5.html#appendix_a</a> → {comparison with fts4}</li> <li><a href="fts5.html#carrotq">fts5.html#carrotq</a> → {FTS5 initial token}</li> @@ -925,6 +924,8 @@ antiRobotDefense(); <li><a href="fts5.html#contentless_delete_tables">fts5.html#contentless_delete_tables</a> → {FTS5 contentless-delete tables}</li> <li><a href="fts5.html#contentless_tables">fts5.html#contentless_tables</a> → {FTS5 contentless tables}</li> <li><a href="fts5.html#custom_auxiliary_functions">fts5.html#custom_auxiliary_functions</a> → {FTS5 custom auxiliary functions}</li> +<li><a href="fts5.html#custom_auxiliary_functions_api_overview">fts5.html#custom_auxiliary_functions_api_overview</a> → {custom auxiliary overview}</li> +<li><a href="fts5.html#custom_auxiliary_functions_api_reference">fts5.html#custom_auxiliary_functions_api_reference</a> → {custom auxiliary functions}</li> <li><a href="fts5.html#custom_tokenizers">fts5.html#custom_tokenizers</a> → {custom tokenizers}</li> <li><a href="fts5.html#extending_fts5">fts5.html#extending_fts5</a> → {Extending FTS5}</li> <li><a href="fts5.html#external_content_and_contentless_tables">fts5.html#external_content_and_contentless_tables</a> → {FTS5 content option}</li> @@ -1024,6 +1025,7 @@ antiRobotDefense(); <li><a href="json1.html#jobjb">json1.html#jobjb</a> → jsonb_object {jsonb_object SQL function}</li> <li><a href="json1.html#jpatch">json1.html#jpatch</a> → json_patch {json_patch SQL function}</li> <li><a href="json1.html#jpatchb">json1.html#jpatchb</a> → jsonb_patch {jsonb_patch SQL function}</li> +<li><a href="json1.html#jpretty">json1.html#jpretty</a> → json_pretty {json_pretty SQL function}</li> <li><a href="json1.html#jptr">json1.html#jptr</a> → {the - and - operators} {the - operator}</li> <li><a href="json1.html#jquote">json1.html#jquote</a> → json_quote {json_quote SQL function}</li> <li><a href="json1.html#jrepl">json1.html#jrepl</a> → json_replace {json_replace SQL function}</li> @@ -1057,9 +1059,11 @@ antiRobotDefense(); <li><a href="lang_altertable.html#altertabrename">lang_altertable.html#altertabrename</a> → {ALTER TABLE RENAME} {ALTER TABLE RENAME documentation} {rename table}</li> <li><a href="lang_altertable.html#otheralter">lang_altertable.html#otheralter</a> → {generalized ALTER TABLE procedure}</li> <li><a href="lang_analyze.html">lang_analyze.html</a> → ANALYZE analyze</li> -<li><a href="lang_analyze.html#approx">lang_analyze.html#approx</a> → {approximate ANALYZE}</li> -<li><a href="lang_analyze.html#autoanalyze">lang_analyze.html#autoanalyze</a> → {automatically running ANALYZE}</li> -<li><a href="lang_analyze.html#req">lang_analyze.html#req</a> → {recommended ANALYZE usage pattern}</li> +<li><a href="lang_analyze.html#approx">lang_analyze.html#approx</a> → {Approximate ANALYZE For Large Databases} {approximate ANALYZE}</li> +<li><a href="lang_analyze.html#autoanalyze">lang_analyze.html#autoanalyze</a> → {Automatically Running ANALYZE} {automatically running ANALYZE}</li> +<li><a href="lang_analyze.html#pragopt">lang_analyze.html#pragopt</a> → {running ANALYZE via PRAGMA optimize}</li> +<li><a href="lang_analyze.html#req">lang_analyze.html#req</a> → {Recommended usage patterns for ANALYZE}</li> +<li><a href="lang_analyze.html#statanal">lang_analyze.html#statanal</a> → {static ANALYZE results}</li> <li><a href="lang_attach.html">lang_attach.html</a> → ATTACH {ATTACH DATABASE} attach attached</li> <li><a href="lang_comment.html">lang_comment.html</a> → comment comments</li> <li><a href="lang_conflict.html">lang_conflict.html</a> → {ON CONFLICT} {ON CONFLICT clause} {ON CONFLICT clauses} conflict {conflict clause} {conflict resolution algorithm}</li> @@ -1134,15 +1138,17 @@ antiRobotDefense(); <li><a href="lang_createvtab.html">lang_createvtab.html</a> → {CREATE VIRTUAL TABLE} createvtab</li> <li><a href="lang_datefunc.html">lang_datefunc.html</a> → {Date And Time Functions} {date and time functions} datefunc</li> <li><a href="lang_datefunc.html#automod">lang_datefunc.html#automod</a> → {auto modifier}</li> +<li><a href="lang_datefunc.html#dtambg">lang_datefunc.html#dtambg</a> → {ambiguous dates}</li> <li><a href="lang_datefunc.html#dtmods">lang_datefunc.html#dtmods</a> → {date/time modifiers} modifiers</li> <li><a href="lang_datefunc.html#dttm">lang_datefunc.html#dttm</a> → date {date SQL function} datetime {datetime SQL function} time {time SQL function}</li> -<li><a href="lang_datefunc.html#jdmod">lang_datefunc.html#jdmod</a> → {julianday modifier}</li> +<li><a href="lang_datefunc.html#jdmod">lang_datefunc.html#jdmod</a> → {julianday modifier} {unixepoch modifier}</li> <li><a href="lang_datefunc.html#jlndy">lang_datefunc.html#jlndy</a> → julianday {julianday SQL function}</li> -<li><a href="lang_datefunc.html#localtime">lang_datefunc.html#localtime</a> → {localtime modifier} {utc modifier}</li> +<li><a href="lang_datefunc.html#localtime">lang_datefunc.html#localtime</a> → {localtime modifier} {utc and localtime modifiers} {utc modifier}</li> <li><a href="lang_datefunc.html#strftm">lang_datefunc.html#strftm</a> → strftime {strftime SQL function}</li> <li><a href="lang_datefunc.html#subsec">lang_datefunc.html#subsec</a> → {subsec modifier} {subsecond modifier}</li> <li><a href="lang_datefunc.html#tmdif">lang_datefunc.html#tmdif</a> → timediff {timediff SQL function}</li> <li><a href="lang_datefunc.html#tmshf">lang_datefunc.html#tmshf</a> → {time shift modifiers}</li> +<li><a href="lang_datefunc.html#tmval">lang_datefunc.html#tmval</a> → {time value} {time values} time-value time-values</li> <li><a href="lang_datefunc.html#uepch">lang_datefunc.html#uepch</a> → unixepoch {unixepoch SQL function} {unixepoch function}</li> <li><a href="lang_delete.html">lang_delete.html</a> → DELETE DELETEs delete</li> <li><a href="lang_delete.html#truncateopt">lang_delete.html#truncateopt</a> → {truncate optimization}</li> @@ -1169,7 +1175,7 @@ antiRobotDefense(); <li><a href="lang_expr.html#isdf">lang_expr.html#isdf</a> → {IS DISTINCT FROM} {IS NOT DISTINCT FROM}</li> <li><a href="lang_expr.html#isisnot">lang_expr.html#isisnot</a> → {IS NOT operator} {IS operator}</li> <li><a href="lang_expr.html#like">lang_expr.html#like</a> → ESCAPE LIKE</li> -<li><a href="lang_expr.html#litvalue">lang_expr.html#litvalue</a> → {literal value}</li> +<li><a href="lang_expr.html#litvalue">lang_expr.html#litvalue</a> → {literal value} {numeric literals}</li> <li><a href="lang_expr.html#match">lang_expr.html#match</a> → MATCH</li> <li><a href="lang_expr.html#regexp">lang_expr.html#regexp</a> → REGEXP</li> <li><a href="lang_expr.html#subq">lang_expr.html#subq</a> → Subqueries</li> @@ -1292,12 +1298,13 @@ antiRobotDefense(); <li><a href="opcode.html#codes">opcode.html#codes</a> → {list of current bytecodes} {opcode definitions}</li> <li><a href="opcode.html#subprog">opcode.html#subprog</a> → subprograms</li> <li><a href="optoverview.html">optoverview.html</a> → {SQLite query planner} optimizer {query planner}</li> -<li><a href="optoverview.html#autoindex">optoverview.html#autoindex</a> → {Automatic indexing} {automatic indexes} {automatic indexing}</li> +<li><a href="optoverview.html#autoindex">optoverview.html#autoindex</a> → {Automatic indexing} {Query-time indexes} {Query-time indexing} {automatic indexes} {automatic indexing} {query-time index} {query-time indexing}</li> <li><a href="optoverview.html#constprop">optoverview.html#constprop</a> → {constant-propagation optimization}</li> <li><a href="optoverview.html#coroutines">optoverview.html#coroutines</a> → co-routines {subquery co-routines}</li> <li><a href="optoverview.html#crossjoin">optoverview.html#crossjoin</a> → {CROSS JOIN} {Manual Control Of Query Plans Using CROSS JOIN}</li> <li><a href="optoverview.html#flattening">optoverview.html#flattening</a> → flattened {flattening optimization} {query flattener}</li> <li><a href="optoverview.html#hashjoin">optoverview.html#hashjoin</a> → {hash join}</li> +<li><a href="optoverview.html#joins">optoverview.html#joins</a> → {join order}</li> <li><a href="optoverview.html#leftjoinreduction">optoverview.html#leftjoinreduction</a> → {LEFT JOIN strength reduction optimization} {OUTER JOIN strength reduction} {OUTER JOIN strength reduction optimization}</li> <li><a href="optoverview.html#like_opt">optoverview.html#like_opt</a> → {LIKE optimization}</li> <li><a href="optoverview.html#manctrl">optoverview.html#manctrl</a> → {Manual Control Of Query Plans Using SQLITE_STAT Tables}</li> @@ -1305,10 +1312,9 @@ antiRobotDefense(); <li><a href="optoverview.html#omitnoopjoin">optoverview.html#omitnoopjoin</a> → {omit-left-join optimization} {omit-outer-join optimization}</li> <li><a href="optoverview.html#or_opt">optoverview.html#or_opt</a> → {OR optimization} {or optimization}</li> <li><a href="optoverview.html#partsort">optoverview.html#partsort</a> → {sorting subsets of the result}</li> -<li><a href="optoverview.html#pushdown">optoverview.html#pushdown</a> → {push-down optimization}</li> +<li><a href="optoverview.html#pushdown">optoverview.html#pushdown</a> → {WHERE-clause push-down optimization} {push-down optimization}</li> <li><a href="optoverview.html#rangequery">optoverview.html#rangequery</a> → {range query optimization}</li> <li><a href="optoverview.html#skipscan">optoverview.html#skipscan</a> → skip-scan {skip-scan optimization}</li> -<li><a href="optoverview.html#table_order">optoverview.html#table_order</a> → {join order}</li> <li><a href="optoverview.html#uplus">optoverview.html#uplus</a> → upluscontrol</li> <li><a href="partialindex.html">partialindex.html</a> → {partial index} {partial indexes} {partial indices}</li> <li><a href="pgszchng2016.html">pgszchng2016.html</a> → {increase in the default page size} {version 3.12.0 page size change}</li> @@ -1554,6 +1560,7 @@ antiRobotDefense(); <li><a href="releaselog/3_45_1.html">releaselog/3_45_1.html</a> → {Version 3.45.1} {version 3.45.1}</li> <li><a href="releaselog/3_45_2.html">releaselog/3_45_2.html</a> → {Version 3.45.2} {version 3.45.2}</li> <li><a href="releaselog/3_45_3.html">releaselog/3_45_3.html</a> → {Version 3.45.3} {version 3.45.3}</li> +<li><a href="releaselog/3_46_0.html">releaselog/3_46_0.html</a> → {Version 3.46.0} {version 3.46.0}</li> <li><a href="releaselog/3_4_0.html">releaselog/3_4_0.html</a> → {Version 3.4.0} {version 3.4.0}</li> <li><a href="releaselog/3_4_1.html">releaselog/3_4_1.html</a> → {Version 3.4.1} {version 3.4.1}</li> <li><a href="releaselog/3_4_2.html">releaselog/3_4_2.html</a> → {Version 3.4.2} {version 3.4.2}</li> @@ -1797,6 +1804,7 @@ antiRobotDefense(); <li><a href="session/rebaser.html">session/rebaser.html</a> → sqlite3_rebaser</li> <li><a href="session/session.html">session/session.html</a> → sqlite3_session</li> <li><a href="session/sqlite3changegroup_add.html">session/sqlite3changegroup_add.html</a> → sqlite3changegroup_add</li> +<li><a href="session/sqlite3changegroup_add_change.html">session/sqlite3changegroup_add_change.html</a> → sqlite3changegroup_add_change</li> <li><a href="session/sqlite3changegroup_add_strm.html">session/sqlite3changegroup_add_strm.html</a> → sqlite3changegroup_add_strm sqlite3changegroup_output_strm sqlite3changeset_apply_strm sqlite3changeset_apply_v2_strm sqlite3changeset_concat_strm sqlite3changeset_invert_strm sqlite3changeset_start_strm sqlite3changeset_start_v2_strm sqlite3rebaser_rebase_strm sqlite3session_changeset_strm sqlite3session_patchset_strm</li> <li><a href="session/sqlite3changegroup_delete.html">session/sqlite3changegroup_delete.html</a> → sqlite3changegroup_delete</li> <li><a href="session/sqlite3changegroup_new.html">session/sqlite3changegroup_new.html</a> → sqlite3changegroup_new</li> @@ -2073,7 +2081,8 @@ antiRobotDefense(); <li><a href="whentouse.html#serversidedb">whentouse.html#serversidedb</a> → {server-side database}</li> <li><a href="whentouse.html#website">whentouse.html#website</a> → {using SQLite for websites}</li> <li><a href="whentouse.html#wireproto">whentouse.html#wireproto</a> → {data transfer format}</li> -<li><a href="windowfunctions.html">windowfunctions.html</a> → {Window functions} {window function} {window functions}</li> +<li><a href="whybytecode.html">whybytecode.html</a> → {Why SQLite Uses Bytecode}</li> +<li><a href="windowfunctions.html">windowfunctions.html</a> → {Window functions} {window function} {window functions} winfunc</li> <li><a href="windowfunctions.html#aggwinfunc">windowfunctions.html#aggwinfunc</a> → {aggregate window functions}</li> <li><a href="windowfunctions.html#biwinfunc">windowfunctions.html#biwinfunc</a> → {builtin window functions}</li> <li><a href="windowfunctions.html#builtins">windowfunctions.html#builtins</a> → {built-in window functions} built-ins</li> diff --git a/www/doclist.html b/www/doclist.html index 3e87b54..909bfe4 100644 --- a/www/doclist.html +++ b/www/doclist.html @@ -333,6 +333,7 @@ See Also: <li><a href="affcase1.html">What If OpenDocument Used SQLite?</a></li> <li><a href="whyc.html">Why Is SQLite Coded In C</a></li> <li><a href="whynotgit.html">Why SQLite Does Not Use Git</a></li> +<li><a href="whybytecode.html">Why SQLite Uses Bytecode</a></li> <li><a href="windowfunctions.html">Window Functions</a></li> <li><a href="wal.html">Write-Ahead Logging</a></li> <li><a href="zeroconf.html">Zero-Configuration</a></li> diff --git a/www/eqp.html b/www/eqp.html index b4e68fa..fff35c6 100644 --- a/www/eqp.html +++ b/www/eqp.html @@ -271,7 +271,7 @@ QUERY PLAN </pre></div> <p> - All joins in SQLite are <a href="optoverview.html#table_order">implemented using nested scans</a>. When a + All joins in SQLite are <a href="optoverview.html#joins">implemented using nested scans</a>. When a SELECT query that features a join is analyzed using EXPLAIN QUERY PLAN, one SCAN or SEARCH record is output for each nested loop. For example: </p><div class="codeblock"><pre>sqlite> EXPLAIN QUERY PLAN SELECT t1.*, t2.* FROM t1, t2 WHERE t1.a=1 AND t1.b>2; diff --git a/www/fileformat.html b/www/fileformat.html index a26002b..f6fb7cc 100644 --- a/www/fileformat.html +++ b/www/fileformat.html @@ -691,7 +691,7 @@ The only exception is when page 1 is an interior b-tree page. Page 1 has 100 fewer bytes of storage space available, due to the presence of the database header at the beginning of that page, and so sometimes (rarely) if page 1 is an interior b-tree page, it can -end up holding just a a single key. In all other cases, K is 2 or more. +end up holding just a single key. In all other cases, K is 2 or more. The upper bound on K is as many keys as will fit on the page. Large keys on index b-trees are split up into <a href="fileformat2.html#ovflpgs">overflow pages</a> so that no single key uses more than one fourth of the available storage space on the page @@ -2201,5 +2201,5 @@ file, and since the wal-index is a transient structure, no further information about the format of the wal-index will be provided here. Additional details on the format of the wal-index are contained in the separate <a href="walformat.html#walidxfmt">WAL-index File Format</a> document.</p> - +<p align="center"><small><i>This page last modified on <a href="https://sqlite.org/docsrc/honeypot" id="mtimelink" data-href="https://sqlite.org/docsrc/finfo/pages/fileformat2.in?m=af2cdeaf41">2024-04-20 09:25:12</a> UTC </small></i></p> diff --git a/www/fileformat2.html b/www/fileformat2.html index a26002b..f6fb7cc 100644 --- a/www/fileformat2.html +++ b/www/fileformat2.html @@ -691,7 +691,7 @@ The only exception is when page 1 is an interior b-tree page. Page 1 has 100 fewer bytes of storage space available, due to the presence of the database header at the beginning of that page, and so sometimes (rarely) if page 1 is an interior b-tree page, it can -end up holding just a a single key. In all other cases, K is 2 or more. +end up holding just a single key. In all other cases, K is 2 or more. The upper bound on K is as many keys as will fit on the page. Large keys on index b-trees are split up into <a href="fileformat2.html#ovflpgs">overflow pages</a> so that no single key uses more than one fourth of the available storage space on the page @@ -2201,5 +2201,5 @@ file, and since the wal-index is a transient structure, no further information about the format of the wal-index will be provided here. Additional details on the format of the wal-index are contained in the separate <a href="walformat.html#walidxfmt">WAL-index File Format</a> document.</p> - +<p align="center"><small><i>This page last modified on <a href="https://sqlite.org/docsrc/honeypot" id="mtimelink" data-href="https://sqlite.org/docsrc/finfo/pages/fileformat2.in?m=af2cdeaf41">2024-04-20 09:25:12</a> UTC </small></i></p> diff --git a/www/flextypegood.html b/www/flextypegood.html index bc1577b..5810ff4 100644 --- a/www/flextypegood.html +++ b/www/flextypegood.html @@ -416,7 +416,7 @@ But type enforcement is no help in prevent subtly incorrect data from being recorded. </p><p> So, for example, rigid type enforcement can successfully prevent -the customer name (text) from being inserted into integer +the customer name (text) from being inserted into the integer Customer.creditScore column. On the other hand, if that mistake occurs, it is very easy to spot the problem and find all affected rows. But type enforcement is no help in preventing a bug where the customer diff --git a/www/fts5.html b/www/fts5.html index c80bc26..1793f2c 100644 --- a/www/fts5.html +++ b/www/fts5.html @@ -177,9 +177,8 @@ Table Of Contents <div class="fancy-toc2"><a href="#custom_tokenizers">7.1. Custom Tokenizers</a></div> <div class="fancy-toc3"><a href="#synonym_support">7.1.1. Synonym Support</a></div> <div class="fancy-toc2"><a href="#custom_auxiliary_functions">7.2. Custom Auxiliary Functions</a></div> -<div class="fancy-toc3"><a href="#_custom_auxiliary_functions_api_reference_">7.2.1. -Custom Auxiliary Functions API Reference -</a></div> +<div class="fancy-toc3"><a href="#custom_auxiliary_functions_api_overview">7.2.1. Custom Auxiliary Functions API Overview</a></div> +<div class="fancy-toc3"><a href="#custom_auxiliary_functions_api_reference">7.2.2. Custom Auxiliary Functions API Reference</a></div> <div class="fancy-toc1"><a href="#the_fts5vocab_virtual_table_module">8. The fts5vocab Virtual Table Module</a></div> <div class="fancy-toc1"><a href="#fts5_data_structures">9. FTS5 Data Structures</a></div> <div class="fancy-toc2"><a href="#varint_format">9.1. Varint Format</a></div> @@ -775,7 +774,7 @@ CREATE VIRTUAL TABLE t1 USING fts5(x, tokenize = 'porter' 'ascii'); <p> -FTS5 features three built-in tokenizer modules, described in subsequent +FTS5 features four built-in tokenizer modules, described in subsequent sections: </p><ul> @@ -787,6 +786,9 @@ sections: </li><li> The <b>porter</b> tokenizer, which implements the <a href="https://tartarus.org/martin/PorterStemmer" /="1">porter stemming algorithm</a>. + + </li><li> The <b>trigram</b> tokenizer, which treats each contiguous sequence of + three characters as a token, allowing FTS5 to support more general substring matching. </li></ul> <p> It is also possible to create custom tokenizers for FTS5. The API for doing so is <a href="fts5.html#custom_tokenizers">described here</a>. @@ -987,6 +989,9 @@ Notes: but still works. If the index is to be used only for LIKE and/or GLOB pattern matching, these options are worth experimenting with to reduce the index size. + + </li><li> The index cannot be used to optimize LIKE patterns if the LIKE operator + has an ESCAPE clause. </li></ul> <a name="external_content_and_contentless_tables"></a> @@ -1400,12 +1405,12 @@ on secondary or tertiary markings in the document or query terms. <p> Auxiliary functions are similar to <a href="lang_corefunc.html">SQL scalar functions</a>, except that they may only be used within full-text queries (those that use -the MATCH operator) on an FTS5 table. Their results are calculated based not -only on the arguments passed to them, but also on the current match and -matched row. For example, an auxiliary function may return a numeric value -indicating the accuracy of the match (see the <a href="fts5.html#the_bm25_function">bm25()</a> function), -or a fragment of text from the matched row that contains one or more -instances of the search terms (see the <a href="fts5.html#the_snippet_function">snippet()</a> function). +the MATCH operator, or LIKE/GLOB with the trigram tokenizer) on an FTS5 table. +Their results are calculated based not only on the arguments passed to them, +but also on the current match and matched row. For example, an auxiliary +function may return a numeric value indicating the accuracy of the match (see +the <a href="fts5.html#the_bm25_function">bm25()</a> function), or a fragment of text from the matched row +that contains one or more instances of the search terms (see the <a href="fts5.html#the_snippet_function">snippet()</a> function). </p><p>To invoke an auxiliary function, the name of the FTS5 table should be specified as the first argument. Other arguments may follow the first, @@ -1437,7 +1442,10 @@ the following section. Applications may also implement fragment of text from one of the columns of the matched row and returns it with each instance of a queried term surrounded by markup in the same manner as the highlight() function. The fragment of text is - selected so as to maximize the number of queried terms it contains. + selected so as to maximize the number of distinct queried terms it + contains. Higher weight is given to snippets that occur at the start + of a column value, or that immediately follow "." or ":" characters + in the text. </li></ul> <a name="the_bm25_function"></a> @@ -2349,18 +2357,19 @@ replaced. returns an SQLite error code. In this case the xDestroy function is <b>not</b> invoked. -</p><p> The final three arguments passed to the auxiliary function callback are -similar to the three arguments passed to the implementation of a scalar SQL -function. All arguments except the first passed to the auxiliary function are -available to the implementation in the apVal[] array. The +</p><p> The final three arguments passed to the auxiliary function callback +(pCtx, nVal and apVal above) are similar to the three arguments passed to the +implementation of a scalar SQL function. The apVal[] array contains all +SQL arguments except the first passed to the auxiliary function. The implementation should return a result or error via the content handle pCtx. </p><p> The first argument passed to an auxiliary function callback is a pointer -to a structure containing methods that may be invoked in order to obtain -information regarding the current query or row. The second argument is an -opaque handle that should be passed as the first argument to any such method -invocation. For example, the following auxiliary function definition returns -the total number of tokens in all columns of the current row: +to a structure (pApi above) containing methods that may be invoked +in order to obtain information regarding the current query or row. The second +argument is an opaque handle (pFts above) that should be passed as the +first argument to any such method invocation. For example, the following +auxiliary function returns the total number of tokens in all columns of the +current row: </p><div class="codeblock"><pre><i>/* ** Implementation of an auxiliary function that returns the number @@ -2388,10 +2397,185 @@ static void column_size_imp( implementations in detail. Further examples may be found in the "fts5_aux.c" file of the source code. -</p><a name="_custom_auxiliary_functions_api_reference_"></a> -<h3 tags="custom auxiliary functions" id="_custom_auxiliary_functions_api_reference_"><span>7.2.1. </span> - Custom Auxiliary Functions API Reference -</h3> +</p><a name="custom_auxiliary_functions_api_overview"></a> +<h3 tags="custom auxiliary overview" id="custom_auxiliary_functions_api_overview"><span>7.2.1. </span>Custom Auxiliary Functions API Overview</h3> + +<p>This section provides an overview of the capabilities of the auxiliary +function API. It does not describe every function. Refer to the <a href="#custom_auxiliary_functions_api_reference">reference text</a> below for a +complete description. + +</p><p>When invoked, an auxiliary function implementation has access to APIs that +allow it to query FTS5 for various information. Some of these APIs return +information relating to the current row of the FTS5 table being visited, +some relating to the entire set of rows that will be visited by the FTS5 +query, and some relating to the FTS5 table. Given an FTS5 table populated as +follows: + +</p><div class="codeblock"><pre>CREATE VIRTUAL TABLE ft USING fts5(a, b); +INSERT INTO ft(rowid, a, b) VALUES + (1, 'ab cd', 'cd de one'), + (2, 'de fg', 'fg gh'), + (3, 'gh ij', 'ij ab three four'); +</pre></div> + +<p>and the query: + +</p><div class="codeblock"><pre>SELECT my_aux_function(ft) FROM ft('ab') +</pre></div> + +<p>then the custom auxiliary function will be invoked for rows 1 and 3 (all +rows that contain the token "ab" and therefore match the query). + +</p><p><b>Number of rows/columns in table: xRowCount, xColumnCount + +</b></p><p>The system may be queried for the total number of rows in the FTS5 table +using the <a href="#xRowCount">xRowCount</a> API. This provides the total number +of rows in the table, not the number that match the current query. + +</p><p>Table columns are numbered from left to right starting from 0. The +"rowid" column does not count - only user declared columns - so in the example +above column "a" is column 0 and column "b" is column 1. From within an +auxiliary function implementation, the <a href="#xColumnCount">xColumnCount</a> +API may be used to determine how many columns the table being queried has. If +the xColumnCount() API is invoked from within the implementation of the +auxiliary function my_aux_function in the example above, it returns 2. + +</p><p><b>Data From Current Row: xColumnText, xRowid + +</b></p><p>The <a href="#xRowid">xRowid</a> API may be used to find the rowid value +for the current row. The <a href="#xColumnText">xColumnText</a> may be used +to obtain the text stored in a specified column of the current row. + +</p><p><b>Token Counts: xColumnSize, xColumnTotalSize + +</b></p><p>FTS5 divides documents inserted into an fts table into tokens. These are +usually just words, perhaps folded to either upper or lower case and with any +punctuation removed. For example, the default +<a href="#unicode61_tokenizer">unicode61 tokenizer</a> tokenizes the text "The +tokenizer is case-insensitive" to a list of 5 tokens - "the", "tokenizer", is", +"case" and "insensitive". Exactly how tokens are extracted from text is +determined by the <a href="#tokenizers">tokenizer</a>. + +</p><p>The auxiliary functions API provides functions to query for both the number +of tokens in a specified column of the current row (the +<a href="#xColumnSize">xColumnSize</a> API), or for the number of tokens in a +specified column of all rows of the table (the <a href="#xColumnTotalSize">xColumnTotalSize</a> API). For the example at the +top of this section, when visiting row 1, xColumnSize returns 2 for column 0 +and 3 for column 1. xColumnTotalSize returns 6 for column 0 and 9 for column 1 +regardless of the current row. + +</p><p><b>The Current Full-Text Query: xPhraseCount, xPhraseSize, xQueryToken + +</b></p><p>An FTS5 query contains one or more <a href="#fts5_phrases">phrases</a>. The +<a href="#xPhraseCount">xPhraseCount</a>, <a href="#xPhraseSize">xPhraseSize</a> +and <a href="#xQueryToken">xQueryToken</a> APIs allow an auxiliary function +implementation to query the system for details of the current query. The +xPhraseCount API returns the number of phrases in the current query. For +example, if an FTS5 table is queried as follows: + +</p><div class="codeblock"><pre>SELECT my_aux_function(ft) FROM ft('ab AND "cd ef gh" OR ij + kl') +</pre></div> + +<p>and the xPhraseCount() API invoked from within the implementation of the +auxiliary function, it returns 3 (the three phrases being "ab", "ce ef gh" and +"ij kl"). + +</p><p>Phrases are numbered in order of appearance within a query starting from 0. +The xPhraseSize() API may be used to query for the number of tokens in a +specified phrase of the query. In the example above, phrase 0 contains 1 token, +phrase 1 contains 3 tokens, and phrase 2 contains 2. + +</p><p>The xQueryToken API may be used to access the text of a specified token +within a specified phrase of the query. Tokens are numbered within their +phrases from left to right starting from 0. For example, if the xQueryToken +API is used to request token 1 of phrase 2 in the example above, it returns +the text "kl". Token 0 of phrase 0 is "ab". + +</p><p><b>Phrase Hits in the Current Row: xPhraseFirst, xPhraseNext + +</b></p><p>These two API functions may be used to iterate through the matches for +a specified phrase of the query within the current row. Phrase matches are +identified by the column and token offset within the current row. For +example, say the following example table: + +</p><div class="codeblock"><pre>CREATE VIRTUAL TABLE ft2 USING fts5(x, y); +INSERT INTO ft2(rowid, x, y) VALUES + (1, 'xxx one two xxx five xxx six', 'seven four'), + (2, 'five four four xxx six', 'three four five six four five six'); +</pre></div> + +<p>is queried with: + +</p><div class="codeblock"><pre>SELECT my_aux_function(ft2) FROM ft2( + '("one two" OR "three") AND y:four NEAR(five six, 2)' +); +</pre></div> + +<p>The query above contains 5 phrases - "one two", "three", "four", +"five" and "six". It matches all rows of the table, so the auxiliary +function is invoked for each row. + +</p><p>In row 1, for phrase 0, "one two", there is exactly one match to iterate +through - at column 0 token offset 1. The column number is 0 because the +match appears in the left most column. The token offset is 1 because there +is exactly one token ("xxx") before the phrase match in the column value. +For phrase 1, "three", there are no matches. Phrase 2, "four", has one +match, at column 1, token offset 0. Phrase 3, "five", has one match at +column 0, token offset 4, and phrase 4, "six", has one match at column 0 +token offset 6. + +</p><p>The set of matches for each phrase in each row of the example is presented +in the table below. Each match is notated as (column-number, token-offset): + +</p><table striped="1" style="margin:1em auto; width:80%; border-spacing:0"> + <tr style="text-align:left"><th>Row</th><th>Phrase 0</th><th>Phrase 1</th><th>Phrase 2</th><th>Phrase 3</th><th>Phrase 4 + </th></tr><tr style="text-align:left;background-color:#DDDDDD"><td>1</td><td>(0, 1) </td><td></td><td>(1, 1)</td><td>(0, 4)</td><td>(0, 6) + </td></tr><tr style="text-align:left"><td>2</td><td></td><td>(1,0)</td><td>(1, 1), (1,4)</td><td>(1, 2), (1, 5)</td><td>(1, 3), (1, 6) +</td></tr></table> + +<p>The second row is slightly more complicated. There were no occurrences of +phrase 0. Phrase 1 ("three") appears once, at column 1 token offset 0. Although +there are instances of phrase 2 ("four") in column 0, none of them are reported +by the API, as phrase 4 has a <a href="#fts5_column_filters">column filter</a> - +"y:". Matches that are filtered out by column filters do not count. Similarly, +although phrases 3 and 4 do occur in column "x" of row 2, they are filtered +out by the <a href="#fts5_near_queries">NEAR filter</a>. Matches that are +filtered out by NEAR filters do not count either. + +</p><p><b>Phrase Hits in the Current Row (2): xInstCount, xInst + +</b></p><p>The <a href="#xInstCount">xInstCount</a> and <a href="#xInst">xInst</a> APIs +provide access to the same information as the xPhraseFirst and xPhraseNext +described above. The difference is that instead of iterating through the +matches for a single, specified phrase, the xInstCount/xInst APIs collate +all matches into a single flat array, sorted in order of occurrence within +the current row. Elements of this array may then be accessed randomly. + +</p><p>Each array element consists of three values: + +</p><ul> + <li> A phrase number, + </li><li> A column number, and + </li><li> A token offset +</li></ul> + +<p>Using the same example data and query as for xPhraseFirst/xPhraseNext +above, the array accessible via xInstCount/xInst consists of the following +entries for each row: + +</p><table striped="1" style="margin:1em auto; width:80%; border-spacing:0"> + <tr style="text-align:left"><th>Row</th><th>xInstCount/xInst array + </th></tr><tr style="text-align:left;background-color:#DDDDDD"><td>1</td><td>(0, 0, 1), (3, 0, 4), (4, 0, 6), (2, 1, 1) + </td></tr><tr style="text-align:left"><td>2</td><td>(1, 1, 0), (2, 1, 1), (3, 1, 2), (4, 1, 3), (2, 1, 4), (3, 1, 5), (4, 1, 6) +</td></tr></table> + +<p>Each entry of the array is called a phrase match. Phrase matches are +numbered in order, starting from 0. So, in the example above, in row 2, phrase +match 3 is (4, 1, 3) - phrase 4 of the query matches at column 1, token offset +3. + +</p><a name="custom_auxiliary_functions_api_reference"></a> +<h3 tags="custom auxiliary functions" id="custom_auxiliary_functions_api_reference"><span>7.2.2. </span>Custom Auxiliary Functions API Reference</h3> <div class="codeblock"><pre>struct Fts5ExtensionApi { int iVersion; <i>/* Currently always set to 3 */</i> @@ -2443,8 +2627,8 @@ file of the source code. <dt style="white-space:pre;font-family:monospace;font-size:120%" id="xUserData"> <b>void *(*xUserData)(Fts5Context*)</b></dt><dd> <p style="margin-top:0.1em"> -Return a copy of the context pointer the extension function was - registered with. +Return a copy of the pUserData pointer passed to the xCreateFunction() + API when the extension function was registered. </p> </dd> <dt style="white-space:pre;font-family:monospace;font-size:120%" id="xColumnTotalSize"> @@ -3090,9 +3274,9 @@ the subset of matches with rowids in the required range. </p><ul> <li> The special <a href="#structure_record_format">structure record</a>, - stored with id=1. - </li><li> The special <a href="#averages_record_format">averages record</a>, stored with id=10. + </li><li> The special <a href="#averages_record_format">averages record</a>, + stored with id=1. </li><li> A record to store each <a href="#segment_b_tree_format">segment b-tree</a> leaf and <a href="#doclist_index_format">doclist index</a> leaf and internal node. See below for how id values are calculated for these @@ -3612,7 +3796,7 @@ CREATE VIRTUAL TABLE t1 USING fts5( <p> FTS5 has no matchinfo() or offsets() function, and the snippet() function is not as fully-featured as in FTS3/4. However, since FTS5 does provide -an API allowing applications to create <a href="fts5.html#_custom_auxiliary_functions_api_reference_">custom auxiliary functions</a>, any +an API allowing applications to create <a href="fts5.html#custom_auxiliary_functions_api_reference">custom auxiliary functions</a>, any required functionality may be implemented within the application code. </p><p> The set of built-in auxiliary functions provided by FTS5 may be @@ -3714,5 +3898,5 @@ using FTS5. the amount of processing that may take place within any given INSERT, UPDATE or DELETE operation. </p></li></ul> -<p align="center"><small><i>This page last modified on <a href="https://sqlite.org/docsrc/honeypot" id="mtimelink" data-href="https://sqlite.org/docsrc/finfo/pages/fts5.in?m=386eeb4c00">2024-03-27 20:33:18</a> UTC </small></i></p> +<p align="center"><small><i>This page last modified on <a href="https://sqlite.org/docsrc/honeypot" id="mtimelink" data-href="https://sqlite.org/docsrc/finfo/pages/fts5.in?m=39d9a3b727">2024-05-22 18:42:01</a> UTC </small></i></p> diff --git a/www/index.html b/www/index.html index 1bdbef9..55e8d59 100644 --- a/www/index.html +++ b/www/index.html @@ -189,7 +189,7 @@ is in the <a href="copyright.html">public-domain</a> and is free to everyone to use for any purpose. <h3>Latest Release</h3> -<a href="releaselog/3_45_3.html">Version 3.45.3</a> (2024-04-15). +<a href="releaselog/3_46_0.html">Version 3.46.0</a> (2024-05-23). <a class="button" href="download.html">Download</a> <a class="button" href="chronology.html">Prior Releases</a> diff --git a/www/json1.html b/www/json1.html index dacfb08..f768fd6 100644 --- a/www/json1.html +++ b/www/json1.html @@ -154,14 +154,15 @@ Table Of Contents <div class="fancy-toc2"><a href="#the_jsonb_object_function">4.13. The jsonb_object() function</a></div> <div class="fancy-toc2"><a href="#the_json_patch_function">4.14. The json_patch() function</a></div> <div class="fancy-toc2"><a href="#the_jsonb_patch_function">4.15. The jsonb_patch() function</a></div> -<div class="fancy-toc2"><a href="#the_json_remove_function">4.16. The json_remove() function</a></div> -<div class="fancy-toc2"><a href="#the_jsonb_remove_function">4.17. The jsonb_remove() function</a></div> -<div class="fancy-toc2"><a href="#the_json_type_function">4.18. The json_type() function</a></div> -<div class="fancy-toc2"><a href="#the_json_valid_function">4.19. The json_valid() function</a></div> -<div class="fancy-toc2"><a href="#the_json_quote_function">4.20. The json_quote() function</a></div> -<div class="fancy-toc2"><a href="#array_and_object_aggregate_functions">4.21. Array and object aggregate functions</a></div> -<div class="fancy-toc2"><a href="#the_json_each_and_json_tree_table_valued_functions">4.22. The json_each() and json_tree() table-valued functions</a></div> -<div class="fancy-toc3"><a href="#examples_using_json_each_and_json_tree_">4.22.1. Examples using json_each() and json_tree()</a></div> +<div class="fancy-toc2"><a href="#the_json_pretty_function">4.16. The json_pretty() function</a></div> +<div class="fancy-toc2"><a href="#the_json_remove_function">4.17. The json_remove() function</a></div> +<div class="fancy-toc2"><a href="#the_jsonb_remove_function">4.18. The jsonb_remove() function</a></div> +<div class="fancy-toc2"><a href="#the_json_type_function">4.19. The json_type() function</a></div> +<div class="fancy-toc2"><a href="#the_json_valid_function">4.20. The json_valid() function</a></div> +<div class="fancy-toc2"><a href="#the_json_quote_function">4.21. The json_quote() function</a></div> +<div class="fancy-toc2"><a href="#array_and_object_aggregate_functions">4.22. Array and object aggregate functions</a></div> +<div class="fancy-toc2"><a href="#the_json_each_and_json_tree_table_valued_functions">4.23. The json_each() and json_tree() table-valued functions</a></div> +<div class="fancy-toc3"><a href="#examples_using_json_each_and_json_tree_">4.23.1. Examples using json_each() and json_tree()</a></div> </div> </div> <script> @@ -185,12 +186,12 @@ mk.innerHTML = "►"; <h1 id="overview"><span>1. </span>Overview</h1> <p> -By default, SQLite supports twenty-nine functions and two operators for +By default, SQLite supports thirty functions and two operators for dealing with JSON values. There are also two <a href="vtab.html#tabfunc2">table-valued functions</a> that can be used to decompose a JSON string. </p><p> -There are 25 scalar functions and operators: +There are twenty-six scalar functions and operators: </p><ol> <li value='1'> @@ -258,38 +259,42 @@ There are 25 scalar functions and operators: </li> <li value='17'> -<a href='#jrm'>json_remove</a>(<i>json</i>,<i>path</i>,...) +<a href='#jpretty'>json_pretty</a>(<i>json</i>) </li> <li value='18'> -<a href='#jrmb'>jsonb_remove</a>(<i>json</i>,<i>path</i>,...) +<a href='#jrm'>json_remove</a>(<i>json</i>,<i>path</i>,...) </li> <li value='19'> -<a href='#jrepl'>json_replace</a>(<i>json</i>,<i>path</i>,<i>value</i>,...) +<a href='#jrmb'>jsonb_remove</a>(<i>json</i>,<i>path</i>,...) </li> <li value='20'> -<a href='#jreplb'>jsonb_replace</a>(<i>json</i>,<i>path</i>,<i>value</i>,...) +<a href='#jrepl'>json_replace</a>(<i>json</i>,<i>path</i>,<i>value</i>,...) </li> <li value='21'> -<a href='#jset'>json_set</a>(<i>json</i>,<i>path</i>,<i>value</i>,...) +<a href='#jreplb'>jsonb_replace</a>(<i>json</i>,<i>path</i>,<i>value</i>,...) </li> <li value='22'> -<a href='#jsetb'>jsonb_set</a>(<i>json</i>,<i>path</i>,<i>value</i>,...) +<a href='#jset'>json_set</a>(<i>json</i>,<i>path</i>,<i>value</i>,...) </li> <li value='23'> -<a href='#jtype'>json_type</a>(<i>json</i>)<br><a href='#jtype'>json_type</a>(<i>json</i>,<i>path</i>) +<a href='#jsetb'>jsonb_set</a>(<i>json</i>,<i>path</i>,<i>value</i>,...) </li> <li value='24'> -<a href='#jvalid'>json_valid</a>(<i>json</i>)<br><a href='#jvalid'>json_valid</a>(<i>json</i>,flags) +<a href='#jtype'>json_type</a>(<i>json</i>)<br><a href='#jtype'>json_type</a>(<i>json</i>,<i>path</i>) </li> <li value='25'> +<a href='#jvalid'>json_valid</a>(<i>json</i>)<br><a href='#jvalid'>json_valid</a>(<i>json</i>,flags) +</li> + +<li value='26'> <a href='#jquote'>json_quote</a>(<i>value</i>) </li> @@ -299,19 +304,19 @@ There are 25 scalar functions and operators: <p>There are four <a href="lang_aggfunc.html">aggregate SQL functions</a>: </p><ol> -<li value='26'> +<li value='27'> <a href='#jgrouparray'>json_group_array</a>(<i>value</i>) </li> -<li value='27'> +<li value='28'> <a href='#jgrouparrayb'>jsonb_group_array</a>(<i>value</i>) </li> -<li value='28'> +<li value='29'> <a href='#jgroupobject'>json_group_object</a>(<i>label</i>,<i>value</i>) </li> -<li value='29'> +<li value='30'> <a href='#jgroupobjectb'>jsonb_group_object</a>(name,<i>value</i>) </li> @@ -321,11 +326,11 @@ There are 25 scalar functions and operators: <p>The two <a href="vtab.html#tabfunc2">table-valued functions</a> are: </p><ol> -<li value='30'> +<li value='31'> <a href='#jeach'>json_each</a>(<i>json</i>)<br><a href='#jeach'>json_each</a>(<i>json</i>,<i>path</i>) </li> -<li value='31'> +<li value='32'> <a href='#jtree'>json_tree</a>(<i>json</i>)<br><a href='#jtree'>json_tree</a>(<i>json</i>,<i>path</i>) </li> @@ -653,7 +658,7 @@ for infinity and not-a-number. <p> Most JSON functions do their internal processing using JSONB. So if the -input is text, they first must translate the input text into JSONB. +input is text, they first most translate the input text into JSONB. If the input is already in the JSONB format, no translation is needed, that step can be skipped, and performance is faster. @@ -849,7 +854,7 @@ well-formed JSON or if P is not a well-formed path. </p><h2 id="the_json_error_position_function"><span>4.6. </span>The json_error_position() function</h2> -<p>The json_error_positionf(X) function returns 0 if the input X is a +<p>The json_error_position(X) function returns 0 if the input X is a well-formed JSON or JSON5 string. If the input X contains one or more syntax errors, then this function returns the character position of the first syntax error. The left-most character is position 1. @@ -1241,9 +1246,23 @@ especially Arrays with lots of substructure. The jsonb_patch() function works just like the <a href="json1.html#jpatch">json_patch()</a> function except that the patched JSON is returned in the binary JSONB format. +<a name="jpretty"></a> + +</p><h2 id="the_json_pretty_function"><span>4.16. </span>The json_pretty() function</h2> +<p> +The json_pretty() function works like <a href="json1.html#jmini">json()</a> except that it adds +extra whitespace to make the JSON result easier for humans to read. +The first argument is the JSON or JSONB that is to be pretty-printed. +The optional second argument is a text string that is used for indentation. +If the second argument is omitted or is NULL, then indentation is four +spaces per level. +</p><p> +The json_pretty() function was added with SQLite version 3.46.0 +(2024-05-23). + <a name="jrm"></a> -</p><h2 id="the_json_remove_function"><span>4.16. </span>The json_remove() function</h2> +</p><h2 id="the_json_remove_function"><span>4.17. </span>The json_remove() function</h2> <p>The json_remove(X,P,...) function takes a single JSON value as its first argument followed by zero or more path arguments. @@ -1295,14 +1314,14 @@ path. <a name="jrmb"></a> -</p><h2 id="the_jsonb_remove_function"><span>4.17. </span>The jsonb_remove() function</h2> +</p><h2 id="the_jsonb_remove_function"><span>4.18. </span>The jsonb_remove() function</h2> <p> The jsonb_remove() function works just like the <a href="json1.html#jrm">json_remove()</a> function except that the edited JSON result is returned in the binary JSONB format. <a name="jtype"></a> -</p><h2 id="the_json_type_function"><span>4.18. </span>The json_type() function</h2> +</p><h2 id="the_json_type_function"><span>4.19. </span>The json_type() function</h2> <p>The json_type(X) function returns the "type" of the outermost element of X. The json_type(X,P) function returns the "type" of the element @@ -1354,7 +1373,7 @@ JSON path. <a name="jvalid"></a> -</p><h2 id="the_json_valid_function"><span>4.19. </span>The json_valid() function</h2> +</p><h2 id="the_json_valid_function"><span>4.20. </span>The json_valid() function</h2> <p>The json_valid(X,Y) function return 1 if the argument X is well-formed JSON, or returns 0 if X is not well-formed. The Y parameter is an integer @@ -1435,7 +1454,7 @@ returns NULL. <a name="jquote"></a> -</p><h2 id="the_json_quote_function"><span>4.20. </span>The json_quote() function</h2> +</p><h2 id="the_json_quote_function"><span>4.21. </span>The json_quote() function</h2> <p>The json_quote(X) function converts the SQL value X (a number or a string) into its corresponding JSON representation. If X is a JSON value @@ -1467,7 +1486,7 @@ returned by another JSON function, then this function is a no-op. <a name="jgrouparrayb"></a> <a name="jgroupobjectb"></a> -</p><h2 id="array_and_object_aggregate_functions"><span>4.21. </span>Array and object aggregate functions</h2> +</p><h2 id="array_and_object_aggregate_functions"><span>4.22. </span>Array and object aggregate functions</h2> <p>The json_group_array(X) function is an <a href="lang_aggfunc.html">aggregate SQL function</a> that returns a JSON array @@ -1481,7 +1500,7 @@ result in the binary <a href="json1.html#jsonbx">JSONB</a> format. <a name="jtree"></a> -</p><h2 id="the_json_each_and_json_tree_table_valued_functions"><span>4.22. </span>The json_each() and json_tree() table-valued functions</h2> +</p><h2 id="the_json_each_and_json_tree_table_valued_functions"><span>4.23. </span>The json_each() and json_tree() table-valued functions</h2> <p>The json_each(X) and json_tree(X) <a href="vtab.html#tabfunc2">table-valued functions</a> walk the JSON value provided as their first argument and return one row for each @@ -1556,7 +1575,7 @@ the current row, or the path to the current row in the case where the iteration starts on a primitive type and thus only provides a single row of output. -</p><h3 id="examples_using_json_each_and_json_tree_"><span>4.22.1. </span>Examples using json_each() and json_tree()</h3> +</p><h3 id="examples_using_json_each_and_json_tree_"><span>4.23.1. </span>Examples using json_each() and json_tree()</h3> <p>Suppose the table "CREATE TABLE user(name,phone)" stores zero or more phone numbers as a JSON array object in the user.phone field. @@ -1616,5 +1635,5 @@ SELECT DISTINCT json_extract(big.json,'$.id') WHERE json_tree.key='uuid' AND json_tree.value='6fa5181e-5721-11e5-a04e-57f3d7b32808'; </pre></blockquote> - +<p align="center"><small><i>This page last modified on <a href="https://sqlite.org/docsrc/honeypot" id="mtimelink" data-href="https://sqlite.org/docsrc/finfo/pages/json1.in?m=f887124e7e">2024-05-05 15:23:53</a> UTC </small></i></p> diff --git a/www/keyword_index.html b/www/keyword_index.html index 6c64d52..b437dee 100644 --- a/www/keyword_index.html +++ b/www/keyword_index.html @@ -165,6 +165,7 @@ Other Documentation Indexes: <li> <a href="syntax/alter-table-stmt.html">alter-table-stmt syntax diagram</a> </li> <li> <a href="amalgamation.html">amalgamation</a> </li> <li> <a href="download.html">amalgamation tarball</a> </li> +<li> <a href="lang_datefunc.html#dtambg">ambiguous dates</a> </li> <li> <a href="testing.html#aflfuzz">American Fuzzy Lop fuzzer</a> </li> <li> <a href="pragma.html#pragma_analysis_limit">analysis_limit pragma</a> </li> <li> <a href="syntax/analyze-stmt.html">analyze-stmt</a> </li> @@ -179,6 +180,7 @@ Other Documentation Indexes: <li> <a href="flextypegood.html">appreciate the freedom</a> </li> <li> <a href="whentouse.html">Appropriate Uses For SQLite</a> </li> <li> <a href="lang_analyze.html#approx">approximate ANALYZE</a> </li> +<li> <a href="lang_analyze.html#approx">Approximate ANALYZE For Large Databases</a> </li> <li> <a href="cli.html#sqlar">.archive command</a> </li> <li> <a href="lang_mathfunc.html#asin">asin() SQL function</a> </li> <li> <a href="lang_mathfunc.html#asinh">asinh() SQL function</a> </li> @@ -418,7 +420,8 @@ Other Documentation Indexes: <li> <a href="csv.html">CSV virtual table</a> </li> <li> <a href="syntax/cte-table-name.html">cte-table-name</a> </li> <li> <a href="syntax/cte-table-name.html">cte-table-name syntax diagram</a> </li> -<li> <a href="fts5.html#_custom_auxiliary_functions_api_reference_">custom auxiliary functions</a> </li> +<li> <a href="fts5.html#custom_auxiliary_functions_api_reference">custom auxiliary functions</a> </li> +<li> <a href="fts5.html#custom_auxiliary_functions_api_overview">custom auxiliary overview</a> </li> <li> <a href="custombuild.html">custom builds</a> </li> <li> <a href="rtree.html#customquery">custom r-tree queries</a> </li> <li> <a href="appfunc.html">custom SQL function</a> </li> @@ -978,7 +981,7 @@ Other Documentation Indexes: <li> <a href="lang_expr.html#isisnot">IS operator</a> </li> <li> <a href="isolation.html">isolation</a> </li> <li> <a href="testing.html#dbsqlfuzz">jfuzz</a> </li> -<li> <a href="optoverview.html#table_order">join order</a> </li> +<li> <a href="optoverview.html#joins">join order</a> </li> <li> <a href="syntax/join-clause.html">join-clause</a> </li> <li> <a href="syntax/join-clause.html">join-clause syntax diagram</a> </li> <li> <a href="syntax/join-constraint.html">join-constraint</a> </li> @@ -1015,6 +1018,8 @@ Other Documentation Indexes: <li> <a href="json1.html#jobj">json_object SQL function</a> </li> <li> <a href="json1.html#jpatch">json_patch</a> </li> <li> <a href="json1.html#jpatch">json_patch SQL function</a> </li> +<li> <a href="json1.html#jpretty">json_pretty</a> </li> +<li> <a href="json1.html#jpretty">json_pretty SQL function</a> </li> <li> <a href="json1.html#jquote">json_quote</a> </li> <li> <a href="json1.html#jquote">json_quote SQL function</a> </li> <li> <a href="json1.html#jrm">json_remove</a> </li> @@ -1165,6 +1170,7 @@ Other Documentation Indexes: <li> <a href="lang_select.html#nullslast">NULLS FIRST</a> </li> <li> <a href="lang_select.html#nullslast">NULLS LAST</a> </li> <li> <a href="tclsqlite.html#nullvalue">nullvalue method</a> </li> +<li> <a href="lang_expr.html#litvalue">numeric literals</a> </li> <li> <a href="syntax/numeric-literal.html">numeric-literal</a> </li> <li> <a href="syntax/numeric-literal.html">numeric-literal syntax diagram</a> </li> <li> <a href="lang_naming.html">object resolution</a> </li> @@ -1349,6 +1355,9 @@ Other Documentation Indexes: <li> <a href="optoverview.html">query planner</a> </li> <li> <a href="queryplanner-ng.html#howtofix">query planner checklist</a> </li> <li> <a href="queryplanner-ng.html#qpstab">query planner stability guarantee</a> </li> +<li> <a href="optoverview.html#autoindex">query-time index</a> </li> +<li> <a href="optoverview.html#autoindex">Query-time indexes</a> </li> +<li> <a href="optoverview.html#autoindex">query-time indexing</a> </li> <li> <a href="pragma.html#pragma_query_only">query_only pragma</a> </li> <li> <a href="quickstart.html">Quick Start Guide</a> </li> <li> <a href="pragma.html#pragma_quick_check">quick_check pragma</a> </li> @@ -1379,10 +1388,10 @@ Other Documentation Indexes: <li> <a href="rtree.html#readwrite">reading and writing an rtree at the same time</a> </li> <li> <a href="fts3.html#*fts4rebuidcmd">"rebuild" command</a> </li> <li> <a href="cves.html#cvetab">recent CVEs</a> </li> -<li> <a href="lang_analyze.html#req">recommended ANALYZE usage pattern</a> </li> <li> <a href="locrsf.html">recommended by the US Library of Congress</a> </li> <li> <a href="compile.html#rcmd">recommended compile-time option</a> </li> <li> <a href="locrsf.html">recommended storage format</a> </li> +<li> <a href="lang_analyze.html#req">Recommended usage patterns for ANALYZE</a> </li> <li> <a href="fileformat2.html#record_format">record format</a> </li> <li> <a href="cli.html#recover">.recover dot-command</a> </li> <li> <a href="walformat.html#recovery">recovery</a> </li> @@ -1439,6 +1448,7 @@ Other Documentation Indexes: <li> <a href="datatype3.html#affname">rules for determining column affinity</a> </li> <li> <a href="datatype3.html#affview">rules for determining column affinity in VIEWs</a> </li> <li> <a href="loadext.html">Run-Time Loadable Extensions</a> </li> +<li> <a href="lang_analyze.html#pragopt">running ANALYZE via PRAGMA optimize</a> </li> <li> <a href="cli.html#safemode">safe command-line option</a> </li> <li> <a href="cli.html#safemode">--safe command-line option</a> </li> <li> <a href="howtocorrupt.html#svptbug">SAVEPOINT bug</a> </li> @@ -1894,6 +1904,7 @@ Other Documentation Indexes: <li> <a href="c3ref/win32_set_directory.html">sqlite3_win32_set_directory16</a> </li> <li> <a href="c3ref/win32_set_directory.html">sqlite3_win32_set_directory8</a> </li> <li> <a href="session/sqlite3changegroup_add.html">sqlite3changegroup_add</a> </li> +<li> <a href="session/sqlite3changegroup_add_change.html">sqlite3changegroup_add_change</a> </li> <li> <a href="session/sqlite3changegroup_add_strm.html">sqlite3changegroup_add_strm</a> </li> <li> <a href="session/sqlite3changegroup_delete.html">sqlite3changegroup_delete</a> </li> <li> <a href="session/sqlite3changegroup_new.html">sqlite3changegroup_new</a> </li> @@ -2646,6 +2657,7 @@ Other Documentation Indexes: <li> <a href="howtocorrupt.html#stalefd">stale file descriptor</a> </li> <li> <a href="uri.html#coreqp">standard query parameters</a> </li> <li> <a href="tempfiles.html#stmtjrnl">statement journal</a> </li> +<li> <a href="lang_analyze.html#statanal">static ANALYZE results</a> </li> <li> <a href="loadext.html#statext">statically linked extensions</a> </li> <li> <a href="pragma.html#pragma_stats">stats pragma</a> </li> <li> <a href="tclsqlite.html#status">status method</a> </li> @@ -2773,8 +2785,10 @@ Other Documentation Indexes: <li> <a href="pragma.html#pragma_threads">threads pragma</a> </li> <li> <a href="testing.html#harnesses">three test harnesses</a> </li> <li> <a href="lang_datefunc.html#tmshf">time shift modifiers</a> </li> +<li> <a href="lang_datefunc.html#tmval">time value</a> </li> <li> <a href="lang_datefunc.html#dttm">time()</a> </li> <li> <a href="lang_datefunc.html#dttm">time() SQL function</a> </li> +<li> <a href="lang_datefunc.html#tmval">time-value</a> </li> <li> <a href="lang_datefunc.html#tmdif">timediff()</a> </li> <li> <a href="lang_datefunc.html#tmdif">timediff() SQL function</a> </li> <li> <a href="tclsqlite.html#timeout">timeout method</a> </li> @@ -2816,6 +2830,7 @@ Other Documentation Indexes: <li> <a href="lang_createtable.html#uniqueconst">UNIQUE</a> </li> <li> <a href="lang_createtable.html#uniqueconst">unique constraint</a> </li> <li> <a href="lang_createindex.html#uniqueidx">unique index</a> </li> +<li> <a href="lang_datefunc.html#jdmod">unixepoch modifier</a> </li> <li> <a href="lang_datefunc.html#uepch">unixepoch()</a> </li> <li> <a href="lang_datefunc.html#uepch">unixepoch() function</a> </li> <li> <a href="lang_datefunc.html#uepch">unixepoch() SQL function</a> </li> @@ -2853,6 +2868,7 @@ Other Documentation Indexes: <li> <a href="whentouse.html#website">using SQLite for websites</a> </li> <li> <a href="backup.html">Using the SQLite Online Backup API</a> </li> <li> <a href="unlock_notify.html">Using the SQLite Unlock Notification Feature</a> </li> +<li> <a href="lang_datefunc.html#localtime">'utc' and 'localtime' modifiers</a> </li> <li> <a href="lang_datefunc.html#localtime">'utc' modifier</a> </li> <li> <a href="lang_vacuum.html">vacuum</a> </li> <li> <a href="lang_vacuum.html#vacuuminto">VACUUM INTO</a> </li> @@ -3033,6 +3049,7 @@ Other Documentation Indexes: <li> <a href="releaselog/3_45_1.html">Version 3.45.1</a> </li> <li> <a href="releaselog/3_45_2.html">Version 3.45.2</a> </li> <li> <a href="releaselog/3_45_3.html">Version 3.45.3</a> </li> +<li> <a href="releaselog/3_46_0.html">Version 3.46.0</a> </li> <li> <a href="releaselog/3_5_0.html">Version 3.5.0</a> </li> <li> <a href="releaselog/3_5_1.html">Version 3.5.1</a> </li> <li> <a href="releaselog/3_5_2.html">Version 3.5.2</a> </li> @@ -3177,7 +3194,9 @@ Other Documentation Indexes: <li> <a href="affcase1.html">What If OpenOffice Used SQLite</a> </li> <li> <a href="withoutrowid.html#wtu">when to use WITHOUT ROWID</a> </li> <li> <a href="lang_select.html#whereclause">WHERE clause</a> </li> +<li> <a href="optoverview.html#pushdown">WHERE-clause push-down optimization</a> </li> <li> <a href="lang_altertable.html#altertableishard">why ALTER TABLE is so difficult</a> </li> +<li> <a href="whybytecode.html">Why SQLite Uses Bytecode</a> </li> <li> <a href="malloc.html#win32heap">Win32 native memory allocator</a> </li> <li> <a href="windowfunctions.html#wchaining">window chaining</a> </li> <li> <a href="windowfunctions.html">window function</a> </li> diff --git a/www/lang.html b/www/lang.html index 15cc26d..bb656c3 100644 --- a/www/lang.html +++ b/www/lang.html @@ -160,7 +160,9 @@ also provided. The SQL language syntax is described by <li><a href='lang_expr.html'>expression</a></li> <li><a href='lang_indexedby.html'>INDEXED BY</a></li> <li><a href='lang_insert.html'>INSERT</a></li> +<li><a href='json1.html'>JSON functions</a></li> <li><a href='lang_keywords.html'>keywords</a></li> +<li><a href='lang_mathfunc.html'>math functions</a></li> <li><a href='lang_conflict.html'>ON CONFLICT clause</a></li> <li><a href='pragma.html#syntax'>PRAGMA</a></li> <li><a href='lang_reindex.html'>REINDEX</a></li> @@ -173,6 +175,7 @@ also provided. The SQL language syntax is described by <li><a href='lang_update.html'>UPDATE</a></li> <li><a href='lang_upsert.html'>UPSERT</a></li> <li><a href='lang_vacuum.html'>VACUUM</a></li> +<li><a href='windowfunctions.html'>window functions</a></li> <li><a href='lang_with.html'>WITH clause</a></li> </ul> </div> diff --git a/www/lang_analyze.html b/www/lang_analyze.html index 7f65a7f..f841633 100644 --- a/www/lang_analyze.html +++ b/www/lang_analyze.html @@ -120,6 +120,34 @@ antiRobotDefense(); <div class="fancy_title"> ANALYZE </div> +<div class="fancy_toc"> +<a onclick="toggle_toc()"> +<span class="fancy_toc_mark" id="toc_mk">►</span> +Table Of Contents +</a> +<div id="toc_sub"><div class="fancy-toc1"><a href="#overview">1. Overview</a></div> +<div class="fancy-toc1"><a href="#recommended_usage_patterns">2. Recommended usage patterns</a></div> +<div class="fancy-toc2"><a href="#periodically_run_pragma_optimize_">2.1. Periodically run "PRAGMA optimize"</a></div> +<div class="fancy-toc2"><a href="#fixed_results_of_analyze">2.2. Fixed results of ANALYZE</a></div> +<div class="fancy-toc1"><a href="#details">3. Details</a></div> +<div class="fancy-toc1"><a href="#automatically_running_analyze">4. Automatically Running ANALYZE</a></div> +<div class="fancy-toc1"><a href="#approximate_analyze_for_large_databases">5. Approximate ANALYZE For Large Databases</a></div> +<div class="fancy-toc2"><a href="#limitations_of_approximate_analyze">5.1. Limitations of approximate ANALYZE</a></div> +</div> +</div> +<script> +function toggle_toc(){ +var sub = document.getElementById("toc_sub") +var mk = document.getElementById("toc_mk") +if( sub.style.display!="block" ){ +sub.style.display = "block"; +mk.innerHTML = "▼"; +} else { +sub.style.display = "none"; +mk.innerHTML = "►"; +} +} +</script> </div> @@ -128,8 +156,8 @@ ANALYZE <h1 id="overview"><span>1. </span>Overview</h1> <p><b><a href="syntax/analyze-stmt.html">analyze-stmt:</a></b> -<button id='x9d08cb93' onclick='hideorshow("x9d08cb93","x6f8054a5")'>hide</button></p> - <div id='x6f8054a5' class='imgcontainer'> +<button id='x3115000d' onclick='hideorshow("x3115000d","x4b619059")'>hide</button></p> + <div id='x4b619059' class='imgcontainer'> <div style="max-width:654px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 654.557 140.4"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="32,17 20,21 20,12" style="fill:rgb(0,0,0)"/> @@ -181,7 +209,7 @@ ANALYZE indices and stores the collected information in <a href="fileformat2.html#intschema">internal tables</a> of the database where the query optimizer can access the information and use it to help make better query planning choices. -If no arguments are given, all attached databases are +If no arguments are given, the main database and all attached databases are analyzed. If a schema name is given as the argument, then all tables and indices in that one database are analyzed. If the argument is a table name, then only that table and the @@ -190,24 +218,121 @@ is an index name, then only that one index is analyzed.</p> <a name="req"></a> -<h2 id="recommended_usage_pattern"><span>1.1. </span>Recommended usage pattern</h2> +<h1 id="recommended_usage_patterns"><span>2. </span>Recommended usage patterns</h1> + +<p> The use of ANALYZE is never required. However, if an application +makes complex queries that have many possible query plans, the query +planner will be better able to pick the best plan if ANALYZE has +been run. This can result it significant performance improvements for +some queries. + +</p><p> Two recommended approaches for when and how to run ANALYZE are +described in the next subsections, in order of preference. + +<a name="pragopt"></a> + +</p><h2 id="periodically_run_pragma_optimize_"><span>2.1. </span>Periodically run "PRAGMA optimize"</h2> + +<p>The <a href="pragma.html#pragma_optimize">PRAGMA optimize</a> command will automatically run ANALYZE when +needed. Suggested use: + +</p><ol> +<li><p> +Applications with short-lived database connections should run +"PRAGMA optimize;" once, just prior to closing each database connection. + +</p></li><li><p> +Applications that use long-lived database connections should run +"PRAGMA optimize=0x10002;" when the connection is first opened, and then +also run "PRAGMA optimize;" periodically, perhaps once per day, or more if +the database is evolving rapidly. + +</p></li><li><p>All applications should run "PRAGMA optimize;" after a schema change, +especially after one or more <a href="lang_createindex.html">CREATE INDEX</a> statements. +</p></li></ol> + +<p> + +</p><p>The <a href="pragma.html#pragma_optimize">PRAGMA optimize</a> command is usually a no-op but it will occasionally +run one or more ANALYZE subcommands on individual tables of the database +if doing so will be useful to the query planner. +Since SQLite version 3.46.0 (2024-05-23), the "PRAGMA optimize" command +automatically limits the scope of ANALYZE subcommands so that +the overall "PRAGMA optimize" command completes quickly even on enormous +databases. There is no need to use <a href="pragma.html#pragma_analysis_limit">PRAGMA analysis_limit</a>. This is the +recommended way of running ANALYZE moving forward. + +</p><p>The <a href="pragma.html#pragma_optimize">PRAGMA optimize</a> command will normally only consider running ANALYZE on +tables that have been previously queried by the same database connection or +that do not have entries in the <a href="fileformat2.html#stat1tab">sqlite_stat1</a> table. +However, if the 0x10000 bit is added to the argument, PRAGMA optimize will +examine all tables to see if they can benefit from ANALYZE, not just those +that have been recently queried. +There is no query history when a database connection first opens, and +that is why adding the 0x10000 bit is recommended when running PRAGMA optimize +on a fresh database connection. + +</p><p>See the <a href="lang_analyze.html#autoanalyze">Automatically Running ANALYZE</a> and +<a href="lang_analyze.html#approx">Approximate ANALYZE For Large Databases</a> sections below for additional +information. + +<a name="statanal"></a> + +</p><h2 id="fixed_results_of_analyze"><span>2.2. </span>Fixed results of ANALYZE</h2> + +<p>Running ANALYZE can cause SQLite to choose different query plans +for subsequent queries. This is almost always a positive thing, as the +query plans chosen after ANALYZE will in nearly every case be better than +the query plans picked before ANALYZE. That is the whole point of ANALYZE. +But there can be no proof of running ANALYZE will always be beneficial. +One can construct pathological cases where running +ANALYZE could make some subsequent queries run slower. + +</p><p>Some developers prefer that once the design of an application is frozen, +SQLite will always pick the same query plans as it did during +development and testing. +Then if a millions of copies of the application are shipped to customers, +the developers are assured that all of those millions of copies are running +the same query plans regardless of what data the individual customers insert +into their particular databases. This can help in reproducing complaints +of performance problems coming back from the field. + +</p><p>To achieve this objection, never run a full ANALYZE nor the +"PRAGMA optimize" command in the application. +Rather, only run ANALYZE during development, manually using the +<a href="cli.html">command-line interface</a> or similar, on a test database +that is similar in size and content to live databases. Then capture +the result of this one-time ANALYZE using a script like the +following: + +</p><div class="codeblock"><pre>.mode list +SELECT + 'ANALYZE sqlite_schema;' || + 'DELETE FROM sqlite_stat1;' || + 'INSERT INTO sqlite_stat1(tbl,idx,stat)VALUES' || + (SELECT group_concat(format('(%Q,%Q,%Q)',tbl,idx,stat),',') + FROM sqlite_stat1) || + ';ANALYZE sqlite_schema;'; +</pre></div> -<p>Applications with long-lived databases that use complex -queries should consider running the following commands just prior -to closing each database connection: +<p>When creating a new instance of the database in deployed instances of +the application, or perhaps every time the application is started up in +the case of long-running applications, run the commands generated by +script above. This will populate the <a href="fileformat2.html#stat1tab">sqlite_stat1</a> table exactly as +it was during development and testing and ensure that the query plans +selected in the field are same has those selected during testing in the +lab. Maybe copy/paste the string generated by the script above into +a static string constant named "zStat1Init" and then invoke: -</p><div class="codeblock"><pre>PRAGMA analysis_limit=400; -PRAGMA optimize; +</p><div class="codeblock"><pre>sqlite3_exec(db, zStat1Init, 0, 0, 0); </pre></div> -<p>The <a href="pragma.html#pragma_optimize">optimize pragma</a> is usually a no-op but it will occasionally -run ANALYZE if it seems like doing so will be useful to the query planner. -The <a href="pragma.html#pragma_analysis_limit">analysis_limit pragma</a> limits the scope of any ANALYZE command that -the <a href="pragma.html#pragma_optimize">optimize pragma</a> runs so that it does not consume too many CPU cycles. -The constant "400" can be adjusted as needed. Values between 100 and -1000 work well for most applications. +<p>Perhaps also add "BEGIN;" at the start of the string constant and +"COMMIT;" at the end, depending on the context in which the script is run. -</p><h1 id="details"><span>2. </span>Details</h1> +</p><p>See the <a href="queryplanner-ng.html#qpstab">query planner stability guarantee</a> for addition information. + +</p><h1 id="details"><span>3. </span>Details</h1> <p> The default implementation stores all statistics in a single table named "<a href="fileformat2.html#stat1tab">sqlite_stat1</a>". @@ -238,7 +363,7 @@ ANALYZE command. See "<a href="optoverview.html#manctrl">Manual Control Of Query Plans Using SQLITE_STAT Tables</a>" for further information.</p> -<p> Statistics gathered by ANALYZE are not automatically updated as +<p> Statistics gathered by ANALYZE are <u>not</u> updated as the content of the database changes. If the content of the database changes significantly, or if the database schema changes, then one should consider rerunning the ANALYZE command in order to update the statistics.</p> @@ -252,12 +377,15 @@ can force the query planner to reread the statistics tables by running <a name="autoanalyze"></a> -<h1 id="automatically_running_analyze"><span>3. </span>Automatically Running ANALYZE</h1> +<h1 id="automatically_running_analyze"><span>4. </span>Automatically Running ANALYZE</h1> <p>The <a href="pragma.html#pragma_optimize">PRAGMA optimize</a> command will automatically run ANALYZE on individual tables on an as-needed basis. The recommended practice is for applications to invoke the <a href="pragma.html#pragma_optimize">PRAGMA optimize</a> statement just before closing each database -connection.</p> +connection. Or, if the application keeps a single database connection open +for a long time, then it should run "PRAGMA optimize=0x10002" when the +connection is first opened and run "PRAGMA optimize;" periodically thereafter, +perhaps once per day or even once per hour.</p> <p>Each SQLite <a href="c3ref/sqlite3.html">database connection</a> records cases when the query planner would benefit from having accurate results of ANALYZE at hand. These records @@ -274,22 +402,23 @@ is recommended that <a href="pragma.html#pragma_optimize">PRAGMA optimize</a> be is closing and has thus had an opportunity to accumulate as much usage information as possible. It is also reasonable to set a timer to run <a href="pragma.html#pragma_optimize">PRAGMA optimize</a> every few hours, or every few days, for database connections that stay open -for a long time.</p> - -<p>Applications that desire more control can run <a href="pragma.html#pragma_optimize">PRAGMA optimize(0x03)</a> to -obtain a list of ANALYZE commands that SQLite thinks are appropriate to run, -but without actually running those commands. If the returned set is -non-empty, the application can then make a decision about whether or not -to run the suggested ANALYZE commands, perhaps after prompting the user -for guidance.</p> +for a long time. When running <a href="pragma.html#pragma_optimize">PRAGMA optimize</a> immediately after a +database connection is opened, one can add the 0x10000 bit to the bitmask +argument (thus making the command read "PRAGMA optimize=0x10002") which +causes all tables to be examined, even tables that have not been +queried during the current connection.</p> <p>The <a href="pragma.html#pragma_optimize">PRAGMA optimize</a> command was first introduced with SQLite 3.18.0 (2017-03-28) and is a no-op for all prior releases -of SQLite.</p> +of SQLite. The <a href="pragma.html#pragma_optimize">PRAGMA optimize</a> command was significantly enhanced +in SQLite 3.46.0 (2024-05-23) and the advice given in this +documentation is based on those enhancements. Applications that +use earlier versions of SQLite should consult the corresponding +documentation for better advice on the best ways to use PRAGMA optimize.</p> <a name="approx"></a> -<h1 id="approximate_analyze_for_large_databases"><span>4. </span>Approximate ANALYZE For Large Databases</h1> +<h1 id="approximate_analyze_for_large_databases"><span>5. </span>Approximate ANALYZE For Large Databases</h1> <p>By default, ANALYZE does a full scan of every index. This can be slow for large databases. So beginning with SQLite version 3.32.0 (2020-05-22), the @@ -335,16 +464,19 @@ is noticeably inferior to a full-scan ANALYZE, but such cases are rare in real-world problems. </p><p>A good rule of thumb seems to be to always set "PRAGMA analysis_limit=N" -for N between 100 and 1000 prior to running either "ANALYZE" or -"<a href="pragma.html#pragma_optimize">PRAGMA optimize</a>". The results are not quite as precise, but they -are precise enough, and the fact that the results are computed so much -faster means that developers are more likely to compute them. An -approximate ANALYZE is better than not running ANALYZE at all. +for N between 100 and 1000 prior to running either "ANALYZE". It used +to be that this was also recommended prior to running +"<a href="pragma.html#pragma_optimize">PRAGMA optimize</a>", but since version 3.46.0 (2024-05-23) that +happens automatically. The results are not quite as precise when using +PRAGMA analysis_limit, but they are precise enough, and the fact that +the results are computed so much faster means that developers are more +likely to compute them. An approximate ANALYZE is better than not +running ANALYZE at all. -</p><h2 id="limitations_of_approximate_analyze"><span>4.1. </span>Limitations of approximate ANALYZE</h2> +</p><h2 id="limitations_of_approximate_analyze"><span>5.1. </span>Limitations of approximate ANALYZE</h2> <p>The content in the sqlite_stat4 table cannot be computed with anything less than a full scan. Hence, if a non-zero analysis limit is specified, the sqlite_stat4 table is not computed. -</p><p align="center"><small><i>This page last modified on <a href="https://sqlite.org/docsrc/honeypot" id="mtimelink" data-href="https://sqlite.org/docsrc/finfo/pages/lang_analyze.in?m=79afc38f73">2024-02-21 13:43:47</a> UTC </small></i></p> +</p><p align="center"><small><i>This page last modified on <a href="https://sqlite.org/docsrc/honeypot" id="mtimelink" data-href="https://sqlite.org/docsrc/finfo/pages/lang_analyze.in?m=4607c3507e">2024-05-05 15:23:53</a> UTC </small></i></p> diff --git a/www/lang_datefunc.html b/www/lang_datefunc.html index 24d0338..7f4ff38 100644 --- a/www/lang_datefunc.html +++ b/www/lang_datefunc.html @@ -126,7 +126,6 @@ Date And Time Functions Table Of Contents </a> <div id="toc_sub"><div class="fancy-toc1"><a href="#overview">1. Overview</a></div> -<div class="fancy-toc2"><a href="#timediff_">1.1. Timediff()</a></div> <div class="fancy-toc1"><a href="#time_values">2. Time Values</a></div> <div class="fancy-toc1"><a href="#modifiers">3. Modifiers</a></div> <div class="fancy-toc1"><a href="#examples">4. Examples</a></div> @@ -169,47 +168,63 @@ SQLite supports seven <a href="lang_corefunc.html">scalar</a> date and time func </ol> <p> -The first six date and time functions take an optional time value as an argument, followed -by zero or more modifiers. +The first six date and time functions take an optional <a href="lang_datefunc.html#tmval">time-value</a> as an argument, followed +by zero or more <a href="lang_datefunc.html#dtmods">modifiers</a>. The strftime() function also takes a format string as its first argument. -The timediff() function takes exactly two arguments which are both time values. +The timediff() function takes exactly two arguments which are both <a href="lang_datefunc.html#tmval">time-values</a>. </p> <p> -Date and time values can be stored as -</p><ul> -<li> text in a subset of the <a href="http://en.wikipedia.org/wiki/ISO_8601">ISO-8601</a> format, -</li><li> numbers representing the <a href="http://en.wikipedia.org/wiki/Julian_day">Julian day</a>, or -</li><li> numbers representing the number of seconds since (or before) 1970-01-01 00:00:00 UTC - (the unix timestamp). -</li></ul> +SQLite does not have a dedicated date/time datatype. Instead, +date and time values can stored as any of the following: + +</p><p></p><blockquote> +<table border="0" cellspacing="0" cellpadding="0"> +<tr> +<td><a href="http://en.wikipedia.org/wiki/ISO_8601">ISO-8601</a> +</td><td>A text string that is an ISO 8601 date/time value. +Example: <tt>'2025-05-29 14:16:00'</tt> +</td></tr><tr> +<td><a href="http://en.wikipedia.org/wiki/Julian_day">Julian day number</a> +</td><td>The number of days including fractional days since -4713-11-24 12:00:00 +Example: <tt>2460825.09444444</tt> +</td></tr><tr> +<td><a href="https://en.wikipedia.org/wiki/Unix_time">Unix timestamp</a> +</td><td>The number of seconds including fractional seconds since 1970-01-01 00:00:00 +Example: <tt>1748528160</tt> +</td></tr></table> +</blockquote> <p> -All of the date time functions access time-values as either ISO-8601 strings or -Julian day numbers. They also access unix timestamps with optional arguments -(the 'auto' and 'unixepoch' modifiers described below). Since the timediff() -function does not accept any optional argument, it can only use ISO-8601 and -Julian day number time values. +These three formats are collectively known as <a href="lang_datefunc.html#tmval">time-values</a>. +All of the date time functions accept time-values as either ISO-8601 text or +as Julian day numbers. They can also be made to accept unix timestamps by +adding optional modifiers arguments <a href="lang_datefunc.html#automod">'auto'</a> or +<a href="lang_datefunc.html#jdmod">'unixepoch'</a>. +Since the timediff() function does not accept modifiers, +it can only use ISO-8601 and julian day number time-values. <a name="dttm"></a> </p><p> -The date() function returns the date as text in this format: YYYY-MM-DD. +The <b>date()</b> function returns the date as text in this format: YYYY-MM-DD. <a name="dttm"></a> </p><p> -The time() function returns the time as text in this format: HH:MM:SS. +The <b>time()</b> function returns the time as text in formatted as HH:MM:SS or as HH:MM:SS.SSS if +the <a href="lang_datefunc.html#subsec">subsec modifier</a> is used. <a name="dttm"></a> </p><p> -The datetime() function returns the date and time as text in this formats: YYYY-MM-DD HH:MM:SS. +The <b>datetime()</b> function returns the date and time formatted as YYYY-MM-DD HH:MM:SS or +as YYYY-MM-DD HH:MM:SS.SSS if the <a href="lang_datefunc.html#subsec">subsec modifier</a> is used. <a name="jlndy"></a> </p><p> -The julianday() function returns the +The <b>julianday()</b> function returns the <a href="http://en.wikipedia.org/wiki/Julian_day">Julian day</a> - the fractional number of days since noon in Greenwich on November 24, 4714 B.C. (<a href="http://en.wikipedia.org/wiki/Proleptic_Gregorian_calendar">Proleptic Gregorian calendar</a>). @@ -217,7 +232,7 @@ fractional number of days since noon in Greenwich on November 24, 4714 B.C. <a name="uepch"></a> </p><p> -The unixepoch() function returns a unix timestamp - the number of seconds +The <b>unixepoch()</b> function returns a unix timestamp - the number of seconds since 1970-01-01 00:00:00 UTC. The unixepoch() function normally returns an integer number of seconds, but with the optional <a href="lang_datefunc.html#subsec">subsec modifier</a> it will return a floating point number which is the fractional number of seconds. @@ -225,22 +240,27 @@ will return a floating point number which is the fractional number of seconds. <a name="strftm"></a> </p><p> -The strftime() routine returns the date formatted according to +The <b>strftime()</b> function returns the date formatted according to the format string specified as the first argument. The format string supports the most common substitutions found in the <a href="http://opengroup.org/onlinepubs/007908799/xsh/strftime.html">strftime() function</a> from the standard C library plus two new substitutions, %f and %J. -The following is a complete list of valid strftime() substitutions: +The following is a complete list of valid strftime() substitutions +as of version 3.46.0 (2024-05-23). Earlier versions of SQLite +might not support all substitutions. If an undefined or unsupported +substitution is seen, the result is NULL. </p> <blockquote> <table border="0" cellpadding="0" cellspacing="0"> <tr><td></td><td width="10"></td><td></td></tr> -<tr><td> %d </td><td></td><td> day of month: 00-31 -</td></tr><tr><td> %e </td><td></td><td> day of month without leading zero: 0-31 +<tr><td> %d </td><td></td><td> day of month: 01-31 +</td></tr><tr><td> %e </td><td></td><td> day of month without leading zero: 1-31 </td></tr><tr><td> %f </td><td></td><td> fractional seconds: SS.SSS </td></tr><tr><td> %F </td><td></td><td> ISO 8601 date: YYYY-MM-DD +</td></tr><tr><td> %G </td><td></td><td> ISO 8601 year corresponding to %V +</td></tr><tr><td> %g </td><td></td><td> 2-digit ISO 8601 year corresponding to %V </td></tr><tr><td> %H </td><td></td><td> hour: 00-24 </td></tr><tr><td> %I </td><td></td><td> hour for 12-hour clock: 01-12 </td></tr><tr><td> %j </td><td></td><td> day of year: 001-366 @@ -255,9 +275,11 @@ The following is a complete list of valid strftime() substitutions: </td></tr><tr><td> %s </td><td></td><td> seconds since 1970-01-01 </td></tr><tr><td> %S </td><td></td><td> seconds: 00-59 </td></tr><tr><td> %T </td><td></td><td> ISO 8601 time: HH:MM:SS +</td></tr><tr><td> %U </td><td></td><td> week of year (00-53) - week 01 starts on the first Sunday </td></tr><tr><td> %u </td><td></td><td> day of week 1-7 with Monday==1 +</td></tr><tr><td> %V </td><td></td><td> ISO 8601 week of year </td></tr><tr><td> %w </td><td></td><td> day of week 0-6 with Sunday==0 -</td></tr><tr><td> %W </td><td></td><td> week of year: 00-53 +</td></tr><tr><td> %W </td><td></td><td> week of year (00-53) - week 01 starts on the first Monday </td></tr><tr><td> %Y </td><td></td><td> year: 0000-9999 </td></tr><tr><td> %% </td><td></td><td> % </td></tr></table> @@ -270,12 +292,12 @@ in terms of strftime(): <blockquote> <table border="0" cellpadding="0" cellspacing="0"> -<tr><td><b>Function</b></td><td width="30"></td><td><b>Equivalent (or nearly) strftime()</b> +<tr><td><b>Function</b></td><td width="30"></td><td><b>Equivalent strftime()</b> </td></tr><tr><td> date(...) </td><td></td><td> strftime('%F', ...) </td></tr><tr><td> time(...) </td><td></td><td> strftime('%T', ...) </td></tr><tr><td> datetime(...) </td><td></td><td> strftime('%F %T', ...) -</td></tr><tr><td> julianday(...) </td><td></td><td> <nobr>strftime('%J', ...) -- (numeric return)</nobr> -</td></tr><tr><td> unixepoch(...) </td><td></td><td> <nobr>strftime('%s', ...) -- (numeric return)</nobr> +</td></tr><tr><td> julianday(...) </td><td></td><td> <nobr>CAST(strftime('%J', ...) as REAL)</nobr> +</td></tr><tr><td> unixepoch(...) </td><td></td><td> <nobr>CAST(strftime('%s', ...) as INT)</nobr> </td></tr></table> </blockquote> @@ -296,10 +318,8 @@ of the '%J' or '%s' format specifiers with the strftime() function. <a name="tmdif"></a> -<h2 id="timediff_"><span>1.1. </span>Timediff()</h2> - <p> -The timediff(A,B) routine returns a string that describes the amount +The <b>timediff(A,B)</b> function returns a string that describes the amount of time that must be added to B in order to reach time A. The format of the timediff() result is designed to be human-readable. The format is: </p><blockquote> @@ -307,7 +327,7 @@ the timediff() result is designed to be human-readable. The format is: </blockquote> <p> This time difference string is also an allowed modifier for the other -date/time functions. The following invariant holds for time values A +date/time functions. The following invariant holds for time-values A and B: </p><blockquote> datetime(A) = datetime(B, timediff(A,B)) @@ -342,9 +362,11 @@ between two julianday() or unixepoch() calls. </p> +<a name="tmval"></a> + <h1 id="time_values"><span>2. </span>Time Values</h1> -<p>A time value can be in any of the following formats shown below. +<p>A time-value can be in any of the following formats shown below. The value is usually a string, though it can be an integer or floating point number in the case of format 12. @@ -378,7 +400,7 @@ Format 12 is the <a href="http://en.wikipedia.org/wiki/Julian_day">Julian day number</a> expressed as an integer or floating point value. Format 12 might also be interpreted as a unix timestamp if it is immediately followed -either the 'auto' or 'unixepoch' modifier. +either the <a href="lang_datefunc.html#automod">'auto'</a> or <a href="lang_datefunc.html#jdmod">'unixepoch'</a> modifier. </p> <p> @@ -386,7 +408,7 @@ Formats 2 through 10 may be optionally followed by a timezone indicator of the f "<i>[+-]HH:MM</i>" or just "<i>Z</i>". The date and time functions use UTC or "zulu" time internally, and so the "Z" suffix is a no-op. Any non-zero "HH:MM" suffix is subtracted from the indicated date and time in order to compute zulu time. -For example, all of the following time values are equivalent: +For example, all of the following time-values are equivalent: </p> <blockquote> @@ -417,9 +439,9 @@ value of 'now' is assumed. </p><h1 id="modifiers"><span>3. </span>Modifiers</h1> <p>For all date/time functions other than timediff(), -the time value argument can be followed by zero or more modifiers that +the time-value argument can be followed by zero or more modifiers that alter date and/or time. Each modifier -is a transformation that is applied to the time value to its left. +is a transformation that is applied to the time-value to its left. Modifiers are applied from left to right; order is important. The available modifiers are as follows.</p> @@ -437,17 +459,19 @@ The available modifiers are as follows.</p> </li><li value="11"> ±YYYY-MM-DD HH:MM </li><li value="12"> ±YYYY-MM-DD HH:MM:SS </li><li value="13"> ±YYYY-MM-DD HH:MM:SS.SSS -</li><li value="14"> start of month -</li><li value="15"> start of year -</li><li value="16"> start of day -</li><li value="17"> weekday N -</li><li value="18"> unixepoch -</li><li value="19"> julianday -</li><li value="20"> auto -</li><li value="21"> localtime -</li><li value="22"> utc -</li><li value="23"> subsec -</li><li value="24"> subsecond +</li><li value="14"> ceiling +</li><li value="15"> floor +</li><li value="16"> start of month +</li><li value="17"> start of year +</li><li value="18"> start of day +</li><li value="19"> weekday N +</li><li value="20"> unixepoch +</li><li value="21"> julianday +</li><li value="22"> auto +</li><li value="23"> localtime +</li><li value="24"> utc +</li><li value="25"> subsec +</li><li value="26"> subsecond </li></ol> <p>The first thirteen modifiers (1 through 13) @@ -455,53 +479,58 @@ add the specified amount of time to the date and time specified by the arguments to its left. The 's' character at the end of the modifier names in 1 through 6 is optional. The NNN value can be any floating point number, with an optional '+' or '-' prefix. -Note that "±NNN months" works by rendering the original date into -the YYYY-MM-DD format, adding the ±NNN to the MM month value, then -normalizing the result. Thus, for example, the date 2001-03-31 modified -by '+1 month' initially yields 2001-04-31, but April only has 30 days -so the date is normalized to 2001-05-01. A similar effect occurs when -the original date is February 29 of a leapyear and the modifier is -±N years where N is not a multiple of four.</p> <a name="tmshf"></a> -<p>The time shift modifiers (7 through 13) move the time value by the +</p><p>The <b>time shift modifiers</b> (7 through 13) move the time-value by the number of years, months, days, hours, minutes, and/or seconds specified. An initial "+" or "-" is required for formats 10 through 13 but is optional for formats 7, 8, and 9. The changes are applies from left to right. First the year is shifted by YYYY, then the month by MM, and then day -by DD, and so forth. The normalization and rounding due to differing month -lengths and leap years is applied after each step. The +by DD, and so forth. The timediff(A,B) function returns a time shift in format 13 that shifts -the time value B into A.</p> - -<p>The "start of" modifiers (14 through 16) shift the date backwards +the time-value B into A.</p> + +<a name="dtambg"></a> + +<p>Because the length of a month or year changes from one month or year +to the next, ambiguities can arise when shifting a date by months and/or years. +For example, what is the date one year after 2024-02-29? Is it 2025-02-28 +or 2025-03-01? Or what is the date that is two months after 2023-12-31? +Is it 2024-02-29 or 2024-03-02? There is no consensus on how to resolve +this ambiguity, so the "<b>ceiling</b>" and "<b>floor</b>" modifiers +(14 and 15) are available to +let the programmer decide. If the next modifier after a time shift is +"ceiling", then any ambiguity in the date is resolved by choosing the +later date. The "floor" modifier resolves ambiguities +by resolving to the last day of the previous month. The default +behavior is "ceiling". + +</p><p>The "<b>start of</b>" modifiers (16 through 18) shift the date backwards to the beginning of the subject month, year or day.</p> -<p>The "weekday" modifier advances the date forward, if necessary, +<p>The "<b>weekday</b>" modifier advances the date forward, if necessary, to the next date where the weekday number is N. Sunday is 0, Monday is 1, and so forth. If the date is already on the desired weekday, the "weekday" modifier leaves the date unchanged. </p> -<p>The "unixepoch" modifier (18) only works if it immediately follows -a time value in the DDDDDDDDDD format. +<a name="jdmod"></a> + +<p>The "<b>unixepoch</b>" modifier (20) only works if it immediately follows +a time-value in the DDDDDDDDDD format. This modifier causes the DDDDDDDDDD to be interpreted not as a Julian day number as it normally would be, but as <a href="http://en.wikipedia.org/wiki/Unix_time">Unix Time</a> - the number of seconds since 1970. If the "unixepoch" modifier does not -follow a time value of the form DDDDDDDDDD which expresses the number +follow a time-value of the form DDDDDDDDDD which expresses the number of seconds since 1970 or if other modifiers separate the "unixepoch" modifier from prior DDDDDDDDDD then the behavior is undefined. -For SQLite versions before 3.16.0 (2017-01-02), -the "unixepoch" modifier only works for -dates between 0000-01-01 00:00:00 and 5352-11-01 10:52:47 (unix times -of -62167219200 through 106751991167).</p> <a name="jdmod"></a> -<p>The "julianday" modifier must immediately follow the initial +</p><p>The "<b>julianday</b>" modifier must immediately follow the initial time-value which must be of the form DDDDDDDDD. Any other use of the 'julianday' modifier is an error and causes the function to return NULL. The 'julianday' modifier forces the time-value number to be interpreted @@ -512,7 +541,7 @@ a NULL to be returned if any other time-value format is used. <a name="automod"></a> -</p><p>The "auto" modifier must immediately follow the initial time-value. +</p><p>The "<b>auto</b>" modifier must immediately follow the initial time-value. If the time-value is numeric (the DDDDDDDDDD format) then the 'auto' modifier causes the time-value to interpreted as either a julian day number or a unix timestamp, depending on its magnitude. If the value @@ -523,35 +552,36 @@ values outside of the range of valid julian day numbers, but within the range of -210866760000 to 253402300799, the 'auto' modifier causes the value to be interpreted as a unix timestamp. Other numeric values are out of range and cause a NULL return. The 'auto' modifier is a no-op -for text time-values. - -</p><p>The 'auto' modifier can be used to work with date/time values even in -cases where it is not known if the julian day number or unix timestamp -formats are in use. The 'auto' modifier will automatically select the -appropriate format. However, there is a region of ambiguity. Unix +for ISO 8601 text time-values. +The "auto" modifier is designed to work with time-values even in +cases where it is not known which time-value format +is stored in the database file, or in cases where the same column +stores time-values in different formats on different rows. +The 'auto' modifier will automatically select the +appropriate format. However, there is some ambiguity. Unix timestamps for the first 63 days of 1970 will be interpreted as julian day numbers. The 'auto' modifier is very useful when the dataset is -guaranteed to not contain any dates within that region, but should be +guaranteed to contain no dates within that range, but should be avoided for applications that might make use of dates in the opening months of 1970. <a name="localtime"></a> -</p><p>The "localtime" modifier (21) assumes the time value to its left is in +</p><p>The "<b>localtime</b>" modifier assumes the time-value to its left is in Universal Coordinated Time (UTC) and adjusts that time value so that it is in localtime. If "localtime" follows a time that is not UTC, then the behavior is undefined. -The "utc" modifier is the opposite of "localtime". -"utc" assumes that the time value -to its left is in the local timezone and adjusts that time value to be in UTC. +The "<b>utc</b>" modifier is the opposite of "localtime". +"utc" assumes that the time-value +to its left is in the local timezone and adjusts that time-value to be in UTC. If the time to the left is not in localtime, then the result of "utc" is undefined.</p> <a name="subsec"></a> <p> -The "subsecond" modifier (which may be abbreviated as just -"subsec") increases the resolution of the output for +The "<b>subsecond</b>" modifier (which may be abbreviated as just +"<b>subsec</b>") increases the resolution of the output for <a href="lang_datefunc.html#dttm">datetime()</a>, <a href="lang_datefunc.html#dttm">time()</a>, and <a href="lang_datefunc.html#uepch">unixepoch()</a>, and for the "%s" format string in <a href="lang_datefunc.html#strftm">strftime()</a>. The "subsecond" modifier has no effect on other date/time functions. @@ -563,12 +593,10 @@ followed by a decimal point and one or more digits to show fractional seconds. When "subsec" is used with <a href="lang_datefunc.html#uepch">unixepoch()</a>, the result is a floating point value which is the number of seconds and fractional seconds since 1970-01-01. - -</p><p> The "subsecond" and "subsec" modifiers have the special property that they can occur as the first argument to date/time functions (or as the first argument after the format string for strftime()). -When this happens, the time value that is normally in the first +When this happens, the time-value that is normally in the first argument is understood to be "now". For example, a short cut to get the current time in seconds since 1970 with millisecond precision is to say: @@ -674,5 +702,5 @@ getting results correct back to 1986, when the rules were also changed.</p> <a href="http://en.wikipedia.org/wiki/Gregorian_calendar">Gregorian calendar</a> system. They also assume that every day is exactly 86400 seconds in duration; no leap seconds are incorporated.</p> - +<p align="center"><small><i>This page last modified on <a href="https://sqlite.org/docsrc/honeypot" id="mtimelink" data-href="https://sqlite.org/docsrc/finfo/pages/lang_datefunc.in?m=91b979fe1e">2024-04-16 16:29:07</a> UTC </small></i></p> diff --git a/www/lang_expr.html b/www/lang_expr.html index e2ea564..7edca23 100644 --- a/www/lang_expr.html +++ b/www/lang_expr.html @@ -163,8 +163,8 @@ mk.innerHTML = "►"; <h1 id="syntax"><span>1. </span>Syntax</h1> <p><b><a href="syntax/expr.html">expr:</a></b> -<button id='x0840e91f' onclick='hideorshow("x0840e91f","x93e29188")'>hide</button></p> - <div id='x93e29188' class='imgcontainer'> +<button id='xa5f3b8e5' onclick='hideorshow("xa5f3b8e5","x17177a92")'>hide</button></p> + <div id='x17177a92' class='imgcontainer'> <div style="max-width:963px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 963.96 1068.77"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="45,17 33,21 33,12" style="fill:rgb(0,0,0)"/> @@ -645,8 +645,8 @@ mk.innerHTML = "►"; </svg> </div> <p><b><a href="syntax/filter-clause.html">filter-clause:</a></b> -<button id='xe791f458' onclick='hideorshow("xe791f458","x8260bcb6")'>show</button></p> - <div id='x8260bcb6' style='display:none;' class='imgcontainer'> +<button id='x98b6880c' onclick='hideorshow("x98b6880c","x6f03314a")'>show</button></p> + <div id='x6f03314a' style='display:none;' class='imgcontainer'> <div style="max-width:422px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 422.381 34.56"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="32,17 20,21 20,12" style="fill:rgb(0,0,0)"/> @@ -676,8 +676,8 @@ mk.innerHTML = "►"; </div> </div> <p><b><a href="syntax/function-arguments.html">function-arguments:</a></b> -<button id='x6b6311f3' onclick='hideorshow("x6b6311f3","x03054146")'>show</button></p> - <div id='x03054146' style='display:none;' class='imgcontainer'> +<button id='x73977ab6' onclick='hideorshow("x73977ab6","x779ab17e")'>show</button></p> + <div id='x779ab17e' style='display:none;' class='imgcontainer'> <div style="max-width:456px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 456.566 223.344"> <circle cx="5" cy="56" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="32,56 20,60 20,52" style="fill:rgb(0,0,0)"/> @@ -739,8 +739,8 @@ mk.innerHTML = "►"; </svg> </div> <p><b><a href="syntax/ordering-term.html">ordering-term:</a></b> -<button id='x89085fed' onclick='hideorshow("x89085fed","x06a9994e")'>show</button></p> - <div id='x06a9994e' style='display:none;' class='imgcontainer'> +<button id='x18036a83' onclick='hideorshow("x18036a83","x49cfd0ec")'>show</button></p> + <div id='x49cfd0ec' style='display:none;' class='imgcontainer'> <div style="max-width:798px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 798.451 99.576"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="32,17 20,21 20,12" style="fill:rgb(0,0,0)"/> @@ -801,8 +801,8 @@ mk.innerHTML = "►"; </div> </div> <p><b><a href="syntax/literal-value.html">literal-value:</a></b> -<button id='x3dcd39c0' onclick='hideorshow("x3dcd39c0","x4bef33ac")'>show</button></p> - <div id='x4bef33ac' style='display:none;' class='imgcontainer'> +<button id='x2851e2dc' onclick='hideorshow("x2851e2dc","x8205f18b")'>show</button></p> + <div id='x8205f18b' style='display:none;' class='imgcontainer'> <div style="max-width:341px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 341.376 336.96"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="50,319 39,324 39,315" style="fill:rgb(0,0,0)"/> @@ -872,8 +872,8 @@ mk.innerHTML = "►"; </div> </div> <p><b><a href="syntax/over-clause.html">over-clause:</a></b> -<button id='x65ac9340' onclick='hideorshow("x65ac9340","xff7cf9ba")'>show</button></p> - <div id='xff7cf9ba' style='display:none;' class='imgcontainer'> +<button id='xcd398ae6' onclick='hideorshow("xcd398ae6","x3809982e")'>show</button></p> + <div id='x3809982e' style='display:none;' class='imgcontainer'> <div style="max-width:600px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 600.706 418.392"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="32,17 20,21 20,12" style="fill:rgb(0,0,0)"/> @@ -964,8 +964,8 @@ mk.innerHTML = "►"; </svg> </div> <p><b><a href="syntax/frame-spec.html">frame-spec:</a></b> -<button id='x5053fd03' onclick='hideorshow("x5053fd03","xc8cecb54")'>show</button></p> - <div id='xc8cecb54' style='display:none;' class='imgcontainer'> +<button id='x2a6fa908' onclick='hideorshow("x2a6fa908","x2f852834")'>show</button></p> + <div id='x2f852834' style='display:none;' class='imgcontainer'> <div style="max-width:1039px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 1039.65 522.72"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="50,92 39,97 39,88" style="fill:rgb(0,0,0)"/> @@ -1174,8 +1174,8 @@ mk.innerHTML = "►"; </div> </div> <p><b><a href="syntax/ordering-term.html">ordering-term:</a></b> -<button id='xbbbbd699' onclick='hideorshow("xbbbbd699","xe30fce1f")'>show</button></p> - <div id='xe30fce1f' style='display:none;' class='imgcontainer'> +<button id='x2f3ff9b2' onclick='hideorshow("x2f3ff9b2","xad93baa8")'>show</button></p> + <div id='xad93baa8' style='display:none;' class='imgcontainer'> <div style="max-width:798px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 798.451 99.576"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="32,17 20,21 20,12" style="fill:rgb(0,0,0)"/> @@ -1236,8 +1236,8 @@ mk.innerHTML = "►"; </div> </div> <p><b><a href="syntax/raise-function.html">raise-function:</a></b> -<button id='x98684bf2' onclick='hideorshow("x98684bf2","x0d0799ad")'>show</button></p> - <div id='x0d0799ad' style='display:none;' class='imgcontainer'> +<button id='x118d5a2a' onclick='hideorshow("x118d5a2a","xc503a433")'>show</button></p> + <div id='xc503a433' style='display:none;' class='imgcontainer'> <div style="max-width:627px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 627.302 147.96"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="32,17 20,21 20,12" style="fill:rgb(0,0,0)"/> @@ -1292,8 +1292,8 @@ mk.innerHTML = "►"; </div> </div> <p><b><a href="syntax/select-stmt.html">select-stmt:</a></b> -<button id='xb57a1b54' onclick='hideorshow("xb57a1b54","x03819efa")'>show</button></p> - <div id='x03819efa' style='display:none;' class='imgcontainer'> +<button id='x5e2a82d5' onclick='hideorshow("x5e2a82d5","x6cc88482")'>show</button></p> + <div id='x6cc88482' style='display:none;' class='imgcontainer'> <div style="max-width:669px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 669.677 1162.3"> <path d="M55,845L667,845L667,99L55,99Z" style="fill:none;stroke-width:3.24;stroke:rgb(211,211,211);" /> <circle cx="6" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> @@ -1571,8 +1571,8 @@ mk.innerHTML = "►"; </svg> </div> <p><b><a href="syntax/common-table-expression.html">common-table-expression:</a></b> -<button id='x54b507bb' onclick='hideorshow("x54b507bb","x8a122cb2")'>show</button></p> - <div id='x8a122cb2' style='display:none;' class='imgcontainer'> +<button id='xa9f9876a' onclick='hideorshow("xa9f9876a","x9712233e")'>show</button></p> + <div id='x9712233e' style='display:none;' class='imgcontainer'> <div style="max-width:638px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 638.525 167.4"> <circle cx="5" cy="29" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="32,29 20,33 20,24" style="fill:rgb(0,0,0)"/> @@ -1642,8 +1642,8 @@ mk.innerHTML = "►"; </div> </div> <p><b><a href="syntax/compound-operator.html">compound-operator:</a></b> -<button id='x002bdbec' onclick='hideorshow("x002bdbec","x02204fc1")'>show</button></p> - <div id='x02204fc1' style='display:none;' class='imgcontainer'> +<button id='xba5a7bde' onclick='hideorshow("xba5a7bde","x96523997")'>show</button></p> + <div id='x96523997' style='display:none;' class='imgcontainer'> <div style="max-width:293px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 293.842 147.96"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="32,17 20,21 20,12" style="fill:rgb(0,0,0)"/> @@ -1684,8 +1684,8 @@ mk.innerHTML = "►"; </div> </div> <p><b><a href="syntax/join-clause.html">join-clause:</a></b> -<button id='xdd7cac4b' onclick='hideorshow("xdd7cac4b","x97ef5c09")'>show</button></p> - <div id='x97ef5c09' style='display:none;' class='imgcontainer'> +<button id='x04956505' onclick='hideorshow("x04956505","x8a93a5c0")'>show</button></p> + <div id='x8a93a5c0' style='display:none;' class='imgcontainer'> <div style="max-width:793px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 793.282 84.24"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="32,17 20,21 20,12" style="fill:rgb(0,0,0)"/> @@ -1716,8 +1716,8 @@ mk.innerHTML = "►"; </svg> </div> <p><b><a href="syntax/join-constraint.html">join-constraint:</a></b> -<button id='xbffbdb20' onclick='hideorshow("xbffbdb20","x223e9189")'>show</button></p> - <div id='x223e9189' style='display:none;' class='imgcontainer'> +<button id='x8cd227be' onclick='hideorshow("x8cd227be","x83fa8a1d")'>show</button></p> + <div id='x83fa8a1d' style='display:none;' class='imgcontainer'> <div style="max-width:483px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 483.336 126.576"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="50,55 39,59 39,50" style="fill:rgb(0,0,0)"/> @@ -1764,8 +1764,8 @@ mk.innerHTML = "►"; </div> </div> <p><b><a href="syntax/join-operator.html">join-operator:</a></b> -<button id='x642af74b' onclick='hideorshow("x642af74b","xc4ef5304")'>show</button></p> - <div id='xc4ef5304' style='display:none;' class='imgcontainer'> +<button id='x5836fe43' onclick='hideorshow("x5836fe43","xf1c14c8c")'>show</button></p> + <div id='xf1c14c8c' style='display:none;' class='imgcontainer'> <div style="max-width:620px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 620.333 255.312"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="50,71 39,76 39,67" style="fill:rgb(0,0,0)"/> @@ -1832,8 +1832,8 @@ mk.innerHTML = "►"; </div> </div> <p><b><a href="syntax/ordering-term.html">ordering-term:</a></b> -<button id='xbc696b27' onclick='hideorshow("xbc696b27","xfe90a62a")'>show</button></p> - <div id='xfe90a62a' style='display:none;' class='imgcontainer'> +<button id='xea6946a4' onclick='hideorshow("xea6946a4","x752b5b81")'>show</button></p> + <div id='x752b5b81' style='display:none;' class='imgcontainer'> <div style="max-width:798px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 798.451 99.576"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="32,17 20,21 20,12" style="fill:rgb(0,0,0)"/> @@ -1893,8 +1893,8 @@ mk.innerHTML = "►"; </div> </div> <p><b><a href="syntax/result-column.html">result-column:</a></b> -<button id='x9c404de4' onclick='hideorshow("x9c404de4","xdf33ac1c")'>show</button></p> - <div id='xdf33ac1c' style='display:none;' class='imgcontainer'> +<button id='x55736445' onclick='hideorshow("x55736445","xdc7efde0")'>show</button></p> + <div id='xdc7efde0' style='display:none;' class='imgcontainer'> <div style="max-width:398px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 398.054 163.08"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="45,17 33,21 33,12" style="fill:rgb(0,0,0)"/> @@ -1946,8 +1946,8 @@ mk.innerHTML = "►"; </div> </div> <p><b><a href="syntax/table-or-subquery.html">table-or-subquery:</a></b> -<button id='xfbf11dae' onclick='hideorshow("xfbf11dae","xf98cfb13")'>show</button></p> - <div id='xf98cfb13' style='display:none;' class='imgcontainer'> +<button id='x67b88cbf' onclick='hideorshow("x67b88cbf","xff270422")'>show</button></p> + <div id='xff270422' style='display:none;' class='imgcontainer'> <div style="max-width:720px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 720.778 457.704"> <circle cx="5" cy="36" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="50,74 39,78 39,70" style="fill:rgb(0,0,0)"/> @@ -2091,8 +2091,8 @@ mk.innerHTML = "►"; </div> </div> <p><b><a href="syntax/window-defn.html">window-defn:</a></b> -<button id='x4037a9c6' onclick='hideorshow("x4037a9c6","x5e8aef24")'>show</button></p> - <div id='x5e8aef24' style='display:none;' class='imgcontainer'> +<button id='xfd77c047' onclick='hideorshow("xfd77c047","x027170f1")'>show</button></p> + <div id='x027170f1' style='display:none;' class='imgcontainer'> <div style="max-width:479px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 479.765 380.592"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="32,17 20,21 20,12" style="fill:rgb(0,0,0)"/> @@ -2172,8 +2172,8 @@ mk.innerHTML = "►"; </svg> </div> <p><b><a href="syntax/frame-spec.html">frame-spec:</a></b> -<button id='x4d23db6c' onclick='hideorshow("x4d23db6c","x2fb93f17")'>show</button></p> - <div id='x2fb93f17' style='display:none;' class='imgcontainer'> +<button id='xe3cf578d' onclick='hideorshow("xe3cf578d","x785e0cad")'>show</button></p> + <div id='x785e0cad' style='display:none;' class='imgcontainer'> <div style="max-width:1039px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 1039.65 522.72"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="50,92 39,97 39,88" style="fill:rgb(0,0,0)"/> @@ -2384,8 +2384,8 @@ mk.innerHTML = "►"; </div> </div> <p><b><a href="syntax/type-name.html">type-name:</a></b> -<button id='x562f33e9' onclick='hideorshow("x562f33e9","x65bea790")'>show</button></p> - <div id='x65bea790' style='display:none;' class='imgcontainer'> +<button id='xcea30177' onclick='hideorshow("xcea30177","x73743335")'>show</button></p> + <div id='x73743335' style='display:none;' class='imgcontainer'> <div style="max-width:661px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 661.008 110.16"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="45,17 33,21 33,12" style="fill:rgb(0,0,0)"/> @@ -2439,8 +2439,8 @@ mk.innerHTML = "►"; </svg> </div> <p><b><a href="syntax/signed-number.html">signed-number:</a></b> -<button id='xa1933444' onclick='hideorshow("xa1933444","xa3236222")'>show</button></p> - <div id='xa3236222' style='display:none;' class='imgcontainer'> +<button id='x32a1800e' onclick='hideorshow("x32a1800e","x542833a7")'>show</button></p> + <div id='x542833a7' style='display:none;' class='imgcontainer'> <div style="max-width:292px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 292.013 99.576"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="50,44 39,48 39,40" style="fill:rgb(0,0,0)"/> @@ -2636,99 +2636,137 @@ The syntax for integer and floating point literals (collectively "numeric literals") is shown by the following diagram:</p> <p><b><a href="syntax/numeric-literal.html">numeric-literal:</a></b></p><div class='imgcontainer'> - <div style="max-width:765px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 765.562 214.056"> -<circle cx="5" cy="36" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<polygon points="63,36 51,41 51,32" style="fill:rgb(0,0,0)"/> -<path d="M9,36L57,36" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<path d="M78,51L98,51A15 15 0 0 0 113 36A15 15 0 0 0 98 21L78,21A15 15 0 0 0 63 36A15 15 0 0 0 78 51Z" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<text x="88" y="36" text-anchor="middle" fill="rgb(0,0,0)" dominant-baseline="central">digit</text> -<polygon points="88,6 99,2 99,10" style="fill:rgb(0,0,0)"/> -<path d="M113,36 L 121,36 Q 128,36 128,21 L 128,21 Q 128,6 113,6 L 109,6 L 94,6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<path d="M88,6 L 51,6 Q 36,6 36,21 L 36,21 Q 36,36 44,36 L 51,36" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<polygon points="176,66 164,71 164,62" style="fill:rgb(0,0,0)"/> -<path d="M113,36 L 134,36 Q 149,36 149,51 L 149,51 Q 149,66 159,66 L 170,66" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<path d="M191,82A15 15 0 0 0 206 66L206,66A15 15 0 0 0 191 51A15 15 0 0 0 176 66L176,66A15 15 0 0 0 191 82Z" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<text x="191" y="66" text-anchor="middle" font-weight="bold" fill="rgb(0,0,0)" dominant-baseline="central">.</text> -<polygon points="267,66 255,71 255,62" style="fill:rgb(0,0,0)"/> -<path d="M206,66L261,66" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<polygon points="340,66 328,71 328,62" style="fill:rgb(0,0,0)"/> -<path d="M267,66L334,66" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<polygon points="381,36 370,41 370,32" style="fill:rgb(0,0,0)"/> -<path d="M340,66 L 347,66 Q 355,66 355,51 L 355,51 Q 355,36 365,36 L 375,36" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<polygon points="423,74 411,78 411,70" style="fill:rgb(0,0,0)"/> -<path d="M381,36 L 389,36 Q 396,36 396,51 L 396,59 Q 396,74 406,74 L 417,74" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<path d="M438,89A15 15 0 0 0 453 74L453,74A15 15 0 0 0 438 59A15 15 0 0 0 423 74L423,74A15 15 0 0 0 438 89Z" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<text x="438" y="74" text-anchor="middle" font-weight="bold" fill="rgb(0,0,0)" dominant-baseline="central">E</text> -<polygon points="494,74 483,78 483,70" style="fill:rgb(0,0,0)"/> -<path d="M453,74L489,74" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<polygon points="423,112 411,116 411,108" style="fill:rgb(0,0,0)"/> -<path d="M381,36 L 389,36 Q 396,36 396,51 L 396,97 Q 396,112 406,112 L 417,112" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<path d="M438,127A15 15 0 0 0 453 112A15 15 0 0 0 438 97A15 15 0 0 0 423 112A15 15 0 0 0 438 127Z" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<text x="438" y="112" text-anchor="middle" font-weight="bold" fill="rgb(0,0,0)" dominant-baseline="central">e</text> -<path d="M453,112 L 460,112 Q 468,112 468,97 L 468,89 Q 468,74 475,74 L 483,74" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<path d="M257,112L277,112A15 15 0 0 0 292 97L292,97A15 15 0 0 0 277 82L257,82A15 15 0 0 0 242 97L242,97A15 15 0 0 0 257 112Z" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<text x="267" y="97" text-anchor="middle" fill="rgb(0,0,0)" dominant-baseline="central">digit</text> -<polygon points="292,97 304,92 304,101" style="fill:rgb(0,0,0)"/> -<path d="M267,66 L 304,66 Q 319,66 319,81 L 319,82 Q 319,97 308,97 L 298,97" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<path d="M242,97 L 234,97 Q 227,97 227,82 L 227,81 Q 227,66 234,66 L 242,66" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<polygon points="267,36 255,41 255,32" style="fill:rgb(0,0,0)"/> -<path d="M113,36L261,36" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<path d="M267,36L370,36" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<polygon points="50,135 39,139 39,130" style="fill:rgb(0,0,0)"/> -<path d="M9,36 L 16,36 Q 24,36 24,51 L 24,120 Q 24,135 34,135 L 45,135" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<path d="M66,150A15 15 0 0 0 81 135A15 15 0 0 0 66 119A15 15 0 0 0 50 135A15 15 0 0 0 66 150Z" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<text x="66" y="135" text-anchor="middle" font-weight="bold" fill="rgb(0,0,0)" dominant-baseline="central">.</text> -<polygon points="117,135 105,139 105,130" style="fill:rgb(0,0,0)"/> -<path d="M81,135L111,135" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<path d="M132,150L152,150A15 15 0 0 0 167 135A15 15 0 0 0 152 119L132,119A15 15 0 0 0 117 135A15 15 0 0 0 132 150Z" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<text x="142" y="135" text-anchor="middle" fill="rgb(0,0,0)" dominant-baseline="central">digit</text> -<polygon points="340,135 328,139 328,130" style="fill:rgb(0,0,0)"/> -<path d="M167,135L334,135" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<path d="M340,135 L 347,135 Q 355,135 355,120 L 355,66 L 355,51" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<polygon points="142,104 153,100 153,109" style="fill:rgb(0,0,0)"/> -<path d="M167,135 L 174,135 Q 182,135 182,120 L 182,119 Q 182,104 167,104 L 162,104 L 147,104" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<path d="M142,104 L 105,104 Q 90,104 90,119 L 90,120 Q 90,135 98,135 L 105,135" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<polygon points="536,142 524,146 524,138" style="fill:rgb(0,0,0)"/> -<path d="M494,74 L 502,74 Q 509,74 509,89 L 509,127 Q 509,142 520,142 L 530,142" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<path d="M551,157A15 15 0 0 0 566 142A15 15 0 0 0 551 127A15 15 0 0 0 536 142A15 15 0 0 0 551 157Z" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<text x="551" y="142" text-anchor="middle" font-weight="bold" fill="rgb(0,0,0)" dominant-baseline="central">-</text> -<polygon points="628,74 616,78 616,70" style="fill:rgb(0,0,0)"/> -<path d="M566,142 L 574,142 Q 581,142 581,127 L 581,89 Q 581,74 596,74 L 607,74 L 622,74" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<path d="M643,89L663,89A15 15 0 0 0 678 74L678,74A15 15 0 0 0 663 59L643,59A15 15 0 0 0 628 74L628,74A15 15 0 0 0 643 89Z" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<text x="653" y="74" text-anchor="middle" fill="rgb(0,0,0)" dominant-baseline="central">digit</text> -<polygon points="714,74 703,78 703,70" style="fill:rgb(0,0,0)"/> -<path d="M678,74L708,74" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<polygon points="756,36 744,41 744,32" style="fill:rgb(0,0,0)"/> -<path d="M714,74 L 722,74 Q 729,74 729,59 L 729,51 Q 729,36 740,36 L 750,36" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<circle cx="759" cy="36" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<polygon points="536,104 524,109 524,100" style="fill:rgb(0,0,0)"/> -<path d="M494,74 L 502,74 Q 509,74 509,89 L 509,89 Q 509,104 520,104 L 530,104" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<path d="M551,119A15 15 0 0 0 566 104A15 15 0 0 0 551 89A15 15 0 0 0 536 104A15 15 0 0 0 551 119Z" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<text x="551" y="104" text-anchor="middle" font-weight="bold" fill="rgb(0,0,0)" dominant-baseline="central">+</text> -<path d="M566,104 L 574,104 Q 581,104 581,97 L 581,89" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<polygon points="551,36 540,41 540,32" style="fill:rgb(0,0,0)"/> -<path d="M381,36L545,36" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<path d="M551,36L744,36" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<polygon points="551,74 540,78 540,70" style="fill:rgb(0,0,0)"/> -<path d="M494,74L545,74" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<path d="M551,74L616,74" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<polygon points="653,50 665,46 665,54" style="fill:rgb(0,0,0)"/> -<path d="M678,74 L 686,74 Q 693,74 693,62 Q 693,50 678,50 L 674,50 L 659,50" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<path d="M653,50 L 616,50 Q 601,50 601,62 Q 601,74 609,74 L 616,74" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<polygon points="50,180 39,184 39,176" style="fill:rgb(0,0,0)"/> -<path d="M9,36 L 16,36 Q 24,36 24,51 L 24,165 Q 24,180 34,180 L 45,180" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<path d="M66,195L69,195A15 15 0 0 0 84 180A15 15 0 0 0 69 165L66,165A15 15 0 0 0 50 180A15 15 0 0 0 66 195Z" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<text x="67" y="180" text-anchor="middle" font-weight="bold" fill="rgb(0,0,0)" dominant-baseline="central">0x</text> -<polygon points="120,180 108,184 108,176" style="fill:rgb(0,0,0)"/> -<path d="M84,180L114,180" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<path d="M135,195L185,195A15 15 0 0 0 200 180A15 15 0 0 0 185 165L135,165A15 15 0 0 0 120 180A15 15 0 0 0 135 195Z" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<text x="160" y="180" text-anchor="middle" fill="rgb(0,0,0)" dominant-baseline="central">hexdigit</text> -<polygon points="714,180 703,184 703,176" style="fill:rgb(0,0,0)"/> -<path d="M200,180L708,180" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<path d="M714,180 L 722,180 Q 729,180 729,165 L 729,74 L 729,59" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<polygon points="160,207 171,203 171,211" style="fill:rgb(0,0,0)"/> -<path d="M200,180 L 207,180 Q 215,180 215,193 Q 215,207 200,207 L 180,207 L 165,207" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<path d="M160,207 L 108,207 Q 93,207 93,193 Q 93,180 101,180 L 108,180" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> + <div style="max-width:765px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 765.562 285.552"> +<circle cx="5" cy="62" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<polygon points="63,62 51,66 51,58" style="fill:rgb(0,0,0)"/> +<path d="M9,62L57,62" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<path d="M78,77L98,77A15 15 0 0 0 113 62A15 15 0 0 0 98 47L78,47A15 15 0 0 0 63 62A15 15 0 0 0 78 77Z" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<text x="88" y="62" text-anchor="middle" fill="rgb(0,0,0)" dominant-baseline="central">digit</text> +<path d="M88,32A15 15 0 0 0 103 17A15 15 0 0 0 88 2A15 15 0 0 0 73 17A15 15 0 0 0 88 32Z" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<text x="88" y="17" text-anchor="middle" font-weight="bold" fill="rgb(0,0,0)" dominant-baseline="central">_</text> +<polygon points="103,38 115,34 115,42" style="fill:rgb(0,0,0)"/> +<path d="M113,62 L 121,62 Q 128,62 128,50 Q 128,38 118,38 L 109,38" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<path d="M103,38 L 51,38 Q 36,38 36,50 Q 36,62 44,62 L 51,62" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<polygon points="103,17 115,12 115,21" style="fill:rgb(0,0,0)"/> +<path d="M113,62 L 121,62 Q 128,62 128,47 L 128,32 Q 128,17 118,17 L 109,17" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<polygon points="63,62 51,66 51,58" style="fill:rgb(0,0,0)"/> +<path d="M73,17 L 51,17 Q 36,17 36,32 L 36,47 Q 36,62 47,62 L 57,62" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<polygon points="176,92 164,97 164,88" style="fill:rgb(0,0,0)"/> +<path d="M113,62 L 134,62 Q 149,62 149,77 L 149,77 Q 149,92 159,92 L 170,92" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<path d="M191,108A15 15 0 0 0 206 92L206,92A15 15 0 0 0 191 77A15 15 0 0 0 176 92L176,92A15 15 0 0 0 191 108Z" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<text x="191" y="92" text-anchor="middle" font-weight="bold" fill="rgb(0,0,0)" dominant-baseline="central">.</text> +<polygon points="267,92 255,97 255,88" style="fill:rgb(0,0,0)"/> +<path d="M206,92L261,92" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<polygon points="340,92 328,97 328,88" style="fill:rgb(0,0,0)"/> +<path d="M267,92L334,92" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<polygon points="381,62 370,66 370,58" style="fill:rgb(0,0,0)"/> +<path d="M340,92 L 347,92 Q 355,92 355,77 L 355,77 Q 355,62 365,62 L 375,62" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<polygon points="423,100 411,104 411,96" style="fill:rgb(0,0,0)"/> +<path d="M381,62 L 389,62 Q 396,62 396,77 L 396,85 Q 396,100 406,100 L 417,100" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<path d="M438,115A15 15 0 0 0 453 100L453,100A15 15 0 0 0 438 85A15 15 0 0 0 423 100L423,100A15 15 0 0 0 438 115Z" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<text x="438" y="100" text-anchor="middle" font-weight="bold" fill="rgb(0,0,0)" dominant-baseline="central">E</text> +<polygon points="494,100 483,104 483,96" style="fill:rgb(0,0,0)"/> +<path d="M453,100L489,100" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<polygon points="423,138 411,142 411,133" style="fill:rgb(0,0,0)"/> +<path d="M381,62 L 389,62 Q 396,62 396,77 L 396,123 Q 396,138 406,138 L 417,138" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<path d="M438,153A15 15 0 0 0 453 138A15 15 0 0 0 438 123A15 15 0 0 0 423 138A15 15 0 0 0 438 153Z" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<text x="438" y="138" text-anchor="middle" font-weight="bold" fill="rgb(0,0,0)" dominant-baseline="central">e</text> +<path d="M453,138 L 460,138 Q 468,138 468,123 L 468,115 Q 468,100 475,100 L 483,100" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<path d="M257,132L277,132A15 15 0 0 0 292 117A15 15 0 0 0 277 101L257,101A15 15 0 0 0 242 117A15 15 0 0 0 257 132Z" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<text x="267" y="117" text-anchor="middle" fill="rgb(0,0,0)" dominant-baseline="central">digit</text> +<path d="M267,168A15 15 0 0 0 282 153A15 15 0 0 0 267 138A15 15 0 0 0 252 153A15 15 0 0 0 267 168Z" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<text x="267" y="153" text-anchor="middle" font-weight="bold" fill="rgb(0,0,0)" dominant-baseline="central">_</text> +<polygon points="292,117 304,112 304,121" style="fill:rgb(0,0,0)"/> +<path d="M267,92 L 304,92 Q 319,92 319,104 Q 319,117 308,117 L 298,117" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<path d="M242,117 L 234,117 Q 227,117 227,104 Q 227,92 234,92 L 242,92" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<polygon points="252,153 240,157 240,149" style="fill:rgb(0,0,0)"/> +<path d="M242,117 L 234,117 Q 227,117 227,132 L 227,138 Q 227,153 236,153 L 246,153" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<polygon points="292,117 304,112 304,121" style="fill:rgb(0,0,0)"/> +<path d="M282,153 L 304,153 Q 319,153 319,138 L 319,132 Q 319,117 308,117 L 298,117" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<polygon points="267,62 255,66 255,58" style="fill:rgb(0,0,0)"/> +<path d="M113,62L261,62" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<path d="M267,62L370,62" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<polygon points="50,177 39,181 39,173" style="fill:rgb(0,0,0)"/> +<path d="M9,62 L 16,62 Q 24,62 24,77 L 24,162 Q 24,177 34,177 L 45,177" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<path d="M66,192A15 15 0 0 0 81 177A15 15 0 0 0 66 162A15 15 0 0 0 50 177A15 15 0 0 0 66 192Z" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<text x="66" y="177" text-anchor="middle" font-weight="bold" fill="rgb(0,0,0)" dominant-baseline="central">.</text> +<polygon points="117,177 105,181 105,173" style="fill:rgb(0,0,0)"/> +<path d="M81,177L111,177" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<path d="M132,192L152,192A15 15 0 0 0 167 177A15 15 0 0 0 152 162L132,162A15 15 0 0 0 117 177A15 15 0 0 0 132 192Z" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<text x="142" y="177" text-anchor="middle" fill="rgb(0,0,0)" dominant-baseline="central">digit</text> +<path d="M142,147A15 15 0 0 0 157 132A15 15 0 0 0 142 117A15 15 0 0 0 127 132A15 15 0 0 0 142 147Z" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<text x="142" y="132" text-anchor="middle" font-weight="bold" fill="rgb(0,0,0)" dominant-baseline="central">_</text> +<polygon points="340,177 328,181 328,173" style="fill:rgb(0,0,0)"/> +<path d="M167,177L334,177" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<path d="M340,177 L 347,177 Q 355,177 355,162 L 355,92 L 355,77" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<polygon points="157,153 168,149 168,157" style="fill:rgb(0,0,0)"/> +<path d="M167,177 L 174,177 Q 182,177 182,165 Q 182,153 172,153 L 163,153" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<path d="M157,153 L 105,153 Q 90,153 90,165 Q 90,177 98,177 L 105,177" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<polygon points="157,132 168,127 168,136" style="fill:rgb(0,0,0)"/> +<path d="M167,177 L 174,177 Q 182,177 182,162 L 182,147 Q 182,132 172,132 L 163,132" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<polygon points="105,177 94,181 94,173" style="fill:rgb(0,0,0)"/> +<path d="M127,132 L 105,132 Q 90,132 90,147 L 90,162 Q 90,177 95,177 L 99,177" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<polygon points="536,168 524,172 524,164" style="fill:rgb(0,0,0)"/> +<path d="M494,100 L 502,100 Q 509,100 509,115 L 509,153 Q 509,168 520,168 L 530,168" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<path d="M551,183A15 15 0 0 0 566 168A15 15 0 0 0 551 153A15 15 0 0 0 536 168A15 15 0 0 0 551 183Z" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<text x="551" y="168" text-anchor="middle" font-weight="bold" fill="rgb(0,0,0)" dominant-baseline="central">-</text> +<polygon points="628,100 616,104 616,96" style="fill:rgb(0,0,0)"/> +<path d="M566,168 L 574,168 Q 581,168 581,153 L 581,115 Q 581,100 596,100 L 607,100 L 622,100" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<path d="M643,115L663,115A15 15 0 0 0 678 100L678,100A15 15 0 0 0 663 85L643,85A15 15 0 0 0 628 100L628,100A15 15 0 0 0 643 115Z" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<text x="653" y="100" text-anchor="middle" fill="rgb(0,0,0)" dominant-baseline="central">digit</text> +<path d="M653,151A15 15 0 0 0 668 136A15 15 0 0 0 653 121A15 15 0 0 0 638 136A15 15 0 0 0 653 151Z" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<text x="653" y="136" text-anchor="middle" font-weight="bold" fill="rgb(0,0,0)" dominant-baseline="central">_</text> +<polygon points="714,100 703,104 703,96" style="fill:rgb(0,0,0)"/> +<path d="M678,100L708,100" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<polygon points="756,62 744,66 744,58" style="fill:rgb(0,0,0)"/> +<path d="M714,100 L 722,100 Q 729,100 729,85 L 729,77 Q 729,62 740,62 L 750,62" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<circle cx="759" cy="62" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<polygon points="536,130 524,135 524,126" style="fill:rgb(0,0,0)"/> +<path d="M494,100 L 502,100 Q 509,100 509,115 L 509,115 Q 509,130 520,130 L 530,130" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<path d="M551,145A15 15 0 0 0 566 130A15 15 0 0 0 551 115A15 15 0 0 0 536 130A15 15 0 0 0 551 145Z" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<text x="551" y="130" text-anchor="middle" font-weight="bold" fill="rgb(0,0,0)" dominant-baseline="central">+</text> +<path d="M566,130 L 574,130 Q 581,130 581,123 L 581,115" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<polygon points="551,62 540,66 540,58" style="fill:rgb(0,0,0)"/> +<path d="M381,62L545,62" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<path d="M551,62L744,62" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<polygon points="551,100 540,104 540,96" style="fill:rgb(0,0,0)"/> +<path d="M494,100L545,100" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<path d="M551,100L616,100" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<polygon points="653,76 665,71 665,80" style="fill:rgb(0,0,0)"/> +<path d="M678,100 L 686,100 Q 693,100 693,88 Q 693,76 678,76 L 674,76 L 659,76" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<path d="M653,76 L 616,76 Q 601,76 601,88 Q 601,100 609,100 L 616,100" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<polygon points="668,136 680,132 680,141" style="fill:rgb(0,0,0)"/> +<path d="M678,100 L 686,100 Q 693,100 693,115 L 693,121 Q 693,136 684,136 L 674,136" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<polygon points="628,100 616,104 616,96" style="fill:rgb(0,0,0)"/> +<path d="M638,136 L 616,136 Q 601,136 601,121 L 601,115 Q 601,100 612,100 L 622,100" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<polygon points="50,222 39,227 39,218" style="fill:rgb(0,0,0)"/> +<path d="M9,62 L 16,62 Q 24,62 24,77 L 24,207 Q 24,222 34,222 L 45,222" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<path d="M66,238L69,238A15 15 0 0 0 84 222A15 15 0 0 0 69 207L66,207A15 15 0 0 0 50 222A15 15 0 0 0 66 238Z" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<text x="67" y="222" text-anchor="middle" font-weight="bold" fill="rgb(0,0,0)" dominant-baseline="central">0x</text> +<polygon points="155,222 144,227 144,218" style="fill:rgb(0,0,0)"/> +<path d="M84,222L149,222" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<polygon points="197,222 185,227 185,218" style="fill:rgb(0,0,0)"/> +<path d="M155,222L191,222" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<path d="M64,277L70,277A15 15 0 0 0 85 262A15 15 0 0 0 70 247L64,247A15 15 0 0 0 49 262A15 15 0 0 0 64 277Z" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<text x="67" y="262" text-anchor="middle" font-weight="bold" fill="rgb(0,0,0)" dominant-baseline="central">0X</text> +<path d="M212,238L262,238A15 15 0 0 0 277 222A15 15 0 0 0 262 207L212,207A15 15 0 0 0 197 222A15 15 0 0 0 212 238Z" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<text x="237" y="222" text-anchor="middle" fill="rgb(0,0,0)" dominant-baseline="central">hexdigit</text> +<path d="M237,283A15 15 0 0 0 252 268A15 15 0 0 0 237 253A15 15 0 0 0 222 268A15 15 0 0 0 237 283Z" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<text x="237" y="268" text-anchor="middle" font-weight="bold" fill="rgb(0,0,0)" dominant-baseline="central">_</text> +<polygon points="714,222 703,227 703,218" style="fill:rgb(0,0,0)"/> +<path d="M277,222L708,222" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<path d="M714,222 L 722,222 Q 729,222 729,207 L 729,100 L 729,85" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<polygon points="49,262 38,266 38,257" style="fill:rgb(0,0,0)"/> +<path d="M24,202 L 24,247 Q 24,262 34,262 L 43,262" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<polygon points="197,222 185,227 185,218" style="fill:rgb(0,0,0)"/> +<path d="M85,262 L 92,262 Q 100,262 100,247 L 100,237 Q 100,222 115,222 L 176,222 L 191,222" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<polygon points="252,247 263,242 263,251" style="fill:rgb(0,0,0)"/> +<path d="M277,222 L 284,222 Q 292,222 292,235 Q 292,247 277,247 L 273,247 L 258,247" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<path d="M252,247 L 185,247 Q 170,247 170,235 Q 170,222 178,222 L 185,222" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<polygon points="252,268 263,263 263,272" style="fill:rgb(0,0,0)"/> +<path d="M277,222 L 284,222 Q 292,222 292,237 L 292,253 Q 292,268 277,268 L 273,268 L 258,268" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<polygon points="197,222 185,227 185,218" style="fill:rgb(0,0,0)"/> +<path d="M222,268 L 185,268 Q 170,268 170,253 L 170,237 Q 170,222 181,222 L 191,222" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> </svg> </div> </div> @@ -2746,6 +2784,11 @@ as the decimal point even if the locale setting specifies "," for this role - the use of "," for the decimal point would result in syntactic ambiguity. +</p><p> +Beginning in SQLite version 3.46.0 (2024-05-23), a single extra underscore ("_") +character can be added between any two digits. The underscores are purely +for human readability and are ignored by SQLite. + <a name="hexint"></a> </p><p>Hexadecimal integer literals follow the C-language notation of diff --git a/www/lang_returning.html b/www/lang_returning.html index 8989e27..8be6131 100644 --- a/www/lang_returning.html +++ b/www/lang_returning.html @@ -129,7 +129,8 @@ Table Of Contents <div class="fancy-toc2"><a href="#typical_use">1.1. Typical Use</a></div> <div class="fancy-toc1"><a href="#details">2. Details</a></div> <div class="fancy-toc2"><a href="#processing_order">2.1. Processing Order</a></div> -<div class="fancy-toc2"><a href="#acid_changes">2.2. ACID Changes</a></div> +<div class="fancy-toc2"><a href="#self_referential_subqueries_are_indeterminate">2.2. Self-Referential Subqueries Are Indeterminate</a></div> +<div class="fancy-toc2"><a href="#acid_changes">2.3. ACID Changes</a></div> <div class="fancy-toc1"><a href="#limitations_and_caveats">3. Limitations And Caveats</a></div> </div> </div> @@ -154,8 +155,8 @@ mk.innerHTML = "►"; <h1 id="overview"><span>1. </span>Overview</h1> <p><b><a href="syntax/returning-clause.html">returning-clause:</a></b> -<button id='x7976e0a4' onclick='hideorshow("x7976e0a4","xa416104f")'>hide</button></p> - <div id='xa416104f' class='imgcontainer'> +<button id='x93686241' onclick='hideorshow("x93686241","x4d62f2b3")'>hide</button></p> + <div id='x4d62f2b3' class='imgcontainer'> <div style="max-width:628px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 628.709 140.4"> <circle cx="5" cy="47" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="27,47 15,51 15,43" style="fill:rgb(0,0,0)"/> @@ -203,8 +204,8 @@ mk.innerHTML = "►"; </svg> </div> <p><b><a href="syntax/expr.html">expr:</a></b> -<button id='xe691e618' onclick='hideorshow("xe691e618","x63f05421")'>show</button></p> - <div id='x63f05421' style='display:none;' class='imgcontainer'> +<button id='xabd0493f' onclick='hideorshow("xabd0493f","x74ec7287")'>show</button></p> + <div id='x74ec7287' style='display:none;' class='imgcontainer'> <div style="max-width:963px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 963.96 1068.77"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="45,17 33,21 33,12" style="fill:rgb(0,0,0)"/> @@ -685,8 +686,8 @@ mk.innerHTML = "►"; </svg> </div> <p><b><a href="syntax/filter-clause.html">filter-clause:</a></b> -<button id='x87b9cf48' onclick='hideorshow("x87b9cf48","x711413a7")'>show</button></p> - <div id='x711413a7' style='display:none;' class='imgcontainer'> +<button id='x1de3098d' onclick='hideorshow("x1de3098d","x565db2c0")'>show</button></p> + <div id='x565db2c0' style='display:none;' class='imgcontainer'> <div style="max-width:422px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 422.381 34.56"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="32,17 20,21 20,12" style="fill:rgb(0,0,0)"/> @@ -716,8 +717,8 @@ mk.innerHTML = "►"; </div> </div> <p><b><a href="syntax/function-arguments.html">function-arguments:</a></b> -<button id='x697afbc6' onclick='hideorshow("x697afbc6","x1531016b")'>show</button></p> - <div id='x1531016b' style='display:none;' class='imgcontainer'> +<button id='x01bf2b13' onclick='hideorshow("x01bf2b13","xefc0fb02")'>show</button></p> + <div id='xefc0fb02' style='display:none;' class='imgcontainer'> <div style="max-width:456px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 456.566 223.344"> <circle cx="5" cy="56" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="32,56 20,60 20,52" style="fill:rgb(0,0,0)"/> @@ -779,8 +780,8 @@ mk.innerHTML = "►"; </svg> </div> <p><b><a href="syntax/ordering-term.html">ordering-term:</a></b> -<button id='xea5af493' onclick='hideorshow("xea5af493","xd5c9781e")'>show</button></p> - <div id='xd5c9781e' style='display:none;' class='imgcontainer'> +<button id='x0d9c7108' onclick='hideorshow("x0d9c7108","x20dfb2f8")'>show</button></p> + <div id='x20dfb2f8' style='display:none;' class='imgcontainer'> <div style="max-width:798px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 798.451 99.576"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="32,17 20,21 20,12" style="fill:rgb(0,0,0)"/> @@ -841,8 +842,8 @@ mk.innerHTML = "►"; </div> </div> <p><b><a href="syntax/literal-value.html">literal-value:</a></b> -<button id='x36c988c0' onclick='hideorshow("x36c988c0","x3488dc16")'>show</button></p> - <div id='x3488dc16' style='display:none;' class='imgcontainer'> +<button id='x99b8dcab' onclick='hideorshow("x99b8dcab","xb8141712")'>show</button></p> + <div id='xb8141712' style='display:none;' class='imgcontainer'> <div style="max-width:341px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 341.376 336.96"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="50,319 39,324 39,315" style="fill:rgb(0,0,0)"/> @@ -912,8 +913,8 @@ mk.innerHTML = "►"; </div> </div> <p><b><a href="syntax/over-clause.html">over-clause:</a></b> -<button id='x65b3ab14' onclick='hideorshow("x65b3ab14","x7bfe6f78")'>show</button></p> - <div id='x7bfe6f78' style='display:none;' class='imgcontainer'> +<button id='x49225cb8' onclick='hideorshow("x49225cb8","xcc92b330")'>show</button></p> + <div id='xcc92b330' style='display:none;' class='imgcontainer'> <div style="max-width:600px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 600.706 418.392"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="32,17 20,21 20,12" style="fill:rgb(0,0,0)"/> @@ -1004,8 +1005,8 @@ mk.innerHTML = "►"; </svg> </div> <p><b><a href="syntax/frame-spec.html">frame-spec:</a></b> -<button id='x5e5db0c0' onclick='hideorshow("x5e5db0c0","xd67aa226")'>show</button></p> - <div id='xd67aa226' style='display:none;' class='imgcontainer'> +<button id='x29fbae00' onclick='hideorshow("x29fbae00","x6dd19d65")'>show</button></p> + <div id='x6dd19d65' style='display:none;' class='imgcontainer'> <div style="max-width:1039px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 1039.65 522.72"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="50,92 39,97 39,88" style="fill:rgb(0,0,0)"/> @@ -1214,8 +1215,8 @@ mk.innerHTML = "►"; </div> </div> <p><b><a href="syntax/ordering-term.html">ordering-term:</a></b> -<button id='x88289188' onclick='hideorshow("x88289188","x471ed888")'>show</button></p> - <div id='x471ed888' style='display:none;' class='imgcontainer'> +<button id='x83e37f5d' onclick='hideorshow("x83e37f5d","x17c66599")'>show</button></p> + <div id='x17c66599' style='display:none;' class='imgcontainer'> <div style="max-width:798px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 798.451 99.576"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="32,17 20,21 20,12" style="fill:rgb(0,0,0)"/> @@ -1276,8 +1277,8 @@ mk.innerHTML = "►"; </div> </div> <p><b><a href="syntax/raise-function.html">raise-function:</a></b> -<button id='x04e1e87f' onclick='hideorshow("x04e1e87f","x12e4cf29")'>show</button></p> - <div id='x12e4cf29' style='display:none;' class='imgcontainer'> +<button id='x5990e23a' onclick='hideorshow("x5990e23a","x4f2086c8")'>show</button></p> + <div id='x4f2086c8' style='display:none;' class='imgcontainer'> <div style="max-width:627px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 627.302 147.96"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="32,17 20,21 20,12" style="fill:rgb(0,0,0)"/> @@ -1332,8 +1333,8 @@ mk.innerHTML = "►"; </div> </div> <p><b><a href="syntax/select-stmt.html">select-stmt:</a></b> -<button id='x97c3dd79' onclick='hideorshow("x97c3dd79","xa0026cbe")'>show</button></p> - <div id='xa0026cbe' style='display:none;' class='imgcontainer'> +<button id='x87730d7b' onclick='hideorshow("x87730d7b","xea9b0edd")'>show</button></p> + <div id='xea9b0edd' style='display:none;' class='imgcontainer'> <div style="max-width:669px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 669.677 1162.3"> <path d="M55,845L667,845L667,99L55,99Z" style="fill:none;stroke-width:3.24;stroke:rgb(211,211,211);" /> <circle cx="6" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> @@ -1611,8 +1612,8 @@ mk.innerHTML = "►"; </svg> </div> <p><b><a href="syntax/common-table-expression.html">common-table-expression:</a></b> -<button id='xbd24aa66' onclick='hideorshow("xbd24aa66","xe4768ac0")'>show</button></p> - <div id='xe4768ac0' style='display:none;' class='imgcontainer'> +<button id='x9e53d5f6' onclick='hideorshow("x9e53d5f6","xb73e6b02")'>show</button></p> + <div id='xb73e6b02' style='display:none;' class='imgcontainer'> <div style="max-width:638px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 638.525 167.4"> <circle cx="5" cy="29" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="32,29 20,33 20,24" style="fill:rgb(0,0,0)"/> @@ -1682,8 +1683,8 @@ mk.innerHTML = "►"; </div> </div> <p><b><a href="syntax/compound-operator.html">compound-operator:</a></b> -<button id='x7945722c' onclick='hideorshow("x7945722c","xd5bf2b0b")'>show</button></p> - <div id='xd5bf2b0b' style='display:none;' class='imgcontainer'> +<button id='x6b280e04' onclick='hideorshow("x6b280e04","xf96608d6")'>show</button></p> + <div id='xf96608d6' style='display:none;' class='imgcontainer'> <div style="max-width:293px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 293.842 147.96"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="32,17 20,21 20,12" style="fill:rgb(0,0,0)"/> @@ -1724,8 +1725,8 @@ mk.innerHTML = "►"; </div> </div> <p><b><a href="syntax/join-clause.html">join-clause:</a></b> -<button id='x3c5dcc36' onclick='hideorshow("x3c5dcc36","x280534b9")'>show</button></p> - <div id='x280534b9' style='display:none;' class='imgcontainer'> +<button id='x80bfe36d' onclick='hideorshow("x80bfe36d","x0a5fe5c8")'>show</button></p> + <div id='x0a5fe5c8' style='display:none;' class='imgcontainer'> <div style="max-width:793px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 793.282 84.24"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="32,17 20,21 20,12" style="fill:rgb(0,0,0)"/> @@ -1756,8 +1757,8 @@ mk.innerHTML = "►"; </svg> </div> <p><b><a href="syntax/join-constraint.html">join-constraint:</a></b> -<button id='xe3d931b0' onclick='hideorshow("xe3d931b0","x31f5087a")'>show</button></p> - <div id='x31f5087a' style='display:none;' class='imgcontainer'> +<button id='xf2dd6526' onclick='hideorshow("xf2dd6526","xb8c656ba")'>show</button></p> + <div id='xb8c656ba' style='display:none;' class='imgcontainer'> <div style="max-width:483px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 483.336 126.576"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="50,55 39,59 39,50" style="fill:rgb(0,0,0)"/> @@ -1804,8 +1805,8 @@ mk.innerHTML = "►"; </div> </div> <p><b><a href="syntax/join-operator.html">join-operator:</a></b> -<button id='xad8e0edd' onclick='hideorshow("xad8e0edd","x399d36e6")'>show</button></p> - <div id='x399d36e6' style='display:none;' class='imgcontainer'> +<button id='x4c00610b' onclick='hideorshow("x4c00610b","x3d7f5768")'>show</button></p> + <div id='x3d7f5768' style='display:none;' class='imgcontainer'> <div style="max-width:620px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 620.333 255.312"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="50,71 39,76 39,67" style="fill:rgb(0,0,0)"/> @@ -1872,8 +1873,8 @@ mk.innerHTML = "►"; </div> </div> <p><b><a href="syntax/ordering-term.html">ordering-term:</a></b> -<button id='x1cdd5f8d' onclick='hideorshow("x1cdd5f8d","xf44d8110")'>show</button></p> - <div id='xf44d8110' style='display:none;' class='imgcontainer'> +<button id='x4711e23a' onclick='hideorshow("x4711e23a","xa7d4295c")'>show</button></p> + <div id='xa7d4295c' style='display:none;' class='imgcontainer'> <div style="max-width:798px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 798.451 99.576"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="32,17 20,21 20,12" style="fill:rgb(0,0,0)"/> @@ -1933,8 +1934,8 @@ mk.innerHTML = "►"; </div> </div> <p><b><a href="syntax/result-column.html">result-column:</a></b> -<button id='xf0c5d5df' onclick='hideorshow("xf0c5d5df","x6951e04e")'>show</button></p> - <div id='x6951e04e' style='display:none;' class='imgcontainer'> +<button id='x443d9e83' onclick='hideorshow("x443d9e83","x9b740539")'>show</button></p> + <div id='x9b740539' style='display:none;' class='imgcontainer'> <div style="max-width:398px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 398.054 163.08"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="45,17 33,21 33,12" style="fill:rgb(0,0,0)"/> @@ -1986,8 +1987,8 @@ mk.innerHTML = "►"; </div> </div> <p><b><a href="syntax/table-or-subquery.html">table-or-subquery:</a></b> -<button id='xfdd4c15e' onclick='hideorshow("xfdd4c15e","x73e7549d")'>show</button></p> - <div id='x73e7549d' style='display:none;' class='imgcontainer'> +<button id='x50c4134b' onclick='hideorshow("x50c4134b","x5db26160")'>show</button></p> + <div id='x5db26160' style='display:none;' class='imgcontainer'> <div style="max-width:720px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 720.778 457.704"> <circle cx="5" cy="36" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="50,74 39,78 39,70" style="fill:rgb(0,0,0)"/> @@ -2131,8 +2132,8 @@ mk.innerHTML = "►"; </div> </div> <p><b><a href="syntax/window-defn.html">window-defn:</a></b> -<button id='x1d3a8086' onclick='hideorshow("x1d3a8086","x44ec2984")'>show</button></p> - <div id='x44ec2984' style='display:none;' class='imgcontainer'> +<button id='x62329f73' onclick='hideorshow("x62329f73","x03778e2f")'>show</button></p> + <div id='x03778e2f' style='display:none;' class='imgcontainer'> <div style="max-width:479px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 479.765 380.592"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="32,17 20,21 20,12" style="fill:rgb(0,0,0)"/> @@ -2212,8 +2213,8 @@ mk.innerHTML = "►"; </svg> </div> <p><b><a href="syntax/frame-spec.html">frame-spec:</a></b> -<button id='x55b16cf1' onclick='hideorshow("x55b16cf1","x2dd27741")'>show</button></p> - <div id='x2dd27741' style='display:none;' class='imgcontainer'> +<button id='xf29a1826' onclick='hideorshow("xf29a1826","x505763ac")'>show</button></p> + <div id='x505763ac' style='display:none;' class='imgcontainer'> <div style="max-width:1039px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 1039.65 522.72"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="50,92 39,97 39,88" style="fill:rgb(0,0,0)"/> @@ -2424,8 +2425,8 @@ mk.innerHTML = "►"; </div> </div> <p><b><a href="syntax/type-name.html">type-name:</a></b> -<button id='xe23774a6' onclick='hideorshow("xe23774a6","xa28beb6b")'>show</button></p> - <div id='xa28beb6b' style='display:none;' class='imgcontainer'> +<button id='xbbd0a9f9' onclick='hideorshow("xbbd0a9f9","x49dd2c71")'>show</button></p> + <div id='x49dd2c71' style='display:none;' class='imgcontainer'> <div style="max-width:661px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 661.008 110.16"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="45,17 33,21 33,12" style="fill:rgb(0,0,0)"/> @@ -2479,8 +2480,8 @@ mk.innerHTML = "►"; </svg> </div> <p><b><a href="syntax/signed-number.html">signed-number:</a></b> -<button id='xd35c20d0' onclick='hideorshow("xd35c20d0","x336c96ab")'>show</button></p> - <div id='x336c96ab' style='display:none;' class='imgcontainer'> +<button id='x39c981de' onclick='hideorshow("x39c981de","x04ae9d48")'>show</button></p> + <div id='x04ae9d48' style='display:none;' class='imgcontainer'> <div style="max-width:292px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 292.013 99.576"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="50,44 39,48 39,40" style="fill:rgb(0,0,0)"/> @@ -2593,36 +2594,6 @@ string or BLOB values, then the statement might use a lot of temporary memory to hold those values while it is running. </p><p> -The first prototype of the RETURNING clause returned -values as they were generated. That approach used less memory, but -it had other problems: - -</p><ol> -<li><p> -If the calls sqlite3_step() for two or more DML statements -where interleaved and if one of the -statements hit a constraint failure and aborted, reverting its -changes, then that could disrupt the operation of the other -DML statement. This could not corrupt the database file, but -it could yield surprising and difficult-to-explain results in -the database. - -</p></li><li><p> -If an application failed to call sqlite3_step() repeatedly until -it received SQLITE_DONE, then some of the database changes might -never occur. - -</p></li><li><p> -The order of operations was different from client/server database -engines like PostgreSQL, which might cause portability issues -for some applications. -</p></li></ol> - -<p> -For these reasons, the current implementation was modified so that -all database changes happen before any RETURNING output is emitted. - -</p><p> While SQLite does guarantee that all database changes will occur before any RETURNING output is emitted, it does <i>not</i> guarantee that the order of individual RETURNING rows will match the order in @@ -2630,7 +2601,26 @@ which those rows were changed in the database. The output order for the RETURNING rows is arbitrary and is not necessarily related to the order in which the rows were processed internally. -</p><h2 id="acid_changes"><span>2.2. </span>ACID Changes</h2> +</p><h2 id="self_referential_subqueries_are_indeterminate"><span>2.2. </span>Self-Referential Subqueries Are Indeterminate</h2> + +<p> +SQLite guarantees that all database changes will occur before +any RETURNING output is <em>emitted</em>, but SQLite makes no +guarantees about the order in which database changes occur nor +when the RETURNING output is <em>computed</em> in relation to +those database changes. RETURNING clause outputs are all computed and +placed in temporary storage during the first call to sqlite3_step() +but the specific order of when those output are computed and the +order in which database changes occur is unspecified. The order +can change from one query to the next. + +</p><p> +Hence if column of RETURNING output contains a +subquery that references the table being modified, then the result +of that subquery might depend on unspecified behavior and hence +could vary from one invocation of the query to the next. + +</p><h2 id="acid_changes"><span>2.3. </span>ACID Changes</h2> <p> When the previous "<i>Processing Order</i>" section says that @@ -2642,7 +2632,7 @@ does not occur until the statement finishes, and maybe not even then if the statement is part of a larger transaction. Changes to the database are still atomic, consistent, isolated, and durable (ACID). When the previous section says "changes occur", -this means that internal data structure are adjusted pending a transaction +this means that internal data structures are adjusted pending a transaction commit. Some of those changes may or may not spill into the <a href="wal.html">write-ahead log</a>, depending on how much pressure there is on the page cache. If the page cache is not under memory pressure, then @@ -2708,5 +2698,5 @@ In an <a href="lang_update.html#upfrom">UPDATE FROM</a> statement, the auxiliary clause may not participate in the RETURNING clause. </p></li></ol> - +<p align="center"><small><i>This page last modified on <a href="https://sqlite.org/docsrc/honeypot" id="mtimelink" data-href="https://sqlite.org/docsrc/finfo/pages/lang_returning.in?m=a90bba5a4f">2024-05-08 20:36:57</a> UTC </small></i></p> diff --git a/www/lang_select.html b/www/lang_select.html index 8e34a69..656c587 100644 --- a/www/lang_select.html +++ b/www/lang_select.html @@ -141,7 +141,8 @@ Table Of Contents <div class="fancy-toc1"><a href="#table_valued_functions_in_the_from_clause">8. Table-valued Functions In The FROM Clause</a></div> <div class="fancy-toc1"><a href="#deviations_from_standard_sql">9. Deviations From Standard SQL</a></div> <div class="fancy-toc2"><a href="#strange_join_names">9.1. Strange JOIN names</a></div> -<div class="fancy-toc2"><a href="#precedence_of_comma_joins_and_cross_join">9.2. Precedence of comma-joins and CROSS JOIN</a></div> +<div class="fancy-toc2"><a href="#flexible_join_syntax">9.2. Flexible join syntax</a></div> +<div class="fancy-toc2"><a href="#precedence_of_comma_joins_and_cross_join">9.3. Precedence of comma-joins and CROSS JOIN</a></div> </div> </div> <script> @@ -164,8 +165,8 @@ mk.innerHTML = "►"; <h1 id="overview"><span>1. </span>Overview</h1> <p><b><a href="syntax/select-stmt.html">select-stmt:</a></b> -<button id='xf2381d42' onclick='hideorshow("xf2381d42","xf05ef6ce")'>hide</button></p> - <div id='xf05ef6ce' class='imgcontainer'> +<button id='xfb231e3b' onclick='hideorshow("xfb231e3b","x5badd154")'>hide</button></p> + <div id='x5badd154' class='imgcontainer'> <div style="max-width:669px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 669.677 1162.3"> <path d="M55,845L667,845L667,99L55,99Z" style="fill:none;stroke-width:3.24;stroke:rgb(211,211,211);" /> <circle cx="6" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> @@ -443,8 +444,8 @@ mk.innerHTML = "►"; </svg> </div> <p><b><a href="syntax/common-table-expression.html">common-table-expression:</a></b> -<button id='xb3186489' onclick='hideorshow("xb3186489","x280d7205")'>show</button></p> - <div id='x280d7205' style='display:none;' class='imgcontainer'> +<button id='x28ec4d8d' onclick='hideorshow("x28ec4d8d","xa7b638b2")'>show</button></p> + <div id='xa7b638b2' style='display:none;' class='imgcontainer'> <div style="max-width:638px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 638.525 167.4"> <circle cx="5" cy="29" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="32,29 20,33 20,24" style="fill:rgb(0,0,0)"/> @@ -514,8 +515,8 @@ mk.innerHTML = "►"; </div> </div> <p><b><a href="syntax/compound-operator.html">compound-operator:</a></b> -<button id='xbc45df4d' onclick='hideorshow("xbc45df4d","x13dd8e0c")'>show</button></p> - <div id='x13dd8e0c' style='display:none;' class='imgcontainer'> +<button id='x5240d97d' onclick='hideorshow("x5240d97d","xcce70f61")'>show</button></p> + <div id='xcce70f61' style='display:none;' class='imgcontainer'> <div style="max-width:293px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 293.842 147.96"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="32,17 20,21 20,12" style="fill:rgb(0,0,0)"/> @@ -556,8 +557,8 @@ mk.innerHTML = "►"; </div> </div> <p><b><a href="syntax/expr.html">expr:</a></b> -<button id='xb5c926c8' onclick='hideorshow("xb5c926c8","x878b8407")'>show</button></p> - <div id='x878b8407' style='display:none;' class='imgcontainer'> +<button id='x2f7ba4fe' onclick='hideorshow("x2f7ba4fe","xfdd47173")'>show</button></p> + <div id='xfdd47173' style='display:none;' class='imgcontainer'> <div style="max-width:963px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 963.96 1068.77"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="45,17 33,21 33,12" style="fill:rgb(0,0,0)"/> @@ -1038,8 +1039,8 @@ mk.innerHTML = "►"; </svg> </div> <p><b><a href="syntax/filter-clause.html">filter-clause:</a></b> -<button id='x22ac5e9d' onclick='hideorshow("x22ac5e9d","xa2879e2c")'>show</button></p> - <div id='xa2879e2c' style='display:none;' class='imgcontainer'> +<button id='x7917b60e' onclick='hideorshow("x7917b60e","xd0307fc8")'>show</button></p> + <div id='xd0307fc8' style='display:none;' class='imgcontainer'> <div style="max-width:422px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 422.381 34.56"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="32,17 20,21 20,12" style="fill:rgb(0,0,0)"/> @@ -1069,8 +1070,8 @@ mk.innerHTML = "►"; </div> </div> <p><b><a href="syntax/function-arguments.html">function-arguments:</a></b> -<button id='x57d52cb6' onclick='hideorshow("x57d52cb6","x22c93439")'>show</button></p> - <div id='x22c93439' style='display:none;' class='imgcontainer'> +<button id='xd29b1290' onclick='hideorshow("xd29b1290","xcf00c8e5")'>show</button></p> + <div id='xcf00c8e5' style='display:none;' class='imgcontainer'> <div style="max-width:456px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 456.566 223.344"> <circle cx="5" cy="56" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="32,56 20,60 20,52" style="fill:rgb(0,0,0)"/> @@ -1133,8 +1134,8 @@ mk.innerHTML = "►"; </div> </div> <p><b><a href="syntax/literal-value.html">literal-value:</a></b> -<button id='x9ed64fc0' onclick='hideorshow("x9ed64fc0","x7b2f36e6")'>show</button></p> - <div id='x7b2f36e6' style='display:none;' class='imgcontainer'> +<button id='xed9e9225' onclick='hideorshow("xed9e9225","xfb66ede4")'>show</button></p> + <div id='xfb66ede4' style='display:none;' class='imgcontainer'> <div style="max-width:341px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 341.376 336.96"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="50,319 39,324 39,315" style="fill:rgb(0,0,0)"/> @@ -1204,8 +1205,8 @@ mk.innerHTML = "►"; </div> </div> <p><b><a href="syntax/over-clause.html">over-clause:</a></b> -<button id='x824bcb06' onclick='hideorshow("x824bcb06","x6ade2ba5")'>show</button></p> - <div id='x6ade2ba5' style='display:none;' class='imgcontainer'> +<button id='x49495f61' onclick='hideorshow("x49495f61","x03f1b76a")'>show</button></p> + <div id='x03f1b76a' style='display:none;' class='imgcontainer'> <div style="max-width:600px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 600.706 418.392"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="32,17 20,21 20,12" style="fill:rgb(0,0,0)"/> @@ -1296,8 +1297,8 @@ mk.innerHTML = "►"; </svg> </div> <p><b><a href="syntax/frame-spec.html">frame-spec:</a></b> -<button id='xd8e79248' onclick='hideorshow("xd8e79248","x5ddb9706")'>show</button></p> - <div id='x5ddb9706' style='display:none;' class='imgcontainer'> +<button id='xf79b0477' onclick='hideorshow("xf79b0477","x553cba85")'>show</button></p> + <div id='x553cba85' style='display:none;' class='imgcontainer'> <div style="max-width:1039px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 1039.65 522.72"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="50,92 39,97 39,88" style="fill:rgb(0,0,0)"/> @@ -1507,8 +1508,8 @@ mk.innerHTML = "►"; </div> </div> <p><b><a href="syntax/raise-function.html">raise-function:</a></b> -<button id='xd9e25840' onclick='hideorshow("xd9e25840","x858831f7")'>show</button></p> - <div id='x858831f7' style='display:none;' class='imgcontainer'> +<button id='x4ac91b13' onclick='hideorshow("x4ac91b13","xfb828d36")'>show</button></p> + <div id='xfb828d36' style='display:none;' class='imgcontainer'> <div style="max-width:627px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 627.302 147.96"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="32,17 20,21 20,12" style="fill:rgb(0,0,0)"/> @@ -1563,8 +1564,8 @@ mk.innerHTML = "►"; </div> </div> <p><b><a href="syntax/type-name.html">type-name:</a></b> -<button id='x827f6b30' onclick='hideorshow("x827f6b30","xcd6f4330")'>show</button></p> - <div id='xcd6f4330' style='display:none;' class='imgcontainer'> +<button id='x914530dd' onclick='hideorshow("x914530dd","x1e2ec979")'>show</button></p> + <div id='x1e2ec979' style='display:none;' class='imgcontainer'> <div style="max-width:661px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 661.008 110.16"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="45,17 33,21 33,12" style="fill:rgb(0,0,0)"/> @@ -1618,8 +1619,8 @@ mk.innerHTML = "►"; </svg> </div> <p><b><a href="syntax/signed-number.html">signed-number:</a></b> -<button id='x3317224a' onclick='hideorshow("x3317224a","x5f8e952c")'>show</button></p> - <div id='x5f8e952c' style='display:none;' class='imgcontainer'> +<button id='xed1dd36c' onclick='hideorshow("xed1dd36c","xc7a77558")'>show</button></p> + <div id='xc7a77558' style='display:none;' class='imgcontainer'> <div style="max-width:292px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 292.013 99.576"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="50,44 39,48 39,40" style="fill:rgb(0,0,0)"/> @@ -1647,8 +1648,8 @@ mk.innerHTML = "►"; </div> </div> <p><b><a href="syntax/join-clause.html">join-clause:</a></b> -<button id='x19cb2983' onclick='hideorshow("x19cb2983","xf1916896")'>show</button></p> - <div id='xf1916896' style='display:none;' class='imgcontainer'> +<button id='xc5e341e8' onclick='hideorshow("xc5e341e8","x0d8d3977")'>show</button></p> + <div id='x0d8d3977' style='display:none;' class='imgcontainer'> <div style="max-width:793px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 793.282 84.24"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="32,17 20,21 20,12" style="fill:rgb(0,0,0)"/> @@ -1679,8 +1680,8 @@ mk.innerHTML = "►"; </svg> </div> <p><b><a href="syntax/join-constraint.html">join-constraint:</a></b> -<button id='x3d452e70' onclick='hideorshow("x3d452e70","x8012aaad")'>show</button></p> - <div id='x8012aaad' style='display:none;' class='imgcontainer'> +<button id='x3ee5afd0' onclick='hideorshow("x3ee5afd0","x41880008")'>show</button></p> + <div id='x41880008' style='display:none;' class='imgcontainer'> <div style="max-width:483px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 483.336 126.576"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="50,55 39,59 39,50" style="fill:rgb(0,0,0)"/> @@ -1727,8 +1728,8 @@ mk.innerHTML = "►"; </div> </div> <p><b><a href="syntax/join-operator.html">join-operator:</a></b> -<button id='x4ac18b9d' onclick='hideorshow("x4ac18b9d","x77661d39")'>show</button></p> - <div id='x77661d39' style='display:none;' class='imgcontainer'> +<button id='xe24ed947' onclick='hideorshow("xe24ed947","xda58e77c")'>show</button></p> + <div id='xda58e77c' style='display:none;' class='imgcontainer'> <div style="max-width:620px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 620.333 255.312"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="50,71 39,76 39,67" style="fill:rgb(0,0,0)"/> @@ -1795,8 +1796,8 @@ mk.innerHTML = "►"; </div> </div> <p><b><a href="syntax/ordering-term.html">ordering-term:</a></b> -<button id='x15c2e5f3' onclick='hideorshow("x15c2e5f3","x2035a2bd")'>show</button></p> - <div id='x2035a2bd' style='display:none;' class='imgcontainer'> +<button id='xf112f1e0' onclick='hideorshow("xf112f1e0","x46f24f2d")'>show</button></p> + <div id='x46f24f2d' style='display:none;' class='imgcontainer'> <div style="max-width:798px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 798.451 99.576"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="32,17 20,21 20,12" style="fill:rgb(0,0,0)"/> @@ -1856,8 +1857,8 @@ mk.innerHTML = "►"; </div> </div> <p><b><a href="syntax/result-column.html">result-column:</a></b> -<button id='xf79db399' onclick='hideorshow("xf79db399","xe0753924")'>show</button></p> - <div id='xe0753924' style='display:none;' class='imgcontainer'> +<button id='x4c4a5b7f' onclick='hideorshow("x4c4a5b7f","x54195310")'>show</button></p> + <div id='x54195310' style='display:none;' class='imgcontainer'> <div style="max-width:398px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 398.054 163.08"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="45,17 33,21 33,12" style="fill:rgb(0,0,0)"/> @@ -1909,8 +1910,8 @@ mk.innerHTML = "►"; </div> </div> <p><b><a href="syntax/table-or-subquery.html">table-or-subquery:</a></b> -<button id='x30756a23' onclick='hideorshow("x30756a23","x25aced32")'>show</button></p> - <div id='x25aced32' style='display:none;' class='imgcontainer'> +<button id='x1e152b03' onclick='hideorshow("x1e152b03","x74379f9e")'>show</button></p> + <div id='x74379f9e' style='display:none;' class='imgcontainer'> <div style="max-width:720px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 720.778 457.704"> <circle cx="5" cy="36" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="50,74 39,78 39,70" style="fill:rgb(0,0,0)"/> @@ -2054,8 +2055,8 @@ mk.innerHTML = "►"; </div> </div> <p><b><a href="syntax/window-defn.html">window-defn:</a></b> -<button id='xe24da894' onclick='hideorshow("xe24da894","x883d91aa")'>show</button></p> - <div id='x883d91aa' style='display:none;' class='imgcontainer'> +<button id='x7926ec00' onclick='hideorshow("x7926ec00","xb067d03e")'>show</button></p> + <div id='xb067d03e' style='display:none;' class='imgcontainer'> <div style="max-width:479px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 479.765 380.592"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="32,17 20,21 20,12" style="fill:rgb(0,0,0)"/> @@ -2135,8 +2136,8 @@ mk.innerHTML = "►"; </svg> </div> <p><b><a href="syntax/frame-spec.html">frame-spec:</a></b> -<button id='x2acdfc23' onclick='hideorshow("x2acdfc23","x46136d83")'>show</button></p> - <div id='x46136d83' style='display:none;' class='imgcontainer'> +<button id='xc728aee3' onclick='hideorshow("xc728aee3","x3333ccd0")'>show</button></p> + <div id='x3333ccd0' style='display:none;' class='imgcontainer'> <div style="max-width:1039px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 1039.65 522.72"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="50,92 39,97 39,88" style="fill:rgb(0,0,0)"/> @@ -2361,8 +2362,8 @@ syntax diagrams that expresses the same syntax but tries to break the syntax down into smaller chunks. <p><b><a href="syntax/factored-select-stmt.html">factored-select-stmt:</a></b> -<button id='x18fb4b68' onclick='hideorshow("x18fb4b68","x1f334094")'>show</button></p> - <div id='x1f334094' style='display:none;' class='imgcontainer'> +<button id='x6b1af3c7' onclick='hideorshow("x6b1af3c7","xdaa171a0")'>show</button></p> + <div id='xdaa171a0' style='display:none;' class='imgcontainer'> <div style="max-width:629px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 629.266 500.04"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="45,17 33,21 33,12" style="fill:rgb(0,0,0)"/> @@ -2468,8 +2469,8 @@ down into smaller chunks. </svg> </div> <p><b><a href="syntax/common-table-expression.html">common-table-expression:</a></b> -<button id='xd14beeed' onclick='hideorshow("xd14beeed","x285547b6")'>show</button></p> - <div id='x285547b6' style='display:none;' class='imgcontainer'> +<button id='x25c5aa5b' onclick='hideorshow("x25c5aa5b","x9a44c688")'>show</button></p> + <div id='x9a44c688' style='display:none;' class='imgcontainer'> <div style="max-width:638px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 638.525 167.4"> <circle cx="5" cy="29" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="32,29 20,33 20,24" style="fill:rgb(0,0,0)"/> @@ -2538,8 +2539,8 @@ down into smaller chunks. </svg> </div> <p><b><a href="syntax/select-stmt.html">select-stmt:</a></b> -<button id='x612291e7' onclick='hideorshow("x612291e7","x8d8a489b")'>show</button></p> - <div id='x8d8a489b' style='display:none;' class='imgcontainer'> +<button id='xb156ad90' onclick='hideorshow("xb156ad90","x71861a9b")'>show</button></p> + <div id='x71861a9b' style='display:none;' class='imgcontainer'> <div style="max-width:669px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 669.677 1162.3"> <path d="M55,845L667,845L667,99L55,99Z" style="fill:none;stroke-width:3.24;stroke:rgb(211,211,211);" /> <circle cx="6" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> @@ -2817,8 +2818,8 @@ down into smaller chunks. </svg> </div> <p><b><a href="syntax/join-clause.html">join-clause:</a></b> -<button id='x338b6388' onclick='hideorshow("x338b6388","x0b2e484c")'>show</button></p> - <div id='x0b2e484c' style='display:none;' class='imgcontainer'> +<button id='x04712806' onclick='hideorshow("x04712806","xdb872a11")'>show</button></p> + <div id='xdb872a11' style='display:none;' class='imgcontainer'> <div style="max-width:793px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 793.282 84.24"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="32,17 20,21 20,12" style="fill:rgb(0,0,0)"/> @@ -2849,8 +2850,8 @@ down into smaller chunks. </svg> </div> <p><b><a href="syntax/join-constraint.html">join-constraint:</a></b> -<button id='x87114650' onclick='hideorshow("x87114650","x8f9809c2")'>show</button></p> - <div id='x8f9809c2' style='display:none;' class='imgcontainer'> +<button id='xe3fccdf4' onclick='hideorshow("xe3fccdf4","x5695b381")'>show</button></p> + <div id='x5695b381' style='display:none;' class='imgcontainer'> <div style="max-width:483px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 483.336 126.576"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="50,55 39,59 39,50" style="fill:rgb(0,0,0)"/> @@ -2897,8 +2898,8 @@ down into smaller chunks. </div> </div> <p><b><a href="syntax/join-operator.html">join-operator:</a></b> -<button id='xa3fd0a0d' onclick='hideorshow("xa3fd0a0d","xdff7089e")'>show</button></p> - <div id='xdff7089e' style='display:none;' class='imgcontainer'> +<button id='x32842ee3' onclick='hideorshow("x32842ee3","xb159619c")'>show</button></p> + <div id='xb159619c' style='display:none;' class='imgcontainer'> <div style="max-width:620px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 620.333 255.312"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="50,71 39,76 39,67" style="fill:rgb(0,0,0)"/> @@ -2965,8 +2966,8 @@ down into smaller chunks. </div> </div> <p><b><a href="syntax/result-column.html">result-column:</a></b> -<button id='xb3703585' onclick='hideorshow("xb3703585","xa1e522d4")'>show</button></p> - <div id='xa1e522d4' style='display:none;' class='imgcontainer'> +<button id='xee21263d' onclick='hideorshow("xee21263d","xda995059")'>show</button></p> + <div id='xda995059' style='display:none;' class='imgcontainer'> <div style="max-width:398px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 398.054 163.08"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="45,17 33,21 33,12" style="fill:rgb(0,0,0)"/> @@ -3018,8 +3019,8 @@ down into smaller chunks. </div> </div> <p><b><a href="syntax/table-or-subquery.html">table-or-subquery:</a></b> -<button id='xd5648fdd' onclick='hideorshow("xd5648fdd","x8ff2b0c6")'>show</button></p> - <div id='x8ff2b0c6' style='display:none;' class='imgcontainer'> +<button id='x9d36624b' onclick='hideorshow("x9d36624b","xc2937370")'>show</button></p> + <div id='xc2937370' style='display:none;' class='imgcontainer'> <div style="max-width:720px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 720.778 457.704"> <circle cx="5" cy="36" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="50,74 39,78 39,70" style="fill:rgb(0,0,0)"/> @@ -3163,8 +3164,8 @@ down into smaller chunks. </div> </div> <p><b><a href="syntax/window-defn.html">window-defn:</a></b> -<button id='x5a5d40ab' onclick='hideorshow("x5a5d40ab","x2ad0f471")'>show</button></p> - <div id='x2ad0f471' style='display:none;' class='imgcontainer'> +<button id='xdff2c8dd' onclick='hideorshow("xdff2c8dd","xe587979e")'>show</button></p> + <div id='xe587979e' style='display:none;' class='imgcontainer'> <div style="max-width:479px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 479.765 380.592"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="32,17 20,21 20,12" style="fill:rgb(0,0,0)"/> @@ -3244,8 +3245,8 @@ down into smaller chunks. </svg> </div> <p><b><a href="syntax/frame-spec.html">frame-spec:</a></b> -<button id='xb79a64f3' onclick='hideorshow("xb79a64f3","x11c28187")'>show</button></p> - <div id='x11c28187' style='display:none;' class='imgcontainer'> +<button id='xd721deee' onclick='hideorshow("xd721deee","xaf37b11b")'>show</button></p> + <div id='xaf37b11b' style='display:none;' class='imgcontainer'> <div style="max-width:1039px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 1039.65 522.72"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="50,92 39,97 39,88" style="fill:rgb(0,0,0)"/> @@ -3457,8 +3458,8 @@ down into smaller chunks. </div> </div> <p><b><a href="syntax/compound-operator.html">compound-operator:</a></b> -<button id='x8b583cba' onclick='hideorshow("x8b583cba","xb5e903a6")'>show</button></p> - <div id='xb5e903a6' style='display:none;' class='imgcontainer'> +<button id='x2dfa9d1f' onclick='hideorshow("x2dfa9d1f","xcbdab688")'>show</button></p> + <div id='xcbdab688' style='display:none;' class='imgcontainer'> <div style="max-width:293px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 293.842 147.96"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="32,17 20,21 20,12" style="fill:rgb(0,0,0)"/> @@ -3499,8 +3500,8 @@ down into smaller chunks. </div> </div> <p><b><a href="syntax/expr.html">expr:</a></b> -<button id='xf450d44a' onclick='hideorshow("xf450d44a","x65d92beb")'>show</button></p> - <div id='x65d92beb' style='display:none;' class='imgcontainer'> +<button id='xb1b1b460' onclick='hideorshow("xb1b1b460","xdb5d9f61")'>show</button></p> + <div id='xdb5d9f61' style='display:none;' class='imgcontainer'> <div style="max-width:963px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 963.96 1068.77"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="45,17 33,21 33,12" style="fill:rgb(0,0,0)"/> @@ -3981,8 +3982,8 @@ down into smaller chunks. </svg> </div> <p><b><a href="syntax/filter-clause.html">filter-clause:</a></b> -<button id='x490bdf90' onclick='hideorshow("x490bdf90","xd15964f8")'>show</button></p> - <div id='xd15964f8' style='display:none;' class='imgcontainer'> +<button id='xd111ee07' onclick='hideorshow("xd111ee07","x9dad8b7f")'>show</button></p> + <div id='x9dad8b7f' style='display:none;' class='imgcontainer'> <div style="max-width:422px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 422.381 34.56"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="32,17 20,21 20,12" style="fill:rgb(0,0,0)"/> @@ -4012,8 +4013,8 @@ down into smaller chunks. </div> </div> <p><b><a href="syntax/function-arguments.html">function-arguments:</a></b> -<button id='x4f74be68' onclick='hideorshow("x4f74be68","x1c44911c")'>show</button></p> - <div id='x1c44911c' style='display:none;' class='imgcontainer'> +<button id='x93fdfbc3' onclick='hideorshow("x93fdfbc3","xda4da07d")'>show</button></p> + <div id='xda4da07d' style='display:none;' class='imgcontainer'> <div style="max-width:456px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 456.566 223.344"> <circle cx="5" cy="56" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="32,56 20,60 20,52" style="fill:rgb(0,0,0)"/> @@ -4076,8 +4077,8 @@ down into smaller chunks. </div> </div> <p><b><a href="syntax/literal-value.html">literal-value:</a></b> -<button id='xed1bfd0d' onclick='hideorshow("xed1bfd0d","xfd4bddef")'>show</button></p> - <div id='xfd4bddef' style='display:none;' class='imgcontainer'> +<button id='x15d4b2c0' onclick='hideorshow("x15d4b2c0","x00768916")'>show</button></p> + <div id='x00768916' style='display:none;' class='imgcontainer'> <div style="max-width:341px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 341.376 336.96"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="50,319 39,324 39,315" style="fill:rgb(0,0,0)"/> @@ -4147,8 +4148,8 @@ down into smaller chunks. </div> </div> <p><b><a href="syntax/over-clause.html">over-clause:</a></b> -<button id='xcbf1149d' onclick='hideorshow("xcbf1149d","x5185a371")'>show</button></p> - <div id='x5185a371' style='display:none;' class='imgcontainer'> +<button id='xd58dbcc8' onclick='hideorshow("xd58dbcc8","x0ed5a4f6")'>show</button></p> + <div id='x0ed5a4f6' style='display:none;' class='imgcontainer'> <div style="max-width:600px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 600.706 418.392"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="32,17 20,21 20,12" style="fill:rgb(0,0,0)"/> @@ -4239,8 +4240,8 @@ down into smaller chunks. </svg> </div> <p><b><a href="syntax/frame-spec.html">frame-spec:</a></b> -<button id='x2701af05' onclick='hideorshow("x2701af05","x50514221")'>show</button></p> - <div id='x50514221' style='display:none;' class='imgcontainer'> +<button id='x684355d2' onclick='hideorshow("x684355d2","x23b94f69")'>show</button></p> + <div id='x23b94f69' style='display:none;' class='imgcontainer'> <div style="max-width:1039px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 1039.65 522.72"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="50,92 39,97 39,88" style="fill:rgb(0,0,0)"/> @@ -4450,8 +4451,8 @@ down into smaller chunks. </div> </div> <p><b><a href="syntax/raise-function.html">raise-function:</a></b> -<button id='xe89538f7' onclick='hideorshow("xe89538f7","x6dd0b61c")'>show</button></p> - <div id='x6dd0b61c' style='display:none;' class='imgcontainer'> +<button id='xd2bb907e' onclick='hideorshow("xd2bb907e","x3a3edd32")'>show</button></p> + <div id='x3a3edd32' style='display:none;' class='imgcontainer'> <div style="max-width:627px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 627.302 147.96"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="32,17 20,21 20,12" style="fill:rgb(0,0,0)"/> @@ -4506,8 +4507,8 @@ down into smaller chunks. </div> </div> <p><b><a href="syntax/select-stmt.html">select-stmt:</a></b> -<button id='xb169d67a' onclick='hideorshow("xb169d67a","x25688559")'>show</button></p> - <div id='x25688559' style='display:none;' class='imgcontainer'> +<button id='xa6ccbf0f' onclick='hideorshow("xa6ccbf0f","x1295befb")'>show</button></p> + <div id='x1295befb' style='display:none;' class='imgcontainer'> <div style="max-width:669px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 669.677 1162.3"> <path d="M55,845L667,845L667,99L55,99Z" style="fill:none;stroke-width:3.24;stroke:rgb(211,211,211);" /> <circle cx="6" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> @@ -4785,8 +4786,8 @@ down into smaller chunks. </svg> </div> <p><b><a href="syntax/join-clause.html">join-clause:</a></b> -<button id='xf9f9d5ae' onclick='hideorshow("xf9f9d5ae","x48ca088e")'>show</button></p> - <div id='x48ca088e' style='display:none;' class='imgcontainer'> +<button id='x3c6a6813' onclick='hideorshow("x3c6a6813","xa3cbe50b")'>show</button></p> + <div id='xa3cbe50b' style='display:none;' class='imgcontainer'> <div style="max-width:793px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 793.282 84.24"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="32,17 20,21 20,12" style="fill:rgb(0,0,0)"/> @@ -4817,8 +4818,8 @@ down into smaller chunks. </svg> </div> <p><b><a href="syntax/join-constraint.html">join-constraint:</a></b> -<button id='xf4c54059' onclick='hideorshow("xf4c54059","x7ef5fecd")'>show</button></p> - <div id='x7ef5fecd' style='display:none;' class='imgcontainer'> +<button id='x30efc704' onclick='hideorshow("x30efc704","x69ad921a")'>show</button></p> + <div id='x69ad921a' style='display:none;' class='imgcontainer'> <div style="max-width:483px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 483.336 126.576"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="50,55 39,59 39,50" style="fill:rgb(0,0,0)"/> @@ -4865,8 +4866,8 @@ down into smaller chunks. </div> </div> <p><b><a href="syntax/join-operator.html">join-operator:</a></b> -<button id='xb4c7876b' onclick='hideorshow("xb4c7876b","xab7735c2")'>show</button></p> - <div id='xab7735c2' style='display:none;' class='imgcontainer'> +<button id='x84c71f4a' onclick='hideorshow("x84c71f4a","xfcecd8c1")'>show</button></p> + <div id='xfcecd8c1' style='display:none;' class='imgcontainer'> <div style="max-width:620px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 620.333 255.312"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="50,71 39,76 39,67" style="fill:rgb(0,0,0)"/> @@ -4933,8 +4934,8 @@ down into smaller chunks. </div> </div> <p><b><a href="syntax/result-column.html">result-column:</a></b> -<button id='xbada6a4f' onclick='hideorshow("xbada6a4f","x1093a306")'>show</button></p> - <div id='x1093a306' style='display:none;' class='imgcontainer'> +<button id='x625df1e1' onclick='hideorshow("x625df1e1","x43c9cf99")'>show</button></p> + <div id='x43c9cf99' style='display:none;' class='imgcontainer'> <div style="max-width:398px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 398.054 163.08"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="45,17 33,21 33,12" style="fill:rgb(0,0,0)"/> @@ -4986,8 +4987,8 @@ down into smaller chunks. </div> </div> <p><b><a href="syntax/table-or-subquery.html">table-or-subquery:</a></b> -<button id='xca6e6bcb' onclick='hideorshow("xca6e6bcb","x2d71c2ed")'>show</button></p> - <div id='x2d71c2ed' style='display:none;' class='imgcontainer'> +<button id='x1e1b9e66' onclick='hideorshow("x1e1b9e66","x54e77329")'>show</button></p> + <div id='x54e77329' style='display:none;' class='imgcontainer'> <div style="max-width:720px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 720.778 457.704"> <circle cx="5" cy="36" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="50,74 39,78 39,70" style="fill:rgb(0,0,0)"/> @@ -5131,8 +5132,8 @@ down into smaller chunks. </div> </div> <p><b><a href="syntax/window-defn.html">window-defn:</a></b> -<button id='xf1b82923' onclick='hideorshow("xf1b82923","x4462294d")'>show</button></p> - <div id='x4462294d' style='display:none;' class='imgcontainer'> +<button id='x17addd5f' onclick='hideorshow("x17addd5f","xcba751ce")'>show</button></p> + <div id='xcba751ce' style='display:none;' class='imgcontainer'> <div style="max-width:479px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 479.765 380.592"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="32,17 20,21 20,12" style="fill:rgb(0,0,0)"/> @@ -5212,8 +5213,8 @@ down into smaller chunks. </svg> </div> <p><b><a href="syntax/frame-spec.html">frame-spec:</a></b> -<button id='xf25e022a' onclick='hideorshow("xf25e022a","x86c017df")'>show</button></p> - <div id='x86c017df' style='display:none;' class='imgcontainer'> +<button id='x43f77217' onclick='hideorshow("x43f77217","x3f12529c")'>show</button></p> + <div id='x3f12529c' style='display:none;' class='imgcontainer'> <div style="max-width:1039px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 1039.65 522.72"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="50,92 39,97 39,88" style="fill:rgb(0,0,0)"/> @@ -5424,8 +5425,8 @@ down into smaller chunks. </div> </div> <p><b><a href="syntax/type-name.html">type-name:</a></b> -<button id='xb0449a50' onclick='hideorshow("xb0449a50","x2b121701")'>show</button></p> - <div id='x2b121701' style='display:none;' class='imgcontainer'> +<button id='xdfbc1631' onclick='hideorshow("xdfbc1631","xcf1a35c0")'>show</button></p> + <div id='xcf1a35c0' style='display:none;' class='imgcontainer'> <div style="max-width:661px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 661.008 110.16"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="45,17 33,21 33,12" style="fill:rgb(0,0,0)"/> @@ -5479,8 +5480,8 @@ down into smaller chunks. </svg> </div> <p><b><a href="syntax/signed-number.html">signed-number:</a></b> -<button id='x93a42f33' onclick='hideorshow("x93a42f33","x4983f8af")'>show</button></p> - <div id='x4983f8af' style='display:none;' class='imgcontainer'> +<button id='xa2472aa8' onclick='hideorshow("xa2472aa8","x0e10ff5d")'>show</button></p> + <div id='x0e10ff5d' style='display:none;' class='imgcontainer'> <div style="max-width:292px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 292.013 99.576"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="50,44 39,48 39,40" style="fill:rgb(0,0,0)"/> @@ -5508,8 +5509,8 @@ down into smaller chunks. </div> </div> <p><b><a href="syntax/ordering-term.html">ordering-term:</a></b> -<button id='xb6b8148e' onclick='hideorshow("xb6b8148e","x9f0de7af")'>show</button></p> - <div id='x9f0de7af' style='display:none;' class='imgcontainer'> +<button id='x670edbd8' onclick='hideorshow("x670edbd8","xd9ad17b7")'>show</button></p> + <div id='xd9ad17b7' style='display:none;' class='imgcontainer'> <div style="max-width:798px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 798.451 99.576"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="32,17 20,21 20,12" style="fill:rgb(0,0,0)"/> @@ -5569,8 +5570,8 @@ down into smaller chunks. </div> </div> <p><b><a href="syntax/select-core.html">select-core:</a></b> -<button id='xcb42dcab' onclick='hideorshow("xcb42dcab","x6e5c7a43")'>show</button></p> - <div id='x6e5c7a43' style='display:none;' class='imgcontainer'> +<button id='x246ff4e4' onclick='hideorshow("x246ff4e4","x1ab12699")'>show</button></p> + <div id='x1ab12699' style='display:none;' class='imgcontainer'> <div style="max-width:655px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 655.157 728.568"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="63,17 51,21 51,12" style="fill:rgb(0,0,0)"/> @@ -5747,8 +5748,8 @@ down into smaller chunks. </svg> </div> <p><b><a href="syntax/join-clause.html">join-clause:</a></b> -<button id='xf2ed18ef' onclick='hideorshow("xf2ed18ef","xb560e673")'>show</button></p> - <div id='xb560e673' style='display:none;' class='imgcontainer'> +<button id='xfc5371b4' onclick='hideorshow("xfc5371b4","xbb3ee51d")'>show</button></p> + <div id='xbb3ee51d' style='display:none;' class='imgcontainer'> <div style="max-width:793px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 793.282 84.24"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="32,17 20,21 20,12" style="fill:rgb(0,0,0)"/> @@ -5779,8 +5780,8 @@ down into smaller chunks. </svg> </div> <p><b><a href="syntax/join-constraint.html">join-constraint:</a></b> -<button id='x31719a7d' onclick='hideorshow("x31719a7d","xadb4a00d")'>show</button></p> - <div id='xadb4a00d' style='display:none;' class='imgcontainer'> +<button id='x8caea1d9' onclick='hideorshow("x8caea1d9","x2f3699d3")'>show</button></p> + <div id='x2f3699d3' style='display:none;' class='imgcontainer'> <div style="max-width:483px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 483.336 126.576"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="50,55 39,59 39,50" style="fill:rgb(0,0,0)"/> @@ -5827,8 +5828,8 @@ down into smaller chunks. </div> </div> <p><b><a href="syntax/join-operator.html">join-operator:</a></b> -<button id='x6f659b63' onclick='hideorshow("x6f659b63","xae1a9ab1")'>show</button></p> - <div id='xae1a9ab1' style='display:none;' class='imgcontainer'> +<button id='x0bd5d5d4' onclick='hideorshow("x0bd5d5d4","xa9f327fe")'>show</button></p> + <div id='xa9f327fe' style='display:none;' class='imgcontainer'> <div style="max-width:620px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 620.333 255.312"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="50,71 39,76 39,67" style="fill:rgb(0,0,0)"/> @@ -5895,8 +5896,8 @@ down into smaller chunks. </div> </div> <p><b><a href="syntax/result-column.html">result-column:</a></b> -<button id='x5c1f3322' onclick='hideorshow("x5c1f3322","x8abaa843")'>show</button></p> - <div id='x8abaa843' style='display:none;' class='imgcontainer'> +<button id='x6dcceba5' onclick='hideorshow("x6dcceba5","x3b9c4086")'>show</button></p> + <div id='x3b9c4086' style='display:none;' class='imgcontainer'> <div style="max-width:398px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 398.054 163.08"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="45,17 33,21 33,12" style="fill:rgb(0,0,0)"/> @@ -5948,8 +5949,8 @@ down into smaller chunks. </div> </div> <p><b><a href="syntax/table-or-subquery.html">table-or-subquery:</a></b> -<button id='x0367bd25' onclick='hideorshow("x0367bd25","x40f45b85")'>show</button></p> - <div id='x40f45b85' style='display:none;' class='imgcontainer'> +<button id='xdba15e83' onclick='hideorshow("xdba15e83","x4ebdb799")'>show</button></p> + <div id='x4ebdb799' style='display:none;' class='imgcontainer'> <div style="max-width:720px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 720.778 457.704"> <circle cx="5" cy="36" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="50,74 39,78 39,70" style="fill:rgb(0,0,0)"/> @@ -6092,8 +6093,8 @@ down into smaller chunks. </svg> </div> <p><b><a href="syntax/select-stmt.html">select-stmt:</a></b> -<button id='x33471d11' onclick='hideorshow("x33471d11","xc9752374")'>show</button></p> - <div id='xc9752374' style='display:none;' class='imgcontainer'> +<button id='xd6369f16' onclick='hideorshow("xd6369f16","xe33b0a57")'>show</button></p> + <div id='xe33b0a57' style='display:none;' class='imgcontainer'> <div style="max-width:669px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 669.677 1162.3"> <path d="M55,845L667,845L667,99L55,99Z" style="fill:none;stroke-width:3.24;stroke:rgb(211,211,211);" /> <circle cx="6" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> @@ -6373,8 +6374,8 @@ down into smaller chunks. </div> </div> <p><b><a href="syntax/window-defn.html">window-defn:</a></b> -<button id='x6c771130' onclick='hideorshow("x6c771130","x90d90faf")'>show</button></p> - <div id='x90d90faf' style='display:none;' class='imgcontainer'> +<button id='x105b6d44' onclick='hideorshow("x105b6d44","x6c4e047b")'>show</button></p> + <div id='x6c4e047b' style='display:none;' class='imgcontainer'> <div style="max-width:479px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 479.765 380.592"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="32,17 20,21 20,12" style="fill:rgb(0,0,0)"/> @@ -6454,8 +6455,8 @@ down into smaller chunks. </svg> </div> <p><b><a href="syntax/frame-spec.html">frame-spec:</a></b> -<button id='xebf078d1' onclick='hideorshow("xebf078d1","xbeaaefa2")'>show</button></p> - <div id='xbeaaefa2' style='display:none;' class='imgcontainer'> +<button id='x5e5289bd' onclick='hideorshow("x5e5289bd","x6e96b239")'>show</button></p> + <div id='x6e96b239' style='display:none;' class='imgcontainer'> <div style="max-width:1039px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 1039.65 522.72"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="50,92 39,97 39,88" style="fill:rgb(0,0,0)"/> @@ -6696,8 +6697,8 @@ this or any other specific process. In practice, most SELECT statements are simple SELECT statements. <p><b><a href="syntax/simple-select-stmt.html">simple-select-stmt:</a></b> -<button id='xf4d39422' onclick='hideorshow("xf4d39422","x793d5c47")'>hide</button></p> - <div id='x793d5c47' class='imgcontainer'> +<button id='x14bcc21e' onclick='hideorshow("x14bcc21e","x42fa10bc")'>hide</button></p> + <div id='x42fa10bc' class='imgcontainer'> <div style="max-width:629px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 629.266 348.84"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="45,17 33,21 33,12" style="fill:rgb(0,0,0)"/> @@ -6796,8 +6797,8 @@ In practice, most SELECT statements are simple SELECT statements. </svg> </div> <p><b><a href="syntax/common-table-expression.html">common-table-expression:</a></b> -<button id='xe303724e' onclick='hideorshow("xe303724e","x1304d3be")'>show</button></p> - <div id='x1304d3be' style='display:none;' class='imgcontainer'> +<button id='x5e52e5bf' onclick='hideorshow("x5e52e5bf","xc568875f")'>show</button></p> + <div id='xc568875f' style='display:none;' class='imgcontainer'> <div style="max-width:638px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 638.525 167.4"> <circle cx="5" cy="29" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="32,29 20,33 20,24" style="fill:rgb(0,0,0)"/> @@ -6866,8 +6867,8 @@ In practice, most SELECT statements are simple SELECT statements. </svg> </div> <p><b><a href="syntax/select-stmt.html">select-stmt:</a></b> -<button id='x002dc602' onclick='hideorshow("x002dc602","x0b27af7d")'>show</button></p> - <div id='x0b27af7d' style='display:none;' class='imgcontainer'> +<button id='x0c6deccf' onclick='hideorshow("x0c6deccf","x9514e549")'>show</button></p> + <div id='x9514e549' style='display:none;' class='imgcontainer'> <div style="max-width:669px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 669.677 1162.3"> <path d="M55,845L667,845L667,99L55,99Z" style="fill:none;stroke-width:3.24;stroke:rgb(211,211,211);" /> <circle cx="6" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> @@ -7145,8 +7146,8 @@ In practice, most SELECT statements are simple SELECT statements. </svg> </div> <p><b><a href="syntax/compound-operator.html">compound-operator:</a></b> -<button id='xb40860b7' onclick='hideorshow("xb40860b7","x21aa2d8c")'>show</button></p> - <div id='x21aa2d8c' style='display:none;' class='imgcontainer'> +<button id='x41c5f6fe' onclick='hideorshow("x41c5f6fe","x9dd2dbd3")'>show</button></p> + <div id='x9dd2dbd3' style='display:none;' class='imgcontainer'> <div style="max-width:293px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 293.842 147.96"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="32,17 20,21 20,12" style="fill:rgb(0,0,0)"/> @@ -7187,8 +7188,8 @@ In practice, most SELECT statements are simple SELECT statements. </div> </div> <p><b><a href="syntax/join-clause.html">join-clause:</a></b> -<button id='xb73d032c' onclick='hideorshow("xb73d032c","xc894a2b3")'>show</button></p> - <div id='xc894a2b3' style='display:none;' class='imgcontainer'> +<button id='xe6b677e5' onclick='hideorshow("xe6b677e5","x2a337403")'>show</button></p> + <div id='x2a337403' style='display:none;' class='imgcontainer'> <div style="max-width:793px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 793.282 84.24"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="32,17 20,21 20,12" style="fill:rgb(0,0,0)"/> @@ -7219,8 +7220,8 @@ In practice, most SELECT statements are simple SELECT statements. </svg> </div> <p><b><a href="syntax/join-constraint.html">join-constraint:</a></b> -<button id='x037100cf' onclick='hideorshow("x037100cf","x509cdbdb")'>show</button></p> - <div id='x509cdbdb' style='display:none;' class='imgcontainer'> +<button id='xdf83c11c' onclick='hideorshow("xdf83c11c","x4cc0e891")'>show</button></p> + <div id='x4cc0e891' style='display:none;' class='imgcontainer'> <div style="max-width:483px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 483.336 126.576"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="50,55 39,59 39,50" style="fill:rgb(0,0,0)"/> @@ -7267,8 +7268,8 @@ In practice, most SELECT statements are simple SELECT statements. </div> </div> <p><b><a href="syntax/join-operator.html">join-operator:</a></b> -<button id='xb0ae2d6e' onclick='hideorshow("xb0ae2d6e","x29126674")'>show</button></p> - <div id='x29126674' style='display:none;' class='imgcontainer'> +<button id='x951441df' onclick='hideorshow("x951441df","xcf1eab4b")'>show</button></p> + <div id='xcf1eab4b' style='display:none;' class='imgcontainer'> <div style="max-width:620px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 620.333 255.312"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="50,71 39,76 39,67" style="fill:rgb(0,0,0)"/> @@ -7335,8 +7336,8 @@ In practice, most SELECT statements are simple SELECT statements. </div> </div> <p><b><a href="syntax/result-column.html">result-column:</a></b> -<button id='x197ecf2e' onclick='hideorshow("x197ecf2e","x5567adb3")'>show</button></p> - <div id='x5567adb3' style='display:none;' class='imgcontainer'> +<button id='x7c242736' onclick='hideorshow("x7c242736","x2db8f7b4")'>show</button></p> + <div id='x2db8f7b4' style='display:none;' class='imgcontainer'> <div style="max-width:398px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 398.054 163.08"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="45,17 33,21 33,12" style="fill:rgb(0,0,0)"/> @@ -7388,8 +7389,8 @@ In practice, most SELECT statements are simple SELECT statements. </div> </div> <p><b><a href="syntax/table-or-subquery.html">table-or-subquery:</a></b> -<button id='xb21a4197' onclick='hideorshow("xb21a4197","xec95716d")'>show</button></p> - <div id='xec95716d' style='display:none;' class='imgcontainer'> +<button id='xe8b061b6' onclick='hideorshow("xe8b061b6","xc4aaadda")'>show</button></p> + <div id='xc4aaadda' style='display:none;' class='imgcontainer'> <div style="max-width:720px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 720.778 457.704"> <circle cx="5" cy="36" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="50,74 39,78 39,70" style="fill:rgb(0,0,0)"/> @@ -7533,8 +7534,8 @@ In practice, most SELECT statements are simple SELECT statements. </div> </div> <p><b><a href="syntax/window-defn.html">window-defn:</a></b> -<button id='x56f314bd' onclick='hideorshow("x56f314bd","xdb58841c")'>show</button></p> - <div id='xdb58841c' style='display:none;' class='imgcontainer'> +<button id='x30aa1685' onclick='hideorshow("x30aa1685","x966d860d")'>show</button></p> + <div id='x966d860d' style='display:none;' class='imgcontainer'> <div style="max-width:479px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 479.765 380.592"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="32,17 20,21 20,12" style="fill:rgb(0,0,0)"/> @@ -7614,8 +7615,8 @@ In practice, most SELECT statements are simple SELECT statements. </svg> </div> <p><b><a href="syntax/frame-spec.html">frame-spec:</a></b> -<button id='x7135de03' onclick='hideorshow("x7135de03","x54367b61")'>show</button></p> - <div id='x54367b61' style='display:none;' class='imgcontainer'> +<button id='xc8267947' onclick='hideorshow("xc8267947","x0bca7cf4")'>show</button></p> + <div id='x0bca7cf4' style='display:none;' class='imgcontainer'> <div style="max-width:1039px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 1039.65 522.72"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="50,92 39,97 39,88" style="fill:rgb(0,0,0)"/> @@ -7827,8 +7828,8 @@ In practice, most SELECT statements are simple SELECT statements. </div> </div> <p><b><a href="syntax/expr.html">expr:</a></b> -<button id='xdb85b9d6' onclick='hideorshow("xdb85b9d6","xde8f239b")'>show</button></p> - <div id='xde8f239b' style='display:none;' class='imgcontainer'> +<button id='x3773e62b' onclick='hideorshow("x3773e62b","x0453da68")'>show</button></p> + <div id='x0453da68' style='display:none;' class='imgcontainer'> <div style="max-width:963px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 963.96 1068.77"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="45,17 33,21 33,12" style="fill:rgb(0,0,0)"/> @@ -8309,8 +8310,8 @@ In practice, most SELECT statements are simple SELECT statements. </svg> </div> <p><b><a href="syntax/filter-clause.html">filter-clause:</a></b> -<button id='x33d80a14' onclick='hideorshow("x33d80a14","x6f94100e")'>show</button></p> - <div id='x6f94100e' style='display:none;' class='imgcontainer'> +<button id='xb28a2ea3' onclick='hideorshow("xb28a2ea3","x0e474180")'>show</button></p> + <div id='x0e474180' style='display:none;' class='imgcontainer'> <div style="max-width:422px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 422.381 34.56"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="32,17 20,21 20,12" style="fill:rgb(0,0,0)"/> @@ -8340,8 +8341,8 @@ In practice, most SELECT statements are simple SELECT statements. </div> </div> <p><b><a href="syntax/function-arguments.html">function-arguments:</a></b> -<button id='x060984e5' onclick='hideorshow("x060984e5","xee7f8fc0")'>show</button></p> - <div id='xee7f8fc0' style='display:none;' class='imgcontainer'> +<button id='x44d044f4' onclick='hideorshow("x44d044f4","xb3074862")'>show</button></p> + <div id='xb3074862' style='display:none;' class='imgcontainer'> <div style="max-width:456px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 456.566 223.344"> <circle cx="5" cy="56" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="32,56 20,60 20,52" style="fill:rgb(0,0,0)"/> @@ -8404,8 +8405,8 @@ In practice, most SELECT statements are simple SELECT statements. </div> </div> <p><b><a href="syntax/literal-value.html">literal-value:</a></b> -<button id='x283d8f59' onclick='hideorshow("x283d8f59","x2eea733a")'>show</button></p> - <div id='x2eea733a' style='display:none;' class='imgcontainer'> +<button id='x7cd50809' onclick='hideorshow("x7cd50809","x63f9e85f")'>show</button></p> + <div id='x63f9e85f' style='display:none;' class='imgcontainer'> <div style="max-width:341px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 341.376 336.96"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="50,319 39,324 39,315" style="fill:rgb(0,0,0)"/> @@ -8475,8 +8476,8 @@ In practice, most SELECT statements are simple SELECT statements. </div> </div> <p><b><a href="syntax/over-clause.html">over-clause:</a></b> -<button id='x4d3f1c2b' onclick='hideorshow("x4d3f1c2b","xecba4e98")'>show</button></p> - <div id='xecba4e98' style='display:none;' class='imgcontainer'> +<button id='xc88bacb6' onclick='hideorshow("xc88bacb6","xe72c3dc7")'>show</button></p> + <div id='xe72c3dc7' style='display:none;' class='imgcontainer'> <div style="max-width:600px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 600.706 418.392"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="32,17 20,21 20,12" style="fill:rgb(0,0,0)"/> @@ -8567,8 +8568,8 @@ In practice, most SELECT statements are simple SELECT statements. </svg> </div> <p><b><a href="syntax/frame-spec.html">frame-spec:</a></b> -<button id='xbf16314b' onclick='hideorshow("xbf16314b","x6f0e6653")'>show</button></p> - <div id='x6f0e6653' style='display:none;' class='imgcontainer'> +<button id='xd03b1294' onclick='hideorshow("xd03b1294","xb3ce48bd")'>show</button></p> + <div id='xb3ce48bd' style='display:none;' class='imgcontainer'> <div style="max-width:1039px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 1039.65 522.72"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="50,92 39,97 39,88" style="fill:rgb(0,0,0)"/> @@ -8778,8 +8779,8 @@ In practice, most SELECT statements are simple SELECT statements. </div> </div> <p><b><a href="syntax/raise-function.html">raise-function:</a></b> -<button id='xb489060c' onclick='hideorshow("xb489060c","x85779a10")'>show</button></p> - <div id='x85779a10' style='display:none;' class='imgcontainer'> +<button id='x77ccb53e' onclick='hideorshow("x77ccb53e","x5a2e35c7")'>show</button></p> + <div id='x5a2e35c7' style='display:none;' class='imgcontainer'> <div style="max-width:627px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 627.302 147.96"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="32,17 20,21 20,12" style="fill:rgb(0,0,0)"/> @@ -8834,8 +8835,8 @@ In practice, most SELECT statements are simple SELECT statements. </div> </div> <p><b><a href="syntax/select-stmt.html">select-stmt:</a></b> -<button id='xc1a3c356' onclick='hideorshow("xc1a3c356","xeaffe9c4")'>show</button></p> - <div id='xeaffe9c4' style='display:none;' class='imgcontainer'> +<button id='x096dbe17' onclick='hideorshow("x096dbe17","xd3deb524")'>show</button></p> + <div id='xd3deb524' style='display:none;' class='imgcontainer'> <div style="max-width:669px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 669.677 1162.3"> <path d="M55,845L667,845L667,99L55,99Z" style="fill:none;stroke-width:3.24;stroke:rgb(211,211,211);" /> <circle cx="6" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> @@ -9113,8 +9114,8 @@ In practice, most SELECT statements are simple SELECT statements. </svg> </div> <p><b><a href="syntax/compound-operator.html">compound-operator:</a></b> -<button id='x5eefbfd0' onclick='hideorshow("x5eefbfd0","x18a116dd")'>show</button></p> - <div id='x18a116dd' style='display:none;' class='imgcontainer'> +<button id='x869111bd' onclick='hideorshow("x869111bd","x0093985c")'>show</button></p> + <div id='x0093985c' style='display:none;' class='imgcontainer'> <div style="max-width:293px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 293.842 147.96"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="32,17 20,21 20,12" style="fill:rgb(0,0,0)"/> @@ -9155,8 +9156,8 @@ In practice, most SELECT statements are simple SELECT statements. </div> </div> <p><b><a href="syntax/join-clause.html">join-clause:</a></b> -<button id='x3b732021' onclick='hideorshow("x3b732021","x0bc880df")'>show</button></p> - <div id='x0bc880df' style='display:none;' class='imgcontainer'> +<button id='x1be590ba' onclick='hideorshow("x1be590ba","x1aa869af")'>show</button></p> + <div id='x1aa869af' style='display:none;' class='imgcontainer'> <div style="max-width:793px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 793.282 84.24"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="32,17 20,21 20,12" style="fill:rgb(0,0,0)"/> @@ -9187,8 +9188,8 @@ In practice, most SELECT statements are simple SELECT statements. </svg> </div> <p><b><a href="syntax/join-constraint.html">join-constraint:</a></b> -<button id='xb205fe1a' onclick='hideorshow("xb205fe1a","x443d8054")'>show</button></p> - <div id='x443d8054' style='display:none;' class='imgcontainer'> +<button id='x899b5f45' onclick='hideorshow("x899b5f45","xe773c0a0")'>show</button></p> + <div id='xe773c0a0' style='display:none;' class='imgcontainer'> <div style="max-width:483px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 483.336 126.576"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="50,55 39,59 39,50" style="fill:rgb(0,0,0)"/> @@ -9235,8 +9236,8 @@ In practice, most SELECT statements are simple SELECT statements. </div> </div> <p><b><a href="syntax/join-operator.html">join-operator:</a></b> -<button id='xa3f08acc' onclick='hideorshow("xa3f08acc","xcb4d76ea")'>show</button></p> - <div id='xcb4d76ea' style='display:none;' class='imgcontainer'> +<button id='x705cb54e' onclick='hideorshow("x705cb54e","x861c0bb5")'>show</button></p> + <div id='x861c0bb5' style='display:none;' class='imgcontainer'> <div style="max-width:620px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 620.333 255.312"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="50,71 39,76 39,67" style="fill:rgb(0,0,0)"/> @@ -9303,8 +9304,8 @@ In practice, most SELECT statements are simple SELECT statements. </div> </div> <p><b><a href="syntax/result-column.html">result-column:</a></b> -<button id='x8ea66a31' onclick='hideorshow("x8ea66a31","x1b65ccd9")'>show</button></p> - <div id='x1b65ccd9' style='display:none;' class='imgcontainer'> +<button id='x0cdc8d06' onclick='hideorshow("x0cdc8d06","xf01ef1f8")'>show</button></p> + <div id='xf01ef1f8' style='display:none;' class='imgcontainer'> <div style="max-width:398px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 398.054 163.08"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="45,17 33,21 33,12" style="fill:rgb(0,0,0)"/> @@ -9356,8 +9357,8 @@ In practice, most SELECT statements are simple SELECT statements. </div> </div> <p><b><a href="syntax/table-or-subquery.html">table-or-subquery:</a></b> -<button id='x41cc3cd1' onclick='hideorshow("x41cc3cd1","xbef26e88")'>show</button></p> - <div id='xbef26e88' style='display:none;' class='imgcontainer'> +<button id='xa087f8e3' onclick='hideorshow("xa087f8e3","x2593cc83")'>show</button></p> + <div id='x2593cc83' style='display:none;' class='imgcontainer'> <div style="max-width:720px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 720.778 457.704"> <circle cx="5" cy="36" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="50,74 39,78 39,70" style="fill:rgb(0,0,0)"/> @@ -9501,8 +9502,8 @@ In practice, most SELECT statements are simple SELECT statements. </div> </div> <p><b><a href="syntax/window-defn.html">window-defn:</a></b> -<button id='x468c49ac' onclick='hideorshow("x468c49ac","xbbef8e34")'>show</button></p> - <div id='xbbef8e34' style='display:none;' class='imgcontainer'> +<button id='x32ca8acb' onclick='hideorshow("x32ca8acb","x4e7202e2")'>show</button></p> + <div id='x4e7202e2' style='display:none;' class='imgcontainer'> <div style="max-width:479px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 479.765 380.592"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="32,17 20,21 20,12" style="fill:rgb(0,0,0)"/> @@ -9582,8 +9583,8 @@ In practice, most SELECT statements are simple SELECT statements. </svg> </div> <p><b><a href="syntax/frame-spec.html">frame-spec:</a></b> -<button id='xea5ec156' onclick='hideorshow("xea5ec156","x2df1eaa9")'>show</button></p> - <div id='x2df1eaa9' style='display:none;' class='imgcontainer'> +<button id='x1d190374' onclick='hideorshow("x1d190374","xe5052b97")'>show</button></p> + <div id='xe5052b97' style='display:none;' class='imgcontainer'> <div style="max-width:1039px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 1039.65 522.72"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="50,92 39,97 39,88" style="fill:rgb(0,0,0)"/> @@ -9794,8 +9795,8 @@ In practice, most SELECT statements are simple SELECT statements. </div> </div> <p><b><a href="syntax/type-name.html">type-name:</a></b> -<button id='x9f9bb566' onclick='hideorshow("x9f9bb566","x0be7e6ca")'>show</button></p> - <div id='x0be7e6ca' style='display:none;' class='imgcontainer'> +<button id='xb80ef37e' onclick='hideorshow("xb80ef37e","x97b0d68d")'>show</button></p> + <div id='x97b0d68d' style='display:none;' class='imgcontainer'> <div style="max-width:661px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 661.008 110.16"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="45,17 33,21 33,12" style="fill:rgb(0,0,0)"/> @@ -9849,8 +9850,8 @@ In practice, most SELECT statements are simple SELECT statements. </svg> </div> <p><b><a href="syntax/signed-number.html">signed-number:</a></b> -<button id='x5ca2d540' onclick='hideorshow("x5ca2d540","x42d87c3a")'>show</button></p> - <div id='x42d87c3a' style='display:none;' class='imgcontainer'> +<button id='x33dd47d7' onclick='hideorshow("x33dd47d7","xac5d148d")'>show</button></p> + <div id='xac5d148d' style='display:none;' class='imgcontainer'> <div style="max-width:292px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 292.013 99.576"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="50,44 39,48 39,40" style="fill:rgb(0,0,0)"/> @@ -9878,8 +9879,8 @@ In practice, most SELECT statements are simple SELECT statements. </div> </div> <p><b><a href="syntax/ordering-term.html">ordering-term:</a></b> -<button id='x6d034886' onclick='hideorshow("x6d034886","x320e6273")'>show</button></p> - <div id='x320e6273' style='display:none;' class='imgcontainer'> +<button id='x4bf1481a' onclick='hideorshow("x4bf1481a","xf422d8f5")'>show</button></p> + <div id='xf422d8f5' style='display:none;' class='imgcontainer'> <div style="max-width:798px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 798.451 99.576"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="32,17 20,21 20,12" style="fill:rgb(0,0,0)"/> @@ -9939,8 +9940,8 @@ In practice, most SELECT statements are simple SELECT statements. </div> </div> <p><b><a href="syntax/select-core.html">select-core:</a></b> -<button id='x046254b2' onclick='hideorshow("x046254b2","x81614949")'>hide</button></p> - <div id='x81614949' class='imgcontainer'> +<button id='x542475bd' onclick='hideorshow("x542475bd","xf3624c5d")'>hide</button></p> + <div id='xf3624c5d' class='imgcontainer'> <div style="max-width:655px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 655.157 728.568"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="63,17 51,21 51,12" style="fill:rgb(0,0,0)"/> @@ -10117,8 +10118,8 @@ In practice, most SELECT statements are simple SELECT statements. </svg> </div> <p><b><a href="syntax/join-clause.html">join-clause:</a></b> -<button id='x28ecd5fe' onclick='hideorshow("x28ecd5fe","xee5ebb83")'>show</button></p> - <div id='xee5ebb83' style='display:none;' class='imgcontainer'> +<button id='xf64cc9d1' onclick='hideorshow("xf64cc9d1","xfabe1157")'>show</button></p> + <div id='xfabe1157' style='display:none;' class='imgcontainer'> <div style="max-width:793px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 793.282 84.24"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="32,17 20,21 20,12" style="fill:rgb(0,0,0)"/> @@ -10149,8 +10150,8 @@ In practice, most SELECT statements are simple SELECT statements. </svg> </div> <p><b><a href="syntax/join-constraint.html">join-constraint:</a></b> -<button id='xc47fdc79' onclick='hideorshow("xc47fdc79","xa72bfe9b")'>show</button></p> - <div id='xa72bfe9b' style='display:none;' class='imgcontainer'> +<button id='x92ae3604' onclick='hideorshow("x92ae3604","xfea88cf1")'>show</button></p> + <div id='xfea88cf1' style='display:none;' class='imgcontainer'> <div style="max-width:483px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 483.336 126.576"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="50,55 39,59 39,50" style="fill:rgb(0,0,0)"/> @@ -10197,8 +10198,8 @@ In practice, most SELECT statements are simple SELECT statements. </div> </div> <p><b><a href="syntax/join-operator.html">join-operator:</a></b> -<button id='x3d0be55d' onclick='hideorshow("x3d0be55d","x5e3f1679")'>show</button></p> - <div id='x5e3f1679' style='display:none;' class='imgcontainer'> +<button id='x35574abf' onclick='hideorshow("x35574abf","x8937e6be")'>show</button></p> + <div id='x8937e6be' style='display:none;' class='imgcontainer'> <div style="max-width:620px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 620.333 255.312"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="50,71 39,76 39,67" style="fill:rgb(0,0,0)"/> @@ -10265,8 +10266,8 @@ In practice, most SELECT statements are simple SELECT statements. </div> </div> <p><b><a href="syntax/result-column.html">result-column:</a></b> -<button id='x0bfc21e5' onclick='hideorshow("x0bfc21e5","xc884f577")'>show</button></p> - <div id='xc884f577' style='display:none;' class='imgcontainer'> +<button id='x0fb8db30' onclick='hideorshow("x0fb8db30","xae40a33a")'>show</button></p> + <div id='xae40a33a' style='display:none;' class='imgcontainer'> <div style="max-width:398px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 398.054 163.08"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="45,17 33,21 33,12" style="fill:rgb(0,0,0)"/> @@ -10318,8 +10319,8 @@ In practice, most SELECT statements are simple SELECT statements. </div> </div> <p><b><a href="syntax/table-or-subquery.html">table-or-subquery:</a></b> -<button id='xbff34af5' onclick='hideorshow("xbff34af5","x36cb15fd")'>show</button></p> - <div id='x36cb15fd' style='display:none;' class='imgcontainer'> +<button id='x6bcf3d64' onclick='hideorshow("x6bcf3d64","x86b46ad3")'>show</button></p> + <div id='x86b46ad3' style='display:none;' class='imgcontainer'> <div style="max-width:720px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 720.778 457.704"> <circle cx="5" cy="36" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="50,74 39,78 39,70" style="fill:rgb(0,0,0)"/> @@ -10462,8 +10463,8 @@ In practice, most SELECT statements are simple SELECT statements. </svg> </div> <p><b><a href="syntax/select-stmt.html">select-stmt:</a></b> -<button id='x9767e441' onclick='hideorshow("x9767e441","xa0bfe660")'>show</button></p> - <div id='xa0bfe660' style='display:none;' class='imgcontainer'> +<button id='x44bc0958' onclick='hideorshow("x44bc0958","xd2959042")'>show</button></p> + <div id='xd2959042' style='display:none;' class='imgcontainer'> <div style="max-width:669px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 669.677 1162.3"> <path d="M55,845L667,845L667,99L55,99Z" style="fill:none;stroke-width:3.24;stroke:rgb(211,211,211);" /> <circle cx="6" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> @@ -10741,8 +10742,8 @@ In practice, most SELECT statements are simple SELECT statements. </svg> </div> <p><b><a href="syntax/compound-operator.html">compound-operator:</a></b> -<button id='x8eb79397' onclick='hideorshow("x8eb79397","x84912f48")'>show</button></p> - <div id='x84912f48' style='display:none;' class='imgcontainer'> +<button id='xdfa12119' onclick='hideorshow("xdfa12119","x4c8daef2")'>show</button></p> + <div id='x4c8daef2' style='display:none;' class='imgcontainer'> <div style="max-width:293px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 293.842 147.96"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="32,17 20,21 20,12" style="fill:rgb(0,0,0)"/> @@ -10785,8 +10786,8 @@ In practice, most SELECT statements are simple SELECT statements. </div> </div> <p><b><a href="syntax/window-defn.html">window-defn:</a></b> -<button id='x4a49b898' onclick='hideorshow("x4a49b898","x14b7e517")'>show</button></p> - <div id='x14b7e517' style='display:none;' class='imgcontainer'> +<button id='x82585551' onclick='hideorshow("x82585551","x8e61bc86")'>show</button></p> + <div id='x8e61bc86' style='display:none;' class='imgcontainer'> <div style="max-width:479px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 479.765 380.592"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="32,17 20,21 20,12" style="fill:rgb(0,0,0)"/> @@ -10866,8 +10867,8 @@ In practice, most SELECT statements are simple SELECT statements. </svg> </div> <p><b><a href="syntax/frame-spec.html">frame-spec:</a></b> -<button id='x84df1f0c' onclick='hideorshow("x84df1f0c","x82b1389c")'>show</button></p> - <div id='x82b1389c' style='display:none;' class='imgcontainer'> +<button id='x9d509eae' onclick='hideorshow("x9d509eae","x9a4aa266")'>show</button></p> + <div id='x9a4aa266' style='display:none;' class='imgcontainer'> <div style="max-width:1039px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 1039.65 522.72"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="50,92 39,97 39,88" style="fill:rgb(0,0,0)"/> @@ -11254,14 +11255,14 @@ evaluates to either false or NULL. </p><p>For a JOIN or INNER JOIN or CROSS JOIN, there is no difference between a constraint expression in the WHERE clause and one in the ON clause. However, -for a LEFT JOIN or LEFT OUTER JOIN, the difference is very important. -In a LEFT JOIN, -the extra NULL row for the right-hand table is added after ON clause processing +for a LEFT or RIGHT or FULL OUTER JOIN, the difference is very important. +In an outer join, the extra NULL rows for non-matched rows on the other +operand are added after ON clause processing but before WHERE clause processing. A constraint of the form "left.x=right.y" -in an ON clause will therefore allow through the added all-NULL rows of the -right table. But if that same constraint is in the WHERE clause a NULL in -"right.y" will prevent the expression "left.x=right.y" from being true, and -thus exclude that row from the output. +in an ON clause will therefore allow through for the added all-NULL rows. +But if that same constraint is in the WHERE clause, a NULL in one of +"right.y" or "left.x" will prevent the expression "left.x=right.y" from being true, +and thus exclude that row from the output. <a name="resultset"></a> @@ -11441,8 +11442,8 @@ a compound SELECT using the UNION, UNION ALL, INTERSECT or EXCEPT operator, as shown by the following diagram: <p><b><a href="syntax/compound-select-stmt.html">compound-select-stmt:</a></b> -<button id='x79298984' onclick='hideorshow("x79298984","x25876c55")'>hide</button></p> - <div id='x25876c55' class='imgcontainer'> +<button id='x8510f929' onclick='hideorshow("x8510f929","x7d357cdf")'>hide</button></p> + <div id='x7d357cdf' class='imgcontainer'> <div style="max-width:652px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 652.306 560.52"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="32,17 20,21 20,12" style="fill:rgb(0,0,0)"/> @@ -11581,8 +11582,8 @@ as shown by the following diagram: </svg> </div> <p><b><a href="syntax/common-table-expression.html">common-table-expression:</a></b> -<button id='x297fc842' onclick='hideorshow("x297fc842","x0b16f6e4")'>show</button></p> - <div id='x0b16f6e4' style='display:none;' class='imgcontainer'> +<button id='x465bf0a6' onclick='hideorshow("x465bf0a6","x29388986")'>show</button></p> + <div id='x29388986' style='display:none;' class='imgcontainer'> <div style="max-width:638px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 638.525 167.4"> <circle cx="5" cy="29" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="32,29 20,33 20,24" style="fill:rgb(0,0,0)"/> @@ -11651,8 +11652,8 @@ as shown by the following diagram: </svg> </div> <p><b><a href="syntax/select-stmt.html">select-stmt:</a></b> -<button id='xe44cb4ee' onclick='hideorshow("xe44cb4ee","x5163e62f")'>show</button></p> - <div id='x5163e62f' style='display:none;' class='imgcontainer'> +<button id='x01afd55c' onclick='hideorshow("x01afd55c","x66b1cdd3")'>show</button></p> + <div id='x66b1cdd3' style='display:none;' class='imgcontainer'> <div style="max-width:669px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 669.677 1162.3"> <path d="M55,845L667,845L667,99L55,99Z" style="fill:none;stroke-width:3.24;stroke:rgb(211,211,211);" /> <circle cx="6" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> @@ -11930,8 +11931,8 @@ as shown by the following diagram: </svg> </div> <p><b><a href="syntax/compound-operator.html">compound-operator:</a></b> -<button id='xd96fe8d9' onclick='hideorshow("xd96fe8d9","x456b1eae")'>show</button></p> - <div id='x456b1eae' style='display:none;' class='imgcontainer'> +<button id='x7f03ad74' onclick='hideorshow("x7f03ad74","xf486c9ca")'>show</button></p> + <div id='xf486c9ca' style='display:none;' class='imgcontainer'> <div style="max-width:293px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 293.842 147.96"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="32,17 20,21 20,12" style="fill:rgb(0,0,0)"/> @@ -11972,8 +11973,8 @@ as shown by the following diagram: </div> </div> <p><b><a href="syntax/join-clause.html">join-clause:</a></b> -<button id='xe1a9e7fb' onclick='hideorshow("xe1a9e7fb","x63d62ab9")'>show</button></p> - <div id='x63d62ab9' style='display:none;' class='imgcontainer'> +<button id='x66a86081' onclick='hideorshow("x66a86081","x95c61755")'>show</button></p> + <div id='x95c61755' style='display:none;' class='imgcontainer'> <div style="max-width:793px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 793.282 84.24"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="32,17 20,21 20,12" style="fill:rgb(0,0,0)"/> @@ -12004,8 +12005,8 @@ as shown by the following diagram: </svg> </div> <p><b><a href="syntax/join-constraint.html">join-constraint:</a></b> -<button id='xcd9909f5' onclick='hideorshow("xcd9909f5","x8a186c96")'>show</button></p> - <div id='x8a186c96' style='display:none;' class='imgcontainer'> +<button id='xd47cf8e5' onclick='hideorshow("xd47cf8e5","x83bba41b")'>show</button></p> + <div id='x83bba41b' style='display:none;' class='imgcontainer'> <div style="max-width:483px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 483.336 126.576"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="50,55 39,59 39,50" style="fill:rgb(0,0,0)"/> @@ -12052,8 +12053,8 @@ as shown by the following diagram: </div> </div> <p><b><a href="syntax/join-operator.html">join-operator:</a></b> -<button id='x98275cc3' onclick='hideorshow("x98275cc3","xced84a8c")'>show</button></p> - <div id='xced84a8c' style='display:none;' class='imgcontainer'> +<button id='xfbe7a1a7' onclick='hideorshow("xfbe7a1a7","xf5150d08")'>show</button></p> + <div id='xf5150d08' style='display:none;' class='imgcontainer'> <div style="max-width:620px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 620.333 255.312"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="50,71 39,76 39,67" style="fill:rgb(0,0,0)"/> @@ -12120,8 +12121,8 @@ as shown by the following diagram: </div> </div> <p><b><a href="syntax/result-column.html">result-column:</a></b> -<button id='x31e27d3e' onclick='hideorshow("x31e27d3e","x670d2a67")'>show</button></p> - <div id='x670d2a67' style='display:none;' class='imgcontainer'> +<button id='xff220fc8' onclick='hideorshow("xff220fc8","x506dfd37")'>show</button></p> + <div id='x506dfd37' style='display:none;' class='imgcontainer'> <div style="max-width:398px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 398.054 163.08"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="45,17 33,21 33,12" style="fill:rgb(0,0,0)"/> @@ -12173,8 +12174,8 @@ as shown by the following diagram: </div> </div> <p><b><a href="syntax/table-or-subquery.html">table-or-subquery:</a></b> -<button id='xfc280618' onclick='hideorshow("xfc280618","x3c6348f4")'>show</button></p> - <div id='x3c6348f4' style='display:none;' class='imgcontainer'> +<button id='x9ef6b9a2' onclick='hideorshow("x9ef6b9a2","x35024829")'>show</button></p> + <div id='x35024829' style='display:none;' class='imgcontainer'> <div style="max-width:720px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 720.778 457.704"> <circle cx="5" cy="36" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="50,74 39,78 39,70" style="fill:rgb(0,0,0)"/> @@ -12318,8 +12319,8 @@ as shown by the following diagram: </div> </div> <p><b><a href="syntax/window-defn.html">window-defn:</a></b> -<button id='xce1ae0b0' onclick='hideorshow("xce1ae0b0","xe3df3276")'>show</button></p> - <div id='xe3df3276' style='display:none;' class='imgcontainer'> +<button id='xf564e8b4' onclick='hideorshow("xf564e8b4","x2e322a0a")'>show</button></p> + <div id='x2e322a0a' style='display:none;' class='imgcontainer'> <div style="max-width:479px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 479.765 380.592"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="32,17 20,21 20,12" style="fill:rgb(0,0,0)"/> @@ -12399,8 +12400,8 @@ as shown by the following diagram: </svg> </div> <p><b><a href="syntax/frame-spec.html">frame-spec:</a></b> -<button id='x0b6da2cb' onclick='hideorshow("x0b6da2cb","xa55ff156")'>show</button></p> - <div id='xa55ff156' style='display:none;' class='imgcontainer'> +<button id='x8d3aaba0' onclick='hideorshow("x8d3aaba0","x2a4f2f78")'>show</button></p> + <div id='x2a4f2f78' style='display:none;' class='imgcontainer'> <div style="max-width:1039px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 1039.65 522.72"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="50,92 39,97 39,88" style="fill:rgb(0,0,0)"/> @@ -12612,8 +12613,8 @@ as shown by the following diagram: </div> </div> <p><b><a href="syntax/expr.html">expr:</a></b> -<button id='xb0110d17' onclick='hideorshow("xb0110d17","xa58b7a65")'>show</button></p> - <div id='xa58b7a65' style='display:none;' class='imgcontainer'> +<button id='x386d0e85' onclick='hideorshow("x386d0e85","x6cd28ebe")'>show</button></p> + <div id='x6cd28ebe' style='display:none;' class='imgcontainer'> <div style="max-width:963px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 963.96 1068.77"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="45,17 33,21 33,12" style="fill:rgb(0,0,0)"/> @@ -13094,8 +13095,8 @@ as shown by the following diagram: </svg> </div> <p><b><a href="syntax/filter-clause.html">filter-clause:</a></b> -<button id='xceda306e' onclick='hideorshow("xceda306e","xea62fd58")'>show</button></p> - <div id='xea62fd58' style='display:none;' class='imgcontainer'> +<button id='x24bbaf82' onclick='hideorshow("x24bbaf82","xbfc3b1ce")'>show</button></p> + <div id='xbfc3b1ce' style='display:none;' class='imgcontainer'> <div style="max-width:422px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 422.381 34.56"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="32,17 20,21 20,12" style="fill:rgb(0,0,0)"/> @@ -13125,8 +13126,8 @@ as shown by the following diagram: </div> </div> <p><b><a href="syntax/function-arguments.html">function-arguments:</a></b> -<button id='x3b1c4694' onclick='hideorshow("x3b1c4694","x05ebb606")'>show</button></p> - <div id='x05ebb606' style='display:none;' class='imgcontainer'> +<button id='x4aaee466' onclick='hideorshow("x4aaee466","x436b72be")'>show</button></p> + <div id='x436b72be' style='display:none;' class='imgcontainer'> <div style="max-width:456px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 456.566 223.344"> <circle cx="5" cy="56" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="32,56 20,60 20,52" style="fill:rgb(0,0,0)"/> @@ -13189,8 +13190,8 @@ as shown by the following diagram: </div> </div> <p><b><a href="syntax/literal-value.html">literal-value:</a></b> -<button id='xe3bbd990' onclick='hideorshow("xe3bbd990","x6fe52e16")'>show</button></p> - <div id='x6fe52e16' style='display:none;' class='imgcontainer'> +<button id='x02ecb1a9' onclick='hideorshow("x02ecb1a9","xaf24b70b")'>show</button></p> + <div id='xaf24b70b' style='display:none;' class='imgcontainer'> <div style="max-width:341px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 341.376 336.96"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="50,319 39,324 39,315" style="fill:rgb(0,0,0)"/> @@ -13260,8 +13261,8 @@ as shown by the following diagram: </div> </div> <p><b><a href="syntax/over-clause.html">over-clause:</a></b> -<button id='xa8bb4111' onclick='hideorshow("xa8bb4111","xaafd812c")'>show</button></p> - <div id='xaafd812c' style='display:none;' class='imgcontainer'> +<button id='x971719a0' onclick='hideorshow("x971719a0","xb3496704")'>show</button></p> + <div id='xb3496704' style='display:none;' class='imgcontainer'> <div style="max-width:600px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 600.706 418.392"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="32,17 20,21 20,12" style="fill:rgb(0,0,0)"/> @@ -13352,8 +13353,8 @@ as shown by the following diagram: </svg> </div> <p><b><a href="syntax/frame-spec.html">frame-spec:</a></b> -<button id='xac187afd' onclick='hideorshow("xac187afd","x7446f303")'>show</button></p> - <div id='x7446f303' style='display:none;' class='imgcontainer'> +<button id='x44f617a7' onclick='hideorshow("x44f617a7","x7f88d487")'>show</button></p> + <div id='x7f88d487' style='display:none;' class='imgcontainer'> <div style="max-width:1039px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 1039.65 522.72"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="50,92 39,97 39,88" style="fill:rgb(0,0,0)"/> @@ -13563,8 +13564,8 @@ as shown by the following diagram: </div> </div> <p><b><a href="syntax/raise-function.html">raise-function:</a></b> -<button id='xaf0ab36f' onclick='hideorshow("xaf0ab36f","x5a9d9547")'>show</button></p> - <div id='x5a9d9547' style='display:none;' class='imgcontainer'> +<button id='x8d3842ac' onclick='hideorshow("x8d3842ac","x9c6b9f93")'>show</button></p> + <div id='x9c6b9f93' style='display:none;' class='imgcontainer'> <div style="max-width:627px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 627.302 147.96"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="32,17 20,21 20,12" style="fill:rgb(0,0,0)"/> @@ -13619,8 +13620,8 @@ as shown by the following diagram: </div> </div> <p><b><a href="syntax/select-stmt.html">select-stmt:</a></b> -<button id='x6462122b' onclick='hideorshow("x6462122b","x5f77c13d")'>show</button></p> - <div id='x5f77c13d' style='display:none;' class='imgcontainer'> +<button id='xaf688c89' onclick='hideorshow("xaf688c89","xf5fcceb6")'>show</button></p> + <div id='xf5fcceb6' style='display:none;' class='imgcontainer'> <div style="max-width:669px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 669.677 1162.3"> <path d="M55,845L667,845L667,99L55,99Z" style="fill:none;stroke-width:3.24;stroke:rgb(211,211,211);" /> <circle cx="6" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> @@ -13898,8 +13899,8 @@ as shown by the following diagram: </svg> </div> <p><b><a href="syntax/compound-operator.html">compound-operator:</a></b> -<button id='xf14d4425' onclick='hideorshow("xf14d4425","x1a6c3ae2")'>show</button></p> - <div id='x1a6c3ae2' style='display:none;' class='imgcontainer'> +<button id='x6e14dced' onclick='hideorshow("x6e14dced","xb2eb8c24")'>show</button></p> + <div id='xb2eb8c24' style='display:none;' class='imgcontainer'> <div style="max-width:293px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 293.842 147.96"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="32,17 20,21 20,12" style="fill:rgb(0,0,0)"/> @@ -13940,8 +13941,8 @@ as shown by the following diagram: </div> </div> <p><b><a href="syntax/join-clause.html">join-clause:</a></b> -<button id='x1a2d29a6' onclick='hideorshow("x1a2d29a6","x2d706d77")'>show</button></p> - <div id='x2d706d77' style='display:none;' class='imgcontainer'> +<button id='x703ea4a5' onclick='hideorshow("x703ea4a5","x414ec75e")'>show</button></p> + <div id='x414ec75e' style='display:none;' class='imgcontainer'> <div style="max-width:793px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 793.282 84.24"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="32,17 20,21 20,12" style="fill:rgb(0,0,0)"/> @@ -13972,8 +13973,8 @@ as shown by the following diagram: </svg> </div> <p><b><a href="syntax/join-constraint.html">join-constraint:</a></b> -<button id='x67e595a0' onclick='hideorshow("x67e595a0","xad556e60")'>show</button></p> - <div id='xad556e60' style='display:none;' class='imgcontainer'> +<button id='x6dc9fba6' onclick='hideorshow("x6dc9fba6","x4c41ef9b")'>show</button></p> + <div id='x4c41ef9b' style='display:none;' class='imgcontainer'> <div style="max-width:483px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 483.336 126.576"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="50,55 39,59 39,50" style="fill:rgb(0,0,0)"/> @@ -14020,8 +14021,8 @@ as shown by the following diagram: </div> </div> <p><b><a href="syntax/join-operator.html">join-operator:</a></b> -<button id='x6e06bdd2' onclick='hideorshow("x6e06bdd2","x566b7594")'>show</button></p> - <div id='x566b7594' style='display:none;' class='imgcontainer'> +<button id='x12e9de81' onclick='hideorshow("x12e9de81","x8f6a733f")'>show</button></p> + <div id='x8f6a733f' style='display:none;' class='imgcontainer'> <div style="max-width:620px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 620.333 255.312"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="50,71 39,76 39,67" style="fill:rgb(0,0,0)"/> @@ -14088,8 +14089,8 @@ as shown by the following diagram: </div> </div> <p><b><a href="syntax/result-column.html">result-column:</a></b> -<button id='x97092db7' onclick='hideorshow("x97092db7","x940219b8")'>show</button></p> - <div id='x940219b8' style='display:none;' class='imgcontainer'> +<button id='xdba1658e' onclick='hideorshow("xdba1658e","xdacd9a05")'>show</button></p> + <div id='xdacd9a05' style='display:none;' class='imgcontainer'> <div style="max-width:398px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 398.054 163.08"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="45,17 33,21 33,12" style="fill:rgb(0,0,0)"/> @@ -14141,8 +14142,8 @@ as shown by the following diagram: </div> </div> <p><b><a href="syntax/table-or-subquery.html">table-or-subquery:</a></b> -<button id='xd5bf60d0' onclick='hideorshow("xd5bf60d0","xd94f9210")'>show</button></p> - <div id='xd94f9210' style='display:none;' class='imgcontainer'> +<button id='xfd5b4100' onclick='hideorshow("xfd5b4100","xa7f13192")'>show</button></p> + <div id='xa7f13192' style='display:none;' class='imgcontainer'> <div style="max-width:720px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 720.778 457.704"> <circle cx="5" cy="36" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="50,74 39,78 39,70" style="fill:rgb(0,0,0)"/> @@ -14286,8 +14287,8 @@ as shown by the following diagram: </div> </div> <p><b><a href="syntax/window-defn.html">window-defn:</a></b> -<button id='x1fd092e6' onclick='hideorshow("x1fd092e6","xb8787981")'>show</button></p> - <div id='xb8787981' style='display:none;' class='imgcontainer'> +<button id='x2d69a673' onclick='hideorshow("x2d69a673","xaac5afbb")'>show</button></p> + <div id='xaac5afbb' style='display:none;' class='imgcontainer'> <div style="max-width:479px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 479.765 380.592"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="32,17 20,21 20,12" style="fill:rgb(0,0,0)"/> @@ -14367,8 +14368,8 @@ as shown by the following diagram: </svg> </div> <p><b><a href="syntax/frame-spec.html">frame-spec:</a></b> -<button id='x27b5b481' onclick='hideorshow("x27b5b481","xedf30102")'>show</button></p> - <div id='xedf30102' style='display:none;' class='imgcontainer'> +<button id='x25cb4a13' onclick='hideorshow("x25cb4a13","x61e15955")'>show</button></p> + <div id='x61e15955' style='display:none;' class='imgcontainer'> <div style="max-width:1039px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 1039.65 522.72"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="50,92 39,97 39,88" style="fill:rgb(0,0,0)"/> @@ -14579,8 +14580,8 @@ as shown by the following diagram: </div> </div> <p><b><a href="syntax/type-name.html">type-name:</a></b> -<button id='xcc909163' onclick='hideorshow("xcc909163","xcaf85157")'>show</button></p> - <div id='xcaf85157' style='display:none;' class='imgcontainer'> +<button id='x5816975f' onclick='hideorshow("x5816975f","xeb555151")'>show</button></p> + <div id='xeb555151' style='display:none;' class='imgcontainer'> <div style="max-width:661px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 661.008 110.16"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="45,17 33,21 33,12" style="fill:rgb(0,0,0)"/> @@ -14634,8 +14635,8 @@ as shown by the following diagram: </svg> </div> <p><b><a href="syntax/signed-number.html">signed-number:</a></b> -<button id='x788a6107' onclick='hideorshow("x788a6107","x1b3d4145")'>show</button></p> - <div id='x1b3d4145' style='display:none;' class='imgcontainer'> +<button id='xbedd75e7' onclick='hideorshow("xbedd75e7","xdb5e196e")'>show</button></p> + <div id='xdb5e196e' style='display:none;' class='imgcontainer'> <div style="max-width:292px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 292.013 99.576"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="50,44 39,48 39,40" style="fill:rgb(0,0,0)"/> @@ -14663,8 +14664,8 @@ as shown by the following diagram: </div> </div> <p><b><a href="syntax/ordering-term.html">ordering-term:</a></b> -<button id='x44708a7c' onclick='hideorshow("x44708a7c","x0cdb687a")'>show</button></p> - <div id='x0cdb687a' style='display:none;' class='imgcontainer'> +<button id='x9b0ecbd9' onclick='hideorshow("x9b0ecbd9","x938018e5")'>show</button></p> + <div id='x938018e5' style='display:none;' class='imgcontainer'> <div style="max-width:798px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 798.451 99.576"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="32,17 20,21 20,12" style="fill:rgb(0,0,0)"/> @@ -14724,8 +14725,8 @@ as shown by the following diagram: </div> </div> <p><b><a href="syntax/select-core.html">select-core:</a></b> -<button id='x10e80211' onclick='hideorshow("x10e80211","xba3ee58c")'>show</button></p> - <div id='xba3ee58c' style='display:none;' class='imgcontainer'> +<button id='x4af73037' onclick='hideorshow("x4af73037","xe1626af5")'>show</button></p> + <div id='xe1626af5' style='display:none;' class='imgcontainer'> <div style="max-width:655px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 655.157 728.568"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="63,17 51,21 51,12" style="fill:rgb(0,0,0)"/> @@ -14902,8 +14903,8 @@ as shown by the following diagram: </svg> </div> <p><b><a href="syntax/join-clause.html">join-clause:</a></b> -<button id='xc3747ad1' onclick='hideorshow("xc3747ad1","xd5279444")'>show</button></p> - <div id='xd5279444' style='display:none;' class='imgcontainer'> +<button id='xe00f7e00' onclick='hideorshow("xe00f7e00","xb93f5353")'>show</button></p> + <div id='xb93f5353' style='display:none;' class='imgcontainer'> <div style="max-width:793px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 793.282 84.24"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="32,17 20,21 20,12" style="fill:rgb(0,0,0)"/> @@ -14934,8 +14935,8 @@ as shown by the following diagram: </svg> </div> <p><b><a href="syntax/join-constraint.html">join-constraint:</a></b> -<button id='x8fe4926f' onclick='hideorshow("x8fe4926f","x6a2007d5")'>show</button></p> - <div id='x6a2007d5' style='display:none;' class='imgcontainer'> +<button id='xb0e816d3' onclick='hideorshow("xb0e816d3","x56fcfdde")'>show</button></p> + <div id='x56fcfdde' style='display:none;' class='imgcontainer'> <div style="max-width:483px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 483.336 126.576"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="50,55 39,59 39,50" style="fill:rgb(0,0,0)"/> @@ -14982,8 +14983,8 @@ as shown by the following diagram: </div> </div> <p><b><a href="syntax/join-operator.html">join-operator:</a></b> -<button id='xcab301ef' onclick='hideorshow("xcab301ef","x3df9ba0e")'>show</button></p> - <div id='x3df9ba0e' style='display:none;' class='imgcontainer'> +<button id='xf0d31cf6' onclick='hideorshow("xf0d31cf6","xfe8b409f")'>show</button></p> + <div id='xfe8b409f' style='display:none;' class='imgcontainer'> <div style="max-width:620px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 620.333 255.312"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="50,71 39,76 39,67" style="fill:rgb(0,0,0)"/> @@ -15050,8 +15051,8 @@ as shown by the following diagram: </div> </div> <p><b><a href="syntax/result-column.html">result-column:</a></b> -<button id='x61f42f9c' onclick='hideorshow("x61f42f9c","xe09b6df9")'>show</button></p> - <div id='xe09b6df9' style='display:none;' class='imgcontainer'> +<button id='xf2b82177' onclick='hideorshow("xf2b82177","xfea02009")'>show</button></p> + <div id='xfea02009' style='display:none;' class='imgcontainer'> <div style="max-width:398px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 398.054 163.08"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="45,17 33,21 33,12" style="fill:rgb(0,0,0)"/> @@ -15103,8 +15104,8 @@ as shown by the following diagram: </div> </div> <p><b><a href="syntax/table-or-subquery.html">table-or-subquery:</a></b> -<button id='xea7208de' onclick='hideorshow("xea7208de","xac9b420d")'>show</button></p> - <div id='xac9b420d' style='display:none;' class='imgcontainer'> +<button id='x48ac33ad' onclick='hideorshow("x48ac33ad","x9a398ffd")'>show</button></p> + <div id='x9a398ffd' style='display:none;' class='imgcontainer'> <div style="max-width:720px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 720.778 457.704"> <circle cx="5" cy="36" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="50,74 39,78 39,70" style="fill:rgb(0,0,0)"/> @@ -15247,8 +15248,8 @@ as shown by the following diagram: </svg> </div> <p><b><a href="syntax/select-stmt.html">select-stmt:</a></b> -<button id='x90ffb670' onclick='hideorshow("x90ffb670","xd685fecf")'>show</button></p> - <div id='xd685fecf' style='display:none;' class='imgcontainer'> +<button id='xf29f61eb' onclick='hideorshow("xf29f61eb","xdd1a58bc")'>show</button></p> + <div id='xdd1a58bc' style='display:none;' class='imgcontainer'> <div style="max-width:669px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 669.677 1162.3"> <path d="M55,845L667,845L667,99L55,99Z" style="fill:none;stroke-width:3.24;stroke:rgb(211,211,211);" /> <circle cx="6" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> @@ -15526,8 +15527,8 @@ as shown by the following diagram: </svg> </div> <p><b><a href="syntax/compound-operator.html">compound-operator:</a></b> -<button id='x62aba7dc' onclick='hideorshow("x62aba7dc","xf7375003")'>show</button></p> - <div id='xf7375003' style='display:none;' class='imgcontainer'> +<button id='xc00870ec' onclick='hideorshow("xc00870ec","x85f235e2")'>show</button></p> + <div id='x85f235e2' style='display:none;' class='imgcontainer'> <div style="max-width:293px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 293.842 147.96"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="32,17 20,21 20,12" style="fill:rgb(0,0,0)"/> @@ -15570,8 +15571,8 @@ as shown by the following diagram: </div> </div> <p><b><a href="syntax/window-defn.html">window-defn:</a></b> -<button id='x165ac4e6' onclick='hideorshow("x165ac4e6","xcd8a346f")'>show</button></p> - <div id='xcd8a346f' style='display:none;' class='imgcontainer'> +<button id='xb2b24b21' onclick='hideorshow("xb2b24b21","x76ab6808")'>show</button></p> + <div id='x76ab6808' style='display:none;' class='imgcontainer'> <div style="max-width:479px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 479.765 380.592"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="32,17 20,21 20,12" style="fill:rgb(0,0,0)"/> @@ -15651,8 +15652,8 @@ as shown by the following diagram: </svg> </div> <p><b><a href="syntax/frame-spec.html">frame-spec:</a></b> -<button id='xd7ba7ea2' onclick='hideorshow("xd7ba7ea2","xd97ae810")'>show</button></p> - <div id='xd97ae810' style='display:none;' class='imgcontainer'> +<button id='x86862995' onclick='hideorshow("x86862995","x7aacbc15")'>show</button></p> + <div id='x7aacbc15' style='display:none;' class='imgcontainer'> <div style="max-width:1039px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 1039.65 522.72"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="50,92 39,97 39,88" style="fill:rgb(0,0,0)"/> @@ -16101,8 +16102,8 @@ we leave it alone and document it here, rather than try to fix it. <p>SQLite accepts all of the usual syntax for JOIN operators: <p><b><a href="syntax/join-operator.html">join-operator:</a></b> -<button id='xcd7cc9da' onclick='hideorshow("xcd7cc9da","x075b2cf8")'>hide</button></p> - <div id='x075b2cf8' class='imgcontainer'> +<button id='x34b7d5df' onclick='hideorshow("x34b7d5df","xfa214324")'>hide</button></p> + <div id='xfa214324' class='imgcontainer'> <div style="max-width:620px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 620.333 255.312"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="50,71 39,76 39,67" style="fill:rgb(0,0,0)"/> @@ -16189,7 +16190,28 @@ which is the same as "FULL JOIN". </p><p>Remember: you <i>can</i> use these non-standard join types but you <i>ought not</i>. Stick to using standard JOIN syntax for portability with other SQL database engines. -</p><h2 id="precedence_of_comma_joins_and_cross_join"><span>9.2. </span>Precedence of comma-joins and CROSS JOIN</h2> +</p><h2 id="flexible_join_syntax"><span>9.2. </span>Flexible join syntax</h2> + +<p>Standard SQL has tighter restrictions on join syntax than does SQLite. +In standard SQL, all joins other than comma-joins, CROSS JOINs, and NATURAL +joins must have either an ON clause or a USING clause and comma-joins, CROSS JOINs, +and NATURAL joins must not have either an ON or USING clause. SQLite is not +nearly so fussy about join syntax. SQLite will accept and process an ON or USING clause +on a comma-join or CROSS JOIN, and will let you omit the ON or USING +clause from any join at all. In SQLite, the only restrictions are: + +</p><ul> +<li><p> You cannot have an ON or USING clause on a NATURAL join. + +</p></li><li><p> You cannot have both an ON clause and a USING clause on the same join. +</p></li></ul> + +<p> +SQLite even allows you to omit the ON or USING clause from an outer join, +though doing so means that the outer join is unconstrained (as if the ON clause +where "<tt>ON true</tt>") which make the outer join behave like an inner join. + +</p><h2 id="precedence_of_comma_joins_and_cross_join"><span>9.3. </span>Precedence of comma-joins and CROSS JOIN</h2> <p>In standard SQL, joins that use the JOIN keyword take higher precedence than comma-joins. That is to say, JOIN operators happen before comma operators. @@ -16225,5 +16247,5 @@ programmers instinctively follow all of these suggestions without having to be told, and so the lack of precedence difference between comma-joins and the JOIN keyword in SQLite rarely comes up in practice. But you should be aware of the problem, in case it ever does appear. -</p><p align="center"><small><i>This page last modified on <a href="https://sqlite.org/docsrc/honeypot" id="mtimelink" data-href="https://sqlite.org/docsrc/finfo/pages/lang_select.in?m=22906d1d5a">2023-06-13 13:23:44</a> UTC </small></i></p> +</p> diff --git a/www/loadext.html b/www/loadext.html index daa2912..dfa850c 100644 --- a/www/loadext.html +++ b/www/loadext.html @@ -191,7 +191,7 @@ by the <a href="c3ref/load_extension.html">sqlite3_load_extension()</a> interfac C interface.</p> <p>Both methods for loading an extension allow you to specify -the name of an entry point for the extension. +the name of an entry point for the extension. You can leave this argument blank - passing in a NULL pointer for the <a href="c3ref/load_extension.html">sqlite3_load_extension()</a> C-language interface or omitting the second argument for the <a href="lang_corefunc.html#load_extension">load_extension()</a> SQL interface - @@ -203,7 +203,7 @@ by the lowercase equivalent of every ASCII character in the filename after the last "/" and before the first following "." omitting the first three characters if they happen to be "lib". So, for example, if the filename is "/usr/lib/libmathfunc-4.8.so" the entry point name -would be "sqlite3_mathfunc_init". Or if the filename is +would be "sqlite3_mathfunc_init". Or if the filename is "./SpellFixExt.dll" then the entry point would be called "sqlite3_spellfixext_init". @@ -289,12 +289,12 @@ code files instead of "<tt>#include <sqlite3.h></tt>". </p> </li><li><p> -Put the macro "<tt>SQLITE_EXTENSION_INIT1</tt>" on a line by itself +Put the macro "<tt>SQLITE_EXTENSION_INIT1</tt>" on a line by itself right after the "<tt>#include <sqlite3ext.h></tt>" line. </p> </li><li><p> -Add an extension loading entry point routine that looks like +Add an extension loading entry point routine that looks like something the following: </p><div class="codeblock"><pre>#ifdef _WIN32 @@ -325,7 +325,7 @@ above, then the correct entry point name would be "sqlite3_yourcode_init". </p></li></ol> -<p>Here is a complete template extension that you can copy/paste +<p>Here is a complete template extension that you can copy/paste to get started:</p> <div class="codeblock"><pre>/* Add your header comment here */ @@ -344,8 +344,8 @@ __declspec(dllexport) ** discarding the first three characters if they are "lib". */ int sqlite3_extension_init( - sqlite3 *db, - char **pzErrMsg, + sqlite3 *db, + char **pzErrMsg, const sqlite3_api_routines *pApi ){ int rc = SQLITE_OK; @@ -363,12 +363,12 @@ int sqlite3_extension_init( <h2 id="example_extensions"><span>4.1. </span>Example Extensions</h2> -<p>Many examples of complete and working loadable extensions can be +<p>Many examples of complete and working loadable extensions can be seen in the SQLite source tree in the <a href="https://www.sqlite.org/src/file/ext/misc">ext/misc</a> subdirectory. Each file in that directory is a separate extension. Documentation is provided by a header comment on the file. -Here are brief notes on a few of the extensions in +Here are brief notes on a few of the extensions in the <a href="https://www.sqlite.org/src/file/ext/misc">ext/misc</a> subdirectory: </p><ul> @@ -388,7 +388,7 @@ This is a larger and more complex extension. Implementation of a new <a href="vfs.html">VFS</a> that stores all content in-memory. </p></li><li><p> <a href="https://www.sqlite.org/src/file/ext/misc/rot13.c">rot13.c</a> — -Implementation of a <a href="https://en.wikipedia.org/wiki/ROT13">rot13()</a> +Implementation of a <a href="https://en.wikipedia.org/wiki/ROT13">rot13()</a> SQL function. This is a very simple example of an extension function and is useful as a template for creating new extensions. </p></li><li><p> diff --git a/www/news.html b/www/news.html index 6e9fba3..8a058a6 100644 --- a/www/news.html +++ b/www/news.html @@ -119,7 +119,19 @@ antiRobotDefense(); <h2>Recent News</h2> -<a name="2024_04_15"></a><h3>2024-04-15 - <a href="releaselog/3_45_3.html">Version 3.45.3</a></h3><blockquote> +<a name="2024_05_23"></a><h3>2024-05-23 - <a href="releaselog/3_46_0.html">Version 3.46.0</a></h3><blockquote> +Version 3.46.0 is an enhancement release. Enhancements include: +<ul> +<li> Improvements to the <a href="pragma.html#pragma_optimize">PRAGMA optimize</a> command +<li> Enhancements to the <a href="lang_datefunc.html">date and time functions</a> +<li> The ability to put "_" between digits in numeric literals for readability +<li> Added the <a href="json1.html#jpretty">json_pretty()</a> function +<li> Improvements to the query planner, especially a new faster implementation + for VALUES clauses with many terms. +</ul> +<p> +None of these enhancements are critical. Update at your convenience. +</blockquote><hr width="50%"><a name="2024_04_15"></a><h3>2024-04-15 - <a href="releaselog/3_45_3.html">Version 3.45.3</a></h3><blockquote> Version 3.45.3 is a patch release that fixes a few obscure problems, including: <ul> @@ -852,5 +864,5 @@ the Firefox developers at Mozilla. The differences from version </blockquote><hr width="50%"> <a href="oldnews.html">Old news...</a> -<p align="center"><small><i>This page last modified on <a href="https://sqlite.org/docsrc/honeypot" id="mtimelink" data-href="https://sqlite.org/docsrc/finfo/pages/news.in?m=5d7fc0049c">2024-04-15 13:35:54</a> UTC </small></i></p> +<p align="center"><small><i>This page last modified on <a href="https://sqlite.org/docsrc/honeypot" id="mtimelink" data-href="https://sqlite.org/docsrc/finfo/pages/news.in?m=ab00e0d532">2024-05-22 19:07:18</a> UTC </small></i></p> diff --git a/www/opcode.html b/www/opcode.html index d24d2a6..a899048 100644 --- a/www/opcode.html +++ b/www/opcode.html @@ -172,6 +172,9 @@ about the bytecode engine change from one release of SQLite to the next. Applications that use SQLite should not depend on any of the details found in this document. +</p><p>See the document "<a href="whybytecode.html">Why SQLite Uses Bytecode</a>" for some reasons why +SQLite prefers to use bytecode to implement SQL. + </p><h1 id="introduction"><span>2. </span>Introduction</h1> @@ -217,8 +220,8 @@ output from SQLite, you should reference the version of this document that corresponds to the version of SQLite that ran the <a href="lang_explain.html">EXPLAIN</a>. Otherwise, the description of the opcodes may not be accurate. This document is derived from SQLite - version 3.45.3 check-in -<a href='https://www.sqlite.org/src/timeline?c=8653b758870e6'>8653b758870e6</a> dated 2024-04-15. + version 3.46.0 check-in +<a href='https://www.sqlite.org/src/timeline?c=96c92aba00c83'>96c92aba00c83</a> dated 2024-05-23. @@ -446,15 +449,15 @@ opcodes defined by the virtual machine. All currently defined opcodes are described in the table below. This table was generated automatically by scanning the source code from the file -<a href="https://www.sqlite.org/src/artifact/b2a45392265cb83f60251406039bf5255462d4a6d8deb05b2eaccab5abb2e20b">vdbe.c</a>. +<a href="https://www.sqlite.org/src/artifact/3b1793c5d2235ae89b01ef051a33d7d2ad3704c71799653b112686735ad401ff">vdbe.c</a>. </p><p>Remember: The VDBE opcodes are <u>not</u> part of the interface definition for SQLite. The number of opcodes and their names and meanings change from one release of SQLite to the next. The opcodes shown in the table below are valid for SQLite - version 3.45.3 check-in -<a href='https://www.sqlite.org/src/timeline?c=8653b758870e6'>8653b758870e6</a> dated 2024-04-15. + version 3.46.0 check-in +<a href='https://www.sqlite.org/src/timeline?c=96c92aba00c83'>96c92aba00c83</a> dated 2024-05-23. <a name="codes"></a> @@ -888,7 +891,9 @@ would have been false or NULL, then fall through.</td></tr> <a name="EndCoroutine"></a>EndCoroutine <td>The instruction at the address in register P1 is a <a href="opcode.html#Yield">Yield</a>. <a href="opcode.html#Jump">Jump</a> to the P2 parameter of that <a href="opcode.html#Yield">Yield</a>. -After the jump, register P1 becomes undefined.</p> +After the jump, the value register P1 is left with a value +such that subsequent OP_Yields go back to the this same +<a href="opcode.html#EndCoroutine">EndCoroutine</a> instruction.</p> <p>See also: <a href="opcode.html#InitCoroutine">InitCoroutine</a></td></tr> <tr><td valign="top" align="center"> @@ -1228,9 +1233,12 @@ value in P1 and jump to P2.</p> <p>If the initial value of register P1 is less than 1, then the value is unchanged and control passes through to the next instruction.</td></tr> <tr><td valign="top" align="center"> -<a name="IfSmaller"></a>IfSmaller -<td>Estimate the number of rows in the table P1. <a href="opcode.html#Jump">Jump</a> to P2 if that -estimate is less than approximately 2**(0.1*P3).</td></tr> +<a name="IfSizeBetween"></a>IfSizeBetween +<td>Let N be the approximate number of rows in the table or index +with cursor P1 and let X be 10*log2(N) if N is positive or -1 +if N is zero.</p> + +<p>Jump to P2 if X is in between P3 and P4, inclusive.</td></tr> <tr><td valign="top" align="center"> <a name="IncrVacuum"></a>IncrVacuum <td>Perform a single step of the incremental vacuum procedure on @@ -1313,11 +1321,11 @@ values.</td></tr> <tr><td valign="top" align="center"> <a name="IntegrityCk"></a>IntegrityCk <td>Do an analysis of the currently open database. Store in -register P1 the text of an error message describing any problems. -If no problems are found, store a NULL in register P1.</p> +register (P1+1) the text of an error message describing any problems. +If no problems are found, store a NULL in register (P1+1).</p> -<p>The register P3 contains one less than the maximum number of allowed errors. -At most reg(P3) errors will be reported. +<p>The register (P1) contains one less than the maximum number of allowed +errors. At most reg(P1) errors will be reported. In other words, the analysis stops as soon as reg(P1) errors are seen. Reg(P1) is updated with the number of errors remaining.</p> @@ -1727,7 +1735,8 @@ individual columns using the <a href="opcode.html#Column">Column</a> opcode. Th is the only cursor opcode that works with a pseudo-table.</p> <p>P3 is the number of fields in the records that will be stored by -the pseudo-table.</td></tr> +the pseudo-table. If P2 is 0 or negative then the pseudo-cursor +will return NULL for every column.</td></tr> <tr><td valign="top" align="center"> <a name="OpenRead"></a>OpenRead <td>Open a read-only cursor for the database table whose root page is @@ -1854,7 +1863,9 @@ number P5-1 in the prepared statement is incremented.</td></tr> <p>P1 contains the address of the memory cell that contains the first memory cell in an array of values used as arguments to the sub-program. P2 contains the address to jump to if the sub-program throws an IGNORE -exception using the RAISE() function. Register P3 contains the address +exception using the RAISE() function. P2 might be zero, if there is +no possibility that an IGNORE exception will be raised. +Register P3 contains the address of a memory cell in this (the parent) VM that is used to allocate the memory required by the sub-vdbe at runtime.</p> @@ -2414,9 +2425,15 @@ identified by P1, invoke this opcode to actually do the sorting. for Sorter objects.</td></tr> <tr><td valign="top" align="center"> <a name="SqlExec"></a>SqlExec -<td>Run the SQL statement or statements specified in the P4 string. -Disable Auth and <a href="opcode.html#Trace">Trace</a> callbacks while those statements are running if -P1 is true.</td></tr> +<td>Run the SQL statement or statements specified in the P4 string.</p> + +<p>The P1 parameter is a bitmask of options:</p> + +<p>0x0001 Disable Auth and <a href="opcode.html#Trace">Trace</a> callbacks while the statements +in P4 are running.</p> + +<p>0x0002 Set db->nAnalysisLimit to P2 while the statements in +P4 are running.</p></td></tr> <tr><td valign="top" align="center"> <a name="String"></a>String <td>The string value P4 of length P1 (bytes) is stored in register P2.</p> @@ -2525,10 +2542,7 @@ the file into which the result of vacuum should be written. When P2 is zero, the vacuum overwrites the original database.</td></tr> <tr><td valign="top" align="center"> <a name="Variable"></a>Variable -<td>Transfer the values of bound parameter P1 into register P2</p> - -<p>If the parameter is named, then its name appears in P4. -The P4 value is used by sqlite3_bind_parameter_name().</td></tr> +<td>Transfer the values of bound parameter P1 into register P2</td></tr> <tr><td valign="top" align="center"> <a name="VBegin"></a>VBegin <td>P4 may be a pointer to an sqlite3_vtab structure. If so, call the diff --git a/www/optoverview.html b/www/optoverview.html index 7a60a3b..313d78e 100644 --- a/www/optoverview.html +++ b/www/optoverview.html @@ -130,12 +130,14 @@ Table Of Contents <div class="fancy-toc2"><a href="#index_term_usage_examples">2.1. Index Term Usage Examples</a></div> <div class="fancy-toc1"><a href="#the_between_optimization">3. The BETWEEN Optimization</a></div> <div class="fancy-toc1"><a href="#or_optimizations">4. OR Optimizations</a></div> +<div class="fancy-toc2"><a href="#converting_or_connected_constraint_into_an_in_operator">4.1. Converting OR-connected constraint into an IN operator</a></div> +<div class="fancy-toc2"><a href="#evaluating_or_constraints_separately_and_taking_the_union_of_the_result">4.2. Evaluating OR constraints separately and taking the UNION of the result</a></div> <div class="fancy-toc1"><a href="#the_like_optimization">5. The LIKE Optimization</a></div> <div class="fancy-toc1"><a href="#the_skip_scan_optimization">6. The Skip-Scan Optimization</a></div> <div class="fancy-toc1"><a href="#joins">7. Joins</a></div> -<div class="fancy-toc2"><a href="#order_of_tables_in_a_join">7.1. Order of Tables in a Join</a></div> -<div class="fancy-toc2"><a href="#manual_control_of_query_plans_using_sqlite_stat_tables">7.2. Manual Control Of Query Plans Using SQLITE_STAT Tables</a></div> -<div class="fancy-toc2"><a href="#manual_control_of_query_plans_using_cross_join">7.3. Manual Control of Query Plans using CROSS JOIN</a></div> +<div class="fancy-toc2"><a href="#manual_control_of_join_order">7.1. Manual Control Of Join Order</a></div> +<div class="fancy-toc3"><a href="#manual_control_of_query_plans_using_sqlite_stat_tables">7.1.1. Manual Control Of Query Plans Using SQLITE_STAT Tables</a></div> +<div class="fancy-toc3"><a href="#manual_control_of_query_plans_using_cross_join">7.1.2. Manual Control of Query Plans using CROSS JOIN</a></div> <div class="fancy-toc1"><a href="#choosing_between_multiple_indexes">8. Choosing Between Multiple Indexes</a></div> <div class="fancy-toc2"><a href="#disqualifying_where_clause_terms_using_unary_">8.1. Disqualifying WHERE Clause Terms using Unary-"+"</a></div> <div class="fancy-toc2"><a href="#range_queries">8.2. Range Queries</a></div> @@ -146,9 +148,9 @@ Table Of Contents <div class="fancy-toc1"><a href="#subquery_co_routines">12. Subquery Co-routines</a></div> <div class="fancy-toc2"><a href="#using_co_routines_to_defer_work_until_after_the_sorting">12.1. Using Co-routines to Defer Work until after the Sorting</a></div> <div class="fancy-toc1"><a href="#the_min_max_optimization">13. The MIN/MAX Optimization</a></div> -<div class="fancy-toc1"><a href="#automatic_indexes">14. Automatic Indexes</a></div> +<div class="fancy-toc1"><a href="#automatic_query_time_indexes">14. Automatic Query-Time Indexes</a></div> <div class="fancy-toc2"><a href="#hash_joins">14.1. Hash Joins</a></div> -<div class="fancy-toc1"><a href="#the_push_down_optimization">15. The Push-Down Optimization</a></div> +<div class="fancy-toc1"><a href="#the_where_clause_push_down_optimization">15. The WHERE-Clause Push-Down Optimization</a></div> <div class="fancy-toc1"><a href="#the_outer_join_strength_reduction_optimization">16. The OUTER JOIN Strength Reduction Optimization</a></div> <div class="fancy-toc1"><a href="#the_omit_outer_join_optimization">17. The Omit OUTER JOIN Optimization</a></div> <div class="fancy-toc1"><a href="#the_constant_propagation_optimization">18. The Constant Propagation Optimization</a></div> @@ -190,29 +192,49 @@ mk.innerHTML = "►"; </p><p> Additional background information is available in the <a href="queryplanner.html">indexing tutorial</a> document. + The <a href="queryplanner-ng.html">Next Generation Query Planner</a> document provides more detail on + how the <a href="optoverview.html#joins">join order</a> is chosen. -</p><p> - With release 3.8.0 (2013-08-26), - the SQLite query planner was reimplemented as the - <a href="queryplanner-ng.html">Next Generation Query Planner</a> or "NGQP". All of the features, techniques, - and algorithms described in this document are applicable to both the - pre-3.8.0 legacy query planner and to the NGQP. For further information on - how the NGQP differs from the legacy query planner, see the - <a href="queryplanner-ng.html">detailed description of the NGQP</a>. +<a name="where_clause"></a> +</p><h1 id="where_clause_analysis"><span>2. </span>WHERE Clause Analysis</h1> +<p> + Prior to analysis, the following transformations are made + to shift all join constraints into the WHERE clause: -<a name="where_clause"></a> +</p><p> +</p><ul> +<li>All NATURAL joins are converted into joins with a USING clause. +</li><li>All USING clauses (including ones created by the previous step) + are converted into equivalent ON clauses. +</li><li>All ON clauses (include ones created by the previous step) + are added as new conjuncts (AND-connected terms) in the WHERE clause. +</li></ul> -</p><h1 id="where_clause_analysis"><span>2. </span>WHERE Clause Analysis</h1> <p> - The WHERE clause on a query is broken up into "terms" where each term - is separated from the others by an AND operator. + SQLite makes no distinction between join constraints that occur in the + WHERE clause and constraints in the ON clause of an inner join, since that + distinction does not affect the outcome. However, there is + a difference between ON clause constraints and WHERE clause constraints for + outer joins. Therefore, when SQLite moves an ON clause constraint from an + outer join over to the WHERE clause it adds special tags to the Abstract + Syntax Tree (AST) to indicate that the constraint came from an outer join + and from which outer join it came. There is no way to add those tags in + pure SQL text. Hence, the SQL input must use ON clauses on outer joins. + But in the internal AST, all constraints are part of the WHERE clause, + because having everything in one place simplifies processing. + +</p><p> + After all constraints have been shifted into the WHERE clause, + The WHERE clause is broken up into conjuncts (hereafter called + "terms"). In other words, the WHERE clause is broken up into pieces + separated from the others by an AND operator. If the WHERE clause is composed of constraints separated by the OR - operator then the entire clause is considered to be a single "term" + operator (disjuncts) then the entire clause is considered to be a single "term" to which the <a href="#or_opt">OR-clause optimization</a> is applied. </p><p> @@ -229,6 +251,7 @@ mk.innerHTML = "►"; </b><i>column</i><b> < </b><i>expression</i><b> </b><i>column</i><b> <= </b><i>expression</i><b> </b><i>expression</i><b> = </b><i>column</i><b> + </b><i>expression</i><b> IS </b><i>column</i><b> </b><i>expression</i><b> > </b><i>column</i><b> </b><i>expression</i><b> >= </b><i>column</i><b> </b><i>expression</i><b> < </b><i>column</i><b> @@ -369,6 +392,10 @@ mk.innerHTML = "►"; <p> WHERE clause constraints that are connected by OR instead of AND can be handled in two different ways. + +</p><h2 id="converting_or_connected_constraint_into_an_in_operator"><span>4.1. </span>Converting OR-connected constraint into an IN operator</h2> + +<p> If a term consists of multiple subterms containing a common column name and separated by OR, like this: @@ -388,7 +415,9 @@ mk.innerHTML = "►"; although the column can occur on either the left or the right side of the <b>=</b> operator. -</p><p> +</p><h2 id="evaluating_or_constraints_separately_and_taking_the_union_of_the_result"><span>4.2. </span>Evaluating OR constraints separately and taking the UNION of the result</h2> + +<p> If and only if the previously described conversion of OR to an IN operator does not work, the second OR-clause optimization is attempted. Suppose the OR clause consists of multiple subterms as follows: @@ -700,41 +729,7 @@ SELECT name FROM people WHERE role='student' AND height>=180; </p><h1 id="joins"><span>7. </span>Joins</h1> <p> - The ON and USING clauses of an inner join are converted into additional - terms of the WHERE clause prior to WHERE clause analysis described - <a href="#where_clause">above in paragraph 2.0</a>. - Thus with SQLite, there is no computational - advantage to use the newer SQL92 join syntax - over the older SQL89 comma-join syntax. They both end up accomplishing - exactly the same thing on inner joins. - -</p><p> - For an OUTER JOIN the situation is more complex. The following - two queries are not equivalent: - -</p><div class="codeblock"><pre>SELECT * FROM tab1 LEFT JOIN tab2 ON tab1.x=tab2.y; -SELECT * FROM tab1 LEFT JOIN tab2 WHERE tab1.x=tab2.y; -</pre></div> -<p> - For an inner join, the two queries above would be identical. However, - special processing applies to the ON and USING clauses of an OUTER join: - specifically, the constraints in an ON or USING clause do not apply if - the right table of the join is on a null row, but the constraints do apply - in the WHERE clause. The net effect is that putting the ON or USING - clause expressions for a LEFT JOIN in the WHERE clause effectively converts - the query to an - ordinary INNER JOIN - albeit an inner join that runs more slowly. - -<a name="table_order"></a> - -</p><h2 id="order_of_tables_in_a_join"><span>7.1. </span>Order of Tables in a Join</h2> - -<p> - The current implementation of - SQLite uses only loop joins. That is to say, joins are implemented as - nested loops. - -</p><p> + SQLite implements joins as nested loops. The default order of the nested loops in a join is for the left-most table in the FROM clause to form the outer loop and the right-most table to form the inner loop. @@ -742,10 +737,10 @@ SELECT * FROM tab1 LEFT JOIN tab2 WHERE tab1.x=tab2.y; will help it to select better indexes. </p><p> - Inner joins can be freely reordered. However a left outer join is + Inner joins can be freely reordered. However outer joins are neither commutative nor associative and hence will not be reordered. - Inner joins to the left and right of the outer join might be reordered - if the optimizer thinks that is advantageous but the outer joins are + Inner joins to the left and right of an outer join might be reordered + if the optimizer thinks that is advantageous but outer joins are always evaluated in the order in which they occur. </p><p> @@ -757,7 +752,8 @@ SELECT * FROM tab1 LEFT JOIN tab2 WHERE tab1.x=tab2.y; </p><p> When selecting the order of tables in a join, SQLite uses an efficient - polynomial-time algorithm. Because of this, + polynomial-time algorithm graph algorithm described in + the <a href="queryplanner-ng.html">Next Generation Query Planner</a> document. Because of this, SQLite is able to plan queries with 50- or 60-way joins in a matter of microseconds @@ -868,20 +864,40 @@ end a different choice might be made if the statistics indicate that the alternative is likely to run faster. +</p><h2 id="manual_control_of_join_order"><span>7.1. </span>Manual Control Of Join Order</h2> + +<p> + SQLite almost always picks the best join order automatically. It is + very rare that a developer needs to intervene to give the query planner + hints about the best join order. The best policy is to make use + of <a href="pragma.html#pragma_optimize">PRAGMA optimize</a> to ensure that the query planner has access to + up-to-date statistics on the shape of the data in the database. + +</p><p> + This section describes techniques by which developers can control the + join order in SQLite, to work around any performance problems that may + arise. However, the use of these techniques is not recommended, except + as a last resort. + +</p><p> + If you do encounter a situation where SQLite is picking a suboptimal + join order even after running <a href="pragma.html#pragma_optimize">PRAGMA optimize</a>, please report your + situation on the <a href="https://sqlite.org/forum">SQLite Community Forum</a> so + that the SQLite maintainers can make new refinements to the query planner + such that manual intervention is not required. + <a name="manctrl"></a> -</p><h2 id="manual_control_of_query_plans_using_sqlite_stat_tables"><span>7.2. </span>Manual Control Of Query Plans Using SQLITE_STAT Tables</h2> +</p><h3 id="manual_control_of_query_plans_using_sqlite_stat_tables"><span>7.1.1. </span>Manual Control Of Query Plans Using SQLITE_STAT Tables</h3> <p> SQLite provides the ability for advanced programmers to exercise control over the query plan chosen by the optimizer. One method for doing this - is to fudge the <a href="lang_analyze.html">ANALYZE</a> results in the <a href="fileformat2.html#stat1tab">sqlite_stat1</a>, - <a href="fileformat2.html#stat3tab">sqlite_stat3</a>, and/or <a href="fileformat2.html#stat4tab">sqlite_stat4</a> tables. This is not - recommended for most situations. + is to fudge the <a href="lang_analyze.html">ANALYZE</a> results in the <a href="fileformat2.html#stat1tab">sqlite_stat1</a> table. <a name="crossjoin"></a> -</p><h2 id="manual_control_of_query_plans_using_cross_join"><span>7.3. </span>Manual Control of Query Plans using CROSS JOIN</h2> +</p><h3 id="manual_control_of_query_plans_using_cross_join"><span>7.1.2. </span>Manual Control of Query Plans using CROSS JOIN</h3> <p> Programmers can force SQLite to use a particular loop nesting order @@ -991,6 +1007,15 @@ SELECT z FROM ex2 WHERE x=5 AND y=6; </p><h2 id="disqualifying_where_clause_terms_using_unary_"><span>8.1. </span>Disqualifying WHERE Clause Terms using Unary-"+"</h2> <p> + <i>Note: Disqualifying WHERE clause terms this way is not recommended. + This is a work-around. + Only do this as a last resort to get the performance you need. If you + find a situation where this work-around is necessary, please report the + situation on the <a href="https://sqlite.org/forum">SQLite Community Forum</a> so + that the SQLite maintainers can try to improve the query planner such + that the work-around is no longer required for your situation.</i> + +</p><p> Terms of the WHERE clause can be manually disqualified for use with indexes by prepending a unary <b>+</b> operator to the column name. The unary <b>+</b> is a no-op and will not generate any byte code in the prepared @@ -1140,8 +1165,10 @@ SELECT z FROM ex3 WHERE w=5 AND x BETWEEN 1 AND 100 AND y BETWEEN 1 AND 100; behavior is to evaluate the subquery into a transient table, then run the outer SELECT against the transient table. Such a plan can be suboptimal since the transient table will not have any indexes - and the outer query (which is likely a join) will be forced to do a - full table scan on the transient table. + and the outer query (which is likely a join) will be forced to either + do full table scan on the transient table or else construct a + <a href="optoverview.html#autoindex">query-time index</a> on the transient table, neither or which is likely + to be particularly fast. </p><p> To overcome this problem, SQLite attempts to flatten subqueries in @@ -1166,56 +1193,36 @@ SELECT z FROM ex3 WHERE w=5 AND x BETWEEN 1 AND 100 AND y BETWEEN 1 AND 100; </p><p> Casual readers are not expected to understand all of these rules. - A key take-away from this section is that the rules for determining - if query flatting is safe or unsafe are subtle and - complex. There have been multiple bugs over the years caused by + The point here is that flattening rules are subtle and complex. + There have been multiple bugs over the years caused by over-aggressive query flattening. On the other hand, performance of complex queries and/or queries involving views tends to suffer if query flattening is more conservative. </p><p> </p><ol> - <li value="1"> <i>(Obsolete. Query flattening is no longer - attempted for aggregate subqueries.)</i> - - </li><li value="2"> <i>(Obsolete. Query flattening is no longer - attempted for aggregate subqueries.)</i> - + <li value="1"> <i>(Obsolete)</i> + </li><li value="2"> <i>(Obsolete)</i> </li><li value="3"> If the subquery is the right operand of a LEFT JOIN then <ol type="a"><li> the subquery may not be a join, and </li><li> the FROM clause of the subquery may - not contain a virtual table, and - </li><li> the outer query may not be an aggregate.</li></ol></li> - - <li value="4"> The subquery is not DISTINCT. - - </li><li value="5"> <i>(Subsumed into constraint 4)</i> - - </li><li value="6"> <i>(Obsolete. Query flattening is no longer - attempted for aggregate subqueries.)</i> - - </li><li value="7"> - The subquery has a FROM clause. - - </li><li value="8"> - The subquery does not use LIMIT or the outer query is not a join. - - </li><li value="9"> - The subquery does not use LIMIT or the outer query does not use - aggregates. - - </li><li value="10"> <i>(Restriction relaxed in 2005)</i> - + not contain a virtual table, and + </li><li> the outer query may not be DISTINCT.</li></ol> + </li><li value="4"> The subquery is not DISTINCT. + </li><li value="5"> <i>(Obsolete - subsumed into constraint 4)</i> + </li><li value="6"> <i>(Obsolete)</i> + </li><li value="7"> The subquery has a FROM clause. + </li><li value="8"> The subquery does not use LIMIT or the outer query is + not a join. + </li><li value="9"> The subquery does not use LIMIT or the outer query + does not use aggregates. + </li><li value="10"> <i>(Obsolete)</i> </li><li value="11"> The subquery and the outer query do not both have ORDER BY clauses. - - </li><li value="12"> <i>(Subsumed into constraint 3)</i> - + </li><li value="12"> <i>(Obsolete - subsumed into constraint 3)</i> </li><li value="13"> The subquery and outer query do not both use LIMIT. - </li><li value="14"> The subquery does not use OFFSET. - </li><li value="15"> If the outer query is part of a compound select, then the subquery may not have a LIMIT clause. @@ -1231,7 +1238,13 @@ SELECT z FROM ex3 WHERE w=5 AND x BETWEEN 1 AND 100 AND y BETWEEN 1 AND 100; </li><li> no terms with the subquery compound may be aggregate or DISTINCT, and </li><li> every term within the subquery must have a FROM clause, and - </li><li> the outer query may not be an aggregate, DISTINCT query, or join. + </li><li> the outer query may not be an aggregateor DISTINCT query. + </li><li> the subquery may not contain window functions. + </li><li> the subquery must not be the right-hand side of a LEFT JOIN. + </li><li> either the subquery is the first element of the outer query + or there are not RIGHT or FULL JOINs in any arm of the subquery. + </li><li> the corresponding result set expressions in all arms of the + compound subquery must have the same <a href="datatype3.html#affinity">affinity</a>. </li></ol> The parent and sub-query may contain WHERE clauses. Subject to @@ -1257,10 +1270,24 @@ SELECT z FROM ex3 WHERE w=5 AND x BETWEEN 1 AND 100 AND y BETWEEN 1 AND 100; </li><li value="22"> The subquery may not be a recursive CTE. - </li><li value="23"> <i>(Subsumed into constraint 17d.)</i> + </li><li value="23"> If the outer query is a recursive CTE, then the sub-query + may not be a compound query. + + </li><li value="24"> <i>(Obsolete)</i> - </li><li value="24"> <i>(Obsolete. Query flattening is no longer - attempted for aggregate subqueries.)</i> + </li><li value="25"> Neither the subquery nor the outer query may contain + a <a href="windowfunctions.html">window function</a> in the result set nor the ORDER BY clause. + + </li><li value="26"> The subquery may not be the right operand of a RIGHT + or FULL OUTER JOIN. + </li><li value="27"> The subquery may not contain a FULL or RIGHT JOIN unless it + is the first element of the parent query. Two subcases: + <ol type="a"> + <li> the subquery is not a compound query. + </li><li> the subquery is a compound query and the RIGHT JOIN occurs + in any arm of the compound query. (See also (17g)). + </li></ol> + </li><li value="28"> The subquery is not a MATERIALIZED CTE. </li></ol> @@ -1273,15 +1300,19 @@ SELECT z FROM ex3 WHERE w=5 AND x BETWEEN 1 AND 100 AND y BETWEEN 1 AND 100; </p><h1 id="subquery_co_routines"><span>12. </span>Subquery Co-routines</h1> <p> - Prior to SQLite 3.7.15 (2012-12-12), - a subquery in the FROM clause would be - either flattened into the outer query, or else the subquery would be run - to completion - before the outer query started, the result set from the subquery - would be stored in a transient table, - and then the transient table would be used in the outer query. Newer - versions of SQLite have a third option, which is to implement the subquery - using a co-routine. + SQLite implements FROM-clause subqueries in one of three ways: + </p><ol> + <li> <a href="optoverview.html#flattening">Flatten</a> the subquery into its outer query + </li><li> Evaluate the subquery into a transient table that exists for + the duration of the one SQL statement that is being evaluated, + then run the outer query against that transient table. + </li><li> Evaluate the subquery in a co-routine that runs in parallel with + the outer query, providing rows to the outer query as needed. + </li></ol> + +<p> + This section describes the third technique: implementing the subquery + as a co-routine. </p><p> A co-routine is like a subroutine in that it runs in the same thread @@ -1374,13 +1405,14 @@ SELECT MAX(x)+1 FROM table; <a name="autoindex"></a> -<h1 id="automatic_indexes"><span>14. </span>Automatic Indexes</h1> +<h1 id="automatic_query_time_indexes"><span>14. </span>Automatic Query-Time Indexes</h1> <p> When no indexes are available to aid the evaluation of a query, SQLite might create an automatic index that lasts only for the duration of a single SQL statement. - Since the cost of constructing the automatic index is + Automatic indexes are also sometimes called "Query-time indexes". + Since the cost of constructing the automatic or query-time index is O(NlogN) (where N is the number of entries in the table) and the cost of doing a full table scan is only O(N), an automatic index will only be created if SQLite expects that the lookup will be run more than @@ -1401,7 +1433,7 @@ SELECT * FROM t1, t2 WHERE a=c; be the cheaper approach. </p><p> - An automatic index might also be used for a subquery: + An automatic query-time index might also be used for a subquery: </p><div class="codeblock"><pre>CREATE TABLE t1(a,b); CREATE TABLE t2(c,d); @@ -1447,7 +1479,7 @@ SELECT a, (SELECT d FROM t2 WHERE c=b) FROM t1; </p><h2 id="hash_joins"><span>14.1. </span>Hash Joins</h2> <p> - An automatic index is about the same thing as a + An automatic index is almost the same thing as a <a href="https://en.wikipedia.org/wiki/Hash_join">hash join</a>. The only difference is that a B-Tree is used instead of a hash table. If you are willing to say that the transient B-Tree constructed for an automatic index is @@ -1467,7 +1499,7 @@ SELECT a, (SELECT d FROM t2 WHERE c=b) FROM t1; <a name="pushdown"></a> -</p><h1 id="the_push_down_optimization"><span>15. </span>The Push-Down Optimization</h1> +</p><h1 id="the_where_clause_push_down_optimization"><span>15. </span>The WHERE-Clause Push-Down Optimization</h1> <p> If a subquery cannot be <a href="optoverview.html#flattening">flattened</a> into the outer query, it might @@ -1499,13 +1531,24 @@ SELECT x, y, b </pre></div> <p> - The push-down optimization cannot always be used. For example, + The WHERE-clause push-down optimization cannot always be used. For example, if the subquery contains a LIMIT, then pushing down any part of the WHERE clause from the outer query could change the result of the inner query. There are other restrictions, explained in a comment in the source code on the pushDownWhereTerms() routine that implements this optimization. +</p><p> + Do not confuse this optimization with the optimization by a similar name + in MySQL. The MySQL push-down optimization changes the order of evaluation + of WHERE-clause constraints such that those that can be evaluated using + only the index and without having to find the corresponding table row are + evaluated first, thus avoiding an unnecessary table row lookup if the + constraint fails. For disambiguation, SQLite calls this the + "MySQL push-down optimization". SQLite does do the MySQL push-down + optimization too, in addition to the WHERE-clause push-down optimization. + But the focus of this section is the WHERE-clause push-down optimization. + <a name="leftjoinreduction"></a> </p><h1 id="the_outer_join_strength_reduction_optimization"><span>16. </span>The OUTER JOIN Strength Reduction Optimization</h1> @@ -1629,5 +1672,5 @@ SELECT * FROM t1 WHERE a=b AND b=5; if those two constraints are true, then it must also be the case that "a=5" is true. This means that the desired row can be looked up quickly using a value of 5 for the INTEGER PRIMARY KEY. -</p><p align="center"><small><i>This page last modified on <a href="https://sqlite.org/docsrc/honeypot" id="mtimelink" data-href="https://sqlite.org/docsrc/finfo/pages/optoverview.in?m=cc5f8f396e">2024-04-10 13:05:44</a> UTC </small></i></p> +</p><p align="center"><small><i>This page last modified on <a href="https://sqlite.org/docsrc/honeypot" id="mtimelink" data-href="https://sqlite.org/docsrc/finfo/pages/optoverview.in?m=8909f126d6">2024-05-10 14:25:41</a> UTC </small></i></p> diff --git a/www/pragma.html b/www/pragma.html index 7af76f8..f17ac38 100644 --- a/www/pragma.html +++ b/www/pragma.html @@ -159,8 +159,8 @@ built-in PRAGMA statements.</p> <hr /><a name="syntax"></a> <h2>PRAGMA command syntax</h2> <p><b><a href="syntax/pragma-stmt.html">pragma-stmt:</a></b> -<button id='xd117fae3' onclick='hideorshow("xd117fae3","xa21fab4a")'>hide</button></p> - <div id='xa21fab4a' class='imgcontainer'> +<button id='x9d6dfba0' onclick='hideorshow("x9d6dfba0","x5f7c219f")'>hide</button></p> + <div id='x5f7c219f' class='imgcontainer'> <div style="max-width:824px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 824.352 99.576"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="32,17 20,21 20,12" style="fill:rgb(0,0,0)"/> @@ -214,8 +214,8 @@ built-in PRAGMA statements.</p> </svg> </div> <p><b><a href="syntax/pragma-value.html">pragma-value:</a></b> -<button id='xc2c54c29' onclick='hideorshow("xc2c54c29","xdbeedbf8")'>hide</button></p> - <div id='xdbeedbf8' class='imgcontainer'> +<button id='x87e7202d' onclick='hideorshow("x87e7202d","xf58fa64f")'>hide</button></p> + <div id='xf58fa64f' class='imgcontainer'> <div style="max-width:264px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 264.499 110.16"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="63,17 51,21 51,12" style="fill:rgb(0,0,0)"/> @@ -242,8 +242,8 @@ built-in PRAGMA statements.</p> </svg> </div> <p><b><a href="syntax/signed-number.html">signed-number:</a></b> -<button id='x8e288662' onclick='hideorshow("x8e288662","x58b8c58c")'>show</button></p> - <div id='x58b8c58c' style='display:none;' class='imgcontainer'> +<button id='x4c53ce39' onclick='hideorshow("x4c53ce39","x1fb8a275")'>show</button></p> + <div id='x1fb8a275' style='display:none;' class='imgcontainer'> <div style="max-width:292px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 292.013 99.576"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="50,44 39,48 39,40" style="fill:rgb(0,0,0)"/> @@ -479,13 +479,19 @@ for use in application programs.</ol></p> on large databases. The results of analysis are not as good when only part of each index is examined, but the results are usually good enough. Setting N to 100 or 1000 allows the - ANALYZE command to run very quickly, even on multi-gigabyte - database files. This pragma is particularly useful in combination - with <a href="pragma.html#pragma_optimize">PRAGMA optimize</a>. + ANALYZE command to run quickly, even on enormous + database files. <p>This pragma was added in SQLite version 3.32.0 (2020-05-22). The current implementation only uses the lower 31 bits of the N value - higher order bits are silently ignored. Future versions of SQLite might begin using higher order bits. + <p>Beginning with SQLite version 3.46.0 (2024-05-23), + the recommended way of running <a href="lang_analyze.html">ANALYZE</a> is with the + <a href="pragma.html#pragma_optimize">PRAGMA optimize</a> command. The <a href="pragma.html#pragma_optimize">PRAGMA optimize</a> will automatically + set a reasonable, temporary analysis limit that ensures that the + <a href="pragma.html#pragma_optimize">PRAGMA optimize</a> command will finish quickly even on enormous + databases. Applications that use the <a href="pragma.html#pragma_optimize">PRAGMA optimize</a> instead of + running <a href="lang_analyze.html">ANALYZE</a> directly do not need to set an analysis limit. <a name="pragma_application_id"></a> <h _id=pragma_application_id style="display:none"> PRAGMA application_id</h><hr> <p><b>PRAGMA </b><i>schema.</i><b>application_id; @@ -1481,74 +1487,93 @@ PRAGMA <b>main.</b>locking_mode=EXCLUSIVE; <p>Attempt to optimize the database. All schemas are optimized in the first two forms, and only the specified schema is optimized in the latter two.</p> - <p>To achieve the best long-term query performance without the need to - do a detailed engineering analysis of the application schema and SQL, - it is recommended that applications run "PRAGMA optimize" (with no arguments) - just before closing each <a href="c3ref/sqlite3.html">database connection</a>. Long-running applications - might also benefit from setting a timer to run "PRAGMA optimize" every - few hours. - </p> - <p>This pragma is usually a no-op or nearly so and is very fast. - However if SQLite feels - that performing database optimizations (such as running <a href="lang_analyze.html">ANALYZE</a> - or creating new indexes) will improve the performance of future queries, then - some database I/O may be done. Applications that want to limit the amount - of work performed can set a timer that will invoke - <a href="c3ref/interrupt.html">sqlite3_interrupt()</a> if the pragma goes on for too long. - Or, since SQLite 3.32.0, the application can use - <a href="pragma.html#pragma_analysis_limit">PRAGMA analysis_limit=<i>N</i></a> for some small - value of <i>N</i> (a few hundred or a few thousand) to limit the depth - of analyze. - </p> + <p>In most applications, using PRAGMA optimize as follows will help + SQLite to achieve the best possible query performance: + <ol> + <li><p> + Applications with short-lived database connections should run + "PRAGMA optimize;" once, just prior to closing each database connection. + + <li><p> + Applications that use long-lived database connections should run + "PRAGMA optimize=0x10002;" when the connection is first opened, and then + also run "PRAGMA optimize;" periodically, perhaps once per day or once + per hour. + + <li><p>All applications should run "PRAGMA optimize;" after a schema change, + especially after one or more <a href="lang_createindex.html">CREATE INDEX</a> statements. + </ol> + <p>This pragma is usually a no-op or nearly so and is very fast. On the + occasions where it does need to run ANALYZE on one or more tables, it + sets a temporary <a href="pragma.html#pragma_analysis_limit">analysis limit</a>, valid for the duration + of this pragma only, that prevents the ANALYZE invocations from running for + to long.</p> + <p>Recommended practice is that applications with short-lived database + connections should run "PRAGMA optimize" once when the database connection + closes. Applications with long-lived database connections should run + "PRAGMA optimize=0x10002" when the database connection first opens, then + run "PRAGMA optimize" again at periodic intervals - perhaps once per day. + All applications should run "PRAGMA optimize" after schema changes, especially + <a href="lang_createindex.html">CREATE INDEX</a>. </p> <p>The details of optimizations performed by this pragma are expected to change and improve over time. Applications should anticipate that this pragma will perform new optimizations in future releases.</p> <p>The optional MASK argument is a bitmask of optimizations to perform: - <ol> - <li value='1'><p> - Debugging mode. Do not actually perform any optimizations + + <table border=0 cellspacing=14 cellpadding=0> + <tr><td valign="top">0x00001 + <td>Debugging mode. Do not actually perform any optimizations but instead return one line of text for each optimization that would have been done. Off by default. - <li value='2'><p> - Run <a href="lang_analyze.html">ANALYZE</a> on tables that might benefit. On by default. - See below for additional information. - <li value='4'><p> - <em>(Not yet implemented)</em> - Record usage and performance - information from the current session in the - database file so that it will be available to "optimize" - pragmas run by future database connections. - <li value='8'><p> - <em>(Not yet implemented)</em> - Create indexes that might have been helpful to recent queries. - </ol> - <p>The default MASK is and always shall be 0xfffe. The 0xfffe mask means - perform all of the optimizations listed above except Debug Mode. If new - optimizations are added in the future that should be off by default, those - new optimizations will be given a mask of 0x10000 or larger.</p> + <tr><td valign="top">0x00002 + <td>Run <a href="lang_analyze.html">ANALYZE</a> on tables that might benefit. On by default.</dd> + <tr><td valign="top">0x00010 + <td>When running <a href="lang_analyze.html">ANALYZE</a>, set a temporary <a href="pragma.html#pragma_analysis_limit">PRAGMA analysis_limit</a> to + prevent excess run-time. On by default. + <tr><td valign="top">0x10000 + <td>Check the size of all tables, not just tables that have not been + recently used, to see if any have grown and shrunk significantly + and hence might + benefit from being re-analyzed. Off by default. + </table> + <p>The default MASK is 0xfffe.</p> <p>To see all optimizations that would have been done without actually - doing them, run "PRAGMA optimize(-1)". To use only the ANALYZE - optimization, run "PRAGMA optimize(0x02)".</p> + doing them, run "PRAGMA optimize(-1)".</p> <p><b>Determination Of When To Run Analyze</b></p> <p> In the current implementation, a table is analyzed if and only if all of the following are true: - <ul> - <li><p> + <ol> + <li> MASK bit 0x02 is set. - <li><p> - The query planner used <a href="fileformat2.html#stat1tab">sqlite_stat1</a>-style statistics for one or - more indexes of the table at some point during the lifetime of - the current connection. - <li><p> - One or more indexes of the table are currently unanalyzed <em>or</em> - the number of rows in the table has increased by 25 times or more - since the last time ANALYZE was run. - </ul> + <li> + The table is an ordinary table, not a view or virtual table. + <li> + The table name does not begin with "sqlite_". + <li> + One or more of the following are true: + <ol type="a"> + <li> The 0x10000 bit of MASK is set + <li> One or more indexes on the table lack entries in the sqlite_stat1 table. + <li> The query planner used sqlite_stat1 statistics for one or more indexes + of this table at some point during the lifetime of the current database + connection. + </ol> + <li> + One or more of the following are true: + <ol type="a"> + <li> One or more indexes on the table lack entries in the sqlite_stat1 table. + <li> The number of rows in the table has increased or decreased by 10-fold + since the last time ANALYZE was run on the table. + </ol> + </ol> <p> The rules for when tables are analyzed are likely to change in - future releases. + future releases. New MASK values may be added in the future. Future + versions of this pragma might accept a string literal argument instead + of a bit mask, though the bit mask argument will continue to be supported + for backwards compatibility. <a name="pragma_page_count"></a> <h _id=pragma_page_count style="display:none"> PRAGMA page_count</h><hr> <p><b>PRAGMA </b><i>schema.</i><b>page_count;</b></p> @@ -2278,5 +2303,5 @@ PRAGMA <b>main.</b>locking_mode=EXCLUSIVE; a <a href="howtocorrupt.html#cfgerr">corrupt database file</a>.</span> <hr> - +<p align="center"><small><i>This page last modified on <a href="https://sqlite.org/docsrc/honeypot" id="mtimelink" data-href="https://sqlite.org/docsrc/finfo/pages/pragma.in?m=c5681f40cb">2024-04-16 16:29:07</a> UTC </small></i></p> diff --git a/www/queryplanner-ng.html b/www/queryplanner-ng.html index b9d7593..69eee6c 100644 --- a/www/queryplanner-ng.html +++ b/www/queryplanner-ng.html @@ -177,7 +177,7 @@ of the problems inherent to query planning, and outlines how the NGQP solves those problems.</p> <p>The NGQP is almost always better than the legacy query planner. -However, there may exist legacy applications that unknowingly depend on +However, there may exist legacy applications that unknowingly depend on undefined and/or suboptimal behavior in the legacy query planner, and upgrading to the NGQP on those legacy applications could cause performance regressions. This risk is considered and a checklist is provided @@ -203,12 +203,12 @@ this multitude of possibilities.</p> (This is true of all SQL database engines, not just SQLite.) The query planner frees the programmer from the chore of selecting a particular query plan, and thereby allows the programmer to -focus more mental energy on higher-level application issues and on +focus more mental energy on higher-level application issues and on providing more value to the end user. For simple queries where the choice of query plan is obvious, this is convenient but not hugely important. But as applications and schemas and queries grow more complex, a clever query planner can greatly speed and simplify the work of application -development. +development. There is amazing power in being about to tell the database engine what content is desired, and then let the database engine figure out the best way to retrieve that content.</p> @@ -218,14 +218,14 @@ The query planner must work with incomplete information. It cannot determine how long any particular plan will take without actually running that plan. So when comparing two or more plans to figure out which is "best", the query planner has to make -some guesses and assumptions and those guesses and assumptions will +some guesses and assumptions and those guesses and assumptions will sometimes be wrong. A good query planner is one that will find the correct solution often enough that application programmers rarely need to get involved.</p> <h2 id="_query_planning_in_sqlite"><span>2.1. </span> Query Planning In SQLite</h2> -<p>SQLite computes joins using nested loops, +<p>SQLite computes joins using nested loops, one loop for each table in the join. (Additional loops might be inserted for IN and OR operators in the WHERE clause. SQLite considers those too, @@ -250,7 +250,7 @@ SQLite will always pick the same query plan for any given SQL statement as long as: </p><ol type="a"> -<li>the database schema does not change in significant ways such as +<li>the database schema does not change in significant ways such as adding or dropping indexes,</li> <li>the ANALYZE command is not rerun, </li> <li>the same version of SQLite is used.</li> @@ -263,22 +263,22 @@ invoking <a href="c3ref/db_config.html">sqlite3_db_config</a>(db,<a href="c3ref/ </p><p>The QPSG means that if all of your queries run efficiently during testing, and if your application does not change the schema, then SQLite will not suddenly decide to start using a different -query plan, possibly causing a performance problem after your application +query plan, possibly causing a performance problem after your application is released to users. If your application works in the lab, it will continue working the same way after deployment.</p> -<p>Enterprise-class client/server SQL database engines do not normally +<p>Client/server SQL database engines do not normally make this guarantee. In client/server SQL database engines, the server keeps track of -statistics on the sizes of tables and on the quality of indexes +statistics on the sizes of tables and on the quality of indexes and the query planner uses those statistics to help select the best plans. -As content is added, deleted, or changed in the database, the statistics -will evolve and may cause the query planner to begin using a different -query plan for some particular query. Usually the new plan will be better +As content is added, deleted, or changed in the database, the statistics +will evolve and may cause the query planner to begin using a different +query plan for some particular query. Usually the new plan will be better for the evolving structure of the data. But sometimes the new query plan will cause a performance reduction. With a client/server database engine, there -is typically a Database Administrator (DBA) on hand to deal with these -rare problems as they come up. But DBAs are not available to fix problems +is typically a Database Administrator (DBA) on hand to deal with these +rare problems as they come up. But DBAs are not available to fix problems in an embedded database like SQLite, and hence SQLite is careful to ensure that plans do not change unexpectedly after deployment.</p> @@ -287,22 +287,28 @@ changes in query plans. The same version of SQLite will always pick the same query plan, but if you relink your application to use a different version of SQLite, then query plans might change. In rare -cases, an SQLite version change might lead to a performance regression. +cases, an SQLite version change might lead to a performance regression. This is one reason -you should consider statically linking your applications against SQLite -rather than use a system-wide SQLite shared library which might +you should consider statically linking your applications against SQLite +rather than use a system-wide SQLite shared library which might change without your knowledge or control.</p> +<p>See also: +</p><ul> +<li> <a href="lang_analyze.html#req">Recommended usage patterns for ANALYZE</a> +</li><li> <a href="pragma.html#pragma_optimize">PRAGMA optimize</a> +</li></ul> + <h1 id="_a_difficult_case"><span>3. </span> A Difficult Case</h1> <p> "TPC-H Q8" is a test query from the <a href="http://www.tpc.org/tpch/">Transaction Processing Performance -Council</a>. The query planners in SQLite versions 3.7.17 and earlier -do not choose good plans for TPC-H Q8. And it has been determined that +Council</a>. The query planners in SQLite versions 3.7.17 and earlier +do not choose good plans for TPC-H Q8. And it has been determined that no amount of tweaking of the legacy query planner will fix that. In order to find -a good solution to the TPC-H Q8 query, and to continue improving the +a good solution to the TPC-H Q8 query, and to continue improving the quality of SQLite's query planner, it became necessary to redesign the query planner. This section tries to explain why this redesign was necessary and how the NGQP is different and addresses the TPC-H Q8 problem. @@ -427,7 +433,7 @@ by the following diagram: In the diagram, each of the 8 tables in the FROM clause of the query is identified by a large circle with the label of the FROM-clause term: N2, S, L, P, O, C, N1 and R. -The arcs in the graph represent the estimated cost of computing each term +The arcs in the graph represent the estimated cost of computing each term assuming that the origin of the arc is in an outer loop. For example, the cost of running the S loop as an inner loop to L is 2.30 whereas the cost of running the S loop as an outer loop to L is 9.17.</p> @@ -447,7 +453,7 @@ one of the other terms is in an outer loop, whichever gives the best result. One can think of the *-costs as a short-hand notation indicating multiple arcs, one from each of the other nodes in the graph. The graph is therefore "complete", meaning that there are arcs -(some explicit and some implied) in both directions between every pair of +(some explicit and some implied) in both directions between every pair of nodes in the graph.</p> <p>The problem of finding the best query plan is equivalent to finding @@ -475,7 +481,7 @@ shown in the graph. SQLite computes several different estimated costs for each loop that apply at different times. For example, there is a "setup" cost that is incurred just once when the query starts. The setup cost is the cost of computing -an <a href="optoverview.html#autoindex">automatic index</a> for a table that does not already +an <a href="optoverview.html#autoindex">query-time index</a> for a table that does not already have an index. Then there is the cost of running each step of the loop. Finally, there is an estimate of the number rows generated by the loop, which is information needed in @@ -491,9 +497,9 @@ since there is no way for an arc to originate at two or more nodes at once.</p> <p>If the query contains an ORDER BY clause or a GROUP BY clause or if -the query uses the DISTINCT keyword then it is advantageous to select a -path through the graph that causes rows to naturally appear in sorted order, -so that no separate sorting step is required. Automatic elimination of +the query uses the DISTINCT keyword then it is advantageous to select a +path through the graph that causes rows to naturally appear in sorted order, +so that no separate sorting step is required. Automatic elimination of ORDER BY clauses can make a large performance difference, so this is another factor that needs to be considered in a complete implementation.</p> @@ -510,7 +516,7 @@ is neglected in the remainder of this article.</p> <p>Prior to <a href="releaselog/3_8_0.html">version 3.8.0</a> (2013-08-26), SQLite always used the "Nearest Neighbor" or "NN" heuristic when searching for the best query plan. The NN heuristic makes a single traversal of the graph, always choosing -the lowest-cost arc as the next step. +the lowest-cost arc as the next step. The NN heuristic works surprisingly well in most cases. And NN is fast, so that SQLite is able to quickly find good plans for even large 64-way joins. In contrast, other SQL database engines that @@ -518,21 +524,21 @@ do more extensive searching tend to bog down when the number of tables in a join goes above 10 or 15.</p> <p>Unfortunately, the query plan computed by NN for TPC-H Q8 is not optimal. -The plan computed using NN is R-N1-N2-S-C-O-L-P with a cost of 36.92. +The plan computed using NN is R-N1-N2-S-C-O-L-P with a cost of 36.92. The notation in the previous sentence means that the R table is run in the outer loop, N1 is in the next inner loop, N2 is in the third loop, and so forth down to P which is in the inner-most loop. The shortest path through the graph (as found via exhaustive search) is P-L-O-C-N1-R-S-N2 -with a cost of 27.38. The difference might not seem like much, but +with a cost of 27.38. The difference might not seem like much, but remember that the costs are logarithmic, so the shortest path is nearly 750 times faster than that path found using the NN heuristic.</p> <p>One solution to this problem is to change SQLite to do an exhaustive -search for the best path. But an exhaustive search requires time +search for the best path. But an exhaustive search requires time proportional to -K! (where K is the number of tables in the join) and so when you get +K! (where K is the number of tables in the join) and so when you get beyond a 10-way join, the time to run <a href="c3ref/prepare.html">sqlite3_prepare()</a> becomes very large.</p> @@ -553,7 +559,7 @@ the four shortest paths to visit any single node in the graph: P (cost: 7.71) <br> </blockquote> -<p>The second step finds the four shortest paths to visit two nodes +<p>The second step finds the four shortest paths to visit two nodes beginning with one of the four paths from the previous step. In the case where two or more paths are equivalent (they have the same set of visited nodes, though possibly in a different order) only the @@ -576,21 +582,21 @@ the four shortest three-node paths:</p> R-N2-S (cost: 15.08) <br> </blockquote> -<p>And so forth. There are 8 nodes in the TPC-H Q8 query, +<p>And so forth. There are 8 nodes in the TPC-H Q8 query, so this process repeats a total of 8 times. In the general case of a K-way join, the storage requirement is O(N) and the computation time is O(K*N), which is significantly faster than the O(2<small><sup>K</sup></small>) exact solution.</p> <p>But what value to choose for N? One might try N=K. This makes the -algorithm O(K<small><sup>2</sup></small>) +algorithm O(K<small><sup>2</sup></small>) which is actually still quite efficient, since the -maximum value of K is 64 and K rarely exceeds 10. +maximum value of K is 64 and K rarely exceeds 10. But that is not enough for the TPC-H Q8 -problem. With N=8 on TPC-H Q8 the N3 algorithm finds -the solution R-N1-C-O-L-S-N2-P with a cost of 29.78. +problem. With N=8 on TPC-H Q8 the N3 algorithm finds +the solution R-N1-C-O-L-S-N2-P with a cost of 29.78. That is a big improvement over NN, but it is still -not optimal. N3 finds the optimal solution for TPC-H Q8 +not optimal. N3 finds the optimal solution for TPC-H Q8 when N is 10 or greater.</p> <p>The initial implementation of NGQP chooses N=1 for simple queries, N=5 @@ -601,30 +607,32 @@ formula for selecting N might change in subsequent releases.</p> <h1 id="_hazards_of_upgrading_to_ngqp"><span>4. </span> Hazards Of Upgrading To NGQP</h1> -<p><i>Update on 2018-11-24: This section was important -when the NGQP was new. But five years have elapsed, the NGQP has been -deployed successfully to billions of devices, and everyone has upgraded. -The upgrade hazard has vanished. +<p><i>→ Update: <b>This section is obsolete and retained for +historical reference only.</b> This section was important +when the NGQP was new. But a decade has elapsed, the NGQP has been +deployed successfully to billions of devices, and everyone has upgraded, +and no performance regressions were ever reported back to the SQLite +developers. The upgrade hazard has vanished. This section is retained for historical reference only. -Modern reads can skip ahead to the <a href="queryplanner-ng.html#howtofix">query planner checklist</a>.</i> +Modern readers can <b>skip ahead to the <a href="queryplanner-ng.html#howtofix">query planner checklist</a></b>.←</i> </p><p>For most applications, upgrading from the legacy query planner to the NGQP requires little thought or effort. -Simply replace the older SQLite version with the newer version of SQLite -and recompile and the application will run faster. +Simply replace the older SQLite version with the newer version of SQLite +and recompile and the application will run faster. There are no API changes nor modifications to compilation procedures.</p> <p>But as with any query planner change, upgrading to the NGQP does carry a small risk of introducing performance regressions. The problem here is not that the NGQP is incorrect or buggy or inferior to the legacy query -planner. Given reliable information about the selectivity of indexes, -the NGQP should always pick a plan that is as good or better than before. +planner. Given reliable information about the selectivity of indexes, +the NGQP should always pick a plan that is as good as before, or better. The problem is that some applications may be using low-quality and low-selectivity indexes without having run <a href="lang_analyze.html">ANALYZE</a>. The older query -planners look at many fewer possible implementations for each query and -so they may have stumbled over a good plan by stupid luck. The NGQP, on -the other hand, looks at many more query plan possibilities, and it may +planners look at many fewer possible implementations for each query and +so they may have stumbled over a good plan by stupid luck. The NGQP, on +the other hand, looks at many more query plan possibilities, and it may choose a different query plan that works better in theory, assuming good indexes, but which gives a performance regression in practice, because of the shape of the data.</p> @@ -635,7 +643,7 @@ regression in practice, because of the shape of the data.</p> <li><p>The NGQP will always find an equal or better query plan, compared to prior query planners, as long as it has access to accurate <a href="lang_analyze.html">ANALYZE</a> data in the <a href="fileformat2.html#stat1tab">SQLITE_STAT1</a> file.</p> -</li><li><p>The NGQP will always find a good query plan +</li><li><p>The NGQP will always find a good query plan as long as the schema does not contain indexes that have more than about 10 or 20 rows with the same value in the left-most column of the index.</p> @@ -654,7 +662,7 @@ control system used to track all of the SQLite source code. A Fossil repository is an SQLite database file. (Readers are invited to ponder this recursion as an independent exercise.) Fossil is both the version-control system for SQLite and a test -platform for SQLite. Whenever enhancements are made to SQLite, +platform for SQLite. Whenever enhancements are made to SQLite, Fossil is one of the first applications to test and evaluate those enhancements. So Fossil was an early adopter of the NGQP.</p> @@ -706,7 +714,7 @@ SELECT </pre></blockquote> <p>This query is not -especially complicated, but even so it replaces hundreds or +especially complicated, but even so it replaces hundreds or perhaps thousands of lines of procedural code. The gist of the query is this: Scan down the EVENT table looking for the most recent 200 check-ins that satisfy any one of three conditions: @@ -781,7 +789,7 @@ better mathematically. This is because, in the absence of other information, the NGQP must assume that the indexes PLINK_I1 and TAGXREF_I1 are of equal quality and are equally selective. Algorithm-2 uses one field of the TAGXREF_I1 index and both fields of the PLINK_I1 index whereas -algorithm-1 only uses the first field of each index. Since +algorithm-1 only uses the first field of each index. Since algorithm-2 uses more index material, the NGQP is correct to judge it to be the better algorithm. The scores are close and algorithm-2 just barely squeaks ahead of algorithm-1. But @@ -797,7 +805,7 @@ this application. The problem is that the indexes are not of equal quality. A check-in is likely to only have one child. So the first field of PLINK_I1 will usually narrow down the search to just a single -row. But there are thousands and thousands check-ins tagged with "trunk", +row. But there are thousands and thousands check-ins tagged with "trunk", so the first field of TAGXREF_I1 will be of little help in narrowing down the search. </p> @@ -806,7 +814,7 @@ of little help in narrowing down the search. The NGQP has no way of knowing that TAGXREF_I1 is almost useless in this query, unless <a href="lang_analyze.html">ANALYZE</a> has been run on the database. The <a href="lang_analyze.html">ANALYZE</a> command gathers statistics on the quality of the various indexes and stores those -statistics in <a href="fileformat2.html#stat1tab">SQLITE_STAT1</a> table. +statistics in <a href="fileformat2.html#stat1tab">SQLITE_STAT1</a> table. Having access to this statistical information, the NGQP easily chooses algorithm-1 as the best algorithm, by a wide margin.</p> @@ -865,10 +873,10 @@ problem look like this:</p> </center> <p> -In the "without ANALYZE" case on the left, the NN algorithm chooses +In the "without ANALYZE" case on the left, the NN algorithm chooses loop P (PLINK) as the outer loop because 4.9 is less than 5.2, resulting in path P-T which is algorithm-1. NN only looks at the single best choice -at each step so it completely misses the fact that +at each step so it completely misses the fact that 5.2+4.4 makes a slightly cheaper plan than 4.9+4.8. But the N3 algorithm keeps track of the 5 best paths for a 2-way join, so it ends up selecting path T-P because of its slightly lower overall cost. @@ -877,13 +885,13 @@ Path T-P is algorithm-2. <p> Note that with ANALYZE the cost estimates are -better aligned with reality and algorithm-1 is +better aligned with reality and algorithm-1 is selected by both NN and N3. </p> -<p>(Side note: The costs estimates in the two most recent graphs +<p>(Side note: The costs estimates in the two most recent graphs were computed by the NGQP using a base-2 logarithm and slightly different -cost assumptions compared to the legacy query planner. +cost assumptions compared to the legacy query planner. Hence, the cost estimates in these latter two graphs are not directly comparable to the cost estimates in the TPC-H Q8 graph.)</p> @@ -893,7 +901,7 @@ in the TPC-H Q8 graph.)</p> <p>Running <a href="lang_analyze.html">ANALYZE</a> on the repository database immediately fixed the performance problem. However, we want Fossil to be robust and to always work quickly regardless of whether or not its repository has been analyzed. -For this reason, the query was modified to use the CROSS JOIN operator +For this reason, the query was modified to use the CROSS JOIN operator instead of the plain JOIN operator. SQLite will not reorder the tables of a CROSS JOIN. This is a long-standing feature of SQLite that is specifically designed @@ -936,11 +944,11 @@ that hand-tuning of queries is no longer required. We have not had to tweak a query in Fossil in ages. </p><p>Therefore, the current recommendation for avoiding problems such -as this one is to simply run "PRAGMA optimize" (possibly preceded by -"<a href="pragma.html#pragma_analysis_limit">PRAGMA analysis_limit=200</a>") just prior to closing each database -connection. The CROSS JOIN hack is still available, but if you keep -the query planner statistics in the <a href="fileformat2.html#stat1tab">sqlite_stat1</a> table up-to-date, -it usually won't be necessary. +as this one is to simply run "PRAGMA optimize" just prior to closing +each database connection. Or, if your application is long-running and +never closes any database connections, then run "PRAGMA optimize" once +per day or so. Also consider running "PRAGMA optimize" after any +schema change. <a name="howtofix"></a> @@ -968,7 +976,7 @@ boolean or "enum" columns as the left-most columns of your indexes.</p> <p>The Fossil performance problem described in the previous section of this document arose because there were over -ten-thousand entries in the TAGXREF table with the same value for the +ten-thousand entries in the TAGXREF table with the same value for the left-most column (the TAGID column) of the TAGXREF_I1 index.</p> </li><li><p><b>If you must use a low-quality index, be sure to run <a href="lang_analyze.html">ANALYZE</a>.</b> @@ -977,9 +985,9 @@ query planner knows that the indexes are of low quality. And the way the query planner knows this is by the content of the <a href="fileformat2.html#stat1tab">SQLITE_STAT1</a> table, which is computed by the ANALYZE command.</p> -<p>Of course, ANALYZE only works effectively if you have a significant -amount of content in your database in the first place. When creating a -new database that you expect to accumulate a lot of data, you can run +<p>Of course, ANALYZE only works effectively if you have a significant +amount of content in your database in the first place. When creating a +new database that you expect to accumulate a lot of data, you can run the command "ANALYZE sqlite_schema" to create the SQLITE_STAT1 table, then prepopulate the <a href="fileformat2.html#stat1tab">sqlite_stat1</a> table (using ordinary INSERT statements) with content that describes a typical @@ -993,7 +1001,23 @@ needed to keep the <a href="fileformat2.html#stat1tab">sqlite_stat1</a> table cu Add logic that lets you know quickly and easily which queries are taking too much time. Then work on just those specific queries.</p> -</li><li><p><b>Use <a href="lang_corefunc.html#unlikely">unlikely()</a> and <a href="lang_corefunc.html#likelihood">likelihood()</a> SQL functions.</b> +<p> +</p><hr> +<i>Update 2024: The query planner has been improved so much over +the years that you should never need to use any of the +hacks described below. The capabilities described below are still +available, for backwards compatibility. But you shouldn't use +them. If you do find a case where you are getting a suboptimal query +plan, please report it to the SQLite developers on the +<a href="https://sqlite.org/forum">SQLite Forum</a> so that they can try to fix +the problem. In other words: +<p> +</p><center><b>Stop Reading Here!</b></center> +<p>To help encourage you to stop reading, the remainder of this checklist +is now grayed out. +</p><hr> + +</i></li><li><p style="color:grey;">Use <a href="lang_corefunc.html#unlikely">unlikely()</a> and <a href="lang_corefunc.html#likelihood">likelihood()</a> SQL functions. SQLite normally assumes that terms in the WHERE clause that cannot be used by indexes have a strong probability of being true. If this assumption is incorrect, it could lead to a suboptimal query plan. The @@ -1002,23 +1026,13 @@ hints to the query planner about WHERE clause terms that are probably not true, and thus aid the query planner in selecting the best possible plan. -</p></li><li><p><b>Use the <a href="optoverview.html#crossjoin">CROSS JOIN</a> syntax to enforce a particular +</p></li><li><p style="color:grey;">Use the <a href="optoverview.html#crossjoin">CROSS JOIN</a> syntax to enforce a particular loop nesting order on queries that might use low-quality indexes in an -unanalyzed database.</b> -SQLite <a href="lang_select.html#crossjoin">treats the CROSS JOIN operator specially</a>, forcing the table to +unanalyzed database. +SQLite <a href="lang_select.html#crossjoin">treats the CROSS JOIN operator specially</a>, forcing the table to the left to be an outer loop relative to the table on the right.</p> -<p>Avoid this step if possible, as it defeats one of the huge advantages -of the whole SQL language concept, specifically that the application -programmer does not need to get involved with query planning. If you -do use CROSS JOIN, wait until late in your development cycle to do so, -and comment the use of CROSS JOIN carefully so that you can take it out -later if possible. Avoid using CROSS JOIN early in the development -cycle as doing so is a premature optimization, which is well known to -be <a href="http://c2.com/cgi/wiki?PrematureOptimization">the root of -all evil</a>.</p> - -</li><li><p><b>Use unary "+" operators to disqualify WHERE clause terms.</b> +</li><li><p style="color:grey;">Use unary "+" operators to disqualify WHERE clause terms. If the query planner insists on selecting a poor-quality index for a particular query when a much higher-quality index is available, then <a href="optoverview.html#uplus">careful use of unary "+" operators</a> in the WHERE clause @@ -1026,12 +1040,12 @@ can force the query planner away from the poor-quality index. Avoid using this trick if at all possible, and especially avoid it early in the application development cycle. Beware that adding a unary "+" operator to an equality expression might change -the result of that expression if +the result of that expression if <a href="datatype3.html#affinity">type affinity</a> is involved.</p> -</li><li><p><b>Use the <a href="lang_indexedby.html">INDEXED BY</a> syntax to enforce the selection of -particular indexes on problem queries.</b> -As with the previous two bullets, avoid this step if possible, and +</li><li><p style="color:grey;">Use the <a href="lang_indexedby.html">INDEXED BY</a> syntax to enforce the selection of +particular indexes on problem queries. +As with the previous two bullets, avoid this step if possible, and especially avoid doing this early in development as it is clearly a premature optimization.</p> </li></ol> @@ -1039,7 +1053,7 @@ premature optimization.</p> <h1 id="_summary"><span>6. </span> Summary</h1> <p>The query planner in SQLite normally does a terrific job of selecting -fast algorithms for running your SQL statements. This is true of the +fast algorithms for running your SQL statements. This is true of the legacy query planner and even more true of the new NGQP. There may be an occasional situation where, due to incomplete information, the query planner selects a suboptimal plan. This will happen less often with the diff --git a/www/quirks.html b/www/quirks.html index 4e053e9..4ddc439 100644 --- a/www/quirks.html +++ b/www/quirks.html @@ -142,6 +142,7 @@ That Are Not In The GROUP BY Clause</a></div> <div class="fancy-toc1"><a href="#autoincrement_does_not_work_the_same_as_mysql">11. AUTOINCREMENT Does Not Work The Same As MySQL</a></div> <div class="fancy-toc1"><a href="#nul_characters_are_allowed_in_text_strings">12. NUL Characters Are Allowed In Text Strings</a></div> <div class="fancy-toc1"><a href="#sqlite_distinguishes_between_integer_and_text_literals">13. SQLite Distinguishes Between Integer And Text Literals</a></div> +<div class="fancy-toc1"><a href="#sqlite_gets_the_precedence_of_comma_joins_wrong">14. SQLite Gets The Precedence Of Comma-Joins Wrong</a></div> </div> </div> <script> @@ -464,7 +465,7 @@ that can be done using the same C-code as shown above except with the third parameter changed from 0 to 1. </p><p> As of SQLite 3.41.0 (2023-02-21) SQLITE_DBCONFIG_DQS_DDL and -SQLTIE_DBCONFIG_DQS_DML are disabled by default in the <a href="cli.html">CLI</a>. Use +SQLITE_DBCONFIG_DQS_DML are disabled by default in the <a href="cli.html">CLI</a>. Use the ".dbconfig" dot-command to reenable the legacy behavior if desired. @@ -545,5 +546,93 @@ See the "<a href="nulinstr.html">NUL characters in strings</a>" document for fur <p>It does this because an integer is not a string. Every other major SQL database engine says this is true, for reasons that the creator of SQLite does not understand. -</p> + +</p><h1 id="sqlite_gets_the_precedence_of_comma_joins_wrong"><span>14. </span>SQLite Gets The Precedence Of Comma-Joins Wrong</h1> + +<p>SQLite gives all join operators equal precedence and processes them +from left to right. But this is not quite correct. It should be that +comma-joins have lower precedence than all others join operators. +In other words, a FROM clause like this: + +</p><blockquote><p> +... FROM a, b RIGHT JOIN c, d ... +</p></blockquote> + +<p>This FROM clause should be parsed as follows: + +</p><div class="imgcontainer"> +<div style="max-width:153px;"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 153.328 245.544"> +<path d="M67,32L120,32L120,2L67,2Z" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<text x="93" y="17" text-anchor="middle" fill="rgb(0,0,0)" dominant-baseline="central">JOIN</text> +<polygon points="53,72 58,61 65,67" style="fill:rgb(0,0,0)"/> +<path d="M93,32L57,68" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<polygon points="134,72 122,67 128,61" style="fill:rgb(0,0,0)"/> +<path d="M93,32L129,68" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<path d="M27,102L80,102L80,72L27,72Z" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<text x="53" y="87" text-anchor="middle" fill="rgb(0,0,0)" dominant-baseline="central">JOIN</text> +<path d="M121,102L146,102L146,72L121,72Z" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<text x="134" y="87" text-anchor="middle" fill="rgb(0,0,0)" dominant-baseline="central">D</text> +<polygon points="13,142 18,131 24,137" style="fill:rgb(0,0,0)"/> +<path d="M53,102L17,138" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<polygon points="93,142 82,137 88,131" style="fill:rgb(0,0,0)"/> +<path d="M53,102L89,138" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<path d="M36,173L151,173L151,142L36,142Z" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<text x="93" y="157" text-anchor="middle" fill="rgb(0,0,0)" dominant-baseline="central">RIGHT JOIN</text> +<path d="M2,173L25,173L25,142L2,142Z" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<text x="13" y="157" text-anchor="middle" fill="rgb(0,0,0)" dominant-baseline="central">A</text> +<polygon points="53,213 58,201 65,208" style="fill:rgb(0,0,0)"/> +<path d="M93,173L57,209" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<polygon points="134,213 122,208 128,201" style="fill:rgb(0,0,0)"/> +<path d="M93,173L129,209" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<path d="M42,243L65,243L65,213L42,213Z" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<text x="53" y="228" text-anchor="middle" fill="rgb(0,0,0)" dominant-baseline="central">B</text> +<path d="M121,243L146,243L146,213L121,213Z" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<text x="134" y="228" text-anchor="middle" fill="rgb(0,0,0)" dominant-baseline="central">C</text> +</svg> +</div> +</div> + +<p>But SQLite instead parses the FROM clause like this: + +</p><div class="imgcontainer"> +<div style="max-width:188px;"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 188.691 245.544"> +<path d="M107,32L160,32L160,2L107,2Z" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<text x="134" y="17" text-anchor="middle" fill="rgb(0,0,0)" dominant-baseline="central">JOIN</text> +<polygon points="93,72 99,61 105,67" style="fill:rgb(0,0,0)"/> +<path d="M134,32L98,68" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<polygon points="174,72 162,67 169,61" style="fill:rgb(0,0,0)"/> +<path d="M134,32L170,68" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<path d="M36,102L151,102L151,72L36,72Z" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<text x="93" y="87" text-anchor="middle" fill="rgb(0,0,0)" dominant-baseline="central">RIGHT JOIN</text> +<path d="M161,102L186,102L186,72L161,72Z" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<text x="174" y="87" text-anchor="middle" fill="rgb(0,0,0)" dominant-baseline="central">D</text> +<polygon points="53,142 58,131 65,137" style="fill:rgb(0,0,0)"/> +<path d="M93,102L57,138" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<polygon points="134,142 122,137 128,131" style="fill:rgb(0,0,0)"/> +<path d="M93,102L129,138" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<path d="M27,173L80,173L80,142L27,142Z" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<text x="53" y="157" text-anchor="middle" fill="rgb(0,0,0)" dominant-baseline="central">JOIN</text> +<path d="M121,173L146,173L146,142L121,142Z" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<text x="134" y="157" text-anchor="middle" fill="rgb(0,0,0)" dominant-baseline="central">C</text> +<polygon points="13,213 18,201 24,208" style="fill:rgb(0,0,0)"/> +<path d="M53,173L17,209" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<polygon points="93,213 82,208 88,201" style="fill:rgb(0,0,0)"/> +<path d="M53,173L89,209" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<path d="M2,243L25,243L25,213L2,213Z" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<text x="13" y="228" text-anchor="middle" fill="rgb(0,0,0)" dominant-baseline="central">A</text> +<path d="M82,243L105,243L105,213L82,213Z" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<text x="93" y="228" text-anchor="middle" fill="rgb(0,0,0)" dominant-baseline="central">B</text> +</svg> +</div> +</div> + +<p>The problem can only makes a difference in the result when using +RIGHT OUTER JOIN or FULL OUTER JOIN in the same FROM clause with +comma-joins, which rarely happens in practice. And +the problem can be easily overcome using parentheses in the FROM clause: + +</p><blockquote><p> +... FROM a, (b RIGHT JOIN c), d ... +</p></blockquote> +<p align="center"><small><i>This page last modified on <a href="https://sqlite.org/docsrc/honeypot" id="mtimelink" data-href="https://sqlite.org/docsrc/finfo/pages/quirks.in?m=e04aef4f57">2024-05-22 18:42:01</a> UTC </small></i></p> diff --git a/www/releaselog/3_13_0.html b/www/releaselog/3_13_0.html index 5490946..a197c7b 100644 --- a/www/releaselog/3_13_0.html +++ b/www/releaselog/3_13_0.html @@ -144,7 +144,7 @@ antiRobotDefense(); the table has one or more indexes that are able to trigger the OR optimization, but none of the indexes reference any table columns other than the INTEGER PRIMARY KEY. Ticket <a href="https://www.sqlite.org/src/info/16c9801ceba49">16c9801ceba49</a>. -<li>When checking for the WHERE-clause push-down optimization, verify that all terms +<li>When checking for the <a href="../optoverview.html#pushdown">WHERE-clause push-down optimization</a>, verify that all terms of the compound inner SELECT are non-aggregate, not just the last term. Fix for ticket <a href="https://www.sqlite.org/src/info/f7f8c97e97597">f7f8c97e97597</a>. <li>Fix a locking race condition in Windows that can occur when two or more processes diff --git a/www/releaselog/3_42_0.html b/www/releaselog/3_42_0.html index e5f5543..661ed3a 100644 --- a/www/releaselog/3_42_0.html +++ b/www/releaselog/3_42_0.html @@ -127,7 +127,7 @@ antiRobotDefense(); <ol type="a"> <li> Enable the "count-of-view" optimization by default. <li> Avoid computing unused columns in subqueries. - <li> Improvements to the <a href="../optoverview.html#pushdown">push-down optimization</a>. + <li> Improvements to the <a href="../optoverview.html#pushdown">WHERE-clause push-down optimization</a>. </ol> <li> Enhancements to the <a href="../cli.html">CLI</a>: <ol type="a"> diff --git a/www/releaselog/3_46_0.html b/www/releaselog/3_46_0.html new file mode 100644 index 0000000..5996306 --- /dev/null +++ b/www/releaselog/3_46_0.html @@ -0,0 +1,175 @@ +<!DOCTYPE html> +<html><head> +<meta name="viewport" content="width=device-width, initial-scale=1.0"> +<meta http-equiv="content-type" content="text/html; charset=UTF-8"> +<link href="../sqlite.css" rel="stylesheet"> +<title>SQLite Release 3.46.0 On 2024-05-23</title> +<!-- path=../ --> +</head> +<body> +<div class=nosearch> +<a href="../index.html"> +<img class="logo" src="../images/sqlite370_banner.gif" alt="SQLite" border="0"> +</a> +<div><!-- IE hack to prevent disappearing logo --></div> +<div class="tagline desktoponly"> +Small. Fast. Reliable.<br>Choose any three. +</div> +<div class="menu mainmenu"> +<ul> +<li><a href="../index.html">Home</a> +<li class='mobileonly'><a href="javascript:void(0)" onclick='toggle_div("submenu")'>Menu</a> +<li class='wideonly'><a href='../about.html'>About</a> +<li class='desktoponly'><a href="../docs.html">Documentation</a> +<li class='desktoponly'><a href="../download.html">Download</a> +<li class='wideonly'><a href='../copyright.html'>License</a> +<li class='desktoponly'><a href="../support.html">Support</a> +<li class='desktoponly'><a href="../prosupport.html">Purchase</a> +<li class='search' id='search_menubutton'> +<a href="javascript:void(0)" onclick='toggle_search()'>Search</a> +</ul> +</div> +<div class="menu submenu" id="submenu"> +<ul> +<li><a href='../about.html'>About</a> +<li><a href='../docs.html'>Documentation</a> +<li><a href='../download.html'>Download</a> +<li><a href='../support.html'>Support</a> +<li><a href='../prosupport.html'>Purchase</a> +</ul> +</div> +<div class="searchmenu" id="searchmenu"> +<form method="GET" action="../search"> +<select name="s" id="searchtype"> +<option value="d">Search Documentation</option> +<option value="c">Search Changelog</option> +</select> +<input type="text" name="q" id="searchbox" value=""> +<input type="submit" value="Go"> +</form> +</div> +</div> +<script> +function toggle_div(nm) { +var w = document.getElementById(nm); +if( w.style.display=="block" ){ +w.style.display = "none"; +}else{ +w.style.display = "block"; +} +} +function toggle_search() { +var w = document.getElementById("searchmenu"); +if( w.style.display=="block" ){ +w.style.display = "none"; +} else { +w.style.display = "block"; +setTimeout(function(){ +document.getElementById("searchbox").focus() +}, 30); +} +} +function div_off(nm){document.getElementById(nm).style.display="none";} +window.onbeforeunload = function(e){div_off("submenu");} +/* Disable the Search feature if we are not operating from CGI, since */ +/* Search is accomplished using CGI and will not work without it. */ +if( !location.origin || !location.origin.match || !location.origin.match(/http/) ){ +document.getElementById("search_menubutton").style.display = "none"; +} +/* Used by the Hide/Show button beside syntax diagrams, to toggle the */ +function hideorshow(btn,obj){ +var x = document.getElementById(obj); +var b = document.getElementById(btn); +if( x.style.display!='none' ){ +x.style.display = 'none'; +b.innerHTML='show'; +}else{ +x.style.display = ''; +b.innerHTML='hide'; +} +return false; +} +var antiRobot = 0; +function antiRobotGo(){ +if( antiRobot!=3 ) return; +antiRobot = 7; +var j = document.getElementById("mtimelink"); +if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); +} +function antiRobotDefense(){ +document.body.onmousedown=function(){ +antiRobot |= 2; +antiRobotGo(); +document.body.onmousedown=null; +} +document.body.onmousemove=function(){ +antiRobot |= 2; +antiRobotGo(); +document.body.onmousemove=null; +} +setTimeout(function(){ +antiRobot |= 1; +antiRobotGo(); +}, 100) +antiRobotGo(); +} +antiRobotDefense(); +</script> +<h2>SQLite Release 3.46.0 On 2024-05-23</h2><p><ol class='lessindent'> +<li> Enhance <a href="../pragma.html#pragma_optimize">PRAGMA optimize</a> in multiple ways, to make it + <a href="../lang_analyze.html#pragopt">simpler to use</a>: + <ol type="a"> + <li> PRAGMA optimize automatically implements a temporary + <a href="../pragma.html#pragma_analysis_limit">analysis limit</a> to prevent excess runtime + on large databases. + <li> Added the new 0x10000 bitmask option to check for updates on all tables. + <li> Automatically re-analyze tables that do not have sqlite_stat1 entries. + </ol> +<li> Enhancements to the <a href="../lang_datefunc.html">date and time functions</a>: + <ol type="a"> + <li> The <a href="../lang_datefunc.html#strftm">strftime() SQL function</a> now supports %G, %g, %U, and %V. + <li> New modifiers 'ceiling' and 'floor' control the algorithm used to + resolve <a href="../lang_datefunc.html#dtambg">ambiguous dates</a> when shifting a date by an integer number + of months and/or years. + <li> The <a href="../lang_datefunc.html#localtime">'utc' and 'localtime' modifiers</a> are now no-ops if SQLite knows + that the time is already in UTC or in the localtime, respectively. + </ol> +<li> Add support for underscore ("_") characters between digits in + <a href="../lang_expr.html#litvalue">numeric literals</a>. +<li> Add the <a href="../json1.html#jpretty">json_pretty()</a> SQL function. +<li> Query planner improvements: + <ol type="a"> + <li> The "VALUES-as-coroutine" optimization enables INSERT statements with + thousands of rows in the VALUES clause to parse and run in about half + the time and using about half as much memory. + <li> Allow the use of an index for queries like "SELECT count(DISTINCT col) FROM ...", + even if the index records are not smaller than the table records. + <li> Improved recognition of cases where the value of an SQL function is + constant because all its arguments are constant. + <li> Enhance the <a href="../optoverview.html#pushdown">WHERE-clause push-down optimization</a> so that it is able to + push down WHERE clause terms containing uncorrelated subqueries. + </ol> +<li> Allocate additional memory from the heap for the SQL parser stack if + that stack overflows, rather than reporting a "parser stack overflow" error. +<li> JSON changes: + <ol type="a"> + <li> Allow ASCII control characters within JSON5 string literals. + <li> Fix <a href="../json1.html#jptr">the -> and ->> operators</a> so that when the right-hand side operand is a string + that looks like an integer it is still treated as a string, because that is what + PostgreSQL does. + </ol> +<li> Allow large hexadecimal literals to be used as the DEFAULT value to a table column. +<p><b>Hashes:</b> +<li>SQLITE_SOURCE_ID: 2024-05-23 13:25:27 96c92aba00c8375bc32fafcdf12429c58bd8aabfcadab6683e35bbb9cdebf19e +<li>SHA3-256 for sqlite3.c: 094429ea827fcd32275e767134bc6c7b9ea394a2c5a9e653dd0a0690b2c11358 + +</ol></p> + + <p>A <a href="../changes.html">complete list of SQLite releases</a> + in a single page and a <a href="../chronology.html">chronology</a> are both also available. + A detailed history of every + check-in is available at + <a href="https://www.sqlite.org/src/timeline"> + SQLite version control site</a>.</p> + + diff --git a/www/releaselog/3_9_0.html b/www/releaselog/3_9_0.html index 6a2127e..a1556ca 100644 --- a/www/releaselog/3_9_0.html +++ b/www/releaselog/3_9_0.html @@ -156,7 +156,7 @@ antiRobotDefense(); <a href="../c3ref/initialize.html">sqlite3_initialize()</a> to help ensure that it is thread-safe. <li>Fix the <a href="../optoverview.html#or_opt">OR optimization</a> so that it always ignores subplans that do not use an index. -<li>Do not apply the WHERE-clause pushdown optimization on terms that originate +<li>Do not apply the <a href="../optoverview.html#pushdown">WHERE-clause push-down optimization</a> on terms that originate in the ON or USING clause of a LEFT JOIN. Fix for ticket <a href="https://www.sqlite.org/src/info/c2a19d81652f40568c">c2a19d81652f40568c</a>. diff --git a/www/releaselog/3_9_1.html b/www/releaselog/3_9_1.html index ead1a50..f272bac 100644 --- a/www/releaselog/3_9_1.html +++ b/www/releaselog/3_9_1.html @@ -157,7 +157,7 @@ antiRobotDefense(); <a href="../c3ref/initialize.html">sqlite3_initialize()</a> to help ensure that it is thread-safe. <li>Fix the <a href="../optoverview.html#or_opt">OR optimization</a> so that it always ignores subplans that do not use an index. -<li>Do not apply the WHERE-clause pushdown optimization on terms that originate +<li>Do not apply the <a href="../optoverview.html#pushdown">WHERE-clause push-down optimization</a> on terms that originate in the ON or USING clause of a LEFT JOIN. Fix for ticket <a href="https://www.sqlite.org/src/info/c2a19d81652f40568c">c2a19d81652f40568c</a>. diff --git a/www/releaselog/3_9_2.html b/www/releaselog/3_9_2.html index dafeab9..54f6233 100644 --- a/www/releaselog/3_9_2.html +++ b/www/releaselog/3_9_2.html @@ -157,7 +157,7 @@ antiRobotDefense(); <a href="../c3ref/initialize.html">sqlite3_initialize()</a> to help ensure that it is thread-safe. <li>Fix the <a href="../optoverview.html#or_opt">OR optimization</a> so that it always ignores subplans that do not use an index. -<li>Do not apply the WHERE-clause pushdown optimization on terms that originate +<li>Do not apply the <a href="../optoverview.html#pushdown">WHERE-clause push-down optimization</a> on terms that originate in the ON or USING clause of a LEFT JOIN. Fix for ticket <a href="https://www.sqlite.org/src/info/c2a19d81652f40568c">c2a19d81652f40568c</a>. diff --git a/www/releaselog/3_9_3.html b/www/releaselog/3_9_3.html index f354dd4..f228776 100644 --- a/www/releaselog/3_9_3.html +++ b/www/releaselog/3_9_3.html @@ -157,7 +157,7 @@ antiRobotDefense(); <a href="../c3ref/initialize.html">sqlite3_initialize()</a> to help ensure that it is thread-safe. <li>Fix the <a href="../optoverview.html#or_opt">OR optimization</a> so that it always ignores subplans that do not use an index. -<li>Do not apply the WHERE-clause pushdown optimization on terms that originate +<li>Do not apply the <a href="../optoverview.html#pushdown">WHERE-clause push-down optimization</a> on terms that originate in the ON or USING clause of a LEFT JOIN. Fix for ticket <a href="https://www.sqlite.org/src/info/c2a19d81652f40568c">c2a19d81652f40568c</a>. diff --git a/www/releaselog/current.html b/www/releaselog/current.html index 4e6d9e3..5996306 100644 --- a/www/releaselog/current.html +++ b/www/releaselog/current.html @@ -3,7 +3,7 @@ <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> <link href="../sqlite.css" rel="stylesheet"> -<title>SQLite Release 3.45.3 On 2024-04-15</title> +<title>SQLite Release 3.46.0 On 2024-05-23</title> <!-- path=../ --> </head> <body> @@ -115,106 +115,53 @@ antiRobotGo(); } antiRobotDefense(); </script> -<h2>SQLite Release 3.45.3 On 2024-04-15</h2><p><b>Prior changes from version 3.45.0 (2024-01-15):</b></p> -<p><ol class='lessindent'> -<li value='1'> Added the <a href="../c3ref/c_deterministic.html#sqliteresultsubtype">SQLITE_RESULT_SUBTYPE</a> property for - <a href="../appfunc.html">application-defined SQL functions</a>. - All application defined SQL functions that invokes - <a href="../c3ref/result_subtype.html">sqlite3_result_subtype()</a> must be registered with this new property. - Failure to do so might cause the call to sqlite3_result_subtype() to - behave as a no-op. Compile with <a href="../compile.html#strict_subtype">-DSQLITE_STRICT_SUBTYPE=1</a> to cause an - SQL error to be raised if a function that is not <a href="../c3ref/c_deterministic.html#sqliteresultsubtype">SQLITE_RESULT_SUBTYPE</a> - tries invokes <a href="../c3ref/result_subtype.html">sqlite3_result_subtype()</a>. The use of <a href="../compile.html#strict_subtype">-DSQLITE_STRICT_SUBTYPE=1</a> - is a recommended compile-time option for every application that makes - use of subtypes. -<li> Enhancements to the <a href="../json1.html">JSON SQL functions</a>: - <ol type="a"> - <li> All JSON functions are rewritten to use a new internal parse tree - format called <a href="../json1.html#jsonbx">JSONB</a>. The new parse-tree format is serializable - and hence can be stored in the database to avoid unnecessary re-parsing - whenever the JSON value is used. - <li> New versions of JSON-generating functions generate binary JSONB instead - of JSON text. - <li> The <a href="../json1.html#jvalid">json_valid()</a> function adds an optional second argument that - specifies what it means for the first argument to be "well-formed". - </ol> -<li> Add the <a href="../fts5.html#the_tokendata_option">FTS5 tokendata option</a> to the <a href="../fts5.html">FTS5</a> virtual table. -<li> The <a href="../compile.html#direct_overflow_read">SQLITE_DIRECT_OVERFLOW_READ</a> optimization is now enabled by default. - Disable it at compile-time using -DSQLITE_DIRECT_OVERFLOW_READ=0. -<li> Query planner improvements: +<h2>SQLite Release 3.46.0 On 2024-05-23</h2><p><ol class='lessindent'> +<li> Enhance <a href="../pragma.html#pragma_optimize">PRAGMA optimize</a> in multiple ways, to make it + <a href="../lang_analyze.html#pragopt">simpler to use</a>: <ol type="a"> - <li> Do not allow the transitive constraint optimization to trick the - query planner into using a range constraint when a better equality - constraint is available. - (<a href="https://sqlite.org/forum/forumpost/2568d1f6e6">Forum post 2568d1f6e6</a>.) - <li> The query planner now does a better job of disregarding - indexes that <a href="../lang_analyze.html">ANALYZE</a> identifies as low-quality. - (<a href="https://sqlite.org/forum/forumpost/6f0958b03b">Forum post 6f0958b03b</a>.) + <li> PRAGMA optimize automatically implements a temporary + <a href="../pragma.html#pragma_analysis_limit">analysis limit</a> to prevent excess runtime + on large databases. + <li> Added the new 0x10000 bitmask option to check for updates on all tables. + <li> Automatically re-analyze tables that do not have sqlite_stat1 entries. </ol> -<li> Increase the default value for <a href="../limits.html#max_page_count">SQLITE_MAX_PAGE_COUNT</a> from 1073741824 to - 4294967294. -<li> Enhancements to the <a href="../cli.html">CLI</a>: +<li> Enhancements to the <a href="../lang_datefunc.html">date and time functions</a>: <ol type="a"> - <li> Improvements to the display of UTF-8 content on Windows - <li> Automatically detect playback of ".dump" scripts and make appropriate - changes to settings such as ".dbconfig defensive off" and - ".dbconfig dqs_dll on". + <li> The <a href="../lang_datefunc.html#strftm">strftime() SQL function</a> now supports %G, %g, %U, and %V. + <li> New modifiers 'ceiling' and 'floor' control the algorithm used to + resolve <a href="../lang_datefunc.html#dtambg">ambiguous dates</a> when shifting a date by an integer number + of months and/or years. + <li> The <a href="../lang_datefunc.html#localtime">'utc' and 'localtime' modifiers</a> are now no-ops if SQLite knows + that the time is already in UTC or in the localtime, respectively. </ol> -</ol> -<p><b>Prior changes from version 3.45.1 (2024-01-30):</b></p> -<p><ol class='lessindent'> -<li value='8'> Restore the <a href="../json1.html#jblobbug">JSON BLOB input bug</a>, and promise to support the anomaly in - subsequent releases, for backward compatibility. -<li> Fix the <a href="../pragma.html#pragma_integrity_check">PRAGMA integrity_check</a> command so that it works on read-only - databases that contain FTS3 and FTS5 tables. This resolves an issue - introduced in <a href="../releaselog/3_44_0.html">version 3.44.0</a> but was undiscovered until after the 3.45.0 release. -<li> Fix issues associated with processing corrupt <a href="../json1.html#jsonbx">JSONB</a> inputs: +<li> Add support for underscore ("_") characters between digits in + <a href="../lang_expr.html#litvalue">numeric literals</a>. +<li> Add the <a href="../json1.html#jpretty">json_pretty()</a> SQL function. +<li> Query planner improvements: <ol type="a"> - <li> Prevent exponential runtime when converting a corrupt JSONB into text. - <li> Fix a possible read of one byte past the end of the JSONB blob when converting - a corrupt JSONB into text. - <li> Enhanced testing using <a href="../testing.html#dbsqlfuzz">jfuzz</a> to prevent any future JSONB problems such - as the above. + <li> The "VALUES-as-coroutine" optimization enables INSERT statements with + thousands of rows in the VALUES clause to parse and run in about half + the time and using about half as much memory. + <li> Allow the use of an index for queries like "SELECT count(DISTINCT col) FROM ...", + even if the index records are not smaller than the table records. + <li> Improved recognition of cases where the value of an SQL function is + constant because all its arguments are constant. + <li> Enhance the <a href="../optoverview.html#pushdown">WHERE-clause push-down optimization</a> so that it is able to + push down WHERE clause terms containing uncorrelated subqueries. </ol> -<li> Fix a long-standing bug in which a read of a few bytes past the end of a - memory-mapped segment might occur when accessing a craftily corrupted database - using <a href="../pragma.html#pragma_mmap_size">memory-mapped database</a>. -<li> Fix a long-standing bug in which a NULL pointer dereference might occur in - the <a href="../opcode.html">bytecode engine</a> due to incorrect bytecode being generated for a class - of SQL statements that are deliberately designed to stress the query planner - but which are otherwise pointless. - -</ol> -<p><b>Prior changes from version 3.45.2 (2024-03-12):</b></p> -<p><ol class='lessindent'> -<li value='13'> Fix an error in <a href="../lang_upsert.html">UPSERT</a>, introduced by enhancement 3a in <a href="../releaselog/3_35_0.html">version 3.35.0</a> - (2021-03-12), that could cause an index to get out-of-sync with its table. - <a href="https://sqlite.org/forum/forumpost/919c6579c8">Forum thread 919c6579c8</a>. -<li> Reduce the scope of the NOT NULL strength reduction optimization that was - added as item 8e in <a href="../releaselog/3_35_0.html">version 3.35.0</a> (2021-03-12). The optimization - was being attempted in some contexts where it did not work, resulting in - incorrect query results. - <a href="https://sqlite.org/forum/forumpost/440f2a2f17">Forum thread 440f2a2f17</a>. -<li> Other trifling corrections and compiler warning fixes that have come up - since the previous patch release. See the - <a href="https://sqlite.org/src/timeline?from=version-3.45.1&to=version-3.45.2&to2=branch-3.45">timeline</a> - for details. -</ol> -<p><b>Changes in this specific patch release, version 3.45.3 (2024-04-15):</b></p> -<p><ol class='lessindent'> -<li value='16'> Fix a long-standing bug (going back to <a href="../releaselog/3_24_0.html">version 3.24.0</a>) - that might (rarely) cause the "old.*" values of an <a href="../lang_createtrigger.html">UPDATE trigger</a> - to be incorrect if that trigger fires in response to an <a href="../lang_upsert.html">UPSERT</a>. - <a href="https://sqlite.org/forum/forumpost/284955a3cd454a15">Forum post 284955a3cd454a15</a>. -<li> Fix a bug in <a href="../lang_aggfunc.html#sumunc">sum()</a> that could cause it to return NULL when it should return - Infinity. <a href="https://sqlite.org/forum/forumpost/23b8688ef4">Forum post 23b8688ef4</a>. -<li> Other trifling corrections and compiler warning fixes that have come up - since the previous patch release. See the - <a href="https://sqlite.org/src/timeline?from=version-3.45.2&to=version-3.45.3&to2=branch-3.45">timeline</a> - for details. +<li> Allocate additional memory from the heap for the SQL parser stack if + that stack overflows, rather than reporting a "parser stack overflow" error. +<li> JSON changes: + <ol type="a"> + <li> Allow ASCII control characters within JSON5 string literals. + <li> Fix <a href="../json1.html#jptr">the -> and ->> operators</a> so that when the right-hand side operand is a string + that looks like an integer it is still treated as a string, because that is what + PostgreSQL does. + </ol> +<li> Allow large hexadecimal literals to be used as the DEFAULT value to a table column. <p><b>Hashes:</b> -<li>SQLITE_SOURCE_ID: 2024-04-15 13:34:05 8653b758870e6ef0c98d46b3ace27849054af85da891eb121e9aaa537f1e8355 -<li>SHA3-256 for sqlite3.c: 21dbe688a71b449d28e2a8ec6a43e7520e54df456e02b6d4f6a1d1c7a998c826 +<li>SQLITE_SOURCE_ID: 2024-05-23 13:25:27 96c92aba00c8375bc32fafcdf12429c58bd8aabfcadab6683e35bbb9cdebf19e +<li>SHA3-256 for sqlite3.c: 094429ea827fcd32275e767134bc6c7b9ea394a2c5a9e653dd0a0690b2c11358 </ol></p> @@ -1230,7 +1230,7 @@ proc searchresults {} { if {$q==""} {return ""} # Count the '"' characters in $::A(q). If there is an odd number of - # occurences, add a " to the end of the query so that fts5 can parse + # occurrences, add a " to the end of the query so that fts5 can parse # it without error. if {[regexp -all \x22 $q] % 2} { append q \x22 } diff --git a/www/search.d/search.db b/www/search.d/search.db Binary files differindex b48940d..31a4392 100644 --- a/www/search.d/search.db +++ b/www/search.d/search.db diff --git a/www/serverless.html b/www/serverless.html index 57090cd..a359751 100644 --- a/www/serverless.html +++ b/www/serverless.html @@ -201,7 +201,7 @@ to help provide database services or implementation. There really is no server. </p><p> -<a href="https://docs.microsoft.com/en-us/azure/cosmos-db/serverless-computing-database">Microsoft Azure Cosmo DB</a> +<a href="https://docs.microsoft.com/en-us/azure/cosmos-db/serverless-computing-database">Microsoft Azure Cosmos DB</a> and <a href="https://aws.amazon.com/s3/">Amazon S3</a> are examples of a neo-serverless databases. diff --git a/www/session.html b/www/session.html index dacb386..20fd7d2 100644 --- a/www/session.html +++ b/www/session.html @@ -175,6 +175,7 @@ code file sqlite3session.h.</p> <div class='columns' style='columns: 15em auto;'> <ul style='padding-top:0;'> <li><a href='#sqlite3changegroup_add'>sqlite3changegroup_add</a></li> +<li><a href='#sqlite3changegroup_add_change'>sqlite3changegroup_add_change</a></li> <li><a href='#sqlite3changegroup_add_strm'>sqlite3changegroup_add_strm</a></li> <li><a href='#sqlite3changegroup_delete'>sqlite3changegroup_delete</a></li> <li><a href='#sqlite3changegroup_new'>sqlite3changegroup_new</a></li> @@ -247,6 +248,7 @@ A changegroup is an object used to combine two or more <p>Destructor: <a href="#sqlite3changegroup_delete">sqlite3changegroup_delete()</a></p> <p>Methods: <a href="#sqlite3changegroup_add">sqlite3changegroup_add()</a>, +<a href="#sqlite3changegroup_add_change">sqlite3changegroup_add_change()</a>, <a href="#sqlite3changegroup_output">sqlite3changegroup_output()</a></p> <hr><a name="sqlite3_changeset_iter"></a> <h2>Changeset Iterator Handle</h2><blockquote><pre>typedef struct sqlite3_changeset_iter sqlite3_changeset_iter; @@ -465,6 +467,24 @@ occurs during processing, this function returns SQLITE_NOMEM. </p> <p>In all cases, if an error occurs the state of the final contents of the changegroup is undefined. If no error occurs, SQLITE_OK is returned. +</p><hr><a name="sqlite3changegroup_add_change"></a> +<h2>Add A Single Change To A Changegroup</h2><blockquote><pre>int sqlite3changegroup_add_change( + sqlite3_changegroup*, + sqlite3_changeset_iter* +); +</pre></blockquote><p> +This function adds the single change currently indicated by the iterator +passed as the second argument to the changegroup object. The rules for +adding the change are just as described for <a href="#sqlite3changegroup_add">sqlite3changegroup_add()</a>.</p> + +<p>If the change is successfully added to the changegroup, SQLITE_OK is +returned. Otherwise, an SQLite error code is returned.</p> + +<p>The iterator must point to a valid entry when this function is called. +If it does not, SQLITE_ERROR is returned and no change is added to the +changegroup. Additionally, the iterator must not have been opened with +the SQLITE_CHANGESETAPPLY_INVERT flag. In this case SQLITE_ERROR is also +returned. </p><hr><a name="sqlite3changegroup_delete"></a> <h2>Delete A Changegroup Object</h2><blockquote><pre>void sqlite3changegroup_delete(sqlite3_changegroup*); </pre></blockquote><p></p><hr><a name="sqlite3changegroup_new"></a> diff --git a/www/session/changegroup.html b/www/session/changegroup.html index e1cc234..fd6d2e1 100644 --- a/www/session/changegroup.html +++ b/www/session/changegroup.html @@ -123,6 +123,7 @@ A changegroup is an object used to combine two or more <p>Destructor: <a href="../session/sqlite3changegroup_delete.html">sqlite3changegroup_delete()</a></p> <p>Methods: <a href="../session/sqlite3changegroup_add.html">sqlite3changegroup_add()</a>, +<a href="../session/sqlite3changegroup_add_change.html">sqlite3changegroup_add_change()</a>, <a href="../session/sqlite3changegroup_output.html">sqlite3changegroup_output()</a></p> <p>See also lists of <a href="../session/objlist.html">Objects</a>, diff --git a/www/session/funclist.html b/www/session/funclist.html index 4bae3fa..fc5bc63 100644 --- a/www/session/funclist.html +++ b/www/session/funclist.html @@ -121,6 +121,7 @@ antiRobotDefense(); <div class='columns' style='columns: 15em auto;'> <ul style='padding-top:0;'> <li><a href='../session/sqlite3changegroup_add.html'>sqlite3changegroup_add</a></li> +<li><a href='../session/sqlite3changegroup_add_change.html'>sqlite3changegroup_add_change</a></li> <li><a href='../session/sqlite3changegroup_add_strm.html'>sqlite3changegroup_add_strm</a></li> <li><a href='../session/sqlite3changegroup_delete.html'>sqlite3changegroup_delete</a></li> <li><a href='../session/sqlite3changegroup_new.html'>sqlite3changegroup_new</a></li> diff --git a/www/session/sqlite3changegroup_add_change.html b/www/session/sqlite3changegroup_add_change.html new file mode 100644 index 0000000..1d9b144 --- /dev/null +++ b/www/session/sqlite3changegroup_add_change.html @@ -0,0 +1,139 @@ +<!DOCTYPE html> +<html><head> +<meta name="viewport" content="width=device-width, initial-scale=1.0"> +<meta http-equiv="content-type" content="text/html; charset=UTF-8"> +<link href="../sqlite.css" rel="stylesheet"> +<title>Add A Single Change To A Changegroup</title> +<!-- path=../ --> +</head> +<body> +<div class=nosearch> +<a href="../index.html"> +<img class="logo" src="../images/sqlite370_banner.gif" alt="SQLite" border="0"> +</a> +<div><!-- IE hack to prevent disappearing logo --></div> +<div class="tagline desktoponly"> +Small. Fast. Reliable.<br>Choose any three. +</div> +<div class="menu mainmenu"> +<ul> +<li><a href="../index.html">Home</a> +<li class='mobileonly'><a href="javascript:void(0)" onclick='toggle_div("submenu")'>Menu</a> +<li class='wideonly'><a href='../about.html'>About</a> +<li class='desktoponly'><a href="../docs.html">Documentation</a> +<li class='desktoponly'><a href="../download.html">Download</a> +<li class='wideonly'><a href='../copyright.html'>License</a> +<li class='desktoponly'><a href="../support.html">Support</a> +<li class='desktoponly'><a href="../prosupport.html">Purchase</a> +<li class='search' id='search_menubutton'> +<a href="javascript:void(0)" onclick='toggle_search()'>Search</a> +</ul> +</div> +<div class="menu submenu" id="submenu"> +<ul> +<li><a href='../about.html'>About</a> +<li><a href='../docs.html'>Documentation</a> +<li><a href='../download.html'>Download</a> +<li><a href='../support.html'>Support</a> +<li><a href='../prosupport.html'>Purchase</a> +</ul> +</div> +<div class="searchmenu" id="searchmenu"> +<form method="GET" action="../search"> +<select name="s" id="searchtype"> +<option value="d">Search Documentation</option> +<option value="c">Search Changelog</option> +</select> +<input type="text" name="q" id="searchbox" value=""> +<input type="submit" value="Go"> +</form> +</div> +</div> +<script> +function toggle_div(nm) { +var w = document.getElementById(nm); +if( w.style.display=="block" ){ +w.style.display = "none"; +}else{ +w.style.display = "block"; +} +} +function toggle_search() { +var w = document.getElementById("searchmenu"); +if( w.style.display=="block" ){ +w.style.display = "none"; +} else { +w.style.display = "block"; +setTimeout(function(){ +document.getElementById("searchbox").focus() +}, 30); +} +} +function div_off(nm){document.getElementById(nm).style.display="none";} +window.onbeforeunload = function(e){div_off("submenu");} +/* Disable the Search feature if we are not operating from CGI, since */ +/* Search is accomplished using CGI and will not work without it. */ +if( !location.origin || !location.origin.match || !location.origin.match(/http/) ){ +document.getElementById("search_menubutton").style.display = "none"; +} +/* Used by the Hide/Show button beside syntax diagrams, to toggle the */ +function hideorshow(btn,obj){ +var x = document.getElementById(obj); +var b = document.getElementById(btn); +if( x.style.display!='none' ){ +x.style.display = 'none'; +b.innerHTML='show'; +}else{ +x.style.display = ''; +b.innerHTML='hide'; +} +return false; +} +var antiRobot = 0; +function antiRobotGo(){ +if( antiRobot!=3 ) return; +antiRobot = 7; +var j = document.getElementById("mtimelink"); +if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); +} +function antiRobotDefense(){ +document.body.onmousedown=function(){ +antiRobot |= 2; +antiRobotGo(); +document.body.onmousedown=null; +} +document.body.onmousemove=function(){ +antiRobot |= 2; +antiRobotGo(); +document.body.onmousemove=null; +} +setTimeout(function(){ +antiRobot |= 1; +antiRobotGo(); +}, 100) +antiRobotGo(); +} +antiRobotDefense(); +</script> +<a href="../session/intro.html"><h2>Session Module C Interface</h2></a><h2>Add A Single Change To A Changegroup</h2><blockquote><pre>int sqlite3changegroup_add_change( + sqlite3_changegroup*, + sqlite3_changeset_iter* +); +</pre></blockquote><p> +This function adds the single change currently indicated by the iterator +passed as the second argument to the changegroup object. The rules for +adding the change are just as described for <a href="../session/sqlite3changegroup_add.html">sqlite3changegroup_add()</a>.</p> + +<p>If the change is successfully added to the changegroup, SQLITE_OK is +returned. Otherwise, an SQLite error code is returned.</p> + +<p>The iterator must point to a valid entry when this function is called. +If it does not, SQLITE_ERROR is returned and no change is added to the +changegroup. Additionally, the iterator must not have been opened with +the SQLITE_CHANGESETAPPLY_INVERT flag. In this case SQLITE_ERROR is also +returned. +</p><p>See also lists of + <a href="../session/objlist.html">Objects</a>, + <a href="../session/constlist.html">Constants</a>, and + <a href="../session/funclist.html">Functions</a>.</p> + diff --git a/www/sessionintro.html b/www/sessionintro.html index 7349cff..efde36f 100644 --- a/www/sessionintro.html +++ b/www/sessionintro.html @@ -518,7 +518,7 @@ static int xConflict(void *pCtx, int eConflict, sqlite3_changset_iter *pIter){ ** ** If parameter bIgnoreConflicts is true, then any conflicting changes ** within the changeset are simply ignored. Or, if bIgnoreConflicts is -** false, then this call fails with an SQLTIE_ABORT error if a changeset +** false, then this call fails with an SQLITE_ABORT error if a changeset ** conflict is encountered. */</i> int apply_changeset( diff --git a/www/sitemap.html b/www/sitemap.html index aa1548e..f83cb3f 100644 --- a/www/sitemap.html +++ b/www/sitemap.html @@ -189,6 +189,7 @@ Other Documentation Indices: <li><b><a href="lang_mathfunc.html">Built In Mathematical SQL Functions</a></b></li> <li><a href="printf.html">Built in printf() — SQLite's</a></li> <li><b><a href="lang_corefunc.html">Built In Scalar SQL Functions</a></b></li> +<li><a href="whybytecode.html">Bytecode — Why SQLite Uses</a></li> <li><a href="opcode.html">Bytecode Engine — The SQLite</a></li> <li><a href="bytecodevtab.html">Bytecode() And Tables_Used() Table Valued Functions — The</a></li> <li><b><a href="capi3ref.html">C/C++ API Reference</a></b></li> @@ -702,6 +703,7 @@ Other Documentation Indices: <li><a href="tempfiles.html">Used By SQLite — Temporary Files</a></li> <li><a href="affcase1.html">Used SQLite? — What If OpenDocument</a></li> <li><a href="famous.html">Users Of SQLite — Well Known</a></li> +<li><a href="whybytecode.html">Uses Bytecode — Why SQLite</a></li> <li><a href="whentouse.html">Uses For SQLite — Appropriate</a></li> <li><b><a href="threadsafe.html">Using SQLite In Multi Threaded Applications</a></b></li> <li><a href="invalidutf.html">UTF Policy — Invalid</a></li> @@ -750,6 +752,7 @@ Other Documentation Indices: <li><b><a href="affcase1.html">What If OpenDocument Used SQLite?</a></b></li> <li><b><a href="whyc.html">Why Is SQLite Coded In C</a></b></li> <li><b><a href="whynotgit.html">Why SQLite Does Not Use Git</a></b></li> +<li><b><a href="whybytecode.html">Why SQLite Uses Bytecode</a></b></li> <li><a href="mostdeployed.html">Widely Deployed SQL Database Engine — Most</a></li> <li><b><a href="windowfunctions.html">Window Functions</a></b></li> <li><a href="lang_with.html">WITH Clause — The</a></li> diff --git a/www/syntax/numeric-literal.html b/www/syntax/numeric-literal.html index 10e389b..3886e2a 100644 --- a/www/syntax/numeric-literal.html +++ b/www/syntax/numeric-literal.html @@ -117,99 +117,137 @@ antiRobotDefense(); </script> <h1 align='center'>numeric-literal</h1> <div class='imgcontainer'> -<div style="max-width:765px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 765.562 214.056"> -<circle cx="5" cy="36" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<polygon points="63,36 51,41 51,32" style="fill:rgb(0,0,0)"/> -<path d="M9,36L57,36" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<path d="M78,51L98,51A15 15 0 0 0 113 36A15 15 0 0 0 98 21L78,21A15 15 0 0 0 63 36A15 15 0 0 0 78 51Z" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<text x="88" y="36" text-anchor="middle" fill="rgb(0,0,0)" dominant-baseline="central">digit</text> -<polygon points="88,6 99,2 99,10" style="fill:rgb(0,0,0)"/> -<path d="M113,36 L 121,36 Q 128,36 128,21 L 128,21 Q 128,6 113,6 L 109,6 L 94,6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<path d="M88,6 L 51,6 Q 36,6 36,21 L 36,21 Q 36,36 44,36 L 51,36" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<polygon points="176,66 164,71 164,62" style="fill:rgb(0,0,0)"/> -<path d="M113,36 L 134,36 Q 149,36 149,51 L 149,51 Q 149,66 159,66 L 170,66" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<path d="M191,82A15 15 0 0 0 206 66L206,66A15 15 0 0 0 191 51A15 15 0 0 0 176 66L176,66A15 15 0 0 0 191 82Z" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<text x="191" y="66" text-anchor="middle" font-weight="bold" fill="rgb(0,0,0)" dominant-baseline="central">.</text> -<polygon points="267,66 255,71 255,62" style="fill:rgb(0,0,0)"/> -<path d="M206,66L261,66" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<polygon points="340,66 328,71 328,62" style="fill:rgb(0,0,0)"/> -<path d="M267,66L334,66" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<polygon points="381,36 370,41 370,32" style="fill:rgb(0,0,0)"/> -<path d="M340,66 L 347,66 Q 355,66 355,51 L 355,51 Q 355,36 365,36 L 375,36" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<polygon points="423,74 411,78 411,70" style="fill:rgb(0,0,0)"/> -<path d="M381,36 L 389,36 Q 396,36 396,51 L 396,59 Q 396,74 406,74 L 417,74" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<path d="M438,89A15 15 0 0 0 453 74L453,74A15 15 0 0 0 438 59A15 15 0 0 0 423 74L423,74A15 15 0 0 0 438 89Z" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<text x="438" y="74" text-anchor="middle" font-weight="bold" fill="rgb(0,0,0)" dominant-baseline="central">E</text> -<polygon points="494,74 483,78 483,70" style="fill:rgb(0,0,0)"/> -<path d="M453,74L489,74" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<polygon points="423,112 411,116 411,108" style="fill:rgb(0,0,0)"/> -<path d="M381,36 L 389,36 Q 396,36 396,51 L 396,97 Q 396,112 406,112 L 417,112" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<path d="M438,127A15 15 0 0 0 453 112A15 15 0 0 0 438 97A15 15 0 0 0 423 112A15 15 0 0 0 438 127Z" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<text x="438" y="112" text-anchor="middle" font-weight="bold" fill="rgb(0,0,0)" dominant-baseline="central">e</text> -<path d="M453,112 L 460,112 Q 468,112 468,97 L 468,89 Q 468,74 475,74 L 483,74" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<path d="M257,112L277,112A15 15 0 0 0 292 97L292,97A15 15 0 0 0 277 82L257,82A15 15 0 0 0 242 97L242,97A15 15 0 0 0 257 112Z" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<text x="267" y="97" text-anchor="middle" fill="rgb(0,0,0)" dominant-baseline="central">digit</text> -<polygon points="292,97 304,92 304,101" style="fill:rgb(0,0,0)"/> -<path d="M267,66 L 304,66 Q 319,66 319,81 L 319,82 Q 319,97 308,97 L 298,97" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<path d="M242,97 L 234,97 Q 227,97 227,82 L 227,81 Q 227,66 234,66 L 242,66" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<polygon points="267,36 255,41 255,32" style="fill:rgb(0,0,0)"/> -<path d="M113,36L261,36" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<path d="M267,36L370,36" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<polygon points="50,135 39,139 39,130" style="fill:rgb(0,0,0)"/> -<path d="M9,36 L 16,36 Q 24,36 24,51 L 24,120 Q 24,135 34,135 L 45,135" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<path d="M66,150A15 15 0 0 0 81 135A15 15 0 0 0 66 119A15 15 0 0 0 50 135A15 15 0 0 0 66 150Z" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<text x="66" y="135" text-anchor="middle" font-weight="bold" fill="rgb(0,0,0)" dominant-baseline="central">.</text> -<polygon points="117,135 105,139 105,130" style="fill:rgb(0,0,0)"/> -<path d="M81,135L111,135" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<path d="M132,150L152,150A15 15 0 0 0 167 135A15 15 0 0 0 152 119L132,119A15 15 0 0 0 117 135A15 15 0 0 0 132 150Z" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<text x="142" y="135" text-anchor="middle" fill="rgb(0,0,0)" dominant-baseline="central">digit</text> -<polygon points="340,135 328,139 328,130" style="fill:rgb(0,0,0)"/> -<path d="M167,135L334,135" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<path d="M340,135 L 347,135 Q 355,135 355,120 L 355,66 L 355,51" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<polygon points="142,104 153,100 153,109" style="fill:rgb(0,0,0)"/> -<path d="M167,135 L 174,135 Q 182,135 182,120 L 182,119 Q 182,104 167,104 L 162,104 L 147,104" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<path d="M142,104 L 105,104 Q 90,104 90,119 L 90,120 Q 90,135 98,135 L 105,135" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<polygon points="536,142 524,146 524,138" style="fill:rgb(0,0,0)"/> -<path d="M494,74 L 502,74 Q 509,74 509,89 L 509,127 Q 509,142 520,142 L 530,142" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<path d="M551,157A15 15 0 0 0 566 142A15 15 0 0 0 551 127A15 15 0 0 0 536 142A15 15 0 0 0 551 157Z" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<text x="551" y="142" text-anchor="middle" font-weight="bold" fill="rgb(0,0,0)" dominant-baseline="central">-</text> -<polygon points="628,74 616,78 616,70" style="fill:rgb(0,0,0)"/> -<path d="M566,142 L 574,142 Q 581,142 581,127 L 581,89 Q 581,74 596,74 L 607,74 L 622,74" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<path d="M643,89L663,89A15 15 0 0 0 678 74L678,74A15 15 0 0 0 663 59L643,59A15 15 0 0 0 628 74L628,74A15 15 0 0 0 643 89Z" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<text x="653" y="74" text-anchor="middle" fill="rgb(0,0,0)" dominant-baseline="central">digit</text> -<polygon points="714,74 703,78 703,70" style="fill:rgb(0,0,0)"/> -<path d="M678,74L708,74" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<polygon points="756,36 744,41 744,32" style="fill:rgb(0,0,0)"/> -<path d="M714,74 L 722,74 Q 729,74 729,59 L 729,51 Q 729,36 740,36 L 750,36" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<circle cx="759" cy="36" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<polygon points="536,104 524,109 524,100" style="fill:rgb(0,0,0)"/> -<path d="M494,74 L 502,74 Q 509,74 509,89 L 509,89 Q 509,104 520,104 L 530,104" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<path d="M551,119A15 15 0 0 0 566 104A15 15 0 0 0 551 89A15 15 0 0 0 536 104A15 15 0 0 0 551 119Z" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<text x="551" y="104" text-anchor="middle" font-weight="bold" fill="rgb(0,0,0)" dominant-baseline="central">+</text> -<path d="M566,104 L 574,104 Q 581,104 581,97 L 581,89" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<polygon points="551,36 540,41 540,32" style="fill:rgb(0,0,0)"/> -<path d="M381,36L545,36" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<path d="M551,36L744,36" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<polygon points="551,74 540,78 540,70" style="fill:rgb(0,0,0)"/> -<path d="M494,74L545,74" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<path d="M551,74L616,74" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<polygon points="653,50 665,46 665,54" style="fill:rgb(0,0,0)"/> -<path d="M678,74 L 686,74 Q 693,74 693,62 Q 693,50 678,50 L 674,50 L 659,50" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<path d="M653,50 L 616,50 Q 601,50 601,62 Q 601,74 609,74 L 616,74" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<polygon points="50,180 39,184 39,176" style="fill:rgb(0,0,0)"/> -<path d="M9,36 L 16,36 Q 24,36 24,51 L 24,165 Q 24,180 34,180 L 45,180" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<path d="M66,195L69,195A15 15 0 0 0 84 180A15 15 0 0 0 69 165L66,165A15 15 0 0 0 50 180A15 15 0 0 0 66 195Z" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<text x="67" y="180" text-anchor="middle" font-weight="bold" fill="rgb(0,0,0)" dominant-baseline="central">0x</text> -<polygon points="120,180 108,184 108,176" style="fill:rgb(0,0,0)"/> -<path d="M84,180L114,180" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<path d="M135,195L185,195A15 15 0 0 0 200 180A15 15 0 0 0 185 165L135,165A15 15 0 0 0 120 180A15 15 0 0 0 135 195Z" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<text x="160" y="180" text-anchor="middle" fill="rgb(0,0,0)" dominant-baseline="central">hexdigit</text> -<polygon points="714,180 703,184 703,176" style="fill:rgb(0,0,0)"/> -<path d="M200,180L708,180" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<path d="M714,180 L 722,180 Q 729,180 729,165 L 729,74 L 729,59" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<polygon points="160,207 171,203 171,211" style="fill:rgb(0,0,0)"/> -<path d="M200,180 L 207,180 Q 215,180 215,193 Q 215,207 200,207 L 180,207 L 165,207" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<path d="M160,207 L 108,207 Q 93,207 93,193 Q 93,180 101,180 L 108,180" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<div style="max-width:765px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 765.562 285.552"> +<circle cx="5" cy="62" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<polygon points="63,62 51,66 51,58" style="fill:rgb(0,0,0)"/> +<path d="M9,62L57,62" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<path d="M78,77L98,77A15 15 0 0 0 113 62A15 15 0 0 0 98 47L78,47A15 15 0 0 0 63 62A15 15 0 0 0 78 77Z" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<text x="88" y="62" text-anchor="middle" fill="rgb(0,0,0)" dominant-baseline="central">digit</text> +<path d="M88,32A15 15 0 0 0 103 17A15 15 0 0 0 88 2A15 15 0 0 0 73 17A15 15 0 0 0 88 32Z" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<text x="88" y="17" text-anchor="middle" font-weight="bold" fill="rgb(0,0,0)" dominant-baseline="central">_</text> +<polygon points="103,38 115,34 115,42" style="fill:rgb(0,0,0)"/> +<path d="M113,62 L 121,62 Q 128,62 128,50 Q 128,38 118,38 L 109,38" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<path d="M103,38 L 51,38 Q 36,38 36,50 Q 36,62 44,62 L 51,62" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<polygon points="103,17 115,12 115,21" style="fill:rgb(0,0,0)"/> +<path d="M113,62 L 121,62 Q 128,62 128,47 L 128,32 Q 128,17 118,17 L 109,17" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<polygon points="63,62 51,66 51,58" style="fill:rgb(0,0,0)"/> +<path d="M73,17 L 51,17 Q 36,17 36,32 L 36,47 Q 36,62 47,62 L 57,62" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<polygon points="176,92 164,97 164,88" style="fill:rgb(0,0,0)"/> +<path d="M113,62 L 134,62 Q 149,62 149,77 L 149,77 Q 149,92 159,92 L 170,92" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<path d="M191,108A15 15 0 0 0 206 92L206,92A15 15 0 0 0 191 77A15 15 0 0 0 176 92L176,92A15 15 0 0 0 191 108Z" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<text x="191" y="92" text-anchor="middle" font-weight="bold" fill="rgb(0,0,0)" dominant-baseline="central">.</text> +<polygon points="267,92 255,97 255,88" style="fill:rgb(0,0,0)"/> +<path d="M206,92L261,92" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<polygon points="340,92 328,97 328,88" style="fill:rgb(0,0,0)"/> +<path d="M267,92L334,92" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<polygon points="381,62 370,66 370,58" style="fill:rgb(0,0,0)"/> +<path d="M340,92 L 347,92 Q 355,92 355,77 L 355,77 Q 355,62 365,62 L 375,62" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<polygon points="423,100 411,104 411,96" style="fill:rgb(0,0,0)"/> +<path d="M381,62 L 389,62 Q 396,62 396,77 L 396,85 Q 396,100 406,100 L 417,100" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<path d="M438,115A15 15 0 0 0 453 100L453,100A15 15 0 0 0 438 85A15 15 0 0 0 423 100L423,100A15 15 0 0 0 438 115Z" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<text x="438" y="100" text-anchor="middle" font-weight="bold" fill="rgb(0,0,0)" dominant-baseline="central">E</text> +<polygon points="494,100 483,104 483,96" style="fill:rgb(0,0,0)"/> +<path d="M453,100L489,100" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<polygon points="423,138 411,142 411,133" style="fill:rgb(0,0,0)"/> +<path d="M381,62 L 389,62 Q 396,62 396,77 L 396,123 Q 396,138 406,138 L 417,138" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<path d="M438,153A15 15 0 0 0 453 138A15 15 0 0 0 438 123A15 15 0 0 0 423 138A15 15 0 0 0 438 153Z" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<text x="438" y="138" text-anchor="middle" font-weight="bold" fill="rgb(0,0,0)" dominant-baseline="central">e</text> +<path d="M453,138 L 460,138 Q 468,138 468,123 L 468,115 Q 468,100 475,100 L 483,100" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<path d="M257,132L277,132A15 15 0 0 0 292 117A15 15 0 0 0 277 101L257,101A15 15 0 0 0 242 117A15 15 0 0 0 257 132Z" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<text x="267" y="117" text-anchor="middle" fill="rgb(0,0,0)" dominant-baseline="central">digit</text> +<path d="M267,168A15 15 0 0 0 282 153A15 15 0 0 0 267 138A15 15 0 0 0 252 153A15 15 0 0 0 267 168Z" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<text x="267" y="153" text-anchor="middle" font-weight="bold" fill="rgb(0,0,0)" dominant-baseline="central">_</text> +<polygon points="292,117 304,112 304,121" style="fill:rgb(0,0,0)"/> +<path d="M267,92 L 304,92 Q 319,92 319,104 Q 319,117 308,117 L 298,117" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<path d="M242,117 L 234,117 Q 227,117 227,104 Q 227,92 234,92 L 242,92" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<polygon points="252,153 240,157 240,149" style="fill:rgb(0,0,0)"/> +<path d="M242,117 L 234,117 Q 227,117 227,132 L 227,138 Q 227,153 236,153 L 246,153" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<polygon points="292,117 304,112 304,121" style="fill:rgb(0,0,0)"/> +<path d="M282,153 L 304,153 Q 319,153 319,138 L 319,132 Q 319,117 308,117 L 298,117" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<polygon points="267,62 255,66 255,58" style="fill:rgb(0,0,0)"/> +<path d="M113,62L261,62" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<path d="M267,62L370,62" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<polygon points="50,177 39,181 39,173" style="fill:rgb(0,0,0)"/> +<path d="M9,62 L 16,62 Q 24,62 24,77 L 24,162 Q 24,177 34,177 L 45,177" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<path d="M66,192A15 15 0 0 0 81 177A15 15 0 0 0 66 162A15 15 0 0 0 50 177A15 15 0 0 0 66 192Z" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<text x="66" y="177" text-anchor="middle" font-weight="bold" fill="rgb(0,0,0)" dominant-baseline="central">.</text> +<polygon points="117,177 105,181 105,173" style="fill:rgb(0,0,0)"/> +<path d="M81,177L111,177" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<path d="M132,192L152,192A15 15 0 0 0 167 177A15 15 0 0 0 152 162L132,162A15 15 0 0 0 117 177A15 15 0 0 0 132 192Z" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<text x="142" y="177" text-anchor="middle" fill="rgb(0,0,0)" dominant-baseline="central">digit</text> +<path d="M142,147A15 15 0 0 0 157 132A15 15 0 0 0 142 117A15 15 0 0 0 127 132A15 15 0 0 0 142 147Z" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<text x="142" y="132" text-anchor="middle" font-weight="bold" fill="rgb(0,0,0)" dominant-baseline="central">_</text> +<polygon points="340,177 328,181 328,173" style="fill:rgb(0,0,0)"/> +<path d="M167,177L334,177" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<path d="M340,177 L 347,177 Q 355,177 355,162 L 355,92 L 355,77" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<polygon points="157,153 168,149 168,157" style="fill:rgb(0,0,0)"/> +<path d="M167,177 L 174,177 Q 182,177 182,165 Q 182,153 172,153 L 163,153" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<path d="M157,153 L 105,153 Q 90,153 90,165 Q 90,177 98,177 L 105,177" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<polygon points="157,132 168,127 168,136" style="fill:rgb(0,0,0)"/> +<path d="M167,177 L 174,177 Q 182,177 182,162 L 182,147 Q 182,132 172,132 L 163,132" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<polygon points="105,177 94,181 94,173" style="fill:rgb(0,0,0)"/> +<path d="M127,132 L 105,132 Q 90,132 90,147 L 90,162 Q 90,177 95,177 L 99,177" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<polygon points="536,168 524,172 524,164" style="fill:rgb(0,0,0)"/> +<path d="M494,100 L 502,100 Q 509,100 509,115 L 509,153 Q 509,168 520,168 L 530,168" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<path d="M551,183A15 15 0 0 0 566 168A15 15 0 0 0 551 153A15 15 0 0 0 536 168A15 15 0 0 0 551 183Z" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<text x="551" y="168" text-anchor="middle" font-weight="bold" fill="rgb(0,0,0)" dominant-baseline="central">-</text> +<polygon points="628,100 616,104 616,96" style="fill:rgb(0,0,0)"/> +<path d="M566,168 L 574,168 Q 581,168 581,153 L 581,115 Q 581,100 596,100 L 607,100 L 622,100" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<path d="M643,115L663,115A15 15 0 0 0 678 100L678,100A15 15 0 0 0 663 85L643,85A15 15 0 0 0 628 100L628,100A15 15 0 0 0 643 115Z" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<text x="653" y="100" text-anchor="middle" fill="rgb(0,0,0)" dominant-baseline="central">digit</text> +<path d="M653,151A15 15 0 0 0 668 136A15 15 0 0 0 653 121A15 15 0 0 0 638 136A15 15 0 0 0 653 151Z" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<text x="653" y="136" text-anchor="middle" font-weight="bold" fill="rgb(0,0,0)" dominant-baseline="central">_</text> +<polygon points="714,100 703,104 703,96" style="fill:rgb(0,0,0)"/> +<path d="M678,100L708,100" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<polygon points="756,62 744,66 744,58" style="fill:rgb(0,0,0)"/> +<path d="M714,100 L 722,100 Q 729,100 729,85 L 729,77 Q 729,62 740,62 L 750,62" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<circle cx="759" cy="62" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<polygon points="536,130 524,135 524,126" style="fill:rgb(0,0,0)"/> +<path d="M494,100 L 502,100 Q 509,100 509,115 L 509,115 Q 509,130 520,130 L 530,130" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<path d="M551,145A15 15 0 0 0 566 130A15 15 0 0 0 551 115A15 15 0 0 0 536 130A15 15 0 0 0 551 145Z" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<text x="551" y="130" text-anchor="middle" font-weight="bold" fill="rgb(0,0,0)" dominant-baseline="central">+</text> +<path d="M566,130 L 574,130 Q 581,130 581,123 L 581,115" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<polygon points="551,62 540,66 540,58" style="fill:rgb(0,0,0)"/> +<path d="M381,62L545,62" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<path d="M551,62L744,62" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<polygon points="551,100 540,104 540,96" style="fill:rgb(0,0,0)"/> +<path d="M494,100L545,100" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<path d="M551,100L616,100" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<polygon points="653,76 665,71 665,80" style="fill:rgb(0,0,0)"/> +<path d="M678,100 L 686,100 Q 693,100 693,88 Q 693,76 678,76 L 674,76 L 659,76" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<path d="M653,76 L 616,76 Q 601,76 601,88 Q 601,100 609,100 L 616,100" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<polygon points="668,136 680,132 680,141" style="fill:rgb(0,0,0)"/> +<path d="M678,100 L 686,100 Q 693,100 693,115 L 693,121 Q 693,136 684,136 L 674,136" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<polygon points="628,100 616,104 616,96" style="fill:rgb(0,0,0)"/> +<path d="M638,136 L 616,136 Q 601,136 601,121 L 601,115 Q 601,100 612,100 L 622,100" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<polygon points="50,222 39,227 39,218" style="fill:rgb(0,0,0)"/> +<path d="M9,62 L 16,62 Q 24,62 24,77 L 24,207 Q 24,222 34,222 L 45,222" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<path d="M66,238L69,238A15 15 0 0 0 84 222A15 15 0 0 0 69 207L66,207A15 15 0 0 0 50 222A15 15 0 0 0 66 238Z" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<text x="67" y="222" text-anchor="middle" font-weight="bold" fill="rgb(0,0,0)" dominant-baseline="central">0x</text> +<polygon points="155,222 144,227 144,218" style="fill:rgb(0,0,0)"/> +<path d="M84,222L149,222" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<polygon points="197,222 185,227 185,218" style="fill:rgb(0,0,0)"/> +<path d="M155,222L191,222" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<path d="M64,277L70,277A15 15 0 0 0 85 262A15 15 0 0 0 70 247L64,247A15 15 0 0 0 49 262A15 15 0 0 0 64 277Z" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<text x="67" y="262" text-anchor="middle" font-weight="bold" fill="rgb(0,0,0)" dominant-baseline="central">0X</text> +<path d="M212,238L262,238A15 15 0 0 0 277 222A15 15 0 0 0 262 207L212,207A15 15 0 0 0 197 222A15 15 0 0 0 212 238Z" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<text x="237" y="222" text-anchor="middle" fill="rgb(0,0,0)" dominant-baseline="central">hexdigit</text> +<path d="M237,283A15 15 0 0 0 252 268A15 15 0 0 0 237 253A15 15 0 0 0 222 268A15 15 0 0 0 237 283Z" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<text x="237" y="268" text-anchor="middle" font-weight="bold" fill="rgb(0,0,0)" dominant-baseline="central">_</text> +<polygon points="714,222 703,227 703,218" style="fill:rgb(0,0,0)"/> +<path d="M277,222L708,222" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<path d="M714,222 L 722,222 Q 729,222 729,207 L 729,100 L 729,85" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<polygon points="49,262 38,266 38,257" style="fill:rgb(0,0,0)"/> +<path d="M24,202 L 24,247 Q 24,262 34,262 L 43,262" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<polygon points="197,222 185,227 185,218" style="fill:rgb(0,0,0)"/> +<path d="M85,262 L 92,262 Q 100,262 100,247 L 100,237 Q 100,222 115,222 L 176,222 L 191,222" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<polygon points="252,247 263,242 263,251" style="fill:rgb(0,0,0)"/> +<path d="M277,222 L 284,222 Q 292,222 292,235 Q 292,247 277,247 L 273,247 L 258,247" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<path d="M252,247 L 185,247 Q 170,247 170,235 Q 170,222 178,222 L 185,222" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<polygon points="252,268 263,263 263,272" style="fill:rgb(0,0,0)"/> +<path d="M277,222 L 284,222 Q 292,222 292,237 L 292,253 Q 292,268 277,268 L 273,268 L 258,268" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<polygon points="197,222 185,227 185,218" style="fill:rgb(0,0,0)"/> +<path d="M222,268 L 185,268 Q 170,268 170,253 L 170,237 Q 170,222 181,222 L 191,222" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> </svg> </div><br> <br></br> diff --git a/www/syntaxdiagrams.html b/www/syntaxdiagrams.html index b5b11b3..1ecbb7a 100644 --- a/www/syntaxdiagrams.html +++ b/www/syntaxdiagrams.html @@ -3775,99 +3775,137 @@ See also: <a href="lang_aggfunc.html">lang_aggfunc.html</a> &nb </div> <a name="numeric-literal"></a><h4>numeric-literal:</h4><div class='imgcontainer'> -<div style="max-width:765px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 765.562 214.056"> -<circle cx="5" cy="36" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<polygon points="63,36 51,41 51,32" style="fill:rgb(0,0,0)"/> -<path d="M9,36L57,36" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<path d="M78,51L98,51A15 15 0 0 0 113 36A15 15 0 0 0 98 21L78,21A15 15 0 0 0 63 36A15 15 0 0 0 78 51Z" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<text x="88" y="36" text-anchor="middle" fill="rgb(0,0,0)" dominant-baseline="central">digit</text> -<polygon points="88,6 99,2 99,10" style="fill:rgb(0,0,0)"/> -<path d="M113,36 L 121,36 Q 128,36 128,21 L 128,21 Q 128,6 113,6 L 109,6 L 94,6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<path d="M88,6 L 51,6 Q 36,6 36,21 L 36,21 Q 36,36 44,36 L 51,36" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<polygon points="176,66 164,71 164,62" style="fill:rgb(0,0,0)"/> -<path d="M113,36 L 134,36 Q 149,36 149,51 L 149,51 Q 149,66 159,66 L 170,66" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<path d="M191,82A15 15 0 0 0 206 66L206,66A15 15 0 0 0 191 51A15 15 0 0 0 176 66L176,66A15 15 0 0 0 191 82Z" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<text x="191" y="66" text-anchor="middle" font-weight="bold" fill="rgb(0,0,0)" dominant-baseline="central">.</text> -<polygon points="267,66 255,71 255,62" style="fill:rgb(0,0,0)"/> -<path d="M206,66L261,66" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<polygon points="340,66 328,71 328,62" style="fill:rgb(0,0,0)"/> -<path d="M267,66L334,66" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<polygon points="381,36 370,41 370,32" style="fill:rgb(0,0,0)"/> -<path d="M340,66 L 347,66 Q 355,66 355,51 L 355,51 Q 355,36 365,36 L 375,36" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<polygon points="423,74 411,78 411,70" style="fill:rgb(0,0,0)"/> -<path d="M381,36 L 389,36 Q 396,36 396,51 L 396,59 Q 396,74 406,74 L 417,74" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<path d="M438,89A15 15 0 0 0 453 74L453,74A15 15 0 0 0 438 59A15 15 0 0 0 423 74L423,74A15 15 0 0 0 438 89Z" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<text x="438" y="74" text-anchor="middle" font-weight="bold" fill="rgb(0,0,0)" dominant-baseline="central">E</text> -<polygon points="494,74 483,78 483,70" style="fill:rgb(0,0,0)"/> -<path d="M453,74L489,74" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<polygon points="423,112 411,116 411,108" style="fill:rgb(0,0,0)"/> -<path d="M381,36 L 389,36 Q 396,36 396,51 L 396,97 Q 396,112 406,112 L 417,112" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<path d="M438,127A15 15 0 0 0 453 112A15 15 0 0 0 438 97A15 15 0 0 0 423 112A15 15 0 0 0 438 127Z" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<text x="438" y="112" text-anchor="middle" font-weight="bold" fill="rgb(0,0,0)" dominant-baseline="central">e</text> -<path d="M453,112 L 460,112 Q 468,112 468,97 L 468,89 Q 468,74 475,74 L 483,74" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<path d="M257,112L277,112A15 15 0 0 0 292 97L292,97A15 15 0 0 0 277 82L257,82A15 15 0 0 0 242 97L242,97A15 15 0 0 0 257 112Z" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<text x="267" y="97" text-anchor="middle" fill="rgb(0,0,0)" dominant-baseline="central">digit</text> -<polygon points="292,97 304,92 304,101" style="fill:rgb(0,0,0)"/> -<path d="M267,66 L 304,66 Q 319,66 319,81 L 319,82 Q 319,97 308,97 L 298,97" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<path d="M242,97 L 234,97 Q 227,97 227,82 L 227,81 Q 227,66 234,66 L 242,66" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<polygon points="267,36 255,41 255,32" style="fill:rgb(0,0,0)"/> -<path d="M113,36L261,36" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<path d="M267,36L370,36" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<polygon points="50,135 39,139 39,130" style="fill:rgb(0,0,0)"/> -<path d="M9,36 L 16,36 Q 24,36 24,51 L 24,120 Q 24,135 34,135 L 45,135" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<path d="M66,150A15 15 0 0 0 81 135A15 15 0 0 0 66 119A15 15 0 0 0 50 135A15 15 0 0 0 66 150Z" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<text x="66" y="135" text-anchor="middle" font-weight="bold" fill="rgb(0,0,0)" dominant-baseline="central">.</text> -<polygon points="117,135 105,139 105,130" style="fill:rgb(0,0,0)"/> -<path d="M81,135L111,135" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<path d="M132,150L152,150A15 15 0 0 0 167 135A15 15 0 0 0 152 119L132,119A15 15 0 0 0 117 135A15 15 0 0 0 132 150Z" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<text x="142" y="135" text-anchor="middle" fill="rgb(0,0,0)" dominant-baseline="central">digit</text> -<polygon points="340,135 328,139 328,130" style="fill:rgb(0,0,0)"/> -<path d="M167,135L334,135" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<path d="M340,135 L 347,135 Q 355,135 355,120 L 355,66 L 355,51" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<polygon points="142,104 153,100 153,109" style="fill:rgb(0,0,0)"/> -<path d="M167,135 L 174,135 Q 182,135 182,120 L 182,119 Q 182,104 167,104 L 162,104 L 147,104" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<path d="M142,104 L 105,104 Q 90,104 90,119 L 90,120 Q 90,135 98,135 L 105,135" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<polygon points="536,142 524,146 524,138" style="fill:rgb(0,0,0)"/> -<path d="M494,74 L 502,74 Q 509,74 509,89 L 509,127 Q 509,142 520,142 L 530,142" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<path d="M551,157A15 15 0 0 0 566 142A15 15 0 0 0 551 127A15 15 0 0 0 536 142A15 15 0 0 0 551 157Z" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<text x="551" y="142" text-anchor="middle" font-weight="bold" fill="rgb(0,0,0)" dominant-baseline="central">-</text> -<polygon points="628,74 616,78 616,70" style="fill:rgb(0,0,0)"/> -<path d="M566,142 L 574,142 Q 581,142 581,127 L 581,89 Q 581,74 596,74 L 607,74 L 622,74" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<path d="M643,89L663,89A15 15 0 0 0 678 74L678,74A15 15 0 0 0 663 59L643,59A15 15 0 0 0 628 74L628,74A15 15 0 0 0 643 89Z" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<text x="653" y="74" text-anchor="middle" fill="rgb(0,0,0)" dominant-baseline="central">digit</text> -<polygon points="714,74 703,78 703,70" style="fill:rgb(0,0,0)"/> -<path d="M678,74L708,74" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<polygon points="756,36 744,41 744,32" style="fill:rgb(0,0,0)"/> -<path d="M714,74 L 722,74 Q 729,74 729,59 L 729,51 Q 729,36 740,36 L 750,36" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<circle cx="759" cy="36" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<polygon points="536,104 524,109 524,100" style="fill:rgb(0,0,0)"/> -<path d="M494,74 L 502,74 Q 509,74 509,89 L 509,89 Q 509,104 520,104 L 530,104" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<path d="M551,119A15 15 0 0 0 566 104A15 15 0 0 0 551 89A15 15 0 0 0 536 104A15 15 0 0 0 551 119Z" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<text x="551" y="104" text-anchor="middle" font-weight="bold" fill="rgb(0,0,0)" dominant-baseline="central">+</text> -<path d="M566,104 L 574,104 Q 581,104 581,97 L 581,89" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<polygon points="551,36 540,41 540,32" style="fill:rgb(0,0,0)"/> -<path d="M381,36L545,36" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<path d="M551,36L744,36" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<polygon points="551,74 540,78 540,70" style="fill:rgb(0,0,0)"/> -<path d="M494,74L545,74" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<path d="M551,74L616,74" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<polygon points="653,50 665,46 665,54" style="fill:rgb(0,0,0)"/> -<path d="M678,74 L 686,74 Q 693,74 693,62 Q 693,50 678,50 L 674,50 L 659,50" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<path d="M653,50 L 616,50 Q 601,50 601,62 Q 601,74 609,74 L 616,74" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<polygon points="50,180 39,184 39,176" style="fill:rgb(0,0,0)"/> -<path d="M9,36 L 16,36 Q 24,36 24,51 L 24,165 Q 24,180 34,180 L 45,180" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<path d="M66,195L69,195A15 15 0 0 0 84 180A15 15 0 0 0 69 165L66,165A15 15 0 0 0 50 180A15 15 0 0 0 66 195Z" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<text x="67" y="180" text-anchor="middle" font-weight="bold" fill="rgb(0,0,0)" dominant-baseline="central">0x</text> -<polygon points="120,180 108,184 108,176" style="fill:rgb(0,0,0)"/> -<path d="M84,180L114,180" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<path d="M135,195L185,195A15 15 0 0 0 200 180A15 15 0 0 0 185 165L135,165A15 15 0 0 0 120 180A15 15 0 0 0 135 195Z" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<text x="160" y="180" text-anchor="middle" fill="rgb(0,0,0)" dominant-baseline="central">hexdigit</text> -<polygon points="714,180 703,184 703,176" style="fill:rgb(0,0,0)"/> -<path d="M200,180L708,180" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<path d="M714,180 L 722,180 Q 729,180 729,165 L 729,74 L 729,59" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<polygon points="160,207 171,203 171,211" style="fill:rgb(0,0,0)"/> -<path d="M200,180 L 207,180 Q 215,180 215,193 Q 215,207 200,207 L 180,207 L 165,207" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> -<path d="M160,207 L 108,207 Q 93,207 93,193 Q 93,180 101,180 L 108,180" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<div style="max-width:765px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 765.562 285.552"> +<circle cx="5" cy="62" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<polygon points="63,62 51,66 51,58" style="fill:rgb(0,0,0)"/> +<path d="M9,62L57,62" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<path d="M78,77L98,77A15 15 0 0 0 113 62A15 15 0 0 0 98 47L78,47A15 15 0 0 0 63 62A15 15 0 0 0 78 77Z" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<text x="88" y="62" text-anchor="middle" fill="rgb(0,0,0)" dominant-baseline="central">digit</text> +<path d="M88,32A15 15 0 0 0 103 17A15 15 0 0 0 88 2A15 15 0 0 0 73 17A15 15 0 0 0 88 32Z" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<text x="88" y="17" text-anchor="middle" font-weight="bold" fill="rgb(0,0,0)" dominant-baseline="central">_</text> +<polygon points="103,38 115,34 115,42" style="fill:rgb(0,0,0)"/> +<path d="M113,62 L 121,62 Q 128,62 128,50 Q 128,38 118,38 L 109,38" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<path d="M103,38 L 51,38 Q 36,38 36,50 Q 36,62 44,62 L 51,62" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<polygon points="103,17 115,12 115,21" style="fill:rgb(0,0,0)"/> +<path d="M113,62 L 121,62 Q 128,62 128,47 L 128,32 Q 128,17 118,17 L 109,17" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<polygon points="63,62 51,66 51,58" style="fill:rgb(0,0,0)"/> +<path d="M73,17 L 51,17 Q 36,17 36,32 L 36,47 Q 36,62 47,62 L 57,62" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<polygon points="176,92 164,97 164,88" style="fill:rgb(0,0,0)"/> +<path d="M113,62 L 134,62 Q 149,62 149,77 L 149,77 Q 149,92 159,92 L 170,92" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<path d="M191,108A15 15 0 0 0 206 92L206,92A15 15 0 0 0 191 77A15 15 0 0 0 176 92L176,92A15 15 0 0 0 191 108Z" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<text x="191" y="92" text-anchor="middle" font-weight="bold" fill="rgb(0,0,0)" dominant-baseline="central">.</text> +<polygon points="267,92 255,97 255,88" style="fill:rgb(0,0,0)"/> +<path d="M206,92L261,92" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<polygon points="340,92 328,97 328,88" style="fill:rgb(0,0,0)"/> +<path d="M267,92L334,92" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<polygon points="381,62 370,66 370,58" style="fill:rgb(0,0,0)"/> +<path d="M340,92 L 347,92 Q 355,92 355,77 L 355,77 Q 355,62 365,62 L 375,62" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<polygon points="423,100 411,104 411,96" style="fill:rgb(0,0,0)"/> +<path d="M381,62 L 389,62 Q 396,62 396,77 L 396,85 Q 396,100 406,100 L 417,100" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<path d="M438,115A15 15 0 0 0 453 100L453,100A15 15 0 0 0 438 85A15 15 0 0 0 423 100L423,100A15 15 0 0 0 438 115Z" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<text x="438" y="100" text-anchor="middle" font-weight="bold" fill="rgb(0,0,0)" dominant-baseline="central">E</text> +<polygon points="494,100 483,104 483,96" style="fill:rgb(0,0,0)"/> +<path d="M453,100L489,100" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<polygon points="423,138 411,142 411,133" style="fill:rgb(0,0,0)"/> +<path d="M381,62 L 389,62 Q 396,62 396,77 L 396,123 Q 396,138 406,138 L 417,138" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<path d="M438,153A15 15 0 0 0 453 138A15 15 0 0 0 438 123A15 15 0 0 0 423 138A15 15 0 0 0 438 153Z" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<text x="438" y="138" text-anchor="middle" font-weight="bold" fill="rgb(0,0,0)" dominant-baseline="central">e</text> +<path d="M453,138 L 460,138 Q 468,138 468,123 L 468,115 Q 468,100 475,100 L 483,100" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<path d="M257,132L277,132A15 15 0 0 0 292 117A15 15 0 0 0 277 101L257,101A15 15 0 0 0 242 117A15 15 0 0 0 257 132Z" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<text x="267" y="117" text-anchor="middle" fill="rgb(0,0,0)" dominant-baseline="central">digit</text> +<path d="M267,168A15 15 0 0 0 282 153A15 15 0 0 0 267 138A15 15 0 0 0 252 153A15 15 0 0 0 267 168Z" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<text x="267" y="153" text-anchor="middle" font-weight="bold" fill="rgb(0,0,0)" dominant-baseline="central">_</text> +<polygon points="292,117 304,112 304,121" style="fill:rgb(0,0,0)"/> +<path d="M267,92 L 304,92 Q 319,92 319,104 Q 319,117 308,117 L 298,117" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<path d="M242,117 L 234,117 Q 227,117 227,104 Q 227,92 234,92 L 242,92" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<polygon points="252,153 240,157 240,149" style="fill:rgb(0,0,0)"/> +<path d="M242,117 L 234,117 Q 227,117 227,132 L 227,138 Q 227,153 236,153 L 246,153" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<polygon points="292,117 304,112 304,121" style="fill:rgb(0,0,0)"/> +<path d="M282,153 L 304,153 Q 319,153 319,138 L 319,132 Q 319,117 308,117 L 298,117" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<polygon points="267,62 255,66 255,58" style="fill:rgb(0,0,0)"/> +<path d="M113,62L261,62" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<path d="M267,62L370,62" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<polygon points="50,177 39,181 39,173" style="fill:rgb(0,0,0)"/> +<path d="M9,62 L 16,62 Q 24,62 24,77 L 24,162 Q 24,177 34,177 L 45,177" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<path d="M66,192A15 15 0 0 0 81 177A15 15 0 0 0 66 162A15 15 0 0 0 50 177A15 15 0 0 0 66 192Z" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<text x="66" y="177" text-anchor="middle" font-weight="bold" fill="rgb(0,0,0)" dominant-baseline="central">.</text> +<polygon points="117,177 105,181 105,173" style="fill:rgb(0,0,0)"/> +<path d="M81,177L111,177" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<path d="M132,192L152,192A15 15 0 0 0 167 177A15 15 0 0 0 152 162L132,162A15 15 0 0 0 117 177A15 15 0 0 0 132 192Z" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<text x="142" y="177" text-anchor="middle" fill="rgb(0,0,0)" dominant-baseline="central">digit</text> +<path d="M142,147A15 15 0 0 0 157 132A15 15 0 0 0 142 117A15 15 0 0 0 127 132A15 15 0 0 0 142 147Z" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<text x="142" y="132" text-anchor="middle" font-weight="bold" fill="rgb(0,0,0)" dominant-baseline="central">_</text> +<polygon points="340,177 328,181 328,173" style="fill:rgb(0,0,0)"/> +<path d="M167,177L334,177" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<path d="M340,177 L 347,177 Q 355,177 355,162 L 355,92 L 355,77" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<polygon points="157,153 168,149 168,157" style="fill:rgb(0,0,0)"/> +<path d="M167,177 L 174,177 Q 182,177 182,165 Q 182,153 172,153 L 163,153" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<path d="M157,153 L 105,153 Q 90,153 90,165 Q 90,177 98,177 L 105,177" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<polygon points="157,132 168,127 168,136" style="fill:rgb(0,0,0)"/> +<path d="M167,177 L 174,177 Q 182,177 182,162 L 182,147 Q 182,132 172,132 L 163,132" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<polygon points="105,177 94,181 94,173" style="fill:rgb(0,0,0)"/> +<path d="M127,132 L 105,132 Q 90,132 90,147 L 90,162 Q 90,177 95,177 L 99,177" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<polygon points="536,168 524,172 524,164" style="fill:rgb(0,0,0)"/> +<path d="M494,100 L 502,100 Q 509,100 509,115 L 509,153 Q 509,168 520,168 L 530,168" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<path d="M551,183A15 15 0 0 0 566 168A15 15 0 0 0 551 153A15 15 0 0 0 536 168A15 15 0 0 0 551 183Z" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<text x="551" y="168" text-anchor="middle" font-weight="bold" fill="rgb(0,0,0)" dominant-baseline="central">-</text> +<polygon points="628,100 616,104 616,96" style="fill:rgb(0,0,0)"/> +<path d="M566,168 L 574,168 Q 581,168 581,153 L 581,115 Q 581,100 596,100 L 607,100 L 622,100" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<path d="M643,115L663,115A15 15 0 0 0 678 100L678,100A15 15 0 0 0 663 85L643,85A15 15 0 0 0 628 100L628,100A15 15 0 0 0 643 115Z" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<text x="653" y="100" text-anchor="middle" fill="rgb(0,0,0)" dominant-baseline="central">digit</text> +<path d="M653,151A15 15 0 0 0 668 136A15 15 0 0 0 653 121A15 15 0 0 0 638 136A15 15 0 0 0 653 151Z" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<text x="653" y="136" text-anchor="middle" font-weight="bold" fill="rgb(0,0,0)" dominant-baseline="central">_</text> +<polygon points="714,100 703,104 703,96" style="fill:rgb(0,0,0)"/> +<path d="M678,100L708,100" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<polygon points="756,62 744,66 744,58" style="fill:rgb(0,0,0)"/> +<path d="M714,100 L 722,100 Q 729,100 729,85 L 729,77 Q 729,62 740,62 L 750,62" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<circle cx="759" cy="62" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<polygon points="536,130 524,135 524,126" style="fill:rgb(0,0,0)"/> +<path d="M494,100 L 502,100 Q 509,100 509,115 L 509,115 Q 509,130 520,130 L 530,130" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<path d="M551,145A15 15 0 0 0 566 130A15 15 0 0 0 551 115A15 15 0 0 0 536 130A15 15 0 0 0 551 145Z" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<text x="551" y="130" text-anchor="middle" font-weight="bold" fill="rgb(0,0,0)" dominant-baseline="central">+</text> +<path d="M566,130 L 574,130 Q 581,130 581,123 L 581,115" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<polygon points="551,62 540,66 540,58" style="fill:rgb(0,0,0)"/> +<path d="M381,62L545,62" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<path d="M551,62L744,62" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<polygon points="551,100 540,104 540,96" style="fill:rgb(0,0,0)"/> +<path d="M494,100L545,100" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<path d="M551,100L616,100" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<polygon points="653,76 665,71 665,80" style="fill:rgb(0,0,0)"/> +<path d="M678,100 L 686,100 Q 693,100 693,88 Q 693,76 678,76 L 674,76 L 659,76" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<path d="M653,76 L 616,76 Q 601,76 601,88 Q 601,100 609,100 L 616,100" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<polygon points="668,136 680,132 680,141" style="fill:rgb(0,0,0)"/> +<path d="M678,100 L 686,100 Q 693,100 693,115 L 693,121 Q 693,136 684,136 L 674,136" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<polygon points="628,100 616,104 616,96" style="fill:rgb(0,0,0)"/> +<path d="M638,136 L 616,136 Q 601,136 601,121 L 601,115 Q 601,100 612,100 L 622,100" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<polygon points="50,222 39,227 39,218" style="fill:rgb(0,0,0)"/> +<path d="M9,62 L 16,62 Q 24,62 24,77 L 24,207 Q 24,222 34,222 L 45,222" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<path d="M66,238L69,238A15 15 0 0 0 84 222A15 15 0 0 0 69 207L66,207A15 15 0 0 0 50 222A15 15 0 0 0 66 238Z" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<text x="67" y="222" text-anchor="middle" font-weight="bold" fill="rgb(0,0,0)" dominant-baseline="central">0x</text> +<polygon points="155,222 144,227 144,218" style="fill:rgb(0,0,0)"/> +<path d="M84,222L149,222" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<polygon points="197,222 185,227 185,218" style="fill:rgb(0,0,0)"/> +<path d="M155,222L191,222" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<path d="M64,277L70,277A15 15 0 0 0 85 262A15 15 0 0 0 70 247L64,247A15 15 0 0 0 49 262A15 15 0 0 0 64 277Z" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<text x="67" y="262" text-anchor="middle" font-weight="bold" fill="rgb(0,0,0)" dominant-baseline="central">0X</text> +<path d="M212,238L262,238A15 15 0 0 0 277 222A15 15 0 0 0 262 207L212,207A15 15 0 0 0 197 222A15 15 0 0 0 212 238Z" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<text x="237" y="222" text-anchor="middle" fill="rgb(0,0,0)" dominant-baseline="central">hexdigit</text> +<path d="M237,283A15 15 0 0 0 252 268A15 15 0 0 0 237 253A15 15 0 0 0 222 268A15 15 0 0 0 237 283Z" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<text x="237" y="268" text-anchor="middle" font-weight="bold" fill="rgb(0,0,0)" dominant-baseline="central">_</text> +<polygon points="714,222 703,227 703,218" style="fill:rgb(0,0,0)"/> +<path d="M277,222L708,222" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<path d="M714,222 L 722,222 Q 729,222 729,207 L 729,100 L 729,85" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<polygon points="49,262 38,266 38,257" style="fill:rgb(0,0,0)"/> +<path d="M24,202 L 24,247 Q 24,262 34,262 L 43,262" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<polygon points="197,222 185,227 185,218" style="fill:rgb(0,0,0)"/> +<path d="M85,262 L 92,262 Q 100,262 100,247 L 100,237 Q 100,222 115,222 L 176,222 L 191,222" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<polygon points="252,247 263,242 263,251" style="fill:rgb(0,0,0)"/> +<path d="M277,222 L 284,222 Q 292,222 292,235 Q 292,247 277,247 L 273,247 L 258,247" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<path d="M252,247 L 185,247 Q 170,247 170,235 Q 170,222 178,222 L 185,222" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<polygon points="252,268 263,263 263,272" style="fill:rgb(0,0,0)"/> +<path d="M277,222 L 284,222 Q 292,222 292,237 L 292,253 Q 292,268 277,268 L 273,268 L 258,268" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<polygon points="197,222 185,227 185,218" style="fill:rgb(0,0,0)"/> +<path d="M222,268 L 185,268 Q 170,268 170,253 L 170,237 Q 170,222 181,222 L 191,222" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> </svg> </div> <br></br> Binary files differdiff --git a/www/vfs.html b/www/vfs.html index 9615971..695c643 100644 --- a/www/vfs.html +++ b/www/vfs.html @@ -415,7 +415,7 @@ on the device. This file implements a shim used during SQLite testing that verifies that the database and rollback journal are written in the correct order and are "synced" at appropriate times in order to guarantee that the database -can recover from a power lose are hard reset at any time. The shim +can recover from a power loss or hard reset at any time. The shim checks several invariants on the operation of databases and rollback journals and raises exceptions if any of those invariants are violated. These invariants, in turn, assure that the database is always recoverable. diff --git a/www/wal.html b/www/wal.html index abb6b4d..2e32dba 100644 --- a/www/wal.html +++ b/www/wal.html @@ -706,14 +706,12 @@ database files in exclusive locking mode, so attempts to read Chrome or Firefox databases while the applications are running will run into this problem, for example. -</p></li><li><p> -When the last connection to a particular database is closing, that -connection will acquire an exclusive lock for a short time while it -cleans up the WAL and shared-memory files. If a second database tries -to open and query the database while the first connection -is still in the middle -of its cleanup process, the second connection might get an <a href="rescode.html#busy">SQLITE_BUSY</a> -error. +</p></li><li><p> When the last connection to a particular database is closing, +that connection will acquire an exclusive lock for a short time while +it cleans up the WAL and shared-memory files. If a separate attempt +is made to open and query the database while the first connection is +still in the middle of its cleanup process, the second connection +might get an <a href="rescode.html#busy">SQLITE_BUSY</a> error. </p></li><li><p> If the last connection to a database crashed, then the first new diff --git a/www/whentouse.html b/www/whentouse.html index 746f097..59d287e 100644 --- a/www/whentouse.html +++ b/www/whentouse.html @@ -115,10 +115,38 @@ antiRobotGo(); } antiRobotDefense(); </script> +<div class=fancy> +<div class=nosearch> +<div class="fancy_title"> +Appropriate Uses For SQLite +</div> +<div class="fancy_toc"> +<a onclick="toggle_toc()"> +<span class="fancy_toc_mark" id="toc_mk">►</span> +Table Of Contents +</a> +<div id="toc_sub"><div class="fancy-toc1"><a href="#situations_where_sqlite_works_well">1. Situations Where SQLite Works Well</a></div> +<div class="fancy-toc1"><a href="#situations_where_a_client_server_rdbms_may_work_better">2. Situations Where A Client/Server RDBMS May Work Better</a></div> +<div class="fancy-toc1"><a href="#checklist_for_choosing_the_right_database_engine">3. Checklist For Choosing The Right Database Engine</a></div> +</div> +</div> +<script> +function toggle_toc(){ +var sub = document.getElementById("toc_sub") +var mk = document.getElementById("toc_mk") +if( sub.style.display!="block" ){ +sub.style.display = "block"; +mk.innerHTML = "▼"; +} else { +sub.style.display = "none"; +mk.innerHTML = "►"; +} +} +</script> +</div> -<h1 align="center">Appropriate Uses For SQLite</h1> <p> SQLite is not directly comparable to client/server SQL database engines such @@ -141,7 +169,7 @@ SQLite does not compete with client/server databases. SQLite competes with <a href="http://man.he.net/man3/fopen">fopen()</a>. </p> -<h2>Situations Where SQLite Works Well</h2> +<h1 id="situations_where_sqlite_works_well"><span>1. </span>Situations Where SQLite Works Well</h1> <ul> @@ -164,7 +192,7 @@ SQLite works there too, but SQLite also thrives at the edge of the network, fending for itself while providing fast and reliable data services to applications that would otherwise have dodgy connectivity. -</li> +</p></li> <li><p><b>Application file format</b></p> @@ -188,7 +216,7 @@ improved reliability. See technical notes This use case is closely related to the <a href="#wireproto">data transfer format</a> and <a href="#container">data container</a> use cases below. -</li> +</p></li> <a name="website"></a> @@ -212,8 +240,8 @@ the database. Dynamic content uses <a href="np1queryprob.html">about 200 SQL st This setup runs on a single VM that shares a physical server with 23 others and yet still keeps the load average below 0.1 most of the time. -<p>See also: <a href="https://news.ycombinator.com/item?id=33975635">Hacker New discussion from 2022-12-13</a>. -</li> +</p><p>See also: <a href="https://news.ycombinator.com/item?id=33975635">Hacker New discussion from 2022-12-13</a>. +</p></li> <li><p><b>Data analysis</b></p> @@ -285,16 +313,16 @@ connections, but each SQLite database is only used by one connection.</p> <a name="wireproto"></a> -<li><p><b>Data transfer format</b><p> +<li><p><b>Data transfer format</b></p><p> -<p>Because an SQLite database is a single compact file in a +</p><p>Because an SQLite database is a single compact file in a <a href="fileformat2.html">well-defined cross-platform format</a>, it is often used as a container for transferring content from one system to another. The sender gathers content into an SQLite database file, transfers that one file to the receiver, then the receiver uses SQL to extract the content as needed. -<p>An SQLite database facilitates data transfer between systems even +</p><p>An SQLite database facilitates data transfer between systems even when the endpoints have different word sizes and/or byte orders. The data can be a complex mix of large binary blobs, text, and small numeric or boolean values. The data format can be easily extended @@ -305,7 +333,7 @@ received content as needed. The data format is "transparent" in the sense that it is easily decoded for human viewing using a variety of universally available, open-source tools, from multiple vendors. -</li> +</p></li> <a name="container"></a> @@ -355,7 +383,7 @@ particularly well as a replacement for these <i>ad hoc</i> data files. Contrary to intuition, SQLite can be <a href="fasterthanfs.html">faster than the filesystem</a> for reading and writing content to disk. -</li> +</p></li> <li><p><b>Internal or temporary databases</b></p> @@ -407,12 +435,12 @@ prototyping new, experimental database language features or ideas. </ul> -<h2>Situations Where A Client/Server RDBMS May Work Better</h2> +<h1 id="situations_where_a_client_server_rdbms_may_work_better"><span>2. </span>Situations Where A Client/Server RDBMS May Work Better</h1> <ul> -<li><p><b>Client/Server Applications</b><p> +<li><p><b>Client/Server Applications</b></p><p> -<p>If there are many client programs sending SQL to the same +</p><p>If there are many client programs sending SQL to the same database over a network, then use a client/server database engine instead of SQLite. SQLite will work over a network filesystem, but because of the latency associated with most network filesystems, @@ -469,7 +497,7 @@ solution. <a name="dbcklst"></a> -<h2>Checklist For Choosing The Right Database Engine</h2> +<h1 id="checklist_for_choosing_the_right_database_engine"><span>3. </span>Checklist For Choosing The Right Database Engine</h1> <ol> <li><p><b>Is the data separated from the application by a network? @@ -481,14 +509,14 @@ the same physical device so that the high-bandwidth engine-to-disk link does not have to traverse the network, only the lower-bandwidth application-to-engine link. -<p>But SQLite is built into the application. So if the data is on a +</p><p>But SQLite is built into the application. So if the data is on a separate device from the application, it is required that the higher bandwidth engine-to-disk link be across the network. This works, but it is suboptimal. Hence, it is usually better to select a client/server database engine when the data is on a separate device from the application. -<p><em>Nota Bene:</em> +</p><p><em>Nota Bene:</em> In this rule, "application" means the code that issues SQL statements. If the "application" is an <a href="whentouse.html#serversidedb">application server</a> and if the content resides on the same physical machine as the application server, @@ -503,14 +531,14 @@ database at the same instant (and they cannot queue up and take turns) then it is best to select a database engine that supports that capability, which always means a client/server database engine. -<p>SQLite only supports one writer at a time per database file. +</p><p>SQLite only supports one writer at a time per database file. But in most cases, a write transaction only takes milliseconds and so multiple writers can simply take turns. SQLite will handle more write concurrency than many people suspect. Nevertheless, client/server database systems, because they have a long-running server process at hand to coordinate access, can usually handle far more write concurrency than SQLite ever will. -</li> +</p></li> <li><p><b>Big data? → choose client/server</b></p> @@ -521,7 +549,7 @@ a solution other than SQLite. SQLite supports databases up to that will support 281-terabyte files. Even so, when the size of the content looks like it might creep into the terabyte range, it would be good to consider a centralized client/server database. -</li> +</p></li> <li><p><b>Otherwise → choose SQLite!</b></p> @@ -529,7 +557,7 @@ be good to consider a centralized client/server database. terabyte of content, SQLite is almost always a better solution. SQLite is fast and reliable and it requires no configuration or maintenance. It keeps things simple. SQLite "just works". -</li> +</p></li> </ol> <p align="center"><small><i>This page last modified on <a href="https://sqlite.org/docsrc/honeypot" id="mtimelink" data-href="https://sqlite.org/docsrc/finfo/pages/whentouse.in?m=3425224a93">2024-04-03 17:48:26</a> UTC </small></i></p> diff --git a/www/whybytecode.html b/www/whybytecode.html new file mode 100644 index 0000000..98da8b3 --- /dev/null +++ b/www/whybytecode.html @@ -0,0 +1,435 @@ +<!DOCTYPE html> +<html><head> +<meta name="viewport" content="width=device-width, initial-scale=1.0"> +<meta http-equiv="content-type" content="text/html; charset=UTF-8"> +<link href="sqlite.css" rel="stylesheet"> +<title>Why SQLite Uses Bytecode</title> +<!-- path= --> +</head> +<body> +<div class=nosearch> +<a href="index.html"> +<img class="logo" src="images/sqlite370_banner.gif" alt="SQLite" border="0"> +</a> +<div><!-- IE hack to prevent disappearing logo --></div> +<div class="tagline desktoponly"> +Small. Fast. Reliable.<br>Choose any three. +</div> +<div class="menu mainmenu"> +<ul> +<li><a href="index.html">Home</a> +<li class='mobileonly'><a href="javascript:void(0)" onclick='toggle_div("submenu")'>Menu</a> +<li class='wideonly'><a href='about.html'>About</a> +<li class='desktoponly'><a href="docs.html">Documentation</a> +<li class='desktoponly'><a href="download.html">Download</a> +<li class='wideonly'><a href='copyright.html'>License</a> +<li class='desktoponly'><a href="support.html">Support</a> +<li class='desktoponly'><a href="prosupport.html">Purchase</a> +<li class='search' id='search_menubutton'> +<a href="javascript:void(0)" onclick='toggle_search()'>Search</a> +</ul> +</div> +<div class="menu submenu" id="submenu"> +<ul> +<li><a href='about.html'>About</a> +<li><a href='docs.html'>Documentation</a> +<li><a href='download.html'>Download</a> +<li><a href='support.html'>Support</a> +<li><a href='prosupport.html'>Purchase</a> +</ul> +</div> +<div class="searchmenu" id="searchmenu"> +<form method="GET" action="search"> +<select name="s" id="searchtype"> +<option value="d">Search Documentation</option> +<option value="c">Search Changelog</option> +</select> +<input type="text" name="q" id="searchbox" value=""> +<input type="submit" value="Go"> +</form> +</div> +</div> +<script> +function toggle_div(nm) { +var w = document.getElementById(nm); +if( w.style.display=="block" ){ +w.style.display = "none"; +}else{ +w.style.display = "block"; +} +} +function toggle_search() { +var w = document.getElementById("searchmenu"); +if( w.style.display=="block" ){ +w.style.display = "none"; +} else { +w.style.display = "block"; +setTimeout(function(){ +document.getElementById("searchbox").focus() +}, 30); +} +} +function div_off(nm){document.getElementById(nm).style.display="none";} +window.onbeforeunload = function(e){div_off("submenu");} +/* Disable the Search feature if we are not operating from CGI, since */ +/* Search is accomplished using CGI and will not work without it. */ +if( !location.origin || !location.origin.match || !location.origin.match(/http/) ){ +document.getElementById("search_menubutton").style.display = "none"; +} +/* Used by the Hide/Show button beside syntax diagrams, to toggle the */ +function hideorshow(btn,obj){ +var x = document.getElementById(obj); +var b = document.getElementById(btn); +if( x.style.display!='none' ){ +x.style.display = 'none'; +b.innerHTML='show'; +}else{ +x.style.display = ''; +b.innerHTML='hide'; +} +return false; +} +var antiRobot = 0; +function antiRobotGo(){ +if( antiRobot!=3 ) return; +antiRobot = 7; +var j = document.getElementById("mtimelink"); +if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); +} +function antiRobotDefense(){ +document.body.onmousedown=function(){ +antiRobot |= 2; +antiRobotGo(); +document.body.onmousedown=null; +} +document.body.onmousemove=function(){ +antiRobot |= 2; +antiRobotGo(); +document.body.onmousemove=null; +} +setTimeout(function(){ +antiRobot |= 1; +antiRobotGo(); +}, 100) +antiRobotGo(); +} +antiRobotDefense(); +</script> +<div class=fancy> +<div class=nosearch> +<div class="fancy_title"> +Why SQLite Uses Bytecode +</div> +<div class="fancy_toc"> +<a onclick="toggle_toc()"> +<span class="fancy_toc_mark" id="toc_mk">►</span> +Table Of Contents +</a> +<div id="toc_sub"><div class="fancy-toc1"><a href="#introduction">1. Introduction</a></div> +<div class="fancy-toc2"><a href="#how_to_provide_feedback">1.1. How To Provide Feedback</a></div> +<div class="fancy-toc2"><a href="#definition_of_bytecode_">1.2. Definition Of "Bytecode"</a></div> +<div class="fancy-toc2"><a href="#definition_of_abstract_syntax_tree_or_ast_">1.3. Definition Of "Abstract Syntax Tree" or "AST"</a></div> +<div class="fancy-toc2"><a href="#dataflow_programming">1.4. Dataflow Programming</a></div> +<div class="fancy-toc1"><a href="#advantages_to_compiling_into_bytecode">2. Advantages To Compiling Into Bytecode</a></div> +<div class="fancy-toc2"><a href="#bytecode_is_easier_to_understand">2.1. Bytecode Is Easier To Understand</a></div> +<div class="fancy-toc2"><a href="#bytecode_is_easier_to_debug">2.2. Bytecode Is Easier To Debug</a></div> +<div class="fancy-toc2"><a href="#bytecode_can_be_run_incrementally">2.3. Bytecode Can Be Run Incrementally</a></div> +<div class="fancy-toc2"><a href="#bytecode_is_smaller">2.4. Bytecode Is Smaller</a></div> +<div class="fancy-toc2"><a href="#bytecode_is_faster">2.5. Bytecode Is Faster</a></div> +<div class="fancy-toc1"><a href="#advantages_of_compiling_into_a_tree_of_objects">3. Advantages Of Compiling Into A Tree Of Objects</a></div> +<div class="fancy-toc2"><a href="#query_planning_decisions_can_be_deferred_until_runtime">3.1. Query Planning Decisions Can Be Deferred Until Runtime</a></div> +<div class="fancy-toc2"><a href="#dataflow_programs_are_easy_to_parallelize">3.2. Dataflow Programs Are Easy To Parallelize</a></div> +</div> +</div> +<script> +function toggle_toc(){ +var sub = document.getElementById("toc_sub") +var mk = document.getElementById("toc_mk") +if( sub.style.display!="block" ){ +sub.style.display = "block"; +mk.innerHTML = "▼"; +} else { +sub.style.display = "none"; +mk.innerHTML = "►"; +} +} +</script> +</div> + + + + + +<h1 id="introduction"><span>1. </span>Introduction</h1> + +<p>Every SQL database engine works in roughly the same way: It first +translates the input SQL text into a "prepared statement". Then it "executes" +the prepared statement to generate a result. + +</p><p>A prepared statement is an object that represents the steps needed +to accomplish the input SQL. Or, to think of it in another way, +the prepared statement is the SQL statement translated into a form that is +more easily understood by the computer. + +</p><p>In SQLite, a prepared statement is an instance of the +<a href="c3ref/stmt.html">sqlite3_stmt object</a>. In other systems, the prepared +statement is usually an internal data structure that is not directly visible to +the application programmer. Developers of other SQL database engines +do not necessarily call these objects "prepared statements". +But such objects exists, whatever they might be called. +This paper will use the term "prepared statement". + +</p><p>There are countless ways of implementing a prepared statement. This +paper will look at the two most common methods: + +</p><ol> +<li><p> +<b>Bytecode</b> → The input SQL is translated into a virtual machine language +that is then run by a virtual machine interpreter. This is the technique +used by SQLite. + +</p></li><li><p> +<b>Tree-Of-Objects</b> → The input SQL is translated in a tree of objects +that represent the processing to be done. The SQL is executed by walking this +tree. This is the technique used by MySQL and PostgreSQL. +</p></li></ol> + +<p> +There are advantages and disadvantages to each of these representations of +a prepared statement. The purpose of this paper is to articulate some of those +advantages and disadvantages. + +</p><h2 id="how_to_provide_feedback"><span>1.1. </span>How To Provide Feedback</h2> + +<p> +This document is written from the perspective of the original author of SQLite. +If you disagree with any of the opinions offered in this document, you are +welcomed to offer corrections and/or contrary views on the +<a href="https://sqlite.org/forum">SQLite Forum</a>. Or you can email the author +directly. + +</p><h2 id="definition_of_bytecode_"><span>1.2. </span>Definition Of "Bytecode"</h2> + +<p>The <a href="opcode.html">bytecode generated by SQLite</a> might be a little different from what +many readers think of as bytecode. The bytecode used (for example) by the +<a href="https://en.wikipedia.org/wiki/Java_virtual_machine">Java virtual machine</a> or +by <a href="https://en.wikipedia.org/wiki/WebAssembly">WebAssembly</a> consists almost +entirely of low-level operations, similar to what physical CPUs implement: +basic math operators, comparisons, conditional jumps, and +instructions to move content between different memory locations. SQLite bytecode +has these kinds of low-level instructions, too. But SQLite bytecode also contains +some high-level operations that are specific to the needs of a database engine. +Here are just a few examples: + +</p><p> +</p><ul> +<li><p><b>OP_Column</b> → Extract the value from the N-th column of the +database row that a particular cursor is currently pointing at. +</p></li><li><p><b>OP_CreateBtree</b> → Allocate space for a new B-Tree in the +database file. +</p></li><li><p><b>OP_ParseSchema</b> → Reread and reparse all or part of the +<a href="schematab.html">sqlite_schema table</a> and refresh internal symbol tables accordingly. +</p></li><li><p><b>OP_SeekGE</b> → Move a cursor on a particular B-Tree to the first +entry that is greater than or equal to a given key. +</p></li><li><p><b>OP_Next</b> → Advance a cursor on a particular B-Tree to the next +entry in the B-Tree and jump, or fall through if there are no more entries in that +B-Tree. +</p></li></ul> + +<p>In other words, the "bytecode" used by SQLite is not so much a set of CPU +instructions as it is a list of database primitives that are to be run +in a particular order. + +</p><h2 id="definition_of_abstract_syntax_tree_or_ast_"><span>1.3. </span>Definition Of "Abstract Syntax Tree" or "AST"</h2> + +<p> +An "<a href="https://en.wikipedia.org/wiki/Abstract_syntax_tree">Abstract Syntax Tree</a>" or AST +is a data structure that describes a program or statement in some kind of formal +language. In our context, the formal language is SQL. An AST is typically +implemented as a tree of objects where each object represents one small part of +the overall SQL statement. ASTs emerge naturally from parsers for formal languages. +The usual technique is to use an +<a href="https://en.wikipedia.org/wiki/LALR_parser">LALR(1) parser</a>. +With such a parser, each terminal +symbol holds metadata that will become a leaf of the AST, and each non-terminal +symbol holds metadata that will become a sub-branch of the overall AST. +As rules of the grammar are "reduced" by the parser, new nodes of the AST are +allocated and connected to subnodes. +After the parse completes, the start-symbol of the grammar is left holding the +root of the AST. + +</p><p>An AST is a tree of objects. But an AST is not a suitable form for +a prepared statement. After being generated, an AST first needs to be +transformed in various ways before it can executed. Symbols need to be +resolved. Semantic rules need to be checked. Optimizations need to be +applied that transform input SQL statement into different forms that +execute more quickly. Finally, the AST needs to be translated into an +alternative representation that is more amenable to execution. + +</p><p>Some people refer to the tree of objects that is used as the +executable form for MySQL and PostgreSQL as an AST. This is probably a +misuse of the term "AST", because by the time the tree of objects is +ready to be executed, it has been changed so much that it has little +resemblance to the original SQL text. The confusion arises in part because +both the final prepared statement object and the original AST are both +trees of objects. The usual technique is for the original AST that comes +directly out of the parser to be transformed little by little, in multiple +passes, until at the end it is fully converted into an tree of objects +that is no longer strictly an AST but that can be evaluated to +generate a result. There is not necessarily a clear point during this +process when the tree-of-objects ceases to be an AST and becomes a +prepared statement instead. And because there is no clear boundary between an +AST and a prepared statement, people often refer to a prepared statement +that is represented as a tree of objects as an "AST", even though that +description is not precise. + +</p><h2 id="dataflow_programming"><span>1.4. </span>Dataflow Programming</h2> + +<p><a href="https://en.wikipedia.org/wiki/Dataflow_programming">Dataflow programming</a> +is a style of programming in which individual nodes specialize in doing +one small part of the overall computation. Each node receives inputs from +other nodes and sends its output to other nodes. Thus the nodes form a +directed graph that carry inputs into outputs. + +</p><p> +A "dataflow program" is perhaps a better description than "AST" for +the tree of objects that an SQL database engine uses as a prepared statement. + +</p><h1 id="advantages_to_compiling_into_bytecode"><span>2. </span>Advantages To Compiling Into Bytecode</h1> + +<p>SQLite compiles to bytecode, and the SQLite developers are very happy +with this approach. Here is why: + +</p><h2 id="bytecode_is_easier_to_understand"><span>2.1. </span>Bytecode Is Easier To Understand</h2> + +<p>A flat list of opcodes can be easily printed to see exactly +how an SQL statement is being implemented. This is what happens in SQLite +when you preface an SQL statement with the "EXPLAIN" keyword: Instead of +actually running the SQL, the result is a listing of the bytecode +that would have been used to implement that SQL. + +</p><p>Bytecode lends itself to this because a bytecode program is easily +represented as a table. In SQLite bytecode, each instruction +has one opcode and five operands. Thus a prepared statement can be +rendered as if it were a query against a six-column table. + +</p><p>A tree-of-objects representation is more difficult to publish in +a human-readable form. The objects that comprise the tree tend to +all be very different, and thus it is tricky to come up with a +consistent and simple table representation with which to display +the objects. Any such table representation that you do come up +with would almost certainly have more than six columns, probably many more. +The problem of rendering a tree-of-objects as a table is sufficiently +difficult that nobody does it, as far as I know. Hence, no +tree-of-objects database engine provides the level +of detail in their "EXPLAIN" output that SQLite provides. + +</p><h2 id="bytecode_is_easier_to_debug"><span>2.2. </span>Bytecode Is Easier To Debug</h2> + +<p>Bytecode provides a clear separation between front-end parsing and +analysis and back-end evaluation of an SQL statement. When problems arise +(incorrect answers and/or poor performance), the developers can examine +the bytecode to quickly determine if the source of the trouble is either the +front-end analysis or the back-end data storage section of the product. + +</p><p>In debugging builds of SQLite, the <a href="pragma.html#pragma_vdbe_trace">PRAGMA vdbe_trace=ON;</a> command will +cause a trace of the bytecode execution to appear on the console. + +</p><h2 id="bytecode_can_be_run_incrementally"><span>2.3. </span>Bytecode Can Be Run Incrementally</h2> + +<p> +SQL statements written in bytecode can be evaluated incrementally. +For example, a statement can be run until it generates just its first +row of output. The statement then pauses until it is stepped again. +It is not necessary to run the statement to completion before examining +the first row of output. + +</p><p> +This is more difficult to achieve in a tree-of-objects design. When +the prepared statement is a tree-of-objects, execution is normally +accomplished by walking the tree. To pause the statement in the middle +of a computation means unwinding the stack back up to the caller, all +the while saving enough state to resume evaluation where it last left +off. This is not impossible to do, but is sufficiently difficult that +I have never seen it actually done. + +</p><p> +Most SQL database engines do not really need to do incremental +execution of prepared statements because most SQL database engines +are client/server. In client/server engines, a single SQL statement is sent +to the server, then the complete reply comes back over the wire +all at once. Thus each statement runs to completion in a single go. +But SQLite is not client/server. SQLite is a library +that runs in the same address space and using the same stack as the +application. Being able to easily and reliably perform incremental +execution of an SQL statement is important to SQLite. + +</p><h2 id="bytecode_is_smaller"><span>2.4. </span>Bytecode Is Smaller</h2> + +<p> +The bytecode generated by SQLite is usually smaller than the corresponding +AST coming out of the parser. During initial processing of SQL text +(during the call to <a href="c3ref/prepare.html">sqlite3_prepare()</a> and similar) both the AST and the +bytecode exist in memory at the same time, so more memory is used then. +But that is a transient state. The AST +is quickly discarded and its memory recycled, even before the call to +<a href="c3ref/prepare.html">sqlite3_prepare()</a> returns, so the resulting <a href="c3ref/stmt.html">prepared statement</a> ends +up consuming less memory in its bytecode representation than it did as an AST. +This is important because calls to <a href="c3ref/prepare.html">sqlite3_prepare()</a> are transient, but +prepared statements are often cached for possible reuse and persist in memory +for a long time. + +</p><h2 id="bytecode_is_faster"><span>2.5. </span>Bytecode Is Faster</h2> + +<p> +I <i>believe</i> that a bytecode representation of a prepared statement +runs faster, because fewer decisions need to be made for each step of +the computation. Emphasis on "believe" in the previous sentence +→ it is difficult to verify +this claim experimentally since nobody has ever put in the multiple years +of effort necessary to generate equivalent bytecode and tree-of-object +representations of a prepared statement to see which one actually runs faster. +We do know that <a href="fasterthanfs.html">SQLite is very fast</a>, but we +do not have good side-by-side comparisons with other SQL databases since +the other databases spend a lot of time doing client/server message processing, +and it is difficult to untangle the message round-trip overhead from the +actual processing time. + +</p><h1 id="advantages_of_compiling_into_a_tree_of_objects"><span>3. </span>Advantages Of Compiling Into A Tree Of Objects</h1> + +<p>The SQLite developers think that the bytecode approach is +best, at least for the use cases the SQLite tries to fill, but the +tree-of-objects approach to processing SQL does have some advantages over +bytecode. There are always tradeoffs. + +</p><h2 id="query_planning_decisions_can_be_deferred_until_runtime"><span>3.1. </span>Query Planning Decisions Can Be Deferred Until Runtime</h2> + +<p> +When a prepared statement is bytecode, once the bytecode has been generated, +the algorithm is fixed and cannot be subsequently changed without completely +rewriting the bytecode. +This is not the case with a tree-of-objects prepared +statement. A tree-of-objects is easier to modify on-the-fly. The query +plan is mutable and can be tweaked as it is running, based on the progress +of the query. Thus a query can be dynamically self-tuning. + +</p><h2 id="dataflow_programs_are_easy_to_parallelize"><span>3.2. </span>Dataflow Programs Are Easy To Parallelize</h2> + +<p>In a dataflow program, each processing node can be assigned to a +different thread. There needs to be some kind of threadsafe queuing +mechanism for transferring intermediate results from one node to the +next. But no synchronization primitives are typically needed within +each node of the program. Node schedule is trivial: A node becomes +eligible to run when it has data available and there is space in its +output queue. + +</p><p>This is an important consideration for database engines that are +designed to run large analytic queries +(<a href="https://en.wikipedia.org/wiki/Online_analytical_processing">OLAP</a>) +on large multi-core servers. +The primary focus of SQLite is transaction processing +(<a href="https://en.wikipedia.org/wiki/Online_transaction_processing">OLTP</a>) +on the internet-of-things, so there is less need to +represent prepared statements as dataflow programs in SQLite. +</p><p align="center"><small><i>This page last modified on <a href="https://sqlite.org/docsrc/honeypot" id="mtimelink" data-href="https://sqlite.org/docsrc/finfo/pages/whybytecode.in?m=d62430c8d6">2024-05-09 17:38:03</a> UTC </small></i></p> + diff --git a/www/windowfunctions.html b/www/windowfunctions.html index d210532..3acd831 100644 --- a/www/windowfunctions.html +++ b/www/windowfunctions.html @@ -175,8 +175,8 @@ have a FILTER clause in between the function and the OVER clause. <p><b><a href="syntax/window-function-invocation.html">window-function-invocation:</a></b> -<button id='x44e4cb77' onclick='hideorshow("x44e4cb77","xb008b89c")'>hide</button></p> - <div id='xb008b89c' class='imgcontainer'> +<button id='x48ad4271' onclick='hideorshow("x48ad4271","x53925228")'>hide</button></p> + <div id='x53925228' class='imgcontainer'> <div style="max-width:870px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 870.446 132.84"> <circle cx="5" cy="55" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="32,55 20,59 20,50" style="fill:rgb(0,0,0)"/> @@ -232,8 +232,8 @@ have a FILTER clause in between the function and the OVER clause. </svg> </div> <p><b><a href="syntax/expr.html">expr:</a></b> -<button id='xde55489c' onclick='hideorshow("xde55489c","xab0ca079")'>show</button></p> - <div id='xab0ca079' style='display:none;' class='imgcontainer'> +<button id='xb2746424' onclick='hideorshow("xb2746424","x64380fba")'>show</button></p> + <div id='x64380fba' style='display:none;' class='imgcontainer'> <div style="max-width:963px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 963.96 1068.77"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="45,17 33,21 33,12" style="fill:rgb(0,0,0)"/> @@ -714,8 +714,8 @@ have a FILTER clause in between the function and the OVER clause. </svg> </div> <p><b><a href="syntax/function-arguments.html">function-arguments:</a></b> -<button id='xd8262bee' onclick='hideorshow("xd8262bee","xc4e3ffe6")'>show</button></p> - <div id='xc4e3ffe6' style='display:none;' class='imgcontainer'> +<button id='x4478980c' onclick='hideorshow("x4478980c","xb3d62a12")'>show</button></p> + <div id='xb3d62a12' style='display:none;' class='imgcontainer'> <div style="max-width:456px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 456.566 223.344"> <circle cx="5" cy="56" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="32,56 20,60 20,52" style="fill:rgb(0,0,0)"/> @@ -777,8 +777,8 @@ have a FILTER clause in between the function and the OVER clause. </svg> </div> <p><b><a href="syntax/ordering-term.html">ordering-term:</a></b> -<button id='x98ae4005' onclick='hideorshow("x98ae4005","x0a87bd5c")'>show</button></p> - <div id='x0a87bd5c' style='display:none;' class='imgcontainer'> +<button id='x76291b21' onclick='hideorshow("x76291b21","x7d4fd215")'>show</button></p> + <div id='x7d4fd215' style='display:none;' class='imgcontainer'> <div style="max-width:798px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 798.451 99.576"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="32,17 20,21 20,12" style="fill:rgb(0,0,0)"/> @@ -839,8 +839,8 @@ have a FILTER clause in between the function and the OVER clause. </div> </div> <p><b><a href="syntax/literal-value.html">literal-value:</a></b> -<button id='x4a625953' onclick='hideorshow("x4a625953","x9125574b")'>show</button></p> - <div id='x9125574b' style='display:none;' class='imgcontainer'> +<button id='x215fbba5' onclick='hideorshow("x215fbba5","x81da5fe3")'>show</button></p> + <div id='x81da5fe3' style='display:none;' class='imgcontainer'> <div style="max-width:341px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 341.376 336.96"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="50,319 39,324 39,315" style="fill:rgb(0,0,0)"/> @@ -910,8 +910,8 @@ have a FILTER clause in between the function and the OVER clause. </div> </div> <p><b><a href="syntax/over-clause.html">over-clause:</a></b> -<button id='xb0bfa350' onclick='hideorshow("xb0bfa350","x3b0338ed")'>show</button></p> - <div id='x3b0338ed' style='display:none;' class='imgcontainer'> +<button id='x1113251e' onclick='hideorshow("x1113251e","xff163cd6")'>show</button></p> + <div id='xff163cd6' style='display:none;' class='imgcontainer'> <div style="max-width:600px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 600.706 418.392"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="32,17 20,21 20,12" style="fill:rgb(0,0,0)"/> @@ -1002,8 +1002,8 @@ have a FILTER clause in between the function and the OVER clause. </svg> </div> <p><b><a href="syntax/frame-spec.html">frame-spec:</a></b> -<button id='x2961ee84' onclick='hideorshow("x2961ee84","x04891692")'>hide</button></p> - <div id='x04891692' class='imgcontainer'> +<button id='x4e8e9265' onclick='hideorshow("x4e8e9265","x17ffaecd")'>hide</button></p> + <div id='x17ffaecd' class='imgcontainer'> <div style="max-width:1039px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 1039.65 522.72"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="50,92 39,97 39,88" style="fill:rgb(0,0,0)"/> @@ -1212,8 +1212,8 @@ have a FILTER clause in between the function and the OVER clause. </div> </div> <p><b><a href="syntax/ordering-term.html">ordering-term:</a></b> -<button id='xcf7c2f66' onclick='hideorshow("xcf7c2f66","x4da0c1d5")'>show</button></p> - <div id='x4da0c1d5' style='display:none;' class='imgcontainer'> +<button id='x8e41936b' onclick='hideorshow("x8e41936b","x6fd1ecaf")'>show</button></p> + <div id='x6fd1ecaf' style='display:none;' class='imgcontainer'> <div style="max-width:798px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 798.451 99.576"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="32,17 20,21 20,12" style="fill:rgb(0,0,0)"/> @@ -1274,8 +1274,8 @@ have a FILTER clause in between the function and the OVER clause. </div> </div> <p><b><a href="syntax/raise-function.html">raise-function:</a></b> -<button id='xd499344a' onclick='hideorshow("xd499344a","x86451066")'>show</button></p> - <div id='x86451066' style='display:none;' class='imgcontainer'> +<button id='x994542dd' onclick='hideorshow("x994542dd","x8b34c08b")'>show</button></p> + <div id='x8b34c08b' style='display:none;' class='imgcontainer'> <div style="max-width:627px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 627.302 147.96"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="32,17 20,21 20,12" style="fill:rgb(0,0,0)"/> @@ -1330,8 +1330,8 @@ have a FILTER clause in between the function and the OVER clause. </div> </div> <p><b><a href="syntax/select-stmt.html">select-stmt:</a></b> -<button id='x3e9b2388' onclick='hideorshow("x3e9b2388","x1db2093e")'>show</button></p> - <div id='x1db2093e' style='display:none;' class='imgcontainer'> +<button id='x0ed31772' onclick='hideorshow("x0ed31772","x95a67155")'>show</button></p> + <div id='x95a67155' style='display:none;' class='imgcontainer'> <div style="max-width:669px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 669.677 1162.3"> <path d="M55,845L667,845L667,99L55,99Z" style="fill:none;stroke-width:3.24;stroke:rgb(211,211,211);" /> <circle cx="6" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> @@ -1609,8 +1609,8 @@ have a FILTER clause in between the function and the OVER clause. </svg> </div> <p><b><a href="syntax/common-table-expression.html">common-table-expression:</a></b> -<button id='x22e81d6a' onclick='hideorshow("x22e81d6a","x4c1ab371")'>show</button></p> - <div id='x4c1ab371' style='display:none;' class='imgcontainer'> +<button id='x5c775959' onclick='hideorshow("x5c775959","x4c86bd0e")'>show</button></p> + <div id='x4c86bd0e' style='display:none;' class='imgcontainer'> <div style="max-width:638px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 638.525 167.4"> <circle cx="5" cy="29" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="32,29 20,33 20,24" style="fill:rgb(0,0,0)"/> @@ -1680,8 +1680,8 @@ have a FILTER clause in between the function and the OVER clause. </div> </div> <p><b><a href="syntax/compound-operator.html">compound-operator:</a></b> -<button id='x89950653' onclick='hideorshow("x89950653","xceff8d96")'>show</button></p> - <div id='xceff8d96' style='display:none;' class='imgcontainer'> +<button id='x2a0433b1' onclick='hideorshow("x2a0433b1","x2a5ff775")'>show</button></p> + <div id='x2a5ff775' style='display:none;' class='imgcontainer'> <div style="max-width:293px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 293.842 147.96"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="32,17 20,21 20,12" style="fill:rgb(0,0,0)"/> @@ -1722,8 +1722,8 @@ have a FILTER clause in between the function and the OVER clause. </div> </div> <p><b><a href="syntax/join-clause.html">join-clause:</a></b> -<button id='x5ecb3f06' onclick='hideorshow("x5ecb3f06","x25642fa8")'>show</button></p> - <div id='x25642fa8' style='display:none;' class='imgcontainer'> +<button id='x3513ae9f' onclick='hideorshow("x3513ae9f","x25979698")'>show</button></p> + <div id='x25979698' style='display:none;' class='imgcontainer'> <div style="max-width:793px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 793.282 84.24"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="32,17 20,21 20,12" style="fill:rgb(0,0,0)"/> @@ -1754,8 +1754,8 @@ have a FILTER clause in between the function and the OVER clause. </svg> </div> <p><b><a href="syntax/join-constraint.html">join-constraint:</a></b> -<button id='x9f0e73e3' onclick='hideorshow("x9f0e73e3","x105195d3")'>show</button></p> - <div id='x105195d3' style='display:none;' class='imgcontainer'> +<button id='x7994968a' onclick='hideorshow("x7994968a","x2661b185")'>show</button></p> + <div id='x2661b185' style='display:none;' class='imgcontainer'> <div style="max-width:483px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 483.336 126.576"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="50,55 39,59 39,50" style="fill:rgb(0,0,0)"/> @@ -1802,8 +1802,8 @@ have a FILTER clause in between the function and the OVER clause. </div> </div> <p><b><a href="syntax/join-operator.html">join-operator:</a></b> -<button id='xfa31f036' onclick='hideorshow("xfa31f036","x58a596b4")'>show</button></p> - <div id='x58a596b4' style='display:none;' class='imgcontainer'> +<button id='x42064693' onclick='hideorshow("x42064693","x950dfd4a")'>show</button></p> + <div id='x950dfd4a' style='display:none;' class='imgcontainer'> <div style="max-width:620px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 620.333 255.312"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="50,71 39,76 39,67" style="fill:rgb(0,0,0)"/> @@ -1870,8 +1870,8 @@ have a FILTER clause in between the function and the OVER clause. </div> </div> <p><b><a href="syntax/ordering-term.html">ordering-term:</a></b> -<button id='x50e5887c' onclick='hideorshow("x50e5887c","x3985c24c")'>show</button></p> - <div id='x3985c24c' style='display:none;' class='imgcontainer'> +<button id='xd4106520' onclick='hideorshow("xd4106520","x5cd745fd")'>show</button></p> + <div id='x5cd745fd' style='display:none;' class='imgcontainer'> <div style="max-width:798px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 798.451 99.576"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="32,17 20,21 20,12" style="fill:rgb(0,0,0)"/> @@ -1931,8 +1931,8 @@ have a FILTER clause in between the function and the OVER clause. </div> </div> <p><b><a href="syntax/result-column.html">result-column:</a></b> -<button id='x0857d62f' onclick='hideorshow("x0857d62f","x094cf564")'>show</button></p> - <div id='x094cf564' style='display:none;' class='imgcontainer'> +<button id='x409b09bb' onclick='hideorshow("x409b09bb","x875cc923")'>show</button></p> + <div id='x875cc923' style='display:none;' class='imgcontainer'> <div style="max-width:398px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 398.054 163.08"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="45,17 33,21 33,12" style="fill:rgb(0,0,0)"/> @@ -1984,8 +1984,8 @@ have a FILTER clause in between the function and the OVER clause. </div> </div> <p><b><a href="syntax/table-or-subquery.html">table-or-subquery:</a></b> -<button id='xee1e290d' onclick='hideorshow("xee1e290d","x1d3f9721")'>show</button></p> - <div id='x1d3f9721' style='display:none;' class='imgcontainer'> +<button id='x827d9266' onclick='hideorshow("x827d9266","x9829c2ab")'>show</button></p> + <div id='x9829c2ab' style='display:none;' class='imgcontainer'> <div style="max-width:720px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 720.778 457.704"> <circle cx="5" cy="36" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="50,74 39,78 39,70" style="fill:rgb(0,0,0)"/> @@ -2130,8 +2130,8 @@ have a FILTER clause in between the function and the OVER clause. </div> </div> <p><b><a href="syntax/type-name.html">type-name:</a></b> -<button id='xcf057e45' onclick='hideorshow("xcf057e45","xdd8e2cf1")'>show</button></p> - <div id='xdd8e2cf1' style='display:none;' class='imgcontainer'> +<button id='x9818642d' onclick='hideorshow("x9818642d","x6455eb06")'>show</button></p> + <div id='x6455eb06' style='display:none;' class='imgcontainer'> <div style="max-width:661px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 661.008 110.16"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="45,17 33,21 33,12" style="fill:rgb(0,0,0)"/> @@ -2185,8 +2185,8 @@ have a FILTER clause in between the function and the OVER clause. </svg> </div> <p><b><a href="syntax/signed-number.html">signed-number:</a></b> -<button id='xbfbe88e9' onclick='hideorshow("xbfbe88e9","x27d3cd5a")'>show</button></p> - <div id='x27d3cd5a' style='display:none;' class='imgcontainer'> +<button id='x75542a8b' onclick='hideorshow("x75542a8b","x04d29758")'>show</button></p> + <div id='x04d29758' style='display:none;' class='imgcontainer'> <div style="max-width:292px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 292.013 99.576"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="50,44 39,48 39,40" style="fill:rgb(0,0,0)"/> @@ -2214,8 +2214,8 @@ have a FILTER clause in between the function and the OVER clause. </div> </div> <p><b><a href="syntax/filter-clause.html">filter-clause:</a></b> -<button id='x42666c57' onclick='hideorshow("x42666c57","x3adc8ba7")'>hide</button></p> - <div id='x3adc8ba7' class='imgcontainer'> +<button id='xf2f57ed1' onclick='hideorshow("xf2f57ed1","xe8bc788f")'>hide</button></p> + <div id='xe8bc788f' class='imgcontainer'> <div style="max-width:422px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 422.381 34.56"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="32,17 20,21 20,12" style="fill:rgb(0,0,0)"/> @@ -2245,8 +2245,8 @@ have a FILTER clause in between the function and the OVER clause. </div> </div> <p><b><a href="syntax/window-defn.html">window-defn:</a></b> -<button id='x792b9975' onclick='hideorshow("x792b9975","x477af11c")'>hide</button></p> - <div id='x477af11c' class='imgcontainer'> +<button id='x0ac8b2da' onclick='hideorshow("x0ac8b2da","x8e58a488")'>hide</button></p> + <div id='x8e58a488' class='imgcontainer'> <div style="max-width:479px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 479.765 380.592"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="32,17 20,21 20,12" style="fill:rgb(0,0,0)"/> @@ -2326,8 +2326,8 @@ have a FILTER clause in between the function and the OVER clause. </svg> </div> <p><b><a href="syntax/frame-spec.html">frame-spec:</a></b> -<button id='x3af3f931' onclick='hideorshow("x3af3f931","xc7f772f6")'>hide</button></p> - <div id='xc7f772f6' class='imgcontainer'> +<button id='xdbb8ae77' onclick='hideorshow("xdbb8ae77","x0842b931")'>hide</button></p> + <div id='x0842b931' class='imgcontainer'> <div style="max-width:1039px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 1039.65 522.72"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="50,92 39,97 39,88" style="fill:rgb(0,0,0)"/> @@ -2536,8 +2536,8 @@ have a FILTER clause in between the function and the OVER clause. </div> </div> <p><b><a href="syntax/ordering-term.html">ordering-term:</a></b> -<button id='xe0fe7824' onclick='hideorshow("xe0fe7824","x537a9e34")'>show</button></p> - <div id='x537a9e34' style='display:none;' class='imgcontainer'> +<button id='xb69c6776' onclick='hideorshow("xb69c6776","xd86e3a7e")'>show</button></p> + <div id='xd86e3a7e' style='display:none;' class='imgcontainer'> <div style="max-width:798px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 798.451 99.576"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="32,17 20,21 20,12" style="fill:rgb(0,0,0)"/> @@ -2609,7 +2609,7 @@ ORDER BY clause of a SELECT statement. </p><p>Window functions come in two varieties: <a href="windowfunctions.html#aggwinfunc">aggregate window functions</a> and <a href="windowfunctions.html#builtins">built-in window functions</a>. Every aggregate window function -can also work as a ordinary aggregate function, simply by omitting +can also work as an ordinary aggregate function, simply by omitting the OVER and FILTER clauses. Furthermore, all of the built-in <a href="lang_aggfunc.html">aggregate functions</a> of SQLite can be used as an aggregate window function by adding an appropriate OVER clause. @@ -2797,8 +2797,8 @@ read by an aggregate window function. The <p> Here are the syntax details: <p><b><a href="syntax/frame-spec.html">frame-spec:</a></b> -<button id='x0199aef6' onclick='hideorshow("x0199aef6","x56b9bd0c")'>hide</button></p> - <div id='x56b9bd0c' class='imgcontainer'> +<button id='x2d48b895' onclick='hideorshow("x2d48b895","xf29b33b1")'>hide</button></p> + <div id='xf29b33b1' class='imgcontainer'> <div style="max-width:1039px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 1039.65 522.72"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="50,92 39,97 39,88" style="fill:rgb(0,0,0)"/> @@ -3006,8 +3006,8 @@ read by an aggregate window function. The </svg> </div> <p><b><a href="syntax/expr.html">expr:</a></b> -<button id='xac4aee76' onclick='hideorshow("xac4aee76","x789c4ff5")'>show</button></p> - <div id='x789c4ff5' style='display:none;' class='imgcontainer'> +<button id='x535031ae' onclick='hideorshow("x535031ae","x5898a7c9")'>show</button></p> + <div id='x5898a7c9' style='display:none;' class='imgcontainer'> <div style="max-width:963px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 963.96 1068.77"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="45,17 33,21 33,12" style="fill:rgb(0,0,0)"/> @@ -3488,8 +3488,8 @@ read by an aggregate window function. The </svg> </div> <p><b><a href="syntax/filter-clause.html">filter-clause:</a></b> -<button id='x6e5adba8' onclick='hideorshow("x6e5adba8","xdbb0e8d4")'>show</button></p> - <div id='xdbb0e8d4' style='display:none;' class='imgcontainer'> +<button id='xa2ba9142' onclick='hideorshow("xa2ba9142","xb4adf57b")'>show</button></p> + <div id='xb4adf57b' style='display:none;' class='imgcontainer'> <div style="max-width:422px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 422.381 34.56"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="32,17 20,21 20,12" style="fill:rgb(0,0,0)"/> @@ -3519,8 +3519,8 @@ read by an aggregate window function. The </div> </div> <p><b><a href="syntax/function-arguments.html">function-arguments:</a></b> -<button id='x62f7c893' onclick='hideorshow("x62f7c893","x2e28c5e5")'>show</button></p> - <div id='x2e28c5e5' style='display:none;' class='imgcontainer'> +<button id='xde7e5666' onclick='hideorshow("xde7e5666","x7c405d41")'>show</button></p> + <div id='x7c405d41' style='display:none;' class='imgcontainer'> <div style="max-width:456px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 456.566 223.344"> <circle cx="5" cy="56" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="32,56 20,60 20,52" style="fill:rgb(0,0,0)"/> @@ -3582,8 +3582,8 @@ read by an aggregate window function. The </svg> </div> <p><b><a href="syntax/ordering-term.html">ordering-term:</a></b> -<button id='xa4e5c48b' onclick='hideorshow("xa4e5c48b","xf02c44ea")'>show</button></p> - <div id='xf02c44ea' style='display:none;' class='imgcontainer'> +<button id='xaca473da' onclick='hideorshow("xaca473da","xbdfb6faa")'>show</button></p> + <div id='xbdfb6faa' style='display:none;' class='imgcontainer'> <div style="max-width:798px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 798.451 99.576"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="32,17 20,21 20,12" style="fill:rgb(0,0,0)"/> @@ -3644,8 +3644,8 @@ read by an aggregate window function. The </div> </div> <p><b><a href="syntax/literal-value.html">literal-value:</a></b> -<button id='x7c347ea1' onclick='hideorshow("x7c347ea1","x94bc3bbf")'>show</button></p> - <div id='x94bc3bbf' style='display:none;' class='imgcontainer'> +<button id='x8c815ca5' onclick='hideorshow("x8c815ca5","xf97a6947")'>show</button></p> + <div id='xf97a6947' style='display:none;' class='imgcontainer'> <div style="max-width:341px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 341.376 336.96"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="50,319 39,324 39,315" style="fill:rgb(0,0,0)"/> @@ -3715,8 +3715,8 @@ read by an aggregate window function. The </div> </div> <p><b><a href="syntax/over-clause.html">over-clause:</a></b> -<button id='x52470a2d' onclick='hideorshow("x52470a2d","x792b8a02")'>show</button></p> - <div id='x792b8a02' style='display:none;' class='imgcontainer'> +<button id='x316aaf72' onclick='hideorshow("x316aaf72","x9c859035")'>show</button></p> + <div id='x9c859035' style='display:none;' class='imgcontainer'> <div style="max-width:600px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 600.706 418.392"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="32,17 20,21 20,12" style="fill:rgb(0,0,0)"/> @@ -3807,8 +3807,8 @@ read by an aggregate window function. The </svg> </div> <p><b><a href="syntax/ordering-term.html">ordering-term:</a></b> -<button id='x85933096' onclick='hideorshow("x85933096","x08cc4720")'>show</button></p> - <div id='x08cc4720' style='display:none;' class='imgcontainer'> +<button id='xcbe16931' onclick='hideorshow("xcbe16931","x134b52e3")'>show</button></p> + <div id='x134b52e3' style='display:none;' class='imgcontainer'> <div style="max-width:798px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 798.451 99.576"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="32,17 20,21 20,12" style="fill:rgb(0,0,0)"/> @@ -3869,8 +3869,8 @@ read by an aggregate window function. The </div> </div> <p><b><a href="syntax/raise-function.html">raise-function:</a></b> -<button id='x78ec9ddf' onclick='hideorshow("x78ec9ddf","xaaf6e4dd")'>show</button></p> - <div id='xaaf6e4dd' style='display:none;' class='imgcontainer'> +<button id='xe58b1bb9' onclick='hideorshow("xe58b1bb9","x544978e2")'>show</button></p> + <div id='x544978e2' style='display:none;' class='imgcontainer'> <div style="max-width:627px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 627.302 147.96"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="32,17 20,21 20,12" style="fill:rgb(0,0,0)"/> @@ -3925,8 +3925,8 @@ read by an aggregate window function. The </div> </div> <p><b><a href="syntax/select-stmt.html">select-stmt:</a></b> -<button id='x55ed670b' onclick='hideorshow("x55ed670b","x8d102754")'>show</button></p> - <div id='x8d102754' style='display:none;' class='imgcontainer'> +<button id='xd6121c61' onclick='hideorshow("xd6121c61","xb2ebe95d")'>show</button></p> + <div id='xb2ebe95d' style='display:none;' class='imgcontainer'> <div style="max-width:669px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 669.677 1162.3"> <path d="M55,845L667,845L667,99L55,99Z" style="fill:none;stroke-width:3.24;stroke:rgb(211,211,211);" /> <circle cx="6" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> @@ -4204,8 +4204,8 @@ read by an aggregate window function. The </svg> </div> <p><b><a href="syntax/common-table-expression.html">common-table-expression:</a></b> -<button id='xb5f243c6' onclick='hideorshow("xb5f243c6","x9ff2c574")'>show</button></p> - <div id='x9ff2c574' style='display:none;' class='imgcontainer'> +<button id='xcdb1b778' onclick='hideorshow("xcdb1b778","xae5136de")'>show</button></p> + <div id='xae5136de' style='display:none;' class='imgcontainer'> <div style="max-width:638px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 638.525 167.4"> <circle cx="5" cy="29" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="32,29 20,33 20,24" style="fill:rgb(0,0,0)"/> @@ -4275,8 +4275,8 @@ read by an aggregate window function. The </div> </div> <p><b><a href="syntax/compound-operator.html">compound-operator:</a></b> -<button id='x91d419e5' onclick='hideorshow("x91d419e5","x5d685770")'>show</button></p> - <div id='x5d685770' style='display:none;' class='imgcontainer'> +<button id='xab893daf' onclick='hideorshow("xab893daf","xcbd83a12")'>show</button></p> + <div id='xcbd83a12' style='display:none;' class='imgcontainer'> <div style="max-width:293px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 293.842 147.96"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="32,17 20,21 20,12" style="fill:rgb(0,0,0)"/> @@ -4317,8 +4317,8 @@ read by an aggregate window function. The </div> </div> <p><b><a href="syntax/join-clause.html">join-clause:</a></b> -<button id='xefb9c824' onclick='hideorshow("xefb9c824","x3aab8e3c")'>show</button></p> - <div id='x3aab8e3c' style='display:none;' class='imgcontainer'> +<button id='xde46189e' onclick='hideorshow("xde46189e","x948e1885")'>show</button></p> + <div id='x948e1885' style='display:none;' class='imgcontainer'> <div style="max-width:793px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 793.282 84.24"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="32,17 20,21 20,12" style="fill:rgb(0,0,0)"/> @@ -4349,8 +4349,8 @@ read by an aggregate window function. The </svg> </div> <p><b><a href="syntax/join-constraint.html">join-constraint:</a></b> -<button id='x1bff3899' onclick='hideorshow("x1bff3899","x2354f933")'>show</button></p> - <div id='x2354f933' style='display:none;' class='imgcontainer'> +<button id='xd1111596' onclick='hideorshow("xd1111596","x60d743e2")'>show</button></p> + <div id='x60d743e2' style='display:none;' class='imgcontainer'> <div style="max-width:483px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 483.336 126.576"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="50,55 39,59 39,50" style="fill:rgb(0,0,0)"/> @@ -4397,8 +4397,8 @@ read by an aggregate window function. The </div> </div> <p><b><a href="syntax/join-operator.html">join-operator:</a></b> -<button id='xd89646f0' onclick='hideorshow("xd89646f0","x06401d72")'>show</button></p> - <div id='x06401d72' style='display:none;' class='imgcontainer'> +<button id='xd0cf6393' onclick='hideorshow("xd0cf6393","x2f88c1d8")'>show</button></p> + <div id='x2f88c1d8' style='display:none;' class='imgcontainer'> <div style="max-width:620px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 620.333 255.312"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="50,71 39,76 39,67" style="fill:rgb(0,0,0)"/> @@ -4465,8 +4465,8 @@ read by an aggregate window function. The </div> </div> <p><b><a href="syntax/ordering-term.html">ordering-term:</a></b> -<button id='xfb6a9b78' onclick='hideorshow("xfb6a9b78","xad22eab0")'>show</button></p> - <div id='xad22eab0' style='display:none;' class='imgcontainer'> +<button id='x32cb9fc5' onclick='hideorshow("x32cb9fc5","xa1e90b9e")'>show</button></p> + <div id='xa1e90b9e' style='display:none;' class='imgcontainer'> <div style="max-width:798px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 798.451 99.576"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="32,17 20,21 20,12" style="fill:rgb(0,0,0)"/> @@ -4526,8 +4526,8 @@ read by an aggregate window function. The </div> </div> <p><b><a href="syntax/result-column.html">result-column:</a></b> -<button id='xdb83a7b9' onclick='hideorshow("xdb83a7b9","xcca4ae9d")'>show</button></p> - <div id='xcca4ae9d' style='display:none;' class='imgcontainer'> +<button id='x445e0b16' onclick='hideorshow("x445e0b16","xaa77a6e7")'>show</button></p> + <div id='xaa77a6e7' style='display:none;' class='imgcontainer'> <div style="max-width:398px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 398.054 163.08"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="45,17 33,21 33,12" style="fill:rgb(0,0,0)"/> @@ -4579,8 +4579,8 @@ read by an aggregate window function. The </div> </div> <p><b><a href="syntax/table-or-subquery.html">table-or-subquery:</a></b> -<button id='x5c9faa54' onclick='hideorshow("x5c9faa54","x02ce5f50")'>show</button></p> - <div id='x02ce5f50' style='display:none;' class='imgcontainer'> +<button id='xc19e5848' onclick='hideorshow("xc19e5848","xe56e459d")'>show</button></p> + <div id='xe56e459d' style='display:none;' class='imgcontainer'> <div style="max-width:720px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 720.778 457.704"> <circle cx="5" cy="36" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="50,74 39,78 39,70" style="fill:rgb(0,0,0)"/> @@ -4724,8 +4724,8 @@ read by an aggregate window function. The </div> </div> <p><b><a href="syntax/window-defn.html">window-defn:</a></b> -<button id='xb0d1461b' onclick='hideorshow("xb0d1461b","xa8f015e1")'>show</button></p> - <div id='xa8f015e1' style='display:none;' class='imgcontainer'> +<button id='x02de707e' onclick='hideorshow("x02de707e","xe3bca836")'>show</button></p> + <div id='xe3bca836' style='display:none;' class='imgcontainer'> <div style="max-width:479px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 479.765 380.592"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="32,17 20,21 20,12" style="fill:rgb(0,0,0)"/> @@ -4807,8 +4807,8 @@ read by an aggregate window function. The </div> </div> <p><b><a href="syntax/type-name.html">type-name:</a></b> -<button id='x187bb7f1' onclick='hideorshow("x187bb7f1","x2230c8ce")'>show</button></p> - <div id='x2230c8ce' style='display:none;' class='imgcontainer'> +<button id='xd448932b' onclick='hideorshow("xd448932b","xe9a3227c")'>show</button></p> + <div id='xe9a3227c' style='display:none;' class='imgcontainer'> <div style="max-width:661px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 661.008 110.16"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="45,17 33,21 33,12" style="fill:rgb(0,0,0)"/> @@ -4862,8 +4862,8 @@ read by an aggregate window function. The </svg> </div> <p><b><a href="syntax/signed-number.html">signed-number:</a></b> -<button id='x2e27fd13' onclick='hideorshow("x2e27fd13","x3f3bc4fd")'>show</button></p> - <div id='x3f3bc4fd' style='display:none;' class='imgcontainer'> +<button id='x4bb1a0c0' onclick='hideorshow("x4bb1a0c0","x25a888e5")'>show</button></p> + <div id='x25a888e5' style='display:none;' class='imgcontainer'> <div style="max-width:292px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 292.013 99.576"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="50,44 39,48 39,40" style="fill:rgb(0,0,0)"/> @@ -5145,8 +5145,8 @@ FROM t1 ORDER BY c, a; <h2 id="the_filter_clause"><span>2.3. </span>The FILTER Clause</h2> <p><b><a href="syntax/filter-clause.html">filter-clause:</a></b> -<button id='x9c6ef48a' onclick='hideorshow("x9c6ef48a","x4dc11b33")'>hide</button></p> - <div id='x4dc11b33' class='imgcontainer'> +<button id='xdfe67349' onclick='hideorshow("xdfe67349","x80505591")'>hide</button></p> + <div id='x80505591' class='imgcontainer'> <div style="max-width:422px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 422.381 34.56"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="32,17 20,21 20,12" style="fill:rgb(0,0,0)"/> @@ -5175,8 +5175,8 @@ FROM t1 ORDER BY c, a; </svg> </div> <p><b><a href="syntax/expr.html">expr:</a></b> -<button id='xdc983a44' onclick='hideorshow("xdc983a44","x697d9515")'>show</button></p> - <div id='x697d9515' style='display:none;' class='imgcontainer'> +<button id='xa2fc8f5d' onclick='hideorshow("xa2fc8f5d","xb80e9d88")'>show</button></p> + <div id='xb80e9d88' style='display:none;' class='imgcontainer'> <div style="max-width:963px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 963.96 1068.77"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="45,17 33,21 33,12" style="fill:rgb(0,0,0)"/> @@ -5657,8 +5657,8 @@ FROM t1 ORDER BY c, a; </svg> </div> <p><b><a href="syntax/function-arguments.html">function-arguments:</a></b> -<button id='x7f57e866' onclick='hideorshow("x7f57e866","xd7a5c5d5")'>show</button></p> - <div id='xd7a5c5d5' style='display:none;' class='imgcontainer'> +<button id='xf6ac8e66' onclick='hideorshow("xf6ac8e66","xec5b4a4b")'>show</button></p> + <div id='xec5b4a4b' style='display:none;' class='imgcontainer'> <div style="max-width:456px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 456.566 223.344"> <circle cx="5" cy="56" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="32,56 20,60 20,52" style="fill:rgb(0,0,0)"/> @@ -5720,8 +5720,8 @@ FROM t1 ORDER BY c, a; </svg> </div> <p><b><a href="syntax/ordering-term.html">ordering-term:</a></b> -<button id='x085f9125' onclick='hideorshow("x085f9125","xa064d583")'>show</button></p> - <div id='xa064d583' style='display:none;' class='imgcontainer'> +<button id='x4dd4cd8d' onclick='hideorshow("x4dd4cd8d","x9cc14ebe")'>show</button></p> + <div id='x9cc14ebe' style='display:none;' class='imgcontainer'> <div style="max-width:798px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 798.451 99.576"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="32,17 20,21 20,12" style="fill:rgb(0,0,0)"/> @@ -5782,8 +5782,8 @@ FROM t1 ORDER BY c, a; </div> </div> <p><b><a href="syntax/literal-value.html">literal-value:</a></b> -<button id='x301b5e69' onclick='hideorshow("x301b5e69","x7dbaddb3")'>show</button></p> - <div id='x7dbaddb3' style='display:none;' class='imgcontainer'> +<button id='x28c234c3' onclick='hideorshow("x28c234c3","x8fafc3ce")'>show</button></p> + <div id='x8fafc3ce' style='display:none;' class='imgcontainer'> <div style="max-width:341px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 341.376 336.96"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="50,319 39,324 39,315" style="fill:rgb(0,0,0)"/> @@ -5853,8 +5853,8 @@ FROM t1 ORDER BY c, a; </div> </div> <p><b><a href="syntax/over-clause.html">over-clause:</a></b> -<button id='xd98e3155' onclick='hideorshow("xd98e3155","x17f939ee")'>show</button></p> - <div id='x17f939ee' style='display:none;' class='imgcontainer'> +<button id='x4682c9e8' onclick='hideorshow("x4682c9e8","xe4d4002e")'>show</button></p> + <div id='xe4d4002e' style='display:none;' class='imgcontainer'> <div style="max-width:600px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 600.706 418.392"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="32,17 20,21 20,12" style="fill:rgb(0,0,0)"/> @@ -5945,8 +5945,8 @@ FROM t1 ORDER BY c, a; </svg> </div> <p><b><a href="syntax/frame-spec.html">frame-spec:</a></b> -<button id='x36e52421' onclick='hideorshow("x36e52421","x0f9f75a4")'>show</button></p> - <div id='x0f9f75a4' style='display:none;' class='imgcontainer'> +<button id='xe32bb2d7' onclick='hideorshow("xe32bb2d7","x48dd3ee9")'>show</button></p> + <div id='x48dd3ee9' style='display:none;' class='imgcontainer'> <div style="max-width:1039px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 1039.65 522.72"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="50,92 39,97 39,88" style="fill:rgb(0,0,0)"/> @@ -6155,8 +6155,8 @@ FROM t1 ORDER BY c, a; </div> </div> <p><b><a href="syntax/ordering-term.html">ordering-term:</a></b> -<button id='x1df87fd8' onclick='hideorshow("x1df87fd8","x420baa92")'>show</button></p> - <div id='x420baa92' style='display:none;' class='imgcontainer'> +<button id='x4cead0b3' onclick='hideorshow("x4cead0b3","xb4ecb865")'>show</button></p> + <div id='xb4ecb865' style='display:none;' class='imgcontainer'> <div style="max-width:798px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 798.451 99.576"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="32,17 20,21 20,12" style="fill:rgb(0,0,0)"/> @@ -6217,8 +6217,8 @@ FROM t1 ORDER BY c, a; </div> </div> <p><b><a href="syntax/raise-function.html">raise-function:</a></b> -<button id='x4a5943b5' onclick='hideorshow("x4a5943b5","x85d7df8c")'>show</button></p> - <div id='x85d7df8c' style='display:none;' class='imgcontainer'> +<button id='x6dd82a26' onclick='hideorshow("x6dd82a26","xfec4a21d")'>show</button></p> + <div id='xfec4a21d' style='display:none;' class='imgcontainer'> <div style="max-width:627px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 627.302 147.96"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="32,17 20,21 20,12" style="fill:rgb(0,0,0)"/> @@ -6273,8 +6273,8 @@ FROM t1 ORDER BY c, a; </div> </div> <p><b><a href="syntax/select-stmt.html">select-stmt:</a></b> -<button id='xb11a1037' onclick='hideorshow("xb11a1037","x12d9418a")'>show</button></p> - <div id='x12d9418a' style='display:none;' class='imgcontainer'> +<button id='xc07d1e39' onclick='hideorshow("xc07d1e39","x063a4d98")'>show</button></p> + <div id='x063a4d98' style='display:none;' class='imgcontainer'> <div style="max-width:669px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 669.677 1162.3"> <path d="M55,845L667,845L667,99L55,99Z" style="fill:none;stroke-width:3.24;stroke:rgb(211,211,211);" /> <circle cx="6" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> @@ -6552,8 +6552,8 @@ FROM t1 ORDER BY c, a; </svg> </div> <p><b><a href="syntax/common-table-expression.html">common-table-expression:</a></b> -<button id='x09152732' onclick='hideorshow("x09152732","x4c0fda46")'>show</button></p> - <div id='x4c0fda46' style='display:none;' class='imgcontainer'> +<button id='xd4ddba1a' onclick='hideorshow("xd4ddba1a","xded90b1e")'>show</button></p> + <div id='xded90b1e' style='display:none;' class='imgcontainer'> <div style="max-width:638px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 638.525 167.4"> <circle cx="5" cy="29" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="32,29 20,33 20,24" style="fill:rgb(0,0,0)"/> @@ -6623,8 +6623,8 @@ FROM t1 ORDER BY c, a; </div> </div> <p><b><a href="syntax/compound-operator.html">compound-operator:</a></b> -<button id='xbe4aff98' onclick='hideorshow("xbe4aff98","xbacc089d")'>show</button></p> - <div id='xbacc089d' style='display:none;' class='imgcontainer'> +<button id='x9b0ac1ee' onclick='hideorshow("x9b0ac1ee","x2ead26cf")'>show</button></p> + <div id='x2ead26cf' style='display:none;' class='imgcontainer'> <div style="max-width:293px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 293.842 147.96"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="32,17 20,21 20,12" style="fill:rgb(0,0,0)"/> @@ -6665,8 +6665,8 @@ FROM t1 ORDER BY c, a; </div> </div> <p><b><a href="syntax/join-clause.html">join-clause:</a></b> -<button id='x09db4fdc' onclick='hideorshow("x09db4fdc","xf6525aa6")'>show</button></p> - <div id='xf6525aa6' style='display:none;' class='imgcontainer'> +<button id='xdda04908' onclick='hideorshow("xdda04908","x93f8cd90")'>show</button></p> + <div id='x93f8cd90' style='display:none;' class='imgcontainer'> <div style="max-width:793px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 793.282 84.24"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="32,17 20,21 20,12" style="fill:rgb(0,0,0)"/> @@ -6697,8 +6697,8 @@ FROM t1 ORDER BY c, a; </svg> </div> <p><b><a href="syntax/join-constraint.html">join-constraint:</a></b> -<button id='xf5b07b14' onclick='hideorshow("xf5b07b14","x7d470f23")'>show</button></p> - <div id='x7d470f23' style='display:none;' class='imgcontainer'> +<button id='x35740004' onclick='hideorshow("x35740004","x414583c7")'>show</button></p> + <div id='x414583c7' style='display:none;' class='imgcontainer'> <div style="max-width:483px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 483.336 126.576"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="50,55 39,59 39,50" style="fill:rgb(0,0,0)"/> @@ -6745,8 +6745,8 @@ FROM t1 ORDER BY c, a; </div> </div> <p><b><a href="syntax/join-operator.html">join-operator:</a></b> -<button id='x1f8f067e' onclick='hideorshow("x1f8f067e","x77621cba")'>show</button></p> - <div id='x77621cba' style='display:none;' class='imgcontainer'> +<button id='x0dcd7060' onclick='hideorshow("x0dcd7060","x90198d7e")'>show</button></p> + <div id='x90198d7e' style='display:none;' class='imgcontainer'> <div style="max-width:620px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 620.333 255.312"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="50,71 39,76 39,67" style="fill:rgb(0,0,0)"/> @@ -6813,8 +6813,8 @@ FROM t1 ORDER BY c, a; </div> </div> <p><b><a href="syntax/ordering-term.html">ordering-term:</a></b> -<button id='x2c2d83da' onclick='hideorshow("x2c2d83da","x4f75c28b")'>show</button></p> - <div id='x4f75c28b' style='display:none;' class='imgcontainer'> +<button id='x74a61c7c' onclick='hideorshow("x74a61c7c","xd78a941d")'>show</button></p> + <div id='xd78a941d' style='display:none;' class='imgcontainer'> <div style="max-width:798px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 798.451 99.576"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="32,17 20,21 20,12" style="fill:rgb(0,0,0)"/> @@ -6874,8 +6874,8 @@ FROM t1 ORDER BY c, a; </div> </div> <p><b><a href="syntax/result-column.html">result-column:</a></b> -<button id='x9766d8b9' onclick='hideorshow("x9766d8b9","xbe4652fc")'>show</button></p> - <div id='xbe4652fc' style='display:none;' class='imgcontainer'> +<button id='x4e7118b7' onclick='hideorshow("x4e7118b7","xd3843625")'>show</button></p> + <div id='xd3843625' style='display:none;' class='imgcontainer'> <div style="max-width:398px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 398.054 163.08"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="45,17 33,21 33,12" style="fill:rgb(0,0,0)"/> @@ -6927,8 +6927,8 @@ FROM t1 ORDER BY c, a; </div> </div> <p><b><a href="syntax/table-or-subquery.html">table-or-subquery:</a></b> -<button id='xa37b1d70' onclick='hideorshow("xa37b1d70","xdd371957")'>show</button></p> - <div id='xdd371957' style='display:none;' class='imgcontainer'> +<button id='x73838f84' onclick='hideorshow("x73838f84","x71e2799e")'>show</button></p> + <div id='x71e2799e' style='display:none;' class='imgcontainer'> <div style="max-width:720px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 720.778 457.704"> <circle cx="5" cy="36" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="50,74 39,78 39,70" style="fill:rgb(0,0,0)"/> @@ -7072,8 +7072,8 @@ FROM t1 ORDER BY c, a; </div> </div> <p><b><a href="syntax/window-defn.html">window-defn:</a></b> -<button id='x5a375ead' onclick='hideorshow("x5a375ead","x050877ef")'>show</button></p> - <div id='x050877ef' style='display:none;' class='imgcontainer'> +<button id='xdc9ba9a7' onclick='hideorshow("xdc9ba9a7","x903a8b75")'>show</button></p> + <div id='x903a8b75' style='display:none;' class='imgcontainer'> <div style="max-width:479px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 479.765 380.592"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="32,17 20,21 20,12" style="fill:rgb(0,0,0)"/> @@ -7153,8 +7153,8 @@ FROM t1 ORDER BY c, a; </svg> </div> <p><b><a href="syntax/frame-spec.html">frame-spec:</a></b> -<button id='xc09a2f4d' onclick='hideorshow("xc09a2f4d","xea11e11d")'>show</button></p> - <div id='xea11e11d' style='display:none;' class='imgcontainer'> +<button id='x27a69ac8' onclick='hideorshow("x27a69ac8","x0837afac")'>show</button></p> + <div id='x0837afac' style='display:none;' class='imgcontainer'> <div style="max-width:1039px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 1039.65 522.72"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="50,92 39,97 39,88" style="fill:rgb(0,0,0)"/> @@ -7365,8 +7365,8 @@ FROM t1 ORDER BY c, a; </div> </div> <p><b><a href="syntax/type-name.html">type-name:</a></b> -<button id='x6fd3d99a' onclick='hideorshow("x6fd3d99a","x5baa1694")'>show</button></p> - <div id='x5baa1694' style='display:none;' class='imgcontainer'> +<button id='xf5f7b40b' onclick='hideorshow("xf5f7b40b","x7cdd2b3d")'>show</button></p> + <div id='x7cdd2b3d' style='display:none;' class='imgcontainer'> <div style="max-width:661px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 661.008 110.16"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="45,17 33,21 33,12" style="fill:rgb(0,0,0)"/> @@ -7420,8 +7420,8 @@ FROM t1 ORDER BY c, a; </svg> </div> <p><b><a href="syntax/signed-number.html">signed-number:</a></b> -<button id='x725d3852' onclick='hideorshow("x725d3852","xa38da6e2")'>show</button></p> - <div id='xa38da6e2' style='display:none;' class='imgcontainer'> +<button id='x6fc5ca4e' onclick='hideorshow("x6fc5ca4e","x1b4a7c7b")'>show</button></p> + <div id='x1b4a7c7b' style='display:none;' class='imgcontainer'> <div style="max-width:292px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 292.013 99.576"> <circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> <polygon points="50,44 39,48 39,40" style="fill:rgb(0,0,0)"/> @@ -7932,5 +7932,5 @@ windows function support was extended to include the EXCLUDE clause, GROUPS frame types, window chaining, and support for "<expr> PRECEDING" and "<expr> FOLLOWING" boundaries in RANGE frames. -</p><p align="center"><small><i>This page last modified on <a href="https://sqlite.org/docsrc/honeypot" id="mtimelink" data-href="https://sqlite.org/docsrc/finfo/pages/windowfunctions.in?m=e661cf1613">2024-04-01 12:41:31</a> UTC </small></i></p> +</p><p align="center"><small><i>This page last modified on <a href="https://sqlite.org/docsrc/honeypot" id="mtimelink" data-href="https://sqlite.org/docsrc/finfo/pages/windowfunctions.in?m=e544fdba2f">2024-04-16 17:22:18</a> UTC </small></i></p> |