Compare commits

..

12 Commits

Author SHA1 Message Date
drh 4760a0655f The ability to DROP multiple tables (or views or indexes or triggers) at once,
as implemented by this branch, appears to work.  However, this branch adds over
1000 bytes to the code footprint.  And the changes is significant, adding risk.
The benefit of being able to drop multiple tables in a single statement is not
seen to be enough to overcome those downsides, and so there are no immediate
plans to merge this branch.

FossilOrigin-Name: 1a49788afd90fa4415c6aae4b6bbad68f9306c1df1026762a9d88bcb40e4cd8f
2024-03-04 18:02:36 +00:00
drh 313aaff7cd Remove an unused line of code.
FossilOrigin-Name: 26272590691aee8569a1ea9c233f9b0e55ece63ed167696cc1ecfe3ca2548ba1
2024-03-02 12:17:08 +00:00
drh 4859e9c642 Simplifications to multi-DROP logic.
FossilOrigin-Name: e70d6be7511837ff11deac10b335e0f613dfa6dedcab269df9ce61c8d8495d2a
2024-03-02 11:02:04 +00:00
drh 3ffea6bc31 Improved rebustness against OOM and corruption.
FossilOrigin-Name: 3992f45033d7c1eb7b2bf7790fbf301c495f3e6ef1610a8d66d7357270a227e4
2024-03-02 00:29:11 +00:00
drh c5c3cde0e3 When doing DROP TABLE or DROP INDEX, use a heap to ensure that the various
btrees are dropped in the right order for autovacuum.

FossilOrigin-Name: e5bf9556ffd1d0880cc982d389e229246d0f3ddce4264905c6a7dd9c55d735e8
2024-03-01 22:42:16 +00:00
drh 29962f9194 RTREE uses multi-DROP to erase shadow tables.
FossilOrigin-Name: cf8a58d679d0cd30bf7c9208780855f0567b5e086422d59e3254b907923e0dd1
2024-03-01 19:08:45 +00:00
drh 0809210f9d Omit unreachable branches in the parser.
FossilOrigin-Name: 90de1f73f9aaab321c0f94b41b6d76ea966d8413d5ad864311d462780e1eadcc
2024-03-01 18:05:57 +00:00
drh b3e1f4cc3c Fix harmless compiler warning.
FossilOrigin-Name: 33d3bb848b578d8e7d1029c6603785d90c399d6bc5075d306561fc3c1ab8f202
2024-03-01 15:56:51 +00:00
drh b0f9538628 Improved handling of foreign-key constraints on a multi-drop of tables.
FossilOrigin-Name: 144e332f44b266a0e594f990088faccd1f0f08fe8e84f2efc9467d99fc14e84b
2024-03-01 14:47:01 +00:00
drh 19fb027eb5 When doing a multi-drop, delete btrees beginning with the largest root page
first and working toward smaller root pages, to avoid problems with root page
renumbering due to autovacuum.

FossilOrigin-Name: 37d4c5e207888b49c224275b05abfc1f63a2d8d2133bcc8970188b15387926ef
2024-03-01 12:21:45 +00:00
drh c3004fc223 Attempt to fix multi-object DROP. Working better, but still not perfect.
FossilOrigin-Name: 02f9fc73eef80f528097581580977aae46942baac2d7fb205c52f7f25472f2a8
2024-02-29 19:40:38 +00:00
drh 6b4c974bec Add the ability to DROP one or more objects of the same class
in a single statement by listing the objects as multiple arguments to the
DROP command.

FossilOrigin-Name: 2266086cf08ee710338667d1cf0b1e81ce7380101707db272ce27124404068a0
2024-02-29 13:44:15 +00:00
77 changed files with 954 additions and 1527 deletions
+30 -32
View File
@@ -1156,37 +1156,35 @@ keywordhash.h: $(TOP)/tool/mkkeywordhash.c
$(BCC) -o mkkeywordhash$(BEXE) $(OPT_FEATURE_FLAGS) $(OPTS) $(TOP)/tool/mkkeywordhash.c
./mkkeywordhash$(BEXE) >keywordhash.h
# Source and header files that shell.c depends on
SHELL_DEP = \
$(TOP)/src/shell.c.in \
$(TOP)/ext/consio/console_io.c \
$(TOP)/ext/consio/console_io.h \
$(TOP)/ext/expert/sqlite3expert.c \
$(TOP)/ext/expert/sqlite3expert.h \
$(TOP)/ext/intck/sqlite3intck.c \
$(TOP)/ext/intck/sqlite3intck.h \
$(TOP)/ext/misc/appendvfs.c \
$(TOP)/ext/misc/base64.c \
$(TOP)/ext/misc/base85.c \
$(TOP)/ext/misc/completion.c \
$(TOP)/ext/misc/decimal.c \
$(TOP)/ext/misc/fileio.c \
$(TOP)/ext/misc/ieee754.c \
$(TOP)/ext/misc/memtrace.c \
$(TOP)/ext/misc/pcachetrace.c \
$(TOP)/ext/misc/regexp.c \
$(TOP)/ext/misc/series.c \
$(TOP)/ext/misc/shathree.c \
$(TOP)/ext/misc/sqlar.c \
$(TOP)/ext/misc/uint.c \
$(TOP)/ext/misc/zipfile.c \
$(TOP)/ext/recover/dbdata.c \
$(TOP)/ext/recover/sqlite3recover.c \
$(TOP)/ext/recover/sqlite3recover.h \
$(TOP)/src/test_windirent.c \
$(TOP)/src/test_windirent.h
# Source files that go into making shell.c
SHELL_SRC = \
$(TOP)/src/shell.c.in \
$(TOP)/ext/consio/console_io.c \
$(TOP)/ext/consio/console_io.h \
$(TOP)/ext/misc/appendvfs.c \
$(TOP)/ext/misc/completion.c \
$(TOP)/ext/misc/decimal.c \
$(TOP)/ext/misc/basexx.c \
$(TOP)/ext/misc/base64.c \
$(TOP)/ext/misc/base85.c \
$(TOP)/ext/misc/fileio.c \
$(TOP)/ext/misc/ieee754.c \
$(TOP)/ext/misc/regexp.c \
$(TOP)/ext/misc/series.c \
$(TOP)/ext/misc/shathree.c \
$(TOP)/ext/misc/sqlar.c \
$(TOP)/ext/misc/uint.c \
$(TOP)/ext/expert/sqlite3expert.c \
$(TOP)/ext/expert/sqlite3expert.h \
$(TOP)/ext/misc/zipfile.c \
$(TOP)/ext/misc/memtrace.c \
$(TOP)/ext/misc/pcachetrace.c \
$(TOP)/ext/recover/dbdata.c \
$(TOP)/ext/recover/sqlite3recover.c \
$(TOP)/ext/recover/sqlite3recover.h \
$(TOP)/src/test_windirent.c
shell.c: $(SHELL_DEP) $(TOP)/tool/mkshellc.tcl has_tclsh84
shell.c: $(SHELL_SRC) $(TOP)/tool/mkshellc.tcl has_tclsh84
$(TCLSH_CMD) $(TOP)/tool/mkshellc.tcl >shell.c
@@ -1314,9 +1312,9 @@ testfixture$(TEXE): has_tclsh85 $(TESTFIXTURE_SRC)
$(LTLINK) -DSQLITE_NO_SYNC=1 $(TEMP_STORE) $(TESTFIXTURE_FLAGS) \
-o $@ $(TESTFIXTURE_SRC) $(LIBTCL) $(TLIBS)
coretestprogs: testfixture$(BEXE) sqlite3$(BEXE)
coretestprogs: $(TESTPROGS)
testprogs: $(TESTPROGS) srcck1$(BEXE) fuzzcheck$(TEXE) sessionfuzz$(TEXE)
testprogs: coretestprogs srcck1$(BEXE) fuzzcheck$(TEXE) sessionfuzz$(TEXE)
# A very detailed test running most or all test cases
fulltest: alltest fuzztest
+30 -35
View File
@@ -2272,44 +2272,39 @@ mkkeywordhash.exe: $(TOP)\tool\mkkeywordhash.c
keywordhash.h: $(TOP)\tool\mkkeywordhash.c mkkeywordhash.exe
.\mkkeywordhash.exe > keywordhash.h
# Source and header files that shell.c depends on
SHELL_DEP = \
$(TOP)\src\shell.c.in \
$(TOP)\ext\consio\console_io.c \
$(TOP)\ext\consio\console_io.h \
$(TOP)\ext\expert\sqlite3expert.c \
$(TOP)\ext\expert\sqlite3expert.h \
$(TOP)\ext\intck\sqlite3intck.c \
$(TOP)\ext\intck\sqlite3intck.h \
$(TOP)\ext\misc\appendvfs.c \
$(TOP)\ext\misc\base64.c \
$(TOP)\ext\misc\base85.c \
$(TOP)\ext\misc\completion.c \
$(TOP)\ext\misc\decimal.c \
$(TOP)\ext\misc\fileio.c \
$(TOP)\ext\misc\ieee754.c \
$(TOP)\ext\misc\memtrace.c \
$(TOP)\ext\misc\pcachetrace.c \
$(TOP)\ext\misc\regexp.c \
$(TOP)\ext\misc\series.c \
$(TOP)\ext\misc\shathree.c \
$(TOP)\ext\misc\sqlar.c \
$(TOP)\ext\misc\uint.c \
$(TOP)\ext\misc\zipfile.c \
$(TOP)\ext\recover\dbdata.c \
$(TOP)\ext\recover\sqlite3recover.c \
$(TOP)\ext\recover\sqlite3recover.h \
$(TOP)\src\test_windirent.c \
$(TOP)\src\test_windirent.h
# Source files that go into making shell.c
SHELL_SRC = \
$(TOP)\src\shell.c.in \
$(TOP)\ext\consio\console_io.c \
$(TOP)\ext\consio\console_io.h \
$(TOP)\ext\misc\appendvfs.c \
$(TOP)\ext\misc\completion.c \
$(TOP)\ext\misc\base64.c \
$(TOP)\ext\misc\base85.c \
$(TOP)\ext\misc\decimal.c \
$(TOP)\ext\misc\fileio.c \
$(TOP)\ext\misc\ieee754.c \
$(TOP)\ext\misc\regexp.c \
$(TOP)\ext\misc\series.c \
$(TOP)\ext\misc\shathree.c \
$(TOP)\ext\misc\uint.c \
$(TOP)\ext\expert\sqlite3expert.c \
$(TOP)\ext\expert\sqlite3expert.h \
$(TOP)\ext\misc\memtrace.c \
$(TOP)\ext\misc\pcachetrace.c \
$(TOP)\ext\recover\dbdata.c \
$(TOP)\ext\recover\sqlite3recover.c \
$(TOP)\ext\recover\sqlite3recover.h \
$(TOP)\src\test_windirent.c
# If use of zlib is enabled, add the "zipfile.c" source file.
#
!IF $(USE_ZLIB)!=0
SHELL_DEP = $(SHELL_DEP) $(TOP)\ext\misc\sqlar.c
SHELL_DEP = $(SHELL_DEP) $(TOP)\ext\misc\zipfile.c
SHELL_SRC = $(SHELL_SRC) $(TOP)\ext\misc\sqlar.c
SHELL_SRC = $(SHELL_SRC) $(TOP)\ext\misc\zipfile.c
!ENDIF
shell.c: $(SHELL_DEP) $(TOP)\tool\mkshellc.tcl
shell.c: $(SHELL_SRC) $(TOP)\tool\mkshellc.tcl
$(TCLSH_CMD) $(TOP)\tool\mkshellc.tcl > shell.c
zlib:
@@ -2496,9 +2491,9 @@ extensiontest: testfixture.exe testloadext.dll
tool-zip: testfixture.exe sqlite3.exe sqldiff.exe sqlite3_analyzer.exe $(TOP)\tool\mktoolzip.tcl
.\testfixture.exe $(TOP)\tool\mktoolzip.tcl
coretestprogs: testfixture.exe sqlite3.exe
coretestprogs: $(TESTPROGS)
testprogs: $(TESTPROGS) srcck1.exe fuzzcheck.exe sessionfuzz.exe
testprogs: coretestprogs srcck1.exe fuzzcheck.exe sessionfuzz.exe
fulltest: alltest fuzztest
@@ -2553,7 +2548,7 @@ mdevtest:
# Testing for a release
#
releasetest: testfixture.exe
releasetest: testfixture.exe fuzztest
testfixture.exe $(TOP)\test\testrunner.tcl release
-1
View File
@@ -8,7 +8,6 @@
# May you share freely, never taking more than you give.
#
#***********************************************************************
# TESTRUNNER: shell
#
# The focus of this file is testing the CLI shell tool. Specifically,
# the ".recommend" command.
+1 -1
View File
@@ -1948,7 +1948,7 @@ sqlite3expert *sqlite3_expert_new(sqlite3 *db, char **pzErrmsg){
sqlite3_stmt *pSql = 0;
rc = idxPrintfPrepareStmt(pNew->db, &pSql, pzErrmsg,
"SELECT sql FROM sqlite_schema WHERE name NOT LIKE 'sqlite_%%'"
" AND sql NOT LIKE 'CREATE VIRTUAL %%' ORDER BY rowid"
" AND sql NOT LIKE 'CREATE VIRTUAL %%'"
);
while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pSql) ){
const char *zSql = (const char*)sqlite3_column_text(pSql, 0);
-1
View File
@@ -15,7 +15,6 @@
source [file join [file dirname [info script]] intck_common.tcl]
set testprefix intck1
return_if_no_intck
foreach {tn sql} {
1 "CREATE TABLE t1(a PRIMARY KEY, b)"
-1
View File
@@ -15,7 +15,6 @@
source [file join [file dirname [info script]] intck_common.tcl]
set testprefix intck2
return_if_no_intck
do_execsql_test 1.0 {
-10
View File
@@ -15,16 +15,6 @@ if {![info exists testdir]} {
}
source $testdir/tester.tcl
ifcapable !vtab||!pragma {
proc return_if_no_intck {} {
finish_test
return -code return
}
return
} else {
proc return_if_no_intck {} {}
}
proc do_intck {db {bSuspend 0}} {
set ic [sqlite3_intck $db main]
-1
View File
@@ -12,7 +12,6 @@
source [file join [file dirname [info script]] intck_common.tcl]
set testprefix intckbusy
return_if_no_intck
-1
View File
@@ -15,7 +15,6 @@
source [file join [file dirname [info script]] intck_common.tcl]
set testprefix intckcorrupt
return_if_no_intck
#-------------------------------------------------------------------------
reset_db
+4 -1
View File
@@ -12,7 +12,8 @@
source [file join [file dirname [info script]] intck_common.tcl]
set testprefix intckfault
return_if_no_intck
do_execsql_test 1.0 {
CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c);
@@ -35,6 +36,8 @@ do_faultsim_test 1 -faults oom-t* -prep {
set res
} -test {
catch { $::ic close }
puts $testresult
puts $testnfail
faultsim_test_result {0 {SQLITE_OK {}}} {0 {SQLITE_NOMEM {}}} {0 {SQLITE_NOMEM {out of memory}}}
}
+3 -2
View File
@@ -422,7 +422,7 @@ static const char *intckParseCreateIndex(const char *z, int iCol, int *pnByte){
int n = intckGetToken(&z[iOff]);
if( n==5 && 0==sqlite3_strnicmp(&z[iOff], "where", 5) ){
zRet = &z[iOff+5];
nRet = (int)strlen(zRet);
nRet = strlen(zRet);
}
iOff += n;
}
@@ -785,7 +785,7 @@ int sqlite3_intck_open(
sqlite3_intck *pNew = 0;
int rc = SQLITE_OK;
const char *zDb = zDbArg ? zDbArg : "main";
int nDb = (int)strlen(zDb);
int nDb = strlen(zDb);
pNew = (sqlite3_intck*)sqlite3_malloc(sizeof(*pNew) + nDb + 1);
if( pNew==0 ){
@@ -938,3 +938,4 @@ const char *sqlite3_intck_test_sql(sqlite3_intck *p, const char *zObj){
}
return p->zTestSql;
}
+3 -3
View File
@@ -79,7 +79,7 @@ static int testIntckCmd(
}
case 1: assert( 0==strcmp("step", aCmd[iIdx].zName) ); {
rc = sqlite3_intck_step(p->intck);
int rc = sqlite3_intck_step(p->intck);
Tcl_SetObjResult(interp, Tcl_NewStringObj(sqlite3ErrName(rc), -1));
break;
}
@@ -92,7 +92,7 @@ static int testIntckCmd(
case 3: assert( 0==strcmp("error", aCmd[iIdx].zName) ); {
const char *zErr = 0;
rc = sqlite3_intck_error(p->intck, 0);
int rc = sqlite3_intck_error(p->intck, 0);
Tcl_Obj *pRes = Tcl_NewObj();
Tcl_ListObjAppendElement(
interp, pRes, Tcl_NewStringObj(sqlite3ErrName(rc), -1)
@@ -106,7 +106,7 @@ static int testIntckCmd(
}
case 4: assert( 0==strcmp("unlock", aCmd[iIdx].zName) ); {
rc = sqlite3_intck_unlock(p->intck);
int rc = sqlite3_intck_unlock(p->intck);
Tcl_SetObjResult(interp, Tcl_NewStringObj(sqlite3ErrName(rc), -1));
break;
}
+4 -7
View File
@@ -1053,9 +1053,9 @@ static int rtreeDestroy(sqlite3_vtab *pVtab){
Rtree *pRtree = (Rtree *)pVtab;
int rc;
char *zCreate = sqlite3_mprintf(
"DROP TABLE '%q'.'%q_node';"
"DROP TABLE '%q'.'%q_rowid';"
"DROP TABLE '%q'.'%q_parent';",
"DROP TABLE '%q'.'%q_node',"
"'%q'.'%q_rowid',"
"'%q'.'%q_parent';",
pRtree->zDb, pRtree->zName,
pRtree->zDb, pRtree->zName,
pRtree->zDb, pRtree->zName
@@ -1841,8 +1841,6 @@ static int deserializeGeometry(sqlite3_value *pValue, RtreeConstraint *pCons){
return SQLITE_OK;
}
int sqlite3IntFloatCompare(i64,double);
/*
** Rtree virtual table module xFilter method.
*/
@@ -1872,8 +1870,7 @@ static int rtreeFilter(
i64 iNode = 0;
int eType = sqlite3_value_numeric_type(argv[0]);
if( eType==SQLITE_INTEGER
|| (eType==SQLITE_FLOAT
&& 0==sqlite3IntFloatCompare(iRowid,sqlite3_value_double(argv[0])))
|| (eType==SQLITE_FLOAT && sqlite3_value_double(argv[0])==iRowid)
){
rc = findLeafNode(pRtree, iRowid, &pLeaf, &iNode);
}else{
-18
View File
@@ -797,22 +797,4 @@ do_test 23.0 {
db eval {PRAGMA integrity_check;}
} {ok}
reset_db
do_execsql_test 24.0 {
CREATE VIRTUAL TABLE rt1 USING rtree_i32(rid, c1, c2);
INSERT INTO rt1(rid, c1, c2) VALUES (9223372036854775807, 10, 18);
}
do_execsql_test 24.1 {
SELECT (rid = (CAST (9223372036854775807 AS REAL)))
FROM rt1 WHERE
(rid = (CAST (9223372036854775807 AS REAL)));
}
do_execsql_test 24.2 {
DELETE FROM rt1;
INSERT INTO rt1(rid, c1, c2) VALUES(1,2,3);
SELECT * FROM rt1 WHERE rid=1.005;
} {}
finish_test
+13 -45
View File
@@ -307,9 +307,8 @@ DISTCLEAN_FILES += $(bin.stripccomments)
########################################################################
# C-PP.FILTER: a $(call)able to transform $(1) to $(2) via:
#
# ./c-pp -f $(1) -o $(2) $(3)
# C-PP.FILTER: a $(call)able to transform $(1) to $(2) via ./c-pp -f
# $(1) ...
#
# Historical notes:
#
@@ -453,14 +452,13 @@ sqlite3-api.jses += $(dir.api)/sqlite3-api-cleanup.js
# the first OPFS VFS and necessarily an external file.
SOAP.js := $(dir.api)/sqlite3-opfs-async-proxy.js
SOAP.js.bld := $(dir.dout)/$(notdir $(SOAP.js))
#
# $(sqlite3-api.ext.jses) = API-related files which are standalone files,
# not part of the amalgamation.
#
sqlite3-api.ext.jses := $(SOAP.js.bld)
sqlite3-api.ext.jses += $(SOAP.js.bld)
$(SOAP.js.bld): $(SOAP.js)
cp $< $@
all quick: $(sqlite3-api.ext.jses)
q: quick
########################################################################
# $(sqlite3-api*.*js) contain the core library code but not the
# Emscripten-related glue which deals with loading sqlite3.wasm. In
@@ -533,10 +531,6 @@ emcc.jsflags += -sSTRICT_JS=0
# 3.1.31. The fix for that in newer emcc's is to throw a built-time
# error if STRICT_JS is used together with those options.
# emcc.jsflags += -sSTRICT=1
# -sSTRICT=1 Causes failures about unknown symbols which the build
# tools should be installing, e.g. __syscall_geteuid32
# -sENVIRONMENT values for the various build modes:
emcc.environment.vanilla := web,worker
emcc.environment.bundler-friendly := $(emcc.environment.vanilla)
@@ -557,11 +551,6 @@ emcc.environment.node := node
# time with 16mb+ memory and 3X time when starting with 8MB. However,
# such test results are inconsistent due to browser internals which
# are opaque to us.
#
# 2024-03-04: emsdk 3.1.55 replaces INITIAL_MEMORY with INITIAL_HEAP,
# but also says (in its changelog): "Note that it is currently not
# supported in all configurations (#21071)."
# https://github.com/emscripten-core/emscripten/blob/main/ChangeLog.md
emcc.jsflags += -sALLOW_MEMORY_GROWTH
emcc.INITIAL_MEMORY.128 := 134217728
emcc.INITIAL_MEMORY.96 := 100663296
@@ -827,13 +816,13 @@ pre-post-jses.deps.common := $(extern-pre-js.js) $(sqlite3-license-version.js)
# $4 = resulting sqlite-api JS/MJS file
# $5 = resulting JS/MJS file
# $6 = -D... flags for $(bin.c-pp)
# $7 = optional extra flags for emcc
# $7 = emcc -sXYZ flags (CURRENTLY UNUSED - was factored out)
#
# Maintenance reminder: be careful not to introduce spaces around args
# ($1, $2), otherwise string concatenation will malfunction.
#
# Before calling this, emcc.environment.$(2) must be set to a value
# for emcc's -sENVIRONMENT flag.
# emcc.environment.$(2) must be set to a value for emcc's
# -sENVIRONMENT flag.
#
# $(cflags.$(1)) and $(cflags.$(1).$(2)) may be defined to append
# CFLAGS to a given build mode.
@@ -940,39 +929,18 @@ sqlite3-worker1.js.in := $(dir.api)/sqlite3-worker1.c-pp.js
sqlite3-worker1-promiser.js.in := $(dir.api)/sqlite3-worker1-promiser.c-pp.js
sqlite3-worker1.js := $(dir.dout)/sqlite3-worker1.js
sqlite3-worker1-promiser.js := $(dir.dout)/sqlite3-worker1-promiser.js
sqlite3-worker1-promiser.mjs := $(dir.dout)/sqlite3-worker1-promiser.mjs
sqlite3-worker1-bundler-friendly.mjs := $(dir.dout)/sqlite3-worker1-bundler-friendly.mjs
sqlite3-worker1-bundler-friendly.js := $(dir.dout)/sqlite3-worker1-bundler-friendly.mjs
sqlite3-worker1-promiser-bundler-friendly.js := $(dir.dout)/sqlite3-worker1-promiser-bundler-friendly.js
$(eval $(call C-PP.FILTER,$(sqlite3-worker1.js.in),$(sqlite3-worker1.js)))
$(eval $(call C-PP.FILTER,$(sqlite3-worker1.js.in),$(sqlite3-worker1-bundler-friendly.mjs),\
$(eval $(call C-PP.FILTER,$(sqlite3-worker1.js.in),$(sqlite3-worker1-bundler-friendly.js),\
$(c-pp.D.sqlite3-bundler-friendly)))
$(eval $(call C-PP.FILTER,$(sqlite3-worker1-promiser.js.in),$(sqlite3-worker1-promiser.js)))
$(eval $(call C-PP.FILTER,$(sqlite3-worker1-promiser.js.in),\
$(sqlite3-worker1-promiser-bundler-friendly.js),\
$(c-pp.D.sqlite3-bundler-friendly)))
$(eval $(call C-PP.FILTER,$(sqlite3-worker1-promiser.js.in),$(sqlite3-worker1-promiser.mjs),\
-Dtarget=es6-module -Dtarget=es6-bundler-friendly))
$(sqlite3-bundler-friendly.mjs): $(sqlite3-worker1-bundler-friendly.mjs) \
$(sqlite3-bundler-friendly.mjs): $(sqlite3-worker1-bundler-friendly.js) \
$(sqlite3-worker1-promiser-bundler-friendly.js)
$(eval $(call C-PP.FILTER,demo-worker1-promiser.c-pp.js,demo-worker1-promiser.js))
$(eval $(call C-PP.FILTER,demo-worker1-promiser.c-pp.js,demo-worker1-promiser.mjs,\
-Dtarget=es6-module))
$(eval $(call C-PP.FILTER,demo-worker1-promiser.c-pp.html,demo-worker1-promiser.html))
$(eval $(call C-PP.FILTER,demo-worker1-promiser.c-pp.html,demo-worker1-promiser-esm.html,\
-Dtarget=es6-module))
all: $(sqlite3-worker1.js) \
$(sqlite3-worker1-promiser.js) $(sqlite3-worker1-promiser.mjs)
demo-worker1-promiser.html: $(sqlite3-worker1-promiser.js) demo-worker1-promiser.js
demo-worker1-promiser-esm.html: $(sqlite3-worker1-promiser.mjs) demo-worker1-promiser.mjs
all: demo-worker1-promiser.html demo-worker1-promiser-esm.html
sqlite3-api.ext.jses += \
$(sqlite3-worker1-promiser.mjs) \
$(sqlite3-worker1-bundler-friendly.mjs) \
$(sqlite3-worker1.js)
all quick: $(sqlite3-api.ext.jses)
q: quick
$(sqlite3.js) $(sqlite3.mjs): $(sqlite3-worker1.js) $(sqlite3-worker1-promiser.js)
########################################################################
# batch-runner.js is part of one of the test apps which reads in SQL
+5 -45
View File
@@ -37,7 +37,7 @@
This function expects a configuration object, intended to abstract
away details specific to any given WASM environment, primarily so
that it can be used without any direct dependency on
that it can be used without any _direct_ dependency on
Emscripten. (Note the default values for the config object!) The
config object is only honored the first time this is
called. Subsequent calls ignore the argument and return the same
@@ -98,37 +98,14 @@
The returned object is the top-level sqlite3 namespace object.
Client code may optionally assign sqlite3ApiBootstrap.defaultConfig
an object-type value before calling sqlite3ApiBootstrap() (without
arguments) in order to tell that call to use this object as its
default config value. The intention of this is to provide
downstream clients with a reasonably flexible approach for plugging
in an environment-suitable configuration without having to define a
new global-scope symbol.
However, because clients who access this library via an
Emscripten-hosted module will not have an opportunity to call
sqlite3ApiBootstrap() themselves, nor to access it before it is
called, an alternative option for setting the configuration is to
define globalThis.sqlite3ApiConfig to an object. If it is set, it
is used instead of sqlite3ApiBootstrap.defaultConfig if
sqlite3ApiBootstrap() is called without arguments.
Both sqlite3ApiBootstrap.defaultConfig and
globalThis.sqlite3ApiConfig get deleted by sqlite3ApiBootstrap()
because any changes to them made after that point would have no
useful effect.
*/
'use strict';
globalThis.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
apiConfig = (globalThis.sqlite3ApiConfig || sqlite3ApiBootstrap.defaultConfig)
){
if(sqlite3ApiBootstrap.sqlite3){ /* already initalized */
(sqlite3ApiBootstrap.sqlite3.config || console).warn(
"sqlite3ApiBootstrap() called multiple times.",
"Config and external initializers are ignored on calls after the first."
);
console.warn("sqlite3ApiBootstrap() called multiple times.",
"Config and external initializers are ignored on calls after the first.");
return sqlite3ApiBootstrap.sqlite3;
}
const config = Object.assign(Object.create(null),{
@@ -137,16 +114,8 @@ globalThis.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
bigIntEnabled: (()=>{
if('undefined'!==typeof Module){
/* Emscripten module will contain HEAPU64 when built with
-sWASM_BIGINT=1, else it will not.
As of emsdk 3.1.55, when building in strict mode, HEAPxyz
are only available if _explicitly_ included in the exports,
else they are not. We do not (as of 2024-03-04) use -sSTRICT
for the canonical builds.
*/
if( !!Module.HEAPU64 ) return true;
/* Else fall through and hope for the best. Nobody _really_
builds this without BigInt support, do they? */
-sWASM_BIGINT=1, else it will not. */
return !!Module.HEAPU64;
}
return !!globalThis.BigInt64Array;
})(),
@@ -180,15 +149,6 @@ globalThis.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
config[k] = config[k]();
}
});
/**
Eliminate any confusion about whether these config objects may
be used after library initialization by eliminating the outward-facing
objects...
*/
delete globalThis.sqlite3ApiConfig;
delete sqlite3ApiBootstrap.defaultConfig;
/**
The main sqlite3 binding API gets installed into this object,
mimicking the C API as closely as we can. The numerous members
-11
View File
@@ -562,17 +562,6 @@ const installAsyncProxy = function(self){
wTimeEnd();
return;
}
if( state.opfsFlags.OPFS_UNLINK_BEFORE_OPEN & opfsFlags ){
//log("async proxy opfsFlags =",opfsFlags);
try{
await hDir.removeEntry(filenamePart);
//log("Unlinked",filename,hDir,filenamePart);
}
catch(e){
/* ignoring */
//warn("Ignoring failed Unlink of",filename,":",e);
}
}
const hFile = await hDir.getFileHandle(filenamePart, {create});
wTimeEnd();
const fh = Object.assign(Object.create(null),{
+3 -22
View File
@@ -423,25 +423,10 @@ const installOpfsVfs = function callee(options){
});
state.opfsFlags = Object.assign(Object.create(null),{
/**
Flag for use with xOpen(). URI flag "opfs-unlock-asap=1"
enables this. See defaultUnlockAsap, below.
Flag for use with xOpen(). "opfs-unlock-asap=1" enables
this. See defaultUnlockAsap, below.
*/
OPFS_UNLOCK_ASAP: 0x01,
/**
Flag for use with xOpen(). URI flag "delete-before-open=1"
tells the VFS to delete the db file before attempting to open
it. This can be used, e.g., to replace a db which has been
corrupted (without forcing us to expose a delete/unlink()
function in the public API).
Failure to unlink the file is ignored but may lead to
downstream errors. An unlink can fail if, e.g., another tab
has the handle open.
It goes without saying that deleting a file out from under another
instance results in Undefined Behavior.
*/
OPFS_UNLINK_BEFORE_OPEN: 0x02,
/**
If true, any async routine which implicitly acquires a sync
access handle (i.e. an OPFS lock) will release that locks at
@@ -890,17 +875,13 @@ const installOpfsVfs = function callee(options){
let opfsFlags = 0;
if(0===zName){
zName = randomFilename();
}else if(wasm.isPtr(zName)){
}else if('number'===typeof zName){
if(capi.sqlite3_uri_boolean(zName, "opfs-unlock-asap", 0)){
/* -----------------------^^^^^ MUST pass the untranslated
C-string here. */
opfsFlags |= state.opfsFlags.OPFS_UNLOCK_ASAP;
}
if(capi.sqlite3_uri_boolean(zName, "delete-before-open", 0)){
opfsFlags |= state.opfsFlags.OPFS_UNLINK_BEFORE_OPEN;
}
zName = wasm.cstrToJs(zName);
//warn("xOpen zName =",zName, "opfsFlags =",opfsFlags);
}
const fh = Object.create(null);
fh.fid = pFile;
+6 -69
View File
@@ -42,13 +42,9 @@
- `onready` (optional, but...): this callback is called with no
arguments when the worker fires its initial
'sqlite3-api'/'worker1-ready' message, which it does when
sqlite3.initWorker1API() completes its initialization. This is the
simplest way to tell the worker to kick off work at the earliest
opportunity, and the only way to know when the worker module has
completed loading. The irony of using a callback for this, instead
of returning a promise from sqlite3Worker1Promiser() is not lost on
the developers: see sqlite3Worker1Promiser.v2() which uses a
Promise instead.
sqlite3.initWorker1API() completes its initialization. This is
the simplest way to tell the worker to kick off work at the
earliest opportunity.
- `onunhandled` (optional): a callback which gets passed the
message event object for any worker.onmessage() events which
@@ -251,10 +247,9 @@ globalThis.sqlite3Worker1Promiser = function callee(config = callee.defaultConfi
return p;
};
}/*sqlite3Worker1Promiser()*/;
globalThis.sqlite3Worker1Promiser.defaultConfig = {
worker: function(){
//#if target=es6-module
//#if target=es6-bundler-friendly
return new Worker(new URL("sqlite3-worker1-bundler-friendly.mjs", import.meta.url),{
type: 'module'
});
@@ -275,72 +270,14 @@ globalThis.sqlite3Worker1Promiser.defaultConfig = {
return new Worker(theJs + globalThis.location.search);
//#endif
}
//#ifnot target=es6-module
//#ifnot target=es6-bundler-friendly
.bind({
currentScript: globalThis?.document?.currentScript
})
//#endif
,
onerror: (...args)=>console.error('worker1 promiser error',...args)
}/*defaultConfig*/;
/**
sqlite3Worker1Promiser.v2() works identically to
sqlite3Worker1Promiser() except that it returns a Promise instead
of relying an an onready callback in the config object. The Promise
resolves to the same factory function which
sqlite3Worker1Promiser() returns.
If config is-a function or is an object which contains an onready
function, that function is replaced by a proxy which will resolve
after calling the original function and will reject if that
function throws.
*/
sqlite3Worker1Promiser.v2 = function(config){
let oldFunc;
if( 'function' == typeof config ){
oldFunc = config;
config = {};
}else if('function'===typeof config?.onready){
oldFunc = config.onready;
delete config.onready;
}
const promiseProxy = Object.create(null);
config = Object.assign((config || Object.create(null)),{
onready: async function(func){
try {
if( oldFunc ) await oldFunc(func);
promiseProxy.resolve(func);
}
catch(e){promiseProxy.reject(e)}
}
});
const p = new Promise(function(resolve,reject){
promiseProxy.resolve = resolve;
promiseProxy.reject = reject;
});
try{
this.original(config);
}catch(e){
promiseProxy.reject(e);
}
return p;
}.bind({
/* We do this because clients are
recommended to delete globalThis.sqlite3Worker1Promiser. */
original: sqlite3Worker1Promiser
});
//#if target=es6-module
/**
When built as a module, we export sqlite3Worker1Promiser.v2()
instead of sqlite3Worker1Promise() because (A) its interface is more
conventional for ESM usage and (B) the ESM option export option for
this API did not exist until v2 was created, so there's no backwards
incompatibility.
*/
export default sqlite3Worker1Promiser.v2;
//#endif /* target=es6-module */
};
//#else
/* Built with the omit-oo1 flag. */
//#endif ifnot omit-oo1
@@ -6,11 +6,7 @@
<link rel="shortcut icon" href="data:image/x-icon;," type="image/x-icon">
<link rel="stylesheet" href="common/emscripten.css"/>
<link rel="stylesheet" href="common/testing.css"/>
//#if target=es6-module
<title>worker-promise (via ESM) tests</title>
//#else
<title>worker-promise tests</title>
//#endif
</head>
<body>
<header id='titlebar'><span>worker-promise tests</span></header>
@@ -26,17 +22,13 @@
</figure>
<div class="emscripten" id="module-status">Downloading...</div>
<div class="emscripten">
<progress value="0" max="100" id="module-progress" hidden='1'></progress>
<progress value="0" max="100" id="module-progress" hidden='1'></progress>
</div><!-- /emscripten bits -->
<div>Most stuff on this page happens in the dev console.</div>
<hr>
<div id='test-output'></div>
<script src="common/SqliteTestUtil.js"></script>
//#if target=es6-module
<script src="demo-worker1-promiser.mjs" type="module"></script>
//#else
<script src="jswasm/sqlite3-worker1-promiser.js"></script>
<script src="demo-worker1-promiser.js"></script>
//#endif
</body>
</html>
@@ -13,15 +13,9 @@
Demonstration of the sqlite3 Worker API #1 Promiser: a Promise-based
proxy for for the sqlite3 Worker #1 API.
*/
//#if target=es6-module
import {default as promiserFactory} from "./jswasm/sqlite3-worker1-promiser.mjs";
//#else
"use strict";
const promiserFactory = globalThis.sqlite3Worker1Promiser.v2;
delete globalThis.sqlite3Worker1Promiser;
//#endif
(async function(){
const T = globalThis.SqliteTestUtil;
'use strict';
(function(){
const T = self.SqliteTestUtil;
const eOutput = document.querySelector('#test-output');
const warn = console.warn.bind(console);
const error = console.error.bind(console);
@@ -39,35 +33,33 @@ delete globalThis.sqlite3Worker1Promiser;
logHtml("","Total test count:",T.counter+". Total time =",(performance.now() - startTime),"ms");
};
//why is this triggered even when we catch() a Promise?
//window.addEventListener('unhandledrejection', function(event) {
// warn('unhandledrejection',event);
//});
const promiserConfig = {
//#ifnot target=es6-module
/**
The v1 interfaces uses an onready function. The v2 interface optionally
accepts one but does not require it. If provided, it is called _before_
the promise is resolved, and the promise is rejected if onready() throws.
*/
onready: function(f){
/* f === the function returned by promiserFactory().
Ostensibly (f === workerPromise) but this function is
called before the promiserFactory() Promise resolves, so
before workerPromise is set. */
console.warn("This is the v2 interface - you don't need an onready() function.");
worker: ()=>{
const w = new Worker("jswasm/sqlite3-worker1.js");
w.onerror = (event)=>error("worker.onerror",event);
return w;
},
//#endif
debug: 1 ? undefined : (...args)=>console.debug('worker debug',...args),
onunhandled: function(ev){
error("Unhandled worker message:",ev.data);
},
onready: function(){
T.affirm(arguments[0] === workerPromise
/* as of version 3.46. Prior to that this callback had no arguments */);
self.sqlite3TestModule.setStatus(null)/*hide the HTML-side is-loading spinner*/;
runTests();
},
onerror: function(ev){
error("worker1 error:",ev);
}
};
const workerPromise = await promiserFactory(promiserConfig)
.then((func)=>{
console.log("Init complete. Starting tests momentarily.");
globalThis.sqlite3TestModule.setStatus(null)/*hide the HTML-side is-loading spinner*/;
return func;
});
const workerPromise = self.sqlite3Worker1Promiser(promiserConfig);
delete self.sqlite3Worker1Promiser;
const wtest = async function(msgType, msgArgs, callback){
if(2===arguments.length && 'function'===typeof msgArgs){
@@ -281,5 +273,5 @@ delete globalThis.sqlite3Worker1Promiser;
}).finally(()=>logHtml('',"That's all, folks!"));
}/*runTests2()*/;
runTests();
log("Init complete, but async init bits may still be running.");
})();
+3 -11
View File
@@ -49,18 +49,12 @@ dist.top.extras := \
tester1.js tester1.mjs \
demo-jsstorage.html demo-jsstorage.js \
demo-worker1.html demo-worker1.js \
demo-worker1-promiser.html demo-worker1-promiser.js \
demo-worker1-promiser-esm.html demo-worker1-promiser.mjs
dist.jswasm.extras := $(sqlite3.wasm) \
$(sqlite3-api.ext.jses)
demo-worker1-promiser.html demo-worker1-promiser.js
dist.jswasm.extras := $(sqlite3-api.ext.jses) $(sqlite3.wasm)
dist.common.extras := \
$(wildcard $(dir.common)/*.css) \
$(dir.common)/SqliteTestUtil.js
#$(info sqlite3-worker1-promiser.mjs = $(sqlite3-worker1-promiser.mjs))
#$(info sqlite3-worker1.js = $(sqlite3-worker1.js))
#$(info sqlite3-api.ext.jses = $(sqlite3-api.ext.jses))
#$(info dist.jswasm.extras = $(dist.jswasm.extras))
.PHONY: dist snapshot
# DIST_STRIP_COMMENTS $(call)able to be used in stripping C-style
# from the dist copies of certain files.
@@ -73,8 +67,7 @@ endef
# STRIP_K1.js = list of JS files which need to be passed through
# $(bin.stripcomments) with a single -k flag.
STRIP_K1.js := $(sqlite3-worker1.js) $(sqlite3-worker1-promiser.js) \
$(sqlite3-worker1-bundler-friendly.js) \
$(sqlite3-api.ext.jses)
$(sqlite3-worker1-bundler-friendly.js) $(sqlite3-worker1-promiser-bundler-friendly.js)
# STRIP_K2.js = list of JS files which need to be passed through
# $(bin.stripcomments) with two -k flags.
STRIP_K2.js := $(sqlite3.js) $(sqlite3.mjs) \
@@ -95,7 +88,6 @@ STRIP_K2.js := $(sqlite3.js) $(sqlite3.mjs) \
dist: \
$(bin.stripccomments) $(bin.version-info) \
$(dist.build) $(STRIP_K1.js) $(STRIP_K2.js) \
$(dist.jswasm.extras) $(dist.common.extras) \
$(MAKEFILE) $(MAKEFILE.dist)
@echo "Making end-user deliverables..."
@rm -fr $(dist-dir.top)
+4 -6
View File
@@ -9,18 +9,16 @@ MAKEFILE.fiddle := $(lastword $(MAKEFILE_LIST))
# shell.c and its build flags...
make-np-0 := make -C $(dir.top) -n -p
make-np-1 := sed -e 's/(TOP)/(dir.top)/g'
# Extract SHELL_OPT and SHELL_DEP from the top-most makefile and import
# them as vars here...
$(eval $(shell $(make-np-0) | grep -e '^SHELL_OPT ' | $(make-np-1)))
$(eval $(shell $(make-np-0) | grep -e '^SHELL_DEP ' | $(make-np-1)))
$(eval $(shell $(make-np-0) | grep -e '^SHELL_SRC ' | $(make-np-1)))
# ^^^ can't do that in 1 invocation b/c newlines get stripped
ifeq (,$(SHELL_OPT))
$(error Could not parse SHELL_OPT from $(dir.top)/Makefile.)
endif
ifeq (,$(SHELL_DEP))
$(error Could not parse SHELL_DEP from $(dir.top)/Makefile.)
ifeq (,$(SHELL_SRC))
$(error Could not parse SHELL_SRC from $(dir.top)/Makefile.)
endif
$(dir.top)/shell.c: $(SHELL_DEP) $(dir.top)/tool/mkshellc.tcl $(sqlite3.c)
$(dir.top)/shell.c: $(SHELL_SRC) $(dir.top)/tool/mkshellc.tcl $(sqlite3.c)
$(MAKE) -C $(dir.top) shell.c
# /shell.c
########################################################################
+3 -2
View File
@@ -166,10 +166,11 @@
stdout("SQLite version", capi.sqlite3_libversion(),
capi.sqlite3_sourceid().substr(0,19));
stdout('Welcome to the "fiddle" shell.');
if(capi.sqlite3_vfs_find("opfs")){
if(sqlite3.opfs){
stdout("\nOPFS is available. To open a persistent db, use:\n\n",
" .open file:name?vfs=opfs\n\nbut note that some",
"features (e.g. upload) do not yet work with OPFS.");
sqlite3.opfs.registerVfs();
}
stdout('\nEnter ".help" for usage hints.');
this.exec([ // initialization commands...
@@ -316,7 +317,7 @@
};
console.warn("Unknown fiddle-worker message type:",ev);
};
/**
emscripten module for use with build mode -sMODULARIZE.
*/
+5 -12
View File
@@ -403,10 +403,8 @@
E('#btn-reset').addEventListener('click',()=>SF.resetDb());
const taInput = E('#input');
const btnClearIn = E('#btn-clear');
const selectExamples = E('#select-examples');
btnClearIn.addEventListener('click',function(){
taInput.value = '';
selectExamples.selectedIndex = 0;
},false);
// Ctrl-enter and shift-enter both run the current SQL.
taInput.addEventListener('keydown',function(ev){
@@ -735,15 +733,16 @@
]},
//{name: "Timer on", sql: ".timer on"},
// ^^^ re-enable if emscripten re-enables getrusage()
{name: "Box Mode", sql: ".mode box"},
{name: "Setup table T", sql:[
".nullvalue NULL\n",
"CREATE TABLE t(a,b);\n",
"INSERT INTO t(a,b) VALUES('abc',123),('def',456),(NULL,789),('ghi',012);\n",
"SELECT * FROM t;\n"
]},
{name: "sqlite_schema", sql: "select * from sqlite_schema"},
{name: "Mandelbrot", sql:[
{name: "Table list", sql: ".tables"},
{name: "Box Mode", sql: ".mode box"},
{name: "JSON Mode", sql: ".mode json"},
{name: "Mandlebrot", sql:[
"WITH RECURSIVE",
" xaxis(x) AS (VALUES(-2.0) UNION ALL SELECT x+0.05 FROM xaxis WHERE x<1.2),\n",
" yaxis(y) AS (VALUES(-1.0) UNION ALL SELECT y+0.1 FROM yaxis WHERE y<1.0),\n",
@@ -761,13 +760,7 @@
" FROM m2 GROUP BY cy\n",
" )\n",
"SELECT group_concat(rtrim(t),x'0a') as Mandelbrot FROM a;\n",
]},
{name: "JSON pretty-print",
sql: "select json_pretty(json_object('ex',json('[52,3.14159]')))"
},
{name: "JSON pretty-print (with tabs)",
sql: "select json_pretty(json_object('ex',json('[52,3.14159]')),char(0x09))"
}
]}
];
const newOpt = function(lbl,val){
const o = document.createElement('option');
-2
View File
@@ -97,8 +97,6 @@
wrapper is significantly easier to use, however.</li>
<li><a href='demo-worker1-promiser.html'>demo-worker1-promiser</a>:
a demo of the Promise-based wrapper of the Worker1 API.</li>
<li><a href='demo-worker1-promiser-esm.html'>demo-worker1-promiser-esm</a>:
same as the previous demo except loads the promiser from an ESM module.</li>
</ul>
</li>
</ul>
-2
View File
@@ -84,8 +84,6 @@
wrapper is significantly easier to use, however.</li>
<li><a href='demo-worker1-promiser.html'>demo-worker1-promiser</a>:
a demo of the Promise-based wrapper of the Worker1 API.</li>
<li><a href='demo-worker1-promiser-esm.html'>demo-worker1-promiser-esm</a>:
same as the previous demo except loads the promiser from an ESM module.</li>
</ul>
</li>
<li>speedtest1 ports (sqlite3's primary benchmarking tool)...
+15 -21
View File
@@ -2888,17 +2888,18 @@ globalThis.sqlite3InitModule = sqlite3InitModule;
.t({
name: 'OPFS db sanity checks',
test: async function(sqlite3){
T.assert(capi.sqlite3_vfs_find('opfs'));
const opfs = sqlite3.opfs;
const filename = this.opfsDbFile = '/dir/sqlite3-tester1.db';
const fileUri = 'file://'+filename+'?delete-before-open=1';
const initSql = [
'create table p(a);',
'insert into p(a) values(1),(2),(3)'
];
let db = new sqlite3.oo1.OpfsDb(fileUri);
const pVfs = this.opfsVfs = capi.sqlite3_vfs_find('opfs');
T.assert(pVfs);
const unlink = this.opfsUnlink =
(fn=filename)=>{sqlite3.util.sqlite3__wasm_vfs_unlink(pVfs,fn)};
unlink();
let db = new sqlite3.oo1.OpfsDb(filename);
try {
db.exec(initSql);
db.exec([
'create table p(a);',
'insert into p(a) values(1),(2),(3)'
]);
T.assert(3 === db.selectValue('select count(*) from p'));
db.close();
db = new sqlite3.oo1.OpfsDb(filename);
@@ -2910,14 +2911,7 @@ globalThis.sqlite3InitModule = sqlite3InitModule;
&& 0===this.opfsDbExport.byteLength % 512);
}finally{
db.close();
}
T.assert(await opfs.entryExists(filename));
try {
db = new sqlite3.oo1.OpfsDb(fileUri);
db.exec(initSql) /* will throw if delete-before-open did not work */;
T.assert(3 === db.selectValue('select count(*) from p'));
}finally{
if(db) db.close();
unlink();
}
}
}/*OPFS db sanity checks*/)
@@ -2925,17 +2919,15 @@ globalThis.sqlite3InitModule = sqlite3InitModule;
name: 'OPFS import',
test: async function(sqlite3){
let db;
const filename = this.opfsDbFile;
try {
const exp = this.opfsDbExport;
const filename = this.opfsDbFile;
delete this.opfsDbExport;
this.opfsImportSize = await sqlite3.oo1.OpfsDb.importDb(filename, exp);
db = new sqlite3.oo1.OpfsDb(this.opfsDbFile);
T.assert(6 === db.selectValue('select count(*) from p')).
assert( this.opfsImportSize == exp.byteLength );
db.close();
const unlink = this.opfsUnlink =
(fn=filename)=>sqlite3.util.sqlite3__wasm_vfs_unlink("opfs",fn);
this.opfsUnlink(filename);
T.assert(!(await sqlite3.opfs.entryExists(filename)));
// Try again with a function as an input source:
@@ -2962,9 +2954,11 @@ globalThis.sqlite3InitModule = sqlite3InitModule;
name: '(Internal-use) OPFS utility APIs',
test: async function(sqlite3){
const filename = this.opfsDbFile;
const pVfs = this.opfsVfs;
const unlink = this.opfsUnlink;
T.assert(filename && !!unlink);
T.assert(filename && pVfs && !!unlink);
delete this.opfsDbFile;
delete this.opfsVfs;
delete this.opfsUnlink;
/**************************************************************
ATTENTION CLIENT-SIDE USERS: sqlite3.opfs is NOT intended
+27 -31
View File
@@ -718,7 +718,8 @@ opcodes.c: opcodes.h $(TOP)/tool/mkopcodec.tcl
tclsh $(TOP)/tool/mkopcodec.tcl opcodes.h >opcodes.c
opcodes.h: parse.h $(TOP)/src/vdbe.c $(TOP)/tool/mkopcodeh.tcl
cat parse.h $(TOP)/src/vdbe.c | tclsh $(TOP)/tool/mkopcodeh.tcl >opcodes.h
cat parse.h $(TOP)/src/vdbe.c | \
tclsh $(TOP)/tool/mkopcodeh.tcl >opcodes.h
# Rules to build parse.c and parse.h - the outputs of lemon.
#
@@ -741,37 +742,32 @@ keywordhash.h: $(TOP)/tool/mkkeywordhash.c
$(BCC) -o mkkeywordhash $(OPTS) $(TOP)/tool/mkkeywordhash.c
./mkkeywordhash >keywordhash.h
# Source and header files that shell.c depends on
SHELL_DEP = \
$(TOP)/src/shell.c.in \
$(TOP)/ext/consio/console_io.c \
$(TOP)/ext/consio/console_io.h \
$(TOP)/ext/expert/sqlite3expert.c \
$(TOP)/ext/expert/sqlite3expert.h \
$(TOP)/ext/intck/sqlite3intck.c \
$(TOP)/ext/intck/sqlite3intck.h \
$(TOP)/ext/misc/appendvfs.c \
$(TOP)/ext/misc/base64.c \
$(TOP)/ext/misc/base85.c \
$(TOP)/ext/misc/completion.c \
$(TOP)/ext/misc/decimal.c \
$(TOP)/ext/misc/fileio.c \
$(TOP)/ext/misc/ieee754.c \
$(TOP)/ext/misc/memtrace.c \
$(TOP)/ext/misc/pcachetrace.c \
$(TOP)/ext/misc/regexp.c \
$(TOP)/ext/misc/series.c \
$(TOP)/ext/misc/shathree.c \
$(TOP)/ext/misc/sqlar.c \
$(TOP)/ext/misc/uint.c \
$(TOP)/ext/misc/zipfile.c \
$(TOP)/ext/recover/dbdata.c \
$(TOP)/ext/recover/sqlite3recover.c \
$(TOP)/ext/recover/sqlite3recover.h \
$(TOP)/src/test_windirent.c \
$(TOP)/src/test_windirent.h
# Source files that go into making shell.c
SHELL_SRC = \
$(TOP)/src/shell.c.in \
$(TOP)/ext/misc/appendvfs.c \
$(TOP)/ext/misc/completion.c \
$(TOP)/ext/misc/base64.c \
$(TOP)/ext/misc/base85.c \
$(TOP)/ext/misc/decimal.c \
$(TOP)/ext/misc/fileio.c \
$(TOP)/ext/misc/ieee754.c \
$(TOP)/ext/misc/regexp.c \
$(TOP)/ext/misc/series.c \
$(TOP)/ext/misc/shathree.c \
$(TOP)/ext/misc/sqlar.c \
$(TOP)/ext/misc/uint.c \
$(TOP)/ext/expert/sqlite3expert.c \
$(TOP)/ext/expert/sqlite3expert.h \
$(TOP)/ext/misc/zipfile.c \
$(TOP)/ext/misc/memtrace.c \
$(TOP)/ext/misc/pcachetrace.c \
$(TOP)/ext/recover/dbdata.c \
$(TOP)/ext/recover/sqlite3recover.c \
$(TOP)/ext/recover/sqlite3recover.h \
$(TOP)/src/test_windirent.c
shell.c: $(SHELL_DEP) $(TOP)/tool/mkshellc.tcl
shell.c: $(SHELL_SRC) $(TOP)/tool/mkshellc.tcl
tclsh $(TOP)/tool/mkshellc.tcl >shell.c
+80 -83
View File
@@ -1,11 +1,11 @@
C Have\stestrunner.tcl\shave\seach\stest\sstore\sits\stemp\sfiles\sin\sits\sworking\sdirectory.\sTo\savoid\sunlikely,\sbut\spossible,\scollisions.
D 2024-03-12T18:04:40.495
C The\sability\sto\sDROP\smultiple\stables\s(or\sviews\sor\sindexes\sor\striggers)\sat\sonce,\nas\simplemented\sby\sthis\sbranch,\sappears\sto\swork.\s\sHowever,\sthis\sbranch\sadds\sover\n1000\sbytes\sto\sthe\scode\sfootprint.\s\sAnd\sthe\schanges\sis\ssignificant,\sadding\srisk.\nThe\sbenefit\sof\sbeing\sable\sto\sdrop\smultiple\stables\sin\sa\ssingle\sstatement\sis\snot\nseen\sto\sbe\senough\sto\sovercome\sthose\sdownsides,\sand\sso\sthere\sare\sno\simmediate\nplans\sto\smerge\sthis\sbranch.
D 2024-03-04T18:02:36.966
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
F Makefile.in 5f2389d2a3c44b56621bb5156a9cb6e2bef01f7ec14a19335b1559cf0474bdde
F Makefile.in 3c4f4879b2301e5486939f68cc64f84430861d246ac11430ff1a1d7347ed5b8c
F Makefile.linux-gcc f3842a0b1efbfbb74ac0ef60e56b301836d05b4d867d014f714fa750048f1ab6
F Makefile.msc e64a52619310d3067f6c38f56eedd15918a82dade70954197d6da486ad99d7f4
F Makefile.msc 15a875f6016c4200e7093db92365fabb8b32eb09f9e40e1aadeedeecad4050d5
F README.md 6358805260a03ebead84e168bbf3740ddf3f683b477e478567186aa7afb490d3
F VERSION c84541c6a9e8426462176fbb1f9ecb5cfd7d1bb56228053ff7eeba8841673eb6
F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50
@@ -57,8 +57,8 @@ F ext/consio/console_io.c f32b757c9ee7fdf68e7586bee306f8368759e7cd12febb2a683919
F ext/consio/console_io.h 0548b83d7c4b7270ad544a67f2bb90cebc519637fa39b1838df4744cf0d87646
F ext/expert/README.md b321c2762bb93c18ea102d5a5f7753a4b8bac646cb392b3b437f633caf2020c3
F ext/expert/expert.c d548d603a4cc9e61f446cc179c120c6713511c413f82a4a32b1e1e69d3f086a4
F ext/expert/expert1.test 53a749de08939e3bc14f804e97410927d46fa772cbce0247d7e8fa6fc2523b0c
F ext/expert/sqlite3expert.c c8cea5ff15fbe792cccc4992a9b40b706411c41d32611f617897fecac6ff06a4
F ext/expert/expert1.test 0dd5cb096d66bed593e33053a3b364f6ef52ed72064bf5cf298364636dbf3cd6
F ext/expert/sqlite3expert.c 90446bb1183429308c68ceb23e00cb8252f43b8886cf5efa3fc7e833b5fa24c8
F ext/expert/sqlite3expert.h ca81efc2679a92373a13a3e76a6138d0310e32be53d6c3bfaedabd158ea8969b
F ext/expert/test_expert.c d56c194b769bdc90cf829a14c9ecbc1edca9c850b837a4d0b13be14095c32a72
F ext/fts3/README.content b9078d0843a094d86af0d48dffbff13c906702b4c3558012e67b9c7cc3bf59ee
@@ -250,15 +250,15 @@ F ext/fts5/tool/showfts5.tcl d54da0e067306663e2d5d523965ca487698e722c
F ext/icu/README.txt 7ab7ced8ae78e3a645b57e78570ff589d4c672b71370f5aa9e1cd7024f400fc9
F ext/icu/icu.c c074519b46baa484bb5396c7e01e051034da8884bad1a1cb7f09bbe6be3f0282
F ext/icu/sqliteicu.h fa373836ed5a1ee7478bdf8a1650689294e41d0c89c1daab26e9ae78a32075a8
F ext/intck/intck1.test f3a3cba14b6aeff145ffa5515546dd22f7510dad91512e519f43b92b56514012
F ext/intck/intck2.test d2457c7e5e5b688046d15ebe08a1e1427cc5e7a6dc8d6af215f42e8bcaf67304
F ext/intck/intck_common.tcl a61fd2697ae55b0a3d89847ca0b590c6e0d8ff64bebb70920d93724799894159
F ext/intck/intckbusy.test d5ed4ef85a4b1dc1dee2484bd14a4bb68529659cca743327df0c775f005fa387
F ext/intck/intckcorrupt.test f6c302792326fb3db9dcfc70b554c55369bc4b52882eaaf039cfe0b74c821029
F ext/intck/intckfault.test cff3f75dff74abb3edfcb13f6aa53f6436746ab64b09fe5e2028f051e985efab
F ext/intck/sqlite3intck.c 0d10df36e2b7b438aa80ecd3f5e584d41b747586b038258fe6b407f66b81e7c5
F ext/intck/intck1.test 8a879640c90fdff5e91e6c2c41d509485ee634e8077fe0ca9f76be4cbd441fa3
F ext/intck/intck2.test 47afb44681d13d11072cd8906e6aa877c967e65be788b01f6139922fd91474ef
F ext/intck/intck_common.tcl 9e51458126576783f11051ac0fd25bea3f6b17f570a55884223737f3200b214b
F ext/intck/intckbusy.test 0732fe3efbb9e0a53ffdcc240073f6ff2777ea82c3e08812b16494f650763fe1
F ext/intck/intckcorrupt.test 3211ef68ac53e83951b6c8f6a8d2396506d123fe5898f97f848a25837744ec56
F ext/intck/intckfault.test ba0213c9c8dce08d519d5251268a3bab076a184b4d07acdea23b65e89c9ae03c
F ext/intck/sqlite3intck.c 52381a627637504a49e93400814b36e99afa0b972a9a24ef1732b8268bb27fa8
F ext/intck/sqlite3intck.h 2b40c38e7063ab822c974c0bd4aed97dabb579ccfe2e180a4639bb3bbef0f1c9
F ext/intck/test_intck.c 34243458378a12d1356c79219a03f244800533b3ab65b4a02861f0403364df12
F ext/intck/test_intck.c d63f1707432802f5db125ee40b794923af77d4686869bd8d3a7eb43332344267
F ext/jni/GNUmakefile 59eb05f2a363bdfac8d15d66bed624bfe1ff289229184f3861b95f98a19cf4b2
F ext/jni/README.md d899789a9082a07b99bf30b1bbb6204ae57c060efcaa634536fa669323918f42
F ext/jni/jar-dist.make 030aaa4ae71dd86e4ec5e7c1e6cd86f9dfa47c4592c070d2e35157e42498e1fa
@@ -506,9 +506,9 @@ F ext/repair/test/checkindex01.test b530f141413b587c9eb78ff734de6bb79bc3515c3350
F ext/repair/test/test.tcl 686d76d888dffd021f64260abf29a55c57b2cedfa7fc69150b42b1d6119aac3c
F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761
F ext/rtree/geopoly.c 0dd4775e896cee6067979d67aff7c998e75c2c9d9cd8d62a1a790c09cde7adca
F ext/rtree/rtree.c b6133dba5ae331fa6c1fc34df6aa623eba951b05ac35116f954a0bf7ab550436
F ext/rtree/rtree.c c65a133bb697d20c0ac60ac09dc3a1cbf55500bfd6e9e730d2469aa6113480ed
F ext/rtree/rtree.h 4a690463901cb5e6127cf05eb8e642f127012fd5003830dbc974eca5802d9412
F ext/rtree/rtree1.test e0608db762b2aadca0ecb6f97396cf66244490adc3ba88f2a292b27be3e1da3e
F ext/rtree/rtree1.test 2b5b8c719c6a4abe377f57766f428a49af36a93061cb146cccfdc3b30000c0a4
F ext/rtree/rtree2.test 9d9deddbb16fd0c30c36e6b4fdc3ee3132d765567f0f9432ee71e1303d32603d
F ext/rtree/rtree3.test 272594f88c344e973864008bbe4c71fd3a41a264c097d568593ee7886d83d409
F ext/rtree/rtree4.test 304de65d484540111b896827e4261815e5dca4ce28eeecd58be648cd73452c4b
@@ -587,7 +587,7 @@ F ext/userauth/sqlite3userauth.h 7f3ea8c4686db8e40b0a0e7a8e0b00fac13aa7a3
F ext/userauth/user-auth.txt ca7e9ee82ca4e1c1744295f8184dd70edfae1992865d26c64303f539eb6c084c
F ext/userauth/userauth.c 7f00cded7dcaa5d47f54539b290a43d2e59f4b1eb5f447545fa865f002fc80cb
F ext/wasm/EXPORTED_FUNCTIONS.fiddle.in 27450c8b8c70875a260aca55435ec927068b34cef801a96205adb81bdcefc65c
F ext/wasm/GNUmakefile 4bb4cf70a8153dd5b5fee17d724075c54174da630b424bbcf48c744633396f62
F ext/wasm/GNUmakefile 316349101671037a30311fbb40bd0b8702d9a223b5205a6a5eae8bac7b8dc1a0
F ext/wasm/README-dist.txt 6382cb9548076fca472fb3330bbdba3a55c1ea0b180ff9253f084f07ff383576
F ext/wasm/README.md a8a2962c3aebdf8d2104a9102e336c5554e78fc6072746e5daf9c61514e7d193
F ext/wasm/SQLTester/GNUmakefile e0794f676d55819951bbfae45cc5e8d7818dc460492dc317ce7f0d2eca15caff
@@ -607,16 +607,16 @@ F ext/wasm/api/pre-js.c-pp.js ad906703f7429590f2fbf5e6498513bf727a1a4f0ebfa057af
F ext/wasm/api/sqlite3-api-cleanup.js d235ad237df6954145404305040991c72ef8b1881715d2a650dda7b3c2576d0e
F ext/wasm/api/sqlite3-api-glue.js 587dc6db2d69329a5f4cb9635c377f516cf4a8e30f443f33380e5044889ec71b
F ext/wasm/api/sqlite3-api-oo1.js 7f3bcf0549ac44cde4b9da0b642d771916738d3f6781fb8a1757c50a91e506c0
F ext/wasm/api/sqlite3-api-prologue.js 93a72b07b2a5d964d2edc76a90b439ece49298bd7ba60a1c6ae5d4878213701e
F ext/wasm/api/sqlite3-api-prologue.js fffcee629bf020a8ccf5c367fbe6a169f5d5d73dfce1707a75c9fbf4aa21c7da
F ext/wasm/api/sqlite3-api-worker1.js 8d9c0562831f62218170a3373468d8a0b7a6503b5985e309b69bf71187b525cf
F ext/wasm/api/sqlite3-license-version-header.js 0c807a421f0187e778dc1078f10d2994b915123c1223fe752b60afdcd1263f89
F ext/wasm/api/sqlite3-opfs-async-proxy.js b4c7ce9d7f7957f243d0fbd5b6e28bac80cd3c1b738374cd0c96d89df8f2f316
F ext/wasm/api/sqlite3-opfs-async-proxy.js 8cf8a897726f14071fae6be6648125162b256dfb4f96555b865dbb7a6b65e379
F ext/wasm/api/sqlite3-vfs-helper.c-pp.js 3f828cc66758acb40e9c5b4dcfd87fd478a14c8fb7f0630264e6c7fa0e57515d
F ext/wasm/api/sqlite3-vfs-opfs-sahpool.c-pp.js 5a430874906ff3f4a6ca69aadf0c2aaedc1bb45489b8365bff7e955a83a8d42a
F ext/wasm/api/sqlite3-vfs-opfs.c-pp.js 3c72f1a0e6a7343c8c882d29d01bb440f10be12c844651605b486e76f3d6cc8c
F ext/wasm/api/sqlite3-vfs-opfs.c-pp.js fe427645e1499618f5fa7bc670af850577d8bcc132df982078690c9bf8400baa
F ext/wasm/api/sqlite3-vtab-helper.c-pp.js a2fcbc3fecdd0eea229283584ebc122f29d98194083675dbe5cb2cf3a17fe309
F ext/wasm/api/sqlite3-wasm.c d33a16495ca871781e78812d3a18fed78b797468fffee657b8d7199b277ff359
F ext/wasm/api/sqlite3-worker1-promiser.c-pp.js bd89edfe42a4d7122a6d6d405c5423cf00aabba1f76f6ea8e2dba9c628ddd91a
F ext/wasm/api/sqlite3-worker1-promiser.c-pp.js e8135b44a568badfe197e2379f6b42899f2240b5c3a77fa044331110f7ce8e50
F ext/wasm/api/sqlite3-worker1.c-pp.js 5e8706c2c4af2a57fbcdc02f4e7ef79869971bc21bb8ede777687786ce1c92d5
F ext/wasm/batch-runner-sahpool.html e9a38fdeb36a13eac7b50241dfe7ae066fe3f51f5c0b0151e7baee5fce0d07a7
F ext/wasm/batch-runner-sahpool.js 54a3ac228e6c4703fe72fb65c897e19156263a51fe9b7e21d2834a45e876aabd
@@ -632,19 +632,19 @@ F ext/wasm/demo-123.html 8c70a412ce386bd3796534257935eb1e3ea5c581e5d5aea0490b823
F ext/wasm/demo-123.js c7b3cca50c55841c381a9ca4f9396e5bbdc6114273d0b10a43e378e32e7be5bf
F ext/wasm/demo-jsstorage.html 409c4be4af5f207fb2877160724b91b33ea36a3cd8c204e8da1acb828ffe588e
F ext/wasm/demo-jsstorage.js 44e3ae7ec2483b6c511384c3c290beb6f305c721186bcf5398ca4e00004a06b8
F ext/wasm/demo-worker1-promiser.c-pp.html 635cf90685805e21772a5f7a35d1ace80f98a9ef7c42ff04d7a125ddca7e5db8
F ext/wasm/demo-worker1-promiser.c-pp.js fcc628cb42fcfaf07d250477801de1e6deb1e319d003976612a0db8d76b9fccc
F ext/wasm/demo-worker1-promiser.html 1de7c248c7c2cfd4a5783d2aa154bce62d74c6de98ab22f5786620b3354ed15f
F ext/wasm/demo-worker1-promiser.js 786ae8a3214c2a29f6fb2c80eb4f90cc401fcc5b524d95c35fdc66a454e32bad
F ext/wasm/demo-worker1.html 2c178c1890a2beb5a5fecb1453e796d067a4b8d3d2a04d65ca2eb1ab2c68ef5d
F ext/wasm/demo-worker1.js 836bece8615b17b1b572584f7b15912236a5947fe8c68b98d2737d7e287447ef
F ext/wasm/dist.make f2ce42305268fe33d4b50f6e4bb3daf4a60302a90736eee382f1b8af9ff32ec1
F ext/wasm/dist.make 3a851858aad72e246a5d9c5aaf6b6a144305f1bf898ac1846760ea7bab95c9a3
F ext/wasm/example_extra_init.c 2347cd69d19d839ef4e5e77b7855103a7fe3ef2af86f2e8c95839afd8b05862f
F ext/wasm/fiddle.make 3c2eace29255d6ddd219f5d8cc2728cb28b9fe717ea80b6062c2a6178947a16b
F ext/wasm/fiddle.make fa2ba6e90457ba2a71cb745f200d409caf773076df75ae5b177cc225d7627a11
F ext/wasm/fiddle/emscripten.css 3d253a6fdb8983a2ac983855bfbdd4b6fa1ff267c28d69513dd6ef1f289ada3f
F ext/wasm/fiddle/fiddle-worker.js 850e66fce39b89d59e161d1abac43a181a4caa89ddeea162765d660277cd84ce
F ext/wasm/fiddle/fiddle.js b444a5646a9aac9f3fc06c53d78af5e1912eb235d69a8e6010723e4eb0e9d4a1
F ext/wasm/fiddle/fiddle-worker.js 9be57887756c6854dbdcb5e7d8b7a26935d565491333a2f91dc4113598c659b5
F ext/wasm/fiddle/fiddle.js 974b995119ac443685d7d94d3b3c58c6a36540e9eb3fed7069d5653284071715
F ext/wasm/fiddle/index.html 5daf54e8f3d7777cbb1ca4f93affe28858dbfff25841cb4ab81d694efed28ec2
F ext/wasm/index-dist.html 564b5ec5669676482c5a25dea9e721d8eafed426ecb155f93d29aeff8507511f
F ext/wasm/index.html 4337f495416756802669f69f9f9f3df9f87ee4c1918e6718719b4b5718e4713a
F ext/wasm/index-dist.html e91d76e4581185238fd3d42ed86ec600f7023ed3e3a944c5c356f25304bf1263
F ext/wasm/index.html b31ce41c0da476d5ffcef23069b9d3415b419d65af5779096ebcfbcbade453a9
F ext/wasm/jaccwabyt/jaccwabyt.js 1264710db3cfbcb6887d95665b7aeba60c1126eaef789ca4cf1a4a17d5bc7f54
F ext/wasm/jaccwabyt/jaccwabyt.md 59a20df389abcc3606eb4eaea7fb7ba14504beb3e345dbea9b99a0618ba3bec8
F ext/wasm/module-symbols.html dc476b403369b26a1a23773e13b80f41b9a49f0825e81435fe3600a7cfbbe337
@@ -662,7 +662,7 @@ F ext/wasm/test-opfs-vfs.html 1f2d672f3f3fce810dfd48a8d56914aba22e45c6834e262555
F ext/wasm/test-opfs-vfs.js 1618670e466f424aa289859fe0ec8ded223e42e9e69b5c851f809baaaca1a00c
F ext/wasm/tester1-worker.html ebc4b820a128963afce328ecf63ab200bd923309eb939f4110510ab449e9814c
F ext/wasm/tester1.c-pp.html 1c1bc78b858af2019e663b1a31e76657b73dc24bede28ca92fbe917c3a972af2
F ext/wasm/tester1.c-pp.js 18331ec28d7e63c8e262a9872a8da3964d37b7ac22eabe0016af93f3c6f74cc4
F ext/wasm/tester1.c-pp.js 7c51d19f3644904156a154ddedd7024539ffba1a4e2df5e1efe10333e5b91b8f
F ext/wasm/tests/opfs/concurrency/index.html 0802373d57034d51835ff6041cda438c7a982deea6079efd98098d3e42fbcbc1
F ext/wasm/tests/opfs/concurrency/test.js a98016113eaf71e81ddbf71655aa29b0fed9a8b79a3cdd3620d1658eb1cc9a5d
F ext/wasm/tests/opfs/concurrency/worker.js 0a8c1a3e6ebb38aabbee24f122693f1fb29d599948915c76906681bb7da1d3d2
@@ -670,7 +670,7 @@ F ext/wasm/wasmfs.make 8a4955882aaa0783b3f60a9484a1f0f3d8b6f775c0fcd17c082f31966
F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x
F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8
F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0
F main.mk e5da4b6c13f2b15bba7f1efb0a47089dfdde0973e85a024785485655d59fd758
F main.mk 2c8b556ba7a4a15f5440663f7b05da221355d1921d5c75298bb50e2bb8081d79
F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271
F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504
F mptest/crash01.test 61e61469e257df0850df4293d7d4d6c2af301421
@@ -692,25 +692,25 @@ F src/btmutex.c 79a43670447eacc651519a429f6ece9fd638563cf95b469d6891185ddae2b522
F src/btree.c 285b493d843e7ba8ef78b6ae7d31238e904901dbc0c484f7904de4cf18fd8802
F src/btree.h 55066f513eb095db935169dab1dc2f7c7a747ef223c533f5d4ad4dfed346cbd0
F src/btreeInt.h 98aadb6dcb77b012cab2574d6a728fad56b337fc946839b9898c4b4c969e30b6
F src/build.c 04f1bcee189f045ab086d84fee95db42cb49df82ff8e84af8136309ff3c8a75f
F src/build.c 7ee3616b8a25577f2fb715d91eaa27f62a34e6ee6d0130cc8b9644c07875b759
F src/callback.c db3a45e376deff6a16c0058163fe0ae2b73a2945f3f408ca32cf74960b28d490
F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e
F src/ctime.c 23331529e654be40ca97d171cbbffe9b3d4c71cc53b78fe5501230675952da8b
F src/date.c 126ba2ab10aeb2e7ba6e089b5f07b747c0625b8287f78b60da346eda8d23c875
F src/date.c 90df32c2d8b2a38dd2e83d32e47802629305c4882fb2ec75c9ecdcd75b68bcb2
F src/dbpage.c 80e46e1df623ec40486da7a5086cb723b0275a6e2a7b01d9f9b5da0f04ba2782
F src/dbstat.c 3b677254d512fcafd4d0b341bf267b38b235ccfddbef24f9154e19360fa22e43
F src/delete.c cb766727c78e715f9fb7ec8a7d03658ed2a3016343ca687acfcec9083cdca500
F src/expr.c 05516e8b7d7d22f98160a0360fde69edce3304a430600567ed33e66d588ca59b
F src/expr.c 2803f5e7e3458ced24c0de48ec3640cd7a68ec61350d99c9f30b1bcd6640bd61
F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007
F src/fkey.c a47610f0a5c6cb0ad79f8fcef039c01833dec0c751bb695f28dc0ec6a4c3ba00
F src/fkey.c 0592046ed7598625234298211cc1fe611efb3fe7870a3f1938038fd9092c82f9
F src/func.c 4204c56196847faefef57fa14e43b8e4d65eb8d7e65318abe463472e3fd148cb
F src/global.c 765a0656d6cbf043cb272ff0ae38f39cc46713539ffe6793258ed3eb4b188b52
F src/hash.c 9ee4269fb1d6632a6fecfb9479c93a1f29271bddbbaf215dd60420bcb80c7220
F src/hash.h 3340ab6e1d13e725571d7cee6d3e3135f0779a7d8e76a9ce0a85971fa3953c51
F src/hwtime.h f9c2dfb84dce7acf95ce6d289e46f5f9d3d1afd328e53da8f8e9008e3b3caae6
F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71
F src/insert.c eb33ea46dcab93e90f112fced343aaf41f59cbd2e951d5066f1f9302be1c2f34
F src/json.c e2e40760d6689134c3e2ece38c6a496b34ff5e2661a8f238444a119af666fdce
F src/insert.c 3f0a94082d978bbdd33c38fefea15346c6c6bffb70bc645a71dc0f1f87dd3276
F src/json.c 3b4e2778d95d923d6d77e8a5efd51a6265017b466782d597303f5f094fcd68af
F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa
F src/loadext.c 7432c944ff197046d67a1207790a1b13eec4548c85a9457eb0896bb3641dfb36
F src/main.c 438b95162acfa17b7d218f586f5bde11d6ae82bcf030c9611fc537556870ad6b
@@ -739,7 +739,7 @@ F src/os_win.c 6ff43bac175bd9ed79e7c0f96840b139f2f51d01689a638fd05128becf94908a
F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a
F src/pager.c ff60e98138d2499082ac6230f01ac508aba545315debccfca2fd6042f5f10fcd
F src/pager.h 4b1140d691860de0be1347474c51fee07d5420bd7f802d38cbab8ea4ab9f538a
F src/parse.y 6209f01e8e7495379571454744fa82a5cfc2e7eeb89e46dee3f410d73ea6252d
F src/parse.y 9a77520c83950ced6e8b981c7826ebfd8e4a5c6e4b5d9743639e357910180c94
F src/pcache.c 040b165f30622a21b7a9a77c6f2e4877a32fb7f22d4c7f0d2a6fa6833a156a75
F src/pcache.h 1497ce1b823cf00094bb0cf3bac37b345937e6f910890c626b16512316d3abf5
F src/pcache1.c 602acb23c471bb8d557a6f0083cc2be641d6cafcafa19e481eba7ef4c9ca0f00
@@ -748,14 +748,14 @@ F src/pragma.h e690a356c18e98414d2e870ea791c1be1545a714ba623719deb63f7f226d8bb7
F src/prepare.c 371f6115cb69286ebc12c6f2d7511279c2e47d9f54f475d46a554d687a3b312c
F src/printf.c 10e8bad30042f8bd6114a013b4afc229ec8ad255ab27518d7d9f52e8cbc5cd0a
F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c
F src/resolve.c ef87e3bc7700bfe761a7bbee2ce6084f1766dc816dd82a3ae77c133eec898432
F src/resolve.c d77c6160bc8f249c2196fdd3e75f66a1dd70e37aa25c39aedc7b1f93c42b7c6d
F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97
F src/select.c 43fabfc01bf87addd15e39f112f1e2ade15b19594835ab8a9e5bd50839d4e1b1
F src/shell.c.in cf80c636bccb0ff9db46995e39d69ca21fde2a8a331d1691e4d62a69d7841c8a
F src/shell.c.in 2ec564ed3ff0147036be313efeb47b3dbfb8753d5eb5ea0e90636427c6b3a365
F src/sqlite.h.in 19a2db3995a699bd7f6dfb423856242bfceb7ec849a93c91d241d19fc28d9f0f
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
F src/sqlite3ext.h 3f046c04ea3595d6bfda99b781926b17e672fd6d27da2ba6d8d8fc39981dcb54
F src/sqliteInt.h 6123ce6ca6a1ef351c3b87189e92c92042728f16c088de56b9b5bc2552d0ae33
F src/sqliteInt.h 532224eec9f53245c8450c662c2a9d06a1aec22cb28e5fc4cdfd0f67239e9049
F src/sqliteLimit.h 6878ab64bdeb8c24a1d762d45635e34b96da21132179023338c93f820eee6728
F src/status.c cb11f8589a6912af2da3bb1ec509a94dd8ef27df4d4c1a97e0bcf2309ece972b
F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1
@@ -814,17 +814,17 @@ F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9
F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c
F src/tokenize.c 3f703cacdab728d7741e5a6ac242006d74fe1c2754d4f03ed889d7253259bd68
F src/treeview.c c6fc972683fd00f975d8b32a81c1f25d2fb7d4035366bf45c9f5622d3ccd70ee
F src/trigger.c 0905b96b04bb6658509f711a8207287f1315cdbc3df1a1b13ba6483c8e341c81
F src/trigger.c 15ca35f491c03197c3ccd5a0b3c5b926719cbe4e185b73da0507dbeb84a52d0e
F src/update.c 6904814dd62a7a93bbb86d9f1419c7f134a9119582645854ab02b36b676d9f92
F src/upsert.c 2e60567a0e9e8520c18671b30712a88dc73534474304af94f32bb5f3ef65ac65
F src/upsert.c fa125a8d3410ce9a97b02cb50f7ae68a2476c405c76aa692d3acf6b8586e9242
F src/utf.c f23165685a67b4caf8ec08fb274cb3f319103decfb2a980b7cfd55d18dfa855e
F src/util.c f27a17e6e43fa362abea4db507a1c409f0adc8048ecf4c6479e8d162158ed529
F src/util.c 0765014847e2a06c952dd64aef0bea5144cd5b335a161eb0768ebe4f63dfe216
F src/vacuum.c 604fcdaebe76f3497c855afcbf91b8fa5046b32de3045bab89cc008d68e40104
F src/vdbe.c da8407be6055f5751bf85681542d130a320b4fd1f4d8719bf83a464743d9aae4
F src/vdbe.c 523a88b3df328810fbcbb407738c352dd9d5163b7af4c953e6e9887a4b582859
F src/vdbe.h c2d78d15112c3fc5ab87f5e8e0b75d2db1c624409de2e858c3d1aafb1650bb4f
F src/vdbeInt.h 949669dfd8a41550d27dcb905b494f2ccde9a2e6c1b0b04daa1227e2e74c2b2c
F src/vdbeapi.c 8f57d60c89da0b60e6d4e272358c511f6bae4e24330bdb11f8b42f986d1bf21b
F src/vdbeaux.c 6385727adf51a649e4993098870a62c3945fe21dbc0e0fd9013772aff930b8fb
F src/vdbeaux.c 66161ba75c4a2d86aab124fe3cbcc2a752d8e4b1fc8c1fc6e00625db4798168c
F src/vdbeblob.c 13f9287b55b6356b4b1845410382d6bede203ceb29ef69388a4a3d007ffacbe5
F src/vdbemem.c 213bf303826c0ef702e3a2a69dab2309d84b8381b822c6787885859fd7cd4c4e
F src/vdbesort.c 237840ca1947511fa59bd4e18b9eeae93f2af2468c34d2427b059f896230a547
@@ -838,21 +838,21 @@ F src/walker.c 7c7ea0115345851c3da4e04e2e239a29983b61fb5b038b94eede6aba462640e2
F src/where.c 33eaaeef3aef10c2b9e82096e70a174d6636e35cb0b180321b8ddf804590e5cd
F src/whereInt.h 82a13766f13d1a53b05387c2e60726289ef26404bc7b9b1f7770204d97357fb8
F src/wherecode.c 5d77db30a2a3dd532492ae882de114edba2fae672622056b1c7fd61f5917a8f1
F src/whereexpr.c 6ebd90b553f4bb5c7df5a4b2f39b6a7c81a67484353827cdd2048f2514ec6f30
F src/whereexpr.c dc5096eca5ed503999be3bdee8a90c51361289a678d396a220912e9cb73b3c00
F src/window.c 5b1387d59df30d481ed14cceef5f4d1dab1f8752aa106ba72c8b62777bd139d2
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
F test/affinity2.test ce1aafc86e110685b324e9a763eab4f2a73f737842ec3b687bd965867de90627
F test/affinity3.test f094773025eddf31135c7ad4cde722b7696f8eb07b97511f98585addf2a510a9
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
F test/aggfault.test 777f269d0da5b0c2524c7ff6d99ae9a93db4f1b1839a914dd2a12e3035c29829
F test/aggnested.test 610b0ce2c3e8f3daee25f9752800ee8d785db10da4aa1fbeea0ea1aabaf1d704
F test/aggorderby.test cc3abf5de64d46ff66395ca8c2346b66c2576d5aedb7bffc5b0742508856e3bf
F test/aggnested.test 4dfdbfab105cec5750a1eeb59284ffffc3b37a32aaaf09143df3f549e28e2081
F test/aggorderby.test af1e07766e8f752d54dd317aa1d956e8e896671a70ddb20228e8cdf9391023b1
F test/alias.test 4529fbc152f190268a15f9384a5651bbbabc9d87
F test/all.test 2ecb8bbd52416642e41c9081182a8df05d42c75637afd4488aace78cc4b69e13
F test/alter.test 3c00eff1e2036b9f93e9cd0f3d3e63750ac87ecb5bc71b9d7bd07cbf2ac4c494
F test/alter2.test 7e3d26ab409df52df887b366a63902c3429b935c41cb962fd58ffc25784f2f19
F test/alter3.test ffc4ab29ce78a3517a66afd69b2730667e3471622509c283b2bd4c46f680fba3
F test/alter4.test 716caa071dd8a3c6d57225778d15d3c3cbf5e34b2e84ae44199aeb2bbf50a707
F test/alter3.test 0663df0cb3b9558ccc21abe642b792d4e2e747164156208e2a44ce88c09fe09b
F test/alter4.test 0ef8e62259bbc17495456d19e33a97b14cc2f634ef67bfdfb6a3f826eb9cfbc1
F test/alterauth.test 63442ba61ceb0c1eeb63aac1f4f5cebfa509d352276059d27106ae256bafc959
F test/alterauth2.test 48967abae0494d9a300d1c92473d99fcb66edfcc23579c89322f033f49410adc
F test/altercol.test 29fed774747777fbbaacdd865b4413ed2d0844a4c824f8af531b5c7d4a832087
@@ -870,7 +870,7 @@ F test/altertab2.test 62597b6fd08feaba1b6bfe7d31dac6117c67e06dc9ce9c478a3abe75b5
F test/altertab3.test 6c432fbb9963e0bd6549bf1422f6861d744ee5a80cb3298564e81e556481df16
F test/altertrig.test aacc980b657354fe2d3d4d3a004f07d04ccc1a93e5ef82d68a79088c274ddc6b
F test/amatch1.test b5ae7065f042b7f4c1c922933f4700add50cdb9f
F test/analyze.test 2fb21d7d64748636384e6cb8998dbf83968caf644c07fcb4f76c18f2e7ede94b
F test/analyze.test e8ab7a3fa8b0294dd72c6d0acd822c3b69fd4ab9392789b29dd29daaa8601b4c
F test/analyze3.test 03f4b3d794760cf15da2d85a52df9bae300e51c8fefe9c36cfae1f86dc10d23f
F test/analyze4.test 68bd069f3ac7ac1e652ddd9f04f57d5606ddb4208450f5297005db7aa0dd707d
F test/analyze5.test fa5131952303ac4146aba101b116b9c8cb89e2637531c334a6df7f7d19dddc0d
@@ -898,7 +898,7 @@ F test/attach2.test 6d1e3a457ce260d6fc8e5945c07fba6c76dc2aa90e1c701f067b50ee88f7
F test/attach3.test c59d92791070c59272e00183b7353eeb94915976
F test/attach4.test 00e754484859998d124d144de6d114d920f2ed6ca2f961e6a7f4183c714f885e
F test/attachmalloc.test 67309af95c6b765c13e7d2279d7fccbef78e6eb0565d75d51cefd5dc88784549
F test/auth.test 5b8558a40571ebc55c1581cb7cec3b2348a699542a0a51b83ef21c6a953d95e3
F test/auth.test 8d4152a8dca10e6dbe15b0c6dfcc183d5e9a7f6f983d9ae6e05f70e947aed7c3
F test/auth2.test 9eb7fce9f34bf1f50d3f366fb3e606be5a2000a1
F test/auth3.test 76d20a7fa136d63bcfcf8bcb65c0b1455ed71078d81f22bcd0550d3eb18594ab
F test/autoanalyze1.test b9cc3f32a990fa56669b668d237c6d53e983554ae80c0604992e18869a0b2dec
@@ -911,7 +911,7 @@ F test/autoindex5.test 2ee94f033b87ca0160e08d81034c507aff8e230df2627f0304fa309b2
F test/autovacuum.test 00671369bbf96c6a49989a9425f5b78b94075d6a4b031e5e00000c2c32f365df
F test/autovacuum2.test 76f7eb4fe6a6bf6d33a196a7141dba98886d2fb53a268d7feca285d5da4759d7
F test/autovacuum_ioerr2.test 8a367b224183ad801e0e24dcb7d1501f45f244b4
F test/avfs.test 76f59743dc1f5fa533840d1818b420fe1ee45e21c0fd6bbac7942ba677903128
F test/avfs.test 0c3a38e03cccb0fc3127838462dc05dc3f4c1480d770c084b388304c25de3652
F test/avtrans.test b7dc25459ecbd86c6fa9c606ee3068f59d81e225118617dcf2bbb6ded2ade89e
F test/backcompat.test 3e64cedda754c778ef6bbe417b6e7a295e662a4d
F test/backup.test 3b08fd4af69f0fa786931103a31f4542b184aba16e239e5f22b18c3c2476697f
@@ -1009,7 +1009,7 @@ F test/corrupt8.test 2399dfe40d2c0c63af86706e30f3e6302a8d0516
F test/corrupt9.test 730a3db08d4ab9aa43392ea30d9c2b4879cbff85
F test/corruptA.test 112f4b2ae0b95ebf3ea63718642fb969a93acea557ace3a307234d19c245989b
F test/corruptB.test 73a8d6c0b9833697ecf16b63e3c5c05c945b5dec
F test/corruptC.test 7d6d9e907334ea3ccb7111a0656cafa30a28f8a5f2aaf1c45ad712236302856a
F test/corruptC.test 9cf32275dae3ca33f645afe5d1d3f5ba5ac2af2b0833dfb5282f9dccb6fb81bb
F test/corruptD.test 614320aa519f6bf6c7dd2f581f9513ff7b6826954180cca1a606d0e25ea084a3
F test/corruptE.test 4143791f2dfb443aec5b7fabfa5821e6063eccc3b49b06f212c2f014715fd476
F test/corruptF.test be9fde98e4c93648f1ba52b74e5318edc8f59fe4
@@ -1042,7 +1042,7 @@ F test/ctime.test 340f362f41f92972bbd71f44e10569a5cc694062b692231bd08aa6fe6c1c47
F test/cursorhint.test 05cf0febe5c5f8a31f199401fd1c9322249e753950d55f26f9d5aca61408a270
F test/cursorhint2.test 6f3aa9cb19e7418967a10ec6905209bcbb5968054da855fc36c8beee9ae9c42f
F test/dataversion1.test 6e5e86ac681f0782e766ebcb56c019ae001522d114e0e111e5ebf68ccf2a7bb8
F test/date.test c8ff835023f2107b57ce7a45c92265d51c98a23fc93231e998f12d850831aad6
F test/date.test b1a5208e6a9c390cf1d1fa4e38a910386b427b0e27046901c6b0fb995d19800e
F test/date2.test 7e12ec14aaf4d5e6294b4ba140445b0eca06ea50062a9c3a69c4ee13d0b6f8b1
F test/date3.test a1b77abf05c6772fe5ca2337cac1398892f2a41e62bce7e6be0f4a08a0e64ae5
F test/date4.test 75dc8401e8c0639a228cd26a6eaa4ff5ea8ccda912b9853d1c9462c476670e17
@@ -1069,6 +1069,7 @@ F test/diskfull.test 106391384780753ea6896b7b4f005d10e9866b6e
F test/distinct.test 691c9e850b0d0b56b66e7e235453198cb4cf0760e324b7403d3c5abbeab0a014
F test/distinct2.test bb71cc7b5e58e895787f9910a788c254f679928d324732d063fe9bc202ecbe71
F test/distinctagg.test 40d7169ae5846caaf62c6e307d2ca3c333daf9b6f7cde888956a339a97afe85f
F test/drop-many.test 30dd091a4fd0a04b1a38e70c93f69c55749e62a3d895ac5e09277cd97caa5bbf
F test/e_blobbytes.test 4c01dfe4f12087b92b20705a3fdfded45dc4ed16d5a211fed4e1d2786ba68a52
F test/e_blobclose.test 692fc02a058476c2222a63d97e3f3b2b809c1842e5525ded7f854d540ac2e075
F test/e_blobopen.test 29f6055ee453b8e679fe9570c4d3acfedbef821622c5dad16875148c5952ef50
@@ -1119,7 +1120,7 @@ F test/filter1.test 590f8ba9a0cd0823b80d89ac75c5ce72276189cef9225d2436adaf1ee87f
F test/filter2.tcl 44e525497ce07382915f01bd29ffd0fa49dab3adb87253b5e5103ba8f93393e8
F test/filter2.test 3cc20eaea2ea1ab245197cc4a62468deb460b78f5aa9bd7d5d3353c2fe569bae
F test/filterfault.test c08fb491d698e8df6c122c98f7db1c65ffcfcad2c1ab0e07fa8a5be1b34eaa8b
F test/fkey1.test e563bcb4cb108ce3f40363cda4f84009dc89a39e2973076e5057ba99fca35378
F test/fkey1.test 6cf3fb520def0950799499b5bd0c6f22517cf7b6aee07523cbb52c1496aa8d00
F test/fkey2.test 1063d65e5923c054cfb8f0555a92a3ae0fa8c067275a33ee1715bd856cdb304c
F test/fkey3.test 76d475c80b84ee7a5d062e56ccb6ea68882e2b49
F test/fkey4.test 86446017011273aad8f9a99c1a65019e7bd9ca9d
@@ -1353,9 +1354,8 @@ F test/json102.test 557a46e16df1aa9bdbc4076a71a45814ea0e7503d6621d87d42a8c04cbc2
F test/json103.test 53df87f83a4e5fa0c0a56eb29ff6c94055c6eb919f33316d62161a8880112dbe
F test/json104.test 1b844a70cddcfa2e4cd81a5db0657b2e61e7f00868310f24f56a9ba0114348c1
F test/json105.test 043838b56e68f3252a0dcf5be1689016f6f3f05056f8dcfcdc9d074f4d932988
F test/json106.test 4aed3afd16549045d198a8d9cea00deea96e1f2ecf55864dce96cac558b8abef
F test/json106.test 1d46a9294e2ced35c7f87cebbcb9626d01abab04f1969d7ded7b6f6a1d9be0f2
F test/json107.test 59054e815c8f6b67d634d44ace421cf975828fb5651c4460aa66015c8e19d562
F test/json108.test 0a5f1e2d4b35a1bc33052563d2a5ede03052e2099e58cb424547656c898e0f49
F test/json501.test b95e2d14988b682a5cadf079dd6162f0f85fb74cd59c6b1f1624110104a974eb
F test/json502.test 84634d3dbb521d2814e43624025b760c6198456c8197bbec6c977c0236648f5b
F test/jsonb01.test f4cdfb4cf5a0c940091b17675ed9583f45add0c938f07d65b0de0e19d3a9a101
@@ -1455,7 +1455,7 @@ F test/notify1.test 669b2b743618efdc18ca4b02f45423d5d2304abf
F test/notify2.test 2ecabaa1305083856b7c39cf32816b612740c161
F test/notify3.test 796c7b7157f55c93b4e672b724e9c923a6fc6aa72ac419379a623e2350472e22
F test/notnull.test a37b663d5bb728d66fc182016613fb8e4a0a4bbf3d75b8876a7527f7d4ed3f18
F test/notnull2.test 2ac7b4e04917148c7a1a9ed36df20150175ce942f07f5714375b29acbaca7106
F test/notnull2.test 1ee4acbd614d3cf5f1c4a52f5af7fc771b82352f1a51a86afeaa02c9df1d82ef
F test/notnullfault.test fc4bb7845582a2b3db376001ef49118393b1b11abe0d24adb03db057ee2b73d5
F test/null.test b7ff206a1c60fe01aa2abd33ef9ea83c93727d993ca8a613de86e925c9f2bc6f
F test/nulls1.test 7a5e4346ee4285034100b4cd20e6784f16a9d6c927e44ecdf10034086bbee9c9
@@ -1501,7 +1501,7 @@ F test/pragma2.test e5d5c176360c321344249354c0c16aec46214c9f
F test/pragma3.test 92a46bbea12322dd94a404f49edcfbfc913a2c98115f0d030a7459bb4712ef31
F test/pragma4.test 9559cf5173864bf47c0431873d158fbeb72f920a59905b1f46069d8543eccdab
F test/pragma5.test 7b33fc43e2e41abf17f35fb73f71b49671a380ea92a6c94b6ce530a25f8d9102
F test/pragma6.test c5ec577ba087954b4dfa619a3cbe97b155b60a0af487527abe89b10fc17e6512
F test/pragma6.test fc3b670ab8ed985b2e5faa870f0f81aba1bfd5c3877ef3214e2df88592ccd3e5
F test/pragmafault.test 275edaf3161771d37de60e5c2b412627ac94cef11739236bec12ed1258b240f8
F test/prefixes.test b524a1c44bffec225b9aec98bd728480352aa8532ac4c15771fb85e8beef65d9
F test/printf.test 685fec5a0c5af2490ab0632775a301554361d674211d690f5bee0a97b05333de
@@ -1520,7 +1520,7 @@ F test/randexpr1.tcl 40dec52119ed3a2b8b2a773bce24b63a3a746459
F test/randexpr1.test eda062a97e60f9c38ae8d806b03b0ddf23d796df
F test/rbu.test 168573d353cd0fd10196b87b0caa322c144ef736
F test/rdonly.test 64e2696c322e3538df0b1ed624e21f9a23ed9ff8
F test/recover.test 6463509a7404e0c35431dd9b4a1c3b4a29d7a6af8a08462b31670c8a5a616d3a
F test/recover.test fd5199f928757cb308661b5fdca1abc19398a798ff7f24b57c3071e9f8e0471e
F test/regexp1.test 8f2a8bc1569666e29a4cee6c1a666cd224eb6d50e2470d1dc1df995170f3e0f1
F test/regexp2.test 55ed41da802b0e284ac7e2fe944be3948f93ff25abbca0361a609acfed1368b5
F test/reindex.test cd9d6021729910ece82267b4f5e1b5ac2911a7566c43b43c176a6a4732e2118d
@@ -1600,15 +1600,15 @@ F test/sharedA.test 64bdd21216dda2c6a3bd3475348ccdc108160f34682c97f2f51c19fc0e21
F test/sharedB.test 1a84863d7a2204e0d42f2e1606577c5e92e4473fa37ea0f5bdf829e4bf8ee707
F test/shared_err.test 32634e404a3317eeb94abc7a099c556a346fdb8fb3858dbe222a4cbb8926a939
F test/sharedlock.test 5ede3c37439067c43b0198f580fd374ebf15d304
F test/shell1.test 17a5ca9c6f24f807b2f505b4b38fcbce143d96cd8664c06c34bbbe0672bf7c30
F test/shell2.test 56da24128304c9ab67da2964cc80beff7b35761c446ec6e6e98bff2775b15026
F test/shell3.test 5ad4b2813717956414f2c0c8a2027895cd98ccf7dd54dbacbde4d4f5591ce5a1
F test/shell4.test 522fdc628c55eff697b061504fb0a9e4e6dfc5d9087a633ab0f3dd11bcc4f807
F test/shell5.test 5b2ab1c0540217773f939927c24163a56257446da3f564d4724042620bfea762
F test/shell6.test e3b883b61d4916b6906678a35f9d19054861123ad91b856461e0a456273bdbb8
F test/shell7.test 753c6ece5361df50025a50cadf378ea36db9cc05fb23d7a96cff7fa130626ef9
F test/shell8.test 9b71d56a6f6fc62edd9163534ac21eaa328ad95f1b9026e7bd08d5b4621eacf6
F test/shell9.test 8742a5b390cdcef6369f5aa223e415aa4255a4129ef249b177887dc635a87209
F test/shell1.test c7127a5e780ffc9e14c476773127fdf292c6db226529c44c1676f37b3793123f
F test/shell2.test 35226c070a8c7f64fd016dfac2a0db2a40f709b3131f61daacd9dad61536c9cb
F test/shell3.test 91febeac0412812bf6370abb8ed72700e32bf8f9878849414518f662dfd55e8a
F test/shell4.test 947029e5a9efae9054d424b309fc0311439c0c3a0866ebfa3b8a771120708220
F test/shell5.test c8b6c54f26ec537f8558273d7ed293ca3725ef42e6b12b8f151718628bd1473b
F test/shell6.test 1ceb51b2678c472ba6cf1e5da96679ce8347889fe2c3bf93a0e0fa73f00b00d3
F test/shell7.test 115132f66d0463417f408562cc2cf534f6bbc6d83a6d50f0072a9eb171bae97f
F test/shell8.test 3fd093d481aaa94dc77fb73f1044c1f19c7efe3477a395cc4f7450133bc54915
F test/shell9.test f457a96c088344908e0518dbabffd02eda8ac2a8733f278679e5f47c103efbab
F test/shmlock.test 3dbf017d34ab0c60abe6a44e447d3552154bd0c87b41eaf5ceacd408dd13fda5
F test/shortread1.test bb591ef20f0fd9ed26d0d12e80eee6d7ac8897a3
F test/show_speedtest1_rtree.tcl 32e6c5f073d7426148a6936a0408f4b5b169aba5
@@ -1687,7 +1687,7 @@ F test/temptable2.test 76821347810ecc88203e6ef0dd6897b6036ac788e9dd3e6b04fd4d163
F test/temptable3.test d11a0974e52b347e45ee54ef1923c91ed91e4637
F test/temptrigger.test 38f0ca479b1822d3117069e014daabcaacefffcc
F test/tester.tcl fe617b88c7eb08bdf983d2aaa31c20fbf439eee7b8e0d61ca636fcd0c305bbbf
F test/testrunner.tcl 9fb1341f4a3fcc169b0cffa2f319abde197a738d98131d178a81509a0638f2df
F test/testrunner.tcl 8e2a5c7550b78d3283eee6103104ae2bcf56aa1df892dbd1608f27b93ebf4de8
F test/testrunner_data.tcl 7ffd951527bbc614e723fd8d123b6834321878530696adecfdf6035100bac64e
F test/thread001.test a0985c117eab62c0c65526e9fa5d1360dd1cac5b03bde223902763274ce21899
F test/thread002.test c24c83408e35ba5a952a3638b7ac03ccdf1ce4409289c54a050ac4c5f1de7502
@@ -1750,7 +1750,7 @@ F test/tkt-b351d95f9.test d14a503c414c5c58fdde3e80f9a3cfef986498c0
F test/tkt-b72787b1.test a95e8cdad0b98af1853ac7f0afd4ab27b77bf5f3
F test/tkt-b75a9ca6b0.test dc6a853c242f7d0326564ae32e9e5eb462b5e8d2bc5b01ea3b18fd24f8e5894b
F test/tkt-ba7cbfaedc.test b4c0deccc12aeb55cfdb57935b16b5d67c5a9877
F test/tkt-bd484a090c.test e6af3e3a4242cd8f1c91c736364f09075d8e33e3b86f6492a1ee36278ea71b61
F test/tkt-bd484a090c.test 60460bf946f79a79712b71f202eda501ca99b898
F test/tkt-bdc6bbbb38.test fc38bb09bdd440e3513a1f5f98fc60a075182d7d
F test/tkt-c48d99d690.test ba61977d62ab612fc515b3c488a6fbd6464a2447
F test/tkt-c694113d5.test 82c461924ada5c14866c47e85535b0b0923ba16a2e907e370061a5ca77f65d77
@@ -1907,7 +1907,7 @@ F test/upsert1.test a512e2f884d3a36159fce2e45108c236f78ae38e35bda55f4050db580ceb
F test/upsert2.test 720e94d09f7362a282bc69b3c6b83d51daeaaf0440eb4920a08b86518b8c7496
F test/upsert3.test 88d7d590a1948a9cb6eac1b54b0642f67a9f35a1fc0f19b200e97d5d39e3179c
F test/upsert4.test 25d2a1da92f149331ae0c51ca6e3eee78189577585eab92de149900d62994fa5
F test/upsert5.test 9953b180d02d1369cdbb6c73c900834e5fef8cb78e98e07511c8762ec21cc176
F test/upsert5.test fff0dcfce73c649204543088d8e5bde01172676063ec9b8f8fc7f195abc386fe
F test/upsertfault.test f21ca47740841fdb4d61acfa7b17646d773e67724fe8c185b71c018db8a94b35
F test/uri.test c1abaaaa28e9422d61e5f3f9cbc8ef993ec49fe802f581520731708561d49384
F test/uri2.test 9d3ba7a53ee167572d53a298ee4a5d38ec4a8fb7
@@ -2009,7 +2009,7 @@ F test/whereH.test e4b07f7a3c2f5d31195cd33710054c78667573b2
F test/whereI.test c4bb7e2ca56d49bd8ab5c7bd085b8b83e353922b46904d68aefb3c7468643581
F test/whereJ.test fc05e374cc9f2dc204148d6c06822c380ad388895fe97a6d335b94a26a08aecf
F test/whereK.test 0270ab7f04ba5436fb9156d31d642a1c82727f4c4bfe5ba90d435c78cf44684a
F test/whereL.test f0e9585623af522ee9f382f8f945ad4b7eb7d806d18746f33f00c374acf6ab65
F test/whereL.test 9d7c8a9f4e5e82d6859e61cf8758c3856c7e0a7fd8be11c92cac8c3ec39228fd
F test/whereM.test 0dbc9998783458ddcf3cc078ca7c2951d8b2677d472ecf0028f449ed327c0250
F test/wherefault.test 6cf2a9c5712952d463d3f45ebee7f6caf400984df51a195d884cfb7eb0e837a7
F test/wherelfault.test 9012e4ef5259058b771606616bd007af5d154e64cc25fa9fd4170f6411db44e3
@@ -2101,7 +2101,7 @@ F tool/mkctimec.tcl a16682eae5f01f85e5861b2aa215ca0d46b4230658ee25977e02b4508566
F tool/mkkeywordhash.c b9faa0ae7e14e4dbbcd951cddd786bf46b8a65bb07b129ba8c0cfade723aaffd
F tool/mkmsvcmin.tcl 8897d515ef7f94772322db95a3b6fce6c614d84fe0bdd06ba5a1c786351d5a1d
F tool/mkopcodec.tcl 33d20791e191df43209b77d37f0ff0904620b28465cca6990cf8d60da61a07ef
F tool/mkopcodeh.tcl 2b4e6967a670ef21bf53a164964c35c6163277d002a4c6f56fa231d68c88d023
F tool/mkopcodeh.tcl 769d9e6a8b462323150dc13a8539d6064664b72974f7894befe2491cc73e05cd
F tool/mkopts.tcl 680f785fdb09729fd9ac50632413da4eadbdf9071535e3f26d03795828ab07fa
F tool/mkpragmatab.tcl 32e359ccb21011958a821955254bd7a5fa7915d01a8c16fed91ffc8b40cb4adf
F tool/mkshellc.tcl b7adf08b82de60811d2cb6af05ff59fc17e5cd6f3e98743c14eaaa3f8971fed0
@@ -2177,11 +2177,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
P 7805844bc4433ae088dae6d54eb972e082c5a3df06e844cfc8b69e7d97aeb432
R 9fe0d14be342ac1becb45016c9700f68
T *branch * testrunner-tmpdir-fix
T *sym-testrunner-tmpdir-fix *
T -sym-trunk *
U dan
Z 7a40c29cf47919cba49700f99392c55a
P 26272590691aee8569a1ea9c233f9b0e55ece63ed167696cc1ecfe3ca2548ba1
R ffcb677589cb061417252fbc7f9600de
U drh
Z 148d8810a6ba162cbd3b9cd95d027cbb
# Remove this line to create a well-formed Fossil manifest.
+1 -1
View File
@@ -1 +1 @@
775a10d10b9bf2227071e778718ba4054d4b2b4238751eb147338d687b4e0d58
1a49788afd90fa4415c6aae4b6bbad68f9306c1df1026762a9d88bcb40e4cd8f
+292 -194
View File
@@ -3260,84 +3260,129 @@ void sqlite3RootPageMoved(sqlite3 *db, int iDb, Pgno iFrom, Pgno iTo){
#endif
/*
** Write code to erase the table with root-page iTable from database iDb.
** Also write code to modify the sqlite_schema table and internal schema
** if a root-page of another table is moved by the btree-layer whilst
** erasing iTable (this can happen with an auto-vacuum database).
** The RootStack object holds a list (really a Heap) of btree root pages
** and schema numbers that need to be deleted using OP_Destroy.
**
** OP_Destroy opcodes must be issued in order of decreasing root page
** numbers in order to avoid having auto-vacuum disrupt subsequent
** OP_Destroy opcodes. For that reason, all pending OP_Destroy calls
** are accumulated in an instance of this object. Then at the end of
** code generation, this object is used to generate the OP_Destroy opcodes
** in decreasing order.
**
** The data structure is a max-heap. Each rootpage/schema-number combo
** is stored as a 64-bit integer, with the schema-number in the upper 32
** bits and the page number in the lower 32-bits. The root of the heap
** (RootStack.a[0]) is the largest entry in the heap. The children of
** heap entry i are i*2+1 and i*2+2. The heap always stays balanced by
** ensuring that a parent entry is larger than both children.
**
*/
static void destroyRootPage(Parse *pParse, int iTable, int iDb){
Vdbe *v = sqlite3GetVdbe(pParse);
int r1 = sqlite3GetTempReg(pParse);
if( iTable<2 ) sqlite3ErrorMsg(pParse, "corrupt schema");
sqlite3VdbeAddOp3(v, OP_Destroy, iTable, r1, iDb);
sqlite3MayAbort(pParse);
#ifndef SQLITE_OMIT_AUTOVACUUM
/* OP_Destroy stores an in integer r1. If this integer
** is non-zero, then it is the root page number of a table moved to
** location iTable. The following code modifies the sqlite_schema table to
** reflect this.
**
** The "#NNN" in the SQL is a special constant that means whatever value
** is in register NNN. See grammar rules associated with the TK_REGISTER
** token for additional information.
*/
sqlite3NestedParse(pParse,
"UPDATE %Q." LEGACY_SCHEMA_TABLE
" SET rootpage=%d WHERE #%d AND rootpage=#%d",
pParse->db->aDb[iDb].zDbSName, iTable, r1, r1);
#endif
sqlite3ReleaseTempReg(pParse, r1);
typedef struct RootStack RootStack;
struct RootStack {
u32 nAlloc; /* Slots allocated for a[] */
u32 nUsed; /* Slots used for in a[] */
u64 *a; /* Sorting heap. Each entry has iDb in the upper 32 bits and
** a page number in the lower 32 bits */
};
/*
** Add a new Pgno and iDb to the RootStack in question.
**
** The new entry is inserted at the of the heap (most distant child)
** and then the heap is rebalanced.
*/
static void rootStackPush(Parse *pParse, RootStack *p, Pgno pgno, int iDb){
u64 iNew;
int i, j;
if( p->nAlloc<p->nUsed+1 ){
p->nAlloc = p->nAlloc*2 + 12;
p->a = sqlite3DbRealloc(pParse->db, p->a, sizeof(Pgno)*p->nAlloc);
if( p->a==0 ){
p->nAlloc = p->nUsed = 0;
return;
}
}
assert( pgno>0 || CORRUPT_DB );
assert( iDb>=0 && iDb<pParse->db->nDb );
iNew = (((u64)iDb)<<32) | pgno;
i = p->nUsed++;
p->a[i] = iNew;
while( i>=1 && p->a[j = (i-1)/2]<p->a[i] ){
u64 tmp = p->a[i];
p->a[i] = p->a[j];
p->a[j] = tmp;
i = j;
}
}
/*
** Write VDBE code to erase table pTab and all associated indices on disk.
** Code to update the sqlite_schema tables and internal schema definitions
** in case a root-page belonging to another table is moved by the btree layer
** is also added (this can happen with an auto-vacuum database).
** Remove the largest entry from the RootStack heap. Rebalance the
** heap and then return that largest entry.
*/
static void destroyTable(Parse *pParse, Table *pTab){
/* If the database may be auto-vacuum capable (if SQLITE_OMIT_AUTOVACUUM
** is not defined), then it is important to call OP_Destroy on the
** table and index root-pages in order, starting with the numerically
** largest root-page number. This guarantees that none of the root-pages
** to be destroyed is relocated by an earlier OP_Destroy. i.e. if the
** following were coded:
**
** OP_Destroy 4 0
** ...
** OP_Destroy 5 0
**
** and root page 5 happened to be the largest root-page number in the
** database, then root page 5 would be moved to page 4 by the
** "OP_Destroy 4 0" opcode. The subsequent "OP_Destroy 5 0" would hit
** a free-list page.
*/
Pgno iTab = pTab->tnum;
Pgno iDestroyed = 0;
while( 1 ){
Index *pIdx;
Pgno iLargest = 0;
if( iDestroyed==0 || iTab<iDestroyed ){
iLargest = iTab;
}
for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
Pgno iIdx = pIdx->tnum;
assert( pIdx->pSchema==pTab->pSchema );
if( (iDestroyed==0 || (iIdx<iDestroyed)) && iIdx>iLargest ){
iLargest = iIdx;
}
}
if( iLargest==0 ){
return;
}else{
int iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema);
assert( iDb>=0 && iDb<pParse->db->nDb );
destroyRootPage(pParse, iLargest, iDb);
iDestroyed = iLargest;
}
static u64 rootStackPop(RootStack *p){
u64 iMax;
int i, j;
assert( p->nUsed>0 );
assert( p->a!=0 );
iMax = p->a[0];
p->a[0] = p->a[--p->nUsed];
i = 0;
while( (j = i*2+1)<p->nUsed ){
u64 tmp;
if( j+1<p->nUsed && p->a[j+1]>p->a[j] ) j++;
if( p->a[i]>p->a[j] ) break;
tmp = p->a[i];
p->a[i] = p->a[j];
p->a[j] = tmp;
i = j;
}
return iMax;
}
/*
** Generate OP_Destroy opcodes for every btree named in the given
** RootStack object. Issue these OP_Destroy opcodes in order of decreasing
** root page number. Then clean up any memory used by the RootStack.
*/
static void rootStackCode(Parse *pParse, RootStack *p){
int iLastDb = -1;
int r1 = sqlite3GetTempReg(pParse);
int r2 = sqlite3GetTempReg(pParse);
int regReturn = sqlite3GetTempReg(pParse);
Vdbe *v = pParse->pVdbe;
int addrSub = 0;
while( pParse->nErr==0 && p->nUsed>0 ){
u64 iNext = rootStackPop(p);
Pgno pgno = iNext & 0xffffffff;
int iDb = (iNext>>32)&0xffff;
if( pgno<2 ) sqlite3ErrorMsg(pParse, "corrupt schema");
sqlite3MayAbort(pParse);
if( iDb!=iLastDb ){
/* Code a subroutine to that will update the schema table when
** a root page number changes. The old root page is in register r1.
** Root page is moved to the value in register r2. */
iLastDb = iDb;
sqlite3VdbeAddOp0(v, OP_Goto);
addrSub = sqlite3VdbeCurrentAddr(v);
sqlite3NestedParse(pParse,
"UPDATE %Q." LEGACY_SCHEMA_TABLE
" SET rootpage=#%d WHERE rootpage=#%d",
pParse->db->aDb[iDb].zDbSName, r2, r1);
sqlite3VdbeAddOp1(v, OP_Return, regReturn);
sqlite3VdbeJumpHere(v, addrSub-1);
}
sqlite3VdbeAddOp3(v, OP_Destroy, pgno, r1, iDb);
sqlite3VdbeAddOp2(v, OP_IfNot, r1, sqlite3VdbeCurrentAddr(v)+3);
VdbeCoverage(v);
sqlite3VdbeAddOp2(v, OP_Integer, pgno, r2);
sqlite3VdbeAddOp2(v, OP_Gosub, regReturn, addrSub);
}
if( pParse->nErr==0 ){
sqlite3ReleaseTempReg(pParse, r1);
sqlite3ReleaseTempReg(pParse, regReturn);
}
sqlite3DbFree(pParse->db, p->a);
}
/*
@@ -3367,7 +3412,12 @@ static void sqlite3ClearStatTables(
/*
** Generate code to drop a table.
*/
void sqlite3CodeDropTable(Parse *pParse, Table *pTab, int iDb, int isView){
static void sqlite3CodeDropTable(
Parse *pParse, /* Parsing context */
RootStack *pStack, /* List of pending OP_Destroys */
Table *pTab, /* Table to be dropped */
int iDb /* Schema holding pTab */
){
Vdbe *v;
sqlite3 *db = pParse->db;
Trigger *pTrigger;
@@ -3420,8 +3470,13 @@ void sqlite3CodeDropTable(Parse *pParse, Table *pTab, int iDb, int isView){
"DELETE FROM %Q." LEGACY_SCHEMA_TABLE
" WHERE tbl_name=%Q and type!='trigger'",
pDb->zDbSName, pTab->zName);
if( !isView && !IsVirtual(pTab) ){
destroyTable(pParse, pTab);
if( IsOrdinaryTable(pTab) ){
Index *pIdx;
rootStackPush(pParse, pStack, pTab->tnum, iDb);
for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
if( pIdx->tnum==pTab->tnum ) continue;
rootStackPush(pParse, pStack, pIdx->tnum, iDb);
}
}
/* Remove the table entry from SQLite's internal schema and modify
@@ -3477,106 +3532,134 @@ static int tableMayNotBeDropped(sqlite3 *db, Table *pTab){
*/
void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView, int noErr){
Table *pTab;
Vdbe *v;
sqlite3 *db = pParse->db;
int iDb;
int ii, jj;
RootStack rootStack;
if( db->mallocFailed ){
goto exit_drop_table;
}
assert( pParse->nErr==0 );
assert( pName->nSrc==1 );
if( sqlite3ReadSchema(pParse) ) goto exit_drop_table;
if( noErr ) db->suppressErr++;
assert( isView==0 || isView==LOCATE_VIEW );
pTab = sqlite3LocateTableItem(pParse, isView, &pName->a[0]);
if( noErr ) db->suppressErr--;
memset(&rootStack, 0, sizeof(rootStack));
(void)sqlite3GetVdbe(pParse);
sqlite3ReadSchema(pParse);
assert( pName!=0 || pParse->nErr!=0 );
for(ii=0; pParse->nErr==0 && ii<pName->nSrc; ii++){
if( noErr ) db->suppressErr++;
assert( isView==0 || isView==LOCATE_VIEW );
pTab = sqlite3LocateTableItem(pParse, isView, &pName->a[ii]);
if( noErr ) db->suppressErr--;
if( pTab==0 ){
if( noErr ){
sqlite3CodeVerifyNamedSchema(pParse, pName->a[0].zDatabase);
sqlite3ForceNotReadOnly(pParse);
if( pTab==0 ){
if( noErr ){
sqlite3CodeVerifyNamedSchema(pParse, pName->a[ii].zDatabase);
sqlite3ForceNotReadOnly(pParse);
}
testcase( ii+1<pName->nSrc );
continue;
}
goto exit_drop_table;
}
iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
assert( iDb>=0 && iDb<db->nDb );
iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
assert( iDb>=0 && iDb<db->nDb );
/* If pTab is a virtual table, call ViewGetColumnNames() to ensure
** it is initialized.
*/
if( IsVirtual(pTab) && sqlite3ViewGetColumnNames(pParse, pTab) ){
goto exit_drop_table;
}
/* If pTab is a virtual table, call ViewGetColumnNames() to ensure
** it is initialized.
*/
if( IsVirtual(pTab) && sqlite3ViewGetColumnNames(pParse, pTab) ){
break;
}
#ifndef SQLITE_OMIT_AUTHORIZATION
{
int code;
const char *zTab = SCHEMA_TABLE(iDb);
const char *zDb = db->aDb[iDb].zDbSName;
const char *zArg2 = 0;
if( sqlite3AuthCheck(pParse, SQLITE_DELETE, zTab, 0, zDb)){
goto exit_drop_table;
}
if( isView ){
if( !OMIT_TEMPDB && iDb==1 ){
code = SQLITE_DROP_TEMP_VIEW;
}else{
code = SQLITE_DROP_VIEW;
{
int code;
const char *zTab = SCHEMA_TABLE(iDb);
const char *zDb = db->aDb[iDb].zDbSName;
const char *zArg2 = 0;
if( sqlite3AuthCheck(pParse, SQLITE_DELETE, zTab, 0, zDb)){
testcase( ii>0 );
testcase( ii+1<pName->nSrc );
break;
}
if( isView ){
if( !OMIT_TEMPDB && iDb==1 ){
code = SQLITE_DROP_TEMP_VIEW;
}else{
code = SQLITE_DROP_VIEW;
}
#ifndef SQLITE_OMIT_VIRTUALTABLE
}else if( IsVirtual(pTab) ){
code = SQLITE_DROP_VTABLE;
zArg2 = sqlite3GetVTable(db, pTab)->pMod->zName;
}else if( IsVirtual(pTab) ){
code = SQLITE_DROP_VTABLE;
zArg2 = sqlite3GetVTable(db, pTab)->pMod->zName;
#endif
}else{
if( !OMIT_TEMPDB && iDb==1 ){
code = SQLITE_DROP_TEMP_TABLE;
}else{
code = SQLITE_DROP_TABLE;
if( !OMIT_TEMPDB && iDb==1 ){
code = SQLITE_DROP_TEMP_TABLE;
}else{
code = SQLITE_DROP_TABLE;
}
}
if( sqlite3AuthCheck(pParse, code, pTab->zName, zArg2, zDb) ){
testcase( ii>0 );
testcase( ii+1<pName->nSrc );
break;
}
if( sqlite3AuthCheck(pParse, SQLITE_DELETE, pTab->zName, 0, zDb) ){
testcase( ii>0 );
testcase( ii+1<pName->nSrc );
break;
}
}
if( sqlite3AuthCheck(pParse, code, pTab->zName, zArg2, zDb) ){
goto exit_drop_table;
}
if( sqlite3AuthCheck(pParse, SQLITE_DELETE, pTab->zName, 0, zDb) ){
goto exit_drop_table;
}
}
#endif
if( tableMayNotBeDropped(db, pTab) ){
sqlite3ErrorMsg(pParse, "table %s may not be dropped", pTab->zName);
goto exit_drop_table;
}
if( tableMayNotBeDropped(db, pTab) ){
testcase( ii>0 );
testcase( ii+1<pName->nSrc );
sqlite3ErrorMsg(pParse, "table %s may not be dropped", pTab->zName);
break;
}
#ifndef SQLITE_OMIT_VIEW
/* Ensure DROP TABLE is not used on a view, and DROP VIEW is not used
** on a table.
*/
if( isView && !IsView(pTab) ){
sqlite3ErrorMsg(pParse, "use DROP TABLE to delete table %s", pTab->zName);
goto exit_drop_table;
}
if( !isView && IsView(pTab) ){
sqlite3ErrorMsg(pParse, "use DROP VIEW to delete view %s", pTab->zName);
goto exit_drop_table;
}
/* Ensure DROP TABLE is not used on a view, and DROP VIEW is not used
** on a table.
*/
if( isView && !IsView(pTab) ){
testcase( ii>0 );
testcase( ii+1<pName->nSrc );
sqlite3ErrorMsg(pParse, "use DROP TABLE to delete table %s", pTab->zName);
break;
}
if( !isView && IsView(pTab) ){
testcase( ii>0 );
testcase( ii+1<pName->nSrc );
sqlite3ErrorMsg(pParse, "use DROP VIEW to delete view %s", pTab->zName);
break;
}
#endif
/* If this table or view has appeared previously in the list of tables
** or views to be dropped, then the prior appearance is sufficient so
** skip this one. */
for(jj=ii-1; jj>=0 && pName->a[jj].pTab!=pTab; jj--){}
if( jj>=0 ) continue;
/* Generate code to remove the table from the schema table
** on disk.
*/
v = sqlite3GetVdbe(pParse);
if( v ){
/* Remember the table for use in the second pass */
pName->a[ii].pTab = pTab;
pTab->nTabRef++;
/* Generate code to clear this table from sqlite_statN and to
** cascade foreign key constraints.
*/
sqlite3BeginWriteOperation(pParse, 1, iDb);
if( !isView ){
if( IsOrdinaryTable(pTab) ){
sqlite3ClearStatTables(pParse, iDb, "tbl", pTab->zName);
sqlite3FkDropTable(pParse, pName, pTab);
}
sqlite3CodeDropTable(pParse, pTab, iDb, isView);
}
exit_drop_table:
/* Generate code to actually delete the tables/views in a second pass.
** Btrees must be deleted largest root page first, to avoid problems
** caused by autovacuum page reordering. */
for(ii=0; pParse->nErr==0 && ii<pName->nSrc; ii++){
pTab = pName->a[ii].pTab;
if( pTab==0 ) continue;
iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
sqlite3CodeDropTable(pParse, &rootStack, pTab, iDb);
}
sqlite3SrcListDelete(db, pName);
rootStackCode(pParse, &rootStack);
}
/*
@@ -4576,67 +4659,82 @@ void sqlite3DefaultRowEst(Index *pIdx){
*/
void sqlite3DropIndex(Parse *pParse, SrcList *pName, int ifExists){
Index *pIndex;
Vdbe *v;
sqlite3 *db = pParse->db;
Vdbe *v;
int iDb;
int ii, jj;
RootStack rootStack;
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;
}
pIndex = sqlite3FindIndex(db, pName->a[0].zName, pName->a[0].zDatabase);
if( pIndex==0 ){
if( !ifExists ){
sqlite3ErrorMsg(pParse, "no such index: %S", pName->a);
}else{
sqlite3CodeVerifyNamedSchema(pParse, pName->a[0].zDatabase);
sqlite3ForceNotReadOnly(pParse);
memset(&rootStack, 0, sizeof(rootStack));
v = sqlite3GetVdbe(pParse);
sqlite3ReadSchema(pParse);
assert( pName!=0 || pParse->nErr!=0 );
for(ii=0; pParse->nErr==0 && ii<pName->nSrc; ii++){
pName->a[ii].regReturn = 0;
pIndex = sqlite3FindIndex(db, pName->a[ii].zName, pName->a[ii].zDatabase);
if( pIndex==0 ){
if( !ifExists ){
sqlite3ErrorMsg(pParse, "no such index: %S", pName->a+ii);
}else{
sqlite3CodeVerifyNamedSchema(pParse, pName->a[ii].zDatabase);
sqlite3ForceNotReadOnly(pParse);
testcase( ii>0 );
testcase( ii+1<pName->nSrc );
}
pParse->checkSchema = 1;
continue;
}
pParse->checkSchema = 1;
goto exit_drop_index;
}
if( pIndex->idxType!=SQLITE_IDXTYPE_APPDEF ){
sqlite3ErrorMsg(pParse, "index associated with UNIQUE "
"or PRIMARY KEY constraint cannot be dropped", 0);
goto exit_drop_index;
}
iDb = sqlite3SchemaToIndex(db, pIndex->pSchema);
if( pIndex->idxType!=SQLITE_IDXTYPE_APPDEF ){
sqlite3ErrorMsg(pParse, "index associated with UNIQUE "
"or PRIMARY KEY constraint cannot be dropped", 0);
testcase( ii>0 );
testcase( ii+1<pName->nSrc );
break;
}
iDb = sqlite3SchemaToIndex(db, pIndex->pSchema);
#ifndef SQLITE_OMIT_AUTHORIZATION
{
int code = SQLITE_DROP_INDEX;
Table *pTab = pIndex->pTable;
const char *zDb = db->aDb[iDb].zDbSName;
const char *zTab = SCHEMA_TABLE(iDb);
if( sqlite3AuthCheck(pParse, SQLITE_DELETE, zTab, 0, zDb) ){
goto exit_drop_index;
{
int code = SQLITE_DROP_INDEX;
Table *pTab = pIndex->pTable;
const char *zDb = db->aDb[iDb].zDbSName;
const char *zTab = SCHEMA_TABLE(iDb);
if( sqlite3AuthCheck(pParse, SQLITE_DELETE, zTab, 0, zDb) ){
testcase( ii>0 );
testcase( ii+1<pName->nSrc );
break;
}
if( !OMIT_TEMPDB && iDb==1 ) code = SQLITE_DROP_TEMP_INDEX;
if( sqlite3AuthCheck(pParse, code, pIndex->zName, pTab->zName, zDb) ){
testcase( ii>0 );
testcase( ii+1<pName->nSrc );
break;
}
}
if( !OMIT_TEMPDB && iDb==1 ) code = SQLITE_DROP_TEMP_INDEX;
if( sqlite3AuthCheck(pParse, code, pIndex->zName, pTab->zName, zDb) ){
goto exit_drop_index;
}
}
#endif
/* Generate code to remove the index and from the schema table */
v = sqlite3GetVdbe(pParse);
if( v ){
/* Skip over redundant DROP INDEXes */
for(jj=ii-1; jj>=0 && pName->a[jj].u2.pIdx!=pIndex; jj--){}
if( jj>=0 ) continue;
/* Record that this index needs to be dropped. */
pName->a[ii].u2.pIdx = pIndex;
/* Generate code to remove the index and from the schema table and
** from sqlite_statN tables */
sqlite3BeginWriteOperation(pParse, 1, iDb);
sqlite3NestedParse(pParse,
"DELETE FROM %Q." LEGACY_SCHEMA_TABLE " WHERE name=%Q AND type='index'",
"DELETE FROM %Q." LEGACY_SCHEMA_TABLE
" WHERE name=%Q AND type='index'",
db->aDb[iDb].zDbSName, pIndex->zName
);
sqlite3ClearStatTables(pParse, iDb, "idx", pIndex->zName);
rootStackPush(pParse, &rootStack, pIndex->tnum, iDb);
sqlite3ChangeCookie(pParse, iDb);
destroyRootPage(pParse, pIndex->tnum, iDb);
sqlite3VdbeAddOp4(v, OP_DropIndex, iDb, 0, 0, pIndex->zName, 0);
}
exit_drop_index:
sqlite3SrcListDelete(db, pName);
rootStackCode(pParse, &rootStack);
}
/*
+29 -138
View File
@@ -71,14 +71,13 @@ struct DateTime {
int tz; /* Timezone offset in minutes */
double s; /* Seconds */
char validJD; /* True (1) if iJD is valid */
char rawS; /* Raw numeric value stored in s */
char validYMD; /* True (1) if Y,M,D are valid */
char validHMS; /* True (1) if h,m,s are valid */
char nFloor; /* Days to implement "floor" */
unsigned rawS : 1; /* Raw numeric value stored in s */
unsigned isError : 1; /* An overflow has occurred */
unsigned useSubsec : 1; /* Display subsecond precision */
unsigned isUtc : 1; /* Time is known to be UTC */
unsigned isLocal : 1; /* Time is known to be localtime */
char validTZ; /* True (1) if tz is valid */
char tzSet; /* Timezone was set explicitly */
char isError; /* An overflow has occurred */
char useSubsec; /* Display subsecond precision */
};
@@ -176,8 +175,6 @@ static int parseTimezone(const char *zDate, DateTime *p){
sgn = +1;
}else if( c=='Z' || c=='z' ){
zDate++;
p->isLocal = 0;
p->isUtc = 1;
goto zulu_time;
}else{
return c!=0;
@@ -190,6 +187,7 @@ static int parseTimezone(const char *zDate, DateTime *p){
p->tz = sgn*(nMn + nHr*60);
zulu_time:
while( sqlite3Isspace(*zDate) ){ zDate++; }
p->tzSet = 1;
return *zDate!=0;
}
@@ -233,6 +231,7 @@ static int parseHhMmSs(const char *zDate, DateTime *p){
p->m = m;
p->s = s + ms;
if( parseTimezone(zDate, p) ) return 1;
p->validTZ = (p->tz!=0)?1:0;
return 0;
}
@@ -279,40 +278,15 @@ static void computeJD(DateTime *p){
p->validJD = 1;
if( p->validHMS ){
p->iJD += p->h*3600000 + p->m*60000 + (sqlite3_int64)(p->s*1000 + 0.5);
if( p->tz ){
if( p->validTZ ){
p->iJD -= p->tz*60000;
p->validYMD = 0;
p->validHMS = 0;
p->tz = 0;
p->isUtc = 1;
p->isLocal = 0;
p->validTZ = 0;
}
}
}
/*
** Given the YYYY-MM-DD information current in p, determine if there
** is day-of-month overflow and set nFloor to the number of days that
** would need to be subtracted from the date in order to bring the
** date back to the end of the month.
*/
static void computeFloor(DateTime *p){
assert( p->validYMD || p->isError );
assert( p->D>=0 && p->D<=31 );
assert( p->M>=0 && p->M<=12 );
if( p->D<=28 ){
p->nFloor = 0;
}else if( (1<<p->M) & 0x15aa ){
p->nFloor = 0;
}else if( p->M!=2 ){
p->nFloor = (p->D==31);
}else if( p->Y%4!=0 || (p->Y%100==0 && p->Y%400!=0) ){
p->nFloor = p->D - 28;
}else{
p->nFloor = p->D - 29;
}
}
/*
** Parse dates of the form
**
@@ -351,16 +325,12 @@ static int parseYyyyMmDd(const char *zDate, DateTime *p){
p->Y = neg ? -Y : Y;
p->M = M;
p->D = D;
computeFloor(p);
if( p->tz ){
if( p->validTZ ){
computeJD(p);
}
return 0;
}
static void clearYMD_HMS_TZ(DateTime *p); /* Forward declaration */
/*
** Set the time to the current time reported by the VFS.
**
@@ -370,9 +340,6 @@ static int setDateTimeToCurrent(sqlite3_context *context, DateTime *p){
p->iJD = sqlite3StmtCurrentTime(context);
if( p->iJD>0 ){
p->validJD = 1;
p->isUtc = 1;
p->isLocal = 0;
clearYMD_HMS_TZ(p);
return 0;
}else{
return 1;
@@ -511,7 +478,7 @@ static void computeYMD_HMS(DateTime *p){
static void clearYMD_HMS_TZ(DateTime *p){
p->validYMD = 0;
p->validHMS = 0;
p->tz = 0;
p->validTZ = 0;
}
#ifndef SQLITE_OMIT_LOCALTIME
@@ -643,7 +610,7 @@ static int toLocaltime(
p->validHMS = 1;
p->validJD = 0;
p->rawS = 0;
p->tz = 0;
p->validTZ = 0;
p->isError = 0;
return SQLITE_OK;
}
@@ -663,12 +630,12 @@ static const struct {
float rLimit; /* Maximum NNN value for this transform */
float rXform; /* Constant used for this transform */
} aXformType[] = {
/* 0 */ { 6, "second", 4.6427e+14, 1.0 },
/* 1 */ { 6, "minute", 7.7379e+12, 60.0 },
/* 2 */ { 4, "hour", 1.2897e+11, 3600.0 },
/* 3 */ { 3, "day", 5373485.0, 86400.0 },
/* 4 */ { 5, "month", 176546.0, 30.0*86400.0 },
/* 5 */ { 4, "year", 14713.0, 365.0*86400.0 },
{ 6, "second", 4.6427e+14, 1.0 },
{ 6, "minute", 7.7379e+12, 60.0 },
{ 4, "hour", 1.2897e+11, 3600.0 },
{ 3, "day", 5373485.0, 86400.0 },
{ 5, "month", 176546.0, 2592000.0 },
{ 4, "year", 14713.0, 31536000.0 },
};
/*
@@ -700,20 +667,14 @@ static void autoAdjustDate(DateTime *p){
** NNN.NNNN seconds
** NNN months
** NNN years
** +/-YYYY-MM-DD HH:MM:SS.SSS
** ceiling
** floor
** start of month
** start of year
** start of week
** start of day
** weekday N
** unixepoch
** auto
** localtime
** utc
** subsec
** subsecond
**
** Return 0 on success and 1 if there is any kind of error. If the error
** is in a system call (i.e. localtime()), then an error message is written
@@ -744,37 +705,6 @@ static int parseModifier(
}
break;
}
case 'c': {
/*
** ceiling
**
** Resolve day-of-month overflow by rolling forward into the next
** month. As this is the default action, this modifier is really
** a no-op that is only included for symmetry. See "floor".
*/
if( sqlite3_stricmp(z, "ceiling")==0 ){
computeJD(p);
clearYMD_HMS_TZ(p);
rc = 0;
p->nFloor = 0;
}
break;
}
case 'f': {
/*
** floor
**
** Resolve day-of-month overflow by rolling back to the end of the
** previous month.
*/
if( sqlite3_stricmp(z, "floor")==0 ){
computeJD(p);
p->iJD -= p->nFloor*86400000;
clearYMD_HMS_TZ(p);
rc = 0;
}
break;
}
case 'j': {
/*
** julianday
@@ -801,9 +731,7 @@ static int parseModifier(
** show local time.
*/
if( sqlite3_stricmp(z, "localtime")==0 && sqlite3NotPureFunc(pCtx) ){
rc = p->isLocal ? SQLITE_OK : toLocaltime(p, pCtx);
p->isUtc = 0;
p->isLocal = 1;
rc = toLocaltime(p, pCtx);
}
break;
}
@@ -828,7 +756,7 @@ static int parseModifier(
}
#ifndef SQLITE_OMIT_LOCALTIME
else if( sqlite3_stricmp(z, "utc")==0 && sqlite3NotPureFunc(pCtx) ){
if( p->isUtc==0 ){
if( p->tzSet==0 ){
i64 iOrigJD; /* Original localtime */
i64 iGuess; /* Guess at the corresponding utc time */
int cnt = 0; /* Safety to prevent infinite loop */
@@ -851,8 +779,7 @@ static int parseModifier(
memset(p, 0, sizeof(*p));
p->iJD = iGuess;
p->validJD = 1;
p->isUtc = 1;
p->isLocal = 0;
p->tzSet = 1;
}
rc = SQLITE_OK;
}
@@ -872,7 +799,7 @@ static int parseModifier(
&& r>=0.0 && r<7.0 && (n=(int)r)==r ){
sqlite3_int64 Z;
computeYMD_HMS(p);
p->tz = 0;
p->validTZ = 0;
p->validJD = 0;
computeJD(p);
Z = ((p->iJD + 129600000)/86400000) % 7;
@@ -912,7 +839,7 @@ static int parseModifier(
p->h = p->m = 0;
p->s = 0.0;
p->rawS = 0;
p->tz = 0;
p->validTZ = 0;
p->validJD = 0;
if( sqlite3_stricmp(z,"month")==0 ){
p->D = 1;
@@ -983,7 +910,6 @@ static int parseModifier(
x = p->M>0 ? (p->M-1)/12 : (p->M-12)/12;
p->Y += x;
p->M -= x*12;
computeFloor(p);
computeJD(p);
p->validHMS = 0;
p->validYMD = 0;
@@ -1030,12 +956,11 @@ static int parseModifier(
z += n;
while( sqlite3Isspace(*z) ) z++;
n = sqlite3Strlen30(z);
if( n<3 || n>10 ) break;
if( n>10 || n<3 ) break;
if( sqlite3UpperToLower[(u8)z[n-1]]=='s' ) n--;
computeJD(p);
assert( rc==1 );
rRounder = r<0 ? -0.5 : +0.5;
p->nFloor = 0;
for(i=0; i<ArraySize(aXformType); i++){
if( aXformType[i].nName==n
&& sqlite3_strnicmp(aXformType[i].zName, z, n)==0
@@ -1043,24 +968,21 @@ static int parseModifier(
){
switch( i ){
case 4: { /* Special processing to add months */
assert( strcmp(aXformType[4].zName,"month")==0 );
assert( strcmp(aXformType[i].zName,"month")==0 );
computeYMD_HMS(p);
p->M += (int)r;
x = p->M>0 ? (p->M-1)/12 : (p->M-12)/12;
p->Y += x;
p->M -= x*12;
computeFloor(p);
p->validJD = 0;
r -= (int)r;
break;
}
case 5: { /* Special processing to add years */
int y = (int)r;
assert( strcmp(aXformType[5].zName,"year")==0 );
assert( strcmp(aXformType[i].zName,"year")==0 );
computeYMD_HMS(p);
assert( p->M>=0 && p->M<=12 );
p->Y += y;
computeFloor(p);
p->validJD = 0;
r -= (int)r;
break;
@@ -1685,7 +1607,9 @@ static void timediffFunc(
d1.iJD = d2.iJD - d1.iJD;
d1.iJD += (u64)1486995408 * (u64)100000;
}
clearYMD_HMS_TZ(&d1);
d1.validYMD = 0;
d1.validHMS = 0;
d1.validTZ = 0;
computeYMD_HMS(&d1);
sqlite3StrAccumInit(&sRes, 0, 0, 0, 100);
sqlite3_str_appendf(&sRes, "%c%04d-%02d-%02d %02d:%02d:%06.3f",
@@ -1754,36 +1678,6 @@ static void currentTimeFunc(
}
#endif
#if !defined(SQLITE_OMIT_DATETIME_FUNCS) && defined(SQLITE_DEBUG)
/*
** datedebug(...)
**
** This routine returns JSON that describes the internal DateTime object.
** Used for debugging and testing only. Subject to change.
*/
static void datedebugFunc(
sqlite3_context *context,
int argc,
sqlite3_value **argv
){
DateTime x;
if( isDate(context, argc, argv, &x)==0 ){
char *zJson;
zJson = sqlite3_mprintf(
"{iJD:%lld,Y:%d,M:%d,D:%d,h:%d,m:%d,tz:%d,"
"s:%.3f,validJD:%d,validYMS:%d,validHMS:%d,"
"nFloor:%d,rawS:%d,isError:%d,useSubsec:%d,"
"isUtc:%d,isLocal:%d}",
x.iJD, x.Y, x.M, x.D, x.h, x.m, x.tz,
x.s, x.validJD, x.validYMD, x.validHMS,
x.nFloor, x.rawS, x.isError, x.useSubsec,
x.isUtc, x.isLocal);
sqlite3_result_text(context, zJson, -1, sqlite3_free);
}
}
#endif /* !SQLITE_OMIT_DATETIME_FUNCS && SQLITE_DEBUG */
/*
** This function registered all of the above C functions as SQL
** functions. This should be the only routine in this file with
@@ -1799,9 +1693,6 @@ void sqlite3RegisterDateTimeFunctions(void){
PURE_DATE(datetime, -1, 0, 0, datetimeFunc ),
PURE_DATE(strftime, -1, 0, 0, strftimeFunc ),
PURE_DATE(timediff, 2, 0, 0, timediffFunc ),
#ifdef SQLITE_DEBUG
PURE_DATE(datedebug, -1, 0, 0, datedebugFunc ),
#endif
DFUNCTION(current_time, 0, 0, 0, ctimeFunc ),
DFUNCTION(current_timestamp, 0, 0, 0, ctimestampFunc),
DFUNCTION(current_date, 0, 0, 0, cdateFunc ),
+6
View File
@@ -4617,6 +4617,12 @@ expr_code_doover:
assert( pExpr->u.zToken!=0 );
assert( pExpr->u.zToken[0]!=0 );
sqlite3VdbeAddOp2(v, OP_Variable, pExpr->iColumn, target);
if( pExpr->u.zToken[1]!=0 ){
const char *z = sqlite3VListNumToName(pParse->pVList, pExpr->iColumn);
assert( pExpr->u.zToken[0]=='?' || (z && !strcmp(pExpr->u.zToken, z)) );
pParse->pVList[0] = 0; /* Indicate VList may no longer be enlarged */
sqlite3VdbeAppendP4(v, (char*)z, P4_STATIC);
}
return target;
}
case TK_REGISTER: {
+25 -6
View File
@@ -718,8 +718,9 @@ void sqlite3FkClearTriggerCache(sqlite3 *db, int iDb){
/*
** This function is called to generate code that runs when table pTab is
** being dropped from the database. The SrcList passed as the second argument
** to this function contains a single entry guaranteed to resolve to
** table pTab.
** to this function contains entries for every table that is being dropped,
** with the SrcItem.pTab line being set to the table being dropped. pTab
** will be one of those tables.
**
** Normally, no code is required. However, if either
**
@@ -728,15 +729,23 @@ void sqlite3FkClearTriggerCache(sqlite3 *db, int iDb){
** determined at runtime that there are outstanding deferred FK
** constraint violations in the database,
**
** then the equivalent of "DELETE FROM <tbl>" is executed before dropping
** the table from the database. Triggers are disabled while running this
** DELETE, but foreign key actions are not.
** then the equivalent of "DELETE FROM <tbl>" is executed for every table
** being dropped, in the order specified in the DROP TABLE statement, which
** is the same as the order in which these tables appear in pName.
** Triggers are disabled while running these DELETEs, but foreign key
** actions are not.
**
** This routine sets the SrcList.addrFillSub value for all pName entries
** for which DELETE FROM has been run. This prevents the DELETE FROM
** from being run multiple times.
*/
void sqlite3FkDropTable(Parse *pParse, SrcList *pName, Table *pTab){
sqlite3 *db = pParse->db;
if( (db->flags&SQLITE_ForeignKeys) && IsOrdinaryTable(pTab) ){
int iSkip = 0;
Vdbe *v = sqlite3GetVdbe(pParse);
SrcList *pSrc;
int ii;
assert( v ); /* VDBE has already been allocated */
assert( IsOrdinaryTable(pTab) );
@@ -756,7 +765,17 @@ void sqlite3FkDropTable(Parse *pParse, SrcList *pName, Table *pTab){
}
pParse->disableTriggers = 1;
sqlite3DeleteFrom(pParse, sqlite3SrcListDup(db, pName, 0), 0, 0, 0);
for(ii=0; ii<pName->nSrc; ii++){
if( pName->a[ii].pTab==0 ) continue;
if( pName->a[ii].addrFillSub ) continue;
pName->a[ii].addrFillSub = 1;
pSrc = sqlite3SrcListAppend(pParse, 0, 0, 0);
if( pSrc ){
pSrc->a[0].zDatabase = sqlite3DbStrDup(db, pName->a[ii].zDatabase);
pSrc->a[0].zName = sqlite3DbStrDup(db, pName->a[ii].zName);
sqlite3DeleteFrom(pParse, pSrc, 0, 0, 0);
}
}
pParse->disableTriggers = 0;
/* If the DELETE has generated immediate foreign key constraint
+1 -1
View File
@@ -1086,7 +1086,7 @@ void sqlite3Insert(
pNx->iDataCur = iDataCur;
pNx->iIdxCur = iIdxCur;
if( pNx->pUpsertTarget ){
if( sqlite3UpsertAnalyzeTarget(pParse, pTabList, pNx, pUpsert) ){
if( sqlite3UpsertAnalyzeTarget(pParse, pTabList, pNx) ){
goto insert_cleanup;
}
}
+3 -144
View File
@@ -563,6 +563,7 @@ static void jsonAppendRawNZ(JsonString *p, const char *zIn, u32 N){
}
}
/* Append formatted text (not to exceed N bytes) to the JsonString.
*/
static void jsonPrintf(int N, JsonString *p, const char *zFormat, ...){
@@ -2335,112 +2336,6 @@ static u32 jsonTranslateBlobToText(
return i+n+sz;
}
/* Context for recursion of json_pretty()
*/
typedef struct JsonPretty JsonPretty;
struct JsonPretty {
JsonParse *pParse; /* The BLOB being rendered */
JsonString *pOut; /* Generate pretty output into this string */
const char *zIndent; /* Use this text for indentation */
u32 szIndent; /* Bytes in zIndent[] */
u32 nIndent; /* Current level of indentation */
};
/* Append indentation to the pretty JSON under construction */
static void jsonPrettyIndent(JsonPretty *pPretty){
u32 jj;
for(jj=0; jj<pPretty->nIndent; jj++){
jsonAppendRaw(pPretty->pOut, pPretty->zIndent, pPretty->szIndent);
}
}
/*
** Translate the binary JSONB representation of JSON beginning at
** pParse->aBlob[i] into a JSON text string. Append the JSON
** text onto the end of pOut. Return the index in pParse->aBlob[]
** of the first byte past the end of the element that is translated.
**
** This is a variant of jsonTranslateBlobToText() that "pretty-prints"
** the output. Extra whitespace is inserted to make the JSON easier
** for humans to read.
**
** If an error is detected in the BLOB input, the pOut->eErr flag
** might get set to JSTRING_MALFORMED. But not all BLOB input errors
** are detected. So a malformed JSONB input might either result
** in an error, or in incorrect JSON.
**
** The pOut->eErr JSTRING_OOM flag is set on a OOM.
*/
static u32 jsonTranslateBlobToPrettyText(
JsonPretty *pPretty, /* Pretty-printing context */
u32 i /* Start rendering at this index */
){
u32 sz, n, j, iEnd;
const JsonParse *pParse = pPretty->pParse;
JsonString *pOut = pPretty->pOut;
n = jsonbPayloadSize(pParse, i, &sz);
if( n==0 ){
pOut->eErr |= JSTRING_MALFORMED;
return pParse->nBlob+1;
}
switch( pParse->aBlob[i] & 0x0f ){
case JSONB_ARRAY: {
j = i+n;
iEnd = j+sz;
jsonAppendChar(pOut, '[');
if( j<iEnd ){
jsonAppendChar(pOut, '\n');
pPretty->nIndent++;
while( pOut->eErr==0 ){
jsonPrettyIndent(pPretty);
j = jsonTranslateBlobToPrettyText(pPretty, j);
if( j>=iEnd ) break;
jsonAppendRawNZ(pOut, ",\n", 2);
}
jsonAppendChar(pOut, '\n');
pPretty->nIndent--;
jsonPrettyIndent(pPretty);
}
jsonAppendChar(pOut, ']');
i = iEnd;
break;
}
case JSONB_OBJECT: {
j = i+n;
iEnd = j+sz;
jsonAppendChar(pOut, '{');
if( j<iEnd ){
jsonAppendChar(pOut, '\n');
pPretty->nIndent++;
while( pOut->eErr==0 ){
jsonPrettyIndent(pPretty);
j = jsonTranslateBlobToText(pParse, j, pOut);
if( j>iEnd ){
pOut->eErr |= JSTRING_MALFORMED;
break;
}
jsonAppendRawNZ(pOut, ": ", 2);
j = jsonTranslateBlobToPrettyText(pPretty, j);
if( j>=iEnd ) break;
jsonAppendRawNZ(pOut, ",\n", 2);
}
jsonAppendChar(pOut, '\n');
pPretty->nIndent--;
jsonPrettyIndent(pPretty);
}
jsonAppendChar(pOut, '}');
i = iEnd;
break;
}
default: {
i = jsonTranslateBlobToText(pParse, i, pOut);
break;
}
}
return i;
}
/* Return true if the input pJson
**
** For performance reasons, this routine does not do a detailed check of the
@@ -4360,40 +4255,6 @@ json_type_done:
jsonParseFree(p);
}
/*
** json_pretty(JSON)
** json_pretty(JSON, INDENT)
**
** Return text that is a pretty-printed rendering of the input JSON.
** If the argument is not valid JSON, return NULL.
**
** The INDENT argument is text that is used for indentation. If omitted,
** it defaults to four spaces (the same as PostgreSQL).
*/
static void jsonPrettyFunc(
sqlite3_context *ctx,
int argc,
sqlite3_value **argv
){
JsonString s; /* The output string */
JsonPretty x; /* Pretty printing context */
memset(&x, 0, sizeof(x));
x.pParse = jsonParseFuncArg(ctx, argv[0], 0);
if( x.pParse==0 ) return;
x.pOut = &s;
jsonStringInit(&s, ctx);
if( argc==1 || (x.zIndent = (const char*)sqlite3_value_text(argv[1]))==0 ){
x.zIndent = " ";
x.szIndent = 4;
}else{
x.szIndent = (u32)strlen(x.zIndent);
}
jsonTranslateBlobToPrettyText(&x, 0);
jsonReturnString(&s, 0, 0);
jsonParseFree(x.pParse);
}
/*
** json_valid(JSON)
** json_valid(JSON, FLAGS)
@@ -5132,9 +4993,9 @@ static int jsonEachColumn(
case JEACH_JSON: {
if( p->sParse.zJson==0 ){
sqlite3_result_blob(ctx, p->sParse.aBlob, p->sParse.nBlob,
SQLITE_TRANSIENT);
SQLITE_STATIC);
}else{
sqlite3_result_text(ctx, p->sParse.zJson, -1, SQLITE_TRANSIENT);
sqlite3_result_text(ctx, p->sParse.zJson, -1, SQLITE_STATIC);
}
break;
}
@@ -5408,8 +5269,6 @@ void sqlite3RegisterJsonFunctions(void){
JFUNCTION(jsonb_object, -1,0,1, 1,1,0, jsonObjectFunc),
JFUNCTION(json_patch, 2,1,1, 0,0,0, jsonPatchFunc),
JFUNCTION(jsonb_patch, 2,1,0, 0,1,0, jsonPatchFunc),
JFUNCTION(json_pretty, 1,1,0, 0,0,0, jsonPrettyFunc),
JFUNCTION(json_pretty, 2,1,0, 0,0,0, jsonPrettyFunc),
JFUNCTION(json_quote, 1,0,1, 1,0,0, jsonQuoteFunc),
JFUNCTION(json_remove, -1,1,1, 0,0,0, jsonRemoveFunc),
JFUNCTION(jsonb_remove, -1,1,0, 0,1,0, jsonRemoveFunc),
+16 -4
View File
@@ -471,7 +471,7 @@ resolvetype(A) ::= REPLACE. {A = OE_Replace;}
////////////////////////// The DROP TABLE /////////////////////////////////////
//
cmd ::= DROP TABLE ifexists(E) fullname(X). {
cmd ::= DROP TABLE ifexists(E) fullnamelist(X). {
sqlite3DropTable(pParse, X, 0, E);
}
%type ifexists {int}
@@ -485,7 +485,7 @@ cmd ::= createkw(X) temp(T) VIEW ifnotexists(E) nm(Y) dbnm(Z) eidlist_opt(C)
AS select(S). {
sqlite3CreateView(pParse, &X, &Y, &Z, C, S, T, E);
}
cmd ::= DROP VIEW ifexists(E) fullname(X). {
cmd ::= DROP VIEW ifexists(E) fullnamelist(X). {
sqlite3DropTable(pParse, X, 1, E);
}
%endif SQLITE_OMIT_VIEW
@@ -774,6 +774,18 @@ fullname(A) ::= nm(X) DOT nm(Y). {
if( IN_RENAME_OBJECT && A ) sqlite3RenameTokenMap(pParse, A->a[0].zName, &Y);
}
%type fullnamelist {SrcList*}
%destructor fullnamelist {sqlite3SrcListDelete(pParse->db, $$);}
fullnamelist(A) ::= fullname(A).
fullnamelist(A) ::= fullnamelist(L) COMMA nm(X). {
A = sqlite3SrcListAppend(pParse,L,&X,0);
assert( !IN_RENAME_OBJECT ); /* Used only by DROP, which cannot be part of schema */
}
fullnamelist(A) ::= fullnamelist(L) COMMA nm(X) DOT nm(Y). {
A = sqlite3SrcListAppend(pParse,L,&X,&Y);
assert( !IN_RENAME_OBJECT ); /* Used only by DROP, which cannot be part of schema */
}
%type xfullname {SrcList*}
%destructor xfullname {sqlite3SrcListDelete(pParse->db, $$);}
xfullname(A) ::= nm(X).
@@ -1504,7 +1516,7 @@ collate(C) ::= COLLATE ids. {C = 1;}
///////////////////////////// The DROP INDEX command /////////////////////////
//
cmd ::= DROP INDEX ifexists(E) fullname(X). {sqlite3DropIndex(pParse, X, E);}
cmd ::= DROP INDEX ifexists(E) fullnamelist(X). {sqlite3DropIndex(pParse, X, E);}
///////////////////////////// The VACUUM command /////////////////////////////
//
@@ -1661,7 +1673,7 @@ raisetype(A) ::= FAIL. {A = OE_Fail;}
//////////////////////// DROP TRIGGER statement //////////////////////////////
%ifndef SQLITE_OMIT_TRIGGER
cmd ::= DROP TRIGGER ifexists(NOERR) fullname(X). {
cmd ::= DROP TRIGGER ifexists(NOERR) fullnamelist(X). {
sqlite3DropTrigger(pParse,X,NOERR);
}
%endif !SQLITE_OMIT_TRIGGER
+10 -42
View File
@@ -971,19 +971,6 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
** resolved. This prevents "column" from being counted as having been
** referenced, which might prevent a SELECT from being erroneously
** marked as correlated.
**
** 2024-03-28: Beware of aggregates. A bare column of aggregated table
** can still evaluate to NULL even though it is marked as NOT NULL.
** Example:
**
** CREATE TABLE t1(a INT NOT NULL);
** SELECT a, a IS NULL, a IS NOT NULL, count(*) FROM t1;
**
** The "a IS NULL" and "a IS NOT NULL" expressions cannot be optimized
** here because at the time this case is hit, we do not yet know whether
** or not t1 is being aggregated. We have to assume the worst and omit
** the optimization. The only time it is safe to apply this optimization
** is within the WHERE clause.
*/
case TK_NOTNULL:
case TK_ISNULL: {
@@ -994,36 +981,19 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
anRef[i] = p->nRef;
}
sqlite3WalkExpr(pWalker, pExpr->pLeft);
if( IN_RENAME_OBJECT ) return WRC_Prune;
if( sqlite3ExprCanBeNull(pExpr->pLeft) ){
/* The expression can be NULL. So the optimization does not apply */
return WRC_Prune;
}
if( 0==sqlite3ExprCanBeNull(pExpr->pLeft) && !IN_RENAME_OBJECT ){
testcase( ExprHasProperty(pExpr, EP_OuterON) );
assert( !ExprHasProperty(pExpr, EP_IntValue) );
pExpr->u.iValue = (pExpr->op==TK_NOTNULL);
pExpr->flags |= EP_IntValue;
pExpr->op = TK_INTEGER;
for(i=0, p=pNC; p; p=p->pNext, i++){
if( (p->ncFlags & NC_Where)==0 ){
return WRC_Prune; /* Not in a WHERE clause. Unsafe to optimize. */
for(i=0, p=pNC; p && i<ArraySize(anRef); p=p->pNext, i++){
p->nRef = anRef[i];
}
sqlite3ExprDelete(pParse->db, pExpr->pLeft);
pExpr->pLeft = 0;
}
testcase( ExprHasProperty(pExpr, EP_OuterON) );
assert( !ExprHasProperty(pExpr, EP_IntValue) );
#if TREETRACE_ENABLED
if( sqlite3TreeTrace & 0x80000 ){
sqlite3DebugPrintf(
"NOT NULL strength reduction converts the following to %d:\n",
pExpr->op==TK_NOTNULL
);
sqlite3ShowExpr(pExpr);
}
#endif /* TREETRACE_ENABLED */
pExpr->u.iValue = (pExpr->op==TK_NOTNULL);
pExpr->flags |= EP_IntValue;
pExpr->op = TK_INTEGER;
for(i=0, p=pNC; p && i<ArraySize(anRef); p=p->pNext, i++){
p->nRef = anRef[i];
}
sqlite3ExprDelete(pParse->db, pExpr->pLeft);
pExpr->pLeft = 0;
return WRC_Prune;
}
@@ -1921,9 +1891,7 @@ static int resolveSelectStep(Walker *pWalker, Select *p){
}
if( sqlite3ResolveExprNames(&sNC, p->pHaving) ) return WRC_Abort;
}
sNC.ncFlags |= NC_Where;
if( sqlite3ResolveExprNames(&sNC, p->pWhere) ) return WRC_Abort;
sNC.ncFlags &= ~NC_Where;
/* Resolve names in table-valued-function arguments */
for(i=0; i<p->pSrc->nSrc; i++){
+38 -65
View File
@@ -3776,7 +3776,6 @@ static void exec_prepared_stmt_columnar(
rc = sqlite3_step(pStmt);
if( rc!=SQLITE_ROW ) return;
nColumn = sqlite3_column_count(pStmt);
if( nColumn==0 ) goto columnar_end;
nAlloc = nColumn*4;
if( nAlloc<=0 ) nAlloc = 1;
azData = sqlite3_malloc64( nAlloc*sizeof(char*) );
@@ -3862,6 +3861,7 @@ static void exec_prepared_stmt_columnar(
if( n>p->actualWidth[j] ) p->actualWidth[j] = n;
}
if( seenInterrupt ) goto columnar_end;
if( nColumn==0 ) goto columnar_end;
switch( p->cMode ){
case MODE_Column: {
colSep = " ";
@@ -8778,15 +8778,16 @@ static int do_meta_command(char *zLine, ShellState *p){
#ifndef SQLITE_SHELL_FIDDLE
if( c=='i' && cli_strncmp(azArg[0], "import", n)==0 ){
char *zTable = 0; /* Insert data into this table */
char *zSchema = 0; /* Schema of zTable */
char *zSchema = 0; /* within this schema (may default to "main") */
char *zFile = 0; /* Name of file to extra content from */
sqlite3_stmt *pStmt = NULL; /* A statement */
int nCol; /* Number of columns in the table */
i64 nByte; /* Number of bytes in an SQL string */
int nByte; /* Number of bytes in an SQL string */
int i, j; /* Loop counters */
int needCommit; /* True to COMMIT or ROLLBACK at end */
int nSep; /* Number of bytes in p->colSeparator[] */
char *zSql = 0; /* An SQL statement */
char *zSql; /* An SQL statement */
char *zFullTabName; /* Table name with schema if applicable */
ImportCtx sCtx; /* Reader context */
char *(SQLITE_CDECL *xRead)(ImportCtx*); /* Func to read one value */
int eVerbose = 0; /* Larger for more console output */
@@ -8920,14 +8921,24 @@ static int do_meta_command(char *zLine, ShellState *p){
while( (nSkip--)>0 ){
while( xRead(&sCtx) && sCtx.cTerm==sCtx.cColSep ){}
}
if( zSchema!=0 ){
zFullTabName = sqlite3_mprintf("\"%w\".\"%w\"", zSchema, zTable);
}else{
zFullTabName = sqlite3_mprintf("\"%w\"", zTable);
}
zSql = sqlite3_mprintf("SELECT * FROM %s", zFullTabName);
if( zSql==0 || zFullTabName==0 ){
import_cleanup(&sCtx);
shell_out_of_memory();
}
nByte = strlen30(zSql);
rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
import_append_char(&sCtx, 0); /* To ensure sCtx.z is allocated */
if( sqlite3_table_column_metadata(p->db, zSchema, zTable,0,0,0,0,0,0) ){
/* Table does not exist. Create it. */
if( rc && sqlite3_strglob("no such table: *", sqlite3_errmsg(p->db))==0 ){
sqlite3 *dbCols = 0;
char *zRenames = 0;
char *zColDefs;
zCreate = sqlite3_mprintf("CREATE TABLE \"%w\".\"%w\"",
zSchema ? zSchema : "main", zTable);
zCreate = sqlite3_mprintf("CREATE TABLE %s", zFullTabName);
while( xRead(&sCtx) ){
zAutoColumn(sCtx.z, &dbCols, 0);
if( sCtx.cTerm!=sCtx.cColSep ) break;
@@ -8942,50 +8953,34 @@ static int do_meta_command(char *zLine, ShellState *p){
assert(dbCols==0);
if( zColDefs==0 ){
eputf("%s: empty file\n", sCtx.zFile);
import_fail:
sqlite3_free(zCreate);
sqlite3_free(zSql);
sqlite3_free(zFullTabName);
import_cleanup(&sCtx);
rc = 1;
goto meta_command_exit;
}
zCreate = sqlite3_mprintf("%z%z\n", zCreate, zColDefs);
if( zCreate==0 ){
import_cleanup(&sCtx);
shell_out_of_memory();
}
if( eVerbose>=1 ){
oputf("%s\n", zCreate);
}
rc = sqlite3_exec(p->db, zCreate, 0, 0, 0);
sqlite3_free(zCreate);
zCreate = 0;
if( rc ){
eputf("%s failed:\n%s\n", zCreate, sqlite3_errmsg(p->db));
import_cleanup(&sCtx);
rc = 1;
goto meta_command_exit;
goto import_fail;
}
sqlite3_free(zCreate);
zCreate = 0;
rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
}
zSql = sqlite3_mprintf("SELECT count(*) FROM pragma_table_info(%Q,%Q);",
zTable, zSchema);
if( zSql==0 ){
import_cleanup(&sCtx);
shell_out_of_memory();
}
nByte = strlen(zSql);
rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
sqlite3_free(zSql);
zSql = 0;
if( rc ){
if (pStmt) sqlite3_finalize(pStmt);
eputf("Error: %s\n", sqlite3_errmsg(p->db));
import_cleanup(&sCtx);
rc = 1;
goto meta_command_exit;
}
if( sqlite3_step(pStmt)==SQLITE_ROW ){
nCol = sqlite3_column_int(pStmt, 0);
}else{
nCol = 0;
goto import_fail;
}
sqlite3_free(zSql);
nCol = sqlite3_column_count(pStmt);
sqlite3_finalize(pStmt);
pStmt = 0;
if( nCol==0 ) return 0; /* no columns, no error */
@@ -8994,12 +8989,7 @@ static int do_meta_command(char *zLine, ShellState *p){
import_cleanup(&sCtx);
shell_out_of_memory();
}
if( zSchema ){
sqlite3_snprintf(nByte+20, zSql, "INSERT INTO \"%w\".\"%w\" VALUES(?",
zSchema, zTable);
}else{
sqlite3_snprintf(nByte+20, zSql, "INSERT INTO \"%w\" VALUES(?", zTable);
}
sqlite3_snprintf(nByte+20, zSql, "INSERT INTO %s VALUES(?", zFullTabName);
j = strlen30(zSql);
for(i=1; i<nCol; i++){
zSql[j++] = ',';
@@ -9011,15 +9001,13 @@ static int do_meta_command(char *zLine, ShellState *p){
oputf("Insert using: %s\n", zSql);
}
rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
sqlite3_free(zSql);
zSql = 0;
if( rc ){
eputf("Error: %s\n", sqlite3_errmsg(p->db));
if (pStmt) sqlite3_finalize(pStmt);
import_cleanup(&sCtx);
rc = 1;
goto meta_command_exit;
goto import_fail;
}
sqlite3_free(zSql);
sqlite3_free(zFullTabName);
needCommit = sqlite3_get_autocommit(p->db);
if( needCommit ) sqlite3_exec(p->db, "BEGIN", 0, 0, 0);
do{
@@ -12784,11 +12772,6 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
#ifndef SQLITE_SHELL_FIDDLE
/* In WASM mode we have to leave the db state in place so that
** client code can "push" SQL into it after this call returns. */
#ifndef SQLITE_OMIT_VIRTUALTABLE
if( data.expert.pExpert ){
expertFinish(&data, 1, 0);
}
#endif
free(azCmd);
set_table_name(&data, 0);
if( data.db ){
@@ -12855,7 +12838,7 @@ sqlite3_vfs * fiddle_db_vfs(const char *zDbName){
/* Only for emcc experimentation purposes. */
sqlite3 * fiddle_db_arg(sqlite3 *arg){
oputf("fiddle_db_arg(%p)\n", (const void*)arg);
printf("fiddle_db_arg(%p)\n", (const void*)arg);
return arg;
}
@@ -12881,22 +12864,12 @@ const char * fiddle_db_filename(const char * zDbName){
/*
** Completely wipes out the contents of the currently-opened database
** but leaves its storage intact for reuse. If any transactions are
** active, they are forcibly rolled back.
** but leaves its storage intact for reuse.
*/
void fiddle_reset_db(void){
if( globalDb ){
int rc;
while( sqlite3_txn_state(globalDb,0)>0 ){
/*
** Resolve problem reported in
** https://sqlite.org/forum/forumpost/0b41a25d65
*/
oputz("Rolling back in-progress transaction.\n");
sqlite3_exec(globalDb,"ROLLBACK", 0, 0, 0);
}
rc = sqlite3_db_config(globalDb, SQLITE_DBCONFIG_RESET_DATABASE, 1, 0);
if( 0==rc ) sqlite3_exec(globalDb, "VACUUM", 0, 0, 0);
int rc = sqlite3_db_config(globalDb, SQLITE_DBCONFIG_RESET_DATABASE, 1, 0);
if( 0==rc ) rc = sqlite3_exec(globalDb, "VACUUM", 0, 0, 0);
sqlite3_db_config(globalDb, SQLITE_DBCONFIG_RESET_DATABASE, 0, 0);
}
}
+4 -6
View File
@@ -1125,7 +1125,6 @@ extern u32 sqlite3TreeTrace;
** 0x00010000 Beginning of DELETE/INSERT/UPDATE processing
** 0x00020000 Transform DISTINCT into GROUP BY
** 0x00040000 SELECT tree dump after all code has been generated
** 0x00080000 NOT NULL strength reduction
*/
/*
@@ -3315,6 +3314,8 @@ struct SrcItem {
union {
Index *pIBIndex; /* Index structure corresponding to u1.zIndexedBy */
CteUse *pCteUse; /* CTE Usage info when fg.isCte is true */
Trigger *pTrig; /* Trigger in argument list of DROP TRIGGER */
Index *pIdx; /* Index in argument list to DROP INDEX */
} u2;
};
@@ -3454,7 +3455,6 @@ struct NameContext {
#define NC_InAggFunc 0x020000 /* True if analyzing arguments to an agg func */
#define NC_FromDDL 0x040000 /* SQL text comes from sqlite_schema */
#define NC_NoSelect 0x080000 /* Do not descend into sub-selects */
#define NC_Where 0x100000 /* Processing WHERE clause of a SELECT */
#define NC_OrderAgg 0x8000000 /* Has an aggregate other than count/min/max */
/*
@@ -3478,7 +3478,6 @@ struct Upsert {
Expr *pUpsertWhere; /* WHERE clause for the ON CONFLICT UPDATE */
Upsert *pNextUpsert; /* Next ON CONFLICT clause in the list */
u8 isDoUpdate; /* True for DO UPDATE. False for DO NOTHING */
u8 isDup; /* True if 2nd or later with same pUpsertIdx */
/* Above this point is the parse tree for the ON CONFLICT clauses.
** The next group of fields stores intermediate data. */
void *pToFree; /* Free memory when deleting the Upsert object */
@@ -4929,7 +4928,6 @@ void sqlite3CreateView(Parse*,Token*,Token*,Token*,ExprList*,Select*,int,int);
int sqlite3DbMaskAllZero(yDbMask);
#endif
void sqlite3DropTable(Parse*, SrcList*, int, int);
void sqlite3CodeDropTable(Parse*, Table*, int, int);
void sqlite3DeleteTable(sqlite3*, Table*);
void sqlite3DeleteTableGeneric(sqlite3*, void*);
void sqlite3FreeIndex(sqlite3*, Index*);
@@ -5555,7 +5553,7 @@ const char *sqlite3JournalModename(int);
Upsert *sqlite3UpsertNew(sqlite3*,ExprList*,Expr*,ExprList*,Expr*,Upsert*);
void sqlite3UpsertDelete(sqlite3*,Upsert*);
Upsert *sqlite3UpsertDup(sqlite3*,Upsert*);
int sqlite3UpsertAnalyzeTarget(Parse*,SrcList*,Upsert*,Upsert*);
int sqlite3UpsertAnalyzeTarget(Parse*,SrcList*,Upsert*);
void sqlite3UpsertDoUpdate(Parse*,Upsert*,Table*,Index*,int);
Upsert *sqlite3UpsertOfIndex(Upsert*,Index*);
int sqlite3UpsertNextIsIPK(Upsert*);
@@ -5577,7 +5575,7 @@ const char *sqlite3JournalModename(int);
*/
#if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER)
void sqlite3FkCheck(Parse*, Table*, int, int, int*, int);
void sqlite3FkDropTable(Parse*, SrcList *, Table*);
void sqlite3FkDropTable(Parse*, SrcList*, Table*);
void sqlite3FkActions(Parse*, Table*, ExprList*, int, int*, int);
int sqlite3FkRequired(Parse*, Table*, int*, int);
u32 sqlite3FkOldmask(Parse*, Table*);
+30 -26
View File
@@ -624,35 +624,39 @@ void sqlite3DropTrigger(Parse *pParse, SrcList *pName, int noErr){
const char *zDb;
const char *zName;
sqlite3 *db = pParse->db;
int ii, jj;
if( db->mallocFailed ) goto drop_trigger_cleanup;
if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){
goto drop_trigger_cleanup;
}
assert( pName->nSrc==1 );
zDb = pName->a[0].zDatabase;
zName = pName->a[0].zName;
assert( zDb!=0 || sqlite3BtreeHoldsAllMutexes(db) );
for(i=OMIT_TEMPDB; i<db->nDb; i++){
int j = (i<2) ? i^1 : i; /* Search TEMP before MAIN */
if( zDb && sqlite3DbIsNamed(db, j, zDb)==0 ) continue;
assert( sqlite3SchemaMutexHeld(db, j, 0) );
pTrigger = sqlite3HashFind(&(db->aDb[j].pSchema->trigHash), zName);
if( pTrigger ) break;
}
if( !pTrigger ){
if( !noErr ){
sqlite3ErrorMsg(pParse, "no such trigger: %S", pName->a);
}else{
sqlite3CodeVerifyNamedSchema(pParse, zDb);
sqlite3ReadSchema(pParse);
assert( pName!=0 || pParse->nErr!=0 );
for(ii=0; pParse->nErr==0 && ii<pName->nSrc; ii++){
zDb = pName->a[ii].zDatabase;
zName = pName->a[ii].zName;
assert( zDb!=0 || sqlite3BtreeHoldsAllMutexes(db) );
for(i=OMIT_TEMPDB; i<db->nDb; i++){
int j = (i<2) ? i^1 : i; /* Search TEMP before MAIN */
if( zDb && sqlite3DbIsNamed(db, j, zDb)==0 ) continue;
assert( sqlite3SchemaMutexHeld(db, j, 0) );
pTrigger = sqlite3HashFind(&(db->aDb[j].pSchema->trigHash), zName);
if( pTrigger ) break;
}
pParse->checkSchema = 1;
goto drop_trigger_cleanup;
pName->a[ii].u2.pTrig = pTrigger;
if( !pTrigger ){
if( !noErr ){
sqlite3ErrorMsg(pParse, "no such trigger: %S", pName->a+ii);
}else{
sqlite3CodeVerifyNamedSchema(pParse, zDb);
}
testcase( ii>0 );
testcase( ii+1<pName->nSrc );
pParse->checkSchema = 1;
continue;
}
for(jj=ii-1; jj>=0; jj--){
if( pName->a[jj].u2.pTrig==pTrigger ) break;
}
if( jj>=0 ) continue;
sqlite3DropTriggerPtr(pParse, pTrigger);
}
sqlite3DropTriggerPtr(pParse, pTrigger);
drop_trigger_cleanup:
sqlite3SrcListDelete(db, pName);
}
+4 -17
View File
@@ -90,8 +90,7 @@ Upsert *sqlite3UpsertNew(
int sqlite3UpsertAnalyzeTarget(
Parse *pParse, /* The parsing context */
SrcList *pTabList, /* Table into which we are inserting */
Upsert *pUpsert, /* The ON CONFLICT clauses */
Upsert *pAll /* Complete list of all ON CONFLICT clauses */
Upsert *pUpsert /* The ON CONFLICT clauses */
){
Table *pTab; /* That table into which we are inserting */
int rc; /* Result code */
@@ -194,14 +193,6 @@ int sqlite3UpsertAnalyzeTarget(
continue;
}
pUpsert->pUpsertIdx = pIdx;
if( sqlite3UpsertOfIndex(pAll,pIdx)!=pUpsert ){
/* Really this should be an error. The isDup ON CONFLICT clause will
** never fire. But this problem was not discovered until three years
** after multi-CONFLICT upsert was added, and so we silently ignore
** the problem to prevent breaking applications that might actually
** have redundant ON CONFLICT clauses. */
pUpsert->isDup = 1;
}
break;
}
if( pUpsert->pUpsertIdx==0 ){
@@ -228,13 +219,9 @@ int sqlite3UpsertNextIsIPK(Upsert *pUpsert){
Upsert *pNext;
if( NEVER(pUpsert==0) ) return 0;
pNext = pUpsert->pNextUpsert;
while( 1 /*exit-by-return*/ ){
if( pNext==0 ) return 1;
if( pNext->pUpsertTarget==0 ) return 1;
if( pNext->pUpsertIdx==0 ) return 1;
if( !pNext->isDup ) return 0;
pNext = pNext->pNextUpsert;
}
if( pNext==0 ) return 1;
if( pNext->pUpsertTarget==0 ) return 1;
if( pNext->pUpsertIdx==0 ) return 1;
return 0;
}
-3
View File
@@ -665,9 +665,6 @@ do_atof_calc:
u64 s2;
rr[0] = (double)s;
s2 = (u64)rr[0];
#if defined(_MSC_VER) && _MSC_VER<1700
if( s2==0x8000000000000000LL ){ s2 = 2*(u64)(0.5*rr[0]); }
#endif
rr[1] = s>=s2 ? (double)(s - s2) : -(double)(s2 - s);
if( e>0 ){
while( e>=100 ){
+19 -17
View File
@@ -1129,7 +1129,7 @@ case OP_Return: { /* in1 */
**
** See also: EndCoroutine
*/
case OP_InitCoroutine: { /* jump0 */
case OP_InitCoroutine: { /* jump */
assert( pOp->p1>0 && pOp->p1<=(p->nMem+1 - p->nCursor) );
assert( pOp->p2>=0 && pOp->p2<p->nOp );
assert( pOp->p3>=0 && pOp->p3<p->nOp );
@@ -1182,7 +1182,7 @@ case OP_EndCoroutine: { /* in1 */
**
** See also: InitCoroutine
*/
case OP_Yield: { /* in1, jump0 */
case OP_Yield: { /* in1, jump */
int pcDest;
pIn1 = &aMem[pOp->p1];
assert( VdbeMemDynamic(pIn1)==0 );
@@ -1512,15 +1512,19 @@ case OP_Blob: { /* out2 */
break;
}
/* Opcode: Variable P1 P2 * * *
** Synopsis: r[P2]=parameter(P1)
/* Opcode: Variable P1 P2 * P4 *
** Synopsis: r[P2]=parameter(P1,P4)
**
** Transfer the values of bound parameter P1 into register P2
**
** If the parameter is named, then its name appears in P4.
** The P4 value is used by sqlite3_bind_parameter_name().
*/
case OP_Variable: { /* out2 */
Mem *pVar; /* Value being transferred */
assert( pOp->p1>0 && pOp->p1<=p->nVar );
assert( pOp->p4.z==0 || pOp->p4.z==sqlite3VListNumToName(p->pVList,pOp->p1) );
pVar = &p->aVar[pOp->p1 - 1];
if( sqlite3VdbeMemTooBig(pVar) ){
goto too_big;
@@ -2041,7 +2045,7 @@ case OP_AddImm: { /* in1 */
** without data loss, then jump immediately to P2, or if P2==0
** raise an SQLITE_MISMATCH exception.
*/
case OP_MustBeInt: { /* jump0, in1 */
case OP_MustBeInt: { /* jump, in1 */
pIn1 = &aMem[pOp->p1];
if( (pIn1->flags & MEM_Int)==0 ){
applyAffinity(pIn1, SQLITE_AFF_NUMERIC, encoding);
@@ -4725,10 +4729,10 @@ case OP_ColumnsUsed: {
**
** See also: Found, NotFound, SeekGt, SeekGe, SeekLt
*/
case OP_SeekLT: /* jump0, in3, group, ncycle */
case OP_SeekLE: /* jump0, in3, group, ncycle */
case OP_SeekGE: /* jump0, in3, group, ncycle */
case OP_SeekGT: { /* jump0, in3, group, ncycle */
case OP_SeekLT: /* jump, in3, group, ncycle */
case OP_SeekLE: /* jump, in3, group, ncycle */
case OP_SeekGE: /* jump, in3, group, ncycle */
case OP_SeekGT: { /* jump, in3, group, ncycle */
int res; /* Comparison result */
int oc; /* Opcode */
VdbeCursor *pC; /* The cursor to seek */
@@ -5395,7 +5399,7 @@ case OP_Found: { /* jump, in3, ncycle */
**
** See also: Found, NotFound, NoConflict, SeekRowid
*/
case OP_SeekRowid: { /* jump0, in3, ncycle */
case OP_SeekRowid: { /* jump, in3, ncycle */
VdbeCursor *pC;
BtCursor *pCrsr;
int res;
@@ -6154,7 +6158,7 @@ case OP_NullRow: {
** configured to use Prev, not Next.
*/
case OP_SeekEnd: /* ncycle */
case OP_Last: { /* jump0, ncycle */
case OP_Last: { /* jump, ncycle */
VdbeCursor *pC;
BtCursor *pCrsr;
int res;
@@ -6271,7 +6275,7 @@ case OP_Sort: { /* jump ncycle */
** from the beginning toward the end. In other words, the cursor is
** configured to use Next, not Prev.
*/
case OP_Rewind: { /* jump0, ncycle */
case OP_Rewind: { /* jump, ncycle */
VdbeCursor *pC;
BtCursor *pCrsr;
int res;
@@ -7279,9 +7283,7 @@ case OP_RowSetTest: { /* jump, in1, in3 */
** P1 contains the address of the memory cell that contains the first memory
** cell in an array of values used as arguments to the sub-program. P2
** contains the address to jump to if the sub-program throws an IGNORE
** exception using the RAISE() function. P2 might be zero, if there is
** no possibility that an IGNORE exception will be raised.
** Register P3 contains the address
** exception using the RAISE() function. Register P3 contains the address
** of a memory cell in this (the parent) VM that is used to allocate the
** memory required by the sub-vdbe at runtime.
**
@@ -7289,7 +7291,7 @@ case OP_RowSetTest: { /* jump, in1, in3 */
**
** If P5 is non-zero, then recursive program invocation is enabled.
*/
case OP_Program: { /* jump0 */
case OP_Program: { /* jump */
int nMem; /* Number of memory registers for sub-program */
int nByte; /* Bytes of runtime space required for sub-program */
Mem *pRt; /* Register to allocate runtime space */
@@ -8838,7 +8840,7 @@ case OP_Filter: { /* jump */
** error is encountered.
*/
case OP_Trace:
case OP_Init: { /* jump0 */
case OP_Init: { /* jump */
int i;
#ifndef SQLITE_OMIT_TRACE
char *zTrace;
-9
View File
@@ -939,15 +939,6 @@ static void resolveP2Values(Vdbe *p, int *pMaxFuncArgs){
assert( aLabel!=0 ); /* True because of tag-20230419-1 */
pOp->p2 = aLabel[ADDR(pOp->p2)];
}
/* OPFLG_JUMP opcodes never have P2==0, though OPFLG_JUMP0 opcodes
** might */
assert( pOp->p2>0
|| (sqlite3OpcodeProperty[pOp->opcode] & OPFLG_JUMP0)!=0 );
/* Jumps never go off the end of the bytecode array */
assert( pOp->p2<p->nOp
|| (sqlite3OpcodeProperty[pOp->opcode] & OPFLG_JUMP)==0 );
break;
}
}
+1 -1
View File
@@ -989,7 +989,7 @@ static SQLITE_NOINLINE int exprMightBeIndexed2(
if( pIdx->aiColumn[i]!=XN_EXPR ) continue;
assert( pIdx->bHasExpr );
if( sqlite3ExprCompareSkip(pExpr,pIdx->aColExpr->a[i].pExpr,iCur)==0
&& !sqlite3ExprIsConstant(pIdx->aColExpr->a[i].pExpr)
&& pExpr->op!=TK_STRING
){
aiCurCol[0] = iCur;
aiCurCol[1] = XN_EXPR;
+6 -12
View File
@@ -117,8 +117,7 @@ do_test aggnested-3.0 {
#
do_test aggnested-3.1 {
db eval {
DROP TABLE IF EXISTS t1;
DROP TABLE IF EXISTS t2;
DROP TABLE IF EXISTS t1, t2;
CREATE TABLE t1 (
id1 INTEGER PRIMARY KEY AUTOINCREMENT,
value1 INTEGER
@@ -150,8 +149,7 @@ do_test aggnested-3.1-rj {
do_test aggnested-3.2 {
db eval {
DROP TABLE IF EXISTS t1;
DROP TABLE IF EXISTS t2;
DROP TABLE IF EXISTS t1, t2;
CREATE TABLE t1 (
id1 INTEGER,
value1 INTEGER,
@@ -178,8 +176,7 @@ do_test aggnested-3.2 {
} {1 0}
do_test aggnested-3.3 {
db eval {
DROP TABLE IF EXISTS t1;
DROP TABLE IF EXISTS t2;
DROP TABLE IF EXISTS t1, t2;
CREATE TABLE t1(id1, value1);
INSERT INTO t1 VALUES(4469,2),(4469,1);
CREATE TABLE t2 (value2);
@@ -249,8 +246,7 @@ do_test aggnested-3.16 {
# Problem found by dbsqlfuzz
#
do_execsql_test aggnested-4.1 {
DROP TABLE IF EXISTS aa;
DROP TABLE IF EXISTS bb;
DROP TABLE IF EXISTS aa, bb;
CREATE TABLE aa(x INT); INSERT INTO aa(x) VALUES(123);
CREATE TABLE bb(y INT); INSERT INTO bb(y) VALUES(456);
SELECT (SELECT sum(x+(SELECT y)) FROM bb) FROM aa;
@@ -259,8 +255,7 @@ do_execsql_test aggnested-4.2 {
SELECT (SELECT sum(x+y) FROM bb) FROM aa;
} {579}
do_execsql_test aggnested-4.3 {
DROP TABLE IF EXISTS tx;
DROP TABLE IF EXISTS ty;
DROP TABLE IF EXISTS tx, ty;
CREATE TABLE tx(x INT);
INSERT INTO tx VALUES(1),(2),(3),(4),(5);
CREATE TABLE ty(y INT);
@@ -477,8 +472,7 @@ do_execsql_test 9.5 {
# https://bugs.chromium.org/p/chromium/issues/detail?id=1511689
#
do_execsql_test 10.1 {
DROP TABLE IF EXISTS t0;
DROP TABLE IF EXISTS t1;
DROP TABLE IF EXISTS t0, t1;
CREATE TABLE t0(c1, c2); INSERT INTO t0 VALUES(1,2);
CREATE TABLE t1(c3, c4); INSERT INTO t1 VALUES(3,4);
SELECT * FROM t0 WHERE EXISTS (SELECT 1 FROM t1 GROUP BY c3 HAVING ( SELECT count(*) FROM (SELECT 1 UNION ALL SELECT sum(DISTINCT c1) ) ) ) BETWEEN 1 AND 1;
+1 -2
View File
@@ -60,8 +60,7 @@ do_execsql_test aggorderby-4.1 {
do_execsql_test aggorderby-5.0 {
DROP TABLE IF EXISTS t1;
DROP TABLE IF EXISTS t3;
DROP TABLE IF EXISTS t1, t3;
CREATE TABLE t1(a TEXT); INSERT INTO t1 VALUES('aaa'),('bbb');
CREATE TABLE t3(d TEXT); INSERT INTO t3 VALUES('/'),('-');
SELECT (SELECT string_agg(a,d) FROM t3) FROM t1;
+2 -5
View File
@@ -105,9 +105,7 @@ do_test alter3-1.99 {
DROP TABLE t2;
}
execsql {
DROP TABLE abc;
DROP TABLE t1;
DROP TABLE t3;
DROP TABLE abc, t1, t3;
}
} {}
@@ -296,8 +294,7 @@ ifcapable attach {
} {1 one 2 two}
do_test alter3-5.99 {
execsql {
DROP TABLE aux.t1;
DROP TABLE t1;
DROP TABLE aux.t1, main.t1;
}
} {}
}
+1 -3
View File
@@ -114,9 +114,7 @@ do_test alter4-1.99 {
DROP TABLE t2;
}
execsql {
DROP TABLE abc;
DROP TABLE t1;
DROP TABLE t3;
DROP TABLE abc, t1, t3;
}
} {}
+1 -2
View File
@@ -195,8 +195,7 @@ do_test analyze-3.8 {
CREATE INDEX t3i1 ON t3(a);
CREATE INDEX t3i2 ON t3(a,b,c,d);
CREATE INDEX t3i3 ON t3(d,b,c,a);
DROP TABLE t1;
DROP TABLE t2;
DROP TABLE t1, t2;
SELECT idx, stat FROM sqlite_stat1 ORDER BY idx;
}
} {}
+5 -5
View File
@@ -216,7 +216,7 @@ do_test auth-1.21.1 {
}
return SQLITE_OK
}
catchsql {DROP TABLE t2}
catchsql {DROP TABLE IF EXISTS none1, none2, t2, none3}
} {1 {not authorized}}
do_test auth-1.21.2 {
set ::authargs
@@ -483,7 +483,7 @@ do_test auth-1.63 {
}
return SQLITE_OK
}
catchsql {DROP TABLE t2}
catchsql {DROP TABLE IF EXISTS none1, t2, none2}
} {1 {not authorized}}
do_test auth-1.64 {
execsql {SELECT name FROM sqlite_master}
@@ -726,7 +726,7 @@ do_test auth-1.101 {
}
return SQLITE_OK
}
catchsql {DROP VIEW v2}
catchsql {DROP VIEW IF EXISTS none1, v2, none2}
} {1 {not authorized}}
do_test auth-1.102 {
set ::authargs
@@ -1090,7 +1090,7 @@ do_test auth-1.153 {
}
return SQLITE_OK
}
catchsql {DROP TRIGGER r2}
catchsql {DROP TRIGGER IF EXISTS none1, r2, none2}
} {1 {not authorized}}
do_test auth-1.154 {
set ::authargs
@@ -1389,7 +1389,7 @@ do_test auth-1.205 {
}
return SQLITE_OK
}
catchsql {DROP INDEX i2}
catchsql {DROP INDEX IF EXISTS none1, i2, none2}
} {1 {not authorized}}
do_test auth-1.205a {
set ::authargs
-1
View File
@@ -8,7 +8,6 @@
# May you share freely, never taking more than you give.
#
#***********************************************************************
# TESTRUNNER: shell
#
# This file implements tests for the appendvfs extension.
#
+1 -1
View File
@@ -98,7 +98,7 @@ do_test corruptC-2.1 {
sqlite3 db test.db
catchsql {PRAGMA integrity_check}
} {0 {{*** in database main ***
Tree 3 page 3: free space corruption} {wrong # of entries in index t1i1}}}
Tree 3 page 3: free space corruption}}}
# test that a corrupt content offset size is handled (seed 5649)
#
+1 -80
View File
@@ -262,7 +262,7 @@ datetest 5.15 {datetime('1994-04-16 14:00:00 +05:00 Z')} NULL
# localtime->utc and utc->localtime conversions.
#
# Use SQLITE_TESTCTRL_LOCALTIME_FAULT=2 to set an alternative localtime_r()
# implementation that is not locale-dependent. The testing localtime_r()
# implementation that is not locale-dependent. This testing localtime_r()
# operates as follows:
#
# (1) Localtime is 30 minutes earlier than (west of) UTC on
@@ -321,38 +321,6 @@ utc_to_local 6.22 {1800-10-29 12:30:00} {1800-10-29 12:00:00}
local_to_utc 6.23 {3000-10-30 12:00:00} {3000-10-30 11:30:00}
utc_to_local 6.24 {3000-10-30 11:30:00} {3000-10-30 12:00:00}
# If the time is specified to be ZULU, or if it has an explicit
# timezone extension, then the time will already be UTC and subsequent
# 'utc' modifiers are no-ops.
#
do_execsql_test date-6.25 {
SELECT datetime('2000-10-29 12:00Z','utc','utc');
} {{2000-10-29 12:00:00}}
do_execsql_test date-6.26 {
SELECT datetime('2000-10-29 12:00:00+05:00');
} {{2000-10-29 07:00:00}}
do_execsql_test date-6.27 {
SELECT datetime('2000-10-29 12:00:00+05:00', 'utc');
} {{2000-10-29 07:00:00}}
# Multiple back-and-forth UTC to LOCAL to UTC...
do_execsql_test date-6.28 {
SELECT datetime('2000-10-29 12:00:00Z', 'localtime');
} {{2000-10-29 12:30:00}}
do_execsql_test date-6.29 {
SELECT datetime('2000-10-29 12:00:00Z', 'utc', 'localtime');
} {{2000-10-29 12:30:00}}
do_execsql_test date-6.30 {
SELECT datetime('2000-10-29 12:00:00Z', 'utc', 'localtime', 'utc');
} {{2000-10-29 12:00:00}}
do_execsql_test date-6.31 {
SELECT datetime('2000-10-29 12:00:00Z', 'utc','localtime','utc','localtime');
} {{2000-10-29 12:30:00}}
do_execsql_test date-6.32 {
SELECT datetime('2000-10-29 12:00:00Z', 'localtime','localtime');
} {{2000-10-29 12:30:00}}
# Restore the use of the OS localtime_r() before going on...
sqlite3_test_control SQLITE_TESTCTRL_LOCALTIME_FAULT 0
@@ -605,51 +573,4 @@ datetest 18.2 {unixepoch('1970-01-01T00:00:00.1', 'subsec')} {0.1}
datetest 18.3 {unixepoch('1970-01-01T00:00:00.2', 'subsecond')} {0.2}
datetest 18.4 {julianday('-4713-11-24 13:40:48.864', 'subsec')} {0.07001}
datetest 18.5 {typeof(unixepoch('now', 'subsecond'))} {real}
# 2024-03-03 the 'ceiling' and 'floor' operators.
#
datetest 19.1 {date('2000-01-31','floor')} {2000-01-31}
datetest 19.2a {date('2000-02-31','floor')} {2000-02-29}
datetest 19.2b {date('1999-02-31','floor')} {1999-02-28}
datetest 19.2c {date('1900-02-31','floor')} {1900-02-28}
datetest 19.3 {date('2000-03-31','floor')} {2000-03-31}
datetest 19.4 {date('2000-04-31','floor')} {2000-04-30}
datetest 19.5 {date('2000-05-31','floor')} {2000-05-31}
datetest 19.6 {date('2000-06-31','floor')} {2000-06-30}
datetest 19.7 {date('2000-07-31','floor')} {2000-07-31}
datetest 19.8 {date('2000-08-31','floor')} {2000-08-31}
datetest 19.9 {date('2000-09-31','floor')} {2000-09-30}
datetest 19.10 {date('2000-10-31','floor')} {2000-10-31}
datetest 19.11 {date('2000-11-31','floor')} {2000-11-30}
datetest 19.12 {date('2000-12-31','floor')} {2000-12-31}
datetest 19.21 {date('2000-01-31','ceiling')} {2000-01-31}
datetest 19.22a {date('2000-02-31','ceiling')} {2000-03-02}
datetest 19.22b {date('1999-02-31','ceiling')} {1999-03-03}
datetest 19.22c {date('1900-02-31','ceiling')} {1900-03-03}
datetest 19.23 {date('2000-03-31','ceiling')} {2000-03-31}
datetest 19.24 {date('2000-04-31','ceiling')} {2000-05-01}
datetest 19.25 {date('2000-05-31','ceiling')} {2000-05-31}
datetest 19.26 {date('2000-06-31','ceiling')} {2000-07-01}
datetest 19.27 {date('2000-07-31','ceiling')} {2000-07-31}
datetest 19.28 {date('2000-08-31','ceiling')} {2000-08-31}
datetest 19.29 {date('2000-09-31','ceiling')} {2000-10-01}
datetest 19.30 {date('2000-10-31','ceiling')} {2000-10-31}
datetest 19.31 {date('2000-11-31','ceiling')} {2000-12-01}
datetest 19.32 {date('2000-12-31','ceiling')} {2000-12-31}
datetest 19.40 {date('2024-01-31','+1 month','ceiling')} {2024-03-02}
datetest 19.41 {date('2024-01-31','+1 month','floor')} {2024-02-29}
datetest 19.42 {date('2023-01-31','+1 month','ceiling')} {2023-03-03}
datetest 19.43 {date('2023-01-31','+1 month','floor')} {2023-02-28}
datetest 19.44 {date('2024-02-29','+1 year','ceiling')} {2025-03-01}
datetest 19.45 {date('2024-02-29','+1 year','floor')} {2025-02-28}
datetest 19.46 {date('2024-02-29','-110 years','ceiling')} {1914-03-01}
datetest 19.47 {date('2024-02-29','-110 years','floor')} {1914-02-28}
datetest 19.48 {date('2024-02-29','-0110-00-00','floor')} {1914-02-28}
datetest 19.49 {date('2024-02-29','-0110-00-00','ceiling')} {1914-03-01}
datetest 19.50 {date('2000-08-31','+0023-06-00','floor')} {2024-02-29}
datetest 19.51 {date('2000-08-31','+0022-06-00','floor')} {2023-02-28}
datetest 19.52 {date('2000-08-31','+0023-06-00','ceiling')} {2024-03-02}
datetest 19.53 {date('2000-08-31','+0022-06-00','ceiling')} {2023-03-03}
finish_test
+161
View File
@@ -0,0 +1,161 @@
# 2024-02-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.
#
#***********************************************************************
#
# Test cases for DROP TABLE, DROP INDEX, DROP TRIGGER, and DROP VIEW that
# list multiple objects to be dropped.
set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix drop-many
do_execsql_test 1.1 {
CREATE TABLE t1(a);
CREATE TABLE t2(b, c UNIQUE);
CREATE TABLE t3(d TEXT PRIMARY KEY, e);
CREATE INDEX t3e ON t3(e);
ATTACH ':memory:' AS aux1;
CREATE TABLE aux1.t4(f INT, g INT, h INT PRIMARY KEY) WITHOUT ROWID;
CREATE INDEX aux1.t4g ON t4(g);
CREATE INDEX t2b ON t2(b);
CREATE VIEW v5 AS SELECT 1,2,3;
CREATE VIEW v6 AS SELECT * FROM t3;
CREATE VIEW aux1.v7 AS SELECT 'hello';
CREATE TRIGGER r1 AFTER INSERT ON t1 BEGIN SELECT 'this is trigger r1'; END;
CREATE TRIGGER r2 BEFORE DELETE ON t2 BEGIN INSERT INTO t1 VALUES(old.b); END;
CREATE TRIGGER aux1.r3 AFTER UPDATE ON t4 BEGIN SELECT 'trigger r3'; END;
CREATE TRIGGER aux1.r4 INSTEAD OF UPDATE ON v7 BEGIN SELECT NULL; END;
} {}
do_execsql_test 1.2 {
BEGIN;
DROP TABLE t2, t4, t3, t1;
SELECT name FROM sqlite_schema WHERE type='table'
UNION ALL
SELECT name from aux1.sqlite_schema WHERE type='table'
ORDER BY name;
ROLLBACK;
} {}
do_catchsql_test 1.3.1 {
DROP TABLE t2, t4, t3, t05, t1;
} {1 {no such table: t05}}
do_execsql_test 1.3.2 {
SELECT name FROM sqlite_schema WHERE type='table'
UNION ALL
SELECT name from aux1.sqlite_schema WHERE type='table'
ORDER BY name;
} {t1 t2 t3 t4}
do_execsql_test 1.4 {
BEGIN;
DROP TABLE IF EXISTS t01, t2, t02, t4, t03, t3, t04, t1, t05;
SELECT name FROM sqlite_schema WHERE type='table'
UNION ALL
SELECT name from aux1.sqlite_schema WHERE type='table'
ORDER BY name;
ROLLBACK;
} {}
do_catchsql_test 1.5.1 {
DROP TABLE IF EXISTS t2, t4, t3, v7, t1;
} {1 {use DROP VIEW to delete view v7}}
do_execsql_test 1.5.2 {
SELECT name FROM sqlite_schema WHERE type='table'
UNION ALL
SELECT name from aux1.sqlite_schema WHERE type='table'
ORDER BY name;
} {t1 t2 t3 t4}
do_execsql_test 2.1 {
BEGIN;
DROP VIEW v5, v6, v7;
SELECT name FROM sqlite_schema WHERE type='view'
UNION ALL
SELECT name from aux1.sqlite_schema WHERE type='view'
ORDER BY name;
ROLLBACK;
} {}
do_catchsql_test 2.2.1 {
DROP VIEW v5, v6, v8, v7;
} {1 {no such view: v8}}
do_execsql_test 2.2.2 {
SELECT name FROM sqlite_schema WHERE type='view'
UNION ALL
SELECT name from aux1.sqlite_schema WHERE type='view'
ORDER BY name;
} {v5 v6 v7}
do_catchsql_test 2.3.1 {
DROP VIEW v5, v6, t1, v7;
} {1 {use DROP TABLE to delete table t1}}
do_execsql_test 2.3.2 {
SELECT name FROM sqlite_schema WHERE type='view'
UNION ALL
SELECT name from aux1.sqlite_schema WHERE type='view'
ORDER BY name;
} {v5 v6 v7}
do_execsql_test 3.1 {
BEGIN;
DROP INDEX t2b, aux1.t4g, main.t3e;
SELECT name FROM sqlite_schema WHERE type='index' AND name NOT LIKE 'sqlite%'
UNION ALL
SELECT name from aux1.sqlite_schema WHERE type='index'
ORDER BY name;
ROLLBACK;
} {}
do_catchsql_test 3.2.1 {
DROP INDEX t2b, aux1.t4g, t1, main.t3e;
} {1 {no such index: t1}}
do_execsql_test 3.2.2 {
SELECT name FROM sqlite_schema WHERE type='index' AND name NOT LIKE 'sqlite%'
UNION ALL
SELECT name from aux1.sqlite_schema WHERE type='index'
ORDER BY name;
} {t2b t3e t4g}
do_execsql_test 3.3 {
BEGIN;
DROP INDEX IF EXISTS aux1.none, t2b, none2, aux1.t4g, main.t3e, none3;
SELECT name FROM sqlite_schema WHERE type='index' AND name NOT LIKE 'sqlite%'
UNION ALL
SELECT name from aux1.sqlite_schema WHERE type='index'
ORDER BY name;
ROLLBACK;
} {}
do_execsql_test 4.1 {
BEGIN;
DROP TRIGGER main.r1, r2, r3, aux1.r4;
SELECT name FROM sqlite_schema WHERE type='trigger'
UNION ALL
SELECT name from aux1.sqlite_schema WHERE type='trigger'
ORDER BY name;
ROLLBACK;
} {}
do_catchsql_test 4.2.1 {
DROP TRIGGER main.r1, r2, r3, main.t1, aux1.r4;
} {1 {no such trigger: main.t1}}
do_execsql_test 4.2.2 {
SELECT name FROM sqlite_schema WHERE type='trigger'
UNION ALL
SELECT name from aux1.sqlite_schema WHERE type='trigger'
ORDER BY name;
} {r1 r2 r3 r4}
do_execsql_test 4.3 {
BEGIN;
DROP TRIGGER IF EXISTS none1, main.r1, r2, aux1.none2, r3, aux1.r4;
SELECT name FROM sqlite_schema WHERE type='trigger'
UNION ALL
SELECT name from aux1.sqlite_schema WHERE type='trigger'
ORDER BY name;
ROLLBACK;
} {}
finish_test
+11
View File
@@ -71,6 +71,17 @@ do_test fkey1-2.1 {
DROP TABLE t10;
}
} {}
do_test fkey1-2.2 {
execsql {
CREATE TABLE t5(x references t4);
CREATE TABLE t6(x references t4);
CREATE TABLE t7(x references t4);
CREATE TABLE t8(x references t4);
CREATE TABLE t9(x references t4);
CREATE TABLE t10(x references t4);
DROP TABLE t7, t9, t5, t8, t6, t10;
}
} {}
do_test fkey1-3.1 {
execsql {
-6
View File
@@ -67,12 +67,6 @@ for {set ii 1} {$ii<=5000} {incr ii} {
FROM t1, kv
WHERE p->>key IS NOT val
} 0
do_execsql_test $ii.8 {
SELECT j0 FROM t1 WHERE json(j0)!=json(json_pretty(j0));
} {}
do_execsql_test $ii.9 {
SELECT j5 FROM t1 WHERE json(j5)!=json(json_pretty(j5));
} {}
}
-45
View File
@@ -1,45 +0,0 @@
# 2024-03-06
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# May you do good and not evil.
# May you find forgiveness for yourself and forgive others.
# May you share freely, never taking more than you give.
#
#***********************************************************************
# Invariant tests for JSON built around the randomjson extension
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix json108
# These tests require virtual table "json_tree" to run.
ifcapable !vtab { finish_test ; return }
load_static_extension db randomjson
db eval {
CREATE TEMP TABLE t1(j0,j5);
WITH RECURSIVE c(n) AS (VALUES(0) UNION ALL SELECT n+1 FROM c WHERE n<9)
INSERT INTO t1 SELECT random_json(n), random_json5(n) FROM c;
}
do_execsql_test 1.1 {
SELECT count(*) FROM t1 WHERE json(j0)==json(json_pretty(j0,NULL));
} 10
do_execsql_test 1.2 {
SELECT count(*) FROM t1 WHERE json(j0)==json(json_pretty(j0,NULL));
} 10
do_execsql_test 1.3 {
SELECT count(*) FROM t1 WHERE json(j0)==json(json_pretty(j0,''));
} 10
do_execsql_test 1.4 {
SELECT count(*) FROM t1 WHERE json(j0)==json(json_pretty(j0,char(9)));
} 10
do_execsql_test 1.5 {
SELECT count(*) FROM t1 WHERE json(j0)==json(json_pretty(j0,'/*hello*/'));
} 10
finish_test
+4 -12
View File
@@ -59,14 +59,14 @@ do_vmstep_test 1.4.2 {
do_vmstep_test 1.5.1 {
SELECT count(*) FROM t2 WHERE EXISTS(
SELECT 1 FROM t1 WHERE t1.a=450 AND t2.d IS NULL
SELECT t2.d IS NULL FROM t1 WHERE t1.a=450
)
} 7000 {0}
} 10000 {1000}
do_vmstep_test 1.5.2 {
SELECT count(*) FROM t2 WHERE EXISTS(
SELECT 1 FROM t1 WHERE t1.a=450 AND t2.c IS NULL
SELECT t2.c IS NULL FROM t1 WHERE t1.a=450
)
} +8000 {0}
} +100000 {1000}
#-------------------------------------------------------------------------
reset_db
@@ -111,12 +111,4 @@ do_execsql_test 4.1 {
SELECT * FROM (SELECT 3 AS c FROM t1) AS t3 LEFT JOIN t2 ON c IS NULL;
} {3 {}}
# 2024-03-08 https://sqlite.org/forum/forumpost/440f2a2f17
#
reset_db
do_execsql_test 5.0 {
CREATE TABLE t1(a INT NOT NULL);
SELECT a IS NULL, a IS NOT NULL, count(*) FROM t1;
} {1 0 0}
finish_test
+10 -13
View File
@@ -51,19 +51,16 @@ do_test 1.0 {
}]
} {}
do_test 1.1 {
execsql {
CREATE TEMP TABLE t2(
a t1 PRIMARY KEY default 27,
b default(current_timestamp),
d TEXT UNIQUE DEFAULT 'ch`arlie',
c TEXT UNIQUE DEFAULT 084,
UNIQUE(c,b,b,a,b)
) WITHOUT ROWID;
}
catchsql { INSERT INTO t1(a) VALUES(zeroblob(40000)) }
set {} {}
} {}
do_execsql_test 1.1 {
CREATE TEMP TABLE t2(
a t1 PRIMARY KEY default 27,
b default(current_timestamp),
d TEXT UNIQUE DEFAULT 'ch`arlie',
c TEXT UNIQUE DEFAULT 084,
UNIQUE(c,b,b,a,b)
) WITHOUT ROWID;
INSERT INTO t1(a) VALUES(zeroblob(40000));
}
do_test 1.2 {
execsql { PRAGMA integrity_check; }
-1
View File
@@ -8,7 +8,6 @@
# May you share freely, never taking more than you give.
#
#***********************************************************************
# TESTRUNNER: shell
#
# Test the shell tool ".ar" command.
#
-1
View File
@@ -11,7 +11,6 @@
#
# The focus of this file is testing the CLI shell tool.
#
# TESTRUNNER: shell
#
# Test plan:
-1
View File
@@ -8,7 +8,6 @@
# May you share freely, never taking more than you give.
#
#***********************************************************************
# TESTRUNNER: shell
#
# The focus of this file is testing the CLI shell tool.
#
-1
View File
@@ -8,7 +8,6 @@
# May you share freely, never taking more than you give.
#
#***********************************************************************
# TESTRUNNER: shell
#
# The focus of this file is testing the CLI shell tool.
#
-1
View File
@@ -8,7 +8,6 @@
# May you share freely, never taking more than you give.
#
#***********************************************************************
# TESTRUNNER: shell
#
# The focus of this file is testing the CLI shell tool.
# These tests are specific to the .stats command.
-15
View File
@@ -8,7 +8,6 @@
# May you share freely, never taking more than you give.
#
#***********************************************************************
# TESTRUNNER: shell
#
# The focus of this file is testing the CLI shell tool.
# These tests are specific to the .import command.
@@ -571,18 +570,4 @@ SELECT * FROM t1;}
} {0 { 1 = あい
2 = うえお}}
# 2024-03-11 https://sqlite.org/forum/forumpost/ca014d7358
# Import into a table that contains computed columns.
#
do_test shell5-7.1 {
set out [open shell5.csv w]
fconfigure $out -translation lf
puts $out {aaa|bbb}
close $out
forcedelete test.db
catchcmd :memory: {CREATE TABLE t1(a TEXT, b TEXT, c AS (a||b));
.import shell5.csv t1
SELECT * FROM t1;}
} {0 aaa|bbb|aaabbb}
finish_test
-1
View File
@@ -8,7 +8,6 @@
# May you share freely, never taking more than you give.
#
#***********************************************************************
# TESTRUNNER: shell
#
# Test the shell tool ".lint fkey-indexes" command.
#
-1
View File
@@ -8,7 +8,6 @@
# May you share freely, never taking more than you give.
#
#***********************************************************************
# TESTRUNNER: shell
#
# Test the readfile() function built into the shell tool. Specifically,
# that it does not truncate the blob read at the first embedded 0x00
-1
View File
@@ -8,7 +8,6 @@
# May you share freely, never taking more than you give.
#
#***********************************************************************
# TESTRUNNER: shell
#
# Test the shell tool ".ar" command.
#
-1
View File
@@ -8,7 +8,6 @@
# May you share freely, never taking more than you give.
#
#***********************************************************************
# TESTRUNNER: shell
#
# The focus of this file is testing the CLI shell tool. Specifically,
# testing that it is possible to run a ".dump" script that creates
+8 -59
View File
@@ -159,7 +159,6 @@ switch -nocase -glob -- $tcl_platform(os) {
set TRG(make) make.sh
set TRG(makecmd) "bash make.sh"
set TRG(testfixture) testfixture
set TRG(shell) sqlite3
set TRG(run) run.sh
set TRG(runcmd) "bash run.sh"
}
@@ -168,16 +167,14 @@ switch -nocase -glob -- $tcl_platform(os) {
set TRG(make) make.sh
set TRG(makecmd) "bash make.sh"
set TRG(testfixture) testfixture
set TRG(shell) sqlite3
set TRG(run) run.sh
set TRG(runcmd) "bash run.sh"
}
*win* {
set TRG(platform) win
set TRG(make) make.bat
set TRG(makecmd) "call make.bat"
set TRG(makecmd) make.bat
set TRG(testfixture) testfixture.exe
set TRG(shell) sqlite3.exe
set TRG(run) run.bat
set TRG(runcmd) "run.bat"
}
@@ -620,16 +617,7 @@ proc add_job {args} {
trdb last_insert_rowid
}
# Argument $build is either an empty string, or else a list of length 3
# describing the job to build testfixture. In the usual form:
#
# {ID DIRNAME DISPLAYNAME}
#
# e.g
#
# {1 /home/user/sqlite/test/testrunner_bld_xyz All-Debug}
#
proc add_tcl_jobs {build config patternlist {shelldepid ""}} {
proc add_tcl_jobs {build config patternlist} {
global TRG
set topdir [file dirname $::testdir]
@@ -678,59 +666,34 @@ proc add_tcl_jobs {build config patternlist {shelldepid ""}} {
if {[lsearch $lProp slow]>=0} { set priority 2 }
if {[lsearch $lProp superslow]>=0} { set priority 4 }
set depid [lindex $build 0]
if {$shelldepid!="" && [lsearch $lProp shell]>=0} { set depid $shelldepid }
add_job \
-displaytype tcl \
-displayname $displayname \
-cmd $cmd \
-depid $depid \
-depid [lindex $build 0] \
-priority $priority
}
}
proc add_build_job {buildname target {postcmd ""} {depid ""}} {
proc add_build_job {buildname target} {
global TRG
set dirname "[string tolower [string map {- _} $buildname]]_$target"
set dirname "testrunner_bld_$dirname"
set cmd "$TRG(makecmd) $target"
if {$postcmd!=""} {
append cmd "\n"
append cmd $postcmd
}
set id [add_job \
-displaytype bld \
-displayname "Build $buildname ($target)" \
-dirname $dirname \
-build $buildname \
-cmd $cmd \
-depid $depid \
-cmd "$TRG(makecmd) $target" \
-priority 3
]
list $id [file normalize $dirname] $buildname
}
proc add_shell_build_job {buildname dirname depid} {
global TRG
if {$TRG(platform)=="win"} {
set path [string map {/ \\} "$dirname/"]
set copycmd "xcopy $TRG(shell) $path"
} else {
set copycmd "cp $TRG(shell) $dirname/"
}
return [
add_build_job $buildname $TRG(shell) $copycmd $depid
]
}
proc add_make_job {bld target} {
global TRG
@@ -804,19 +767,10 @@ proc add_devtest_jobs {lBld patternlist} {
foreach b $lBld {
set bld [add_build_job $b $TRG(testfixture)]
add_tcl_jobs $bld veryquick $patternlist SHELL
add_tcl_jobs $bld veryquick $patternlist
if {$patternlist==""} {
add_fuzztest_jobs $b
}
if {[trdb one "SELECT EXISTS (SELECT 1 FROM jobs WHERE depid='SHELL')"]} {
set sbld [add_shell_build_job $b [lindex $bld 1] [lindex $bld 0]]
set sbldid [lindex $sbld 0]
trdb eval {
UPDATE jobs SET depid=$sbldid WHERE depid='SHELL'
}
}
}
}
@@ -994,11 +948,6 @@ proc launch_another_job {iJob} {
close $fd
}
set job_cmd $job(cmd)
if {$TRG(platform)!="win"} {
set job_cmd "export SQLITE_TMPDIR=\"[file normalize $dir]\"\n$job_cmd"
}
if { $TRG(dryrun) } {
mark_job_as_finished $job(jobid) "" done 0
@@ -1013,7 +962,7 @@ proc launch_another_job {iJob} {
set pwd [pwd]
cd $dir
set fd [open $TRG(run) w]
puts $fd $job_cmd
puts $fd $job(cmd)
close $fd
set fd [open "|$TRG(runcmd) 2>@1" r]
cd $pwd
+1 -1
View File
@@ -30,7 +30,7 @@ do_test 2.1 {
catchsql { SELECT datetime('now', 'localtime') }
} {1 {local time unavailable}}
do_test 2.2 {
catchsql { SELECT datetime('2000-01-01', 'utc') }
catchsql { SELECT datetime('now', 'utc') }
} {1 {local time unavailable}}
sqlite3_test_control SQLITE_TESTCTRL_LOCALTIME_FAULT 0
-42
View File
@@ -408,46 +408,4 @@ do_catchsql_test 2.1 {
} {1 {no such table: nosuchtable}}
# 2024-03-08 https://sqlite.org/forum/forumpost/919c6579c8
# A redundant ON CONFLICT clause in an upsert can lead to
# index corruption.
#
reset_db
do_execsql_test 3.0 {
CREATE TABLE t1(aa INTEGER PRIMARY KEY, bb INT);
INSERT INTO t1 VALUES(11,22);
CREATE UNIQUE INDEX t1bb ON t1(bb);
REPLACE INTO t1 VALUES(11,33)
ON CONFLICT(bb) DO UPDATE SET aa = 44
ON CONFLICT(bb) DO UPDATE SET aa = 44;
PRAGMA integrity_check;
} {ok}
do_execsql_test 3.1 {
SELECT * FROM t1 NOT INDEXED;
} {11 33}
do_execsql_test 3.2 {
SELECT * FROM t1 INDEXED BY t1bb;
} {11 33}
do_execsql_test 3.3 {
DROP TABLE t1;
CREATE TABLE t1(aa INTEGER PRIMARY KEY, bb INT, cc INT);
INSERT INTO t1 VALUES(10,21,32),(11,22,33),(12,23,34);
CREATE UNIQUE INDEX t1bb ON t1(bb);
CREATE UNIQUE INDEX t1cc ON t1(cc);
REPLACE INTO t1 VALUES(11,44,55)
ON CONFLICT(bb) DO UPDATE SET aa = 99
ON CONFLICT(cc) DO UPDATE SET aa = 99
ON CONFLICT(bb) DO UPDATE SET aa = 99;
PRAGMA integrity_check;
} {ok}
do_execsql_test 3.4 {
SELECT * FROM t1 NOT INDEXED ORDER BY +aa;
} {10 21 32 11 44 55 12 23 34}
do_execsql_test 3.5 {
SELECT * FROM t1 INDEXED BY t1bb ORDER BY +aa;
} {10 21 32 11 44 55 12 23 34}
do_execsql_test 3.6 {
SELECT * FROM t1 INDEXED BY t1cc ORDER BY +aa;
} {10 21 32 11 44 55 12 23 34}
finish_test
-18
View File
@@ -209,22 +209,4 @@ do_eqp_test 710 {
`--SEARCH t1 USING INDEX idx (<expr>=?)
}
# 2024-03-07 https://sqlite.org/forum/forumpost/ecdfc02339
# A refinement is needed to the enhancements tested by the prior test case
# to avoid another problem with indexes on constant expressions.
#
reset_db
db null NULL
do_execsql_test 800 {
CREATE TABLE t0(c0, c1);
CREATE TABLE t1(c2);
CREATE INDEX i0 ON t1(NULL);
INSERT INTO t1(c2) VALUES (0.2);
CREATE VIEW v0(c3) AS SELECT DISTINCT c2 FROM t1;
SELECT * FROM v0 LEFT JOIN t0 ON c3<NULL LEFT JOIN t1 ON 1;
} {0.2 NULL NULL 0.2}
do_execsql_test 810 {
SELECT * FROM v0 LEFT JOIN t0 ON c3<NULL LEFT JOIN t1 ON 1 WHERE c2/0.1;
} {0.2 NULL NULL 0.2}
finish_test
+1 -8
View File
@@ -81,7 +81,6 @@ while {![eof $in]} {
set op($name) -1
set group($name) 0
set jump($name) 0
set jump0($name) 0
set in1($name) 0
set in2($name) 0
set in3($name) 0
@@ -110,7 +109,6 @@ while {![eof $in]} {
out2 {set out2($name) 1}
out3 {set out3($name) 1}
ncycle {set ncycle($name) 1}
jump0 {set jump($name) 1; set jump0($name) 1;}
}
}
if {$group($name)} {
@@ -139,7 +137,6 @@ puts "/* Automatically generated. Do not edit */"
puts "/* See the tool/mkopcodeh.tcl script for details */"
foreach name {OP_Noop OP_Explain OP_Abortable} {
set jump($name) 0
set jump0($name) 0
set in1($name) 0
set in2($name) 0
set in3($name) 0
@@ -259,9 +256,7 @@ for {set i 0} {$i<=$max} {incr i} {
set name $def($i)
puts -nonewline [format {#define %-16s %3d} $name $i]
set com {}
if {[info exists jump0($name)] && $jump0($name)} {
lappend com "jump0"
} elseif {[info exists jump($name)] && $jump($name)} {
if {[info exists jump($name)] && $jump($name)} {
lappend com "jump"
}
if {[info exists sameas($i)]} {
@@ -294,7 +289,6 @@ for {set i 0} {$i<=$max} {incr i} {
if {$out2($name)} {incr x 16}
if {$out3($name)} {incr x 32}
if {$ncycle($name)} {incr x 64}
if {$jump0($name)} {incr x 128}
}
set bv($i) $x
}
@@ -310,7 +304,6 @@ puts "#define OPFLG_IN3 0x08 /* in3: P3 is an input */"
puts "#define OPFLG_OUT2 0x10 /* out2: P2 is an output */"
puts "#define OPFLG_OUT3 0x20 /* out3: P3 is an output */"
puts "#define OPFLG_NCYCLE 0x40 /* ncycle:Cycles count against P1 */"
puts "#define OPFLG_JUMP0 0x80 /* jump0: P2 might be zero */"
puts "#define OPFLG_INITIALIZER \173\\"
for {set i 0} {$i<=$max} {incr i} {
if {$i%8==0} {