Compare commits
87 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 9a1bb3f616 | |||
| 480620c713 | |||
| 3b9f154bb7 | |||
| 541ef2c36c | |||
| 45248de39a | |||
| 871f45441c | |||
| 7a43100afb | |||
| 1d9ea27f7e | |||
| 054a081555 | |||
| 7576a68c8c | |||
| c39b121a95 | |||
| f05dd03a6e | |||
| e6a85962e7 | |||
| 43e862723e | |||
| 4b3282d8a0 | |||
| aa0696ee9a | |||
| 2d99f95721 | |||
| b3120fdf5b | |||
| 4047bdfd2c | |||
| d44390c8c5 | |||
| 85f2c76cf9 | |||
| 47f8ef32a0 | |||
| 2e52a9c611 | |||
| c59b4acf5d | |||
| a96a69b7db | |||
| c415d91007 | |||
| 4db7ab53f9 | |||
| fb99e388ec | |||
| 91654b2016 | |||
| 892edb69c4 | |||
| 3e42b99175 | |||
| 218da8c6f1 | |||
| b1243a6d9c | |||
| 97ccc1bd11 | |||
| 95b395901a | |||
| cdbb28154e | |||
| 8e9297fb79 | |||
| 74a07986ce | |||
| f7f6dbf501 | |||
| 7d76fad8eb | |||
| 31f170f396 | |||
| 465c2b8964 | |||
| 2c3629e1c9 | |||
| 62b6e1d042 | |||
| 2aee514b4c | |||
| 00bd55e1ae | |||
| ec8e689a20 | |||
| 589c787620 | |||
| f0a2172d1d | |||
| 91a23dc299 | |||
| 553948e514 | |||
| 14c98a4f40 | |||
| ba25c7e29f | |||
| 576d0a9fd9 | |||
| 2267a7fa87 | |||
| 9b258c54e4 | |||
| 38dfbdae8a | |||
| 8d5cea6b61 | |||
| e7375bfa72 | |||
| 5cf1b611a2 | |||
| 24e399038b | |||
| 0c76e892d9 | |||
| 088489e8d9 | |||
| afa1ecac9b | |||
| ccb3781673 | |||
| 45dc9ca46b | |||
| ed5e66881e | |||
| db9cb17dc7 | |||
| 0ea2d42ac3 | |||
| 42a630b1da | |||
| 4cf2121e1c | |||
| f5cfe6f2c4 | |||
| d346fe0ab5 | |||
| b3f0d92b91 | |||
| 39b3bcf8ef | |||
| a2ec2e4843 | |||
| 7f05d52c4c | |||
| 0a21ea997d | |||
| 4a3a3eb3d7 | |||
| 2826918d10 | |||
| 9e5ecdc172 | |||
| be284e4ece | |||
| 67e2bb92df | |||
| 47a60d4518 | |||
| df97d43930 | |||
| a8781d9d93 | |||
| f575c1cf06 |
@@ -1069,6 +1069,7 @@ SHELL_SRC = \
|
||||
$(TOP)/ext/misc/fileio.c \
|
||||
$(TOP)/ext/misc/completion.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 \
|
||||
|
||||
@@ -2182,6 +2182,7 @@ SHELL_SRC = \
|
||||
$(TOP)\ext\misc\shathree.c \
|
||||
$(TOP)\ext\misc\fileio.c \
|
||||
$(TOP)\ext\misc\completion.c \
|
||||
$(TOP)\ext\misc\uint.c \
|
||||
$(TOP)\ext\expert\sqlite3expert.c \
|
||||
$(TOP)\ext\expert\sqlite3expert.h \
|
||||
$(TOP)\ext\misc\memtrace.c \
|
||||
|
||||
+6
-6
@@ -123,7 +123,7 @@ Suppress generation of the report file.
|
||||
<li><b>-r</b>
|
||||
Do not sort or renumber the parser states as part of optimization.
|
||||
<li><b>-s</b>
|
||||
Show parser statistics before existing.
|
||||
Show parser statistics before exiting.
|
||||
<li><b>-T<i>file</i></b>
|
||||
Use <i>file</i> as the template for the generated C-code parser implementation.
|
||||
<li><b>-x</b>
|
||||
@@ -488,7 +488,7 @@ is an error.</p>
|
||||
The precedence of a grammar rule is equal to the precedence of the
|
||||
left-most terminal symbol in the rule for which a precedence is
|
||||
defined. This is normally what you want, but in those cases where
|
||||
you want to precedence of a grammar rule to be something different,
|
||||
you want the precedence of a grammar rule to be something different,
|
||||
you can specify an alternative precedence symbol by putting the
|
||||
symbol in square braces after the period at the end of the rule and
|
||||
before any C-code. For example:</p>
|
||||
@@ -689,7 +689,7 @@ on Parse().
|
||||
<a name='extractx'></a>
|
||||
<h4>The <tt>%extra_context</tt> directive</h4>
|
||||
|
||||
The <tt>%extra_context</tt> directive instructs Lemon to add a 2th parameter
|
||||
The <tt>%extra_context</tt> directive instructs Lemon to add a 2nd parameter
|
||||
to the parameter list of the ParseAlloc() and ParseInif() functions. Lemon
|
||||
doesn't do anything itself with these extra argument, but it does
|
||||
store the value make it available to C-code action routines, destructors,
|
||||
@@ -699,9 +699,9 @@ and so forth. For example, if the grammar file contains:</p>
|
||||
%extra_context { MyStruct *pAbc }
|
||||
</pre></p>
|
||||
|
||||
<p>Then the ParseAlloc() and ParseInit() functions will have an 2th parameter
|
||||
<p>Then the ParseAlloc() and ParseInit() functions will have an 2nd parameter
|
||||
of type "MyStruct*" and all action routines will have access to
|
||||
a variable named "pAbc" that is the value of that 2th parameter.</p>
|
||||
a variable named "pAbc" that is the value of that 2nd parameter.</p>
|
||||
|
||||
<p>The <tt>%extra_argument</tt> directive works the same except that it
|
||||
is passed in on the Parse() routine instead of on ParseAlloc()/ParseInit().
|
||||
@@ -996,7 +996,7 @@ on the parser's stack associated with terminal and non-terminal
|
||||
symbols. The values of all terminal symbols must be of the same
|
||||
type. This turns out to be the same data type as the 3rd parameter
|
||||
to the Parse() function generated by Lemon. Typically, you will
|
||||
make the value of a terminal symbol by a pointer to some kind of
|
||||
make the value of a terminal symbol be a pointer to some kind of
|
||||
token structure. Like this:</p>
|
||||
|
||||
<p><pre>
|
||||
|
||||
+11
-4
@@ -37,6 +37,9 @@ proc squish {txt} {
|
||||
|
||||
proc do_setup_rec_test {tn setup sql res} {
|
||||
reset_db
|
||||
if {[info exists ::set_main_db_name]} {
|
||||
dbconfig_maindbname_icecube db
|
||||
}
|
||||
db eval $setup
|
||||
uplevel [list do_rec_test $tn $sql $res]
|
||||
}
|
||||
@@ -76,6 +79,10 @@ foreach {tn setup} {
|
||||
}
|
||||
}
|
||||
3 {
|
||||
if {[info commands sqlite3_expert_new]==""} { continue }
|
||||
set ::set_main_db_name 1
|
||||
}
|
||||
4 {
|
||||
if {![file executable $CLI]} { continue }
|
||||
|
||||
proc do_rec_test {tn sql res} {
|
||||
@@ -336,7 +343,7 @@ proc do_candidates_test {tn sql res} {
|
||||
|
||||
|
||||
reset_db
|
||||
do_execsql_test 4.0 {
|
||||
do_execsql_test 5.0 {
|
||||
CREATE TABLE t1(a, b);
|
||||
CREATE TABLE t2(c, d);
|
||||
|
||||
@@ -346,7 +353,7 @@ do_execsql_test 4.0 {
|
||||
WITH s(i) AS ( VALUES(1) UNION ALL SELECT i+1 FROM s WHERE i<100)
|
||||
INSERT INTO t2 SELECT (i-1)/20, (i-1)/5 FROM s;
|
||||
}
|
||||
do_candidates_test 4.1 {
|
||||
do_candidates_test 5.1 {
|
||||
SELECT * FROM t1,t2 WHERE (b=? OR a=?) AND (c=? OR d=?)
|
||||
} {
|
||||
CREATE INDEX t1_idx_00000062 ON t1(b); -- stat1: 100 20
|
||||
@@ -355,14 +362,14 @@ do_candidates_test 4.1 {
|
||||
CREATE INDEX t2_idx_00000064 ON t2(d); -- stat1: 100 5
|
||||
}
|
||||
|
||||
do_candidates_test 4.2 {
|
||||
do_candidates_test 5.2 {
|
||||
SELECT * FROM t1,t2 WHERE a=? AND b=? AND c=? AND d=?
|
||||
} {
|
||||
CREATE INDEX t1_idx_000123a7 ON t1(a, b); -- stat1: 100 50 17
|
||||
CREATE INDEX t2_idx_0001295b ON t2(c, d); -- stat1: 100 20 5
|
||||
}
|
||||
|
||||
do_execsql_test 4.3 {
|
||||
do_execsql_test 5.3 {
|
||||
CREATE INDEX t1_idx_00000061 ON t1(a); -- stat1: 100 50
|
||||
CREATE INDEX t1_idx_00000062 ON t1(b); -- stat1: 100 20
|
||||
CREATE INDEX t1_idx_000123a7 ON t1(a, b); -- stat1: 100 50 16
|
||||
|
||||
+5
-1
@@ -1884,6 +1884,7 @@ static int fts3ScanInteriorNode(
|
||||
i64 nAlloc = 0; /* Size of allocated buffer */
|
||||
int isFirstTerm = 1; /* True when processing first term on page */
|
||||
sqlite3_int64 iChild; /* Block id of child node to descend to */
|
||||
int nBuffer = 0; /* Total term size */
|
||||
|
||||
/* Skip over the 'height' varint that occurs at the start of every
|
||||
** interior node. Then load the blockid of the left-child of the b-tree
|
||||
@@ -1908,12 +1909,15 @@ static int fts3ScanInteriorNode(
|
||||
int cmp; /* memcmp() result */
|
||||
int nSuffix; /* Size of term suffix */
|
||||
int nPrefix = 0; /* Size of term prefix */
|
||||
int nBuffer; /* Total term size */
|
||||
|
||||
/* Load the next term on the node into zBuffer. Use realloc() to expand
|
||||
** the size of zBuffer if required. */
|
||||
if( !isFirstTerm ){
|
||||
zCsr += fts3GetVarint32(zCsr, &nPrefix);
|
||||
if( nPrefix>nBuffer ){
|
||||
rc = FTS_CORRUPT_VTAB;
|
||||
goto finish_scan;
|
||||
}
|
||||
}
|
||||
isFirstTerm = 0;
|
||||
zCsr += fts3GetVarint32(zCsr, &nSuffix);
|
||||
|
||||
@@ -1415,6 +1415,7 @@ static int fts3SegReaderNext(
|
||||
*/
|
||||
if( pReader->nDoclist > pReader->nNode-(pReader->aDoclist-pReader->aNode)
|
||||
|| (pReader->nPopulate==0 && pReader->aDoclist[pReader->nDoclist-1])
|
||||
|| pReader->nDoclist==0
|
||||
){
|
||||
return FTS_CORRUPT_VTAB;
|
||||
}
|
||||
@@ -4953,6 +4954,12 @@ int sqlite3Fts3Incrmerge(Fts3Table *p, int nMerge, int nMin){
|
||||
** Exit early in this case. */
|
||||
if( nSeg<=0 ) break;
|
||||
|
||||
assert( nMod<=0x7FFFFFFF );
|
||||
if( iAbsLevel<0 || iAbsLevel>(nMod<<32) ){
|
||||
rc = FTS_CORRUPT_VTAB;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Open a cursor to iterate through the contents of the oldest nSeg
|
||||
** indexes of absolute level iAbsLevel. If this cursor is opened using
|
||||
** the 'hint' parameters, it is possible that there are less than nSeg
|
||||
|
||||
+3
-3
@@ -143,7 +143,7 @@ static int icuLikeCompare(
|
||||
** 3. uPattern is an unescaped escape character, or
|
||||
** 4. uPattern is to be handled as an ordinary character
|
||||
*/
|
||||
if( !prevEscape && uPattern==MATCH_ALL ){
|
||||
if( uPattern==MATCH_ALL && !prevEscape && uPattern!=(uint32_t)uEsc ){
|
||||
/* Case 1. */
|
||||
uint8_t c;
|
||||
|
||||
@@ -169,12 +169,12 @@ static int icuLikeCompare(
|
||||
}
|
||||
return 0;
|
||||
|
||||
}else if( !prevEscape && uPattern==MATCH_ONE ){
|
||||
}else if( uPattern==MATCH_ONE && !prevEscape && uPattern!=(uint32_t)uEsc ){
|
||||
/* Case 2. */
|
||||
if( *zString==0 ) return 0;
|
||||
SQLITE_ICU_SKIP_UTF8(zString);
|
||||
|
||||
}else if( !prevEscape && uPattern==(uint32_t)uEsc){
|
||||
}else if( uPattern==(uint32_t)uEsc && !prevEscape ){
|
||||
/* Case 3. */
|
||||
prevEscape = 1;
|
||||
|
||||
|
||||
@@ -394,6 +394,7 @@ static int writeFile(
|
||||
|
||||
if( mtime>=0 ){
|
||||
#if defined(_WIN32)
|
||||
#if !SQLITE_OS_WINRT
|
||||
/* Windows */
|
||||
FILETIME lastAccess;
|
||||
FILETIME lastWrite;
|
||||
@@ -424,6 +425,7 @@ static int writeFile(
|
||||
}else{
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
#elif defined(AT_FDCWD) && 0 /* utimensat() is not universally available */
|
||||
/* Recent unix */
|
||||
struct timespec times[2];
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
** 2020-04-14
|
||||
**
|
||||
** The author disclaims copyright to this source code. In place of
|
||||
** a legal notice, here is a blessing:
|
||||
**
|
||||
** May you do good and not evil.
|
||||
** May you find forgiveness for yourself and forgive others.
|
||||
** May you share freely, never taking more than you give.
|
||||
**
|
||||
******************************************************************************
|
||||
**
|
||||
** This SQLite extension implements the UINT collating sequence.
|
||||
**
|
||||
** UINT works like BINARY for text, except that embedded strings
|
||||
** of digits compare in numeric order.
|
||||
**
|
||||
** * Leading zeros are handled properly, in the sense that
|
||||
** they do not mess of the maginitude comparison of embedded
|
||||
** strings of digits. "x00123y" is equal to "x123y".
|
||||
**
|
||||
** * Only unsigned integers are recognized. Plus and minus
|
||||
** signs are ignored. Decimal points and exponential notation
|
||||
** are ignored.
|
||||
**
|
||||
** * Embedded integers can be of arbitrary length. Comparison
|
||||
** is *not* limited integers that can be expressed as a
|
||||
** 64-bit machine integer.
|
||||
*/
|
||||
#include "sqlite3ext.h"
|
||||
SQLITE_EXTENSION_INIT1
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
|
||||
/*
|
||||
** Compare text in lexicographic order, except strings of digits
|
||||
** compare in numeric order.
|
||||
*/
|
||||
static int uintCollFunc(
|
||||
void *notUsed,
|
||||
int nKey1, const void *pKey1,
|
||||
int nKey2, const void *pKey2
|
||||
){
|
||||
const unsigned char *zA = (const unsigned char*)pKey1;
|
||||
const unsigned char *zB = (const unsigned char*)pKey2;
|
||||
int i=0, j=0, x;
|
||||
while( i<nKey1 && j<nKey2 ){
|
||||
x = zA[i] - zB[j];
|
||||
if( isdigit(zA[i]) ){
|
||||
int k;
|
||||
if( !isdigit(zB[j]) ) return x;
|
||||
while( i<nKey1 && zA[i]=='0' ){ i++; }
|
||||
while( j<nKey2 && zB[j]=='0' ){ j++; }
|
||||
k = 0;
|
||||
while( i+k<nKey1 && isdigit(zA[i+k])
|
||||
&& j+k<nKey2 && isdigit(zB[j+k]) ){
|
||||
k++;
|
||||
}
|
||||
if( i+k<nKey1 && isdigit(zA[i+k]) ){
|
||||
return +1;
|
||||
}else if( j+k<nKey2 && isdigit(zB[j+k]) ){
|
||||
return -1;
|
||||
}else{
|
||||
x = memcmp(zA+i, zB+j, k);
|
||||
if( x ) return x;
|
||||
i += k;
|
||||
j += k;
|
||||
}
|
||||
}else if( x ){
|
||||
return x;
|
||||
}else{
|
||||
i++;
|
||||
j++;
|
||||
}
|
||||
}
|
||||
return (nKey1 - i) - (nKey2 - j);
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
__declspec(dllexport)
|
||||
#endif
|
||||
int sqlite3_uint_init(
|
||||
sqlite3 *db,
|
||||
char **pzErrMsg,
|
||||
const sqlite3_api_routines *pApi
|
||||
){
|
||||
SQLITE_EXTENSION_INIT2(pApi);
|
||||
(void)pzErrMsg; /* Unused parameter */
|
||||
return sqlite3_create_collation(db, "uint", SQLITE_UTF8, 0, uintCollFunc);
|
||||
}
|
||||
+3
-1
@@ -3746,8 +3746,10 @@ static int rtreeInit(
|
||||
}else if( pRtree->nAux>0 ){
|
||||
break;
|
||||
}else{
|
||||
static const char *azFormat[] = {",%.*s REAL", ",%.*s INT"};
|
||||
pRtree->nDim2++;
|
||||
sqlite3_str_appendf(pSql, ",%.*s NUM", rtreeTokenLength(zArg), zArg);
|
||||
sqlite3_str_appendf(pSql, azFormat[eCoordType],
|
||||
rtreeTokenLength(zArg), zArg);
|
||||
}
|
||||
}
|
||||
sqlite3_str_appendf(pSql, ");");
|
||||
|
||||
+13
-1
@@ -716,6 +716,18 @@ do_execsql_test 18.0 {
|
||||
SELECT rt0.c1 > '-1' FROM rt0;
|
||||
} {9 1}
|
||||
|
||||
|
||||
expand_all_sql db
|
||||
|
||||
# 2020-02-28 ticket e63b4d1a65546532
|
||||
reset_db
|
||||
do_execsql_test 19.0 {
|
||||
CREATE VIRTUAL TABLE rt0 USING rtree(a,b,c);
|
||||
INSERT INTO rt0(a,b,c) VALUES(0,0.0,0.0);
|
||||
CREATE VIEW v0(x) AS SELECT DISTINCT rt0.b FROM rt0;
|
||||
SELECT v0.x FROM v0, rt0;
|
||||
} {0.0}
|
||||
do_execsql_test 19.1 {
|
||||
SELECT v0.x FROM v0, rt0 WHERE v0.x = rt0.b;
|
||||
} {0.0}
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -34,5 +34,51 @@ do_test 1.0 {
|
||||
compare_db db db2
|
||||
} {}
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
db2 close
|
||||
reset_db
|
||||
|
||||
do_execsql_test 2.0 {
|
||||
CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c);
|
||||
INSERT INTO main.t1 VALUES(1, 2, 3), (4, 5, 6), (7, 8, 9);
|
||||
}
|
||||
|
||||
do_test 2.1 {
|
||||
sqlite3session S db main
|
||||
S attach *
|
||||
db eval {
|
||||
BEGIN;
|
||||
INSERT INTO t1 VALUES(10, 11, 12);
|
||||
DELETE FROM t1 WHERE a=1;
|
||||
UPDATE t1 SET b='five', c='six' WHERE a=4;
|
||||
}
|
||||
|
||||
set C [S changeset]
|
||||
db eval ROLLBACK
|
||||
S delete
|
||||
set {} {}
|
||||
} {}
|
||||
|
||||
do_execsql_test 2.2 {
|
||||
CREATE TEMP TABLE t1(a INTEGER PRIMARY KEY, b, c);
|
||||
INSERT INTO temp.t1 VALUES(1, 2, 3), (4, 5, 6), (7, 8, 9);
|
||||
}
|
||||
|
||||
set ::conflict [list]
|
||||
proc xConflict {args} { lappend ::conflict $args ; return "" }
|
||||
do_test 2.3 {
|
||||
sqlite3changeset_apply db $C xConflict
|
||||
set ::conflict
|
||||
} {}
|
||||
do_execsql_test 2.4 {
|
||||
SELECT * FROM main.t1;
|
||||
SELECT '****';
|
||||
SELECT * FROM temp.t1;
|
||||
} {
|
||||
4 five six 7 8 9 10 11 12
|
||||
****
|
||||
1 2 3 4 5 6 7 8 9
|
||||
}
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -3513,7 +3513,7 @@ static int sessionDeleteRow(
|
||||
SessionBuffer buf = {0, 0, 0};
|
||||
int nPk = 0;
|
||||
|
||||
sessionAppendStr(&buf, "DELETE FROM ", &rc);
|
||||
sessionAppendStr(&buf, "DELETE FROM main.", &rc);
|
||||
sessionAppendIdent(&buf, zTab, &rc);
|
||||
sessionAppendStr(&buf, " WHERE ", &rc);
|
||||
|
||||
@@ -3596,7 +3596,7 @@ static int sessionUpdateRow(
|
||||
SessionBuffer buf = {0, 0, 0};
|
||||
|
||||
/* Append "UPDATE tbl SET " */
|
||||
sessionAppendStr(&buf, "UPDATE ", &rc);
|
||||
sessionAppendStr(&buf, "UPDATE main.", &rc);
|
||||
sessionAppendIdent(&buf, zTab, &rc);
|
||||
sessionAppendStr(&buf, " SET ", &rc);
|
||||
|
||||
|
||||
@@ -733,6 +733,7 @@ SHELL_SRC = \
|
||||
$(TOP)/ext/misc/fileio.c \
|
||||
$(TOP)/ext/misc/completion.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 \
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
C Rework\sthis\schanges\sso\sthat\sinstead\sof\ssetting\sthe\sWhereTerm.truthProb\swhen\na\sterm\sis\sseen\sto\sbe\sof\slow\sselectivity,\sit\smerely\ssets\sa\snew\sflag\n(the\sTERM_HIGHTRUTH\sflag)\swhich\scauses\swhereLoopOutputAdjust()\sto\signore\nthat\sterm.
|
||||
D 2020-02-24T16:46:08.182
|
||||
C Add\sthe\ssqlite3_database_file_object()\sinterface\sto\ssqlite3ext.h.
|
||||
D 2020-04-21T19:27:08.207
|
||||
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
|
||||
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
|
||||
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
|
||||
F Makefile.in 9dfc7936f675785309b74d09202bb656732325e65df889e5aaa18cc8932e5b0c
|
||||
F Makefile.in f6ab6e307d31e09d82aa4eca87ccb21ce66f486279e204b54b3149ff0d71616f
|
||||
F Makefile.linux-gcc f609543700659711fbd230eced1f01353117621dccae7b9fb70daa64236c5241
|
||||
F Makefile.msc fab23c6b10cb6f06a7e9c407fc2e35cb184a6d653f1b793bda87fcee2eafa4f6
|
||||
F Makefile.msc 46c338b1151fbeed42c82416c6bc4da7ff9a10f851bf379f8592280fd53d6efa
|
||||
F README.md 1514a365ffca3c138e00c5cc839906108a01011a6b082bad19b09781e3aa498a
|
||||
F VERSION 980d78a2ce04a1fd0ebefbaabd665f7f9186563820629ee29c6e350e96f19b52
|
||||
F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50
|
||||
@@ -38,7 +38,7 @@ F configure 4bbb5f13998f2faf929b9ae708aea9fbcb08a46cb6dd3150e36c3f09c0a05a75 x
|
||||
F configure.ac 798a24cee2879325ca5b688a618199eb32cc77ed8136edbaa43d9137b470d54e
|
||||
F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad
|
||||
F doc/F2FS.txt c1d4a0ae9711cfe0e1d8b019d154f1c29e0d3abfe820787ba1e9ed7691160fcd
|
||||
F doc/lemon.html 24956ab2995e55fe171e55bdd04f22b553957dc8bb43501dbb9311e30187e0d3
|
||||
F doc/lemon.html 857495c0ce060a4e2f2ad7111135ad7e28041a32c10612279ab398eddf678f58
|
||||
F doc/pager-invariants.txt 27fed9a70ddad2088750c4a2b493b63853da2710
|
||||
F doc/trusted-schema.md 33625008620e879c7bcfbbfa079587612c434fa094d338b08242288d358c3e8a
|
||||
F doc/vfs-shm.txt e101f27ea02a8387ce46a05be2b1a902a021d37a
|
||||
@@ -48,7 +48,7 @@ F ext/async/sqlite3async.c 0f3070cc3f5ede78f2b9361fb3b629ce200d7d74
|
||||
F ext/async/sqlite3async.h f489b080af7e72aec0e1ee6f1d98ab6cf2e4dcef
|
||||
F ext/expert/README.md b321c2762bb93c18ea102d5a5f7753a4b8bac646cb392b3b437f633caf2020c3
|
||||
F ext/expert/expert.c d548d603a4cc9e61f446cc179c120c6713511c413f82a4a32b1e1e69d3f086a4
|
||||
F ext/expert/expert1.test e2afc53a27610e8251e44c7f961806607a5490ff204b3db342740d558e052662
|
||||
F ext/expert/expert1.test 2e10ff875c31c9e6fc5e324767624181273859771fe34c5daeeadf3f2974a4f7
|
||||
F ext/expert/sqlite3expert.c 3da865f2286433588260f41e796422c611bceaca3a0bbf9139a619cf7d062c19
|
||||
F ext/expert/sqlite3expert.h ca81efc2679a92373a13a3e76a6138d0310e32be53d6c3bfaedabd158ea8969b
|
||||
F ext/expert/test_expert.c d56c194b769bdc90cf829a14c9ecbc1edca9c850b837a4d0b13be14095c32a72
|
||||
@@ -82,7 +82,7 @@ F ext/fts3/README.content fdc666a70d5257a64fee209f97cf89e0e6e32b51
|
||||
F ext/fts3/README.syntax a19711dc5458c20734b8e485e75fb1981ec2427a
|
||||
F ext/fts3/README.tokenizers b92bdeb8b46503f0dd301d364efc5ef59ef9fa8e2758b8e742f39fa93a2e422d
|
||||
F ext/fts3/README.txt 8c18f41574404623b76917b9da66fcb0ab38328d
|
||||
F ext/fts3/fts3.c 52c09f459364732b5df73eff0373f991fd6af8f0f60fcdbb4b649205e88a7568
|
||||
F ext/fts3/fts3.c 2a9dd452003a143248e68449302da80dd0c43df72195b56577e3562e43c408a0
|
||||
F ext/fts3/fts3.h 3a10a0af180d502cecc50df77b1b22df142817fe
|
||||
F ext/fts3/fts3Int.h f091030b976045e7df91af2337935952b477cdbd9f48058c44c965684484cb50
|
||||
F ext/fts3/fts3_aux.c 96708c8b3a7d9b8ca1b68ea2b7e503e283f20e95f145becadedfad096dbd0f34
|
||||
@@ -100,7 +100,7 @@ F ext/fts3/fts3_tokenizer.h 64c6ef6c5272c51ebe60fc607a896e84288fcbc3
|
||||
F ext/fts3/fts3_tokenizer1.c 5c98225a53705e5ee34824087478cf477bdb7004
|
||||
F ext/fts3/fts3_unicode.c 4b9af6151c29b35ed09574937083cece7c31e911f69615e168a39677569b684d
|
||||
F ext/fts3/fts3_unicode2.c 416eb7e1e81142703520d284b768ca2751d40e31fa912cae24ba74860532bf0f
|
||||
F ext/fts3/fts3_write.c ddf34315b6c3dce79a28d966981cc76919b18f645d82c6132133a7c65b8ed283
|
||||
F ext/fts3/fts3_write.c d5da5f010b2e2c1523f0e359ec43858bb724f608d3805d0e2a82ca2b466eb22e
|
||||
F ext/fts3/fts3speed.tcl b54caf6a18d38174f1a6e84219950d85e98bb1e9
|
||||
F ext/fts3/mkfts3amal.tcl 252ecb7fe6467854f2aa237bf2c390b74e71f100
|
||||
F ext/fts3/tool/fts3cov.sh c331d006359456cf6f8f953e37f2b9c7d568f3863f00bb5f7eb87fea4ac01b73
|
||||
@@ -231,7 +231,7 @@ F ext/fts5/tool/loadfts5.tcl 95b03429ee6b138645703c6ca192c3ac96eaf093
|
||||
F ext/fts5/tool/mkfts5c.tcl d1c2a9ab8e0ec690a52316f33dd9b1d379942f45
|
||||
F ext/fts5/tool/showfts5.tcl d54da0e067306663e2d5d523965ca487698e722c
|
||||
F ext/icu/README.txt a295e91db742b153e8dce8f7efd31d28ad1eea4df31ef4daa3eedc85be2f5138
|
||||
F ext/icu/icu.c 7adfe8a72dd4f54b47684dc9b88523399c6ef119d733b73e17371445f7428dd1
|
||||
F ext/icu/icu.c 91c021c7e3e8bbba286960810fa303295c622e323567b2e6def4ce58e4466e60
|
||||
F ext/icu/sqliteicu.h 728867a802baa5a96de7495e9689a8e01715ef37
|
||||
F ext/lsm1/Makefile a553b728bba6c11201b795188c5708915cc4290f02b7df6ba7e8c4c943fd5cd9
|
||||
F ext/lsm1/Makefile.msc f8c878b467232226de288da320e1ac71c131f5ec91e08b21f502303347260013
|
||||
@@ -293,7 +293,7 @@ F ext/misc/dbdata.c e316fba936571584e55abd5b974a32a191727a6b746053a0c9d439bd2cf9
|
||||
F ext/misc/dbdump.c baf6e37447c9d6968417b1cd34cbedb0b0ab3f91b5329501d8a8d5be3287c336
|
||||
F ext/misc/eval.c 04bc9aada78c888394204b4ed996ab834b99726fb59603b0ee3ed6e049755dc1
|
||||
F ext/misc/explain.c d5c12962d79913ef774b297006872af1fccda388f61a11d37758f9179a09551f
|
||||
F ext/misc/fileio.c bfa11a207da4eed8e5f84a1e3954608492f25f8850f9f00d0d2076f4648d7608
|
||||
F ext/misc/fileio.c 9b69e25da3b51d4a1d905a464ccb96709792ad627a742ba09215bc0d1447e7bd
|
||||
F ext/misc/fossildelta.c 1240b2d3e52eab1d50c160c7fe1902a9bd210e052dc209200a750bbf885402d5
|
||||
F ext/misc/fuzzer.c eae560134f66333e9e1ca4c8ffea75df42056e2ce8456734565dbe1c2a92bf3d
|
||||
F ext/misc/ieee754.c eaffd9b364d7c8371727e9c43fc8bec38cdacc4d11fc26beffaa3ca05a0ea9d6
|
||||
@@ -320,6 +320,7 @@ F ext/misc/sqlar.c c9e5d58544e1506135806a1e0f525f92d4bb6bb125348dce469d778fb334f
|
||||
F ext/misc/stmt.c 8a8dc4675042e4551e4afe99b8d0cc7a4a2fc1a8dacc0a9ce1b1bbff145da93d
|
||||
F ext/misc/templatevtab.c 8a16a91a5ceaccfcbd6aaaa56d46828806e460dd194965b3f77bf38f14b942c4
|
||||
F ext/misc/totype.c fa4aedeb07f66169005dffa8de3b0a2b621779fd44f85c103228a42afa71853b
|
||||
F ext/misc/uint.c 5870865fb5f6153db18db443f3ecdcdb17a06567ee47ecd9fd26e3ec7e5f6ce8
|
||||
F ext/misc/unionvtab.c 36237f0607ca954ac13a4a0e2d2ac40c33bc6e032a5f55f431713061ef1625f9
|
||||
F ext/misc/urifuncs.c f71360d14fa9e7626b563f1f781c6148109462741c5235ac63ae0f8917b9c751
|
||||
F ext/misc/uuid.c 5bb2264c1b64d163efa46509544fd7500cb8769cb7c16dd52052da8d961505cf
|
||||
@@ -384,9 +385,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 cac70b5502742bd0ba8877a1329a74e86a379c78567546a2a18cf5f9c3787f73
|
||||
F ext/rtree/rtree.c 84b939a9a558edd0461bb976b98f60012e3e574b3b17a0f44533d6f2a9aa2f2e
|
||||
F ext/rtree/rtree.c 0ee39cc787b95aa03a012e09e6090b0fa452154fa812af9a379898560fd6c00f
|
||||
F ext/rtree/rtree.h 4a690463901cb5e6127cf05eb8e642f127012fd5003830dbc974eca5802d9412
|
||||
F ext/rtree/rtree1.test 4092a8bd2b5eafc4fafe4fe9024249c12b13e4bab23c2c3eaff57412fdf805fa
|
||||
F ext/rtree/rtree1.test 00792b030a4e188ff1b22e8530e8aa0452bb5dd81c2b18cb004afc7dc63e040e
|
||||
F ext/rtree/rtree2.test 9d9deddbb16fd0c30c36e6b4fdc3ee3132d765567f0f9432ee71e1303d32603d
|
||||
F ext/rtree/rtree3.test 4ee5d7df86040efe3d8d84f141f2962a7745452200a7cba1db06f86d97050499
|
||||
F ext/rtree/rtree4.test 304de65d484540111b896827e4261815e5dca4ce28eeecd58be648cd73452c4b
|
||||
@@ -433,7 +434,7 @@ F ext/session/sessionD.test 4f91d0ca8afc4c3969c72c9f0b5ea9527e21de29039937d0d973
|
||||
F ext/session/sessionE.test b2010949c9d7415306f64e3c2072ddabc4b8250c98478d3c0c4d064bce83111d
|
||||
F ext/session/sessionF.test d37ed800881e742c208df443537bf29aa49fd56eac520d0f0c6df3e6320f3401
|
||||
F ext/session/sessionG.test 3828b944cd1285f4379340fd36f8b64c464fc84df6ff3ccbc95578fd87140b9c
|
||||
F ext/session/sessionH.test a417559f29a7e775950fc5fc82b3d01256a7cbe793ddf1180df234df823d56e2
|
||||
F ext/session/sessionH.test b17afdbd3b8f17e9bab91e235acf167cf35485db2ab2df0ea8893fbb914741a4
|
||||
F ext/session/session_common.tcl 29ec9910aca1e996ca1c8531b8cecabf96eb576aa53de65a8ff03d848b9a2a8b
|
||||
F ext/session/session_speed_test.c dcf0ef58d76b70c8fbd9eab3be77cf9deb8bc1638fed8be518b62d6cbdef88b3
|
||||
F ext/session/sessionat.test efe88965e74ff1bc2af9c310b28358c02d420c1fb2705cc7a28f0c1cc142c3ec
|
||||
@@ -444,7 +445,7 @@ F ext/session/sessioninvert.test ae1a003a9ab1f8d64227dbb5c3a4c97e65b561b01e7b295
|
||||
F ext/session/sessionrebase.test ccfa716b23bd1d3b03217ee58cfd90c78d4b99f53e6a9a2f05e82363b9142810
|
||||
F ext/session/sessionstat1.test 218d351cf9fcd6648f125a26b607b140310160184723c2666091b54450a68fb5
|
||||
F ext/session/sessionwor.test 67b5ab91d4f93ce65ff1f58240ac5ddf73f8670facc1ffa49cef56293d52818d
|
||||
F ext/session/sqlite3session.c a4dfb372f270df93422b0dc7666fd46849e6979b62a152f11287c21eed4ac21b
|
||||
F ext/session/sqlite3session.c e25b345896fa3646ff8b6c4058b3d9e365dc7eab4afe80b110808681098551c8
|
||||
F ext/session/sqlite3session.h a2db5b72b938d12c727b4b4ec632254ca493670a9c0de597af3271a7f774fc57
|
||||
F ext/session/test_session.c 98797aba475a799376c9a42214f2d1debf2d0c3cb657d9c8bbf4f70bf3fb4aec
|
||||
F ext/userauth/sqlite3userauth.h 7f3ea8c4686db8e40b0a0e7a8e0b00fac13aa7a3
|
||||
@@ -453,7 +454,7 @@ F ext/userauth/userauth.c 7f00cded7dcaa5d47f54539b290a43d2e59f4b1eb5f447545fa865
|
||||
F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x
|
||||
F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8
|
||||
F magic.txt 8273bf49ba3b0c8559cb2774495390c31fd61c60
|
||||
F main.mk 7ce055f3df31a4f7d21e38f493f907c21db1f673863a573e231f55e2ab005023
|
||||
F main.mk f3a972451ed68fa1101d81606a2a1b0a2600b85547059fe89ccb2380b983e50c
|
||||
F mkso.sh fd21c06b063bb16a5d25deea1752c2da6ac3ed83
|
||||
F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271
|
||||
F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504
|
||||
@@ -465,38 +466,38 @@ F spec.template 86a4a43b99ebb3e75e6b9a735d5fd293a24e90ca
|
||||
F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b
|
||||
F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786
|
||||
F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a
|
||||
F src/alter.c f48a4423c8f198d7f1ae4940f74b606707d05384ac79fb219be8e3323af2a2de
|
||||
F src/analyze.c b3ceec3fc052df8a96ca8a8c858d455dc5029ba681b4be98bb5c5a9162cfa58c
|
||||
F src/attach.c fee2f4279474edad2df73f38ff17d8b6b250429c6e9b59a708fb48a090f3ad32
|
||||
F src/alter.c fa2c3be9b0ebecfafb7062072a0ae6eda126d3e5a9fd51b2eded5acd95dc783c
|
||||
F src/analyze.c 831bb090988477a00d3b4c000746e1b0454dcc93b10b793e6ebe1c47f25d193a
|
||||
F src/attach.c ff2daea0fe62080192e3f262670e4f61f5a86c1e7bea9cec34e960fe79852aa1
|
||||
F src/auth.c a3d5bfdba83d25abed1013a8c7a5f204e2e29b0c25242a56bc02bb0c07bf1e06
|
||||
F src/backup.c 5e617c087f1c2d6005c2ec694ce80d6e16bc68d906e1b1c556d7c7c2228b636b
|
||||
F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33
|
||||
F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6
|
||||
F src/btree.c 4dfab5862184da86103795ee2a31a22d2bbf9d8cf183bd3e05f3e32267c0855f
|
||||
F src/btree.h 6111552f19ed7a40f029cf4b33badc6fef9880314fffd80a945f0b7f43ab7471
|
||||
F src/btreeInt.h dee1a1d0c621524e006bb260bd6b66d5d1867da6fe38cba9ad7b6a9bb9c0c175
|
||||
F src/build.c 2394d2c853088106dfc1cf485d609f20e6421d7c84892b795824e454f78e50ad
|
||||
F src/callback.c c547d00963ae28100117b4fb1f0f32242109b5804374ee3bfe01138a54da7f76
|
||||
F src/btree.c 97673c54a3023845e7320cfa9e0de67fd6ca34b37a17a420981bb6e767601310
|
||||
F src/btree.h 32672fa1aa74a7e9ab3aae822f94ffc8e732b1eb005988dc2283f91dc7573398
|
||||
F src/btreeInt.h 887cdd2ea7f4a65143074a8a7c8928b0546f8c18dda3c06a408ce7992cbab0c0
|
||||
F src/build.c ec6c0bda1e43ef55e5f5121a77ba19fac51fc6585f95ce2da795bcedcf6e8f36
|
||||
F src/callback.c d0b853dd413255d2e337b34545e54d888ea02f20da5ad0e63585b389624c4a6c
|
||||
F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e
|
||||
F src/ctime.c 6a77ec9e0eb87aea929e002c816298907e337094a7b556898ae2d1e6be209f90
|
||||
F src/date.c 6c408fdd2e9ddf6e8431aba76315a2d061bea2cec8fbb75e25d7c1ba08274712
|
||||
F src/date.c b29b349d277e3d579dcc295b24c0a2caed83fd8f090a9f7cbe6070c0fd662384
|
||||
F src/dbpage.c 8a01e865bf8bc6d7b1844b4314443a6436c07c3efe1d488ed89e81719047833a
|
||||
F src/dbstat.c 0f55297469d4244ab7df395849e1af98eb5e95816af7c661e7d2d8402dea23da
|
||||
F src/dbstat.c 793deaf88a0904f88285d93d6713c636d55ede0ffd9f08d10f4ea825531d367f
|
||||
F src/delete.c 11000121c4281c0bce4e41db29addfaea0038eaa127ece02557c9207bc3e541d
|
||||
F src/expr.c 4b25db7f9472b3532560242193bc4eefaefc7720dc4f2d7ec9a89ada410c6ea2
|
||||
F src/expr.c b292bdecd64cd695109ceaa3c810f8b41f202368c75adb9ea680a875df5b0308
|
||||
F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007
|
||||
F src/fkey.c 4b575423b0a5d4898b1a7868ce985cf1a8ad91c741c9abbb108ff02536d20f41
|
||||
F src/func.c 108577cebe8a50c86d849a93b99493a54e348dd0b846f00d13b52ca973d5baf4
|
||||
F src/func.c f3dcdc0e95509864767c1f0991b19360f969e44177f4e058fd51da9a6154f47e
|
||||
F src/global.c 79a988b56b06ce2d08ebefe1d35da9aa25b3851faa47ea5233361c4827185a64
|
||||
F src/hash.c 8d7dda241d0ebdafb6ffdeda3149a412d7df75102cecfc1021c98d6219823b19
|
||||
F src/hash.h 9d56a9079d523b648774c1784b74b89bd93fac7b365210157482e4319a468f38
|
||||
F src/hwtime.h cb1d7e3e1ed94b7aa6fde95ae2c2daccc3df826be26fc9ed7fd90d1750ae6144
|
||||
F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71
|
||||
F src/insert.c 9b487eb4b756a2bab16fa5ba19d207375551f7d0b8da3f4dff769f3035dc6bab
|
||||
F src/insert.c 8e4211d04eb460c0694d486c6ba1c068d468c6f653c3f237869a802ad82854de
|
||||
F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa
|
||||
F src/loadext.c b179df50e6e8bb0c36c149e95d958d49bd8c6c7469e59c01b53d164360bc6c32
|
||||
F src/main.c 42577fa09d195dd0f09d4a3d95158ff7f4a677dc83ccb0d6d7e73ff86c2dc6f1
|
||||
F src/malloc.c eaa4dc9602ce28b077f7de2eb275db2be270c5cc56d7fec5466301bd9b80e2f5
|
||||
F src/loadext.c 4540fb20e8606b5cea7efee1d727cc69b20390ddc2e6a6c5515e20f96dcc205c
|
||||
F src/main.c 652a782cd7b6c6ddf7419fcaf06b8aa9440b7c815857241171c9bdf03ab6544c
|
||||
F src/malloc.c cabfef0d725e04c8abfe0231a556ed8b78bf329dcc3fddbf903f6cdcd53cf4e6
|
||||
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
|
||||
F src/mem1.c c12a42539b1ba105e3707d0e628ad70e611040d8f5e38cf942cee30c867083de
|
||||
F src/mem2.c f1940d9e91948dd6a908fbb9ce3835c36b5d83c3
|
||||
@@ -515,28 +516,28 @@ F src/os.c 669cc3839cc35d20f81faf0be1ab6d4581cea35e9d8f3a9d48a98d6571f7c285
|
||||
F src/os.h 48388821692e87da174ea198bf96b1b2d9d83be5dfc908f673ee21fafbe0d432
|
||||
F src/os_common.h b2f4707a603e36811d9b1a13278bffd757857b85
|
||||
F src/os_setup.h 0dbaea40a7d36bf311613d31342e0b99e2536586
|
||||
F src/os_unix.c 238ad16109b4160d0fba2597ef71459995ab5e304b3d8bbe290a8d5d6d6000e0
|
||||
F src/os_unix.c 7ef8b60222558a373d89c18d0c3bc44365b45273a528183d40bec5bb76ce23fc
|
||||
F src/os_win.c 035a813cbd17f355bdcad7ab894af214a9c13a1db8aeac902365350b98cd45a7
|
||||
F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a
|
||||
F src/pager.c f1c92d05440f0f6826430b56e29addf453785f5c5651b8510d17d6310ba5df04
|
||||
F src/pager.c 29ee0618daa1f49c24431a9f21b7ac15fa148eb63626c9e0ac145fffbe0b209d
|
||||
F src/pager.h 3b33619a90180e0874c7eca31d6f6ceb464d9322c6fb4e9a7bbb318c8a17bdb3
|
||||
F src/parse.y 61ae75b1764c86f56fdfe384d736e4ba9b0d54015a5ca61925d8cb6b94943d4c
|
||||
F src/parse.y c8eff38606f443d5ba245263fa7abc05e4116d95656e050c4b78e9bfbf931add
|
||||
F src/pcache.c 385ff064bca69789d199a98e2169445dc16e4291fa807babd61d4890c3b34177
|
||||
F src/pcache.h 4f87acd914cef5016fae3030343540d75f5b85a1877eed1a2a19b9f284248586
|
||||
F src/pcache1.c 6596e10baf3d8f84cc1585d226cf1ab26564a5f5caf85a15757a281ff977d51a
|
||||
F src/pragma.c 4c8f3665cb3e1b114d22319f944a0c73c9563869c1f01a322732a880a7a2f82a
|
||||
F src/pragma.c 5fd004b89c77319008ddff6d65dcc83ccca9584d3048f4f66b108b5906a20dba
|
||||
F src/pragma.h 9473160d220416456b40f27323bb4b316d4e4e08ffbf8bf88c5f7045d49c38e5
|
||||
F src/prepare.c 6049beb71385f017af6fc320d2c75a4e50b75e280c54232442b785fbb83df057
|
||||
F src/prepare.c 8d4d6c8aa6afefc48027c54b41cdf134b4d6bc2fc4badbe483ad7fd9e1728a28
|
||||
F src/printf.c 9be6945837c839ba57837b4bc3af349eba630920fa5532aa518816defe42a7d4
|
||||
F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384
|
||||
F src/resolve.c 38e3a5636f5bdc92e3683e4cafbba6418c0aa15e0d89ca5b28bd0b621dbb80bf
|
||||
F src/rowset.c d977b011993aaea002cab3e0bb2ce50cf346000dff94e944d547b989f4b1fe93
|
||||
F src/select.c 466f57380528f1d7deeef87a3af09e0ad806fa2eef5e97384ec9376727fdd847
|
||||
F src/shell.c.in c2e20c43a44fb5588a6c27ce60589538fbf4794fd7686f5b2598eca22eaae1fa
|
||||
F src/sqlite.h.in 802957feeb249ede54f8dfe99b72aa19e70a0b7737969c46e625dc2f9f2d42b0
|
||||
F src/resolve.c d36a2b1639e1c33d7b508abfd3452a63e7fd81737f6f3940bfef085fca6f21f4
|
||||
F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92
|
||||
F src/select.c ab4eb1aee1bd066feea5b6eff264220ae54459019654264e9f688368a7d0c0b5
|
||||
F src/shell.c.in 5402d3a7281576c96d788569778483746859c5e47052facfc4a4ccfac025d5da
|
||||
F src/sqlite.h.in fd6fcfe173accab8d9cb9a843856d9e9fb475f893b60a455e01d8739b5076f0e
|
||||
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
|
||||
F src/sqlite3ext.h 9c5269260409eb3275324ccace6a13a96f4ad330c708415f70ca6097901ff4ee
|
||||
F src/sqliteInt.h d736043dc6291d3af289d911237da0801b6c05be086ae322eedd47a089ae8d2f
|
||||
F src/sqlite3ext.h 2d1af80082edffd71c6f96f70ad1ce6a4fb46615ad10291fc77fe0dea9ff0197
|
||||
F src/sqliteInt.h 0f3848c46310d197246003f052985b72d1cdbfc0b31e069db76cb5231062fa1d
|
||||
F src/sqliteLimit.h 95cb8479ca459496d9c1c6a9f76b38aee12203a56ce1092fe13e50ae2454c032
|
||||
F src/status.c 9ff2210207c6c3b4d9631a8241a7d45ab1b26a0e9c84cb07a9b5ce2de9a3b278
|
||||
F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34
|
||||
@@ -595,33 +596,33 @@ F src/test_windirent.h 90dfbe95442c9762357fe128dc7ae3dc199d006de93eb33ba3972e0a9
|
||||
F src/test_window.c cdae419fdcea5bad6dcd9368c685abdad6deb59e9fc8b84b153de513d394ba3f
|
||||
F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9
|
||||
F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c
|
||||
F src/tokenize.c 7b17f6e2f20f6cbcb0b215025a86b7457c38451fc7622f705e553d7a488c572d
|
||||
F src/treeview.c 438c1000587b33faba35e87596bebcf7f40638d98f33781cdd9e04711b18b09c
|
||||
F src/trigger.c a40d50e88bd3355f1d2a73f0a3b2d6b42eae26ca4219001b82ef0d064439badc
|
||||
F src/tokenize.c eee7bae3ec0bc4abee951554bf46a8ba567c0f7752ac90c820ed8afff4c612dc
|
||||
F src/treeview.c 82c6391a3ba76215d4185fd4719a56ec4caf186a40c8a7b6e6ba4ae4467c2742
|
||||
F src/trigger.c 4ada1037cc99777f647a882cdacbd1a4deb6567b69daf02946286401b88cdc04
|
||||
F src/update.c 3eb778c42155d944377a4ee5e440b04520f07094804ed6ce63d2528f619614d9
|
||||
F src/upsert.c 2920de71b20f04fe25eb00b655d086f0ba60ea133c59d7fa3325c49838818e78
|
||||
F src/utf.c 95fb6e03a5ca679045c5adccd05380f0addccabef5911abddcb06af069500ab7
|
||||
F src/util.c a285c1e026907b69fa2592bd05047a565a1d8a1aef2b73c924b6a8ffe772871a
|
||||
F src/vacuum.c 813b510ba887fee6492bcb11f2bf77d7eb58b232b83649136372e0a2fc17f4b9
|
||||
F src/vdbe.c 15cae95de3c1301747f7ee17a70046772741e7e630b6d5554c685b613798b8e8
|
||||
F src/util.c 3b6cedf7a0c69bd6e1acce832873952d416212d6293b18d03064e07d7a9b5118
|
||||
F src/vacuum.c f25d3b39681595e321a8a4e7fca3e5971cb14a401213d0742c9bf7d4ce8c2a1a
|
||||
F src/vdbe.c 972999395eee88702091fb5d50cf4effd07889c371807d222a7f517388e6378e
|
||||
F src/vdbe.h 51282fbe819ee0e8eeeaab176240860d334c20a12b14f3b363e7f1a4e05d60b9
|
||||
F src/vdbeInt.h a17146053a1aa438474012998fe07e314f3df274a61491ad838ad85d848ac051
|
||||
F src/vdbeapi.c 1252d80c548711e47a6d84dae88ed4e95d3fbb4e7bd0eaa1347299af7efddf02
|
||||
F src/vdbeaux.c 2d8d863e6b85a5b4362a248c04d82f0df8df79be289b2fc75b488c3cd79ddb5f
|
||||
F src/vdbeInt.h 0b728ee662862a38b1912af741e2ac64f524de3c77aa86cf4306c42bdcd9de59
|
||||
F src/vdbeapi.c d176ee7251d5344de7bb2a0d2dd0fe536834e5843d9bc2389e0f5cdcd5374141
|
||||
F src/vdbeaux.c 8349559e72bf0cfa2258b1159b004ec4d1717a054d2e1829c8cc897c32da8752
|
||||
F src/vdbeblob.c 253ed82894924c362a7fa3079551d3554cd1cdace39aa833da77d3bc67e7c1b1
|
||||
F src/vdbemem.c ff2a1fd86ea943efb7174bd74bc661815c449be6165e136e8849e1dc59e24353
|
||||
F src/vdbemem.c 39b942ecca179f4f30a32b54579a85d74ccaefa5af2a0ad2700abe5ef0768b22
|
||||
F src/vdbesort.c 2be76d26998ce2b3324cdcc9f6443728e54b6c7677c553ad909c7d7cfab587df
|
||||
F src/vdbetrace.c fa3bf238002f0bbbdfb66cc8afb0cea284ff9f148d6439bc1f6f2b4c3b7143f0
|
||||
F src/vtab.c 7b704a90515a239c6cdba6a66b1bb3a385e62326cceb5ecb05ec7a091d6b8515
|
||||
F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9
|
||||
F src/wal.c 697424314e40d99f93f548c7bfa526c10e87f4bdf64d5a76a96b999dd7133ebc
|
||||
F src/wal.c ea8dad28bb0e2b85ac1ab7618968687ff5fd522af8a1a38d6960ec176ebc8ee6
|
||||
F src/wal.h 606292549f5a7be50b6227bd685fa76e3a4affad71bb8ac5ce4cb5c79f6a176a
|
||||
F src/walker.c a137468bf36c92e64d2275caa80c83902e3a0fc59273591b96c6416d3253d05d
|
||||
F src/where.c 3b8c9bd013eb0736e16f60bdc109e83337ef99513a3aff5f16ddac036e6c277e
|
||||
F src/walker.c 7c429c694abd12413a5c17aec9f47cfe9eba6807e6b0a32df883e8e3a14835ed
|
||||
F src/where.c 9546c82056e8cdb27291f98cf1adca5d271240b399bb97b32f77fc2bea6146c9
|
||||
F src/whereInt.h 6b874aa15f94e43a2cec1080be64d955b04deeafeac90ffb5d6975c0d511be3c
|
||||
F src/wherecode.c f5df56e395ade2240cabb2d39500c681bd29f8cc0636c3301c4996ad160df94d
|
||||
F src/wherecode.c 7b939de85d65cc4b4bfa197513136b9e0ae03167e3b82842ca5a0ba1055ba65d
|
||||
F src/whereexpr.c 264d58971eaf8256eb5b0917bcd7fc7a1f1109fdda183a8382308a1b18a2dce7
|
||||
F src/window.c f8ba2ee12a19b51d3ba42c16277c74185ee9215306bc0d5a03974ade8b5bc98f
|
||||
F src/window.c ba1ffb78d73c5831433681aab7ee634230ee32f14ad508efa585044662141d5a
|
||||
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
|
||||
F test/affinity2.test ce1aafc86e110685b324e9a763eab4f2a73f737842ec3b687bd965867de90627
|
||||
F test/affinity3.test 6a101af2fc945ce2912f6fe54dd646018551710d
|
||||
@@ -639,7 +640,7 @@ F test/altercol.test 1d6a6fe698b81e626baea4881f5717f9bc53d7d07f1cd23ee7ad1b931f1
|
||||
F test/alterlegacy.test 82022721ce0de29cedc9a7af63bc9fcc078b0ee000f8283b4b6ea9c3eab2f44b
|
||||
F test/altermalloc.test 167a47de41b5c638f5f5c6efb59784002b196fff70f98d9b4ed3cd74a3fb80c9
|
||||
F test/altermalloc2.test fa7b1c1139ea39b8dec407cf1feb032ca8e0076bd429574969b619175ad0174b
|
||||
F test/altertab.test 89735fee876427c3f25dc76d887295fbe3659a91bab92468de9f0e622d48bb57
|
||||
F test/altertab.test 523ba6368e0da19f462f7c05563c569675736d946724cac1c4ae848f76783434
|
||||
F test/altertab2.test b0d62f323ca5dab42b0bc028c52e310ebdd13e655e8fac070fe622bad7852c2b
|
||||
F test/altertab3.test 155b8dc225ce484454a7fb4c8ba745680b6fa0fc3e08919cbbc19f9309d128ff
|
||||
F test/amatch1.test b5ae7065f042b7f4c1c922933f4700add50cdb9f
|
||||
@@ -666,7 +667,7 @@ F test/atof1.test 1ccfc96a6888566597b83d882c81b3c04258dc39317e8c1cec89ba481eaa2f
|
||||
F test/atomic.test 065a453dde33c77ff586d91ccaa6ed419829d492dbb1a5694b8a09f3f9d7d061
|
||||
F test/atomic2.test b6863b4aa552543874f80b42fb3063f1c8c2e3d8e56b6562f00a3cc347b5c1da
|
||||
F test/atrc.c ec92d56d8fbed9eb3e11aaf1ab98cf7dd59e69dae31f128013f1d97e54e7dfed
|
||||
F test/attach.test 21bce8681f780a8d631a5ec7ecd0d849bfe84611257b038ae4ffeccc609d8a4e
|
||||
F test/attach.test d42862c72fef3d54367d962d41dcfb5363442a4a1bd898c22ae950cea1aa0dd3
|
||||
F test/attach2.test 256bd240da1835fb8408dd59fb7ef71f8358c7a756c46662434d11d07ba3a0ce
|
||||
F test/attach3.test c59d92791070c59272e00183b7353eeb94915976
|
||||
F test/attach4.test aa05b1d8218b24eba5a7cccf4f224f514ba57ba705c9267f09d2bb63fed0eea1
|
||||
@@ -794,7 +795,7 @@ F test/crash8.test 64366e459c28dd62edfb7ad87253a409c7533b92d16fcc479a6a8131bdcc3
|
||||
F test/crashM.test d95f59046fa749b0d0822edf18a717788c8f318d
|
||||
F test/crashtest1.c 09c1c7d728ccf4feb9e481671e29dda5669bbcc2
|
||||
F test/createtab.test 85cdfdae5c3de331cd888d6c66e1aba575b47c2e3c3cc4a1d6f54140699f5165
|
||||
F test/cse.test 277350a26264495e86b1785f34d2d0c8600e021c
|
||||
F test/cse.test 00b3aea44b16828833c94fbe92475fd6977583fcb064ae0bc590986812b38d0c
|
||||
F test/csv01.test c9c3af0d58c34e9ac970c5875a77939edb958762c8aafb95409e19a3f088b6cd
|
||||
F test/ctime.test 78749e6c9a5f0010d67985be80788f841e3cd2da18114e2ed6010399a7d807f3
|
||||
F test/cursorhint.test 7bc346788390475e77a345da2b92270d04d35856
|
||||
@@ -810,7 +811,7 @@ F test/dbfuzz2.c c2c9cb40082a77b7e95ffb8b2da1e93322efadfb1c8c1e0001c95a0af1e156c
|
||||
F test/dbpage.test 650234ba683b9d82b899c6c51439819787e7609f17a0cc40e0080a7b6443bc38
|
||||
F test/dbstatus.test 4a4221a883025ffd39696b3d1b3910b928fb097d77e671351acb35f3aed42759
|
||||
F test/dbstatus2.test f5fe0afed3fa45e57cfa70d1147606c20d2ba23feac78e9a172f2fe8ab5b78ef
|
||||
F test/default.test 3e46c421eebefd2787c2f96673efabf792d360f3a1d5073918cbe450ce672a62
|
||||
F test/default.test 9687cfb16717e4b8238c191697c98be88c0b16e568dd5368cd9284154097ef50
|
||||
F test/delete.test 31832b0c45ecb51a54348c68db173be462985901e6ed7f403d6d7a8f70ab4ef0
|
||||
F test/delete2.test 3a03f2cca1f9a67ec469915cb8babd6485db43fa
|
||||
F test/delete3.test 555e84a00a99230b7d049d477a324a631126a6ab
|
||||
@@ -828,10 +829,10 @@ F test/e_blobclose.test 4b3c8c60c2171164d472059c73e9f3c1844bb66d
|
||||
F test/e_blobopen.test e95e1d40f995056f6f322cd5e1a1b83a27e1a145
|
||||
F test/e_blobwrite.test f87ff598b67af5b3ec002a8d83e804dc8d23808e88cf0080c176612fc9ffce14
|
||||
F test/e_changes.test fd66105385153dbf21fdb35eb8ef6c3e1eade579
|
||||
F test/e_createtable.test 1c602347e73ab80b11b9fa083f47155861aaafcff8054aac9e0b76d0df33b0a7
|
||||
F test/e_createtable.test ea27082d6f84df61e1d9e383f3fd79220418856a4a8afc41af75d458b8e7ac33
|
||||
F test/e_delete.test ab39084f26ae1f033c940b70ebdbbd523dc4962e
|
||||
F test/e_droptrigger.test 3cd080807622c13e5bbb61fc9a57bd7754da2412
|
||||
F test/e_dropview.test 21ce09c361227ddbc9819a5608ee2700c276bdd5
|
||||
F test/e_dropview.test 74e405df7fa0f762e0c9445b166fe03955856532e2bb234c372f7c51228d75e7
|
||||
F test/e_expr.test 328d2d7c84f8e53e942a13eac771b337bcdfcf4c3569324001868b5639f3c857
|
||||
F test/e_fkey.test 2febb2084aef9b0186782421c07bc9d377abf067c9cb4efd49d9647ae31f5afe
|
||||
F test/e_fts3.test 17ba7c373aba4d4f5696ba147ee23fd1a1ef70782af050e03e262ca187c5ee07
|
||||
@@ -849,7 +850,7 @@ F test/e_walauto.test 248af31e73c98df23476a22bdb815524c9dc3ba8
|
||||
F test/e_walckpt.test 28c371a6bb5e5fe7f31679c1df1763a19d19e8a0
|
||||
F test/e_walhook.test 01b494287ba9e60b70f6ebf3c6c62e0ffe01788e344a4846b08e5de0b344cb66
|
||||
F test/emptytable.test a38110becbdfa6325cd65cb588dca658cd885f62
|
||||
F test/enc.test e54531cd6bf941ee6760be041dff19a104c7acea
|
||||
F test/enc.test 9a7be5479da985381d740b15f432800f65e2c87029ee57a318f42cb2eb43763a
|
||||
F test/enc2.test 848bf05f15b011719f478dddb7b5e9aea35e39e457493cba4c4eef75d849a5ec
|
||||
F test/enc3.test 6807f7a7740a00361ca8d0ccd66bc60c8dc5f2b6
|
||||
F test/enc4.test c8f1ce3618508fd0909945beb8b8831feef2c020
|
||||
@@ -942,10 +943,10 @@ F test/fts3b.test c15c4a9d04e210d0be67e54ce6a87b927168fbf9c1e3faec8c1a732c366fd4
|
||||
F test/fts3c.test fc723a9cf10b397fdfc2b32e73c53c8b1ec02958
|
||||
F test/fts3comp1.test a0f5b16a2df44dd0b15751787130af2183167c0c
|
||||
F test/fts3conf.test c84bbaec81281c1788aa545ac6e78a6bd6cde2bdbbce2da261690e3659f5a76b
|
||||
F test/fts3corrupt.test ce7f7b5eaeee5f1804584d061b978d85e64abf2af9adaa7577589fac6f7eae01
|
||||
F test/fts3corrupt.test 79a32ffdcd5254e2f7fa121d9656e61949ad049c3c6554229911b7ceac37c9c6
|
||||
F test/fts3corrupt2.test bf55c3fa0b0dc8ea1c0fe5543623bd27714585da6a129038fd6999fe3b0d25f3
|
||||
F test/fts3corrupt3.test 0d5b69a0998b4adf868cc301fc78f3d0707745f1d984ce044c205cdb764b491f
|
||||
F test/fts3corrupt4.test e8ad49403179cbf714b6b669d2e0f9234ae95f4ca258a253b0f29ce28c1b027c
|
||||
F test/fts3corrupt4.test 6a1331bb51dc27acc063d26e0f1b610863b56a833ee54fa32767d17cf96bda4a
|
||||
F test/fts3corrupt5.test 0549f85ec4bd22e992f645f13c59b99d652f2f5e643dac75568bfd23a6db7ed5
|
||||
F test/fts3cov.test 7eacdbefd756cfa4dc2241974e3db2834e9b372ca215880e00032222f32194cf
|
||||
F test/fts3d.test 2bd8c97bcb9975f2334147173b4872505b6a41359a4f9068960a36afe07a679f
|
||||
@@ -966,7 +967,7 @@ F test/fts3fuzz001.test e3c7b0ce9b04cc02281dcc96812a277f02df03cd7dc082055d87e11e
|
||||
F test/fts3join.test 949b4f5ae3ae9cc2423cb865d711e32476bdb205ab2be923fdf48246e4a44166
|
||||
F test/fts3malloc.test b0e4c133b8d61d4f6d112d8110f8320e9e453ef6
|
||||
F test/fts3matchinfo.test aa66cc50615578b30f6df9984819ae5b702511cf8a94251ec7c594096a703a4a
|
||||
F test/fts3misc.test c47d2c1ea1351c51c32c688545b02c8180a3f22156d1aedc206a8c09b9d95905
|
||||
F test/fts3misc.test 236f37a57d97fa1b7e0a4303aab7e02da87a9818c106e513ae88af76f25ace4a
|
||||
F test/fts3near.test 7e3354d46f155a822b59c0e957fd2a70c1d7e905
|
||||
F test/fts3offsets.test b85fd382abdc78ebce721d8117bd552dfb75094c
|
||||
F test/fts3prefix.test fa794eaab0bdae466494947b0b153d7844478ab2
|
||||
@@ -980,7 +981,7 @@ F test/fts3sort.test ed34c716a11cc2009a35210e84ad5f9c102362ca
|
||||
F test/fts3tok1.test a663f4cac22a9505400bc22aacb818d7055240409c28729669ea7d4cc2120d15
|
||||
F test/fts3tok_err.test 52273cd193b9036282f7bacb43da78c6be87418d
|
||||
F test/fts3varint.test 0b84a3fd4eba8a39f3687523804d18f3b322e6d4539a55bf342079c3614f2ada
|
||||
F test/fts4aa.test 9857f939f5aeb6cc4c143e74cf1cfe07ac87972240ac26d3a0100e36d02f4359
|
||||
F test/fts4aa.test 0e6bfd6a81695a39b23e448dda25d864e63dda75bde6949c45ddc95426c6c3f5
|
||||
F test/fts4check.test 6259f856604445d7b684c9b306b2efb6346834c3f50e8fc4a59a2ca6d5319ad0
|
||||
F test/fts4content.test 73bbb123420d2c46ef2fb3b24761e9acdb78b0877179d3a5d7d57aada08066f6
|
||||
F test/fts4docid.test e33c383cfbdff0284685604d256f347a18fdbf01
|
||||
@@ -994,6 +995,7 @@ F test/fts4merge2.test 5faa558d1b672f82b847d2a337465fa745e46891
|
||||
F test/fts4merge3.test 8d9ccb4a3d41c4c617a149d6c4b13ad02de797d0
|
||||
F test/fts4merge4.test d895b1057a7798b67e03455d0fa50e9ea836c47b
|
||||
F test/fts4merge5.test 69932d85cda8a1c4dcfb742865900ed8fbda51724b8cf9a45bbe226dfd06c596
|
||||
F test/fts4min.test 1c11e4bde16674a0c795953509cbc3731a7d9cbd1ddc7f35467bf39d632d749f
|
||||
F test/fts4noti.test 5553d7bb2e20bf4a06b23e849352efc022ce6309
|
||||
F test/fts4onepass.test d69ddc4ee3415e40b0c5d1d0408488a87614d4f63ba9c44f3e52db541d6b7cc7
|
||||
F test/fts4opt.test 0fd0cc84000743ff2a883b9b84b4a5be07249f0ba790c8848a757164cdd46b2a
|
||||
@@ -1002,11 +1004,11 @@ F test/fts4rename.test 15fd9985c2bce6dea20da2245b22029ec89bd4710ed317c4c53abbe3c
|
||||
F test/fts4umlaut.test fcaca4471de7e78c9d1f7e8976e3e8704d7d8ad979d57a739d00f3f757380429
|
||||
F test/fts4unicode.test ceca76422abc251818cb25dabe33d3c3970da5f7c90e1540f190824e6b3a7c95
|
||||
F test/full.test 6b3c8fb43c6beab6b95438c1675374b95fab245d
|
||||
F test/func.test b7f1a706d1bb8de103a24bd0c30c9e3dc3eedf0df24aabc54b0a4f6e08742622
|
||||
F test/func.test f673822636fb8ed618dd2b80230d16e495d19c8f2e2e7d6c22e93e2b3de097ad
|
||||
F test/func2.test 772d66227e4e6684b86053302e2d74a2500e1e0f
|
||||
F test/func3.test 2bb0f31ab7baaed690b962a88544d7be6b34fa389364bc36a44e441ed3e3f1e6
|
||||
F test/func4.test a94858a8c1f10a408b0b3db439c990b59dbb2349411d503de011ac4e2b5f27a6
|
||||
F test/func5.test cdd224400bc3e48d891827cc913a57051a426fa4
|
||||
F test/func5.test 863e6d1bd0013d09c17236f8a13ea34008dd857d87d85a13a673960e4c25d82a
|
||||
F test/func6.test 90e42b64c4f9fb6f04f44cb8a1da586c8542502e926b19c76504fe74ff2a9b7c
|
||||
F test/fuzz-oss1.test e58330d01cbbd8215ee636b17a03fe220b37dbfa
|
||||
F test/fuzz.test 96083052bf5765e4518c1ba686ce2bab785670d1
|
||||
@@ -1015,7 +1017,7 @@ F test/fuzz3.test 9c813e6613b837cb7a277b0383cd66bfa07042b4cf0317157c35852f30043c
|
||||
F test/fuzz4.test c229bcdb45518a89e1d208a21343e061503460ac69fae1539320a89f572eb634
|
||||
F test/fuzz_common.tcl b7197de6ed1ee8250a4f82d67876f4561b42ee8cbbfc6160dcb66331bad3f830
|
||||
F test/fuzz_malloc.test f348276e732e814802e39f042b1f6da6362a610af73a528d8f76898fde6b22f2
|
||||
F test/fuzzcheck.c a9746aa49843827f960bc875cc70e04b0cfcd3e10e6676e3abc402ad190e165f
|
||||
F test/fuzzcheck.c 656ee850f331872a784e7d6a10649efe2af123bdaacb728b5a03e4faee8b959c
|
||||
F test/fuzzdata1.db d36e88741b4f23bcbaaf55b006290669d03c6c891cf13c7b3a53bc1b097b693f
|
||||
F test/fuzzdata2.db 128b3feeb78918d075c9b14b48610145a0dd4c8d6f1ca7c2870c7e425f5bf31f
|
||||
F test/fuzzdata3.db c6586d3e3cef0fbc18108f9bb649aa77bfc38aba
|
||||
@@ -1023,7 +1025,7 @@ F test/fuzzdata4.db b502c7d5498261715812dd8b3c2005bad08b3a26e6489414bd13926cd3e4
|
||||
F test/fuzzdata5.db e35f64af17ec48926481cfaf3b3855e436bd40d1cfe2d59a9474cb4b748a52a5
|
||||
F test/fuzzdata6.db 92a80e4afc172c24f662a10a612d188fb272de4a9bd19e017927c95f737de6d7
|
||||
F test/fuzzdata7.db 0166b56fd7a6b9636a1d60ef0a060f86ddaecf99400a666bb6e5bbd7199ad1f2
|
||||
F test/fuzzdata8.db 8bd41f8e1b9c61af011bf5cf16a85fb7f718fdd3348e476b78ba36adab872653
|
||||
F test/fuzzdata8.db fb701c5653f0a75a58e2ee0f8baf5b207faa7702dda88c913ebbe2abb3b33de3
|
||||
F test/fuzzer1.test 3d4c4b7e547aba5e5511a2991e3e3d07166cfbb8
|
||||
F test/fuzzer2.test a85ef814ce071293bce1ad8dffa217cbbaad4c14
|
||||
F test/fuzzerfault.test 8792cd77fd5bce765b05d0c8e01b9edcf8af8536
|
||||
@@ -1035,7 +1037,7 @@ F test/hexlit.test 4a6a5f46e3c65c4bf1fa06f5dd5a9507a5627751
|
||||
F test/hidden.test 23c1393a79e846d68fd902d72c85d5e5dcf98711
|
||||
F test/hook.test 1604b3b2f5931430087540404555c1b6be3618600b81558657c66b533ed70b13
|
||||
F test/hook2.test b9ff3b8c6519fb67f33192f1afe86e7782ee4ac8
|
||||
F test/icu.test 41aa8847745a879b897a7febea0f8f9efc8e67fe8bf680589b6e07c7b0a1569a
|
||||
F test/icu.test 716a6b89fbabe5cc63e0cd4c260befb08fd7b9d761f04d43669233292f0753b1
|
||||
F test/ieee754.test 806fc0ce7f305f57e3331eaceeddcfec9339e607
|
||||
F test/imposter1.test c3f1db2d3db2c24611a6596a3fc0ffc14f1466c8
|
||||
F test/in.test ae4ba0fe3232fdd84ef1090a68c5cd6ccd93f1f8774d5c967dd0c1b301492eed
|
||||
@@ -1043,7 +1045,7 @@ F test/in2.test 5d4c61d17493c832f7d2d32bef785119e87bde75
|
||||
F test/in3.test 3cbf58c87f4052cee3a58b37b6389777505aa0c0
|
||||
F test/in4.test 65460600d48933adba4283c6ebd089aae173d16136ab9d01f74c89089090c5a5
|
||||
F test/in5.test b32ce7f4a93f44c5dee94af16886d922cc16ebe33c8e1765c73d4049d0f4b40f
|
||||
F test/in6.test 62d943a02f722948f4410ee0b53c3cb39acd7c41afb083df8d7004238fe90a20
|
||||
F test/in6.test 8562d0945195cab3cc4ab3794e9118e72cb44c43f785c2b04d48a9d06ca6b4ec
|
||||
F test/incrblob.test c9b96afc292aeff43d6687bcb09b0280aa599822
|
||||
F test/incrblob2.test a494c9e848560039a23974b9119cfc2cf3ad3bd15cc2694ee6367ae537ef8f1f
|
||||
F test/incrblob3.test d8d036fde015d4a159cd3cbae9d29003b37227a4
|
||||
@@ -1112,9 +1114,9 @@ F test/kvtest.c 94da54bb66aae7a54e47cf7e4ea4acecc0f217560f79ad3abfcc0361d6d557ba
|
||||
F test/lastinsert.test 42e948fd6442f07d60acbd15d33fb86473e0ef63
|
||||
F test/laststmtchanges.test ae613f53819206b3222771828d024154d51db200
|
||||
F test/lemon-test01.y 58b764610fd934e189ffbb0bbfa33d171b9cb06019b55bdc04d090d6767e11d7
|
||||
F test/like.test 3d702d79bf871fa32985b1ce334294c587e3948d3ab972001e811a58577e8b3c
|
||||
F test/like.test 47b81d5de2ff19d996d49a65d50ec9754246aacbe0e950b48d186d9d8171eaf0
|
||||
F test/like2.test 3b2ee13149ba4a8a60b59756f4e5d345573852da
|
||||
F test/like3.test 4f940ad275c006319950054a7a65661f476772171b82b6fdf795e4dda36f246f
|
||||
F test/like3.test 03d1bdf848483b78d2cfd1db283d75c4ec2e37c8b8eccc006813f3978d78fbbd
|
||||
F test/limit.test 0c99a27a87b14c646a9d583c7c89fd06c352663e
|
||||
F test/limit2.test 9409b033284642a859fafc95f29a5a6a557bd57c1f0d7c3f554bd64ed69df77e
|
||||
F test/loadext.test faa4f6eed07a5aac35d57fdd7bc07f8fc82464cfd327567c10cf0ba3c86cde04
|
||||
@@ -1172,7 +1174,7 @@ F test/misc4.test 10cd6addb2fa9093df4751a1b92b50440175dd5468a6ec84d0386e78f087db
|
||||
F test/misc5.test c4aeaa0fa28faa08f2485309c38db4719e6cd1364215d5687a5b96d340a3fa58
|
||||
F test/misc6.test 953cc693924d88e6117aeba16f46f0bf5abede91
|
||||
F test/misc7.test 4f21954012e4eb0a923c54a311f38c81bf6798ccdd7b51584db46d4007f63daa
|
||||
F test/misc8.test 8fb0f31d7a8aed484d759773ab8ad12ec746a477f4a67394a4af0e677494c3ca
|
||||
F test/misc8.test 8782708f4c8a459591c3e8fe1215bd2048bffb4024b3df249e9b9ed407dc61ed
|
||||
F test/misuse.test 9e7f78402005e833af71dcab32d048003869eca5abcaccc985d4f8dc1d86bcc7
|
||||
F test/mjournal.test 28a08d5cb5fb5b5702a46e19176e45e964e0800d1f894677169e79f34030e152
|
||||
F test/mmap1.test fb04e0c10492455007624ade884ca0c8852ff3e4e11d95408f9709ca2ef7f626
|
||||
@@ -1196,7 +1198,7 @@ F test/notify2.test 2ecabaa1305083856b7c39cf32816b612740c161
|
||||
F test/notify3.test 10ff25cde502e72a92053a2f215d64bece4ef934
|
||||
F test/notnull.test a37b663d5bb728d66fc182016613fb8e4a0a4bbf3d75b8876a7527f7d4ed3f18
|
||||
F test/null.test 0dcce4f04284ec66108c503327ad6d224c0752b3
|
||||
F test/nulls1.test fe4153fd59a3786b4b9f3663a3e65a3aa43a318c7b4d7dcb3f6c3ed5652c9095
|
||||
F test/nulls1.test 82c5bc33148405f21205865abf13c786084438d573a4ac4e87e11b6091cde526
|
||||
F test/numcast.test 5d126f7f581432e86a90d1e35cac625164aec4a1
|
||||
F test/numindex1.test 20a5450d4b056e48cd5db30e659f13347a099823
|
||||
F test/offset1.test f06b83657bcf26f9ce805e67450e189e282143b2
|
||||
@@ -1231,7 +1233,7 @@ F test/parser1.test 6ccdf5e459a5dc4673d3273dc311a7e9742ca952dd0551a6a6320d27035c
|
||||
F test/pcache.test c8acbedd3b6fd0f9a7ca887a83b11d24a007972b
|
||||
F test/pcache2.test af7f3deb1a819f77a6d0d81534e97d1cf62cd442
|
||||
F test/percentile.test 4243af26b8f3f4555abe166f723715a1f74c77ff
|
||||
F test/permutations.test 8587800fe1a0eb01456a3f4500b821e54e3347e78acf11dbf05f4990530f6cee
|
||||
F test/permutations.test c83339862d72b6272f957905205f874e6eefdbad2823380452c4f0128fd3d906
|
||||
F test/pg_common.tcl 222a1bad1c41c308fa366313cd7b51b3be7e9b21c8736a421b974ac941693b54
|
||||
F test/pragma.test 59becdfd720b80d463ab750f69f7118fde10dfd556aa5d554f3bf6b7e5ea7533
|
||||
F test/pragma2.test e5d5c176360c321344249354c0c16aec46214c9f
|
||||
@@ -1302,8 +1304,8 @@ F test/securedel.test 2f70b2449186a1921bd01ec9da407fbfa98c3a7a5521854c300c194b2f
|
||||
F test/securedel2.test 2d54c28e46eb1fd6902089958b20b1b056c6f1c5
|
||||
F test/select1.test 009a6d8eacd9684d046302b8d13b50846a87e39d6f08e92178aa13e95ea29a2d
|
||||
F test/select2.test 352480e0e9c66eda9c3044e412abdf5be0215b56
|
||||
F test/select3.test 3905450067c28766bc83ee397f6d87342de868baa60f2bcfd00f286dfbd62cb9
|
||||
F test/select4.test 5389d9895968d1196c457d59b3ee6515d771d328
|
||||
F test/select3.test ddd1bc6d0c8dece136321c11bd26d0d8ad17f2b27c72935fdd6574d8cb99d1d4
|
||||
F test/select4.test e8a2502e3623f3058871030599a48abb35789d2244d5b380ecf3696873fdd4a4
|
||||
F test/select5.test df9ec0d218cedceb4fe7b63262025b547b50a55e59148c6f40b60ca25f1d4546
|
||||
F test/select6.test 319d45e414cdd321bf17cfacedaf19e3935ad64dac357c53f1492338c6e9b801
|
||||
F test/select7.test f659f231489349e8c5734e610803d7654207318f
|
||||
@@ -1332,11 +1334,11 @@ F test/sharedA.test 49d87ec54ab640fbbc3786ee3c01de94aaa482a3a9f834ad3fe92770eb69
|
||||
F test/sharedB.test 16cc7178e20965d75278f410943109b77b2e645e
|
||||
F test/shared_err.test 32634e404a3317eeb94abc7a099c556a346fdb8fb3858dbe222a4cbb8926a939
|
||||
F test/sharedlock.test 5ede3c37439067c43b0198f580fd374ebf15d304
|
||||
F test/shell1.test 3c9707dce15e8fdca529503378660f099777d3ddcedccf801a37589a405c5942
|
||||
F test/shell1.test 5bd10014ec494744f5e966a1521334e9d612119a0afcfa5251684a4e1f2ffc66
|
||||
F test/shell2.test e242a9912f44f4c23c3d1d802a83e934e84c853b
|
||||
F test/shell3.test ac8c2b744014c3e9a0e26bfd829ab65f00923dc1a91ffd044863e9423cc91494
|
||||
F test/shell4.test 1c6aef11daaa2d6830acaba3ac9cbec93fbc1c3d5530743a637f39b3987d08ce
|
||||
F test/shell5.test 23939a4c51f0421330ea61dbd3c74f9c215f5f8d3d1a94846da6ffc777a35458
|
||||
F test/shell5.test 84a30b55722a95a5b72989e691c469a999ca7591e7aa00b7fabc783ea5c9a6fe
|
||||
F test/shell6.test 1ceb51b2678c472ba6cf1e5da96679ce8347889fe2c3bf93a0e0fa73f00b00d3
|
||||
F test/shell7.test 115132f66d0463417f408562cc2cf534f6bbc6d83a6d50f0072a9eb171bae97f
|
||||
F test/shell8.test 96be02ea0c21f05b24c1883d7b711a1fa8525a68ab7b636aacf6057876941013
|
||||
@@ -1414,7 +1416,7 @@ F test/temptable.test d2c9b87a54147161bcd1822e30c1d1cd891e5b30
|
||||
F test/temptable2.test d2940417496e2b9548e01d09990763fbe88c316504033256d51493e1f1a5ce6a
|
||||
F test/temptable3.test d11a0974e52b347e45ee54ef1923c91ed91e4637
|
||||
F test/temptrigger.test 38f0ca479b1822d3117069e014daabcaacefffcc
|
||||
F test/tester.tcl abba168acd7f01dbfa3ffdbf402d151eb97e8a824d9208e845ab34c194441483
|
||||
F test/tester.tcl fd9d134a7cc4e31b307ad028a195f51cdcf556fc620d74b680515562f0137f25
|
||||
F test/thread001.test b61a29dd87cf669f5f6ac96124a7c97d71b0c80d9012746072055877055cf9ef
|
||||
F test/thread002.test e630504f8a06c00bf8bbe68528774dd96aeb2e58
|
||||
F test/thread003.test ee4c9efc3b86a6a2767516a37bd64251272560a7
|
||||
@@ -1720,20 +1722,20 @@ F test/win32heap.test 10fd891266bd00af68671e702317726375e5407561d859be1aa04696f2
|
||||
F test/win32lock.test fbf107c91d8f5512be5a5b87c4c42ab9fdd54972
|
||||
F test/win32longpath.test 169c75a3b2e43481f4a62122510210c67b08f26d
|
||||
F test/win32nolock.test ac4f08811a562e45a5755e661f45ca85892bdbbc
|
||||
F test/window1.test cec56b9a0a2e7ca4bd63b30590c7b049dce9acfd87478e2597e13b67152bd821
|
||||
F test/window1.test ec792f92e63ee457447c5c04de8f8d42f4a94b842b5bac1f403ac38a6d867c22
|
||||
F test/window2.tcl 492c125fa550cda1dd3555768a2303b3effbeceee215293adf8871efc25f1476
|
||||
F test/window2.test e466a88bd626d66edc3d352d7d7e1d5531e0079b549ba44efb029d1fbff9fd3c
|
||||
F test/window3.tcl acea6e86a4324a210fd608d06741010ca83ded9fde438341cb978c49928faf03
|
||||
F test/window3.test e9959a993c8a71e96433be8daaa1827d78b8921e4f12debd7bdbeb3c856ef3cb
|
||||
F test/window4.tcl d732df0e81beedc0ba8a563ade68611d322d27303ad0c0c8e4444107c39e84ec
|
||||
F test/window4.test 807f3e6b15f9338e5b9742b87c5c7ca825b42b9657fde6096e890119370848e0
|
||||
F test/window4.tcl 6f85307eb67242b654d051f7da32a996a66aee039a09c5ae358541aa61720742
|
||||
F test/window4.test fbead87f681400ac07ef3555e0488b544a47d35491f8bf09a7474b6f76ce9b4e
|
||||
F test/window5.test d328dd18221217c49c144181975eea17339eaeaf0e9aa558cee3afb84652821e
|
||||
F test/window6.test f8d674254b23289cc17c84d79dec7eda7caa1dfb7836c43122cfdf3640d1df32
|
||||
F test/window7.tcl 6a1210f05d40ec89c22960213a22cd3f98d4e2f2eb20646c83c8c30d4d76108f
|
||||
F test/window7.test 1d31276961ae7801edc72173edaf7593e3cbc79c06d1f1f09e20d8418af403cd
|
||||
F test/window8.tcl f2711aa3571e4e6b0dad98db8d95fd6cb8d9db0c92bbdf535f153b07606a1ce2
|
||||
F test/window8.test c4331b27a6f66d69fa8f8bab10cc731db1a81d293ae108a68f7c3487fa94e65b
|
||||
F test/window9.test b63f6f74d730547e63e78946f951f5d1a7d4e99f91f6d5906305469043d92a15
|
||||
F test/window9.test c22c25377c820613e1842fe7ad4af7c03df625f6a7caee99e6fdb4fcd52e0a8b
|
||||
F test/windowA.test 6d63dc1260daa17141a55007600581778523a8b420629f1282d2acfc36af23be
|
||||
F test/windowB.test 7a983ea1cc1cf72be7f378e4b32f6cb2d73014c5cd8b25aaee825164cd4269e5
|
||||
F test/windowerr.tcl f5acd6fbc210d7b5546c0e879d157888455cd4a17a1d3f28f07c1c8a387019e0
|
||||
@@ -1859,7 +1861,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
|
||||
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
|
||||
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
||||
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
||||
P 4a9d3005769e0398183b03a3e132e3946b9d1c48073af2e0559d7beeac3245c0
|
||||
R 2f59a601b560c09f0f628a3935395fd4
|
||||
P ae697b152d22737169892411a0c4d908895ff5fb249cce9bdb1ba0bbe32806f0
|
||||
R cc7f5aa23076777d96573db8bef15752
|
||||
U drh
|
||||
Z 144378d74bf58f80a9e1ca77433de7e1
|
||||
Z 0fbe741b842883ec4b35af5da437ce6d
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
4558163b6a525990f0f1b6629dbb76daf49bcaf1ddbaf0c50fe05ce9ee480ff8
|
||||
3cabe06b6e9433cbfb4bf7bd72a425f43b54f57d84a205adbaa6a1147bbe46bf
|
||||
+19
-1
@@ -469,6 +469,7 @@ void sqlite3AlterBeginAddColumn(Parse *pParse, SrcList *pSrc){
|
||||
for(i=0; i<pNew->nCol; i++){
|
||||
Column *pCol = &pNew->aCol[i];
|
||||
pCol->zName = sqlite3DbStrDup(db, pCol->zName);
|
||||
pCol->hName = sqlite3StrIHash(pCol->zName);
|
||||
pCol->zColl = 0;
|
||||
pCol->pDflt = 0;
|
||||
}
|
||||
@@ -697,7 +698,7 @@ void *sqlite3RenameTokenMap(Parse *pParse, void *pPtr, Token *pToken){
|
||||
RenameToken *pNew;
|
||||
assert( pPtr || pParse->db->mallocFailed );
|
||||
renameTokenCheckAll(pParse, pPtr);
|
||||
if( pParse->eParseMode!=PARSE_MODE_UNMAP ){
|
||||
if( ALWAYS(pParse->eParseMode!=PARSE_MODE_UNMAP) ){
|
||||
pNew = sqlite3DbMallocZero(pParse->db, sizeof(RenameToken));
|
||||
if( pNew ){
|
||||
pNew->p = pPtr;
|
||||
@@ -755,6 +756,21 @@ static void renameWalkWith(Walker *pWalker, Select *pSelect){
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Unmap all tokens in the IdList object passed as the second argument.
|
||||
*/
|
||||
static void unmapColumnIdlistNames(
|
||||
Parse *pParse,
|
||||
IdList *pIdList
|
||||
){
|
||||
if( pIdList ){
|
||||
int ii;
|
||||
for(ii=0; ii<pIdList->nId; ii++){
|
||||
sqlite3RenameTokenRemap(pParse, 0, (void*)pIdList->a[ii].zName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Walker callback used by sqlite3RenameExprUnmap().
|
||||
*/
|
||||
@@ -776,6 +792,7 @@ static int renameUnmapSelectCb(Walker *pWalker, Select *p){
|
||||
for(i=0; i<pSrc->nSrc; i++){
|
||||
sqlite3RenameTokenRemap(pParse, 0, (void*)pSrc->a[i].zName);
|
||||
if( sqlite3WalkExpr(pWalker, pSrc->a[i].pOn) ) return WRC_Abort;
|
||||
unmapColumnIdlistNames(pParse, pSrc->a[i].pUsing);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -984,6 +1001,7 @@ static void renameColumnIdlistNames(
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Parse the SQL statement zSql using Parse object (*p). The Parse object
|
||||
** is initialized by this function before it is used.
|
||||
|
||||
+61
-62
@@ -256,9 +256,9 @@ static void openStatTable(
|
||||
** share an instance of the following structure to hold their state
|
||||
** information.
|
||||
*/
|
||||
typedef struct Stat4Accum Stat4Accum;
|
||||
typedef struct Stat4Sample Stat4Sample;
|
||||
struct Stat4Sample {
|
||||
typedef struct StatAccum StatAccum;
|
||||
typedef struct StatSample StatSample;
|
||||
struct StatSample {
|
||||
tRowcnt *anEq; /* sqlite_stat4.nEq */
|
||||
tRowcnt *anDLt; /* sqlite_stat4.nDLt */
|
||||
#ifdef SQLITE_ENABLE_STAT4
|
||||
@@ -273,27 +273,29 @@ struct Stat4Sample {
|
||||
u32 iHash; /* Tiebreaker hash */
|
||||
#endif
|
||||
};
|
||||
struct Stat4Accum {
|
||||
struct StatAccum {
|
||||
sqlite3 *db; /* Database connection, for malloc() */
|
||||
tRowcnt nRow; /* Number of rows in the entire table */
|
||||
tRowcnt nPSample; /* How often to do a periodic sample */
|
||||
int nCol; /* Number of columns in index + pk/rowid */
|
||||
int nKeyCol; /* Number of index columns w/o the pk/rowid */
|
||||
StatSample current; /* Current row as a StatSample */
|
||||
#ifdef SQLITE_ENABLE_STAT4
|
||||
tRowcnt nPSample; /* How often to do a periodic sample */
|
||||
int mxSample; /* Maximum number of samples to accumulate */
|
||||
Stat4Sample current; /* Current row as a Stat4Sample */
|
||||
u32 iPrn; /* Pseudo-random number used for sampling */
|
||||
Stat4Sample *aBest; /* Array of nCol best samples */
|
||||
StatSample *aBest; /* Array of nCol best samples */
|
||||
int iMin; /* Index in a[] of entry with minimum score */
|
||||
int nSample; /* Current number of samples */
|
||||
int nMaxEqZero; /* Max leading 0 in anEq[] for any a[] entry */
|
||||
int iGet; /* Index of current sample accessed by stat_get() */
|
||||
Stat4Sample *a; /* Array of mxSample Stat4Sample objects */
|
||||
sqlite3 *db; /* Database connection, for malloc() */
|
||||
StatSample *a; /* Array of mxSample StatSample objects */
|
||||
#endif
|
||||
};
|
||||
|
||||
/* Reclaim memory used by a Stat4Sample
|
||||
/* Reclaim memory used by a StatSample
|
||||
*/
|
||||
#ifdef SQLITE_ENABLE_STAT4
|
||||
static void sampleClear(sqlite3 *db, Stat4Sample *p){
|
||||
static void sampleClear(sqlite3 *db, StatSample *p){
|
||||
assert( db!=0 );
|
||||
if( p->nRowid ){
|
||||
sqlite3DbFree(db, p->u.aRowid);
|
||||
@@ -305,7 +307,7 @@ static void sampleClear(sqlite3 *db, Stat4Sample *p){
|
||||
/* Initialize the BLOB value of a ROWID
|
||||
*/
|
||||
#ifdef SQLITE_ENABLE_STAT4
|
||||
static void sampleSetRowid(sqlite3 *db, Stat4Sample *p, int n, const u8 *pData){
|
||||
static void sampleSetRowid(sqlite3 *db, StatSample *p, int n, const u8 *pData){
|
||||
assert( db!=0 );
|
||||
if( p->nRowid ) sqlite3DbFree(db, p->u.aRowid);
|
||||
p->u.aRowid = sqlite3DbMallocRawNN(db, n);
|
||||
@@ -321,7 +323,7 @@ static void sampleSetRowid(sqlite3 *db, Stat4Sample *p, int n, const u8 *pData){
|
||||
/* Initialize the INTEGER value of a ROWID.
|
||||
*/
|
||||
#ifdef SQLITE_ENABLE_STAT4
|
||||
static void sampleSetRowidInt64(sqlite3 *db, Stat4Sample *p, i64 iRowid){
|
||||
static void sampleSetRowidInt64(sqlite3 *db, StatSample *p, i64 iRowid){
|
||||
assert( db!=0 );
|
||||
if( p->nRowid ) sqlite3DbFree(db, p->u.aRowid);
|
||||
p->nRowid = 0;
|
||||
@@ -334,7 +336,7 @@ static void sampleSetRowidInt64(sqlite3 *db, Stat4Sample *p, i64 iRowid){
|
||||
** Copy the contents of object (*pFrom) into (*pTo).
|
||||
*/
|
||||
#ifdef SQLITE_ENABLE_STAT4
|
||||
static void sampleCopy(Stat4Accum *p, Stat4Sample *pTo, Stat4Sample *pFrom){
|
||||
static void sampleCopy(StatAccum *p, StatSample *pTo, StatSample *pFrom){
|
||||
pTo->isPSample = pFrom->isPSample;
|
||||
pTo->iCol = pFrom->iCol;
|
||||
pTo->iHash = pFrom->iHash;
|
||||
@@ -350,10 +352,10 @@ static void sampleCopy(Stat4Accum *p, Stat4Sample *pTo, Stat4Sample *pFrom){
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Reclaim all memory of a Stat4Accum structure.
|
||||
** Reclaim all memory of a StatAccum structure.
|
||||
*/
|
||||
static void stat4Destructor(void *pOld){
|
||||
Stat4Accum *p = (Stat4Accum*)pOld;
|
||||
static void statAccumDestructor(void *pOld){
|
||||
StatAccum *p = (StatAccum*)pOld;
|
||||
#ifdef SQLITE_ENABLE_STAT4
|
||||
int i;
|
||||
for(i=0; i<p->nCol; i++) sampleClear(p->db, p->aBest+i);
|
||||
@@ -381,9 +383,9 @@ static void stat4Destructor(void *pOld){
|
||||
** PRIMARY KEY of the table. The covering index that implements the
|
||||
** original WITHOUT ROWID table as N==K as a special case.
|
||||
**
|
||||
** This routine allocates the Stat4Accum object in heap memory. The return
|
||||
** value is a pointer to the Stat4Accum object. The datatype of the
|
||||
** return value is BLOB, but it is really just a pointer to the Stat4Accum
|
||||
** This routine allocates the StatAccum object in heap memory. The return
|
||||
** value is a pointer to the StatAccum object. The datatype of the
|
||||
** return value is BLOB, but it is really just a pointer to the StatAccum
|
||||
** object.
|
||||
*/
|
||||
static void statInit(
|
||||
@@ -391,7 +393,7 @@ static void statInit(
|
||||
int argc,
|
||||
sqlite3_value **argv
|
||||
){
|
||||
Stat4Accum *p;
|
||||
StatAccum *p;
|
||||
int nCol; /* Number of columns in index being sampled */
|
||||
int nKeyCol; /* Number of key columns */
|
||||
int nColUp; /* nCol rounded up for alignment */
|
||||
@@ -410,13 +412,13 @@ static void statInit(
|
||||
assert( nKeyCol<=nCol );
|
||||
assert( nKeyCol>0 );
|
||||
|
||||
/* Allocate the space required for the Stat4Accum object */
|
||||
/* Allocate the space required for the StatAccum object */
|
||||
n = sizeof(*p)
|
||||
+ sizeof(tRowcnt)*nColUp /* Stat4Accum.anEq */
|
||||
+ sizeof(tRowcnt)*nColUp /* Stat4Accum.anDLt */
|
||||
+ sizeof(tRowcnt)*nColUp /* StatAccum.anEq */
|
||||
+ sizeof(tRowcnt)*nColUp /* StatAccum.anDLt */
|
||||
#ifdef SQLITE_ENABLE_STAT4
|
||||
+ sizeof(tRowcnt)*nColUp /* Stat4Accum.anLt */
|
||||
+ sizeof(Stat4Sample)*(nCol+mxSample) /* Stat4Accum.aBest[], a[] */
|
||||
+ sizeof(tRowcnt)*nColUp /* StatAccum.anLt */
|
||||
+ sizeof(StatSample)*(nCol+mxSample) /* StatAccum.aBest[], a[] */
|
||||
+ sizeof(tRowcnt)*3*nColUp*(nCol+mxSample)
|
||||
#endif
|
||||
;
|
||||
@@ -445,8 +447,8 @@ static void statInit(
|
||||
p->current.anLt = &p->current.anEq[nColUp];
|
||||
p->iPrn = 0x689e962d*(u32)nCol ^ 0xd0944565*(u32)sqlite3_value_int(argv[2]);
|
||||
|
||||
/* Set up the Stat4Accum.a[] and aBest[] arrays */
|
||||
p->a = (struct Stat4Sample*)&p->current.anLt[nColUp];
|
||||
/* Set up the StatAccum.a[] and aBest[] arrays */
|
||||
p->a = (struct StatSample*)&p->current.anLt[nColUp];
|
||||
p->aBest = &p->a[mxSample];
|
||||
pSpace = (u8*)(&p->a[mxSample+nCol]);
|
||||
for(i=0; i<(mxSample+nCol); i++){
|
||||
@@ -466,7 +468,7 @@ static void statInit(
|
||||
** only the pointer (the 2nd parameter) matters. The size of the object
|
||||
** (given by the 3rd parameter) is never used and can be any positive
|
||||
** value. */
|
||||
sqlite3_result_blob(context, p, sizeof(*p), stat4Destructor);
|
||||
sqlite3_result_blob(context, p, sizeof(*p), statAccumDestructor);
|
||||
}
|
||||
static const FuncDef statInitFuncdef = {
|
||||
2+IsStat4, /* nArg */
|
||||
@@ -493,9 +495,9 @@ static const FuncDef statInitFuncdef = {
|
||||
** the anEq[] array from pSample->anEq[pSample->iCol+1] onwards are valid.
|
||||
*/
|
||||
static int sampleIsBetterPost(
|
||||
Stat4Accum *pAccum,
|
||||
Stat4Sample *pNew,
|
||||
Stat4Sample *pOld
|
||||
StatAccum *pAccum,
|
||||
StatSample *pNew,
|
||||
StatSample *pOld
|
||||
){
|
||||
int nCol = pAccum->nCol;
|
||||
int i;
|
||||
@@ -517,9 +519,9 @@ static int sampleIsBetterPost(
|
||||
** the anEq[] array from pSample->anEq[pSample->iCol] onwards are valid.
|
||||
*/
|
||||
static int sampleIsBetter(
|
||||
Stat4Accum *pAccum,
|
||||
Stat4Sample *pNew,
|
||||
Stat4Sample *pOld
|
||||
StatAccum *pAccum,
|
||||
StatSample *pNew,
|
||||
StatSample *pOld
|
||||
){
|
||||
tRowcnt nEqNew = pNew->anEq[pNew->iCol];
|
||||
tRowcnt nEqOld = pOld->anEq[pOld->iCol];
|
||||
@@ -539,21 +541,21 @@ static int sampleIsBetter(
|
||||
** Copy the contents of sample *pNew into the p->a[] array. If necessary,
|
||||
** remove the least desirable sample from p->a[] to make room.
|
||||
*/
|
||||
static void sampleInsert(Stat4Accum *p, Stat4Sample *pNew, int nEqZero){
|
||||
Stat4Sample *pSample = 0;
|
||||
static void sampleInsert(StatAccum *p, StatSample *pNew, int nEqZero){
|
||||
StatSample *pSample = 0;
|
||||
int i;
|
||||
|
||||
assert( IsStat4 || nEqZero==0 );
|
||||
|
||||
/* Stat4Accum.nMaxEqZero is set to the maximum number of leading 0
|
||||
** values in the anEq[] array of any sample in Stat4Accum.a[]. In
|
||||
/* StatAccum.nMaxEqZero is set to the maximum number of leading 0
|
||||
** values in the anEq[] array of any sample in StatAccum.a[]. In
|
||||
** other words, if nMaxEqZero is n, then it is guaranteed that there
|
||||
** are no samples with Stat4Sample.anEq[m]==0 for (m>=n). */
|
||||
** are no samples with StatSample.anEq[m]==0 for (m>=n). */
|
||||
if( nEqZero>p->nMaxEqZero ){
|
||||
p->nMaxEqZero = nEqZero;
|
||||
}
|
||||
if( pNew->isPSample==0 ){
|
||||
Stat4Sample *pUpgrade = 0;
|
||||
StatSample *pUpgrade = 0;
|
||||
assert( pNew->anEq[pNew->iCol]>0 );
|
||||
|
||||
/* This sample is being added because the prefix that ends in column
|
||||
@@ -562,7 +564,7 @@ static void sampleInsert(Stat4Accum *p, Stat4Sample *pNew, int nEqZero){
|
||||
** this one. Instead, upgrade the priority of the highest priority
|
||||
** existing sample that shares this prefix. */
|
||||
for(i=p->nSample-1; i>=0; i--){
|
||||
Stat4Sample *pOld = &p->a[i];
|
||||
StatSample *pOld = &p->a[i];
|
||||
if( pOld->anEq[pNew->iCol]==0 ){
|
||||
if( pOld->isPSample ) return;
|
||||
assert( pOld->iCol>pNew->iCol );
|
||||
@@ -581,7 +583,7 @@ static void sampleInsert(Stat4Accum *p, Stat4Sample *pNew, int nEqZero){
|
||||
|
||||
/* If necessary, remove sample iMin to make room for the new sample. */
|
||||
if( p->nSample>=p->mxSample ){
|
||||
Stat4Sample *pMin = &p->a[p->iMin];
|
||||
StatSample *pMin = &p->a[p->iMin];
|
||||
tRowcnt *anEq = pMin->anEq;
|
||||
tRowcnt *anLt = pMin->anLt;
|
||||
tRowcnt *anDLt = pMin->anDLt;
|
||||
@@ -624,20 +626,20 @@ find_new_min:
|
||||
}
|
||||
#endif /* SQLITE_ENABLE_STAT4 */
|
||||
|
||||
#ifdef SQLITE_ENABLE_STAT4
|
||||
/*
|
||||
** Field iChng of the index being scanned has changed. So at this point
|
||||
** p->current contains a sample that reflects the previous row of the
|
||||
** index. The value of anEq[iChng] and subsequent anEq[] elements are
|
||||
** correct at this point.
|
||||
*/
|
||||
static void samplePushPrevious(Stat4Accum *p, int iChng){
|
||||
#ifdef SQLITE_ENABLE_STAT4
|
||||
static void samplePushPrevious(StatAccum *p, int iChng){
|
||||
int i;
|
||||
|
||||
/* Check if any samples from the aBest[] array should be pushed
|
||||
** into IndexSample.a[] at this point. */
|
||||
for(i=(p->nCol-2); i>=iChng; i--){
|
||||
Stat4Sample *pBest = &p->aBest[i];
|
||||
StatSample *pBest = &p->aBest[i];
|
||||
pBest->anEq[i] = p->current.anEq[i];
|
||||
if( p->nSample<p->mxSample || sampleIsBetter(p, pBest, &p->a[p->iMin]) ){
|
||||
sampleInsert(p, pBest, i);
|
||||
@@ -661,25 +663,20 @@ static void samplePushPrevious(Stat4Accum *p, int iChng){
|
||||
}
|
||||
p->nMaxEqZero = iChng;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef SQLITE_ENABLE_STAT4
|
||||
UNUSED_PARAMETER( p );
|
||||
UNUSED_PARAMETER( iChng );
|
||||
#endif
|
||||
}
|
||||
#endif /* SQLITE_ENABLE_STAT4 */
|
||||
|
||||
/*
|
||||
** Implementation of the stat_push SQL function: stat_push(P,C,R)
|
||||
** Arguments:
|
||||
**
|
||||
** P Pointer to the Stat4Accum object created by stat_init()
|
||||
** P Pointer to the StatAccum object created by stat_init()
|
||||
** C Index of left-most column to differ from previous row
|
||||
** R Rowid for the current row. Might be a key record for
|
||||
** WITHOUT ROWID tables.
|
||||
**
|
||||
** This SQL function always returns NULL. It's purpose it to accumulate
|
||||
** statistical data and/or samples in the Stat4Accum object about the
|
||||
** statistical data and/or samples in the StatAccum object about the
|
||||
** index being analyzed. The stat_get() SQL function will later be used to
|
||||
** extract relevant information for constructing the sqlite_statN tables.
|
||||
**
|
||||
@@ -693,7 +690,7 @@ static void statPush(
|
||||
int i;
|
||||
|
||||
/* The three function arguments */
|
||||
Stat4Accum *p = (Stat4Accum*)sqlite3_value_blob(argv[0]);
|
||||
StatAccum *p = (StatAccum*)sqlite3_value_blob(argv[0]);
|
||||
int iChng = sqlite3_value_int(argv[1]);
|
||||
|
||||
UNUSED_PARAMETER( argc );
|
||||
@@ -706,7 +703,9 @@ static void statPush(
|
||||
for(i=0; i<p->nCol; i++) p->current.anEq[i] = 1;
|
||||
}else{
|
||||
/* Second and subsequent calls get processed here */
|
||||
#ifdef SQLITE_ENABLE_STAT4
|
||||
samplePushPrevious(p, iChng);
|
||||
#endif
|
||||
|
||||
/* Update anDLt[], anLt[] and anEq[] to reflect the values that apply
|
||||
** to the current row of the index. */
|
||||
@@ -775,15 +774,15 @@ static const FuncDef statPushFuncdef = {
|
||||
/*
|
||||
** Implementation of the stat_get(P,J) SQL function. This routine is
|
||||
** used to query statistical information that has been gathered into
|
||||
** the Stat4Accum object by prior calls to stat_push(). The P parameter
|
||||
** has type BLOB but it is really just a pointer to the Stat4Accum object.
|
||||
** the StatAccum object by prior calls to stat_push(). The P parameter
|
||||
** has type BLOB but it is really just a pointer to the StatAccum object.
|
||||
** The content to returned is determined by the parameter J
|
||||
** which is one of the STAT_GET_xxxx values defined above.
|
||||
**
|
||||
** The stat_get(P,J) function is not available to generic SQL. It is
|
||||
** inserted as part of a manually constructed bytecode program. (See
|
||||
** the callStatGet() routine below.) It is guaranteed that the P
|
||||
** parameter will always be a poiner to a Stat4Accum object, never a
|
||||
** parameter will always be a pointer to a StatAccum object, never a
|
||||
** NULL.
|
||||
**
|
||||
** If STAT4 is not enabled, then J is always
|
||||
@@ -796,7 +795,7 @@ static void statGet(
|
||||
int argc,
|
||||
sqlite3_value **argv
|
||||
){
|
||||
Stat4Accum *p = (Stat4Accum*)sqlite3_value_blob(argv[0]);
|
||||
StatAccum *p = (StatAccum*)sqlite3_value_blob(argv[0]);
|
||||
#ifdef SQLITE_ENABLE_STAT4
|
||||
/* STAT4 has a parameter on this routine. */
|
||||
int eCall = sqlite3_value_int(argv[1]);
|
||||
@@ -817,7 +816,7 @@ static void statGet(
|
||||
** the index. The first integer in the list is the total number of
|
||||
** entries in the index. There is one additional integer in the list
|
||||
** for each indexed column. This additional integer is an estimate of
|
||||
** the number of rows matched by a stabbing query on the index using
|
||||
** the number of rows matched by a equality query on the index using
|
||||
** a key with the corresponding number of fields. In other words,
|
||||
** if the index is on columns (a,b) and the sqlite_stat1 value is
|
||||
** "100 10 2", then SQLite estimates that:
|
||||
@@ -860,7 +859,7 @@ static void statGet(
|
||||
p->iGet = 0;
|
||||
}
|
||||
if( p->iGet<p->nSample ){
|
||||
Stat4Sample *pS = p->a + p->iGet;
|
||||
StatSample *pS = p->a + p->iGet;
|
||||
if( pS->nRowid==0 ){
|
||||
sqlite3_result_int64(context, pS->u.iRowid);
|
||||
}else{
|
||||
@@ -951,7 +950,7 @@ static void analyzeOneTable(
|
||||
int iDb; /* Index of database containing pTab */
|
||||
u8 needTableCnt = 1; /* True to count the table */
|
||||
int regNewRowid = iMem++; /* Rowid for the inserted record */
|
||||
int regStat4 = iMem++; /* Register to hold Stat4Accum object */
|
||||
int regStat4 = iMem++; /* Register to hold StatAccum object */
|
||||
int regChng = iMem++; /* Index of changed index field */
|
||||
#ifdef SQLITE_ENABLE_STAT4
|
||||
int regRowid = iMem++; /* Rowid argument passed to stat_push() */
|
||||
|
||||
+20
-9
@@ -45,6 +45,17 @@ static int resolveAttachExpr(NameContext *pName, Expr *pExpr)
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
** Return true if zName points to a name that may be used to refer to
|
||||
** database iDb attached to handle db.
|
||||
*/
|
||||
int sqlite3DbIsNamed(sqlite3 *db, int iDb, const char *zName){
|
||||
return (
|
||||
sqlite3StrICmp(db->aDb[iDb].zDbSName, zName)==0
|
||||
|| (iDb==0 && sqlite3StrICmp("main", zName)==0)
|
||||
);
|
||||
}
|
||||
|
||||
/*
|
||||
** An SQL user-function registered to do the work of an ATTACH statement. The
|
||||
** three arguments to the function come directly from an attach statement:
|
||||
@@ -117,9 +128,8 @@ static void attachFunc(
|
||||
goto attach_error;
|
||||
}
|
||||
for(i=0; i<db->nDb; i++){
|
||||
char *z = db->aDb[i].zDbSName;
|
||||
assert( z && zName );
|
||||
if( sqlite3StrICmp(z, zName)==0 ){
|
||||
assert( zName );
|
||||
if( sqlite3DbIsNamed(db, i, zName) ){
|
||||
zErrDyn = sqlite3MPrintf(db, "database %s is already in use", zName);
|
||||
goto attach_error;
|
||||
}
|
||||
@@ -187,7 +197,7 @@ static void attachFunc(
|
||||
if( rc==SQLITE_OK && pNew->zDbSName==0 ){
|
||||
rc = SQLITE_NOMEM_BKPT;
|
||||
}
|
||||
sqlite3_free( zPath );
|
||||
sqlite3_free_filename( zPath );
|
||||
|
||||
/* If the file was opened successfully, read the schema for the new database.
|
||||
** If this fails, or if opening the file failed, then close the file and
|
||||
@@ -272,7 +282,7 @@ static void detachFunc(
|
||||
for(i=0; i<db->nDb; i++){
|
||||
pDb = &db->aDb[i];
|
||||
if( pDb->pBt==0 ) continue;
|
||||
if( sqlite3StrICmp(pDb->zDbSName, zName)==0 ) break;
|
||||
if( sqlite3DbIsNamed(db, i, zName) ) break;
|
||||
}
|
||||
|
||||
if( i>=db->nDb ){
|
||||
@@ -463,20 +473,21 @@ int sqlite3FixSrcList(
|
||||
SrcList *pList /* The Source list to check and modify */
|
||||
){
|
||||
int i;
|
||||
const char *zDb;
|
||||
struct SrcList_item *pItem;
|
||||
sqlite3 *db = pFix->pParse->db;
|
||||
int iDb = sqlite3FindDbName(db, pFix->zDb);
|
||||
|
||||
if( NEVER(pList==0) ) return 0;
|
||||
zDb = pFix->zDb;
|
||||
|
||||
for(i=0, pItem=pList->a; i<pList->nSrc; i++, pItem++){
|
||||
if( pFix->bTemp==0 ){
|
||||
if( pItem->zDatabase && sqlite3StrICmp(pItem->zDatabase, zDb) ){
|
||||
if( pItem->zDatabase && iDb!=sqlite3FindDbName(db, pItem->zDatabase) ){
|
||||
sqlite3ErrorMsg(pFix->pParse,
|
||||
"%s %T cannot reference objects in database %s",
|
||||
pFix->zType, pFix->pName, pItem->zDatabase);
|
||||
return 1;
|
||||
}
|
||||
sqlite3DbFree(pFix->pParse->db, pItem->zDatabase);
|
||||
sqlite3DbFree(db, pItem->zDatabase);
|
||||
pItem->zDatabase = 0;
|
||||
pItem->pSchema = pFix->pSchema;
|
||||
pItem->fg.fromDDL = 1;
|
||||
|
||||
+10
-10
@@ -611,7 +611,7 @@ static int btreeSetHasContent(BtShared *pBt, Pgno pgno){
|
||||
*/
|
||||
static int btreeGetHasContent(BtShared *pBt, Pgno pgno){
|
||||
Bitvec *p = pBt->pHasContent;
|
||||
return (p && (pgno>sqlite3BitvecSize(p) || sqlite3BitvecTest(p, pgno)));
|
||||
return p && (pgno>sqlite3BitvecSize(p) || sqlite3BitvecTestNotNull(p, pgno));
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -2857,8 +2857,11 @@ int sqlite3BtreeSetPagerFlags(
|
||||
int sqlite3BtreeSetPageSize(Btree *p, int pageSize, int nReserve, int iFix){
|
||||
int rc = SQLITE_OK;
|
||||
BtShared *pBt = p->pBt;
|
||||
assert( nReserve>=-1 && nReserve<=255 );
|
||||
assert( nReserve>=-1 && nReserve<=254 );
|
||||
sqlite3BtreeEnter(p);
|
||||
if( nReserve>=0 ){
|
||||
pBt->nReserveWanted = nReserve + 1;
|
||||
}
|
||||
if( pBt->btsFlags & BTS_PAGESIZE_FIXED ){
|
||||
sqlite3BtreeLeave(p);
|
||||
return SQLITE_READONLY;
|
||||
@@ -2910,15 +2913,12 @@ int sqlite3BtreeGetReserveNoMutex(Btree *p){
|
||||
** Return the number of bytes of space at the end of every page that
|
||||
** are intentually left unused. This is the "reserved" space that is
|
||||
** sometimes used by extensions.
|
||||
**
|
||||
** If SQLITE_HAS_MUTEX is defined then the number returned is the
|
||||
** greater of the current reserved space and the maximum requested
|
||||
** reserve space.
|
||||
*/
|
||||
int sqlite3BtreeGetOptimalReserve(Btree *p){
|
||||
int sqlite3BtreeGetRequestedReserve(Btree *p){
|
||||
int n;
|
||||
sqlite3BtreeEnter(p);
|
||||
n = sqlite3BtreeGetReserveNoMutex(p);
|
||||
n = ((int)p->pBt->nReserveWanted) - 1;
|
||||
if( n<0 ) n = sqlite3BtreeGetReserveNoMutex(p);
|
||||
sqlite3BtreeLeave(p);
|
||||
return n;
|
||||
}
|
||||
@@ -9530,7 +9530,7 @@ int sqlite3BtreeCount(sqlite3 *db, BtCursor *pCur, i64 *pnEntry){
|
||||
/* Unless an error occurs, the following loop runs one iteration for each
|
||||
** page in the B-Tree structure (not including overflow pages).
|
||||
*/
|
||||
while( rc==SQLITE_OK && !db->u1.isInterrupted ){
|
||||
while( rc==SQLITE_OK && !AtomicLoad(&db->u1.isInterrupted) ){
|
||||
int iIdx; /* Index of child node in parent */
|
||||
MemPage *pPage; /* Current page of the b-tree */
|
||||
|
||||
@@ -9656,7 +9656,7 @@ static int checkRef(IntegrityCk *pCheck, Pgno iPage){
|
||||
checkAppendMsg(pCheck, "2nd reference to page %d", iPage);
|
||||
return 1;
|
||||
}
|
||||
if( pCheck->db->u1.isInterrupted ) return 1;
|
||||
if( AtomicLoad(&pCheck->db->u1.isInterrupted) ) return 1;
|
||||
setPageReferenced(pCheck, iPage);
|
||||
return 0;
|
||||
}
|
||||
|
||||
+1
-1
@@ -74,7 +74,7 @@ int sqlite3BtreeGetPageSize(Btree*);
|
||||
int sqlite3BtreeMaxPageCount(Btree*,int);
|
||||
u32 sqlite3BtreeLastPage(Btree*);
|
||||
int sqlite3BtreeSecureDelete(Btree*,int);
|
||||
int sqlite3BtreeGetOptimalReserve(Btree*);
|
||||
int sqlite3BtreeGetRequestedReserve(Btree*);
|
||||
int sqlite3BtreeGetReserveNoMutex(Btree *p);
|
||||
int sqlite3BtreeSetAutoVacuum(Btree *, int);
|
||||
int sqlite3BtreeGetAutoVacuum(Btree *);
|
||||
|
||||
@@ -417,6 +417,7 @@ struct BtShared {
|
||||
#endif
|
||||
u8 inTransaction; /* Transaction state */
|
||||
u8 max1bytePayload; /* Maximum first byte of cell for a 1-byte payload */
|
||||
u8 nReserveWanted; /* 1 more than desired number of extra bytes per page */
|
||||
u16 btsFlags; /* Boolean parameters. See BTS_* macros below */
|
||||
u16 maxLocal; /* Maximum local payload in non-LEAFDATA tables */
|
||||
u16 minLocal; /* Minimum local payload in non-LEAFDATA tables */
|
||||
|
||||
+32
-2
@@ -315,7 +315,7 @@ Table *sqlite3FindTable(sqlite3 *db, const char *zName, const char *zDatabase){
|
||||
while(1){
|
||||
for(i=OMIT_TEMPDB; i<db->nDb; i++){
|
||||
int j = (i<2) ? i^1 : i; /* Search TEMP before MAIN */
|
||||
if( zDatabase==0 || sqlite3StrICmp(zDatabase, db->aDb[j].zDbSName)==0 ){
|
||||
if( zDatabase==0 || sqlite3DbIsNamed(db, j, zDatabase) ){
|
||||
assert( sqlite3SchemaMutexHeld(db, j, 0) );
|
||||
p = sqlite3HashFind(&db->aDb[j].pSchema->tblHash, zName);
|
||||
if( p ) return p;
|
||||
@@ -437,7 +437,7 @@ Index *sqlite3FindIndex(sqlite3 *db, const char *zName, const char *zDb){
|
||||
int j = (i<2) ? i^1 : i; /* Search TEMP before MAIN */
|
||||
Schema *pSchema = db->aDb[j].pSchema;
|
||||
assert( pSchema );
|
||||
if( zDb && sqlite3StrICmp(zDb, db->aDb[j].zDbSName) ) continue;
|
||||
if( zDb && sqlite3DbIsNamed(db, j, zDb)==0 ) continue;
|
||||
assert( sqlite3SchemaMutexHeld(db, j, 0) );
|
||||
p = sqlite3HashFind(&pSchema->idxHash, zName);
|
||||
if( p ) break;
|
||||
@@ -590,6 +590,7 @@ void sqlite3DeleteColumnNames(sqlite3 *db, Table *pTable){
|
||||
assert( pTable!=0 );
|
||||
if( (pCol = pTable->aCol)!=0 ){
|
||||
for(i=0; i<pTable->nCol; i++, pCol++){
|
||||
assert( pCol->zName==0 || pCol->hName==sqlite3StrIHash(pCol->zName) );
|
||||
sqlite3DbFree(db, pCol->zName);
|
||||
sqlite3ExprDelete(db, pCol->pDflt);
|
||||
sqlite3DbFree(db, pCol->zColl);
|
||||
@@ -1238,6 +1239,7 @@ void sqlite3AddColumn(Parse *pParse, Token *pName, Token *pType){
|
||||
pCol = &p->aCol[p->nCol];
|
||||
memset(pCol, 0, sizeof(p->aCol[0]));
|
||||
pCol->zName = z;
|
||||
pCol->hName = sqlite3StrIHash(z);
|
||||
sqlite3ColumnPropertiesFromName(p, pCol);
|
||||
|
||||
if( pType->n==0 ){
|
||||
@@ -2157,6 +2159,32 @@ int sqlite3ShadowTableName(sqlite3 *db, const char *zName){
|
||||
}
|
||||
#endif /* ifndef SQLITE_OMIT_VIRTUALTABLE */
|
||||
|
||||
#ifdef SQLITE_DEBUG
|
||||
/*
|
||||
** Mark all nodes of an expression as EP_Immutable, indicating that
|
||||
** they should not be changed. Expressions attached to a table or
|
||||
** index definition are tagged this way to help ensure that we do
|
||||
** not pass them into code generator routines by mistake.
|
||||
*/
|
||||
static int markImmutableExprStep(Walker *pWalker, Expr *pExpr){
|
||||
ExprSetVVAProperty(pExpr, EP_Immutable);
|
||||
return WRC_Continue;
|
||||
}
|
||||
static void markExprListImmutable(ExprList *pList){
|
||||
if( pList ){
|
||||
Walker w;
|
||||
memset(&w, 0, sizeof(w));
|
||||
w.xExprCallback = markImmutableExprStep;
|
||||
w.xSelectCallback = sqlite3SelectWalkNoop;
|
||||
w.xSelectCallback2 = 0;
|
||||
sqlite3WalkExprList(&w, pList);
|
||||
}
|
||||
}
|
||||
#else
|
||||
#define markExprListImmutable(X) /* no-op */
|
||||
#endif /* SQLITE_DEBUG */
|
||||
|
||||
|
||||
/*
|
||||
** This routine is called to report the final ")" that terminates
|
||||
** a CREATE TABLE statement.
|
||||
@@ -2249,6 +2277,8 @@ void sqlite3EndTable(
|
||||
** actually be used if PRAGMA writable_schema=ON is set. */
|
||||
sqlite3ExprListDelete(db, p->pCheck);
|
||||
p->pCheck = 0;
|
||||
}else{
|
||||
markExprListImmutable(p->pCheck);
|
||||
}
|
||||
}
|
||||
#endif /* !defined(SQLITE_OMIT_CHECK) */
|
||||
|
||||
+16
-3
@@ -163,17 +163,30 @@ CollSeq *sqlite3FindCollSeq(
|
||||
int create /* True to create CollSeq if doesn't already exist */
|
||||
){
|
||||
CollSeq *pColl;
|
||||
assert( SQLITE_UTF8==1 && SQLITE_UTF16LE==2 && SQLITE_UTF16BE==3 );
|
||||
assert( enc>=SQLITE_UTF8 && enc<=SQLITE_UTF16BE );
|
||||
if( zName ){
|
||||
pColl = findCollSeqEntry(db, zName, create);
|
||||
if( pColl ) pColl += enc-1;
|
||||
}else{
|
||||
pColl = db->pDfltColl;
|
||||
}
|
||||
assert( SQLITE_UTF8==1 && SQLITE_UTF16LE==2 && SQLITE_UTF16BE==3 );
|
||||
assert( enc>=SQLITE_UTF8 && enc<=SQLITE_UTF16BE );
|
||||
if( pColl ) pColl += enc-1;
|
||||
return pColl;
|
||||
}
|
||||
|
||||
/*
|
||||
** Change the text encoding for a database connection. This means that
|
||||
** the pDfltColl must change as well.
|
||||
*/
|
||||
void sqlite3SetTextEncoding(sqlite3 *db, u8 enc){
|
||||
assert( enc==SQLITE_UTF8 || enc==SQLITE_UTF16LE || enc==SQLITE_UTF16BE );
|
||||
db->enc = enc;
|
||||
/* EVIDENCE-OF: R-08308-17224 The default collating function for all
|
||||
** strings is BINARY.
|
||||
*/
|
||||
db->pDfltColl = sqlite3FindCollSeq(db, enc, sqlite3StrBINARY, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
** This function is responsible for invoking the collation factory callback
|
||||
** or substituting a collation sequence of a different encoding when the
|
||||
|
||||
+6
-6
@@ -621,12 +621,12 @@ static const struct {
|
||||
double rLimit; /* Maximum NNN value for this transform */
|
||||
double rXform; /* Constant used for this transform */
|
||||
} aXformType[] = {
|
||||
{ 0, 6, "second", 464269060800.0, 86400000.0/(24.0*60.0*60.0) },
|
||||
{ 0, 6, "minute", 7737817680.0, 86400000.0/(24.0*60.0) },
|
||||
{ 0, 4, "hour", 128963628.0, 86400000.0/24.0 },
|
||||
{ 0, 3, "day", 5373485.0, 86400000.0 },
|
||||
{ 1, 5, "month", 176546.0, 30.0*86400000.0 },
|
||||
{ 2, 4, "year", 14713.0, 365.0*86400000.0 },
|
||||
{ 0, 6, "second", 464269060800.0, 1000.0 },
|
||||
{ 0, 6, "minute", 7737817680.0, 60000.0 },
|
||||
{ 0, 4, "hour", 128963628.0, 3600000.0 },
|
||||
{ 0, 3, "day", 5373485.0, 86400000.0 },
|
||||
{ 1, 5, "month", 176546.0, 2592000000.0 },
|
||||
{ 2, 4, "year", 14713.0, 31536000000.0 },
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
+4
-1
@@ -238,6 +238,7 @@ static int statBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
|
||||
i = 0;
|
||||
if( iSchema>=0 ){
|
||||
pIdxInfo->aConstraintUsage[iSchema].argvIndex = ++i;
|
||||
pIdxInfo->aConstraintUsage[iSchema].omit = 1;
|
||||
pIdxInfo->idxNum |= 0x01;
|
||||
}
|
||||
if( iName>=0 ){
|
||||
@@ -452,7 +453,9 @@ static int statDecodePage(Btree *pBt, StatPage *p){
|
||||
if( nPayload>(u32)nLocal ){
|
||||
int j;
|
||||
int nOvfl = ((nPayload - nLocal) + nUsable-4 - 1) / (nUsable - 4);
|
||||
if( iOff+nLocal>nUsable ) goto statPageIsCorrupt;
|
||||
if( iOff+nLocal>nUsable || nPayload>0x7fffffff ){
|
||||
goto statPageIsCorrupt;
|
||||
}
|
||||
pCell->nLastOvfl = (nPayload-nLocal) - (nOvfl-1) * (nUsable-4);
|
||||
pCell->nOvfl = nOvfl;
|
||||
pCell->aOvfl = sqlite3_malloc64(sizeof(u32)*nOvfl);
|
||||
|
||||
+106
-72
@@ -42,7 +42,7 @@ char sqlite3TableColumnAffinity(Table *pTab, int iCol){
|
||||
** SELECT a AS b FROM t1 WHERE b;
|
||||
** SELECT * FROM t1 WHERE (select a from t1);
|
||||
*/
|
||||
char sqlite3ExprAffinity(Expr *pExpr){
|
||||
char sqlite3ExprAffinity(const Expr *pExpr){
|
||||
int op;
|
||||
while( ExprHasProperty(pExpr, EP_Skip) ){
|
||||
assert( pExpr->op==TK_COLLATE );
|
||||
@@ -152,10 +152,10 @@ Expr *sqlite3ExprSkipCollateAndLikely(Expr *pExpr){
|
||||
** COLLATE operators take first precedence. Left operands take
|
||||
** precedence over right operands.
|
||||
*/
|
||||
CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr){
|
||||
CollSeq *sqlite3ExprCollSeq(Parse *pParse, const Expr *pExpr){
|
||||
sqlite3 *db = pParse->db;
|
||||
CollSeq *pColl = 0;
|
||||
Expr *p = pExpr;
|
||||
const Expr *p = pExpr;
|
||||
while( p ){
|
||||
int op = p->op;
|
||||
if( op==TK_REGISTER ) op = p->op2;
|
||||
@@ -224,7 +224,7 @@ CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr){
|
||||
** The sqlite3ExprCollSeq() routine works the same except that it
|
||||
** returns NULL if there is no defined collation.
|
||||
*/
|
||||
CollSeq *sqlite3ExprNNCollSeq(Parse *pParse, Expr *pExpr){
|
||||
CollSeq *sqlite3ExprNNCollSeq(Parse *pParse, const Expr *pExpr){
|
||||
CollSeq *p = sqlite3ExprCollSeq(pParse, pExpr);
|
||||
if( p==0 ) p = pParse->db->pDfltColl;
|
||||
assert( p!=0 );
|
||||
@@ -234,7 +234,7 @@ CollSeq *sqlite3ExprNNCollSeq(Parse *pParse, Expr *pExpr){
|
||||
/*
|
||||
** Return TRUE if the two expressions have equivalent collating sequences.
|
||||
*/
|
||||
int sqlite3ExprCollSeqMatch(Parse *pParse, Expr *pE1, Expr *pE2){
|
||||
int sqlite3ExprCollSeqMatch(Parse *pParse, const Expr *pE1, const Expr *pE2){
|
||||
CollSeq *pColl1 = sqlite3ExprNNCollSeq(pParse, pE1);
|
||||
CollSeq *pColl2 = sqlite3ExprNNCollSeq(pParse, pE2);
|
||||
return sqlite3StrICmp(pColl1->zName, pColl2->zName)==0;
|
||||
@@ -245,7 +245,7 @@ int sqlite3ExprCollSeqMatch(Parse *pParse, Expr *pE1, Expr *pE2){
|
||||
** type affinity of the other operand. This routine returns the
|
||||
** type affinity that should be used for the comparison operator.
|
||||
*/
|
||||
char sqlite3CompareAffinity(Expr *pExpr, char aff2){
|
||||
char sqlite3CompareAffinity(const Expr *pExpr, char aff2){
|
||||
char aff1 = sqlite3ExprAffinity(pExpr);
|
||||
if( aff1>SQLITE_AFF_NONE && aff2>SQLITE_AFF_NONE ){
|
||||
/* Both sides of the comparison are columns. If one has numeric
|
||||
@@ -267,7 +267,7 @@ char sqlite3CompareAffinity(Expr *pExpr, char aff2){
|
||||
** pExpr is a comparison operator. Return the type affinity that should
|
||||
** be applied to both operands prior to doing the comparison.
|
||||
*/
|
||||
static char comparisonAffinity(Expr *pExpr){
|
||||
static char comparisonAffinity(const Expr *pExpr){
|
||||
char aff;
|
||||
assert( pExpr->op==TK_EQ || pExpr->op==TK_IN || pExpr->op==TK_LT ||
|
||||
pExpr->op==TK_GT || pExpr->op==TK_GE || pExpr->op==TK_LE ||
|
||||
@@ -290,7 +290,7 @@ static char comparisonAffinity(Expr *pExpr){
|
||||
** if the index with affinity idx_affinity may be used to implement
|
||||
** the comparison in pExpr.
|
||||
*/
|
||||
int sqlite3IndexAffinityOk(Expr *pExpr, char idx_affinity){
|
||||
int sqlite3IndexAffinityOk(const Expr *pExpr, char idx_affinity){
|
||||
char aff = comparisonAffinity(pExpr);
|
||||
if( aff<SQLITE_AFF_TEXT ){
|
||||
return 1;
|
||||
@@ -305,7 +305,11 @@ int sqlite3IndexAffinityOk(Expr *pExpr, char idx_affinity){
|
||||
** Return the P5 value that should be used for a binary comparison
|
||||
** opcode (OP_Eq, OP_Ge etc.) used to compare pExpr1 and pExpr2.
|
||||
*/
|
||||
static u8 binaryCompareP5(Expr *pExpr1, Expr *pExpr2, int jumpIfNull){
|
||||
static u8 binaryCompareP5(
|
||||
const Expr *pExpr1, /* Left operand */
|
||||
const Expr *pExpr2, /* Right operand */
|
||||
int jumpIfNull /* Extra flags added to P5 */
|
||||
){
|
||||
u8 aff = (char)sqlite3ExprAffinity(pExpr2);
|
||||
aff = (u8)sqlite3CompareAffinity(pExpr1, aff) | (u8)jumpIfNull;
|
||||
return aff;
|
||||
@@ -325,8 +329,8 @@ static u8 binaryCompareP5(Expr *pExpr1, Expr *pExpr2, int jumpIfNull){
|
||||
*/
|
||||
CollSeq *sqlite3BinaryCompareCollSeq(
|
||||
Parse *pParse,
|
||||
Expr *pLeft,
|
||||
Expr *pRight
|
||||
const Expr *pLeft,
|
||||
const Expr *pRight
|
||||
){
|
||||
CollSeq *pColl;
|
||||
assert( pLeft );
|
||||
@@ -351,7 +355,7 @@ CollSeq *sqlite3BinaryCompareCollSeq(
|
||||
** is reversed in the sqlite3BinaryCompareCollSeq() call so that the
|
||||
** correct collating sequence is found.
|
||||
*/
|
||||
CollSeq *sqlite3ExprCompareCollSeq(Parse *pParse, Expr *p){
|
||||
CollSeq *sqlite3ExprCompareCollSeq(Parse *pParse, const Expr *p){
|
||||
if( ExprHasProperty(p, EP_Commuted) ){
|
||||
return sqlite3BinaryCompareCollSeq(pParse, p->pRight, p->pLeft);
|
||||
}else{
|
||||
@@ -594,6 +598,7 @@ static void codeVectorCompare(
|
||||
int addrDone = sqlite3VdbeMakeLabel(pParse);
|
||||
int isCommuted = ExprHasProperty(pExpr,EP_Commuted);
|
||||
|
||||
assert( !ExprHasVVAProperty(pExpr,EP_Immutable) );
|
||||
if( pParse->nErr ) return;
|
||||
if( nLeft!=sqlite3ExprVectorSize(pRight) ){
|
||||
sqlite3ErrorMsg(pParse, "row value misused");
|
||||
@@ -1206,7 +1211,7 @@ static int dupedExprStructSize(Expr *p, int flags){
|
||||
assert( !ExprHasProperty(p, EP_TokenOnly|EP_Reduced) );
|
||||
assert( !ExprHasProperty(p, EP_FromJoin) );
|
||||
assert( !ExprHasProperty(p, EP_MemToken) );
|
||||
assert( !ExprHasProperty(p, EP_NoReduce) );
|
||||
assert( !ExprHasVVAProperty(p, EP_NoReduce) );
|
||||
if( p->pLeft || p->x.pList ){
|
||||
nSize = EXPR_REDUCEDSIZE | EP_Reduced;
|
||||
}else{
|
||||
@@ -1311,6 +1316,10 @@ static Expr *exprDup(sqlite3 *db, Expr *p, int dupFlags, u8 **pzBuffer){
|
||||
pNew->flags &= ~(EP_Reduced|EP_TokenOnly|EP_Static|EP_MemToken);
|
||||
pNew->flags |= nStructSize & (EP_Reduced|EP_TokenOnly);
|
||||
pNew->flags |= staticFlag;
|
||||
ExprClearVVAProperties(pNew);
|
||||
if( dupFlags ){
|
||||
ExprSetVVAProperty(pNew, EP_Immutable);
|
||||
}
|
||||
|
||||
/* Copy the p->u.zToken string, if any. */
|
||||
if( nToken ){
|
||||
@@ -1778,6 +1787,7 @@ void sqlite3ExprListSetName(
|
||||
int dequote /* True to cause the name to be dequoted */
|
||||
){
|
||||
assert( pList!=0 || pParse->db->mallocFailed!=0 );
|
||||
assert( pParse->eParseMode!=PARSE_MODE_UNMAP || dequote==0 );
|
||||
if( pList ){
|
||||
struct ExprList_item *pItem;
|
||||
assert( pList->nExpr>0 );
|
||||
@@ -1785,9 +1795,14 @@ void sqlite3ExprListSetName(
|
||||
assert( pItem->zEName==0 );
|
||||
assert( pItem->eEName==ENAME_NAME );
|
||||
pItem->zEName = sqlite3DbStrNDup(pParse->db, pName->z, pName->n);
|
||||
if( dequote ) sqlite3Dequote(pItem->zEName);
|
||||
if( IN_RENAME_OBJECT ){
|
||||
sqlite3RenameTokenMap(pParse, (void*)pItem->zEName, pName);
|
||||
if( dequote ){
|
||||
/* If dequote==0, then pName->z does not point to part of a DDL
|
||||
** statement handled by the parser. And so no token need be added
|
||||
** to the token-map. */
|
||||
sqlite3Dequote(pItem->zEName);
|
||||
if( IN_RENAME_OBJECT ){
|
||||
sqlite3RenameTokenMap(pParse, (void*)pItem->zEName, pName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2087,7 +2102,7 @@ int sqlite3ExprIsConstant(Expr *p){
|
||||
**
|
||||
** When this routine returns true, it indicates that the expression
|
||||
** can be added to the pParse->pConstExpr list and evaluated once when
|
||||
** the prepared statement starts up. See sqlite3ExprCodeAtInit().
|
||||
** the prepared statement starts up. See sqlite3ExprCodeRunJustOnce().
|
||||
*/
|
||||
int sqlite3ExprIsConstantNotJoin(Expr *p){
|
||||
return exprIsConst(p, 2, 0);
|
||||
@@ -2850,6 +2865,7 @@ void sqlite3CodeRhsOfIN(
|
||||
|
||||
/* Begin coding the subroutine */
|
||||
ExprSetProperty(pExpr, EP_Subrtn);
|
||||
assert( !ExprHasProperty(pExpr, EP_TokenOnly|EP_Reduced) );
|
||||
pExpr->y.sub.regReturn = ++pParse->nMem;
|
||||
pExpr->y.sub.iAddr =
|
||||
sqlite3VdbeAddOp2(v, OP_Integer, 0, pExpr->y.sub.regReturn) + 1;
|
||||
@@ -2931,6 +2947,8 @@ void sqlite3CodeRhsOfIN(
|
||||
affinity = sqlite3ExprAffinity(pLeft);
|
||||
if( affinity<=SQLITE_AFF_NONE ){
|
||||
affinity = SQLITE_AFF_BLOB;
|
||||
}else if( affinity==SQLITE_AFF_REAL ){
|
||||
affinity = SQLITE_AFF_NUMERIC;
|
||||
}
|
||||
if( pKeyInfo ){
|
||||
assert( sqlite3KeyInfoIsWriteable(pKeyInfo) );
|
||||
@@ -3169,7 +3187,9 @@ static void sqlite3ExprCodeIN(
|
||||
int destNotNull; /* Jump here if a comparison is not true in step 6 */
|
||||
int addrTop; /* Top of the step-6 loop */
|
||||
int iTab = 0; /* Index to use */
|
||||
u8 okConstFactor = pParse->okConstFactor;
|
||||
|
||||
assert( !ExprHasVVAProperty(pExpr,EP_Immutable) );
|
||||
pLeft = pExpr->pLeft;
|
||||
if( sqlite3ExprCheckIN(pParse, pExpr) ) return;
|
||||
zAff = exprINAffinity(pParse, pExpr);
|
||||
@@ -3212,8 +3232,14 @@ static void sqlite3ExprCodeIN(
|
||||
** so that the fields are in the same order as an existing index. The
|
||||
** aiMap[] array contains a mapping from the original LHS field order to
|
||||
** the field order that matches the RHS index.
|
||||
*/
|
||||
**
|
||||
** Avoid factoring the LHS of the IN(...) expression out of the loop,
|
||||
** even if it is constant, as OP_Affinity may be used on the register
|
||||
** by code generated below. */
|
||||
assert( pParse->okConstFactor==okConstFactor );
|
||||
pParse->okConstFactor = 0;
|
||||
rLhsOrig = exprCodeVector(pParse, pLeft, &iDummy);
|
||||
pParse->okConstFactor = okConstFactor;
|
||||
for(i=0; i<nVector && aiMap[i]==i; i++){} /* Are LHS fields reordered? */
|
||||
if( i==nVector ){
|
||||
/* LHS fields are not reordered */
|
||||
@@ -3239,21 +3265,13 @@ static void sqlite3ExprCodeIN(
|
||||
int r2, regToFree;
|
||||
int regCkNull = 0;
|
||||
int ii;
|
||||
int bLhsReal; /* True if the LHS of the IN has REAL affinity */
|
||||
assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
|
||||
if( destIfNull!=destIfFalse ){
|
||||
regCkNull = sqlite3GetTempReg(pParse);
|
||||
sqlite3VdbeAddOp3(v, OP_BitAnd, rLhs, rLhs, regCkNull);
|
||||
}
|
||||
bLhsReal = sqlite3ExprAffinity(pExpr->pLeft)==SQLITE_AFF_REAL;
|
||||
for(ii=0; ii<pList->nExpr; ii++){
|
||||
if( bLhsReal ){
|
||||
r2 = regToFree = sqlite3GetTempReg(pParse);
|
||||
sqlite3ExprCode(pParse, pList->a[ii].pExpr, r2);
|
||||
sqlite3VdbeAddOp4(v, OP_Affinity, r2, 1, 0, "E", P4_STATIC);
|
||||
}else{
|
||||
r2 = sqlite3ExprCodeTemp(pParse, pList->a[ii].pExpr, ®ToFree);
|
||||
}
|
||||
r2 = sqlite3ExprCodeTemp(pParse, pList->a[ii].pExpr, ®ToFree);
|
||||
if( regCkNull && sqlite3ExprCanBeNull(pList->a[ii].pExpr) ){
|
||||
sqlite3VdbeAddOp3(v, OP_BitAnd, regCkNull, r2, regCkNull);
|
||||
}
|
||||
@@ -3496,7 +3514,7 @@ void sqlite3ExprCodeGeneratedColumn(
|
||||
}else{
|
||||
iAddr = 0;
|
||||
}
|
||||
sqlite3ExprCode(pParse, pCol->pDflt, regOut);
|
||||
sqlite3ExprCodeCopy(pParse, pCol->pDflt, regOut);
|
||||
if( pCol->affinity>=SQLITE_AFF_TEXT ){
|
||||
sqlite3VdbeAddOp4(v, OP_Affinity, regOut, 1, 0, &pCol->affinity, 1);
|
||||
}
|
||||
@@ -3780,6 +3798,7 @@ expr_code_doover:
|
||||
if( pExpr==0 ){
|
||||
op = TK_NULL;
|
||||
}else{
|
||||
assert( !ExprHasVVAProperty(pExpr,EP_Immutable) );
|
||||
op = pExpr->op;
|
||||
}
|
||||
switch( op ){
|
||||
@@ -3790,8 +3809,17 @@ expr_code_doover:
|
||||
assert( pCol->iMem>0 );
|
||||
return pCol->iMem;
|
||||
}else if( pAggInfo->useSortingIdx ){
|
||||
Table *pTab = pCol->pTab;
|
||||
sqlite3VdbeAddOp3(v, OP_Column, pAggInfo->sortingIdxPTab,
|
||||
pCol->iSorterColumn, target);
|
||||
if( pCol->iColumn<0 ){
|
||||
VdbeComment((v,"%s.rowid",pTab->zName));
|
||||
}else{
|
||||
VdbeComment((v,"%s.%s",pTab->zName,pTab->aCol[pCol->iColumn].zName));
|
||||
if( pTab->aCol[pCol->iColumn].affinity==SQLITE_AFF_REAL ){
|
||||
sqlite3VdbeAddOp1(v, OP_RealAffinity, target);
|
||||
}
|
||||
}
|
||||
return target;
|
||||
}
|
||||
/* Otherwise, fall thru into the TK_COLUMN case */
|
||||
@@ -3817,10 +3845,6 @@ expr_code_doover:
|
||||
static const char zAff[] = "B\000C\000D\000E";
|
||||
assert( SQLITE_AFF_BLOB=='A' );
|
||||
assert( SQLITE_AFF_TEXT=='B' );
|
||||
if( iReg!=target ){
|
||||
sqlite3VdbeAddOp2(v, OP_SCopy, iReg, target);
|
||||
iReg = target;
|
||||
}
|
||||
sqlite3VdbeAddOp4(v, OP_Affinity, iReg, 1, 0,
|
||||
&zAff[(aff-'B')*2], P4_STATIC);
|
||||
}
|
||||
@@ -4034,6 +4058,7 @@ expr_code_doover:
|
||||
tempX.op = TK_INTEGER;
|
||||
tempX.flags = EP_IntValue|EP_TokenOnly;
|
||||
tempX.u.iValue = 0;
|
||||
ExprClearVVAProperties(&tempX);
|
||||
r1 = sqlite3ExprCodeTemp(pParse, &tempX, ®Free1);
|
||||
r2 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free2);
|
||||
sqlite3VdbeAddOp3(v, OP_Subtract, r2, r1, target);
|
||||
@@ -4105,16 +4130,13 @@ expr_code_doover:
|
||||
#endif
|
||||
|
||||
if( ConstFactorOk(pParse) && sqlite3ExprIsConstantNotJoin(pExpr) ){
|
||||
/* SQL functions can be expensive. So try to move constant functions
|
||||
** out of the inner loop, even if that means an extra OP_Copy. */
|
||||
return sqlite3ExprCodeAtInit(pParse, pExpr, -1);
|
||||
/* SQL functions can be expensive. So try to avoid running them
|
||||
** multiple times if we know they always give the same result */
|
||||
return sqlite3ExprCodeRunJustOnce(pParse, pExpr, -1);
|
||||
}
|
||||
assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
|
||||
if( ExprHasProperty(pExpr, EP_TokenOnly) ){
|
||||
pFarg = 0;
|
||||
}else{
|
||||
pFarg = pExpr->x.pList;
|
||||
}
|
||||
assert( !ExprHasProperty(pExpr, EP_TokenOnly) );
|
||||
pFarg = pExpr->x.pList;
|
||||
nFarg = pFarg ? pFarg->nExpr : 0;
|
||||
assert( !ExprHasProperty(pExpr, EP_IntValue) );
|
||||
zId = pExpr->u.zToken;
|
||||
@@ -4488,15 +4510,23 @@ expr_code_doover:
|
||||
}
|
||||
|
||||
/*
|
||||
** Factor out the code of the given expression to initialization time.
|
||||
** Generate code that will evaluate expression pExpr just one time
|
||||
** per prepared statement execution.
|
||||
**
|
||||
** If the expression uses functions (that might throw an exception) then
|
||||
** guard them with an OP_Once opcode to ensure that the code is only executed
|
||||
** once. If no functions are involved, then factor the code out and put it at
|
||||
** the end of the prepared statement in the initialization section.
|
||||
**
|
||||
** If regDest>=0 then the result is always stored in that register and the
|
||||
** result is not reusable. If regDest<0 then this routine is free to
|
||||
** store the value whereever it wants. The register where the expression
|
||||
** is stored is returned. When regDest<0, two identical expressions will
|
||||
** code to the same register.
|
||||
** is stored is returned. When regDest<0, two identical expressions might
|
||||
** code to the same register, if they do not contain function calls and hence
|
||||
** are factored out into the initialization section at the end of the
|
||||
** prepared statement.
|
||||
*/
|
||||
int sqlite3ExprCodeAtInit(
|
||||
int sqlite3ExprCodeRunJustOnce(
|
||||
Parse *pParse, /* Parsing context */
|
||||
Expr *pExpr, /* The expression to code when the VDBE initializes */
|
||||
int regDest /* Store the value in this register */
|
||||
@@ -4514,14 +4544,29 @@ int sqlite3ExprCodeAtInit(
|
||||
}
|
||||
}
|
||||
pExpr = sqlite3ExprDup(pParse->db, pExpr, 0);
|
||||
p = sqlite3ExprListAppend(pParse, p, pExpr);
|
||||
if( p ){
|
||||
struct ExprList_item *pItem = &p->a[p->nExpr-1];
|
||||
pItem->reusable = regDest<0;
|
||||
if( regDest<0 ) regDest = ++pParse->nMem;
|
||||
pItem->u.iConstExprReg = regDest;
|
||||
if( pExpr!=0 && ExprHasProperty(pExpr, EP_HasFunc) ){
|
||||
Vdbe *v = pParse->pVdbe;
|
||||
int addr;
|
||||
assert( v );
|
||||
addr = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v);
|
||||
pParse->okConstFactor = 0;
|
||||
if( !pParse->db->mallocFailed ){
|
||||
if( regDest<0 ) regDest = ++pParse->nMem;
|
||||
sqlite3ExprCode(pParse, pExpr, regDest);
|
||||
}
|
||||
pParse->okConstFactor = 1;
|
||||
sqlite3ExprDelete(pParse->db, pExpr);
|
||||
sqlite3VdbeJumpHere(v, addr);
|
||||
}else{
|
||||
p = sqlite3ExprListAppend(pParse, p, pExpr);
|
||||
if( p ){
|
||||
struct ExprList_item *pItem = &p->a[p->nExpr-1];
|
||||
pItem->reusable = regDest<0;
|
||||
if( regDest<0 ) regDest = ++pParse->nMem;
|
||||
pItem->u.iConstExprReg = regDest;
|
||||
}
|
||||
pParse->pConstExpr = p;
|
||||
}
|
||||
pParse->pConstExpr = p;
|
||||
return regDest;
|
||||
}
|
||||
|
||||
@@ -4546,7 +4591,7 @@ int sqlite3ExprCodeTemp(Parse *pParse, Expr *pExpr, int *pReg){
|
||||
&& sqlite3ExprIsConstantNotJoin(pExpr)
|
||||
){
|
||||
*pReg = 0;
|
||||
r2 = sqlite3ExprCodeAtInit(pParse, pExpr, -1);
|
||||
r2 = sqlite3ExprCodeRunJustOnce(pParse, pExpr, -1);
|
||||
}else{
|
||||
int r1 = sqlite3GetTempReg(pParse);
|
||||
r2 = sqlite3ExprCodeTarget(pParse, pExpr, r1);
|
||||
@@ -4568,6 +4613,7 @@ int sqlite3ExprCodeTemp(Parse *pParse, Expr *pExpr, int *pReg){
|
||||
void sqlite3ExprCode(Parse *pParse, Expr *pExpr, int target){
|
||||
int inReg;
|
||||
|
||||
assert( pExpr==0 || !ExprHasVVAProperty(pExpr,EP_Immutable) );
|
||||
assert( target>0 && target<=pParse->nMem );
|
||||
inReg = sqlite3ExprCodeTarget(pParse, pExpr, target);
|
||||
assert( pParse->pVdbe!=0 || pParse->db->mallocFailed );
|
||||
@@ -4602,9 +4648,9 @@ void sqlite3ExprCodeCopy(Parse *pParse, Expr *pExpr, int target){
|
||||
*/
|
||||
void sqlite3ExprCodeFactorable(Parse *pParse, Expr *pExpr, int target){
|
||||
if( pParse->okConstFactor && sqlite3ExprIsConstantNotJoin(pExpr) ){
|
||||
sqlite3ExprCodeAtInit(pParse, pExpr, target);
|
||||
sqlite3ExprCodeRunJustOnce(pParse, pExpr, target);
|
||||
}else{
|
||||
sqlite3ExprCode(pParse, pExpr, target);
|
||||
sqlite3ExprCodeCopy(pParse, pExpr, target);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4662,7 +4708,7 @@ int sqlite3ExprCodeExprList(
|
||||
}else if( (flags & SQLITE_ECEL_FACTOR)!=0
|
||||
&& sqlite3ExprIsConstantNotJoin(pExpr)
|
||||
){
|
||||
sqlite3ExprCodeAtInit(pParse, pExpr, target+i);
|
||||
sqlite3ExprCodeRunJustOnce(pParse, pExpr, target+i);
|
||||
}else{
|
||||
int inReg = sqlite3ExprCodeTarget(pParse, pExpr, target+i);
|
||||
if( inReg!=target+i ){
|
||||
@@ -4785,6 +4831,7 @@ void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){
|
||||
assert( jumpIfNull==SQLITE_JUMPIFNULL || jumpIfNull==0 );
|
||||
if( NEVER(v==0) ) return; /* Existence of VDBE checked by caller */
|
||||
if( NEVER(pExpr==0) ) return; /* No way this can happen */
|
||||
assert( !ExprHasVVAProperty(pExpr, EP_Immutable) );
|
||||
op = pExpr->op;
|
||||
switch( op ){
|
||||
case TK_AND:
|
||||
@@ -4926,6 +4973,7 @@ void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){
|
||||
assert( jumpIfNull==SQLITE_JUMPIFNULL || jumpIfNull==0 );
|
||||
if( NEVER(v==0) ) return; /* Existence of VDBE checked by caller */
|
||||
if( pExpr==0 ) return;
|
||||
assert( !ExprHasVVAProperty(pExpr,EP_Immutable) );
|
||||
|
||||
/* The value of pExpr->op and op are related as follows:
|
||||
**
|
||||
@@ -5209,7 +5257,7 @@ int sqlite3ExprCompare(Parse *pParse, Expr *pA, Expr *pB, int iTab){
|
||||
}
|
||||
if( (pA->flags & (EP_Distinct|EP_Commuted))
|
||||
!= (pB->flags & (EP_Distinct|EP_Commuted)) ) return 2;
|
||||
if( (combinedFlags & EP_TokenOnly)==0 ){
|
||||
if( ALWAYS((combinedFlags & EP_TokenOnly)==0) ){
|
||||
if( combinedFlags & EP_xIsSelect ) return 2;
|
||||
if( (combinedFlags & EP_FixedCol)==0
|
||||
&& sqlite3ExprCompare(pParse, pA->pLeft, pB->pLeft, iTab) ) return 2;
|
||||
@@ -5217,24 +5265,10 @@ int sqlite3ExprCompare(Parse *pParse, Expr *pA, Expr *pB, int iTab){
|
||||
if( sqlite3ExprListCompare(pA->x.pList, pB->x.pList, iTab) ) return 2;
|
||||
if( pA->op!=TK_STRING
|
||||
&& pA->op!=TK_TRUEFALSE
|
||||
&& (combinedFlags & EP_Reduced)==0
|
||||
&& ALWAYS((combinedFlags & EP_Reduced)==0)
|
||||
){
|
||||
if( pA->iColumn!=pB->iColumn ) return 2;
|
||||
if( pA->op2!=pB->op2 ){
|
||||
if( pA->op==TK_TRUTH ) return 2;
|
||||
if( pA->op==TK_FUNCTION && iTab<0 ){
|
||||
/* Ex: CREATE TABLE t1(a CHECK( a<julianday('now') ));
|
||||
** INSERT INTO t1(a) VALUES(julianday('now')+10);
|
||||
** Without this test, sqlite3ExprCodeAtInit() will run on the
|
||||
** the julianday() of INSERT first, and remember that expression.
|
||||
** Then sqlite3ExprCodeInit() will see the julianday() in the CHECK
|
||||
** constraint as redundant, reusing the one from the INSERT, even
|
||||
** though the julianday() in INSERT lacks the critical NC_IsCheck
|
||||
** flag. See ticket [830277d9db6c3ba1] (2019-10-30)
|
||||
*/
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
if( pA->op2!=pB->op2 && pA->op==TK_TRUTH ) return 2;
|
||||
if( pA->op!=TK_IN && pA->iTable!=pB->iTable && pA->iTable!=iTab ){
|
||||
return 2;
|
||||
}
|
||||
|
||||
+21
-10
@@ -853,6 +853,7 @@ static void likeFunc(
|
||||
int nPat;
|
||||
sqlite3 *db = sqlite3_context_db_handle(context);
|
||||
struct compareInfo *pInfo = sqlite3_user_data(context);
|
||||
struct compareInfo backupInfo;
|
||||
|
||||
#ifdef SQLITE_LIKE_DOESNT_MATCH_BLOBS
|
||||
if( sqlite3_value_type(argv[0])==SQLITE_BLOB
|
||||
@@ -888,6 +889,12 @@ static void likeFunc(
|
||||
return;
|
||||
}
|
||||
escape = sqlite3Utf8Read(&zEsc);
|
||||
if( escape==pInfo->matchAll || escape==pInfo->matchOne ){
|
||||
memcpy(&backupInfo, pInfo, sizeof(backupInfo));
|
||||
pInfo = &backupInfo;
|
||||
if( escape==pInfo->matchAll ) pInfo->matchAll = 0;
|
||||
if( escape==pInfo->matchOne ) pInfo->matchOne = 0;
|
||||
}
|
||||
}else{
|
||||
escape = pInfo->matchSet;
|
||||
}
|
||||
@@ -1870,16 +1877,6 @@ int sqlite3IsLikeFunction(sqlite3 *db, Expr *pExpr, int *pIsNocase, char *aWc){
|
||||
if( NEVER(pDef==0) || (pDef->funcFlags & SQLITE_FUNC_LIKE)==0 ){
|
||||
return 0;
|
||||
}
|
||||
if( nExpr<3 ){
|
||||
aWc[3] = 0;
|
||||
}else{
|
||||
Expr *pEscape = pExpr->x.pList->a[2].pExpr;
|
||||
char *zEscape;
|
||||
if( pEscape->op!=TK_STRING ) return 0;
|
||||
zEscape = pEscape->u.zToken;
|
||||
if( zEscape[0]==0 || zEscape[1]!=0 ) return 0;
|
||||
aWc[3] = zEscape[0];
|
||||
}
|
||||
|
||||
/* The memcpy() statement assumes that the wildcard characters are
|
||||
** the first three statements in the compareInfo structure. The
|
||||
@@ -1889,6 +1886,20 @@ int sqlite3IsLikeFunction(sqlite3 *db, Expr *pExpr, int *pIsNocase, char *aWc){
|
||||
assert( (char*)&likeInfoAlt == (char*)&likeInfoAlt.matchAll );
|
||||
assert( &((char*)&likeInfoAlt)[1] == (char*)&likeInfoAlt.matchOne );
|
||||
assert( &((char*)&likeInfoAlt)[2] == (char*)&likeInfoAlt.matchSet );
|
||||
|
||||
if( nExpr<3 ){
|
||||
aWc[3] = 0;
|
||||
}else{
|
||||
Expr *pEscape = pExpr->x.pList->a[2].pExpr;
|
||||
char *zEscape;
|
||||
if( pEscape->op!=TK_STRING ) return 0;
|
||||
zEscape = pEscape->u.zToken;
|
||||
if( zEscape[0]==0 || zEscape[1]!=0 ) return 0;
|
||||
if( zEscape[0]==aWc[0] ) return 0;
|
||||
if( zEscape[0]==aWc[1] ) return 0;
|
||||
aWc[3] = zEscape[0];
|
||||
}
|
||||
|
||||
*pIsNocase = (pDef->funcFlags & SQLITE_FUNC_CASE)==0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
+7
-2
@@ -1606,7 +1606,7 @@ void sqlite3GenerateConstraintChecks(
|
||||
VdbeCoverage(v);
|
||||
assert( (pCol->colFlags & COLFLAG_GENERATED)==0 );
|
||||
nSeenReplace++;
|
||||
sqlite3ExprCode(pParse, pCol->pDflt, iReg);
|
||||
sqlite3ExprCodeCopy(pParse, pCol->pDflt, iReg);
|
||||
sqlite3VdbeJumpHere(v, addr1);
|
||||
break;
|
||||
}
|
||||
@@ -1661,6 +1661,7 @@ void sqlite3GenerateConstraintChecks(
|
||||
onError = overrideError!=OE_Default ? overrideError : OE_Abort;
|
||||
for(i=0; i<pCheck->nExpr; i++){
|
||||
int allOk;
|
||||
Expr *pCopy;
|
||||
Expr *pExpr = pCheck->a[i].pExpr;
|
||||
if( aiChng
|
||||
&& !sqlite3ExprReferencesUpdatedColumn(pExpr, aiChng, pkChng)
|
||||
@@ -1675,7 +1676,11 @@ void sqlite3GenerateConstraintChecks(
|
||||
}
|
||||
allOk = sqlite3VdbeMakeLabel(pParse);
|
||||
sqlite3VdbeVerifyAbortable(v, onError);
|
||||
sqlite3ExprIfTrue(pParse, pExpr, allOk, SQLITE_JUMPIFNULL);
|
||||
pCopy = sqlite3ExprDup(db, pExpr, 0);
|
||||
if( !db->mallocFailed ){
|
||||
sqlite3ExprIfTrue(pParse, pCopy, allOk, SQLITE_JUMPIFNULL);
|
||||
}
|
||||
sqlite3ExprDelete(db, pCopy);
|
||||
if( onError==OE_Ignore ){
|
||||
sqlite3VdbeGoto(v, ignoreDest);
|
||||
}else{
|
||||
|
||||
@@ -477,6 +477,7 @@ static const sqlite3_api_routines sqlite3Apis = {
|
||||
/* Version 3.32.0 and later */
|
||||
sqlite3_create_filename,
|
||||
sqlite3_free_filename,
|
||||
sqlite3_database_file_object,
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
+43
-36
@@ -1569,9 +1569,21 @@ static int sqliteDefaultBusyCallback(
|
||||
#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
|
||||
if( sqlite3OsFileControl(pFile,SQLITE_FCNTL_LOCK_TIMEOUT,&tmout)==SQLITE_OK ){
|
||||
if( count ){
|
||||
tmout = 0;
|
||||
sqlite3OsFileControl(pFile, SQLITE_FCNTL_LOCK_TIMEOUT, &tmout);
|
||||
return 0;
|
||||
/* If this is the second or later invocation of the busy-handler,
|
||||
** but tmout==0, then code in wal.c must have disabled the blocking
|
||||
** lock before the SQLITE_BUSY error was hit. In this case, no delay
|
||||
** occurred while waiting for the lock, so fall through to the xSleep()
|
||||
** code below to delay a while before retrying the lock.
|
||||
**
|
||||
** Alternatively, if tmout!=0, then SQLite has already waited
|
||||
** sqlite3.busyTimeout ms for a lock. In this case, return 0 to
|
||||
** indicate that the lock should not be retried and the SQLITE_BUSY
|
||||
** error returned to the application. */
|
||||
if( tmout ){
|
||||
tmout = 0;
|
||||
sqlite3OsFileControl(pFile, SQLITE_FCNTL_LOCK_TIMEOUT, &tmout);
|
||||
return 0;
|
||||
}
|
||||
}else{
|
||||
return 1;
|
||||
}
|
||||
@@ -1721,7 +1733,7 @@ void sqlite3_interrupt(sqlite3 *db){
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
db->u1.isInterrupted = 1;
|
||||
AtomicStore(&db->u1.isInterrupted, 1);
|
||||
}
|
||||
|
||||
|
||||
@@ -2343,7 +2355,7 @@ int sqlite3_wal_checkpoint_v2(
|
||||
/* If there are no active statements, clear the interrupt flag at this
|
||||
** point. */
|
||||
if( db->nVdbeActive==0 ){
|
||||
db->u1.isInterrupted = 0;
|
||||
AtomicStore(&db->u1.isInterrupted, 0);
|
||||
}
|
||||
|
||||
sqlite3_mutex_leave(db->mutex);
|
||||
@@ -2753,9 +2765,11 @@ int sqlite3_limit(sqlite3 *db, int limitId, int newLimit){
|
||||
**
|
||||
** If successful, SQLITE_OK is returned. In this case *ppVfs is set to point to
|
||||
** the VFS that should be used to open the database file. *pzFile is set to
|
||||
** point to a buffer containing the name of the file to open. It is the
|
||||
** responsibility of the caller to eventually call sqlite3_free() to release
|
||||
** this buffer.
|
||||
** point to a buffer containing the name of the file to open. The value
|
||||
** stored in *pzFile is a database name acceptable to sqlite3_uri_parameter()
|
||||
** and is in the same format as names created using sqlite3_create_filename().
|
||||
** The caller must invoke sqlite3_free_filename() (not sqlite3_free()!) on
|
||||
** the value returned in *pzFile to avoid a memory leak.
|
||||
**
|
||||
** If an error occurs, then an SQLite error code is returned and *pzErrMsg
|
||||
** may be set to point to a buffer containing an English language error
|
||||
@@ -2787,7 +2801,7 @@ int sqlite3ParseUri(
|
||||
int eState; /* Parser state when parsing URI */
|
||||
int iIn; /* Input character index */
|
||||
int iOut = 0; /* Output character index */
|
||||
u64 nByte = nUri+2; /* Bytes of space to allocate */
|
||||
u64 nByte = nUri+8; /* Bytes of space to allocate */
|
||||
|
||||
/* Make sure the SQLITE_OPEN_URI flag is set to indicate to the VFS xOpen
|
||||
** method that there may be extra parameters following the file-name. */
|
||||
@@ -2797,6 +2811,9 @@ int sqlite3ParseUri(
|
||||
zFile = sqlite3_malloc64(nByte);
|
||||
if( !zFile ) return SQLITE_NOMEM_BKPT;
|
||||
|
||||
memset(zFile, 0, 4); /* 4-byte of 0x00 is the start of DB name marker */
|
||||
zFile += 4;
|
||||
|
||||
iIn = 5;
|
||||
#ifdef SQLITE_ALLOW_URI_AUTHORITY
|
||||
if( strncmp(zUri+5, "///", 3)==0 ){
|
||||
@@ -2886,8 +2903,7 @@ int sqlite3ParseUri(
|
||||
zFile[iOut++] = c;
|
||||
}
|
||||
if( eState==1 ) zFile[iOut++] = '\0';
|
||||
zFile[iOut++] = '\0';
|
||||
zFile[iOut++] = '\0';
|
||||
memset(zFile+iOut, 0, 4); /* end-of-options + empty journal filenames */
|
||||
|
||||
/* Check if there were any options specified that should be interpreted
|
||||
** here. Options that are interpreted here include "vfs" and those that
|
||||
@@ -2967,13 +2983,14 @@ int sqlite3ParseUri(
|
||||
}
|
||||
|
||||
}else{
|
||||
zFile = sqlite3_malloc64(nUri+2);
|
||||
zFile = sqlite3_malloc64(nUri+8);
|
||||
if( !zFile ) return SQLITE_NOMEM_BKPT;
|
||||
memset(zFile, 0, 4);
|
||||
zFile += 4;
|
||||
if( nUri ){
|
||||
memcpy(zFile, zUri, nUri);
|
||||
}
|
||||
zFile[nUri] = '\0';
|
||||
zFile[nUri+1] = '\0';
|
||||
memset(zFile+nUri, 0, 4);
|
||||
flags &= ~SQLITE_OPEN_URI;
|
||||
}
|
||||
|
||||
@@ -2984,7 +3001,7 @@ int sqlite3ParseUri(
|
||||
}
|
||||
parse_uri_out:
|
||||
if( rc!=SQLITE_OK ){
|
||||
sqlite3_free(zFile);
|
||||
sqlite3_free_filename(zFile);
|
||||
zFile = 0;
|
||||
}
|
||||
*pFlags = flags;
|
||||
@@ -3194,11 +3211,6 @@ static int openDatabase(
|
||||
if( db->mallocFailed ){
|
||||
goto opendb_out;
|
||||
}
|
||||
/* EVIDENCE-OF: R-08308-17224 The default collating function for all
|
||||
** strings is BINARY.
|
||||
*/
|
||||
db->pDfltColl = sqlite3FindCollSeq(db, SQLITE_UTF8, sqlite3StrBINARY, 0);
|
||||
assert( db->pDfltColl!=0 );
|
||||
|
||||
/* Parse the filename/URI argument
|
||||
**
|
||||
@@ -3243,7 +3255,9 @@ static int openDatabase(
|
||||
}
|
||||
sqlite3BtreeEnter(db->aDb[0].pBt);
|
||||
db->aDb[0].pSchema = sqlite3SchemaGet(db, db->aDb[0].pBt);
|
||||
if( !db->mallocFailed ) ENC(db) = SCHEMA_ENC(db);
|
||||
if( !db->mallocFailed ){
|
||||
sqlite3SetTextEncoding(db, SCHEMA_ENC(db));
|
||||
}
|
||||
sqlite3BtreeLeave(db->aDb[0].pBt);
|
||||
db->aDb[1].pSchema = sqlite3SchemaGet(db, 0);
|
||||
|
||||
@@ -3391,7 +3405,7 @@ opendb_out:
|
||||
sqlite3GlobalConfig.xSqllog(pArg, db, zFilename, 0);
|
||||
}
|
||||
#endif
|
||||
sqlite3_free(zOpen);
|
||||
sqlite3_free_filename(zOpen);
|
||||
return rc & 0xff;
|
||||
}
|
||||
|
||||
@@ -3829,6 +3843,13 @@ int sqlite3_file_control(sqlite3 *db, const char *zDbName, int op, void *pArg){
|
||||
}else if( op==SQLITE_FCNTL_DATA_VERSION ){
|
||||
*(unsigned int*)pArg = sqlite3PagerDataVersion(pPager);
|
||||
rc = SQLITE_OK;
|
||||
}else if( op==SQLITE_FCNTL_RESERVE_BYTES ){
|
||||
int iNew = *(int*)pArg;
|
||||
*(int*)pArg = sqlite3BtreeGetRequestedReserve(pBtree);
|
||||
if( iNew>=0 && iNew<=254 ){
|
||||
sqlite3BtreeSetPageSize(pBtree, 0, iNew, 0);
|
||||
}
|
||||
rc = SQLITE_OK;
|
||||
}else{
|
||||
rc = sqlite3OsFileControl(fd, op, pArg);
|
||||
}
|
||||
@@ -4045,20 +4066,6 @@ int sqlite3_test_control(int op, ...){
|
||||
break;
|
||||
}
|
||||
|
||||
/* sqlite3_test_control(SQLITE_TESTCTRL_RESERVE, sqlite3 *db, int N)
|
||||
**
|
||||
** Set the nReserve size to N for the main database on the database
|
||||
** connection db.
|
||||
*/
|
||||
case SQLITE_TESTCTRL_RESERVE: {
|
||||
sqlite3 *db = va_arg(ap, sqlite3*);
|
||||
int x = va_arg(ap,int);
|
||||
sqlite3_mutex_enter(db->mutex);
|
||||
sqlite3BtreeSetPageSize(db->aDb[0].pBt, 0, x, 0);
|
||||
sqlite3_mutex_leave(db->mutex);
|
||||
break;
|
||||
}
|
||||
|
||||
/* sqlite3_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS, sqlite3 *db, int N)
|
||||
**
|
||||
** Enable or disable various optimizations for testing purposes. The
|
||||
|
||||
+2
-2
@@ -760,7 +760,7 @@ void sqlite3OomFault(sqlite3 *db){
|
||||
if( db->mallocFailed==0 && db->bBenignMalloc==0 ){
|
||||
db->mallocFailed = 1;
|
||||
if( db->nVdbeExec>0 ){
|
||||
db->u1.isInterrupted = 1;
|
||||
AtomicStore(&db->u1.isInterrupted, 1);
|
||||
}
|
||||
DisableLookaside;
|
||||
if( db->pParse ){
|
||||
@@ -779,7 +779,7 @@ void sqlite3OomFault(sqlite3 *db){
|
||||
void sqlite3OomClear(sqlite3 *db){
|
||||
if( db->mallocFailed && db->nVdbeExec==0 ){
|
||||
db->mallocFailed = 0;
|
||||
db->u1.isInterrupted = 0;
|
||||
AtomicStore(&db->u1.isInterrupted, 0);
|
||||
assert( db->lookaside.bDisable>0 );
|
||||
EnableLookaside;
|
||||
}
|
||||
|
||||
+21
-1
@@ -3685,7 +3685,7 @@ static int openDirectory(const char *zFilename, int *pFd){
|
||||
if( zDirname[0]!='/' ) zDirname[0] = '.';
|
||||
zDirname[1] = 0;
|
||||
}
|
||||
fd = robust_open(zDirname, O_RDONLY|O_BINARY|O_NOFOLLOW, 0);
|
||||
fd = robust_open(zDirname, O_RDONLY|O_BINARY, 0);
|
||||
if( fd>=0 ){
|
||||
OSTRACE(("OPENDIR %-3d %s\n", fd, zDirname));
|
||||
}
|
||||
@@ -3995,7 +3995,9 @@ static int unixFileControl(sqlite3_file *id, int op, void *pArg){
|
||||
}
|
||||
#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
|
||||
case SQLITE_FCNTL_LOCK_TIMEOUT: {
|
||||
int iOld = pFile->iBusyTimeout;
|
||||
pFile->iBusyTimeout = *(int*)pArg;
|
||||
*(int*)pArg = iOld;
|
||||
return SQLITE_OK;
|
||||
}
|
||||
#endif
|
||||
@@ -4817,6 +4819,24 @@ static int unixShmLock(
|
||||
assert( pShmNode->hShm>=0 || pDbFd->pInode->bProcessLock==1 );
|
||||
assert( pShmNode->hShm<0 || pDbFd->pInode->bProcessLock==0 );
|
||||
|
||||
/* Check that, if this to be a blocking lock, that locks have been
|
||||
** obtained in the following order.
|
||||
**
|
||||
** 1. Checkpointer lock (ofst==1).
|
||||
** 2. Recover lock (ofst==2).
|
||||
** 3. Read locks (ofst>=3 && ofst<SQLITE_SHM_NLOCK).
|
||||
** 4. Write lock (ofst==0).
|
||||
**
|
||||
** In other words, if this is a blocking lock, none of the locks that
|
||||
** occur later in the above list than the lock being obtained may be
|
||||
** held. */
|
||||
#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
|
||||
assert( pDbFd->iBusyTimeout==0
|
||||
|| (flags & SQLITE_SHM_UNLOCK) || ofst==0
|
||||
|| ((p->exclMask|p->sharedMask)&~((1<<ofst)-2))==0
|
||||
);
|
||||
#endif
|
||||
|
||||
mask = (1<<(ofst+n)) - (1<<ofst);
|
||||
assert( n>1 || mask==(1<<ofst) );
|
||||
sqlite3_mutex_enter(pShmNode->pShmMutex);
|
||||
|
||||
+17
-1
@@ -4742,6 +4742,7 @@ int sqlite3PagerOpen(
|
||||
** Database file handle (pVfs->szOsFile bytes)
|
||||
** Sub-journal file handle (journalFileSize bytes)
|
||||
** Main journal file handle (journalFileSize bytes)
|
||||
** Ptr back to the Pager (sizeof(Pager*) bytes)
|
||||
** \0\0\0\0 database prefix (4 bytes)
|
||||
** Database file name (nPathname+1 bytes)
|
||||
** URI query parameters (nUriByte bytes)
|
||||
@@ -4781,6 +4782,7 @@ int sqlite3PagerOpen(
|
||||
ROUND8(pcacheSize) + /* PCache object */
|
||||
ROUND8(pVfs->szOsFile) + /* The main db file */
|
||||
journalFileSize * 2 + /* The two journal files */
|
||||
sizeof(pPager) + /* Space to hold a pointer */
|
||||
4 + /* Database prefix */
|
||||
nPathname + 1 + /* database filename */
|
||||
nUriByte + /* query parameters */
|
||||
@@ -4801,6 +4803,7 @@ int sqlite3PagerOpen(
|
||||
pPager->sjfd = (sqlite3_file*)pPtr; pPtr += journalFileSize;
|
||||
pPager->jfd = (sqlite3_file*)pPtr; pPtr += journalFileSize;
|
||||
assert( EIGHT_BYTE_ALIGNMENT(pPager->jfd) );
|
||||
memcpy(pPtr, &pPager, sizeof(pPager)); pPtr += sizeof(pPager);
|
||||
|
||||
/* Fill in the Pager.zFilename and pPager.zQueryParam fields */
|
||||
pPtr += 4; /* Skip zero prefix */
|
||||
@@ -5001,6 +5004,19 @@ act_like_temp_file:
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Return the sqlite3_file for the main database given the name
|
||||
** of the corresonding WAL or Journal name as passed into
|
||||
** xOpen.
|
||||
*/
|
||||
sqlite3_file *sqlite3_database_file_object(const char *zName){
|
||||
Pager *pPager;
|
||||
while( zName[-1]!=0 || zName[-2]!=0 || zName[-3]!=0 || zName[-4]!=0 ){
|
||||
zName--;
|
||||
}
|
||||
pPager = *(Pager**)(zName - 4 - sizeof(Pager*));
|
||||
return pPager->fd;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
@@ -6959,7 +6975,7 @@ int sqlite3PagerSavepoint(Pager *pPager, int op, int iSavepoint){
|
||||
** sqlite3_uri_parameter() and sqlite3_filename_database() and friends.
|
||||
*/
|
||||
const char *sqlite3PagerFilename(const Pager *pPager, int nullIfMemDb){
|
||||
static const char zFake[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
static const char zFake[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
return (nullIfMemDb && pPager->memDb) ? &zFake[4] : pPager->zFilename;
|
||||
}
|
||||
|
||||
|
||||
+3
-1
@@ -965,6 +965,7 @@ idlist(A) ::= nm(Y).
|
||||
p->op = (u8)op;
|
||||
p->affExpr = 0;
|
||||
p->flags = EP_Leaf;
|
||||
ExprClearVVAProperties(p);
|
||||
p->iAgg = -1;
|
||||
p->pLeft = p->pRight = 0;
|
||||
p->x.pList = 0;
|
||||
@@ -1193,10 +1194,11 @@ expr(A) ::= expr(A) between_op(N) expr(X) AND expr(Y). [BETWEEN] {
|
||||
*/
|
||||
sqlite3ExprUnmapAndDelete(pParse, A);
|
||||
A = sqlite3Expr(pParse->db, TK_INTEGER, N ? "1" : "0");
|
||||
}else if( 0 && Y->nExpr==1 && sqlite3ExprIsConstant(Y->a[0].pExpr) ){
|
||||
}else if( Y->nExpr==1 && sqlite3ExprIsConstant(Y->a[0].pExpr) ){
|
||||
Expr *pRHS = Y->a[0].pExpr;
|
||||
Y->a[0].pExpr = 0;
|
||||
sqlite3ExprListDelete(pParse->db, Y);
|
||||
pRHS = sqlite3PExpr(pParse, TK_UPLUS, pRHS, 0);
|
||||
A = sqlite3PExpr(pParse, TK_EQ, A, pRHS);
|
||||
if( N ) A = sqlite3PExpr(pParse, TK_NOT, A, 0);
|
||||
}else{
|
||||
|
||||
+4
-13
@@ -1824,21 +1824,12 @@ void sqlite3Pragma(
|
||||
** will be overwritten when the schema is next loaded. If it does not
|
||||
** already exists, it will be created to use the new encoding value.
|
||||
*/
|
||||
int canChangeEnc = 1; /* True if allowed to change the encoding */
|
||||
int i; /* For looping over all attached databases */
|
||||
for(i=0; i<db->nDb; i++){
|
||||
if( db->aDb[i].pBt!=0
|
||||
&& DbHasProperty(db,i,DB_SchemaLoaded)
|
||||
&& !DbHasProperty(db,i,DB_Empty)
|
||||
){
|
||||
canChangeEnc = 0;
|
||||
}
|
||||
}
|
||||
if( canChangeEnc ){
|
||||
if( (db->mDbFlags & DBFLAG_EncodingFixed)==0 ){
|
||||
for(pEnc=&encnames[0]; pEnc->zName; pEnc++){
|
||||
if( 0==sqlite3StrICmp(zRight, pEnc->zName) ){
|
||||
SCHEMA_ENC(db) = ENC(db) =
|
||||
pEnc->enc ? pEnc->enc : SQLITE_UTF16NATIVE;
|
||||
u8 enc = pEnc->enc ? pEnc->enc : SQLITE_UTF16NATIVE;
|
||||
SCHEMA_ENC(db) = enc;
|
||||
sqlite3SetTextEncoding(db, enc);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
+9
-10
@@ -91,7 +91,7 @@ int sqlite3InitCallback(void *pInit, int argc, char **argv, char **NotUsed){
|
||||
assert( argc==5 );
|
||||
UNUSED_PARAMETER2(NotUsed, argc);
|
||||
assert( sqlite3_mutex_held(db->mutex) );
|
||||
DbClearProperty(db, iDb, DB_Empty);
|
||||
db->mDbFlags |= DBFLAG_EncodingFixed;
|
||||
pData->nInitRow++;
|
||||
if( db->mallocFailed ){
|
||||
corruptSchema(pData, argv[1], 0);
|
||||
@@ -179,6 +179,7 @@ int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg, u32 mFlags){
|
||||
InitData initData;
|
||||
const char *zMasterName;
|
||||
int openedTransaction = 0;
|
||||
int mask = ((db->mDbFlags & DBFLAG_EncodingFixed) | ~DBFLAG_EncodingFixed);
|
||||
|
||||
assert( (db->mDbFlags & DBFLAG_SchemaKnownOk)==0 );
|
||||
assert( iDb>=0 && iDb<db->nDb );
|
||||
@@ -207,6 +208,7 @@ int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg, u32 mFlags){
|
||||
initData.mInitFlags = mFlags;
|
||||
initData.nInitRow = 0;
|
||||
sqlite3InitCallback(&initData, 5, (char **)azArg, 0);
|
||||
db->mDbFlags &= mask;
|
||||
if( initData.rc ){
|
||||
rc = initData.rc;
|
||||
goto error_out;
|
||||
@@ -266,27 +268,25 @@ int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg, u32 mFlags){
|
||||
** as sqlite3.enc.
|
||||
*/
|
||||
if( meta[BTREE_TEXT_ENCODING-1] ){ /* text encoding */
|
||||
if( iDb==0 ){
|
||||
#ifndef SQLITE_OMIT_UTF16
|
||||
if( iDb==0 && (db->mDbFlags & DBFLAG_EncodingFixed)==0 ){
|
||||
u8 encoding;
|
||||
#ifndef SQLITE_OMIT_UTF16
|
||||
/* If opening the main database, set ENC(db). */
|
||||
encoding = (u8)meta[BTREE_TEXT_ENCODING-1] & 3;
|
||||
if( encoding==0 ) encoding = SQLITE_UTF8;
|
||||
ENC(db) = encoding;
|
||||
#else
|
||||
ENC(db) = SQLITE_UTF8;
|
||||
encoding = SQLITE_UTF8;
|
||||
#endif
|
||||
sqlite3SetTextEncoding(db, encoding);
|
||||
}else{
|
||||
/* If opening an attached database, the encoding much match ENC(db) */
|
||||
if( meta[BTREE_TEXT_ENCODING-1]!=ENC(db) ){
|
||||
if( (meta[BTREE_TEXT_ENCODING-1] & 3)!=ENC(db) ){
|
||||
sqlite3SetString(pzErrMsg, db, "attached databases must use the same"
|
||||
" text encoding as main database");
|
||||
rc = SQLITE_ERROR;
|
||||
goto initone_error_out;
|
||||
}
|
||||
}
|
||||
}else{
|
||||
DbSetProperty(db, iDb, DB_Empty);
|
||||
}
|
||||
pDb->pSchema->enc = ENC(db);
|
||||
|
||||
@@ -398,8 +398,7 @@ error_out:
|
||||
** error occurs, write an error message into *pzErrMsg.
|
||||
**
|
||||
** After a database is initialized, the DB_SchemaLoaded bit is set
|
||||
** bit is set in the flags field of the Db structure. If the database
|
||||
** file was of zero-length, then the DB_Empty flag is also set.
|
||||
** bit is set in the flags field of the Db structure.
|
||||
*/
|
||||
int sqlite3Init(sqlite3 *db, char **pzErrMsg){
|
||||
int i, rc;
|
||||
|
||||
+72
-23
@@ -140,7 +140,7 @@ int sqlite3MatchEName(
|
||||
){
|
||||
int n;
|
||||
const char *zSpan;
|
||||
if( NEVER(pItem->eEName!=ENAME_TAB) ) return 0;
|
||||
if( pItem->eEName!=ENAME_TAB ) return 0;
|
||||
zSpan = pItem->zEName;
|
||||
for(n=0; ALWAYS(zSpan[n]) && zSpan[n]!='.'; n++){}
|
||||
if( zDb && (sqlite3StrNICmp(zSpan, zDb, n)!=0 || zDb[n]!=0) ){
|
||||
@@ -175,6 +175,31 @@ static int areDoubleQuotedStringsEnabled(sqlite3 *db, NameContext *pTopNC){
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** The argument is guaranteed to be a non-NULL Expr node of type TK_COLUMN.
|
||||
** return the appropriate colUsed mask.
|
||||
*/
|
||||
Bitmask sqlite3ExprColUsed(Expr *pExpr){
|
||||
int n;
|
||||
Table *pExTab;
|
||||
|
||||
n = pExpr->iColumn;
|
||||
pExTab = pExpr->y.pTab;
|
||||
assert( pExTab!=0 );
|
||||
if( (pExTab->tabFlags & TF_HasGenerated)!=0
|
||||
&& (pExTab->aCol[n].colFlags & COLFLAG_GENERATED)!=0
|
||||
){
|
||||
testcase( pExTab->nCol==BMS-1 );
|
||||
testcase( pExTab->nCol==BMS );
|
||||
return pExTab->nCol>=BMS ? ALLBITS : MASKBIT(pExTab->nCol)-1;
|
||||
}else{
|
||||
testcase( n==BMS-1 );
|
||||
testcase( n==BMS );
|
||||
if( n>=BMS ) n = BMS-1;
|
||||
return ((Bitmask)1)<<n;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Given the name of a column of the form X.Y.Z or Y.Z or just Z, look up
|
||||
** that name in the set of source tables in pSrcList and make the pExpr
|
||||
@@ -252,6 +277,12 @@ static int lookupName(
|
||||
break;
|
||||
}
|
||||
}
|
||||
if( i==db->nDb && sqlite3StrICmp("main", zDb)==0 ){
|
||||
/* This branch is taken when the main database has been renamed
|
||||
** using SQLITE_DBCONFIG_MAINDBNAME. */
|
||||
pSchema = db->aDb[0].pSchema;
|
||||
zDb = db->aDb[0].zDbSName;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -263,6 +294,7 @@ static int lookupName(
|
||||
|
||||
if( pSrcList ){
|
||||
for(i=0, pItem=pSrcList->a; i<pSrcList->nSrc; i++, pItem++){
|
||||
u8 hCol;
|
||||
pTab = pItem->pTab;
|
||||
assert( pTab!=0 && pTab->zName!=0 );
|
||||
assert( pTab->nCol>0 );
|
||||
@@ -296,8 +328,9 @@ static int lookupName(
|
||||
if( 0==(cntTab++) ){
|
||||
pMatch = pItem;
|
||||
}
|
||||
hCol = sqlite3StrIHash(zCol);
|
||||
for(j=0, pCol=pTab->aCol; j<pTab->nCol; j++, pCol++){
|
||||
if( sqlite3StrICmp(pCol->zName, zCol)==0 ){
|
||||
if( pCol->hName==hCol && sqlite3StrICmp(pCol->zName, zCol)==0 ){
|
||||
/* If there has been exactly one prior match and this match
|
||||
** is for the right-hand table of a NATURAL JOIN or is in a
|
||||
** USING clause, then skip this match.
|
||||
@@ -358,10 +391,11 @@ static int lookupName(
|
||||
|
||||
if( pTab ){
|
||||
int iCol;
|
||||
u8 hCol = sqlite3StrIHash(zCol);
|
||||
pSchema = pTab->pSchema;
|
||||
cntTab++;
|
||||
for(iCol=0, pCol=pTab->aCol; iCol<pTab->nCol; iCol++, pCol++){
|
||||
if( sqlite3StrICmp(pCol->zName, zCol)==0 ){
|
||||
if( pCol->hName==hCol && sqlite3StrICmp(pCol->zName, zCol)==0 ){
|
||||
if( iCol==pTab->iPKey ){
|
||||
iCol = -1;
|
||||
}
|
||||
@@ -571,22 +605,7 @@ static int lookupName(
|
||||
** of the table.
|
||||
*/
|
||||
if( pExpr->iColumn>=0 && pMatch!=0 ){
|
||||
int n = pExpr->iColumn;
|
||||
Table *pExTab = pExpr->y.pTab;
|
||||
assert( pExTab!=0 );
|
||||
assert( pMatch->iCursor==pExpr->iTable );
|
||||
if( (pExTab->tabFlags & TF_HasGenerated)!=0
|
||||
&& (pExTab->aCol[n].colFlags & COLFLAG_GENERATED)!=0
|
||||
){
|
||||
testcase( pExTab->nCol==BMS-1 );
|
||||
testcase( pExTab->nCol==BMS );
|
||||
pMatch->colUsed = pExTab->nCol>=BMS ? ALLBITS : MASKBIT(pExTab->nCol)-1;
|
||||
}else{
|
||||
testcase( n==BMS-1 );
|
||||
testcase( n==BMS );
|
||||
if( n>=BMS ) n = BMS-1;
|
||||
pMatch->colUsed |= ((Bitmask)1)<<n;
|
||||
}
|
||||
pMatch->colUsed |= sqlite3ExprColUsed(pExpr);
|
||||
}
|
||||
|
||||
/* Clean up and return
|
||||
@@ -1177,7 +1196,7 @@ static int resolveOrderByTermToExprList(
|
||||
nc.nErr = 0;
|
||||
db = pParse->db;
|
||||
savedSuppErr = db->suppressErr;
|
||||
db->suppressErr = 1;
|
||||
if( IN_RENAME_OBJECT==0 ) db->suppressErr = 1;
|
||||
rc = sqlite3ResolveExprNames(&nc, pE);
|
||||
db->suppressErr = savedSuppErr;
|
||||
if( rc ) return 0;
|
||||
@@ -1812,11 +1831,41 @@ int sqlite3ResolveExprListNames(
|
||||
ExprList *pList /* The expression list to be analyzed. */
|
||||
){
|
||||
int i;
|
||||
if( pList ){
|
||||
for(i=0; i<pList->nExpr; i++){
|
||||
if( sqlite3ResolveExprNames(pNC, pList->a[i].pExpr) ) return WRC_Abort;
|
||||
int savedHasAgg = 0;
|
||||
Walker w;
|
||||
if( pList==0 ) return WRC_Continue;
|
||||
w.pParse = pNC->pParse;
|
||||
w.xExprCallback = resolveExprStep;
|
||||
w.xSelectCallback = resolveSelectStep;
|
||||
w.xSelectCallback2 = 0;
|
||||
w.u.pNC = pNC;
|
||||
savedHasAgg = pNC->ncFlags & (NC_HasAgg|NC_MinMaxAgg|NC_HasWin);
|
||||
pNC->ncFlags &= ~(NC_HasAgg|NC_MinMaxAgg|NC_HasWin);
|
||||
for(i=0; i<pList->nExpr; i++){
|
||||
Expr *pExpr = pList->a[i].pExpr;
|
||||
if( pExpr==0 ) continue;
|
||||
#if SQLITE_MAX_EXPR_DEPTH>0
|
||||
w.pParse->nHeight += pExpr->nHeight;
|
||||
if( sqlite3ExprCheckHeight(w.pParse, w.pParse->nHeight) ){
|
||||
return WRC_Abort;
|
||||
}
|
||||
#endif
|
||||
sqlite3WalkExpr(&w, pExpr);
|
||||
#if SQLITE_MAX_EXPR_DEPTH>0
|
||||
w.pParse->nHeight -= pExpr->nHeight;
|
||||
#endif
|
||||
assert( EP_Agg==NC_HasAgg );
|
||||
assert( EP_Win==NC_HasWin );
|
||||
testcase( pNC->ncFlags & NC_HasAgg );
|
||||
testcase( pNC->ncFlags & NC_HasWin );
|
||||
if( pNC->ncFlags & (NC_HasAgg|NC_MinMaxAgg|NC_HasWin) ){
|
||||
ExprSetProperty(pExpr, pNC->ncFlags & (NC_HasAgg|NC_HasWin) );
|
||||
savedHasAgg |= pNC->ncFlags & (NC_HasAgg|NC_MinMaxAgg|NC_HasWin);
|
||||
pNC->ncFlags &= ~(NC_HasAgg|NC_MinMaxAgg|NC_HasWin);
|
||||
}
|
||||
if( pNC->nErr>0 || w.pParse->nErr>0 ) return WRC_Abort;
|
||||
}
|
||||
pNC->ncFlags |= savedHasAgg;
|
||||
return WRC_Continue;
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -177,7 +177,7 @@ void sqlite3RowSetDelete(void *pArg){
|
||||
/*
|
||||
** Allocate a new RowSetEntry object that is associated with the
|
||||
** given RowSet. Return a pointer to the new and completely uninitialized
|
||||
** objected.
|
||||
** object.
|
||||
**
|
||||
** In an OOM situation, the RowSet.db->mallocFailed flag is set and this
|
||||
** routine returns NULL.
|
||||
@@ -453,7 +453,7 @@ int sqlite3RowSetTest(RowSet *pRowSet, int iBatch, sqlite3_int64 iRowid){
|
||||
if( p ){
|
||||
struct RowSetEntry **ppPrevTree = &pRowSet->pForest;
|
||||
if( (pRowSet->rsFlags & ROWSET_SORTED)==0 ){ /*OPTIMIZATION-IF-FALSE*/
|
||||
/* Only sort the current set of entiries if they need it */
|
||||
/* Only sort the current set of entries if they need it */
|
||||
p = rowSetEntrySort(p);
|
||||
}
|
||||
for(pTree = pRowSet->pForest; pTree; pTree=pTree->pRight){
|
||||
|
||||
+48
-4
@@ -103,7 +103,6 @@ static void clearSelect(sqlite3 *db, Select *p, int bFree){
|
||||
if( OK_IF_ALWAYS_TRUE(p->pWinDefn) ){
|
||||
sqlite3WindowListDelete(db, p->pWinDefn);
|
||||
}
|
||||
assert( p->pWin==0 );
|
||||
#endif
|
||||
if( OK_IF_ALWAYS_TRUE(p->pWith) ) sqlite3WithDelete(db, p->pWith);
|
||||
if( bFree ) sqlite3DbFreeNN(db, p);
|
||||
@@ -2024,6 +2023,7 @@ int sqlite3ColumnsFromExprList(
|
||||
if( cnt>3 ) sqlite3_randomness(sizeof(cnt), &cnt);
|
||||
}
|
||||
pCol->zName = zName;
|
||||
pCol->hName = sqlite3StrIHash(zName);
|
||||
sqlite3ColumnPropertiesFromName(0, pCol);
|
||||
if( zName && sqlite3HashInsert(&ht, zName, pCol)==pCol ){
|
||||
sqlite3OomFault(db);
|
||||
@@ -3477,7 +3477,10 @@ static Expr *substExpr(
|
||||
){
|
||||
pExpr->iRightJoinTable = pSubst->iNewTable;
|
||||
}
|
||||
if( pExpr->op==TK_COLUMN && pExpr->iTable==pSubst->iTable ){
|
||||
if( pExpr->op==TK_COLUMN
|
||||
&& pExpr->iTable==pSubst->iTable
|
||||
&& !ExprHasProperty(pExpr, EP_FixedCol)
|
||||
){
|
||||
if( pExpr->iColumn<0 ){
|
||||
pExpr->op = TK_NULL;
|
||||
}else{
|
||||
@@ -3581,6 +3584,38 @@ static void substSelect(
|
||||
}
|
||||
#endif /* !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) */
|
||||
|
||||
#if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW)
|
||||
/*
|
||||
** pSelect is a SELECT statement and pSrcItem is one item in the FROM
|
||||
** clause of that SELECT.
|
||||
**
|
||||
** This routine scans the entire SELECT statement and recomputes the
|
||||
** pSrcItem->colUsed mask.
|
||||
*/
|
||||
static int recomputeColumnsUsedExpr(Walker *pWalker, Expr *pExpr){
|
||||
struct SrcList_item *pItem;
|
||||
if( pExpr->op!=TK_COLUMN ) return WRC_Continue;
|
||||
pItem = pWalker->u.pSrcItem;
|
||||
if( pItem->iCursor!=pExpr->iTable ) return WRC_Continue;
|
||||
if( pExpr->iColumn<0 ) return WRC_Continue;
|
||||
pItem->colUsed |= sqlite3ExprColUsed(pExpr);
|
||||
return WRC_Continue;
|
||||
}
|
||||
static void recomputeColumnsUsed(
|
||||
Select *pSelect, /* The complete SELECT statement */
|
||||
struct SrcList_item *pSrcItem /* Which FROM clause item to recompute */
|
||||
){
|
||||
Walker w;
|
||||
if( NEVER(pSrcItem->pTab==0) ) return;
|
||||
memset(&w, 0, sizeof(w));
|
||||
w.xExprCallback = recomputeColumnsUsedExpr;
|
||||
w.xSelectCallback = sqlite3SelectWalkNoop;
|
||||
w.u.pSrcItem = pSrcItem;
|
||||
pSrcItem->colUsed = 0;
|
||||
sqlite3WalkSelect(&w, pSelect);
|
||||
}
|
||||
#endif /* !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) */
|
||||
|
||||
#if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW)
|
||||
/*
|
||||
** This routine attempts to flatten subqueries as a performance optimization.
|
||||
@@ -4119,6 +4154,12 @@ static int flattenSubquery(
|
||||
pParent->pLimit = pSub->pLimit;
|
||||
pSub->pLimit = 0;
|
||||
}
|
||||
|
||||
/* Recompute the SrcList_item.colUsed masks for the flattened
|
||||
** tables. */
|
||||
for(i=0; i<nSubSrc; i++){
|
||||
recomputeColumnsUsed(pParent, &pSrc->a[i+iFrom]);
|
||||
}
|
||||
}
|
||||
|
||||
/* Finially, delete what is left of the subquery and return
|
||||
@@ -4466,7 +4507,7 @@ static u8 minMaxQuery(sqlite3 *db, Expr *pFunc, ExprList **ppMinMax){
|
||||
ExprList *pEList = pFunc->x.pList; /* Arguments to agg function */
|
||||
const char *zFunc; /* Name of aggregate function pFunc */
|
||||
ExprList *pOrderBy;
|
||||
u8 sortFlags;
|
||||
u8 sortFlags = 0;
|
||||
|
||||
assert( *ppMinMax==0 );
|
||||
assert( pFunc->op==TK_AGG_FUNCTION );
|
||||
@@ -4477,7 +4518,9 @@ static u8 minMaxQuery(sqlite3 *db, Expr *pFunc, ExprList **ppMinMax){
|
||||
zFunc = pFunc->u.zToken;
|
||||
if( sqlite3StrICmp(zFunc, "min")==0 ){
|
||||
eRet = WHERE_ORDERBY_MIN;
|
||||
sortFlags = KEYINFO_ORDER_BIGNULL;
|
||||
if( sqlite3ExprCanBeNull(pEList->a[0].pExpr) ){
|
||||
sortFlags = KEYINFO_ORDER_BIGNULL;
|
||||
}
|
||||
}else if( sqlite3StrICmp(zFunc, "max")==0 ){
|
||||
eRet = WHERE_ORDERBY_MAX;
|
||||
sortFlags = KEYINFO_ORDER_DESC;
|
||||
@@ -5349,6 +5392,7 @@ static void resetAccumulator(Parse *pParse, AggInfo *pAggInfo){
|
||||
struct AggInfo_func *pFunc;
|
||||
int nReg = pAggInfo->nFunc + pAggInfo->nColumn;
|
||||
if( nReg==0 ) return;
|
||||
if( pParse->nErr ) return;
|
||||
#ifdef SQLITE_DEBUG
|
||||
/* Verify that all AggInfo registers are within the range specified by
|
||||
** AggInfo.mnReg..AggInfo.mxReg */
|
||||
|
||||
+412
-141
@@ -17,6 +17,14 @@
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Determine if we are dealing with WinRT, which provides only a subset of
|
||||
** the full Win32 API.
|
||||
*/
|
||||
#if !defined(SQLITE_OS_WINRT)
|
||||
# define SQLITE_OS_WINRT 0
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Warning pragmas copied from msvc.h in the core.
|
||||
*/
|
||||
@@ -129,22 +137,26 @@ typedef unsigned char u8;
|
||||
|
||||
|
||||
#if defined(_WIN32) || defined(WIN32)
|
||||
# include <io.h>
|
||||
# include <fcntl.h>
|
||||
# define isatty(h) _isatty(h)
|
||||
# ifndef access
|
||||
# define access(f,m) _access((f),(m))
|
||||
# if SQLITE_OS_WINRT
|
||||
# define SQLITE_OMIT_POPEN 1
|
||||
# else
|
||||
# include <io.h>
|
||||
# include <fcntl.h>
|
||||
# define isatty(h) _isatty(h)
|
||||
# ifndef access
|
||||
# define access(f,m) _access((f),(m))
|
||||
# endif
|
||||
# ifndef unlink
|
||||
# define unlink _unlink
|
||||
# endif
|
||||
# ifndef strdup
|
||||
# define strdup _strdup
|
||||
# endif
|
||||
# undef popen
|
||||
# define popen _popen
|
||||
# undef pclose
|
||||
# define pclose _pclose
|
||||
# endif
|
||||
# ifndef unlink
|
||||
# define unlink _unlink
|
||||
# endif
|
||||
# ifndef strdup
|
||||
# define strdup _strdup
|
||||
# endif
|
||||
# undef popen
|
||||
# define popen _popen
|
||||
# undef pclose
|
||||
# define pclose _pclose
|
||||
#else
|
||||
/* Make sure isatty() has a prototype. */
|
||||
extern int isatty(int);
|
||||
@@ -173,6 +185,9 @@ typedef unsigned char u8;
|
||||
#define ToLower(X) (char)tolower((unsigned char)X)
|
||||
|
||||
#if defined(_WIN32) || defined(WIN32)
|
||||
#if SQLITE_OS_WINRT
|
||||
#include <intrin.h>
|
||||
#endif
|
||||
#include <windows.h>
|
||||
|
||||
/* string conversion routines only needed on Win32 */
|
||||
@@ -188,7 +203,7 @@ extern LPWSTR sqlite3_win32_utf8_to_unicode(const char *zText);
|
||||
** rendering quoted strings that contain \n characters). The following
|
||||
** routines take care of that.
|
||||
*/
|
||||
#if defined(_WIN32) || defined(WIN32)
|
||||
#if (defined(_WIN32) || defined(WIN32)) && !SQLITE_OS_WINRT
|
||||
static void setBinaryMode(FILE *file, int isOutput){
|
||||
if( isOutput ) fflush(file);
|
||||
_setmode(_fileno(file), _O_BINARY);
|
||||
@@ -292,6 +307,7 @@ static int hasTimer(void){
|
||||
if( getProcessTimesAddr ){
|
||||
return 1;
|
||||
} else {
|
||||
#if !SQLITE_OS_WINRT
|
||||
/* GetProcessTimes() isn't supported in WIN95 and some other Windows
|
||||
** versions. See if the version we are running on has it, and if it
|
||||
** does, save off a pointer to it and the current process handle.
|
||||
@@ -308,6 +324,7 @@ static int hasTimer(void){
|
||||
FreeLibrary(hinstLib);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -397,6 +414,15 @@ static sqlite3 *globalDb = 0;
|
||||
*/
|
||||
static volatile int seenInterrupt = 0;
|
||||
|
||||
#ifdef SQLITE_DEBUG
|
||||
/*
|
||||
** Out-of-memory simulator variables
|
||||
*/
|
||||
static unsigned int oomCounter = 0; /* Simulate OOM when equals 1 */
|
||||
static unsigned int oomRepeat = 0; /* Number of OOMs in a row */
|
||||
static void*(*defaultMalloc)(int) = 0; /* The low-level malloc routine */
|
||||
#endif /* SQLITE_DEBUG */
|
||||
|
||||
/*
|
||||
** This is the name of our program. It is set in main(), used
|
||||
** in a number of other places, mostly for error messages.
|
||||
@@ -448,6 +474,49 @@ static void shell_out_of_memory(void){
|
||||
exit(1);
|
||||
}
|
||||
|
||||
#ifdef SQLITE_DEBUG
|
||||
/* This routine is called when a simulated OOM occurs. It is broken
|
||||
** out as a separate routine to make it easy to set a breakpoint on
|
||||
** the OOM
|
||||
*/
|
||||
void shellOomFault(void){
|
||||
if( oomRepeat>0 ){
|
||||
oomRepeat--;
|
||||
}else{
|
||||
oomCounter--;
|
||||
}
|
||||
}
|
||||
#endif /* SQLITE_DEBUG */
|
||||
|
||||
#ifdef SQLITE_DEBUG
|
||||
/* This routine is a replacement malloc() that is used to simulate
|
||||
** Out-Of-Memory (OOM) errors for testing purposes.
|
||||
*/
|
||||
static void *oomMalloc(int nByte){
|
||||
if( oomCounter ){
|
||||
if( oomCounter==1 ){
|
||||
shellOomFault();
|
||||
return 0;
|
||||
}else{
|
||||
oomCounter--;
|
||||
}
|
||||
}
|
||||
return defaultMalloc(nByte);
|
||||
}
|
||||
#endif /* SQLITE_DEBUG */
|
||||
|
||||
#ifdef SQLITE_DEBUG
|
||||
/* Register the OOM simulator. This must occur before any memory
|
||||
** allocations */
|
||||
static void registerOomSimulator(void){
|
||||
sqlite3_mem_methods mem;
|
||||
sqlite3_config(SQLITE_CONFIG_GETMALLOC, &mem);
|
||||
defaultMalloc = mem.xMalloc;
|
||||
mem.xMalloc = oomMalloc;
|
||||
sqlite3_config(SQLITE_CONFIG_MALLOC, &mem);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Write I/O traces to the following stream.
|
||||
*/
|
||||
@@ -941,6 +1010,7 @@ INCLUDE ../ext/misc/fileio.c
|
||||
INCLUDE ../ext/misc/completion.c
|
||||
INCLUDE ../ext/misc/appendvfs.c
|
||||
INCLUDE ../ext/misc/memtrace.c
|
||||
INCLUDE ../ext/misc/uint.c
|
||||
#ifdef SQLITE_HAVE_ZLIB
|
||||
INCLUDE ../ext/misc/zipfile.c
|
||||
INCLUDE ../ext/misc/sqlar.c
|
||||
@@ -1037,6 +1107,7 @@ struct ShellState {
|
||||
unsigned mxProgress; /* Maximum progress callbacks before failing */
|
||||
unsigned flgProgress; /* Flags for the progress callback */
|
||||
unsigned shellFlgs; /* Various flags */
|
||||
unsigned priorShFlgs; /* Saved copy of flags */
|
||||
sqlite3_int64 szMax; /* --maxsize argument to .open */
|
||||
char *zDestTable; /* Name of destination table when MODE_Insert */
|
||||
char *zTempFile; /* Temporary file that might need deleting */
|
||||
@@ -1337,11 +1408,13 @@ edit_func_end:
|
||||
*/
|
||||
static void outputModePush(ShellState *p){
|
||||
p->modePrior = p->mode;
|
||||
p->priorShFlgs = p->shellFlgs;
|
||||
memcpy(p->colSepPrior, p->colSeparator, sizeof(p->colSeparator));
|
||||
memcpy(p->rowSepPrior, p->rowSeparator, sizeof(p->rowSeparator));
|
||||
}
|
||||
static void outputModePop(ShellState *p){
|
||||
p->mode = p->modePrior;
|
||||
p->shellFlgs = p->priorShFlgs;
|
||||
memcpy(p->colSeparator, p->colSepPrior, sizeof(p->colSeparator));
|
||||
memcpy(p->rowSeparator, p->rowSepPrior, sizeof(p->rowSeparator));
|
||||
}
|
||||
@@ -2306,8 +2379,7 @@ static void set_table_name(ShellState *p, const char *zName){
|
||||
*/
|
||||
static int run_table_dump_query(
|
||||
ShellState *p, /* Query context */
|
||||
const char *zSelect, /* SELECT statement to extract content */
|
||||
const char *zFirstRow /* Print before first row, if not NULL */
|
||||
const char *zSelect /* SELECT statement to extract content */
|
||||
){
|
||||
sqlite3_stmt *pSelect;
|
||||
int rc;
|
||||
@@ -2324,10 +2396,6 @@ static int run_table_dump_query(
|
||||
rc = sqlite3_step(pSelect);
|
||||
nResult = sqlite3_column_count(pSelect);
|
||||
while( rc==SQLITE_ROW ){
|
||||
if( zFirstRow ){
|
||||
utf8_printf(p->out, "%s", zFirstRow);
|
||||
zFirstRow = 0;
|
||||
}
|
||||
z = (const char*)sqlite3_column_text(pSelect, 0);
|
||||
utf8_printf(p->out, "%s", z);
|
||||
for(i=1; i<nResult; i++){
|
||||
@@ -2784,9 +2852,9 @@ static void bind_table_init(ShellState *p){
|
||||
** CREATE TEMP TABLE sqlite_parameters(key TEXT PRIMARY KEY, value)
|
||||
** WITHOUT ROWID;
|
||||
**
|
||||
** No bindings occur if this table does not exist. The special character '$'
|
||||
** is included in the table name to help prevent collisions with actual tables.
|
||||
** The table must be in the TEMP schema.
|
||||
** No bindings occur if this table does not exist. The name of the table
|
||||
** begins with "sqlite_" so that it will not collide with ordinary application
|
||||
** tables. The table must be in the TEMP schema.
|
||||
*/
|
||||
static void bind_prepared_stmt(ShellState *pArg, sqlite3_stmt *pStmt){
|
||||
int nVar;
|
||||
@@ -3500,11 +3568,12 @@ static const char *(azHelp[]) = {
|
||||
".databases List names and files of attached databases",
|
||||
".dbconfig ?op? ?val? List or change sqlite3_db_config() options",
|
||||
".dbinfo ?DB? Show status information about the database",
|
||||
".dump ?TABLE? ... Render all database content as SQL",
|
||||
".dump ?TABLE? Render database content as SQL",
|
||||
" Options:",
|
||||
" --preserve-rowids Include ROWID values in the output",
|
||||
" --newlines Allow unescaped newline characters in output",
|
||||
" TABLE is a LIKE pattern for the tables to dump",
|
||||
" Additional LIKE patterns can be given in subsequent arguments",
|
||||
".echo on|off Turn command echo on or off",
|
||||
".eqp on|off|full|... Enable or disable automatic EXPLAIN QUERY PLAN",
|
||||
" Other Modes:",
|
||||
@@ -3514,15 +3583,29 @@ static const char *(azHelp[]) = {
|
||||
#endif
|
||||
" trigger Like \"full\" but also show trigger bytecode",
|
||||
".excel Display the output of next command in spreadsheet",
|
||||
" --bom Put a UTF8 byte-order mark on intermediate file",
|
||||
".exit ?CODE? Exit this program with return-code CODE",
|
||||
".expert EXPERIMENTAL. Suggest indexes for queries",
|
||||
".explain ?on|off|auto? Change the EXPLAIN formatting mode. Default: auto",
|
||||
".filectrl CMD ... Run various sqlite3_file_control() operations",
|
||||
" Run \".filectrl\" with no arguments for details",
|
||||
" --schema SCHEMA Use SCHEMA instead of \"main\"",
|
||||
" --help Show CMD details",
|
||||
".fullschema ?--indent? Show schema and the content of sqlite_stat tables",
|
||||
".headers on|off Turn display of headers on or off",
|
||||
".help ?-all? ?PATTERN? Show help text for PATTERN",
|
||||
".import FILE TABLE Import data from FILE into TABLE",
|
||||
" Options:",
|
||||
" --ascii Use \\037 and \\036 as column and row separators",
|
||||
" --csv Use , and \\n as column and row separators",
|
||||
" --skip N Skip the first N rows of input",
|
||||
" -v \"Verbose\" - increase auxiliary output",
|
||||
" Notes:",
|
||||
" * If TABLE does not exist, it is created. The first row of input",
|
||||
" determines the column names.",
|
||||
" * If neither --csv or --ascii are used, the input mode is derived",
|
||||
" from the \".mode\" output mode",
|
||||
" * If FILE begins with \"|\" then it is a command that generates the",
|
||||
" input text.",
|
||||
#ifndef SQLITE_OMIT_TEST_CONTROL
|
||||
".imposter INDEX TABLE Create imposter table TABLE on index INDEX",
|
||||
#endif
|
||||
@@ -3553,11 +3636,14 @@ static const char *(azHelp[]) = {
|
||||
" tabs Tab-separated values",
|
||||
" tcl TCL list elements",
|
||||
".nullvalue STRING Use STRING in place of NULL values",
|
||||
".once (-e|-x|FILE) Output for the next SQL command only to FILE",
|
||||
".once ?OPTIONS? ?FILE? Output for the next SQL command only to FILE",
|
||||
" If FILE begins with '|' then open as a pipe",
|
||||
" Other options:",
|
||||
" -e Invoke system text editor",
|
||||
" -x Open in a spreadsheet",
|
||||
" --bom Put a UTF8 byte-order mark at the beginning",
|
||||
" -e Send output to the system text editor",
|
||||
" -x Send output as CSV to a spreadsheet (same as \".excel\")",
|
||||
#ifdef SQLITE_DEBUG
|
||||
".oom [--repeat M] [N] Simulate an OOM error on the N-th allocation",
|
||||
#endif
|
||||
".open ?OPTIONS? ?FILE? Close existing database and reopen FILE",
|
||||
" Options:",
|
||||
" --append Use appendvfs to append database to the end of FILE",
|
||||
@@ -3571,7 +3657,11 @@ static const char *(azHelp[]) = {
|
||||
" --readonly Open FILE readonly",
|
||||
" --zip FILE is a ZIP archive",
|
||||
".output ?FILE? Send output to FILE or stdout if FILE is omitted",
|
||||
" If FILE begins with '|' then open it as a pipe.",
|
||||
" If FILE begins with '|' then open it as a pipe.",
|
||||
" Options:",
|
||||
" --bom Prefix output with a UTF8 byte-order mark",
|
||||
" -e Send output to the system text editor",
|
||||
" -x Send output as CSV to a spreadsheet",
|
||||
".parameter CMD ... Manage SQL parameter bindings",
|
||||
" clear Erase all bindings",
|
||||
" init Initialize the TEMP table that holds bindings",
|
||||
@@ -3691,6 +3781,7 @@ static int showHelp(FILE *out, const char *zPattern){
|
||||
|| zPattern[0]=='0'
|
||||
|| strcmp(zPattern,"-a")==0
|
||||
|| strcmp(zPattern,"-all")==0
|
||||
|| strcmp(zPattern,"--all")==0
|
||||
){
|
||||
/* Show all commands, but only one line per command */
|
||||
if( zPattern==0 ) zPattern = "";
|
||||
@@ -4172,6 +4263,7 @@ static void open_db(ShellState *p, int openFlags){
|
||||
sqlite3_fileio_init(p->db, 0, 0);
|
||||
sqlite3_shathree_init(p->db, 0, 0);
|
||||
sqlite3_completion_init(p->db, 0, 0);
|
||||
sqlite3_uint_init(p->db, 0, 0);
|
||||
#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB)
|
||||
sqlite3_dbdata_init(p->db, 0, 0);
|
||||
#endif
|
||||
@@ -4508,6 +4600,8 @@ struct ImportCtx {
|
||||
int n; /* Number of bytes in z */
|
||||
int nAlloc; /* Space allocated for z[] */
|
||||
int nLine; /* Current line number */
|
||||
int nRow; /* Number of rows imported */
|
||||
int nErr; /* Number of errors encountered */
|
||||
int bNotFirst; /* True if one or more bytes already read */
|
||||
int cTerm; /* Character that terminated the most recent field */
|
||||
int cColSep; /* The column separator character. (Usually ",") */
|
||||
@@ -4889,11 +4983,15 @@ static void output_reset(ShellState *p){
|
||||
zCmd = sqlite3_mprintf("%s %s", zXdgOpenCmd, p->zTempFile);
|
||||
if( system(zCmd) ){
|
||||
utf8_printf(stderr, "Failed: [%s]\n", zCmd);
|
||||
}else{
|
||||
/* Give the start/open/xdg-open command some time to get
|
||||
** going before we continue, and potential delete the
|
||||
** p->zTempFile data file out from under it */
|
||||
sqlite3_sleep(2000);
|
||||
}
|
||||
sqlite3_free(zCmd);
|
||||
outputModePop(p);
|
||||
p->doXdgOpen = 0;
|
||||
sqlite3_sleep(100);
|
||||
}
|
||||
#endif /* !defined(SQLITE_NOHAVE_SYSTEM) */
|
||||
}
|
||||
@@ -5183,9 +5281,21 @@ static void newTempFile(ShellState *p, const char *zSuffix){
|
||||
sqlite3_file_control(p->db, 0, SQLITE_FCNTL_TEMPFILENAME, &p->zTempFile);
|
||||
}
|
||||
if( p->zTempFile==0 ){
|
||||
/* If p->db is an in-memory database then the TEMPFILENAME file-control
|
||||
** will not work and we will need to fallback to guessing */
|
||||
char *zTemp;
|
||||
sqlite3_uint64 r;
|
||||
sqlite3_randomness(sizeof(r), &r);
|
||||
p->zTempFile = sqlite3_mprintf("temp%llx.%s", r, zSuffix);
|
||||
zTemp = getenv("TEMP");
|
||||
if( zTemp==0 ) zTemp = getenv("TMP");
|
||||
if( zTemp==0 ){
|
||||
#ifdef _WIN32
|
||||
zTemp = "\\tmp";
|
||||
#else
|
||||
zTemp = "/tmp";
|
||||
#endif
|
||||
}
|
||||
p->zTempFile = sqlite3_mprintf("%s/temp%llx.%s", zTemp, r, zSuffix);
|
||||
}else{
|
||||
p->zTempFile = sqlite3_mprintf("%z.%s", p->zTempFile, zSuffix);
|
||||
}
|
||||
@@ -7209,7 +7319,8 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
#endif /* !(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB) */
|
||||
|
||||
if( c=='d' && strncmp(azArg[0], "dump", n)==0 ){
|
||||
const char *zLike = 0;
|
||||
char *zLike = 0;
|
||||
char *zSql;
|
||||
int i;
|
||||
int savedShowHeader = p->showHeader;
|
||||
int savedShellFlags = p->shellFlgs;
|
||||
@@ -7237,12 +7348,10 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
goto meta_command_exit;
|
||||
}
|
||||
}else if( zLike ){
|
||||
raw_printf(stderr, "Usage: .dump ?--preserve-rowids? "
|
||||
"?--newlines? ?LIKE-PATTERN?\n");
|
||||
rc = 1;
|
||||
goto meta_command_exit;
|
||||
zLike = sqlite3_mprintf("%z OR name LIKE %Q ESCAPE '\\'",
|
||||
zLike, azArg[i]);
|
||||
}else{
|
||||
zLike = azArg[i];
|
||||
zLike = sqlite3_mprintf("name LIKE %Q ESCAPE '\\'", azArg[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7260,35 +7369,25 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
** corrupt. */
|
||||
sqlite3_exec(p->db, "SAVEPOINT dump; PRAGMA writable_schema=ON", 0, 0, 0);
|
||||
p->nErr = 0;
|
||||
if( zLike==0 ){
|
||||
run_schema_dump_query(p,
|
||||
"SELECT name, type, sql FROM sqlite_master "
|
||||
"WHERE sql NOT NULL AND type=='table' AND name!='sqlite_sequence'"
|
||||
);
|
||||
run_schema_dump_query(p,
|
||||
"SELECT name, type, sql FROM sqlite_master "
|
||||
"WHERE name=='sqlite_sequence'"
|
||||
);
|
||||
run_table_dump_query(p,
|
||||
"SELECT sql FROM sqlite_master "
|
||||
"WHERE sql NOT NULL AND type IN ('index','trigger','view')", 0
|
||||
);
|
||||
}else{
|
||||
char *zSql;
|
||||
zSql = sqlite3_mprintf(
|
||||
"SELECT name, type, sql FROM sqlite_master "
|
||||
"WHERE tbl_name LIKE %Q AND type=='table'"
|
||||
" AND sql NOT NULL", zLike);
|
||||
run_schema_dump_query(p,zSql);
|
||||
sqlite3_free(zSql);
|
||||
zSql = sqlite3_mprintf(
|
||||
"SELECT sql FROM sqlite_master "
|
||||
"WHERE sql NOT NULL"
|
||||
" AND type IN ('index','trigger','view')"
|
||||
" AND tbl_name LIKE %Q", zLike);
|
||||
run_table_dump_query(p, zSql, 0);
|
||||
sqlite3_free(zSql);
|
||||
}
|
||||
if( zLike==0 ) zLike = sqlite3_mprintf("true");
|
||||
zSql = sqlite3_mprintf(
|
||||
"SELECT name, type, sql FROM sqlite_master "
|
||||
"WHERE (%s) AND type=='table'"
|
||||
" AND sql NOT NULL"
|
||||
" ORDER BY tbl_name='sqlite_sequence', rowid",
|
||||
zLike
|
||||
);
|
||||
run_schema_dump_query(p,zSql);
|
||||
sqlite3_free(zSql);
|
||||
zSql = sqlite3_mprintf(
|
||||
"SELECT sql FROM sqlite_master "
|
||||
"WHERE (%s) AND sql NOT NULL"
|
||||
" AND type IN ('index','trigger','view')",
|
||||
zLike
|
||||
);
|
||||
run_table_dump_query(p, zSql);
|
||||
sqlite3_free(zSql);
|
||||
sqlite3_free(zLike);
|
||||
if( p->writableSchema ){
|
||||
raw_printf(p->out, "PRAGMA writable_schema=OFF;\n");
|
||||
p->writableSchema = 0;
|
||||
@@ -7391,6 +7490,7 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
{ "tempfilename", SQLITE_FCNTL_TEMPFILENAME, "" },
|
||||
{ "has_moved", SQLITE_FCNTL_HAS_MOVED, "" },
|
||||
{ "lock_timeout", SQLITE_FCNTL_LOCK_TIMEOUT, "MILLISEC" },
|
||||
{ "reserve_bytes", SQLITE_FCNTL_RESERVE_BYTES, "[N]" },
|
||||
};
|
||||
int filectrl = -1;
|
||||
int iCtrl = -1;
|
||||
@@ -7398,10 +7498,21 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
int isOk = 0; /* 0: usage 1: %lld 2: no-result */
|
||||
int n2, i;
|
||||
const char *zCmd = 0;
|
||||
const char *zSchema = 0;
|
||||
|
||||
open_db(p, 0);
|
||||
zCmd = nArg>=2 ? azArg[1] : "help";
|
||||
|
||||
if( zCmd[0]=='-'
|
||||
&& (strcmp(zCmd,"--schema")==0 || strcmp(zCmd,"-schema")==0)
|
||||
&& nArg>=4
|
||||
){
|
||||
zSchema = azArg[2];
|
||||
for(i=3; i<nArg; i++) azArg[i-2] = azArg[i];
|
||||
nArg -= 2;
|
||||
zCmd = azArg[1];
|
||||
}
|
||||
|
||||
/* The argument can optionally begin with "-" or "--" */
|
||||
if( zCmd[0]=='-' && zCmd[1] ){
|
||||
zCmd++;
|
||||
@@ -7443,7 +7554,7 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
case SQLITE_FCNTL_SIZE_LIMIT: {
|
||||
if( nArg!=2 && nArg!=3 ) break;
|
||||
iRes = nArg==3 ? integerValue(azArg[2]) : -1;
|
||||
sqlite3_file_control(p->db, 0, SQLITE_FCNTL_SIZE_LIMIT, &iRes);
|
||||
sqlite3_file_control(p->db, zSchema, SQLITE_FCNTL_SIZE_LIMIT, &iRes);
|
||||
isOk = 1;
|
||||
break;
|
||||
}
|
||||
@@ -7452,7 +7563,7 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
int x;
|
||||
if( nArg!=3 ) break;
|
||||
x = (int)integerValue(azArg[2]);
|
||||
sqlite3_file_control(p->db, 0, filectrl, &x);
|
||||
sqlite3_file_control(p->db, zSchema, filectrl, &x);
|
||||
isOk = 2;
|
||||
break;
|
||||
}
|
||||
@@ -7461,7 +7572,7 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
int x;
|
||||
if( nArg!=2 && nArg!=3 ) break;
|
||||
x = nArg==3 ? booleanValue(azArg[2]) : -1;
|
||||
sqlite3_file_control(p->db, 0, filectrl, &x);
|
||||
sqlite3_file_control(p->db, zSchema, filectrl, &x);
|
||||
iRes = x;
|
||||
isOk = 1;
|
||||
break;
|
||||
@@ -7469,7 +7580,7 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
case SQLITE_FCNTL_HAS_MOVED: {
|
||||
int x;
|
||||
if( nArg!=2 ) break;
|
||||
sqlite3_file_control(p->db, 0, filectrl, &x);
|
||||
sqlite3_file_control(p->db, zSchema, filectrl, &x);
|
||||
iRes = x;
|
||||
isOk = 1;
|
||||
break;
|
||||
@@ -7477,7 +7588,7 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
case SQLITE_FCNTL_TEMPFILENAME: {
|
||||
char *z = 0;
|
||||
if( nArg!=2 ) break;
|
||||
sqlite3_file_control(p->db, 0, filectrl, &z);
|
||||
sqlite3_file_control(p->db, zSchema, filectrl, &z);
|
||||
if( z ){
|
||||
utf8_printf(p->out, "%s\n", z);
|
||||
sqlite3_free(z);
|
||||
@@ -7485,6 +7596,18 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
isOk = 2;
|
||||
break;
|
||||
}
|
||||
case SQLITE_FCNTL_RESERVE_BYTES: {
|
||||
int x;
|
||||
if( nArg>=3 ){
|
||||
x = atoi(azArg[2]);
|
||||
sqlite3_file_control(p->db, zSchema, filectrl, &x);
|
||||
}
|
||||
x = -1;
|
||||
sqlite3_file_control(p->db, zSchema, filectrl, &x);
|
||||
utf8_printf(p->out,"%d\n", x);
|
||||
isOk = 2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if( isOk==0 && iCtrl>=0 ){
|
||||
@@ -7568,8 +7691,8 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
}else
|
||||
|
||||
if( c=='i' && strncmp(azArg[0], "import", n)==0 ){
|
||||
char *zTable; /* Insert data into this table */
|
||||
char *zFile; /* Name of file to extra content from */
|
||||
char *zTable = 0; /* Insert data into this table */
|
||||
char *zFile = 0; /* Name of file to extra content from */
|
||||
sqlite3_stmt *pStmt = NULL; /* A statement */
|
||||
int nCol; /* Number of columns in the table */
|
||||
int nByte; /* Number of bytes in an SQL string */
|
||||
@@ -7580,51 +7703,108 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
ImportCtx sCtx; /* Reader context */
|
||||
char *(SQLITE_CDECL *xRead)(ImportCtx*); /* Func to read one value */
|
||||
int (SQLITE_CDECL *xCloser)(FILE*); /* Func to close file */
|
||||
int eVerbose = 0; /* Larger for more console output */
|
||||
int nSkip = 0; /* Initial lines to skip */
|
||||
int useOutputMode = 1; /* Use output mode to determine separators */
|
||||
|
||||
if( nArg!=3 ){
|
||||
raw_printf(stderr, "Usage: .import FILE TABLE\n");
|
||||
memset(&sCtx, 0, sizeof(sCtx));
|
||||
if( p->mode==MODE_Ascii ){
|
||||
xRead = ascii_read_one_field;
|
||||
}else{
|
||||
xRead = csv_read_one_field;
|
||||
}
|
||||
for(i=1; i<nArg; i++){
|
||||
char *z = azArg[i];
|
||||
if( z[0]=='-' && z[1]=='-' ) z++;
|
||||
if( z[0]!='-' ){
|
||||
if( zFile==0 ){
|
||||
zFile = z;
|
||||
}else if( zTable==0 ){
|
||||
zTable = z;
|
||||
}else{
|
||||
utf8_printf(p->out, "ERROR: extra argument: \"%s\". Usage:\n", z);
|
||||
showHelp(p->out, "import");
|
||||
rc = 1;
|
||||
goto meta_command_exit;
|
||||
}
|
||||
}else if( strcmp(z,"-v")==0 ){
|
||||
eVerbose++;
|
||||
}else if( strcmp(z,"-skip")==0 && i<nArg-1 ){
|
||||
nSkip = integerValue(azArg[++i]);
|
||||
}else if( strcmp(z,"-ascii")==0 ){
|
||||
sCtx.cColSep = SEP_Unit[0];
|
||||
sCtx.cRowSep = SEP_Record[0];
|
||||
xRead = ascii_read_one_field;
|
||||
useOutputMode = 0;
|
||||
}else if( strcmp(z,"-csv")==0 ){
|
||||
sCtx.cColSep = ',';
|
||||
sCtx.cRowSep = '\n';
|
||||
xRead = csv_read_one_field;
|
||||
useOutputMode = 0;
|
||||
}else{
|
||||
utf8_printf(p->out, "ERROR: unknown option: \"%s\". Usage:\n", z);
|
||||
showHelp(p->out, "import");
|
||||
rc = 1;
|
||||
goto meta_command_exit;
|
||||
}
|
||||
}
|
||||
if( zTable==0 ){
|
||||
utf8_printf(p->out, "ERROR: missing %s argument. Usage:\n",
|
||||
zFile==0 ? "FILE" : "TABLE");
|
||||
showHelp(p->out, "import");
|
||||
rc = 1;
|
||||
goto meta_command_exit;
|
||||
}
|
||||
zFile = azArg[1];
|
||||
zTable = azArg[2];
|
||||
seenInterrupt = 0;
|
||||
memset(&sCtx, 0, sizeof(sCtx));
|
||||
open_db(p, 0);
|
||||
nSep = strlen30(p->colSeparator);
|
||||
if( nSep==0 ){
|
||||
raw_printf(stderr,
|
||||
"Error: non-null column separator required for import\n");
|
||||
return 1;
|
||||
}
|
||||
if( nSep>1 ){
|
||||
raw_printf(stderr, "Error: multi-character column separators not allowed"
|
||||
" for import\n");
|
||||
return 1;
|
||||
}
|
||||
nSep = strlen30(p->rowSeparator);
|
||||
if( nSep==0 ){
|
||||
raw_printf(stderr, "Error: non-null row separator required for import\n");
|
||||
return 1;
|
||||
}
|
||||
if( nSep==2 && p->mode==MODE_Csv && strcmp(p->rowSeparator, SEP_CrLf)==0 ){
|
||||
/* When importing CSV (only), if the row separator is set to the
|
||||
** default output row separator, change it to the default input
|
||||
** row separator. This avoids having to maintain different input
|
||||
** and output row separators. */
|
||||
sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row);
|
||||
if( useOutputMode ){
|
||||
/* If neither the --csv or --ascii options are specified, then set
|
||||
** the column and row separator characters from the output mode. */
|
||||
nSep = strlen30(p->colSeparator);
|
||||
if( nSep==0 ){
|
||||
raw_printf(stderr,
|
||||
"Error: non-null column separator required for import\n");
|
||||
rc = 1;
|
||||
goto meta_command_exit;
|
||||
}
|
||||
if( nSep>1 ){
|
||||
raw_printf(stderr,
|
||||
"Error: multi-character column separators not allowed"
|
||||
" for import\n");
|
||||
rc = 1;
|
||||
goto meta_command_exit;
|
||||
}
|
||||
nSep = strlen30(p->rowSeparator);
|
||||
}
|
||||
if( nSep>1 ){
|
||||
raw_printf(stderr, "Error: multi-character row separators not allowed"
|
||||
" for import\n");
|
||||
return 1;
|
||||
if( nSep==0 ){
|
||||
raw_printf(stderr,
|
||||
"Error: non-null row separator required for import\n");
|
||||
rc = 1;
|
||||
goto meta_command_exit;
|
||||
}
|
||||
if( nSep==2 && p->mode==MODE_Csv && strcmp(p->rowSeparator,SEP_CrLf)==0 ){
|
||||
/* When importing CSV (only), if the row separator is set to the
|
||||
** default output row separator, change it to the default input
|
||||
** row separator. This avoids having to maintain different input
|
||||
** and output row separators. */
|
||||
sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row);
|
||||
nSep = strlen30(p->rowSeparator);
|
||||
}
|
||||
if( nSep>1 ){
|
||||
raw_printf(stderr, "Error: multi-character row separators not allowed"
|
||||
" for import\n");
|
||||
rc = 1;
|
||||
goto meta_command_exit;
|
||||
}
|
||||
sCtx.cColSep = p->colSeparator[0];
|
||||
sCtx.cRowSep = p->rowSeparator[0];
|
||||
}
|
||||
sCtx.zFile = zFile;
|
||||
sCtx.nLine = 1;
|
||||
if( sCtx.zFile[0]=='|' ){
|
||||
#ifdef SQLITE_OMIT_POPEN
|
||||
raw_printf(stderr, "Error: pipes are not supported in this OS\n");
|
||||
return 1;
|
||||
rc = 1;
|
||||
goto meta_command_exit;
|
||||
#else
|
||||
sCtx.in = popen(sCtx.zFile+1, "r");
|
||||
sCtx.zFile = "<pipe>";
|
||||
@@ -7634,17 +7814,26 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
sCtx.in = fopen(sCtx.zFile, "rb");
|
||||
xCloser = fclose;
|
||||
}
|
||||
if( p->mode==MODE_Ascii ){
|
||||
xRead = ascii_read_one_field;
|
||||
}else{
|
||||
xRead = csv_read_one_field;
|
||||
}
|
||||
if( sCtx.in==0 ){
|
||||
utf8_printf(stderr, "Error: cannot open \"%s\"\n", zFile);
|
||||
return 1;
|
||||
rc = 1;
|
||||
goto meta_command_exit;
|
||||
}
|
||||
if( eVerbose>=2 || (eVerbose>=1 && useOutputMode) ){
|
||||
char zSep[2];
|
||||
zSep[1] = 0;
|
||||
zSep[0] = sCtx.cColSep;
|
||||
utf8_printf(p->out, "Column separator ");
|
||||
output_c_string(p->out, zSep);
|
||||
utf8_printf(p->out, ", row separator ");
|
||||
zSep[0] = sCtx.cRowSep;
|
||||
output_c_string(p->out, zSep);
|
||||
utf8_printf(p->out, "\n");
|
||||
}
|
||||
while( (nSkip--)>0 ){
|
||||
while( xRead(&sCtx) && sCtx.cTerm==sCtx.cColSep ){}
|
||||
sCtx.nLine++;
|
||||
}
|
||||
sCtx.cColSep = p->colSeparator[0];
|
||||
sCtx.cRowSep = p->rowSeparator[0];
|
||||
zSql = sqlite3_mprintf("SELECT * FROM %s", zTable);
|
||||
if( zSql==0 ){
|
||||
xCloser(sCtx.in);
|
||||
@@ -7666,9 +7855,13 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
sqlite3_free(sCtx.z);
|
||||
xCloser(sCtx.in);
|
||||
utf8_printf(stderr,"%s: empty file\n", sCtx.zFile);
|
||||
return 1;
|
||||
rc = 1;
|
||||
goto meta_command_exit;
|
||||
}
|
||||
zCreate = sqlite3_mprintf("%z\n)", zCreate);
|
||||
if( eVerbose>=1 ){
|
||||
utf8_printf(p->out, "%s\n", zCreate);
|
||||
}
|
||||
rc = sqlite3_exec(p->db, zCreate, 0, 0, 0);
|
||||
sqlite3_free(zCreate);
|
||||
if( rc ){
|
||||
@@ -7676,7 +7869,8 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
sqlite3_errmsg(p->db));
|
||||
sqlite3_free(sCtx.z);
|
||||
xCloser(sCtx.in);
|
||||
return 1;
|
||||
rc = 1;
|
||||
goto meta_command_exit;
|
||||
}
|
||||
rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
|
||||
}
|
||||
@@ -7685,7 +7879,8 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
if (pStmt) sqlite3_finalize(pStmt);
|
||||
utf8_printf(stderr,"Error: %s\n", sqlite3_errmsg(p->db));
|
||||
xCloser(sCtx.in);
|
||||
return 1;
|
||||
rc = 1;
|
||||
goto meta_command_exit;
|
||||
}
|
||||
nCol = sqlite3_column_count(pStmt);
|
||||
sqlite3_finalize(pStmt);
|
||||
@@ -7704,13 +7899,17 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
}
|
||||
zSql[j++] = ')';
|
||||
zSql[j] = 0;
|
||||
if( eVerbose>=2 ){
|
||||
utf8_printf(p->out, "Insert using: %s\n", zSql);
|
||||
}
|
||||
rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
|
||||
sqlite3_free(zSql);
|
||||
if( rc ){
|
||||
utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
|
||||
if (pStmt) sqlite3_finalize(pStmt);
|
||||
xCloser(sCtx.in);
|
||||
return 1;
|
||||
rc = 1;
|
||||
goto meta_command_exit;
|
||||
}
|
||||
needCommit = sqlite3_get_autocommit(p->db);
|
||||
if( needCommit ) sqlite3_exec(p->db, "BEGIN", 0, 0, 0);
|
||||
@@ -7753,6 +7952,9 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
if( rc!=SQLITE_OK ){
|
||||
utf8_printf(stderr, "%s:%d: INSERT failed: %s\n", sCtx.zFile,
|
||||
startLine, sqlite3_errmsg(p->db));
|
||||
sCtx.nErr++;
|
||||
}else{
|
||||
sCtx.nRow++;
|
||||
}
|
||||
}
|
||||
}while( sCtx.cTerm!=EOF );
|
||||
@@ -7761,6 +7963,11 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
sqlite3_free(sCtx.z);
|
||||
sqlite3_finalize(pStmt);
|
||||
if( needCommit ) sqlite3_exec(p->db, "COMMIT", 0, 0, 0);
|
||||
if( eVerbose>0 ){
|
||||
utf8_printf(p->out,
|
||||
"Added %d rows with %d errors using %d lines of input\n",
|
||||
sCtx.nRow, sCtx.nErr, sCtx.nLine-1);
|
||||
}
|
||||
}else
|
||||
|
||||
#ifndef SQLITE_UNTESTABLE
|
||||
@@ -8039,6 +8246,34 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
}
|
||||
}else
|
||||
|
||||
#ifdef SQLITE_DEBUG
|
||||
if( c=='o' && strcmp(azArg[0],"oom")==0 ){
|
||||
int i;
|
||||
for(i=1; i<nArg; i++){
|
||||
const char *z = azArg[i];
|
||||
if( z[0]=='-' && z[1]=='-' ) z++;
|
||||
if( strcmp(z,"-repeat")==0 ){
|
||||
if( i==nArg-1 ){
|
||||
raw_printf(p->out, "missing argument on \"%s\"\n", azArg[i]);
|
||||
rc = 1;
|
||||
}else{
|
||||
oomRepeat = (int)integerValue(azArg[++i]);
|
||||
}
|
||||
}else if( IsDigit(z[0]) ){
|
||||
oomCounter = (int)integerValue(azArg[i]);
|
||||
}else{
|
||||
raw_printf(p->out, "unknown argument: \"%s\"\n", azArg[i]);
|
||||
raw_printf(p->out, "Usage: .oom [--repeat N] [M]\n");
|
||||
rc = 1;
|
||||
}
|
||||
}
|
||||
if( rc==0 ){
|
||||
raw_printf(p->out, "oomCounter = %d\n", oomCounter);
|
||||
raw_printf(p->out, "oomRepeat = %d\n", oomRepeat);
|
||||
}
|
||||
}else
|
||||
#endif /* SQLITE_DEBUG */
|
||||
|
||||
if( c=='o' && strncmp(azArg[0], "open", n)==0 && n>=2 ){
|
||||
char *zNewFilename; /* Name of the database file to open */
|
||||
int iName = 1; /* Index in azArg[] of the filename */
|
||||
@@ -8106,42 +8341,66 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
&& (strncmp(azArg[0], "output", n)==0||strncmp(azArg[0], "once", n)==0))
|
||||
|| (c=='e' && n==5 && strcmp(azArg[0],"excel")==0)
|
||||
){
|
||||
const char *zFile = nArg>=2 ? azArg[1] : "stdout";
|
||||
const char *zFile = 0;
|
||||
int bTxtMode = 0;
|
||||
if( azArg[0][0]=='e' ){
|
||||
/* Transform the ".excel" command into ".once -x" */
|
||||
nArg = 2;
|
||||
azArg[0] = "once";
|
||||
zFile = azArg[1] = "-x";
|
||||
n = 4;
|
||||
int i;
|
||||
int eMode = 0;
|
||||
int bBOM = 0;
|
||||
int bOnce;
|
||||
|
||||
if( c=='e' ){
|
||||
eMode = 'x';
|
||||
bOnce = 2;
|
||||
}else if( strncmp(azArg[0],"once",n)==0 ){
|
||||
bOnce = 1;
|
||||
}
|
||||
if( nArg>2 ){
|
||||
utf8_printf(stderr, "Usage: .%s [-e|-x|FILE]\n", azArg[0]);
|
||||
rc = 1;
|
||||
goto meta_command_exit;
|
||||
}
|
||||
if( n>1 && strncmp(azArg[0], "once", n)==0 ){
|
||||
if( nArg<2 ){
|
||||
raw_printf(stderr, "Usage: .once (-e|-x|FILE)\n");
|
||||
for(i=1; i<nArg; i++){
|
||||
char *z = azArg[i];
|
||||
if( z[0]=='-' ){
|
||||
if( z[1]=='-' ) z++;
|
||||
if( strcmp(z,"-bom")==0 ){
|
||||
bBOM = 1;
|
||||
}else if( c!='e' && strcmp(z,"-x")==0 ){
|
||||
eMode = 'x'; /* spreadsheet */
|
||||
}else if( c!='e' && strcmp(z,"-e")==0 ){
|
||||
eMode = 'e'; /* text editor */
|
||||
}else{
|
||||
utf8_printf(p->out, "ERROR: unknown option: \"%s\". Usage:\n",
|
||||
azArg[i]);
|
||||
showHelp(p->out, azArg[0]);
|
||||
rc = 1;
|
||||
goto meta_command_exit;
|
||||
}
|
||||
}else if( zFile==0 ){
|
||||
zFile = z;
|
||||
}else{
|
||||
utf8_printf(p->out,"ERROR: extra parameter: \"%s\". Usage:\n",
|
||||
azArg[i]);
|
||||
showHelp(p->out, azArg[0]);
|
||||
rc = 1;
|
||||
goto meta_command_exit;
|
||||
}
|
||||
}
|
||||
if( zFile==0 ) zFile = "stdout";
|
||||
if( bOnce ){
|
||||
p->outCount = 2;
|
||||
}else{
|
||||
p->outCount = 0;
|
||||
}
|
||||
output_reset(p);
|
||||
if( zFile[0]=='-' && zFile[1]=='-' ) zFile++;
|
||||
#ifndef SQLITE_NOHAVE_SYSTEM
|
||||
if( strcmp(zFile, "-e")==0 || strcmp(zFile, "-x")==0 ){
|
||||
if( eMode=='e' || eMode=='x' ){
|
||||
p->doXdgOpen = 1;
|
||||
outputModePush(p);
|
||||
if( zFile[1]=='x' ){
|
||||
if( eMode=='x' ){
|
||||
/* spreadsheet mode. Output as CSV. */
|
||||
newTempFile(p, "csv");
|
||||
ShellClearFlag(p, SHFLG_Echo);
|
||||
p->mode = MODE_Csv;
|
||||
sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Comma);
|
||||
sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_CrLf);
|
||||
}else{
|
||||
/* text editor mode */
|
||||
newTempFile(p, "txt");
|
||||
bTxtMode = 1;
|
||||
}
|
||||
@@ -8160,6 +8419,7 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
p->out = stdout;
|
||||
rc = 1;
|
||||
}else{
|
||||
if( bBOM ) fprintf(p->out,"\357\273\277");
|
||||
sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile);
|
||||
}
|
||||
#endif
|
||||
@@ -8172,6 +8432,7 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
p->out = stdout;
|
||||
rc = 1;
|
||||
} else {
|
||||
if( bBOM ) fprintf(p->out,"\357\273\277");
|
||||
sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile);
|
||||
}
|
||||
}
|
||||
@@ -9235,7 +9496,6 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
{ "prng_restore", SQLITE_TESTCTRL_PRNG_RESTORE, "" },
|
||||
{ "prng_save", SQLITE_TESTCTRL_PRNG_SAVE, "" },
|
||||
{ "prng_seed", SQLITE_TESTCTRL_PRNG_SEED, "SEED ?db?" },
|
||||
{ "reserve", SQLITE_TESTCTRL_RESERVE, "BYTES-OF-RESERVE"},
|
||||
};
|
||||
int testctrl = -1;
|
||||
int iCtrl = -1;
|
||||
@@ -9288,7 +9548,6 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
|
||||
/* sqlite3_test_control(int, db, int) */
|
||||
case SQLITE_TESTCTRL_OPTIMIZATIONS:
|
||||
case SQLITE_TESTCTRL_RESERVE:
|
||||
if( nArg==3 ){
|
||||
int opt = (int)strtol(azArg[2], 0, 0);
|
||||
rc2 = sqlite3_test_control(testctrl, p->db, opt);
|
||||
@@ -10060,14 +10319,18 @@ static void main_init(ShellState *data) {
|
||||
*/
|
||||
#ifdef _WIN32
|
||||
static void printBold(const char *zText){
|
||||
#if !SQLITE_OS_WINRT
|
||||
HANDLE out = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
CONSOLE_SCREEN_BUFFER_INFO defaultScreenInfo;
|
||||
GetConsoleScreenBufferInfo(out, &defaultScreenInfo);
|
||||
SetConsoleTextAttribute(out,
|
||||
FOREGROUND_RED|FOREGROUND_INTENSITY
|
||||
);
|
||||
#endif
|
||||
printf("%s", zText);
|
||||
#if !SQLITE_OS_WINRT
|
||||
SetConsoleTextAttribute(out, defaultScreenInfo.wAttributes);
|
||||
#endif
|
||||
}
|
||||
#else
|
||||
static void printBold(const char *zText){
|
||||
@@ -10122,6 +10385,10 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
|
||||
stdin_is_interactive = isatty(0);
|
||||
stdout_is_console = isatty(1);
|
||||
|
||||
#ifdef SQLITE_DEBUG
|
||||
registerOomSimulator();
|
||||
#endif
|
||||
|
||||
#if !defined(_WIN32_WCE)
|
||||
if( getenv("SQLITE_DEBUG_BREAK") ){
|
||||
if( isatty(0) && isatty(2) ){
|
||||
@@ -10131,7 +10398,11 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
|
||||
fgetc(stdin);
|
||||
}else{
|
||||
#if defined(_WIN32) || defined(WIN32)
|
||||
#if SQLITE_OS_WINRT
|
||||
__debugbreak();
|
||||
#else
|
||||
DebugBreak();
|
||||
#endif
|
||||
#elif defined(SIGTRAP)
|
||||
raise(SIGTRAP);
|
||||
#endif
|
||||
|
||||
+68
-8
@@ -1087,10 +1087,12 @@ struct sqlite3_io_methods {
|
||||
** a prior successful call to [SQLITE_FCNTL_BEGIN_ATOMIC_WRITE].
|
||||
**
|
||||
** <li>[[SQLITE_FCNTL_LOCK_TIMEOUT]]
|
||||
** The [SQLITE_FCNTL_LOCK_TIMEOUT] opcode causes attempts to obtain
|
||||
** a file lock using the xLock or xShmLock methods of the VFS to wait
|
||||
** for up to M milliseconds before failing, where M is the single
|
||||
** unsigned integer parameter.
|
||||
** The [SQLITE_FCNTL_LOCK_TIMEOUT] opcode is used to configure a VFS
|
||||
** to block for up to M milliseconds before failing when attempting to
|
||||
** obtain a file lock using the xLock or xShmLock methods of the VFS.
|
||||
** The parameter is a pointer to a 32-bit signed integer that contains
|
||||
** the value that M is to be set to. Before returning, the 32-bit signed
|
||||
** integer is overwritten with the previous value of M.
|
||||
**
|
||||
** <li>[[SQLITE_FCNTL_DATA_VERSION]]
|
||||
** The [SQLITE_FCNTL_DATA_VERSION] opcode is used to detect changes to
|
||||
@@ -1155,6 +1157,7 @@ struct sqlite3_io_methods {
|
||||
#define SQLITE_FCNTL_DATA_VERSION 35
|
||||
#define SQLITE_FCNTL_SIZE_LIMIT 36
|
||||
#define SQLITE_FCNTL_CKPT_DONE 37
|
||||
#define SQLITE_FCNTL_RESERVE_BYTES 38
|
||||
|
||||
/* deprecated names */
|
||||
#define SQLITE_GET_LOCKPROXYFILE SQLITE_FCNTL_GET_LOCKPROXYFILE
|
||||
@@ -3617,6 +3620,25 @@ const char *sqlite3_filename_database(const char*);
|
||||
const char *sqlite3_filename_journal(const char*);
|
||||
const char *sqlite3_filename_wal(const char*);
|
||||
|
||||
/*
|
||||
** CAPI3REF: Database File Corresponding To A Journal
|
||||
**
|
||||
** ^If X is the name of a rollback or WAL-mode journal file that is
|
||||
** passed into the xOpen method of [sqlite3_vfs], then
|
||||
** sqlite3_database_file_object(X) returns a pointer to the [sqlite3_file]
|
||||
** object that represents the main database file.
|
||||
**
|
||||
** This routine is intended for use in custom [VFS] implementations
|
||||
** only. It is not a general-purpose interface.
|
||||
** The argument sqlite3_file_object(X) must be a filename pointer that
|
||||
** has been passed into [sqlite3_vfs].xOpen method where the
|
||||
** flags parameter to xOpen contains one of the bits
|
||||
** [SQLITE_OPEN_MAIN_JOURNAL] or [SQLITE_OPEN_WAL]. Any other use
|
||||
** of this routine results in undefined and probably undesirable
|
||||
** behavior.
|
||||
*/
|
||||
sqlite3_file *sqlite3_database_file_object(const char*);
|
||||
|
||||
/*
|
||||
** CAPI3REF: Create and Destroy VFS Filenames
|
||||
**
|
||||
@@ -4258,6 +4280,24 @@ typedef struct sqlite3_context sqlite3_context;
|
||||
** ^If the third parameter to sqlite3_bind_text() or sqlite3_bind_text16()
|
||||
** or sqlite3_bind_blob() is a NULL pointer then the fourth parameter
|
||||
** is ignored and the end result is the same as sqlite3_bind_null().
|
||||
** ^If the third parameter to sqlite3_bind_text() is not NULL, then
|
||||
** it should be a pointer to well-formed UTF8 text.
|
||||
** ^If the third parameter to sqlite3_bind_text16() is not NULL, then
|
||||
** it should be a pointer to well-formed UTF16 text.
|
||||
** ^If the third parameter to sqlite3_bind_text64() is not NULL, then
|
||||
** it should be a pointer to a well-formed unicode string that is
|
||||
** either UTF8 if the sixth parameter is SQLITE_UTF8, or UTF16
|
||||
** otherwise.
|
||||
**
|
||||
** [[byte-order determination rules]] ^The byte-order of
|
||||
** UTF16 input text is determined by the byte-order mark (BOM, U+FEFF)
|
||||
** found in first character, which is removed, or in the absence of a BOM
|
||||
** the byte order is the native byte order of the host
|
||||
** machine for sqlite3_bind_text16() or the byte order specified in
|
||||
** the 6th parameter for sqlite3_bind_text64().)^
|
||||
** ^If UTF16 input text contains invalid unicode
|
||||
** characters, then SQLite might change those invalid characters
|
||||
** into the unicode replacement character: U+FFFD.
|
||||
**
|
||||
** ^(In those routines that have a fourth argument, its value is the
|
||||
** number of bytes in the parameter. To be clear: the value is the
|
||||
@@ -4271,7 +4311,7 @@ typedef struct sqlite3_context sqlite3_context;
|
||||
** or sqlite3_bind_text16() or sqlite3_bind_text64() then
|
||||
** that parameter must be the byte offset
|
||||
** where the NUL terminator would occur assuming the string were NUL
|
||||
** terminated. If any NUL characters occur at byte offsets less than
|
||||
** terminated. If any NUL characters occurs at byte offsets less than
|
||||
** the value of the fourth parameter then the resulting string value will
|
||||
** contain embedded NULs. The result of expressions involving strings
|
||||
** with embedded NULs is undefined.
|
||||
@@ -5596,8 +5636,9 @@ typedef void (*sqlite3_destructor_type)(void*);
|
||||
** 2nd parameter of sqlite3_result_error() or sqlite3_result_error16()
|
||||
** as the text of an error message. ^SQLite interprets the error
|
||||
** message string from sqlite3_result_error() as UTF-8. ^SQLite
|
||||
** interprets the string from sqlite3_result_error16() as UTF-16 in native
|
||||
** byte order. ^If the third parameter to sqlite3_result_error()
|
||||
** interprets the string from sqlite3_result_error16() as UTF-16 using
|
||||
** the same [byte-order determination rules] as [sqlite3_bind_text16()].
|
||||
** ^If the third parameter to sqlite3_result_error()
|
||||
** or sqlite3_result_error16() is negative then SQLite takes as the error
|
||||
** message all text up through the first zero character.
|
||||
** ^If the third parameter to sqlite3_result_error() or
|
||||
@@ -5665,6 +5706,25 @@ typedef void (*sqlite3_destructor_type)(void*);
|
||||
** then SQLite makes a copy of the result into space obtained
|
||||
** from [sqlite3_malloc()] before it returns.
|
||||
**
|
||||
** ^For the sqlite3_result_text16(), sqlite3_result_text16le(), and
|
||||
** sqlite3_result_text16be() routines, and for sqlite3_result_text64()
|
||||
** when the encoding is not UTF8, if the input UTF16 begins with a
|
||||
** byte-order mark (BOM, U+FEFF) then the BOM is removed from the
|
||||
** string and the rest of the string is interpreted according to the
|
||||
** byte-order specified by the BOM. ^The byte-order specified by
|
||||
** the BOM at the beginning of the text overrides the byte-order
|
||||
** specified by the interface procedure. ^So, for example, if
|
||||
** sqlite3_result_text16le() is invoked with text that begins
|
||||
** with bytes 0xfe, 0xff (a big-endian byte-order mark) then the
|
||||
** first two bytes of input are skipped and the remaining input
|
||||
** is interpreted as UTF16BE text.
|
||||
**
|
||||
** ^For UTF16 input text to the sqlite3_result_text16(),
|
||||
** sqlite3_result_text16be(), sqlite3_result_text16le(), and
|
||||
** sqlite3_result_text64() routines, if the text contains invalid
|
||||
** UTF16 characters, the invalid characters might be converted
|
||||
** into the unicode replacement character, U+FFFD.
|
||||
**
|
||||
** ^The sqlite3_result_value() interface sets the result of
|
||||
** the application-defined function to be a copy of the
|
||||
** [unprotected sqlite3_value] object specified by the 2nd parameter. ^The
|
||||
@@ -7612,7 +7672,7 @@ int sqlite3_test_control(int op, ...);
|
||||
#define SQLITE_TESTCTRL_PENDING_BYTE 11
|
||||
#define SQLITE_TESTCTRL_ASSERT 12
|
||||
#define SQLITE_TESTCTRL_ALWAYS 13
|
||||
#define SQLITE_TESTCTRL_RESERVE 14
|
||||
#define SQLITE_TESTCTRL_RESERVE 14 /* NOT USED */
|
||||
#define SQLITE_TESTCTRL_OPTIMIZATIONS 15
|
||||
#define SQLITE_TESTCTRL_ISKEYWORD 16 /* NOT USED */
|
||||
#define SQLITE_TESTCTRL_SCRATCHMALLOC 17 /* NOT USED */
|
||||
|
||||
@@ -334,6 +334,7 @@ struct sqlite3_api_routines {
|
||||
char *(*create_filename)(const char*,const char*,const char*,
|
||||
int,const char**);
|
||||
void (*free_filename)(char*);
|
||||
sqlite3_file *(*database_file_object)(const char*);
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -637,6 +638,7 @@ typedef int (*sqlite3_loadext_entry)(
|
||||
/* Version 3.32.0 and later */
|
||||
#define sqlite3_create_filename sqlite3_api->create_filename
|
||||
#define sqlite3_free_filename sqlite3_api->free_filename
|
||||
#define sqlite3_database_file_object sqlite3_api->database_file_object
|
||||
#endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */
|
||||
|
||||
#if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
|
||||
|
||||
+48
-13
@@ -186,6 +186,21 @@
|
||||
#pragma warn -spa /* Suspicious pointer arithmetic */
|
||||
#endif
|
||||
|
||||
/*
|
||||
** WAL mode depends on atomic aligned 32-bit loads and stores in a few
|
||||
** places. The following macros try to make this explicit.
|
||||
*/
|
||||
#ifndef __has_feature
|
||||
# define __has_feature(x) 0 /* compatibility with non-clang compilers */
|
||||
#endif
|
||||
#if GCC_VERSION>=4007000 || __has_feature(c_atomic)
|
||||
# define AtomicLoad(PTR) __atomic_load_n((PTR),__ATOMIC_RELAXED)
|
||||
# define AtomicStore(PTR,VAL) __atomic_store_n((PTR),(VAL),__ATOMIC_RELAXED)
|
||||
#else
|
||||
# define AtomicLoad(PTR) (*(PTR))
|
||||
# define AtomicStore(PTR,VAL) (*(PTR) = (VAL))
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Include standard header files as necessary
|
||||
*/
|
||||
@@ -1264,7 +1279,6 @@ struct Schema {
|
||||
*/
|
||||
#define DB_SchemaLoaded 0x0001 /* The schema has been loaded */
|
||||
#define DB_UnresetViews 0x0002 /* Some views have defined column names */
|
||||
#define DB_Empty 0x0004 /* The file is empty (length 0 bytes) */
|
||||
#define DB_ResetWanted 0x0008 /* Reset the schema when nSchemaLock==0 */
|
||||
|
||||
/*
|
||||
@@ -1422,7 +1436,7 @@ void sqlite3CryptFunc(sqlite3_context*,int,sqlite3_value**);
|
||||
struct sqlite3 {
|
||||
sqlite3_vfs *pVfs; /* OS Interface */
|
||||
struct Vdbe *pVdbe; /* List of active virtual machines */
|
||||
CollSeq *pDfltColl; /* The default collating sequence (BINARY) */
|
||||
CollSeq *pDfltColl; /* BINARY collseq for the database encoding */
|
||||
sqlite3_mutex *mutex; /* Connection mutex */
|
||||
Db *aDb; /* All backends */
|
||||
int nDb; /* Number of backends currently in use */
|
||||
@@ -1631,6 +1645,7 @@ struct sqlite3 {
|
||||
#define DBFLAG_VacuumInto 0x0008 /* Currently running VACUUM INTO */
|
||||
#define DBFLAG_SchemaKnownOk 0x0010 /* Schema is known to be valid */
|
||||
#define DBFLAG_InternalFunc 0x0020 /* Allow use of internal functions */
|
||||
#define DBFLAG_EncodingFixed 0x0040 /* No longer possible to change enc. */
|
||||
|
||||
/*
|
||||
** Bits of the sqlite3.dbOptFlags field that are used by the
|
||||
@@ -1934,6 +1949,7 @@ struct Column {
|
||||
u8 notNull; /* An OE_ code for handling a NOT NULL constraint */
|
||||
char affinity; /* One of the SQLITE_AFF_... values */
|
||||
u8 szEst; /* Estimated size of value in this column. sizeof(INT)==1 */
|
||||
u8 hName; /* Column name hash for faster lookup */
|
||||
u16 colFlags; /* Boolean properties. See COLFLAG_ defines below */
|
||||
};
|
||||
|
||||
@@ -2594,6 +2610,9 @@ struct Expr {
|
||||
** TK_COLUMN: the value of p5 for OP_Column
|
||||
** TK_AGG_FUNCTION: nesting depth
|
||||
** TK_FUNCTION: NC_SelfRef flag if needs OP_PureFunc */
|
||||
#ifdef SQLITE_DEBUG
|
||||
u8 vvaFlags; /* Verification flags. */
|
||||
#endif
|
||||
u32 flags; /* Various flags. EP_* See below */
|
||||
union {
|
||||
char *zToken; /* Token value. Zero terminated and dequoted */
|
||||
@@ -2668,7 +2687,7 @@ struct Expr {
|
||||
#define EP_TokenOnly 0x004000 /* Expr struct EXPR_TOKENONLYSIZE bytes only */
|
||||
#define EP_Win 0x008000 /* Contains window functions */
|
||||
#define EP_MemToken 0x010000 /* Need to sqlite3DbFree() Expr.zToken */
|
||||
#define EP_NoReduce 0x020000 /* Cannot EXPRDUP_REDUCE this Expr */
|
||||
/* 0x020000 // available for reuse */
|
||||
#define EP_Unlikely 0x040000 /* unlikely() or likelihood() function */
|
||||
#define EP_ConstFunc 0x080000 /* A SQLITE_FUNC_CONSTANT or _SLOCHNG function */
|
||||
#define EP_CanBeNull 0x100000 /* Can be null despite NOT NULL constraint */
|
||||
@@ -2682,6 +2701,7 @@ struct Expr {
|
||||
#define EP_IsTrue 0x10000000 /* Always has boolean value of TRUE */
|
||||
#define EP_IsFalse 0x20000000 /* Always has boolean value of FALSE */
|
||||
#define EP_FromDDL 0x40000000 /* Originates from sqlite_master */
|
||||
/* 0x80000000 // Available */
|
||||
|
||||
/*
|
||||
** The EP_Propagate mask is a set of properties that automatically propagate
|
||||
@@ -2700,14 +2720,24 @@ struct Expr {
|
||||
#define ExprAlwaysTrue(E) (((E)->flags&(EP_FromJoin|EP_IsTrue))==EP_IsTrue)
|
||||
#define ExprAlwaysFalse(E) (((E)->flags&(EP_FromJoin|EP_IsFalse))==EP_IsFalse)
|
||||
|
||||
|
||||
/* Flags for use with Expr.vvaFlags
|
||||
*/
|
||||
#define EP_NoReduce 0x01 /* Cannot EXPRDUP_REDUCE this Expr */
|
||||
#define EP_Immutable 0x02 /* Do not change this Expr node */
|
||||
|
||||
/* The ExprSetVVAProperty() macro is used for Verification, Validation,
|
||||
** and Accreditation only. It works like ExprSetProperty() during VVA
|
||||
** processes but is a no-op for delivery.
|
||||
*/
|
||||
#ifdef SQLITE_DEBUG
|
||||
# define ExprSetVVAProperty(E,P) (E)->flags|=(P)
|
||||
# define ExprSetVVAProperty(E,P) (E)->vvaFlags|=(P)
|
||||
# define ExprHasVVAProperty(E,P) (((E)->vvaFlags&(P))!=0)
|
||||
# define ExprClearVVAProperties(E) (E)->vvaFlags = 0
|
||||
#else
|
||||
# define ExprSetVVAProperty(E,P)
|
||||
# define ExprHasVVAProperty(E,P) 0
|
||||
# define ExprClearVVAProperties(E)
|
||||
#endif
|
||||
|
||||
/*
|
||||
@@ -3681,6 +3711,7 @@ struct Walker {
|
||||
struct WhereConst *pConst; /* WHERE clause constants */
|
||||
struct RenameCtx *pRename; /* RENAME COLUMN context */
|
||||
struct Table *pTab; /* Table of generated column */
|
||||
struct SrcList_item *pSrcItem; /* A single FROM clause item */
|
||||
} u;
|
||||
};
|
||||
|
||||
@@ -4225,7 +4256,7 @@ void sqlite3ExprCodeGeneratedColumn(Parse*, Column*, int);
|
||||
#endif
|
||||
void sqlite3ExprCodeCopy(Parse*, Expr*, int);
|
||||
void sqlite3ExprCodeFactorable(Parse*, Expr*, int);
|
||||
int sqlite3ExprCodeAtInit(Parse*, Expr*, int);
|
||||
int sqlite3ExprCodeRunJustOnce(Parse*, Expr*, int);
|
||||
int sqlite3ExprCodeTemp(Parse*, Expr*, int*);
|
||||
int sqlite3ExprCodeTarget(Parse*, Expr*, int);
|
||||
int sqlite3ExprCodeExprList(Parse*, ExprList*, int, int, u8);
|
||||
@@ -4380,6 +4411,7 @@ void sqlite3DeferForeignKey(Parse*, int);
|
||||
# define sqlite3AuthContextPush(a,b,c)
|
||||
# define sqlite3AuthContextPop(a) ((void)(a))
|
||||
#endif
|
||||
int sqlite3DbIsNamed(sqlite3 *db, int iDb, const char *zName);
|
||||
void sqlite3Attach(Parse*, Expr*, Expr*, Expr*);
|
||||
void sqlite3Detach(Parse*, Expr*);
|
||||
void sqlite3FixInit(DbFixer*, Parse*, int, const char*, const Token*);
|
||||
@@ -4439,10 +4471,10 @@ int sqlite3VarintLen(u64 v);
|
||||
|
||||
const char *sqlite3IndexAffinityStr(sqlite3*, Index*);
|
||||
void sqlite3TableAffinity(Vdbe*, Table*, int);
|
||||
char sqlite3CompareAffinity(Expr *pExpr, char aff2);
|
||||
int sqlite3IndexAffinityOk(Expr *pExpr, char idx_affinity);
|
||||
char sqlite3CompareAffinity(const Expr *pExpr, char aff2);
|
||||
int sqlite3IndexAffinityOk(const Expr *pExpr, char idx_affinity);
|
||||
char sqlite3TableColumnAffinity(Table*,int);
|
||||
char sqlite3ExprAffinity(Expr *pExpr);
|
||||
char sqlite3ExprAffinity(const Expr *pExpr);
|
||||
int sqlite3Atoi64(const char*, i64*, int, u8);
|
||||
int sqlite3DecOrHexToI64(const char*, i64*);
|
||||
void sqlite3ErrorWithMsg(sqlite3*, int, const char*,...);
|
||||
@@ -4465,9 +4497,10 @@ int sqlite3ReadSchema(Parse *pParse);
|
||||
CollSeq *sqlite3FindCollSeq(sqlite3*,u8 enc, const char*,int);
|
||||
int sqlite3IsBinary(const CollSeq*);
|
||||
CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char*zName);
|
||||
CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr);
|
||||
CollSeq *sqlite3ExprNNCollSeq(Parse *pParse, Expr *pExpr);
|
||||
int sqlite3ExprCollSeqMatch(Parse*,Expr*,Expr*);
|
||||
void sqlite3SetTextEncoding(sqlite3 *db, u8);
|
||||
CollSeq *sqlite3ExprCollSeq(Parse *pParse, const Expr *pExpr);
|
||||
CollSeq *sqlite3ExprNNCollSeq(Parse *pParse, const Expr *pExpr);
|
||||
int sqlite3ExprCollSeqMatch(Parse*,const Expr*,const Expr*);
|
||||
Expr *sqlite3ExprAddCollateToken(Parse *pParse, Expr*, const Token*, int);
|
||||
Expr *sqlite3ExprAddCollateString(Parse*,Expr*,const char*);
|
||||
Expr *sqlite3ExprSkipCollate(Expr*);
|
||||
@@ -4534,6 +4567,8 @@ int sqlite3MatchEName(
|
||||
const char*,
|
||||
const char*
|
||||
);
|
||||
Bitmask sqlite3ExprColUsed(Expr*);
|
||||
u8 sqlite3StrIHash(const char*);
|
||||
int sqlite3ResolveExprNames(NameContext*, Expr*);
|
||||
int sqlite3ResolveExprListNames(NameContext*, ExprList*);
|
||||
void sqlite3ResolveSelectNames(Parse*, Select*, NameContext*);
|
||||
@@ -4698,8 +4733,8 @@ char *sqlite3Normalize(Vdbe*, const char*);
|
||||
#endif
|
||||
int sqlite3Reprepare(Vdbe*);
|
||||
void sqlite3ExprListCheckLength(Parse*, ExprList*, const char*);
|
||||
CollSeq *sqlite3ExprCompareCollSeq(Parse*,Expr*);
|
||||
CollSeq *sqlite3BinaryCompareCollSeq(Parse *, Expr *, Expr *);
|
||||
CollSeq *sqlite3ExprCompareCollSeq(Parse*,const Expr*);
|
||||
CollSeq *sqlite3BinaryCompareCollSeq(Parse *, const Expr*, const Expr*);
|
||||
int sqlite3TempInMemory(const sqlite3*);
|
||||
const char *sqlite3JournalModename(int);
|
||||
#ifndef SQLITE_OMIT_WAL
|
||||
|
||||
+2
-2
@@ -568,7 +568,7 @@ int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzErrMsg){
|
||||
assert( zSql!=0 );
|
||||
mxSqlLen = db->aLimit[SQLITE_LIMIT_SQL_LENGTH];
|
||||
if( db->nVdbeActive==0 ){
|
||||
db->u1.isInterrupted = 0;
|
||||
AtomicStore(&db->u1.isInterrupted, 0);
|
||||
}
|
||||
pParse->rc = SQLITE_OK;
|
||||
pParse->zTail = zSql;
|
||||
@@ -613,7 +613,7 @@ int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzErrMsg){
|
||||
if( tokenType>=TK_SPACE ){
|
||||
assert( tokenType==TK_SPACE || tokenType==TK_ILLEGAL );
|
||||
#endif /* SQLITE_OMIT_WINDOWFUNC */
|
||||
if( db->u1.isInterrupted ){
|
||||
if( AtomicLoad(&db->u1.isInterrupted) ){
|
||||
pParse->rc = SQLITE_INTERRUPT;
|
||||
break;
|
||||
}
|
||||
|
||||
+8
-4
@@ -138,8 +138,8 @@ void sqlite3TreeViewSrcList(TreeView *pView, const SrcList *pSrc){
|
||||
sqlite3_str_appendf(&x, " %s", pItem->zName);
|
||||
}
|
||||
if( pItem->pTab ){
|
||||
sqlite3_str_appendf(&x, " tab=%Q nCol=%d ptr=%p",
|
||||
pItem->pTab->zName, pItem->pTab->nCol, pItem->pTab);
|
||||
sqlite3_str_appendf(&x, " tab=%Q nCol=%d ptr=%p used=%llx",
|
||||
pItem->pTab->zName, pItem->pTab->nCol, pItem->pTab, pItem->colUsed);
|
||||
}
|
||||
if( pItem->zAlias ){
|
||||
sqlite3_str_appendf(&x, " (AS %s)", pItem->zAlias);
|
||||
@@ -398,14 +398,14 @@ void sqlite3TreeViewWinFunc(TreeView *pView, const Window *pWin, u8 more){
|
||||
void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 moreToFollow){
|
||||
const char *zBinOp = 0; /* Binary operator */
|
||||
const char *zUniOp = 0; /* Unary operator */
|
||||
char zFlgs[60];
|
||||
char zFlgs[200];
|
||||
pView = sqlite3TreeViewPush(pView, moreToFollow);
|
||||
if( pExpr==0 ){
|
||||
sqlite3TreeViewLine(pView, "nil");
|
||||
sqlite3TreeViewPop(pView);
|
||||
return;
|
||||
}
|
||||
if( pExpr->flags || pExpr->affExpr ){
|
||||
if( pExpr->flags || pExpr->affExpr || pExpr->vvaFlags ){
|
||||
StrAccum x;
|
||||
sqlite3StrAccumInit(&x, 0, zFlgs, sizeof(zFlgs), 0);
|
||||
sqlite3_str_appendf(&x, " fg.af=%x.%c",
|
||||
@@ -416,6 +416,9 @@ void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 moreToFollow){
|
||||
if( ExprHasProperty(pExpr, EP_FromDDL) ){
|
||||
sqlite3_str_appendf(&x, " DDL");
|
||||
}
|
||||
if( ExprHasVVAProperty(pExpr, EP_Immutable) ){
|
||||
sqlite3_str_appendf(&x, " IMMUTABLE");
|
||||
}
|
||||
sqlite3StrAccumFinish(&x);
|
||||
}else{
|
||||
zFlgs[0] = 0;
|
||||
@@ -522,6 +525,7 @@ void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 moreToFollow){
|
||||
case TK_RSHIFT: zBinOp = "RSHIFT"; break;
|
||||
case TK_CONCAT: zBinOp = "CONCAT"; break;
|
||||
case TK_DOT: zBinOp = "DOT"; break;
|
||||
case TK_LIMIT: zBinOp = "LIMIT"; break;
|
||||
|
||||
case TK_UMINUS: zUniOp = "UMINUS"; break;
|
||||
case TK_UPLUS: zUniOp = "UPLUS"; break;
|
||||
|
||||
+1
-1
@@ -580,7 +580,7 @@ void sqlite3DropTrigger(Parse *pParse, SrcList *pName, int noErr){
|
||||
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 && sqlite3StrICmp(db->aDb[j].zDbSName, zDb) ) continue;
|
||||
if( zDb && sqlite3DbIsNamed(db, j, zDb)==0 ) continue;
|
||||
assert( sqlite3SchemaMutexHeld(db, j, 0) );
|
||||
pTrigger = sqlite3HashFind(&(db->aDb[j].pSchema->trigHash), zName);
|
||||
if( pTrigger ) break;
|
||||
|
||||
+13
@@ -317,6 +317,19 @@ int sqlite3_strnicmp(const char *zLeft, const char *zRight, int N){
|
||||
return N<0 ? 0 : UpperToLower[*a] - UpperToLower[*b];
|
||||
}
|
||||
|
||||
/*
|
||||
** Compute an 8-bit hash on a string that is insensitive to case differences
|
||||
*/
|
||||
u8 sqlite3StrIHash(const char *z){
|
||||
u8 h = 0;
|
||||
if( z==0 ) return 0;
|
||||
while( z[0] ){
|
||||
h += UpperToLower[(unsigned char)z[0]];
|
||||
z++;
|
||||
}
|
||||
return h;
|
||||
}
|
||||
|
||||
/*
|
||||
** Compute 10 to the E-th power. Examples: E==1 results in 10.
|
||||
** E==2 results in 100. E==50 results in 1.0e50.
|
||||
|
||||
+1
-1
@@ -233,7 +233,7 @@ SQLITE_NOINLINE int sqlite3RunVacuum(
|
||||
}
|
||||
db->mDbFlags |= DBFLAG_VacuumInto;
|
||||
}
|
||||
nRes = sqlite3BtreeGetOptimalReserve(pMain);
|
||||
nRes = sqlite3BtreeGetRequestedReserve(pMain);
|
||||
|
||||
sqlite3BtreeSetCacheSize(pTemp, db->aDb[iDb].pSchema->cache_size);
|
||||
sqlite3BtreeSetSpillSize(pTemp, sqlite3BtreeSetSpillSize(pMain,0));
|
||||
|
||||
+28
-24
@@ -707,7 +707,7 @@ int sqlite3VdbeExec(
|
||||
assert( p->explain==0 );
|
||||
p->pResultSet = 0;
|
||||
db->busyHandler.nBusy = 0;
|
||||
if( db->u1.isInterrupted ) goto abort_due_to_interrupt;
|
||||
if( AtomicLoad(&db->u1.isInterrupted) ) goto abort_due_to_interrupt;
|
||||
sqlite3VdbeIOTraceSql(p);
|
||||
#ifdef SQLITE_DEBUG
|
||||
sqlite3BeginBenignMalloc();
|
||||
@@ -891,7 +891,7 @@ jump_to_p2_and_check_for_interrupt:
|
||||
** checks on every opcode. This helps sqlite3_step() to run about 1.5%
|
||||
** faster according to "valgrind --tool=cachegrind" */
|
||||
check_for_interrupt:
|
||||
if( db->u1.isInterrupted ) goto abort_due_to_interrupt;
|
||||
if( AtomicLoad(&db->u1.isInterrupted) ) goto abort_due_to_interrupt;
|
||||
#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
|
||||
/* Call the progress callback if it is configured and the required number
|
||||
** of VDBE ops have been executed (either since this invocation of
|
||||
@@ -1544,7 +1544,6 @@ case OP_Concat: { /* same as TK_CONCAT, in1, in2, out3 */
|
||||
pIn1 = &aMem[pOp->p1];
|
||||
pIn2 = &aMem[pOp->p2];
|
||||
pOut = &aMem[pOp->p3];
|
||||
testcase( pIn1==pIn2 );
|
||||
testcase( pOut==pIn2 );
|
||||
assert( pIn1!=pOut );
|
||||
flags1 = pIn1->flags;
|
||||
@@ -3665,7 +3664,7 @@ case OP_SetCookie: {
|
||||
** <ul>
|
||||
** <li> <b>0x02 OPFLAG_SEEKEQ</b>: This cursor will only be used for
|
||||
** equality lookups (implemented as a pair of opcodes OP_SeekGE/OP_IdxGT
|
||||
** of OP_SeekLE/OP_IdxGT)
|
||||
** of OP_SeekLE/OP_IdxLT)
|
||||
** </ul>
|
||||
**
|
||||
** The P4 value may be either an integer (P4_INT32) or a pointer to
|
||||
@@ -3695,7 +3694,7 @@ case OP_SetCookie: {
|
||||
** <ul>
|
||||
** <li> <b>0x02 OPFLAG_SEEKEQ</b>: This cursor will only be used for
|
||||
** equality lookups (implemented as a pair of opcodes OP_SeekGE/OP_IdxGT
|
||||
** of OP_SeekLE/OP_IdxGT)
|
||||
** of OP_SeekLE/OP_IdxLT)
|
||||
** </ul>
|
||||
**
|
||||
** See also: OP_OpenRead, OP_OpenWrite
|
||||
@@ -3719,7 +3718,7 @@ case OP_SetCookie: {
|
||||
** <ul>
|
||||
** <li> <b>0x02 OPFLAG_SEEKEQ</b>: This cursor will only be used for
|
||||
** equality lookups (implemented as a pair of opcodes OP_SeekGE/OP_IdxGT
|
||||
** of OP_SeekLE/OP_IdxGT)
|
||||
** of OP_SeekLE/OP_IdxLT)
|
||||
** <li> <b>0x08 OPFLAG_FORDELETE</b>: This cursor is used only to seek
|
||||
** and subsequently delete entries in an index btree. This is a
|
||||
** hint to the storage engine that the storage engine is allowed to
|
||||
@@ -3831,9 +3830,7 @@ open_cursor_set_hints:
|
||||
assert( OPFLAG_BULKCSR==BTREE_BULKLOAD );
|
||||
assert( OPFLAG_SEEKEQ==BTREE_SEEK_EQ );
|
||||
testcase( pOp->p5 & OPFLAG_BULKCSR );
|
||||
#ifdef SQLITE_ENABLE_CURSOR_HINTS
|
||||
testcase( pOp->p2 & OPFLAG_SEEKEQ );
|
||||
#endif
|
||||
sqlite3BtreeCursorHintFlags(pCur->uc.pCursor,
|
||||
(pOp->p5 & (OPFLAG_BULKCSR|OPFLAG_SEEKEQ)));
|
||||
if( rc ) goto abort_due_to_error;
|
||||
@@ -4089,11 +4086,13 @@ case OP_ColumnsUsed: {
|
||||
** greater than or equal to the key and P2 is not zero, then jump to P2.
|
||||
**
|
||||
** If the cursor P1 was opened using the OPFLAG_SEEKEQ flag, then this
|
||||
** opcode will always land on a record that equally equals the key, or
|
||||
** else jump immediately to P2. When the cursor is OPFLAG_SEEKEQ, this
|
||||
** opcode must be followed by an IdxLE opcode with the same arguments.
|
||||
** The IdxLE opcode will be skipped if this opcode succeeds, but the
|
||||
** IdxLE opcode will be used on subsequent loop iterations.
|
||||
** opcode will either land on a record that exactly matches the key, or
|
||||
** else it will cause a jump to P2. When the cursor is OPFLAG_SEEKEQ,
|
||||
** this opcode must be followed by an IdxLE opcode with the same arguments.
|
||||
** The IdxGT opcode will be skipped if this opcode succeeds, but the
|
||||
** IdxGT opcode will be used on subsequent loop iterations. The
|
||||
** OPFLAG_SEEKEQ flags is a hint to the btree layer to say that this
|
||||
** is an equality search.
|
||||
**
|
||||
** This opcode leaves the cursor configured to move in forward order,
|
||||
** from the beginning toward the end. In other words, the cursor is
|
||||
@@ -4109,7 +4108,7 @@ case OP_ColumnsUsed: {
|
||||
** to an SQL index, then P3 is the first in an array of P4 registers
|
||||
** that are used as an unpacked index key.
|
||||
**
|
||||
** Reposition cursor P1 so that it points to the smallest entry that
|
||||
** Reposition cursor P1 so that it points to the smallest entry that
|
||||
** is greater than the key value. If there are no records greater than
|
||||
** the key and P2 is not zero, then jump to P2.
|
||||
**
|
||||
@@ -4154,11 +4153,13 @@ case OP_ColumnsUsed: {
|
||||
** configured to use Prev, not Next.
|
||||
**
|
||||
** If the cursor P1 was opened using the OPFLAG_SEEKEQ flag, then this
|
||||
** opcode will always land on a record that equally equals the key, or
|
||||
** else jump immediately to P2. When the cursor is OPFLAG_SEEKEQ, this
|
||||
** opcode must be followed by an IdxGE opcode with the same arguments.
|
||||
** opcode will either land on a record that exactly matches the key, or
|
||||
** else it will cause a jump to P2. When the cursor is OPFLAG_SEEKEQ,
|
||||
** this opcode must be followed by an IdxLE opcode with the same arguments.
|
||||
** The IdxGE opcode will be skipped if this opcode succeeds, but the
|
||||
** IdxGE opcode will be used on subsequent loop iterations.
|
||||
** IdxGE opcode will be used on subsequent loop iterations. The
|
||||
** OPFLAG_SEEKEQ flags is a hint to the btree layer to say that this
|
||||
** is an equality search.
|
||||
**
|
||||
** See also: Found, NotFound, SeekGt, SeekGe, SeekLt
|
||||
*/
|
||||
@@ -4195,7 +4196,7 @@ case OP_SeekGT: { /* jump, in3, group */
|
||||
pC->cacheStatus = CACHE_STALE;
|
||||
if( pC->isTable ){
|
||||
u16 flags3, newType;
|
||||
/* The BTREE_SEEK_EQ flag is only set on index cursors */
|
||||
/* The OPFLAG_SEEKEQ/BTREE_SEEK_EQ flag is only set on index cursors */
|
||||
assert( sqlite3BtreeCursorHasHint(pC->uc.pCursor, BTREE_SEEK_EQ)==0
|
||||
|| CORRUPT_DB );
|
||||
|
||||
@@ -4254,14 +4255,17 @@ case OP_SeekGT: { /* jump, in3, group */
|
||||
goto abort_due_to_error;
|
||||
}
|
||||
}else{
|
||||
/* For a cursor with the BTREE_SEEK_EQ hint, only the OP_SeekGE and
|
||||
** OP_SeekLE opcodes are allowed, and these must be immediately followed
|
||||
** by an OP_IdxGT or OP_IdxLT opcode, respectively, with the same key.
|
||||
/* For a cursor with the OPFLAG_SEEKEQ/BTREE_SEEK_EQ hint, only the
|
||||
** OP_SeekGE and OP_SeekLE opcodes are allowed, and these must be
|
||||
** immediately followed by an OP_IdxGT or OP_IdxLT opcode, respectively,
|
||||
** with the same key.
|
||||
*/
|
||||
if( sqlite3BtreeCursorHasHint(pC->uc.pCursor, BTREE_SEEK_EQ) ){
|
||||
eqOnly = 1;
|
||||
assert( pOp->opcode==OP_SeekGE || pOp->opcode==OP_SeekLE );
|
||||
assert( pOp[1].opcode==OP_IdxLT || pOp[1].opcode==OP_IdxGT );
|
||||
assert( pOp->opcode==OP_SeekGE || pOp[1].opcode==OP_IdxLT );
|
||||
assert( pOp->opcode==OP_SeekLE || pOp[1].opcode==OP_IdxGT );
|
||||
assert( pOp[1].p1==pOp[0].p1 );
|
||||
assert( pOp[1].p2==pOp[0].p2 );
|
||||
assert( pOp[1].p3==pOp[0].p3 );
|
||||
@@ -6476,7 +6480,7 @@ case OP_Program: { /* jump */
|
||||
int i;
|
||||
for(i=0; i<p->nMem; i++){
|
||||
aMem[i].pScopyFrom = 0; /* Prevent false-positive AboutToChange() errs */
|
||||
aMem[i].flags |= MEM_Undefined; /* Cause a fault if this reg is reused */
|
||||
MemSetTypeFlag(&aMem[i], MEM_Undefined); /* Fault if this reg is reused */
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -7995,7 +7999,7 @@ no_mem:
|
||||
** flag.
|
||||
*/
|
||||
abort_due_to_interrupt:
|
||||
assert( db->u1.isInterrupted );
|
||||
assert( AtomicLoad(&db->u1.isInterrupted) );
|
||||
rc = db->mallocFailed ? SQLITE_NOMEM_BKPT : SQLITE_INTERRUPT;
|
||||
p->rc = rc;
|
||||
sqlite3VdbeError(p, "%s", sqlite3ErrStr(rc));
|
||||
|
||||
+1
-1
@@ -418,9 +418,9 @@ struct Vdbe {
|
||||
u8 errorAction; /* Recovery action to do in case of an error */
|
||||
u8 minWriteFileFormat; /* Minimum file format for writable database files */
|
||||
u8 prepFlags; /* SQLITE_PREPARE_* flags */
|
||||
u8 doingRerun; /* True if rerunning after an auto-reprepare */
|
||||
bft expired:2; /* 1: recompile VM immediately 2: when convenient */
|
||||
bft explain:2; /* True if EXPLAIN present on SQL command */
|
||||
bft doingRerun:1; /* True if rerunning after an auto-reprepare */
|
||||
bft changeCntOn:1; /* True to update the change-counter */
|
||||
bft runOnlyOnce:1; /* Automatically expire on reset */
|
||||
bft usesStmtJournal:1; /* True if uses a statement journal */
|
||||
|
||||
+1
-1
@@ -663,7 +663,7 @@ static int sqlite3Step(Vdbe *p){
|
||||
** from interrupting a statement that has not yet started.
|
||||
*/
|
||||
if( db->nVdbeActive==0 ){
|
||||
db->u1.isInterrupted = 0;
|
||||
AtomicStore(&db->u1.isInterrupted, 0);
|
||||
}
|
||||
|
||||
assert( db->nVdbeWrite>0 || db->autoCommit==0
|
||||
|
||||
+7
-4
@@ -424,7 +424,7 @@ void sqlite3ExplainBreakpoint(const char *z1, const char *z2){
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Add a new OP_ opcode.
|
||||
** Add a new OP_Explain opcode.
|
||||
**
|
||||
** If the bPush flag is true, then make this opcode the parent for
|
||||
** subsequent Explains until sqlite3VdbeExplainPop() is called.
|
||||
@@ -1658,8 +1658,11 @@ static char *displayP4(Op *pOp, char *zTemp, int nTemp){
|
||||
}
|
||||
#endif
|
||||
case P4_COLLSEQ: {
|
||||
static const char *const encnames[] = {"?", "8", "16LE", "16BE"};
|
||||
CollSeq *pColl = pOp->p4.pColl;
|
||||
sqlite3_str_appendf(&x, "(%.20s)", pColl->zName);
|
||||
assert( pColl->enc>=0 && pColl->enc<4 );
|
||||
sqlite3_str_appendf(&x, "%.18s-%s", pColl->zName,
|
||||
encnames[pColl->enc]);
|
||||
break;
|
||||
}
|
||||
case P4_FUNCDEF: {
|
||||
@@ -2090,7 +2093,7 @@ int sqlite3VdbeList(
|
||||
}
|
||||
|
||||
if( rc==SQLITE_OK ){
|
||||
if( db->u1.isInterrupted ){
|
||||
if( AtomicLoad(&db->u1.isInterrupted) ){
|
||||
p->rc = SQLITE_INTERRUPT;
|
||||
rc = SQLITE_ERROR;
|
||||
sqlite3VdbeError(p, sqlite3ErrStr(p->rc));
|
||||
@@ -2372,6 +2375,7 @@ void sqlite3VdbeMakeReady(
|
||||
};
|
||||
int iFirst, mx, i;
|
||||
if( nMem<10 ) nMem = 10;
|
||||
p->explain = pParse->explain;
|
||||
if( pParse->explain==2 ){
|
||||
sqlite3VdbeSetNumCols(p, 4);
|
||||
iFirst = 8;
|
||||
@@ -2422,7 +2426,6 @@ void sqlite3VdbeMakeReady(
|
||||
|
||||
p->pVList = pParse->pVList;
|
||||
pParse->pVList = 0;
|
||||
p->explain = pParse->explain;
|
||||
if( db->mallocFailed ){
|
||||
p->nVar = 0;
|
||||
p->nCursor = 0;
|
||||
|
||||
+1
-6
@@ -961,7 +961,7 @@ void sqlite3VdbeMemAboutToChange(Vdbe *pVdbe, Mem *pMem){
|
||||
sqlite3DebugPrintf("Invalidate R[%d] due to change in R[%d]\n",
|
||||
(int)(pX - pVdbe->aMem), (int)(pMem - pVdbe->aMem));
|
||||
}
|
||||
/* If pX is marked as a shallow copy of pMem, then verify that
|
||||
/* If pX is marked as a shallow copy of pMem, then try to verify that
|
||||
** no significant changes have been made to pX since the OP_SCopy.
|
||||
** A significant change would indicated a missed call to this
|
||||
** function for pX. Minor changes, such as adding or removing a
|
||||
@@ -969,11 +969,6 @@ void sqlite3VdbeMemAboutToChange(Vdbe *pVdbe, Mem *pMem){
|
||||
** same. */
|
||||
mFlags = pMem->flags & pX->flags & pX->mScopyFlags;
|
||||
assert( (mFlags&(MEM_Int|MEM_IntReal))==0 || pMem->u.i==pX->u.i );
|
||||
/* assert( (mFlags&MEM_Real)==0 || pMem->u.r==pX->u.r ); */
|
||||
/* ^^ */
|
||||
/* Cannot reliably compare doubles for equality */
|
||||
assert( (mFlags&MEM_Str)==0 || (pMem->n==pX->n && pMem->z==pX->z) );
|
||||
assert( (mFlags&MEM_Blob)==0 || sqlite3BlobCompare(pMem,pX)==0 );
|
||||
|
||||
/* pMem is the register that is changing. But also mark pX as
|
||||
** undefined so that we can quickly detect the shallow-copy error */
|
||||
|
||||
@@ -258,18 +258,6 @@ int sqlite3WalTrace = 0;
|
||||
# define WALTRACE(X)
|
||||
#endif
|
||||
|
||||
/*
|
||||
** WAL mode depends on atomic aligned 32-bit loads and stores in a few
|
||||
** places. The following macros try to make this explicit.
|
||||
*/
|
||||
#if GCC_VESRION>=5004000
|
||||
# define AtomicLoad(PTR) __atomic_load_n((PTR),__ATOMIC_RELAXED)
|
||||
# define AtomicStore(PTR,VAL) __atomic_store_n((PTR),(VAL),__ATOMIC_RELAXED)
|
||||
#else
|
||||
# define AtomicLoad(PTR) (*(PTR))
|
||||
# define AtomicStore(PTR,VAL) (*(PTR) = (VAL))
|
||||
#endif
|
||||
|
||||
/*
|
||||
** The maximum (and only) versions of the wal and wal-index formats
|
||||
** that may be interpreted by this version of SQLite.
|
||||
@@ -1140,6 +1128,11 @@ static int walIndexRecover(Wal *pWal){
|
||||
u32 aFrameCksum[2] = {0, 0};
|
||||
int iLock; /* Lock offset to lock for checkpoint */
|
||||
|
||||
#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
|
||||
int tmout = 0;
|
||||
sqlite3OsFileControl(pWal->pDbFd, SQLITE_FCNTL_LOCK_TIMEOUT, (void*)&tmout);
|
||||
#endif
|
||||
|
||||
/* Obtain an exclusive lock on all byte in the locking range not already
|
||||
** locked by the caller. The caller is guaranteed to have locked the
|
||||
** WAL_WRITE_LOCK byte, and may have also locked the WAL_CKPT_LOCK byte.
|
||||
@@ -1886,7 +1879,7 @@ static int walCheckpoint(
|
||||
while( rc==SQLITE_OK && 0==walIteratorNext(pIter, &iDbpage, &iFrame) ){
|
||||
i64 iOffset;
|
||||
assert( walFramePgno(pWal, iFrame)==iDbpage );
|
||||
if( db->u1.isInterrupted ){
|
||||
if( AtomicLoad(&db->u1.isInterrupted) ){
|
||||
rc = db->mallocFailed ? SQLITE_NOMEM_BKPT : SQLITE_INTERRUPT;
|
||||
break;
|
||||
}
|
||||
@@ -2599,7 +2592,8 @@ static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int cnt){
|
||||
for(i=1; i<WAL_NREADER; i++){
|
||||
rc = walLockExclusive(pWal, WAL_READ_LOCK(i), 1);
|
||||
if( rc==SQLITE_OK ){
|
||||
mxReadMark = AtomicStore(pInfo->aReadMark+i,mxFrame);
|
||||
AtomicStore(pInfo->aReadMark+i,mxFrame);
|
||||
mxReadMark = mxFrame;
|
||||
mxI = i;
|
||||
walUnlockExclusive(pWal, WAL_READ_LOCK(i), 1);
|
||||
break;
|
||||
@@ -2758,6 +2752,9 @@ int sqlite3WalSnapshotRecover(Wal *pWal){
|
||||
int sqlite3WalBeginReadTransaction(Wal *pWal, int *pChanged){
|
||||
int rc; /* Return code */
|
||||
int cnt = 0; /* Number of TryBeginRead attempts */
|
||||
#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
|
||||
int tmout = 0;
|
||||
#endif
|
||||
|
||||
#ifdef SQLITE_ENABLE_SNAPSHOT
|
||||
int bChanged = 0;
|
||||
@@ -2767,6 +2764,12 @@ int sqlite3WalBeginReadTransaction(Wal *pWal, int *pChanged){
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
|
||||
/* Disable blocking locks. They are not useful when trying to open a
|
||||
** read-transaction, and blocking may cause deadlock anyway. */
|
||||
sqlite3OsFileControl(pWal->pDbFd, SQLITE_FCNTL_LOCK_TIMEOUT, (void*)&tmout);
|
||||
#endif
|
||||
|
||||
do{
|
||||
rc = walTryBeginRead(pWal, pChanged, 0, ++cnt);
|
||||
}while( rc==WAL_RETRY );
|
||||
@@ -2775,6 +2778,16 @@ int sqlite3WalBeginReadTransaction(Wal *pWal, int *pChanged){
|
||||
testcase( rc==SQLITE_PROTOCOL );
|
||||
testcase( rc==SQLITE_OK );
|
||||
|
||||
#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
|
||||
/* If they were disabled earlier and the read-transaction has been
|
||||
** successfully opened, re-enable blocking locks. This is because the
|
||||
** connection may attempt to upgrade to a write-transaction, which does
|
||||
** benefit from using blocking locks. */
|
||||
if( rc==SQLITE_OK ){
|
||||
sqlite3OsFileControl(pWal->pDbFd, SQLITE_FCNTL_LOCK_TIMEOUT, (void*)&tmout);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SQLITE_ENABLE_SNAPSHOT
|
||||
if( rc==SQLITE_OK ){
|
||||
if( pSnapshot && memcmp(pSnapshot, &pWal->hdr, sizeof(WalIndexHdr))!=0 ){
|
||||
|
||||
+10
-9
@@ -156,15 +156,16 @@ int sqlite3WalkSelectFrom(Walker *pWalker, Select *p){
|
||||
struct SrcList_item *pItem;
|
||||
|
||||
pSrc = p->pSrc;
|
||||
assert( pSrc!=0 );
|
||||
for(i=pSrc->nSrc, pItem=pSrc->a; i>0; i--, pItem++){
|
||||
if( pItem->pSelect && sqlite3WalkSelect(pWalker, pItem->pSelect) ){
|
||||
return WRC_Abort;
|
||||
}
|
||||
if( pItem->fg.isTabFunc
|
||||
&& sqlite3WalkExprList(pWalker, pItem->u1.pFuncArg)
|
||||
){
|
||||
return WRC_Abort;
|
||||
if( pSrc ){
|
||||
for(i=pSrc->nSrc, pItem=pSrc->a; i>0; i--, pItem++){
|
||||
if( pItem->pSelect && sqlite3WalkSelect(pWalker, pItem->pSelect) ){
|
||||
return WRC_Abort;
|
||||
}
|
||||
if( pItem->fg.isTabFunc
|
||||
&& sqlite3WalkExprList(pWalker, pItem->u1.pFuncArg)
|
||||
){
|
||||
return WRC_Abort;
|
||||
}
|
||||
}
|
||||
}
|
||||
return WRC_Continue;
|
||||
|
||||
+9
-8
@@ -5178,7 +5178,7 @@ WhereInfo *sqlite3WhereBegin(
|
||||
&& (pWInfo->wctrlFlags&WHERE_ORDERBY_MIN)==0
|
||||
&& pWInfo->eDistinct!=WHERE_DISTINCT_ORDERED
|
||||
){
|
||||
sqlite3VdbeChangeP5(v, OPFLAG_SEEKEQ); /* Hint to COMDB2 */
|
||||
sqlite3VdbeChangeP5(v, OPFLAG_SEEKEQ);
|
||||
}
|
||||
VdbeComment((v, "%s", pIx->zName));
|
||||
#ifdef SQLITE_ENABLE_COLUMN_USED_MASK
|
||||
@@ -5336,12 +5336,6 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){
|
||||
if( pIn->eEndLoopOp!=OP_Noop ){
|
||||
if( pIn->nPrefix ){
|
||||
assert( pLoop->wsFlags & WHERE_IN_EARLYOUT );
|
||||
if( (pLoop->wsFlags & WHERE_VIRTUALTABLE)==0 ){
|
||||
sqlite3VdbeAddOp4Int(v, OP_IfNoHope, pLevel->iIdxCur,
|
||||
sqlite3VdbeCurrentAddr(v)+2+(pLevel->iLeftJoin!=0),
|
||||
pIn->iBase, pIn->nPrefix);
|
||||
VdbeCoverage(v);
|
||||
}
|
||||
if( pLevel->iLeftJoin ){
|
||||
/* For LEFT JOIN queries, cursor pIn->iCur may not have been
|
||||
** opened yet. This occurs for WHERE clauses such as
|
||||
@@ -5352,10 +5346,17 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){
|
||||
** jump over the OP_Next or OP_Prev instruction about to
|
||||
** be coded. */
|
||||
sqlite3VdbeAddOp2(v, OP_IfNotOpen, pIn->iCur,
|
||||
sqlite3VdbeCurrentAddr(v) + 2
|
||||
sqlite3VdbeCurrentAddr(v) + 2 +
|
||||
((pLoop->wsFlags & WHERE_VIRTUALTABLE)==0)
|
||||
);
|
||||
VdbeCoverage(v);
|
||||
}
|
||||
if( (pLoop->wsFlags & WHERE_VIRTUALTABLE)==0 ){
|
||||
sqlite3VdbeAddOp4Int(v, OP_IfNoHope, pLevel->iIdxCur,
|
||||
sqlite3VdbeCurrentAddr(v)+2,
|
||||
pIn->iBase, pIn->nPrefix);
|
||||
VdbeCoverage(v);
|
||||
}
|
||||
}
|
||||
sqlite3VdbeAddOp2(v, pIn->eEndLoopOp, pIn->iCur, pIn->addrInTop);
|
||||
VdbeCoverage(v);
|
||||
|
||||
@@ -1711,6 +1711,9 @@ Bitmask sqlite3WhereCodeOneLoopStart(
|
||||
nExtraReg = 1;
|
||||
bSeekPastNull = 1;
|
||||
pLevel->regBignull = regBignull = ++pParse->nMem;
|
||||
if( pLevel->iLeftJoin ){
|
||||
sqlite3VdbeAddOp2(v, OP_Integer, 0, regBignull);
|
||||
}
|
||||
pLevel->addrBignull = sqlite3VdbeMakeLabel(pParse);
|
||||
}
|
||||
|
||||
|
||||
@@ -933,6 +933,7 @@ int sqlite3WindowRewrite(Parse *pParse, Select *p){
|
||||
Window *pMWin = p->pWin; /* Master window object */
|
||||
Window *pWin; /* Window object iterator */
|
||||
Table *pTab;
|
||||
u32 selFlags = p->selFlags;
|
||||
|
||||
pTab = sqlite3DbMallocZero(db, sizeof(Table));
|
||||
if( pTab==0 ){
|
||||
@@ -1022,6 +1023,7 @@ int sqlite3WindowRewrite(Parse *pParse, Select *p){
|
||||
sqlite3SrcListAssignCursors(pParse, p->pSrc);
|
||||
pSub->selFlags |= SF_Expanded;
|
||||
pTab2 = sqlite3ResultSetOfSelect(pParse, pSub, SQLITE_AFF_NONE);
|
||||
pSub->selFlags |= (selFlags & SF_Aggregate);
|
||||
if( pTab2==0 ){
|
||||
/* Might actually be some other kind of error, but in that case
|
||||
** pParse->nErr will be set, so if SQLITE_NOMEM is set, we will get
|
||||
@@ -1910,6 +1912,7 @@ static int windowInitAccum(Parse *pParse, Window *pMWin){
|
||||
Window *pWin;
|
||||
for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
|
||||
FuncDef *pFunc = pWin->pFunc;
|
||||
assert( pWin->regAccum );
|
||||
sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regAccum);
|
||||
nArg = MAX(nArg, windowArgCount(pWin));
|
||||
if( pMWin->regStartRowid==0 ){
|
||||
@@ -2288,6 +2291,10 @@ Window *sqlite3WindowDup(sqlite3 *db, Expr *pOwner, Window *p){
|
||||
pNew->eStart = p->eStart;
|
||||
pNew->eExclude = p->eExclude;
|
||||
pNew->regResult = p->regResult;
|
||||
pNew->regAccum = p->regAccum;
|
||||
pNew->iArgCol = p->iArgCol;
|
||||
pNew->iEphCsr = p->iEphCsr;
|
||||
pNew->bExprArgs = p->bExprArgs;
|
||||
pNew->pStart = sqlite3ExprDup(db, p->pStart, 0);
|
||||
pNew->pEnd = sqlite3ExprDup(db, p->pEnd, 0);
|
||||
pNew->pOwner = pOwner;
|
||||
|
||||
+30
-1
@@ -594,7 +594,6 @@ reset_db
|
||||
do_execsql_test 18.1.0 {
|
||||
CREATE TABLE t0 (c0 INTEGER, PRIMARY KEY(c0)) WITHOUT ROWID;
|
||||
}
|
||||
breakpoint
|
||||
do_execsql_test 18.1.1 {
|
||||
ALTER TABLE t0 RENAME COLUMN c0 TO c1;
|
||||
}
|
||||
@@ -630,4 +629,34 @@ do_execsql_test 19.120 {
|
||||
SELECT * FROM t2;
|
||||
} {1 1 1 1 1 1 1 1}
|
||||
|
||||
# Ticket 4722bdab08cb14
|
||||
reset_db
|
||||
do_execsql_test 20.0 {
|
||||
CREATE TABLE a(a);
|
||||
CREATE VIEW b AS SELECT(SELECT *FROM c JOIN a USING(d, a, a, a) JOIN a) IN();
|
||||
}
|
||||
do_execsql_test 20.1 {
|
||||
ALTER TABLE a RENAME a TO e;
|
||||
} {}
|
||||
|
||||
reset_db
|
||||
do_execsql_test 21.0 {
|
||||
CREATE TABLE a(b);
|
||||
CREATE VIEW c AS
|
||||
SELECT NULL INTERSECT
|
||||
SELECT NULL ORDER BY
|
||||
likelihood(NULL, (d, (SELECT c)));
|
||||
} {}
|
||||
do_catchsql_test 21.1 {
|
||||
SELECT likelihood(NULL, (d, (SELECT c)));
|
||||
} {1 {second argument to likelihood() must be a constant between 0.0 and 1.0}}
|
||||
do_catchsql_test 21.2 {
|
||||
SELECT * FROM c;
|
||||
} {1 {1st ORDER BY term does not match any column in the result set}}
|
||||
|
||||
do_catchsql_test 21.3 {
|
||||
ALTER TABLE a RENAME TO e;
|
||||
} {1 {error in view c: 1st ORDER BY term does not match any column in the result set}}
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
+5
-8
@@ -148,10 +148,8 @@ do_test attach-1.14 {
|
||||
ATTACH 'test.db' as db9;
|
||||
}
|
||||
} {1 {database db9 is already in use}}
|
||||
do_test attach-1.15 {
|
||||
catchsql {
|
||||
ATTACH 'test.db' as main;
|
||||
}
|
||||
do_catchsql_test attach-1.15 {
|
||||
ATTACH 'test.db' as main;
|
||||
} {1 {database main is already in use}}
|
||||
ifcapable tempdb {
|
||||
do_test attach-1.16 {
|
||||
@@ -160,10 +158,8 @@ ifcapable tempdb {
|
||||
}
|
||||
} {1 {database temp is already in use}}
|
||||
}
|
||||
do_test attach-1.17 {
|
||||
catchsql {
|
||||
ATTACH 'test.db' as MAIN;
|
||||
}
|
||||
do_catchsql_test attach-1.17 {
|
||||
ATTACH 'test.db' as MAIN;
|
||||
} {1 {database MAIN is already in use}}
|
||||
do_test attach-1.18 {
|
||||
catchsql {
|
||||
@@ -231,6 +227,7 @@ do_test attach-1.26 {
|
||||
}
|
||||
} {1 {cannot detach database main}}
|
||||
|
||||
|
||||
ifcapable tempdb {
|
||||
do_test attach-1.27 {
|
||||
catchsql {
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
set testprefix cse
|
||||
|
||||
do_test cse-1.1 {
|
||||
execsql {
|
||||
@@ -157,4 +158,43 @@ for {set i 1} {$i<100} {incr i} {
|
||||
} $answer
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# Ticket fd1bda016d1a
|
||||
#
|
||||
reset_db
|
||||
do_execsql_test 3.0 {
|
||||
CREATE TABLE t1(a TEXT, b);
|
||||
INSERT INTO t1 VALUES('hello', 0);
|
||||
INSERT INTO t1 VALUES('world', 0);
|
||||
|
||||
CREATE TABLE t2(x TEXT);
|
||||
INSERT INTO t2 VALUES('hello');
|
||||
INSERT INTO t2 VALUES('world');
|
||||
|
||||
CREATE TABLE t3(y);
|
||||
INSERT INTO t3 VALUES(1000);
|
||||
} {}
|
||||
|
||||
do_execsql_test 3.1 {
|
||||
SELECT 1000 = y FROM t3
|
||||
} {1}
|
||||
|
||||
do_execsql_test 3.2 {
|
||||
SELECT 1000 IN (SELECT x FROM t2), 1000 = y FROM t3
|
||||
} {0 1}
|
||||
|
||||
do_execsql_test 3.3 {
|
||||
SELECT 0 IN (SELECT a), (SELECT a LIMIT 0) FROM t1
|
||||
} {0 {} 0 {}}
|
||||
|
||||
do_execsql_test 3.4 {
|
||||
SELECT 0 IN (SELECT a) FROM t1 WHERE a = 'hello' OR (SELECT a LIMIT 0);
|
||||
} {0}
|
||||
|
||||
do_execsql_test 3.5 {
|
||||
CREATE TABLE v0(v1 VARCHAR0);
|
||||
INSERT INTO v0 VALUES(2), (3);
|
||||
SELECT 0 IN(SELECT v1) FROM v0 WHERE v1 = 2 OR(SELECT v1 LIMIT 0);
|
||||
} {0}
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -128,4 +128,13 @@ do_catchsql_test default-4.4 {
|
||||
CREATE TABLE t2(a TEXT, b TEXT DEFAULT(98+coalesce(5,:xyz)));
|
||||
} {1 {default value of column [b] is not constant}}
|
||||
|
||||
# 2020-03-09 out-of-bounds memory access discovered by "Eternal Sakura"
|
||||
# and reported to chromium.
|
||||
#
|
||||
reset_db
|
||||
do_catchsql_test default-5.1 {
|
||||
CREATE TABLE t1 (a,b DEFAULT(random() NOTNULL IN (RAISE(IGNORE),2,3)));
|
||||
INSERT INTO t1(a) VALUES(1);
|
||||
} {1 {RAISE() may only be used within a trigger-program}}
|
||||
|
||||
finish_test
|
||||
|
||||
+44
-36
@@ -395,17 +395,19 @@ do_createtable_tests 1.2.2 {
|
||||
4 {CREATE TABLE auxb.xyz(z)} {}
|
||||
}
|
||||
drop_all_tables
|
||||
do_createtable_tests 1.3 -tclquery {
|
||||
unset -nocomplain X
|
||||
array set X [table_list]
|
||||
list $X(main) $X(temp) $X(auxa) $X(auxb)
|
||||
} {
|
||||
1 "CREATE TABLE main.abc(a, b, c)" {abc {} {} {}}
|
||||
2 "CREATE TABLE main.t1(a, b, c)" {{abc t1} {} {} {}}
|
||||
3 "CREATE TABLE temp.tmp(a, b, c)" {{abc t1} tmp {} {}}
|
||||
4 "CREATE TABLE auxb.tbl(x, y)" {{abc t1} tmp {} tbl}
|
||||
5 "CREATE TABLE auxb.t1(k, v)" {{abc t1} tmp {} {t1 tbl}}
|
||||
6 "CREATE TABLE auxa.next(c, d)" {{abc t1} tmp next {t1 tbl}}
|
||||
if {[permutation]!="maindbname"} {
|
||||
do_createtable_tests 1.3 -tclquery {
|
||||
unset -nocomplain X
|
||||
array set X [table_list]
|
||||
list $X(main) $X(temp) $X(auxa) $X(auxb)
|
||||
} {
|
||||
1 "CREATE TABLE main.abc(a, b, c)" {abc {} {} {}}
|
||||
2 "CREATE TABLE main.t1(a, b, c)" {{abc t1} {} {} {}}
|
||||
3 "CREATE TABLE temp.tmp(a, b, c)" {{abc t1} tmp {} {}}
|
||||
4 "CREATE TABLE auxb.tbl(x, y)" {{abc t1} tmp {} tbl}
|
||||
5 "CREATE TABLE auxb.t1(k, v)" {{abc t1} tmp {} {t1 tbl}}
|
||||
6 "CREATE TABLE auxa.next(c, d)" {{abc t1} tmp next {t1 tbl}}
|
||||
}
|
||||
}
|
||||
|
||||
# EVIDENCE-OF: R-18895-27365 If the "TEMP" or "TEMPORARY" keyword occurs
|
||||
@@ -413,13 +415,15 @@ do_createtable_tests 1.3 -tclquery {
|
||||
# temp database.
|
||||
#
|
||||
drop_all_tables
|
||||
do_createtable_tests 1.4 -tclquery {
|
||||
unset -nocomplain X
|
||||
array set X [table_list]
|
||||
list $X(main) $X(temp) $X(auxa) $X(auxb)
|
||||
} {
|
||||
1 "CREATE TEMP TABLE t1(a, b)" {{} t1 {} {}}
|
||||
2 "CREATE TEMPORARY TABLE t2(a, b)" {{} {t1 t2} {} {}}
|
||||
if {[permutation]!="maindbname"} {
|
||||
do_createtable_tests 1.4 -tclquery {
|
||||
unset -nocomplain X
|
||||
array set X [table_list]
|
||||
list $X(main) $X(temp) $X(auxa) $X(auxb)
|
||||
} {
|
||||
1 "CREATE TEMP TABLE t1(a, b)" {{} t1 {} {}}
|
||||
2 "CREATE TEMPORARY TABLE t2(a, b)" {{} {t1 t2} {} {}}
|
||||
}
|
||||
}
|
||||
|
||||
# EVIDENCE-OF: R-23976-43329 It is an error to specify both a
|
||||
@@ -436,30 +440,34 @@ do_createtable_tests 1.5.1 -error {
|
||||
4 "CREATE TEMPORARY TABLE main.xxx(x)" {}
|
||||
}
|
||||
drop_all_tables
|
||||
do_createtable_tests 1.5.2 -tclquery {
|
||||
unset -nocomplain X
|
||||
array set X [table_list]
|
||||
list $X(main) $X(temp) $X(auxa) $X(auxb)
|
||||
} {
|
||||
1 "CREATE TEMP TABLE temp.t1(a, b)" {{} t1 {} {}}
|
||||
2 "CREATE TEMPORARY TABLE temp.t2(a, b)" {{} {t1 t2} {} {}}
|
||||
3 "CREATE TEMP TABLE TEMP.t3(a, b)" {{} {t1 t2 t3} {} {}}
|
||||
4 "CREATE TEMPORARY TABLE TEMP.xxx(x)" {{} {t1 t2 t3 xxx} {} {}}
|
||||
if {[permutation]!="maindbname"} {
|
||||
do_createtable_tests 1.5.2 -tclquery {
|
||||
unset -nocomplain X
|
||||
array set X [table_list]
|
||||
list $X(main) $X(temp) $X(auxa) $X(auxb)
|
||||
} {
|
||||
1 "CREATE TEMP TABLE temp.t1(a, b)" {{} t1 {} {}}
|
||||
2 "CREATE TEMPORARY TABLE temp.t2(a, b)" {{} {t1 t2} {} {}}
|
||||
3 "CREATE TEMP TABLE TEMP.t3(a, b)" {{} {t1 t2 t3} {} {}}
|
||||
4 "CREATE TEMPORARY TABLE TEMP.xxx(x)" {{} {t1 t2 t3 xxx} {} {}}
|
||||
}
|
||||
}
|
||||
|
||||
# EVIDENCE-OF: R-31997-24564 If no schema name is specified and the TEMP
|
||||
# keyword is not present then the table is created in the main database.
|
||||
#
|
||||
drop_all_tables
|
||||
do_createtable_tests 1.6 -tclquery {
|
||||
unset -nocomplain X
|
||||
array set X [table_list]
|
||||
list $X(main) $X(temp) $X(auxa) $X(auxb)
|
||||
} {
|
||||
1 "CREATE TABLE t1(a, b)" {t1 {} {} {}}
|
||||
2 "CREATE TABLE t2(a, b)" {{t1 t2} {} {} {}}
|
||||
3 "CREATE TABLE t3(a, b)" {{t1 t2 t3} {} {} {}}
|
||||
4 "CREATE TABLE xxx(x)" {{t1 t2 t3 xxx} {} {} {}}
|
||||
if {[permutation]!="maindbname"} {
|
||||
do_createtable_tests 1.6 -tclquery {
|
||||
unset -nocomplain X
|
||||
array set X [table_list]
|
||||
list $X(main) $X(temp) $X(auxa) $X(auxb)
|
||||
} {
|
||||
1 "CREATE TABLE t1(a, b)" {t1 {} {} {}}
|
||||
2 "CREATE TABLE t2(a, b)" {{t1 t2} {} {} {}}
|
||||
3 "CREATE TABLE t3(a, b)" {{t1 t2 t3} {} {} {}}
|
||||
4 "CREATE TABLE xxx(x)" {{t1 t2 t3 xxx} {} {} {}}
|
||||
}
|
||||
}
|
||||
|
||||
drop_all_tables
|
||||
|
||||
+18
-18
@@ -126,37 +126,37 @@ do_execsql_test 3.1.0 { SELECT * FROM temp.v1 } {{a temp} {b temp}}
|
||||
do_execsql_test 3.1.1 { DROP VIEW temp.v1 } {}
|
||||
do_catchsql_test 3.1.2 { SELECT * FROM temp.v1 } {1 {no such table: temp.v1}}
|
||||
do_test 3.1.3 { list_all_views } {main.v1 main.v2 aux.v1 aux.v2 aux.v3}
|
||||
do_test 3.1.4 { list_all_data } $databasedata
|
||||
do_test 3.1.4 { string compare [list_all_data] $databasedata } 0
|
||||
|
||||
do_execsql_test 3.2.0 { SELECT * FROM v1 } {{a main} {b main}}
|
||||
do_execsql_test 3.2.1 { DROP VIEW v1 } {}
|
||||
do_catchsql_test 3.2.2 { SELECT * FROM main.v1 } {1 {no such table: main.v1}}
|
||||
do_test 3.2.3 { list_all_views } {main.v2 aux.v1 aux.v2 aux.v3}
|
||||
do_test 3.2.4 { list_all_data } $databasedata
|
||||
do_test 3.2.4 { string compare [list_all_data] $databasedata } 0
|
||||
|
||||
do_execsql_test 3.3.0 { SELECT * FROM v2 } {{a main} {b main}}
|
||||
do_execsql_test 3.3.1 { DROP VIEW v2 } {}
|
||||
do_catchsql_test 3.3.2 { SELECT * FROM main.v2 } {1 {no such table: main.v2}}
|
||||
do_test 3.3.3 { list_all_views } {aux.v1 aux.v2 aux.v3}
|
||||
do_test 3.3.4 { list_all_data } $databasedata
|
||||
do_test 3.3.4 { string compare [list_all_data] $databasedata } 0
|
||||
|
||||
do_execsql_test 3.4.0 { SELECT * FROM v1 } {{a aux} {b aux}}
|
||||
do_execsql_test 3.4.1 { DROP VIEW v1 } {}
|
||||
do_catchsql_test 3.4.2 { SELECT * FROM v1 } {1 {no such table: v1}}
|
||||
do_test 3.4.3 { list_all_views } {aux.v2 aux.v3}
|
||||
do_test 3.4.4 { list_all_data } $databasedata
|
||||
do_test 3.4.4 { string compare [list_all_data] $databasedata } 0
|
||||
|
||||
do_execsql_test 3.4.0 { SELECT * FROM aux.v2 } {{a aux} {b aux}}
|
||||
do_execsql_test 3.4.1 { DROP VIEW aux.v2 } {}
|
||||
do_catchsql_test 3.4.2 { SELECT * FROM aux.v2 } {1 {no such table: aux.v2}}
|
||||
do_test 3.4.3 { list_all_views } {aux.v3}
|
||||
do_test 3.4.4 { list_all_data } $databasedata
|
||||
do_execsql_test 3.5.0 { SELECT * FROM aux.v2 } {{a aux} {b aux}}
|
||||
do_execsql_test 3.5.1 { DROP VIEW aux.v2 } {}
|
||||
do_catchsql_test 3.5.2 { SELECT * FROM aux.v2 } {1 {no such table: aux.v2}}
|
||||
do_test 3.5.3 { list_all_views } {aux.v3}
|
||||
do_test 3.5.4 { string compare [list_all_data] $databasedata } 0
|
||||
|
||||
do_execsql_test 3.5.0 { SELECT * FROM v3 } {{a aux} {b aux}}
|
||||
do_execsql_test 3.5.1 { DROP VIEW v3 } {}
|
||||
do_catchsql_test 3.5.2 { SELECT * FROM v3 } {1 {no such table: v3}}
|
||||
do_test 3.5.3 { list_all_views } {}
|
||||
do_test 3.5.4 { list_all_data } $databasedata
|
||||
do_execsql_test 3.6.0 { SELECT * FROM v3 } {{a aux} {b aux}}
|
||||
do_execsql_test 3.6.1 { DROP VIEW v3 } {}
|
||||
do_catchsql_test 3.6.2 { SELECT * FROM v3 } {1 {no such table: v3}}
|
||||
do_test 3.6.3 { list_all_views } {}
|
||||
do_test 3.6.4 { string compare [list_all_data] $databasedata } 0
|
||||
|
||||
# EVIDENCE-OF: R-25558-37487 If the specified view cannot be found and
|
||||
# the IF EXISTS clause is not present, it is an error.
|
||||
@@ -179,11 +179,11 @@ do_dropview_tests 5 -repair {
|
||||
dropview_reopen_db
|
||||
} -tclquery {
|
||||
list_all_views
|
||||
expr {[list_all_views] == "main.v1 main.v2 temp.v1 aux.v1 aux.v2 aux.v3"}
|
||||
#expr {[list_all_views] == "main.v1 main.v2 temp.v1 aux.v1 aux.v2 aux.v3"}
|
||||
} {
|
||||
1 "DROP VIEW IF EXISTS xx" 1
|
||||
2 "DROP VIEW IF EXISTS main.xx" 1
|
||||
3 "DROP VIEW IF EXISTS temp.v2" 1
|
||||
1 "DROP VIEW IF EXISTS xx" "main.v1 main.v2 temp.v1 aux.v1 aux.v2 aux.v3"
|
||||
2 "DROP VIEW IF EXISTS main.xx" "main.v1 main.v2 temp.v1 aux.v1 aux.v2 aux.v3"
|
||||
3 "DROP VIEW IF EXISTS temp.v2" "main.v1 main.v2 temp.v1 aux.v1 aux.v2 aux.v3"
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -169,4 +169,84 @@ do_test enc-11.2 {
|
||||
}
|
||||
} {2}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
reset_db
|
||||
forcedelete test.db2
|
||||
forcedelete test.db3
|
||||
|
||||
do_execsql_test enc-12.0 {
|
||||
PRAGMA encoding = 'utf-8';
|
||||
CREATE TABLE t1(a, b, c);
|
||||
INSERT INTO t1 VALUES('a', 'b', 'c');
|
||||
ATTACH 'test.db3' AS aux;
|
||||
CREATE TABLE aux.t3(x, y, z);
|
||||
INSERT INTO t3 VALUES('xxx', 'yyy', 'zzz');
|
||||
PRAGMA encoding;
|
||||
} {UTF-8}
|
||||
|
||||
do_test enc-12.1 {
|
||||
sqlite3 db2 test.db2
|
||||
db2 eval {
|
||||
PRAGMA encoding = 'UTF-16le';
|
||||
CREATE TABLE t2(d, e, f);
|
||||
INSERT INTO t2 VALUES('d', 'e', 'f');
|
||||
PRAGMA encoding;
|
||||
}
|
||||
} {UTF-16le}
|
||||
|
||||
do_test enc-12.2 {
|
||||
db2 backup test.db
|
||||
db2 close
|
||||
} {}
|
||||
|
||||
do_catchsql_test enc-12.3 {
|
||||
SELECT * FROM t2;
|
||||
} {1 {attached databases must use the same text encoding as main database}}
|
||||
|
||||
db close
|
||||
sqlite3 db test.db3
|
||||
do_execsql_test enc-12.4 {
|
||||
SELECT * FROM t3;
|
||||
PRAGMA encoding = 'UTF-16le';
|
||||
SELECT * FROM t3;
|
||||
} {xxx yyy zzz xxx yyy zzz}
|
||||
|
||||
db close
|
||||
sqlite3 db test.db3
|
||||
breakpoint
|
||||
do_execsql_test enc-12.5 {
|
||||
PRAGMA encoding = 'UTF-16le';
|
||||
PRAGMA encoding;
|
||||
} {UTF-8}
|
||||
|
||||
reset_db
|
||||
do_execsql_test enc-12.6 {
|
||||
PRAGMA encoding = 'UTF-8';
|
||||
CREATE TEMP TABLE t1(a, b, c);
|
||||
INSERT INTO t1 VALUES('xxx', 'yyy', 'zzz');
|
||||
}
|
||||
do_test enc-12.7 {
|
||||
sqlite3 db2 test.db2
|
||||
db2 backup test.db
|
||||
db2 close
|
||||
db eval {
|
||||
SELECT * FROM t1;
|
||||
}
|
||||
} {xxx yyy zzz}
|
||||
do_catchsql_test enc-12.8 {
|
||||
SELECT * FROM t2;
|
||||
SELECT * FROM t1;
|
||||
} {1 {attached databases must use the same text encoding as main database}}
|
||||
|
||||
db close
|
||||
sqlite3 db test.db
|
||||
do_execsql_test enc-12.9 {
|
||||
CREATE TEMP TABLE t1(a, b, c);
|
||||
INSERT INTO t1 VALUES('xxx', 'yyy', 'zzz');
|
||||
}
|
||||
do_execsql_test enc-12.10 {
|
||||
SELECT * FROM t2;
|
||||
SELECT * FROM t1;
|
||||
} {d e f xxx yyy zzz}
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -181,4 +181,16 @@ do_catchsql_test 6.10 {
|
||||
INSERT INTO f(f) VALUES ("merge=1");
|
||||
} {1 {database disk image is malformed}}
|
||||
|
||||
# 2020-03-02 https://bugs.chromium.org/p/chromium/issues/detail?id=1057441
|
||||
# The ticket complains of use of an uninitialized value. That part is harmless.
|
||||
# The only reason to fix this is the failure to detect a subtly corrupt
|
||||
# inverted index.
|
||||
#
|
||||
reset_db
|
||||
do_catchsql_test 7.10 {
|
||||
CREATE VIRTUAL TABLE f USING fts3(a,b);
|
||||
INSERT INTO f_segdir VALUES (0,0,1,0,'0 0',x'01010101020101');
|
||||
SELECT matchinfo( f , 'pcx') FROM f WHERE b MATCH x'c533';
|
||||
} {1 {database disk image is malformed}}
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -5834,4 +5834,17 @@ do_catchsql_test 36.1 {
|
||||
INSERT INTO f(f) VALUES ('merge=59,59');
|
||||
} {1 {database disk image is malformed}}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
reset_db
|
||||
do_execsql_test 37.0 {
|
||||
CREATE VIRTUAL TABLE f USING fts3(a,b);
|
||||
INSERT INTO f_segdir VALUES (28,0,0,0,'0 0',x'00');
|
||||
INSERT INTO f_segdir VALUES (0,241,0,0,'0 0',x'0001000030310000f1');
|
||||
}
|
||||
|
||||
do_catchsql_test 37.1 {
|
||||
INSERT INTO f VALUES (0,x'00');
|
||||
} {1 {database disk image is malformed}}
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -303,4 +303,16 @@ do_execsql_test 9.2 {
|
||||
-4764623217061966105 8324454597464624651
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
reset_db
|
||||
do_execsql_test 10.0 {
|
||||
CREATE VIRTUAL TABLE f USING fts3(a,b);
|
||||
CREATE TABLE 'f_stat'(id INTEGER PRIMARY KEY, value BLOB);
|
||||
INSERT INTO f_stat VALUES (1,x'3b3b3b3b3b3b3b28ffffffffffffffffff1807f9073481f1d43bc93b3b3b3b3b3b3b3b3b3b18073b3b3b3b3b3b3b9b003b');
|
||||
} {}
|
||||
|
||||
do_catchsql_test 10.1 {
|
||||
INSERT INTO f(f) VALUES ('merge=69,59');
|
||||
} {1 {database disk image is malformed}}
|
||||
|
||||
finish_test
|
||||
|
||||
+2
-2
@@ -234,13 +234,13 @@ if {$tcl_platform(byteOrder)=="littleEndian"} {
|
||||
} else {
|
||||
set res {X'0000000200000000000000000000000E0000000E00000001000000010000000100000001'}
|
||||
}
|
||||
do_execsql_test fts4aa-6.10 {
|
||||
do_catchsql_test fts4aa-6.10 {
|
||||
CREATE VIRTUAL TABLE f USING fts4();
|
||||
INSERT INTO f_segdir VALUES (77,91,0,0,'255 77',x'0001308000004d5c4ddddddd4d4d7b4d4d4d614d8019ff4d05000001204d4d2e4d6e4d4d4d4b4d6c4d004d4d4d4d4d4d3d000000004d5d4d4d645d4d004d4d4d4d4d4d4d4d4d454d6910004d05ffff054d646c4d004d5d4d4d4d4d3d000000004d4d4d4d4d4d4d4d4d4d4d69624d4d4d04004d4d4d4d4d604d4ce1404d554d45');
|
||||
INSERT INTO f_segdir VALUES (77,108,0,0,'255 77',x'0001310000fa64004d4d4d3c5d4d654d4d4d614d8000ff4d05000001204d4d2e4d6e4d4d4dff4d4d4d4d4d4d00104d4d4d4d000000004d4d4d0400311d4d4d4d4d4d4d4d4d4d684d6910004d05ffff054d4d6c4d004d4d4d4d4d4d3d000000004d4d4d4d644d4d4d4d4d4d69624d4d4d03ed4d4d4d4d4d604d4ce1404d550080');
|
||||
INSERT INTO f_stat VALUES (0,x'80808080100000000064004d4d4d3c4d4d654d4d4d614d8000ff4df6ff1a00204d4d2e4d6e4d4d4d104d4d4d4d4d4d00104d4d4d4d4d4d69574d4d4d000031044d4d4d3e4d4d4c4d05004d6910');
|
||||
SELECT quote(matchinfo(f,'pnax')) from f where f match '0 1';
|
||||
} $res
|
||||
} {1 {database disk image is malformed}}
|
||||
|
||||
# 2019-11-18 Detect infinite loop in fts3SelectLeaf()
|
||||
db close
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
# 2020 February 27
|
||||
#
|
||||
# The author disclaims copyright to this source code. In place of
|
||||
# a legal notice, here is a blessing:
|
||||
#
|
||||
# May you do good and not evil.
|
||||
# May you find forgiveness for yourself and forgive others.
|
||||
# May you share freely, never taking more than you give.
|
||||
#
|
||||
#*************************************************************************
|
||||
#
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
source $testdir/fts3_common.tcl
|
||||
set ::testprefix fts4min
|
||||
|
||||
# If SQLITE_ENABLE_FTS3 is defined, omit this file.
|
||||
ifcapable !fts3 {
|
||||
finish_test
|
||||
return
|
||||
}
|
||||
|
||||
#------------------------------------------------------------------
|
||||
do_execsql_test 0.0 {
|
||||
CREATE TABLE t1(a NOT NULL, b);
|
||||
CREATE INDEX i1 ON t1(a);
|
||||
}
|
||||
|
||||
do_execsql_test 1.0 {
|
||||
CREATE VIRTUAL TABLE ft USING fts3(c);
|
||||
INSERT INTO ft(docid, c) VALUES(22, 'hello world');
|
||||
INSERT INTO ft(docid, c) VALUES(44, 'hello world');
|
||||
INSERT INTO ft(docid, c) VALUES(11, 'hello world');
|
||||
}
|
||||
|
||||
do_eqp_test 1.1.1 {
|
||||
SELECT max(rowid) FROM ft
|
||||
} {VIRTUAL TABLE INDEX 0:DESC}
|
||||
|
||||
do_eqp_test 1.1.2 {
|
||||
SELECT min(rowid) FROM ft
|
||||
} {VIRTUAL TABLE INDEX 0:ASC}
|
||||
|
||||
do_execsql_test 1.2.1 {
|
||||
SELECT max(rowid) FROM ft
|
||||
} {44}
|
||||
|
||||
do_execsql_test 1.2.2 {
|
||||
SELECT min(rowid) FROM ft
|
||||
} {11}
|
||||
|
||||
finish_test
|
||||
@@ -1477,4 +1477,24 @@ do_execsql_test func-34.10 {
|
||||
SELECT * FROM t1;
|
||||
} {1 2}
|
||||
|
||||
# 2020-03-11 COALESCE() should short-circuit
|
||||
# See also ticket 3c9eadd2a6ba0aa5
|
||||
# Both issues stem from the fact that functions that could
|
||||
# throw exceptions were being factored out into initialization
|
||||
# code. The fix was to put those function calls inside of
|
||||
# OP_Once instead.
|
||||
#
|
||||
reset_db
|
||||
do_execsql_test func-35.100 {
|
||||
CREATE TABLE t1(x);
|
||||
SELECT coalesce(x, abs(-9223372036854775808)) FROM t1;
|
||||
} {}
|
||||
do_execsql_test func-35.110 {
|
||||
SELECT coalesce(x, 'xyz' LIKE printf('%.1000000c','y')) FROM t1;
|
||||
} {}
|
||||
do_execsql_test func-35.200 {
|
||||
CREATE TABLE t0(c0 CHECK(ABS(-9223372036854775808)));
|
||||
PRAGMA integrity_check;
|
||||
} {ok}
|
||||
|
||||
finish_test
|
||||
|
||||
+2
-1
@@ -53,9 +53,10 @@ do_execsql_test func5-2.2 {
|
||||
WHERE x+counter1('hello')=counter1('hello')+x
|
||||
ORDER BY +x;
|
||||
} {}
|
||||
set cvalue [db one {SELECT counter2('hello')+1}]
|
||||
do_execsql_test func5-2.3 {
|
||||
SELECT x, y FROM t2
|
||||
WHERE x+counter2('hello')=counter2('hello')+x
|
||||
WHERE x+counter2('hello')=$cvalue+x
|
||||
ORDER BY +x;
|
||||
} {1 2 3 4 5 6 7 8}
|
||||
|
||||
|
||||
+138
-14
@@ -11,8 +11,7 @@
|
||||
*************************************************************************
|
||||
**
|
||||
** This is a utility program designed to aid running regressions tests on
|
||||
** the SQLite library using data from an external fuzzer, such as American
|
||||
** Fuzzy Lop (AFL) (http://lcamtuf.coredump.cx/afl/).
|
||||
** the SQLite library using data from external fuzzers.
|
||||
**
|
||||
** This program reads content from an SQLite database file with the following
|
||||
** schema:
|
||||
@@ -63,6 +62,21 @@
|
||||
** If fuzzcheck does crash, it can be run in the debugger and the content
|
||||
** of the global variable g.zTextName[] will identify the specific XSQL and
|
||||
** DB values that were running when the crash occurred.
|
||||
**
|
||||
** DBSQLFUZZ:
|
||||
**
|
||||
** The dbsqlfuzz fuzzer includes both a database file and SQL to run against
|
||||
** that database in its input. This utility can now process dbsqlfuzz
|
||||
** input files. Load such files using the "--load-dbsql FILE ..." command-line
|
||||
** option.
|
||||
**
|
||||
** Dbsqlfuzz inputs are ordinary text. The first part of the file is text
|
||||
** that describes the content of the database (using a lot of hexadecimal),
|
||||
** then there is a divider line followed by the SQL to run against the
|
||||
** database. Because they are ordinary text, dbsqlfuzz inputs are stored
|
||||
** in the XSQL table, as if they were ordinary SQL inputs. The isDbSql()
|
||||
** function can look at a text string and determine whether or not it is
|
||||
** a valid dbsqlfuzz input.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@@ -80,11 +94,9 @@
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
#ifdef SQLITE_OSS_FUZZ
|
||||
# include <stddef.h>
|
||||
# if !defined(_MSC_VER)
|
||||
# include <stdint.h>
|
||||
# endif
|
||||
#include <stddef.h>
|
||||
#if !defined(_MSC_VER)
|
||||
# include <stdint.h>
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
@@ -322,6 +334,39 @@ static void readfileFunc(
|
||||
fclose(in);
|
||||
}
|
||||
|
||||
/*
|
||||
** Implementation of the "readtextfile(X)" SQL function. The text content
|
||||
** of the file named X through the end of the file or to the first \000
|
||||
** character, whichever comes first, is read and returned as TEXT. NULL
|
||||
** is returned if the file does not exist or is unreadable.
|
||||
*/
|
||||
static void readtextfileFunc(
|
||||
sqlite3_context *context,
|
||||
int argc,
|
||||
sqlite3_value **argv
|
||||
){
|
||||
const char *zName;
|
||||
FILE *in;
|
||||
long nIn;
|
||||
char *pBuf;
|
||||
|
||||
zName = (const char*)sqlite3_value_text(argv[0]);
|
||||
if( zName==0 ) return;
|
||||
in = fopen(zName, "rb");
|
||||
if( in==0 ) return;
|
||||
fseek(in, 0, SEEK_END);
|
||||
nIn = ftell(in);
|
||||
rewind(in);
|
||||
pBuf = sqlite3_malloc64( nIn+1 );
|
||||
if( pBuf && 1==fread(pBuf, nIn, 1, in) ){
|
||||
pBuf[nIn] = 0;
|
||||
sqlite3_result_text(context, pBuf, -1, sqlite3_free);
|
||||
}else{
|
||||
sqlite3_free(pBuf);
|
||||
}
|
||||
fclose(in);
|
||||
}
|
||||
|
||||
/*
|
||||
** Implementation of the "writefile(X,Y)" SQL function. The argument Y
|
||||
** is written into file X. The number of bytes written is returned. Or
|
||||
@@ -466,13 +511,64 @@ static int lengthLimit = 1000000;
|
||||
static int depthLimit = 500;
|
||||
|
||||
/* Limit on the amount of heap memory that can be used */
|
||||
static sqlite3_int64 heapLimit = 1000000000;
|
||||
static sqlite3_int64 heapLimit = 100000000;
|
||||
|
||||
/* Maximum byte-code program length in SQLite */
|
||||
static int vdbeOpLimit = 25000;
|
||||
|
||||
/* Maximum size of the in-memory database */
|
||||
static sqlite3_int64 maxDbSize = 104857600;
|
||||
/* OOM simulation parameters */
|
||||
static unsigned int oomCounter = 0; /* Simulate OOM when equals 1 */
|
||||
static unsigned int oomRepeat = 0; /* Number of OOMs in a row */
|
||||
static void*(*defaultMalloc)(int) = 0; /* The low-level malloc routine */
|
||||
|
||||
/* This routine is called when a simulated OOM occurs. It is broken
|
||||
** out as a separate routine to make it easy to set a breakpoint on
|
||||
** the OOM
|
||||
*/
|
||||
void oomFault(void){
|
||||
if( eVerbosity ){
|
||||
printf("Simulated OOM fault\n");
|
||||
}
|
||||
if( oomRepeat>0 ){
|
||||
oomRepeat--;
|
||||
}else{
|
||||
oomCounter--;
|
||||
}
|
||||
}
|
||||
|
||||
/* This routine is a replacement malloc() that is used to simulate
|
||||
** Out-Of-Memory (OOM) errors for testing purposes.
|
||||
*/
|
||||
static void *oomMalloc(int nByte){
|
||||
if( oomCounter ){
|
||||
if( oomCounter==1 ){
|
||||
oomFault();
|
||||
return 0;
|
||||
}else{
|
||||
oomCounter--;
|
||||
}
|
||||
}
|
||||
return defaultMalloc(nByte);
|
||||
}
|
||||
|
||||
/* Register the OOM simulator. This must occur before any memory
|
||||
** allocations */
|
||||
static void registerOomSimulator(void){
|
||||
sqlite3_mem_methods mem;
|
||||
sqlite3_shutdown();
|
||||
sqlite3_config(SQLITE_CONFIG_GETMALLOC, &mem);
|
||||
defaultMalloc = mem.xMalloc;
|
||||
mem.xMalloc = oomMalloc;
|
||||
sqlite3_config(SQLITE_CONFIG_MALLOC, &mem);
|
||||
}
|
||||
|
||||
/* Turn off any pending OOM simulation */
|
||||
static void disableOom(void){
|
||||
oomCounter = 0;
|
||||
oomRepeat = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
** Translate a single byte of Hex into an integer.
|
||||
@@ -653,6 +749,9 @@ static int block_troublesome_sql(
|
||||
){
|
||||
return SQLITE_DENY;
|
||||
}
|
||||
if( sqlite3_stricmp("oom",zArg1)==0 && zArg2!=0 && zArg2[0]!=0 ){
|
||||
oomCounter = atoi(zArg2);
|
||||
}
|
||||
}else if( (eCode==SQLITE_ATTACH || eCode==SQLITE_DETACH)
|
||||
&& zArg1 && zArg1[0] ){
|
||||
return SQLITE_DENY;
|
||||
@@ -795,6 +894,7 @@ int runCombinedDbSqlInput(const uint8_t *aData, size_t nByte){
|
||||
if( depthLimit>0 ){
|
||||
sqlite3_limit(cx.db, SQLITE_LIMIT_EXPR_DEPTH, depthLimit);
|
||||
}
|
||||
sqlite3_limit(cx.db, SQLITE_LIMIT_LIKE_PATTERN_LENGTH, 100);
|
||||
sqlite3_hard_heap_limit64(heapLimit);
|
||||
|
||||
if( nDb>=20 && aDb[18]==2 && aDb[19]==2 ){
|
||||
@@ -1324,6 +1424,7 @@ static void showHelp(void){
|
||||
" -q|--quiet Reduced output\n"
|
||||
" --rebuild Rebuild and vacuum the database file\n"
|
||||
" --result-trace Show the results of each SQL command\n"
|
||||
" --spinner Use a spinner to show progress\n"
|
||||
" --sqlid N Use only SQL where sqlid=N\n"
|
||||
" --timeout N Abort if any single test needs more than N seconds\n"
|
||||
" -v|--verbose Increased output. Repeat for more output.\n"
|
||||
@@ -1350,6 +1451,7 @@ int main(int argc, char **argv){
|
||||
int rebuildFlag = 0; /* --rebuild */
|
||||
int vdbeLimitFlag = 0; /* --limit-vdbe */
|
||||
int infoFlag = 0; /* --info */
|
||||
int bSpinner = 0; /* True for --spinner */
|
||||
int timeoutTest = 0; /* undocumented --timeout-test flag */
|
||||
int runFlags = 0; /* Flags sent to runSql() */
|
||||
char *zMsg = 0; /* Add this message */
|
||||
@@ -1374,6 +1476,7 @@ int main(int argc, char **argv){
|
||||
int openFlags4Data; /* Flags for sqlite3_open_v2() */
|
||||
int nV; /* How much to increase verbosity with -vvvv */
|
||||
|
||||
registerOomSimulator();
|
||||
sqlite3_initialize();
|
||||
iBegin = timeOfDay();
|
||||
#ifdef __unix__
|
||||
@@ -1425,7 +1528,8 @@ int main(int argc, char **argv){
|
||||
vdbeLimitFlag = 1;
|
||||
}else
|
||||
if( strcmp(z,"load-sql")==0 ){
|
||||
zInsSql = "INSERT INTO xsql(sqltext)VALUES(CAST(readfile(?1) AS text))";
|
||||
zInsSql = "INSERT INTO xsql(sqltext)"
|
||||
"VALUES(CAST(readtextfile(?1) AS text))";
|
||||
iFirstInsArg = i+1;
|
||||
openFlags4Data = SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE;
|
||||
break;
|
||||
@@ -1437,7 +1541,8 @@ int main(int argc, char **argv){
|
||||
break;
|
||||
}else
|
||||
if( strcmp(z,"load-dbsql")==0 ){
|
||||
zInsSql = "INSERT INTO xsql(sqltext)VALUES(CAST(readfile(?1) AS text))";
|
||||
zInsSql = "INSERT INTO xsql(sqltext)"
|
||||
"VALUES(CAST(readtextfile(?1) AS text))";
|
||||
iFirstInsArg = i+1;
|
||||
openFlags4Data = SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE;
|
||||
dbSqlOnly = 1;
|
||||
@@ -1473,6 +1578,9 @@ int main(int argc, char **argv){
|
||||
if( strcmp(z,"result-trace")==0 ){
|
||||
runFlags |= SQL_OUTPUT;
|
||||
}else
|
||||
if( strcmp(z,"spinner")==0 ){
|
||||
bSpinner = 1;
|
||||
}else
|
||||
if( strcmp(z,"sqlid")==0 ){
|
||||
if( i>=argc-1 ) fatalError("missing arguments on %s", argv[i]);
|
||||
onlySqlid = integerValue(argv[++i]);
|
||||
@@ -1623,6 +1731,8 @@ int main(int argc, char **argv){
|
||||
if( zInsSql ){
|
||||
sqlite3_create_function(db, "readfile", 1, SQLITE_UTF8, 0,
|
||||
readfileFunc, 0, 0);
|
||||
sqlite3_create_function(db, "readtextfile", 1, SQLITE_UTF8, 0,
|
||||
readtextfileFunc, 0, 0);
|
||||
sqlite3_create_function(db, "isdbsql", 1, SQLITE_UTF8, 0,
|
||||
isDbSqlFunc, 0, 0);
|
||||
rc = sqlite3_prepare_v2(db, zInsSql, -1, &pStmt, 0);
|
||||
@@ -1741,6 +1851,7 @@ int main(int argc, char **argv){
|
||||
|
||||
/* Limit available memory, if requested */
|
||||
sqlite3_shutdown();
|
||||
|
||||
if( nMemThisDb>0 && nMem==0 ){
|
||||
if( !nativeMalloc ){
|
||||
pHeap = realloc(pHeap, nMemThisDb);
|
||||
@@ -1765,11 +1876,16 @@ int main(int argc, char **argv){
|
||||
|
||||
/* Run a test using each SQL script against each database.
|
||||
*/
|
||||
if( !verboseFlag && !quietFlag ) printf("%s:", zDbName);
|
||||
if( !verboseFlag && !quietFlag && !bSpinner ) printf("%s:", zDbName);
|
||||
for(pSql=g.pFirstSql; pSql; pSql=pSql->pNext){
|
||||
if( isDbSql(pSql->a, pSql->sz) ){
|
||||
sqlite3_snprintf(sizeof(g.zTestName), g.zTestName, "sqlid=%d",pSql->id);
|
||||
if( verboseFlag ){
|
||||
if( bSpinner ){
|
||||
int nTotal =g.nSql;
|
||||
int idx = pSql->seq;
|
||||
printf("\r%s: %d/%d ", zDbName, idx, nTotal);
|
||||
fflush(stdout);
|
||||
}else if( verboseFlag ){
|
||||
printf("%s\n", g.zTestName);
|
||||
fflush(stdout);
|
||||
}else if( !quietFlag ){
|
||||
@@ -1785,6 +1901,7 @@ int main(int argc, char **argv){
|
||||
runCombinedDbSqlInput(pSql->a, pSql->sz);
|
||||
nTest++;
|
||||
g.zTestName[0] = 0;
|
||||
disableOom();
|
||||
continue;
|
||||
}
|
||||
for(pDb=g.pFirstDb; pDb; pDb=pDb->pNext){
|
||||
@@ -1792,7 +1909,12 @@ int main(int argc, char **argv){
|
||||
const char *zVfs = "inmem";
|
||||
sqlite3_snprintf(sizeof(g.zTestName), g.zTestName, "sqlid=%d,dbid=%d",
|
||||
pSql->id, pDb->id);
|
||||
if( verboseFlag ){
|
||||
if( bSpinner ){
|
||||
int nTotal = g.nDb*g.nSql;
|
||||
int idx = pSql->seq*g.nDb + pDb->id - 1;
|
||||
printf("\r%s: %d/%d ", zDbName, idx, nTotal);
|
||||
fflush(stdout);
|
||||
}else if( verboseFlag ){
|
||||
printf("%s\n", g.zTestName);
|
||||
fflush(stdout);
|
||||
}else if( !quietFlag ){
|
||||
@@ -1871,7 +1993,9 @@ int main(int argc, char **argv){
|
||||
}
|
||||
}
|
||||
}
|
||||
if( !quietFlag && !verboseFlag ){
|
||||
if( bSpinner ){
|
||||
printf("\n");
|
||||
}else if( !quietFlag && !verboseFlag ){
|
||||
printf(" 100%% - %d tests\n", g.nDb*g.nSql);
|
||||
}
|
||||
|
||||
|
||||
Binary file not shown.
@@ -146,4 +146,22 @@ ifcapable icu {
|
||||
}
|
||||
}
|
||||
|
||||
# 2020-03-19
|
||||
# The ESCAPE clause on LIKE takes precedence over wildcards
|
||||
#
|
||||
do_execsql_test idu-6.0 {
|
||||
DROP TABLE IF EXISTS t1;
|
||||
CREATE TABLE t1(id INTEGER PRIMARY KEY, x TEXT);
|
||||
INSERT INTO t1 VALUES
|
||||
(1,'abcde'),
|
||||
(2,'abc_'),
|
||||
(3,'abc__'),
|
||||
(4,'abc%'),
|
||||
(5,'abc%%');
|
||||
SELECT id FROM t1 WHERE x LIKE 'abc%%' ESCAPE '%';
|
||||
} {4}
|
||||
do_execsql_test icu-6.1 {
|
||||
SELECT id FROM t1 WHERE x LIKE 'abc__' ESCAPE '_';
|
||||
} {2}
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -77,4 +77,24 @@ do_execsql_test in6-2.1 {
|
||||
ORDER BY +d;
|
||||
} {1 {} 2 {} 3 {} 4 {} 5 {} 8 {} 9 {}}
|
||||
|
||||
# 2020-03-16 ticket 82b588d342d515d1
|
||||
# Ensure that the IN-early-out optimization works with LEFT JOINs
|
||||
#
|
||||
reset_db
|
||||
do_execsql_test in6-3.100 {
|
||||
CREATE TABLE t1(a);
|
||||
INSERT INTO t1 VALUES(0);
|
||||
CREATE TABLE t2(b, c, d);
|
||||
INSERT INTO t2(b,c,d) VALUES(4,5,3),(4,5,4),(4,5,8);
|
||||
CREATE INDEX t2bcd ON t2(b, c, d);
|
||||
SELECT * FROM t1 LEFT JOIN t2 ON b=NULL AND c=5 AND d IN (2,3,4);
|
||||
} {0 {} {} {}}
|
||||
do_execsql_test in6-3.110 {
|
||||
CREATE TABLE v0(v1);
|
||||
CREATE TABLE v3(v5, v4);
|
||||
INSERT INTO v0 VALUES(0);
|
||||
CREATE INDEX v9 ON v3(v4, v4, v5);
|
||||
SELECT quote(v5) FROM v0 LEFT JOIN v3 ON v4 = NULL AND v5 IN(0);
|
||||
} {NULL}
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -1113,4 +1113,22 @@ do_execsql_test 16.2 {
|
||||
SELECT * FROM t1 WHERE a LIKE ' 1-';
|
||||
} {{ 1-}}
|
||||
|
||||
# 2020-03-19
|
||||
# The ESCAPE clause on LIKE takes precedence over wildcards
|
||||
#
|
||||
do_execsql_test 17.0 {
|
||||
DROP TABLE IF EXISTS t1;
|
||||
CREATE TABLE t1(id INTEGER PRIMARY KEY, x TEXT);
|
||||
INSERT INTO t1 VALUES
|
||||
(1,'abcde'),
|
||||
(2,'abc_'),
|
||||
(3,'abc__'),
|
||||
(4,'abc%'),
|
||||
(5,'abc%%');
|
||||
SELECT id FROM t1 WHERE x LIKE 'abc%%' ESCAPE '%';
|
||||
} {4}
|
||||
do_execsql_test 17.1 {
|
||||
SELECT id FROM t1 WHERE x LIKE 'abc__' ESCAPE '_';
|
||||
} {2}
|
||||
|
||||
finish_test
|
||||
|
||||
+3
-3
@@ -237,7 +237,7 @@ do_eqp_test like3-6.110 {
|
||||
`--SEARCH TABLE t1 USING PRIMARY KEY (path>? AND path<?)
|
||||
}
|
||||
do_eqp_test like3-6.120 {
|
||||
SELECT * FROM t1 WHERE path LIKE 'a%' ESCAPE '_';
|
||||
SELECT * FROM t1 WHERE path LIKE 'a%' ESCAPE 'x';
|
||||
} {
|
||||
QUERY PLAN
|
||||
`--SEARCH TABLE t1 USING PRIMARY KEY (path>? AND path<?)
|
||||
@@ -255,7 +255,7 @@ do_eqp_test like3-6.210 {
|
||||
`--SEARCH TABLE t2 USING INDEX t2path (path>? AND path<?)
|
||||
}
|
||||
do_eqp_test like3-6.220 {
|
||||
SELECT * FROM t2 WHERE path LIKE 'a%' ESCAPE '_';
|
||||
SELECT * FROM t2 WHERE path LIKE 'a%' ESCAPE '\';
|
||||
} {
|
||||
QUERY PLAN
|
||||
`--SEARCH TABLE t2 USING INDEX t2path (path>? AND path<?)
|
||||
@@ -268,7 +268,7 @@ do_eqp_test like3-6.230 {
|
||||
`--SEARCH TABLE t2 USING INDEX t2path2 (path>? AND path<?)
|
||||
}
|
||||
do_eqp_test like3-6.240 {
|
||||
SELECT * FROM t2 WHERE path LIKE 'a%' ESCAPE '_';
|
||||
SELECT * FROM t2 WHERE path LIKE 'a%' ESCAPE '\';
|
||||
} {
|
||||
QUERY PLAN
|
||||
`--SEARCH TABLE t2 USING INDEX t2path2 (path>? AND path<?)
|
||||
|
||||
+3
-3
@@ -132,9 +132,9 @@ dbconfig_maindbname_icecube db
|
||||
do_execsql_test misc8-4.2 {
|
||||
SELECT name FROM icecube.sqlite_master;
|
||||
} {t1}
|
||||
do_execsql_test misc8-4.3 {
|
||||
PRAGMA database_list;
|
||||
} {/0 icecube .* 2 aux2/}
|
||||
do_test misc8-4.3 {
|
||||
regexp {0 icecube .* 2 aux2} [db eval {PRAGMA database_list}]
|
||||
} 1
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -297,5 +297,47 @@ do_eqp_test 9.4 {
|
||||
} {SEARCH TABLE v0 USING COVERING INDEX v3 (ANY(c1) AND c2=?)}
|
||||
|
||||
|
||||
# 2020-03-01 ticket e12a0ae526bb51c7
|
||||
# NULLS LAST on a LEFT JOIN
|
||||
#
|
||||
reset_db
|
||||
do_execsql_test 10.10 {
|
||||
CREATE TABLE t1(x);
|
||||
INSERT INTO t1(x) VALUES('X');
|
||||
CREATE TABLE t2(c, d);
|
||||
CREATE INDEX t2dc ON t2(d, c);
|
||||
SELECT c FROM t1 LEFT JOIN t2 ON d=NULL ORDER BY d, c NULLS LAST;
|
||||
} {{}}
|
||||
do_execsql_test 10.20 {
|
||||
INSERT INTO t2(c,d) VALUES(5,'X'),(6,'Y'),(7,'Z'),(3,'A'),(4,'B');
|
||||
SELECT c FROM t1 LEFT JOIN t2 ON d=x ORDER BY d, c NULLS LAST;
|
||||
} {5}
|
||||
do_execsql_test 10.30 {
|
||||
UPDATE t2 SET d='X';
|
||||
UPDATE t2 SET c=NULL WHERE c=6;
|
||||
SELECT c FROM t1 LEFT JOIN t2 ON d=x ORDER BY d NULLS FIRST, c NULLS FIRST;
|
||||
} {{} 3 4 5 7}
|
||||
do_execsql_test 10.40 {
|
||||
SELECT c FROM t1 LEFT JOIN t2 ON d=x ORDER BY d NULLS LAST, c NULLS LAST;
|
||||
} {3 4 5 7 {}}
|
||||
do_execsql_test 10.41 {
|
||||
SELECT c FROM t1 LEFT JOIN t2 ON d=x ORDER BY c NULLS LAST;
|
||||
} {3 4 5 7 {}}
|
||||
do_execsql_test 10.42 {
|
||||
SELECT c FROM t1 LEFT JOIN t2 ON d=x ORDER BY +d NULLS LAST, +c NULLS LAST;
|
||||
} {3 4 5 7 {}}
|
||||
do_execsql_test 10.50 {
|
||||
INSERT INTO t1(x) VALUES(NULL),('Y');
|
||||
SELECT x, c, d, '|' FROM t1 LEFT JOIN t2 ON d=x
|
||||
ORDER BY d NULLS LAST, c NULLS LAST;
|
||||
} {X 3 X | X 4 X | X 5 X | X 7 X | X {} X | {} {} {} | Y {} {} |}
|
||||
do_execsql_test 10.51 {
|
||||
SELECT x, c, d, '|' FROM t1 LEFT JOIN t2 ON d=x
|
||||
ORDER BY +d NULLS LAST, +c NULLS LAST;
|
||||
} {X 3 X | X 4 X | X 5 X | X 7 X | X {} X | {} {} {} | Y {} {} |}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -1075,6 +1075,16 @@ test_suite "sorterref" -prefix "" -description {
|
||||
autoinstall_test_functions
|
||||
}
|
||||
|
||||
test_suite "maindbname" -prefix "" -description {
|
||||
Run the "veryquick" test suite with SQLITE_DBCONFIG_MAINDBNAME used to
|
||||
set the name of database 0 to "icecube".
|
||||
} -files [
|
||||
test_set $allquicktests -exclude *malloc* *ioerr* *fault* *bigfile* *_err* \
|
||||
*fts5corrupt* *fts5big* *fts5aj*
|
||||
] -dbconfig {
|
||||
dbconfig_maindbname_icecube $::dbhandle
|
||||
}
|
||||
|
||||
# End of tests
|
||||
#############################################################################
|
||||
|
||||
|
||||
@@ -306,4 +306,12 @@ foreach {id x} {
|
||||
} {{} 1.0 ok}
|
||||
}
|
||||
|
||||
# 2020-03-10 ticket e0c2ad1aa8a9c691
|
||||
reset_db
|
||||
do_execsql_test select3-9.100 {
|
||||
CREATE TABLE t0(c0 REAL, c1 REAL GENERATED ALWAYS AS (c0));
|
||||
INSERT INTO t0(c0) VALUES (1);
|
||||
SELECT * FROM t0 GROUP BY c0;
|
||||
} {1.0 1.0}
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -1005,6 +1005,25 @@ do_catchsql_test select4-17.3 {
|
||||
ORDER BY +x;
|
||||
} {1 {LIMIT clause should come after UNION not before}}
|
||||
|
||||
# 2020-04-03 ticket 51166be0159fd2ce from Yong Heng.
|
||||
# Adverse interaction between the constant propagation and push-down
|
||||
# optimizations.
|
||||
#
|
||||
reset_db
|
||||
do_execsql_test select4-18.1 {
|
||||
CREATE VIEW v0(v0) AS WITH v0 AS(SELECT 0 v0) SELECT(SELECT min(v0) OVER()) FROM v0 GROUP BY v0;
|
||||
SELECT *FROM v0 v1 JOIN v0 USING(v0) WHERE datetime(v0) = (v0.v0)AND v0 = 10;
|
||||
} {}
|
||||
do_execsql_test select4-18.2 {
|
||||
CREATE VIEW t1(aa) AS
|
||||
WITH t2(bb) AS (SELECT 123)
|
||||
SELECT (SELECT min(bb) OVER()) FROM t2 GROUP BY bb;
|
||||
SELECT * FROM t1;
|
||||
} {123}
|
||||
do_execsql_test select4-18.3 {
|
||||
SELECT * FROM t1 AS z1 JOIN t1 AS z2 USING(aa)
|
||||
WHERE abs(z1.aa)=z2.aa AND z1.aa=123;
|
||||
} {123}
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
+24
-12
@@ -297,10 +297,11 @@ do_test shell1-3.4.2 {
|
||||
list [regexp {BEGIN TRANSACTION;} $res] \
|
||||
[regexp {COMMIT;} $res]
|
||||
} {1 1}
|
||||
do_test shell1-3.4.3 {
|
||||
# too many arguments
|
||||
catchcmd "test.db" ".dump FOO BAD"
|
||||
} {1 {Usage: .dump ?--preserve-rowids? ?--newlines? ?LIKE-PATTERN?}}
|
||||
# The .dump command now accepts multiple arguments
|
||||
#do_test shell1-3.4.3 {
|
||||
# # too many arguments
|
||||
# catchcmd "test.db" ".dump FOO BAD"
|
||||
#} {1 {Usage: .dump ?--preserve-rowids? ?--newlines? ?LIKE-PATTERN?}}
|
||||
|
||||
# .echo ON|OFF Turn command echo on or off
|
||||
do_test shell1-3.5.1 {
|
||||
@@ -388,17 +389,14 @@ do_test shell1-3.10.2 {
|
||||
# .import FILE TABLE Import data from FILE into TABLE
|
||||
do_test shell1-3.11.1 {
|
||||
catchcmd "test.db" ".import"
|
||||
} {1 {Usage: .import FILE TABLE}}
|
||||
} {/1 .ERROR: missing FILE argument.*/}
|
||||
do_test shell1-3.11.2 {
|
||||
catchcmd "test.db" ".import FOO"
|
||||
} {1 {Usage: .import FILE TABLE}}
|
||||
#do_test shell1-3.11.2 {
|
||||
# catchcmd "test.db" ".import FOO BAR"
|
||||
#} {1 {Error: no such table: BAR}}
|
||||
} {/1 .ERROR: missing TABLE argument.*/}
|
||||
do_test shell1-3.11.3 {
|
||||
# too many arguments
|
||||
catchcmd "test.db" ".import FOO BAR BAD"
|
||||
} {1 {Usage: .import FILE TABLE}}
|
||||
} {/1 .ERROR: extra argument: "BAD".*./}
|
||||
|
||||
# .indexes ?TABLE? Show names of all indexes
|
||||
# If TABLE specified, only show indexes for tables
|
||||
@@ -495,7 +493,14 @@ do_test shell1-3.15.2 {
|
||||
do_test shell1-3.15.3 {
|
||||
# too many arguments
|
||||
catchcmd "test.db" ".output FOO BAD"
|
||||
} {1 {Usage: .output [-e|-x|FILE]}}
|
||||
} {1 {ERROR: extra parameter: "BAD". Usage:
|
||||
.output ?FILE? Send output to FILE or stdout if FILE is omitted
|
||||
If FILE begins with '|' then open it as a pipe.
|
||||
Options:
|
||||
--bom Prefix output with a UTF8 byte-order mark
|
||||
-e Send output to the system text editor
|
||||
-x Send output as CSV to a spreadsheet
|
||||
child process exited abnormally}}
|
||||
|
||||
# .output stdout Send output to the screen
|
||||
do_test shell1-3.16.1 {
|
||||
@@ -504,7 +509,14 @@ do_test shell1-3.16.1 {
|
||||
do_test shell1-3.16.2 {
|
||||
# too many arguments
|
||||
catchcmd "test.db" ".output stdout BAD"
|
||||
} {1 {Usage: .output [-e|-x|FILE]}}
|
||||
} {1 {ERROR: extra parameter: "BAD". Usage:
|
||||
.output ?FILE? Send output to FILE or stdout if FILE is omitted
|
||||
If FILE begins with '|' then open it as a pipe.
|
||||
Options:
|
||||
--bom Prefix output with a UTF8 byte-order mark
|
||||
-e Send output to the system text editor
|
||||
-x Send output as CSV to a spreadsheet
|
||||
child process exited abnormally}}
|
||||
|
||||
# .prompt MAIN CONTINUE Replace the standard prompts
|
||||
do_test shell1-3.17.1 {
|
||||
|
||||
+3
-6
@@ -32,17 +32,14 @@ forcedelete test.db test.db-journal test.db-wal
|
||||
# .import FILE TABLE Import data from FILE into TABLE
|
||||
do_test shell5-1.1.1 {
|
||||
catchcmd "test.db" ".import"
|
||||
} {1 {Usage: .import FILE TABLE}}
|
||||
} {/1 .ERROR: missing FILE argument.*/}
|
||||
do_test shell5-1.1.2 {
|
||||
catchcmd "test.db" ".import FOO"
|
||||
} {1 {Usage: .import FILE TABLE}}
|
||||
#do_test shell5-1.1.2 {
|
||||
# catchcmd "test.db" ".import FOO BAR"
|
||||
#} {1 {Error: no such table: BAR}}
|
||||
} {/1 .ERROR: missing TABLE argument.*/}
|
||||
do_test shell5-1.1.3 {
|
||||
# too many arguments
|
||||
catchcmd "test.db" ".import FOO BAR BAD"
|
||||
} {1 {Usage: .import FILE TABLE}}
|
||||
} {/1 .ERROR: extra argument.*/}
|
||||
|
||||
# .separator STRING Change separator used by output mode and .import
|
||||
do_test shell5-1.2.1 {
|
||||
|
||||
@@ -782,6 +782,9 @@ proc do_test {name cmd expected} {
|
||||
output2 "\nError: $result"
|
||||
fail_test $name
|
||||
} else {
|
||||
if {[permutation]=="maindbname"} {
|
||||
set result [string map [list [string tolower ICECUBE] main] $result]
|
||||
}
|
||||
if {[regexp {^[~#]?/.*/$} $expected]} {
|
||||
# "expected" is of the form "/PATTERN/" then the result if correct if
|
||||
# regular expression PATTERN matches the result. "~/PATTERN/" means
|
||||
|
||||
@@ -1593,5 +1593,74 @@ do_execsql_test 48.1 {
|
||||
FROM (SELECT (SELECT sum(a) FROM t1 GROUP BY a) AS x FROM t1);
|
||||
} {2 2 2}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
reset_db
|
||||
do_execsql_test 49.1 {
|
||||
CREATE TABLE t1 (a PRIMARY KEY);
|
||||
INSERT INTO t1 VALUES(1);
|
||||
}
|
||||
|
||||
do_execsql_test 49.2 {
|
||||
SELECT b AS c FROM (
|
||||
SELECT a AS b FROM (
|
||||
SELECT a FROM t1 WHERE a=1 OR (SELECT sum(a) OVER ())
|
||||
)
|
||||
WHERE b=1 OR b<10
|
||||
)
|
||||
WHERE c=1 OR c>=10;
|
||||
} {1}
|
||||
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
reset_db
|
||||
do_execsql_test 50.0 {
|
||||
CREATE TABLE t1 (a DOUBLE PRIMARY KEY);
|
||||
INSERT INTO t1 VALUES(10.0);
|
||||
}
|
||||
|
||||
do_execsql_test 50.1 {
|
||||
SELECT * FROM t1 WHERE a%1 OR (SELECT sum(a) OVER (ORDER BY a%2))
|
||||
} {10.0}
|
||||
|
||||
do_execsql_test 50.2 {
|
||||
SELECT * FROM (
|
||||
SELECT * FROM t1 WHERE a%1 OR (SELECT sum(a) OVER (ORDER BY a%2))
|
||||
)
|
||||
WHERE a=1 OR ( (SELECT sum(a) OVER (ORDER BY a%4)) AND a<=10 )
|
||||
} {10.0}
|
||||
|
||||
do_execsql_test 50.3 {
|
||||
SELECT a FROM (
|
||||
SELECT * FROM (
|
||||
SELECT * FROM t1 WHERE a%1 OR (SELECT sum(a) OVER (ORDER BY a%2))
|
||||
)
|
||||
WHERE a=1 OR ( (SELECT sum(a) OVER (ORDER BY a%4)) AND a<=10 )
|
||||
)
|
||||
WHERE a=1 OR a=10.0
|
||||
} {10.0}
|
||||
|
||||
do_execsql_test 50.4 {
|
||||
SELECT a FROM (
|
||||
SELECT * FROM (
|
||||
SELECT * FROM t1 WHERE a%1 OR (SELECT sum(a) OVER (ORDER BY a%2))
|
||||
)
|
||||
WHERE a=1 OR ( (SELECT sum(a) OVER (ORDER BY a%4)) AND a<=10 )
|
||||
)
|
||||
WHERE a=1 OR ((SELECT sum(a) OVER(ORDER BY a%8)) AND 10<=a)
|
||||
} {10.0}
|
||||
|
||||
do_execsql_test 50.5 {
|
||||
SELECT * FROM (SELECT * FROM t1 NATURAL JOIN t1 WHERE a%1 OR ((SELECT sum(a)OVER(ORDER BY a)) AND a<=10)) NATURAL JOIN t1 WHERE a=1 OR ((SELECT sum((SELECT * FROM (SELECT * FROM (SELECT * FROM t1 NATURAL JOIN t1 WHERE a%1 OR ((SELECT sum(a)OVER(ORDER BY a)) AND a<=10)) NATURAL JOIN t1 WHERE a=1 OR ((SELECT sum((SELECT * FROM t1 NATURAL JOIN t1 WHERE a=1 OR ((SELECT sum(a)OVER(ORDER BY a)) AND a<=10)))OVER(ORDER BY a% 1 )) AND a<=10)) NATURAL JOIN t1 WHERE a=1 OR ((SELECT sum(a)OVER(ORDER BY a)) AND 10<=a)))OVER(ORDER BY a%5)) AND a<=10);
|
||||
} {10.0}
|
||||
|
||||
# 2020-04-03 ticket af4556bb5c285c08
|
||||
#
|
||||
reset_db
|
||||
do_catchsql_test 51.1 {
|
||||
CREATE TABLE a(b, c);
|
||||
SELECT c FROM a GROUP BY c
|
||||
HAVING(SELECT(sum(b) OVER(ORDER BY b),
|
||||
sum(b) OVER(PARTITION BY min(DISTINCT c), c ORDER BY b)));
|
||||
} {1 {row value misused}}
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -385,6 +385,20 @@ execsql_test 11.4 {
|
||||
) sub;
|
||||
}
|
||||
|
||||
execsql_test 11.5 {
|
||||
SELECT sum( min(t) ) OVER () FROM t8 GROUP BY total;
|
||||
}
|
||||
execsql_test 11.5 {
|
||||
SELECT sum( max(t) ) OVER () FROM t8 GROUP BY total;
|
||||
}
|
||||
|
||||
execsql_test 11.7 {
|
||||
SELECT sum( min(t) ) OVER () FROM t8;
|
||||
}
|
||||
execsql_test 11.8 {
|
||||
SELECT sum( max(t) ) OVER () FROM t8;
|
||||
}
|
||||
|
||||
execsql_test 12.0 {
|
||||
DROP TABLE IF EXISTS t2;
|
||||
CREATE TABLE t2(a INTEGER);
|
||||
|
||||
@@ -1324,6 +1324,22 @@ do_execsql_test 11.4 {
|
||||
) sub;
|
||||
} {0 1 2}
|
||||
|
||||
do_execsql_test 11.5 {
|
||||
SELECT sum( min(t) ) OVER () FROM t8 GROUP BY total;
|
||||
} {5 5}
|
||||
|
||||
do_execsql_test 11.5 {
|
||||
SELECT sum( max(t) ) OVER () FROM t8 GROUP BY total;
|
||||
} {10 10}
|
||||
|
||||
do_execsql_test 11.7 {
|
||||
SELECT sum( min(t) ) OVER () FROM t8;
|
||||
} {0}
|
||||
|
||||
do_execsql_test 11.8 {
|
||||
SELECT sum( max(t) ) OVER () FROM t8;
|
||||
} {10}
|
||||
|
||||
do_execsql_test 12.0 {
|
||||
DROP TABLE IF EXISTS t2;
|
||||
CREATE TABLE t2(a INTEGER);
|
||||
|
||||
@@ -232,4 +232,37 @@ do_execsql_test 7.4 {
|
||||
7.2 8.75 10.0 11.0 15.0
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
reset_db
|
||||
do_execsql_test 8.1.1 {
|
||||
CREATE TABLE t1(a, b);
|
||||
INSERT INTO t1 VALUES(1, 2), (3, 4);
|
||||
SELECT min( sum(a) ) OVER () FROM t1;
|
||||
} {4}
|
||||
|
||||
do_execsql_test 8.1.2 {
|
||||
SELECT min( sum(a) ) OVER () FROM t1 GROUP BY a;
|
||||
} {1 1}
|
||||
|
||||
do_execsql_test 8.2 {
|
||||
CREATE VIEW v1 AS
|
||||
SELECT 0 AS x
|
||||
UNION
|
||||
SELECT count() OVER() FROM (SELECT 0)
|
||||
ORDER BY 1
|
||||
;
|
||||
}
|
||||
|
||||
do_catchsql_test 8.3 {
|
||||
SELECT min( max((SELECT x FROM v1)) ) OVER()
|
||||
} {1 {misuse of aggregate: max()}}
|
||||
|
||||
do_execsql_test 8.4 {
|
||||
SELECT(
|
||||
SELECT x UNION
|
||||
SELECT sum( avg((SELECT x FROM v1)) ) OVER()
|
||||
)
|
||||
FROM v1;
|
||||
} {0.0}
|
||||
|
||||
finish_test
|
||||
|
||||
Reference in New Issue
Block a user