Compare commits
158 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 86fbbbf964 | |||
| 5eea5054d0 | |||
| b64cf9b28c | |||
| 2dc539addd | |||
| e62f31cdb4 | |||
| 1905379eb1 | |||
| 51907db8ca | |||
| e40d899afe | |||
| 2f0ebf5e5c | |||
| 2fc20b68e8 | |||
| 52fceac318 | |||
| 72327c367c | |||
| 7fa8b4acf4 | |||
| 8a5d1585f1 | |||
| e3afca73dc | |||
| 3e7d815579 | |||
| 401697bb54 | |||
| c606152c7b | |||
| d8659ad141 | |||
| 4acead62b1 | |||
| c36de71968 | |||
| 468657ec19 | |||
| 3b7520b747 | |||
| c2384cdbea | |||
| 54068138f0 | |||
| 312d0ec0a7 | |||
| 135f5fb747 | |||
| 2614c7c873 | |||
| b9d060e934 | |||
| 7b7932bed3 | |||
| 1909223648 | |||
| c95b28ebea | |||
| 98095e3949 | |||
| 60f3657b4a | |||
| 16f56e8416 | |||
| a12500005f | |||
| 91260dcf83 | |||
| d01a1bd94a | |||
| a7919add6a | |||
| 1ff855b22e | |||
| b15a3940d1 | |||
| dedd51aed4 | |||
| 24ea5fb3e8 | |||
| be4e3c88f5 | |||
| 537a6bf189 | |||
| 0ca0988355 | |||
| e63b7bdac8 | |||
| 7d5113f0a3 | |||
| 9a4e88604c | |||
| 0aa0945111 | |||
| 3363386145 | |||
| 42de1c52dd | |||
| dfcb11de18 | |||
| 02ede43da2 | |||
| 8443505dc9 | |||
| af7b8dcb58 | |||
| 43a196a3bb | |||
| 0a704c3145 | |||
| 78138397b5 | |||
| f17f607556 | |||
| 7b57aa3da9 | |||
| eba21cd4be | |||
| 11fc3c0fa7 | |||
| 4ba1c5cc49 | |||
| 63a47336af | |||
| 85548fac8d | |||
| a03372745e | |||
| fa3ee3b10b | |||
| 0d58ae010c | |||
| 4c5c6214b1 | |||
| b30af022da | |||
| d7e185ce5d | |||
| eadccaa926 | |||
| 522608d3a2 | |||
| ddd3fe6fc4 | |||
| 58a53d6e7b | |||
| 208b7141d0 | |||
| 0d36368601 | |||
| e2adc0eea1 | |||
| 252fe67bdd | |||
| 9f4ce3b19f | |||
| 4e532958c1 | |||
| 07fc85a2bf | |||
| 633c798283 | |||
| 3e46db21d4 | |||
| e1c4743121 | |||
| 6e85b27cbb | |||
| 5d20a21814 | |||
| 51896e6fd7 | |||
| 89e9baa2ca | |||
| 2ef111168f | |||
| 17a93ae1b8 | |||
| 62fc069eb4 | |||
| 4f77c9208a | |||
| 796588ae07 | |||
| 4734b3f9b7 | |||
| dfce5b6dd5 | |||
| 569c10566e | |||
| 6c758900c2 | |||
| d515ea5b56 | |||
| bcd60d20a3 | |||
| 10d29c7a94 | |||
| 0fab10991b | |||
| 5a80050dd3 | |||
| 69b0ce33fd | |||
| 02e3e04134 | |||
| 7f1c111948 | |||
| 697c50b947 | |||
| 3832c3c10f | |||
| 19eef9af64 | |||
| 044a017abc | |||
| cc0db61364 | |||
| d96ab99588 | |||
| 2725db836b | |||
| 3d7a69e5ef | |||
| 38d1e44350 | |||
| 30e314e4cb | |||
| 9ede896ac1 | |||
| b30298d3ea | |||
| a9f18f0172 | |||
| 0fe7e7d924 | |||
| e66532a63b | |||
| ca1776b5f3 | |||
| cc4d55c9cb | |||
| 5aabdaebd5 | |||
| 47741b8de9 | |||
| 3769501235 | |||
| 5dce6f96d1 | |||
| 87fb37efce | |||
| e40f28618c | |||
| 92ecf306ec | |||
| b617219bac | |||
| 09a39ed522 | |||
| e229ca0307 | |||
| ddd166a350 | |||
| 86c756015b | |||
| 665b6b6b35 | |||
| f6f7888622 | |||
| 75863ec11c | |||
| cee5cb484d | |||
| d0c7baf505 | |||
| 0ae56fbdd0 | |||
| 8f2c0b59da | |||
| 233ba1b8eb | |||
| 895bab3383 | |||
| 4b51e8bd68 | |||
| a5c9a70757 | |||
| 15b01def1e | |||
| a2417ec75c | |||
| b32b30930f | |||
| 1da88b5ce6 | |||
| 0c7d3d399d | |||
| c692df2784 | |||
| b5d4473221 | |||
| 3cdb1394b9 | |||
| f5bc444077 | |||
| d48e88e56d | |||
| bcba3655ee |
+3
-3
@@ -609,7 +609,7 @@ TESTOPTS = --verbose=file --output=test-out.txt
|
||||
|
||||
# Extra compiler options for various shell tools
|
||||
#
|
||||
SHELL_OPT = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_FTS4
|
||||
SHELL_OPT = -DSQLITE_ENABLE_FTS4
|
||||
#SHELL_OPT += -DSQLITE_ENABLE_FTS5
|
||||
SHELL_OPT += -DSQLITE_ENABLE_RTREE
|
||||
SHELL_OPT += -DSQLITE_ENABLE_EXPLAIN_COMMENTS
|
||||
@@ -619,8 +619,8 @@ SHELL_OPT += -DSQLITE_ENABLE_DBPAGE_VTAB
|
||||
SHELL_OPT += -DSQLITE_ENABLE_DBSTAT_VTAB
|
||||
SHELL_OPT += -DSQLITE_ENABLE_BYTECODE_VTAB
|
||||
SHELL_OPT += -DSQLITE_ENABLE_OFFSET_SQL_FUNC
|
||||
FUZZERSHELL_OPT = -DSQLITE_ENABLE_JSON1
|
||||
FUZZCHECK_OPT = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_MEMSYS5 -DSQLITE_OSS_FUZZ
|
||||
FUZZERSHELL_OPT =
|
||||
FUZZCHECK_OPT = -DSQLITE_ENABLE_MEMSYS5 -DSQLITE_OSS_FUZZ
|
||||
FUZZCHECK_OPT += -DSQLITE_MAX_MEMORY=50000000
|
||||
FUZZCHECK_OPT += -DSQLITE_PRINTF_PRECISION_LIMIT=1000
|
||||
FUZZCHECK_OPT += -DSQLITE_ENABLE_FTS4
|
||||
|
||||
+3
-5
@@ -363,7 +363,6 @@ SQLITE_TCL_DEP =
|
||||
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_FTS3=1
|
||||
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_RTREE=1
|
||||
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_GEOPOLY=1
|
||||
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_JSON1=1
|
||||
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_STMTVTAB=1
|
||||
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_DBPAGE_VTAB=1
|
||||
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_DBSTAT_VTAB=1
|
||||
@@ -1696,9 +1695,9 @@ SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_OFFSET_SQL_FUNC=1
|
||||
# <<mark>>
|
||||
# Extra compiler options for various test tools.
|
||||
#
|
||||
MPTESTER_COMPILE_OPTS = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_FTS5
|
||||
FUZZERSHELL_COMPILE_OPTS = -DSQLITE_ENABLE_JSON1
|
||||
FUZZCHECK_OPTS = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_MEMSYS5 -DSQLITE_OSS_FUZZ -DSQLITE_MAX_MEMORY=50000000 -DSQLITE_PRINTF_PRECISION_LIMIT=1000
|
||||
MPTESTER_COMPILE_OPTS = -DSQLITE_ENABLE_FTS5
|
||||
FUZZERSHELL_COMPILE_OPTS =
|
||||
FUZZCHECK_OPTS = -DSQLITE_ENABLE_MEMSYS5 -DSQLITE_OSS_FUZZ -DSQLITE_MAX_MEMORY=50000000 -DSQLITE_PRINTF_PRECISION_LIMIT=1000
|
||||
FUZZCHECK_OPTS = $(FUZZCHECK_OPTS) -DSQLITE_ENABLE_FTS4
|
||||
FUZZCHECK_OPTS = $(FUZZCHECK_OPTS) -DSQLITE_ENABLE_FTS5
|
||||
FUZZCHECK_OPTS = $(FUZZCHECK_OPTS) -DSQLITE_ENABLE_RTREE
|
||||
@@ -2393,7 +2392,6 @@ TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_DEFAULT_PAGE_SIZE=1024
|
||||
TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_ENABLE_STMTVTAB=1
|
||||
TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_ENABLE_DBPAGE_VTAB=1
|
||||
TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_ENABLE_BYTECODE_VTAB=1
|
||||
TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_ENABLE_JSON1=1
|
||||
TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_CKSUMVFS_STATIC=1
|
||||
TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) $(TEST_CCONV_OPTS)
|
||||
|
||||
|
||||
@@ -285,7 +285,6 @@ SQLITE3EXEPDB = /pdb:sqlite3sh.pdb
|
||||
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_FTS3=1
|
||||
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_RTREE=1
|
||||
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_GEOPOLY=1
|
||||
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_JSON1=1
|
||||
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_STMTVTAB=1
|
||||
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_DBPAGE_VTAB=1
|
||||
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_DBSTAT_VTAB=1
|
||||
|
||||
+1
-1
@@ -105,7 +105,7 @@ may be specified in this manner as some require the amalgamation to be built
|
||||
with them enabled (see http://www.sqlite.org/compile.html). For example, the
|
||||
following will work:
|
||||
|
||||
"OPTS=-DSQLITE_ENABLE_STAT4=1 -DSQLITE_ENABLE_JSON1=1"
|
||||
"OPTS=-DSQLITE_ENABLE_STAT4=1 -DSQLITE_OMIT_JSON=1"
|
||||
|
||||
However, the following will not compile unless the amalgamation was built
|
||||
with it enabled:
|
||||
|
||||
@@ -173,21 +173,6 @@ else
|
||||
fi
|
||||
#-----------------------------------------------------------------------
|
||||
|
||||
#-----------------------------------------------------------------------
|
||||
# --enable-json1
|
||||
#
|
||||
AC_ARG_ENABLE(json1, [AS_HELP_STRING(
|
||||
[--enable-json1], [include json1 support [default=yes]])],
|
||||
[],[enable_json1=yes])
|
||||
AC_MSG_CHECKING([JSON functions])
|
||||
if test x"$enable_json1" = "xyes"; then
|
||||
BUILD_CFLAGS="$BUILD_CFLAGS -DSQLITE_ENABLE_JSON1"
|
||||
AC_MSG_RESULT([enabled])
|
||||
else
|
||||
AC_MSG_RESULT([disabled])
|
||||
fi
|
||||
#-----------------------------------------------------------------------
|
||||
|
||||
#-----------------------------------------------------------------------
|
||||
# --enable-rtree
|
||||
#
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#! /bin/sh
|
||||
# Guess values for system-dependent variables and create Makefiles.
|
||||
# Generated by GNU Autoconf 2.69 for sqlite 3.38.0.
|
||||
# Generated by GNU Autoconf 2.69 for sqlite 3.38.2.
|
||||
#
|
||||
#
|
||||
# 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.38.0'
|
||||
PACKAGE_STRING='sqlite 3.38.0'
|
||||
PACKAGE_VERSION='3.38.2'
|
||||
PACKAGE_STRING='sqlite 3.38.2'
|
||||
PACKAGE_BUGREPORT=''
|
||||
PACKAGE_URL=''
|
||||
|
||||
@@ -1468,7 +1468,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.38.0 to adapt to many kinds of systems.
|
||||
\`configure' configures sqlite 3.38.2 to adapt to many kinds of systems.
|
||||
|
||||
Usage: $0 [OPTION]... [VAR=VALUE]...
|
||||
|
||||
@@ -1533,7 +1533,7 @@ fi
|
||||
|
||||
if test -n "$ac_init_help"; then
|
||||
case $ac_init_help in
|
||||
short | recursive ) echo "Configuration of sqlite 3.38.0:";;
|
||||
short | recursive ) echo "Configuration of sqlite 3.38.2:";;
|
||||
esac
|
||||
cat <<\_ACEOF
|
||||
|
||||
@@ -1661,7 +1661,7 @@ fi
|
||||
test -n "$ac_init_help" && exit $ac_status
|
||||
if $ac_init_version; then
|
||||
cat <<\_ACEOF
|
||||
sqlite configure 3.38.0
|
||||
sqlite configure 3.38.2
|
||||
generated by GNU Autoconf 2.69
|
||||
|
||||
Copyright (C) 2012 Free Software Foundation, Inc.
|
||||
@@ -2080,7 +2080,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.38.0, which was
|
||||
It was created by sqlite $as_me 3.38.2, which was
|
||||
generated by GNU Autoconf 2.69. Invocation command line was
|
||||
|
||||
$ $0 $@
|
||||
@@ -12390,7 +12390,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.38.0, which was
|
||||
This file was extended by sqlite $as_me 3.38.2, which was
|
||||
generated by GNU Autoconf 2.69. Invocation command line was
|
||||
|
||||
CONFIG_FILES = $CONFIG_FILES
|
||||
@@ -12456,7 +12456,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.38.0
|
||||
sqlite config.status 3.38.2
|
||||
configured by $0, generated by GNU Autoconf 2.69,
|
||||
with options \\"\$ac_cs_config\\"
|
||||
|
||||
|
||||
@@ -804,7 +804,7 @@ static int fts5SorterNext(Fts5Cursor *pCsr){
|
||||
rc = sqlite3_step(pSorter->pStmt);
|
||||
if( rc==SQLITE_DONE ){
|
||||
rc = SQLITE_OK;
|
||||
CsrFlagSet(pCsr, FTS5CSR_EOF);
|
||||
CsrFlagSet(pCsr, FTS5CSR_EOF|FTS5CSR_REQUIRE_CONTENT);
|
||||
}else if( rc==SQLITE_ROW ){
|
||||
const u8 *a;
|
||||
const u8 *aBlob;
|
||||
|
||||
@@ -15366,6 +15366,160 @@ do_catchsql_test 79.2 {
|
||||
INSERT INTO t1(t1) SELECT 'merge' FROM t2;
|
||||
} {1 {query aborted}}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
reset_db
|
||||
do_test 80.0 {
|
||||
sqlite3 db {}
|
||||
db deserialize [decode_hexdb {
|
||||
.open --hexdb
|
||||
| size 40960 pagesize 4096 filename crash-f928a9c1ec68dd.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 0a .....@ ........
|
||||
| 32: 00 00 00 00 00 00 00 00 00 00 00 0d 00 00 00 04 ................
|
||||
| 96: 00 00 00 00 0d 00 00 00 0d 0b 6e 00 0f a3 0f 4c ..........n....L
|
||||
| 112: 0e e1 0e 81 0e 24 0d cc 0d 72 0d 1b 0c b0 0c 50 .....$...r.....P
|
||||
| 128: 0b f8 0b b3 0b 6e 00 00 00 00 00 00 00 00 00 00 .....n..........
|
||||
| 2912: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 43 0d ..............C.
|
||||
| 2928: 06 17 11 11 08 75 74 61 62 6c 65 74 34 74 34 43 .....utablet4t4C
|
||||
| 2944: 52 45 41 54 45 20 56 49 52 54 55 41 4c 20 54 41 REATE VIRTUAL TA
|
||||
| 2960: 42 4c 45 20 74 34 20 55 53 49 4e 47 20 66 74 73 BLE t4 USING fts
|
||||
| 2976: 35 76 6f 63 61 62 28 27 74 32 27 2c 20 27 72 6f 5vocab('t2', 'ro
|
||||
| 2992: 77 27 29 43 0c 06 17 11 11 08 75 74 61 62 6c 65 w')C......utable
|
||||
| 3008: 74 33 74 33 43 52 45 41 54 45 20 56 49 52 54 55 t3t3CREATE VIRTU
|
||||
| 3024: 41 4c 20 54 41 42 4c 45 20 74 33 20 55 53 49 4e AL TABLE t3 USIN
|
||||
| 3040: 47 20 66 74 73 35 76 6f 63 61 62 28 27 74 31 27 G fts5vocab('t1'
|
||||
| 3056: 2c 20 27 72 6f 77 27 29 56 0b 06 17 1f 1f 01 7d , 'row')V.......
|
||||
| 3072: 74 61 62 6c 65 74 32 5f 63 6f 6e 66 69 67 74 32 tablet2_configt2
|
||||
| 3088: 5f 63 6f 6e 66 69 67 0a 43 52 45 41 54 45 20 54 _config.CREATE T
|
||||
| 3104: 41 42 4c 45 20 27 74 32 5f 63 6f 6e 66 69 67 27 ABLE 't2_config'
|
||||
| 3120: 28 6b 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 (k PRIMARY KEY,
|
||||
| 3136: 76 29 20 57 49 54 48 4f 55 54 20 52 4f 57 49 44 v) WITHOUT ROWID
|
||||
| 3152: 5e 0a 07 17 21 21 01 81 07 74 61 62 6c 65 74 32 ^...!!...tablet2
|
||||
| 3168: 5f 63 6f 6e 74 65 6e 74 74 32 5f 63 6f 6e 74 65 _contentt2_conte
|
||||
| 3184: 6e 74 09 43 52 45 41 54 45 20 54 41 42 4c 45 20 nt.CREATE TABLE
|
||||
| 3200: 27 74 32 5f 63 6f 6e 74 65 6e 74 27 28 69 64 20 't2_content'(id
|
||||
| 3216: 49 4e 54 45 47 45 52 20 50 52 49 4d 41 52 59 20 INTEGER PRIMARY
|
||||
| 3232: 4b 45 59 2c 20 63 30 2c 20 63 31 2c 20 63 32 29 KEY, c0, c1, c2)
|
||||
| 3248: 69 09 07 17 19 19 01 81 2d 74 61 62 6c 65 74 32 i.......-tablet2
|
||||
| 3264: 5f 69 64 78 74 32 5f 69 64 78 08 43 52 45 41 54 _idxt2_idx.CREAT
|
||||
| 3280: 45 20 54 41 42 4c 45 20 27 74 32 5f 69 64 78 27 E TABLE 't2_idx'
|
||||
| 3296: 28 73 65 67 69 64 2c 20 74 65 72 6d 2c 20 70 67 (segid, term, pg
|
||||
| 3312: 6e 6f 2c 20 50 52 49 4d 41 52 59 20 4b 45 59 28 no, PRIMARY KEY(
|
||||
| 3328: 73 65 67 69 64 2c 20 74 65 72 6d 29 29 20 57 49 segid, term)) WI
|
||||
| 3344: 54 48 4f 55 54 20 52 4f 57 49 44 55 08 07 17 1b THOUT ROWIDU....
|
||||
| 3360: 1b 01 81 01 74 61 62 6c 65 74 32 5f 64 61 74 61 ....tablet2_data
|
||||
| 3376: 74 32 5f 64 61 74 61 07 43 52 45 41 54 45 20 54 t2_data.CREATE T
|
||||
| 3392: 41 42 4c 45 20 27 74 32 5f 64 61 74 61 27 28 69 ABLE 't2_data'(i
|
||||
| 3408: 64 20 49 4e 54 45 47 45 52 20 50 52 49 4d 41 52 d INTEGER PRIMAR
|
||||
| 3424: 59 20 4b 45 59 2c 20 62 6c 6f 63 6b 20 42 4c 4f Y KEY, block BLO
|
||||
| 3440: 42 29 58 07 07 17 11 11 08 81 1d 74 61 62 6c 65 B)X........table
|
||||
| 3456: 74 32 74 32 43 52 45 41 54 45 20 56 49 52 54 55 t2t2CREATE VIRTU
|
||||
| 3472: 41 4c 20 54 41 42 4c 45 20 74 32 20 55 53 49 4e AL TABLE t2 USIN
|
||||
| 3488: 47 20 66 74 73 35 28 27 61 27 2c 5b 62 5d 2c 22 G fts5('a',[b],.
|
||||
| 3504: 63 22 2c 64 65 74 61 69 6c 3d 6e 6f 6e 65 2c 63 c.,detail=none,c
|
||||
| 3520: 6f 6c 75 6d 6e 73 69 7a 65 3d 30 29 56 06 06 17 olumnsize=0)V...
|
||||
| 3536: 1f 1f 01 7d 74 61 62 6c 65 74 31 5f 63 6f 6e 66 ....tablet1_conf
|
||||
| 3552: 69 67 74 31 5f 63 6f 6e 66 69 67 06 43 52 45 41 igt1_config.CREA
|
||||
| 3568: 54 45 20 54 41 42 4c 45 20 27 74 31 5f 63 6f 6e TE TABLE 't1_con
|
||||
| 3584: 66 69 67 27 28 6b 20 50 52 49 4d 41 52 59 20 4b fig'(k PRIMARY K
|
||||
| 3600: 45 59 2c 20 76 29 20 57 49 54 48 4f 55 54 20 52 EY, v) WITHOUT R
|
||||
| 3616: 4f 57 49 44 5b 05 07 17 21 21 01 81 01 74 61 62 OWID[...!!...tab
|
||||
| 3632: 6c 65 74 31 5f 64 6f 63 73 69 7a 65 74 31 5f 64 let1_docsizet1_d
|
||||
| 3648: 6f 63 73 69 7a 65 05 43 52 45 41 54 45 20 54 41 ocsize.CREATE TA
|
||||
| 3664: 42 4c 45 20 27 74 31 5f 64 6f 63 73 69 7a 65 27 BLE 't1_docsize'
|
||||
| 3680: 28 69 64 20 49 4e 54 45 47 45 52 20 50 52 49 4d (id INTEGER PRIM
|
||||
| 3696: 41 52 59 20 4b 45 59 2c 20 73 7a 20 42 4c 4f 42 ARY KEY, sz BLOB
|
||||
| 3712: 29 5e 04 07 17 21 21 01 81 07 74 61 62 6c 65 74 )^...!!...tablet
|
||||
| 3728: 31 5f 63 6f 6e 74 65 6e 74 74 31 5f 63 6f 6e 74 1_contentt1_cont
|
||||
| 3744: 65 6e 74 04 43 52 45 41 54 45 20 54 41 42 4c 45 ent.CREATE TABLE
|
||||
| 3760: 20 27 74 31 5f 63 6f 6e 74 65 6e 74 27 28 69 64 't1_content'(id
|
||||
| 3776: 20 49 4e 54 45 47 45 52 20 50 52 49 4d 41 52 59 INTEGER PRIMARY
|
||||
| 3792: 20 4b 45 59 2c 20 63 30 2c 20 63 31 2c 20 63 32 KEY, c0, c1, c2
|
||||
| 3808: 29 69 03 07 17 19 19 01 81 2d 74 61 62 6c 65 74 )i.......-tablet
|
||||
| 3824: 31 5f 69 64 78 74 31 5f 69 64 78 03 43 52 45 41 1_idxt1_idx.CREA
|
||||
| 3840: 54 45 20 54 41 42 4c 45 20 27 74 31 5f 69 64 78 TE TABLE 't1_idx
|
||||
| 3856: 27 28 73 65 67 69 64 2c 20 74 65 72 6d 2c 20 70 '(segid, term, p
|
||||
| 3872: 67 6e 6f 2c 20 50 52 49 4d 41 52 59 20 4b 45 59 gno, PRIMARY KEY
|
||||
| 3888: 28 73 65 67 69 64 2c 20 74 65 72 6d 29 29 20 57 (segid, term)) W
|
||||
| 3904: 49 54 48 4f 55 54 20 52 4f 57 49 44 55 02 07 17 ITHOUT ROWIDU...
|
||||
| 3920: 1b 1b 01 81 01 74 61 62 6c 65 74 31 5f 64 61 74 .....tablet1_dat
|
||||
| 3936: 61 74 31 5f 64 61 74 61 02 43 52 45 41 54 45 20 at1_data.CREATE
|
||||
| 3952: 54 41 42 4c 45 20 27 74 31 5f 64 61 74 61 27 28 TABLE 't1_data'(
|
||||
| 3968: 69 64 20 49 4e 54 45 47 45 52 20 50 52 49 4d 41 id INTEGER PRIMA
|
||||
| 3984: 52 59 20 4b 45 59 2c 20 62 6c 6f 63 6b 20 42 4c RY KEY, block BL
|
||||
| 4000: 4f 42 29 5b 01 07 17 11 11 08 81 23 74 61 62 6c OB)[.......#tabl
|
||||
| 4016: 65 74 31 74 31 43 52 45 41 54 45 20 56 49 52 54 et1t1CREATE VIRT
|
||||
| 4032: 55 41 4c 20 54 41 42 4c 45 20 74 31 20 55 53 49 UAL TABLE t1 USI
|
||||
| 4048: 4e 47 20 66 74 73 35 28 61 2c 62 20 75 6e 69 6e NG fts5(a,b unin
|
||||
| 4064: 64 65 78 65 64 2c 63 2c 74 6f 6b 65 6e 69 7a 65 dexed,c,tokenize
|
||||
| 4080: 3d 22 70 6f 72 74 65 72 20 61 73 63 69 69 22 29 =.porter ascii.)
|
||||
| page 2 offset 4096
|
||||
| 0: 0d 0f 68 00 05 0f 13 00 0f e6 0f 13 0f a8 0f 7c ..h............|
|
||||
| 16: 0f 2a 00 00 00 00 00 00 00 00 00 00 00 00 00 00 .*..............
|
||||
| 3856: 00 00 00 15 0a 03 00 30 00 00 00 00 01 03 03 00 .......0........
|
||||
| 3872: 03 01 01 01 02 01 01 03 01 01 37 8c 80 80 80 80 ..........7.....
|
||||
| 3888: 01 03 00 74 00 00 00 2e 02 30 61 03 02 02 01 01 ...t.....0a.....
|
||||
| 3904: 62 03 02 03 01 01 63 03 02 04 01 01 67 03 06 01 b.....c.....g...
|
||||
| 3920: 02 02 01 01 68 03 06 01 02 03 01 01 69 03 06 01 ....h.......i...
|
||||
| 3936: 02 04 04 06 06 06 08 08 0f ef 00 14 2a 00 00 00 ............*...
|
||||
| 3952: 00 01 02 02 00 02 01 01 01 02 01 01 25 88 80 80 ............%...
|
||||
| 3968: 80 80 01 03 00 50 00 00 00 1f 02 30 67 02 08 02 .....P.....0g...
|
||||
| 3984: 01 02 02 01 01 68 02 08 03 01 02 03 01 01 69 02 .....h........i.
|
||||
| 4000: 08 04 01 02 04 04 09 09 37 84 80 80 80 80 01 03 ........7.......
|
||||
| 4016: 00 74 00 00 00 2e 02 30 61 01 02 02 01 01 62 01 .t.....0a.....b.
|
||||
| 4032: 02 03 01 01 63 01 02 04 01 01 67 01 06 01 02 02 ....c.....g.....
|
||||
| 4048: 01 01 68 01 06 01 02 03 01 01 69 01 06 01 02 04 ..h.......i.....
|
||||
| 4064: 04 06 06 06 08 08 07 01 03 00 14 03 09 00 09 00 ................
|
||||
| 4080: 00 00 11 24 00 00 00 00 01 01 01 00 01 01 01 01 ...$............
|
||||
| page 3 offset 8192
|
||||
| 0: 0a 00 00 00 03 00 00 00 00 00 00 00 00 00 00 00 ................
|
||||
| 4064: 00 00 00 00 00 00 00 00 00 00 00 00 06 04 01 0c ................
|
||||
| 4080: 01 03 02 06 04 01 0c 01 02 02 05 04 09 0c 01 02 ................
|
||||
| page 4 offset 12288
|
||||
| 0: 0d 00 00 00 03 0f be 00 0f ea 0f d4 0f be 00 00 ................
|
||||
| 4016: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 14 03 ................
|
||||
| 4032: 05 00 17 17 17 61 20 62 20 63 67 20 68 20 69 67 .....a b cg h ig
|
||||
| 4048: 20 68 20 69 14 02 05 00 17 17 17 67 20 68 20 69 h i.......g h i
|
||||
| 4064: 61 20 62 20 63 67 20 68 20 69 14 01 05 00 17 17 a b cg h i......
|
||||
| 4080: 17 61 20 62 20 63 64 20 65 20 66 67 20 68 20 69 .a b cd e fg h i
|
||||
| page 5 offset 16384
|
||||
| 0: 0d 00 00 00 03 0f e8 00 0f f8 0f f0 0f e8 00 00 ................
|
||||
| 4064: 00 00 00 00 00 00 00 00 06 03 03 00 12 03 00 03 ................
|
||||
| 4080: 06 02 03 00 12 03 00 03 06 01 03 00 12 03 00 03 ................
|
||||
| page 6 offset 20480
|
||||
| 0: 0a 00 00 00 01 0f f4 00 0f f4 00 00 01 00 00 00 ................
|
||||
| 4080: 00 00 00 00 0b 03 1b 01 76 65 72 73 69 6f 6e 04 ........version.
|
||||
| page 7 offset 24576
|
||||
| 0: 0d 00 00 00 03 0f 9e 00 0f e6 0f ef 00 00 00 00 ................
|
||||
| 3984: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 41 84 ..............A.
|
||||
| 4000: 80 80 80 80 01 04 00 81 06 00 00 00 34 02 30 61 ............4.0a
|
||||
| 4016: 01 01 01 01 01 62 01 01 01 01 01 63 01 01 01 01 .....b.....c....
|
||||
| 4032: 01 64 01 01 01 65 01 01 01 66 01 01 01 67 01 01 .d...e...f...g..
|
||||
| 4048: 01 01 01 68 01 01 01 01 01 69 01 01 01 04 06 06 ...h.....i......
|
||||
| 4064: 06 04 04 04 06 06 07 01 03 00 14 03 09 09 09 0f ................
|
||||
| 4080: 0a 03 00 24 00 00 00 00 01 01 01 00 01 01 01 01 ...$............
|
||||
| page 8 offset 28672
|
||||
| 0: 0a 00 00 00 01 0f fa 00 00 00 00 00 00 00 00 00 ................
|
||||
| 4080: 00 00 00 00 00 00 00 00 00 00 05 04 09 0c 01 12 ................
|
||||
| page 9 offset 32768
|
||||
| 0: 0d 00 00 00 03 0f be 00 0f ea 0f d4 0f be 00 00 ................
|
||||
| 4016: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 14 03 ................
|
||||
| 4032: 05 00 17 17 17 61 20 62 20 63 67 20 68 20 69 67 .....a b cg h ig
|
||||
| 4048: 20 68 20 69 14 02 05 00 17 17 17 67 20 68 20 69 h i.......g h i
|
||||
| 4064: 61 20 62 20 63 67 20 68 20 69 14 01 05 00 17 17 a b cg h i......
|
||||
| 4080: 17 61 20 62 20 63 64 20 65 20 66 67 20 68 20 69 .a b cd e fg h i
|
||||
| page 10 offset 36864
|
||||
| 0: 0a 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 ................
|
||||
| 4080: 00 00 00 00 0b 03 1b 01 76 65 72 73 00 00 00 00 ........vers....
|
||||
| end crash-f928a9c1ec68dd.db
|
||||
}]} {}
|
||||
|
||||
do_catchsql_test 80.1 {
|
||||
SELECT snippet(rowid, -1, '.', '..', '[', '(]'),snippet(rowid, -1, '.', '.', '', '(]'), highlight(t1, 29, 1 , '') FROM t1('g+ h') WHERE rank MATCH 'bm25(1.0, 10)' ORDER BY NOT (SELECT 1 FROM t1('g+ æ') WHERE rank MATCH 'bm25(1.0, 10)' ORDER BY rank);
|
||||
} {1 {database disk image is malformed}}
|
||||
|
||||
|
||||
sqlite3_fts5_may_be_corrupt 0
|
||||
finish_test
|
||||
|
||||
|
||||
+1
-1
@@ -26,7 +26,7 @@
|
||||
**
|
||||
** The virtual table contains read-only hidden columns:
|
||||
**
|
||||
** lsm1_key A BLOB which is the raw LSM key. If the "keytype"
|
||||
** lsm1_key A BLOB which is the raw LSM key. If the "keytype"
|
||||
** is BLOB or TEXT then this column is exactly the
|
||||
** same as the key. For the UINT keytype, this column
|
||||
** will be a variable-length integer encoding of the key.
|
||||
|
||||
+1
-1
@@ -941,7 +941,7 @@ int sqlite3_csv_init(
|
||||
char **pzErrMsg,
|
||||
const sqlite3_api_routines *pApi
|
||||
){
|
||||
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
||||
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
||||
int rc;
|
||||
SQLITE_EXTENSION_INIT2(pApi);
|
||||
rc = sqlite3_create_module(db, "csv", &CsvModule, 0);
|
||||
|
||||
+1
-1
@@ -284,7 +284,7 @@ int sqlite3_ieee_init(
|
||||
SQLITE_EXTENSION_INIT2(pApi);
|
||||
(void)pzErrMsg; /* Unused parameter */
|
||||
for(i=0; i<sizeof(aFunc)/sizeof(aFunc[0]) && rc==SQLITE_OK; i++){
|
||||
rc = sqlite3_create_function(db, aFunc[i].zFName, aFunc[i].nArg,
|
||||
rc = sqlite3_create_function(db, aFunc[i].zFName, aFunc[i].nArg,
|
||||
SQLITE_UTF8|SQLITE_INNOCUOUS,
|
||||
(void*)&aFunc[i].iAux,
|
||||
aFunc[i].xFunc, 0, 0);
|
||||
|
||||
+32
-7
@@ -40,7 +40,7 @@
|
||||
**
|
||||
** Option 1 is the default behavior. 2 is use if there is a usable
|
||||
** constraint on "flags" with an integer right-hand side that where the
|
||||
** value of the right-hand side has its 0x01 bit set.
|
||||
** value of the right-hand side has its 0x001 bit set.
|
||||
**
|
||||
** All constraints on columns "a" through "e" are marked as "omit".
|
||||
**
|
||||
@@ -48,6 +48,12 @@
|
||||
** is an integer and that integer has its 0x02 bit set, then the
|
||||
** orderByConsumed flag is set.
|
||||
**
|
||||
** FLAGS SUMMARY:
|
||||
**
|
||||
** 0x001 Columns 'a' through 'e' have INT values
|
||||
** 0x002 orderByConsumed is set
|
||||
** 0x004 OFFSET and LIMIT have omit set
|
||||
**
|
||||
** COMPILE:
|
||||
**
|
||||
** gcc -Wall -g -shared -fPIC -I. qpvtab.c -o qqvtab.so
|
||||
@@ -103,7 +109,8 @@ static const char *azColname[] = {
|
||||
"ux",
|
||||
"rhs",
|
||||
"a", "b", "c", "d", "e",
|
||||
"flags"
|
||||
"flags",
|
||||
""
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -143,6 +150,7 @@ static int qpvtabConnect(
|
||||
#define QPVTAB_D 9
|
||||
#define QPVTAB_E 10
|
||||
#define QPVTAB_FLAGS 11
|
||||
#define QPVTAB_NONE 12
|
||||
if( rc==SQLITE_OK ){
|
||||
pNew = sqlite3_malloc( sizeof(*pNew) );
|
||||
*ppVtab = (sqlite3_vtab*)pNew;
|
||||
@@ -226,7 +234,7 @@ static int qpvtabColumn(
|
||||
sqlite3_result_text64(ctx, z, zEnd-z, SQLITE_TRANSIENT, SQLITE_UTF8);
|
||||
}
|
||||
}else if( i>=QPVTAB_A && i<=QPVTAB_E ){
|
||||
if( pCur->flags & 1 ){
|
||||
if( pCur->flags & 0x001 ){
|
||||
sqlite3_result_int(ctx, i-QPVTAB_A+1);
|
||||
}else{
|
||||
char x = 'a'+i-QPVTAB_A;
|
||||
@@ -338,19 +346,25 @@ static int qpvtabBestIndex(
|
||||
for(i=0; i<pIdxInfo->nConstraint; i++){
|
||||
sqlite3_value *pVal;
|
||||
int iCol = pIdxInfo->aConstraint[i].iColumn;
|
||||
int op = pIdxInfo->aConstraint[i].op;
|
||||
if( iCol==QPVTAB_FLAGS && pIdxInfo->aConstraint[i].usable ){
|
||||
pVal = 0;
|
||||
rc = sqlite3_vtab_rhs_value(pIdxInfo, i, &pVal);
|
||||
assert( rc==SQLITE_OK || pVal==0 );
|
||||
if( pVal ){
|
||||
pIdxInfo->idxNum = sqlite3_value_int(pVal);
|
||||
if( pIdxInfo->idxNum & 2 ) pIdxInfo->orderByConsumed = 1;
|
||||
if( pIdxInfo->idxNum & 0x002 ) pIdxInfo->orderByConsumed = 1;
|
||||
}
|
||||
}
|
||||
if( op==SQLITE_INDEX_CONSTRAINT_LIMIT
|
||||
|| op==SQLITE_INDEX_CONSTRAINT_OFFSET
|
||||
){
|
||||
iCol = QPVTAB_NONE;
|
||||
}
|
||||
sqlite3_str_appendf(pStr,"aConstraint,%d,%s,%d,%d,",
|
||||
i,
|
||||
azColname[iCol],
|
||||
pIdxInfo->aConstraint[i].op,
|
||||
op,
|
||||
pIdxInfo->aConstraint[i].usable);
|
||||
pVal = 0;
|
||||
rc = sqlite3_vtab_rhs_value(pIdxInfo, i, &pVal);
|
||||
@@ -359,9 +373,20 @@ static int qpvtabBestIndex(
|
||||
qpvtabStrAppendValue(pStr, pVal);
|
||||
}
|
||||
sqlite3_str_append(pStr, "\n", 1);
|
||||
}
|
||||
for(i=0; i<pIdxInfo->nConstraint; i++){
|
||||
int iCol = pIdxInfo->aConstraint[i].iColumn;
|
||||
int op = pIdxInfo->aConstraint[i].op;
|
||||
if( op==SQLITE_INDEX_CONSTRAINT_LIMIT
|
||||
|| op==SQLITE_INDEX_CONSTRAINT_OFFSET
|
||||
){
|
||||
iCol = QPVTAB_NONE;
|
||||
}
|
||||
if( iCol>=QPVTAB_A && pIdxInfo->aConstraint[i].usable ){
|
||||
pIdxInfo->aConstraintUsage[i].argvIndex = ++k;
|
||||
pIdxInfo->aConstraintUsage[i].omit = 1;
|
||||
pIdxInfo->aConstraintUsage[i].argvIndex = ++k;
|
||||
if( iCol<=QPVTAB_FLAGS || (pIdxInfo->idxNum & 0x004)!=0 ){
|
||||
pIdxInfo->aConstraintUsage[i].omit = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
sqlite3_str_appendf(pStr, "nOrderBy,%d,,,,\n", pIdxInfo->nOrderBy);
|
||||
|
||||
@@ -1262,9 +1262,14 @@ static int zipfileFilter(
|
||||
zipfileCursorErr(pCsr, "zipfile() function requires an argument");
|
||||
return SQLITE_ERROR;
|
||||
}else if( sqlite3_value_type(argv[0])==SQLITE_BLOB ){
|
||||
static const u8 aEmptyBlob = 0;
|
||||
const u8 *aBlob = (const u8*)sqlite3_value_blob(argv[0]);
|
||||
int nBlob = sqlite3_value_bytes(argv[0]);
|
||||
assert( pTab->pFirstEntry==0 );
|
||||
if( aBlob==0 ){
|
||||
aBlob = &aEmptyBlob;
|
||||
nBlob = 0;
|
||||
}
|
||||
rc = zipfileLoadDirectory(pTab, aBlob, nBlob);
|
||||
pCsr->pFreeEntry = pTab->pFirstEntry;
|
||||
pTab->pFirstEntry = pTab->pLastEntry = 0;
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
*/
|
||||
#define TCLSH_INIT_PROC sqlite3_checker_init_proc
|
||||
#define SQLITE_ENABLE_DBPAGE_VTAB 1
|
||||
#define SQLITE_ENABLE_JSON1 1
|
||||
#undef SQLITE_THREADSAFE
|
||||
#define SQLITE_THREADSAFE 0
|
||||
#undef SQLITE_ENABLE_COLUMN_METADATA
|
||||
|
||||
@@ -324,7 +324,7 @@ static int SQLITE_TCLAPI register_box_query(
|
||||
}
|
||||
if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
|
||||
|
||||
pCtx = (BoxQueryCtx*)ckalloc(sizeof(BoxQueryCtx*));
|
||||
pCtx = (BoxQueryCtx*)ckalloc(sizeof(BoxQueryCtx));
|
||||
pCtx->interp = interp;
|
||||
pCtx->pScript = Tcl_DuplicateObj(objv[2]);
|
||||
Tcl_IncrRefCount(pCtx->pScript);
|
||||
|
||||
@@ -529,7 +529,7 @@ TESTOPTS = --verbose=file --output=test-out.txt
|
||||
|
||||
# Extra compiler options for various shell tools
|
||||
#
|
||||
SHELL_OPT += -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_FTS5
|
||||
SHELL_OPT += -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_FTS5
|
||||
SHELL_OPT += -DSQLITE_ENABLE_RTREE
|
||||
SHELL_OPT += -DSQLITE_ENABLE_EXPLAIN_COMMENTS
|
||||
SHELL_OPT += -DSQLITE_ENABLE_UNKNOWN_SQL_FUNCTION
|
||||
@@ -538,8 +538,7 @@ SHELL_OPT += -DSQLITE_ENABLE_DBPAGE_VTAB
|
||||
SHELL_OPT += -DSQLITE_ENABLE_DBSTAT_VTAB
|
||||
SHELL_OPT += -DSQLITE_ENABLE_BYTECODE_VTAB
|
||||
SHELL_OPT += -DSQLITE_ENABLE_OFFSET_SQL_FUNC
|
||||
FUZZERSHELL_OPT = -DSQLITE_ENABLE_JSON1
|
||||
FUZZCHECK_OPT = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_MEMSYS5
|
||||
FUZZCHECK_OPT = -DSQLITE_ENABLE_MEMSYS5
|
||||
FUZZCHECK_OPT += -DSQLITE_MAX_MEMORY=50000000
|
||||
FUZZCHECK_OPT += -DSQLITE_PRINTF_PRECISION_LIMIT=1000
|
||||
FUZZCHECK_OPT += -DSQLITE_ENABLE_FTS4
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
C Bring\ssqlite3_vtab_distinct()\sup\sto\sspec\sso\sthat\sit\sworks\sas\sdescribed\sin\sthe\ndocumentation.
|
||||
D 2022-01-22T20:45:57.210
|
||||
C Version\s3.38.2
|
||||
D 2022-03-26T13:51:10.240
|
||||
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
|
||||
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
|
||||
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
|
||||
F Makefile.in 3271f3cffa0fb1e214816bbffbdb8a367f8d3b8415eda5346839cf427a138c70
|
||||
F Makefile.in b210ad2733317f1a4353085dfb9d385ceec30b0e6a61d20a5accabecac6b1949
|
||||
F Makefile.linux-gcc f609543700659711fbd230eced1f01353117621dccae7b9fb70daa64236c5241
|
||||
F Makefile.msc eeb45109d245d1bc5d6ce78da818d62848307419f950b0de0a00ab0672b15081
|
||||
F Makefile.msc b28a8a7a977e7312f6859f560348e1eb110c21bd6cf9fab0d16537c0a514eef3
|
||||
F README.md 2dd87a5c1d108b224921f3dd47dea567973f706e1f6959386282a626f459a70c
|
||||
F VERSION 392c2f83569705069415a5d98b1c138ec8fe8a56a663a0d94cea019e806537b2
|
||||
F VERSION 2c46bf3c621980e333221949b5ea8ce0bf5e6f0c328e6b228501ea3190abe467
|
||||
F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50
|
||||
F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2
|
||||
F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90
|
||||
@@ -15,10 +15,10 @@ F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2
|
||||
F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903
|
||||
F autoconf/Makefile.am a8d1d24affe52ebf8d7ddcf91aa973fa0316618ab95bb68c87cabf8faf527dc8
|
||||
F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac
|
||||
F autoconf/Makefile.msc 262dad10223b39a6853c4faefadb0f71931ca55c742fa285f8ee8d56b7543ddc
|
||||
F autoconf/Makefile.msc 8401a514e4e70add3c6448348ae31322d5cb7db427b05a20828f943c3ddb2733
|
||||
F autoconf/README.first 6c4f34fe115ff55d4e8dbfa3cecf04a0188292f7
|
||||
F autoconf/README.txt 4f04b0819303aabaa35fff5f7b257fb0c1ef95f1
|
||||
F autoconf/configure.ac a8ba2a9e61216f5093d44f3b7d2cb8fe1890d6b7dc330a02f802d8efaa1fdc79
|
||||
F autoconf/README.txt 42cfd21d0b19dc7d5d85fb5c405c5f3c6a4c923021c39128f6ba685355d8fd56
|
||||
F autoconf/configure.ac ec7fa914c5e74ff212fe879f9bb6918e1234497e05facfb641f30c4d5893b277
|
||||
F autoconf/tea/Makefile.in b438a7020446c8a8156e8d97c8914a04833da6fd
|
||||
F autoconf/tea/README 3e9a3c060f29a44344ab50aec506f4db903fb873
|
||||
F autoconf/tea/aclocal.m4 52c47aac44ce0ddb1f918b6993e8beb8eee88f43
|
||||
@@ -34,7 +34,7 @@ F autoconf/tea/win/rules.vc c511f222b80064096b705dbeb97060ee1d6b6d63
|
||||
F config.guess 883205ddf25b46f10c181818bf42c09da9888884af96f79e1719264345053bd6
|
||||
F config.h.in 6376abec766e9a0785178b1823b5a587e9f1ccbc
|
||||
F config.sub c2d0260f17f3e4bc0b6808fccf1b291cb5e9126c14fc5890efc77b9fd0175559
|
||||
F configure a2877fe63cc821af0df41abe70f1f7c4e97cb7e23a42e0a1402e8a2f55a88aa2 x
|
||||
F configure 40cf509efcf3fe6062a5f6a25742a9622cfb6e2df127ba7b5e2400de41994dd8 x
|
||||
F configure.ac 3ef6eeff4387585bfcab76b0c3f6e15a0618587bb90245dd5d44e4378141bb35
|
||||
F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad
|
||||
F doc/F2FS.txt c1d4a0ae9711cfe0e1d8b019d154f1c29e0d3abfe820787ba1e9ed7691160fcd
|
||||
@@ -120,7 +120,7 @@ F ext/fts5/fts5_config.c 501e7d3566bc92766b0e11c0109a7c5a6146bc41144195459af5422
|
||||
F ext/fts5/fts5_expr.c fcd0770d53028c2b53a15d0f53bf6d0e01b1bf3dd97630b9fedf0801f03aa3ec
|
||||
F ext/fts5/fts5_hash.c d4fb70940359f2120ccd1de7ffe64cc3efe65de9e8995b822cd536ff64c96982
|
||||
F ext/fts5/fts5_index.c fdfbc8a62827ec1d1b6f207a1e59c1c4986c3ce245592b5128ffe738867cfcd1
|
||||
F ext/fts5/fts5_main.c 7c6092a53e6802962fa07b0fad3e61cb077b6c98b74b727d8d44ac2cf63bd914
|
||||
F ext/fts5/fts5_main.c 6078ae86d3b813753a4f1201054550aff21a3f660e97b30f200d2b1472874151
|
||||
F ext/fts5/fts5_storage.c 76c6085239eb44424004c022e9da17a5ecd5aaec859fba90ad47d3b08f4c8082
|
||||
F ext/fts5/fts5_tcl.c b1445cbe69908c411df8084a10b2485500ac70a9c747cdc8cda175a3da59d8ae
|
||||
F ext/fts5/fts5_test_mi.c 08c11ec968148d4cb4119d96d819f8c1f329812c568bac3684f5464be177d3ee
|
||||
@@ -160,7 +160,7 @@ F ext/fts5/test/fts5connect.test 08030168fc96fc278fa81f28654fb7e90566f33aff269c0
|
||||
F ext/fts5/test/fts5content.test 213506436fb2c87567b8e31f6d43ab30aab99354cec74ed679f22aad0cdbf283
|
||||
F ext/fts5/test/fts5corrupt.test 77ae6f41a7eba10620efb921cf7dbe218b0ef232b04519deb43581cb17a57ebe
|
||||
F ext/fts5/test/fts5corrupt2.test 7453752ba12ce91690c469a6449d412561cc604b1dec994e16ab132952e7805f
|
||||
F ext/fts5/test/fts5corrupt3.test 0e473620582a53ac61f468f364db8a151c1e18d2a879b16439d172c12c4c9828
|
||||
F ext/fts5/test/fts5corrupt3.test 7da9895dafa404efd20728f66ff4b94399788bdc042c36fe2689801bba2ccd78
|
||||
F ext/fts5/test/fts5corrupt4.test f4c08e2182a48d8b70975fd869ee5391855c06d8a0ff87b6a2529e7c5a88a1d3
|
||||
F ext/fts5/test/fts5corrupt5.test 550d0884c14424f9acad051a741f1dd99ec9342277d938e91ff3daf9123d1209
|
||||
F ext/fts5/test/fts5corrupt6.test bf8eeae07825b088b9665d9d8e4accbd8dc9bf3cb85b6c64cf6c9e18ccc420a4
|
||||
@@ -280,7 +280,7 @@ F ext/lsm1/lsm_str.c 65e361b488c87b10bf3e5c0070b14ffc602cf84f094880bece77bbf6678
|
||||
F ext/lsm1/lsm_tree.c 682679d7ef2b8b6f2fe77aeb532c8d29695bca671c220b0abac77069de5fb9fb
|
||||
F ext/lsm1/lsm_unix.c 11e0a5c19d754a4e1d93dfad06de8cc201f10f886b8e61a4c599ed34e334fc24
|
||||
F ext/lsm1/lsm_varint.c 43f954af668a66c7928b81597c14d6ad4be9fedbc276bbd80f52fa28a02fdb62
|
||||
F ext/lsm1/lsm_vtab.c 169bfe7ef8e6c9de9c77e17c4c50c9ae55fb0167d80be3d1be82c991184b6f35
|
||||
F ext/lsm1/lsm_vtab.c e57aa3eb456bf2b98064014027e097c9402d6dec7b59564ddbfa1c0ead8f96c5
|
||||
F ext/lsm1/lsm_win32.c 0a4acbd7e8d136dd3a5753f0a9e7a9802263a9d96cef3278cf120bcaa724db7c
|
||||
F ext/lsm1/test/lsm1_common.tcl 5ed4bab07c93be2e4f300ebe46007ecf4b3e20bc5fbe1dedaf04a8774a6d8d82
|
||||
F ext/lsm1/test/lsm1_simple.test a04d08e8661ae6fc53786c67f0bd102c6692f003e859dde03ed9ac3f12e066e5
|
||||
@@ -297,7 +297,7 @@ F ext/misc/cksumvfs.c b42ef52eaaa510d54ec320c87bea149e934a3b06cd232be2093562bf66
|
||||
F ext/misc/closure.c dbfd8543b2a017ae6b1a5843986b22ddf99ff126ec9634a2f4047cd14c85c243
|
||||
F ext/misc/completion.c 6dafd7f4348eecc7be9e920d4b419d1fb2af75d938cd9c59a20cfe8beb2f22b9
|
||||
F ext/misc/compress.c 3354c77a7c8e86e07d849916000cdac451ed96500bfb5bd83b20eb61eee012c9
|
||||
F ext/misc/csv.c 53b3338d4fa812eda51a2637df30233a4dae16b964ee5666e2051b9672ed8bb4
|
||||
F ext/misc/csv.c d14709096280dc0e20c533f184568952bf4b8022ea80afc4aa9fec5ab3637bb3
|
||||
F ext/misc/dbdata.c e316fba936571584e55abd5b974a32a191727a6b746053a0c9d439bd2cf93940
|
||||
F ext/misc/dbdump.c b8592f6f2da292c62991a13864a60d6c573c47a9cc58362131b9e6a64f823e01
|
||||
F ext/misc/decimal.c 09f967dcf4a1ee35a76309829308ec278d3648168733f4a1147820e11ebefd12
|
||||
@@ -306,7 +306,7 @@ F ext/misc/explain.c 0086fab288d4352ea638cf40ac382aad3b0dc5e845a1ea829a694c015fd
|
||||
F ext/misc/fileio.c 4e7f7cd30de8df4820c552f14af3c9ca451c5ffe1f2e7bef34d598a12ebfb720
|
||||
F ext/misc/fossildelta.c 1240b2d3e52eab1d50c160c7fe1902a9bd210e052dc209200a750bbf885402d5
|
||||
F ext/misc/fuzzer.c eae560134f66333e9e1ca4c8ffea75df42056e2ce8456734565dbe1c2a92bf3d
|
||||
F ext/misc/ieee754.c 91a5594071143a4ab79c638fe9f059af1db09932faf2e704c3e29216a7d4f511
|
||||
F ext/misc/ieee754.c 984d51fe23e956484ec1049df6f5257002e3ab338cabceb39761c2e80ad10bf4
|
||||
F ext/misc/memstat.c 3017a0832c645c0f8c773435620d663855f04690172316bd127270d1a7523d4d
|
||||
F ext/misc/memtrace.c 7c0d115d2ef716ad0ba632c91e05bd119cb16c1aedf3bec9f06196ead2d5537b
|
||||
F ext/misc/memvfs.c 7dffa8cc89c7f2d73da4bd4ccea1bcbd2bd283e3bb4cea398df7c372a197291b
|
||||
@@ -316,7 +316,7 @@ F ext/misc/noop.c 81efe4cad9ec740e64388b14281cb983e6e2c223fed43eb77ab3e34946e0c1
|
||||
F ext/misc/normalize.c bd84355c118e297522aba74de34a4fd286fc775524e0499b14473918d09ea61f
|
||||
F ext/misc/percentile.c b9086e223d583bdaf8cb73c98a6539d501a2fc4282654adbfea576453d82e691
|
||||
F ext/misc/prefixes.c 0f4f8cff5aebc00a7e3ac4021fd59cfe1a8e17c800ceaf592859ecb9cbc38196
|
||||
F ext/misc/qpvtab.c c662fa0a452ad286e49b6c83ac917600656b2eb47d2225ff6185c56bf80cf8d2
|
||||
F ext/misc/qpvtab.c 09738419e25f603a35c0ac8bd0a04daab794f48d08a9bc07a6085b9057b99009
|
||||
F ext/misc/regexp.c b267fd05ff8d38b22f4c2809d7b7a2c61d522e9faf2feb928dbb9662e4a3a386
|
||||
F ext/misc/remember.c add730f0f7e7436cd15ea3fd6a90fd83c3f706ab44169f7f048438b7d6baa69c
|
||||
F ext/misc/rot13.c 51ac5f51e9d5fd811db58a9c23c628ad5f333c173f1fc53c8491a3603d38556c
|
||||
@@ -339,7 +339,7 @@ F ext/misc/vfsstat.c 474d08efc697b8eba300082cb1eb74a5f0f3df31ed257db1cb07e72ab0e
|
||||
F ext/misc/vtablog.c 5538acd0c8ddaae372331bee11608d76973436b77d6a91e8635cfc9432fba5ae
|
||||
F ext/misc/vtshim.c 1976e6dd68dd0d64508c91a6dfab8e75f8aaf6cd
|
||||
F ext/misc/wholenumber.c a838d1bea913c514ff316c69695efbb49ea3b8cb37d22afc57f73b6b010b4546
|
||||
F ext/misc/zipfile.c 238ccb990ed45a74e24d0fbb449d7752a568c2b7c1d5b255d451f11703ced592
|
||||
F ext/misc/zipfile.c 3e76c6c3f73e05bfc7b2f743c268071c31e9aec0491282506ecb79cdef69d6f2
|
||||
F ext/misc/zorder.c b0ff58fa643afa1d846786d51ea8d5c4b6b35aa0254ab5a82617db92f3adda64
|
||||
F ext/rbu/rbu.c 801450b24eaf14440d8fd20385aacc751d5c9d6123398df41b1b5aa804bf4ce8
|
||||
F ext/rbu/rbu1.test c62904bd9526dcdc3496a21199aaf14ae191bbadbf67f076bf16be6b3f2115c2
|
||||
@@ -388,7 +388,7 @@ F ext/rbu/test_rbu.c 03f6f177096a5f822d68d8e4069ad8907fe572c62ff2d19b141f5974282
|
||||
F ext/repair/README.md 92f5e8aae749a4dae14f02eea8e1bb42d4db2b6ce5e83dbcdd6b1446997e0c15
|
||||
F ext/repair/checkfreelist.c e21f06995ff4efdc1622dcceaea4dcba2caa83ca2f31a1607b98a8509168a996
|
||||
F ext/repair/checkindex.c 4383e4469c21e5b9ae321d0d63cec53e981af9d7a6564be6374f0eeb93dfc890
|
||||
F ext/repair/sqlite3_checker.c.in 4a5a3af3f450fe503e5a2985e98516dc2a6b9ad247449e284c1cf140fc91720f
|
||||
F ext/repair/sqlite3_checker.c.in 445118c5f7fea958b36fba1b2c464283e60ed4842039ddee3265f1698115ebf7
|
||||
F ext/repair/sqlite3_checker.tcl a9a2caa9660567257c177a91124d8c0dccdfa341e25c51e6da7f1fd9e601eafa
|
||||
F ext/repair/test/README.md 34b2f542cf5be7bffe479242b33ee3492cea30711e447cc4a1a86cb5915f419e
|
||||
F ext/repair/test/checkfreelist01.test 3e8aa6aeb4007680c94a8d07b41c339aa635cc78249442da72ff3f8297398a69
|
||||
@@ -426,7 +426,7 @@ F ext/rtree/rtreedoc2.test 194ebb7d561452dcdc10bf03f44e30c082c2f0c14efeb07f5e02c
|
||||
F ext/rtree/rtreedoc3.test 555a878c4d79c4e37fa439a1c3b02ee65d3ebaf75d9e8d96a9c55d66db3efbf8
|
||||
F ext/rtree/rtreefuzz001.test 0fc793f67897c250c5fde96cefee455a5e2fb92f4feeabde5b85ea02040790ee
|
||||
F ext/rtree/sqlite3rtree.h 03c8db3261e435fbddcfc961471795cbf12b24e03001d0015b2636b0f3881373
|
||||
F ext/rtree/test_rtreedoc.c 5ad4029d6804eb9efafcac1598a9e0582f6119e48f818854f5b4db1788ca8bd4
|
||||
F ext/rtree/test_rtreedoc.c de76b3472bc74b788d079342fdede22ff598796dd3d97acffe46e09228af83a3
|
||||
F ext/rtree/tkt3363.test 142ab96eded44a3615ec79fba98c7bde7d0f96de
|
||||
F ext/rtree/util/randomshape.tcl 54ee03d0d4a1c621806f7f44d5b78d2db8fac26e0e8687c36c4bd0203b27dbff
|
||||
F ext/rtree/viewrtree.tcl eea6224b3553599ae665b239bd827e182b466024
|
||||
@@ -473,7 +473,7 @@ F ext/userauth/userauth.c 7f00cded7dcaa5d47f54539b290a43d2e59f4b1eb5f447545fa865
|
||||
F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x
|
||||
F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8
|
||||
F magic.txt 8273bf49ba3b0c8559cb2774495390c31fd61c60
|
||||
F main.mk 3de4bca45fee4b843aaf74df8ffc639aa8ae3c52af997bbbd6927add30154fda
|
||||
F main.mk 80ac3d2f82eb21c6fb4423f9c7f8e207abb51be6676845a00e246cfb22f9c77c
|
||||
F mkso.sh fd21c06b063bb16a5d25deea1752c2da6ac3ed83
|
||||
F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271
|
||||
F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504
|
||||
@@ -485,46 +485,46 @@ F spec.template 86a4a43b99ebb3e75e6b9a735d5fd293a24e90ca
|
||||
F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b
|
||||
F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786
|
||||
F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a
|
||||
F src/alter.c e3943d8fbcaf60f79f39d4aecc56a6a8092f51f93d6a7c5b1db2633c5fa10c30
|
||||
F src/alter.c 006325f8844c65d885b3ba469b4c08d9dd0cd3e9ec481d5bcff621f224cb2302
|
||||
F src/analyze.c 7518b99e07c5494111fe3bd867f28f804b6c5c1ad0703ec3d116de9bab3fa516
|
||||
F src/attach.c e3f9d9a2a4a844750f3f348f37afb244535f21382cbfcd840152cb21cb41cfaf
|
||||
F src/attach.c f26d400f3ffe2cdca01406bca70e5f58c5488bf165b4fc37c228136dfcf1b583
|
||||
F src/auth.c f4fa91b6a90bbc8e0d0f738aa284551739c9543a367071f55574681e0f24f8cf
|
||||
F src/backup.c 3014889fa06e20e6adfa0d07b60097eec1f6e5b06671625f476a714d2356513d
|
||||
F src/backup.c a2891172438e385fdbe97c11c9745676bec54f518d4447090af97189fd8e52d7
|
||||
F src/bitvec.c 7c849aac407230278445cb069bebc5f89bf2ddd87c5ed9459b070a9175707b3d
|
||||
F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6
|
||||
F src/btree.c ddab31c38d5f16114bc68392430556b1063fe14e0020f9a56d2c35ddd58ba7e3
|
||||
F src/btree.c 1ebe34ee736e05ead62bcf762a71c5779526356b0616dec67f20478d008e2eb4
|
||||
F src/btree.h 74d64b8f28cfa4a894d14d4ed64fa432cd697b98b61708d4351482ae15913e22
|
||||
F src/btreeInt.h ee9348c4cb9077243b049edc93a82c1f32ca48baeabf2140d41362b9f9139ff7
|
||||
F src/build.c c72407a27a28982a384cd453a3a6b6992a1ceae8bd8d95e96d7fb9c0d645a32f
|
||||
F src/btreeInt.h 8be97d3939d626f734ec1b577efa4e6e186da00daf5b3227af199ca1c24cdd71
|
||||
F src/build.c a0cc68fe8172c0a31b54576f9c6c0fe6f7c82b1b5e1387afdd6a5a13132bc131
|
||||
F src/callback.c 4c19af69835787bfe790ac560f3071a824eb629f34e41f97b52ce5235c77de1c
|
||||
F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e
|
||||
F src/ctime.c 2cce39df1a13e05b7633e6d21b651f21492471f991dd7b323a4ee4e7b7f0b7f1
|
||||
F src/date.c e25773f06a8f9043bfa1e5fa0bee93483c41933adfff0891752f00eadd12ab1c
|
||||
F src/dbpage.c 8a01e865bf8bc6d7b1844b4314443a6436c07c3efe1d488ed89e81719047833a
|
||||
F src/date.c 15082566229d4b1e5f24fdb490bf9bcc68824b911d70e3573ef075a1b9e2d26f
|
||||
F src/dbpage.c 30ff075a9a9156bd2cccb5c1ea579f2afbaa64989648e8c9d72cb4a3417f5136
|
||||
F src/dbstat.c 861e08690fcb0f2ee1165eff0060ea8d4f3e2ea10f80dab7d32ad70443a6ff2d
|
||||
F src/delete.c 19814f621cde10b1771a0dea7fe25d3d7d39975b8d4be4888537d30860e7c08c
|
||||
F src/expr.c 827179c78d2ca7cc318392811de8151c60eacf7ce804b13e61bb7ef38f954846
|
||||
F src/delete.c b5f1716b4d723db48254ee0f896e362cd029e865e05414139ea7f539f3884e1d
|
||||
F src/expr.c b90a029105a93a93a0ed5e5f8c5eaed8f19043a3b62e4c4d235a4611d9ada178
|
||||
F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007
|
||||
F src/fkey.c 5b73f7a7c00f06017531a5bd258cbc2c7a294e55a7f84a729fe27aa525242560
|
||||
F src/func.c 8fddc42bce95d17938252a543f86fe29e479366e80fbd112a1822913b6247776
|
||||
F src/global.c 1f56aead86e8a18c4415638f5e6c4d0a0550427f4b3f5d065ba5164cc09c22e8
|
||||
F src/fkey.c 06e4ac33031b02dde7130c12e79cddf4dc5cfa72b23d8e63a3c26878fc9c1d3c
|
||||
F src/func.c a3407a6fbb0d4088d8d502e46f0ace63e0aeae7467ae23a9ca9815bbf9239761
|
||||
F src/global.c a3daa18a1696aadd94f18d37cbbdebf0bbdb827b8397a534f021cd56c15cd0f9
|
||||
F src/hash.c 8d7dda241d0ebdafb6ffdeda3149a412d7df75102cecfc1021c98d6219823b19
|
||||
F src/hash.h 3340ab6e1d13e725571d7cee6d3e3135f0779a7d8e76a9ce0a85971fa3953c51
|
||||
F src/hwtime.h cb1d7e3e1ed94b7aa6fde95ae2c2daccc3df826be26fc9ed7fd90d1750ae6144
|
||||
F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71
|
||||
F src/insert.c e528416ff5d86fc5d656ea6a26f03fde39836b6175f93048c32a03cb2ee16743
|
||||
F src/json.c 78fdec9af3a8bfb5ae685707b2701276fec1942b8f5f26689b2701debe32bcd2
|
||||
F src/insert.c 6c0641efc3636732a02f45defe358899d695c065fc26fbba1b2cab415b5b2e57
|
||||
F src/json.c 225b00422112ecd7094a555f3ace16b25d7d5894062b823269ed03899907c2a2
|
||||
F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa
|
||||
F src/loadext.c 657534339585ac234839e5187aa51d8802f292e0771c4f874b3af1f1223f81e2
|
||||
F src/main.c 2b6b0dbfeb14d4bb57e368604b0736b2aa42b51b00339d399b01d6b1fc9b4960
|
||||
F src/malloc.c ef796bcc0e81d845d59a469f1cf235056caf9024172fd524e32136e65593647b
|
||||
F src/loadext.c aa919a6a7884f8b34d7b791841b24d14b1b0ab43f45b3940f4851043b2855c0c
|
||||
F src/main.c 0840cee6984034c7e73cc747a1562c7eaed4673694bf20b00980aaa0672c0405
|
||||
F src/malloc.c fec841aa0a0400a6f7d20706178a5d8e8219a6bf562b6fe712c17f6c26813266
|
||||
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
|
||||
F src/mem1.c c12a42539b1ba105e3707d0e628ad70e611040d8f5e38cf942cee30c867083de
|
||||
F src/mem2.c c8bfc9446fd0798bddd495eb5d9dbafa7d4b7287d8c22d50a83ac9daa26d8a75
|
||||
F src/mem3.c 30301196cace2a085cbedee1326a49f4b26deff0af68774ca82c1f7c06fda4f6
|
||||
F src/mem5.c 9bf955937b07f8c32541c8a9991f33ce3173d944
|
||||
F src/memdb.c c2dc88f97c410eb68a24468344b65526685e18354ddfd15906750c1eaf9dc2dd
|
||||
F src/memjournal.c ff4336a98b05ede2adee7595f22d6f7d1cdc6bf0f0a5c3d77b0acdf017b2e8b2
|
||||
F src/memjournal.c 8bd50ae6d9c6d34b3a96cc3b4f567f9935dc358444d872ab48901a8c11ad82a6
|
||||
F src/msvc.h 3a15918220367a8876be3fa4f2abe423a861491e84b864fb2b7426bf022a28f8
|
||||
F src/mutex.c 5e3409715552348732e97b9194abe92fdfcd934cfb681df4ba0ab87ac6c18d25
|
||||
F src/mutex.h a7b2293c48db5f27007c3bdb21d438873637d12658f5a0bf8ad025bb96803c4a
|
||||
@@ -536,33 +536,33 @@ F src/os.c b1c4f2d485961e9a5b6b648c36687d25047c252222e9660b7cc25a6e1ea436ab
|
||||
F src/os.h 26890f540b475598cd9881dcc68931377b8d429d3ea3e2eeb64470cde64199f8
|
||||
F src/os_common.h b2f4707a603e36811d9b1a13278bffd757857b85
|
||||
F src/os_setup.h 0dbaea40a7d36bf311613d31342e0b99e2536586
|
||||
F src/os_unix.c f5ad51cfd024116db8531feab9efd831c2621436dca1464e4ff1e8af9bf3252e
|
||||
F src/os_win.c 77d39873836f1831a9b0b91894fec45ab0e9ca8e067dc8c549e1d1eca1566fe9
|
||||
F src/os_unix.c df6142ed776b5e52c7c3106767283be2d510b63d72beb3b205898462f340a176
|
||||
F src/os_win.c a8ea80037e81127ca01959daa87387cc135f325c88dc745376c4f760de852a10
|
||||
F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a
|
||||
F src/pager.c f6183fb7370425cd8642759693d9994649217cf7111caef89bc2c4946afbc36d
|
||||
F src/pager.c e4f4c1e07b2cc4fa44fc0bd51957ca6066f6b8c0b0e0388f11a6728b50d8f4e6
|
||||
F src/pager.h 4bf9b3213a4b2bebbced5eaa8b219cf25d4a82f385d093cd64b7e93e5285f66f
|
||||
F src/parse.y 04f61db1cdd7036c6d74baad1c342d3e3110cb0765c48fcfd3bdf4e974a1e5bb
|
||||
F src/pcache.c 084e638432c610f95aea72b8509f0845d2791293f39d1b82f0c0a7e089c3bb6b
|
||||
F src/parse.y 0f02b27cdaa334441463153fff3ceb780fea006ab53ffd6ef566d4468f93e924
|
||||
F src/pcache.c 0aab73936341fad83d107cf62c6a7bc2d2d5fb9aaec8c3ce61e19fc18e4560fc
|
||||
F src/pcache.h 4f87acd914cef5016fae3030343540d75f5b85a1877eed1a2a19b9f284248586
|
||||
F src/pcache1.c 54881292a9a5db202b2c0ac541c5e3ef9a5e8c4f1c1383adb2601d5499a60e65
|
||||
F src/pragma.c c536665ce8431c8b1efbf7e0a5c01852f49f7bf28f1954f8118b2d28e4a3797f
|
||||
F src/pragma.c 7c024d690a3dc93f61830f11f900e4af2357f31d081b0c79099ca5e28919cba7
|
||||
F src/pragma.h 87330ed2fbfa2a1274de93ca0ab850fba336189228cb256089202c3b52766fad
|
||||
F src/prepare.c 45fe7408eb78d80eca8392669070a6e5caf231b09e5c7b1ff65c1ad64a3734c5
|
||||
F src/printf.c 975f1f5417f2526365b6e6d7f22332e3e11806dad844701d92846292b654ba9a
|
||||
F src/prepare.c fd940149c691684e7c1073c3787a7170e44852b02d1275d2e30a5b58e89cfcaf
|
||||
F src/printf.c 05d8dfd2018bc4fc3ddb8b37eb97ccef7abf985643fa1caebdcf2916ca90fa32
|
||||
F src/random.c 097dc8b31b8fba5a9aca1697aeb9fd82078ec91be734c16bffda620ced7ab83c
|
||||
F src/resolve.c 359bc0e445d427583d2ab6110433a5dc777f64a0ecdf8d24826d8b475233ead9
|
||||
F src/resolve.c ea935b87d6fb36c78b70cdc7b28561dc8f33f2ef37048389549c7b5ef9b0ba5e
|
||||
F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92
|
||||
F src/select.c ab5717255420972e69b9b9ce4d1c4730fe82cfbdc14b7743e389a8bdb79ca027
|
||||
F src/shell.c.in 4690f216dc4da0c104a8fd9f9e12bec0483242e630324aa7a3ccd155922e346e
|
||||
F src/sqlite.h.in 31c2c8d737814369bd3b71f3849c4a97ef7ede0aa3ce976ecb11632fa5f1f863
|
||||
F src/select.c 3baa9dd8cf240654773c7974e2bcce398ac9dd24419c36684156963defe43b35
|
||||
F src/shell.c.in 69d1e59da4881f096ab47fbd3e6d99794f3e4a43f41fd9e4d2e845c9b8d20fd5
|
||||
F src/sqlite.h.in b93deee892f1bc4030e5c8712df9e21d786a1bf8e921ab8dc987eaf1e44c676f
|
||||
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
|
||||
F src/sqlite3ext.h 5d54cf13d3406d8eb65d921a0d3c349de6126b732e695e79ecd4830ce86b4f8a
|
||||
F src/sqliteInt.h 21a31abf60222f50c1d654cdc27ad9d4040249f0341129dd8286b8b5b32bcd30
|
||||
F src/sqlite3ext.h a95cb9ed106e3d39e2118e4dcc15a14faec3fa50d0093425083d340d9dfd96e6
|
||||
F src/sqliteInt.h e7b93bb693cb14259f6c3faadc6d7c824ff509aac673622a76c161a96c5872d0
|
||||
F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a31657
|
||||
F src/status.c 4b8bc2a6905163a38b739854a35b826c737333fab5b1f8e03fa7eb9a4799c4c1
|
||||
F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1
|
||||
F src/tclsqlite.c 48f291e1a7e672a7204884d4c164a8ed3a522ff087c361ada2991f5d54e987f6
|
||||
F src/test1.c 9287559cc1f7c5a25f927aa172e69778237f0e037960dbcdb4257d0bea500114
|
||||
F src/tclsqlite.c 1f6673991147bc2cecc08a40d22f9803b84c805b24b499fe727f392256f73474
|
||||
F src/test1.c 87fda59eea3ac1eba1baef37c1967565cb1b8d6d264649f2e57f252ca5989914
|
||||
F src/test2.c 3efb99ab7f1fc8d154933e02ae1378bac9637da5
|
||||
F src/test3.c 61798bb0d38b915067a8c8e03f5a534b431181f802659a6616f9b4ff7d872644
|
||||
F src/test4.c 7c4420e01c577b5c4add2cb03119743b1a357543d347773b9e717195ea967159
|
||||
@@ -574,10 +574,10 @@ 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 78809f11026f18a93fcfd798d9479cba37e1201c830260bf1edc674b2fa9b857
|
||||
F src/test_bestindex.c 8294d8223b7f18a3ddb7f9a0e30815dcca4e61681f78b538c870f7d934f88b81
|
||||
F src/test_blob.c ae4a0620b478548afb67963095a7417cd06a4ec0a56adb453542203bfdcb31ce
|
||||
F src/test_btree.c 8b2dc8b8848cf3a4db93f11578f075e82252a274
|
||||
F src/test_config.c 284c29912736f68b0a583a920bf63fd8f9125dffb8a75cb0676e58502b2f7908
|
||||
F src/test_config.c 8264637b06a3c1f0727c88d1ea32dcf7986b9e7e358a970cae87cdac8a5b2708
|
||||
F src/test_delete.c e2fe07646dff6300b48d49b2fee2fe192ed389e834dd635e3b3bac0ce0bf9f8f
|
||||
F src/test_demovfs.c 86142ba864d4297d54c5b2e972e74f3141ae4b30f05b3a95824184ed2d3d7f91
|
||||
F src/test_devsym.c aff2255ea290d7718da08af30cdf18e470ff7325a5eff63e0057b1496ed66593
|
||||
@@ -616,34 +616,34 @@ F src/test_windirent.h 90dfbe95442c9762357fe128dc7ae3dc199d006de93eb33ba3972e0a9
|
||||
F src/test_window.c cdae419fdcea5bad6dcd9368c685abdad6deb59e9fc8b84b153de513d394ba3f
|
||||
F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9
|
||||
F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c
|
||||
F src/tokenize.c b74d878aa7c82ec8460779468061a96185e22257f68ab785b69abce354b70446
|
||||
F src/treeview.c 9dfdb7ff7f6645d0a6458dbdf4ffac041c071c4533a6db8bb6e502b979ac67bc
|
||||
F src/trigger.c 40e7c3dcff57a770d5fa38ba21ed4725572fd2e224c58af61eb980598b60f9c8
|
||||
F src/update.c d6f5c7b9e072660757ac7d58175aca11c07cb95ebbb297ae7f38853700f52328
|
||||
F src/tokenize.c 6661a9fa660ecbd3ac0df1acd2ec788b3a8122b4316022bcdaf476ea6754a8de
|
||||
F src/treeview.c a84b57d15e46007d8b1ae249344b3f0b7f3c62def908b98baaa54935a57c8476
|
||||
F src/trigger.c 5fc3cde35cc4de510be68bb2db4dcff0ce0e1625f43e28a0920be9a6f010cd3f
|
||||
F src/update.c f875b0d59da5c3055a0b2ac20560e1650229c6787e78de5e9836267b5cbb8359
|
||||
F src/upsert.c 8789047a8f0a601ea42fa0256d1ba3190c13746b6ba940fe2d25643a7e991937
|
||||
F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0
|
||||
F src/util.c 89e51820bcb468ff3877a8d942f5cc807208087f021227e0927693e928a195bc
|
||||
F src/util.c 602fe229f32a96ceccae4f40824129669582096f7c355f53dbac156c9fecef23
|
||||
F src/vacuum.c 6c38ddc52f0619865c91dae9c441d4d48bf3040d7dc1bc5b22da1e45547ed0b3
|
||||
F src/vdbe.c cfe1980fbeb87eb35297b4a41808034761f26277cf45c9cf3e4eac20edcba1d5
|
||||
F src/vdbe.c 8239c69f3cb6fa27bac30d60c5a1ebac723abc007ff870ffc3af93e5159c7216
|
||||
F src/vdbe.h 25dabb25c7e157b84e59260cfb5b466c3ac103ede9f36f4db371332c47601abe
|
||||
F src/vdbeInt.h d89d5d2150500cfb08615329fd20aea9d746bba5f2c3ecb8a17e2d2d9be029e5
|
||||
F src/vdbeapi.c 22c79072ae7d8a01e9bcae8ba16e918d60d202eaa9553b5fda38f99f7464d99a
|
||||
F src/vdbeaux.c c1b452cc17f5887b3d36bc277a2181914d6bed508ea45827b5f348160491e6a6
|
||||
F src/vdbeblob.c 29c4118f7ee615cdee829e8401f6ead1b96b95d545b4de0042f6de39c962c652
|
||||
F src/vdbemem.c da4d594084d581be6436582bb44bb128feeb138a3e6c313eda6749ebdc3a65ec
|
||||
F src/vdbeInt.h b45599a2b59f1ce042512ab6786b0b82a8cf3002f6b0fa60b4834e2cd3ac61d8
|
||||
F src/vdbeapi.c 8863ffb5a7bac42fe9a68aaa3526ee29fc18fb02a9b27188b756de41e33856e9
|
||||
F src/vdbeaux.c 0d7659fe8cb38ce86092b9bc5131c99a834a04eb78745e54acb77d79d7af2fb5
|
||||
F src/vdbeblob.c 5e61ce31aca17db8fb60395407457a8c1c7fb471dde405e0cd675974611dcfcd
|
||||
F src/vdbemem.c 69d3092d47b7a3a466a161961abd92bca7ab148abd8b497438eb17c6afdcbad8
|
||||
F src/vdbesort.c 43756031ca7430f7aec3ef904824a7883c4ede783e51f280d99b9b65c0796e35
|
||||
F src/vdbetrace.c fe0bc29ebd4e02c8bc5c1945f1d2e6be5927ec12c06d89b03ef2a4def34bf823
|
||||
F src/vdbevtab.c f99b275366c5fc5e2d99f734729880994ab9500bdafde7fae3b02d562b9d323c
|
||||
F src/vtab.c a47cc12ebaa350800c0c87b6b0095debbb5a6ed32727bcab9d82ad070a81b738
|
||||
F src/vtab.c 3d72c780d1ea08906a198e4f033921a658a54590e3ed72c544995d84f3f9464a
|
||||
F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9
|
||||
F src/wal.c b9df133a705093da8977da5eb202eaadb844839f1c7297c08d33471f5491843d
|
||||
F src/wal.h c3aa7825bfa2fe0d85bef2db94655f99870a285778baa36307c0a16da32b226a
|
||||
F src/walker.c f890a3298418d7cba3b69b8803594fdc484ea241206a8dfa99db6dd36f8cbb3b
|
||||
F src/where.c 9824d15f2a92cbe4d6566e2a97fa4466ce6297e68693322e64281db5e942fa92
|
||||
F src/whereInt.h 8a215acde0f833a4dea3d30a7bbed9f48b4b547b5d5e34cd02acee366476ab80
|
||||
F src/wherecode.c a0a5138b28550dd95916435283c507aa6bf24607ef38a0a18011e6626684330a
|
||||
F src/whereexpr.c 9f64c39e53070584e99e4d20c1dd3397e125fabbae8fd414ffec574c410ac7d3
|
||||
F src/window.c 5d3b397b0c026d0ff5890244ac41359e524c01ae31e78782e1ff418c3e271a9e
|
||||
F src/where.c 48d9836b7bdf301783719156fd50d45685a601605334035c559ed2d655df9fb6
|
||||
F src/whereInt.h 15d2975c3b4c193c78c26674400a840da8647fe1777ae3b026e2d15937b38a03
|
||||
F src/wherecode.c 84be340684393248b9f3ecbce9b87c8a6f818149b52302702ea0b8d2a9d51faf
|
||||
F src/whereexpr.c 2a71f5491798460c9590317329234d332d9eb1717cba4f3403122189a75c465e
|
||||
F src/window.c 731980c0887f7ec9859f5e0d3c69d5fbeb6e512a9e1d338935f53938eaba431e
|
||||
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
|
||||
F test/affinity2.test ce1aafc86e110685b324e9a763eab4f2a73f737842ec3b687bd965867de90627
|
||||
F test/affinity3.test eecb0dabee4b7765a8465439d5e99429279ffba23ca74a7eae270a452799f9e7
|
||||
@@ -657,18 +657,18 @@ F test/alter3.test ffc4ab29ce78a3517a66afd69b2730667e3471622509c283b2bd4c46f680f
|
||||
F test/alter4.test 716caa071dd8a3c6d57225778d15d3c3cbf5e34b2e84ae44199aeb2bbf50a707
|
||||
F test/alterauth.test 63442ba61ceb0c1eeb63aac1f4f5cebfa509d352276059d27106ae256bafc959
|
||||
F test/alterauth2.test 48967abae0494d9a300d1c92473d99fcb66edfcc23579c89322f033f49410adc
|
||||
F test/altercol.test 9471187fe155d9c4211ae185e104ff48ce8f114262ee1256cf1e110b339c725f
|
||||
F test/altercol.test 8465ca659c2c55a359cf16cc261df4fcb5c45a5f104a50827c337ae66c09dc15
|
||||
F test/altercorrupt.test 2e1d705342cf9d7de884518ddbb053fd52d7e60d2b8869b7b63b2fda68435c12
|
||||
F test/alterdropcol.test a653a3945f964d26845ec0cd0a8e74189f46de3119a984c5bc45457da392612e
|
||||
F test/alterdropcol2.test 527fce683b200d620f560f666c44ae33e22728e990a10a48a543280dfd4b4d41
|
||||
F test/alterfault.test 289067108947bedca27534edd4ff251bcd298cf84402d7b24eaa3749305418c6
|
||||
F test/alterlegacy.test f38c6d06cda39e1f7b955bbce57f2e3ef5b7cb566d3d1234502093e228c15811
|
||||
F test/altermalloc.test 167a47de41b5c638f5f5c6efb59784002b196fff70f98d9b4ed3cd74a3fb80c9
|
||||
F test/altermalloc2.test ca3ebc01670d9313953a2b7628d8cc00dc5ea9988f229b3cbbbe1cca506dae45
|
||||
F test/altermalloc3.test 4660ac6240a8c82ba3947b927612dcc7c05a8eec3fe3c9f38e047ca69a789a33
|
||||
F test/alterqf.test 3008318ba9e16b4ac0b5f83cf7683caa4b0a3154aafe3b4099838a250d4ba74a
|
||||
F test/altermalloc2.test 17fb3724c4b004c469c27dc4ef181608aa644555fbd3f3236767584f73747c81
|
||||
F test/altermalloc3.test 55e606edf4b0acfbbd851ddfe93cfdddfae43d103644dcfd6008ae4ab3c44adf
|
||||
F test/alterqf.test ff6c6f881485c29ed699b8ef4774864ca1b0c01a6c08f5cdd624a008e4b40fca
|
||||
F test/altertab.test 7273b8506eab46342be016af78028df49f3bd99037412f997a8f1011b37a6912
|
||||
F test/altertab2.test b0d62f323ca5dab42b0bc028c52e310ebdd13e655e8fac070fe622bad7852c2b
|
||||
F test/altertab2.test 62597b6fd08feaba1b6bfe7d31dac6117c67e06dc9ce9c478a3abe75b5926de0
|
||||
F test/altertab3.test 5929f522fd6fd708396ad9f317d4af9ff1a93e460df85bb1d54d4499eeb94960
|
||||
F test/amatch1.test b5ae7065f042b7f4c1c922933f4700add50cdb9f
|
||||
F test/analyze.test 547bb700f903107b38611b014ca645d6b5bb819f5210d7bf39c40802aafeb7d7
|
||||
@@ -715,7 +715,7 @@ F test/autovacuum_ioerr2.test 8a367b224183ad801e0e24dcb7d1501f45f244b4
|
||||
F test/avfs.test 0c3a38e03cccb0fc3127838462dc05dc3f4c1480d770c084b388304c25de3652
|
||||
F test/avtrans.test b7dc25459ecbd86c6fa9c606ee3068f59d81e225118617dcf2bbb6ded2ade89e
|
||||
F test/backcompat.test 3e64cedda754c778ef6bbe417b6e7a295e662a4d
|
||||
F test/backup.test dd4a5ff756e3df3931dacb1791db0584d4bad989
|
||||
F test/backup.test fc1ecefce723fad5199b55cec7a5a992ec8c3ad6873419e5e8919066dec457f3
|
||||
F test/backup2.test 8facb54df1388419d34b362ab1f7e233310ff3a3af64e8ad5ec47ba3c2bbe5cf
|
||||
F test/backup4.test 8f6fd48e0dfde77b9a3bb26dc471ede3e101df32
|
||||
F test/backup5.test ee5da6d7fe5082f5b9b0bbfa31d016f52412a2e4
|
||||
@@ -724,13 +724,14 @@ F test/backup_malloc.test 0c9abdf74c51e7bedb66d504cd684f28d4bd4027
|
||||
F test/badutf.test d5360fc31f643d37a973ab0d8b4fb85799c3169f
|
||||
F test/badutf2.test f310fd3b24a491b6b77bccdf14923b85d6ebcce751068c180d93a6b8ff854399
|
||||
F test/bc_common.tcl b5e42d80305be95697e6370e015af571e5333a1c
|
||||
F test/bestindex1.test 7cc626f1f4a7483bb6b38487d467db4477083be5cd93958aeda5d5127640dc81
|
||||
F test/bestindex2.test 60266e2854055788459cbfd86cef575601eabe74a2c61faba72601739fea4398
|
||||
F test/bestindex3.test e061a6ed0f519beee037ba7e7a4c37f80c8a7e4a303e2559ed1f760e4b0235eb
|
||||
F test/bestindex4.test 82250e7dcc6d5b15244edc9d6554b1760583af1b8548c2a255a1c4f28e744c0e
|
||||
F test/bestindex5.test 67c1166131bb59f9e47c00118f7d432ca5491e6cae6ca3f87ca9db20103a78f9
|
||||
F test/bestindex6.test d856a9bb63d927493575823eed44053bc36251e241aa364e54d0f2a2d302e1d4
|
||||
F test/bestindex7.test a11348824aed0de2bb9030f092636929000cd72882bdf919adacc3792f67ccbd
|
||||
F test/bestindex1.test 856a453dff8c68b4568601eed5a8b5e20b4763af9229f3947c215729ed878db0
|
||||
F test/bestindex2.test 394ff8fbf34703391247116d6a44e1c50ee7282236ee77909044573cefc37bc0
|
||||
F test/bestindex3.test 34bea272b0e0f835651b16a3931dbe7ac927039be6b2e1cb617bbe1d584b492b
|
||||
F test/bestindex4.test 3039894f2dad50f3a68443dffad1b44c9b067ac03870102df1ce3d9a46ea602e
|
||||
F test/bestindex5.test a0c90b2dad7836e80a01379e200e5f8ec9476d49b349af02c0dbff2fb75dc98d
|
||||
F test/bestindex6.test 16942535b551273f3ad9df8d7cc4b7f22b1fcd8882714358859eb049a6f99dd4
|
||||
F test/bestindex7.test f094c669a6400777f4d2ddc3ed28e39169f1adb5be3d59b55f22ccf8c414b71e
|
||||
F test/bestindex8.test abd0016fc04f19dc382976750b06df5463d2757e11e78a8ba7d7dc50671f3337
|
||||
F test/between.test b9a65fb065391980119e8a781a7409d3fcf059d89968279c750e190a9a1d5263
|
||||
F test/bigfile.test aa74f4e5db51c8e54a1d9de9fa65d01d1eb20b59
|
||||
F test/bigfile2.test 1b489a3a39ae90c7f027b79110d6b4e1dbc71bfc
|
||||
@@ -738,6 +739,7 @@ F test/bigmmap.test b820c234daa56d24bc3bf006e3ac7aa9d9623c8ac656a38f59063b444a2d
|
||||
F test/bigrow.test f0aeb7573dcb8caaafea76454be3ade29b7fc747
|
||||
F test/bigsort.test 8299fa9298f4f1e02fc7d2712e8b77d6cd60e5a2
|
||||
F test/bind.test 1e136709b306f7ed3192d349c2930d89df6ab621654ad6f1a72381d3fe76f483
|
||||
F test/bind2.test 918bc35135f4141809ead7585909cde57d44db90a7a62aef540127148f91aab7
|
||||
F test/bindxfer.test efecd12c580c14df5f4ad3b3e83c667744a4f7e0
|
||||
F test/bitvec.test 75894a880520164d73b1305c1c3f96882615e142
|
||||
F test/blob.test e7ac6c7d3a985cc4678c64f325292529a69ae252
|
||||
@@ -761,7 +763,7 @@ F test/capi2.test 4ee545824adc3eb33bf57ef89f77440b28188ec3da72e5425ff0fcdba32e8d
|
||||
F test/capi3.test 3910a73c38ac76d69778dd9eb481ab7cd6ed59117fc047b4f6056a5c72529de1
|
||||
F test/capi3b.test efb2b9cfd127efa84433cd7a2d72ce0454ae0dc4
|
||||
F test/capi3c.test 54e2dc0c8fd7c34ad1590d1be6864397da2438c95a9f5aee2f8fbc60c112e44b
|
||||
F test/capi3d.test aba917805573a03deed961a21f07a5a84505ad0a616f7e3fc1508844a15bccc4
|
||||
F test/capi3d.test 8b778794af891b0dca3d900bd345fbc8ebd2aa2aae425a9dccdd10d5233dfbde
|
||||
F test/capi3e.test 3d49c01ef2a1a55f41d73cba2b23b5059ec460fe
|
||||
F test/carray01.test d55d57bf66b1af1c7ac55fae66ff4910884a8f5d21a90a18797ce386212a2634
|
||||
F test/cast.test 336fa21989b5170ebcaf90c24266be22dd97b3e23d1fad5ecf6ad4efb04c4423
|
||||
@@ -835,14 +837,15 @@ F test/ctime.test 340f362f41f92972bbd71f44e10569a5cc694062b692231bd08aa6fe6c1c47
|
||||
F test/cursorhint.test 0175e4404181ace3ceca8b114eb0a98eae600d565aa4e2705abbe6614c7fe201
|
||||
F test/cursorhint2.test 6f3aa9cb19e7418967a10ec6905209bcbb5968054da855fc36c8beee9ae9c42f
|
||||
F test/dataversion1.test 6e5e86ac681f0782e766ebcb56c019ae001522d114e0e111e5ebf68ccf2a7bb8
|
||||
F test/date.test 9b73bbeb1b82d9c1f44dec5cf563bf7da58d2373
|
||||
F test/date.test 118e04db8c8b4efeb885542b4918c7b869a34c460a6bebbfe927dfd75706b80d
|
||||
F test/date2.test 7e12ec14aaf4d5e6294b4ba140445b0eca06ea50062a9c3a69c4ee13d0b6f8b1
|
||||
F test/date3.test a1b77abf05c6772fe5ca2337cac1398892f2a41e62bce7e6be0f4a08a0e64ae5
|
||||
F test/dbdata.test 042f49acff3438f940eeba5868d3af080ae64ddf26ae78f80c92bec3ca7d8603
|
||||
F test/dbfuzz.c 73047c920d6210e5912c87cdffd9a1c281d4252e
|
||||
F test/dbfuzz001.test 55e1a3504f8dea84155e09912fe3b1c3ad77e0b1a938ec42ca03b8e51b321e30
|
||||
F test/dbfuzz2-seed1.db e6225c6f3d7b63f9c5b6867146a5f329d997ab105bee64644dc2b3a2f2aebaee
|
||||
F test/dbfuzz2.c 4b3c12de4d98b1b2d908ab03d217d4619e47c8b23d5e67f8a6f2b1bdee7cae23
|
||||
F test/dbpage.test 650234ba683b9d82b899c6c51439819787e7609f17a0cc40e0080a7b6443bc38
|
||||
F test/dbpage.test fce29035c7566fd7835ec0f19422cb4b9c6944ce0e1b936ff8452443f92e887d
|
||||
F test/dbstatus.test 4a4221a883025ffd39696b3d1b3910b928fb097d77e671351acb35f3aed42759
|
||||
F test/dbstatus2.test f5fe0afed3fa45e57cfa70d1147606c20d2ba23feac78e9a172f2fe8ab5b78ef
|
||||
F test/decimal.test fcf403fd5585f47342234e153c4a4338cd737b8e0884ac66fc484df47dbcf1a7
|
||||
@@ -864,7 +867,7 @@ F test/e_blobclose.test 692fc02a058476c2222a63d97e3f3b2b809c1842e5525ded7f854d54
|
||||
F test/e_blobopen.test 29f6055ee453b8e679fe9570c4d3acfedbef821622c5dad16875148c5952ef50
|
||||
F test/e_blobwrite.test 3075ff539827576d9a34cbb5a2ac75eb65fb49cd5aadc27686b0719fbf99c156
|
||||
F test/e_changes.test 0f8c3e6aab7335cb772d5a3ea34ca4c82f98d0eb896e2eb3add971c16984b405
|
||||
F test/e_createtable.test 04c50b7fe41c12ed9cd88fbbc09b4900bcfc66f98ad198874fc993a2771f3913
|
||||
F test/e_createtable.test e3b9782e80c0cf2898ac0eb1d9cd058412955ff53a8e47307a60c8289d62ff9c
|
||||
F test/e_delete.test ab39084f26ae1f033c940b70ebdbbd523dc4962e
|
||||
F test/e_droptrigger.test 235c610f8bf8ec44513e222b9085c7e49fad65ad0c1975ac2577109dd06fd8fa
|
||||
F test/e_dropview.test 74e405df7fa0f762e0c9445b166fe03955856532e2bb234c372f7c51228d75e7
|
||||
@@ -1052,16 +1055,16 @@ F test/func2.test 772d66227e4e6684b86053302e2d74a2500e1e0f
|
||||
F test/func3.test 600a632c305a88f3946d38f9a51efe145c989b2e13bd2b2a488db47fe76bab6a
|
||||
F test/func4.test 2285fb5792d593fef442358763f0fd9de806eda47dbc7a5934df57ffdc484c31
|
||||
F test/func5.test 863e6d1bd0013d09c17236f8a13ea34008dd857d87d85a13a673960e4c25d82a
|
||||
F test/func6.test 90e42b64c4f9fb6f04f44cb8a1da586c8542502e926b19c76504fe74ff2a9b7c
|
||||
F test/func6.test 9cc9b1f43b435af34fe1416eb1e318c8920448ea7a6962f2121972f5215cb9b0
|
||||
F test/func7.test b9e2a1a30a8562b00841b4a21a5d2d81754fa3ab99275fd71fd5279287b44b1c
|
||||
F test/fuzz-oss1.test 514dcabb24687818ea949fa6760229eaacad74ca70157743ef36d35bbe01ffb0
|
||||
F test/fuzz.test 96083052bf5765e4518c1ba686ce2bab785670d1
|
||||
F test/fuzz.test 4608c1310cff4c3014a84bcced6278139743e080046e5f6784b0de7b069371d8
|
||||
F test/fuzz2.test 76dc35b32b6d6f965259508508abce75a6c4d7e1
|
||||
F test/fuzz3.test 9c813e6613b837cb7a277b0383cd66bfa07042b4cf0317157c35852f30043c31
|
||||
F test/fuzz4.test c229bcdb45518a89e1d208a21343e061503460ac69fae1539320a89f572eb634
|
||||
F test/fuzz_common.tcl b7197de6ed1ee8250a4f82d67876f4561b42ee8cbbfc6160dcb66331bad3f830
|
||||
F test/fuzz_malloc.test f348276e732e814802e39f042b1f6da6362a610af73a528d8f76898fde6b22f2
|
||||
F test/fuzzcheck.c bdb852815048a0beebbe5768bca61e75295324a811a8d7216f97b96501befd1e
|
||||
F test/fuzzcheck.c e34696a5db46738118b2efd14fb71f8458ecf0f482df8bbae18fa1d64db9ab7b
|
||||
F test/fuzzdata1.db d36e88741b4f23bcbaaf55b006290669d03c6c891cf13c7b3a53bc1b097b693f
|
||||
F test/fuzzdata2.db 128b3feeb78918d075c9b14b48610145a0dd4c8d6f1ca7c2870c7e425f5bf31f
|
||||
F test/fuzzdata3.db c6586d3e3cef0fbc18108f9bb649aa77bfc38aba
|
||||
@@ -1069,7 +1072,7 @@ F test/fuzzdata4.db b502c7d5498261715812dd8b3c2005bad08b3a26e6489414bd13926cd3e4
|
||||
F test/fuzzdata5.db e35f64af17ec48926481cfaf3b3855e436bd40d1cfe2d59a9474cb4b748a52a5
|
||||
F test/fuzzdata6.db 92a80e4afc172c24f662a10a612d188fb272de4a9bd19e017927c95f737de6d7
|
||||
F test/fuzzdata7.db 0166b56fd7a6b9636a1d60ef0a060f86ddaecf99400a666bb6e5bbd7199ad1f2
|
||||
F test/fuzzdata8.db a0c7af954bcbb226ed7ae087b3b6d6e48eaac8fac5671150ffd23c35b55bffe6
|
||||
F test/fuzzdata8.db ca9a97f401b06b0d5376139ec7e1f9e773e13345a9a2d9ccc0032cdbfedea230
|
||||
F test/fuzzer1.test 3d4c4b7e547aba5e5511a2991e3e3d07166cfbb8
|
||||
F test/fuzzer2.test a85ef814ce071293bce1ad8dffa217cbbaad4c14
|
||||
F test/fuzzerfault.test f64c4aef4c9e9edf1d6dc0d3f1e65dcc81e67c996403c88d14f09b74807a42bc
|
||||
@@ -1118,7 +1121,7 @@ F test/init.test 15c823093fdabbf7b531fe22cf037134d09587a7
|
||||
F test/insert.test 4e3f0de67aac3c5be1f4aaedbcea11638f1b5cdc9a3115be14d19aa9db7623c6
|
||||
F test/insert2.test 4d14b8f1b810a41995f6286b64a6943215d52208
|
||||
F test/insert3.test 1b7db95a03ad9c5013fdf7d6722b6cd66ee55e30
|
||||
F test/insert4.test 59cb99521be01a5aefc9be8e8b5a51ee7f3944781d4d7f6201b9f774fcd51662
|
||||
F test/insert4.test 2bf81535a990c969665d66db51fcf76c23499b39893b5109f413d1de4ad34cd3
|
||||
F test/insert5.test 394f96728d1258f406fe5f5aeb0aaf29487c39a6
|
||||
F test/insertfault.test ac63d14ea3b49c573673a572f4014b9117383a03e497c58f308b5c776e4a7f74
|
||||
F test/instr.test 107df2b9b74a4b59315916b575590a08f2a714de0754abe541f10a0971d0a2a4
|
||||
@@ -1140,7 +1143,7 @@ F test/join.test 25cf0ac11c3b81fedfd166f9062166bdb39dea92f5a7c16cacbf6dc1f7f6702
|
||||
F test/join2.test 9bdc615841b91c97a16d68bad9508aea11fa0c6b34e5689847bcc4dac70e4990
|
||||
F test/join3.test 6f0c774ff1ba0489e6c88a3e77b9d3528fb4fda0
|
||||
F test/join4.test 1a352e4e267114444c29266ce79e941af5885916
|
||||
F test/join5.test d22395f7d4020a58cabbc8316f300a5cfef84aee9e8ba7ce79b33cc43a3e1e2e
|
||||
F test/join5.test 0d63c7e43b3160b9d4b93f196ef83b6efc7751b9edd0d18c53a46fbec7a49cfc
|
||||
F test/join6.test f809c025fa253f9e150c0e9afd4cef8813257bceeb6f46e04041228c9403cc2c
|
||||
F test/journal1.test c7b768041b7f494471531e17abc2f4f5ebf9e5096984f43ed17c4eb80ba34497
|
||||
F test/journal2.test 9dac6b4ba0ca79c3b21446bbae993a462c2397c4
|
||||
@@ -1148,11 +1151,11 @@ F test/journal3.test 7c3cf23ffc77db06601c1fcfc9743de8441cb77db9d1aa931863d94f5ff
|
||||
F test/jrnlmode.test 9b5bc01dac22223cb60ec2d5f97acf568d73820794386de5634dcadbea9e1946
|
||||
F test/jrnlmode2.test 8759a1d4657c064637f8b079592651530db738419e1d649c6df7048cd724363d
|
||||
F test/jrnlmode3.test 556b447a05be0e0963f4311e95ab1632b11c9eaa
|
||||
F test/json101.test bb71538005f2d9e18620bdd3b76839a93ca0be61903eb8d751a64e78cf99b8fb
|
||||
F test/json102.test 86edc7d283085addff8593b178997e75875530d1385f5926717543d3475e6b01
|
||||
F test/json103.test aff6b7a4c17d5a20b487a7bc1a274bfdc63b829413bdfb83bedac42ec7f67e3b
|
||||
F test/json104.test 2cb7ff2cca2c8214d3e5260eeb9ce45faec0926f68b3e40c1aaa6ca247284144
|
||||
F test/json105.test 45f7d6a9a54c85f8a9589b68d3e7a1f42d02f2359911a8cdbad1f9988f571173
|
||||
F test/json101.test d7c84854acafaf80f883e183ac4248ea2742615086c94a61a46ad7d7382ce123
|
||||
F test/json102.test 327e77275f338c028faefa2da5164daf6b142a165e3015ff2a6e4251ddc6a0ac
|
||||
F test/json103.test 53df87f83a4e5fa0c0a56eb29ff6c94055c6eb919f33316d62161a8880112dbe
|
||||
F test/json104.test a502dc01853aada95d721b3b275afbe2dc18fffdac1fea6e96fb20c13586bbb5
|
||||
F test/json105.test 11670a4387f4308ae0318cadcbd6a918ea7edcd19fbafde020720a073952675d
|
||||
F test/keyword1.test 37ef6bba5d2ed5b07ecdd6810571de2956599dff
|
||||
F test/kvtest.c feb4358fb022da8ebd098c45811f2f6507688bb6c43aa72b3e840df19026317b
|
||||
F test/lastinsert.test 42e948fd6442f07d60acbd15d33fb86473e0ef63
|
||||
@@ -1209,7 +1212,7 @@ F test/memjournal2.test 89a4e0d1084170a281efa4d54c2677599f986f44227f98f7dfae2828
|
||||
F test/memleak.test 10b9c6c57e19fc68c32941495e9ba1c50123f6e2
|
||||
F test/memsubsys1.test 9e7555a22173b8f1c96c281ce289b338fcba2abe8b157f8798ca195bbf1d347e
|
||||
F test/memsubsys2.test 3e4a8d0c05fd3e5fa92017c64666730a520c7e08
|
||||
F test/merge1.test c5abf7d4eca25b3d5ee96927efff18efc3cee5a8af54b8415cbddd6d4471fd70
|
||||
F test/merge1.test 0ade470d77b689c4a64dc7f736527fcd893140bcafa70af8f7b98523cfb83f16
|
||||
F test/minmax.test fe638b55d77d2375531a8f549b338eafcd9adfbd2f72df37ed77d9b26ca0a71a
|
||||
F test/minmax2.test cf9311babb6f0518d04e42fd6a42c619531c4309a9dd790a2c4e9b3bc595e0de
|
||||
F test/minmax3.test cc1e8b010136db0d01a6f2a29ba5a9f321034354
|
||||
@@ -1269,7 +1272,7 @@ F test/oserror.test 1fc9746b83d778e70d115049747ba19c7fba154afce7cc165b09feb6ca6a
|
||||
F test/ossfuzz.c 9636dad2092a05a32110df0ca06713038dd0c43dd89a77dabe4b8b0d71096715
|
||||
F test/ossshell.c f125c5bd16e537a2549aa579b328dd1c59905e7ab1338dfc210e755bb7b69f17
|
||||
F test/ovfl.test 199c482696defceacee8c8e0e0ef36da62726b2f
|
||||
F test/pager1.test 8cb45ccbdb3ba423fc8158701c8f010a1d104336b8f14ef14bbfbadf14bad700
|
||||
F test/pager1.test ffd885cdc98b986c9f746496508c0c4810ed0eaade3575ddf53c222e85880552
|
||||
F test/pager2.test 67b8f40ae98112bcdba1f2b2d03ea83266418c71
|
||||
F test/pager3.test 4e9a83d6ca0838d7c602c9eb93d1357562d9059c1e02ffb138a8271020838370
|
||||
F test/pager4.test a122e9e6925d5b23b31e3dfef8c6a44bbf19590e
|
||||
@@ -1310,10 +1313,10 @@ F test/recover.test ccb8c2623902a92ebb76770edd075cb4f75a4760bb7afde38026572c6e79
|
||||
F test/regexp1.test 0c3ff80f66b0eff80e623eb5db7a3dad512095c573d78ac23009785f6d8f51ce
|
||||
F test/regexp2.test 55ed41da802b0e284ac7e2fe944be3948f93ff25abbca0361a609acfed1368b5
|
||||
F test/reindex.test cd9d6021729910ece82267b4f5e1b5ac2911a7566c43b43c176a6a4732e2118d
|
||||
F test/releasetest_data.tcl 7cea6c852ae6bb3a9ff1a2b910e4dd13c16a05f74443984dfd52159b0b01ea55
|
||||
F test/releasetest_data.tcl 11ba48a21ed1c808147b0e77c6e93d204577f4327ffe6d7c3b34cd3c01eac3a2
|
||||
F test/resetdb.test 8062cf10a09d8c048f8de7711e94571c38b38168db0e5877ba7561789e5eeb2b
|
||||
F test/resolver01.test f4022acafda7f4d40eca94dbf16bc5fc4ac30ceb
|
||||
F test/returning1.test ee0b115162b17f59fe486767899596b1e8290bcd845db05d7d1d9e6c2dad1b8b
|
||||
F test/returning1.test c43b8370a351f77aec6d71f4a2cde59b849369ed1933261a2c2c69e23e34ff5e
|
||||
F test/returningfault.test ae4c4b5e8745813287a359d9ccdb9d5c883c2e68afb18fb0767937d5de5692a4
|
||||
F test/rollback.test 06680159bc6746d0f26276e339e3ae2f951c64812468308838e0a3362d911eaa
|
||||
F test/rollback2.test 3f3a4e20401825017df7e7671e9f31b6de5fae5620c2b9b49917f52f8c160a8f
|
||||
@@ -1322,11 +1325,11 @@ F test/round1.test 768018b04522ca420b1aba8a24bd76091d269f3bce3902af3ec6ebcee41ab
|
||||
F test/rowallock.test 3f88ec6819489d0b2341c7a7528ae17c053ab7cc
|
||||
F test/rowhash.test 0bc1d31415e4575d10cacf31e1a66b5cc0f8be81
|
||||
F test/rowid.test e29025be95baf6b32f0d5edef59a7633028325896a98f1caa8019559ca910350
|
||||
F test/rowvalue.test 02214016f747854ef636e64ff204778649937aa801ca78e2495a960f8e0d509d
|
||||
F test/rowvalue.test 228b312f8526ed000ecda559a6a9adf30aa2d79dcb12afa5c04eebaafcf55eae
|
||||
F test/rowvalue2.test 060d238b7e5639a7c5630cb5e63e311b44efef2b
|
||||
F test/rowvalue3.test 3068f508753af69884b12125995f023da0dbb256
|
||||
F test/rowvalue4.test 441e7e366ac6d939a3a95a574031c56ec2a854077a91d66eee5ff1d86cb5be58
|
||||
F test/rowvalue5.test c81c7d8cf36711ab37675ad7376084ae2a359cb6
|
||||
F test/rowvalue5.test 00740304ea6a53a8704640c7405690f0045d5d2a6b4b04dde7bccc14c3068ea7
|
||||
F test/rowvalue6.test d19b54feb604d5601f8614b15e214e0774c01087
|
||||
F test/rowvalue7.test c1cbdbf407029db01f87764097c6ac02a1c5a37efd2776eff32a9cdfdf6f2dba
|
||||
F test/rowvalue8.test 5900eddad9e2c3c2e26f1a95f74aafc1232ee5e0
|
||||
@@ -1385,11 +1388,11 @@ F test/sharedA.test 49d87ec54ab640fbbc3786ee3c01de94aaa482a3a9f834ad3fe92770eb69
|
||||
F test/sharedB.test 16cc7178e20965d75278f410943109b77b2e645e
|
||||
F test/shared_err.test 32634e404a3317eeb94abc7a099c556a346fdb8fb3858dbe222a4cbb8926a939
|
||||
F test/sharedlock.test 5ede3c37439067c43b0198f580fd374ebf15d304
|
||||
F test/shell1.test 70f46b5d07776a107335c3c2c9cbd0431d44637bfeae1f6b9ded5e33b4c7c0bf
|
||||
F test/shell2.test f00a0501c00583cbc46f7510e1d713366326b2b3e63d06d15937284171a8787c
|
||||
F test/shell3.test cb4b835a901742c9719437a89171172ecc4a8823ad97349af8e4e841e6f82566
|
||||
F test/shell4.test 3ed6c4b42fd695efcbc25d69ef759dbb15855ca8e52ba6c5ee076f8b435f48be
|
||||
F test/shell5.test b85069bfcf3159b225228629ab2c3e69aa923d098fea8ea074b5dcd743522e2c
|
||||
F test/shell1.test b224e0793c5f48aa3749e65d8c64b93a30731bd206f2e41e6c5f1bee1bdb16c6
|
||||
F test/shell2.test 89e4b2db062d52baed75022227b462d085cff495809de1699652779d8e0257d6
|
||||
F test/shell3.test a50628ab1d78d90889d9d3f32fb2c084ee15674771e96afe954aaa0accd1de3c
|
||||
F test/shell4.test 8f6c0fce4abed19a8a7f7262517149812a04caa905d01bdc8f5e92573504b759
|
||||
F test/shell5.test 0a9920d81fae28c45cd5dbd1deb809487a23c5f4b422a49f9d31c85f926d4a9c
|
||||
F test/shell6.test 1ceb51b2678c472ba6cf1e5da96679ce8347889fe2c3bf93a0e0fa73f00b00d3
|
||||
F test/shell7.test 115132f66d0463417f408562cc2cf534f6bbc6d83a6d50f0072a9eb171bae97f
|
||||
F test/shell8.test 388471d16e4de767333107e30653983f186232c0e863f4490bb230419e830aae
|
||||
@@ -1462,7 +1465,7 @@ F test/tabfunc01.test 241425ce3998687ab24adba09cb95e8012e17499b84a0ed47e128ab45e
|
||||
F test/table.test eb3463b7add9f16a5bb836badf118cf391b809d09fdccd1f79684600d07ec132
|
||||
F test/tableapi.test ecbcc29c4ab62c1912c3717c48ea5c5e59f7d64e4a91034e6148bd2b82f177f4
|
||||
F test/tableopts.test dba698ba97251017b7c80d738c198d39ab747930
|
||||
F test/tclsqlite.test 97cda6e4843e9f3e06c56f656d9b77ee0178fe1ee33fb09a6eeae8f125757ac1
|
||||
F test/tclsqlite.test ad0bbd92edabe64cc91d990a0748142fe5ab962d74ac71fa3bfa94d50d2f4c87
|
||||
F test/tempdb.test 4cdaa23ddd8acb4d79cbb1b68ccdfd09b0537aaba909ca69a876157c2a2cbd08
|
||||
F test/tempdb2.test 353864e96fd3ae2f70773d0ffbf8b1fe48589b02c2ec05013b540879410c3440
|
||||
F test/tempfault.test 0c0d349c9a99bf5f374655742577f8712c647900
|
||||
@@ -1637,7 +1640,7 @@ F test/trans.test 45f6f9ab6f66a7b5744f1caac06b558f95da62501916906cf55586a896f9f4
|
||||
F test/trans2.test 62bd045bfc7a1c14c5ba83ba64d21ade31583f76
|
||||
F test/trans3.test 91a100e5412b488e22a655fe423a14c26403ab94
|
||||
F test/transitive1.test f8ee983600b33d167da1885657f064aec404e1c0d0bc8765fdf163f4c749237a
|
||||
F test/trigger1.test d30cd09ae8ac365a088f09daba583cc5c0b8fc7d4e1d70809d0b4be3bf6ae2ab
|
||||
F test/trigger1.test 02cc64dc98278816c1c1ed8e472e18db8edbad88f37018bf46223e9614831963
|
||||
F test/trigger2.test 6e35bd7321c49e63d540aee980eb95dec63e1d1caca175224101045bcc80871f
|
||||
F test/trigger3.test aa640bb2bbb03edd5ff69c055117ea088f121945
|
||||
F test/trigger4.test 74700b76ebf3947b2f7a92405141eb2cf2a5d359
|
||||
@@ -1677,7 +1680,7 @@ F test/update.test eb7f4eb172ce270e51bb67d7867521f33a63635bb671e261bbafccaef3bd6
|
||||
F test/update2.test 67455bc61fcbcf96923c45b3bc4f87bc72be7d67575ad35f134906148c7b06d3
|
||||
F test/upfrom1.tcl 8859d9d437f03b44174c4524a7a734a391fd4526fcff65be08285dafc9dc9041
|
||||
F test/upfrom1.test 8cb06689e99cd707d884faa16da0e8eb26ff658bb01c47ddf72fadade666e6e1
|
||||
F test/upfrom2.test 88d39cb755db5789541e645d4e2764abc697a56958f28a3f8451a0e9342bbd6b
|
||||
F test/upfrom2.test 66f3ebf721b3cebd922faee5c386bf244f816d416b57c000753ff51af62328a1
|
||||
F test/upfrom3.test 6130f24ebf97f5ea865e5d2a14a2d543fe5428a62e87cc60f62d875e45c1f5f0
|
||||
F test/upfromfault.test 3a10075a0043f0c4fad6614b2c371f88a8ba5a4acab68b907438413865d6a8d6
|
||||
F test/upsert1.test b0ae2f58680c5205b4bc1cdeed3c3d444057c506f6c44494fa3eac60731d68a2
|
||||
@@ -1726,7 +1729,7 @@ F test/vtab_err.test dcc8b7b9cb67522b3fe7a272c73856829dae4ab7fdb30399aea1b6981bd
|
||||
F test/vtab_shared.test 5253bff2355a9a3f014c15337da7e177ab0ef8ad
|
||||
F test/vtabdistinct.test 7688f0889358f849fd60bbfde1ded38b014b18066076d4bfbb75395804dfe072
|
||||
F test/vtabdrop.test 65d4cf6722972e5499bdaf0c0d70ee3b8133944a4e4bc31862563f32a7edca12
|
||||
F test/vtabrhs1.test c138346be341916ecc9d918dcfc2657d27bce211a350a82b01d62d224b167b56
|
||||
F test/vtabrhs1.test 9b5ecbc74a689500c33a4b2b36761f9bcc22fcc4e3f9d21066ee0c9c74cf5f6c
|
||||
F test/wal.test b7cc6984709f54afbf8441747ced1f646af120bf0c1b1d847bfa39306fbea089
|
||||
F test/wal2.test 31f6e2c404b9f2cdf9ca19b105a1742fdc19653c2c936da39e3658c617524046
|
||||
F test/wal3.test 2a93004bc0fb2b5c29888964024695bade278ab2
|
||||
@@ -1771,7 +1774,7 @@ F test/where3.test 5b4ffc0ac2ea0fe92f02b1244b7531522fe4d7bccf6fa8741d54e82c10e67
|
||||
F test/where4.test 4a371bfcc607f41d233701bdec33ac2972908ba8
|
||||
F test/where5.test fdf66f96d29a064b63eb543e28da4dfdccd81ad2
|
||||
F test/where6.test 5da5a98cec820d488e82708301b96cb8c18a258b
|
||||
F test/where7.test ab41d53ce8f2a6919ea3d5b13cd1153c1375a8e3ddaa129b81781f9033981383
|
||||
F test/where7.test 1c1bf436bf31b913d4764a2b62ac6e98b9681e5c7ae2b562605592a56b7e946b
|
||||
F test/where8.test 461ca40265ed996a6305da99bb024b0e41602bb586acf544c08f95922358e49f
|
||||
F test/where9.test 1ffb75edc50a8faa6e7bd77f8221d783febb00b44b0bdb32fb48cec6e38eca95
|
||||
F test/whereA.test 9d1077b117f1b68d5f739d94f36956c36cf995eb87bb19b77b2e81af020edd20
|
||||
@@ -1823,7 +1826,7 @@ F test/with4.test 257be66c0c67fee1defbbac0f685c3465e2cad037f21ce65f23f86084f1982
|
||||
F test/with5.test 6248213c41fab36290b5b73aa3f937309dfba337004d9d8434c3fabc8c7d4be8
|
||||
F test/with6.test 661d7e416bef6c0a2556b2c9f0c8178a5b15932bed65246abed99723a8d4e7c0
|
||||
F test/withM.test 693b61765f2b387b5e3e24a4536e2e82de15ff64
|
||||
F test/without_rowid1.test 78fd9b437f4cdb46f76e6a510d545334e4f58e3e4ce37aaf19384eda5b27de8c
|
||||
F test/without_rowid1.test a5210b8770dc4736bca4e74bc96588f43025ad03ad6a80f885afd36d9890e217
|
||||
F test/without_rowid2.test af260339f79d13cb220288b67cd287fbcf81ad99
|
||||
F test/without_rowid3.test 39ab0dd773eaa62e59b17093f875327630f54c4145458f6d2b053d68d4b2f67b
|
||||
F test/without_rowid4.test 4e08bcbaee0399f35d58b5581881e7a6243d458a
|
||||
@@ -1884,7 +1887,7 @@ F tool/mksqlite3h.tcl 1f5e4a1dbbbc43c83cc6e74fe32c6c620502240b66c7c0f33a51378e78
|
||||
F tool/mksqlite3internalh.tcl eb994013e833359137eb53a55acdad0b5ae1049b
|
||||
F tool/mkvsix.tcl b9e0777a213c23156b6542842c238479e496ebf5
|
||||
F tool/offsets.c 8ed2b344d33f06e71366a9b93ccedaa38c096cc1dbd4c3c26ad08c6115285845
|
||||
F tool/omittest.tcl 3d222272b1d840b4e3d67bff0cb743ce3f633faddadb3702b2056b726775db8f
|
||||
F tool/omittest.tcl 3bc9609aceea871e1ca6ed6749df9ce79b89369d22b492f6ce6078f40647cc3f
|
||||
F tool/opcodesum.tcl 740ed206ba8c5040018988129abbf3089a0ccf4a
|
||||
F tool/pagesig.c ff0ca355fd3c2398e933da5e22439bbff89b803b
|
||||
F tool/replace.tcl 937c931ad560688e85bdd6258bdc754371bb1e2732e1fb28ef441e44c9228fce
|
||||
@@ -1906,7 +1909,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
|
||||
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
|
||||
F tool/speedtest8inst1.c 7ce07da76b5e745783e703a834417d725b7d45fd
|
||||
F tool/split-sqlite3c.tcl 3efcd4240b738f6bb2b5af0aea7e1e0ef9bc1c61654f645076cec883030b710c
|
||||
F tool/sqldiff.c 9c639de9fa541a947ea9776435c84adf00f43945e262556e15219ef09f0d912c
|
||||
F tool/sqldiff.c 4f967c199c5f93eec64978e3a625d6c07fb1162212b1d48f65740d9eb4607eee
|
||||
F tool/sqlite3_analyzer.c.in f88615bf33098945e0a42f17733f472083d150b58bdaaa5555a7129d0a51621c
|
||||
F tool/sqltclsh.c.in 1bcc2e9da58fadf17b0bf6a50e68c1159e602ce057210b655d50bad5aaaef898
|
||||
F tool/sqltclsh.tcl 862f4cf1418df5e1315b5db3b5ebe88969e2a784525af5fbf9596592f14ed848
|
||||
@@ -1915,10 +1918,10 @@ F tool/stack_usage.tcl f8e71b92cdb099a147dad572375595eae55eca43
|
||||
F tool/symbols-mingw.sh 4dbcea7e74768305384c9fd2ed2b41bbf9f0414d
|
||||
F tool/symbols.sh 1612bd947750e21e7b47befad5f6b3825b06cce0705441f903bf35ced65ae9b9
|
||||
F tool/varint.c 5d94cb5003db9dbbcbcc5df08d66f16071aee003
|
||||
F tool/vdbe-compress.tcl 5926c71f9c12d2ab73ef35c29376e756eb68361c
|
||||
F tool/vdbe-compress.tcl 1dcb7632e57cf57105248029e6e162fddaf6c0fccb3bb9e6215603752c5a2d4a
|
||||
F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f
|
||||
F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7
|
||||
F tool/warnings.sh 09311479bdc290e20ec8e35a3d1b14b096bbd96222277cfd6274c3a99b3d012f
|
||||
F tool/warnings.sh d58dc38367cc776550f90327e205d7946802d4004fb9f291fd8b81256bc1eedd
|
||||
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
|
||||
F vsixtest/App.xaml b76d3b48860e7454775c47ea38ffea9c4abe3e85
|
||||
F vsixtest/App.xaml.cpp 41158ee43269820136fa3bba00c0bd91b26cc38b650ee392aec2a8d823e54318
|
||||
@@ -1941,8 +1944,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
|
||||
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
|
||||
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
||||
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
||||
P 7af03f02940b5380ee7375672ca8d0ff68c5f741d0ea206911631f3eb5a78555
|
||||
R 8c92b45cd50ac9ababc3056da5861966
|
||||
P 4977d8f453bcd56fb1dfab02cc5b283fb32d402bafdf2b6112e7dd322b7c32ad
|
||||
R da11ed5f90621f5fb7c0aa8d0a45881c
|
||||
T +sym-release *
|
||||
T +sym-version-3.38.2 *
|
||||
U drh
|
||||
Z 0f40ebbc8d49180e2de4a825f9a960d1
|
||||
Z 1c2a1cc2a9288218f72e9d4db2ebcd7a
|
||||
# Remove this line to create a well-formed Fossil manifest.
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
4289edf3c5e32a05b51f232020099b33f6f5e79b0ceca2b96baf1186168d9af6
|
||||
d33c709cc0af66bc5b6dc6216eba9f1f0b40960b9ae83694c986fbf4c1d6f08f
|
||||
+56
-30
@@ -324,7 +324,9 @@ void sqlite3AlterFinishAddColumn(Parse *pParse, Token *pColDef){
|
||||
int r1; /* Temporary registers */
|
||||
|
||||
db = pParse->db;
|
||||
if( pParse->nErr || db->mallocFailed ) return;
|
||||
assert( db->pParse==pParse );
|
||||
if( pParse->nErr ) return;
|
||||
assert( db->mallocFailed==0 );
|
||||
pNew = pParse->pNewTable;
|
||||
assert( pNew );
|
||||
|
||||
@@ -629,7 +631,7 @@ void sqlite3AlterRenameColumn(
|
||||
if( 0==sqlite3StrICmp(pTab->aCol[iCol].zCnName, zOld) ) break;
|
||||
}
|
||||
if( iCol==pTab->nCol ){
|
||||
sqlite3ErrorMsg(pParse, "no such column: \"%s\"", zOld);
|
||||
sqlite3ErrorMsg(pParse, "no such column: \"%T\"", pOld);
|
||||
goto exit_rename_column;
|
||||
}
|
||||
|
||||
@@ -735,7 +737,9 @@ struct RenameCtx {
|
||||
** following a valid object, it may not be used in comparison operations.
|
||||
*/
|
||||
static void renameTokenCheckAll(Parse *pParse, const void *pPtr){
|
||||
if( pParse->nErr==0 && pParse->db->mallocFailed==0 ){
|
||||
assert( pParse==pParse->db->pParse );
|
||||
assert( pParse->db->mallocFailed==0 || pParse->nErr!=0 );
|
||||
if( pParse->nErr==0 ){
|
||||
const RenameToken *p;
|
||||
u8 i = 0;
|
||||
for(p=pParse->pRename; p; p=p->pNext){
|
||||
@@ -1057,12 +1061,12 @@ static void renameColumnParseError(
|
||||
const char *zN = (const char*)sqlite3_value_text(pObject);
|
||||
char *zErr;
|
||||
|
||||
zErr = sqlite3_mprintf("error in %s %s%s%s: %s",
|
||||
zErr = sqlite3MPrintf(pParse->db, "error in %s %s%s%s: %s",
|
||||
zT, zN, (zWhen[0] ? " " : ""), zWhen,
|
||||
pParse->zErrMsg
|
||||
);
|
||||
sqlite3_result_error(pCtx, zErr, -1);
|
||||
sqlite3_free(zErr);
|
||||
sqlite3DbFree(pParse->db, zErr);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1127,19 +1131,21 @@ static int renameParseSql(
|
||||
){
|
||||
int rc;
|
||||
|
||||
sqlite3ParseObjectInit(p, db);
|
||||
if( zSql==0 ){
|
||||
return SQLITE_NOMEM;
|
||||
}
|
||||
if( sqlite3StrNICmp(zSql,"CREATE ",7)!=0 ){
|
||||
return SQLITE_CORRUPT_BKPT;
|
||||
}
|
||||
db->init.iDb = bTemp ? 1 : sqlite3FindDbName(db, zDb);
|
||||
|
||||
/* Parse the SQL statement passed as the first argument. If no error
|
||||
** occurs and the parse does not result in a new table, index or
|
||||
** trigger object, the database must be corrupt. */
|
||||
memset(p, 0, sizeof(Parse));
|
||||
p->eParseMode = PARSE_MODE_RENAME;
|
||||
p->db = db;
|
||||
p->nQueryLoop = 1;
|
||||
rc = zSql ? sqlite3RunParser(p, zSql) : SQLITE_NOMEM;
|
||||
rc = sqlite3RunParser(p, zSql);
|
||||
if( db->mallocFailed ) rc = SQLITE_NOMEM;
|
||||
if( rc==SQLITE_OK
|
||||
&& p->pNewTable==0 && p->pNewIndex==0 && p->pNewTrigger==0
|
||||
&& NEVER(p->pNewTable==0 && p->pNewIndex==0 && p->pNewTrigger==0)
|
||||
){
|
||||
rc = SQLITE_CORRUPT_BKPT;
|
||||
}
|
||||
@@ -1417,13 +1423,13 @@ static void renameParseCleanup(Parse *pParse){
|
||||
sqlite3DeleteTrigger(db, pParse->pNewTrigger);
|
||||
sqlite3DbFree(db, pParse->zErrMsg);
|
||||
renameTokenFree(db, pParse->pRename);
|
||||
sqlite3ParserReset(pParse);
|
||||
sqlite3ParseObjectReset(pParse);
|
||||
}
|
||||
|
||||
/*
|
||||
** SQL function:
|
||||
**
|
||||
** sqlite_rename_column(zSql, iCol, bQuote, zNew, zTable, zOld)
|
||||
** sqlite_rename_column(SQL,TYPE,OBJ,DB,TABLE,COL,NEWNAME,QUOTE,TEMP)
|
||||
**
|
||||
** 0. zSql: SQL statement to rewrite
|
||||
** 1. type: Type of object ("table", "view" etc.)
|
||||
@@ -1441,7 +1447,8 @@ static void renameParseCleanup(Parse *pParse){
|
||||
**
|
||||
** This function is used internally by the ALTER TABLE RENAME COLUMN command.
|
||||
** It is only accessible to SQL created using sqlite3NestedParse(). It is
|
||||
** not reachable from ordinary SQL passed into sqlite3_prepare().
|
||||
** not reachable from ordinary SQL passed into sqlite3_prepare() unless the
|
||||
** SQLITE_TESTCTRL_INTERNAL_FUNCTIONS test setting is enabled.
|
||||
*/
|
||||
static void renameColumnFunc(
|
||||
sqlite3_context *context,
|
||||
@@ -1590,7 +1597,9 @@ static void renameColumnFunc(
|
||||
|
||||
renameColumnFunc_done:
|
||||
if( rc!=SQLITE_OK ){
|
||||
if( sParse.zErrMsg ){
|
||||
if( rc==SQLITE_ERROR && sqlite3WritableSchema(db) ){
|
||||
sqlite3_result_value(context, argv[0]);
|
||||
}else if( sParse.zErrMsg ){
|
||||
renameColumnParseError(context, "", argv[1], argv[2], &sParse);
|
||||
}else{
|
||||
sqlite3_result_error_code(context, rc);
|
||||
@@ -1789,7 +1798,9 @@ static void renameTableFunc(
|
||||
rc = renameEditSql(context, &sCtx, zInput, zNew, bQuote);
|
||||
}
|
||||
if( rc!=SQLITE_OK ){
|
||||
if( sParse.zErrMsg ){
|
||||
if( rc==SQLITE_ERROR && sqlite3WritableSchema(db) ){
|
||||
sqlite3_result_value(context, argv[3]);
|
||||
}else if( sParse.zErrMsg ){
|
||||
renameColumnParseError(context, "", argv[1], argv[2], &sParse);
|
||||
}else{
|
||||
sqlite3_result_error_code(context, rc);
|
||||
@@ -1814,10 +1825,10 @@ static int renameQuotefixExprCb(Walker *pWalker, Expr *pExpr){
|
||||
return WRC_Continue;
|
||||
}
|
||||
|
||||
/*
|
||||
** The implementation of an SQL scalar function that rewrites DDL statements
|
||||
** so that any string literals that use double-quotes are modified so that
|
||||
** they use single quotes.
|
||||
/* SQL function: sqlite_rename_quotefix(DB,SQL)
|
||||
**
|
||||
** Rewrite the DDL statement "SQL" so that any string literals that use
|
||||
** double-quotes use single quotes instead.
|
||||
**
|
||||
** Two arguments must be passed:
|
||||
**
|
||||
@@ -1836,6 +1847,10 @@ static int renameQuotefixExprCb(Walker *pWalker, Expr *pExpr){
|
||||
** returns the string:
|
||||
**
|
||||
** CREATE VIEW v1 AS SELECT "a", 'string' FROM t1
|
||||
**
|
||||
** If there is a error in the input SQL, then raise an error, except
|
||||
** if PRAGMA writable_schema=ON, then just return the input string
|
||||
** unmodified following an error.
|
||||
*/
|
||||
static void renameQuotefixFunc(
|
||||
sqlite3_context *context,
|
||||
@@ -1910,7 +1925,11 @@ static void renameQuotefixFunc(
|
||||
renameTokenFree(db, sCtx.pList);
|
||||
}
|
||||
if( rc!=SQLITE_OK ){
|
||||
sqlite3_result_error_code(context, rc);
|
||||
if( sqlite3WritableSchema(db) && rc==SQLITE_ERROR ){
|
||||
sqlite3_result_value(context, argv[1]);
|
||||
}else{
|
||||
sqlite3_result_error_code(context, rc);
|
||||
}
|
||||
}
|
||||
renameParseCleanup(&sParse);
|
||||
}
|
||||
@@ -1922,7 +1941,8 @@ static void renameQuotefixFunc(
|
||||
sqlite3BtreeLeaveAll(db);
|
||||
}
|
||||
|
||||
/*
|
||||
/* Function: sqlite_rename_test(DB,SQL,TYPE,NAME,ISTEMP,WHEN,DQS)
|
||||
**
|
||||
** An SQL user function that checks that there are no parse or symbol
|
||||
** resolution problems in a CREATE TRIGGER|TABLE|VIEW|INDEX statement.
|
||||
** After an ALTER TABLE .. RENAME operation is performed and the schema
|
||||
@@ -1937,11 +1957,13 @@ static void renameQuotefixFunc(
|
||||
** 5: "when" part of error message.
|
||||
** 6: True to disable the DQS quirk when parsing SQL.
|
||||
**
|
||||
** Unless it finds an error, this function normally returns NULL. However, it
|
||||
** returns integer value 1 if:
|
||||
** The return value is computed as follows:
|
||||
**
|
||||
** * the SQL argument creates a trigger, and
|
||||
** * the table that the trigger is attached to is in database zDb.
|
||||
** A. If an error is seen and not in PRAGMA writable_schema=ON mode,
|
||||
** then raise the error.
|
||||
** B. Else if a trigger is created and the the table that the trigger is
|
||||
** attached to is in database zDb, then return 1.
|
||||
** C. Otherwise return NULL.
|
||||
*/
|
||||
static void renameTableTest(
|
||||
sqlite3_context *context,
|
||||
@@ -1986,12 +2008,16 @@ static void renameTableTest(
|
||||
if( rc==SQLITE_OK ){
|
||||
int i1 = sqlite3SchemaToIndex(db, sParse.pNewTrigger->pTabSchema);
|
||||
int i2 = sqlite3FindDbName(db, zDb);
|
||||
if( i1==i2 ) sqlite3_result_int(context, 1);
|
||||
if( i1==i2 ){
|
||||
/* Handle output case B */
|
||||
sqlite3_result_int(context, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( rc!=SQLITE_OK && zWhen ){
|
||||
if( rc!=SQLITE_OK && zWhen && !sqlite3WritableSchema(db) ){
|
||||
/* Output case A */
|
||||
renameColumnParseError(context, zWhen, argv[2], argv[3],&sParse);
|
||||
}
|
||||
renameParseCleanup(&sParse);
|
||||
@@ -2107,7 +2133,7 @@ void sqlite3AlterDropColumn(Parse *pParse, SrcList *pSrc, const Token *pName){
|
||||
}
|
||||
iCol = sqlite3ColumnIndex(pTab, zCol);
|
||||
if( iCol<0 ){
|
||||
sqlite3ErrorMsg(pParse, "no such column: \"%s\"", zCol);
|
||||
sqlite3ErrorMsg(pParse, "no such column: \"%T\"", pName);
|
||||
goto exit_drop_column;
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -354,7 +354,7 @@ static void codeAttach(
|
||||
}
|
||||
|
||||
#ifndef SQLITE_OMIT_AUTHORIZATION
|
||||
if( pAuthArg ){
|
||||
if( ALWAYS(pAuthArg) ){
|
||||
char *zAuthArg;
|
||||
if( pAuthArg->op==TK_STRING ){
|
||||
assert( !ExprHasProperty(pAuthArg, EP_IntValue) );
|
||||
|
||||
+2
-3
@@ -85,14 +85,13 @@ static Btree *findBtree(sqlite3 *pErrorDb, sqlite3 *pDb, const char *zDb){
|
||||
if( i==1 ){
|
||||
Parse sParse;
|
||||
int rc = 0;
|
||||
memset(&sParse, 0, sizeof(sParse));
|
||||
sParse.db = pDb;
|
||||
sqlite3ParseObjectInit(&sParse,pDb);
|
||||
if( sqlite3OpenTempDatabase(&sParse) ){
|
||||
sqlite3ErrorWithMsg(pErrorDb, sParse.rc, "%s", sParse.zErrMsg);
|
||||
rc = SQLITE_ERROR;
|
||||
}
|
||||
sqlite3DbFree(pErrorDb, sParse.zErrMsg);
|
||||
sqlite3ParserReset(&sParse);
|
||||
sqlite3ParseObjectReset(&sParse);
|
||||
if( rc ){
|
||||
return 0;
|
||||
}
|
||||
|
||||
+43
-34
@@ -1782,7 +1782,7 @@ static int freeSpace(MemPage *pPage, u16 iStart, u16 iSize){
|
||||
if( iFreeBlk>pPage->pBt->usableSize-4 ){ /* TH3: corrupt081.100 */
|
||||
return SQLITE_CORRUPT_PAGE(pPage);
|
||||
}
|
||||
assert( iFreeBlk>iPtr || iFreeBlk==0 );
|
||||
assert( iFreeBlk>iPtr || iFreeBlk==0 || CORRUPT_DB );
|
||||
|
||||
/* At this point:
|
||||
** iFreeBlk: First freeblock after iStart, or zero if none
|
||||
@@ -2053,7 +2053,7 @@ static int btreeInitPage(MemPage *pPage){
|
||||
pPage->nOverflow = 0;
|
||||
pPage->cellOffset = pPage->hdrOffset + 8 + pPage->childPtrSize;
|
||||
pPage->aCellIdx = data + pPage->childPtrSize + 8;
|
||||
pPage->aDataEnd = pPage->aData + pBt->usableSize;
|
||||
pPage->aDataEnd = pPage->aData + pBt->pageSize;
|
||||
pPage->aDataOfst = pPage->aData + pPage->childPtrSize;
|
||||
/* EVIDENCE-OF: R-37002-32774 The two-byte integer at offset 3 gives the
|
||||
** number of cells on the page. */
|
||||
@@ -2088,7 +2088,7 @@ static void zeroPage(MemPage *pPage, int flags){
|
||||
u8 hdr = pPage->hdrOffset;
|
||||
u16 first;
|
||||
|
||||
assert( sqlite3PagerPagenumber(pPage->pDbPage)==pPage->pgno );
|
||||
assert( sqlite3PagerPagenumber(pPage->pDbPage)==pPage->pgno || CORRUPT_DB );
|
||||
assert( sqlite3PagerGetExtra(pPage->pDbPage) == (void*)pPage );
|
||||
assert( sqlite3PagerGetData(pPage->pDbPage) == data );
|
||||
assert( sqlite3PagerIswriteable(pPage->pDbPage) );
|
||||
@@ -2104,7 +2104,7 @@ static void zeroPage(MemPage *pPage, int flags){
|
||||
pPage->nFree = (u16)(pBt->usableSize - first);
|
||||
decodeFlags(pPage, flags);
|
||||
pPage->cellOffset = first;
|
||||
pPage->aDataEnd = &data[pBt->usableSize];
|
||||
pPage->aDataEnd = &data[pBt->pageSize];
|
||||
pPage->aCellIdx = &data[first];
|
||||
pPage->aDataOfst = &data[pPage->childPtrSize];
|
||||
pPage->nOverflow = 0;
|
||||
@@ -2230,7 +2230,7 @@ static int getAndInitPage(
|
||||
goto getAndInitPage_error2;
|
||||
}
|
||||
}
|
||||
assert( (*ppPage)->pgno==pgno );
|
||||
assert( (*ppPage)->pgno==pgno || CORRUPT_DB );
|
||||
assert( (*ppPage)->aData==sqlite3PagerGetData(pDbPage) );
|
||||
|
||||
/* If obtaining a child page for a cursor, we must verify that the page is
|
||||
@@ -5317,7 +5317,7 @@ static int moveToRoot(BtCursor *pCur){
|
||||
pCur->curIntKey = pCur->pPage->intKey;
|
||||
}
|
||||
pRoot = pCur->pPage;
|
||||
assert( pRoot->pgno==pCur->pgnoRoot );
|
||||
assert( pRoot->pgno==pCur->pgnoRoot || CORRUPT_DB );
|
||||
|
||||
/* If pCur->pKeyInfo is not NULL, then the caller that opened this cursor
|
||||
** expected to open it on an index b-tree. Otherwise, if pKeyInfo is
|
||||
@@ -6411,7 +6411,7 @@ static int freePage2(BtShared *pBt, MemPage *pMemPage, Pgno iPage){
|
||||
assert( CORRUPT_DB || iPage>1 );
|
||||
assert( !pMemPage || pMemPage->pgno==iPage );
|
||||
|
||||
if( NEVER(iPage<2) || iPage>pBt->nPage ){
|
||||
if( iPage<2 || iPage>pBt->nPage ){
|
||||
return SQLITE_CORRUPT_BKPT;
|
||||
}
|
||||
if( pMemPage ){
|
||||
@@ -6846,6 +6846,12 @@ static void dropCell(MemPage *pPage, int idx, int sz, int *pRC){
|
||||
assert( pPage->pBt->usableSize > (u32)(ptr-data) );
|
||||
pc = get2byte(ptr);
|
||||
hdr = pPage->hdrOffset;
|
||||
#if 0 /* Not required. Omit for efficiency */
|
||||
if( pc<hdr+pPage->nCell*2 ){
|
||||
*pRC = SQLITE_CORRUPT_BKPT;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
testcase( pc==(u32)get2byte(&data[hdr+5]) );
|
||||
testcase( pc+sz==pPage->pBt->usableSize );
|
||||
if( pc+sz > pPage->pBt->usableSize ){
|
||||
@@ -8842,24 +8848,6 @@ int sqlite3BtreeInsert(
|
||||
assert( (flags & (BTREE_SAVEPOSITION|BTREE_APPEND|BTREE_PREFORMAT))==flags );
|
||||
assert( (flags & BTREE_PREFORMAT)==0 || seekResult || pCur->pKeyInfo==0 );
|
||||
|
||||
if( pCur->eState==CURSOR_FAULT ){
|
||||
assert( pCur->skipNext!=SQLITE_OK );
|
||||
return pCur->skipNext;
|
||||
}
|
||||
|
||||
assert( cursorOwnsBtShared(pCur) );
|
||||
assert( (pCur->curFlags & BTCF_WriteFlag)!=0
|
||||
&& pBt->inTransaction==TRANS_WRITE
|
||||
&& (pBt->btsFlags & BTS_READ_ONLY)==0 );
|
||||
assert( hasSharedCacheTableLock(p, pCur->pgnoRoot, pCur->pKeyInfo!=0, 2) );
|
||||
|
||||
/* Assert that the caller has been consistent. If this cursor was opened
|
||||
** expecting an index b-tree, then the caller should be inserting blob
|
||||
** keys with no associated data. If the cursor was opened expecting an
|
||||
** intkey table, the caller should be inserting integer keys with a
|
||||
** blob of associated data. */
|
||||
assert( (flags & BTREE_PREFORMAT) || (pX->pKey==0)==(pCur->pKeyInfo==0) );
|
||||
|
||||
/* Save the positions of any other cursors open on this table.
|
||||
**
|
||||
** In some cases, the call to btreeMoveto() below is a no-op. For
|
||||
@@ -8884,6 +8872,24 @@ int sqlite3BtreeInsert(
|
||||
}
|
||||
}
|
||||
|
||||
if( pCur->eState>=CURSOR_REQUIRESEEK ){
|
||||
rc = moveToRoot(pCur);
|
||||
if( rc && rc!=SQLITE_EMPTY ) return rc;
|
||||
}
|
||||
|
||||
assert( cursorOwnsBtShared(pCur) );
|
||||
assert( (pCur->curFlags & BTCF_WriteFlag)!=0
|
||||
&& pBt->inTransaction==TRANS_WRITE
|
||||
&& (pBt->btsFlags & BTS_READ_ONLY)==0 );
|
||||
assert( hasSharedCacheTableLock(p, pCur->pgnoRoot, pCur->pKeyInfo!=0, 2) );
|
||||
|
||||
/* Assert that the caller has been consistent. If this cursor was opened
|
||||
** expecting an index b-tree, then the caller should be inserting blob
|
||||
** keys with no associated data. If the cursor was opened expecting an
|
||||
** intkey table, the caller should be inserting integer keys with a
|
||||
** blob of associated data. */
|
||||
assert( (flags & BTREE_PREFORMAT) || (pX->pKey==0)==(pCur->pKeyInfo==0) );
|
||||
|
||||
if( pCur->pKeyInfo==0 ){
|
||||
assert( pX->pKey==0 );
|
||||
/* If this is an insert into a table b-tree, invalidate any incrblob
|
||||
@@ -8972,14 +8978,13 @@ int sqlite3BtreeInsert(
|
||||
}
|
||||
}
|
||||
assert( pCur->eState==CURSOR_VALID
|
||||
|| (pCur->eState==CURSOR_INVALID && loc)
|
||||
|| CORRUPT_DB );
|
||||
|| (pCur->eState==CURSOR_INVALID && loc) );
|
||||
|
||||
pPage = pCur->pPage;
|
||||
assert( pPage->intKey || pX->nKey>=0 || (flags & BTREE_PREFORMAT) );
|
||||
assert( pPage->leaf || !pPage->intKey );
|
||||
if( pPage->nFree<0 ){
|
||||
if( NEVER(pCur->eState>CURSOR_INVALID) ){
|
||||
if( pCur->eState>CURSOR_INVALID ){
|
||||
rc = SQLITE_CORRUPT_BKPT;
|
||||
}else{
|
||||
rc = btreeComputeFreeSpace(pPage);
|
||||
@@ -9260,12 +9265,16 @@ int sqlite3BtreeDelete(BtCursor *pCur, u8 flags){
|
||||
assert( hasSharedCacheTableLock(p, pCur->pgnoRoot, pCur->pKeyInfo!=0, 2) );
|
||||
assert( !hasReadConflicts(p, pCur->pgnoRoot) );
|
||||
assert( (flags & ~(BTREE_SAVEPOSITION | BTREE_AUXDELETE))==0 );
|
||||
if( pCur->eState==CURSOR_REQUIRESEEK ){
|
||||
rc = btreeRestoreCursorPosition(pCur);
|
||||
assert( rc!=SQLITE_OK || CORRUPT_DB || pCur->eState==CURSOR_VALID );
|
||||
if( rc || pCur->eState!=CURSOR_VALID ) return rc;
|
||||
if( pCur->eState!=CURSOR_VALID ){
|
||||
if( pCur->eState>=CURSOR_REQUIRESEEK ){
|
||||
rc = btreeRestoreCursorPosition(pCur);
|
||||
assert( rc!=SQLITE_OK || CORRUPT_DB || pCur->eState==CURSOR_VALID );
|
||||
if( rc || pCur->eState!=CURSOR_VALID ) return rc;
|
||||
}else{
|
||||
return SQLITE_CORRUPT_BKPT;
|
||||
}
|
||||
}
|
||||
assert( CORRUPT_DB || pCur->eState==CURSOR_VALID );
|
||||
assert( pCur->eState==CURSOR_VALID );
|
||||
|
||||
iCellDepth = pCur->iPage;
|
||||
iCellIdx = pCur->ix;
|
||||
@@ -9616,7 +9625,7 @@ static int clearDatabasePage(
|
||||
rc = getAndInitPage(pBt, pgno, &pPage, 0, 0);
|
||||
if( rc ) return rc;
|
||||
if( (pBt->openFlags & BTREE_SINGLE)==0
|
||||
&& sqlite3PagerPageRefcount(pPage->pDbPage)!=1
|
||||
&& sqlite3PagerPageRefcount(pPage->pDbPage) != (1 + (pgno==1))
|
||||
){
|
||||
rc = SQLITE_CORRUPT_BKPT;
|
||||
goto cleardatabasepage_out;
|
||||
|
||||
+3
-1
@@ -293,7 +293,9 @@ struct MemPage {
|
||||
u8 *apOvfl[4]; /* Pointers to the body of overflow cells */
|
||||
BtShared *pBt; /* Pointer to BtShared that this page is part of */
|
||||
u8 *aData; /* Pointer to disk image of the page data */
|
||||
u8 *aDataEnd; /* One byte past the end of usable data */
|
||||
u8 *aDataEnd; /* One byte past the end of the entire page - not just
|
||||
** the usable space, the entire page. Used to prevent
|
||||
** corruption-induced of buffer overflow. */
|
||||
u8 *aCellIdx; /* The cell index area */
|
||||
u8 *aDataOfst; /* Same as aData for leaves. aData+4 for interior */
|
||||
DbPage *pDbPage; /* Pager page handle */
|
||||
|
||||
+25
-11
@@ -143,11 +143,13 @@ void sqlite3FinishCoding(Parse *pParse){
|
||||
|
||||
assert( pParse->pToplevel==0 );
|
||||
db = pParse->db;
|
||||
assert( db->pParse==pParse );
|
||||
if( pParse->nested ) return;
|
||||
if( db->mallocFailed || pParse->nErr ){
|
||||
if( pParse->rc==SQLITE_OK ) pParse->rc = SQLITE_ERROR;
|
||||
if( pParse->nErr ){
|
||||
if( db->mallocFailed ) pParse->rc = SQLITE_NOMEM;
|
||||
return;
|
||||
}
|
||||
assert( db->mallocFailed==0 );
|
||||
|
||||
/* Begin by generating some termination code at the end of the
|
||||
** vdbe program
|
||||
@@ -280,7 +282,9 @@ void sqlite3FinishCoding(Parse *pParse){
|
||||
|
||||
/* Get the VDBE program ready for execution
|
||||
*/
|
||||
if( v && pParse->nErr==0 && !db->mallocFailed ){
|
||||
assert( v!=0 || pParse->nErr );
|
||||
assert( db->mallocFailed==0 || pParse->nErr );
|
||||
if( pParse->nErr==0 ){
|
||||
/* A minimum of one cursor is required if autoincrement is used
|
||||
* See ticket [a696379c1f08866] */
|
||||
assert( pParse->pAinc==0 || pParse->nTab>0 );
|
||||
@@ -329,6 +333,8 @@ void sqlite3NestedParse(Parse *pParse, const char *zFormat, ...){
|
||||
memset(PARSE_TAIL(pParse), 0, PARSE_TAIL_SZ);
|
||||
db->mDbFlags |= DBFLAG_PreferBuiltin;
|
||||
sqlite3RunParser(pParse, zSql);
|
||||
sqlite3DbFree(db, pParse->zErrMsg);
|
||||
pParse->zErrMsg = 0;
|
||||
db->mDbFlags = savedDbFlags;
|
||||
sqlite3DbFree(db, zSql);
|
||||
memcpy(PARSE_TAIL(pParse), saveBuf, PARSE_TAIL_SZ);
|
||||
@@ -1289,7 +1295,8 @@ void sqlite3StartTable(
|
||||
pTable = sqlite3FindTable(db, zName, zDb);
|
||||
if( pTable ){
|
||||
if( !noErr ){
|
||||
sqlite3ErrorMsg(pParse, "table %T already exists", pName);
|
||||
sqlite3ErrorMsg(pParse, "%s %T already exists",
|
||||
(IsView(pTable)? "view" : "table"), pName);
|
||||
}else{
|
||||
assert( !db->init.busy || CORRUPT_DB );
|
||||
sqlite3CodeVerifySchema(pParse, iDb);
|
||||
@@ -2384,10 +2391,11 @@ static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){
|
||||
pTab->iPKey = -1;
|
||||
sqlite3CreateIndex(pParse, 0, 0, 0, pList, pTab->keyConf, 0, 0, 0, 0,
|
||||
SQLITE_IDXTYPE_PRIMARYKEY);
|
||||
if( db->mallocFailed || pParse->nErr ){
|
||||
if( pParse->nErr ){
|
||||
pTab->tabFlags &= ~TF_WithoutRowid;
|
||||
return;
|
||||
}
|
||||
assert( db->mallocFailed==0 );
|
||||
pPk = sqlite3PrimaryKeyIndex(pTab);
|
||||
assert( pPk->nKeyCol==1 );
|
||||
}else{
|
||||
@@ -2818,6 +2826,11 @@ void sqlite3EndTable(
|
||||
int addrInsLoop; /* Top of the loop for inserting rows */
|
||||
Table *pSelTab; /* A table that describes the SELECT results */
|
||||
|
||||
if( IN_SPECIAL_PARSE ){
|
||||
pParse->rc = SQLITE_ERROR;
|
||||
pParse->nErr++;
|
||||
return;
|
||||
}
|
||||
regYield = ++pParse->nMem;
|
||||
regRec = ++pParse->nMem;
|
||||
regRowid = ++pParse->nMem;
|
||||
@@ -3128,10 +3141,10 @@ int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){
|
||||
*/
|
||||
sqlite3ColumnsFromExprList(pParse, pTable->pCheck,
|
||||
&pTable->nCol, &pTable->aCol);
|
||||
if( db->mallocFailed==0
|
||||
&& pParse->nErr==0
|
||||
if( pParse->nErr==0
|
||||
&& pTable->nCol==pSel->pEList->nExpr
|
||||
){
|
||||
assert( db->mallocFailed==0 );
|
||||
sqlite3SelectAddColumnTypeAndCollation(pParse, pTable, pSel,
|
||||
SQLITE_AFF_NONE);
|
||||
}
|
||||
@@ -3750,7 +3763,7 @@ static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){
|
||||
tnum = pIndex->tnum;
|
||||
}
|
||||
pKey = sqlite3KeyInfoOfIndex(pParse, pIndex);
|
||||
assert( pKey!=0 || db->mallocFailed || pParse->nErr );
|
||||
assert( pKey!=0 || pParse->nErr );
|
||||
|
||||
/* Open the sorter cursor if we are to use one. */
|
||||
iSorter = pParse->nTab++;
|
||||
@@ -3914,9 +3927,11 @@ void sqlite3CreateIndex(
|
||||
char *zExtra = 0; /* Extra space after the Index object */
|
||||
Index *pPk = 0; /* PRIMARY KEY index for WITHOUT ROWID tables */
|
||||
|
||||
if( db->mallocFailed || pParse->nErr>0 ){
|
||||
assert( db->pParse==pParse );
|
||||
if( pParse->nErr ){
|
||||
goto exit_create_index;
|
||||
}
|
||||
assert( db->mallocFailed==0 );
|
||||
if( IN_DECLARE_VTAB && idxType!=SQLITE_IDXTYPE_PRIMARYKEY ){
|
||||
goto exit_create_index;
|
||||
}
|
||||
@@ -3980,7 +3995,6 @@ void sqlite3CreateIndex(
|
||||
pDb = &db->aDb[iDb];
|
||||
|
||||
assert( pTab!=0 );
|
||||
assert( pParse->nErr==0 );
|
||||
if( sqlite3StrNICmp(pTab->zName, "sqlite_", 7)==0
|
||||
&& db->init.busy==0
|
||||
&& pTblName!=0
|
||||
@@ -4544,10 +4558,10 @@ void sqlite3DropIndex(Parse *pParse, SrcList *pName, int ifExists){
|
||||
sqlite3 *db = pParse->db;
|
||||
int iDb;
|
||||
|
||||
assert( pParse->nErr==0 ); /* Never called with prior errors */
|
||||
if( db->mallocFailed ){
|
||||
goto exit_drop_index;
|
||||
}
|
||||
assert( pParse->nErr==0 ); /* Never called with prior non-OOM errors */
|
||||
assert( pName->nSrc==1 );
|
||||
if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){
|
||||
goto exit_drop_index;
|
||||
|
||||
+146
-72
@@ -503,8 +503,10 @@ static void clearYMD_HMS_TZ(DateTime *p){
|
||||
** is available. This routine returns 0 on success and
|
||||
** non-zero on any kind of error.
|
||||
**
|
||||
** If the sqlite3GlobalConfig.bLocaltimeFault variable is true then this
|
||||
** routine will always fail.
|
||||
** If the sqlite3GlobalConfig.bLocaltimeFault variable is non-zero then this
|
||||
** routine will always fail. If bLocaltimeFault is nonzero and
|
||||
** sqlite3GlobalConfig.xAltLocaltime is not NULL, then xAltLocaltime() is
|
||||
** invoked in place of the OS-defined localtime() function.
|
||||
**
|
||||
** EVIDENCE-OF: R-62172-00036 In this implementation, the standard C
|
||||
** library function localtime_r() is used to assist in the calculation of
|
||||
@@ -520,7 +522,15 @@ static int osLocaltime(time_t *t, struct tm *pTm){
|
||||
sqlite3_mutex_enter(mutex);
|
||||
pX = localtime(t);
|
||||
#ifndef SQLITE_UNTESTABLE
|
||||
if( sqlite3GlobalConfig.bLocaltimeFault ) pX = 0;
|
||||
if( sqlite3GlobalConfig.bLocaltimeFault ){
|
||||
if( sqlite3GlobalConfig.xAltLocaltime!=0
|
||||
&& 0==sqlite3GlobalConfig.xAltLocaltime((const void*)t,(void*)pTm)
|
||||
){
|
||||
pX = pTm;
|
||||
}else{
|
||||
pX = 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if( pX ) *pTm = *pX;
|
||||
#if SQLITE_THREADSAFE>0
|
||||
@@ -529,7 +539,13 @@ static int osLocaltime(time_t *t, struct tm *pTm){
|
||||
rc = pX==0;
|
||||
#else
|
||||
#ifndef SQLITE_UNTESTABLE
|
||||
if( sqlite3GlobalConfig.bLocaltimeFault ) return 1;
|
||||
if( sqlite3GlobalConfig.bLocaltimeFault ){
|
||||
if( sqlite3GlobalConfig.xAltLocaltime!=0 ){
|
||||
return sqlite3GlobalConfig.xAltLocaltime((const void*)t,(void*)pTm);
|
||||
}else{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#if HAVE_LOCALTIME_R
|
||||
rc = localtime_r(t, pTm)==0;
|
||||
@@ -544,67 +560,56 @@ static int osLocaltime(time_t *t, struct tm *pTm){
|
||||
|
||||
#ifndef SQLITE_OMIT_LOCALTIME
|
||||
/*
|
||||
** Compute the difference (in milliseconds) between localtime and UTC
|
||||
** (a.k.a. GMT) for the time value p where p is in UTC. If no error occurs,
|
||||
** return this value and set *pRc to SQLITE_OK.
|
||||
**
|
||||
** Or, if an error does occur, set *pRc to SQLITE_ERROR. The returned value
|
||||
** is undefined in this case.
|
||||
** Assuming the input DateTime is UTC, move it to its localtime equivalent.
|
||||
*/
|
||||
static sqlite3_int64 localtimeOffset(
|
||||
DateTime *p, /* Date at which to calculate offset */
|
||||
sqlite3_context *pCtx, /* Write error here if one occurs */
|
||||
int *pRc /* OUT: Error code. SQLITE_OK or ERROR */
|
||||
static int toLocaltime(
|
||||
DateTime *p, /* Date at which to calculate offset */
|
||||
sqlite3_context *pCtx /* Write error here if one occurs */
|
||||
){
|
||||
DateTime x, y;
|
||||
time_t t;
|
||||
struct tm sLocal;
|
||||
int iYearDiff;
|
||||
|
||||
/* Initialize the contents of sLocal to avoid a compiler warning. */
|
||||
memset(&sLocal, 0, sizeof(sLocal));
|
||||
|
||||
x = *p;
|
||||
computeYMD_HMS(&x);
|
||||
if( x.Y<1971 || x.Y>=2038 ){
|
||||
computeJD(p);
|
||||
if( p->iJD<2108667600*(i64)100000 /* 1970-01-01 */
|
||||
|| p->iJD>2130141456*(i64)100000 /* 2038-01-18 */
|
||||
){
|
||||
/* EVIDENCE-OF: R-55269-29598 The localtime_r() C function normally only
|
||||
** works for years between 1970 and 2037. For dates outside this range,
|
||||
** SQLite attempts to map the year into an equivalent year within this
|
||||
** range, do the calculation, then map the year back.
|
||||
*/
|
||||
x.Y = 2000;
|
||||
x.M = 1;
|
||||
x.D = 1;
|
||||
x.h = 0;
|
||||
x.m = 0;
|
||||
x.s = 0.0;
|
||||
} else {
|
||||
int s = (int)(x.s + 0.5);
|
||||
x.s = s;
|
||||
DateTime x = *p;
|
||||
computeYMD_HMS(&x);
|
||||
iYearDiff = (2000 + x.Y%4) - x.Y;
|
||||
x.Y += iYearDiff;
|
||||
x.validJD = 0;
|
||||
computeJD(&x);
|
||||
t = (time_t)(x.iJD/1000 - 21086676*(i64)10000);
|
||||
}else{
|
||||
iYearDiff = 0;
|
||||
t = (time_t)(p->iJD/1000 - 21086676*(i64)10000);
|
||||
}
|
||||
x.tz = 0;
|
||||
x.validJD = 0;
|
||||
computeJD(&x);
|
||||
t = (time_t)(x.iJD/1000 - 21086676*(i64)10000);
|
||||
if( osLocaltime(&t, &sLocal) ){
|
||||
sqlite3_result_error(pCtx, "local time unavailable", -1);
|
||||
*pRc = SQLITE_ERROR;
|
||||
return 0;
|
||||
return SQLITE_ERROR;
|
||||
}
|
||||
y.Y = sLocal.tm_year + 1900;
|
||||
y.M = sLocal.tm_mon + 1;
|
||||
y.D = sLocal.tm_mday;
|
||||
y.h = sLocal.tm_hour;
|
||||
y.m = sLocal.tm_min;
|
||||
y.s = sLocal.tm_sec;
|
||||
y.validYMD = 1;
|
||||
y.validHMS = 1;
|
||||
y.validJD = 0;
|
||||
y.rawS = 0;
|
||||
y.validTZ = 0;
|
||||
y.isError = 0;
|
||||
computeJD(&y);
|
||||
*pRc = SQLITE_OK;
|
||||
return y.iJD - x.iJD;
|
||||
p->Y = sLocal.tm_year + 1900 - iYearDiff;
|
||||
p->M = sLocal.tm_mon + 1;
|
||||
p->D = sLocal.tm_mday;
|
||||
p->h = sLocal.tm_hour;
|
||||
p->m = sLocal.tm_min;
|
||||
p->s = sLocal.tm_sec + (p->iJD%1000)*0.001;
|
||||
p->validYMD = 1;
|
||||
p->validHMS = 1;
|
||||
p->validJD = 0;
|
||||
p->rawS = 0;
|
||||
p->validTZ = 0;
|
||||
p->isError = 0;
|
||||
return SQLITE_OK;
|
||||
}
|
||||
#endif /* SQLITE_OMIT_LOCALTIME */
|
||||
|
||||
@@ -676,7 +681,9 @@ static int parseModifier(
|
||||
if( !p->rawS || p->validJD ){
|
||||
rc = 0;
|
||||
p->rawS = 0;
|
||||
}else if( p->s>=-210866760000 && p->s<=253402300799 ){
|
||||
}else if( p->s>=-21086676*(i64)10000 /* -4713-11-24 12:00:00 */
|
||||
&& p->s<=(25340230*(i64)10000)+799 /* 9999-12-31 23:59:59 */
|
||||
){
|
||||
r = p->s*1000.0 + 210866760000000.0;
|
||||
clearYMD_HMS_TZ(p);
|
||||
p->iJD = (sqlite3_int64)(r + 0.5);
|
||||
@@ -697,7 +704,7 @@ static int parseModifier(
|
||||
** SQLite (0..5373484.5) then the result will be NULL.
|
||||
*/
|
||||
if( sqlite3_stricmp(z, "julianday")==0 ){
|
||||
if( idx>1 ) return 1;
|
||||
if( idx>1 ) return 1; /* IMP: R-31176-64601 */
|
||||
if( p->validJD && p->rawS ){
|
||||
rc = 0;
|
||||
p->rawS = 0;
|
||||
@@ -713,9 +720,7 @@ static int parseModifier(
|
||||
** show local time.
|
||||
*/
|
||||
if( sqlite3_stricmp(z, "localtime")==0 && sqlite3NotPureFunc(pCtx) ){
|
||||
computeJD(p);
|
||||
p->iJD += localtimeOffset(p, pCtx, &rc);
|
||||
clearYMD_HMS_TZ(p);
|
||||
rc = toLocaltime(p, pCtx);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -728,6 +733,7 @@ static int parseModifier(
|
||||
** seconds since 1970. Convert to a real julian day number.
|
||||
*/
|
||||
if( sqlite3_stricmp(z, "unixepoch")==0 && p->rawS ){
|
||||
if( idx>1 ) return 1; /* IMP: R-49255-55373 */
|
||||
r = p->s*1000.0 + 210866760000000.0;
|
||||
if( r>=0.0 && r<464269060800000.0 ){
|
||||
clearYMD_HMS_TZ(p);
|
||||
@@ -740,18 +746,31 @@ static int parseModifier(
|
||||
#ifndef SQLITE_OMIT_LOCALTIME
|
||||
else if( sqlite3_stricmp(z, "utc")==0 && sqlite3NotPureFunc(pCtx) ){
|
||||
if( p->tzSet==0 ){
|
||||
sqlite3_int64 c1;
|
||||
i64 iOrigJD; /* Original localtime */
|
||||
i64 iGuess; /* Guess at the corresponding utc time */
|
||||
int cnt = 0; /* Safety to prevent infinite loop */
|
||||
int iErr; /* Guess is off by this much */
|
||||
|
||||
computeJD(p);
|
||||
c1 = localtimeOffset(p, pCtx, &rc);
|
||||
if( rc==SQLITE_OK ){
|
||||
p->iJD -= c1;
|
||||
clearYMD_HMS_TZ(p);
|
||||
p->iJD += c1 - localtimeOffset(p, pCtx, &rc);
|
||||
}
|
||||
iGuess = iOrigJD = p->iJD;
|
||||
iErr = 0;
|
||||
do{
|
||||
DateTime new;
|
||||
memset(&new, 0, sizeof(new));
|
||||
iGuess -= iErr;
|
||||
new.iJD = iGuess;
|
||||
new.validJD = 1;
|
||||
rc = toLocaltime(&new, pCtx);
|
||||
if( rc ) return rc;
|
||||
computeJD(&new);
|
||||
iErr = new.iJD - iOrigJD;
|
||||
}while( iErr && cnt++<3 );
|
||||
memset(p, 0, sizeof(*p));
|
||||
p->iJD = iGuess;
|
||||
p->validJD = 1;
|
||||
p->tzSet = 1;
|
||||
}else{
|
||||
rc = SQLITE_OK;
|
||||
}
|
||||
rc = SQLITE_OK;
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
@@ -1001,11 +1020,38 @@ static void datetimeFunc(
|
||||
){
|
||||
DateTime x;
|
||||
if( isDate(context, argc, argv, &x)==0 ){
|
||||
char zBuf[100];
|
||||
int Y, s;
|
||||
char zBuf[24];
|
||||
computeYMD_HMS(&x);
|
||||
sqlite3_snprintf(sizeof(zBuf), zBuf, "%04d-%02d-%02d %02d:%02d:%02d",
|
||||
x.Y, x.M, x.D, x.h, x.m, (int)(x.s));
|
||||
sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT);
|
||||
Y = x.Y;
|
||||
if( Y<0 ) Y = -Y;
|
||||
zBuf[1] = '0' + (Y/1000)%10;
|
||||
zBuf[2] = '0' + (Y/100)%10;
|
||||
zBuf[3] = '0' + (Y/10)%10;
|
||||
zBuf[4] = '0' + (Y)%10;
|
||||
zBuf[5] = '-';
|
||||
zBuf[6] = '0' + (x.M/10)%10;
|
||||
zBuf[7] = '0' + (x.M)%10;
|
||||
zBuf[8] = '-';
|
||||
zBuf[9] = '0' + (x.D/10)%10;
|
||||
zBuf[10] = '0' + (x.D)%10;
|
||||
zBuf[11] = ' ';
|
||||
zBuf[12] = '0' + (x.h/10)%10;
|
||||
zBuf[13] = '0' + (x.h)%10;
|
||||
zBuf[14] = ':';
|
||||
zBuf[15] = '0' + (x.m/10)%10;
|
||||
zBuf[16] = '0' + (x.m)%10;
|
||||
zBuf[17] = ':';
|
||||
s = (int)x.s;
|
||||
zBuf[18] = '0' + (s/10)%10;
|
||||
zBuf[19] = '0' + (s)%10;
|
||||
zBuf[20] = 0;
|
||||
if( x.Y<0 ){
|
||||
zBuf[0] = '-';
|
||||
sqlite3_result_text(context, zBuf, 20, SQLITE_TRANSIENT);
|
||||
}else{
|
||||
sqlite3_result_text(context, &zBuf[1], 19, SQLITE_TRANSIENT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1021,10 +1067,20 @@ static void timeFunc(
|
||||
){
|
||||
DateTime x;
|
||||
if( isDate(context, argc, argv, &x)==0 ){
|
||||
char zBuf[100];
|
||||
int s;
|
||||
char zBuf[16];
|
||||
computeHMS(&x);
|
||||
sqlite3_snprintf(sizeof(zBuf), zBuf, "%02d:%02d:%02d", x.h, x.m, (int)x.s);
|
||||
sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT);
|
||||
zBuf[0] = '0' + (x.h/10)%10;
|
||||
zBuf[1] = '0' + (x.h)%10;
|
||||
zBuf[2] = ':';
|
||||
zBuf[3] = '0' + (x.m/10)%10;
|
||||
zBuf[4] = '0' + (x.m)%10;
|
||||
zBuf[5] = ':';
|
||||
s = (int)x.s;
|
||||
zBuf[6] = '0' + (s/10)%10;
|
||||
zBuf[7] = '0' + (s)%10;
|
||||
zBuf[8] = 0;
|
||||
sqlite3_result_text(context, zBuf, 8, SQLITE_TRANSIENT);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1040,10 +1096,28 @@ static void dateFunc(
|
||||
){
|
||||
DateTime x;
|
||||
if( isDate(context, argc, argv, &x)==0 ){
|
||||
char zBuf[100];
|
||||
int Y;
|
||||
char zBuf[16];
|
||||
computeYMD(&x);
|
||||
sqlite3_snprintf(sizeof(zBuf), zBuf, "%04d-%02d-%02d", x.Y, x.M, x.D);
|
||||
sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT);
|
||||
Y = x.Y;
|
||||
if( Y<0 ) Y = -Y;
|
||||
zBuf[1] = '0' + (Y/1000)%10;
|
||||
zBuf[2] = '0' + (Y/100)%10;
|
||||
zBuf[3] = '0' + (Y/10)%10;
|
||||
zBuf[4] = '0' + (Y)%10;
|
||||
zBuf[5] = '-';
|
||||
zBuf[6] = '0' + (x.M/10)%10;
|
||||
zBuf[7] = '0' + (x.M)%10;
|
||||
zBuf[8] = '-';
|
||||
zBuf[9] = '0' + (x.D/10)%10;
|
||||
zBuf[10] = '0' + (x.D)%10;
|
||||
zBuf[11] = 0;
|
||||
if( x.Y<0 ){
|
||||
zBuf[0] = '-';
|
||||
sqlite3_result_text(context, zBuf, 11, SQLITE_TRANSIENT);
|
||||
}else{
|
||||
sqlite3_result_text(context, &zBuf[1], 10, SQLITE_TRANSIENT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -156,6 +156,7 @@ static int dbpageBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
|
||||
){
|
||||
pIdxInfo->orderByConsumed = 1;
|
||||
}
|
||||
sqlite3VtabWriteAll(pIdxInfo);
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
|
||||
+4
-2
@@ -293,9 +293,11 @@ void sqlite3DeleteFrom(
|
||||
|
||||
memset(&sContext, 0, sizeof(sContext));
|
||||
db = pParse->db;
|
||||
if( pParse->nErr || db->mallocFailed ){
|
||||
assert( db->pParse==pParse );
|
||||
if( pParse->nErr ){
|
||||
goto delete_from_cleanup;
|
||||
}
|
||||
assert( db->mallocFailed==0 );
|
||||
assert( pTabList->nSrc==1 );
|
||||
|
||||
|
||||
@@ -476,7 +478,7 @@ void sqlite3DeleteFrom(
|
||||
** ONEPASS_SINGLE: One-pass approach - at most one row deleted.
|
||||
** ONEPASS_MULTI: One-pass approach - any number of rows may be deleted.
|
||||
*/
|
||||
pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0, 0, wcf, iTabCur+1);
|
||||
pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0, 0,0,wcf,iTabCur+1);
|
||||
if( pWInfo==0 ) goto delete_from_cleanup;
|
||||
eOnePass = sqlite3WhereOkOnePass(pWInfo, aiCurOnePass);
|
||||
assert( IsVirtual(pTab)==0 || eOnePass!=ONEPASS_MULTI );
|
||||
|
||||
+15
-16
@@ -769,9 +769,8 @@ static void heightOfSelect(const Select *pSelect, int *pnHeight){
|
||||
** if appropriate.
|
||||
*/
|
||||
static void exprSetHeight(Expr *p){
|
||||
int nHeight = 0;
|
||||
heightOfExpr(p->pLeft, &nHeight);
|
||||
heightOfExpr(p->pRight, &nHeight);
|
||||
int nHeight = p->pLeft ? p->pLeft->nHeight : 0;
|
||||
if( p->pRight && p->pRight->nHeight>nHeight ) nHeight = p->pRight->nHeight;
|
||||
if( ExprUseXSelect(p) ){
|
||||
heightOfSelect(p->x.pSelect, &nHeight);
|
||||
}else if( p->x.pList ){
|
||||
@@ -1070,6 +1069,7 @@ Expr *sqlite3ExprFunction(
|
||||
sqlite3ExprListDelete(db, pList); /* Avoid memory leak when malloc fails */
|
||||
return 0;
|
||||
}
|
||||
pNew->w.iOfst = (int)(pToken->z - pParse->zTail);
|
||||
if( pList
|
||||
&& pList->nExpr > pParse->db->aLimit[SQLITE_LIMIT_FUNCTION_ARG]
|
||||
&& !pParse->nested
|
||||
@@ -1113,7 +1113,7 @@ void sqlite3ExprFunctionUsable(
|
||||
** SQLITE_DBCONFIG_TRUSTED_SCHEMA is off (meaning
|
||||
** that the schema is possibly tainted).
|
||||
*/
|
||||
sqlite3ErrorMsg(pParse, "unsafe use of %s()", pDef->zName);
|
||||
sqlite3ErrorMsg(pParse, "unsafe use of %#T()", pExpr);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1169,6 +1169,7 @@ void sqlite3ExprAssignVarNumber(Parse *pParse, Expr *pExpr, u32 n){
|
||||
if( bOk==0 || i<1 || i>db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] ){
|
||||
sqlite3ErrorMsg(pParse, "variable number must be between ?1 and ?%d",
|
||||
db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER]);
|
||||
sqlite3RecordErrorOffsetOfExpr(pParse->db, pExpr);
|
||||
return;
|
||||
}
|
||||
x = (ynVar)i;
|
||||
@@ -1196,6 +1197,7 @@ void sqlite3ExprAssignVarNumber(Parse *pParse, Expr *pExpr, u32 n){
|
||||
pExpr->iColumn = x;
|
||||
if( x>db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] ){
|
||||
sqlite3ErrorMsg(pParse, "too many SQL variables");
|
||||
sqlite3RecordErrorOffsetOfExpr(pParse->db, pExpr);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2803,8 +2805,7 @@ int sqlite3FindInIndex(
|
||||
CollSeq *pReq = sqlite3BinaryCompareCollSeq(pParse, pLhs, pRhs);
|
||||
int j;
|
||||
|
||||
assert( pReq!=0 || pRhs->iColumn==XN_ROWID
|
||||
|| pParse->nErr || db->mallocFailed );
|
||||
assert( pReq!=0 || pRhs->iColumn==XN_ROWID || pParse->nErr );
|
||||
for(j=0; j<nExpr; j++){
|
||||
if( pIdx->aiColumn[j]!=pRhs->iColumn ) continue;
|
||||
assert( pIdx->azColl[j] );
|
||||
@@ -3280,10 +3281,8 @@ int sqlite3CodeSubselect(Parse *pParse, Expr *pExpr){
|
||||
}
|
||||
pSel->iLimit = 0;
|
||||
if( sqlite3Select(pParse, pSel, &dest) ){
|
||||
if( pParse->nErr ){
|
||||
pExpr->op2 = pExpr->op;
|
||||
pExpr->op = TK_ERROR;
|
||||
}
|
||||
pExpr->op2 = pExpr->op;
|
||||
pExpr->op = TK_ERROR;
|
||||
return 0;
|
||||
}
|
||||
pExpr->iTable = rReg = dest.iSDParm;
|
||||
@@ -3500,10 +3499,9 @@ static void sqlite3ExprCodeIN(
|
||||
}else{
|
||||
destStep2 = destStep6 = sqlite3VdbeMakeLabel(pParse);
|
||||
}
|
||||
if( pParse->nErr ) goto sqlite3ExprCodeIN_finished;
|
||||
for(i=0; i<nVector; i++){
|
||||
Expr *p = sqlite3VectorFieldSubexpr(pExpr->pLeft, i);
|
||||
if( pParse->db->mallocFailed ) goto sqlite3ExprCodeIN_oom_error;
|
||||
if( pParse->nErr ) goto sqlite3ExprCodeIN_oom_error;
|
||||
if( sqlite3ExprCanBeNull(p) ){
|
||||
sqlite3VdbeAddOp2(v, OP_IsNull, rLhs+i, destStep2);
|
||||
VdbeCoverage(v);
|
||||
@@ -3641,11 +3639,12 @@ static void codeInteger(Parse *pParse, Expr *pExpr, int negFlag, int iMem){
|
||||
c = sqlite3DecOrHexToI64(z, &value);
|
||||
if( (c==3 && !negFlag) || (c==2) || (negFlag && value==SMALLEST_INT64)){
|
||||
#ifdef SQLITE_OMIT_FLOATING_POINT
|
||||
sqlite3ErrorMsg(pParse, "oversized integer: %s%s", negFlag ? "-" : "", z);
|
||||
sqlite3ErrorMsg(pParse, "oversized integer: %s%#T", negFlag?"-":"",pExpr);
|
||||
#else
|
||||
#ifndef SQLITE_OMIT_HEX_INTEGER
|
||||
if( sqlite3_strnicmp(z,"0x",2)==0 ){
|
||||
sqlite3ErrorMsg(pParse, "hex literal too big: %s%s", negFlag?"-":"",z);
|
||||
sqlite3ErrorMsg(pParse, "hex literal too big: %s%#T",
|
||||
negFlag?"-":"",pExpr);
|
||||
}else
|
||||
#endif
|
||||
{
|
||||
@@ -4321,7 +4320,7 @@ expr_code_doover:
|
||||
|| NEVER(pExpr->iAgg>=pInfo->nFunc)
|
||||
){
|
||||
assert( !ExprHasProperty(pExpr, EP_IntValue) );
|
||||
sqlite3ErrorMsg(pParse, "misuse of aggregate: %s()", pExpr->u.zToken);
|
||||
sqlite3ErrorMsg(pParse, "misuse of aggregate: %#T()", pExpr);
|
||||
}else{
|
||||
return pInfo->aFunc[pExpr->iAgg].iMem;
|
||||
}
|
||||
@@ -4362,7 +4361,7 @@ expr_code_doover:
|
||||
}
|
||||
#endif
|
||||
if( pDef==0 || pDef->xFinalize!=0 ){
|
||||
sqlite3ErrorMsg(pParse, "unknown function: %s()", zId);
|
||||
sqlite3ErrorMsg(pParse, "unknown function: %#T()", pExpr);
|
||||
break;
|
||||
}
|
||||
if( pDef->funcFlags & SQLITE_FUNC_INLINE ){
|
||||
|
||||
+1
-1
@@ -651,7 +651,7 @@ static void fkScanChildren(
|
||||
** clause. For each row found, increment either the deferred or immediate
|
||||
** foreign key constraint counter. */
|
||||
if( pParse->nErr==0 ){
|
||||
pWInfo = sqlite3WhereBegin(pParse, pSrc, pWhere, 0, 0, 0, 0);
|
||||
pWInfo = sqlite3WhereBegin(pParse, pSrc, pWhere, 0, 0, 0, 0, 0);
|
||||
sqlite3VdbeAddOp2(v, OP_FkCounter, pFKey->isDeferred, nIncr);
|
||||
if( pWInfo ){
|
||||
sqlite3WhereEnd(pWInfo);
|
||||
|
||||
+6
-4
@@ -106,6 +106,7 @@ static void subtypeFunc(
|
||||
int argc,
|
||||
sqlite3_value **argv
|
||||
){
|
||||
UNUSED_PARAMETER(argc);
|
||||
sqlite3_result_int(context, sqlite3_value_subtype(argv[0]));
|
||||
}
|
||||
|
||||
@@ -1119,8 +1120,9 @@ static void quoteFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
|
||||
sqlite3QuoteValue(&str,argv[0]);
|
||||
sqlite3_result_text(context, sqlite3StrAccumFinish(&str), str.nChar,
|
||||
SQLITE_DYNAMIC);
|
||||
if( str.accError==SQLITE_NOMEM ){
|
||||
sqlite3_result_error_nomem(context);
|
||||
if( str.accError!=SQLITE_OK ){
|
||||
sqlite3_result_null(context);
|
||||
sqlite3_result_error_code(context, str.accError);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2239,8 +2241,8 @@ void sqlite3RegisterBuiltinFunctions(void){
|
||||
INLINE_FUNC(likelihood, 2, INLINEFUNC_unlikely, SQLITE_FUNC_UNLIKELY),
|
||||
INLINE_FUNC(likely, 1, INLINEFUNC_unlikely, SQLITE_FUNC_UNLIKELY),
|
||||
#ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC
|
||||
FUNCTION2(sqlite_offset, 1, 0, 0, noopFunc, SQLITE_FUNC_OFFSET|
|
||||
SQLITE_FUNC_TYPEOF),
|
||||
{1, SQLITE_FUNC_BUILTIN|SQLITE_UTF8|SQLITE_FUNC_OFFSET|SQLITE_FUNC_TYPEOF,
|
||||
0, 0, noopFunc, 0, 0, 0, "sqlite_offset", {0} },
|
||||
#endif
|
||||
FUNCTION(ltrim, 1, 1, 0, trimFunc ),
|
||||
FUNCTION(ltrim, 2, 1, 0, trimFunc ),
|
||||
|
||||
@@ -286,6 +286,7 @@ SQLITE_WSD struct Sqlite3Config sqlite3Config = {
|
||||
0, /* xTestCallback */
|
||||
#endif
|
||||
0, /* bLocaltimeFault */
|
||||
0, /* xAltLocaltime */
|
||||
0x7ffffffe, /* iOnceResetThreshold */
|
||||
SQLITE_DEFAULT_SORTERREF_SIZE, /* szSorterRef */
|
||||
0, /* iPrngSeed */
|
||||
|
||||
+13
-10
@@ -181,7 +181,7 @@ void sqlite3TableAffinity(Vdbe *v, Table *pTab, int iReg){
|
||||
}
|
||||
|
||||
for(i=j=0; i<pTab->nCol; i++){
|
||||
assert( pTab->aCol[i].affinity!=0 );
|
||||
assert( pTab->aCol[i].affinity!=0 || sqlite3VdbeParser(v)->nErr>0 );
|
||||
if( (pTab->aCol[i].colFlags & COLFLAG_VIRTUAL)==0 ){
|
||||
zColAff[j++] = pTab->aCol[i].affinity;
|
||||
}
|
||||
@@ -715,9 +715,11 @@ void sqlite3Insert(
|
||||
#endif
|
||||
|
||||
db = pParse->db;
|
||||
if( pParse->nErr || db->mallocFailed ){
|
||||
assert( db->pParse==pParse );
|
||||
if( pParse->nErr ){
|
||||
goto insert_cleanup;
|
||||
}
|
||||
assert( db->mallocFailed==0 );
|
||||
dest.iSDParm = 0; /* Suppress a harmless compiler warning */
|
||||
|
||||
/* If the Select object is really just a simple VALUES() list with a
|
||||
@@ -793,7 +795,11 @@ void sqlite3Insert(
|
||||
**
|
||||
** This is the 2nd template.
|
||||
*/
|
||||
if( pColumn==0 && xferOptimization(pParse, pTab, pSelect, onError, iDb) ){
|
||||
if( pColumn==0
|
||||
&& pSelect!=0
|
||||
&& pTrigger==0
|
||||
&& xferOptimization(pParse, pTab, pSelect, onError, iDb)
|
||||
){
|
||||
assert( !pTrigger );
|
||||
assert( pList==0 );
|
||||
goto insert_end;
|
||||
@@ -893,7 +899,9 @@ void sqlite3Insert(
|
||||
dest.nSdst = pTab->nCol;
|
||||
rc = sqlite3Select(pParse, pSelect, &dest);
|
||||
regFromSelect = dest.iSdst;
|
||||
if( rc || db->mallocFailed || pParse->nErr ) goto insert_cleanup;
|
||||
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 );
|
||||
@@ -2762,18 +2770,13 @@ static int xferOptimization(
|
||||
int destHasUniqueIdx = 0; /* True if pDest has a UNIQUE index */
|
||||
int regData, regRowid; /* Registers holding data and rowid */
|
||||
|
||||
if( pSelect==0 ){
|
||||
return 0; /* Must be of the form INSERT INTO ... SELECT ... */
|
||||
}
|
||||
assert( pSelect!=0 );
|
||||
if( pParse->pWith || pSelect->pWith ){
|
||||
/* Do not attempt to process this query if there are an WITH clauses
|
||||
** attached to it. Proceeding may generate a false "no such table: xxx"
|
||||
** error if pSelect reads from a CTE named "xxx". */
|
||||
return 0;
|
||||
}
|
||||
if( sqlite3TriggerList(pParse, pDest) ){
|
||||
return 0; /* tab1 must not have triggers */
|
||||
}
|
||||
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
||||
if( IsVirtual(pDest) ){
|
||||
return 0; /* tab1 must not be a virtual table */
|
||||
|
||||
+1
-1
@@ -2666,7 +2666,7 @@ int sqlite3JsonTableFunctions(sqlite3 *db){
|
||||
{ "json_each", &jsonEachModule },
|
||||
{ "json_tree", &jsonTreeModule },
|
||||
};
|
||||
int i;
|
||||
unsigned int i;
|
||||
for(i=0; i<sizeof(aMod)/sizeof(aMod[0]) && rc==SQLITE_OK; i++){
|
||||
rc = sqlite3_create_module(db, aMod[i].zName, aMod[i].pModule, 0);
|
||||
}
|
||||
|
||||
@@ -489,6 +489,9 @@ static const sqlite3_api_routines sqlite3Apis = {
|
||||
sqlite3_error_offset,
|
||||
sqlite3_vtab_rhs_value,
|
||||
sqlite3_vtab_distinct,
|
||||
sqlite3_vtab_in,
|
||||
sqlite3_vtab_in_first,
|
||||
sqlite3_vtab_in_next
|
||||
};
|
||||
|
||||
/* True if x is the directory separator character
|
||||
|
||||
+25
-7
@@ -4029,12 +4029,16 @@ int sqlite3_test_control(int op, ...){
|
||||
** sqlite3_test_control().
|
||||
*/
|
||||
case SQLITE_TESTCTRL_FAULT_INSTALL: {
|
||||
/* MSVC is picky about pulling func ptrs from va lists.
|
||||
** http://support.microsoft.com/kb/47961
|
||||
/* A bug in MSVC prevents it from understanding pointers to functions
|
||||
** types in the second argument to va_arg(). Work around the problem
|
||||
** using a typedef.
|
||||
** http://support.microsoft.com/kb/47961 <-- dead hyperlink
|
||||
** Search at http://web.archive.org/ to find the 2015-03-16 archive
|
||||
** of the link above to see the original text.
|
||||
** sqlite3GlobalConfig.xTestCallback = va_arg(ap, int(*)(int));
|
||||
*/
|
||||
typedef int(*TESTCALLBACKFUNC_t)(int);
|
||||
sqlite3GlobalConfig.xTestCallback = va_arg(ap, TESTCALLBACKFUNC_t);
|
||||
typedef int(*sqlite3FaultFuncType)(int);
|
||||
sqlite3GlobalConfig.xTestCallback = va_arg(ap, sqlite3FaultFuncType);
|
||||
rc = sqlite3FaultSim(0);
|
||||
break;
|
||||
}
|
||||
@@ -4161,13 +4165,27 @@ int sqlite3_test_control(int op, ...){
|
||||
break;
|
||||
}
|
||||
|
||||
/* sqlite3_test_control(SQLITE_TESTCTRL_LOCALTIME_FAULT, int onoff);
|
||||
/* sqlite3_test_control(SQLITE_TESTCTRL_LOCALTIME_FAULT, onoff, xAlt);
|
||||
**
|
||||
** If parameter onoff is non-zero, subsequent calls to localtime()
|
||||
** and its variants fail. If onoff is zero, undo this setting.
|
||||
** If parameter onoff is 1, subsequent calls to localtime() fail.
|
||||
** If 2, then invoke xAlt() instead of localtime(). If 0, normal
|
||||
** processing.
|
||||
**
|
||||
** xAlt arguments are void pointers, but they really want to be:
|
||||
**
|
||||
** int xAlt(const time_t*, struct tm*);
|
||||
**
|
||||
** xAlt should write results in to struct tm object of its 2nd argument
|
||||
** and return zero on success, or return non-zero on failure.
|
||||
*/
|
||||
case SQLITE_TESTCTRL_LOCALTIME_FAULT: {
|
||||
sqlite3GlobalConfig.bLocaltimeFault = va_arg(ap, int);
|
||||
if( sqlite3GlobalConfig.bLocaltimeFault==2 ){
|
||||
typedef int(*sqlite3LocaltimeType)(const void*,void*);
|
||||
sqlite3GlobalConfig.xAltLocaltime = va_arg(ap, sqlite3LocaltimeType);
|
||||
}else{
|
||||
sqlite3GlobalConfig.xAltLocaltime = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
+10
-1
@@ -759,8 +759,15 @@ void sqlite3SetString(char **pz, sqlite3 *db, const char *zNew){
|
||||
** has happened. This routine will set db->mallocFailed, and also
|
||||
** temporarily disable the lookaside memory allocator and interrupt
|
||||
** any running VDBEs.
|
||||
**
|
||||
** Always return a NULL pointer so that this routine can be invoked using
|
||||
**
|
||||
** return sqlite3OomFault(db);
|
||||
**
|
||||
** and thereby avoid unnecessary stack frame allocations for the overwhelmingly
|
||||
** common case where no OOM occurs.
|
||||
*/
|
||||
void sqlite3OomFault(sqlite3 *db){
|
||||
void *sqlite3OomFault(sqlite3 *db){
|
||||
if( db->mallocFailed==0 && db->bBenignMalloc==0 ){
|
||||
db->mallocFailed = 1;
|
||||
if( db->nVdbeExec>0 ){
|
||||
@@ -768,9 +775,11 @@ void sqlite3OomFault(sqlite3 *db){
|
||||
}
|
||||
DisableLookaside;
|
||||
if( db->pParse ){
|
||||
sqlite3ErrorMsg(db->pParse, "out of memory");
|
||||
db->pParse->rc = SQLITE_NOMEM_BKPT;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
+13
-11
@@ -178,6 +178,9 @@ static int memjrnlCreateFile(MemJournal *p){
|
||||
}
|
||||
|
||||
|
||||
/* Forward reference */
|
||||
static int memjrnlTruncate(sqlite3_file *pJfd, sqlite_int64 size);
|
||||
|
||||
/*
|
||||
** Write data to the file.
|
||||
*/
|
||||
@@ -207,23 +210,21 @@ static int memjrnlWrite(
|
||||
** access writes are not required. The only exception to this is when
|
||||
** the in-memory journal is being used by a connection using the
|
||||
** atomic-write optimization. In this case the first 28 bytes of the
|
||||
** journal file may be written as part of committing the transaction. */
|
||||
assert( iOfst==p->endpoint.iOffset || iOfst==0 );
|
||||
#if defined(SQLITE_ENABLE_ATOMIC_WRITE) \
|
||||
|| defined(SQLITE_ENABLE_BATCH_ATOMIC_WRITE)
|
||||
** journal file may be written as part of committing the transaction. */
|
||||
assert( iOfst<=p->endpoint.iOffset );
|
||||
if( iOfst>0 && iOfst!=p->endpoint.iOffset ){
|
||||
memjrnlTruncate(pJfd, iOfst);
|
||||
}
|
||||
if( iOfst==0 && p->pFirst ){
|
||||
assert( p->nChunkSize>iAmt );
|
||||
memcpy((u8*)p->pFirst->zChunk, zBuf, iAmt);
|
||||
}else
|
||||
#else
|
||||
assert( iOfst>0 || p->pFirst==0 );
|
||||
#endif
|
||||
{
|
||||
}else{
|
||||
while( nWrite>0 ){
|
||||
FileChunk *pChunk = p->endpoint.pChunk;
|
||||
int iChunkOffset = (int)(p->endpoint.iOffset%p->nChunkSize);
|
||||
int iSpace = MIN(nWrite, p->nChunkSize - iChunkOffset);
|
||||
|
||||
assert( pChunk!=0 || iChunkOffset==0 );
|
||||
if( iChunkOffset==0 ){
|
||||
/* New chunk is required to extend the file. */
|
||||
FileChunk *pNew = sqlite3_malloc(fileChunkSize(p->nChunkSize));
|
||||
@@ -238,10 +239,11 @@ static int memjrnlWrite(
|
||||
assert( !p->pFirst );
|
||||
p->pFirst = pNew;
|
||||
}
|
||||
p->endpoint.pChunk = pNew;
|
||||
pChunk = p->endpoint.pChunk = pNew;
|
||||
}
|
||||
|
||||
memcpy((u8*)p->endpoint.pChunk->zChunk + iChunkOffset, zWrite, iSpace);
|
||||
assert( pChunk!=0 );
|
||||
memcpy((u8*)pChunk->zChunk + iChunkOffset, zWrite, iSpace);
|
||||
zWrite += iSpace;
|
||||
nWrite -= iSpace;
|
||||
p->endpoint.iOffset += iSpace;
|
||||
|
||||
+9
-3
@@ -4910,11 +4910,17 @@ static int unixShmLock(
|
||||
int flags /* What to do with the lock */
|
||||
){
|
||||
unixFile *pDbFd = (unixFile*)fd; /* Connection holding shared memory */
|
||||
unixShm *p = pDbFd->pShm; /* The shared memory being locked */
|
||||
unixShmNode *pShmNode = p->pShmNode; /* The underlying file iNode */
|
||||
unixShm *p; /* The shared memory being locked */
|
||||
unixShmNode *pShmNode; /* The underlying file iNode */
|
||||
int rc = SQLITE_OK; /* Result code */
|
||||
u16 mask; /* Mask of locks to take or release */
|
||||
int *aLock = pShmNode->aLock;
|
||||
int *aLock;
|
||||
|
||||
p = pDbFd->pShm;
|
||||
if( p==0 ) return SQLITE_IOERR_SHMLOCK;
|
||||
pShmNode = p->pShmNode;
|
||||
if( NEVER(pShmNode==0) ) return SQLITE_IOERR_SHMLOCK;
|
||||
aLock = pShmNode->aLock;
|
||||
|
||||
assert( pShmNode==pDbFd->pInode->pShmNode );
|
||||
assert( pShmNode->pInode==pDbFd->pInode );
|
||||
|
||||
+5
-1
@@ -4070,10 +4070,14 @@ static int winShmLock(
|
||||
winFile *pDbFd = (winFile*)fd; /* Connection holding shared memory */
|
||||
winShm *p = pDbFd->pShm; /* The shared memory being locked */
|
||||
winShm *pX; /* For looping over all siblings */
|
||||
winShmNode *pShmNode = p->pShmNode;
|
||||
winShmNode *pShmNode;
|
||||
int rc = SQLITE_OK; /* Result code */
|
||||
u16 mask; /* Mask of locks to take or release */
|
||||
|
||||
if( p==0 ) return SQLITE_IOERR_SHMLOCK;
|
||||
pShmNode = p->pShmNode;
|
||||
if( NEVER(pShmNode==0) ) return SQLITE_IOERR_SHMLOCK;
|
||||
|
||||
assert( ofst>=0 && ofst+n<=SQLITE_SHM_NLOCK );
|
||||
assert( n>=1 );
|
||||
assert( flags==(SQLITE_SHM_LOCK | SQLITE_SHM_SHARED)
|
||||
|
||||
+16
-1
@@ -2844,6 +2844,9 @@ static int pager_playback(Pager *pPager, int isHot){
|
||||
goto end_playback;
|
||||
}
|
||||
pPager->dbSize = mxPg;
|
||||
if( pPager->mxPgno<mxPg ){
|
||||
pPager->mxPgno = mxPg;
|
||||
}
|
||||
}
|
||||
|
||||
/* Copy original pages out of the journal and back into the
|
||||
@@ -3945,7 +3948,7 @@ static void assertTruncateConstraint(Pager *pPager){
|
||||
** then continue writing to the database.
|
||||
*/
|
||||
void sqlite3PagerTruncateImage(Pager *pPager, Pgno nPage){
|
||||
assert( pPager->dbSize>=nPage );
|
||||
assert( pPager->dbSize>=nPage || CORRUPT_DB );
|
||||
assert( pPager->eState>=PAGER_WRITER_CACHEMOD );
|
||||
pPager->dbSize = nPage;
|
||||
|
||||
@@ -7425,6 +7428,18 @@ int sqlite3PagerCheckpoint(
|
||||
int *pnCkpt /* OUT: Final number of checkpointed frames */
|
||||
){
|
||||
int rc = SQLITE_OK;
|
||||
if( pPager->pWal==0 && pPager->journalMode==PAGER_JOURNALMODE_WAL ){
|
||||
/* This only happens when a database file is zero bytes in size opened and
|
||||
** then "PRAGMA journal_mode=WAL" is run and then sqlite3_wal_checkpoint()
|
||||
** is invoked without any intervening transactions. We need to start
|
||||
** a transaction to initialize pWal. The PRAGMA table_list statement is
|
||||
** used for this since it starts transactions on every database file,
|
||||
** including all ATTACHed databases. This seems expensive for a single
|
||||
** sqlite3_wal_checkpoint() call, but it happens very rarely.
|
||||
** https://sqlite.org/forum/forumpost/fd0f19d229156939
|
||||
*/
|
||||
sqlite3_exec(db, "PRAGMA table_list",0,0,0);
|
||||
}
|
||||
if( pPager->pWal ){
|
||||
rc = sqlite3WalCheckpoint(pPager->pWal, db, eMode,
|
||||
(eMode==SQLITE_CHECKPOINT_PASSIVE ? 0 : pPager->xBusyHandler),
|
||||
|
||||
+11
-17
@@ -659,7 +659,7 @@ selcollist(A) ::= sclp(A) scanpt STAR. {
|
||||
}
|
||||
selcollist(A) ::= sclp(A) scanpt nm(X) DOT STAR. {
|
||||
Expr *pRight = sqlite3PExpr(pParse, TK_ASTERISK, 0, 0);
|
||||
Expr *pLeft = sqlite3ExprAlloc(pParse->db, TK_ID, &X, 1);
|
||||
Expr *pLeft = tokenExpr(pParse, TK_ID, X);
|
||||
Expr *pDot = sqlite3PExpr(pParse, TK_DOT, pLeft, pRight);
|
||||
A = sqlite3ExprListAppend(pParse,A, pDot);
|
||||
}
|
||||
@@ -1025,10 +1025,7 @@ idlist(A) ::= nm(Y).
|
||||
|
||||
%include {
|
||||
|
||||
/* Construct a new Expr object from a single identifier. Use the
|
||||
** new Expr to populate pOut. Set the span of pOut to be the identifier
|
||||
** that created the expression.
|
||||
*/
|
||||
/* Construct a new Expr object from a single token */
|
||||
static Expr *tokenExpr(Parse *pParse, int op, Token t){
|
||||
Expr *p = sqlite3DbMallocRawNN(pParse->db, sizeof(Expr)+t.n+1);
|
||||
if( p ){
|
||||
@@ -1048,6 +1045,7 @@ idlist(A) ::= nm(Y).
|
||||
p->u.zToken = (char*)&p[1];
|
||||
memcpy(p->u.zToken, t.z, t.n);
|
||||
p->u.zToken[t.n] = 0;
|
||||
p->w.iOfst = (int)(t.z - pParse->zTail);
|
||||
if( sqlite3Isquote(p->u.zToken[0]) ){
|
||||
sqlite3DequoteExpr(p);
|
||||
}
|
||||
@@ -1068,22 +1066,17 @@ expr(A) ::= LP expr(X) RP. {A = X;}
|
||||
expr(A) ::= id(X). {A=tokenExpr(pParse,TK_ID,X); /*A-overwrites-X*/}
|
||||
expr(A) ::= JOIN_KW(X). {A=tokenExpr(pParse,TK_ID,X); /*A-overwrites-X*/}
|
||||
expr(A) ::= nm(X) DOT nm(Y). {
|
||||
Expr *temp1 = sqlite3ExprAlloc(pParse->db, TK_ID, &X, 1);
|
||||
Expr *temp2 = sqlite3ExprAlloc(pParse->db, TK_ID, &Y, 1);
|
||||
if( IN_RENAME_OBJECT ){
|
||||
sqlite3RenameTokenMap(pParse, (void*)temp2, &Y);
|
||||
sqlite3RenameTokenMap(pParse, (void*)temp1, &X);
|
||||
}
|
||||
Expr *temp1 = tokenExpr(pParse,TK_ID,X);
|
||||
Expr *temp2 = tokenExpr(pParse,TK_ID,Y);
|
||||
A = sqlite3PExpr(pParse, TK_DOT, temp1, temp2);
|
||||
}
|
||||
expr(A) ::= nm(X) DOT nm(Y) DOT nm(Z). {
|
||||
Expr *temp1 = sqlite3ExprAlloc(pParse->db, TK_ID, &X, 1);
|
||||
Expr *temp2 = sqlite3ExprAlloc(pParse->db, TK_ID, &Y, 1);
|
||||
Expr *temp3 = sqlite3ExprAlloc(pParse->db, TK_ID, &Z, 1);
|
||||
Expr *temp1 = tokenExpr(pParse,TK_ID,X);
|
||||
Expr *temp2 = tokenExpr(pParse,TK_ID,Y);
|
||||
Expr *temp3 = tokenExpr(pParse,TK_ID,Z);
|
||||
Expr *temp4 = sqlite3PExpr(pParse, TK_DOT, temp2, temp3);
|
||||
if( IN_RENAME_OBJECT ){
|
||||
sqlite3RenameTokenMap(pParse, (void*)temp3, &Z);
|
||||
sqlite3RenameTokenMap(pParse, (void*)temp2, &Y);
|
||||
sqlite3RenameTokenRemap(pParse, 0, temp1);
|
||||
}
|
||||
A = sqlite3PExpr(pParse, TK_DOT, temp1, temp4);
|
||||
}
|
||||
@@ -1091,6 +1084,7 @@ term(A) ::= NULL|FLOAT|BLOB(X). {A=tokenExpr(pParse,@X,X); /*A-overwrites-X*/}
|
||||
term(A) ::= STRING(X). {A=tokenExpr(pParse,@X,X); /*A-overwrites-X*/}
|
||||
term(A) ::= INTEGER(X). {
|
||||
A = sqlite3ExprAlloc(pParse->db, TK_INTEGER, &X, 1);
|
||||
if( A ) A->w.iOfst = (int)(X.z - pParse->zTail);
|
||||
}
|
||||
expr(A) ::= VARIABLE(X). {
|
||||
if( !(X.z[0]=='#' && sqlite3Isdigit(X.z[1])) ){
|
||||
@@ -1593,7 +1587,7 @@ expr(A) ::= RAISE LP IGNORE RP. {
|
||||
}
|
||||
}
|
||||
expr(A) ::= RAISE LP raisetype(T) COMMA nm(Z) RP. {
|
||||
A = sqlite3ExprAlloc(pParse->db, TK_RAISE, &Z, 1);
|
||||
A = sqlite3ExprAlloc(pParse->db, TK_RAISE, &Z, 1);
|
||||
if( A ) {
|
||||
A->affExpr = (char)T;
|
||||
}
|
||||
|
||||
+2
-1
@@ -551,7 +551,8 @@ void sqlite3PcacheDrop(PgHdr *p){
|
||||
** make it so.
|
||||
*/
|
||||
void sqlite3PcacheMakeDirty(PgHdr *p){
|
||||
assert( p->nRef>0 );
|
||||
assert( p->nRef>0 || p->pCache->bPurgeable==0 );
|
||||
testcase( p->nRef==0 );
|
||||
assert( sqlite3PcachePageSanity(p) );
|
||||
if( p->flags & (PGHDR_CLEAN|PGHDR_DONT_WRITE) ){ /*OPTIMIZATION-IF-FALSE*/
|
||||
p->flags &= ~PGHDR_DONT_WRITE;
|
||||
|
||||
@@ -1250,6 +1250,10 @@ void sqlite3Pragma(
|
||||
(void)sqlite3_finalize(pDummy);
|
||||
sqlite3DbFree(db, zSql);
|
||||
}
|
||||
if( db->mallocFailed ){
|
||||
sqlite3ErrorMsg(db->pParse, "out of memory");
|
||||
db->pParse->rc = SQLITE_NOMEM_BKPT;
|
||||
}
|
||||
pHash = &db->aDb[ii].pSchema->tblHash;
|
||||
break;
|
||||
}
|
||||
|
||||
+37
-12
@@ -389,7 +389,7 @@ int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg, u32 mFlags){
|
||||
sqlite3ResetAllSchemasOfConnection(db);
|
||||
pDb = &db->aDb[iDb];
|
||||
}else
|
||||
if( rc==SQLITE_OK || (db->flags&SQLITE_NoSchemaError)){
|
||||
if( rc==SQLITE_OK || ((db->flags&SQLITE_NoSchemaError) && rc!=SQLITE_NOMEM)){
|
||||
/* Hack: If the SQLITE_NoSchemaError flag is set, then consider
|
||||
** the schema loaded, even if errors (other than OOM) occurred. In
|
||||
** this situation the current sqlite3_prepare() operation will fail,
|
||||
@@ -568,8 +568,10 @@ int sqlite3SchemaToIndex(sqlite3 *db, Schema *pSchema){
|
||||
/*
|
||||
** Free all memory allocations in the pParse object
|
||||
*/
|
||||
void sqlite3ParserReset(Parse *pParse){
|
||||
void sqlite3ParseObjectReset(Parse *pParse){
|
||||
sqlite3 *db = pParse->db;
|
||||
assert( db!=0 );
|
||||
assert( db->pParse==pParse );
|
||||
assert( pParse->nested==0 );
|
||||
#ifndef SQLITE_OMIT_SHARED_CACHE
|
||||
sqlite3DbFree(db, pParse->aTableLock);
|
||||
@@ -584,11 +586,12 @@ void sqlite3ParserReset(Parse *pParse){
|
||||
if( pParse->pConstExpr ){
|
||||
sqlite3ExprListDelete(db, pParse->pConstExpr);
|
||||
}
|
||||
if( db ){
|
||||
assert( db->lookaside.bDisable >= pParse->disableLookaside );
|
||||
db->lookaside.bDisable -= pParse->disableLookaside;
|
||||
db->lookaside.sz = db->lookaside.bDisable ? 0 : db->lookaside.szTrue;
|
||||
}
|
||||
assert( db->lookaside.bDisable >= pParse->disableLookaside );
|
||||
db->lookaside.bDisable -= pParse->disableLookaside;
|
||||
db->lookaside.sz = db->lookaside.bDisable ? 0 : db->lookaside.szTrue;
|
||||
assert( pParse->db->pParse==pParse );
|
||||
db->pParse = pParse->pOuterParse;
|
||||
pParse->db = 0;
|
||||
pParse->disableLookaside = 0;
|
||||
}
|
||||
|
||||
@@ -601,7 +604,7 @@ void sqlite3ParserReset(Parse *pParse){
|
||||
** cost for this mechansim (an extra malloc), so it should not be used
|
||||
** for common cleanups that happen on most calls. But for less
|
||||
** common cleanups, we save a single NULL-pointer comparison in
|
||||
** sqlite3ParserReset(), which reduces the total CPU cycle count.
|
||||
** sqlite3ParseObjectReset(), which reduces the total CPU cycle count.
|
||||
**
|
||||
** If a memory allocation error occurs, then the cleanup happens immediately.
|
||||
** When either SQLITE_DEBUG or SQLITE_COVERAGE_TEST are defined, the
|
||||
@@ -641,6 +644,25 @@ void *sqlite3ParserAddCleanup(
|
||||
return pPtr;
|
||||
}
|
||||
|
||||
/*
|
||||
** Turn bulk memory into a valid Parse object and link that Parse object
|
||||
** into database connection db.
|
||||
**
|
||||
** Call sqlite3ParseObjectReset() to undo this operation.
|
||||
**
|
||||
** Caution: Do not confuse this routine with sqlite3ParseObjectInit() which
|
||||
** is generated by Lemon.
|
||||
*/
|
||||
void sqlite3ParseObjectInit(Parse *pParse, sqlite3 *db){
|
||||
memset(PARSE_HDR(pParse), 0, PARSE_HDR_SZ);
|
||||
memset(PARSE_TAIL(pParse), 0, PARSE_TAIL_SZ);
|
||||
assert( db->pParse!=pParse );
|
||||
pParse->pOuterParse = db->pParse;
|
||||
db->pParse = pParse;
|
||||
pParse->db = db;
|
||||
if( db->mallocFailed ) sqlite3ErrorMsg(pParse, "out of memory");
|
||||
}
|
||||
|
||||
/*
|
||||
** Compile the UTF-8 encoded SQL statement zSql into a statement handle.
|
||||
*/
|
||||
@@ -657,11 +679,15 @@ static int sqlite3Prepare(
|
||||
int i; /* Loop counter */
|
||||
Parse sParse; /* Parsing context */
|
||||
|
||||
memset(&sParse, 0, PARSE_HDR_SZ);
|
||||
/* sqlite3ParseObjectInit(&sParse, db); // inlined for performance */
|
||||
memset(PARSE_HDR(&sParse), 0, PARSE_HDR_SZ);
|
||||
memset(PARSE_TAIL(&sParse), 0, PARSE_TAIL_SZ);
|
||||
sParse.pOuterParse = db->pParse;
|
||||
db->pParse = &sParse;
|
||||
sParse.db = db;
|
||||
sParse.pReprepare = pReprepare;
|
||||
assert( ppStmt && *ppStmt==0 );
|
||||
/* assert( !db->mallocFailed ); // not true with SQLITE_USE_ALLOCA */
|
||||
if( db->mallocFailed ) sqlite3ErrorMsg(&sParse, "out of memory");
|
||||
assert( sqlite3_mutex_held(db->mutex) );
|
||||
|
||||
/* For a long-term use prepared statement avoid the use of
|
||||
@@ -714,7 +740,6 @@ static int sqlite3Prepare(
|
||||
|
||||
sqlite3VtabUnlockList(db);
|
||||
|
||||
sParse.db = db;
|
||||
if( nBytes>=0 && (nBytes==0 || zSql[nBytes-1]!=0) ){
|
||||
char *zSqlCopy;
|
||||
int mxLen = db->aLimit[SQLITE_LIMIT_SQL_LENGTH];
|
||||
@@ -781,7 +806,7 @@ static int sqlite3Prepare(
|
||||
|
||||
end_prepare:
|
||||
|
||||
sqlite3ParserReset(&sParse);
|
||||
sqlite3ParseObjectReset(&sParse);
|
||||
return rc;
|
||||
}
|
||||
static int sqlite3LockAndPrepare(
|
||||
|
||||
+27
-6
@@ -849,13 +849,22 @@ void sqlite3_str_vappendf(
|
||||
goto adjust_width_for_utf8;
|
||||
}
|
||||
case etTOKEN: {
|
||||
Token *pToken;
|
||||
if( (pAccum->printfFlags & SQLITE_PRINTF_INTERNAL)==0 ) return;
|
||||
pToken = va_arg(ap, Token*);
|
||||
assert( bArgList==0 );
|
||||
if( pToken && pToken->n ){
|
||||
sqlite3_str_append(pAccum, (const char*)pToken->z, pToken->n);
|
||||
sqlite3RecordErrorByteOffset(pAccum->db, pToken->z);
|
||||
if( flag_alternateform ){
|
||||
/* %#T means an Expr pointer that uses Expr.u.zToken */
|
||||
Expr *pExpr = va_arg(ap,Expr*);
|
||||
if( ALWAYS(pExpr) && ALWAYS(!ExprHasProperty(pExpr,EP_IntValue)) ){
|
||||
sqlite3_str_appendall(pAccum, (const char*)pExpr->u.zToken);
|
||||
sqlite3RecordErrorOffsetOfExpr(pAccum->db, pExpr);
|
||||
}
|
||||
}else{
|
||||
/* %T means a Token pointer */
|
||||
Token *pToken = va_arg(ap, Token*);
|
||||
assert( bArgList==0 );
|
||||
if( pToken && pToken->n ){
|
||||
sqlite3_str_append(pAccum, (const char*)pToken->z, pToken->n);
|
||||
sqlite3RecordErrorByteOffset(pAccum->db, pToken->z);
|
||||
}
|
||||
}
|
||||
length = width = 0;
|
||||
break;
|
||||
@@ -934,6 +943,18 @@ void sqlite3RecordErrorByteOffset(sqlite3 *db, const char *z){
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** If pExpr has a byte offset for the start of a token, record that as
|
||||
** as the error offset.
|
||||
*/
|
||||
void sqlite3RecordErrorOffsetOfExpr(sqlite3 *db, const Expr *pExpr){
|
||||
while( pExpr && (ExprHasProperty(pExpr,EP_FromJoin) || pExpr->w.iOfst<=0) ){
|
||||
pExpr = pExpr->pLeft;
|
||||
}
|
||||
if( pExpr==0 ) return;
|
||||
db->errByteOffset = pExpr->w.iOfst;
|
||||
}
|
||||
|
||||
/*
|
||||
** Enlarge the memory allocation on a StrAccum object so that it is
|
||||
** able to accept at least N more bytes of text.
|
||||
|
||||
+35
-29
@@ -620,6 +620,7 @@ static int lookupName(
|
||||
}else{
|
||||
sqlite3ErrorMsg(pParse, "%s: %s", zErr, zCol);
|
||||
}
|
||||
sqlite3RecordErrorOffsetOfExpr(pParse->db, pExpr);
|
||||
pParse->checkSchema = 1;
|
||||
pTopNC->nNcErr++;
|
||||
}
|
||||
@@ -728,7 +729,8 @@ static void notValidImpl(
|
||||
Parse *pParse, /* Leave error message here */
|
||||
NameContext *pNC, /* The name context */
|
||||
const char *zMsg, /* Type of error */
|
||||
Expr *pExpr /* Invalidate this expression on error */
|
||||
Expr *pExpr, /* Invalidate this expression on error */
|
||||
Expr *pError /* Associate error with this expression */
|
||||
){
|
||||
const char *zIn = "partial index WHERE clauses";
|
||||
if( pNC->ncFlags & NC_IdxExpr ) zIn = "index expressions";
|
||||
@@ -740,10 +742,11 @@ static void notValidImpl(
|
||||
#endif
|
||||
sqlite3ErrorMsg(pParse, "%s prohibited in %s", zMsg, zIn);
|
||||
if( pExpr ) pExpr->op = TK_NULL;
|
||||
sqlite3RecordErrorOffsetOfExpr(pParse->db, pError);
|
||||
}
|
||||
#define sqlite3ResolveNotValid(P,N,M,X,E) \
|
||||
#define sqlite3ResolveNotValid(P,N,M,X,E,R) \
|
||||
assert( ((X)&~(NC_IsCheck|NC_PartIdx|NC_IdxExpr|NC_GenCol))==0 ); \
|
||||
if( ((N)->ncFlags & (X))!=0 ) notValidImpl(P,N,M,E);
|
||||
if( ((N)->ncFlags & (X))!=0 ) notValidImpl(P,N,M,E,R);
|
||||
|
||||
/*
|
||||
** Expression p should encode a floating point value between 1.0 and 0.0.
|
||||
@@ -878,7 +881,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
|
||||
testcase( pNC->ncFlags & NC_IdxExpr );
|
||||
testcase( pNC->ncFlags & NC_GenCol );
|
||||
sqlite3ResolveNotValid(pParse, pNC, "the \".\" operator",
|
||||
NC_IdxExpr|NC_GenCol, 0);
|
||||
NC_IdxExpr|NC_GenCol, 0, pExpr);
|
||||
pRight = pExpr->pRight;
|
||||
if( pRight->op==TK_ID ){
|
||||
zDb = 0;
|
||||
@@ -909,7 +912,6 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
|
||||
int no_such_func = 0; /* True if no such function exists */
|
||||
int wrong_num_args = 0; /* True if wrong number of arguments */
|
||||
int is_agg = 0; /* True if is an aggregate function */
|
||||
int nId; /* Number of characters in function name */
|
||||
const char *zId; /* The function name. */
|
||||
FuncDef *pDef; /* Information about the function */
|
||||
u8 enc = ENC(pParse->db); /* The database encoding */
|
||||
@@ -919,7 +921,6 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
|
||||
#endif
|
||||
assert( !ExprHasProperty(pExpr, EP_xIsSelect|EP_IntValue) );
|
||||
zId = pExpr->u.zToken;
|
||||
nId = sqlite3Strlen30(zId);
|
||||
pDef = sqlite3FindFunction(pParse->db, zId, n, enc, 0);
|
||||
if( pDef==0 ){
|
||||
pDef = sqlite3FindFunction(pParse->db, zId, -2, enc, 0);
|
||||
@@ -936,8 +937,8 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
|
||||
pExpr->iTable = exprProbability(pList->a[1].pExpr);
|
||||
if( pExpr->iTable<0 ){
|
||||
sqlite3ErrorMsg(pParse,
|
||||
"second argument to likelihood() must be a "
|
||||
"constant between 0.0 and 1.0");
|
||||
"second argument to %#T() must be a "
|
||||
"constant between 0.0 and 1.0", pExpr);
|
||||
pNC->nNcErr++;
|
||||
}
|
||||
}else{
|
||||
@@ -958,8 +959,8 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
|
||||
int auth = sqlite3AuthCheck(pParse, SQLITE_FUNCTION, 0,pDef->zName,0);
|
||||
if( auth!=SQLITE_OK ){
|
||||
if( auth==SQLITE_DENY ){
|
||||
sqlite3ErrorMsg(pParse, "not authorized to use function: %s",
|
||||
pDef->zName);
|
||||
sqlite3ErrorMsg(pParse, "not authorized to use function: %#T",
|
||||
pExpr);
|
||||
pNC->nNcErr++;
|
||||
}
|
||||
pExpr->op = TK_NULL;
|
||||
@@ -982,7 +983,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
|
||||
** in a CHECK constraint. SQLServer, MySQL, and PostgreSQL all
|
||||
** all this. */
|
||||
sqlite3ResolveNotValid(pParse, pNC, "non-deterministic functions",
|
||||
NC_IdxExpr|NC_PartIdx|NC_GenCol, 0);
|
||||
NC_IdxExpr|NC_PartIdx|NC_GenCol, 0, pExpr);
|
||||
}else{
|
||||
assert( (NC_SelfRef & 0xff)==NC_SelfRef ); /* Must fit in 8 bits */
|
||||
pExpr->op2 = pNC->ncFlags & NC_SelfRef;
|
||||
@@ -995,7 +996,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
|
||||
/* Internal-use-only functions are disallowed unless the
|
||||
** SQL is being compiled using sqlite3NestedParse() or
|
||||
** the SQLITE_TESTCTRL_INTERNAL_FUNCTIONS test-control has be
|
||||
** used to activate internal functionsn for testing purposes */
|
||||
** used to activate internal functions for testing purposes */
|
||||
no_such_func = 1;
|
||||
pDef = 0;
|
||||
}else
|
||||
@@ -1014,7 +1015,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
|
||||
);
|
||||
if( pDef && pDef->xValue==0 && pWin ){
|
||||
sqlite3ErrorMsg(pParse,
|
||||
"%.*s() may not be used as a window function", nId, zId
|
||||
"%#T() may not be used as a window function", pExpr
|
||||
);
|
||||
pNC->nNcErr++;
|
||||
}else if(
|
||||
@@ -1028,13 +1029,13 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
|
||||
}else{
|
||||
zType = "aggregate";
|
||||
}
|
||||
sqlite3ErrorMsg(pParse, "misuse of %s function %.*s()",zType,nId,zId);
|
||||
sqlite3ErrorMsg(pParse, "misuse of %s function %#T()",zType,pExpr);
|
||||
pNC->nNcErr++;
|
||||
is_agg = 0;
|
||||
}
|
||||
#else
|
||||
if( (is_agg && (pNC->ncFlags & NC_AllowAgg)==0) ){
|
||||
sqlite3ErrorMsg(pParse,"misuse of aggregate function %.*s()",nId,zId);
|
||||
sqlite3ErrorMsg(pParse,"misuse of aggregate function %#T()",pExpr);
|
||||
pNC->nNcErr++;
|
||||
is_agg = 0;
|
||||
}
|
||||
@@ -1044,18 +1045,18 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
|
||||
&& pParse->explain==0
|
||||
#endif
|
||||
){
|
||||
sqlite3ErrorMsg(pParse, "no such function: %.*s", nId, zId);
|
||||
sqlite3ErrorMsg(pParse, "no such function: %#T", pExpr);
|
||||
pNC->nNcErr++;
|
||||
}else if( wrong_num_args ){
|
||||
sqlite3ErrorMsg(pParse,"wrong number of arguments to function %.*s()",
|
||||
nId, zId);
|
||||
sqlite3ErrorMsg(pParse,"wrong number of arguments to function %#T()",
|
||||
pExpr);
|
||||
pNC->nNcErr++;
|
||||
}
|
||||
#ifndef SQLITE_OMIT_WINDOWFUNC
|
||||
else if( is_agg==0 && ExprHasProperty(pExpr, EP_WinFunc) ){
|
||||
sqlite3ErrorMsg(pParse,
|
||||
"FILTER may not be used with non-aggregate %.*s()",
|
||||
nId, zId
|
||||
"FILTER may not be used with non-aggregate %#T()",
|
||||
pExpr
|
||||
);
|
||||
pNC->nNcErr++;
|
||||
}
|
||||
@@ -1140,7 +1141,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
|
||||
testcase( pNC->ncFlags & NC_IdxExpr );
|
||||
testcase( pNC->ncFlags & NC_GenCol );
|
||||
if( pNC->ncFlags & NC_SelfRef ){
|
||||
notValidImpl(pParse, pNC, "subqueries", pExpr);
|
||||
notValidImpl(pParse, pNC, "subqueries", pExpr, pExpr);
|
||||
}else{
|
||||
sqlite3WalkSelect(pWalker, pExpr->x.pSelect);
|
||||
}
|
||||
@@ -1158,7 +1159,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
|
||||
testcase( pNC->ncFlags & NC_IdxExpr );
|
||||
testcase( pNC->ncFlags & NC_GenCol );
|
||||
sqlite3ResolveNotValid(pParse, pNC, "parameters",
|
||||
NC_IsCheck|NC_PartIdx|NC_IdxExpr|NC_GenCol, pExpr);
|
||||
NC_IsCheck|NC_PartIdx|NC_IdxExpr|NC_GenCol, pExpr, pExpr);
|
||||
break;
|
||||
}
|
||||
case TK_IS:
|
||||
@@ -1210,11 +1211,13 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
|
||||
testcase( pExpr->op==TK_ISNOT );
|
||||
testcase( pExpr->op==TK_BETWEEN );
|
||||
sqlite3ErrorMsg(pParse, "row value misused");
|
||||
sqlite3RecordErrorOffsetOfExpr(pParse->db, pExpr);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return (pParse->nErr || pParse->db->mallocFailed) ? WRC_Abort : WRC_Continue;
|
||||
assert( pParse->db->mallocFailed==0 || pParse->nErr!=0 );
|
||||
return pParse->nErr ? WRC_Abort : WRC_Continue;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1322,11 +1325,13 @@ static void resolveOutOfRangeError(
|
||||
Parse *pParse, /* The error context into which to write the error */
|
||||
const char *zType, /* "ORDER" or "GROUP" */
|
||||
int i, /* The index (1-based) of the term out of range */
|
||||
int mx /* Largest permissible value of i */
|
||||
int mx, /* Largest permissible value of i */
|
||||
Expr *pError /* Associate the error with the expression */
|
||||
){
|
||||
sqlite3ErrorMsg(pParse,
|
||||
"%r %s BY term out of range - should be "
|
||||
"between 1 and %d", i, zType, mx);
|
||||
sqlite3RecordErrorOffsetOfExpr(pParse->db, pError);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1382,7 +1387,7 @@ static int resolveCompoundOrderBy(
|
||||
if( NEVER(pE==0) ) continue;
|
||||
if( sqlite3ExprIsInteger(pE, &iCol) ){
|
||||
if( iCol<=0 || iCol>pEList->nExpr ){
|
||||
resolveOutOfRangeError(pParse, "ORDER", i+1, pEList->nExpr);
|
||||
resolveOutOfRangeError(pParse, "ORDER", i+1, pEList->nExpr, pE);
|
||||
return 1;
|
||||
}
|
||||
}else{
|
||||
@@ -1478,7 +1483,7 @@ int sqlite3ResolveOrderGroupBy(
|
||||
for(i=0, pItem=pOrderBy->a; i<pOrderBy->nExpr; i++, pItem++){
|
||||
if( pItem->u.x.iOrderByCol ){
|
||||
if( pItem->u.x.iOrderByCol>pEList->nExpr ){
|
||||
resolveOutOfRangeError(pParse, zType, i+1, pEList->nExpr);
|
||||
resolveOutOfRangeError(pParse, zType, i+1, pEList->nExpr, 0);
|
||||
return 1;
|
||||
}
|
||||
resolveAlias(pParse, pEList, pItem->u.x.iOrderByCol-1, pItem->pExpr,0);
|
||||
@@ -1570,7 +1575,7 @@ static int resolveOrderGroupBy(
|
||||
** number so that sqlite3ResolveOrderGroupBy() will convert the
|
||||
** order-by term to a copy of the result-set expression */
|
||||
if( iCol<1 || iCol>0xffff ){
|
||||
resolveOutOfRangeError(pParse, zType, i+1, nResult);
|
||||
resolveOutOfRangeError(pParse, zType, i+1, nResult, pE2);
|
||||
return 1;
|
||||
}
|
||||
pItem->u.x.iOrderByCol = (u16)iCol;
|
||||
@@ -1628,7 +1633,7 @@ static int resolveSelectStep(Walker *pWalker, Select *p){
|
||||
*/
|
||||
if( (p->selFlags & SF_Expanded)==0 ){
|
||||
sqlite3SelectPrep(pParse, p, pOuterNC);
|
||||
return (pParse->nErr || db->mallocFailed) ? WRC_Abort : WRC_Prune;
|
||||
return pParse->nErr ? WRC_Abort : WRC_Prune;
|
||||
}
|
||||
|
||||
isCompound = p->pPrior!=0;
|
||||
@@ -1676,7 +1681,8 @@ static int resolveSelectStep(Walker *pWalker, Select *p){
|
||||
if( pItem->zName ) pParse->zAuthContext = pItem->zName;
|
||||
sqlite3ResolveSelectNames(pParse, pItem->pSelect, pOuterNC);
|
||||
pParse->zAuthContext = zSavedContext;
|
||||
if( pParse->nErr || db->mallocFailed ) return WRC_Abort;
|
||||
if( pParse->nErr ) return WRC_Abort;
|
||||
assert( db->mallocFailed==0 );
|
||||
|
||||
/* If the number of references to the outer context changed when
|
||||
** expressions in the sub-select were resolved, the sub-select
|
||||
|
||||
+34
-25
@@ -354,14 +354,14 @@ static void addWhereTerm(
|
||||
ExprSetProperty(pEq, EP_FromJoin);
|
||||
assert( !ExprHasProperty(pEq, EP_TokenOnly|EP_Reduced) );
|
||||
ExprSetVVAProperty(pEq, EP_NoReduce);
|
||||
pEq->iRightJoinTable = pE2->iTable;
|
||||
pEq->w.iRightJoinTable = pE2->iTable;
|
||||
}
|
||||
*ppWhere = sqlite3ExprAnd(pParse, *ppWhere, pEq);
|
||||
}
|
||||
|
||||
/*
|
||||
** Set the EP_FromJoin property on all terms of the given expression.
|
||||
** And set the Expr.iRightJoinTable to iTable for every term in the
|
||||
** And set the Expr.w.iRightJoinTable to iTable for every term in the
|
||||
** expression.
|
||||
**
|
||||
** The EP_FromJoin property is used on terms of an expression to tell
|
||||
@@ -371,8 +371,8 @@ static void addWhereTerm(
|
||||
** WHERE clause during join processing but we need to remember that they
|
||||
** originated in the ON or USING clause.
|
||||
**
|
||||
** The Expr.iRightJoinTable tells the WHERE clause processing that the
|
||||
** expression depends on table iRightJoinTable even if that table is not
|
||||
** The Expr.w.iRightJoinTable tells the WHERE clause processing that the
|
||||
** expression depends on table w.iRightJoinTable even if that table is not
|
||||
** explicitly mentioned in the expression. That information is needed
|
||||
** for cases like this:
|
||||
**
|
||||
@@ -390,7 +390,7 @@ void sqlite3SetJoinExpr(Expr *p, int iTable){
|
||||
ExprSetProperty(p, EP_FromJoin);
|
||||
assert( !ExprHasProperty(p, EP_TokenOnly|EP_Reduced) );
|
||||
ExprSetVVAProperty(p, EP_NoReduce);
|
||||
p->iRightJoinTable = iTable;
|
||||
p->w.iRightJoinTable = iTable;
|
||||
if( p->op==TK_FUNCTION ){
|
||||
assert( ExprUseXList(p) );
|
||||
if( p->x.pList ){
|
||||
@@ -406,7 +406,7 @@ void sqlite3SetJoinExpr(Expr *p, int iTable){
|
||||
}
|
||||
|
||||
/* Undo the work of sqlite3SetJoinExpr(). In the expression p, convert every
|
||||
** term that is marked with EP_FromJoin and iRightJoinTable==iTable into
|
||||
** term that is marked with EP_FromJoin and w.iRightJoinTable==iTable into
|
||||
** an ordinary term that omits the EP_FromJoin mark.
|
||||
**
|
||||
** This happens when a LEFT JOIN is simplified into an ordinary JOIN.
|
||||
@@ -414,7 +414,7 @@ void sqlite3SetJoinExpr(Expr *p, int iTable){
|
||||
static void unsetJoinExpr(Expr *p, int iTable){
|
||||
while( p ){
|
||||
if( ExprHasProperty(p, EP_FromJoin)
|
||||
&& (iTable<0 || p->iRightJoinTable==iTable) ){
|
||||
&& (iTable<0 || p->w.iRightJoinTable==iTable) ){
|
||||
ExprClearProperty(p, EP_FromJoin);
|
||||
}
|
||||
if( p->op==TK_COLUMN && p->iTable==iTable ){
|
||||
@@ -1404,7 +1404,7 @@ KeyInfo *sqlite3KeyInfoAlloc(sqlite3 *db, int N, int X){
|
||||
p->nRef = 1;
|
||||
memset(&p[1], 0, nExtra);
|
||||
}else{
|
||||
sqlite3OomFault(db);
|
||||
return (KeyInfo*)sqlite3OomFault(db);
|
||||
}
|
||||
return p;
|
||||
}
|
||||
@@ -3648,9 +3648,9 @@ static Expr *substExpr(
|
||||
){
|
||||
if( pExpr==0 ) return 0;
|
||||
if( ExprHasProperty(pExpr, EP_FromJoin)
|
||||
&& pExpr->iRightJoinTable==pSubst->iTable
|
||||
&& pExpr->w.iRightJoinTable==pSubst->iTable
|
||||
){
|
||||
pExpr->iRightJoinTable = pSubst->iNewTable;
|
||||
pExpr->w.iRightJoinTable = pSubst->iNewTable;
|
||||
}
|
||||
if( pExpr->op==TK_COLUMN
|
||||
&& pExpr->iTable==pSubst->iTable
|
||||
@@ -3689,7 +3689,7 @@ static Expr *substExpr(
|
||||
ExprSetProperty(pNew, EP_CanBeNull);
|
||||
}
|
||||
if( ExprHasProperty(pExpr,EP_FromJoin) ){
|
||||
sqlite3SetJoinExpr(pNew, pExpr->iRightJoinTable);
|
||||
sqlite3SetJoinExpr(pNew, pExpr->w.iRightJoinTable);
|
||||
}
|
||||
sqlite3ExprDelete(db, pExpr);
|
||||
pExpr = pNew;
|
||||
@@ -3854,7 +3854,7 @@ static int renumberCursorsCb(Walker *pWalker, Expr *pExpr){
|
||||
renumberCursorDoMapping(pWalker, &pExpr->iTable);
|
||||
}
|
||||
if( ExprHasProperty(pExpr, EP_FromJoin) ){
|
||||
renumberCursorDoMapping(pWalker, &pExpr->iRightJoinTable);
|
||||
renumberCursorDoMapping(pWalker, &pExpr->w.iRightJoinTable);
|
||||
}
|
||||
return WRC_Continue;
|
||||
}
|
||||
@@ -4864,11 +4864,13 @@ static int pushDownWhereTerms(
|
||||
}
|
||||
if( isLeftJoin
|
||||
&& (ExprHasProperty(pWhere,EP_FromJoin)==0
|
||||
|| pWhere->iRightJoinTable!=iCursor)
|
||||
|| pWhere->w.iRightJoinTable!=iCursor)
|
||||
){
|
||||
return 0; /* restriction (4) */
|
||||
}
|
||||
if( ExprHasProperty(pWhere,EP_FromJoin) && pWhere->iRightJoinTable!=iCursor ){
|
||||
if( ExprHasProperty(pWhere,EP_FromJoin)
|
||||
&& pWhere->w.iRightJoinTable!=iCursor
|
||||
){
|
||||
return 0; /* restriction (5) */
|
||||
}
|
||||
if( sqlite3ExprIsTableConstant(pWhere, iCursor) ){
|
||||
@@ -5588,7 +5590,8 @@ static int selectExpander(Walker *pWalker, Select *p){
|
||||
|
||||
/* Process NATURAL keywords, and ON and USING clauses of joins.
|
||||
*/
|
||||
if( pParse->nErr || db->mallocFailed || sqliteProcessJoin(pParse, p) ){
|
||||
assert( db->mallocFailed==0 || pParse->nErr!=0 );
|
||||
if( pParse->nErr || sqliteProcessJoin(pParse, p) ){
|
||||
return WRC_Abort;
|
||||
}
|
||||
|
||||
@@ -5885,12 +5888,13 @@ void sqlite3SelectPrep(
|
||||
NameContext *pOuterNC /* Name context for container */
|
||||
){
|
||||
assert( p!=0 || pParse->db->mallocFailed );
|
||||
assert( pParse->db->pParse==pParse );
|
||||
if( pParse->db->mallocFailed ) return;
|
||||
if( p->selFlags & SF_HasTypeInfo ) return;
|
||||
sqlite3SelectExpand(pParse, p);
|
||||
if( pParse->nErr || pParse->db->mallocFailed ) return;
|
||||
if( pParse->nErr ) return;
|
||||
sqlite3ResolveSelectNames(pParse, p, pOuterNC);
|
||||
if( pParse->nErr || pParse->db->mallocFailed ) return;
|
||||
if( pParse->nErr ) return;
|
||||
sqlite3SelectAddTypeInfo(pParse, p);
|
||||
}
|
||||
|
||||
@@ -5907,8 +5911,10 @@ static void resetAccumulator(Parse *pParse, AggInfo *pAggInfo){
|
||||
int i;
|
||||
struct AggInfo_func *pFunc;
|
||||
int nReg = pAggInfo->nFunc + pAggInfo->nColumn;
|
||||
assert( pParse->db->pParse==pParse );
|
||||
assert( pParse->db->mallocFailed==0 || pParse->nErr!=0 );
|
||||
if( nReg==0 ) return;
|
||||
if( pParse->nErr || pParse->db->mallocFailed ) return;
|
||||
if( pParse->nErr ) return;
|
||||
#ifdef SQLITE_DEBUG
|
||||
/* Verify that all AggInfo registers are within the range specified by
|
||||
** AggInfo.mnReg..AggInfo.mxReg */
|
||||
@@ -6331,10 +6337,12 @@ int sqlite3Select(
|
||||
u8 minMaxFlag; /* Flag for min/max queries */
|
||||
|
||||
db = pParse->db;
|
||||
assert( pParse==db->pParse );
|
||||
v = sqlite3GetVdbe(pParse);
|
||||
if( p==0 || db->mallocFailed || pParse->nErr ){
|
||||
if( p==0 || pParse->nErr ){
|
||||
return 1;
|
||||
}
|
||||
assert( db->mallocFailed==0 );
|
||||
if( sqlite3AuthCheck(pParse, SQLITE_SELECT, 0, 0, 0) ) return 1;
|
||||
#if SELECTTRACE_ENABLED
|
||||
SELECTTRACE(1,pParse,p, ("begin processing:\n", pParse->addrExplain));
|
||||
@@ -6369,9 +6377,10 @@ int sqlite3Select(
|
||||
p->selFlags |= SF_NoopOrderBy;
|
||||
}
|
||||
sqlite3SelectPrep(pParse, p, 0);
|
||||
if( pParse->nErr || db->mallocFailed ){
|
||||
if( pParse->nErr ){
|
||||
goto select_end;
|
||||
}
|
||||
assert( db->mallocFailed==0 );
|
||||
assert( p->pEList!=0 );
|
||||
#if SELECTTRACE_ENABLED
|
||||
if( sqlite3SelectTrace & 0x104 ){
|
||||
@@ -6415,7 +6424,7 @@ int sqlite3Select(
|
||||
|
||||
#ifndef SQLITE_OMIT_WINDOWFUNC
|
||||
if( sqlite3WindowRewrite(pParse, p) ){
|
||||
assert( db->mallocFailed || pParse->nErr>0 );
|
||||
assert( pParse->nErr );
|
||||
goto select_end;
|
||||
}
|
||||
#if SELECTTRACE_ENABLED
|
||||
@@ -6891,7 +6900,7 @@ int sqlite3Select(
|
||||
/* Begin the database scan. */
|
||||
SELECTTRACE(1,pParse,p,("WhereBegin\n"));
|
||||
pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, sSort.pOrderBy,
|
||||
p->pEList, wctrlFlags, p->nSelectRow);
|
||||
p->pEList, p, wctrlFlags, p->nSelectRow);
|
||||
if( pWInfo==0 ) goto select_end;
|
||||
if( sqlite3WhereOutputRowCount(pWInfo) < p->nSelectRow ){
|
||||
p->nSelectRow = sqlite3WhereOutputRowCount(pWInfo);
|
||||
@@ -7155,7 +7164,7 @@ int sqlite3Select(
|
||||
sqlite3VdbeAddOp2(v, OP_Gosub, regReset, addrReset);
|
||||
SELECTTRACE(1,pParse,p,("WhereBegin\n"));
|
||||
pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, pGroupBy, pDistinct,
|
||||
WHERE_GROUPBY | (orderByGrp ? WHERE_SORTBYGROUP : 0) | distFlag, 0
|
||||
0, (WHERE_GROUPBY|(orderByGrp ? WHERE_SORTBYGROUP : 0)|distFlag), 0
|
||||
);
|
||||
if( pWInfo==0 ){
|
||||
sqlite3ExprListDelete(db, pDistinct);
|
||||
@@ -7453,7 +7462,7 @@ int sqlite3Select(
|
||||
|
||||
SELECTTRACE(1,pParse,p,("WhereBegin\n"));
|
||||
pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, pMinMaxOrderBy,
|
||||
pDistinct, minMaxFlag|distFlag, 0);
|
||||
pDistinct, 0, minMaxFlag|distFlag, 0);
|
||||
if( pWInfo==0 ){
|
||||
goto select_end;
|
||||
}
|
||||
@@ -7510,7 +7519,7 @@ int sqlite3Select(
|
||||
*/
|
||||
select_end:
|
||||
assert( db->mallocFailed==0 || db->mallocFailed==1 );
|
||||
pParse->nErr += db->mallocFailed;
|
||||
assert( db->mallocFailed==0 || pParse->nErr!=0 );
|
||||
sqlite3ExprListDelete(db, pMinMaxOrderBy);
|
||||
#ifdef SQLITE_DEBUG
|
||||
if( pAggInfo && !db->mallocFailed ){
|
||||
|
||||
+648
-104
File diff suppressed because it is too large
Load Diff
+220
-41
@@ -566,7 +566,7 @@ int sqlite3_exec(
|
||||
#define SQLITE_WARNING_AUTOINDEX (SQLITE_WARNING | (1<<8))
|
||||
#define SQLITE_AUTH_USER (SQLITE_AUTH | (1<<8))
|
||||
#define SQLITE_OK_LOAD_PERMANENTLY (SQLITE_OK | (1<<8))
|
||||
#define SQLITE_OK_SYMLINK (SQLITE_OK | (2<<8))
|
||||
#define SQLITE_OK_SYMLINK (SQLITE_OK | (2<<8)) /* internal use only */
|
||||
|
||||
/*
|
||||
** CAPI3REF: Flags For File Open Operations
|
||||
@@ -3850,7 +3850,7 @@ void sqlite3_free_filename(char*);
|
||||
** SQL, the sqlite3_error_offset() interface returns the byte offset
|
||||
** of the start of that token. ^The byte offset returned by
|
||||
** sqlite3_error_offset() assumes that the input SQL is UTF8.
|
||||
** ^If the most error does not reference a specific token in the input
|
||||
** ^If the most recent error does not reference a specific token in the input
|
||||
** SQL, then the sqlite3_error_offset() function returns -1.
|
||||
**
|
||||
** When the serialized [threading mode] is in use, it might be the
|
||||
@@ -4284,6 +4284,10 @@ const char *sqlite3_normalized_sql(sqlite3_stmt *pStmt);
|
||||
** be false. ^Similarly, a CREATE TABLE IF NOT EXISTS statement is a
|
||||
** read-only no-op if the table already exists, but
|
||||
** sqlite3_stmt_readonly() still returns false for such a statement.
|
||||
**
|
||||
** ^If prepared statement X is an [EXPLAIN] or [EXPLAIN QUERY PLAN]
|
||||
** statement, then sqlite3_stmt_readonly(X) returns the same value as
|
||||
** if the EXPLAIN or EXPLAIN QUERY PLAN prefix were omitted.
|
||||
*/
|
||||
int sqlite3_stmt_readonly(sqlite3_stmt *pStmt);
|
||||
|
||||
@@ -4352,6 +4356,8 @@ int sqlite3_stmt_busy(sqlite3_stmt*);
|
||||
**
|
||||
** ^The sqlite3_value objects that are passed as parameters into the
|
||||
** implementation of [application-defined SQL functions] are protected.
|
||||
** ^The sqlite3_value objects returned by [sqlite3_vtab_rhs_value()]
|
||||
** are protected.
|
||||
** ^The sqlite3_value object returned by
|
||||
** [sqlite3_column_value()] is unprotected.
|
||||
** Unprotected sqlite3_value objects may only be used as arguments
|
||||
@@ -4973,6 +4979,10 @@ int sqlite3_data_count(sqlite3_stmt *pStmt);
|
||||
** even empty strings, are always zero-terminated. ^The return
|
||||
** value from sqlite3_column_blob() for a zero-length BLOB is a NULL pointer.
|
||||
**
|
||||
** ^Strings returned by sqlite3_column_text16() always have the endianness
|
||||
** which is native to the platform, regardless of the text encoding set
|
||||
** for the database.
|
||||
**
|
||||
** <b>Warning:</b> ^The object returned by [sqlite3_column_value()] is an
|
||||
** [unprotected sqlite3_value] object. In a multithreaded environment,
|
||||
** an unprotected sqlite3_value object may only be used safely with
|
||||
@@ -4986,7 +4996,7 @@ int sqlite3_data_count(sqlite3_stmt *pStmt);
|
||||
** [application-defined SQL functions] or [virtual tables], not within
|
||||
** top-level application code.
|
||||
**
|
||||
** The these routines may attempt to convert the datatype of the result.
|
||||
** These routines may attempt to convert the datatype of the result.
|
||||
** ^For example, if the internal representation is FLOAT and a text result
|
||||
** is requested, [sqlite3_snprintf()] is used internally to perform the
|
||||
** conversion automatically. ^(The following table details the conversions
|
||||
@@ -5011,7 +5021,7 @@ int sqlite3_data_count(sqlite3_stmt *pStmt);
|
||||
** <tr><td> TEXT <td> BLOB <td> No change
|
||||
** <tr><td> BLOB <td> INTEGER <td> [CAST] to INTEGER
|
||||
** <tr><td> BLOB <td> FLOAT <td> [CAST] to REAL
|
||||
** <tr><td> BLOB <td> TEXT <td> Add a zero terminator if needed
|
||||
** <tr><td> BLOB <td> TEXT <td> [CAST] to TEXT, ensure zero terminator
|
||||
** </table>
|
||||
** </blockquote>)^
|
||||
**
|
||||
@@ -7131,24 +7141,56 @@ struct sqlite3_index_info {
|
||||
**
|
||||
** These macros define the allowed values for the
|
||||
** [sqlite3_index_info].aConstraint[].op field. Each value represents
|
||||
** an operator that is part of a constraint term in the wHERE clause of
|
||||
** an operator that is part of a constraint term in the WHERE clause of
|
||||
** a query that uses a [virtual table].
|
||||
**
|
||||
** ^The left-hand operand of the operator is given by the corresponding
|
||||
** aConstraint[].iColumn field. ^An iColumn of -1 indicates the left-hand
|
||||
** operand is the rowid.
|
||||
** The SQLITE_INDEX_CONSTRAINT_LIMIT and SQLITE_INDEX_CONSTRAINT_OFFSET
|
||||
** operators have no left-hand operand, and so for those operators the
|
||||
** corresponding aConstraint[].iColumn is meaningless and should not be
|
||||
** used.
|
||||
**
|
||||
** All operator values from SQLITE_INDEX_CONSTRAINT_FUNCTION through
|
||||
** value 255 are reserved to represent functions that are overloaded
|
||||
** by the [xFindFunction|xFindFunction method] of the virtual table
|
||||
** implementation.
|
||||
**
|
||||
** The right-hand operands for each constraint might be accessible using
|
||||
** the [sqlite3_vtab_rhs_value()] interface. Usually the right-hand
|
||||
** operand is only available if it appears as a single constant literal
|
||||
** in the input SQL. If the right-hand operand is another column or an
|
||||
** expression (even a constant expression) or a parameter, then the
|
||||
** sqlite3_vtab_rhs_value() probably will not be able to extract it.
|
||||
** ^The SQLITE_INDEX_CONSTRAINT_ISNULL and
|
||||
** SQLITE_INDEX_CONSTRAINT_ISNOTNULL operators have no right-hand operand
|
||||
** and hence calls to sqlite3_vtab_rhs_value() for those operators will
|
||||
** always return SQLITE_NOTFOUND.
|
||||
**
|
||||
** The collating sequence to be used for comparison can be found using
|
||||
** the [sqlite3_vtab_collation()] interface. For most real-world virtual
|
||||
** tables, the collating sequence of constraints does not matter (for example
|
||||
** because the constraints are numeric) and so the sqlite3_vtab_collation()
|
||||
** interface is no commonly needed.
|
||||
*/
|
||||
#define SQLITE_INDEX_CONSTRAINT_EQ 2
|
||||
#define SQLITE_INDEX_CONSTRAINT_GT 4
|
||||
#define SQLITE_INDEX_CONSTRAINT_LE 8
|
||||
#define SQLITE_INDEX_CONSTRAINT_LT 16
|
||||
#define SQLITE_INDEX_CONSTRAINT_GE 32
|
||||
#define SQLITE_INDEX_CONSTRAINT_MATCH 64
|
||||
#define SQLITE_INDEX_CONSTRAINT_LIKE 65
|
||||
#define SQLITE_INDEX_CONSTRAINT_GLOB 66
|
||||
#define SQLITE_INDEX_CONSTRAINT_REGEXP 67
|
||||
#define SQLITE_INDEX_CONSTRAINT_NE 68
|
||||
#define SQLITE_INDEX_CONSTRAINT_ISNOT 69
|
||||
#define SQLITE_INDEX_CONSTRAINT_ISNOTNULL 70
|
||||
#define SQLITE_INDEX_CONSTRAINT_ISNULL 71
|
||||
#define SQLITE_INDEX_CONSTRAINT_IS 72
|
||||
#define SQLITE_INDEX_CONSTRAINT_FUNCTION 150
|
||||
#define SQLITE_INDEX_CONSTRAINT_EQ 2
|
||||
#define SQLITE_INDEX_CONSTRAINT_GT 4
|
||||
#define SQLITE_INDEX_CONSTRAINT_LE 8
|
||||
#define SQLITE_INDEX_CONSTRAINT_LT 16
|
||||
#define SQLITE_INDEX_CONSTRAINT_GE 32
|
||||
#define SQLITE_INDEX_CONSTRAINT_MATCH 64
|
||||
#define SQLITE_INDEX_CONSTRAINT_LIKE 65
|
||||
#define SQLITE_INDEX_CONSTRAINT_GLOB 66
|
||||
#define SQLITE_INDEX_CONSTRAINT_REGEXP 67
|
||||
#define SQLITE_INDEX_CONSTRAINT_NE 68
|
||||
#define SQLITE_INDEX_CONSTRAINT_ISNOT 69
|
||||
#define SQLITE_INDEX_CONSTRAINT_ISNOTNULL 70
|
||||
#define SQLITE_INDEX_CONSTRAINT_ISNULL 71
|
||||
#define SQLITE_INDEX_CONSTRAINT_IS 72
|
||||
#define SQLITE_INDEX_CONSTRAINT_LIMIT 73
|
||||
#define SQLITE_INDEX_CONSTRAINT_OFFSET 74
|
||||
#define SQLITE_INDEX_CONSTRAINT_FUNCTION 150
|
||||
|
||||
/*
|
||||
** CAPI3REF: Register A Virtual Table Implementation
|
||||
@@ -7177,7 +7219,7 @@ struct sqlite3_index_info {
|
||||
** destructor.
|
||||
**
|
||||
** ^If the third parameter (the pointer to the sqlite3_module object) is
|
||||
** NULL then no new module is create and any existing modules with the
|
||||
** NULL then no new module is created and any existing modules with the
|
||||
** same name are dropped.
|
||||
**
|
||||
** See also: [sqlite3_drop_modules()]
|
||||
@@ -9508,15 +9550,16 @@ SQLITE_EXPERIMENTAL const char *sqlite3_vtab_collation(sqlite3_index_info*,int);
|
||||
** CAPI3REF: Determine if a virtual table query is DISTINCT
|
||||
** METHOD: sqlite3_index_info
|
||||
**
|
||||
** This API may only be used from within an xBestIndex() callback. The
|
||||
** results of calling it from outside of an xBestIndex() callback are
|
||||
** undefined and probably harmful.
|
||||
** This API may only be used from within an [xBestIndex|xBestIndex method]
|
||||
** of a [virtual table] implementation. The result of calling this
|
||||
** interface from outside of xBestIndex() is undefined and probably harmful.
|
||||
**
|
||||
** ^The sqlite3_vtab_distinct() returns an integer that is either 0, 1, or
|
||||
** 2. The integer returned by sqlite3_vtab_distinct() gives the virtual table
|
||||
** additional information about how the query planner wants the output to be
|
||||
** ordered. As long as the virtual table can meet the ordering requirements
|
||||
** of the query planner, it may set the "orderByConsumed" flag.
|
||||
** ^The sqlite3_vtab_distinct() interface returns an integer that is
|
||||
** either 0, 1, or 2. The integer returned by sqlite3_vtab_distinct()
|
||||
** gives the virtual table additional information about how the query
|
||||
** planner wants the output to be ordered. As long as the virtual table
|
||||
** can meet the ordering requirements of the query planner, it may set
|
||||
** the "orderByConsumed" flag.
|
||||
**
|
||||
** <ol><li value="0"><p>
|
||||
** ^If the sqlite3_vtab_distinct() interface returns 0, that means
|
||||
@@ -9525,7 +9568,7 @@ SQLITE_EXPERIMENTAL const char *sqlite3_vtab_collation(sqlite3_index_info*,int);
|
||||
** [sqlite3_index_info] object. This is the default expectation. If the
|
||||
** virtual table outputs all rows in sorted order, then it is always safe for
|
||||
** the xBestIndex method to set the "orderByConsumed" flag, regardless of
|
||||
** what the return value from sqlite3_vtab_distinct().
|
||||
** the return value from sqlite3_vtab_distinct().
|
||||
** <li value="1"><p>
|
||||
** ^(If the sqlite3_vtab_distinct() interface returns 1, that means
|
||||
** that the query planner does not need the rows to be returned in sorted order
|
||||
@@ -9538,7 +9581,7 @@ SQLITE_EXPERIMENTAL const char *sqlite3_vtab_collation(sqlite3_index_info*,int);
|
||||
** 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 ok always for two or more rows with the same
|
||||
** 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".
|
||||
@@ -9569,31 +9612,167 @@ SQLITE_EXPERIMENTAL const char *sqlite3_vtab_collation(sqlite3_index_info*,int);
|
||||
*/
|
||||
int sqlite3_vtab_distinct(sqlite3_index_info*);
|
||||
|
||||
/*
|
||||
** CAPI3REF: Identify and handle IN constraints in xBestIndex
|
||||
**
|
||||
** This interface may only be used from within an
|
||||
** [xBestIndex|xBestIndex() method] of a [virtual table] implementation.
|
||||
** The result of invoking this interface from any other context is
|
||||
** undefined and probably harmful.
|
||||
**
|
||||
** ^(A constraint on a virtual table of the form
|
||||
** "[IN operator|column IN (...)]" is
|
||||
** communicated to the xBestIndex method as a
|
||||
** [SQLITE_INDEX_CONSTRAINT_EQ] constraint.)^ If xBestIndex wants to use
|
||||
** this constraint, it must set the corresponding
|
||||
** aConstraintUsage[].argvIndex to a postive integer. ^(Then, under
|
||||
** the usual mode of handling IN operators, SQLite generates [bytecode]
|
||||
** that invokes the [xFilter|xFilter() method] once for each value
|
||||
** on the right-hand side of the IN operator.)^ Thus the virtual table
|
||||
** only sees a single value from the right-hand side of the IN operator
|
||||
** at a time.
|
||||
**
|
||||
** In some cases, however, it would be advantageous for the virtual
|
||||
** table to see all values on the right-hand of the IN operator all at
|
||||
** once. The sqlite3_vtab_in() interfaces facilitates this in two ways:
|
||||
**
|
||||
** <ol>
|
||||
** <li><p>
|
||||
** ^A call to sqlite3_vtab_in(P,N,-1) will return true (non-zero)
|
||||
** if and only if the [sqlite3_index_info|P->aConstraint][N] constraint
|
||||
** is an [IN operator] that can be processed all at once. ^In other words,
|
||||
** sqlite3_vtab_in() with -1 in the third argument is a mechanism
|
||||
** by which the virtual table can ask SQLite if all-at-once processing
|
||||
** of the IN operator is even possible.
|
||||
**
|
||||
** <li><p>
|
||||
** ^A call to sqlite3_vtab_in(P,N,F) with F==1 or F==0 indicates
|
||||
** to SQLite that the virtual table does or does not want to process
|
||||
** the IN operator all-at-once, respectively. ^Thus when the third
|
||||
** parameter (F) is non-negative, this interface is the mechanism by
|
||||
** which the virtual table tells SQLite how it wants to process the
|
||||
** IN operator.
|
||||
** </ol>
|
||||
**
|
||||
** ^The sqlite3_vtab_in(P,N,F) interface can be invoked multiple times
|
||||
** within the same xBestIndex method call. ^For any given P,N pair,
|
||||
** the return value from sqlite3_vtab_in(P,N,F) will always be the same
|
||||
** within the same xBestIndex call. ^If the interface returns true
|
||||
** (non-zero), that means that the constraint is an IN operator
|
||||
** that can be processed all-at-once. ^If the constraint is not an IN
|
||||
** operator or cannot be processed all-at-once, then the interface returns
|
||||
** false.
|
||||
**
|
||||
** ^(All-at-once processing of the IN operator is selected if both of the
|
||||
** following conditions are met:
|
||||
**
|
||||
** <ol>
|
||||
** <li><p> The P->aConstraintUsage[N].argvIndex value is set to a positive
|
||||
** integer. This is how the virtual table tells SQLite that it wants to
|
||||
** use the N-th constraint.
|
||||
**
|
||||
** <li><p> The last call to sqlite3_vtab_in(P,N,F) for which F was
|
||||
** non-negative had F>=1.
|
||||
** </ol>)^
|
||||
**
|
||||
** ^If either or both of the conditions above are false, then SQLite uses
|
||||
** the traditional one-at-a-time processing strategy for the IN constraint.
|
||||
** ^If both conditions are true, then the argvIndex-th parameter to the
|
||||
** xFilter method will be an [sqlite3_value] that appears to be NULL,
|
||||
** but which can be passed to [sqlite3_vtab_in_first()] and
|
||||
** [sqlite3_vtab_in_next()] to find all values on the right-hand side
|
||||
** of the IN constraint.
|
||||
*/
|
||||
int sqlite3_vtab_in(sqlite3_index_info*, int iCons, int bHandle);
|
||||
|
||||
/*
|
||||
** CAPI3REF: Find all elements on the right-hand side of an IN constraint.
|
||||
**
|
||||
** These interfaces are only useful from within the
|
||||
** [xFilter|xFilter() method] of a [virtual table] implementation.
|
||||
** The result of invoking these interfaces from any other context
|
||||
** is undefined and probably harmful.
|
||||
**
|
||||
** The X parameter in a call to sqlite3_vtab_in_first(X,P) or
|
||||
** sqlite3_vtab_in_next(X,P) must be one of the parameters to the
|
||||
** xFilter method which invokes these routines, and specifically
|
||||
** a parameter that was previously selected for all-at-once IN constraint
|
||||
** processing use the [sqlite3_vtab_in()] interface in the
|
||||
** [xBestIndex|xBestIndex method]. ^(If the X parameter is not
|
||||
** an xFilter argument that was selected for all-at-once IN constraint
|
||||
** processing, then these routines return [SQLITE_MISUSE])^ or perhaps
|
||||
** exhibit some other undefined or harmful behavior.
|
||||
**
|
||||
** ^(Use these routines to access all values on the right-hand side
|
||||
** of the IN constraint using code like the following:
|
||||
**
|
||||
** <blockquote><pre>
|
||||
** for(rc=sqlite3_vtab_in_first(pList, &pVal);
|
||||
** rc==SQLITE_OK && pVal
|
||||
** rc=sqlite3_vtab_in_next(pList, &pVal)
|
||||
** ){
|
||||
** // do something with pVal
|
||||
** }
|
||||
** if( rc!=SQLITE_OK ){
|
||||
** // an error has occurred
|
||||
** }
|
||||
** </pre></blockquote>)^
|
||||
**
|
||||
** ^On success, the sqlite3_vtab_in_first(X,P) and sqlite3_vtab_in_next(X,P)
|
||||
** routines return SQLITE_OK and set *P to point to the first or next value
|
||||
** on the RHS of the IN constraint. ^If there are no more values on the
|
||||
** right hand side of the IN constraint, then *P is set to NULL and these
|
||||
** routines return [SQLITE_DONE]. ^The return value might be
|
||||
** some other value, such as SQLITE_NOMEM, in the event of a malfunction.
|
||||
**
|
||||
** The *ppOut values returned by these routines are only valid until the
|
||||
** next call to either of these routines or until the end of the xFilter
|
||||
** method from which these routines were called. If the virtual table
|
||||
** implementation needs to retain the *ppOut values for longer, it must make
|
||||
** copies. The *ppOut values are [protected sqlite3_value|protected].
|
||||
*/
|
||||
int sqlite3_vtab_in_first(sqlite3_value *pVal, sqlite3_value **ppOut);
|
||||
int sqlite3_vtab_in_next(sqlite3_value *pVal, sqlite3_value **ppOut);
|
||||
|
||||
/*
|
||||
** CAPI3REF: Constraint values in xBestIndex()
|
||||
** METHOD: sqlite3_index_info
|
||||
**
|
||||
** This API may only be used from within an xBestIndex() callback. The
|
||||
** results of calling it from outside of an xBestIndex() callback are
|
||||
** undefined and probably harmful.
|
||||
** This API may only be used from within the [xBestIndex|xBestIndex method]
|
||||
** of a [virtual table] implementation. The result of calling this interface
|
||||
** from outside of an xBestIndex method are undefined and probably harmful.
|
||||
**
|
||||
** ^When the sqlite3_vtab_rhs_value(P,J,V) interface is invoked from within
|
||||
** the [xBestIndex] method of a [virtual table] implementation, with P being
|
||||
** a copy of the [sqlite3_index_info] object pointer passed into xBestIndex and
|
||||
** J being a 0-based index into P->aConstraint[], then this routine
|
||||
** attempts to set *V to be the value on the right-hand side of
|
||||
** that constraint if the right-hand side is a known constant. ^If the
|
||||
** right-hand side of the constraint is not known, then *V is set to a NULL
|
||||
** pointer. ^The sqlite3_vtab_rhs_value(P,J,V) interface returns SQLITE_OK if
|
||||
** attempts to set *V to the value of the right-hand operand of
|
||||
** that constraint if the right-hand operand is known. ^If the
|
||||
** right-hand operand is not known, then *V is set to a NULL pointer.
|
||||
** ^The sqlite3_vtab_rhs_value(P,J,V) interface returns SQLITE_OK if
|
||||
** and only if *V is set to a value. ^The sqlite3_vtab_rhs_value(P,J,V)
|
||||
** inteface returns SQLITE_NOTFOUND if the right-hand side of the J-th
|
||||
** constraint is not available. ^The sqlite3_vtab_rhs_value() interface
|
||||
** can return an result code other than SQLITE_OK or SQLITE_NOTFOUND if
|
||||
** something goes wrong.
|
||||
**
|
||||
** ^The sqlite3_value object returned in *V remains valid for the duration of
|
||||
** the xBestIndex method code. ^When xBestIndex returns, the sqlite3_value
|
||||
** object returned by sqlite3_vtab_rhs_value() is automatically deallocated.
|
||||
** The sqlite3_vtab_rhs_value() interface is usually only successful if
|
||||
** the right-hand operand of a constraint is a literal value in the original
|
||||
** SQL statement. If the right-hand operand is an expression or a reference
|
||||
** to some other column or a [host parameter], then sqlite3_vtab_rhs_value()
|
||||
** will probably return [SQLITE_NOTFOUND].
|
||||
**
|
||||
** ^(Some constraints, such as [SQLITE_INDEX_CONSTRAINT_ISNULL] and
|
||||
** [SQLITE_INDEX_CONSTRAINT_ISNOTNULL], have no right-hand operand. For such
|
||||
** constraints, sqlite3_vtab_rhs_value() always returns SQLITE_NOTFOUND.)^
|
||||
**
|
||||
** ^The [sqlite3_value] object returned in *V is a protected sqlite3_value
|
||||
** and remains valid for the duration of the xBestIndex method call.
|
||||
** ^When xBestIndex returns, the sqlite3_value object returned by
|
||||
** sqlite3_vtab_rhs_value() is automatically deallocated.
|
||||
**
|
||||
** The "_rhs_" in the name of this routine is an abbreviation for
|
||||
** "Right-Hand Side".
|
||||
*/
|
||||
int sqlite3_vtab_rhs_value(sqlite3_index_info*, int, sqlite3_value **ppVal);
|
||||
|
||||
|
||||
@@ -348,6 +348,9 @@ struct sqlite3_api_routines {
|
||||
int (*error_offset)(sqlite3*);
|
||||
int (*vtab_rhs_value)(sqlite3_index_info*,int,sqlite3_value**);
|
||||
int (*vtab_distinct)(sqlite3_index_info*);
|
||||
int (*vtab_in)(sqlite3_index_info*,int,int);
|
||||
int (*vtab_in_first)(sqlite3_value*,sqlite3_value**);
|
||||
int (*vtab_in_next)(sqlite3_value*,sqlite3_value**);
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -663,6 +666,9 @@ typedef int (*sqlite3_loadext_entry)(
|
||||
#define sqlite3_error_offset sqlite3_api->error_offset
|
||||
#define sqlite3_vtab_rhs_value sqlite3_api->vtab_rhs_value
|
||||
#define sqlite3_vtab_distinct sqlite3_api->vtab_distinct
|
||||
#define sqlite3_vtab_in sqlite3_api->vtab_in
|
||||
#define sqlite3_vtab_in_first sqlite3_api->vtab_in_first
|
||||
#define sqlite3_vtab_in_next sqlite3_api->vtab_in_next
|
||||
#endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */
|
||||
|
||||
#if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
|
||||
|
||||
+24
-9
@@ -1231,10 +1231,11 @@ typedef struct With With;
|
||||
/*
|
||||
** A bit in a Bitmask
|
||||
*/
|
||||
#define MASKBIT(n) (((Bitmask)1)<<(n))
|
||||
#define MASKBIT64(n) (((u64)1)<<(n))
|
||||
#define MASKBIT32(n) (((unsigned int)1)<<(n))
|
||||
#define ALLBITS ((Bitmask)-1)
|
||||
#define MASKBIT(n) (((Bitmask)1)<<(n))
|
||||
#define MASKBIT64(n) (((u64)1)<<(n))
|
||||
#define MASKBIT32(n) (((unsigned int)1)<<(n))
|
||||
#define SMASKBIT32(n) ((n)<=31?((unsigned int)1)<<(n):0)
|
||||
#define ALLBITS ((Bitmask)-1)
|
||||
|
||||
/* A VList object records a mapping between parameters/variables/wildcards
|
||||
** in the SQL statement (such as $abc, @pqr, or :xyz) and the integer
|
||||
@@ -2823,7 +2824,10 @@ struct Expr {
|
||||
** TK_VARIABLE: variable number (always >= 1).
|
||||
** TK_SELECT_COLUMN: column of the result vector */
|
||||
i16 iAgg; /* Which entry in pAggInfo->aCol[] or ->aFunc[] */
|
||||
int iRightJoinTable; /* If EP_FromJoin, the right table of the join */
|
||||
union {
|
||||
int iRightJoinTable; /* If EP_FromJoin, the right table of the join */
|
||||
int iOfst; /* else: start of token from start of statement */
|
||||
} w;
|
||||
AggInfo *pAggInfo; /* Used by TK_AGG_COLUMN and TK_AGG_FUNCTION */
|
||||
union {
|
||||
Table *pTab; /* TK_COLUMN: Table containing column. Can be NULL
|
||||
@@ -3585,6 +3589,7 @@ struct Parse {
|
||||
**************************************************************************/
|
||||
|
||||
int aTempReg[8]; /* Holding area for temporary registers */
|
||||
Parse *pOuterParse; /* Outer Parse object when nested */
|
||||
Token sNameToken; /* Token with unqualified schema object name */
|
||||
|
||||
/************************************************************************
|
||||
@@ -3635,7 +3640,8 @@ struct Parse {
|
||||
/*
|
||||
** Sizes and pointers of various parts of the Parse object.
|
||||
*/
|
||||
#define PARSE_HDR_SZ offsetof(Parse,aTempReg) /* Recursive part w/o aColCache*/
|
||||
#define PARSE_HDR(X) (((char*)(X))+offsetof(Parse,zErrMsg))
|
||||
#define PARSE_HDR_SZ (offsetof(Parse,aTempReg)-offsetof(Parse,zErrMsg)) /* Recursive part w/o aColCache*/
|
||||
#define PARSE_RECURSE_SZ offsetof(Parse,sLastToken) /* Recursive part */
|
||||
#define PARSE_TAIL_SZ (sizeof(Parse)-PARSE_RECURSE_SZ) /* Non-recursive part */
|
||||
#define PARSE_TAIL(X) (((char*)(X))+PARSE_RECURSE_SZ) /* Pointer to tail */
|
||||
@@ -3930,6 +3936,7 @@ struct Sqlite3Config {
|
||||
int (*xTestCallback)(int); /* Invoked by sqlite3FaultSim() */
|
||||
#endif
|
||||
int bLocaltimeFault; /* True to fail localtime() calls */
|
||||
int (*xAltLocaltime)(const void*,void*); /* Alternative localtime() routine */
|
||||
int iOnceResetThreshold; /* When to reset OP_Once counters */
|
||||
u32 szSorterRef; /* Min size in bytes to use sorter-refs */
|
||||
unsigned int iPrngSeed; /* Alternative fixed seed for the PRNG */
|
||||
@@ -4575,7 +4582,8 @@ void sqlite3CodeChangeCount(Vdbe*,int,const char*);
|
||||
void sqlite3DeleteFrom(Parse*, SrcList*, Expr*, ExprList*, Expr*);
|
||||
void sqlite3Update(Parse*, SrcList*, ExprList*,Expr*,int,ExprList*,Expr*,
|
||||
Upsert*);
|
||||
WhereInfo *sqlite3WhereBegin(Parse*,SrcList*,Expr*,ExprList*,ExprList*,u16,int);
|
||||
WhereInfo *sqlite3WhereBegin(Parse*,SrcList*,Expr*,ExprList*,
|
||||
ExprList*,Select*,u16,int);
|
||||
void sqlite3WhereEnd(WhereInfo*);
|
||||
LogEst sqlite3WhereOutputRowCount(WhereInfo*);
|
||||
int sqlite3WhereIsDistinct(WhereInfo*);
|
||||
@@ -4975,7 +4983,7 @@ int sqlite3CreateFunc(sqlite3 *, const char *, int, int, void *,
|
||||
FuncDestructor *pDestructor
|
||||
);
|
||||
void sqlite3NoopDestructor(void*);
|
||||
void sqlite3OomFault(sqlite3*);
|
||||
void *sqlite3OomFault(sqlite3*);
|
||||
void sqlite3OomClear(sqlite3*);
|
||||
int sqlite3ApiExit(sqlite3 *db, int);
|
||||
int sqlite3OpenTempDatabase(Parse *);
|
||||
@@ -4988,6 +4996,7 @@ void sqlite3ResultStrAccum(sqlite3_context*,StrAccum*);
|
||||
void sqlite3SelectDestInit(SelectDest*,int,int);
|
||||
Expr *sqlite3CreateColumnExpr(sqlite3 *, SrcList *, int, int);
|
||||
void sqlite3RecordErrorByteOffset(sqlite3*,const char*);
|
||||
void sqlite3RecordErrorOffsetOfExpr(sqlite3*,const Expr*);
|
||||
|
||||
void sqlite3BackupRestart(sqlite3_backup *);
|
||||
void sqlite3BackupUpdate(sqlite3_backup *, Pgno, const u8 *);
|
||||
@@ -5092,11 +5101,17 @@ int sqlite3VtabCallCreate(sqlite3*, int, const char *, char **);
|
||||
int sqlite3VtabCallConnect(Parse*, Table*);
|
||||
int sqlite3VtabCallDestroy(sqlite3*, int, const char *);
|
||||
int sqlite3VtabBegin(sqlite3 *, VTable *);
|
||||
|
||||
FuncDef *sqlite3VtabOverloadFunction(sqlite3 *,FuncDef*, int nArg, Expr*);
|
||||
#if (defined(SQLITE_ENABLE_DBPAGE_VTAB) || defined(SQLITE_TEST)) \
|
||||
&& !defined(SQLITE_OMIT_VIRTUALTABLE)
|
||||
void sqlite3VtabWriteAll(sqlite3_index_info*);
|
||||
#endif
|
||||
sqlite3_int64 sqlite3StmtCurrentTime(sqlite3_context*);
|
||||
int sqlite3VdbeParameterIndex(Vdbe*, const char*, int);
|
||||
int sqlite3TransferBindings(sqlite3_stmt *, sqlite3_stmt *);
|
||||
void sqlite3ParserReset(Parse*);
|
||||
void sqlite3ParseObjectInit(Parse*,sqlite3*);
|
||||
void sqlite3ParseObjectReset(Parse*);
|
||||
void *sqlite3ParserAddCleanup(Parse*,void(*)(sqlite3*,void*),void*);
|
||||
#ifdef SQLITE_ENABLE_NORMALIZE
|
||||
char *sqlite3Normalize(Vdbe*, const char*);
|
||||
|
||||
+30
-18
@@ -1943,15 +1943,16 @@ static int SQLITE_TCLAPI DbObjCmd(
|
||||
"close", "collate", "collation_needed",
|
||||
"commit_hook", "complete", "config",
|
||||
"copy", "deserialize", "enable_load_extension",
|
||||
"errorcode", "eval", "exists",
|
||||
"function", "incrblob", "interrupt",
|
||||
"last_insert_rowid", "nullvalue", "onecolumn",
|
||||
"preupdate", "profile", "progress",
|
||||
"rekey", "restore", "rollback_hook",
|
||||
"serialize", "status", "timeout",
|
||||
"total_changes", "trace", "trace_v2",
|
||||
"transaction", "unlock_notify", "update_hook",
|
||||
"version", "wal_hook", 0
|
||||
"errorcode", "erroroffset", "eval",
|
||||
"exists", "function", "incrblob",
|
||||
"interrupt", "last_insert_rowid", "nullvalue",
|
||||
"onecolumn", "preupdate", "profile",
|
||||
"progress", "rekey", "restore",
|
||||
"rollback_hook", "serialize", "status",
|
||||
"timeout", "total_changes", "trace",
|
||||
"trace_v2", "transaction", "unlock_notify",
|
||||
"update_hook", "version", "wal_hook",
|
||||
0
|
||||
};
|
||||
enum DB_enum {
|
||||
DB_AUTHORIZER, DB_BACKUP, DB_BIND_FALLBACK,
|
||||
@@ -1959,15 +1960,15 @@ static int SQLITE_TCLAPI DbObjCmd(
|
||||
DB_CLOSE, DB_COLLATE, DB_COLLATION_NEEDED,
|
||||
DB_COMMIT_HOOK, DB_COMPLETE, DB_CONFIG,
|
||||
DB_COPY, DB_DESERIALIZE, DB_ENABLE_LOAD_EXTENSION,
|
||||
DB_ERRORCODE, DB_EVAL, DB_EXISTS,
|
||||
DB_FUNCTION, DB_INCRBLOB, DB_INTERRUPT,
|
||||
DB_LAST_INSERT_ROWID, DB_NULLVALUE, DB_ONECOLUMN,
|
||||
DB_PREUPDATE, DB_PROFILE, DB_PROGRESS,
|
||||
DB_REKEY, DB_RESTORE, DB_ROLLBACK_HOOK,
|
||||
DB_SERIALIZE, DB_STATUS, DB_TIMEOUT,
|
||||
DB_TOTAL_CHANGES, DB_TRACE, DB_TRACE_V2,
|
||||
DB_TRANSACTION, DB_UNLOCK_NOTIFY, DB_UPDATE_HOOK,
|
||||
DB_VERSION, DB_WAL_HOOK
|
||||
DB_ERRORCODE, DB_ERROROFFSET, DB_EVAL,
|
||||
DB_EXISTS, DB_FUNCTION, DB_INCRBLOB,
|
||||
DB_INTERRUPT, DB_LAST_INSERT_ROWID, DB_NULLVALUE,
|
||||
DB_ONECOLUMN, DB_PREUPDATE, DB_PROFILE,
|
||||
DB_PROGRESS, DB_REKEY, DB_RESTORE,
|
||||
DB_ROLLBACK_HOOK, DB_SERIALIZE, DB_STATUS,
|
||||
DB_TIMEOUT, DB_TOTAL_CHANGES, DB_TRACE,
|
||||
DB_TRACE_V2, DB_TRANSACTION, DB_UNLOCK_NOTIFY,
|
||||
DB_UPDATE_HOOK, DB_VERSION, DB_WAL_HOOK,
|
||||
};
|
||||
/* don't leave trailing commas on DB_enum, it confuses the AIX xlc compiler */
|
||||
|
||||
@@ -2730,6 +2731,17 @@ deserialize_error:
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
** $db erroroffset
|
||||
**
|
||||
** Return the numeric error code that was returned by the most recent
|
||||
** call to sqlite3_exec().
|
||||
*/
|
||||
case DB_ERROROFFSET: {
|
||||
Tcl_SetObjResult(interp, Tcl_NewIntObj(sqlite3_error_offset(pDb->db)));
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
** $db exists $sql
|
||||
** $db onecolumn $sql
|
||||
|
||||
+150
-3
@@ -3977,6 +3977,102 @@ static int SQLITE_TCLAPI test_bind_blob(
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Usage: sqlite3_bind_value_from_preupdate STMT N NEW|OLD IDX
|
||||
**
|
||||
** Test the sqlite3_bind_value interface using sqlite3_value objects
|
||||
** obtained from either sqlite3_preupdate_new() (if arg[3]=="new") or
|
||||
** sqlite3_preupdate_old() if (arg[3]=="old"). IDX is the index to
|
||||
** pass to the sqlite3_preupdate_xxx() function.
|
||||
*/
|
||||
static int SQLITE_TCLAPI test_bind_value_from_preupdate(
|
||||
void * clientData,
|
||||
Tcl_Interp *interp,
|
||||
int objc,
|
||||
Tcl_Obj *CONST objv[]
|
||||
){
|
||||
sqlite3_stmt *pStmt;
|
||||
int idx;
|
||||
int bidx;
|
||||
const char *z3 = 0;
|
||||
sqlite3 *db = 0;
|
||||
sqlite3_value *pVal = 0;
|
||||
|
||||
if( objc!=5 ){
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "STMT N NEW|OLD IDX");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
|
||||
if( Tcl_GetIntFromObj(interp, objv[2], &idx) ) return TCL_ERROR;
|
||||
z3 = Tcl_GetString(objv[3]);
|
||||
if( Tcl_GetIntFromObj(interp, objv[4], &bidx) ) return TCL_ERROR;
|
||||
db = sqlite3_db_handle(pStmt);
|
||||
|
||||
#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
|
||||
if( z3[0]=='n' ){
|
||||
sqlite3_preupdate_new(db, bidx, &pVal);
|
||||
}else if( z3[0]=='o' ){
|
||||
sqlite3_preupdate_old(db, bidx, &pVal);
|
||||
}else{
|
||||
Tcl_AppendResult(interp, "expected new or old, got: ", z3, (char*)0);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
sqlite3_bind_value(pStmt, idx, pVal);
|
||||
#endif
|
||||
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Usage: sqlite3_bind_value_from_select STMT N SELECT
|
||||
**
|
||||
** Test the sqlite3_bind_value interface. STMT is a prepared statement.
|
||||
** N is the index of a wildcard in the prepared statement.
|
||||
*/
|
||||
static int SQLITE_TCLAPI test_bind_value_from_select(
|
||||
void * clientData,
|
||||
Tcl_Interp *interp,
|
||||
int objc,
|
||||
Tcl_Obj *CONST objv[]
|
||||
){
|
||||
sqlite3_stmt *pStmt;
|
||||
sqlite3_stmt *pStmt2;
|
||||
int idx;
|
||||
const char *zSql = 0;
|
||||
sqlite3 *db = 0;
|
||||
int rc = SQLITE_OK;
|
||||
|
||||
if( objc!=4 ){
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "STMT N SELECT");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
|
||||
if( Tcl_GetIntFromObj(interp, objv[2], &idx) ) return TCL_ERROR;
|
||||
zSql = Tcl_GetString(objv[3]);
|
||||
db = sqlite3_db_handle(pStmt);
|
||||
|
||||
rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt2, 0);
|
||||
if( rc!=SQLITE_OK ){
|
||||
Tcl_AppendResult(interp, "error in SQL: ", sqlite3_errmsg(db), (char*)0);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if( sqlite3_step(pStmt2)==SQLITE_ROW ){
|
||||
sqlite3_value *pVal = sqlite3_column_value(pStmt2, 0);
|
||||
sqlite3_bind_value(pStmt, idx, pVal);
|
||||
}
|
||||
rc = sqlite3_finalize(pStmt2);
|
||||
if( rc!=SQLITE_OK ){
|
||||
Tcl_AppendResult(interp,
|
||||
"error runnning SQL: ", sqlite3_errmsg(db), (char*)0
|
||||
);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
|
||||
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
||||
/*
|
||||
@@ -7111,6 +7207,55 @@ static int SQLITE_TCLAPI test_print_eqp(
|
||||
}
|
||||
#endif /* SQLITE_OMIT_EXPLAIN */
|
||||
|
||||
#include <time.h>
|
||||
/*
|
||||
** This is an alternative localtime_r() implementation used for testing
|
||||
** the 'localtime' and 'utc' modifiers of date-time functions. Because
|
||||
** the OS-supplied localtime_r() is locale-dependent, this alternative is
|
||||
** provided as a stable test platform.
|
||||
**
|
||||
** Operation:
|
||||
**
|
||||
** (1) Localtime is 30 minutes earlier than (west of) UTC on
|
||||
** even days (counting from 1970-01-01)
|
||||
**
|
||||
** (2) Localtime is 30 minutes later than (east of) UTC on odd days.
|
||||
**
|
||||
** (3) The function fails for the specific date/time value
|
||||
** of 2000-05-29 14:16:00 in order to test the ability of
|
||||
** SQLite to deal with localtime_r() failures.
|
||||
*/
|
||||
static int testLocaltime(const void *aliasT, void *aliasTM){
|
||||
const time_t t = *(const time_t*)aliasT;
|
||||
struct tm *pTm = (struct tm *)aliasTM;
|
||||
time_t altT;
|
||||
sqlite3_int64 iJD;
|
||||
int Z, A, B, C, D, E, X1, S;
|
||||
|
||||
if( (t/86400) & 1 ){
|
||||
altT = t + 1800; /* 30 minutes later on odd days */
|
||||
}else{
|
||||
altT = t - 1800; /* 30 minutes earlier on even days */
|
||||
}
|
||||
iJD = (sqlite3_int64)(altT + 210866760000);
|
||||
Z = (int)((iJD + 43200)/86400);
|
||||
A = (int)((Z - 1867216.25)/36524.25);
|
||||
A = Z + 1 + A - (A/4);
|
||||
B = A + 1524;
|
||||
C = (int)((B - 122.1)/365.25);
|
||||
D = (36525*(C&32767))/100;
|
||||
E = (int)((B-D)/30.6001);
|
||||
X1 = (int)(30.6001*E);
|
||||
pTm->tm_mday = B - D - X1;
|
||||
pTm->tm_mon = E<14 ? E-2 : E-14;
|
||||
pTm->tm_year = (pTm->tm_mon>1 ? C - 4716 : C - 4715) - 1900;
|
||||
S = (int)((iJD + 43200)%86400);
|
||||
pTm->tm_hour = S/3600;
|
||||
pTm->tm_min = (S/60)%60;
|
||||
pTm->tm_sec = S % 60;
|
||||
return t==959609760; /* Special case: 2000-05-29 14:16:00 fails */
|
||||
}
|
||||
|
||||
/*
|
||||
** sqlite3_test_control VERB ARGS...
|
||||
*/
|
||||
@@ -7158,11 +7303,11 @@ static int SQLITE_TCLAPI test_test_control(
|
||||
case SQLITE_TESTCTRL_LOCALTIME_FAULT: {
|
||||
int val;
|
||||
if( objc!=3 ){
|
||||
Tcl_WrongNumArgs(interp, 2, objv, "ONOFF");
|
||||
Tcl_WrongNumArgs(interp, 2, objv, "0|1|2");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if( Tcl_GetBooleanFromObj(interp, objv[2], &val) ) return TCL_ERROR;
|
||||
sqlite3_test_control(iFlag, val);
|
||||
if( Tcl_GetIntFromObj(interp, objv[2], &val) ) return TCL_ERROR;
|
||||
sqlite3_test_control(iFlag, val, testLocaltime);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -8442,6 +8587,8 @@ int Sqlitetest1_Init(Tcl_Interp *interp){
|
||||
{ "sqlite3_bind_text", test_bind_text ,0 },
|
||||
{ "sqlite3_bind_text16", test_bind_text16 ,0 },
|
||||
{ "sqlite3_bind_blob", test_bind_blob ,0 },
|
||||
{ "sqlite3_bind_value_from_select",test_bind_value_from_select ,0 },
|
||||
{ "sqlite3_bind_value_from_preupdate",test_bind_value_from_preupdate ,0 },
|
||||
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
||||
{ "sqlite3_carray_bind", test_carray_bind ,0 },
|
||||
#endif
|
||||
|
||||
+173
-22
@@ -299,7 +299,21 @@ static int tclFilter(
|
||||
const char *zVal = (const char*)sqlite3_value_text(argv[ii]);
|
||||
Tcl_Obj *pVal;
|
||||
if( zVal==0 ){
|
||||
sqlite3_value *pMem;
|
||||
pVal = Tcl_NewObj();
|
||||
for(rc=sqlite3_vtab_in_first(argv[ii], &pMem);
|
||||
rc==SQLITE_OK && pMem;
|
||||
rc=sqlite3_vtab_in_next(argv[ii], &pMem)
|
||||
){
|
||||
Tcl_Obj *pVal2 = 0;
|
||||
zVal = (const char*)sqlite3_value_text(pMem);
|
||||
if( zVal ){
|
||||
pVal2 = Tcl_NewStringObj(zVal, -1);
|
||||
}else{
|
||||
pVal2 = Tcl_NewObj();
|
||||
}
|
||||
Tcl_ListObjAppendElement(interp, pVal, pVal2);
|
||||
}
|
||||
}else{
|
||||
pVal = Tcl_NewStringObj(zVal, -1);
|
||||
}
|
||||
@@ -374,20 +388,13 @@ static int tclEof(sqlite3_vtab_cursor *pVtabCursor){
|
||||
return (pCsr->pStmt==0);
|
||||
}
|
||||
|
||||
static int tclBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
|
||||
tcl_vtab *pTab = (tcl_vtab*)tab;
|
||||
Tcl_Interp *interp = pTab->interp;
|
||||
Tcl_Obj *pArg;
|
||||
Tcl_Obj *pScript;
|
||||
static void testBestIndexObjConstraints(
|
||||
Tcl_Interp *interp,
|
||||
sqlite3_index_info *pIdxInfo
|
||||
){
|
||||
int ii;
|
||||
int rc = SQLITE_OK;
|
||||
|
||||
pScript = Tcl_DuplicateObj(pTab->pCmd);
|
||||
Tcl_IncrRefCount(pScript);
|
||||
Tcl_ListObjAppendElement(interp, pScript, Tcl_NewStringObj("xBestIndex", -1));
|
||||
|
||||
pArg = Tcl_NewObj();
|
||||
Tcl_IncrRefCount(pArg);
|
||||
Tcl_Obj *pRes = Tcl_NewObj();
|
||||
Tcl_IncrRefCount(pRes);
|
||||
for(ii=0; ii<pIdxInfo->nConstraint; ii++){
|
||||
struct sqlite3_index_constraint const *pCons = &pIdxInfo->aConstraint[ii];
|
||||
Tcl_Obj *pElem = Tcl_NewObj();
|
||||
@@ -424,6 +431,10 @@ static int tclBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
|
||||
zOp = "isnull"; break;
|
||||
case SQLITE_INDEX_CONSTRAINT_IS:
|
||||
zOp = "is"; break;
|
||||
case SQLITE_INDEX_CONSTRAINT_LIMIT:
|
||||
zOp = "limit"; break;
|
||||
case SQLITE_INDEX_CONSTRAINT_OFFSET:
|
||||
zOp = "offset"; break;
|
||||
}
|
||||
|
||||
Tcl_ListObjAppendElement(0, pElem, Tcl_NewStringObj("op", -1));
|
||||
@@ -433,15 +444,21 @@ static int tclBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
|
||||
Tcl_ListObjAppendElement(0, pElem, Tcl_NewStringObj("usable", -1));
|
||||
Tcl_ListObjAppendElement(0, pElem, Tcl_NewIntObj(pCons->usable));
|
||||
|
||||
Tcl_ListObjAppendElement(0, pArg, pElem);
|
||||
Tcl_ListObjAppendElement(0, pRes, pElem);
|
||||
Tcl_DecrRefCount(pElem);
|
||||
}
|
||||
|
||||
Tcl_ListObjAppendElement(0, pScript, pArg);
|
||||
Tcl_DecrRefCount(pArg);
|
||||
Tcl_SetObjResult(interp, pRes);
|
||||
Tcl_DecrRefCount(pRes);
|
||||
}
|
||||
|
||||
pArg = Tcl_NewObj();
|
||||
Tcl_IncrRefCount(pArg);
|
||||
static void testBestIndexObjOrderby(
|
||||
Tcl_Interp *interp,
|
||||
sqlite3_index_info *pIdxInfo
|
||||
){
|
||||
int ii;
|
||||
Tcl_Obj *pRes = Tcl_NewObj();
|
||||
Tcl_IncrRefCount(pRes);
|
||||
for(ii=0; ii<pIdxInfo->nOrderBy; ii++){
|
||||
struct sqlite3_index_orderby const *pOrder = &pIdxInfo->aOrderBy[ii];
|
||||
Tcl_Obj *pElem = Tcl_NewObj();
|
||||
@@ -452,17 +469,150 @@ static int tclBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
|
||||
Tcl_ListObjAppendElement(0, pElem, Tcl_NewStringObj("desc", -1));
|
||||
Tcl_ListObjAppendElement(0, pElem, Tcl_NewIntObj(pOrder->desc));
|
||||
|
||||
Tcl_ListObjAppendElement(0, pArg, pElem);
|
||||
Tcl_ListObjAppendElement(0, pRes, pElem);
|
||||
Tcl_DecrRefCount(pElem);
|
||||
}
|
||||
|
||||
Tcl_ListObjAppendElement(0, pScript, pArg);
|
||||
Tcl_DecrRefCount(pArg);
|
||||
Tcl_SetObjResult(interp, pRes);
|
||||
Tcl_DecrRefCount(pRes);
|
||||
}
|
||||
|
||||
Tcl_ListObjAppendElement(0, pScript, Tcl_NewWideIntObj(pIdxInfo->colUsed));
|
||||
/*
|
||||
** Implementation of the handle passed to each xBestIndex callback. This
|
||||
** object features the following sub-commands:
|
||||
**
|
||||
** $hdl constraints
|
||||
** $hdl orderby
|
||||
** $hdl mask
|
||||
**
|
||||
** $hdl distinct
|
||||
** Return the result (an integer) of calling sqlite3_vtab_distinct()
|
||||
** on the index-info structure.
|
||||
**
|
||||
** $hdl in IDX BOOLEAN
|
||||
** Wrapper around sqlite3_vtab_in(). Returns an integer.
|
||||
**
|
||||
** $hdl rhs_value IDX ?DEFAULT?
|
||||
** Wrapper around sqlite3_vtab_rhs_value().
|
||||
*/
|
||||
static int SQLITE_TCLAPI testBestIndexObj(
|
||||
ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
|
||||
Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
|
||||
int objc, /* Number of arguments */
|
||||
Tcl_Obj *CONST objv[] /* Command arguments */
|
||||
){
|
||||
const char *azSub[] = {
|
||||
"constraints", /* 0 */
|
||||
"orderby", /* 1 */
|
||||
"mask", /* 2 */
|
||||
"distinct", /* 3 */
|
||||
"in", /* 4 */
|
||||
"rhs_value", /* 5 */
|
||||
0
|
||||
};
|
||||
int ii;
|
||||
sqlite3_index_info *pIdxInfo = (sqlite3_index_info*)clientData;
|
||||
|
||||
if( objc<2 ){
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "SUB-COMMAND");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if( Tcl_GetIndexFromObj(interp, objv[1], azSub, "sub-command", 0, &ii) ){
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
if( ii<4 && objc!=2 ){
|
||||
Tcl_WrongNumArgs(interp, 2, objv, "");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if( ii==4 && objc!=4 ){
|
||||
Tcl_WrongNumArgs(interp, 2, objv, "INDEX BOOLEAN");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if( ii==5 && objc!=3 && objc!=4 ){
|
||||
Tcl_WrongNumArgs(interp, 2, objv, "INDEX ?DEFAULT?");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
switch( ii ){
|
||||
case 0: assert( sqlite3_stricmp(azSub[ii], "constraints")==0 );
|
||||
testBestIndexObjConstraints(interp, pIdxInfo);
|
||||
break;
|
||||
|
||||
case 1: assert( sqlite3_stricmp(azSub[ii], "orderby")==0 );
|
||||
testBestIndexObjOrderby(interp, pIdxInfo);
|
||||
break;
|
||||
|
||||
case 2: assert( sqlite3_stricmp(azSub[ii], "mask")==0 );
|
||||
Tcl_SetObjResult(interp, Tcl_NewWideIntObj(pIdxInfo->colUsed));
|
||||
break;
|
||||
|
||||
case 3: assert( sqlite3_stricmp(azSub[ii], "distinct")==0 ); {
|
||||
int bDistinct = sqlite3_vtab_distinct(pIdxInfo);
|
||||
Tcl_SetObjResult(interp, Tcl_NewIntObj(bDistinct));
|
||||
break;
|
||||
}
|
||||
|
||||
case 4: assert( sqlite3_stricmp(azSub[ii], "in")==0 ); {
|
||||
int iCons;
|
||||
int bHandle;
|
||||
if( Tcl_GetIntFromObj(interp, objv[2], &iCons)
|
||||
|| Tcl_GetBooleanFromObj(interp, objv[3], &bHandle)
|
||||
){
|
||||
return TCL_ERROR;
|
||||
}
|
||||
Tcl_SetObjResult(interp,
|
||||
Tcl_NewIntObj(sqlite3_vtab_in(pIdxInfo, iCons, bHandle))
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
case 5: assert( sqlite3_stricmp(azSub[ii], "rhs_value")==0 ); {
|
||||
int iCons = 0;
|
||||
int rc;
|
||||
sqlite3_value *pVal = 0;
|
||||
const char *zVal = "";
|
||||
if( Tcl_GetIntFromObj(interp, objv[2], &iCons) ){
|
||||
return TCL_ERROR;
|
||||
}
|
||||
rc = sqlite3_vtab_rhs_value(pIdxInfo, iCons, &pVal);
|
||||
if( rc!=SQLITE_OK && rc!=SQLITE_NOTFOUND ){
|
||||
Tcl_SetResult(interp, (char *)sqlite3ErrName(rc), TCL_VOLATILE);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if( pVal ){
|
||||
zVal = (const char*)sqlite3_value_text(pVal);
|
||||
}else if( objc==4 ){
|
||||
zVal = Tcl_GetString(objv[3]);
|
||||
}
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(zVal, -1));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
static int tclBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
|
||||
tcl_vtab *pTab = (tcl_vtab*)tab;
|
||||
Tcl_Interp *interp = pTab->interp;
|
||||
int rc = SQLITE_OK;
|
||||
|
||||
static int iNext = 43;
|
||||
char zHdl[24];
|
||||
Tcl_Obj *pScript;
|
||||
|
||||
pScript = Tcl_DuplicateObj(pTab->pCmd);
|
||||
Tcl_IncrRefCount(pScript);
|
||||
Tcl_ListObjAppendElement(interp, pScript, Tcl_NewStringObj("xBestIndex", -1));
|
||||
|
||||
sqlite3_snprintf(sizeof(zHdl), zHdl, "bestindex%d", iNext++);
|
||||
Tcl_CreateObjCommand(interp, zHdl, testBestIndexObj, pIdxInfo, 0);
|
||||
Tcl_ListObjAppendElement(interp, pScript, Tcl_NewStringObj(zHdl, -1));
|
||||
rc = Tcl_EvalObjEx(interp, pScript, TCL_EVAL_GLOBAL);
|
||||
Tcl_DeleteCommand(interp, zHdl);
|
||||
Tcl_DecrRefCount(pScript);
|
||||
|
||||
if( rc!=TCL_OK ){
|
||||
const char *zErr = Tcl_GetStringResult(interp);
|
||||
rc = SQLITE_ERROR;
|
||||
@@ -489,6 +639,7 @@ static int tclBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
|
||||
rc = SQLITE_ERROR;
|
||||
pTab->base.zErrMsg = sqlite3_mprintf("%s", zErr);
|
||||
}else{
|
||||
int ii;
|
||||
int iArgv = 1;
|
||||
for(ii=0; rc==SQLITE_OK && ii<nElem; ii+=2){
|
||||
const char *zCmd = Tcl_GetString(apElem[ii]);
|
||||
|
||||
+1
-1
@@ -239,7 +239,7 @@ static void set_options(Tcl_Interp *interp){
|
||||
Tcl_SetVar2(interp, "sqlite_options", "geopoly", "0", TCL_GLOBAL_ONLY);
|
||||
#endif
|
||||
|
||||
#ifdef SQLITE_ENABLE_JSON1
|
||||
#ifndef SQLITE_OMIT_JSON
|
||||
Tcl_SetVar2(interp, "sqlite_options", "json1", "1", TCL_GLOBAL_ONLY);
|
||||
#else
|
||||
Tcl_SetVar2(interp, "sqlite_options", "json1", "0", TCL_GLOBAL_ONLY);
|
||||
|
||||
+4
-1
@@ -657,7 +657,10 @@ int sqlite3RunParser(Parse *pParse, const char *zSql){
|
||||
tokenType = analyzeFilterKeyword((const u8*)&zSql[6], lastTokenParsed);
|
||||
#endif /* SQLITE_OMIT_WINDOWFUNC */
|
||||
}else{
|
||||
sqlite3ErrorMsg(pParse, "unrecognized token: \"%.*s\"", n, zSql);
|
||||
Token x;
|
||||
x.z = zSql;
|
||||
x.n = n;
|
||||
sqlite3ErrorMsg(pParse, "unrecognized token: \"%T\"", &x);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -412,7 +412,7 @@ void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 moreToFollow){
|
||||
sqlite3_str_appendf(&x, " fg.af=%x.%c",
|
||||
pExpr->flags, pExpr->affExpr ? pExpr->affExpr : 'n');
|
||||
if( ExprHasProperty(pExpr, EP_FromJoin) ){
|
||||
sqlite3_str_appendf(&x, " iRJT=%d", pExpr->iRightJoinTable);
|
||||
sqlite3_str_appendf(&x, " iRJT=%d", pExpr->w.iRightJoinTable);
|
||||
}
|
||||
if( ExprHasProperty(pExpr, EP_FromDDL) ){
|
||||
sqlite3_str_appendf(&x, " DDL");
|
||||
|
||||
+31
-28
@@ -446,6 +446,7 @@ static TriggerStep *triggerStepAllocate(
|
||||
sqlite3 *db = pParse->db;
|
||||
TriggerStep *pTriggerStep;
|
||||
|
||||
if( pParse->nErr ) return 0;
|
||||
pTriggerStep = sqlite3DbMallocZero(db, sizeof(TriggerStep) + pName->n + 1);
|
||||
if( pTriggerStep ){
|
||||
char *z = (char*)&pTriggerStep[1];
|
||||
@@ -918,6 +919,7 @@ static void codeReturningTrigger(
|
||||
|
||||
assert( v!=0 );
|
||||
assert( pParse->bReturning );
|
||||
assert( db->pParse==pParse );
|
||||
pReturning = pParse->u1.pReturning;
|
||||
assert( pTrigger == &(pReturning->retTrig) );
|
||||
memset(&sSelect, 0, sizeof(sSelect));
|
||||
@@ -928,7 +930,8 @@ static void codeReturningTrigger(
|
||||
sFrom.a[0].pTab = pTab;
|
||||
sFrom.a[0].iCursor = -1;
|
||||
sqlite3SelectPrep(pParse, &sSelect, 0);
|
||||
if( db->mallocFailed==0 && pParse->nErr==0 ){
|
||||
if( pParse->nErr==0 ){
|
||||
assert( db->mallocFailed==0 );
|
||||
sqlite3GenerateColumnNames(pParse, &sSelect);
|
||||
}
|
||||
sqlite3ExprListDelete(db, sSelect.pEList);
|
||||
@@ -946,7 +949,7 @@ static void codeReturningTrigger(
|
||||
pParse->eTriggerOp = pTrigger->op;
|
||||
pParse->pTriggerTab = pTab;
|
||||
if( sqlite3ResolveExprListNames(&sNC, pNew)==SQLITE_OK
|
||||
&& !db->mallocFailed
|
||||
&& ALWAYS(!db->mallocFailed)
|
||||
){
|
||||
int i;
|
||||
int nCol = pNew->nExpr;
|
||||
@@ -1110,8 +1113,8 @@ static TriggerPrg *codeRowTrigger(
|
||||
Vdbe *v; /* Temporary VM */
|
||||
NameContext sNC; /* Name context for sub-vdbe */
|
||||
SubProgram *pProgram = 0; /* Sub-vdbe for trigger program */
|
||||
Parse *pSubParse; /* Parse context for sub-vdbe */
|
||||
int iEndTrigger = 0; /* Label to jump to if WHEN is false */
|
||||
Parse sSubParse; /* Parse context for sub-vdbe */
|
||||
|
||||
assert( pTrigger->zName==0 || pTab==tableOfTrigger(pTrigger) );
|
||||
assert( pTop->pVdbe );
|
||||
@@ -1133,19 +1136,17 @@ static TriggerPrg *codeRowTrigger(
|
||||
|
||||
/* Allocate and populate a new Parse context to use for coding the
|
||||
** trigger sub-program. */
|
||||
pSubParse = sqlite3StackAllocZero(db, sizeof(Parse));
|
||||
if( !pSubParse ) return 0;
|
||||
sqlite3ParseObjectInit(&sSubParse, db);
|
||||
memset(&sNC, 0, sizeof(sNC));
|
||||
sNC.pParse = pSubParse;
|
||||
pSubParse->db = db;
|
||||
pSubParse->pTriggerTab = pTab;
|
||||
pSubParse->pToplevel = pTop;
|
||||
pSubParse->zAuthContext = pTrigger->zName;
|
||||
pSubParse->eTriggerOp = pTrigger->op;
|
||||
pSubParse->nQueryLoop = pParse->nQueryLoop;
|
||||
pSubParse->disableVtab = pParse->disableVtab;
|
||||
sNC.pParse = &sSubParse;
|
||||
sSubParse.pTriggerTab = pTab;
|
||||
sSubParse.pToplevel = pTop;
|
||||
sSubParse.zAuthContext = pTrigger->zName;
|
||||
sSubParse.eTriggerOp = pTrigger->op;
|
||||
sSubParse.nQueryLoop = pParse->nQueryLoop;
|
||||
sSubParse.disableVtab = pParse->disableVtab;
|
||||
|
||||
v = sqlite3GetVdbe(pSubParse);
|
||||
v = sqlite3GetVdbe(&sSubParse);
|
||||
if( v ){
|
||||
VdbeComment((v, "Start: %s.%s (%s %s%s%s ON %s)",
|
||||
pTrigger->zName, onErrorText(orconf),
|
||||
@@ -1171,14 +1172,14 @@ static TriggerPrg *codeRowTrigger(
|
||||
if( db->mallocFailed==0
|
||||
&& SQLITE_OK==sqlite3ResolveExprNames(&sNC, pWhen)
|
||||
){
|
||||
iEndTrigger = sqlite3VdbeMakeLabel(pSubParse);
|
||||
sqlite3ExprIfFalse(pSubParse, pWhen, iEndTrigger, SQLITE_JUMPIFNULL);
|
||||
iEndTrigger = sqlite3VdbeMakeLabel(&sSubParse);
|
||||
sqlite3ExprIfFalse(&sSubParse, pWhen, iEndTrigger, SQLITE_JUMPIFNULL);
|
||||
}
|
||||
sqlite3ExprDelete(db, pWhen);
|
||||
}
|
||||
|
||||
/* Code the trigger program into the sub-vdbe. */
|
||||
codeTriggerProgram(pSubParse, pTrigger->step_list, orconf);
|
||||
codeTriggerProgram(&sSubParse, pTrigger->step_list, orconf);
|
||||
|
||||
/* Insert an OP_Halt at the end of the sub-program. */
|
||||
if( iEndTrigger ){
|
||||
@@ -1186,23 +1187,24 @@ static TriggerPrg *codeRowTrigger(
|
||||
}
|
||||
sqlite3VdbeAddOp0(v, OP_Halt);
|
||||
VdbeComment((v, "End: %s.%s", pTrigger->zName, onErrorText(orconf)));
|
||||
transferParseError(pParse, &sSubParse);
|
||||
|
||||
transferParseError(pParse, pSubParse);
|
||||
if( db->mallocFailed==0 && pParse->nErr==0 ){
|
||||
if( pParse->nErr==0 ){
|
||||
assert( db->mallocFailed==0 );
|
||||
pProgram->aOp = sqlite3VdbeTakeOpArray(v, &pProgram->nOp, &pTop->nMaxArg);
|
||||
}
|
||||
pProgram->nMem = pSubParse->nMem;
|
||||
pProgram->nCsr = pSubParse->nTab;
|
||||
pProgram->nMem = sSubParse.nMem;
|
||||
pProgram->nCsr = sSubParse.nTab;
|
||||
pProgram->token = (void *)pTrigger;
|
||||
pPrg->aColmask[0] = pSubParse->oldmask;
|
||||
pPrg->aColmask[1] = pSubParse->newmask;
|
||||
pPrg->aColmask[0] = sSubParse.oldmask;
|
||||
pPrg->aColmask[1] = sSubParse.newmask;
|
||||
sqlite3VdbeDelete(v);
|
||||
}else{
|
||||
transferParseError(pParse, &sSubParse);
|
||||
}
|
||||
|
||||
assert( !pSubParse->pTriggerPrg && !pSubParse->nMaxArg );
|
||||
sqlite3ParserReset(pSubParse);
|
||||
sqlite3StackFree(db, pSubParse);
|
||||
|
||||
assert( !sSubParse.pTriggerPrg && !sSubParse.nMaxArg );
|
||||
sqlite3ParseObjectReset(&sSubParse);
|
||||
return pPrg;
|
||||
}
|
||||
|
||||
@@ -1235,6 +1237,7 @@ static TriggerPrg *getRowTrigger(
|
||||
/* If an existing TriggerPrg could not be located, create a new one. */
|
||||
if( !pPrg ){
|
||||
pPrg = codeRowTrigger(pParse, pTrigger, pTab, orconf);
|
||||
pParse->db->errByteOffset = -1;
|
||||
}
|
||||
|
||||
return pPrg;
|
||||
@@ -1257,7 +1260,7 @@ void sqlite3CodeRowTriggerDirect(
|
||||
Vdbe *v = sqlite3GetVdbe(pParse); /* Main VM */
|
||||
TriggerPrg *pPrg;
|
||||
pPrg = getRowTrigger(pParse, p, pTab, orconf);
|
||||
assert( pPrg || pParse->nErr || pParse->db->mallocFailed );
|
||||
assert( pPrg || pParse->nErr );
|
||||
|
||||
/* Code the OP_Program opcode in the parent VDBE. P4 of the OP_Program
|
||||
** is a pointer to the sub-vdbe containing the trigger program. */
|
||||
|
||||
+7
-3
@@ -347,9 +347,11 @@ void sqlite3Update(
|
||||
|
||||
memset(&sContext, 0, sizeof(sContext));
|
||||
db = pParse->db;
|
||||
if( pParse->nErr || db->mallocFailed ){
|
||||
assert( db->pParse==pParse );
|
||||
if( pParse->nErr ){
|
||||
goto update_cleanup;
|
||||
}
|
||||
assert( db->mallocFailed==0 );
|
||||
|
||||
/* Locate the table which we want to update.
|
||||
*/
|
||||
@@ -721,7 +723,7 @@ void sqlite3Update(
|
||||
if( !pParse->nested && !pTrigger && !hasFK && !chngKey && !bReplace ){
|
||||
flags |= WHERE_ONEPASS_MULTIROW;
|
||||
}
|
||||
pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0, 0, flags,iIdxCur);
|
||||
pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere,0,0,0,flags,iIdxCur);
|
||||
if( pWInfo==0 ) goto update_cleanup;
|
||||
|
||||
/* A one-pass strategy that might update more than one row may not
|
||||
@@ -1243,7 +1245,9 @@ static void updateVirtualTable(
|
||||
regRowid = ++pParse->nMem;
|
||||
|
||||
/* Start scanning the virtual table */
|
||||
pWInfo = sqlite3WhereBegin(pParse, pSrc,pWhere,0,0,WHERE_ONEPASS_DESIRED,0);
|
||||
pWInfo = sqlite3WhereBegin(
|
||||
pParse, pSrc, pWhere, 0, 0, 0, WHERE_ONEPASS_DESIRED, 0
|
||||
);
|
||||
if( pWInfo==0 ) return;
|
||||
|
||||
/* Populate the argument registers. */
|
||||
|
||||
@@ -189,6 +189,8 @@ void sqlite3ErrorMsg(Parse *pParse, const char *zFormat, ...){
|
||||
char *zMsg;
|
||||
va_list ap;
|
||||
sqlite3 *db = pParse->db;
|
||||
assert( db!=0 );
|
||||
assert( db->pParse==pParse );
|
||||
db->errByteOffset = -2;
|
||||
va_start(ap, zFormat);
|
||||
zMsg = sqlite3VMPrintf(db, zFormat, ap);
|
||||
@@ -196,6 +198,10 @@ void sqlite3ErrorMsg(Parse *pParse, const char *zFormat, ...){
|
||||
if( db->errByteOffset<-1 ) db->errByteOffset = -1;
|
||||
if( db->suppressErr ){
|
||||
sqlite3DbFree(db, zMsg);
|
||||
if( db->mallocFailed ){
|
||||
pParse->nErr++;
|
||||
pParse->rc = SQLITE_NOMEM;
|
||||
}
|
||||
}else{
|
||||
pParse->nErr++;
|
||||
sqlite3DbFree(db, pParse->zErrMsg);
|
||||
|
||||
+43
-3
@@ -2627,10 +2627,18 @@ case OP_Offset: { /* out3 */
|
||||
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
|
||||
pC = p->apCsr[pOp->p1];
|
||||
pOut = &p->aMem[pOp->p3];
|
||||
if( NEVER(pC==0) || pC->eCurType!=CURTYPE_BTREE ){
|
||||
if( pC==0 || pC->eCurType!=CURTYPE_BTREE ){
|
||||
sqlite3VdbeMemSetNull(pOut);
|
||||
}else{
|
||||
sqlite3VdbeMemSetInt64(pOut, sqlite3BtreeOffset(pC->uc.pCursor));
|
||||
if( pC->deferredMoveto ){
|
||||
rc = sqlite3VdbeFinishMoveto(pC);
|
||||
if( rc ) goto abort_due_to_error;
|
||||
}
|
||||
if( sqlite3BtreeEof(pC->uc.pCursor) ){
|
||||
sqlite3VdbeMemSetNull(pOut);
|
||||
}else{
|
||||
sqlite3VdbeMemSetInt64(pOut, sqlite3BtreeOffset(pC->uc.pCursor));
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -3243,7 +3251,7 @@ case OP_MakeRecord: {
|
||||
testcase( uu==127 ); testcase( uu==128 );
|
||||
testcase( uu==32767 ); testcase( uu==32768 );
|
||||
testcase( uu==8388607 ); testcase( uu==8388608 );
|
||||
testcase( uu==2147483647 ); testcase( uu==2147483648 );
|
||||
testcase( uu==2147483647 ); testcase( uu==2147483648LL );
|
||||
testcase( uu==140737488355327LL ); testcase( uu==140737488355328LL );
|
||||
if( uu<=127 ){
|
||||
if( (i&1)==i && file_format>=4 ){
|
||||
@@ -5709,6 +5717,10 @@ case OP_Rowid: { /* out2 */
|
||||
** Move the cursor P1 to a null row. Any OP_Column operations
|
||||
** that occur while the cursor is on the null row will always
|
||||
** write a NULL.
|
||||
**
|
||||
** Or, if P1 is a Pseudo-Cursor (a cursor opened using OP_OpenPseudo)
|
||||
** just reset the cache for that cursor. This causes the row of
|
||||
** content held by the pseudo-cursor to be reparsed.
|
||||
*/
|
||||
case OP_NullRow: {
|
||||
VdbeCursor *pC;
|
||||
@@ -7734,6 +7746,34 @@ case OP_VOpen: {
|
||||
}
|
||||
#endif /* SQLITE_OMIT_VIRTUALTABLE */
|
||||
|
||||
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
||||
/* Opcode: VInitIn P1 P2 P3 * *
|
||||
** Synopsis: r[P2]=ValueList(P1,P3)
|
||||
**
|
||||
** Set register P2 to be a pointer to a ValueList object for cursor P1
|
||||
** with cache register P3 and output register P3+1. This ValueList object
|
||||
** can be used as the first argument to sqlite3_vtab_in_first() and
|
||||
** sqlite3_vtab_in_next() to extract all of the values stored in the P1
|
||||
** cursor. Register P3 is used to hold the values returned by
|
||||
** sqlite3_vtab_in_first() and sqlite3_vtab_in_next().
|
||||
*/
|
||||
case OP_VInitIn: { /* out2 */
|
||||
VdbeCursor *pC; /* The cursor containing the RHS values */
|
||||
ValueList *pRhs; /* New ValueList object to put in reg[P2] */
|
||||
|
||||
pC = p->apCsr[pOp->p1];
|
||||
pRhs = sqlite3_malloc64( sizeof(*pRhs) );
|
||||
if( pRhs==0 ) goto no_mem;
|
||||
pRhs->pCsr = pC->uc.pCursor;
|
||||
pRhs->pOut = &aMem[pOp->p3];
|
||||
pOut = out2Prerelease(p, pOp);
|
||||
pOut->flags = MEM_Null;
|
||||
sqlite3VdbeMemSetPointer(pOut, pRhs, "ValueList", sqlite3_free);
|
||||
break;
|
||||
}
|
||||
#endif /* SQLITE_OMIT_VIRTUALTABLE */
|
||||
|
||||
|
||||
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
||||
/* Opcode: VFilter P1 P2 P3 P4 *
|
||||
** Synopsis: iplan=r[P3] zplan='P4'
|
||||
|
||||
@@ -482,6 +482,24 @@ struct PreUpdate {
|
||||
Index *pPk; /* PK index if pTab is WITHOUT ROWID */
|
||||
};
|
||||
|
||||
/*
|
||||
** An instance of this object is used to pass an vector of values into
|
||||
** OP_VFilter, the xFilter method of a virtual table. The vector is the
|
||||
** set of values on the right-hand side of an IN constraint.
|
||||
**
|
||||
** The value as passed into xFilter is an sqlite3_value with a "pointer"
|
||||
** type, such as is generated by sqlite3_result_pointer() and read by
|
||||
** sqlite3_value_pointer. Such values have MEM_Term|MEM_Subtype|MEM_Null
|
||||
** and a subtype of 'p'. The sqlite3_vtab_in_first() and _next() interfaces
|
||||
** know how to use this object to step through all the values in the
|
||||
** right operand of the IN constraint.
|
||||
*/
|
||||
typedef struct ValueList ValueList;
|
||||
struct ValueList {
|
||||
BtCursor *pCsr; /* An ephemeral table holding all values */
|
||||
sqlite3_value *pOut; /* Register to hold each decoded output value */
|
||||
};
|
||||
|
||||
/*
|
||||
** Function prototypes
|
||||
*/
|
||||
|
||||
+68
-1
@@ -846,6 +846,70 @@ int sqlite3_vtab_nochange(sqlite3_context *p){
|
||||
return sqlite3_value_nochange(p->pOut);
|
||||
}
|
||||
|
||||
/*
|
||||
** Implementation of sqlite3_vtab_in_first() (if bNext==0) and
|
||||
** sqlite3_vtab_in_next() (if bNext!=0).
|
||||
*/
|
||||
static int valueFromValueList(
|
||||
sqlite3_value *pVal, /* Pointer to the ValueList object */
|
||||
sqlite3_value **ppOut, /* Store the next value from the list here */
|
||||
int bNext /* 1 for _next(). 0 for _first() */
|
||||
){
|
||||
int rc;
|
||||
ValueList *pRhs;
|
||||
|
||||
*ppOut = 0;
|
||||
if( pVal==0 ) return SQLITE_MISUSE;
|
||||
pRhs = (ValueList*)sqlite3_value_pointer(pVal, "ValueList");
|
||||
if( pRhs==0 ) return SQLITE_MISUSE;
|
||||
if( bNext ){
|
||||
rc = sqlite3BtreeNext(pRhs->pCsr, 0);
|
||||
}else{
|
||||
int dummy = 0;
|
||||
rc = sqlite3BtreeFirst(pRhs->pCsr, &dummy);
|
||||
assert( rc==SQLITE_OK || sqlite3BtreeEof(pRhs->pCsr) );
|
||||
if( sqlite3BtreeEof(pRhs->pCsr) ) rc = SQLITE_DONE;
|
||||
}
|
||||
if( rc==SQLITE_OK ){
|
||||
u32 sz; /* Size of current row in bytes */
|
||||
Mem sMem; /* Raw content of current row */
|
||||
memset(&sMem, 0, sizeof(sMem));
|
||||
sz = sqlite3BtreePayloadSize(pRhs->pCsr);
|
||||
rc = sqlite3VdbeMemFromBtreeZeroOffset(pRhs->pCsr,(int)sz,&sMem);
|
||||
if( rc==SQLITE_OK ){
|
||||
u8 *zBuf = (u8*)sMem.z;
|
||||
u32 iSerial;
|
||||
sqlite3_value *pOut = pRhs->pOut;
|
||||
int iOff = 1 + getVarint32(&zBuf[1], iSerial);
|
||||
sqlite3VdbeSerialGet(&zBuf[iOff], iSerial, pOut);
|
||||
pOut->enc = ENC(pOut->db);
|
||||
if( (pOut->flags & MEM_Ephem)!=0 && sqlite3VdbeMemMakeWriteable(pOut) ){
|
||||
rc = SQLITE_NOMEM;
|
||||
}else{
|
||||
*ppOut = pOut;
|
||||
}
|
||||
}
|
||||
sqlite3VdbeMemRelease(&sMem);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
** Set the iterator value pVal to point to the first value in the set.
|
||||
** Set (*ppOut) to point to this value before returning.
|
||||
*/
|
||||
int sqlite3_vtab_in_first(sqlite3_value *pVal, sqlite3_value **ppOut){
|
||||
return valueFromValueList(pVal, ppOut, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
** Set the iterator value pVal to point to the next value in the set.
|
||||
** Set (*ppOut) to point to this value before returning.
|
||||
*/
|
||||
int sqlite3_vtab_in_next(sqlite3_value *pVal, sqlite3_value **ppOut){
|
||||
return valueFromValueList(pVal, ppOut, 1);
|
||||
}
|
||||
|
||||
/*
|
||||
** Return the current time for a statement. If the current time
|
||||
** is requested more than once within the same run of a single prepared
|
||||
@@ -1530,7 +1594,10 @@ int sqlite3_bind_value(sqlite3_stmt *pStmt, int i, const sqlite3_value *pValue){
|
||||
break;
|
||||
}
|
||||
case SQLITE_FLOAT: {
|
||||
rc = sqlite3_bind_double(pStmt, i, pValue->u.r);
|
||||
assert( pValue->flags & (MEM_Real|MEM_IntReal) );
|
||||
rc = sqlite3_bind_double(pStmt, i,
|
||||
(pValue->flags & MEM_Real) ? pValue->u.r : (double)pValue->u.i
|
||||
);
|
||||
break;
|
||||
}
|
||||
case SQLITE_BLOB: {
|
||||
|
||||
+2
-2
@@ -1378,8 +1378,7 @@ void sqlite3VdbeSetP4KeyInfo(Parse *pParse, Index *pIdx){
|
||||
*/
|
||||
static void vdbeVComment(Vdbe *p, const char *zFormat, va_list ap){
|
||||
assert( p->nOp>0 || p->aOp==0 );
|
||||
assert( p->aOp==0 || p->aOp[p->nOp-1].zComment==0 || p->db->mallocFailed
|
||||
|| p->pParse->nErr>0 );
|
||||
assert( p->aOp==0 || p->aOp[p->nOp-1].zComment==0 || p->pParse->nErr>0 );
|
||||
if( p->nOp ){
|
||||
assert( p->aOp );
|
||||
sqlite3DbFree(p->db, p->aOp[p->nOp-1].zComment);
|
||||
@@ -3250,6 +3249,7 @@ int sqlite3VdbeTransferError(Vdbe *p){
|
||||
sqlite3ValueSetNull(db->pErr);
|
||||
}
|
||||
db->errCode = rc;
|
||||
db->errByteOffset = -1;
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
+6
-5
@@ -152,10 +152,9 @@ int sqlite3_blob_open(
|
||||
sqlite3_mutex_enter(db->mutex);
|
||||
|
||||
pBlob = (Incrblob *)sqlite3DbMallocZero(db, sizeof(Incrblob));
|
||||
do {
|
||||
memset(&sParse, 0, sizeof(Parse));
|
||||
while(1){
|
||||
sqlite3ParseObjectInit(&sParse,db);
|
||||
if( !pBlob ) goto blob_open_out;
|
||||
sParse.db = db;
|
||||
sqlite3DbFree(db, zErr);
|
||||
zErr = 0;
|
||||
|
||||
@@ -332,7 +331,9 @@ int sqlite3_blob_open(
|
||||
goto blob_open_out;
|
||||
}
|
||||
rc = blobSeekToRow(pBlob, iRow, &zErr);
|
||||
} while( (++nAttempt)<SQLITE_MAX_SCHEMA_RETRY && rc==SQLITE_SCHEMA );
|
||||
if( (++nAttempt)>=SQLITE_MAX_SCHEMA_RETRY || rc!=SQLITE_SCHEMA ) break;
|
||||
sqlite3ParseObjectReset(&sParse);
|
||||
}
|
||||
|
||||
blob_open_out:
|
||||
if( rc==SQLITE_OK && db->mallocFailed==0 ){
|
||||
@@ -343,7 +344,7 @@ blob_open_out:
|
||||
}
|
||||
sqlite3ErrorWithMsg(db, rc, (zErr ? "%s" : 0), zErr);
|
||||
sqlite3DbFree(db, zErr);
|
||||
sqlite3ParserReset(&sParse);
|
||||
sqlite3ParseObjectReset(&sParse);
|
||||
rc = sqlite3ApiExit(db, rc);
|
||||
sqlite3_mutex_leave(db->mutex);
|
||||
return rc;
|
||||
|
||||
+2
-5
@@ -916,6 +916,7 @@ void sqlite3VdbeMemSetPointer(
|
||||
void (*xDestructor)(void*)
|
||||
){
|
||||
assert( pMem->flags==MEM_Null );
|
||||
vdbeMemClear(pMem);
|
||||
pMem->u.zPType = zPType ? zPType : "";
|
||||
pMem->z = pPtr;
|
||||
pMem->flags = MEM_Null|MEM_Dyn|MEM_Subtype|MEM_Term;
|
||||
@@ -1530,11 +1531,7 @@ static int valueFromExpr(
|
||||
|
||||
assert( pExpr!=0 );
|
||||
while( (op = pExpr->op)==TK_UPLUS || op==TK_SPAN ) pExpr = pExpr->pLeft;
|
||||
#if defined(SQLITE_ENABLE_STAT4)
|
||||
if( op==TK_REGISTER ) op = pExpr->op2;
|
||||
#else
|
||||
if( NEVER(op==TK_REGISTER) ) op = pExpr->op2;
|
||||
#endif
|
||||
|
||||
/* Compressed expressions only appear when parsing the DEFAULT clause
|
||||
** on a table column definition, and hence only when pCtx==0. This
|
||||
@@ -1649,7 +1646,7 @@ static int valueFromExpr(
|
||||
|
||||
no_mem:
|
||||
#ifdef SQLITE_ENABLE_STAT4
|
||||
if( pCtx==0 || pCtx->pParse->nErr==0 )
|
||||
if( pCtx==0 || NEVER(pCtx->pParse->nErr==0) )
|
||||
#endif
|
||||
sqlite3OomFault(db);
|
||||
sqlite3DbFree(db, zVal);
|
||||
|
||||
+3
-3
@@ -825,9 +825,9 @@ int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){
|
||||
pTab = pCtx->pTab;
|
||||
assert( IsVirtual(pTab) );
|
||||
|
||||
memset(&sParse, 0, sizeof(sParse));
|
||||
sqlite3ParseObjectInit(&sParse, db);
|
||||
sParse.eParseMode = PARSE_MODE_DECLARE_VTAB;
|
||||
sParse.db = db;
|
||||
sParse.disableTriggers = 1;
|
||||
/* We should never be able to reach this point while loading the
|
||||
** schema. Nevertheless, defend against that (turn off db->init.busy)
|
||||
** in case a bug arises. */
|
||||
@@ -881,7 +881,7 @@ int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){
|
||||
sqlite3VdbeFinalize(sParse.pVdbe);
|
||||
}
|
||||
sqlite3DeleteTable(db, sParse.pNewTable);
|
||||
sqlite3ParserReset(&sParse);
|
||||
sqlite3ParseObjectReset(&sParse);
|
||||
db->init.busy = initBusy;
|
||||
|
||||
assert( (rc&0xff)==rc );
|
||||
|
||||
+163
-19
@@ -33,6 +33,8 @@ struct HiddenIndexInfo {
|
||||
WhereClause *pWC; /* The Where clause being analyzed */
|
||||
Parse *pParse; /* The parsing context */
|
||||
int eDistinct; /* Value to return from sqlite3_vtab_distinct() */
|
||||
u32 mIn; /* Mask of terms that are <col> IN (...) */
|
||||
u32 mHandleIn; /* Terms that vtab will handle as <col> IN (...) */
|
||||
sqlite3_value *aRhs[1]; /* RHS values for constraints. MUST BE LAST
|
||||
** because extra space is allocated to hold up
|
||||
** to nTerm such values */
|
||||
@@ -1076,7 +1078,10 @@ static SQLITE_NOINLINE void sqlite3ConstructBloomFilter(
|
||||
pLoop->wsFlags &= ~WHERE_BLOOMFILTER;
|
||||
if( OptimizationDisabled(pParse->db, SQLITE_BloomPulldown) ) break;
|
||||
while( ++iLevel < pWInfo->nLevel ){
|
||||
const SrcItem *pTabItem;
|
||||
pLevel = &pWInfo->a[iLevel];
|
||||
pTabItem = &pWInfo->pTabList->a[pLevel->iFrom];
|
||||
if( pTabItem->fg.jointype & JT_LEFT ) continue;
|
||||
pLoop = pLevel->pWLoop;
|
||||
if( NEVER(pLoop==0) ) continue;
|
||||
if( pLoop->prereq & notReady ) continue;
|
||||
@@ -1143,6 +1148,7 @@ static sqlite3_index_info *allocateIndexInfo(
|
||||
testcase( pTerm->eOperator & WO_ALL );
|
||||
if( (pTerm->eOperator & ~(WO_EQUIV))==0 ) continue;
|
||||
if( pTerm->wtFlags & TERM_VNULL ) continue;
|
||||
|
||||
assert( (pTerm->eOperator & (WO_OR|WO_AND))==0 );
|
||||
assert( pTerm->u.x.leftColumn>=XN_ROWID );
|
||||
assert( pTerm->u.x.leftColumn<pTab->nCol );
|
||||
@@ -1204,7 +1210,7 @@ static sqlite3_index_info *allocateIndexInfo(
|
||||
/* No matches cause a break out of the loop */
|
||||
break;
|
||||
}
|
||||
if( i==n){
|
||||
if( i==n ){
|
||||
nOrderBy = n;
|
||||
if( (pWInfo->wctrlFlags & (WHERE_GROUPBY|WHERE_DISTINCTBY)) ){
|
||||
eDistinct = 1 + ((pWInfo->wctrlFlags & WHERE_DISTINCTBY)!=0);
|
||||
@@ -1232,13 +1238,19 @@ static sqlite3_index_info *allocateIndexInfo(
|
||||
pHidden->pWC = pWC;
|
||||
pHidden->pParse = pParse;
|
||||
pHidden->eDistinct = eDistinct;
|
||||
pHidden->mIn = 0;
|
||||
for(i=j=0, pTerm=pWC->a; i<pWC->nTerm; i++, pTerm++){
|
||||
u16 op;
|
||||
if( (pTerm->wtFlags & TERM_OK)==0 ) continue;
|
||||
pIdxCons[j].iColumn = pTerm->u.x.leftColumn;
|
||||
pIdxCons[j].iTermOffset = i;
|
||||
op = pTerm->eOperator & WO_ALL;
|
||||
if( op==WO_IN ) op = WO_EQ;
|
||||
if( op==WO_IN ){
|
||||
if( (pTerm->wtFlags & TERM_SLICE)==0 ){
|
||||
pHidden->mIn |= SMASKBIT32(j);
|
||||
}
|
||||
op = WO_EQ;
|
||||
}
|
||||
if( op==WO_AUX ){
|
||||
pIdxCons[j].op = pTerm->eMatchOp;
|
||||
}else if( op & (WO_ISNULL|WO_IS) ){
|
||||
@@ -1328,7 +1340,9 @@ static int vtabBestIndex(Parse *pParse, Table *pTab, sqlite3_index_info *p){
|
||||
int rc;
|
||||
|
||||
whereTraceIndexInfoInputs(p);
|
||||
pParse->db->nSchemaLock++;
|
||||
rc = pVtab->pModule->xBestIndex(pVtab, p);
|
||||
pParse->db->nSchemaLock--;
|
||||
whereTraceIndexInfoOutputs(p);
|
||||
|
||||
if( rc!=SQLITE_OK && rc!=SQLITE_CONSTRAINT ){
|
||||
@@ -2580,8 +2594,17 @@ static void whereLoopOutputAdjust(
|
||||
/* If there are extra terms in the WHERE clause not used by an index
|
||||
** that depend only on the table being scanned, and that will tend to
|
||||
** cause many rows to be omitted, then mark that table as
|
||||
** "self-culling". */
|
||||
pLoop->wsFlags |= WHERE_SELFCULL;
|
||||
** "self-culling".
|
||||
**
|
||||
** 2022-03-24: Self-culling only applies if either the extra terms
|
||||
** are straight comparison operators that are non-true with NULL
|
||||
** operand, or if the loop is not a LEFT JOIN.
|
||||
*/
|
||||
if( (pTerm->eOperator & 0x3f)!=0
|
||||
|| (pWC->pWInfo->pTabList->a[pLoop->iTab].fg.jointype & JT_LEFT)==0
|
||||
){
|
||||
pLoop->wsFlags |= WHERE_SELFCULL;
|
||||
}
|
||||
}
|
||||
if( pTerm->truthProb<=0 ){
|
||||
/* If a truth probability is specified using the likelihood() hints,
|
||||
@@ -3157,7 +3180,7 @@ static int whereUsablePartialIndex(
|
||||
for(i=0, pTerm=pWC->a; i<pWC->nTerm; i++, pTerm++){
|
||||
Expr *pExpr;
|
||||
pExpr = pTerm->pExpr;
|
||||
if( (!ExprHasProperty(pExpr, EP_FromJoin) || pExpr->iRightJoinTable==iTab)
|
||||
if( (!ExprHasProperty(pExpr, EP_FromJoin) || pExpr->w.iRightJoinTable==iTab)
|
||||
&& (isLeft==0 || ExprHasProperty(pExpr, EP_FromJoin))
|
||||
&& sqlite3ExprImpliesExpr(pParse, pExpr, pWhere, iTab)
|
||||
&& (pTerm->wtFlags & TERM_VNULL)==0
|
||||
@@ -3459,6 +3482,15 @@ static int whereLoopAddBtree(
|
||||
|
||||
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
||||
|
||||
/*
|
||||
** Return true if pTerm is a virtual table LIMIT or OFFSET term.
|
||||
*/
|
||||
static int isLimitTerm(WhereTerm *pTerm){
|
||||
assert( pTerm->eOperator==WO_AUX || pTerm->eMatchOp==0 );
|
||||
return pTerm->eMatchOp>=SQLITE_INDEX_CONSTRAINT_LIMIT
|
||||
&& pTerm->eMatchOp<=SQLITE_INDEX_CONSTRAINT_OFFSET;
|
||||
}
|
||||
|
||||
/*
|
||||
** Argument pIdxInfo is already populated with all constraints that may
|
||||
** be used by the virtual table identified by pBuilder->pNew->iTab. This
|
||||
@@ -3486,9 +3518,11 @@ static int whereLoopAddVirtualOne(
|
||||
u16 mExclude, /* Exclude terms using these operators */
|
||||
sqlite3_index_info *pIdxInfo, /* Populated object for xBestIndex */
|
||||
u16 mNoOmit, /* Do not omit these constraints */
|
||||
int *pbIn /* OUT: True if plan uses an IN(...) op */
|
||||
int *pbIn, /* OUT: True if plan uses an IN(...) op */
|
||||
int *pbRetryLimit /* OUT: Retry without LIMIT/OFFSET */
|
||||
){
|
||||
WhereClause *pWC = pBuilder->pWC;
|
||||
HiddenIndexInfo *pHidden = (HiddenIndexInfo*)&pIdxInfo[1];
|
||||
struct sqlite3_index_constraint *pIdxCons;
|
||||
struct sqlite3_index_constraint_usage *pUsage = pIdxInfo->aConstraintUsage;
|
||||
int i;
|
||||
@@ -3511,6 +3545,7 @@ static int whereLoopAddVirtualOne(
|
||||
pIdxCons->usable = 0;
|
||||
if( (pTerm->prereqRight & mUsable)==pTerm->prereqRight
|
||||
&& (pTerm->eOperator & mExclude)==0
|
||||
&& (pbRetryLimit || !isLimitTerm(pTerm))
|
||||
){
|
||||
pIdxCons->usable = 1;
|
||||
}
|
||||
@@ -3526,6 +3561,7 @@ static int whereLoopAddVirtualOne(
|
||||
pIdxInfo->estimatedRows = 25;
|
||||
pIdxInfo->idxFlags = 0;
|
||||
pIdxInfo->colUsed = (sqlite3_int64)pSrc->colUsed;
|
||||
pHidden->mHandleIn = 0;
|
||||
|
||||
/* Invoke the virtual table xBestIndex() method */
|
||||
rc = vtabBestIndex(pParse, pSrc->pTab, pIdxInfo);
|
||||
@@ -3543,8 +3579,8 @@ static int whereLoopAddVirtualOne(
|
||||
|
||||
mxTerm = -1;
|
||||
assert( pNew->nLSlot>=nConstraint );
|
||||
for(i=0; i<nConstraint; i++) pNew->aLTerm[i] = 0;
|
||||
pNew->u.vtab.omitMask = 0;
|
||||
memset(pNew->aLTerm, 0, sizeof(pNew->aLTerm[0])*nConstraint );
|
||||
memset(&pNew->u.vtab, 0, sizeof(pNew->u.vtab));
|
||||
pIdxCons = *(struct sqlite3_index_constraint**)&pIdxInfo->aConstraint;
|
||||
for(i=0; i<nConstraint; i++, pIdxCons++){
|
||||
int iTerm;
|
||||
@@ -3578,8 +3614,13 @@ static int whereLoopAddVirtualOne(
|
||||
}else{
|
||||
testcase( i!=iTerm );
|
||||
}
|
||||
if( pTerm->eMatchOp==SQLITE_INDEX_CONSTRAINT_OFFSET ){
|
||||
pNew->u.vtab.bOmitOffset = 1;
|
||||
}
|
||||
}
|
||||
if( (pTerm->eOperator & WO_IN)!=0 ){
|
||||
if( SMASKBIT32(i) & pHidden->mHandleIn ){
|
||||
pNew->u.vtab.mHandleIn |= MASKBIT32(iTerm);
|
||||
}else if( (pTerm->eOperator & WO_IN)!=0 ){
|
||||
/* A virtual table that is constrained by an IN clause may not
|
||||
** consume the ORDER BY clause because (1) the order of IN terms
|
||||
** is not necessarily related to the order of output terms and
|
||||
@@ -3589,6 +3630,21 @@ static int whereLoopAddVirtualOne(
|
||||
pIdxInfo->idxFlags &= ~SQLITE_INDEX_SCAN_UNIQUE;
|
||||
*pbIn = 1; assert( (mExclude & WO_IN)==0 );
|
||||
}
|
||||
|
||||
if( isLimitTerm(pTerm) && *pbIn ){
|
||||
/* 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. */
|
||||
if( pIdxInfo->needToFreeIdxStr ){
|
||||
sqlite3_free(pIdxInfo->idxStr);
|
||||
pIdxInfo->idxStr = 0;
|
||||
pIdxInfo->needToFreeIdxStr = 0;
|
||||
}
|
||||
*pbRetryLimit = 1;
|
||||
return SQLITE_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3662,6 +3718,25 @@ const char *sqlite3_vtab_collation(sqlite3_index_info *pIdxInfo, int iCons){
|
||||
return zRet;
|
||||
}
|
||||
|
||||
/*
|
||||
** Return true if constraint iCons is really an IN(...) constraint, or
|
||||
** false otherwise. If iCons is an IN(...) constraint, set (if bHandle!=0)
|
||||
** or clear (if bHandle==0) the flag to handle it using an iterator.
|
||||
*/
|
||||
int sqlite3_vtab_in(sqlite3_index_info *pIdxInfo, int iCons, int bHandle){
|
||||
HiddenIndexInfo *pHidden = (HiddenIndexInfo*)&pIdxInfo[1];
|
||||
u32 m = SMASKBIT32(iCons);
|
||||
if( m & pHidden->mIn ){
|
||||
if( bHandle==0 ){
|
||||
pHidden->mHandleIn &= ~m;
|
||||
}else if( bHandle>0 ){
|
||||
pHidden->mHandleIn |= m;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
** This interface is callable from within the xBestIndex callback only.
|
||||
**
|
||||
@@ -3698,7 +3773,6 @@ int sqlite3_vtab_rhs_value(
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Return true if ORDER BY clause may be handled as DISTINCT.
|
||||
*/
|
||||
@@ -3710,6 +3784,22 @@ int sqlite3_vtab_distinct(sqlite3_index_info *pIdxInfo){
|
||||
return pHidden->eDistinct;
|
||||
}
|
||||
|
||||
#if (defined(SQLITE_ENABLE_DBPAGE_VTAB) || defined(SQLITE_TEST)) \
|
||||
&& !defined(SQLITE_OMIT_VIRTUALTABLE)
|
||||
/*
|
||||
** Cause the prepared statement that is associated with a call to
|
||||
** xBestIndex to open write transactions on all attached schemas.
|
||||
** This is used by the (built-in) sqlite_dbpage virtual table.
|
||||
*/
|
||||
void sqlite3VtabWriteAll(sqlite3_index_info *pIdxInfo){
|
||||
HiddenIndexInfo *pHidden = (HiddenIndexInfo*)&pIdxInfo[1];
|
||||
Parse *pParse = pHidden->pParse;
|
||||
int nDb = pParse->db->nDb;
|
||||
int i;
|
||||
for(i=0; i<nDb; i++) sqlite3BeginWriteOperation(pParse, 0, i);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Add all WhereLoop objects for a table of the join identified by
|
||||
** pBuilder->pNew->iTab. That table is guaranteed to be a virtual table.
|
||||
@@ -3751,6 +3841,7 @@ static int whereLoopAddVirtual(
|
||||
WhereLoop *pNew;
|
||||
Bitmask mBest; /* Tables used by best possible plan */
|
||||
u16 mNoOmit;
|
||||
int bRetry = 0; /* True to retry with LIMIT/OFFSET disabled */
|
||||
|
||||
assert( (mPrereq & mUnusable)==0 );
|
||||
pWInfo = pBuilder->pWInfo;
|
||||
@@ -3774,7 +3865,15 @@ static int whereLoopAddVirtual(
|
||||
/* First call xBestIndex() with all constraints usable. */
|
||||
WHERETRACE(0x800, ("BEGIN %s.addVirtual()\n", pSrc->pTab->zName));
|
||||
WHERETRACE(0x40, (" VirtualOne: all usable\n"));
|
||||
rc = whereLoopAddVirtualOne(pBuilder, mPrereq, ALLBITS, 0, p, mNoOmit, &bIn);
|
||||
rc = whereLoopAddVirtualOne(
|
||||
pBuilder, mPrereq, ALLBITS, 0, p, mNoOmit, &bIn, &bRetry
|
||||
);
|
||||
if( bRetry ){
|
||||
assert( rc==SQLITE_OK );
|
||||
rc = whereLoopAddVirtualOne(
|
||||
pBuilder, mPrereq, ALLBITS, 0, p, mNoOmit, &bIn, 0
|
||||
);
|
||||
}
|
||||
|
||||
/* If the call to xBestIndex() with all terms enabled produced a plan
|
||||
** that does not require any source tables (IOW: a plan with mBest==0)
|
||||
@@ -3792,7 +3891,7 @@ static int whereLoopAddVirtual(
|
||||
if( bIn ){
|
||||
WHERETRACE(0x40, (" VirtualOne: all usable w/o IN\n"));
|
||||
rc = whereLoopAddVirtualOne(
|
||||
pBuilder, mPrereq, ALLBITS, WO_IN, p, mNoOmit, &bIn);
|
||||
pBuilder, mPrereq, ALLBITS, WO_IN, p, mNoOmit, &bIn, 0);
|
||||
assert( bIn==0 );
|
||||
mBestNoIn = pNew->prereq & ~mPrereq;
|
||||
if( mBestNoIn==0 ){
|
||||
@@ -3819,7 +3918,7 @@ static int whereLoopAddVirtual(
|
||||
WHERETRACE(0x40, (" VirtualOne: mPrev=%04llx mNext=%04llx\n",
|
||||
(sqlite3_uint64)mPrev, (sqlite3_uint64)mNext));
|
||||
rc = whereLoopAddVirtualOne(
|
||||
pBuilder, mPrereq, mNext|mPrereq, 0, p, mNoOmit, &bIn);
|
||||
pBuilder, mPrereq, mNext|mPrereq, 0, p, mNoOmit, &bIn, 0);
|
||||
if( pNew->prereq==mPrereq ){
|
||||
seenZero = 1;
|
||||
if( bIn==0 ) seenZeroNoIN = 1;
|
||||
@@ -3832,7 +3931,7 @@ static int whereLoopAddVirtual(
|
||||
if( rc==SQLITE_OK && seenZero==0 ){
|
||||
WHERETRACE(0x40, (" VirtualOne: all disabled\n"));
|
||||
rc = whereLoopAddVirtualOne(
|
||||
pBuilder, mPrereq, mPrereq, 0, p, mNoOmit, &bIn);
|
||||
pBuilder, mPrereq, mPrereq, 0, p, mNoOmit, &bIn, 0);
|
||||
if( bIn==0 ) seenZeroNoIN = 1;
|
||||
}
|
||||
|
||||
@@ -3842,7 +3941,7 @@ static int whereLoopAddVirtual(
|
||||
if( rc==SQLITE_OK && seenZeroNoIN==0 ){
|
||||
WHERETRACE(0x40, (" VirtualOne: all disabled and w/o IN\n"));
|
||||
rc = whereLoopAddVirtualOne(
|
||||
pBuilder, mPrereq, mPrereq, WO_IN, p, mNoOmit, &bIn);
|
||||
pBuilder, mPrereq, mPrereq, WO_IN, p, mNoOmit, &bIn, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5076,7 +5175,7 @@ static SQLITE_NOINLINE Bitmask whereOmitNoopJoin(
|
||||
for(pTerm=pWInfo->sWC.a; pTerm<pEnd; pTerm++){
|
||||
if( (pTerm->prereqAll & pLoop->maskSelf)!=0 ){
|
||||
if( !ExprHasProperty(pTerm->pExpr, EP_FromJoin)
|
||||
|| pTerm->pExpr->iRightJoinTable!=pItem->iCursor
|
||||
|| pTerm->pExpr->w.iRightJoinTable!=pItem->iCursor
|
||||
){
|
||||
break;
|
||||
}
|
||||
@@ -5248,6 +5347,7 @@ WhereInfo *sqlite3WhereBegin(
|
||||
Expr *pWhere, /* The WHERE clause */
|
||||
ExprList *pOrderBy, /* An ORDER BY (or GROUP BY) clause, or NULL */
|
||||
ExprList *pResultSet, /* Query result set. Req'd for DISTINCT */
|
||||
Select *pLimit, /* Use this LIMIT/OFFSET clause, if any */
|
||||
u16 wctrlFlags, /* The WHERE_* flags defined in sqliteInt.h */
|
||||
int iAuxArg /* If WHERE_OR_SUBCLAUSE is set, index cursor number
|
||||
** If WHERE_USE_LIMIT, then the limit amount */
|
||||
@@ -5324,6 +5424,9 @@ WhereInfo *sqlite3WhereBegin(
|
||||
pWInfo->wctrlFlags = wctrlFlags;
|
||||
pWInfo->iLimit = iAuxArg;
|
||||
pWInfo->savedNQueryLoop = pParse->nQueryLoop;
|
||||
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
||||
pWInfo->pLimit = pLimit;
|
||||
#endif
|
||||
memset(&pWInfo->nOBSat, 0,
|
||||
offsetof(WhereInfo,sWC) - offsetof(WhereInfo,nOBSat));
|
||||
memset(&pWInfo->a[0], 0, sizeof(WhereLoop)+nTabList*sizeof(WhereLevel));
|
||||
@@ -5392,6 +5495,7 @@ WhereInfo *sqlite3WhereBegin(
|
||||
|
||||
/* Analyze all of the subexpressions. */
|
||||
sqlite3WhereExprAnalyze(pTabList, &pWInfo->sWC);
|
||||
sqlite3WhereAddLimit(&pWInfo->sWC, pLimit);
|
||||
if( db->mallocFailed ) goto whereBeginError;
|
||||
|
||||
/* Special case: WHERE terms that do not refer to any tables in the join
|
||||
@@ -5491,9 +5595,10 @@ WhereInfo *sqlite3WhereBegin(
|
||||
if( pWInfo->pOrderBy==0 && (db->flags & SQLITE_ReverseOrder)!=0 ){
|
||||
pWInfo->revMask = ALLBITS;
|
||||
}
|
||||
if( pParse->nErr || db->mallocFailed ){
|
||||
if( pParse->nErr ){
|
||||
goto whereBeginError;
|
||||
}
|
||||
assert( db->mallocFailed==0 );
|
||||
#ifdef WHERETRACE_ENABLED
|
||||
if( sqlite3WhereTrace ){
|
||||
sqlite3DebugPrintf("---- Solution nRow=%d", pWInfo->nRowOut);
|
||||
@@ -5637,6 +5742,7 @@ WhereInfo *sqlite3WhereBegin(
|
||||
if( pWInfo->eOnePass==ONEPASS_OFF
|
||||
&& pTab->nCol<BMS
|
||||
&& (pTab->tabFlags & (TF_HasGenerated|TF_WithoutRowid))==0
|
||||
&& (pLoop->wsFlags & (WHERE_AUTO_INDEX|WHERE_BLOOMFILTER))==0
|
||||
){
|
||||
/* If we know that only a prefix of the record will be used,
|
||||
** it is advantageous to reduce the "column count" field in
|
||||
@@ -5797,6 +5903,26 @@ whereBeginError:
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SQLITE_DEBUG
|
||||
/*
|
||||
** Return true if cursor iCur is opened by instruction k of the
|
||||
** bytecode. Used inside of assert() only.
|
||||
*/
|
||||
static int cursorIsOpen(Vdbe *v, int iCur, int k){
|
||||
while( k>=0 ){
|
||||
VdbeOp *pOp = sqlite3VdbeGetOp(v,k--);
|
||||
if( pOp->p1!=iCur ) continue;
|
||||
if( pOp->opcode==OP_Close ) return 0;
|
||||
if( pOp->opcode==OP_OpenRead ) return 1;
|
||||
if( pOp->opcode==OP_OpenWrite ) return 1;
|
||||
if( pOp->opcode==OP_OpenDup ) return 1;
|
||||
if( pOp->opcode==OP_OpenAutoindex ) return 1;
|
||||
if( pOp->opcode==OP_OpenEphemeral ) return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif /* SQLITE_DEBUG */
|
||||
|
||||
/*
|
||||
** Generate the end of the WHERE loop. See comments on
|
||||
** sqlite3WhereBegin() for additional information.
|
||||
@@ -6049,6 +6175,11 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){
|
||||
){
|
||||
int x = pOp->p2;
|
||||
assert( pIdx->pTable==pTab );
|
||||
#ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC
|
||||
if( pOp->opcode==OP_Offset ){
|
||||
/* Do not need to translate the column number */
|
||||
}else
|
||||
#endif
|
||||
if( !HasRowid(pTab) ){
|
||||
Index *pPk = sqlite3PrimaryKeyIndex(pTab);
|
||||
x = pPk->aiColumn[x];
|
||||
@@ -6062,9 +6193,22 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){
|
||||
pOp->p2 = x;
|
||||
pOp->p1 = pLevel->iIdxCur;
|
||||
OpcodeRewriteTrace(db, k, pOp);
|
||||
}else{
|
||||
/* Unable to translate the table reference into an index
|
||||
** reference. Verify that this is harmless - that the
|
||||
** table being referenced really is open.
|
||||
*/
|
||||
#ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC
|
||||
assert( (pLoop->wsFlags & WHERE_IDX_ONLY)==0
|
||||
|| cursorIsOpen(v,pOp->p1,k)
|
||||
|| pOp->opcode==OP_Offset
|
||||
);
|
||||
#else
|
||||
assert( (pLoop->wsFlags & WHERE_IDX_ONLY)==0
|
||||
|| cursorIsOpen(v,pOp->p1,k)
|
||||
);
|
||||
#endif
|
||||
}
|
||||
assert( (pLoop->wsFlags & WHERE_IDX_ONLY)==0 || x>=0
|
||||
|| pWInfo->eOnePass );
|
||||
}else if( pOp->opcode==OP_Rowid ){
|
||||
pOp->p1 = pLevel->iIdxCur;
|
||||
pOp->opcode = OP_IdxRowid;
|
||||
|
||||
+9
-1
@@ -123,10 +123,12 @@ struct WhereLoop {
|
||||
} btree;
|
||||
struct { /* Information for virtual tables */
|
||||
int idxNum; /* Index number */
|
||||
u8 needFree; /* True if sqlite3_free(idxStr) is needed */
|
||||
u32 needFree : 1; /* True if sqlite3_free(idxStr) is needed */
|
||||
u32 bOmitOffset : 1; /* True to let virtual table handle offset */
|
||||
i8 isOrdered; /* True if satisfies ORDER BY */
|
||||
u16 omitMask; /* Terms that may be omitted */
|
||||
char *idxStr; /* Index identifier string */
|
||||
u32 mHandleIn; /* Terms to handle as IN(...) instead of == */
|
||||
} vtab;
|
||||
} u;
|
||||
u32 wsFlags; /* WHERE_* flags describing the plan */
|
||||
@@ -283,6 +285,7 @@ struct WhereTerm {
|
||||
#else
|
||||
# define TERM_HIGHTRUTH 0 /* Only used with STAT4 */
|
||||
#endif
|
||||
#define TERM_SLICE 0x8000 /* One slice of a row-value/vector comparison */
|
||||
|
||||
/*
|
||||
** An instance of the WhereScan object is used as an iterator for locating
|
||||
@@ -453,6 +456,9 @@ struct WhereInfo {
|
||||
ExprList *pOrderBy; /* The ORDER BY clause or NULL */
|
||||
ExprList *pResultSet; /* Result set of the query */
|
||||
Expr *pWhere; /* The complete WHERE clause */
|
||||
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
||||
Select *pLimit; /* Used to access LIMIT expr/registers for vtabs */
|
||||
#endif
|
||||
int aiCurOnePass[2]; /* OP_OpenWrite cursors for the ONEPASS opt */
|
||||
int iContinue; /* Jump here to continue with next record */
|
||||
int iBreak; /* Jump here to break out of the loop */
|
||||
@@ -538,6 +544,7 @@ Bitmask sqlite3WhereCodeOneLoopStart(
|
||||
void sqlite3WhereClauseInit(WhereClause*,WhereInfo*);
|
||||
void sqlite3WhereClauseClear(WhereClause*);
|
||||
void sqlite3WhereSplit(WhereClause*,Expr*,u8);
|
||||
void sqlite3WhereAddLimit(WhereClause*, Select*);
|
||||
Bitmask sqlite3WhereExprUsage(WhereMaskSet*, Expr*);
|
||||
Bitmask sqlite3WhereExprUsageNN(WhereMaskSet*, Expr*);
|
||||
Bitmask sqlite3WhereExprListUsage(WhereMaskSet*, ExprList*);
|
||||
@@ -608,5 +615,6 @@ void sqlite3WhereTabFuncArgs(Parse*, SrcItem*, WhereClause*);
|
||||
#define WHERE_TRANSCONS 0x00200000 /* Uses a transitive constraint */
|
||||
#define WHERE_BLOOMFILTER 0x00400000 /* Consider using a Bloom-filter */
|
||||
#define WHERE_SELFCULL 0x00800000 /* nOut reduced by extra WHERE terms */
|
||||
#define WHERE_OMIT_OFFSET 0x01000000 /* Set offset counter to zero */
|
||||
|
||||
#endif /* !defined(SQLITE_WHEREINT_H) */
|
||||
|
||||
+79
-34
@@ -792,6 +792,7 @@ static int codeAllEqualityTerms(
|
||||
VdbeCoverageIf(v, bRev!=0);
|
||||
VdbeComment((v, "begin skip-scan on %s", pIdx->zName));
|
||||
j = sqlite3VdbeAddOp0(v, OP_Goto);
|
||||
assert( pLevel->addrSkip==0 );
|
||||
pLevel->addrSkip = sqlite3VdbeAddOp4Int(v, (bRev?OP_SeekLT:OP_SeekGT),
|
||||
iIdxCur, 0, regBase, nSkip);
|
||||
VdbeCoverageIf(v, bRev==0);
|
||||
@@ -841,7 +842,8 @@ static int codeAllEqualityTerms(
|
||||
sqlite3VdbeAddOp2(v, OP_IsNull, regBase+j, pLevel->addrBrk);
|
||||
VdbeCoverage(v);
|
||||
}
|
||||
if( pParse->db->mallocFailed==0 && pParse->nErr==0 ){
|
||||
if( pParse->nErr==0 ){
|
||||
assert( pParse->db->mallocFailed==0 );
|
||||
if( sqlite3CompareAffinity(pRight, zAff[j])==SQLITE_AFF_BLOB ){
|
||||
zAff[j] = SQLITE_AFF_BLOB;
|
||||
}
|
||||
@@ -1061,7 +1063,7 @@ static void codeCursorHint(
|
||||
if( pTabItem->fg.jointype & JT_LEFT ){
|
||||
Expr *pExpr = pTerm->pExpr;
|
||||
if( !ExprHasProperty(pExpr, EP_FromJoin)
|
||||
|| pExpr->iRightJoinTable!=pTabItem->iCursor
|
||||
|| pExpr->w.iRightJoinTable!=pTabItem->iCursor
|
||||
){
|
||||
sWalker.eCode = 0;
|
||||
sWalker.xExprCallback = codeCursorHintIsOrFunction;
|
||||
@@ -1388,6 +1390,7 @@ static SQLITE_NOINLINE void filterPullDown(
|
||||
WhereLevel *pLevel = &pWInfo->a[iLevel];
|
||||
WhereLoop *pLoop = pLevel->pWLoop;
|
||||
if( pLevel->regFilter==0 ) continue;
|
||||
if( pLevel->pWLoop->nSkip ) continue;
|
||||
/* ,--- Because sqlite3ConstructBloomFilter() has will not have set
|
||||
** vvvvv--' pLevel->regFilter if this were true. */
|
||||
if( NEVER(pLoop->prereq & notReady) ) continue;
|
||||
@@ -1522,7 +1525,6 @@ Bitmask sqlite3WhereCodeOneLoopStart(
|
||||
int iReg; /* P3 Value for OP_VFilter */
|
||||
int addrNotFound;
|
||||
int nConstraint = pLoop->nLTerm;
|
||||
int iIn; /* Counter for IN constraints */
|
||||
|
||||
iReg = sqlite3GetTempRange(pParse, nConstraint+2);
|
||||
addrNotFound = pLevel->addrBrk;
|
||||
@@ -1531,11 +1533,27 @@ Bitmask sqlite3WhereCodeOneLoopStart(
|
||||
pTerm = pLoop->aLTerm[j];
|
||||
if( NEVER(pTerm==0) ) continue;
|
||||
if( pTerm->eOperator & WO_IN ){
|
||||
codeEqualityTerm(pParse, pTerm, pLevel, j, bRev, iTarget);
|
||||
addrNotFound = pLevel->addrNxt;
|
||||
if( SMASKBIT32(j) & pLoop->u.vtab.mHandleIn ){
|
||||
int iTab = pParse->nTab++;
|
||||
int iCache = ++pParse->nMem;
|
||||
sqlite3CodeRhsOfIN(pParse, pTerm->pExpr, iTab);
|
||||
sqlite3VdbeAddOp3(v, OP_VInitIn, iTab, iTarget, iCache);
|
||||
}else{
|
||||
codeEqualityTerm(pParse, pTerm, pLevel, j, bRev, iTarget);
|
||||
addrNotFound = pLevel->addrNxt;
|
||||
}
|
||||
}else{
|
||||
Expr *pRight = pTerm->pExpr->pRight;
|
||||
codeExprOrVector(pParse, pRight, iTarget, 1);
|
||||
if( pTerm->eMatchOp==SQLITE_INDEX_CONSTRAINT_OFFSET
|
||||
&& pLoop->u.vtab.bOmitOffset
|
||||
){
|
||||
assert( pTerm->eOperator==WO_AUX );
|
||||
assert( pWInfo->pLimit!=0 );
|
||||
assert( pWInfo->pLimit->iOffset>0 );
|
||||
sqlite3VdbeAddOp2(v, OP_Integer, 0, pWInfo->pLimit->iOffset);
|
||||
VdbeComment((v,"Zero OFFSET counter"));
|
||||
}
|
||||
}
|
||||
}
|
||||
sqlite3VdbeAddOp2(v, OP_Integer, pLoop->u.vtab.idxNum, iReg);
|
||||
@@ -1552,44 +1570,54 @@ Bitmask sqlite3WhereCodeOneLoopStart(
|
||||
pLevel->op = pWInfo->eOnePass ? OP_Noop : OP_VNext;
|
||||
pLevel->p2 = sqlite3VdbeCurrentAddr(v);
|
||||
assert( (pLoop->wsFlags & WHERE_MULTI_OR)==0 );
|
||||
if( pLoop->wsFlags & WHERE_IN_ABLE ){
|
||||
iIn = pLevel->u.in.nIn;
|
||||
}else{
|
||||
iIn = 0;
|
||||
}
|
||||
for(j=nConstraint-1; j>=0; j--){
|
||||
|
||||
for(j=0; j<nConstraint; j++){
|
||||
pTerm = pLoop->aLTerm[j];
|
||||
if( (pTerm->eOperator & WO_IN)!=0 ) iIn--;
|
||||
if( j<16 && (pLoop->u.vtab.omitMask>>j)&1 ){
|
||||
disableTerm(pLevel, pTerm);
|
||||
}else if( (pTerm->eOperator & WO_IN)!=0
|
||||
&& sqlite3ExprVectorSize(pTerm->pExpr->pLeft)==1
|
||||
continue;
|
||||
}
|
||||
if( (pTerm->eOperator & WO_IN)!=0
|
||||
&& (SMASKBIT32(j) & pLoop->u.vtab.mHandleIn)==0
|
||||
&& !db->mallocFailed
|
||||
){
|
||||
Expr *pCompare; /* The comparison operator */
|
||||
Expr *pRight; /* RHS of the comparison */
|
||||
VdbeOp *pOp; /* Opcode to access the value of the IN constraint */
|
||||
int iIn; /* IN loop corresponding to the j-th constraint */
|
||||
|
||||
/* Reload the constraint value into reg[iReg+j+2]. The same value
|
||||
** was loaded into the same register prior to the OP_VFilter, but
|
||||
** the xFilter implementation might have changed the datatype or
|
||||
** encoding of the value in the register, so it *must* be reloaded. */
|
||||
assert( pLevel->u.in.aInLoop!=0 || db->mallocFailed );
|
||||
if( !db->mallocFailed ){
|
||||
assert( iIn>=0 && iIn<pLevel->u.in.nIn );
|
||||
** encoding of the value in the register, so it *must* be reloaded.
|
||||
*/
|
||||
for(iIn=0; ALWAYS(iIn<pLevel->u.in.nIn); iIn++){
|
||||
pOp = sqlite3VdbeGetOp(v, pLevel->u.in.aInLoop[iIn].addrInTop);
|
||||
assert( pOp->opcode==OP_Column || pOp->opcode==OP_Rowid );
|
||||
assert( pOp->opcode!=OP_Column || pOp->p3==iReg+j+2 );
|
||||
assert( pOp->opcode!=OP_Rowid || pOp->p2==iReg+j+2 );
|
||||
testcase( pOp->opcode==OP_Rowid );
|
||||
sqlite3VdbeAddOp3(v, pOp->opcode, pOp->p1, pOp->p2, pOp->p3);
|
||||
if( (pOp->opcode==OP_Column && pOp->p3==iReg+j+2)
|
||||
|| (pOp->opcode==OP_Rowid && pOp->p2==iReg+j+2)
|
||||
){
|
||||
testcase( pOp->opcode==OP_Rowid );
|
||||
sqlite3VdbeAddOp3(v, pOp->opcode, pOp->p1, pOp->p2, pOp->p3);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Generate code that will continue to the next row if
|
||||
** the IN constraint is not satisfied */
|
||||
** the IN constraint is not satisfied
|
||||
*/
|
||||
pCompare = sqlite3PExpr(pParse, TK_EQ, 0, 0);
|
||||
assert( pCompare!=0 || db->mallocFailed );
|
||||
if( pCompare ){
|
||||
pCompare->pLeft = pTerm->pExpr->pLeft;
|
||||
if( !db->mallocFailed ){
|
||||
int iFld = pTerm->u.x.iField;
|
||||
Expr *pLeft = pTerm->pExpr->pLeft;
|
||||
assert( pLeft!=0 );
|
||||
if( iFld>0 ){
|
||||
assert( pLeft->op==TK_VECTOR );
|
||||
assert( ExprUseXList(pLeft) );
|
||||
assert( iFld<=pLeft->x.pList->nExpr );
|
||||
pCompare->pLeft = pLeft->x.pList->a[iFld-1].pExpr;
|
||||
}else{
|
||||
pCompare->pLeft = pLeft;
|
||||
}
|
||||
pCompare->pRight = pRight = sqlite3Expr(db, TK_REGISTER, 0);
|
||||
if( pRight ){
|
||||
pRight->iTable = iReg+j+2;
|
||||
@@ -1598,11 +1626,11 @@ Bitmask sqlite3WhereCodeOneLoopStart(
|
||||
);
|
||||
}
|
||||
pCompare->pLeft = 0;
|
||||
sqlite3ExprDelete(db, pCompare);
|
||||
}
|
||||
sqlite3ExprDelete(db, pCompare);
|
||||
}
|
||||
}
|
||||
assert( iIn==0 || db->mallocFailed );
|
||||
|
||||
/* These registers need to be preserved in case there is an IN operator
|
||||
** loop. So we could deallocate the registers here (and potentially
|
||||
** reuse them later) if (pLoop->wsFlags & WHERE_IN_ABLE)==0. But it seems
|
||||
@@ -2294,7 +2322,7 @@ Bitmask sqlite3WhereCodeOneLoopStart(
|
||||
iRetInit = sqlite3VdbeAddOp2(v, OP_Integer, 0, regReturn);
|
||||
|
||||
/* If the original WHERE clause is z of the form: (x1 OR x2 OR ...) AND y
|
||||
** Then for every term xN, evaluate as the subexpression: xN AND z
|
||||
** Then for every term xN, evaluate as the subexpression: xN AND y
|
||||
** That way, terms in y that are factored into the disjunction will
|
||||
** be picked up by the recursive calls to sqlite3WhereBegin() below.
|
||||
**
|
||||
@@ -2306,6 +2334,20 @@ Bitmask sqlite3WhereCodeOneLoopStart(
|
||||
** This optimization also only applies if the (x1 OR x2 OR ...) term
|
||||
** is not contained in the ON clause of a LEFT JOIN.
|
||||
** See ticket http://www.sqlite.org/src/info/f2369304e4
|
||||
**
|
||||
** 2022-02-04: Do not push down slices of a row-value comparison.
|
||||
** In other words, "w" or "y" may not be a slice of a vector. Otherwise,
|
||||
** the initialization of the right-hand operand of the vector comparison
|
||||
** might not occur, or might occur only in an OR branch that is not
|
||||
** taken. dbsqlfuzz 80a9fade844b4fb43564efc972bcb2c68270f5d1.
|
||||
**
|
||||
** 2022-03-03: Do not push down expressions that involve subqueries.
|
||||
** The subquery might get coded as a subroutine. Any table-references
|
||||
** in the subquery might be resolved to index-references for the index on
|
||||
** the OR branch in which the subroutine is coded. But if the subroutine
|
||||
** is invoked from a different OR branch that uses a different index, such
|
||||
** index-references will not work. tag-20220303a
|
||||
** https://sqlite.org/forum/forumpost/36937b197273d403
|
||||
*/
|
||||
if( pWC->nTerm>1 ){
|
||||
int iTerm;
|
||||
@@ -2314,9 +2356,12 @@ Bitmask sqlite3WhereCodeOneLoopStart(
|
||||
if( &pWC->a[iTerm] == pTerm ) continue;
|
||||
testcase( pWC->a[iTerm].wtFlags & TERM_VIRTUAL );
|
||||
testcase( pWC->a[iTerm].wtFlags & TERM_CODED );
|
||||
if( (pWC->a[iTerm].wtFlags & (TERM_VIRTUAL|TERM_CODED))!=0 ) continue;
|
||||
testcase( pWC->a[iTerm].wtFlags & TERM_SLICE );
|
||||
if( (pWC->a[iTerm].wtFlags & (TERM_VIRTUAL|TERM_CODED|TERM_SLICE))!=0 ){
|
||||
continue;
|
||||
}
|
||||
if( (pWC->a[iTerm].eOperator & WO_ALL)==0 ) continue;
|
||||
testcase( pWC->a[iTerm].wtFlags & TERM_ORINFO );
|
||||
if( ExprHasProperty(pExpr, EP_Subquery) ) continue; /* tag-20220303a */
|
||||
pExpr = sqlite3ExprDup(db, pExpr, 0);
|
||||
pAndExpr = sqlite3ExprAnd(pParse, pAndExpr, pExpr);
|
||||
}
|
||||
@@ -2357,9 +2402,9 @@ Bitmask sqlite3WhereCodeOneLoopStart(
|
||||
/* Loop through table entries that match term pOrTerm. */
|
||||
ExplainQueryPlan((pParse, 1, "INDEX %d", ii+1));
|
||||
WHERETRACE(0xffff, ("Subplan for OR-clause:\n"));
|
||||
pSubWInfo = sqlite3WhereBegin(pParse, pOrTab, pOrExpr, 0, 0,
|
||||
pSubWInfo = sqlite3WhereBegin(pParse, pOrTab, pOrExpr, 0, 0, 0,
|
||||
WHERE_OR_SUBCLAUSE, iCovCur);
|
||||
assert( pSubWInfo || pParse->nErr || db->mallocFailed );
|
||||
assert( pSubWInfo || pParse->nErr );
|
||||
if( pSubWInfo ){
|
||||
WhereLoop *pSubLoop;
|
||||
int addrExplain = sqlite3WhereExplainOneScan(
|
||||
|
||||
+119
-7
@@ -422,7 +422,7 @@ static int isAuxiliaryVtabOperator(
|
||||
assert( pVtab!=0 );
|
||||
assert( pVtab->pModule!=0 );
|
||||
assert( !ExprHasProperty(pExpr, EP_IntValue) );
|
||||
pMod = (sqlite3_module *)pVtab->pModule;
|
||||
pMod = (sqlite3_module *)pVtab->pModule;
|
||||
if( pMod->xFindFunction!=0 ){
|
||||
i = pMod->xFindFunction(pVtab,2, pExpr->u.zToken, &xNotUsed, &pNotUsed);
|
||||
if( i>=SQLITE_INDEX_CONSTRAINT_FUNCTION ){
|
||||
@@ -466,7 +466,7 @@ static int isAuxiliaryVtabOperator(
|
||||
static void transferJoinMarkings(Expr *pDerived, Expr *pBase){
|
||||
if( pDerived ){
|
||||
pDerived->flags |= pBase->flags & EP_FromJoin;
|
||||
pDerived->iRightJoinTable = pBase->iRightJoinTable;
|
||||
pDerived->w.iRightJoinTable = pBase->w.iRightJoinTable;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1111,7 +1111,7 @@ static void exprAnalyze(
|
||||
#endif
|
||||
|
||||
if( ExprHasProperty(pExpr, EP_FromJoin) ){
|
||||
Bitmask x = sqlite3WhereGetMask(pMaskSet, pExpr->iRightJoinTable);
|
||||
Bitmask x = sqlite3WhereGetMask(pMaskSet, pExpr->w.iRightJoinTable);
|
||||
prereqAll |= x;
|
||||
extraRight = x-1; /* ON clause terms may not be used with an index
|
||||
** on left table of a LEFT JOIN. Ticket #3015 */
|
||||
@@ -1379,7 +1379,10 @@ static void exprAnalyze(
|
||||
** no longer used.
|
||||
**
|
||||
** This is only required if at least one side of the comparison operation
|
||||
** is not a sub-select. */
|
||||
** is not a sub-select.
|
||||
**
|
||||
** tag-20220128a
|
||||
*/
|
||||
if( (pExpr->op==TK_EQ || pExpr->op==TK_IS)
|
||||
&& (nLeft = sqlite3ExprVectorSize(pExpr->pLeft))>1
|
||||
&& sqlite3ExprVectorSize(pExpr->pRight)==nLeft
|
||||
@@ -1396,7 +1399,7 @@ static void exprAnalyze(
|
||||
|
||||
pNew = sqlite3PExpr(pParse, pExpr->op, pLeft, pRight);
|
||||
transferJoinMarkings(pNew, pExpr);
|
||||
idxNew = whereClauseInsert(pWC, pNew, TERM_DYNAMIC);
|
||||
idxNew = whereClauseInsert(pWC, pNew, TERM_DYNAMIC|TERM_SLICE);
|
||||
exprAnalyze(pSrc, pWC, idxNew);
|
||||
}
|
||||
pTerm = &pWC->a[idxTerm];
|
||||
@@ -1426,7 +1429,7 @@ static void exprAnalyze(
|
||||
int i;
|
||||
for(i=0; i<sqlite3ExprVectorSize(pExpr->pLeft); i++){
|
||||
int idxNew;
|
||||
idxNew = whereClauseInsert(pWC, pExpr, TERM_VIRTUAL);
|
||||
idxNew = whereClauseInsert(pWC, pExpr, TERM_VIRTUAL|TERM_SLICE);
|
||||
pWC->a[idxNew].u.x.iField = i+1;
|
||||
exprAnalyze(pSrc, pWC, idxNew);
|
||||
markTermAsChild(pWC, idxNew, idxTerm);
|
||||
@@ -1459,7 +1462,7 @@ static void exprAnalyze(
|
||||
0, sqlite3ExprDup(db, pRight, 0));
|
||||
if( ExprHasProperty(pExpr, EP_FromJoin) && pNewExpr ){
|
||||
ExprSetProperty(pNewExpr, EP_FromJoin);
|
||||
pNewExpr->iRightJoinTable = pExpr->iRightJoinTable;
|
||||
pNewExpr->w.iRightJoinTable = pExpr->w.iRightJoinTable;
|
||||
}
|
||||
idxNew = whereClauseInsert(pWC, pNewExpr, TERM_VIRTUAL|TERM_DYNAMIC);
|
||||
testcase( idxNew==0 );
|
||||
@@ -1522,6 +1525,113 @@ void sqlite3WhereSplit(WhereClause *pWC, Expr *pExpr, u8 op){
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Add either a LIMIT (if eMatchOp==SQLITE_INDEX_CONSTRAINT_LIMIT) or
|
||||
** OFFSET (if eMatchOp==SQLITE_INDEX_CONSTRAINT_OFFSET) term to the
|
||||
** where-clause passed as the first argument. The value for the term
|
||||
** is found in register iReg.
|
||||
**
|
||||
** In the common case where the value is a simple integer
|
||||
** (example: "LIMIT 5 OFFSET 10") then the expression codes as a
|
||||
** TK_INTEGER so that it will be available to sqlite3_vtab_rhs_value().
|
||||
** If not, then it codes as a TK_REGISTER expression.
|
||||
*/
|
||||
static void whereAddLimitExpr(
|
||||
WhereClause *pWC, /* Add the constraint to this WHERE clause */
|
||||
int iReg, /* Register that will hold value of the limit/offset */
|
||||
Expr *pExpr, /* Expression that defines the limit/offset */
|
||||
int iCsr, /* Cursor to which the constraint applies */
|
||||
int eMatchOp /* SQLITE_INDEX_CONSTRAINT_LIMIT or _OFFSET */
|
||||
){
|
||||
Parse *pParse = pWC->pWInfo->pParse;
|
||||
sqlite3 *db = pParse->db;
|
||||
Expr *pNew;
|
||||
int iVal = 0;
|
||||
|
||||
if( sqlite3ExprIsInteger(pExpr, &iVal) && iVal>=0 ){
|
||||
Expr *pVal = sqlite3Expr(db, TK_INTEGER, 0);
|
||||
if( pVal==0 ) return;
|
||||
ExprSetProperty(pVal, EP_IntValue);
|
||||
pVal->u.iValue = iVal;
|
||||
pNew = sqlite3PExpr(pParse, TK_MATCH, 0, pVal);
|
||||
}else{
|
||||
Expr *pVal = sqlite3Expr(db, TK_REGISTER, 0);
|
||||
if( pVal==0 ) return;
|
||||
pVal->iTable = iReg;
|
||||
pNew = sqlite3PExpr(pParse, TK_MATCH, 0, pVal);
|
||||
}
|
||||
if( pNew ){
|
||||
WhereTerm *pTerm;
|
||||
int idx;
|
||||
idx = whereClauseInsert(pWC, pNew, TERM_DYNAMIC|TERM_VIRTUAL);
|
||||
pTerm = &pWC->a[idx];
|
||||
pTerm->leftCursor = iCsr;
|
||||
pTerm->eOperator = WO_AUX;
|
||||
pTerm->eMatchOp = eMatchOp;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Possibly add terms corresponding to the LIMIT and OFFSET clauses of the
|
||||
** SELECT statement passed as the second argument. These terms are only
|
||||
** added if:
|
||||
**
|
||||
** 1. The SELECT statement has a LIMIT clause, and
|
||||
** 2. The SELECT statement is not an aggregate or DISTINCT query, and
|
||||
** 3. The SELECT statement has exactly one object in its from clause, and
|
||||
** that object is a virtual table, and
|
||||
** 4. There are no terms in the WHERE clause that will not be passed
|
||||
** to the virtual table xBestIndex method.
|
||||
** 5. The ORDER BY clause, if any, will be made available to the xBestIndex
|
||||
** method.
|
||||
**
|
||||
** LIMIT and OFFSET terms are ignored by most of the planner code. They
|
||||
** exist only so that they may be passed to the xBestIndex method of the
|
||||
** single virtual table in the FROM clause of the SELECT.
|
||||
*/
|
||||
void sqlite3WhereAddLimit(WhereClause *pWC, Select *p){
|
||||
assert( p==0 || (p->pGroupBy==0 && (p->selFlags & SF_Aggregate)==0) );
|
||||
if( (p && p->pLimit) /* 1 */
|
||||
&& (p->selFlags & (SF_Distinct|SF_Aggregate))==0 /* 2 */
|
||||
&& (p->pSrc->nSrc==1 && IsVirtual(p->pSrc->a[0].pTab)) /* 3 */
|
||||
){
|
||||
ExprList *pOrderBy = p->pOrderBy;
|
||||
int iCsr = p->pSrc->a[0].iCursor;
|
||||
int ii;
|
||||
|
||||
/* Check condition (4). Return early if it is not met. */
|
||||
for(ii=0; ii<pWC->nTerm; ii++){
|
||||
if( pWC->a[ii].wtFlags & TERM_CODED ){
|
||||
/* This term is a vector operation that has been decomposed into
|
||||
** other, subsequent terms. It can be ignored. See tag-20220128a */
|
||||
assert( pWC->a[ii].wtFlags & TERM_VIRTUAL );
|
||||
assert( pWC->a[ii].eOperator==0 );
|
||||
continue;
|
||||
}
|
||||
if( pWC->a[ii].leftCursor!=iCsr ) return;
|
||||
}
|
||||
|
||||
/* Check condition (5). Return early if it is not met. */
|
||||
if( pOrderBy ){
|
||||
for(ii=0; ii<pOrderBy->nExpr; ii++){
|
||||
Expr *pExpr = pOrderBy->a[ii].pExpr;
|
||||
if( pExpr->op!=TK_COLUMN ) return;
|
||||
if( pExpr->iTable!=iCsr ) return;
|
||||
if( pOrderBy->a[ii].sortFlags & KEYINFO_ORDER_BIGNULL ) return;
|
||||
}
|
||||
}
|
||||
|
||||
/* 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 ){
|
||||
whereAddLimitExpr(pWC, p->iOffset, p->pLimit->pRight,
|
||||
iCsr, SQLITE_INDEX_CONSTRAINT_OFFSET);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Initialize a preallocated WhereClause structure.
|
||||
*/
|
||||
@@ -1557,6 +1667,7 @@ void sqlite3WhereClauseClear(WhereClause *pWC){
|
||||
}
|
||||
#endif
|
||||
while(1){
|
||||
assert( a->eMatchOp==0 || a->eOperator==WO_AUX );
|
||||
if( a->wtFlags & TERM_DYNAMIC ){
|
||||
sqlite3ExprDelete(db, a->pExpr);
|
||||
}
|
||||
@@ -1714,6 +1825,7 @@ void sqlite3WhereTabFuncArgs(
|
||||
pColRef->iColumn = k++;
|
||||
assert( ExprUseYTab(pColRef) );
|
||||
pColRef->y.pTab = pTab;
|
||||
pItem->colUsed |= sqlite3ExprColUsed(pColRef);
|
||||
pRhs = sqlite3PExpr(pParse, TK_UPLUS,
|
||||
sqlite3ExprDup(pParse->db, pArgs->a[j].pExpr, 0), 0);
|
||||
pTerm = sqlite3PExpr(pParse, TK_EQ, pColRef, pRhs);
|
||||
|
||||
+7
-7
@@ -957,7 +957,11 @@ static int disallowAggregatesInOrderByCb(Walker *pWalker, Expr *pExpr){
|
||||
*/
|
||||
int sqlite3WindowRewrite(Parse *pParse, Select *p){
|
||||
int rc = SQLITE_OK;
|
||||
if( p->pWin && p->pPrior==0 && ALWAYS((p->selFlags & SF_WinRewrite)==0) ){
|
||||
if( p->pWin
|
||||
&& p->pPrior==0
|
||||
&& ALWAYS((p->selFlags & SF_WinRewrite)==0)
|
||||
&& ALWAYS(!IN_RENAME_OBJECT)
|
||||
){
|
||||
Vdbe *v = sqlite3GetVdbe(pParse);
|
||||
sqlite3 *db = pParse->db;
|
||||
Select *pSub = 0; /* The subquery */
|
||||
@@ -1032,6 +1036,7 @@ int sqlite3WindowRewrite(Parse *pParse, Select *p){
|
||||
for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
|
||||
ExprList *pArgs;
|
||||
assert( ExprUseXList(pWin->pOwner) );
|
||||
assert( pWin->pFunc!=0 );
|
||||
pArgs = pWin->pOwner->x.pList;
|
||||
if( pWin->pFunc->funcFlags & SQLITE_FUNC_SUBTYPE ){
|
||||
selectWindowRewriteEList(pParse, pMWin, pSrc, pArgs, pTab, &pSublist);
|
||||
@@ -1106,12 +1111,7 @@ int sqlite3WindowRewrite(Parse *pParse, Select *p){
|
||||
sqlite3ParserAddCleanup(pParse, sqlite3DbFree, pTab);
|
||||
}
|
||||
|
||||
if( rc ){
|
||||
if( pParse->nErr==0 ){
|
||||
assert( pParse->db->mallocFailed );
|
||||
sqlite3ErrorToParser(pParse->db, SQLITE_NOMEM);
|
||||
}
|
||||
}
|
||||
assert( rc==SQLITE_OK || pParse->nErr!=0 );
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
+70
-1
@@ -553,8 +553,9 @@ do_execsql_test 13.1.3 {
|
||||
|
||||
sqlite3_db_config db DEFENSIVE 0
|
||||
do_execsql_test 13.1.4 {
|
||||
PRAGMA writable_schema = 1;
|
||||
PRAGMA writable_schema = ON;
|
||||
UPDATE sqlite_master SET sql = 'CREATE INDEX x1i ON x1(j)' WHERE name='x1i';
|
||||
PRAGMA writable_schema = OFF;
|
||||
} {}
|
||||
|
||||
do_catchsql_test 13.1.5 {
|
||||
@@ -562,7 +563,9 @@ do_catchsql_test 13.1.5 {
|
||||
} {1 {error in index x1i: no such column: j}}
|
||||
|
||||
do_execsql_test 13.1.6 {
|
||||
PRAGMA writable_schema = ON;
|
||||
UPDATE sqlite_master SET sql = '' WHERE name='x1i';
|
||||
PRAGMA writable_schema = OFF;
|
||||
} {}
|
||||
|
||||
do_catchsql_test 13.1.7 {
|
||||
@@ -570,7 +573,9 @@ do_catchsql_test 13.1.7 {
|
||||
} {1 {error in index x1i: }}
|
||||
|
||||
do_execsql_test 13.1.8 {
|
||||
PRAGMA writable_schema = ON;
|
||||
DELETE FROM sqlite_master WHERE name = 'x1i';
|
||||
PRAGMA writable_schema = OFF;
|
||||
}
|
||||
|
||||
do_execsql_test 13.2.0 {
|
||||
@@ -861,5 +866,69 @@ do_execsql_test 23.0 {
|
||||
|
||||
} {ok {CREATE TABLE t1("x" "b",c)}}
|
||||
|
||||
# 2022-02-04
|
||||
# Do not complain about syntax errors in the schema if
|
||||
# in PRAGMA writable_schema=ON mode.
|
||||
#
|
||||
reset_db
|
||||
do_execsql_test 23.0 {
|
||||
CREATE TABLE t1(a INT, b REAL, c TEXT, d BLOB, e ANY);
|
||||
CREATE INDEX t1abx ON t1(a, b, a+b) WHERE c IS NOT NULL;
|
||||
CREATE VIEW t2 AS SELECT a+10, b*5.0, xyz FROM t1; -- unknown column "xyz"
|
||||
CREATE TABLE schema_copy(name TEXT, sql TEXT);
|
||||
INSERT INTO schema_copy(name,sql) SELECT name, sql FROM sqlite_schema WHERE sql IS NOT NULL;
|
||||
} {}
|
||||
do_catchsql_test 23.1 {
|
||||
ALTER TABLE t1 RENAME COLUMN e TO eeee;
|
||||
} {1 {error in view t2: no such column: xyz}}
|
||||
do_execsql_test 23.2 {
|
||||
SELECT name, sql FROM sqlite_master
|
||||
EXCEPT SELECT name, sql FROM schema_copy;
|
||||
} {}
|
||||
do_execsql_test 23.3 {
|
||||
BEGIN;
|
||||
PRAGMA writable_schema=ON;
|
||||
ALTER TABLE t1 RENAME COLUMN e TO eeee;
|
||||
PRAGMA writable_schema=OFF;
|
||||
SELECT name FROM sqlite_master
|
||||
WHERE (name, sql) NOT IN (SELECT name, sql FROM schema_copy);
|
||||
ROLLBACK;
|
||||
} {t1}
|
||||
do_execsql_test 23.10 {
|
||||
DROP VIEW t2;
|
||||
CREATE TRIGGER r3 AFTER INSERT ON t1 BEGIN
|
||||
INSERT INTO t3(x,y) VALUES(new.a, new.b);
|
||||
INSERT INTO t4(p) VALUES(new.c); -- no such table "t4"
|
||||
END;
|
||||
DELETE FROM schema_copy;
|
||||
INSERT INTO schema_copy(name,sql) SELECT name, sql FROM sqlite_schema WHERE sql IS NOT NULL;
|
||||
} {}
|
||||
do_catchsql_test 23.11 {
|
||||
ALTER TABLE t1 RENAME COLUMN e TO eeee;
|
||||
} {1 {error in trigger r3: no such table: main.t3}}
|
||||
do_execsql_test 23.12 {
|
||||
SELECT name, sql FROM sqlite_master
|
||||
EXCEPT SELECT name, sql FROM schema_copy;
|
||||
} {}
|
||||
do_execsql_test 23.13 {
|
||||
BEGIN;
|
||||
PRAGMA writable_schema=ON;
|
||||
ALTER TABLE t1 RENAME COLUMN e TO eeee;
|
||||
PRAGMA writable_schema=OFF;
|
||||
SELECT name FROM sqlite_master
|
||||
WHERE (name, sql) NOT IN (SELECT name, sql FROM schema_copy);
|
||||
ROLLBACK;
|
||||
} {t1}
|
||||
do_execsql_test 23.20 {
|
||||
CREATE TABLE t4(id INTEGER PRIMARY KEY, c1 INT, c2 INT);
|
||||
CREATE VIEW t4v1 AS SELECT id, c1, c99 FROM t4;
|
||||
DELETE FROM schema_copy;
|
||||
INSERT INTO schema_copy SELECT name, sql FROM sqlite_schema;
|
||||
BEGIN;
|
||||
PRAGMA writable_schema=ON;
|
||||
ALTER TABLE t4 RENAME to t4new;
|
||||
SELECT name FROM sqlite_schema WHERE (name,sql) NOT IN (SELECT * FROM schema_copy);
|
||||
ROLLBACK;
|
||||
} {t4new}
|
||||
|
||||
finish_test
|
||||
|
||||
+10
-5
@@ -26,6 +26,11 @@ do_execsql_test 1.0 {
|
||||
}
|
||||
faultsim_save_and_close
|
||||
|
||||
set ::TMPDBERROR [list 1 \
|
||||
{unable to open a temporary database file for storing temporary tables}
|
||||
]
|
||||
|
||||
|
||||
do_faultsim_test 1 -prep {
|
||||
faultsim_restore_and_reopen
|
||||
} -body {
|
||||
@@ -33,7 +38,7 @@ do_faultsim_test 1 -prep {
|
||||
ALTER TABLE t1 RENAME abcd TO dcba
|
||||
}
|
||||
} -test {
|
||||
faultsim_test_result {0 {}}
|
||||
faultsim_test_result {0 {}} $::TMPDBERROR
|
||||
}
|
||||
|
||||
catch {db close}
|
||||
@@ -52,7 +57,7 @@ do_faultsim_test 2 -prep {
|
||||
ALTER TABLE t1 RENAME abcd TO dcba
|
||||
}
|
||||
} -test {
|
||||
faultsim_test_result {0 {}}
|
||||
faultsim_test_result {0 {}} $::TMPDBERROR
|
||||
}
|
||||
|
||||
|
||||
@@ -70,7 +75,7 @@ do_faultsim_test 3 -prep {
|
||||
ALTER TABLE t1 RENAME abcd TO dcba
|
||||
}
|
||||
} -test {
|
||||
faultsim_test_result {0 {}}
|
||||
faultsim_test_result {0 {}} $::TMPDBERROR
|
||||
}
|
||||
|
||||
reset_db
|
||||
@@ -95,7 +100,7 @@ do_faultsim_test 4 -faults oom-* -prep {
|
||||
ALTER TABLE rr RENAME a TO c;
|
||||
}
|
||||
} -test {
|
||||
faultsim_test_result {0 {}}
|
||||
faultsim_test_result {0 {}} $::TMPDBERROR
|
||||
}
|
||||
|
||||
reset_db
|
||||
@@ -116,7 +121,7 @@ do_faultsim_test 5 -faults oom-* -prep {
|
||||
ALTER TABLE rr RENAME TO c;
|
||||
}
|
||||
} -test {
|
||||
faultsim_test_result {0 {}}
|
||||
faultsim_test_result {0 {}} $::TMPDBERROR
|
||||
}
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -21,6 +21,10 @@ ifcapable !altertable {
|
||||
return
|
||||
}
|
||||
|
||||
set ::TMPDBERROR [list 1 \
|
||||
{unable to open a temporary database file for storing temporary tables}
|
||||
]
|
||||
|
||||
do_execsql_test 1.0 {
|
||||
CREATE TABLE x1(
|
||||
one, two, three, PRIMARY KEY(one),
|
||||
@@ -40,7 +44,7 @@ do_faultsim_test 1 -prep {
|
||||
} -body {
|
||||
execsql { ALTER TABLE t1 DROP COLUMN c }
|
||||
} -test {
|
||||
faultsim_test_result {0 {}}
|
||||
faultsim_test_result {0 {}} $::TMPDBERROR
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
@@ -72,7 +76,7 @@ do_faultsim_test 2.2 -prep {
|
||||
ALTER TABLE t2 RENAME TO t2x;
|
||||
}
|
||||
} -test {
|
||||
faultsim_test_result {0 {}}
|
||||
faultsim_test_result {0 {}} $::TMPDBERROR
|
||||
}
|
||||
|
||||
finish_test
|
||||
|
||||
+2
-4
@@ -63,8 +63,7 @@ foreach {tn before after} {
|
||||
10 {CREATE TABLE t2(abc, xyz CHECK (xyz != "123"))}
|
||||
{CREATE TABLE t2(abc, xyz CHECK (xyz != '123'))}
|
||||
|
||||
11 {
|
||||
CREATE TRIGGER ott AFTER UPDATE ON t1 BEGIN
|
||||
11 {CREATE TRIGGER ott AFTER UPDATE ON t1 BEGIN
|
||||
SELECT max("str", new."a") FROM t1
|
||||
WHERE group_concat("b", ",") OVER (ORDER BY c||"str");
|
||||
UPDATE t1 SET c= b + "str";
|
||||
@@ -72,8 +71,7 @@ foreach {tn before after} {
|
||||
SELECT 1 FROM t1 AS o WHERE o."a" = "o.a" AND t1.b IN("t1.b")
|
||||
);
|
||||
END;
|
||||
} {
|
||||
CREATE TRIGGER ott AFTER UPDATE ON t1 BEGIN
|
||||
} {CREATE TRIGGER ott AFTER UPDATE ON t1 BEGIN
|
||||
SELECT max('str', new."a") FROM t1
|
||||
WHERE group_concat("b", ',') OVER (ORDER BY c||'str');
|
||||
UPDATE t1 SET c= b + 'str';
|
||||
|
||||
+1
-1
@@ -355,7 +355,7 @@ do_execsql_test 8.5 {
|
||||
reset_db
|
||||
do_catchsql_test 8.6 {
|
||||
CREATE TABLE t0(c0);
|
||||
CREATE INDEX i0 ON t0(LIKELIHOOD(1,2) AND 0);
|
||||
CREATE INDEX i0 ON t0(likelihood(1,2) AND 0);
|
||||
ALTER TABLE t0 RENAME TO t1;
|
||||
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}}
|
||||
|
||||
@@ -969,4 +969,13 @@ foreach {tn file rc} {
|
||||
db2 close
|
||||
}
|
||||
|
||||
# 2021-01-31 https://sqlite.org/forum/forumpost/8b39fbf3e7
|
||||
#
|
||||
do_test backup-11.1 {
|
||||
sqlite3 db1 :memory:
|
||||
sqlite3 db2 :memory:
|
||||
sqlite3_backup B db1 main db2 temp
|
||||
B finish
|
||||
} {SQLITE_OK}
|
||||
|
||||
finish_test
|
||||
|
||||
+19
-5
@@ -29,7 +29,10 @@ proc vtab_command {method args} {
|
||||
}
|
||||
|
||||
xBestIndex {
|
||||
set clist [lindex $args 0]
|
||||
set hdl [lindex $args 0]
|
||||
set clist [$hdl constraints]
|
||||
set orderby [$hdl orderby]
|
||||
|
||||
if {[llength $clist]!=1} { error "unexpected constraint list" }
|
||||
catch { array unset C }
|
||||
array set C [lindex $clist 0]
|
||||
@@ -76,10 +79,13 @@ proc t1_vtab {mode method args} {
|
||||
}
|
||||
|
||||
xBestIndex {
|
||||
set hdl [lindex $args 0]
|
||||
set clist [$hdl constraints]
|
||||
set orderby [$hdl orderby]
|
||||
|
||||
set SQL_FILTER {SELECT * FROM t1x WHERE a='%1%'}
|
||||
set SQL_SCAN {SELECT * FROM t1x}
|
||||
|
||||
set clist [lindex $args 0]
|
||||
set idx 0
|
||||
for {set idx 0} {$idx < [llength $clist]} {incr idx} {
|
||||
array unset C
|
||||
@@ -177,7 +183,10 @@ proc vtab_command {method args} {
|
||||
}
|
||||
|
||||
xBestIndex {
|
||||
set clist [lindex $args 0]
|
||||
set hdl [lindex $args 0]
|
||||
set clist [$hdl constraints]
|
||||
set orderby [$hdl orderby]
|
||||
|
||||
#puts $clist
|
||||
set W [list]
|
||||
set U [list]
|
||||
@@ -287,12 +296,17 @@ proc vtab_command {method args} {
|
||||
}
|
||||
|
||||
xBestIndex {
|
||||
set clist [lindex $args 0]
|
||||
set hdl [lindex $args 0]
|
||||
set clist [$hdl constraints]
|
||||
set orderby [$hdl orderby]
|
||||
|
||||
lappend ::bestindex_calls $clist
|
||||
set ret "cost 1000000 idxnum 555"
|
||||
for {set i 0} {$i < [llength $clist]} {incr i} {
|
||||
array set C [lindex $clist $i]
|
||||
if {$C(usable)} { lappend ret use $i }
|
||||
if {$C(usable)} {
|
||||
lappend ret use $i
|
||||
}
|
||||
}
|
||||
return $ret
|
||||
}
|
||||
|
||||
@@ -47,7 +47,10 @@ proc vtab_cmd {tbl cols method args} {
|
||||
return "CREATE TABLE $tbl ([join $cols ,])"
|
||||
}
|
||||
xBestIndex {
|
||||
foreach {clist orderby mask} $args {}
|
||||
set hdl [lindex $args 0]
|
||||
set clist [$hdl constraints]
|
||||
set orderby [$hdl orderby]
|
||||
set mask [$hdl mask]
|
||||
|
||||
set cons [list]
|
||||
set used [list]
|
||||
|
||||
@@ -34,7 +34,10 @@ proc vtab_cmd {bOmit method args} {
|
||||
}
|
||||
|
||||
xBestIndex {
|
||||
foreach {clist orderby mask} $args {}
|
||||
set hdl [lindex $args 0]
|
||||
set clist [$hdl constraints]
|
||||
set orderby [$hdl orderby]
|
||||
set mask [$hdl mask]
|
||||
|
||||
set ret [list]
|
||||
set use use
|
||||
|
||||
@@ -48,7 +48,10 @@ proc vtab_cmd {param method args} {
|
||||
}
|
||||
|
||||
xBestIndex {
|
||||
foreach {clist orderby mask} $args {}
|
||||
set hdl [lindex $args 0]
|
||||
set clist [$hdl constraints]
|
||||
set orderby [$hdl orderby]
|
||||
set mask [$hdl mask]
|
||||
|
||||
set ret [list]
|
||||
|
||||
@@ -135,7 +138,11 @@ proc vtab_command {method args} {
|
||||
}
|
||||
|
||||
xBestIndex {
|
||||
set clist [lindex $args 0]
|
||||
set hdl [lindex $args 0]
|
||||
set clist [$hdl constraints]
|
||||
set orderby [$hdl orderby]
|
||||
set mask [$hdl mask]
|
||||
|
||||
if {[llength $clist]!=1} { error "unexpected constraint list" }
|
||||
catch { array unset C }
|
||||
array set C [lindex $clist 0]
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
set testprefix bestindex4
|
||||
set testprefix bestindex5
|
||||
|
||||
ifcapable !vtab {
|
||||
finish_test
|
||||
@@ -44,7 +44,10 @@ proc vtab_cmd {method args} {
|
||||
}
|
||||
|
||||
xBestIndex {
|
||||
foreach {clist orderby mask} $args {}
|
||||
set hdl [lindex $args 0]
|
||||
set clist [$hdl constraints]
|
||||
set orderby [$hdl orderby]
|
||||
set mask [$hdl mask]
|
||||
|
||||
set cost 1000000.0
|
||||
set ret [list]
|
||||
|
||||
@@ -28,7 +28,11 @@ proc vtab_command {src method args} {
|
||||
}
|
||||
|
||||
xBestIndex {
|
||||
set clist [lindex $args 0]
|
||||
set hdl [lindex $args 0]
|
||||
set clist [$hdl constraints]
|
||||
set orderby [$hdl orderby]
|
||||
set mask [$hdl mask]
|
||||
|
||||
set wlist 1
|
||||
|
||||
set iCons 0
|
||||
|
||||
@@ -28,7 +28,11 @@ proc vtab_command {src method args} {
|
||||
}
|
||||
|
||||
xBestIndex {
|
||||
set clist [lindex $args 0]
|
||||
set hdl [lindex $args 0]
|
||||
set clist [$hdl constraints]
|
||||
set orderby [$hdl orderby]
|
||||
set mask [$hdl mask]
|
||||
|
||||
set iCons 0
|
||||
set ret [list]
|
||||
foreach cons $clist {
|
||||
|
||||
@@ -0,0 +1,463 @@
|
||||
# 2020-01-29
|
||||
#
|
||||
# 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 bestindex8
|
||||
|
||||
ifcapable !vtab {
|
||||
finish_test
|
||||
return
|
||||
}
|
||||
|
||||
register_tcl_module db
|
||||
|
||||
proc vtab_command {src method args} {
|
||||
switch -- $method {
|
||||
xConnect {
|
||||
return "CREATE TABLE xxx(a, b)"
|
||||
}
|
||||
|
||||
xBestIndex {
|
||||
set hdl [lindex $args 0]
|
||||
set clist [$hdl constraints]
|
||||
set orderby [$hdl orderby]
|
||||
lappend ::lBestIndexDistinct [$hdl distinct]
|
||||
|
||||
#puts "ORDERBY: $orderby"
|
||||
set iCons 0
|
||||
set ret [list]
|
||||
foreach cons $clist {
|
||||
catch { array unset C }
|
||||
array set C $cons
|
||||
if {$C(usable)} {
|
||||
lappend ret use $iCons
|
||||
}
|
||||
incr iCons
|
||||
}
|
||||
if {$orderby=="{column 0 desc 0} {column 1 desc 0}"
|
||||
|| $orderby=="{column 0 desc 0}"
|
||||
} {
|
||||
lappend ret orderby 1
|
||||
lappend ret idxnum 1
|
||||
set ::lOrderByConsumed 1
|
||||
}
|
||||
return $ret
|
||||
}
|
||||
|
||||
xFilter {
|
||||
set idxnum [lindex $args 0]
|
||||
if {$idxnum} {
|
||||
return [list sql "SELECT rowid, a, b FROM $src order by 2, 3"]
|
||||
}
|
||||
return [list sql "SELECT rowid, a, b FROM $src"]
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return {}
|
||||
}
|
||||
|
||||
do_execsql_test 1.0 {
|
||||
CREATE TABLE t1(a, b);
|
||||
CREATE INDEX i1 ON t1(a, b);
|
||||
INSERT INTO t1 VALUES('a', 'b'), ('c', 'd');
|
||||
INSERT INTO t1 VALUES('a', 'b'), ('c', 'd');
|
||||
CREATE VIRTUAL TABLE vt1 USING tcl(vtab_command t1);
|
||||
|
||||
CREATE TABLE t0(c0);
|
||||
INSERT INTO t0(c0) VALUES (1), (0);
|
||||
}
|
||||
|
||||
foreach {tn sql bDistinct idxinsert bConsumed res} {
|
||||
1 "SELECT a, b FROM vt1" 0 0 0 {a b c d a b c d}
|
||||
2 "SELECT DISTINCT a, b FROM vt1" 2 1 1 {a b c d}
|
||||
3 "SELECT DISTINCT a FROM vt1" 2 1 1 {a c}
|
||||
4 "SELECT DISTINCT b FROM vt1" 2 1 0 {b d}
|
||||
5 "SELECT DISTINCT b FROM vt1 ORDER BY a" 0 1 1 {b d}
|
||||
6 "SELECT DISTINCT t0.c0 FROM vt1, t0 ORDER BY vt1.a" 0 1 1 {1 0}
|
||||
7 "SELECT DISTINCT a, b FROM vt1 ORDER BY a, b" 1 0 1 {a b c d}
|
||||
8 "SELECT DISTINCT a, b FROM vt1 ORDER BY a" 0 1 1 {a b c d}
|
||||
9 "SELECT DISTINCT a FROM vt1 ORDER BY a, b" 0 1 1 {a c}
|
||||
|
||||
10 "SELECT DISTINCT a, b FROM vt1 WHERE b='b'" 2 1 1 {a b}
|
||||
11 "SELECT DISTINCT a, b FROM vt1 WHERE +b='b'" 2 1 1 {a b}
|
||||
} {
|
||||
set ::lBestIndexDistinct ""
|
||||
set ::lOrderByConsumed 0
|
||||
do_execsql_test 1.$tn.1 $sql $res
|
||||
do_test 1.$tn.2 {
|
||||
set ::lBestIndexDistinct
|
||||
} $bDistinct
|
||||
do_test 1.$tn.3 {
|
||||
expr {[lsearch [execsql "explain $sql"] IdxInsert]>=0}
|
||||
} $idxinsert
|
||||
do_test 1.$tn.4 {
|
||||
set ::lOrderByConsumed
|
||||
} $bConsumed
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
reset_db
|
||||
register_tcl_module db
|
||||
|
||||
proc vtab_command {src method args} {
|
||||
switch -- $method {
|
||||
xConnect {
|
||||
return "CREATE TABLE xxx(a, b)"
|
||||
}
|
||||
|
||||
xBestIndex {
|
||||
set hdl [lindex $args 0]
|
||||
set ret [list]
|
||||
|
||||
set iCons 0
|
||||
foreach cons [$hdl constraints] {
|
||||
array set C $cons
|
||||
if {($C(op)=="limit" || $C(op)=="offset") && $C(usable)} {
|
||||
lappend ret use $iCons
|
||||
}
|
||||
incr iCons
|
||||
}
|
||||
|
||||
return $ret
|
||||
}
|
||||
|
||||
xFilter {
|
||||
lappend ::lFilterArgs [lindex $args 2]
|
||||
return [list sql "SELECT rowid, a, b FROM $src"]
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return {}
|
||||
}
|
||||
|
||||
do_execsql_test 2.0 {
|
||||
CREATE TABLE t1(a, b);
|
||||
CREATE INDEX i1 ON t1(a, b);
|
||||
CREATE VIRTUAL TABLE vt1 USING tcl(vtab_command t1);
|
||||
}
|
||||
|
||||
do_test 2.1 {
|
||||
set ::lFilterArgs [list]
|
||||
execsql { SELECT * FROM vt1 LIMIT 10 }
|
||||
set ::lFilterArgs
|
||||
} {10}
|
||||
|
||||
do_test 2.2 {
|
||||
set ::lFilterArgs [list]
|
||||
execsql { SELECT * FROM vt1 LIMIT 5 OFFSET 50 }
|
||||
set ::lFilterArgs
|
||||
} {{5 50}}
|
||||
|
||||
do_test 2.3 {
|
||||
set ::lFilterArgs [list]
|
||||
execsql { SELECT * FROM vt1 ORDER BY a, b LIMIT 1 OFFSET 1 }
|
||||
set ::lFilterArgs
|
||||
} {{1 1}}
|
||||
|
||||
do_test 2.4 {
|
||||
set ::lFilterArgs [list]
|
||||
execsql { SELECT * FROM vt1 ORDER BY a, +b LIMIT 1 OFFSET 1 }
|
||||
set ::lFilterArgs
|
||||
} {{}}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
reset_db
|
||||
register_tcl_module db
|
||||
|
||||
proc vtab_command {src method args} {
|
||||
switch -- $method {
|
||||
xConnect {
|
||||
return "CREATE TABLE xxx(a, b)"
|
||||
}
|
||||
|
||||
xBestIndex {
|
||||
set hdl [lindex $args 0]
|
||||
set lCons [$hdl constraints]
|
||||
|
||||
set ret [list]
|
||||
for {set i 0} {$i < [llength $lCons]} {incr i} {
|
||||
array set C [lindex $lCons $i]
|
||||
if {$C(usable)} {
|
||||
lappend ret use $i
|
||||
$hdl in $i 1
|
||||
}
|
||||
}
|
||||
return $ret
|
||||
}
|
||||
|
||||
xFilter {
|
||||
set lArg [lindex $args 2]
|
||||
lappend ::lFilterArg {*}$lArg
|
||||
return [list sql "SELECT rowid, a, b FROM $src"]
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return {}
|
||||
}
|
||||
|
||||
do_execsql_test 3.0 {
|
||||
CREATE TABLE t1(a, b);
|
||||
CREATE INDEX i1 ON t1(a, b);
|
||||
CREATE VIRTUAL TABLE vt1 USING tcl(vtab_command t1);
|
||||
}
|
||||
|
||||
foreach {tn sql lfa} {
|
||||
1 "SELECT * FROM vt1 WHERE b IN (10, 20, 30)" {{10 20 30}}
|
||||
2 "SELECT * FROM vt1 WHERE b IN ('abc', 'def')" {{abc def}}
|
||||
3 "SELECT * FROM vt1 WHERE a IS NULL AND b IN ('abc', 'def')" {{} {abc def}}
|
||||
4 "SELECT * FROM vt1 WHERE a IN (1,2,3) AND b IN ('abc', 'def')"
|
||||
{{1 2 3} {abc def}}
|
||||
|
||||
5 "SELECT * FROM vt1
|
||||
WHERE a IN (SELECT 1 UNION SELECT 2) AND b IN ('abc', 'def')"
|
||||
{{1 2} {abc def}}
|
||||
|
||||
6 "SELECT * FROM vt1
|
||||
WHERE b IN ('abc', 'def') AND a IN (SELECT 1 UNION SELECT 2)"
|
||||
{{abc def} {1 2}}
|
||||
} {
|
||||
do_test 3.$tn {
|
||||
set ::lFilterArg [list]
|
||||
execsql $sql
|
||||
set ::lFilterArg
|
||||
} $lfa
|
||||
}
|
||||
|
||||
#explain_i { SELECT * FROM vt1 WHERE b IN (10, 20, 30) }
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
reset_db
|
||||
register_tcl_module db
|
||||
|
||||
proc vtab_command {src method args} {
|
||||
switch -- $method {
|
||||
xConnect {
|
||||
return "CREATE TABLE xxx(a, b, c)"
|
||||
}
|
||||
|
||||
xBestIndex {
|
||||
set hdl [lindex $args 0]
|
||||
set lCons [$hdl constraints]
|
||||
|
||||
set ret [list]
|
||||
for {set i 0} {$i < [llength $lCons]} {incr i} {
|
||||
lappend ::lBestIndexRhs [$hdl rhs_value $i -]
|
||||
}
|
||||
return $ret
|
||||
}
|
||||
|
||||
xFilter {
|
||||
return [list sql "SELECT rowid, a, b, c FROM $src"]
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return {}
|
||||
}
|
||||
|
||||
do_execsql_test 4.0 {
|
||||
CREATE TABLE t1(a, b, c);
|
||||
CREATE VIRTUAL TABLE vt1 USING tcl(vtab_command t1);
|
||||
}
|
||||
|
||||
foreach {tn sql lbir} {
|
||||
1 "SELECT * FROM vt1 WHERE b = 10" {10}
|
||||
2 "SELECT * FROM vt1 WHERE a = 'abc' AND b < 30" {abc 30}
|
||||
3 "SELECT * FROM vt1 WHERE a = 'abc' AND b < 30+2" {abc -}
|
||||
4 "SELECT * FROM vt1 WHERE a IN (1,2,3) AND b < 30+2" {- -}
|
||||
5 "SELECT * FROM vt1 WHERE a IS 111 AND b < 30+2" {111 -}
|
||||
} {
|
||||
do_test 4.$tn {
|
||||
set ::lBestIndexRhs [list]
|
||||
execsql $sql
|
||||
set ::lBestIndexRhs
|
||||
} $lbir
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
reset_db
|
||||
db cache size 0
|
||||
register_tcl_module db
|
||||
|
||||
set ::vtab_handle_in 1
|
||||
proc vtab_command {src method args} {
|
||||
switch -- $method {
|
||||
xConnect {
|
||||
return "CREATE TABLE xxx(a, b, c)"
|
||||
}
|
||||
|
||||
xBestIndex {
|
||||
set lCols [list a b c]
|
||||
|
||||
set hdl [lindex $args 0]
|
||||
set lCons [$hdl constraints]
|
||||
set lOrder [$hdl order]
|
||||
|
||||
set L ""
|
||||
set O ""
|
||||
set W [list]
|
||||
set a 0
|
||||
for {set i 0} {$i < [llength $lCons]} {incr i} {
|
||||
array set C [lindex $lCons $i]
|
||||
if {$C(usable)} {
|
||||
if { $C(op)=="eq" } {
|
||||
set bIn 0
|
||||
if {$::vtab_handle_in} { set bIn [$hdl in $i 1] }
|
||||
if {$bIn} {
|
||||
lappend W "[lindex $lCols $C(column)] IN (%I$a%)"
|
||||
} else {
|
||||
lappend W "[lindex $lCols $C(column)] = %$a%"
|
||||
}
|
||||
lappend ret omit $i
|
||||
}
|
||||
if { $C(op)=="limit" } { set L " LIMIT %$a%" ; lappend ret use $i }
|
||||
if { $C(op)=="offset" } { set O " OFFSET %$a%" ; lappend ret use $i }
|
||||
incr a
|
||||
}
|
||||
}
|
||||
|
||||
set order ""
|
||||
set selectlist "rowid, a, b, c"
|
||||
if {[llength $lOrder]} {
|
||||
array set sl [list]
|
||||
set lO [list]
|
||||
foreach s $lOrder {
|
||||
array set C $s
|
||||
set ad ""
|
||||
if {$C(desc)} { set ad " DESC" }
|
||||
lappend lO "[lindex $lCols $C(column)]$ad"
|
||||
set sl($C(column)) 1
|
||||
}
|
||||
if {[$hdl distinct]==2} {
|
||||
set selectlist "DISTINCT 0"
|
||||
foreach i {0 1 2} {
|
||||
if {[info exists sl($i)]} {
|
||||
append selectlist ", [lindex $lCols $i]"
|
||||
} else {
|
||||
append selectlist ", 0"
|
||||
}
|
||||
}
|
||||
} else {
|
||||
set order " ORDER BY [join $lO ,]"
|
||||
}
|
||||
}
|
||||
|
||||
set where ""
|
||||
if {[llength $W]} { set where " WHERE [join $W { AND }]" }
|
||||
set sql "SELECT $selectlist FROM $src$where$order$L$O"
|
||||
|
||||
lappend ret idxStr $sql
|
||||
return $ret
|
||||
}
|
||||
|
||||
xFilter {
|
||||
foreach {idxnum idxstr lArg} $args {}
|
||||
set ii 0
|
||||
set sql $idxstr
|
||||
foreach a $lArg {
|
||||
set sql [string map [list %$ii% $a] $sql]
|
||||
set sql [string map [list %I$ii% [join $a ,]] $sql]
|
||||
incr ii
|
||||
}
|
||||
lappend ::lFilterSql $sql
|
||||
|
||||
if {[regexp {OFFSET (.*)$} $sql -> off]} {
|
||||
set real_sql "
|
||||
WITH c(i) AS ( SELECT 1 UNION ALL SELECT i+1 FROM c WHERE i<$off )
|
||||
SELECT 0,0,0,0 FROM c
|
||||
UNION ALL SELECT * FROM (
|
||||
$sql
|
||||
)
|
||||
"
|
||||
} else {
|
||||
set real_sql $sql
|
||||
}
|
||||
|
||||
return [list sql $real_sql]
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return {}
|
||||
}
|
||||
|
||||
do_execsql_test 5.0 {
|
||||
CREATE TABLE t1(a, b, c);
|
||||
CREATE VIRTUAL TABLE vt1 USING tcl(vtab_command t1);
|
||||
INSERT INTO t1 VALUES(1, 2, 3);
|
||||
INSERT INTO t1 VALUES(2, 3, 4);
|
||||
INSERT INTO t1 VALUES(3, 4, 5);
|
||||
INSERT INTO t1 VALUES(1, 5, 6);
|
||||
INSERT INTO t1 VALUES(2, 6, 7);
|
||||
INSERT INTO t1 VALUES(3, 7, 8);
|
||||
INSERT INTO t1 VALUES(1, 8, 9);
|
||||
INSERT INTO t1 VALUES(2, 9, 0);
|
||||
}
|
||||
|
||||
proc do_vtab_test {tn sql vtsql {res {}}} {
|
||||
set ::lFilterSql [list]
|
||||
uplevel [list do_execsql_test $tn.1 $sql $res]
|
||||
uplevel [list do_test $tn.2 {set ::lFilterSql} [list {*}$vtsql]]
|
||||
}
|
||||
|
||||
do_vtab_test 5.1.1 {
|
||||
SELECT DISTINCT a FROM vt1
|
||||
} {
|
||||
{SELECT DISTINCT 0, a, 0, 0 FROM t1}
|
||||
} {1 2 3}
|
||||
|
||||
do_vtab_test 5.1.2 {
|
||||
SELECT DISTINCT a FROM vt1 ORDER BY a
|
||||
} {
|
||||
{SELECT rowid, a, b, c FROM t1 ORDER BY a}
|
||||
} {1 2 3}
|
||||
|
||||
do_vtab_test 5.1.3 {
|
||||
SELECT DISTINCT a FROM vt1 WHERE c IN (4,5,6,7,8)
|
||||
} {
|
||||
{SELECT DISTINCT 0, a, 0, 0 FROM t1 WHERE c IN (4,5,6,7,8)}
|
||||
} {2 3 1}
|
||||
|
||||
set ::vtab_handle_in 0
|
||||
do_vtab_test 5.1.4 {
|
||||
SELECT DISTINCT a FROM vt1 WHERE c IN (4,5,6,7,8)
|
||||
} {
|
||||
{SELECT DISTINCT 0, a, 0, 0 FROM t1 WHERE c = 4}
|
||||
{SELECT DISTINCT 0, a, 0, 0 FROM t1 WHERE c = 5}
|
||||
{SELECT DISTINCT 0, a, 0, 0 FROM t1 WHERE c = 6}
|
||||
{SELECT DISTINCT 0, a, 0, 0 FROM t1 WHERE c = 7}
|
||||
{SELECT DISTINCT 0, a, 0, 0 FROM t1 WHERE c = 8}
|
||||
} {2 3 1}
|
||||
|
||||
set ::vtab_handle_in 1
|
||||
do_vtab_test 5.1.5a {
|
||||
SELECT a, b, c FROM vt1 WHERE c IN (4,5,6,7,8) LIMIT 2 OFFSET 2
|
||||
} {
|
||||
{SELECT rowid, a, b, c FROM t1 WHERE c IN (4,5,6,7,8) LIMIT 2 OFFSET 2}
|
||||
} {1 5 6 2 6 7}
|
||||
|
||||
set ::vtab_handle_in 0
|
||||
do_vtab_test 5.1.5b {
|
||||
SELECT a, b, c FROM vt1 WHERE c IN (4,5,6,7,8) LIMIT 2 OFFSET 2
|
||||
} {
|
||||
{SELECT rowid, a, b, c FROM t1 WHERE c = 4}
|
||||
{SELECT rowid, a, b, c FROM t1 WHERE c = 5}
|
||||
{SELECT rowid, a, b, c FROM t1 WHERE c = 6}
|
||||
{SELECT rowid, a, b, c FROM t1 WHERE c = 7}
|
||||
} {1 5 6 2 6 7}
|
||||
set ::vtab_handle_in 1
|
||||
|
||||
finish_test
|
||||
@@ -0,0 +1,63 @@
|
||||
# 2022 Feb 10
|
||||
#
|
||||
# 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 bind2
|
||||
|
||||
|
||||
# Test that using bind_value() on a REAL sqlite3_value that was stored
|
||||
# as an INTEGER works properly.
|
||||
#
|
||||
# 1.1: An IntReal value read from a table,
|
||||
# 1.2: IntReal values obtained via the sqlite3_preupdate_old|new()
|
||||
# interfaces.
|
||||
#
|
||||
do_execsql_test 1.0 {
|
||||
CREATE TABLE t1(a REAL);
|
||||
INSERT INTO t1 VALUES(42.0);
|
||||
SELECT * FROM t1;
|
||||
} {42.0}
|
||||
|
||||
do_test 1.1 {
|
||||
set stmt [sqlite3_prepare db "SELECT ?" -1 tail]
|
||||
sqlite3_bind_value_from_select $stmt 1 "SELECT a FROM t1"
|
||||
sqlite3_step $stmt
|
||||
sqlite3_column_text $stmt 0
|
||||
} {42.0}
|
||||
sqlite3_finalize $stmt
|
||||
|
||||
ifcapable !preupdate {
|
||||
finish_test
|
||||
return
|
||||
}
|
||||
|
||||
proc preup {args} {
|
||||
set stmt [sqlite3_prepare db "SELECT ?" -1 tail]
|
||||
sqlite3_bind_value_from_preupdate $stmt 1 old 0
|
||||
sqlite3_step $stmt
|
||||
lappend ::reslist [sqlite3_column_text $stmt 0]
|
||||
sqlite3_reset $stmt
|
||||
sqlite3_bind_value_from_preupdate $stmt 1 new 0
|
||||
sqlite3_step $stmt
|
||||
lappend ::reslist [sqlite3_column_text $stmt 0]
|
||||
sqlite3_finalize $stmt
|
||||
}
|
||||
db preupdate hook preup
|
||||
|
||||
do_test 1.2 {
|
||||
set ::reslist [list]
|
||||
execsql { UPDATE t1 SET a=43; }
|
||||
set ::reslist
|
||||
} {42.0 43.0}
|
||||
|
||||
finish_test
|
||||
@@ -100,8 +100,32 @@ proc test_is_readonly {testname sql truth} {
|
||||
sqlite3_finalize $STMT
|
||||
set rc
|
||||
} $sql] $truth
|
||||
|
||||
# EVIDENCE-OF: R-61212-30018 If prepared statement X is an EXPLAIN or
|
||||
# EXPLAIN QUERY PLAN statement, then sqlite3_stmt_readonly(X) returns
|
||||
# the same value as if the EXPLAIN or EXPLAIN QUERY PLAN prefix were
|
||||
# omitted.
|
||||
#
|
||||
do_test $testname.explain [format {
|
||||
set DB [sqlite3_connection_pointer db]
|
||||
set STMT [sqlite3_prepare $DB {EXPLAIN %s} -1 TAIL]
|
||||
set rc [sqlite3_stmt_readonly $STMT]
|
||||
sqlite3_finalize $STMT
|
||||
set rc
|
||||
} $sql] $truth
|
||||
do_test $testname.eqp [format {
|
||||
set DB [sqlite3_connection_pointer db]
|
||||
set STMT [sqlite3_prepare $DB {EXPLAIN QUERY PLAN %s} -1 TAIL]
|
||||
set rc [sqlite3_stmt_readonly $STMT]
|
||||
sqlite3_finalize $STMT
|
||||
set rc
|
||||
} $sql] $truth
|
||||
}
|
||||
|
||||
# EVIDENCE-OF: R-23332-64992 The sqlite3_stmt_readonly(X) interface
|
||||
# returns true (non-zero) if and only if the prepared statement X makes
|
||||
# no direct changes to the content of the database file.
|
||||
#
|
||||
test_is_readonly capi3d-2.1 {SELECT * FROM sqlite_master} 1
|
||||
test_is_readonly capi3d-2.2 {CREATE TABLE t1(x)} 0
|
||||
db eval {CREATE TABLE t1(x)}
|
||||
@@ -120,6 +144,68 @@ do_test capi3-2.49 {
|
||||
} 1
|
||||
|
||||
|
||||
# EVIDENCE-OF: R-04929-09147 This routine returns false if there is any
|
||||
# possibility that the statement might change the database file.
|
||||
#
|
||||
# EVIDENCE-OF: R-13288-53765 A false return does not guarantee that the
|
||||
# statement will change the database file.
|
||||
#
|
||||
# EVIDENCE-OF: R-22182-18548 For example, an UPDATE statement might have
|
||||
# a WHERE clause that makes it a no-op, but the sqlite3_stmt_readonly()
|
||||
# result would still be false.
|
||||
#
|
||||
# EVIDENCE-OF: R-50998-48593 Similarly, a CREATE TABLE IF NOT EXISTS
|
||||
# statement is a read-only no-op if the table already exists, but
|
||||
# sqlite3_stmt_readonly() still returns false for such a statement.
|
||||
#
|
||||
db eval {
|
||||
CREATE TABLE t2(a,b,c);
|
||||
INSERT INTO t2 VALUES(1,2,3);
|
||||
}
|
||||
test_is_readonly capi3d-2.11 {UPDATE t2 SET a=a+1 WHERE false} 0
|
||||
test_is_readonly capi3d-2.12 {CREATE TABLE IF NOT EXISTS t2(x,y)} 0
|
||||
|
||||
|
||||
# EVIDENCE-OF: R-37014-01401 The ATTACH and DETACH statements also cause
|
||||
# sqlite3_stmt_readonly() to return true since, while those statements
|
||||
# change the configuration of a database connection, they do not make
|
||||
# changes to the content of the database files on disk.
|
||||
#
|
||||
test_is_readonly capi3d-2.13 {ATTACH ':memory:' AS mem1} 1
|
||||
db eval {ATTACH ':memory:' AS mem1}
|
||||
test_is_readonly capi3d-2.14 {DETACH mem1} 1
|
||||
db eval {DETACH mem1}
|
||||
|
||||
# EVIDENCE-OF: R-07474-04783 Transaction control statements such as
|
||||
# BEGIN, COMMIT, ROLLBACK, SAVEPOINT, and RELEASE cause
|
||||
# sqlite3_stmt_readonly() to return true, since the statements
|
||||
# themselves do not actually modify the database but rather they control
|
||||
# the timing of when other statements modify the database.
|
||||
#
|
||||
test_is_readonly capi3d-2.15 {BEGIN} 1
|
||||
test_is_readonly capi3d-2.16 {COMMIT} 1
|
||||
test_is_readonly capi3d-2.17 {SAVEPOINT one} 1
|
||||
test_is_readonly capi3d-2.18 {RELEASE one} 1
|
||||
|
||||
# EVIDENCE-OF: R-36961-63052 The sqlite3_stmt_readonly() interface
|
||||
# returns true for BEGIN since BEGIN merely sets internal flags, but the
|
||||
# BEGIN IMMEDIATE and BEGIN EXCLUSIVE commands do touch the database and
|
||||
# so sqlite3_stmt_readonly() returns false for those commands.
|
||||
#
|
||||
test_is_readonly capi3d-2.19 {BEGIN IMMEDIATE} 0
|
||||
test_is_readonly capi3d-2.20 {BEGIN EXCLUSIVE} 0
|
||||
|
||||
# EVIDENCE-OF: R-21769-42523 For example, if an application defines a
|
||||
# function "eval()" that calls sqlite3_exec(), then the following SQL
|
||||
# statement would change the database file through side-effects: SELECT
|
||||
# eval('DELETE FROM t1') FROM t2; But because the SELECT statement does
|
||||
# not change the database file directly, sqlite3_stmt_readonly() would
|
||||
# still return true.
|
||||
#
|
||||
proc evalsql {sql} {db eval $sql}
|
||||
db func eval evalsql
|
||||
test_is_readonly capi3d-2.21 {SELECT eval('DELETE FROM t1') FROM t2} 1
|
||||
|
||||
# Tests for the is-explain interface.
|
||||
#
|
||||
proc test_is_explain {testname sql truth} {
|
||||
|
||||
+60
-125
@@ -239,138 +239,70 @@ datetest 5.13 {datetime('1994-04-16 14:00:00Zulu')} NULL
|
||||
datetest 5.14 {datetime('1994-04-16 14:00:00Z +05:00')} NULL
|
||||
datetest 5.15 {datetime('1994-04-16 14:00:00 +05:00 Z')} NULL
|
||||
|
||||
# localtime->utc and utc->localtime conversions. These tests only work
|
||||
# if the localtime is in the US Eastern Time (the time in Charlotte, NC
|
||||
# and in New York.)
|
||||
# localtime->utc and utc->localtime conversions.
|
||||
#
|
||||
# On non-Vista Windows platform, '2006-03-31' is treated incorrectly as being
|
||||
# in DST giving a 4 hour offset instead of 5. In 2007, DST was extended to
|
||||
# start three weeks earlier (second Sunday in March) and end one week
|
||||
# later (first Sunday in November). Older Windows systems apply this
|
||||
# new rule incorrectly to dates prior to 2007.
|
||||
# Use SQLITE_TESTCTRL_LOCALTIME_FAULT=2 to set an alternative localtime_r()
|
||||
# implementation that is not locale-dependent. This testing localtime_r()
|
||||
# operates as follows:
|
||||
#
|
||||
# It might be argued that this is masking a problem on non-Vista Windows
|
||||
# platform. A ticket has already been opened for this issue
|
||||
# (http://www.sqlite.org/cvstrac/tktview?tn=2322). This is just to prevent
|
||||
# more confusion/reports of the issue.
|
||||
# (1) Localtime is 30 minutes earlier than (west of) UTC on
|
||||
# even days (counting from 1970-01-01)
|
||||
#
|
||||
|
||||
# $tzoffset_old should be 5 if DST is working correctly.
|
||||
set tzoffset_old [db one {
|
||||
SELECT CAST(24*(julianday('2006-03-31') -
|
||||
julianday('2006-03-31','localtime'))+0.5
|
||||
AS INT)
|
||||
}]
|
||||
|
||||
# $tzoffset_new should be 4 if DST is working correctly.
|
||||
set tzoffset_new [db one {
|
||||
SELECT CAST(24*(julianday('2007-03-31') -
|
||||
julianday('2007-03-31','localtime'))+0.5
|
||||
AS INT)
|
||||
}]
|
||||
|
||||
# Warn about possibly broken Windows DST implementations.
|
||||
if {$::tcl_platform(platform)=="windows" && $tzoffset_new==4 && $tzoffset_old==4} {
|
||||
puts "******************************************************************"
|
||||
puts "N.B.: The DST support provided by your current O/S seems to be"
|
||||
puts "suspect in that it is reporting incorrect DST values for dates"
|
||||
puts "prior to 2007. This is the known case for most (all?) non-Vista"
|
||||
puts "Windows versions. Please see ticket #2322 for more information."
|
||||
puts "******************************************************************"
|
||||
# (2) Localtime is 30 minutes later than (east of) UTC on odd days.
|
||||
#
|
||||
# (3) The function fails for the specific date/time value
|
||||
# of 2000-05-29 14:16:00 in order to test the ability of
|
||||
# SQLite to deal with localtime_r() failures.
|
||||
#
|
||||
proc local_to_utc {tn utc local} {
|
||||
do_execsql_test date-$tn "SELECT datetime('$utc','localtime')" [list $local]
|
||||
}
|
||||
proc utc_to_local {tn local utc} {
|
||||
do_execsql_test date-$tn "SELECT datetime('$local','utc')" [list $utc]
|
||||
}
|
||||
|
||||
if {$tzoffset_new==4} {
|
||||
datetest 6.1 {datetime('2000-10-29 05:59:00','localtime')}\
|
||||
{2000-10-29 01:59:00}
|
||||
datetest 6.1.1 {datetime('2006-10-29 05:59:00','localtime')}\
|
||||
{2006-10-29 01:59:00}
|
||||
datetest 6.1.2 {datetime('2007-11-04 05:59:00','localtime')}\
|
||||
{2007-11-04 01:59:00}
|
||||
sqlite3_test_control SQLITE_TESTCTRL_LOCALTIME_FAULT 2
|
||||
local_to_utc 6.1 {2000-10-29 12:00:00} {2000-10-29 12:30:00}
|
||||
utc_to_local 6.2 {2000-10-29 12:30:00} {2000-10-29 12:00:00}
|
||||
local_to_utc 6.3 {2000-10-30 12:00:00} {2000-10-30 11:30:00}
|
||||
utc_to_local 6.4 {2000-10-30 11:30:00} {2000-10-30 12:00:00}
|
||||
|
||||
# If the new and old DST rules seem to be working correctly...
|
||||
if {$tzoffset_new==4 && $tzoffset_old==5} {
|
||||
datetest 6.2 {datetime('2000-10-29 06:00:00','localtime')}\
|
||||
{2000-10-29 01:00:00}
|
||||
datetest 6.2.1 {datetime('2006-10-29 06:00:00','localtime')}\
|
||||
{2006-10-29 01:00:00}
|
||||
}
|
||||
datetest 6.2.2 {datetime('2007-11-04 06:00:00','localtime')}\
|
||||
{2007-11-04 01:00:00}
|
||||
local_to_utc 6.5 {2000-10-28 23:59:59} {2000-10-28 23:29:59}
|
||||
local_to_utc 6.6 {2000-10-29 00:00:00} {2000-10-29 00:30:00}
|
||||
|
||||
# If the new and old DST rules seem to be working correctly...
|
||||
if {$tzoffset_new==4 && $tzoffset_old==5} {
|
||||
datetest 6.3 {datetime('2000-04-02 06:59:00','localtime')}\
|
||||
{2000-04-02 01:59:00}
|
||||
datetest 6.3.1 {datetime('2006-04-02 06:59:00','localtime')}\
|
||||
{2006-04-02 01:59:00}
|
||||
}
|
||||
datetest 6.3.2 {datetime('2007-03-11 07:00:00','localtime')}\
|
||||
{2007-03-11 03:00:00}
|
||||
|
||||
datetest 6.4 {datetime('2000-04-02 07:00:00','localtime')}\
|
||||
{2000-04-02 03:00:00}
|
||||
datetest 6.4.1 {datetime('2006-04-02 07:00:00','localtime')}\
|
||||
{2006-04-02 03:00:00}
|
||||
datetest 6.4.2 {datetime('2007-03-11 07:00:00','localtime')}\
|
||||
{2007-03-11 03:00:00}
|
||||
|
||||
datetest 6.5 {datetime('2000-10-29 01:59:00','utc')} {2000-10-29 05:59:00}
|
||||
datetest 6.5.1 {datetime('2006-10-29 01:59:00','utc')} {2006-10-29 05:59:00}
|
||||
datetest 6.5.2 {datetime('2007-11-04 01:59:00','utc')} {2007-11-04 05:59:00}
|
||||
|
||||
# If the new and old DST rules seem to be working correctly...
|
||||
if {$tzoffset_new==4 && $tzoffset_old==5} {
|
||||
datetest 6.6 {datetime('2000-10-29 02:00:00','utc')} {2000-10-29 07:00:00}
|
||||
datetest 6.6.1 {datetime('2006-10-29 02:00:00','utc')} {2006-10-29 07:00:00}
|
||||
}
|
||||
datetest 6.6.2 {datetime('2007-11-04 02:00:00','utc')} {2007-11-04 07:00:00}
|
||||
|
||||
# If the new and old DST rules seem to be working correctly...
|
||||
if {$tzoffset_new==4 && $tzoffset_old==5} {
|
||||
datetest 6.7 {datetime('2000-04-02 01:59:00','utc')} {2000-04-02 06:59:00}
|
||||
datetest 6.7.1 {datetime('2006-04-02 01:59:00','utc')} {2006-04-02 06:59:00}
|
||||
}
|
||||
datetest 6.7.2 {datetime('2007-03-11 01:59:00','utc')} {2007-03-11 06:59:00}
|
||||
|
||||
datetest 6.8 {datetime('2000-04-02 02:00:00','utc')} {2000-04-02 06:00:00}
|
||||
datetest 6.8.1 {datetime('2006-04-02 02:00:00','utc')} {2006-04-02 06:00:00}
|
||||
datetest 6.8.2 {datetime('2007-03-11 02:00:00','utc')} {2007-03-11 06:00:00}
|
||||
|
||||
# The 'utc' modifier is a no-op if the LHS is known to already be in UTC
|
||||
datetest 6.9.1 {datetime('2015-12-23 12:00:00','utc')} {2015-12-23 17:00:00}
|
||||
datetest 6.9.2 {datetime('2015-12-23 12:00:00z','utc')} {2015-12-23 12:00:00}
|
||||
datetest 6.9.3 {datetime('2015-12-23 12:00:00-03:00','utc')} \
|
||||
{2015-12-23 15:00:00}
|
||||
datetest 6.9.4 {datetime('2015-12-23 12:00:00','utc','utc','utc')} \
|
||||
{2015-12-23 17:00:00}
|
||||
|
||||
|
||||
datetest 6.10 {datetime('2000-01-01 12:00:00','localtime')} \
|
||||
{2000-01-01 07:00:00}
|
||||
datetest 6.11 {datetime('1969-01-01 12:00:00','localtime')} \
|
||||
{1969-01-01 07:00:00}
|
||||
datetest 6.12 {datetime('2039-01-01 12:00:00','localtime')} \
|
||||
{2039-01-01 07:00:00}
|
||||
datetest 6.13 {datetime('2000-07-01 12:00:00','localtime')} \
|
||||
{2000-07-01 08:00:00}
|
||||
datetest 6.14 {datetime('1969-07-01 12:00:00','localtime')} \
|
||||
{1969-07-01 07:00:00}
|
||||
datetest 6.15 {datetime('2039-07-01 12:00:00','localtime')} \
|
||||
{2039-07-01 07:00:00}
|
||||
set sqlite_current_time \
|
||||
[db eval {SELECT strftime('%s','2000-07-01 12:34:56')}]
|
||||
datetest 6.16 {datetime('now','localtime')} {2000-07-01 08:34:56}
|
||||
datetest 6.17 {datetime('now','localtimex')} NULL
|
||||
datetest 6.18 {datetime('now','localtim')} NULL
|
||||
set sqlite_current_time 0
|
||||
}
|
||||
|
||||
# These two are a bit of a scam. They are added to ensure that 100% of
|
||||
# the date.c file is covered by testing, even when the time-zone
|
||||
# is not -0400 (the condition for running of the block of tests above).
|
||||
# The previous two cases establish that no such localtime as
|
||||
# 2000-10-29 00:10:00 exists. Verify that we get a reasonable
|
||||
# answer if we try to convert this non-existant localtime to utc?
|
||||
#
|
||||
datetest 6.19 {datetime('2039-07-01 12:00:00','localtime',null)} NULL
|
||||
datetest 6.20 {datetime('2039-07-01 12:00:00','utc',null)} NULL
|
||||
utc_to_local 6.7 {2000-10-29 00:10:00} {2000-10-28 23:40:00}
|
||||
|
||||
local_to_utc 6.8 {2022-02-10 23:59:59} {2022-02-11 00:29:59}
|
||||
local_to_utc 6.9 {2022-02-11 00:00:00} {2022-02-10 23:30:00}
|
||||
local_to_utc 6.10 {2022-02-10 23:45:00} {2022-02-11 00:15:00}
|
||||
local_to_utc 6.11 {2022-02-11 00:45:00} {2022-02-11 00:15:00}
|
||||
|
||||
# The previous two cases show that two different UTC values give
|
||||
# the same localtime of 2022-02-11 00:15:00. When converting from
|
||||
# that localtime back to UTC, we should get one or the other of
|
||||
# the two UTC values.
|
||||
#
|
||||
utc_to_local 6.12 {2022-02-11 00:15:00} {2022-02-11 00:45:00}
|
||||
|
||||
# If localtime_r() fails, the datetime() SQL function should raise an error
|
||||
#
|
||||
do_catchsql_test date-6.20 {
|
||||
SELECT datetime('2000-05-29 14:16:00','localtime');
|
||||
} {1 {local time unavailable}}
|
||||
|
||||
# Modifiers work for dates that are way out of band for localtime_r()
|
||||
#
|
||||
local_to_utc 6.21 {1800-10-29 12:00:00} {1800-10-29 12:30:00}
|
||||
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}
|
||||
|
||||
# Restore the use of the OS localtime_r() before going on...
|
||||
sqlite3_test_control SQLITE_TESTCTRL_LOCALTIME_FAULT 0
|
||||
|
||||
# Date-time functions that contain NULL arguments return a NULL
|
||||
# result.
|
||||
@@ -607,6 +539,9 @@ datetest 17.5 {datetime(2457828,'start of year')} {2017-01-01 00:00:00}
|
||||
datetest 17.6 {datetime(37,'start of year')} NULL
|
||||
datetest 17.7 {datetime(38,'start of year')} {-4712-01-01 00:00:00}
|
||||
|
||||
|
||||
# 2022-03-04 https://sqlite.org/forum/forumpost/2ffbaa2c3fd7fb82
|
||||
# The 'localtime' modifier should preserve fractional seconds.
|
||||
#
|
||||
datetest 18.1 {strftime('%f',1.234,'unixepoch','localtime')} {01.234}
|
||||
|
||||
finish_test
|
||||
|
||||
+149
@@ -0,0 +1,149 @@
|
||||
# 2022-01-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 regression tests for SQLite library. The
|
||||
# focus of this file is testing date and time functions.
|
||||
#
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
|
||||
# Skip this whole file if date and time functions are omitted
|
||||
# at compile-time
|
||||
#
|
||||
ifcapable {!datetime} {
|
||||
finish_test
|
||||
return
|
||||
}
|
||||
|
||||
proc datetest {tnum expr result} {
|
||||
do_test date3-$tnum [subst {
|
||||
execsql "SELECT coalesce($expr,'NULL')"
|
||||
}] [list $result]
|
||||
}
|
||||
set tcl_precision 15
|
||||
|
||||
# EVIDENCE-OF: R-45708-63005 unixepoch(time-value, modifier, modifier,
|
||||
# ...)
|
||||
#
|
||||
datetest 1.1 {unixepoch('1970-01-01')} {0}
|
||||
datetest 1.2 {unixepoch('1969-12-31 23:59:59')} {-1}
|
||||
datetest 1.3 {unixepoch('2106-02-07 06:28:15')} {4294967295}
|
||||
datetest 1.4 {unixepoch('2106-02-07 06:28:16')} {4294967296}
|
||||
datetest 1.5 {unixepoch('9999-12-31 23:59:59')} {253402300799}
|
||||
datetest 1.6 {unixepoch('0000-01-01 00:00:00')} {-62167219200}
|
||||
|
||||
# EVIDENCE-OF: R-30877-63179 The unixepoch() function returns a unix
|
||||
# timestamp - the number of seconds since 1970-01-01 00:00:00 UTC.
|
||||
#
|
||||
for {set i 1} {$i<=100} {incr i} {
|
||||
set x [expr {int(rand()*0xfffffffff)-0xffffffff}]
|
||||
datetest 1.7.$i "unixepoch($x,'unixepoch')==$x" {1}
|
||||
}
|
||||
|
||||
# EVIDENCE-OF: R-62992-54137 The unixepoch() always returns an integer,
|
||||
# even if the input time-value has millisecond precision.
|
||||
#
|
||||
datetest 1.8 {unixepoch('2022-01-27 12:59:28.052')} {1643288368}
|
||||
|
||||
# EVIDENCE-OF: R-05412-24332 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.
|
||||
#
|
||||
# EVIDENCE-OF: R-56763-40111 If the value is between 0.0 and
|
||||
# 5373484.499999, then it is interpreted as a julian day number
|
||||
# (corresponding to dates between -4713-11-24 12:00:00 and 9999-12-31
|
||||
# 23:59:59, inclusive).
|
||||
#
|
||||
# EVIDENCE-OF: R-07289-49223 For numeric 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.
|
||||
#
|
||||
# EVIDENCE-OF: R-20795-34947 Other numeric values are out of range and
|
||||
# cause a NULL return.
|
||||
#
|
||||
foreach {tn jd date} {
|
||||
2.1 0.0 {-4713-11-24 12:00:00}
|
||||
2.2 5373484.4999999 {9999-12-31 23:59:59}
|
||||
2.3 2440587.5 {1970-01-01 00:00:00}
|
||||
2.4 2440587.49998843 {1969-12-31 23:59:59}
|
||||
2.5 2440615.7475463 {1970-01-29 05:56:28}
|
||||
|
||||
2.10 -1 {1969-12-31 23:59:59}
|
||||
2.11 5373485 {1970-03-04 04:38:05}
|
||||
2.12 -210866760000 {-4713-11-24 12:00:00}
|
||||
2.13 253402300799 {9999-12-31 23:59:59}
|
||||
|
||||
2.20 -210866760001 {NULL}
|
||||
2.21 253402300800 {NULL}
|
||||
} {
|
||||
datetest $tn "datetime($jd,'auto')" $date
|
||||
}
|
||||
|
||||
# EVIDENCE-OF: R-38886-35357 The 'auto' modifier is a no-op for text
|
||||
# time-values.
|
||||
#
|
||||
datetest 2.30 {date('2022-01-29','auto')==date('2022-01-29')} {1}
|
||||
|
||||
# EVIDENCE-OF: R-53132-26856 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.
|
||||
#
|
||||
do_execsql_test date3-2.40 {
|
||||
WITH tx(timeval,datetime) AS (
|
||||
VALUES('2022-01-27 13:15:44','2022-01-27 13:15:44'),
|
||||
(2459607.05260275,'2022-01-27 13:15:44'),
|
||||
(1643289344,'2022-01-27 13:15:44')
|
||||
)
|
||||
SELECT datetime(timeval,'auto') == datetime FROM tx;
|
||||
} {1 1 1}
|
||||
|
||||
# EVIDENCE-OF: R-49255-55373 The "unixepoch" modifier (11) only works if
|
||||
# it immediately follows a time value in the DDDDDDDDDD format.
|
||||
#
|
||||
# EVIDENCE-OF: R-23075-39245 This modifier causes the DDDDDDDDDD to be
|
||||
# interpreted not as a Julian day number as it normally would be, but as
|
||||
# Unix Time - the number of seconds since 1970.
|
||||
#
|
||||
datetest 3.1 {datetime(2459607.05,'+1 hour','unixepoch')} {NULL}
|
||||
datetest 3.2 {datetime(2459607.05,'unixepoch','+1 hour')} {1970-01-29 12:13:27}
|
||||
|
||||
# EVIDENCE-OF: R-21150-52363 The "julianday" modifier must immediately
|
||||
# follow the initial time-value which must be of the form DDDDDDDDD.
|
||||
#
|
||||
# EVIDENCE-OF: R-31176-64601 Any other use of the 'julianday' modifier
|
||||
# is an error and causes the function to return NULL.
|
||||
#
|
||||
# EVIDENCE-OF: R-32483-36353 The 'julianday' modifier forces the
|
||||
# time-value number to be interpreted as a julian-day number.
|
||||
#
|
||||
# EVIDENCE-OF: R-25859-20124 The only difference is that adding
|
||||
# 'julianday' forces the DDDDDDDDD time-value format, and causes a NULL
|
||||
# to be returned if any other time-value format is used.
|
||||
#
|
||||
datetest 4.1 {datetime(2459607,'julianday')} {2022-01-27 12:00:00}
|
||||
datetest 4.2 {datetime(2459607,'+1 hour','julianday')} {NULL}
|
||||
datetest 4.3 {datetime('2022-01-27','julianday')} {NULL}
|
||||
|
||||
|
||||
|
||||
# EVIDENCE-OF: R-33431-18865 Unix timestamps for the first 63 days of
|
||||
# 1970 will be interpreted as julian day numbers.
|
||||
#
|
||||
do_execsql_test date3-5.0 {
|
||||
WITH inc(x) AS (VALUES(-10) UNION ALL SELECT x+1 FROM inc WHERE x<100)
|
||||
SELECT count(*) FROM inc
|
||||
WHERE datetime('1970-01-01',format('%+d days',x))
|
||||
<> datetime(unixepoch('1970-01-01',format('%+d days',x)),'auto');
|
||||
} {63}
|
||||
|
||||
finish_test
|
||||
@@ -102,4 +102,10 @@ do_catchsql_test 270 {
|
||||
PRAGMA aux1.integrity_check;
|
||||
} {0 ok}
|
||||
|
||||
db close
|
||||
sqlite3 db :memory:
|
||||
do_execsql_test 300 {
|
||||
SELECT * FROM sqlite_temp_schema, sqlite_dbpage;
|
||||
} {}
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -493,10 +493,10 @@ do_execsql_test e_createtable-1.7.0 {
|
||||
do_createtable_tests 1.7.1 -error { %s } {
|
||||
1 "CREATE TABLE t1(a, b)" {{table t1 already exists}}
|
||||
2 "CREATE TABLE i1(a, b)" {{there is already an index named i1}}
|
||||
3 "CREATE TABLE v1(a, b)" {{table v1 already exists}}
|
||||
3 "CREATE TABLE v1(a, b)" {{view v1 already exists}}
|
||||
4 "CREATE TABLE auxa.tbl1(a, b)" {{table tbl1 already exists}}
|
||||
5 "CREATE TABLE auxa.idx1(a, b)" {{there is already an index named idx1}}
|
||||
6 "CREATE TABLE auxa.view1(a, b)" {{table view1 already exists}}
|
||||
6 "CREATE TABLE auxa.view1(a, b)" {{view view1 already exists}}
|
||||
}
|
||||
do_createtable_tests 1.7.2 {
|
||||
1 "CREATE TABLE auxa.t1(a, b)" {}
|
||||
|
||||
@@ -171,4 +171,13 @@ do_execsql_test func6-200 {
|
||||
SELECT offrec( sqlite_offset(y), x, y ) FROM t2 ORDER BY x
|
||||
} $z100
|
||||
|
||||
# 2022-03-14 dbsqlfuzz 474499f3977d95fdf2dbcd99c50be1d0082e4c92
|
||||
reset_db
|
||||
do_execsql_test func6-300 {
|
||||
CREATE TABLE t2(a INT, b INT PRIMARY KEY) WITHOUT ROWID;
|
||||
CREATE INDEX x3 ON t2(b);
|
||||
CREATE TABLE t1(a INT PRIMARY KEY, b TEXT);
|
||||
SELECT * FROM t1 WHERE a IN (SELECT sqlite_offset(b) FROM t2);
|
||||
} {}
|
||||
|
||||
finish_test
|
||||
|
||||
+1
-1
@@ -372,7 +372,7 @@ integrity_check fuzz-7.5.integrity
|
||||
#----------------------------------------------------------------
|
||||
# Many CREATE and DROP TABLE statements:
|
||||
#
|
||||
set E [list table duplicate {no such col} {ambiguous column name} {use DROP}]
|
||||
set E [list table view duplicate {no such col} {ambiguous column name} {use DROP}]
|
||||
do_fuzzy_test fuzz-8.1 -template {[CreateOrDropTableOrView]} -errorlist $E
|
||||
|
||||
close $::log
|
||||
|
||||
@@ -156,6 +156,14 @@ static struct GlobalVars {
|
||||
char zTestName[100]; /* Name of current test */
|
||||
} g;
|
||||
|
||||
/*
|
||||
** Include the external vt02.c module, if requested by compile-time
|
||||
** options.
|
||||
*/
|
||||
#ifdef VT02_SOURCES
|
||||
# include "vt02.c"
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Print an error message and quit.
|
||||
*/
|
||||
@@ -1052,6 +1060,10 @@ int runCombinedDbSqlInput(
|
||||
** deserialize to do this because deserialize depends on ATTACH */
|
||||
sqlite3_set_authorizer(cx.db, block_troublesome_sql, 0);
|
||||
|
||||
#ifdef VT02_SOURCES
|
||||
sqlite3_vt02_init(cx.db, 0, 0);
|
||||
#endif
|
||||
|
||||
/* Consistent PRNG seed */
|
||||
#ifdef SQLITE_TESTCTRL_PRNG_SEED
|
||||
sqlite3_table_column_metadata(cx.db, 0, "x", 0, 0, 0, 0, 0, 0);
|
||||
|
||||
Binary file not shown.
+7
-1
@@ -11,7 +11,6 @@
|
||||
# This file implements regression tests for SQLite library. The
|
||||
# focus of this file is testing the INSERT transfer optimization.
|
||||
#
|
||||
# $Id: insert4.test,v 1.10 2008/01/21 16:22:46 drh Exp $
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
@@ -598,6 +597,13 @@ do_test 10.3 {
|
||||
set sqlite3_xferopt_count
|
||||
} {1}
|
||||
|
||||
do_test 10.4 {
|
||||
execsql { PRAGMA integrity_check }
|
||||
set sqlite3_xferopt_count 0
|
||||
execsql { INSERT INTO x SELECT * FROM t8 RETURNING * }
|
||||
set sqlite3_xferopt_count
|
||||
} {0}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# xfer transfer between tables where the source has an empty partial index.
|
||||
#
|
||||
|
||||
@@ -300,6 +300,13 @@ do_execsql_test 7.3 {
|
||||
|
||||
do_eqp_test 7.4 {
|
||||
SELECT * FROM t3 LEFT JOIN t4 ON (t4.x = t3.x) WHERE (t4.y = ? OR t4.z = ?);
|
||||
} {
|
||||
QUERY PLAN
|
||||
|--SCAN t3
|
||||
`--SEARCH t4 USING INDEX t4xz (x=?)
|
||||
}
|
||||
do_eqp_test 7.4b {
|
||||
SELECT * FROM t3 CROSS JOIN t4 ON (t4.x = t3.x) WHERE (+t4.y = ? OR t4.z = ?);
|
||||
} {
|
||||
QUERY PLAN
|
||||
|--SCAN t3
|
||||
@@ -328,4 +335,64 @@ do_execsql_test 8.1 {
|
||||
2 10 2
|
||||
}
|
||||
|
||||
|
||||
# 2022-01-31 dbsqlfuzz 787d9bd73164c6f0c85469e2e48b2aff19af6938
|
||||
#
|
||||
reset_db
|
||||
do_execsql_test 9.1 {
|
||||
CREATE TABLE t1(a ,b FLOAT);
|
||||
INSERT INTO t1 VALUES(1,1);
|
||||
CREATE INDEX t1x1 ON t1(a,b,a,a,a,a,a,a,a,a,a,b);
|
||||
ANALYZE sqlite_schema;
|
||||
INSERT INTO sqlite_stat1 VALUES('t1','t1x1','648 324 81 81 81 81 81 81 81081 81 81 81');
|
||||
ANALYZE sqlite_schema;
|
||||
SELECT a FROM (SELECT a FROM t1 NATURAL LEFT JOIN t1) NATURAL LEFT JOIN t1 WHERE (rowid,1)<=(5,0);
|
||||
} {1}
|
||||
|
||||
# 2022-03-02 https://sqlite.org/forum/info/50a1bbe08ce4c29c
|
||||
# Bloom-filter pulldown is incompatible with skip-scan.
|
||||
#
|
||||
reset_db
|
||||
do_execsql_test 10.1 {
|
||||
CREATE TABLE t1(x INT);
|
||||
WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<20)
|
||||
INSERT INTO t1(x) SELECT 0 FROM c;
|
||||
CREATE INDEX t1x1 ON t1(x BETWEEN 0 AND 10, x);
|
||||
ANALYZE;
|
||||
DELETE FROM t1;
|
||||
INSERT INTO t1 VALUES(0),(0);
|
||||
CREATE VIEW v1 AS SELECT * FROM t1 NATURAL JOIN t1 WHERE (x BETWEEN 0 AND 10) OR true;
|
||||
CREATE VIEW v2 AS SELECT * FROM v1 NATURAL JOIN v1;
|
||||
CREATE VIEW v3 AS SELECT * FROM v2, v1 USING (x) GROUP BY x;
|
||||
SELECT x FROM v3;
|
||||
} {0}
|
||||
|
||||
# 2022-03-24 https://sqlite.org/forum/forumpost/031e262a89b6a9d2
|
||||
# Bloom-filter on a LEFT JOIN with NULL-based WHERE constraints.
|
||||
#
|
||||
reset_db
|
||||
do_execsql_test 11.1 {
|
||||
CREATE TABLE t1(a INTEGER PRIMARY KEY, b INT);
|
||||
CREATE TABLE t2(c INTEGER PRIMARY KEY, d INT);
|
||||
WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<8)
|
||||
INSERT INTO t1(a,b) SELECT x, 10*x FROM c;
|
||||
INSERT INTO t2(c,d) SELECT b*2, 100*a FROM t1;
|
||||
ANALYZE;
|
||||
DELETE FROM sqlite_stat1;
|
||||
INSERT INTO sqlite_stat1(tbl,idx,stat) VALUES
|
||||
('t1',NULL,150105),('t2',NULL,98747);
|
||||
ANALYZE sqlite_schema;
|
||||
} {}
|
||||
do_execsql_test 11.2 {
|
||||
SELECT count(*) FROM t1 LEFT JOIN t2 ON c=b WHERE d IS NULL;
|
||||
} {4}
|
||||
do_execsql_test 11.3 {
|
||||
SELECT count(*) FROM t1 LEFT JOIN t2 ON c=b WHERE d=100;
|
||||
} {1}
|
||||
do_execsql_test 11.4 {
|
||||
SELECT count(*) FROM t1 LEFT JOIN t2 ON c=b WHERE d>=300;
|
||||
} {2}
|
||||
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
+8
-5
@@ -15,11 +15,6 @@
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
|
||||
ifcapable !json1 {
|
||||
finish_test
|
||||
return
|
||||
}
|
||||
|
||||
do_execsql_test json101-1.1.00 {
|
||||
SELECT json_array(1,2.5,null,'hello');
|
||||
} {[1,2.5,null,"hello"]}
|
||||
@@ -846,5 +841,13 @@ do_execsql_test json-16.30 {
|
||||
SELECT unicode(json_extract('"\uD834\uDD1E"','$'));
|
||||
} {119070}
|
||||
|
||||
# 2022-01-30 dbsqlfuzz 4678cf825d27f87c9b8343720121e12cf944b71a
|
||||
do_execsql_test json-17.1 {
|
||||
DROP TABLE IF EXISTS t1;
|
||||
DROP TABLE IF EXISTS t2;
|
||||
CREATE TABLE t1(a,b,c);
|
||||
CREATE TABLE t2(d);
|
||||
SELECT * FROM t1 LEFT JOIN t2 ON (SELECT b FROM json_each ORDER BY 1);
|
||||
} {}
|
||||
|
||||
finish_test
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user