Merge sqlite-release(3.29.0) into prerelease-integration

This commit is contained in:
Stephen Lombardo
2019-09-25 12:13:27 -04:00
140 changed files with 11240 additions and 2953 deletions
+5 -22
View File
@@ -437,30 +437,13 @@ describes its purpose and role within the larger system.
<a name="vauth"></a>
## Verifying Code Authenticity
If you obtained an SQLite source tree from a secondary source, such as a
GitHub mirror, and you want to verify that it has not been altered, there
are a couple of ways to do that.
If you have a release version of SQLite, and you are using the
`sqlite3.c` amalgamation, then SHA3-256 hashes for the amalgamation are
available in the [change log](https://www.sqlite.org/changes.html) on
the official website. After building the `sqlite3.c` file, you can check
that it is authentic by comparing the hash. This does not ensure that the
test scripts are unaltered, but it does validate the deliverable part of
the code and the verification process only involves computing and
comparing a single hash.
For versions other than an official release, or if you are building the
`sqlite3.c` amalgamation using non-standard build options, the verification
process is a little more involved. The `manifest` file at the root directory
of the source tree
The `manifest` file at the root directory of the source tree
contains either a SHA3-256 hash (for newer files) or a SHA1 hash (for
older files) for every source file in the repository. You can write a script
to extracts hashes from `manifest` and verifies the hashes against the
corresponding files in the source tree. The SHA3-256 hash of the `manifest`
older files) for every source file in the repository.
The SHA3-256 hash of the `manifest`
file itself is the official name of the version of the source tree that you
have. The `manifest.uuid` file should contain the SHA3-256 hash of the
`manifest` file. If all of the above hash comparisons are correct, then
have. The `manifest.uuid` file should contain the SHA3-256 hash of the
`manifest` file. If all of the above hash comparisons are correct, then
you can be confident that your source tree is authentic and unadulterated.
The format of the `manifest` file should be mostly self-explanatory, but
+1 -1
View File
@@ -1 +1 @@
3.28.0
3.29.0
+732 -608
View File
File diff suppressed because it is too large Load Diff
Vendored
+1417 -1263
View File
File diff suppressed because it is too large Load Diff
Vendored
+9 -9
View File
@@ -1,6 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.69 for sqlcipher 3.28.0.
# Generated by GNU Autoconf 2.69 for sqlcipher 3.29.0.
#
#
# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
@@ -587,8 +587,8 @@ MAKEFLAGS=
# Identity of this package.
PACKAGE_NAME='sqlcipher'
PACKAGE_TARNAME='sqlcipher'
PACKAGE_VERSION='3.28.0'
PACKAGE_STRING='sqlcipher 3.28.0'
PACKAGE_VERSION='3.29.0'
PACKAGE_STRING='sqlcipher 3.29.0'
PACKAGE_BUGREPORT=''
PACKAGE_URL=''
@@ -1337,7 +1337,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
\`configure' configures sqlcipher 3.28.0 to adapt to many kinds of systems.
\`configure' configures sqlcipher 3.29.0 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1402,7 +1402,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
short | recursive ) echo "Configuration of sqlcipher 3.28.0:";;
short | recursive ) echo "Configuration of sqlcipher 3.29.0:";;
esac
cat <<\_ACEOF
@@ -1538,7 +1538,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
sqlcipher configure 3.28.0
sqlcipher configure 3.29.0
generated by GNU Autoconf 2.69
Copyright (C) 2012 Free Software Foundation, Inc.
@@ -1957,7 +1957,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
It was created by sqlcipher $as_me 3.28.0, which was
It was created by sqlcipher $as_me 3.29.0, which was
generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@
@@ -13808,7 +13808,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
This file was extended by sqlcipher $as_me 3.28.0, which was
This file was extended by sqlcipher $as_me 3.29.0, which was
generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -13874,7 +13874,7 @@ _ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\
sqlcipher config.status 3.28.0
sqlcipher config.status 3.29.0
configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\"
+35 -24
View File
@@ -2619,14 +2619,14 @@ static void fts3ColumnFilter(
nList -= (int)(p - pList);
pList = p;
if( nList==0 ){
if( nList<=0 ){
break;
}
p = &pList[1];
p += fts3GetVarint32(p, &iCurrent);
}
if( bZero && &pList[nList]!=pEnd ){
if( bZero && (pEnd - &pList[nList])>0){
memset(&pList[nList], 0, pEnd - &pList[nList]);
}
*ppList = pList;
@@ -3754,7 +3754,7 @@ static int nodeReaderNext(NodeReader *p){
}
p->iOff += fts3GetVarint32(&p->aNode[p->iOff], &nSuffix);
if( nPrefix>p->iOff || nSuffix>p->nNode-p->iOff ){
if( nPrefix>p->term.n || nSuffix>p->nNode-p->iOff || nSuffix==0 ){
return FTS_CORRUPT_VTAB;
}
blobGrowBuffer(&p->term, nPrefix+nSuffix, &rc);
@@ -3773,7 +3773,7 @@ static int nodeReaderNext(NodeReader *p){
}
}
assert( p->iOff<=p->nNode );
assert_fts3_nc( p->iOff<=p->nNode );
return rc;
}
@@ -3934,7 +3934,7 @@ static int fts3AppendToNode(
/* Node must have already been started. There must be a doclist for a
** leaf node, and there must not be a doclist for an internal node. */
assert( pNode->n>0 );
assert( (pNode->a[0]=='\0')==(aDoclist!=0) );
assert_fts3_nc( (pNode->a[0]=='\0')==(aDoclist!=0) );
blobGrowBuffer(pPrev, nTerm, &rc);
if( rc!=SQLITE_OK ) return rc;
@@ -4150,7 +4150,7 @@ static int fts3TermCmp(
int nCmp = MIN(nLhs, nRhs);
int res;
res = memcmp(zLhs, zRhs, nCmp);
res = (nCmp ? memcmp(zLhs, zRhs, nCmp) : 0);
if( res==0 ) res = nLhs - nRhs;
return res;
@@ -4282,10 +4282,13 @@ static int fts3IncrmergeLoad(
pNode = &pWriter->aNodeWriter[nHeight];
pNode->iBlock = pWriter->iStart + pWriter->nLeafEst*nHeight;
blobGrowBuffer(&pNode->block, MAX(nRoot, p->nNodeSize), &rc);
blobGrowBuffer(&pNode->block,
MAX(nRoot, p->nNodeSize)+FTS3_NODE_PADDING, &rc
);
if( rc==SQLITE_OK ){
memcpy(pNode->block.a, aRoot, nRoot);
pNode->block.n = nRoot;
memset(&pNode->block.a[nRoot], 0, FTS3_NODE_PADDING);
}
for(i=nHeight; i>=0 && rc==SQLITE_OK; i--){
@@ -4293,23 +4296,28 @@ static int fts3IncrmergeLoad(
pNode = &pWriter->aNodeWriter[i];
rc = nodeReaderInit(&reader, pNode->block.a, pNode->block.n);
while( reader.aNode && rc==SQLITE_OK ) rc = nodeReaderNext(&reader);
blobGrowBuffer(&pNode->key, reader.term.n, &rc);
if( rc==SQLITE_OK ){
memcpy(pNode->key.a, reader.term.a, reader.term.n);
pNode->key.n = reader.term.n;
if( i>0 ){
char *aBlock = 0;
int nBlock = 0;
pNode = &pWriter->aNodeWriter[i-1];
pNode->iBlock = reader.iChild;
rc = sqlite3Fts3ReadBlock(p, reader.iChild, &aBlock, &nBlock, 0);
blobGrowBuffer(&pNode->block, MAX(nBlock, p->nNodeSize), &rc);
if( rc==SQLITE_OK ){
memcpy(pNode->block.a, aBlock, nBlock);
pNode->block.n = nBlock;
if( reader.aNode ){
while( reader.aNode && rc==SQLITE_OK ) rc = nodeReaderNext(&reader);
blobGrowBuffer(&pNode->key, reader.term.n, &rc);
if( rc==SQLITE_OK ){
memcpy(pNode->key.a, reader.term.a, reader.term.n);
pNode->key.n = reader.term.n;
if( i>0 ){
char *aBlock = 0;
int nBlock = 0;
pNode = &pWriter->aNodeWriter[i-1];
pNode->iBlock = reader.iChild;
rc = sqlite3Fts3ReadBlock(p, reader.iChild, &aBlock, &nBlock, 0);
blobGrowBuffer(&pNode->block,
MAX(nBlock, p->nNodeSize)+FTS3_NODE_PADDING, &rc
);
if( rc==SQLITE_OK ){
memcpy(pNode->block.a, aBlock, nBlock);
pNode->block.n = nBlock;
memset(&pNode->block.a[nBlock], 0, FTS3_NODE_PADDING);
}
sqlite3_free(aBlock);
}
sqlite3_free(aBlock);
}
}
nodeReaderRelease(&reader);
@@ -4552,7 +4560,10 @@ static int fts3TruncateNode(
NodeReader reader; /* Reader object */
Blob prev = {0, 0, 0}; /* Previous term written to new node */
int rc = SQLITE_OK; /* Return code */
int bLeaf = aNode[0]=='\0'; /* True for a leaf node */
int bLeaf; /* True for a leaf node */
if( nNode<1 ) return FTS_CORRUPT_VTAB;
bLeaf = aNode[0]=='\0';
/* Allocate required output space */
blobGrowBuffer(pNew, nNode, &rc);
+10 -1
View File
@@ -178,10 +178,19 @@ int sqlite3Fts5PoslistNext64(
i64 iOff = *piOff;
int iVal;
fts5FastGetVarint32(a, i, iVal);
if( iVal==1 ){
if( iVal<=1 ){
if( iVal==0 ){
*pi = i;
return 0;
}
fts5FastGetVarint32(a, i, iVal);
iOff = ((i64)iVal) << 32;
fts5FastGetVarint32(a, i, iVal);
if( iVal<2 ){
/* This is a corrupt record. So stop parsing it here. */
*piOff = -1;
return 1;
}
}
*piOff = iOff + ((iVal-2) & 0x7FFFFFFF);
*pi = i;
+16 -8
View File
@@ -992,7 +992,7 @@ static Fts5Structure *fts5StructureReadUncached(Fts5Index *p){
/* TODO: Do we need this if the leaf-index is appended? Probably... */
memset(&pData->p[pData->nn], 0, FTS5_DATA_PADDING);
p->rc = fts5StructureDecode(pData->p, pData->nn, &iCookie, &pRet);
if( p->rc==SQLITE_OK && pConfig->iCookie!=iCookie ){
if( p->rc==SQLITE_OK && (pConfig->pgsz==0 || pConfig->iCookie!=iCookie) ){
p->rc = sqlite3Fts5ConfigLoad(pConfig, iCookie);
}
fts5DataRelease(pData);
@@ -4953,8 +4953,14 @@ static void fts5MergePrefixLists(
** first rowid in one input is a large negative number, and the first in
** the other a non-negative number, the delta for the non-negative
** number will be larger on disk than the literal integer value
** was. */
if( sqlite3Fts5BufferSize(&p->rc, &out, p1->n + p2->n + 9) ) return;
** was.
**
** Or, if the input position-lists are corrupt, then the output might
** include up to 2 extra 10-byte positions created by interpreting -1
** (the value PoslistNext64() uses for EOF) as a position and appending
** it to the output. This can happen at most once for each input
** position-list, hence two 10 byte paddings. */
if( sqlite3Fts5BufferSize(&p->rc, &out, p1->n + p2->n + 9+10+10) ) return;
fts5DoclistIterInit(p1, &i1);
fts5DoclistIterInit(p2, &i2);
@@ -4965,6 +4971,7 @@ static void fts5MergePrefixLists(
fts5BufferSafeAppendBlob(&out, i1.aPoslist, i1.nPoslist+i1.nSize);
fts5DoclistIterNext(&i1);
if( i1.aPoslist==0 ) break;
assert( out.n<=((i1.aPoslist-p1->p) + (i2.aPoslist-p2->p)+9+10+10) );
}
else if( i2.iRowid!=i1.iRowid ){
/* Copy entry from i2 */
@@ -4972,6 +4979,7 @@ static void fts5MergePrefixLists(
fts5BufferSafeAppendBlob(&out, i2.aPoslist, i2.nPoslist+i2.nSize);
fts5DoclistIterNext(&i2);
if( i2.aPoslist==0 ) break;
assert( out.n<=((i1.aPoslist-p1->p) + (i2.aPoslist-p2->p)+9+10+10) );
}
else{
/* Merge the two position lists. */
@@ -4995,7 +5003,7 @@ static void fts5MergePrefixLists(
sqlite3Fts5PoslistNext64(a1, i1.nPoslist, &iOff1, &iPos1);
sqlite3Fts5PoslistNext64(a2, i2.nPoslist, &iOff2, &iPos2);
assert( iPos1>=0 && iPos2>=0 );
assert_nc( iPos1>=0 && iPos2>=0 );
if( iPos1<iPos2 ){
sqlite3Fts5PoslistSafeAppend(&tmp, &iPrev, iPos1);
@@ -5004,7 +5012,6 @@ static void fts5MergePrefixLists(
sqlite3Fts5PoslistSafeAppend(&tmp, &iPrev, iPos2);
sqlite3Fts5PoslistNext64(a2, i2.nPoslist, &iOff2, &iPos2);
}
if( iPos1>=0 && iPos2>=0 ){
while( 1 ){
if( iPos1<iPos2 ){
@@ -5029,7 +5036,7 @@ static void fts5MergePrefixLists(
aCopy = &a1[iOff1];
nCopy = i1.nPoslist - iOff1;
}else{
assert( iPos2>=0 && iPos2!=iPrev );
assert_nc( iPos2>=0 && iPos2!=iPrev );
sqlite3Fts5PoslistSafeAppend(&tmp, &iPrev, iPos2);
aCopy = &a2[iOff2];
nCopy = i2.nPoslist - iOff2;
@@ -5043,8 +5050,9 @@ static void fts5MergePrefixLists(
fts5BufferSafeAppendBlob(&out, tmp.p, tmp.n);
fts5DoclistIterNext(&i1);
fts5DoclistIterNext(&i2);
assert( out.n<=(p1->n+p2->n+9) );
assert_nc( out.n<=(p1->n+p2->n+9) );
if( i1.aPoslist==0 || i2.aPoslist==0 ) break;
assert( out.n<=((i1.aPoslist-p1->p) + (i2.aPoslist-p2->p)+9+10+10) );
}
}
@@ -5056,7 +5064,7 @@ static void fts5MergePrefixLists(
fts5MergeAppendDocid(&out, iLastRowid, i2.iRowid);
fts5BufferSafeAppendBlob(&out, i2.aPoslist, i2.aEof - i2.aPoslist);
}
assert( out.n<=(p1->n+p2->n+9) );
assert_nc( out.n<=(p1->n+p2->n+9) );
fts5BufferSet(&p->rc, p1, out.n, out.p);
fts5BufferFree(&tmp);
+4 -2
View File
@@ -573,8 +573,10 @@ static int fts5VocabNextMethod(sqlite3_vtab_cursor *pCursor){
}
if( rc==SQLITE_OK && pCsr->bEof==0 && pTab->eType==FTS5_VOCAB_COL ){
while( pCsr->aDoc[pCsr->iCol]==0 ) pCsr->iCol++;
assert( pCsr->iCol<pCsr->pFts5->pConfig->nCol );
for(/* noop */; pCsr->iCol<nCol && pCsr->aDoc[pCsr->iCol]==0; pCsr->iCol++);
if( pCsr->iCol==nCol ){
rc = FTS5_CORRUPT;
}
}
return rc;
}
File diff suppressed because it is too large Load Diff
+61
View File
@@ -0,0 +1,61 @@
# 2019 May 16
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# May you do good and not evil.
# May you find forgiveness for yourself and forgive others.
# May you share freely, never taking more than you give.
#
#***********************************************************************
#
#
source [file join [file dirname [info script]] fts5_common.tcl]
set testprefix fts5corrupt4
# If SQLITE_ENABLE_FTS5 is defined, omit this file.
ifcapable !fts5 {
finish_test
return
}
sqlite3_fts5_may_be_corrupt 1
do_execsql_test 1.0 {
CREATE VIRTUAL TABLE ttt USING fts5(a, b);
INSERT INTO ttt
VALUES('e ee eee e ee eee e ee eee', 'eee ee e e e ee eee ee ee');
INSERT INTO ttt SELECT a||a, b||b FROM ttt;
INSERT INTO ttt SELECT a||a, b||b FROM ttt;
}
proc mutate {blob i} {
set o [expr {$i % [string length $blob]}]
set a [string range $blob 0 $o-1]
set b [string range $blob $o+1 end]
set v [expr int(rand()*255) - 127]
return "$a[binary format c $v]$b"
}
db func mutate mutate
for {set j 1000} {$j <= 5000} {incr j 1000} {
do_test 1.$j {
for {set i 0} {$i < 1000} {incr i} {
execsql {
BEGIN;
UPDATE ttt_data SET block = mutate(block, $i) WHERE id>10;
}
foreach sql {
{SELECT snippet(ttt, -1, '.', '..', '[', ']'), * FROM ttt('e*')}
{SELECT snippet(ttt, -1, '.', '..', '[', ']'), * FROM ttt('e* NOT ee*')}
} {
catch { execsql $sql }
}
execsql ROLLBACK
}
} {}
}
sqlite3_fts5_may_be_corrupt 0
finish_test
+1 -1
View File
@@ -76,7 +76,7 @@ static void readblobFunc(
sqlite3_blob_close(pBlob);
if( rc ){
sqlite3_free(aData);
sqlite3_result_error(context, "BLOB write failed", -1);
sqlite3_result_error(context, "BLOB read failed", -1);
}else{
sqlite3_result_blob(context, aData, nData, sqlite3_free);
}
+851
View File
@@ -0,0 +1,851 @@
/*
** 2019-04-17
**
** The author disclaims copyright to this source code. In place of
** a legal notice, here is a blessing:
**
** May you do good and not evil.
** May you find forgiveness for yourself and forgive others.
** May you share freely, never taking more than you give.
**
******************************************************************************
**
** This file contains an implementation of two eponymous virtual tables,
** "sqlite_dbdata" and "sqlite_dbptr". Both modules require that the
** "sqlite_dbpage" eponymous virtual table be available.
**
** SQLITE_DBDATA:
** sqlite_dbdata is used to extract data directly from a database b-tree
** page and its associated overflow pages, bypassing the b-tree layer.
** The table schema is equivalent to:
**
** CREATE TABLE sqlite_dbdata(
** pgno INTEGER,
** cell INTEGER,
** field INTEGER,
** value ANY,
** schema TEXT HIDDEN
** );
**
** IMPORTANT: THE VIRTUAL TABLE SCHEMA ABOVE IS SUBJECT TO CHANGE. IN THE
** FUTURE NEW NON-HIDDEN COLUMNS MAY BE ADDED BETWEEN "value" AND
** "schema".
**
** Each page of the database is inspected. If it cannot be interpreted as
** a b-tree page, or if it is a b-tree page containing 0 entries, the
** sqlite_dbdata table contains no rows for that page. Otherwise, the
** table contains one row for each field in the record associated with
** each cell on the page. For intkey b-trees, the key value is stored in
** field -1.
**
** For example, for the database:
**
** CREATE TABLE t1(a, b); -- root page is page 2
** INSERT INTO t1(rowid, a, b) VALUES(5, 'v', 'five');
** INSERT INTO t1(rowid, a, b) VALUES(10, 'x', 'ten');
**
** the sqlite_dbdata table contains, as well as from entries related to
** page 1, content equivalent to:
**
** INSERT INTO sqlite_dbdata(pgno, cell, field, value) VALUES
** (2, 0, -1, 5 ),
** (2, 0, 0, 'v' ),
** (2, 0, 1, 'five'),
** (2, 1, -1, 10 ),
** (2, 1, 0, 'x' ),
** (2, 1, 1, 'ten' );
**
** If database corruption is encountered, this module does not report an
** error. Instead, it attempts to extract as much data as possible and
** ignores the corruption.
**
** SQLITE_DBPTR:
** The sqlite_dbptr table has the following schema:
**
** CREATE TABLE sqlite_dbptr(
** pgno INTEGER,
** child INTEGER,
** schema TEXT HIDDEN
** );
**
** It contains one entry for each b-tree pointer between a parent and
** child page in the database.
*/
#if !defined(SQLITEINT_H)
#include "sqlite3ext.h"
typedef unsigned char u8;
#endif
SQLITE_EXTENSION_INIT1
#include <string.h>
#include <assert.h>
#define DBDATA_PADDING_BYTES 100
typedef struct DbdataTable DbdataTable;
typedef struct DbdataCursor DbdataCursor;
/* Cursor object */
struct DbdataCursor {
sqlite3_vtab_cursor base; /* Base class. Must be first */
sqlite3_stmt *pStmt; /* For fetching database pages */
int iPgno; /* Current page number */
u8 *aPage; /* Buffer containing page */
int nPage; /* Size of aPage[] in bytes */
int nCell; /* Number of cells on aPage[] */
int iCell; /* Current cell number */
int bOnePage; /* True to stop after one page */
int szDb;
sqlite3_int64 iRowid;
/* Only for the sqlite_dbdata table */
u8 *pRec; /* Buffer containing current record */
int nRec; /* Size of pRec[] in bytes */
int nHdr; /* Size of header in bytes */
int iField; /* Current field number */
u8 *pHdrPtr;
u8 *pPtr;
sqlite3_int64 iIntkey; /* Integer key value */
};
/* Table object */
struct DbdataTable {
sqlite3_vtab base; /* Base class. Must be first */
sqlite3 *db; /* The database connection */
sqlite3_stmt *pStmt; /* For fetching database pages */
int bPtr; /* True for sqlite3_dbptr table */
};
/* Column and schema definitions for sqlite_dbdata */
#define DBDATA_COLUMN_PGNO 0
#define DBDATA_COLUMN_CELL 1
#define DBDATA_COLUMN_FIELD 2
#define DBDATA_COLUMN_VALUE 3
#define DBDATA_COLUMN_SCHEMA 4
#define DBDATA_SCHEMA \
"CREATE TABLE x(" \
" pgno INTEGER," \
" cell INTEGER," \
" field INTEGER," \
" value ANY," \
" schema TEXT HIDDEN" \
")"
/* Column and schema definitions for sqlite_dbptr */
#define DBPTR_COLUMN_PGNO 0
#define DBPTR_COLUMN_CHILD 1
#define DBPTR_COLUMN_SCHEMA 2
#define DBPTR_SCHEMA \
"CREATE TABLE x(" \
" pgno INTEGER," \
" child INTEGER," \
" schema TEXT HIDDEN" \
")"
/*
** Connect to an sqlite_dbdata (pAux==0) or sqlite_dbptr (pAux!=0) virtual
** table.
*/
static int dbdataConnect(
sqlite3 *db,
void *pAux,
int argc, const char *const*argv,
sqlite3_vtab **ppVtab,
char **pzErr
){
DbdataTable *pTab = 0;
int rc = sqlite3_declare_vtab(db, pAux ? DBPTR_SCHEMA : DBDATA_SCHEMA);
if( rc==SQLITE_OK ){
pTab = (DbdataTable*)sqlite3_malloc64(sizeof(DbdataTable));
if( pTab==0 ){
rc = SQLITE_NOMEM;
}else{
memset(pTab, 0, sizeof(DbdataTable));
pTab->db = db;
pTab->bPtr = (pAux!=0);
}
}
*ppVtab = (sqlite3_vtab*)pTab;
return rc;
}
/*
** Disconnect from or destroy a sqlite_dbdata or sqlite_dbptr virtual table.
*/
static int dbdataDisconnect(sqlite3_vtab *pVtab){
DbdataTable *pTab = (DbdataTable*)pVtab;
if( pTab ){
sqlite3_finalize(pTab->pStmt);
sqlite3_free(pVtab);
}
return SQLITE_OK;
}
/*
** This function interprets two types of constraints:
**
** schema=?
** pgno=?
**
** If neither are present, idxNum is set to 0. If schema=? is present,
** the 0x01 bit in idxNum is set. If pgno=? is present, the 0x02 bit
** in idxNum is set.
**
** If both parameters are present, schema is in position 0 and pgno in
** position 1.
*/
static int dbdataBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdx){
DbdataTable *pTab = (DbdataTable*)tab;
int i;
int iSchema = -1;
int iPgno = -1;
int colSchema = (pTab->bPtr ? DBPTR_COLUMN_SCHEMA : DBDATA_COLUMN_SCHEMA);
for(i=0; i<pIdx->nConstraint; i++){
struct sqlite3_index_constraint *p = &pIdx->aConstraint[i];
if( p->op==SQLITE_INDEX_CONSTRAINT_EQ ){
if( p->iColumn==colSchema ){
if( p->usable==0 ) return SQLITE_CONSTRAINT;
iSchema = i;
}
if( p->iColumn==DBDATA_COLUMN_PGNO && p->usable ){
iPgno = i;
}
}
}
if( iSchema>=0 ){
pIdx->aConstraintUsage[iSchema].argvIndex = 1;
pIdx->aConstraintUsage[iSchema].omit = 1;
}
if( iPgno>=0 ){
pIdx->aConstraintUsage[iPgno].argvIndex = 1 + (iSchema>=0);
pIdx->aConstraintUsage[iPgno].omit = 1;
pIdx->estimatedCost = 100;
pIdx->estimatedRows = 50;
if( pTab->bPtr==0 && pIdx->nOrderBy && pIdx->aOrderBy[0].desc==0 ){
int iCol = pIdx->aOrderBy[0].iColumn;
if( pIdx->nOrderBy==1 ){
pIdx->orderByConsumed = (iCol==0 || iCol==1);
}else if( pIdx->nOrderBy==2 && pIdx->aOrderBy[1].desc==0 && iCol==0 ){
pIdx->orderByConsumed = (pIdx->aOrderBy[1].iColumn==1);
}
}
}else{
pIdx->estimatedCost = 100000000;
pIdx->estimatedRows = 1000000000;
}
pIdx->idxNum = (iSchema>=0 ? 0x01 : 0x00) | (iPgno>=0 ? 0x02 : 0x00);
return SQLITE_OK;
}
/*
** Open a new sqlite_dbdata or sqlite_dbptr cursor.
*/
static int dbdataOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){
DbdataCursor *pCsr;
pCsr = (DbdataCursor*)sqlite3_malloc64(sizeof(DbdataCursor));
if( pCsr==0 ){
return SQLITE_NOMEM;
}else{
memset(pCsr, 0, sizeof(DbdataCursor));
pCsr->base.pVtab = pVTab;
}
*ppCursor = (sqlite3_vtab_cursor *)pCsr;
return SQLITE_OK;
}
/*
** Restore a cursor object to the state it was in when first allocated
** by dbdataOpen().
*/
static void dbdataResetCursor(DbdataCursor *pCsr){
DbdataTable *pTab = (DbdataTable*)(pCsr->base.pVtab);
if( pTab->pStmt==0 ){
pTab->pStmt = pCsr->pStmt;
}else{
sqlite3_finalize(pCsr->pStmt);
}
pCsr->pStmt = 0;
pCsr->iPgno = 1;
pCsr->iCell = 0;
pCsr->iField = 0;
pCsr->bOnePage = 0;
sqlite3_free(pCsr->aPage);
sqlite3_free(pCsr->pRec);
pCsr->pRec = 0;
pCsr->aPage = 0;
}
/*
** Close an sqlite_dbdata or sqlite_dbptr cursor.
*/
static int dbdataClose(sqlite3_vtab_cursor *pCursor){
DbdataCursor *pCsr = (DbdataCursor*)pCursor;
dbdataResetCursor(pCsr);
sqlite3_free(pCsr);
return SQLITE_OK;
}
/*
** Utility methods to decode 16 and 32-bit big-endian unsigned integers.
*/
static unsigned int get_uint16(unsigned char *a){
return (a[0]<<8)|a[1];
}
static unsigned int get_uint32(unsigned char *a){
return ((unsigned int)a[0]<<24)
| ((unsigned int)a[1]<<16)
| ((unsigned int)a[2]<<8)
| ((unsigned int)a[3]);
}
/*
** Load page pgno from the database via the sqlite_dbpage virtual table.
** If successful, set (*ppPage) to point to a buffer containing the page
** data, (*pnPage) to the size of that buffer in bytes and return
** SQLITE_OK. In this case it is the responsibility of the caller to
** eventually free the buffer using sqlite3_free().
**
** Or, if an error occurs, set both (*ppPage) and (*pnPage) to 0 and
** return an SQLite error code.
*/
static int dbdataLoadPage(
DbdataCursor *pCsr, /* Cursor object */
unsigned int pgno, /* Page number of page to load */
u8 **ppPage, /* OUT: pointer to page buffer */
int *pnPage /* OUT: Size of (*ppPage) in bytes */
){
int rc2;
int rc = SQLITE_OK;
sqlite3_stmt *pStmt = pCsr->pStmt;
*ppPage = 0;
*pnPage = 0;
sqlite3_bind_int64(pStmt, 2, pgno);
if( SQLITE_ROW==sqlite3_step(pStmt) ){
int nCopy = sqlite3_column_bytes(pStmt, 0);
if( nCopy>0 ){
u8 *pPage;
pPage = (u8*)sqlite3_malloc64(nCopy + DBDATA_PADDING_BYTES);
if( pPage==0 ){
rc = SQLITE_NOMEM;
}else{
const u8 *pCopy = sqlite3_column_blob(pStmt, 0);
memcpy(pPage, pCopy, nCopy);
memset(&pPage[nCopy], 0, DBDATA_PADDING_BYTES);
}
*ppPage = pPage;
*pnPage = nCopy;
}
}
rc2 = sqlite3_reset(pStmt);
if( rc==SQLITE_OK ) rc = rc2;
return rc;
}
/*
** Read a varint. Put the value in *pVal and return the number of bytes.
*/
static int dbdataGetVarint(const u8 *z, sqlite3_int64 *pVal){
sqlite3_int64 v = 0;
int i;
for(i=0; i<8; i++){
v = (v<<7) + (z[i]&0x7f);
if( (z[i]&0x80)==0 ){ *pVal = v; return i+1; }
}
v = (v<<8) + (z[i]&0xff);
*pVal = v;
return 9;
}
/*
** Return the number of bytes of space used by an SQLite value of type
** eType.
*/
static int dbdataValueBytes(int eType){
switch( eType ){
case 0: case 8: case 9:
case 10: case 11:
return 0;
case 1:
return 1;
case 2:
return 2;
case 3:
return 3;
case 4:
return 4;
case 5:
return 6;
case 6:
case 7:
return 8;
default:
if( eType>0 ){
return ((eType-12) / 2);
}
return 0;
}
}
/*
** Load a value of type eType from buffer pData and use it to set the
** result of context object pCtx.
*/
static void dbdataValue(
sqlite3_context *pCtx,
int eType,
u8 *pData,
int nData
){
if( eType>=0 && dbdataValueBytes(eType)<=nData ){
switch( eType ){
case 0:
case 10:
case 11:
sqlite3_result_null(pCtx);
break;
case 8:
sqlite3_result_int(pCtx, 0);
break;
case 9:
sqlite3_result_int(pCtx, 1);
break;
case 1: case 2: case 3: case 4: case 5: case 6: case 7: {
sqlite3_uint64 v = (signed char)pData[0];
pData++;
switch( eType ){
case 7:
case 6: v = (v<<16) + (pData[0]<<8) + pData[1]; pData += 2;
case 5: v = (v<<16) + (pData[0]<<8) + pData[1]; pData += 2;
case 4: v = (v<<8) + pData[0]; pData++;
case 3: v = (v<<8) + pData[0]; pData++;
case 2: v = (v<<8) + pData[0]; pData++;
}
if( eType==7 ){
double r;
memcpy(&r, &v, sizeof(r));
sqlite3_result_double(pCtx, r);
}else{
sqlite3_result_int64(pCtx, (sqlite3_int64)v);
}
break;
}
default: {
int n = ((eType-12) / 2);
if( eType % 2 ){
sqlite3_result_text(pCtx, (const char*)pData, n, SQLITE_TRANSIENT);
}else{
sqlite3_result_blob(pCtx, pData, n, SQLITE_TRANSIENT);
}
}
}
}
}
/*
** Move an sqlite_dbdata or sqlite_dbptr cursor to the next entry.
*/
static int dbdataNext(sqlite3_vtab_cursor *pCursor){
DbdataCursor *pCsr = (DbdataCursor*)pCursor;
DbdataTable *pTab = (DbdataTable*)pCursor->pVtab;
pCsr->iRowid++;
while( 1 ){
int rc;
int iOff = (pCsr->iPgno==1 ? 100 : 0);
int bNextPage = 0;
if( pCsr->aPage==0 ){
while( 1 ){
if( pCsr->bOnePage==0 && pCsr->iPgno>pCsr->szDb ) return SQLITE_OK;
rc = dbdataLoadPage(pCsr, pCsr->iPgno, &pCsr->aPage, &pCsr->nPage);
if( rc!=SQLITE_OK ) return rc;
if( pCsr->aPage ) break;
pCsr->iPgno++;
}
pCsr->iCell = pTab->bPtr ? -2 : 0;
pCsr->nCell = get_uint16(&pCsr->aPage[iOff+3]);
}
if( pTab->bPtr ){
if( pCsr->aPage[iOff]!=0x02 && pCsr->aPage[iOff]!=0x05 ){
pCsr->iCell = pCsr->nCell;
}
pCsr->iCell++;
if( pCsr->iCell>=pCsr->nCell ){
sqlite3_free(pCsr->aPage);
pCsr->aPage = 0;
if( pCsr->bOnePage ) return SQLITE_OK;
pCsr->iPgno++;
}else{
return SQLITE_OK;
}
}else{
/* If there is no record loaded, load it now. */
if( pCsr->pRec==0 ){
int bHasRowid = 0;
int nPointer = 0;
sqlite3_int64 nPayload = 0;
sqlite3_int64 nHdr = 0;
int iHdr;
int U, X;
int nLocal;
switch( pCsr->aPage[iOff] ){
case 0x02:
nPointer = 4;
break;
case 0x0a:
break;
case 0x0d:
bHasRowid = 1;
break;
default:
/* This is not a b-tree page with records on it. Continue. */
pCsr->iCell = pCsr->nCell;
break;
}
if( pCsr->iCell>=pCsr->nCell ){
bNextPage = 1;
}else{
iOff += 8 + nPointer + pCsr->iCell*2;
if( iOff>pCsr->nPage ){
bNextPage = 1;
}else{
iOff = get_uint16(&pCsr->aPage[iOff]);
}
/* For an interior node cell, skip past the child-page number */
iOff += nPointer;
/* Load the "byte of payload including overflow" field */
if( bNextPage || iOff>pCsr->nPage ){
bNextPage = 1;
}else{
iOff += dbdataGetVarint(&pCsr->aPage[iOff], &nPayload);
}
/* If this is a leaf intkey cell, load the rowid */
if( bHasRowid && !bNextPage && iOff<pCsr->nPage ){
iOff += dbdataGetVarint(&pCsr->aPage[iOff], &pCsr->iIntkey);
}
/* Figure out how much data to read from the local page */
U = pCsr->nPage;
if( bHasRowid ){
X = U-35;
}else{
X = ((U-12)*64/255)-23;
}
if( nPayload<=X ){
nLocal = nPayload;
}else{
int M, K;
M = ((U-12)*32/255)-23;
K = M+((nPayload-M)%(U-4));
if( K<=X ){
nLocal = K;
}else{
nLocal = M;
}
}
if( bNextPage || nLocal+iOff>pCsr->nPage ){
bNextPage = 1;
}else{
/* Allocate space for payload. And a bit more to catch small buffer
** overruns caused by attempting to read a varint or similar from
** near the end of a corrupt record. */
pCsr->pRec = (u8*)sqlite3_malloc64(nPayload+DBDATA_PADDING_BYTES);
if( pCsr->pRec==0 ) return SQLITE_NOMEM;
memset(pCsr->pRec, 0, nPayload+DBDATA_PADDING_BYTES);
pCsr->nRec = nPayload;
/* Load the nLocal bytes of payload */
memcpy(pCsr->pRec, &pCsr->aPage[iOff], nLocal);
iOff += nLocal;
/* Load content from overflow pages */
if( nPayload>nLocal ){
sqlite3_int64 nRem = nPayload - nLocal;
unsigned int pgnoOvfl = get_uint32(&pCsr->aPage[iOff]);
while( nRem>0 ){
u8 *aOvfl = 0;
int nOvfl = 0;
int nCopy;
rc = dbdataLoadPage(pCsr, pgnoOvfl, &aOvfl, &nOvfl);
assert( rc!=SQLITE_OK || aOvfl==0 || nOvfl==pCsr->nPage );
if( rc!=SQLITE_OK ) return rc;
if( aOvfl==0 ) break;
nCopy = U-4;
if( nCopy>nRem ) nCopy = nRem;
memcpy(&pCsr->pRec[nPayload-nRem], &aOvfl[4], nCopy);
nRem -= nCopy;
pgnoOvfl = get_uint32(aOvfl);
sqlite3_free(aOvfl);
}
}
iHdr = dbdataGetVarint(pCsr->pRec, &nHdr);
pCsr->nHdr = nHdr;
pCsr->pHdrPtr = &pCsr->pRec[iHdr];
pCsr->pPtr = &pCsr->pRec[pCsr->nHdr];
pCsr->iField = (bHasRowid ? -1 : 0);
}
}
}else{
pCsr->iField++;
if( pCsr->iField>0 ){
sqlite3_int64 iType;
if( pCsr->pHdrPtr>&pCsr->pRec[pCsr->nRec] ){
bNextPage = 1;
}else{
pCsr->pHdrPtr += dbdataGetVarint(pCsr->pHdrPtr, &iType);
pCsr->pPtr += dbdataValueBytes(iType);
}
}
}
if( bNextPage ){
sqlite3_free(pCsr->aPage);
sqlite3_free(pCsr->pRec);
pCsr->aPage = 0;
pCsr->pRec = 0;
if( pCsr->bOnePage ) return SQLITE_OK;
pCsr->iPgno++;
}else{
if( pCsr->iField<0 || pCsr->pHdrPtr<&pCsr->pRec[pCsr->nHdr] ){
return SQLITE_OK;
}
/* Advance to the next cell. The next iteration of the loop will load
** the record and so on. */
sqlite3_free(pCsr->pRec);
pCsr->pRec = 0;
pCsr->iCell++;
}
}
}
assert( !"can't get here" );
return SQLITE_OK;
}
/*
** Return true if the cursor is at EOF.
*/
static int dbdataEof(sqlite3_vtab_cursor *pCursor){
DbdataCursor *pCsr = (DbdataCursor*)pCursor;
return pCsr->aPage==0;
}
/*
** Determine the size in pages of database zSchema (where zSchema is
** "main", "temp" or the name of an attached database) and set
** pCsr->szDb accordingly. If successful, return SQLITE_OK. Otherwise,
** an SQLite error code.
*/
static int dbdataDbsize(DbdataCursor *pCsr, const char *zSchema){
DbdataTable *pTab = (DbdataTable*)pCsr->base.pVtab;
char *zSql = 0;
int rc, rc2;
sqlite3_stmt *pStmt = 0;
zSql = sqlite3_mprintf("PRAGMA %Q.page_count", zSchema);
if( zSql==0 ) return SQLITE_NOMEM;
rc = sqlite3_prepare_v2(pTab->db, zSql, -1, &pStmt, 0);
sqlite3_free(zSql);
if( rc==SQLITE_OK && sqlite3_step(pStmt)==SQLITE_ROW ){
pCsr->szDb = sqlite3_column_int(pStmt, 0);
}
rc2 = sqlite3_finalize(pStmt);
if( rc==SQLITE_OK ) rc = rc2;
return rc;
}
/*
** xFilter method for sqlite_dbdata and sqlite_dbptr.
*/
static int dbdataFilter(
sqlite3_vtab_cursor *pCursor,
int idxNum, const char *idxStr,
int argc, sqlite3_value **argv
){
DbdataCursor *pCsr = (DbdataCursor*)pCursor;
DbdataTable *pTab = (DbdataTable*)pCursor->pVtab;
int rc = SQLITE_OK;
const char *zSchema = "main";
dbdataResetCursor(pCsr);
assert( pCsr->iPgno==1 );
if( idxNum & 0x01 ){
zSchema = (const char*)sqlite3_value_text(argv[0]);
}
if( idxNum & 0x02 ){
pCsr->iPgno = sqlite3_value_int(argv[(idxNum & 0x01)]);
pCsr->bOnePage = 1;
}else{
pCsr->nPage = dbdataDbsize(pCsr, zSchema);
rc = dbdataDbsize(pCsr, zSchema);
}
if( rc==SQLITE_OK ){
if( pTab->pStmt ){
pCsr->pStmt = pTab->pStmt;
pTab->pStmt = 0;
}else{
rc = sqlite3_prepare_v2(pTab->db,
"SELECT data FROM sqlite_dbpage(?) WHERE pgno=?", -1,
&pCsr->pStmt, 0
);
}
}
if( rc==SQLITE_OK ){
rc = sqlite3_bind_text(pCsr->pStmt, 1, zSchema, -1, SQLITE_TRANSIENT);
}else{
pTab->base.zErrMsg = sqlite3_mprintf("%s", sqlite3_errmsg(pTab->db));
}
if( rc==SQLITE_OK ){
rc = dbdataNext(pCursor);
}
return rc;
}
/*
** Return a column for the sqlite_dbdata or sqlite_dbptr table.
*/
static int dbdataColumn(
sqlite3_vtab_cursor *pCursor,
sqlite3_context *ctx,
int i
){
DbdataCursor *pCsr = (DbdataCursor*)pCursor;
DbdataTable *pTab = (DbdataTable*)pCursor->pVtab;
if( pTab->bPtr ){
switch( i ){
case DBPTR_COLUMN_PGNO:
sqlite3_result_int64(ctx, pCsr->iPgno);
break;
case DBPTR_COLUMN_CHILD: {
int iOff = pCsr->iPgno==1 ? 100 : 0;
if( pCsr->iCell<0 ){
iOff += 8;
}else{
iOff += 12 + pCsr->iCell*2;
if( iOff>pCsr->nPage ) return SQLITE_OK;
iOff = get_uint16(&pCsr->aPage[iOff]);
}
if( iOff<=pCsr->nPage ){
sqlite3_result_int64(ctx, get_uint32(&pCsr->aPage[iOff]));
}
break;
}
}
}else{
switch( i ){
case DBDATA_COLUMN_PGNO:
sqlite3_result_int64(ctx, pCsr->iPgno);
break;
case DBDATA_COLUMN_CELL:
sqlite3_result_int(ctx, pCsr->iCell);
break;
case DBDATA_COLUMN_FIELD:
sqlite3_result_int(ctx, pCsr->iField);
break;
case DBDATA_COLUMN_VALUE: {
if( pCsr->iField<0 ){
sqlite3_result_int64(ctx, pCsr->iIntkey);
}else{
sqlite3_int64 iType;
dbdataGetVarint(pCsr->pHdrPtr, &iType);
dbdataValue(
ctx, iType, pCsr->pPtr, &pCsr->pRec[pCsr->nRec] - pCsr->pPtr
);
}
break;
}
}
}
return SQLITE_OK;
}
/*
** Return the rowid for an sqlite_dbdata or sqlite_dptr table.
*/
static int dbdataRowid(sqlite3_vtab_cursor *pCursor, sqlite_int64 *pRowid){
DbdataCursor *pCsr = (DbdataCursor*)pCursor;
*pRowid = pCsr->iRowid;
return SQLITE_OK;
}
/*
** Invoke this routine to register the "sqlite_dbdata" virtual table module
*/
static int sqlite3DbdataRegister(sqlite3 *db){
static sqlite3_module dbdata_module = {
0, /* iVersion */
0, /* xCreate */
dbdataConnect, /* xConnect */
dbdataBestIndex, /* xBestIndex */
dbdataDisconnect, /* xDisconnect */
0, /* xDestroy */
dbdataOpen, /* xOpen - open a cursor */
dbdataClose, /* xClose - close a cursor */
dbdataFilter, /* xFilter - configure scan constraints */
dbdataNext, /* xNext - advance a cursor */
dbdataEof, /* xEof - check for end of scan */
dbdataColumn, /* xColumn - read data */
dbdataRowid, /* xRowid - read data */
0, /* xUpdate */
0, /* xBegin */
0, /* xSync */
0, /* xCommit */
0, /* xRollback */
0, /* xFindMethod */
0, /* xRename */
0, /* xSavepoint */
0, /* xRelease */
0, /* xRollbackTo */
0 /* xShadowName */
};
int rc = sqlite3_create_module(db, "sqlite_dbdata", &dbdata_module, 0);
if( rc==SQLITE_OK ){
rc = sqlite3_create_module(db, "sqlite_dbptr", &dbdata_module, (void*)1);
}
return rc;
}
#ifdef _WIN32
__declspec(dllexport)
#endif
int sqlite3_dbdata_init(
sqlite3 *db,
char **pzErrMsg,
const sqlite3_api_routines *pApi
){
SQLITE_EXTENSION_INIT2(pApi);
return sqlite3DbdataRegister(db);
}
+1
View File
@@ -849,6 +849,7 @@ static int deltaparsevtabOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
*/
static int deltaparsevtabClose(sqlite3_vtab_cursor *cur){
deltaparsevtab_cursor *pCur = (deltaparsevtab_cursor*)cur;
sqlite3_free(pCur->aDelta);
sqlite3_free(pCur);
return SQLITE_OK;
}
+1 -1
View File
@@ -1123,7 +1123,7 @@ static JsonNode *jsonLookupStep(
u32 iStart, iLabel;
JsonNode *pNode;
iStart = jsonParseAddNode(pParse, JSON_OBJECT, 2, 0);
iLabel = jsonParseAddNode(pParse, JSON_STRING, i, zPath);
iLabel = jsonParseAddNode(pParse, JSON_STRING, nKey, zKey);
zPath += i;
pNode = jsonLookupAppend(pParse, zPath, pApnd, pzErr);
if( pParse->oom ) return 0;
+4 -4
View File
@@ -89,16 +89,16 @@ proc step_rbu_legacy {target rbu} {
proc do_rbu_vacuum_test {tn step {statedb state.db}} {
forcedelete $statedb
if {$statedb=="" && $step==1} breakpoint
uplevel [list do_test $tn.1 [string map [list %state% $statedb] {
if {$step==0} { sqlite3rbu_vacuum rbu test.db {%state%}}
uplevel [list do_test $tn.1 [string map [list %state% $statedb %step% $step] {
if {%step%==0} { sqlite3rbu_vacuum rbu test.db {%state%}}
while 1 {
if {$step==1} { sqlite3rbu_vacuum rbu test.db {%state%}}
if {%step%==1} { sqlite3rbu_vacuum rbu test.db {%state%}}
set state [rbu state]
check_prestep_state test.db $state
set rc [rbu step]
check_poststep_state $rc test.db $state
if {$rc!="SQLITE_OK"} break
if {$step==1} { rbu close }
if {%step%==1} { rbu close }
}
rbu close
}] {SQLITE_DONE}]
+9
View File
@@ -52,6 +52,15 @@ do_faultsim_test 1 -faults oom* -prep {
}
sqlite3rbu_create_vfs -default rbu ""
sqlite3 db test.db
set ::vfsname [file_control_vfsname db]
do_faultsim_test 2 -faults oom* -prep {
} -body {
file_control_vfsname db
}
db close
sqlite3rbu_destroy_vfs rbu
finish_test
-2
View File
@@ -83,7 +83,6 @@ foreach {fault errlist} {
do_faultsim_test 3 -faults $fault -prep {
faultsim_restore_and_reopen
forcedelete test.db2
} -body {
sqlite3rbu_vacuum rbu test.db test.db2
rbu step
@@ -91,7 +90,6 @@ foreach {fault errlist} {
} -test {
eval [list faultsim_test_result {0 SQLITE_OK} {*}$::errlist]
}
}
finish_test
+180
View File
@@ -0,0 +1,180 @@
# 2014 August 30
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# May you do good and not evil.
# May you find forgiveness for yourself and forgive others.
# May you share freely, never taking more than you give.
#
#***********************************************************************
#
source [file join [file dirname [info script]] rbu_common.tcl]
set ::testprefix rbumisc
db close
sqlite3_shutdown
sqlite3_config_uri 1
reset_db
proc populate_rbu_db {} {
forcedelete rbu.db
sqlite3 rbu rbu.db
rbu eval {
CREATE TABLE data_x1(a, b, c, rbu_control);
INSERT INTO data_x1 VALUES(1, 1, 1, 0);
INSERT INTO data_x1 VALUES(2, 2, 2, 0);
CREATE TABLE dat(a, b, c, rbu_control);
CREATE TABLE "data x1"(a, b, c, rbu_control);
CREATE TABLE datax1(a, b, c, rbu_control);
CREATE TABLE data_(a, b, c, rbu_control);
INSERT INTO "data x1" VALUES(3, 3, 3, 0);
INSERT INTO datax1 VALUES(3, 3, 3, 0);
INSERT INTO data_ VALUES(3, 3, 3, 0);
INSERT INTO dat VALUES(3, 3, 3, 0);
}
rbu close
}
#-------------------------------------------------------------------------
# Ensure that RBU is not confused by oddly named tables in an RBU
# database.
#
do_execsql_test 1.0 {
CREATE TABLE x1(a, b, c INTEGER PRIMARY KEY);
}
do_test 1.1 {
populate_rbu_db
} {}
do_test 1.2 {
step_rbu test.db rbu.db
db eval { SELECT * FROM x1 }
} {1 1 1 2 2 2}
do_test 1.3 {
db eval { DELETE FROM x1 }
sqlite3 rbu rbu.db
rbu eval { DELETE FROM rbu_state }
rbu close
step_rbu test.db rbu.db
db eval { SELECT * FROM x1 }
} {1 1 1 2 2 2}
do_test 1.4 {
db eval { DELETE FROM x1 }
populate_rbu_db
sqlite3rbu rbu test.db rbu.db
rbu step
rbu step
rbu close
forcecopy test.db-oal test.db-wal
sqlite3rbu rbu test.db rbu.db
rbu step
list [catch { rbu close } msg] $msg
} {1 {SQLITE_ERROR - cannot update wal mode database}}
#-------------------------------------------------------------------------
# Test the effect of a wal file appearing after the target database has
# been opened, but before it has been locked.
#
catch { db close }
testvfs tvfs -default 1
for {set N 1} {$N < 10} {incr N} {
reset_db
populate_rbu_db
do_execsql_test 2.$N.0 {
CREATE TABLE x1(a, b, c INTEGER PRIMARY KEY);
}
set nAccessCnt 0
do_test 2.$N.1 {
sqlite3rbu rbu test.db rbu.db
rbu step
rbu step
rbu close
} {SQLITE_OK}
tvfs script xAccess
tvfs filter xAccess
set nAccessCnt 0
proc xAccess {method file args} {
global nAccessCnt
if {[file tail $file]=="test.db-wal"} {
incr nAccessCnt -1
if {$nAccessCnt==0} {
set fd [open test.db-wal w]
puts -nonewline $fd [string repeat 0 2000]
close $fd
}
}
return SQLITE_OK
}
foreach r {
{1 {SQLITE_ERROR - cannot update wal mode database}}
{0 SQLITE_OK}
{1 {SQLITE_CANTOPEN - unable to open database file}}
} {
set RES($r) 1
}
do_test 2.$N.2 {
set ::nAccessCnt $N
set res [list [catch {
sqlite3rbu rbu test.db rbu.db
rbu step
rbu close
} msg ] $msg]
set RES($res)
} {1}
catch {rbu close}
}
catch {db close}
catch {tvfs delete}
#-------------------------------------------------------------------------
testvfs tvfs -default 1
reset_db
populate_rbu_db
do_execsql_test 3.0 {
CREATE TABLE x1(a, b, c INTEGER PRIMARY KEY);
}
tvfs script xFileControl
tvfs filter xFileControl
proc xFileControl {method file verb args} {
if {$verb=="ZIPVFS" && [info exists ::zipvfs_filecontrol]} {
return $::zipvfs_filecontrol
}
return "SQLITE_NOTFOUND"
}
breakpoint
foreach {tn ret err} {
1 SQLITE_OK 0
2 SQLITE_ERROR 1
3 SQLITE_NOTFOUND 0
4 SQLITE_OMIT 1
} {
set ::zipvfs_filecontrol $ret
do_test 3.$tn.1 {
catch {
sqlite3rbu rbu test.db rbu.db
rbu step
rbu close
}
} $err
}
catch {db close}
catch {tvfs delete}
#-------------------------------------------------------------------------
finish_test
+4
View File
@@ -80,6 +80,10 @@ foreach {tn without_rowid a b c d} {
set step 0
do_rbu_vacuum_test $tn.1.5 0
do_test $tn.1.6 {
execsql { PRAGMA integrity_check }
} {ok}
}]
}
+1
View File
@@ -65,6 +65,7 @@ proc step_rbu_cachesize {target rbu stepsize cachesize temp_limit} {
while 1 {
sqlite3rbu rbu $target $rbu
rbu temp_size_limit $temp_limit
if { [rbu temp_size_limit -1]!=$temp_limit } { error "round trip problem!" }
sqlite3_exec_nr [rbu db 1] "PRAGMA cache_size = $cachesize"
for {set i 0} {$i < $stepsize} {incr i} {
set rc [rbu step]
+116
View File
@@ -0,0 +1,116 @@
# 2019 Jan 3
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# May you do good and not evil.
# May you find forgiveness for yourself and forgive others.
# May you share freely, never taking more than you give.
#
#***********************************************************************
#
# This file contains tests for the RBU module. More specifically, it
# contains tests to ensure that the sqlite3rbu_vacuum() API works as
# expected.
#
source [file join [file dirname [info script]] rbu_common.tcl]
set testprefix rbuvacuum4
set step 1
do_execsql_test 1.0 {
CREATE TABLE t1(a PRIMARY KEY, b, c) WITHOUT ROWID;
INSERT INTO t1 VALUES(1, 2, 3);
INSERT INTO t1 VALUES(4, 5, 6);
INSERT INTO t1 VALUES(7, 8, 9);
}
do_rbu_vacuum_test 1.1 1
#-------------------------------------------------------------------------
reset_db
do_execsql_test 2.0 {
CREATE TABLE t1(a, b, c, PRIMARY KEY(a, b, c)) WITHOUT ROWID;
INSERT INTO t1 VALUES(1, 2, 3);
INSERT INTO t1 VALUES(4, 5, 6);
INSERT INTO t1 VALUES(7, 8, 9);
}
do_rbu_vacuum_test 2.1 1
do_execsql_test 2.2 {
SELECT * FROM t1;
} {1 2 3 4 5 6 7 8 9}
#-------------------------------------------------------------------------
reset_db
do_execsql_test 3.0 {
CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c);
CREATE INDEX i1 oN t1(b, c);
INSERT INTO t1 VALUES(1, 2, 3);
INSERT INTO t1 VALUES(4, 5, 6);
INSERT INTO t1 VALUES(7, 8, 9);
CREATE TABLE t2(a, b, c INTEGER, PRIMARY KEY(c));
CREATE INDEX i2 oN t2(b, a);
INSERT INTO t2 VALUES('a', 'b', -1);
INSERT INTO t2 VALUES('c', 'd', -2);
INSERT INTO t2 VALUES('e', 'f', -3);
}
do_rbu_vacuum_test 3.1 1
do_execsql_test 3.2 {
SELECT * FROM t1;
SELECT * FROM t2;
} {1 2 3 4 5 6 7 8 9 e f -3 c d -2 a b -1}
#-------------------------------------------------------------------------
reset_db
do_execsql_test 4.0 {
CREATE TABLE x1(a, b, c, d, PRIMARY KEY(c, b)) WITHOUT ROWID;
INSERT INTO x1 VALUES(1, 1, 1, 1);
INSERT INTO x1 VALUES(1, 1, 2, 1);
INSERT INTO x1 VALUES(1, 2, 2, 1);
INSERT INTO x1 VALUES(NULL, 2, 3, NULL);
INSERT INTO x1 VALUES(NULL, 2, 4, NULL);
INSERT INTO x1 VALUES(NULL, 2, 5, NULL);
CREATE INDEX x1ad ON x1(d, a);
CREATE INDEX x1null ON x1(d, a) WHERE d>15;
}
do_rbu_vacuum_test 4.1.1 1
do_execsql_test 4.2 {
SELECT count(*) fROM x1
} 6
do_rbu_vacuum_test 4.1.2 0
#-------------------------------------------------------------------------
reset_db
do_execsql_test 5.0 {
CREATE TABLE "a b c"(a, "b b" PRIMARY KEY, "c c");
CREATE INDEX abc1 ON "a b c"(a, "c c");
INSERT INTO "a b c" VALUES(NULL, 'a', NULL);
INSERT INTO "a b c" VALUES(NULL, 'b', NULL);
INSERT INTO "a b c" VALUES(NULL, 'c', NULL);
INSERT INTO "a b c" VALUES(1, 2, 3);
INSERT INTO "a b c" VALUES(3, 9, 1);
INSERT INTO "a b c" VALUES('aaa', 'bbb', 'ccc');
CREATE INDEX abc2 ON "a b c"("c c" DESC, a);
CREATE TABLE x(a);
INSERT INTO x VALUES('a'), ('b'), ('d');
CREATE UNIQUE INDEX y ON x(a);
}
do_rbu_vacuum_test 5.1 1
finish_test
+283 -34
View File
@@ -930,7 +930,8 @@ static void rbuTargetNameFunc(
zIn = (const char*)sqlite3_value_text(argv[0]);
if( zIn ){
if( rbuIsVacuum(p) ){
if( argc==1 || 0==sqlite3_value_int(argv[1]) ){
assert( argc==2 );
if( 0==sqlite3_value_int(argv[1]) ){
sqlite3_result_text(pCtx, zIn, -1, SQLITE_STATIC);
}
}else{
@@ -1381,7 +1382,8 @@ static int rbuObjIterCacheTableInfo(sqlite3rbu *p, RbuObjIter *pIter){
}
pIter->azTblType[iOrder] = rbuStrndup(zType, &p->rc);
pIter->abTblPk[iOrder] = (iPk!=0);
assert( iPk>=0 );
pIter->abTblPk[iOrder] = (u8)iPk;
pIter->abNotNull[iOrder] = (u8)bNotNull || (iPk!=0);
iOrder++;
}
@@ -1416,6 +1418,213 @@ static char *rbuObjIterGetCollist(
return zList;
}
/*
** Return a comma separated list of the quoted PRIMARY KEY column names,
** in order, for the current table. Before each column name, add the text
** zPre. After each column name, add the zPost text. Use zSeparator as
** the separator text (usually ", ").
*/
static char *rbuObjIterGetPkList(
sqlite3rbu *p, /* RBU object */
RbuObjIter *pIter, /* Object iterator for column names */
const char *zPre, /* Before each quoted column name */
const char *zSeparator, /* Separator to use between columns */
const char *zPost /* After each quoted column name */
){
int iPk = 1;
char *zRet = 0;
const char *zSep = "";
while( 1 ){
int i;
for(i=0; i<pIter->nTblCol; i++){
if( (int)pIter->abTblPk[i]==iPk ){
const char *zCol = pIter->azTblCol[i];
zRet = rbuMPrintf(p, "%z%s%s\"%w\"%s", zRet, zSep, zPre, zCol, zPost);
zSep = zSeparator;
break;
}
}
if( i==pIter->nTblCol ) break;
iPk++;
}
return zRet;
}
/*
** This function is called as part of restarting an RBU vacuum within
** stage 1 of the process (while the *-oal file is being built) while
** updating a table (not an index). The table may be a rowid table or
** a WITHOUT ROWID table. It queries the target database to find the
** largest key that has already been written to the target table and
** constructs a WHERE clause that can be used to extract the remaining
** rows from the source table. For a rowid table, the WHERE clause
** is of the form:
**
** "WHERE _rowid_ > ?"
**
** and for WITHOUT ROWID tables:
**
** "WHERE (key1, key2) > (?, ?)"
**
** Instead of "?" placeholders, the actual WHERE clauses created by
** this function contain literal SQL values.
*/
static char *rbuVacuumTableStart(
sqlite3rbu *p, /* RBU handle */
RbuObjIter *pIter, /* RBU iterator object */
int bRowid, /* True for a rowid table */
const char *zWrite /* Target table name prefix */
){
sqlite3_stmt *pMax = 0;
char *zRet = 0;
if( bRowid ){
p->rc = prepareFreeAndCollectError(p->dbMain, &pMax, &p->zErrmsg,
sqlite3_mprintf(
"SELECT max(_rowid_) FROM \"%s%w\"", zWrite, pIter->zTbl
)
);
if( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pMax) ){
sqlite3_int64 iMax = sqlite3_column_int64(pMax, 0);
zRet = rbuMPrintf(p, " WHERE _rowid_ > %lld ", iMax);
}
rbuFinalize(p, pMax);
}else{
char *zOrder = rbuObjIterGetPkList(p, pIter, "", ", ", " DESC");
char *zSelect = rbuObjIterGetPkList(p, pIter, "quote(", "||','||", ")");
char *zList = rbuObjIterGetPkList(p, pIter, "", ", ", "");
if( p->rc==SQLITE_OK ){
p->rc = prepareFreeAndCollectError(p->dbMain, &pMax, &p->zErrmsg,
sqlite3_mprintf(
"SELECT %s FROM \"%s%w\" ORDER BY %s LIMIT 1",
zSelect, zWrite, pIter->zTbl, zOrder
)
);
if( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pMax) ){
const char *zVal = (const char*)sqlite3_column_text(pMax, 0);
zRet = rbuMPrintf(p, " WHERE (%s) > (%s) ", zList, zVal);
}
rbuFinalize(p, pMax);
}
sqlite3_free(zOrder);
sqlite3_free(zSelect);
sqlite3_free(zList);
}
return zRet;
}
/*
** This function is called as part of restating an RBU vacuum when the
** current operation is writing content to an index. If possible, it
** queries the target index b-tree for the largest key already written to
** it, then composes and returns an expression that can be used in a WHERE
** clause to select the remaining required rows from the source table.
** It is only possible to return such an expression if:
**
** * The index contains no DESC columns, and
** * The last key written to the index before the operation was
** suspended does not contain any NULL values.
**
** The expression is of the form:
**
** (index-field1, index-field2, ...) > (?, ?, ...)
**
** except that the "?" placeholders are replaced with literal values.
**
** If the expression cannot be created, NULL is returned. In this case,
** the caller has to use an OFFSET clause to extract only the required
** rows from the sourct table, just as it does for an RBU update operation.
*/
char *rbuVacuumIndexStart(
sqlite3rbu *p, /* RBU handle */
RbuObjIter *pIter /* RBU iterator object */
){
char *zOrder = 0;
char *zLhs = 0;
char *zSelect = 0;
char *zVector = 0;
char *zRet = 0;
int bFailed = 0;
const char *zSep = "";
int iCol = 0;
sqlite3_stmt *pXInfo = 0;
p->rc = prepareFreeAndCollectError(p->dbMain, &pXInfo, &p->zErrmsg,
sqlite3_mprintf("PRAGMA main.index_xinfo = %Q", pIter->zIdx)
);
while( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pXInfo) ){
int iCid = sqlite3_column_int(pXInfo, 1);
const char *zCollate = (const char*)sqlite3_column_text(pXInfo, 4);
const char *zCol;
if( sqlite3_column_int(pXInfo, 3) ){
bFailed = 1;
break;
}
if( iCid<0 ){
if( pIter->eType==RBU_PK_IPK ){
int i;
for(i=0; pIter->abTblPk[i]==0; i++);
assert( i<pIter->nTblCol );
zCol = pIter->azTblCol[i];
}else{
zCol = "_rowid_";
}
}else{
zCol = pIter->azTblCol[iCid];
}
zLhs = rbuMPrintf(p, "%z%s \"%w\" COLLATE %Q",
zLhs, zSep, zCol, zCollate
);
zOrder = rbuMPrintf(p, "%z%s \"rbu_imp_%d%w\" COLLATE %Q DESC",
zOrder, zSep, iCol, zCol, zCollate
);
zSelect = rbuMPrintf(p, "%z%s quote(\"rbu_imp_%d%w\")",
zSelect, zSep, iCol, zCol
);
zSep = ", ";
iCol++;
}
rbuFinalize(p, pXInfo);
if( bFailed ) goto index_start_out;
if( p->rc==SQLITE_OK ){
sqlite3_stmt *pSel = 0;
p->rc = prepareFreeAndCollectError(p->dbMain, &pSel, &p->zErrmsg,
sqlite3_mprintf("SELECT %s FROM \"rbu_imp_%w\" ORDER BY %s LIMIT 1",
zSelect, pIter->zTbl, zOrder
)
);
if( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pSel) ){
zSep = "";
for(iCol=0; iCol<pIter->nCol; iCol++){
const char *zQuoted = (const char*)sqlite3_column_text(pSel, iCol);
if( zQuoted[0]=='N' ){
bFailed = 1;
break;
}
zVector = rbuMPrintf(p, "%z%s%s", zVector, zSep, zQuoted);
zSep = ", ";
}
if( !bFailed ){
zRet = rbuMPrintf(p, "(%s) > (%s)", zLhs, zVector);
}
}
rbuFinalize(p, pSel);
}
index_start_out:
sqlite3_free(zOrder);
sqlite3_free(zSelect);
sqlite3_free(zVector);
sqlite3_free(zLhs);
return zRet;
}
/*
** This function is used to create a SELECT list (the list of SQL
** expressions that follows a SELECT keyword) for a SELECT statement
@@ -2092,12 +2301,24 @@ static int rbuObjIterPrepareAll(
if( p->rc==SQLITE_OK ){
char *zSql;
if( rbuIsVacuum(p) ){
char *zStart = 0;
if( nOffset ){
zStart = rbuVacuumIndexStart(p, pIter);
if( zStart ){
sqlite3_free(zLimit);
zLimit = 0;
}
}
zSql = sqlite3_mprintf(
"SELECT %s, 0 AS rbu_control FROM '%q' %s ORDER BY %s%s",
"SELECT %s, 0 AS rbu_control FROM '%q' %s %s %s ORDER BY %s%s",
zCollist,
pIter->zDataTbl,
zPart, zCollist, zLimit
zPart,
(zStart ? (zPart ? "AND" : "WHERE") : ""), zStart,
zCollist, zLimit
);
sqlite3_free(zStart);
}else
if( pIter->eType==RBU_PK_EXTERNAL || pIter->eType==RBU_PK_NONE ){
@@ -2120,7 +2341,11 @@ static int rbuObjIterPrepareAll(
zCollist, zLimit
);
}
p->rc = prepareFreeAndCollectError(p->dbRbu, &pIter->pSelect, pz, zSql);
if( p->rc==SQLITE_OK ){
p->rc = prepareFreeAndCollectError(p->dbRbu,&pIter->pSelect,pz,zSql);
}else{
sqlite3_free(zSql);
}
}
sqlite3_free(zImposterCols);
@@ -2220,18 +2445,42 @@ static int rbuObjIterPrepareAll(
/* Create the SELECT statement to read keys from data_xxx */
if( p->rc==SQLITE_OK ){
const char *zRbuRowid = "";
char *zStart = 0;
char *zOrder = 0;
if( bRbuRowid ){
zRbuRowid = rbuIsVacuum(p) ? ",_rowid_ " : ",rbu_rowid";
}
p->rc = prepareFreeAndCollectError(p->dbRbu, &pIter->pSelect, pz,
sqlite3_mprintf(
"SELECT %s,%s rbu_control%s FROM '%q'%s",
zCollist,
(rbuIsVacuum(p) ? "0 AS " : ""),
zRbuRowid,
pIter->zDataTbl, zLimit
)
);
if( rbuIsVacuum(p) ){
if( nOffset ){
zStart = rbuVacuumTableStart(p, pIter, bRbuRowid, zWrite);
if( zStart ){
sqlite3_free(zLimit);
zLimit = 0;
}
}
if( bRbuRowid ){
zOrder = rbuMPrintf(p, "_rowid_");
}else{
zOrder = rbuObjIterGetPkList(p, pIter, "", ", ", "");
}
}
if( p->rc==SQLITE_OK ){
p->rc = prepareFreeAndCollectError(p->dbRbu, &pIter->pSelect, pz,
sqlite3_mprintf(
"SELECT %s,%s rbu_control%s FROM '%q'%s %s %s %s",
zCollist,
(rbuIsVacuum(p) ? "0 AS " : ""),
zRbuRowid,
pIter->zDataTbl, (zStart ? zStart : ""),
(zOrder ? "ORDER BY" : ""), zOrder,
zLimit
)
);
}
sqlite3_free(zStart);
sqlite3_free(zOrder);
}
sqlite3_free(zWhere);
@@ -4458,9 +4707,7 @@ static int rbuVfsFileControl(sqlite3_file *pFile, int op, void *pArg){
}else if( rc==SQLITE_NOTFOUND ){
pRbu->pTargetFd = p;
p->pRbu = pRbu;
if( p->openFlags & SQLITE_OPEN_MAIN_DB ){
rbuMainlistAdd(p);
}
rbuMainlistAdd(p);
if( p->pWalFd ) p->pWalFd->pRbu = pRbu;
rc = SQLITE_OK;
}
@@ -4523,10 +4770,7 @@ static int rbuVfsShmLock(sqlite3_file *pFile, int ofst, int n, int flags){
if( ofst==WAL_LOCK_CKPT && n==1 ) rc = SQLITE_BUSY;
}else{
int bCapture = 0;
if( n==1 && (flags & SQLITE_SHM_EXCLUSIVE)
&& pRbu && pRbu->eStage==RBU_STAGE_CAPTURE
&& (ofst==WAL_LOCK_WRITE || ofst==WAL_LOCK_CKPT || ofst==WAL_LOCK_READ0)
){
if( pRbu && pRbu->eStage==RBU_STAGE_CAPTURE ){
bCapture = 1;
}
@@ -4559,20 +4803,24 @@ static int rbuVfsShmMap(
** rbu is in the RBU_STAGE_OAL state, use heap memory for *-shm space
** instead of a file on disk. */
assert( p->openFlags & (SQLITE_OPEN_MAIN_DB|SQLITE_OPEN_TEMP_DB) );
if( eStage==RBU_STAGE_OAL || eStage==RBU_STAGE_MOVE ){
if( iRegion<=p->nShm ){
sqlite3_int64 nByte = (iRegion+1) * sizeof(char*);
char **apNew = (char**)sqlite3_realloc64(p->apShm, nByte);
if( apNew==0 ){
rc = SQLITE_NOMEM;
}else{
memset(&apNew[p->nShm], 0, sizeof(char*) * (1 + iRegion - p->nShm));
p->apShm = apNew;
p->nShm = iRegion+1;
}
if( eStage==RBU_STAGE_OAL ){
sqlite3_int64 nByte = (iRegion+1) * sizeof(char*);
char **apNew = (char**)sqlite3_realloc64(p->apShm, nByte);
/* This is an RBU connection that uses its own heap memory for the
** pages of the *-shm file. Since no other process can have run
** recovery, the connection must request *-shm pages in order
** from start to finish. */
assert( iRegion==p->nShm );
if( apNew==0 ){
rc = SQLITE_NOMEM;
}else{
memset(&apNew[p->nShm], 0, sizeof(char*) * (1 + iRegion - p->nShm));
p->apShm = apNew;
p->nShm = iRegion+1;
}
if( rc==SQLITE_OK && p->apShm[iRegion]==0 ){
if( rc==SQLITE_OK ){
char *pNew = (char*)sqlite3_malloc64(szRegion);
if( pNew==0 ){
rc = SQLITE_NOMEM;
@@ -4801,7 +5049,8 @@ static int rbuVfsAccess(
*/
if( rc==SQLITE_OK && flags==SQLITE_ACCESS_EXISTS ){
rbu_file *pDb = rbuFindMaindb(pRbuVfs, zPath, 1);
if( pDb && pDb->pRbu && pDb->pRbu->eStage==RBU_STAGE_OAL ){
if( pDb && pDb->pRbu->eStage==RBU_STAGE_OAL ){
assert( pDb->pRbu );
if( *pResOut ){
rc = SQLITE_CANTOPEN;
}else{
+10 -4
View File
@@ -63,10 +63,6 @@
#include "sqlite3.h"
#endif
#include <string.h>
#include <assert.h>
#include <stdio.h>
#ifndef SQLITE_AMALGAMATION
#include "sqlite3rtree.h"
typedef sqlite3_int64 i64;
@@ -74,7 +70,17 @@ typedef sqlite3_uint64 u64;
typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned int u32;
#if !defined(NDEBUG) && !defined(SQLITE_DEBUG)
# define NDEBUG 1
#endif
#if defined(NDEBUG) && defined(SQLITE_DEBUG)
# undef NDEBUG
#endif
#endif
#include <string.h>
#include <stdio.h>
#include <assert.h>
/* The following macro is used to suppress compiler warnings.
*/
+4 -2
View File
@@ -1624,7 +1624,9 @@ int sqlite3session_diff(
}
sqlite3_free((char*)azCol);
if( bMismatch ){
*pzErrMsg = sqlite3_mprintf("table schemas do not match");
if( pzErrMsg ){
*pzErrMsg = sqlite3_mprintf("table schemas do not match");
}
rc = SQLITE_SCHEMA;
}
if( bHasPk==0 ){
@@ -1830,7 +1832,7 @@ int sqlite3session_attach(
** set *pRc to SQLITE_NOMEM and return non-zero.
*/
static int sessionBufferGrow(SessionBuffer *p, size_t nByte, int *pRc){
if( *pRc==SQLITE_OK && p->nAlloc-p->nBuf<nByte ){
if( *pRc==SQLITE_OK && (size_t)(p->nAlloc-p->nBuf)<nByte ){
u8 *aNew;
i64 nNew = p->nAlloc ? p->nAlloc : 128;
do {
+1
View File
@@ -738,6 +738,7 @@ SHELL_SRC = \
$(TOP)/ext/expert/sqlite3expert.h \
$(TOP)/ext/misc/zipfile.c \
$(TOP)/ext/misc/memtrace.c \
$(TOP)/ext/misc/dbdata.c \
$(TOP)/src/test_windirent.c
shell.c: $(SHELL_SRC) $(TOP)/tool/mkshellc.tcl
+144 -131
View File
@@ -1,13 +1,13 @@
C Version\s3.28.0
D 2019-04-16T19:49:53.412
C Version\s3.29.0
D 2019-07-10T17:32:03.802
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
F Makefile.in 4640daf826b80947a924ac44275c451ffc13007c7c866a5730c8ce5cf9e1dc74
F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
F Makefile.msc 26957950b2b4f3b26e311eeea70437f85a77765f71d3a06489466d66ee321100
F README.md 74745e53db87fdc86f571dd7ec1bd18e154d0abd6d37d2292a1062e931318a29
F VERSION 288d756b1b7be03ecdbf1795c23af2c8425f2e46ba6979a14ef53360308f080d
F README.md 1514a365ffca3c138e00c5cc839906108a01011a6b082bad19b09781e3aa498a
F VERSION cc8cd90333c65cdf4cb346f356a2ce1eb0f5b7fa1d17a34d7350103e7320af1f
F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50
F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2
F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90
@@ -31,10 +31,10 @@ F autoconf/tea/tclconfig/tcl.m4 66ddf0a5d5e4b1d29bff472c0985fd7fa89d0fb5
F autoconf/tea/win/makefile.vc f89d0184d0eee5f7e356ea407964dcd139939928
F autoconf/tea/win/nmakehlp.c 247538ad8e8c508f33c03ec1fbd67d3a07ef6291
F autoconf/tea/win/rules.vc c511f222b80064096b705dbeb97060ee1d6b6d63
F config.guess 226d9a188c6196f3033ffc651cbc9dcee1a42977
F config.guess 883205ddf25b46f10c181818bf42c09da9888884af96f79e1719264345053bd6
F config.h.in 6376abec766e9a0785178b1823b5a587e9f1ccbc
F config.sub 9ebe4c3b3dab6431ece34f16828b594fb420da55
F configure b013bf805064650b072817c7c7f0a295cfcec5b1afec15e59ea4e9996543f51e x
F config.sub c2d0260f17f3e4bc0b6808fccf1b291cb5e9126c14fc5890efc77b9fd0175559
F configure 4a97fb6ccce582ebb3dc5a7e281e5e2823574dad851b8ccf814aa6de9f4c7ad2 x
F configure.ac 3552d3aecade98a9d4b64bceb48ffb7726cbc85902efde956812942f060fbd0a
F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad
F doc/F2FS.txt c1d4a0ae9711cfe0e1d8b019d154f1c29e0d3abfe820787ba1e9ed7691160fcd
@@ -99,7 +99,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 1d814248a42ddecc6ebd8d9e09673228de2ff5ae1410b8b7f1b22e04b7299fdf
F ext/fts3/fts3_write.c 9e88111ca9f70e4079880d842c8323bffc4968b39ee38c0a75962a3485af9333
F ext/fts3/fts3speed.tcl b54caf6a18d38174f1a6e84219950d85e98bb1e9
F ext/fts3/mkfts3amal.tcl 252ecb7fe6467854f2aa237bf2c390b74e71f100
F ext/fts3/tool/fts3cov.sh c331d006359456cf6f8f953e37f2b9c7d568f3863f00bb5f7eb87fea4ac01b73
@@ -112,11 +112,11 @@ F ext/fts5/extract_api_docs.tcl a36e54ec777172ddd3f9a88daf593b00848368e0
F ext/fts5/fts5.h 7c9da96f2b9dcfa4dd94081fb2d87ec418d8cdb35b25df56756c334b6b558fd7
F ext/fts5/fts5Int.h 5c26dce0ec9272fca726c6fddb92f634d0c912d4ca170330270d488a94b80416
F ext/fts5/fts5_aux.c dcc627d8b6e3fc773db528ff67b39955dab7b51628f9dba8e15849e5bedfd7fa
F ext/fts5/fts5_buffer.c 7d91caa0d862079d787660ec405d2fda6fd4f206d95b870dc7adc3b8f66a400f
F ext/fts5/fts5_buffer.c 5a5fe0159752c0fb0a5a93c722e9db2662822709490769d482b76a6dc8aaca70
F ext/fts5/fts5_config.c d7523cba5e66da077233c023aecbc3e6a37978ff75a18131c5ab5b1229d5bac7
F ext/fts5/fts5_expr.c 840c88d55e78083a5e61a35968df877712ae28791b347eced1e98e3b337d2d3c
F ext/fts5/fts5_hash.c 1cc0095646f5f3b46721aa112fb4f9bf29ae175cb5338f89dcec66ed97acfe75
F ext/fts5/fts5_index.c 9146da94d0b9f62217c6ad234342fda3fbac3c254455d0b3f53957ad85262e08
F ext/fts5/fts5_index.c 5a89e0341297fade9a8f2c7aecc1ebd2e7e0989da84ece4d287a153da73cf0e6
F ext/fts5/fts5_main.c abd04720e2729ba5bab2648d9d541faab18f45d481ae21fc30f125b55e979d6b
F ext/fts5/fts5_storage.c b24f6916fcdd68989a549f25962f286bdba9d9d59c7581567a6a0eb647cd07cc
F ext/fts5/fts5_tcl.c 39bcbae507f594aad778172fa914cad0f585bf92fd3b078c686e249282db0d95
@@ -125,7 +125,7 @@ F ext/fts5/fts5_test_tok.c f96c6e193c466711d6d7828d5f190407fe7ab897062d371426dd3
F ext/fts5/fts5_tokenize.c 2e508c6a3bd8ee56c48e98a38052e1a650e49b32a484cce9b189984114bc3b88
F ext/fts5/fts5_unicode2.c 8bd0cd07396b74c1a05590e4070d635bccfc849812c305619f109e6c0485e250
F ext/fts5/fts5_varint.c e64d2113f6e1bfee0032972cffc1207b77af63319746951bf1d09885d1dadf80
F ext/fts5/fts5_vocab.c 906dff069840347e68f654b12ca60a53a27cd1780daf155fbe7dd331f27c2329
F ext/fts5/fts5_vocab.c c3f12188570abb423303cd193b16dd19ba54e21c2e930e9b748d743de3b385f5
F ext/fts5/fts5parse.y eb526940f892ade5693f22ffd6c4f2702543a9059942772526eac1fde256bb05
F ext/fts5/mkportersteps.tcl 5acf962d2e0074f701620bb5308155fa1e4a63ba
F ext/fts5/test/fts5_common.tcl b01c584144b5064f30e6c648145a2dd6bc440841
@@ -157,7 +157,8 @@ F ext/fts5/test/fts5connect.test 08030168fc96fc278fa81f28654fb7e90566f33aff269c0
F ext/fts5/test/fts5content.test 688d5ac7af194ebc67495daea76a69e3cd5480122c2320e72d41241b423b4116
F ext/fts5/test/fts5corrupt.test 77ae6f41a7eba10620efb921cf7dbe218b0ef232b04519deb43581cb17a57ebe
F ext/fts5/test/fts5corrupt2.test 7453752ba12ce91690c469a6449d412561cc604b1dec994e16ab132952e7805f
F ext/fts5/test/fts5corrupt3.test d3a07e6fe172ade03310af6056cae45ac3d2880a9bba187908eba735bd170742
F ext/fts5/test/fts5corrupt3.test ee32b76e1b4beae8051f0bd5bc9cc9609667fdaed87886eda69b96b305d21897
F ext/fts5/test/fts5corrupt4.test ea805c4d7c68b5f185b9db5d2060a7ae5875339738dd48203c92162f41e7ca91
F ext/fts5/test/fts5delete.test cbf87e3b8867c4d5cfcaed975c7475fd3f99d072bce2075fcedf43d1f82af775
F ext/fts5/test/fts5detail.test 31b240dbf6d44ac3507e2f8b65f29fdc12465ffd531212378c7ce1066766f54e
F ext/fts5/test/fts5determin.test 1b77879b2ae818b5b71c859e534ee334dac088b7cf3ff3bf76a2c82b1c788d11
@@ -277,21 +278,22 @@ F ext/misc/README.md d6dd0fe1d8af77040216798a6a2b0c46c73054d2f0ea544fbbcdccf6f23
F ext/misc/amatch.c 50a9ef2d38dabfa371f8c1904097d493271e63d58ccb0e9b79a4fa4a94e66660
F ext/misc/anycollseq.c 5ffdfde9829eeac52219136ad6aa7cd9a4edb3b15f4f2532de52f4a22525eddb
F ext/misc/appendvfs.c 3777f22ec1057dc4e5fd89f2fbddcc7a29fbeef1ad038c736c54411bb1967af7
F ext/misc/blobio.c 085bbfa57ea58bb15d994ba4cd397bff6f0c38c4f618adbc62cf4d3780e5d88a
F ext/misc/blobio.c a867c4c4617f6ec223a307ebfe0eabb45e0992f74dd47722b96f3e631c0edb2a
F ext/misc/btreeinfo.c 4f0ebf278f46e68e6306c667917766cebc5550fd35d5de17847988e22892d4d2
F ext/misc/carray.c ed96c218ea940b85c9a274c4d9c59fe9491c299147a38a8bba537687bd6c6005
F ext/misc/closure.c dbfd8543b2a017ae6b1a5843986b22ddf99ff126ec9634a2f4047cd14c85c243
F ext/misc/completion.c cec672d40604075bb341a7f11ac48393efdcd90a979269b8fe7977ea62d0547f
F ext/misc/compress.c dd4f8a6d0baccff3c694757db5b430f3bbd821d8686d1fc24df55cf9f035b189
F ext/misc/csv.c 7f047aeb68f5802e7ce6639292095d622a488bb43526ed04810e0649faa71ceb
F ext/misc/dbdata.c e316fba936571584e55abd5b974a32a191727a6b746053a0c9d439bd2cf93940
F ext/misc/dbdump.c baf6e37447c9d6968417b1cd34cbedb0b0ab3f91b5329501d8a8d5be3287c336
F ext/misc/eval.c 4b4757592d00fd32e44c7a067e6a0e4839c81a4d57abc4131ee7806d1be3104e
F ext/misc/explain.c d5c12962d79913ef774b297006872af1fccda388f61a11d37758f9179a09551f
F ext/misc/fileio.c 288e7230e0fe464d71b0694e2d8bdd3a353118ac2e31da3964b95f460f09915f
F ext/misc/fossildelta.c 910510968a30ab77b8ac1a27931f2cb834e9db9fd5ab122f53b6045b4315665d
F ext/misc/fossildelta.c 5c04d0a5657615daf4c6cd01c4281de8983dd28f6eed592b2691c10e3f6710e1
F ext/misc/fuzzer.c c4e27daf41433a64cad5265cd27dbcb891147e9994d0422200ce81ce9a54b625
F ext/misc/ieee754.c f190d0cc5182529acb15babd177781be1ac1718c
F ext/misc/json1.c 8af4672f43634257dbcfdb4515b4070325463d67c6968b4be1bd414de28d4d58
F ext/misc/json1.c c99b5f04fccba87c1c8c5ab5c0e53eef37c0144086e33911290a67dfba541d59
F ext/misc/memstat.c 3017a0832c645c0f8c773435620d663855f04690172316bd127270d1a7523d4d
F ext/misc/memtrace.c 7c0d115d2ef716ad0ba632c91e05bd119cb16c1aedf3bec9f06196ead2d5537b
F ext/misc/memvfs.c ab36f49e02ebcdf85a1e08dc4d8599ea8f343e073ac9e0bca18a98b7e1ec9567
@@ -337,28 +339,30 @@ F ext/rbu/rbu9.test 0e4d985e25620d61920597e8ea69c871c9e8c1f5a0be2ae9fa70bb641d74
F ext/rbu/rbuA.test b34a90cb495682c25b5fc03a9d5e7a4fc99541c29256f25e2e2a4f6542b4f5b3
F ext/rbu/rbuB.test 52b07158824c6927b7e25554ace92a695cdebfc296ae3d308ac386984aded9bc
F ext/rbu/rbuC.test 80f1cc2fb74f44b1128fd0ed8eedab3a76fefeb72a947860e2869ef76fc8dc6b
F ext/rbu/rbu_common.tcl 4b3d033b3e3844292ae3a1aefc0e524e64b0db5a0e4310657919e4504ac3073f
F ext/rbu/rbu_common.tcl 60d904133ff843fe72cc0514e9dd2486707181e6e0fbab20979da28c48d21de9
F ext/rbu/rbucollate.test cac528a9a46318cba42e61258bb42660bbbf4fdb9a8c863de5a54ad0c658d197
F ext/rbu/rbucrash.test 000981a1fe8a6e4d9a684232f6a129e66a3ef595f5ed74655e2f9c68ffa613b4
F ext/rbu/rbucrash2.test efa143cc94228eb0266d3f1abfbee60a5838a84cef7cc3fcb8c145b74d96fd41
F ext/rbu/rbudiff.test 156957851136b63c143478518dc1bda6c832103cdbe8ac1d7cdd47edb3cbe0a3
F ext/rbu/rbudor.test e3e8623926012f43eebe51fedf06a102df2640750d971596b052495f2536db20
F ext/rbu/rbufault.test 2d7f567b79d558f6e093c58808cab4354f8a174e3802f69e7790a9689b3c09f8
F ext/rbu/rbufault2.test 06e735c002c17802d93debca41f59b027e7429db7de17f2a81318ecfd3c651d4
F ext/rbu/rbufault3.test e0052ccba428ffdd2bb989d3ae84716f058ec5ab5f7196c64ba407b9d23c7255
F ext/rbu/rbufault2.test c81327a3ac2c385b9b954db3644d4e0df93eeebfc3de9f1f29975a1e73fd3d0c
F ext/rbu/rbufault3.test b2fcc9db5c982b869f67d1d4688d8cb515d5b92f58011fff95665f2e62cec179
F ext/rbu/rbufault4.test 03d2849c3df7d7bd14a622e789ff049e5080edd34a79cd432e01204db2a5930a
F ext/rbu/rbufts.test 0ae8d1da191c75bd776b86e24456db0fb6e97b7c944259fae5407ea55d23c31d
F ext/rbu/rbumisc.test 329986cf5dd51890c4eb906c2f960ebb773a79a64bed90f506b7c417825b37eb
F ext/rbu/rbumulti.test 5fb139058f37ddc5a113c5b93238de915b769b7792de41b44c983bc7c18cf5b9
F ext/rbu/rbupartial.test 73baf12a5941fe6891a829106a6f2e0a973f89aa49bd8659b12f547beb29b482
F ext/rbu/rbupartial.test 1c8bd6d42615b94caf08f129f5817fa26975523f0f51bceda1dca90e8114c7c4
F ext/rbu/rbuprogress.test 04614ff8820bab9c1ec1b7dbec1edc4b45474421d4fe7abbd2a879a9c02884f9
F ext/rbu/rburesume.test dbdc4ca504e9c76375a69e5f0d91205db967dcc509a5166ca80231f8fda49eb1
F ext/rbu/rbusave.test f4190a1a86fccf84f723af5c93813365ae33feda35845ba107b59683d1cdd926
F ext/rbu/rbusplit.test b37e7b40b38760881dc9c854bd40b4744c6b6cd74990754eca3bda0f407051e8
F ext/rbu/rbutemplimit.test 7f408f49b90fa0a720d7599f3aec74a3c85e6cd78e56fdf726ce00af9147a341
F ext/rbu/rbutemplimit.test 05ceefa90a2e26a99f40dd48282ed63a00df5e59c1f2bfd479c143e201a1b0ba
F ext/rbu/rbuvacuum.test 55e101e90168c2b31df6c9638fe73dc7f7cc666b6142266d1563697d79f73534
F ext/rbu/rbuvacuum2.test b8e5b51dc8b2c0153373d024c0936be3f66f9234acbd6d0baab0869d56b14e6b
F ext/rbu/rbuvacuum3.test 8addd82e4b83b4c93fa47428eae4fd0dbf410f8512c186f38e348feb49ba03dc
F ext/rbu/sqlite3rbu.c f222350c33f063cbc754001cd4e9683164c6cb06be76ae43f15b396ec6fc1993
F ext/rbu/rbuvacuum4.test a78898e438a44803eb2bc897ba3323373c9f277418e2d6d76e90f2f1dbccfd10
F ext/rbu/sqlite3rbu.c 8741c0ee1496b41ff888b983a1a32547bc8822602603c68b3e524e5e0e287395
F ext/rbu/sqlite3rbu.h 1dc88ab7bd32d0f15890ea08d23476c4198d3da3056985403991f8c9cd389812
F ext/rbu/test_rbu.c 03f6f177096a5f822d68d8e4069ad8907fe572c62ff2d19b141f59742821828a
F ext/repair/README.md 92f5e8aae749a4dae14f02eea8e1bb42d4db2b6ce5e83dbcdd6b1446997e0c15
@@ -372,7 +376,7 @@ F ext/repair/test/checkindex01.test b530f141413b587c9eb78ff734de6bb79bc3515c3350
F ext/repair/test/test.tcl 686d76d888dffd021f64260abf29a55c57b2cedfa7fc69150b42b1d6119aac3c
F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761
F ext/rtree/geopoly.c c591164125808f8bba9659e92665b78412cd263e654b6f05294f3a8da7cdd9fb
F ext/rtree/rtree.c f2ce90120f3e2e01f8a510a227cafbea224c08ba2bf6809b0139c671de2873dc
F ext/rtree/rtree.c 78c0d989c32e5baac471f0463e83cda5006c7e71ded39d633b5fc001a301a26e
F ext/rtree/rtree.h 4a690463901cb5e6127cf05eb8e642f127012fd5003830dbc974eca5802d9412
F ext/rtree/rtree1.test 7573134f1b4f59df36c1b0a6de51268fd3b9c714d91f3811482263e734e416ea
F ext/rtree/rtree2.test 5f25b01acd03470067a2d52783b2eb0a50bf836803d4342d20ca39e541220fe2
@@ -431,7 +435,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 12c958dcd093fca229ca3d3fd833f2f99f1d9c70093dca60f697d5f8e20ebde1
F ext/session/sqlite3session.c 3d9d3a414be386b87d83e642f4d93c8cbe83fe7b975d17b398f96caa1bfdc2cf
F ext/session/sqlite3session.h 919be6649d39d6413ce7a63fc3e3bca3270e18bc2d57ad4040a70007b9e54397
F ext/session/test_session.c 98797aba475a799376c9a42214f2d1debf2d0c3cb657d9c8bbf4f70bf3fb4aec
F ext/userauth/sqlite3userauth.h 7f3ea8c4686db8e40b0a0e7a8e0b00fac13aa7a3
@@ -440,7 +444,7 @@ F ext/userauth/userauth.c f81aa5a3ecacf406f170c62a144405858f6f6de51dbdc0920134e6
F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x
F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8
F magic.txt 8273bf49ba3b0c8559cb2774495390c31fd61c60
F main.mk 23d3660f7053d196aef76938bf78b10fc3ce1831a85d96bd71565758788f34d4
F main.mk 125adda36bb32c99dc3a11340bd029ef373b9523eac2b2af76087bfe82d4fdf8
F mkso.sh fd21c06b063bb16a5d25deea1752c2da6ac3ed83
F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271
F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504
@@ -452,37 +456,37 @@ F spec.template 86a4a43b99ebb3e75e6b9a735d5fd293a24e90ca
F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b
F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786
F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a
F src/alter.c 25f54387121a0c5fd0f49b299f4070c81af8f26a84edaae6de679c4e4b71b1ff
F src/alter.c c1b5e5639b88dcc146db326315f2dea4f7f1c599e524eeb421d544927a0b1e86
F src/analyze.c 58db66344a5c58dcabb57f26696f6f2993956c830446da40b444051d2fdaf644
F src/attach.c 78e986baee90cb7b83fb9eafa79c22581a8ada14030fd633b0683c95cf11213c
F src/auth.c 0fac71038875693a937e506bceb492c5f136dd7b1249fbd4ae70b4e8da14f9df
F src/backup.c 78d3cecfbe28230a3a9a1793e2ead609f469be43e8f486ca996006be551857ab
F src/backup.c b1d37f6f7f5913944583733ed0f9e182f3ece0d42c27f46701142141a6e6fd33
F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33
F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6
F src/btree.c 958939f608e351a36756e3749596472baa0e5aae54eebd14e6beffe7a68aafc7
F src/btree.c 1dbc191e5c1d9bca84a956fed5d73924c574ae5390855009f067bd0f6422e462
F src/btree.h c11446f07ec0e9dc85af8041cb0855c52f5359c8b2a43e47e02a685282504d89
F src/btreeInt.h 6111c15868b90669f79081039d19e7ea8674013f907710baa3c814dc3f8bfd3f
F src/build.c 61655dad911a967a69fb49df57268fd15ce8f1af3fe0a1bd90c128ef2cacfb7a
F src/build.c 23a0253ab53e62feadcc0c6f31e7e418ef9d4b92c82a1398e98433776b920a4e
F src/callback.c 25dda5e1c2334a367b94a64077b1d06b2553369f616261ca6783c48bcb6bda73
F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e
F src/ctime.c 109e58d00f62e8e71ee1eb5944ac18b90171c928ab2e082e058056e1137cc20b
F src/date.c ebe1dc7c8a347117bb02570f1a931c62dd78f4a2b1b516f4837d45b7d6426957
F src/ctime.c 37f3d21193c4f7d141d0691cced5b39c99951bfef78df9887faf9167b9c42f37
F src/date.c e1d8ac7102f3f283e63e13867acb0efa33861cf34f0faf4cdbaf9fa7a1eb7041
F src/dbpage.c 135eb3b5e74f9ef74bde5cec2571192c90c86984fa534c88bf4a055076fa19b7
F src/dbstat.c c12833de69cb655751487d2c5a59607e36be1c58ba1f4bd536609909ad47b319
F src/delete.c d08c9e01a2664afd12edcfa3a9c6578517e8ff8735f35509582693adbe0edeaf
F src/expr.c e100212835d20498780e7c6d2bdb16c677ecc04350fb75db3bf192a86ba48c92
F src/expr.c 2756d2875ac5b7a7efcc54edea3c8a31f4126684ded18da6fb406f4d3780a5f5
F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007
F src/fkey.c bd0138acdc008c1845ccf92f8e73787880562de649471804801c06fed814c765
F src/func.c 2ccf4ae12430b1ae7096be5f0675887e1bd0732828af0ac0f7496339b7c6edee
F src/global.c 0dea3065ea72a65ae941559b6686aad6516d4913e76fa4f79a95ff7787f624ec
F src/fkey.c 0e14d4bef8eac2d87bbd517e492d9084c65008d117823f8922c5e7b2b599bd33
F src/func.c 905c0424900979fade3731b4a271592059425c988cb7d5b245032253712dd7c8
F src/global.c 1e942b1e6fb6a2a15e6015bda72be0abefc4b1339a8640a47b1b71b7f317917b
F src/hash.c 8d7dda241d0ebdafb6ffdeda3149a412d7df75102cecfc1021c98d6219823b19
F src/hash.h 9d56a9079d523b648774c1784b74b89bd93fac7b365210157482e4319a468f38
F src/hwtime.h 747c1bbe9df21a92e9c50f3bbec1de841dc5e5da
F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71
F src/insert.c fc3cf5c371f9a400144e8c2f148ab29cd3f67f7da7eaf47e6a6959f8255fd92c
F src/insert.c f20925c2c08144442dabeb73dcd0f5026f5f085d827f3d5635f7c45e5d195320
F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa
F src/loadext.c 22afc33c3a61b4fd80a60a54f1882688371e6bc64685df2696b008fce65a999c
F src/main.c 16eea1ab004331312da0538dafb497cc0ed82fd9bb2e67f7684b40bf2797b666
F src/main.c 591a0084b1a6b0ed6741f77181bd1a630ca10bb460420f00e8c11809da7df5b9
F src/malloc.c 0f9da2a66b230a5785af94b9672126845099b57b70a32c987d04ac28c69da990
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
F src/mem1.c c12a42539b1ba105e3707d0e628ad70e611040d8f5e38cf942cee30c867083de
@@ -491,7 +495,7 @@ F src/mem3.c 8768ac94694f31ffaf8b4d0ea5dc08af7010a35a
F src/mem5.c 9bf955937b07f8c32541c8a9991f33ce3173d944
F src/memdb.c 02a5fcec19b9d40dd449ca802dc1b2e8f93f255fbf2a886277a3c3800d8d35db
F src/memjournal.c 6f3d36a0a8f72f48f6c3c722f04301ac64f2515435fa42924293e46fc7994661
F src/msvc.h 4942752b6a253116baaa8de75256c51a459a5e81
F src/msvc.h 3a15918220367a8876be3fa4f2abe423a861491e84b864fb2b7426bf022a28f8
F src/mutex.c bae36f8af32c22ad80bbf0ccebec63c252b6a2b86e4d3e42672ff287ebf4a604
F src/mutex.h 779d588e3b7756ec3ecf7d78cde1d84aba414f85
F src/mutex_noop.c 9d4309c075ba9cc7249e19412d3d62f7f94839c4
@@ -507,28 +511,28 @@ F src/os_win.c 85d9e532d0444ab6c16d7431490c2e279e282aa0917b0e988996b1ae0de5c5a0
F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a
F src/pager.c 422fd8cfa59fb9173eff36a95878904a0eeb0dcc62ba49350acc8b1e51c4dc7b
F src/pager.h 217921e81eb5fe455caa5cda96061959706bcdd29ddb57166198645ef7822ac3
F src/parse.y 8de9b1da4dc0f9615cfa9f4cbdd368b4ac822e1cbbc57b0fe071d9a83988df6d
F src/pcache.c 696a01f1a6370c1b50a09c15972bc3bee3333f8fcd1f2da8e9a76b1b062c59ee
F src/parse.y 026e3e6fff32432166a4eae0bdb78ad09a53c84eb49acb44dc32e49b4c0b8a48
F src/pcache.c fd2d0553b3222d6b9f7cb251079e5bca1299d1161da3027b525932d8bf46340a
F src/pcache.h 4f87acd914cef5016fae3030343540d75f5b85a1877eed1a2a19b9f284248586
F src/pcache1.c be64b2f3908a7f97c56c963676eb12f0d6254c95b28cdc1d73a186eff213219d
F src/pragma.c af67dedaad8bafe9a5f9adcec32a0da6dd118617dd8220ad1d118f5a6bf83a02
F src/pragma.h a776bb9c915207e9d1117b5754743ddf1bf6a39cc092a4a44e74e6cb5fab1177
F src/pcache1.c e6373934cdafea272d94feb224344f9fd93ff94318221b64ccabd72d98b4672e
F src/pragma.c 925bcac0afd98a0d4255c7524b93239ab4d83893d96f7f8fdccd78d4929a39bb
F src/pragma.h 4a9fabff14db4487a734dfeeb4be984ce662bfdccfae16145b9c732327735e13
F src/prepare.c 78027c6231fbb19ca186a5f5f0c0a1375d9c2cec0655273f9bd90d9ff74a34b3
F src/printf.c 67f79227273a9009d86a017619717c3f554f50b371294526da59faa6014ed2cd
F src/printf.c 9be6945837c839ba57837b4bc3af349eba630920fa5532aa518816defe42a7d4
F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384
F src/resolve.c 567888ee3faec14dae06519b4306201771058364a37560186a3e0e755ebc4cb8
F src/resolve.c 93b7bc7c45efa6322d92293361c51a873690daed50cf77eeff88a448246b0d5a
F src/rowset.c d977b011993aaea002cab3e0bb2ce50cf346000dff94e944d547b989f4b1fe93
F src/select.c 9263f5c30dd44c7ac2eb29f40a7ec64322a96885b71c00de6bc30b756c2e1c49
F src/shell.c.in c1986496062f9dba4ed5b70db06b5e0f32e1954cdcfab0b30372c6c186796810
F src/sqlite.h.in 38390767acc1914d58930e03149595ee4710afa4e3c43ab6c3a8aea3f1a6b8cd
F src/select.c 62f21307b280791c50554c9fa3766758dd695ed66a05d2408d213355c7b0aa89
F src/shell.c.in 82f8a473c01662f52233c6c75b9bf88d0d2cab276086d5d4ca6f2ff57a3e48eb
F src/sqlite.h.in 83ebc8ab1a2e82d92214006ea2c15bf8a0604f3fac2c31dd9ce9021f568c71f2
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
F src/sqlite3ext.h 9ecc93b8493bd20c0c07d52e2ac0ed8bab9b549c7f7955b59869597b650dd8b5
F src/sqliteInt.h d229b6a5f70fe6c57d2f91f0edc60a9c4437397b4a5b59fd72fe9eb3b94d3437
F src/sqliteInt.h bf65dfa6565fae2e0d501088fc9c5212244adc1429a543827a16b2f5eaf41982
F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b
F src/status.c 46e7aec11f79dad50965a5ca5fa9de009f7d6bde08be2156f1538a0a296d4d0e
F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34
F src/tclsqlite.c cfe7f93daf9d8787f65e099efb67d7cdfc2c35236dec5d3f6758520bd3519424
F src/test1.c 0dc98af0769302672dcefd07a6128ee14e837b9f6e338a1aaca7ac31e4d8d2f8
F src/test1.c f57c229ad7878215d0b3bb5d59ffe94772c099ce5b5e147a4a59d3157923a988
F src/test2.c 3efb99ab7f1fc8d154933e02ae1378bac9637da5
F src/test3.c 61798bb0d38b915067a8c8e03f5a534b431181f802659a6616f9b4ff7d872644
F src/test4.c 405834f6a93ec395cc4c9bb8ecebf7c3d8079e7ca16ae65e82d01afd229694bb
@@ -545,8 +549,8 @@ F src/test_blob.c ae4a0620b478548afb67963095a7417cd06a4ec0a56adb453542203bfdcb31
F src/test_btree.c 8b2dc8b8848cf3a4db93f11578f075e82252a274
F src/test_config.c 5ebafbcd5c75ac1c16bb0c8fe926dc325cc03e780943a88ca50e0d9a4fc4d2f5
F src/test_delete.c e2fe07646dff6300b48d49b2fee2fe192ed389e834dd635e3b3bac0ce0bf9f8f
F src/test_demovfs.c a0c3bdd45ed044115c2c9f7779e56eafff18741e
F src/test_devsym.c 1960abbb234b97e9b920f07e99503fc04b443f62bbc3c6ff2c2cea2133e3b8a2
F src/test_demovfs.c 86142ba864d4297d54c5b2e972e74f3141ae4b30f05b3a95824184ed2d3d7f91
F src/test_devsym.c 6109b45c3db3ef7b002320947ed448c027356ab8b885156ff535fd8684d4a571
F src/test_fs.c ba1e1dc18fd3159fdba0b9c4256f14032159785320dfbd6776eb9973cb75d480
F src/test_func.c 181f992e5495644434c4f0e3cc72362a78c295eb2cf3ff4d02498b8bde7aa276
F src/test_hexio.c 1d4469ca61ab202a1fcec6543f584d2407205e8d
@@ -575,7 +579,7 @@ F src/test_tclsh.c eeafce33ad2136d57e5dec10f1e9a4347447eb72ffd504a1c7b9c6bfe2e71
F src/test_tclvar.c 33ff42149494a39c5fbb0df3d25d6fafb2f668888e41c0688d07273dcb268dfc
F src/test_thread.c 911d15fb14e19c0c542bdc8aabf981c2f10a4858
F src/test_vdbecov.c f60c6f135ec42c0de013a1d5136777aa328a776d33277f92abac648930453d43
F src/test_vfs.c 0868f1d4d7cdc7c6df60e895ca26b19e4f433dd1be0fc9c18c3ee63755804039
F src/test_vfs.c 32618cbd953963278804bb47e97be7085d9e0d8755b1e734c3e54e9b9e115277
F src/test_vfstrace.c bab9594adc976cbe696ff3970728830b4c5ed698
F src/test_windirent.c a895e2c068a06644eef91a7f0a32182445a893b9a0f33d0cdb4283dca2486ac1
F src/test_windirent.h 90dfbe95442c9762357fe128dc7ae3dc199d006de93eb33ba3972e0a90484215
@@ -583,32 +587,32 @@ F src/test_window.c cdae419fdcea5bad6dcd9368c685abdad6deb59e9fc8b84b153de513d394
F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9
F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c
F src/tokenize.c d3615f0cbe4db5949503bf5916f3cd4fa5de855d5b4ef560f3b6dd5629423a1e
F src/treeview.c 56724725c62a0d0f408f7c257475dc33309198afee36a1d18be1bc268b09055e
F src/treeview.c cf03f9f6efb93288c7b9f17374ea48e4ce9111b0bc7e428d6850c3eee532b461
F src/trigger.c bb034c08eca111e66a19cda045903a12547c1be2294b5570d794b869d9c44a73
F src/update.c 0b973357d88092140531e07ff641139c26fb4380b0b9f5ed98c5f7691b4604d1
F src/update.c 3cb9150d2cf661d938e2f1b1749945f3faa767f88febdb739ab1793bbf895ff2
F src/upsert.c 0dd81b40206841814d46942a7337786932475f085716042d0cb2fc7791bf8ca4
F src/utf.c 2f0fac345c7660d5c5bd3df9e9d8d33d4c27f366bcfb09e07443064d751a0507
F src/util.c e12939405e77906d06ab0b78c5f513dcd2b7cec2fbb553877b0abfece6067141
F src/vacuum.c 72690ccb6877a88f8473a893cf9f6d7592236f3eebfebfa840b19c708acde574
F src/vdbe.c 711ef421b3bb3db3b2476067b2dc3c71ef5844d9b1a723026578f89f6da621e8
F src/util.c aef606a78b85d042138a841babbc0f98471b19b9a340b962e8fae307bc8cf3da
F src/vacuum.c 82dcec9e7b1afa980288718ad11bc499651c722d7b9f32933c4d694d91cb6ebf
F src/vdbe.c aaa36d1ac7d55baf007e9c03ee7c826834a51dfe7a56ba4c386318695dd87c99
F src/vdbe.h 712bca562eaed1c25506b9faf9680bdc75fc42e2f4a1cd518d883fa79c7a4237
F src/vdbeInt.h 2c12704db9740c8e899786ecfc7a5797a9d067563496eb1b6ed03c592d7b8d90
F src/vdbeapi.c 2ddd60f4a351f15ee98d841e346af16111ad59dfa4d25d2dd4012e9875bf7d92
F src/vdbeaux.c f873b5c2efcf8a4d6ecfc5b1a5b06fd810419198f3bd882175d371cc03801873
F src/vdbeInt.h 3ba14553508d66f58753952d6dd287dce4ec735de02c6440858b4891aed51c17
F src/vdbeapi.c f9161e5c77f512fbb80091ce8af621d19c9556bda5e734cffaac1198407400da
F src/vdbeaux.c 3a803d75875031309204df90977059b12ffb706d16b4baa5e2d99f4353962582
F src/vdbeblob.c f5c70f973ea3a9e915d1693278a5f890dc78594300cf4d54e64f2b0917c94191
F src/vdbemem.c 8e6889761e344babdb8a56dd1ac8911501fa648396544d1644f1cd6a87c80dc0
F src/vdbemem.c f6f277d17d50972571d1394535d4c3d156fdea871d8f327f5b9479984054015a
F src/vdbesort.c 66592d478dbb46f19aed0b42222325eadb84deb40a90eebe25c6e7c1d8468f47
F src/vdbetrace.c 79d6dbbc479267b255a7de8080eee6e729928a0ef93ed9b0bfa5618875b48392
F src/vtab.c 4c5959e00b7a142198d178e3a822f4e05f36f2d1a3c57657373f9487154fc06b
F src/vdbetrace.c fa3bf238002f0bbbdfb66cc8afb0cea284ff9f148d6439bc1f6f2b4c3b7143f0
F src/vtab.c 1fa256c6ddad7a81e2a4dc080d015d4b0a7135767717d311298e47f6fca64bb3
F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9
F src/wal.c 9eccc7ebb532a7b0fd3cabc16cff576b9afa763472272db67d84fb8cec96f5c0
F src/wal.c b09a2a9cab50efa08451a8c81d47052120ad5da174048c6d0b08d405384abdf2
F src/wal.h 606292549f5a7be50b6227bd685fa76e3a4affad71bb8ac5ce4cb5c79f6a176a
F src/walker.c 7607f1a68130c028255d8d56094ea602fc402c79e1e35a46e6282849d90d5fe4
F src/where.c ff2955dc2743c1af05ba5a8232ab72724d9a63b76dbee256368f40fd3ef82db5
F src/whereInt.h 5f14db426ca46a83eabab1ae9aa6d4b8f27504ad35b64c290916289b1ddb2e88
F src/wherecode.c 83be72e8d1c0231d0db06ffe5cfd32c7834bd00d2ed869306a2c1e0828488752
F src/whereexpr.c 90859652920f153d2c03f075488744be2926625ebd36911bcbcb17d0d29c891c
F src/window.c 038c248267e74ff70a2bb9b1884d40fd145c5183b017823ecb6cbb14bc781478
F src/where.c 2f11eeb14335b7640f886b2fb441f54a94c35ab5cde8b53461a1074bfd587081
F src/whereInt.h 1b728f71654ebf8421a1715497a587f02d6f538e819af58dc826908f8577e810
F src/wherecode.c 37a1004237d630d785c47bba2290eac652a7a8b0047518eba3cb7c808b604c4a
F src/whereexpr.c 5e559bdd24b06e3bc2e68f258bf751302954dc1e432daf71fdd8098a71462326
F src/window.c 3408c0f606574d41033d461506bad68790239844b23e70610738a71152873d05
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd
F test/affinity3.test 6a101af2fc945ce2912f6fe54dd646018551710d
@@ -626,9 +630,9 @@ F test/altercol.test 54374d2ba18af25bb24e23acf18a60270d4ec120b7ec0558078b59d5aa1
F test/alterlegacy.test 82022721ce0de29cedc9a7af63bc9fcc078b0ee000f8283b4b6ea9c3eab2f44b
F test/altermalloc.test 167a47de41b5c638f5f5c6efb59784002b196fff70f98d9b4ed3cd74a3fb80c9
F test/altermalloc2.test fa7b1c1139ea39b8dec407cf1feb032ca8e0076bd429574969b619175ad0174b
F test/altertab.test 6e13f13d8c30708f16187908c31dadb1bfff9e3cb2a07a7392a7a5e076f58f4a
F test/altertab2.test 5d423a2d1006085b05cc1b788863d5a860ea2da21c4f892d15e2f2a34c78348a
F test/altertab3.test 40f2ce9be675e354d3e55c72f8baf38813be975ff4dd9e6b3144493c3c5bc033
F test/altertab.test b6901287474841cffbd8f90b098d3bd7d8445868b42caeb01b27034698f7245f
F test/altertab2.test 8883693952f6d7fb5f754dbf1d694ed780aa883027bef04cb1fb99a3b88c9272
F test/altertab3.test 7a2419829b2b908985b2c83d680388ef2eb9a74e446b68cee7b9b1551ae69078
F test/amatch1.test b5ae7065f042b7f4c1c922933f4700add50cdb9f
F test/analyze.test 7168c8bffa5d5cbc53c05b7e9c7fcdd24b365a1bc5046ce80c45efa3c02e6b7c
F test/analyze3.test ff62d9029e6deb2c914490c6b00caf7fae47cc85cdc046e4a0d0a4d4b87c71d8
@@ -668,7 +672,7 @@ F test/autoindex1.test 96185415f5faacd5b8d7a7f505efddd5abb1f111d58338e9c0b1dc40b
F test/autoindex2.test 12ef578928102baaa0dc23ad397601a2f4ecb0df
F test/autoindex3.test 2dd997d6590438b53e4f715f9278aa91c9299cf3f81246a0915269c35beb790e
F test/autoindex4.test 49d3cd791a9baa16fb461d7ea3de80d019a819cf
F test/autoindex5.test 1d8c1134e1488a35c6fa205b2f52e72fc220972d946c59492d10bba01d6fecd4
F test/autoindex5.test a5d72fe8c217cc0ea356dc6fa06a282a8a3fc53aa807709d79dba07a8f248102
F test/autovacuum.test 0831cd34e14695d297187f7f6519265e3121c5b0a1720e548e86829e796129e9
F test/autovacuum_ioerr2.test 8a367b224183ad801e0e24dcb7d1501f45f244b4
F test/avtrans.test b7dc25459ecbd86c6fa9c606ee3068f59d81e225118617dcf2bbb6ded2ade89e
@@ -688,7 +692,7 @@ F test/bestindex3.test 7622e792ff2da16d262d3cea6ad914591ac4806d57ed128e6c940b792
F test/bestindex4.test 038e3d0789332f3f1d61474f9bbc9c6d08c6bd1783a978f31f38ad82688de601
F test/bestindex5.test 67c1166131bb59f9e47c00118f7d432ca5491e6cae6ca3f87ca9db20103a78f9
F test/bestindex6.test d856a9bb63d927493575823eed44053bc36251e241aa364e54d0f2a2d302e1d4
F test/between.test 34d375fb5ce1ae283ffe82b6b233e9f38e84fc6c
F test/between.test 68137a6e941c221417c15b6fe2d55f27bb1b6ab48bdf9e2aa51efdd85bc53802
F test/bigfile.test aa74f4e5db51c8e54a1d9de9fa65d01d1eb20b59
F test/bigfile2.test 1b489a3a39ae90c7f027b79110d6b4e1dbc71bfc
F test/bigmmap.test 31dad31573638bd32de866cdefd11843f75685be4ba6aec1a47918f098f1899b
@@ -719,13 +723,14 @@ F test/capi3b.test efb2b9cfd127efa84433cd7a2d72ce0454ae0dc4
F test/capi3c.test 54e2dc0c8fd7c34ad1590d1be6864397da2438c95a9f5aee2f8fbc60c112e44b
F test/capi3d.test aba917805573a03deed961a21f07a5a84505ad0a616f7e3fc1508844a15bccc4
F test/capi3e.test 3d49c01ef2a1a55f41d73cba2b23b5059ec460fe
F test/cast.test 5ceb920718d280b61163500a7d29e0e0a86458b1cbd92d96f962c9d970aa3857
F test/cast.test 3619f0c58c2e4b2a94aa86e75607e497d34ef40ab74418e71aef7b4ca5155895
F test/cffault.test 9d6b20606afe712374952eec4f8fd74b1a8097ef
F test/check.test 33a698e8c63613449d85d624a38ef669bf20331daabebe3891c9405dd6df463a
F test/check.test dcc952a127c394ce0de2aa634d26c78207e855327cc63a24d3638ca8fbfa641e
F test/chunksize.test 427d87791743486cbf0c3b8c625002f3255cb3a89c6eba655a98923b1387b760
F test/close.test 799ea4599d2f5704b0a30f477d17c2c760d8523fa5d0c8be4a7df2a8cad787d8
F test/closure01.test 9905883f1b171a4638f98fc764879f154e214a306d3d8daf412a15e7f3a9b1e0
F test/coalesce.test cee0dccb9fbd2d494b77234bccf9dc6c6786eb91
F test/collate1.test 08c18e7512a5a32c97938854263fa15362eeb846
F test/collate1.test f9b653f515ef3324a0c4e3c6adbf136bb1903622af678d482a60c11c9c054e6c
F test/collate2.test 9aaa410a00734e48bcb27f3872617d6f69b2a621
F test/collate3.test 89defc49983ddfbf0a0555aca8c0521a676f56a5
F test/collate4.test c953715fb498b87163e3e73dd94356bff1f317bd
@@ -762,10 +767,10 @@ F test/corruptH.test 79801d97ec5c2f9f3c87739aa1ec2eb786f96454
F test/corruptI.test a17bbf54fdde78d43cf3cc34b0057719fd4a173a3d824285b67dc5257c064c7b
F test/corruptJ.test 4d5ccc4bf959464229a836d60142831ef76a5aa4
F test/corruptK.test 5b4212fe346699831c5ad559a62c54e11c0611bdde1ea8423a091f9c01aa32af
F test/corruptL.test a569f3cece872a1f21568bd5378f55ce5c365c50845a06fae65a2721cce62264
F test/corruptL.test 15882a75d06de29df9ad33a3503eb0fe21efbd1afcd676949c0d82e1f4e55360
F test/cost.test 51f4fcaae6e78ad5a57096831259ed6c760e2ac6876836e91c00030fad385b34
F test/count.test cb2e0f934c6eb33670044520748d2ecccd46259c
F test/countofview.test e3d4cd6900e4e4f074968ab24b8b87d3671cd624961bef40fd3a6b8f574343cf
F test/countofview.test e17d6e6688cf74f22783c9ec6e788c0790ee4fbbaee713affd00b1ac0bb39b86
F test/coveridxscan.test 5ec98719a2e2914e8908dc75f7247d9b54a26df04625f846ac7900d5483f7296
F test/crash.test fb9dc4a02dcba30d4aa5c2c226f98b220b2b959f
F test/crash2.test 5b14d4eb58b880e231361d3b609b216acda86651
@@ -786,10 +791,11 @@ F test/cursorhint2.test 6f3aa9cb19e7418967a10ec6905209bcbb5968054da855fc36c8beee
F test/dataversion1.test 6e5e86ac681f0782e766ebcb56c019ae001522d114e0e111e5ebf68ccf2a7bb8
F test/date.test 9b73bbeb1b82d9c1f44dec5cf563bf7da58d2373
F test/date2.test 74c234bece1b016e94dd4ef9c8cc7a199a8806c0e2291cab7ba64bace6350b10
F test/dbdata.test 042f49acff3438f940eeba5868d3af080ae64ddf26ae78f80c92bec3ca7d8603
F test/dbfuzz.c 73047c920d6210e5912c87cdffd9a1c281d4252e
F test/dbfuzz001.test e32d14465f1c77712896fda6a1ccc0f037b481c191c1696a9c44f6c9e4964faf
F test/dbfuzz2-seed1.db e6225c6f3d7b63f9c5b6867146a5f329d997ab105bee64644dc2b3a2f2aebaee
F test/dbfuzz2.c 6c355cf70c4a308b1b84a11a65282bcac5b4038db77de5cfc8ad080ef371f109
F test/dbfuzz2.c b93db9056ad057733463ba333f89d2d195a95155805065c5962422955d7fb011
F test/dbpage.test 650234ba683b9d82b899c6c51439819787e7609f17a0cc40e0080a7b6443bc38
F test/dbstatus.test cd83aa623b8aab477269bc94cf8aa90c1e195a144561dd04a1620770aaa8524e
F test/dbstatus2.test f5fe0afed3fa45e57cfa70d1147606c20d2ba23feac78e9a172f2fe8ab5b78ef
@@ -815,7 +821,7 @@ F test/e_createtable.test 1c602347e73ab80b11b9fa083f47155861aaafcff8054aac9e0b76
F test/e_delete.test ab39084f26ae1f033c940b70ebdbbd523dc4962e
F test/e_droptrigger.test 3cd080807622c13e5bbb61fc9a57bd7754da2412
F test/e_dropview.test 21ce09c361227ddbc9819a5608ee2700c276bdd5
F test/e_expr.test ca8896601ade1e27c6559614c7f32c63d44636fdfa720436a160f09b8bf66c89
F test/e_expr.test e6048fe3901241799c4315bdd625f39dae790ff089c454979ca85f03b644dc6f
F test/e_fkey.test 2febb2084aef9b0186782421c07bc9d377abf067c9cb4efd49d9647ae31f5afe
F test/e_fts3.test 17ba7c373aba4d4f5696ba147ee23fd1a1ef70782af050e03e262ca187c5ee07
F test/e_insert.test f02f7f17852b2163732c6611d193f84fc67bc641fb4882c77a464076e5eba80e
@@ -844,6 +850,7 @@ F test/exclusive2.test 984090e8e9d1b331d2e8111daf6e5d61dda0bef7
F test/exec.test e949714dc127eaa5ecc7d723efec1ec27118fdd7
F test/exists.test 79a75323c78f02bbe9c251ea502a092f9ef63dac
F test/expr.test 7cb55e80aeb41d65fec968c08212505123063fea60bdc355d764d747670e9eea
F test/expr2.test c27327ae9c017a7ff6280123f67aff496f912da74d78c888926d68b46ec75fd8
F test/extension01.test 00d13cec817f331a687a243e0e5a2d87b0e358c9
F test/extraquick.test cb254400bd42bfb777ff675356aabf3287978f79
F test/fallocate.test 37a62e396a68eeede8f8d2ecf23573a80faceb630788d314d0a073d862616717
@@ -855,8 +862,8 @@ F test/fkey3.test 76d475c80b84ee7a5d062e56ccb6ea68882e2b49
F test/fkey4.test 86446017011273aad8f9a99c1a65019e7bd9ca9d
F test/fkey5.test 24dd28eb3d9f1b5a174f47e9899ace5facb08373a4223593c8c631e6cf9f7d5a
F test/fkey6.test d078a1e323a740062bed38df32b8a736fd320dc0
F test/fkey7.test 24076d43d3449f12f25503909ca4bfb5fc5fefd5af1f930723a496343eb28454
F test/fkey8.test 863c6d84f0d289fd2c1a1c293abb9803f77efd35211d9012c0986c8f6ccf5d5a
F test/fkey7.test 64fb28da03da5dfe3cdef5967aa7e832c2507bf7fb8f0780cacbca1f2338d031
F test/fkey8.test 1d44df25d3b9cba72db4b4324201daf6ae1fc8a85cb68146bd6669a977d8867d
F test/fkey_malloc.test 594a7ea1fbab553c036c70813cd8bd9407d63749
F test/fordelete.test eb93a2f34137bb87bdab88fcab06c0bd92719aff
F test/format4.test 1f0cac8ff3895e9359ed87e41aaabee982a812eb
@@ -923,7 +930,8 @@ F test/fts3conf.test c84bbaec81281c1788aa545ac6e78a6bd6cde2bdbbce2da261690e3659f
F test/fts3corrupt.test 46b9ddda7f6588fd5a5b1f4bb4fc0618dc45010e7dddb8a3a188baf3197177ae
F test/fts3corrupt2.test bf55c3fa0b0dc8ea1c0fe5543623bd27714585da6a129038fd6999fe3b0d25f3
F test/fts3corrupt3.test 0d5b69a0998b4adf868cc301fc78f3d0707745f1d984ce044c205cdb764b491f
F test/fts3corrupt4.test af68ede153cbeff7309f7da2f9d8fd12a01f7e1debb03eb748c302079ac5ae05
F test/fts3corrupt4.test c311911898e9ddac93fe71b947660a9716b285e2e600ad02810c231ff79a5925
F test/fts3corrupt5.test 1911bd38381fe7eb28b204e7171937d09e113e5ceb018399ded9f42ec7e6ae66
F test/fts3cov.test cb932743da52a1c79a1ab8983e26c8121cf02263d6ff16e1f642e6f9b8348338
F test/fts3d.test 2bd8c97bcb9975f2334147173b4872505b6a41359a4f9068960a36afe07a679f
F test/fts3defer.test f4c20e4c7153d20a98ee49ee5f3faef624fefc9a067f8d8d629db380c4d9f1de
@@ -973,12 +981,13 @@ F test/fts4merge4.test d895b1057a7798b67e03455d0fa50e9ea836c47b
F test/fts4noti.test 5553d7bb2e20bf4a06b23e849352efc022ce6309
F test/fts4onepass.test d69ddc4ee3415e40b0c5d1d0408488a87614d4f63ba9c44f3e52db541d6b7cc7
F test/fts4opt.test 0fd0cc84000743ff2a883b9b84b4a5be07249f0ba790c8848a757164cdd46b2a
F test/fts4rename.test 6015a355ec3a11a51eb5b88802b3b2c1788786c54b77b17f3e077b7c93ff8611
F test/fts4umlaut.test fcaca4471de7e78c9d1f7e8976e3e8704d7d8ad979d57a739d00f3f757380429
F test/fts4unicode.test ceca76422abc251818cb25dabe33d3c3970da5f7c90e1540f190824e6b3a7c95
F test/full.test 6b3c8fb43c6beab6b95438c1675374b95fab245d
F test/func.test 150270b6e2e0281697c116e5ca0e46b41ace8d34b1c92461d88fdd9968c9b03c
F test/func.test e4313baba80bf933e58eb89a7c617bec0f0c348c862b096ec4387f36e05ad0a6
F test/func2.test 772d66227e4e6684b86053302e2d74a2500e1e0f
F test/func3.test d202a7606d23f90988a664e88e268aed1087c11c
F test/func3.test 2bb0f31ab7baaed690b962a88544d7be6b34fa389364bc36a44e441ed3e3f1e6
F test/func4.test 6beacdfcb0e18c358e6c2dcacf1b65d1fa80955f
F test/func5.test cdd224400bc3e48d891827cc913a57051a426fa4
F test/func6.test 90e42b64c4f9fb6f04f44cb8a1da586c8542502e926b19c76504fe74ff2a9b7c
@@ -996,8 +1005,8 @@ F test/fuzzdata3.db c6586d3e3cef0fbc18108f9bb649aa77bfc38aba
F test/fuzzdata4.db b502c7d5498261715812dd8b3c2005bad08b3a26e6489414bd13926cd3e42ed2
F test/fuzzdata5.db e35f64af17ec48926481cfaf3b3855e436bd40d1cfe2d59a9474cb4b748a52a5
F test/fuzzdata6.db 92a80e4afc172c24f662a10a612d188fb272de4a9bd19e017927c95f737de6d7
F test/fuzzdata7.db f46c9a5698c1ca75ca6280c7c879a3f46dc82fe4b1ce246827496b806488952d
F test/fuzzdata8.db 5f12b6a8579e89616da9bd6dede1f38748eb04a1265f0b89117274f44d76b227
F test/fuzzdata7.db babb1c560fef766171972c119c1bc3b7be20b134e2f46ae0c52390cd3059b6f4
F test/fuzzdata8.db c69ca6d4bf1b25fd56ab432e9b96f2db0da752cfc6aa32700867f3a2d8a0514a
F test/fuzzer1.test 3d4c4b7e547aba5e5511a2991e3e3d07166cfbb8
F test/fuzzer2.test a85ef814ce071293bce1ad8dffa217cbbaad4c14
F test/fuzzerfault.test 8792cd77fd5bce765b05d0c8e01b9edcf8af8536
@@ -1011,7 +1020,7 @@ F test/hook2.test b9ff3b8c6519fb67f33192f1afe86e7782ee4ac8
F test/icu.test 41aa8847745a879b897a7febea0f8f9efc8e67fe8bf680589b6e07c7b0a1569a
F test/ieee754.test 806fc0ce7f305f57e3331eaceeddcfec9339e607
F test/imposter1.test c3f1db2d3db2c24611a6596a3fc0ffc14f1466c8
F test/in.test 4b985774a64f143f486418cec53379bed3aeb0503179353cc7c7ce15fb464349
F test/in.test 63e642e97bc22c8fd970752fb4f0b3992a957003ea87524fe69e5a700500c500
F test/in2.test 5d4c61d17493c832f7d2d32bef785119e87bde75
F test/in3.test 3cbf58c87f4052cee3a58b37b6389777505aa0c0
F test/in4.test d2b38cba404bc4320f4fe1b595b3d163f212c068
@@ -1028,18 +1037,18 @@ F test/incrvacuum.test 2aaee202b1f230e55779f70d155f6ba67bbdff8481d650214d256ab0f
F test/incrvacuum2.test 7d26cfda66c7e55898d196de54ac4ec7d86a4e3d
F test/incrvacuum3.test 75256fb1377e7c39ef2de62bfc42bbff67be295a
F test/incrvacuum_ioerr.test 6ae2f783424e47a0033304808fe27789cf93e635
F test/index.test df4cddf4435314a948237fdfa9acee67de21f7bebc789beab4b89b575b4f6a70
F test/index.test a2e948ed949e575487b5c1d521767d4584ac42d352f2dcd8e48004638e7bc7dc
F test/index2.test f835d5e13ca163bd78c4459ca15fd2e4ed487407
F test/index3.test 51685f39345462b84fcf77eb8537af847fdf438cc96b05c45d6aaca4e473ade0
F test/index4.test ab92e736d5946840236cd61ac3191f91a7856bf6
F test/index5.test 8621491915800ec274609e42e02a97d67e9b13e7
F test/index6.test 6b3e6cd4bef343ed4541e74c55936ed112962a6552c085242612b598e12910a4
F test/index7.test 72b59b8ddc5c13f4962886b4011eb9975014317d17ef36c6297921362fb7dd98
F test/index6.test a6cf96bb70bf57b2221e102060a18af46bc366f704722f410d6f42c13a75534a
F test/index7.test 2222ccd1858097f734d6ac3d39117334fd1cc26460f92fced4ef57cd15c940c1
F test/index8.test bc2e3db70e8e62459aaa1bd7e4a9b39664f8f9d7
F test/index9.test 0aa3e509dddf81f93380396e40e9bb386904c1054924ba8fa9bcdfe85a8e7721
F test/indexedby.test a52c8c6abfae4fbfb51d99440de4ca1840dbacc606b05e29328a2a8ba7cd914e
F test/indexexpr1.test 635261197bcdc19b9b2c59bbfa7227d525c00e9587faddb2d293c44d287ce60e
F test/indexexpr2.test 38020c247ee77ba19322fadde99db84bdf2aef34f714866786563c3834bb2dce
F test/indexexpr2.test d319e7d1b1043403f39a20c892d512e02b5549c6004806b977030f2430c60208
F test/indexfault.test 98d78a8ff1f5335628b62f886a1cb7c7dac1ef6d48fa39c51ec871c87dce9811
F test/init.test 15c823093fdabbf7b531fe22cf037134d09587a7
F test/insert.test 9773604f8e1a2595f51488a5643c359d8a11dc55a11cb185910d93387d378458
@@ -1054,6 +1063,7 @@ F test/intarray.test 8319986182af37c8eb4879c6bfe9cf0074e9d43b193a4c728a0efa3417c
F test/interrupt.test 16ea879ec728cb76414c148c5f24afd5d1f91054
F test/interrupt2.test e4408ca770a6feafbadb0801e54a0dcd1a8d108d
F test/intpkey.test ac71107a49a06492b69b82aafaf225400598d3c8
F test/intreal.test 2c80b5c90c597e65c6606b333515261c73a534b6c527b7009e97ed6b78f8b79a
F test/io.test f95bca1783b01ea7761671560d023360d2dfa4cc
F test/ioerr.test 470fcc78e9cd352d162baf782fe301ea807d764241f58a48fc58109c2dfcdb6b
F test/ioerr2.test 2593563599e2cc6b6b4fcf5878b177bdd5d8df26
@@ -1061,31 +1071,31 @@ F test/ioerr3.test d3cec5e1a11ad6d27527d0d38573fbff14c71bdd
F test/ioerr4.test f130fe9e71008577b342b8874d52984bd04ede2c
F test/ioerr5.test 2edfa4fb0f896f733071303b42224df8bedd9da4
F test/ioerr6.test a395a6ab144b26a9e3e21059a1ab6a7149cca65b
F test/istrue.test 62372ad3ddcc5d0eb8ff9097dcb0aad8961bf1b9cb45ba634f6e284695126f9a
F test/istrue.test 75327829744e65cc8700e69340b8e6c192e10e39dfae7ccb0e970d3c4f49090a
F test/join.test d53a3662762eff50b65da8775201e609878a27dd0885a1ae7bcde9bb46cecbc5
F test/join2.test 10f7047e723ebd68b2f47189be8eed20451a6f665d8bf46f1774c640d1062417
F test/join3.test 6f0c774ff1ba0489e6c88a3e77b9d3528fb4fda0
F test/join4.test 1a352e4e267114444c29266ce79e941af5885916
F test/join5.test f8b5ffdf3c1513486b52ad4e49225507ecee5005f210eb18688f791d25370972
F test/join5.test 3a96dc62f0b45402d7207e22d1993fe0c2fce1c57644a11439891dd62b990eb7
F test/join6.test cfe6503791ceb0cbb509966740286ec423cbf10b
F test/journal1.test c7b768041b7f494471531e17abc2f4f5ebf9e5096984f43ed17c4eb80ba34497
F test/journal2.test 9dac6b4ba0ca79c3b21446bbae993a462c2397c4
F test/journal3.test 939a3578396dffa0cdaa9b2685088c5a1a644db90d61aca08bd7e19d33932c00
F test/jrnlmode.test a6693f2bed4541a21e703aaa37bb3e10de154130645952933b82b2dec0a8b539
F test/jrnlmode.test 9b5bc01dac22223cb60ec2d5f97acf568d73820794386de5634dcadbea9e1946
F test/jrnlmode2.test 8759a1d4657c064637f8b079592651530db738419e1d649c6df7048cd724363d
F test/jrnlmode3.test 556b447a05be0e0963f4311e95ab1632b11c9eaa
F test/json101.test 8f8977b00ba02f9a26c1d1f52f29f540f6d5eb162cbd5eb78bb805366d4ab26d
F test/json102.test eeb54efa221e50b74a2d6fb9259963b48d7414dca3ce2fdfdeed45cb28487bc1
F test/json103.test aff6b7a4c17d5a20b487a7bc1a274bfdc63b829413bdfb83bedac42ec7f67e3b
F test/json104.test 877d5845f6303899b7889ea5dd1bea99076e3100574d5c536082245c5805dcaa
F test/json104.test cf0dbd220cba81e6c3cf8bc326e2321049cec05ab0b529308d76f28a52529800
F test/keyword1.test 37ef6bba5d2ed5b07ecdd6810571de2956599dff
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 11cfd7d4ef8625389df9efc46735ff0b0b41d5e62047ef0f3bc24c380d28a7a6
F test/like.test 5013f18e7242fe118524fcf8e484b8827bcd5906b509d106f3587c7bfcf274ae
F test/like2.test 3b2ee13149ba4a8a60b59756f4e5d345573852da
F test/like3.test 0ce2630e39e32e42ce02d171f0a315189ca71fec37c5ddfb0191eecc3fe9d4da
F test/like3.test 62bf82ac674b7d4126e73532e1ad96cdcd8e1752a4ed90b28a6f98305f5a66aa
F test/limit.test 0c99a27a87b14c646a9d583c7c89fd06c352663e
F test/limit2.test 9409b033284642a859fafc95f29a5a6a557bd57c1f0d7c3f554bd64ed69df77e
F test/loadext.test faa4f6eed07a5aac35d57fdd7bc07f8fc82464cfd327567c10cf0ba3c86cde04
@@ -1183,7 +1193,7 @@ F test/orderby6.test 8b38138ab0972588240b3fca0985d2e400432859
F test/orderby7.test 3d1383d52ade5b9eb3a173b3147fdd296f0202da
F test/orderby8.test 23ef1a5d72bd3adcc2f65561c654295d1b8047bd
F test/orderby9.test 87fb9548debcc2cd141c5299002dd94672fa76a3
F test/oserror.test e7b3416be4b9d5dd2fe0b42dd394daaddbb6c83eeec1f0e47b120b53e0ad3ace
F test/oserror.test 1fc9746b83d778e70d115049747ba19c7fba154afce7cc165b09feb6ca6abbc5
F test/ossfuzz.c 18af635fa73d12a109b305faca727a734c1fa28a421b161d9d15c5a84a4998a2
F test/ossshell.c f125c5bd16e537a2549aa579b328dd1c59905e7ab1338dfc210e755bb7b69f17
F test/ovfl.test 199c482696defceacee8c8e0e0ef36da62726b2f
@@ -1200,12 +1210,12 @@ F test/parser1.test 6ccdf5e459a5dc4673d3273dc311a7e9742ca952dd0551a6a6320d27035c
F test/pcache.test c8acbedd3b6fd0f9a7ca887a83b11d24a007972b
F test/pcache2.test af7f3deb1a819f77a6d0d81534e97d1cf62cd442
F test/percentile.test 4243af26b8f3f4555abe166f723715a1f74c77ff
F test/permutations.test b8f0da2f53ef1bd7ff149a140ee625aa7276c94ae15eb9acc2d8ed4af8f22b13
F test/permutations.test 4282fb00e5ac0f8c2cd1be62652f6da4ac03ce3c58b7d785fa17f4684492a0e0
F test/pg_common.tcl 4740dc35190d6acdab14c097783331361301ab504a94d948f6afbb56ce0a51e8
F test/pragma.test cf066fe0f7f5d49f4758de4986407b8676c61aaa7871599340d64f42a8edc352
F test/pragma2.test e5d5c176360c321344249354c0c16aec46214c9f
F test/pragma3.test 8300aa9c63cff1027006ca34bf413a148abbd6dcd471fa9a1ded322fe18c0df9
F test/pragma4.test 26b250531f1c58d9b6187b663f411cd6baf227a4afeffa8f75d0f4c101f4920d
F test/pragma4.test 1cb4b32f1a304ed9e291d7c4d49c91c2c8dc1b9450e6d2c1198b2cc895d40d77
F test/pragma5.test 824ce6ced5d6b7ec71abe37fc6005ff836fe39d638273dc5192b39864b9ee983
F test/pragmafault.test 275edaf3161771d37de60e5c2b412627ac94cef11739236bec12ed1258b240f8
F test/prefixes.test b524a1c44bffec225b9aec98bd728480352aa8532ac4c15771fb85e8beef65d9
@@ -1219,24 +1229,26 @@ F test/quick.test 1681febc928d686362d50057c642f77a02c62e57
F test/quota-glob.test 32901e9eed6705d68ca3faee2a06b73b57cb3c26
F test/quota.test bfb269ce81ea52f593f9648316cd5013d766dd2a
F test/quota2.test 7dc12e08b11cbc4c16c9ba2aa2e040ea8d8ab4b8
F test/quote.test 215897dbe8de1a6f701265836d6601cc6ed103e6
F test/quote.test 626149eda89ee64d81a3790de370f9f0211921b11568a49c28c861f394330508
F test/randexpr1.tcl 40dec52119ed3a2b8b2a773bce24b63a3a746459
F test/randexpr1.test eda062a97e60f9c38ae8d806b03b0ddf23d796df
F test/rbu.test 168573d353cd0fd10196b87b0caa322c144ef736
F test/rdonly.test 64e2696c322e3538df0b1ed624e21f9a23ed9ff8
F test/recover.test ccb8c2623902a92ebb76770edd075cb4f75a4760bb7afde38026572c6e79070d
F test/regexp1.test 497ea812f264d12b6198d6e50a76be4a1973a9d8
F test/regexp2.test 40e894223b3d6672655481493f1be12012f2b33c
F test/reindex.test 44edd3966b474468b823d481eafef0c305022254
F test/releasetest.tcl 204efd3a87ec1d62da2efde42c673b18b955350a9d3c6ac0b4dbba5bc8595808 x
F test/releasetest_data.tcl c3746248b5ad8f99a29020f83501bb25e024156ecc37e05c71c76da4fc8601c6
F test/reindex.test cd9d6021729910ece82267b4f5e1b5ac2911a7566c43b43c176a6a4732e2118d
F test/releasetest.tcl 968fc1e8fd23e113fb8a04379747f3a9f2c12d207b2de85aeff5a825962e1cd7 x
F test/releasetest_data.tcl 146a73e8c8212f962b6558fee0711b895f11b607ee0610e6910781dc8f83797d
F test/resetdb.test 8062cf10a09d8c048f8de7711e94571c38b38168db0e5877ba7561789e5eeb2b
F test/resolver01.test f4022acafda7f4d40eca94dbf16bc5fc4ac30ceb
F test/rollback.test 06680159bc6746d0f26276e339e3ae2f951c64812468308838e0a3362d911eaa
F test/rollback2.test bc868d57899dc6972e2b4483faae0e03365a0556941474eec487ae21d8d38bb6
F test/rollbackfault.test 0e646aeab8840c399cfbfa43daab46fd609cf04a
F test/round1.test 768018b04522ca420b1aba8a24bd76091d269f3bce3902af3ec6ebcee41ab21e
F test/rowallock.test 3f88ec6819489d0b2341c7a7528ae17c053ab7cc
F test/rowhash.test 0bc1d31415e4575d10cacf31e1a66b5cc0f8be81
F test/rowid.test 5b7509f384f4f6fae1af3c8c104c8ca299fea18d
F test/rowid.test bfbd7b97d9267660be3c8f28507c4ed7f205196b8877c0db42df347c2e8845e3
F test/rowvalue.test b8680f07d19c8c5223b808bba998faffcec6d505f5689ff6070280119173bb51
F test/rowvalue2.test 060d238b7e5639a7c5630cb5e63e311b44efef2b
F test/rowvalue3.test 3068f508753af69884b12125995f023da0dbb256
@@ -1268,10 +1280,10 @@ F test/securedel.test 2f70b2449186a1921bd01ec9da407fbfa98c3a7a5521854c300c194b2f
F test/securedel2.test 2d54c28e46eb1fd6902089958b20b1b056c6f1c5
F test/select1.test 7d41f354998524070317207d4e2b68e725e4cf14a57835fc746d4bea686a8714
F test/select2.test 352480e0e9c66eda9c3044e412abdf5be0215b56
F test/select3.test 2ce595f8fb8e2ac10071d3b4e424cadd4634a054
F test/select3.test 3905450067c28766bc83ee397f6d87342de868baa60f2bcfd00f286dfbd62cb9
F test/select4.test 5389d9895968d1196c457d59b3ee6515d771d328
F test/select5.test df9ec0d218cedceb4fe7b63262025b547b50a55e59148c6f40b60ca25f1d4546
F test/select6.test 39eac4a5c03650b2b473c532882273283ee8b7a0
F test/select6.test 319d45e414cdd321bf17cfacedaf19e3935ad64dac357c53f1492338c6e9b801
F test/select7.test f659f231489349e8c5734e610803d7654207318f
F test/select8.test 8c8f5ae43894c891efc5755ed905467d1d67ad5d
F test/select9.test aebc2bb0c3bc44606125033cbcaac2c8d1f33a95
@@ -1339,7 +1351,7 @@ F test/speed3.test 694affeb9100526007436334cf7d08f3d74b85ef
F test/speed4.test abc0ad3399dcf9703abed2fff8705e4f8e416715
F test/speed4p.explain 6b5f104ebeb34a038b2f714150f51d01143e59aa
F test/speed4p.test 377a0c48e5a92e0b11c1c5ebb1bc9d83a7312c922bc0cb05970ef5d6a96d1f0c
F test/speedtest1.c cc7e6b4a7c9f3e3d1a497ae3f75236a832a2ce0f6a9b017f95d996c821605bfb
F test/speedtest1.c f3bfe3c6a87cbd88e4c4e38005d972bcc1019d1b2fe9569425f86629b11f6c31
F test/spellfix.test 951a6405d49d1a23d6b78027d3877b4a33eeb8221dcab5704b499755bb4f552e
F test/spellfix2.test dfc8f519a3fc204cb2dfa8b4f29821ae90f6f8c3
F test/spellfix3.test 0f9efaaa502a0e0a09848028518a6fb096c8ad33
@@ -1353,7 +1365,7 @@ F test/stmt.test 54ed2cc0764bf3e48a058331813c3dbd19fc1d0827c3d8369914a5d8f564ec7
F test/stmtvtab1.test 6873dfb24f8e79cbb5b799b95c2e4349060eb7a3b811982749a84b359468e2d5
F test/subjournal.test 8d4e2572c0ee9a15549f0d8e40863161295107e52f07a3e8012a2e1fdd093c49
F test/subquery.test d7268d193dd33d5505df965399d3a594e76ae13f
F test/subquery2.test 8250dfd6a773b04c7a5c37ac63276f62b329157ce171244d0cbe1acc365e3303
F test/subquery2.test 90cf944b9de8204569cf656028391e4af1ccc8c0cc02d4ef38ee3be8de1ffb12
F test/subselect.test 0966aa8e720224dbd6a5e769a3ec2a723e332303
F test/substr.test 18f57c4ca8a598805c4d64e304c418734d843c1a
F test/subtype1.test 7fe09496352f97053af1437150751be2d0a0cae8
@@ -1415,7 +1427,7 @@ F test/tkt-5e10420e8d.test 904d1687b3c06d43e5b3555bbcf6802e7c0ffd84
F test/tkt-5ee23731f.test 9db6e1d7209dc0794948b260d6f82b2b1de83a9f
F test/tkt-6bfb98dfc0.test 24780633627b5cfc0635a5500c2389ebfb563336
F test/tkt-752e1646fc.test ea78d88d14fe9866bdd991c634483334639e13bf
F test/tkt-78e04e52ea.test 1b5be1bac961833a9fd70fe50738cb4064822c61f82c54f7d488435ec806ea62
F test/tkt-78e04e52ea.test cb44d0f5e7940223be740a39913a1b9b9b30d7e4a17ed3349141f893bae1b8f2
F test/tkt-7a31705a7e6.test 9e9c057b6a9497c8f7ba7b16871029414ccf6550e7345d9085d6d71c9a56bb6f
F test/tkt-7bbfb7d442.test 7b2cd79c7a17ae6750e75ec1a7846712a69c9d18
F test/tkt-80ba201079.test 105a721e6aad0ae3c5946d7615d1e4d03f6145b8
@@ -1429,7 +1441,7 @@ F test/tkt-9a8b09f8e6.test b2ef151d0984b2ebf237760dbeaa50724e5a0667
F test/tkt-9d68c883.test 16f7cb96781ba579bc2e19bb14b4ad609d9774b6
F test/tkt-9f2eb3abac.test cb6123ac695a08b4454c3792fbe85108f67fabf8
F test/tkt-a7b7803e.test 159ef554234fa1f9fb318c751b284bd1cf858da4
F test/tkt-a8a0d2996a.test 76662ff0622c90e7ce7bbcb4d9e1129acddf877d17c3489f2da7f17ddfaad1f4
F test/tkt-a8a0d2996a.test 002e1cde8fc30c39611b52cf981c88200b858765748556822da72e0d32fac73e
F test/tkt-b1d3a2e531.test 8f7576e41ca179289ee1a8fee28386fd8e4b0550
F test/tkt-b351d95f9.test d14a503c414c5c58fdde3e80f9a3cfef986498c0
F test/tkt-b72787b1.test a95e8cdad0b98af1853ac7f0afd4ab27b77bf5f3
@@ -1593,8 +1605,8 @@ F test/vacuum5.test 263b144d537e92ad8e9ca8a73cc6e1583f41cfd0dda9432b87f7806174a2
F test/vacuummem.test 7b42abb3208bd82dd23a7536588396f295a314f2
F test/varint.test bbce22cda8fc4d135bcc2b589574be8410614e62
F test/veryquick.test 57ab846bacf7b90cf4e9a672721ea5c5b669b661
F test/view.test 71e1bf4c0e2e0d37c84d7db5b33cd47eb4a7662c19d93ede4112b350b186f61f
F test/vtab1.test 60b4f70aafa6078d6fdfc11417af3bd216d7ef5eafce16707a6ca3dae5166d20
F test/view.test 40d54c9ddf5b9fdee692bf936d3352159fe467838f92742aa1d08c7c7d1eac73
F test/vtab1.test 47b935205d7b6290765973abd6fce0e13e94e040017099170f43f81886efa5ba
F test/vtab2.test 14d4ab26cee13ba6cf5c5601b158e4f57552d3b055cdd9406cf7f711e9c84082
F test/vtab3.test b45f47d20f225ccc9c28dc915d92740c2dee311e
F test/vtab4.test 8e73ed268f3d596bc3590f45fc948fb40f28e9c3
@@ -1609,7 +1621,7 @@ F test/vtabC.test 4528f459a13136f982e75614d120aef165f17292
F test/vtabD.test 05b3f1d77117271671089e48719524b676842e96
F test/vtabE.test 2a143fe75a11275781d1fd1988d86b66a3f69cb98f4add62e3da8fd0f637b45f
F test/vtabF.test 1918844c7c902f6a16c8dacf1ec8f84886d6e78b
F test/vtabH.test 3cf9aa1c1c4381b3b3ac33f933376f06fbb99d2294a83c79b7562d3ed87be450
F test/vtabH.test e65540eed0f7434cdf0b160374570b51f3e3179548f0fa5e99b1d33f8dcdf9a0
F test/vtabI.test 751b07636700dbdea328e4265b6077ccd6811a3f
F test/vtabJ.test d7b73675708cf63cfcb9d443bb451fc01a028347275b7311e51f9fdf3ca6757f
F test/vtab_alter.test 736e66fb5ec7b4fee58229aa3ada2f27ec58bc58c00edae4836890c3784c6783
@@ -1652,7 +1664,7 @@ F test/walslow.test c05c68d4dc2700a982f89133ce103a1a84cc285f
F test/walthread.test 14b20fcfa6ae152f5d8e12f5dc8a8a724b7ef189f5d8ef1e2ceab79f2af51747
F test/walvfs.test c0faffda13d045a96dfc541347886bb1a3d6f3205857fc98e683edfab766ea88
F test/wapp.tcl b440cd8cf57953d3a49e7ee81e6a18f18efdaf113b69f7d8482b0710a64566ec
F test/wapptest.tcl 78aff97afe76fd9728cf5f84710a772412735bc68a612b4789279072177a424e x
F test/wapptest.tcl 56d2b7974ecd8cca3189a670f757306d5ff3334cc9fe3744f7a6ad7ae4380e8c x
F test/where.test 0607caa5a1fbfe7b93b95705981b463a3a0408038f22ae6e9dc11b36902b0e95
F test/where2.test 478d2170637b9211f593120648858593bf2445a1
F test/where3.test 2341a294e17193a6b1699ea7f192124a5286ca6acfcc3f4b06d16c931fbcda2c
@@ -1684,8 +1696,8 @@ F test/win32lock.test fbf107c91d8f5512be5a5b87c4c42ab9fdd54972
F test/win32longpath.test 169c75a3b2e43481f4a62122510210c67b08f26d
F test/win32nolock.test ac4f08811a562e45a5755e661f45ca85892bdbbc
F test/window1.test 8d453bfaa3f8f0873ba16ca1270c7368f18445065a0003a1b5954ac4e95797b4
F test/window2.tcl 9bfa842d8a62b0d36dc8c1b5972206393c43847433c6d75940b87fec93ce3143
F test/window2.test 8e6d2a1b9f54dfebee1cde961c8590cd87b4db45c50f44947a211e1b63c2a05e
F test/window2.tcl 0c2918ef2a1640553fd791972d458356808a608418c64c02a0a379cecfc7fb0d
F test/window2.test 96ef949f0197c025652f6c6e5812cdbfb948989bd40cf79cbb02104249a89513
F test/window3.tcl acea6e86a4324a210fd608d06741010ca83ded9fde438341cb978c49928faf03
F test/window3.test e9959a993c8a71e96433be8daaa1827d78b8921e4f12debd7bdbeb3c856ef3cb
F test/window4.tcl 5fbaab489677914ee5686b2008426e336daf88a2f58be7df92757f780a5ebf91
@@ -1696,15 +1708,16 @@ F test/window7.tcl 6a1210f05d40ec89c22960213a22cd3f98d4e2f2eb20646c83c8c30d4d761
F test/window7.test ce7f865241fdd1c5c4db869cd7bb2986c3be836bc2e73649a6846dd920f63e0f
F test/window8.tcl 9e9a82ae9eea90a4a83481d641a812b974980c38f9247f3b89a6e3c8bed45518
F test/window8.test df187dc19921f7be0ab709d531d681bd80ccaac96a913a89ecee8b272b91d43f
F test/window9.test 06495ac733843849b1fca8a79d13ba330d04aba02099703198af2ba7e231f90c
F test/windowerr.tcl abf4d6d0c6d360213af98ed7d538295d905689e83692106f3ece0e3afb9d7f36
F test/windowerr.test 675b5e6debfc9370bfacb0b91e2a93a8923512f92600b16f4ea70a1cd9b8e6e4
F test/windowfault.test 16e906a2c4110c88372ff4bd5de59ac7397ec2f025912eff8e5677eedd126898
F test/with1.test a07b5aad7f77acdf13e52e8814ea94606fcc72e9ea4c99baf293e9d7c63940be
F test/windowfault.test 403693d7d951c5473f052f7ecddb61ed15ac9d212f238b8904ea270ba90f83e5
F test/with1.test d32792084dcb5f6c047d77bb8a032822ef9fe050ade07d0aeffa37753a05e3c9
F test/with2.test e0030e2f0267a910d6c0e4f46f2dfe941c1cc0d4f659ba69b3597728e7e8f1ab
F test/with3.test 8d26920c88283e0a473ceebd3451554922108ce7b2a6a1157c47eb0a7011212c
F test/with3.test b5f1372097690c6ef84db2f13fc7e64a88c7263c3f88493605f90597e8a68d45
F test/with4.test 257be66c0c67fee1defbbac0f685c3465e2cad037f21ce65f23f86084f198205
F test/withM.test 693b61765f2b387b5e3e24a4536e2e82de15ff64
F test/without_rowid1.test b5ec93f7df2c1d684e0923247dac6aca8888e088bf50a9f244c3933e0e813a72
F test/without_rowid1.test 89d101a7c6e0802882002cf3713f405319ddb6b9f08449dcc08c6082c995cab1
F test/without_rowid2.test af260339f79d13cb220288b67cd287fbcf81ad99
F test/without_rowid3.test ea4b59dd1b0d7f5f5e4b7cca978cdb905752a9d7c57dc4344a591dba765a3691
F test/without_rowid4.test 4e08bcbaee0399f35d58b5581881e7a6243d458a
@@ -1737,7 +1750,7 @@ F tool/genfkey.test b6afd7b825d797a1e1274f519ab5695373552ecad5cd373530c63533638a
F tool/getlock.c f4c39b651370156cae979501a7b156bdba50e7ce
F tool/index_usage.c 9ec344d29cbeb03fdc0fce668eedfb7495792170de933adf95cf8d6904a166ad
F tool/kvtest-speed.sh 4761a9c4b3530907562314d7757995787f7aef8f
F tool/lemon.c 900a15b9efba9890d10e7959914db94c4ad5162912127f061c4328add122d6fb
F tool/lemon.c cc43148d2793ab93668e74a6a6319bb71c2e65c1ffcd6deeaa59e12be9362a43
F tool/lempar.c 61af95b8fac2bfd59c09d55330e78f3f5e352d7aa80bf37404b96ef795be3fdc
F tool/libvers.c caafc3b689638a1d88d44bc5f526c2278760d9b9
F tool/loadfts.c c3c64e4d5e90e8ba41159232c2189dba4be7b862
@@ -1751,8 +1764,8 @@ F tool/mkmsvcmin.tcl cad0c7b54d7dd92bc87d59f36d4cc4f070eb2e625f14159dc2f5c4204e6
F tool/mkopcodec.tcl d1b6362bd3aa80d5520d4d6f3765badf01f6c43c
F tool/mkopcodeh.tcl 352a4319c0ad869eb26442bf7c3b015aa15594c21f1cce5a6420dbe999367c21
F tool/mkopts.tcl 680f785fdb09729fd9ac50632413da4eadbdf9071535e3f26d03795828ab07fa
F tool/mkpragmatab.tcl 49039adedafbc430d2959400da2e0e8f20ef8dcf6898e447c946e7d50ef5906b
F tool/mkshellc.tcl 1f45770aea226ac093a9c72f718efbb88a2a2833409ec2e1c4cecae4202626f5
F tool/mkpragmatab.tcl 8250ef3df54aee09f6c6ed36cad390bb6dd20bbe71927d8bff069ed9fe0bbf98
F tool/mkshellc.tcl 70a9978e363b0f3280ca9ce1c46d72563ff479c1930a12a7375e3881b7325712
F tool/mksourceid.c d458f9004c837bee87a6382228ac20d3eae3c49ea3b0a5aace936f8b60748d3b
F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97
F tool/mksqlite3c-noext.tcl 4f7cfef5152b0c91920355cbfc1d608a4ad242cb819f1aea07f6d0274f584a7f
@@ -1768,7 +1781,7 @@ F tool/replace.tcl 60f91e8dd06ab81f74d213ecbd9c9945f32ac048
F tool/restore_jrnl.tcl 6957a34f8f1f0f8285e07536225ec3b292a9024a
F tool/rollback-test.c 9fc98427d1e23e84429d7e6d07d9094fbdec65a5
F tool/run-speed-test.sh f95d19fd669b68c4c38b6b475242841d47c66076
F tool/showdb.c af978d1437562776fa4d94bf0cb772314c464e71ef24134a6e2301564ae60bc2
F tool/showdb.c 97d14a1ce32d5edda84081a5c939bd8975abd89568a773b288940e67e4c7e3ad
F tool/showjournal.c 5bad7ae8784a43d2b270d953060423b8bd480818
F tool/showlocks.c 9920bcc64f58378ff1118caead34147201f48c68
F tool/showshm.c a0ab6ec32dd1f11218ca2a4018f8fb875b59414801ab8ceed8b2e69b7b45a809
@@ -1818,11 +1831,11 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
P af61a2fc45a0fa1277d7453779238b77de4c298a9f60714b7dc62ddca5874f80
R 53d48b50e3fea254b204992be6aac766
P 6f328c35947d6b3a0741514757b8944692203e89bdb2e7f9bbce8ad9288be344
R 3dc95c8af87e7b557da20a5426ebc03a
T +bgcolor * #d0c0ff
T +sym-release *
T +sym-version-3.28.0 *
T +sym-version-3.29.0 *
U drh
Z 50f60d1cc2f388d0c03013011d963653
Z 4d356946c4c6edd871b6d6986b095a05
# Remove this line to create a well-formed manifest.
+1 -1
View File
@@ -1 +1 @@
884b4b7e502b4e991677b53971277adfaf0a04a284f8e483e2553d0f83156b50
fc82b73eaac8b36950e527f12c4b5dc1e147e6f4ad2217ae43ad82882a88bfa6
+31 -5
View File
@@ -54,7 +54,7 @@ static void renameTestSchema(Parse *pParse, const char *zDb, int bTemp){
sqlite3NestedParse(pParse,
"SELECT 1 "
"FROM \"%w\".%s "
"WHERE name NOT LIKE 'sqlite_%%'"
"WHERE name NOT LIKE 'sqliteX_%%' ESCAPE 'X'"
" AND sql NOT LIKE 'create virtual%%'"
" AND sqlite_rename_test(%Q, sql, type, name, %d)=NULL ",
zDb, MASTER_NAME,
@@ -65,7 +65,7 @@ static void renameTestSchema(Parse *pParse, const char *zDb, int bTemp){
sqlite3NestedParse(pParse,
"SELECT 1 "
"FROM temp.%s "
"WHERE name NOT LIKE 'sqlite_%%'"
"WHERE name NOT LIKE 'sqliteX_%%' ESCAPE 'X'"
" AND sql NOT LIKE 'create virtual%%'"
" AND sqlite_rename_test(%Q, sql, type, name, 1)=NULL ",
MASTER_NAME, zDb
@@ -186,7 +186,7 @@ void sqlite3AlterRenameTable(
"UPDATE \"%w\".%s SET "
"sql = sqlite_rename_table(%Q, type, name, sql, %Q, %Q, %d) "
"WHERE (type!='index' OR tbl_name=%Q COLLATE nocase)"
"AND name NOT LIKE 'sqlite_%%'"
"AND name NOT LIKE 'sqliteX_%%' ESCAPE 'X'"
, zDb, MASTER_NAME, zDb, zTabName, zName, (iDb==1), zTabName
);
@@ -197,7 +197,8 @@ void sqlite3AlterRenameTable(
"tbl_name = %Q, "
"name = CASE "
"WHEN type='table' THEN %Q "
"WHEN name LIKE 'sqlite_autoindex%%' AND type='index' THEN "
"WHEN name LIKE 'sqliteX_autoindex%%' ESCAPE 'X' "
" AND type='index' THEN "
"'sqlite_autoindex_' || %Q || substr(name,%d+18) "
"ELSE name END "
"WHERE tbl_name=%Q COLLATE nocase AND "
@@ -571,7 +572,8 @@ void sqlite3AlterRenameColumn(
sqlite3NestedParse(pParse,
"UPDATE \"%w\".%s SET "
"sql = sqlite_rename_column(sql, type, name, %Q, %Q, %d, %Q, %d, %d) "
"WHERE name NOT LIKE 'sqlite_%%' AND (type != 'index' OR tbl_name = %Q)"
"WHERE name NOT LIKE 'sqliteX_%%' ESCAPE 'X' "
" AND (type != 'index' OR tbl_name = %Q)"
" AND sql NOT LIKE 'create virtual%%'",
zDb, MASTER_NAME,
zDb, pTab->zName, iCol, zNew, bQuote, iSchema==1,
@@ -725,6 +727,29 @@ static int renameUnmapExprCb(Walker *pWalker, Expr *pExpr){
return WRC_Continue;
}
/*
** Walker callback used by sqlite3RenameExprUnmap().
*/
static int renameUnmapSelectCb(Walker *pWalker, Select *p){
Parse *pParse = pWalker->pParse;
int i;
if( ALWAYS(p->pEList) ){
ExprList *pList = p->pEList;
for(i=0; i<pList->nExpr; i++){
if( pList->a[i].zName ){
sqlite3RenameTokenRemap(pParse, 0, (void*)pList->a[i].zName);
}
}
}
if( ALWAYS(p->pSrc) ){ /* Every Select as a SrcList, even if it is empty */
SrcList *pSrc = p->pSrc;
for(i=0; i<pSrc->nSrc; i++){
sqlite3RenameTokenRemap(pParse, 0, (void*)pSrc->a[i].zName);
}
}
return WRC_Continue;
}
/*
** Remove all nodes that are part of expression pExpr from the rename list.
*/
@@ -733,6 +758,7 @@ void sqlite3RenameExprUnmap(Parse *pParse, Expr *pExpr){
memset(&sWalker, 0, sizeof(Walker));
sWalker.pParse = pParse;
sWalker.xExprCallback = renameUnmapExprCb;
sWalker.xSelectCallback = renameUnmapSelectCb;
sqlite3WalkExpr(&sWalker, pExpr);
}
+1 -1
View File
@@ -294,7 +294,7 @@ static int backupOnePage(
if( nSrcReserve!=nDestReserve ){
u32 newPgsz = nSrcPgsz;
rc = sqlite3PagerSetPagesize(pDestPager, &newPgsz, nSrcReserve);
if( rc==SQLITE_OK && newPgsz!=nSrcPgsz ) rc = SQLITE_READONLY;
if( rc==SQLITE_OK && newPgsz!=(u32)nSrcPgsz ) rc = SQLITE_READONLY;
}
#endif
+30 -13
View File
@@ -1628,7 +1628,7 @@ static int allocateSpace(MemPage *pPage, int nByte, int *pIdx){
** However, that integer is too large to be stored in a 2-byte unsigned
** integer, so a value of 0 is used in its place. */
top = get2byte(&data[hdr+5]);
assert( top<=(int)pPage->pBt->usableSize ); /* Prevent by getAndInitPage() */
assert( top<=(int)pPage->pBt->usableSize ); /* by btreeComputeFreeSpace() */
if( gap>top ){
if( top==0 && pPage->pBt->usableSize==65536 ){
top = 65536;
@@ -1925,7 +1925,7 @@ static int btreeComputeFreeSpace(MemPage *pPage){
** serves to verify that the offset to the start of the cell-content
** area, according to the page header, lies within the page.
*/
if( nFree>usableSize ){
if( nFree>usableSize || nFree<iCellFirst ){
return SQLITE_CORRUPT_PAGE(pPage);
}
pPage->nFree = (u16)(nFree - iCellFirst);
@@ -4153,6 +4153,18 @@ int sqlite3BtreeTripAllCursors(Btree *pBtree, int errCode, int writeOnly){
return rc;
}
/*
** Set the pBt->nPage field correctly, according to the current
** state of the database. Assume pBt->pPage1 is valid.
*/
static void btreeSetNPage(BtShared *pBt, MemPage *pPage1){
int nPage = get4byte(&pPage1->aData[28]);
testcase( nPage==0 );
if( nPage==0 ) sqlite3PagerPagecount(pBt->pPager, &nPage);
testcase( pBt->nPage!=nPage );
pBt->nPage = nPage;
}
/*
** Rollback the transaction in progress.
**
@@ -4198,11 +4210,7 @@ int sqlite3BtreeRollback(Btree *p, int tripCode, int writeOnly){
** call btreeGetPage() on page 1 again to make
** sure pPage1->aData is set correctly. */
if( btreeGetPage(pBt, 1, &pPage1, 0)==SQLITE_OK ){
int nPage = get4byte(28+(u8*)pPage1->aData);
testcase( nPage==0 );
if( nPage==0 ) sqlite3PagerPagecount(pBt->pPager, &nPage);
testcase( pBt->nPage!=nPage );
pBt->nPage = nPage;
btreeSetNPage(pBt, pPage1);
releasePageOne(pPage1);
}
assert( countValidCursors(pBt, 1)==0 );
@@ -4282,12 +4290,11 @@ int sqlite3BtreeSavepoint(Btree *p, int op, int iSavepoint){
pBt->nPage = 0;
}
rc = newDatabase(pBt);
pBt->nPage = get4byte(28 + pBt->pPage1->aData);
btreeSetNPage(pBt, pBt->pPage1);
/* The database size was written into the offset 28 of the header
** when the transaction started, so we know that the value at offset
** 28 is nonzero. */
assert( pBt->nPage>0 );
/* pBt->nPage might be zero if the database was corrupt when
** the transaction was started. Otherwise, it must be at least 1. */
assert( CORRUPT_DB || pBt->nPage>0 );
}
sqlite3BtreeLeave(p);
}
@@ -5295,6 +5302,7 @@ int sqlite3BtreeLast(BtCursor *pCur, int *pRes){
assert( pCur->ix==pCur->pPage->nCell-1 );
assert( pCur->pPage->leaf );
#endif
*pRes = 0;
return SQLITE_OK;
}
@@ -5516,6 +5524,7 @@ int sqlite3BtreeMovetoUnpacked(
** case this happens. */
void *pCellKey;
u8 * const pCellBody = pCell - pPage->childPtrSize;
const int nOverrun = 18; /* Size of the overrun padding */
pPage->xParseCell(pPage, pCellBody, &pCur->info);
nCell = (int)pCur->info.nKey;
testcase( nCell<0 ); /* True if key size is 2^32 or more */
@@ -5526,13 +5535,14 @@ int sqlite3BtreeMovetoUnpacked(
rc = SQLITE_CORRUPT_PAGE(pPage);
goto moveto_finish;
}
pCellKey = sqlite3Malloc( nCell+18 );
pCellKey = sqlite3Malloc( nCell+nOverrun );
if( pCellKey==0 ){
rc = SQLITE_NOMEM_BKPT;
goto moveto_finish;
}
pCur->ix = (u16)idx;
rc = accessPayload(pCur, 0, nCell, (unsigned char*)pCellKey, 0);
memset(((u8*)pCellKey)+nCell,0,nOverrun); /* Fix uninit warnings */
pCur->curFlags &= ~BTCF_ValidOvfl;
if( rc ){
sqlite3_free(pCellKey);
@@ -7637,6 +7647,7 @@ static int balance_nonroot(
u16 maskPage = pOld->maskPage;
u8 *piCell = aData + pOld->cellOffset;
u8 *piEnd;
VVA_ONLY( int nCellAtStart = b.nCell; )
/* Verify that all sibling pages are of the same "type" (table-leaf,
** table-interior, index-leaf, or index-interior).
@@ -7665,6 +7676,10 @@ static int balance_nonroot(
*/
memset(&b.szCell[b.nCell], 0, sizeof(b.szCell[0])*(limit+pOld->nOverflow));
if( pOld->nOverflow>0 ){
if( limit<pOld->aiOvfl[0] ){
rc = SQLITE_CORRUPT_BKPT;
goto balance_cleanup;
}
limit = pOld->aiOvfl[0];
for(j=0; j<limit; j++){
b.apCell[b.nCell] = aData + (maskPage & get2byteAligned(piCell));
@@ -7684,6 +7699,7 @@ static int balance_nonroot(
piCell += 2;
b.nCell++;
}
assert( (b.nCell-nCellAtStart)==(pOld->nCell+pOld->nOverflow) );
cntOld[i] = b.nCell;
if( i<nOld-1 && !leafData){
@@ -7984,6 +8000,7 @@ static int balance_nonroot(
while( i==cntOldNext ){
iOld++;
assert( iOld<nNew || iOld<nOld );
assert( iOld>=0 && iOld<NB );
pOld = iOld<nNew ? apNew[iOld] : apOld[iOld];
cntOldNext += pOld->nCell + pOld->nOverflow + !leafData;
}
+87 -12
View File
@@ -618,10 +618,14 @@ static void SQLITE_NOINLINE deleteTable(sqlite3 *db, Table *pTable){
#ifdef SQLITE_DEBUG
/* Record the number of outstanding lookaside allocations in schema Tables
** prior to doing any free() operations. Since schema Tables do not use
** lookaside, this number should not change. */
** prior to doing any free() operations. Since schema Tables do not use
** lookaside, this number should not change.
**
** If malloc has already failed, it may be that it failed while allocating
** a Table object that was going to be marked ephemeral. So do not check
** that no lookaside memory is used in this case either. */
int nLookaside = 0;
if( db && (pTable->tabFlags & TF_Ephemeral)==0 ){
if( db && !db->mallocFailed && (pTable->tabFlags & TF_Ephemeral)==0 ){
nLookaside = sqlite3LookasideUsed(db, 0);
}
#endif
@@ -1329,7 +1333,7 @@ void sqlite3AddDefaultValue(
** accept it. This routine does the necessary conversion. It converts
** the expression given in its argument from a TK_STRING into a TK_ID
** if the expression is just a TK_STRING with an optional COLLATE clause.
** If the epxression is anything other than TK_STRING, the expression is
** If the expression is anything other than TK_STRING, the expression is
** unchanged.
*/
static void sqlite3StringToId(Expr *p){
@@ -1726,10 +1730,51 @@ static void estimateIndexWidth(Index *pIdx){
pIdx->szIdxRow = sqlite3LogEst(wIndex*4);
}
/* Return true if value x is found any of the first nCol entries of aiCol[]
/* Return true if column number x is any of the first nCol entries of aiCol[].
** This is used to determine if the column number x appears in any of the
** first nCol entries of an index.
*/
static int hasColumn(const i16 *aiCol, int nCol, int x){
while( nCol-- > 0 ) if( x==*(aiCol++) ) return 1;
while( nCol-- > 0 ){
assert( aiCol[0]>=0 );
if( x==*(aiCol++) ){
return 1;
}
}
return 0;
}
/*
** Return true if any of the first nKey entries of index pIdx exactly
** match the iCol-th entry of pPk. pPk is always a WITHOUT ROWID
** PRIMARY KEY index. pIdx is an index on the same table. pIdx may
** or may not be the same index as pPk.
**
** The first nKey entries of pIdx are guaranteed to be ordinary columns,
** not a rowid or expression.
**
** This routine differs from hasColumn() in that both the column and the
** collating sequence must match for this routine, but for hasColumn() only
** the column name must match.
*/
static int isDupColumn(Index *pIdx, int nKey, Index *pPk, int iCol){
int i, j;
assert( nKey<=pIdx->nColumn );
assert( iCol<MAX(pPk->nColumn,pPk->nKeyCol) );
assert( pPk->idxType==SQLITE_IDXTYPE_PRIMARYKEY );
assert( pPk->pTable->tabFlags & TF_WithoutRowid );
assert( pPk->pTable==pIdx->pTable );
testcase( pPk==pIdx );
j = pPk->aiColumn[iCol];
assert( j!=XN_ROWID && j!=XN_EXPR );
for(i=0; i<nKey; i++){
assert( pIdx->aiColumn[i]>=0 || j>=0 );
if( pIdx->aiColumn[i]==j
&& sqlite3StrICmp(pIdx->azColl[i], pPk->azColl[iCol])==0
){
return 1;
}
}
return 0;
}
@@ -1818,13 +1863,16 @@ static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){
pList = sqlite3ExprListAppend(pParse, 0,
sqlite3ExprAlloc(db, TK_ID, &ipkToken, 0));
if( pList==0 ) return;
if( IN_RENAME_OBJECT ){
sqlite3RenameTokenRemap(pParse, pList->a[0].pExpr, &pTab->iPKey);
}
pList->a[0].sortOrder = pParse->iPkSortOrder;
assert( pParse->pNewTable==pTab );
pTab->iPKey = -1;
sqlite3CreateIndex(pParse, 0, 0, 0, pList, pTab->keyConf, 0, 0, 0, 0,
SQLITE_IDXTYPE_PRIMARYKEY);
if( db->mallocFailed || pParse->nErr ) return;
pPk = sqlite3PrimaryKeyIndex(pTab);
pTab->iPKey = -1;
}else{
pPk = sqlite3PrimaryKeyIndex(pTab);
assert( pPk!=0 );
@@ -1835,9 +1883,10 @@ static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){
** code assumes the PRIMARY KEY contains no repeated columns.
*/
for(i=j=1; i<pPk->nKeyCol; i++){
if( hasColumn(pPk->aiColumn, j, pPk->aiColumn[i]) ){
if( isDupColumn(pPk, j, pPk, i) ){
pPk->nColumn--;
}else{
testcase( hasColumn(pPk->aiColumn, j, pPk->aiColumn[i]) );
pPk->aiColumn[j++] = pPk->aiColumn[i];
}
}
@@ -1867,7 +1916,10 @@ static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){
int n;
if( IsPrimaryKeyIndex(pIdx) ) continue;
for(i=n=0; i<nPk; i++){
if( !hasColumn(pIdx->aiColumn, pIdx->nKeyCol, pPk->aiColumn[i]) ) n++;
if( !isDupColumn(pIdx, pIdx->nKeyCol, pPk, i) ){
testcase( hasColumn(pIdx->aiColumn, pIdx->nKeyCol, pPk->aiColumn[i]) );
n++;
}
}
if( n==0 ){
/* This index is a superset of the primary key */
@@ -1876,9 +1928,14 @@ static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){
}
if( resizeIndexObject(db, pIdx, pIdx->nKeyCol+n) ) return;
for(i=0, j=pIdx->nKeyCol; i<nPk; i++){
if( !hasColumn(pIdx->aiColumn, pIdx->nKeyCol, pPk->aiColumn[i]) ){
if( !isDupColumn(pIdx, pIdx->nKeyCol, pPk, i) ){
testcase( hasColumn(pIdx->aiColumn, pIdx->nKeyCol, pPk->aiColumn[i]) );
pIdx->aiColumn[j] = pPk->aiColumn[i];
pIdx->azColl[j] = pPk->azColl[i];
if( pPk->aSortOrder[i] ){
/* See ticket https://www.sqlite.org/src/info/bba7b69f9849b5bf */
pIdx->bAscKeyBug = 1;
}
j++;
}
}
@@ -2997,10 +3054,27 @@ static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){
sqlite3UniqueConstraint(pParse, OE_Abort, pIndex);
sqlite3VdbeJumpHere(v, j2);
}else{
/* Most CREATE INDEX and REINDEX statements that are not UNIQUE can not
** abort. The exception is if one of the indexed expressions contains a
** user function that throws an exception when it is evaluated. But the
** overhead of adding a statement journal to a CREATE INDEX statement is
** very small (since most of the pages written do not contain content that
** needs to be restored if the statement aborts), so we call
** sqlite3MayAbort() for all CREATE INDEX statements. */
sqlite3MayAbort(pParse);
addr2 = sqlite3VdbeCurrentAddr(v);
}
sqlite3VdbeAddOp3(v, OP_SorterData, iSorter, regRecord, iIdx);
sqlite3VdbeAddOp1(v, OP_SeekEnd, iIdx);
if( !pIndex->bAscKeyBug ){
/* This OP_SeekEnd opcode makes index insert for a REINDEX go much
** faster by avoiding unnecessary seeks. But the optimization does
** not work for UNIQUE constraint indexes on WITHOUT ROWID tables
** with DESC primary keys, since those indexes have there keys in
** a different order from the main table.
** See ticket: https://www.sqlite.org/src/info/bba7b69f9849b5bf
*/
sqlite3VdbeAddOp1(v, OP_SeekEnd, iIdx);
}
sqlite3VdbeAddOp2(v, OP_IdxInsert, iIdx, regRecord);
sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT);
sqlite3ReleaseTempReg(pParse, regRecord);
@@ -3392,9 +3466,10 @@ void sqlite3CreateIndex(
for(j=0; j<pPk->nKeyCol; j++){
int x = pPk->aiColumn[j];
assert( x>=0 );
if( hasColumn(pIndex->aiColumn, pIndex->nKeyCol, x) ){
if( isDupColumn(pIndex, pIndex->nKeyCol, pPk, j) ){
pIndex->nColumn--;
}else{
testcase( hasColumn(pIndex->aiColumn,pIndex->nKeyCol,x) );
pIndex->aiColumn[i] = x;
pIndex->azColl[i] = pPk->azColl[j];
pIndex->aSortOrder[i] = pPk->aSortOrder[j];
+1 -1
View File
@@ -14,7 +14,7 @@
** SQLite was built with.
*/
#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS
#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS /* IMP: R-16824-07538 */
/*
** Include the configuration header output by 'configure' if we're using the
+3 -3
View File
@@ -388,7 +388,7 @@ static int parseDateOrTime(
return 0;
}else if( sqlite3StrICmp(zDate,"now")==0 && sqlite3NotPureFunc(context) ){
return setDateTimeToCurrent(context, p);
}else if( sqlite3AtoF(zDate, &r, sqlite3Strlen30(zDate), SQLITE_UTF8) ){
}else if( sqlite3AtoF(zDate, &r, sqlite3Strlen30(zDate), SQLITE_UTF8)>0 ){
setRawDateNumber(p, r);
return 0;
}
@@ -722,7 +722,7 @@ static int parseModifier(
** date is already on the appropriate weekday, this is a no-op.
*/
if( sqlite3_strnicmp(z, "weekday ", 8)==0
&& sqlite3AtoF(&z[8], &r, sqlite3Strlen30(&z[8]), SQLITE_UTF8)
&& sqlite3AtoF(&z[8], &r, sqlite3Strlen30(&z[8]), SQLITE_UTF8)>0
&& (n=(int)r)==r && n>=0 && r<7 ){
sqlite3_int64 Z;
computeYMD_HMS(p);
@@ -781,7 +781,7 @@ static int parseModifier(
double rRounder;
int i;
for(n=1; z[n] && z[n]!=':' && !sqlite3Isspace(z[n]); n++){}
if( !sqlite3AtoF(z, &r, n, SQLITE_UTF8) ){
if( sqlite3AtoF(z, &r, n, SQLITE_UTF8)<=0 ){
rc = 1;
break;
}
+179 -86
View File
@@ -44,8 +44,12 @@ char sqlite3TableColumnAffinity(Table *pTab, int iCol){
*/
char sqlite3ExprAffinity(Expr *pExpr){
int op;
pExpr = sqlite3ExprSkipCollate(pExpr);
if( pExpr->flags & EP_Generic ) return 0;
while( ExprHasProperty(pExpr, EP_Skip) ){
assert( pExpr->op==TK_COLLATE );
pExpr = pExpr->pLeft;
assert( pExpr!=0 );
}
op = pExpr->op;
if( op==TK_SELECT ){
assert( pExpr->flags&EP_xIsSelect );
@@ -106,7 +110,7 @@ Expr *sqlite3ExprAddCollateString(Parse *pParse, Expr *pExpr, const char *zC){
** or likelihood() function at the root of an expression.
*/
Expr *sqlite3ExprSkipCollate(Expr *pExpr){
while( pExpr && ExprHasProperty(pExpr, EP_Skip) ){
while( pExpr && ExprHasProperty(pExpr, EP_Skip|EP_Unlikely) ){
if( ExprHasProperty(pExpr, EP_Unlikely) ){
assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
assert( pExpr->x.pList->nExpr>0 );
@@ -773,7 +777,7 @@ Expr *sqlite3ExprAlloc(
pNew->iAgg = -1;
if( pToken ){
if( nExtra==0 ){
pNew->flags |= EP_IntValue|EP_Leaf;
pNew->flags |= EP_IntValue|EP_Leaf|(iValue?EP_IsTrue:EP_IsFalse);
pNew->u.iValue = iValue;
}else{
pNew->u.zToken = (char*)&pNew[1];
@@ -850,20 +854,16 @@ Expr *sqlite3PExpr(
Expr *pRight /* Right operand */
){
Expr *p;
if( op==TK_AND && pParse->nErr==0 && !IN_RENAME_OBJECT ){
/* Take advantage of short-circuit false optimization for AND */
p = sqlite3ExprAnd(pParse->db, pLeft, pRight);
}else{
p = sqlite3DbMallocRawNN(pParse->db, sizeof(Expr));
if( p ){
memset(p, 0, sizeof(Expr));
p->op = op & 0xff;
p->iAgg = -1;
}
p = sqlite3DbMallocRawNN(pParse->db, sizeof(Expr));
if( p ){
memset(p, 0, sizeof(Expr));
p->op = op & 0xff;
p->iAgg = -1;
sqlite3ExprAttachSubtrees(pParse->db, p, pLeft, pRight);
}
if( p ) {
sqlite3ExprCheckHeight(pParse, p->nHeight);
}else{
sqlite3ExprDelete(pParse->db, pLeft);
sqlite3ExprDelete(pParse->db, pRight);
}
return p;
}
@@ -884,33 +884,6 @@ void sqlite3PExprAddSelect(Parse *pParse, Expr *pExpr, Select *pSelect){
}
/*
** If the expression is always either TRUE or FALSE (respectively),
** then return 1. If one cannot determine the truth value of the
** expression at compile-time return 0.
**
** This is an optimization. If is OK to return 0 here even if
** the expression really is always false or false (a false negative).
** But it is a bug to return 1 if the expression might have different
** boolean values in different circumstances (a false positive.)
**
** Note that if the expression is part of conditional for a
** LEFT JOIN, then we cannot determine at compile-time whether or not
** is it true or false, so always return 0.
*/
static int exprAlwaysTrue(Expr *p){
int v = 0;
if( ExprHasProperty(p, EP_FromJoin) ) return 0;
if( !sqlite3ExprIsInteger(p, &v) ) return 0;
return v!=0;
}
static int exprAlwaysFalse(Expr *p){
int v = 0;
if( ExprHasProperty(p, EP_FromJoin) ) return 0;
if( !sqlite3ExprIsInteger(p, &v) ) return 0;
return v==0;
}
/*
** Join two expressions using an AND operator. If either expression is
** NULL, then just return the other expression.
@@ -919,19 +892,18 @@ static int exprAlwaysFalse(Expr *p){
** of returning an AND expression, just return a constant expression with
** a value of false.
*/
Expr *sqlite3ExprAnd(sqlite3 *db, Expr *pLeft, Expr *pRight){
if( pLeft==0 ){
Expr *sqlite3ExprAnd(Parse *pParse, Expr *pLeft, Expr *pRight){
sqlite3 *db = pParse->db;
if( pLeft==0 ){
return pRight;
}else if( pRight==0 ){
return pLeft;
}else if( exprAlwaysFalse(pLeft) || exprAlwaysFalse(pRight) ){
sqlite3ExprDelete(db, pLeft);
sqlite3ExprDelete(db, pRight);
}else if( ExprAlwaysFalse(pLeft) || ExprAlwaysFalse(pRight) ){
sqlite3ExprUnmapAndDelete(pParse, pLeft);
sqlite3ExprUnmapAndDelete(pParse, pRight);
return sqlite3ExprAlloc(db, TK_INTEGER, &sqlite3IntTokens[0], 0);
}else{
Expr *pNew = sqlite3ExprAlloc(db, TK_AND, 0, 0);
sqlite3ExprAttachSubtrees(db, pNew, pLeft, pRight);
return pNew;
return sqlite3PExpr(pParse, TK_AND, pLeft, pRight);
}
}
@@ -1088,6 +1060,18 @@ void sqlite3ExprDelete(sqlite3 *db, Expr *p){
if( p ) sqlite3ExprDeleteNN(db, p);
}
/* Invoke sqlite3RenameExprUnmap() and sqlite3ExprDelete() on the
** expression.
*/
void sqlite3ExprUnmapAndDelete(Parse *pParse, Expr *p){
if( p ){
if( IN_RENAME_OBJECT ){
sqlite3RenameExprUnmap(pParse, p);
}
sqlite3ExprDeleteNN(pParse->db, p);
}
}
/*
** Return the number of bytes allocated for the expression structure
** passed as the first argument. This is always one of EXPR_FULLSIZE,
@@ -1670,10 +1654,7 @@ ExprList *sqlite3ExprListAppendVector(
}
vector_append_error:
if( IN_RENAME_OBJECT ){
sqlite3RenameExprUnmap(pParse, pExpr);
}
sqlite3ExprDelete(db, pExpr);
sqlite3ExprUnmapAndDelete(pParse, pExpr);
sqlite3IdListDelete(db, pColumns);
return pList;
}
@@ -1821,6 +1802,7 @@ int sqlite3ExprIdToTrueFalse(Expr *pExpr){
|| sqlite3StrICmp(pExpr->u.zToken, "false")==0)
){
pExpr->op = TK_TRUEFALSE;
ExprSetProperty(pExpr, pExpr->u.zToken[4]==0 ? EP_IsTrue : EP_IsFalse);
return 1;
}
return 0;
@@ -1831,12 +1813,40 @@ int sqlite3ExprIdToTrueFalse(Expr *pExpr){
** and 0 if it is FALSE.
*/
int sqlite3ExprTruthValue(const Expr *pExpr){
pExpr = sqlite3ExprSkipCollate((Expr*)pExpr);
assert( pExpr->op==TK_TRUEFALSE );
assert( sqlite3StrICmp(pExpr->u.zToken,"true")==0
|| sqlite3StrICmp(pExpr->u.zToken,"false")==0 );
return pExpr->u.zToken[4]==0;
}
/*
** If pExpr is an AND or OR expression, try to simplify it by eliminating
** terms that are always true or false. Return the simplified expression.
** Or return the original expression if no simplification is possible.
**
** Examples:
**
** (x<10) AND true => (x<10)
** (x<10) AND false => false
** (x<10) AND (y=22 OR false) => (x<10) AND (y=22)
** (x<10) AND (y=22 OR true) => (x<10)
** (y=22) OR true => true
*/
Expr *sqlite3ExprSimplifiedAndOr(Expr *pExpr){
assert( pExpr!=0 );
if( pExpr->op==TK_AND || pExpr->op==TK_OR ){
Expr *pRight = sqlite3ExprSimplifiedAndOr(pExpr->pRight);
Expr *pLeft = sqlite3ExprSimplifiedAndOr(pExpr->pLeft);
if( ExprAlwaysTrue(pLeft) || ExprAlwaysFalse(pRight) ){
pExpr = pExpr->op==TK_AND ? pRight : pLeft;
}else if( ExprAlwaysTrue(pRight) || ExprAlwaysFalse(pLeft) ){
pExpr = pExpr->op==TK_AND ? pLeft : pRight;
}
}
return pExpr;
}
/*
** These routines are Walker callbacks used to check expressions to
@@ -2081,7 +2091,7 @@ int sqlite3ExprContainsSubquery(Expr *p){
*/
int sqlite3ExprIsInteger(Expr *p, int *pValue){
int rc = 0;
if( p==0 ) return 0; /* Can only happen following on OOM */
if( NEVER(p==0) ) return 0; /* Used to only happen following on OOM */
/* If an expression is an integer literal that fits in a signed 32-bit
** integer, then the EP_IntValue flag will have already been set */
@@ -2810,6 +2820,7 @@ void sqlite3CodeRhsOfIN(
*/
if( addrOnce && !sqlite3ExprIsConstant(pE2) ){
sqlite3VdbeChangeToNoop(v, addrOnce);
ExprClearProperty(pExpr, EP_Subrtn);
addrOnce = 0;
}
@@ -3376,7 +3387,8 @@ void sqlite3ExprCodeMove(Parse *pParse, int iFrom, int iTo, int nReg){
** register iReg. The caller must ensure that iReg already contains
** the correct value for the expression.
*/
static void exprToRegister(Expr *p, int iReg){
static void exprToRegister(Expr *pExpr, int iReg){
Expr *p = sqlite3ExprSkipCollate(pExpr);
p->op2 = p->op;
p->op = TK_REGISTER;
p->iTable = iReg;
@@ -4428,18 +4440,23 @@ void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){
if( NEVER(pExpr==0) ) return; /* No way this can happen */
op = pExpr->op;
switch( op ){
case TK_AND: {
int d2 = sqlite3VdbeMakeLabel(pParse);
testcase( jumpIfNull==0 );
sqlite3ExprIfFalse(pParse, pExpr->pLeft, d2,jumpIfNull^SQLITE_JUMPIFNULL);
sqlite3ExprIfTrue(pParse, pExpr->pRight, dest, jumpIfNull);
sqlite3VdbeResolveLabel(v, d2);
break;
}
case TK_AND:
case TK_OR: {
testcase( jumpIfNull==0 );
sqlite3ExprIfTrue(pParse, pExpr->pLeft, dest, jumpIfNull);
sqlite3ExprIfTrue(pParse, pExpr->pRight, dest, jumpIfNull);
Expr *pAlt = sqlite3ExprSimplifiedAndOr(pExpr);
if( pAlt!=pExpr ){
sqlite3ExprIfTrue(pParse, pAlt, dest, jumpIfNull);
}else if( op==TK_AND ){
int d2 = sqlite3VdbeMakeLabel(pParse);
testcase( jumpIfNull==0 );
sqlite3ExprIfFalse(pParse, pExpr->pLeft, d2,
jumpIfNull^SQLITE_JUMPIFNULL);
sqlite3ExprIfTrue(pParse, pExpr->pRight, dest, jumpIfNull);
sqlite3VdbeResolveLabel(v, d2);
}else{
testcase( jumpIfNull==0 );
sqlite3ExprIfTrue(pParse, pExpr->pLeft, dest, jumpIfNull);
sqlite3ExprIfTrue(pParse, pExpr->pRight, dest, jumpIfNull);
}
break;
}
case TK_NOT: {
@@ -4525,9 +4542,9 @@ void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){
#endif
default: {
default_expr:
if( exprAlwaysTrue(pExpr) ){
if( ExprAlwaysTrue(pExpr) ){
sqlite3VdbeGoto(v, dest);
}else if( exprAlwaysFalse(pExpr) ){
}else if( ExprAlwaysFalse(pExpr) ){
/* No-op */
}else{
r1 = sqlite3ExprCodeTemp(pParse, pExpr, &regFree1);
@@ -4595,18 +4612,23 @@ void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){
assert( pExpr->op!=TK_GE || op==OP_Lt );
switch( pExpr->op ){
case TK_AND: {
testcase( jumpIfNull==0 );
sqlite3ExprIfFalse(pParse, pExpr->pLeft, dest, jumpIfNull);
sqlite3ExprIfFalse(pParse, pExpr->pRight, dest, jumpIfNull);
break;
}
case TK_AND:
case TK_OR: {
int d2 = sqlite3VdbeMakeLabel(pParse);
testcase( jumpIfNull==0 );
sqlite3ExprIfTrue(pParse, pExpr->pLeft, d2, jumpIfNull^SQLITE_JUMPIFNULL);
sqlite3ExprIfFalse(pParse, pExpr->pRight, dest, jumpIfNull);
sqlite3VdbeResolveLabel(v, d2);
Expr *pAlt = sqlite3ExprSimplifiedAndOr(pExpr);
if( pAlt!=pExpr ){
sqlite3ExprIfFalse(pParse, pAlt, dest, jumpIfNull);
}else if( pExpr->op==TK_AND ){
testcase( jumpIfNull==0 );
sqlite3ExprIfFalse(pParse, pExpr->pLeft, dest, jumpIfNull);
sqlite3ExprIfFalse(pParse, pExpr->pRight, dest, jumpIfNull);
}else{
int d2 = sqlite3VdbeMakeLabel(pParse);
testcase( jumpIfNull==0 );
sqlite3ExprIfTrue(pParse, pExpr->pLeft, d2,
jumpIfNull^SQLITE_JUMPIFNULL);
sqlite3ExprIfFalse(pParse, pExpr->pRight, dest, jumpIfNull);
sqlite3VdbeResolveLabel(v, d2);
}
break;
}
case TK_NOT: {
@@ -4695,9 +4717,9 @@ void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){
#endif
default: {
default_expr:
if( exprAlwaysFalse(pExpr) ){
if( ExprAlwaysFalse(pExpr) ){
sqlite3VdbeGoto(v, dest);
}else if( exprAlwaysTrue(pExpr) ){
}else if( ExprAlwaysTrue(pExpr) ){
/* no-op */
}else{
r1 = sqlite3ExprCodeTemp(pParse, pExpr, &regFree1);
@@ -4853,6 +4875,7 @@ int sqlite3ExprCompare(Parse *pParse, Expr *pA, Expr *pB, int iTab){
&& (combinedFlags & EP_Reduced)==0
){
if( pA->iColumn!=pB->iColumn ) return 2;
if( pA->op2!=pB->op2 ) return 2;
if( pA->iTable!=pB->iTable
&& (pA->iTable!=iTab || NEVER(pB->iTable>=0)) ) return 2;
}
@@ -4900,6 +4923,76 @@ int sqlite3ExprCompareSkip(Expr *pA, Expr *pB, int iTab){
iTab);
}
/*
** Return non-zero if Expr p can only be true if pNN is not NULL.
*/
static int exprImpliesNotNull(
Parse *pParse, /* Parsing context */
Expr *p, /* The expression to be checked */
Expr *pNN, /* The expression that is NOT NULL */
int iTab, /* Table being evaluated */
int seenNot /* True if p is an operand of NOT */
){
assert( p );
assert( pNN );
if( sqlite3ExprCompare(pParse, p, pNN, iTab)==0 ) return 1;
switch( p->op ){
case TK_IN: {
if( seenNot && ExprHasProperty(p, EP_xIsSelect) ) return 0;
assert( ExprHasProperty(p,EP_xIsSelect)
|| (p->x.pList!=0 && p->x.pList->nExpr>0) );
return exprImpliesNotNull(pParse, p->pLeft, pNN, iTab, seenNot);
}
case TK_BETWEEN: {
ExprList *pList = p->x.pList;
assert( pList!=0 );
assert( pList->nExpr==2 );
if( seenNot ) return 0;
if( exprImpliesNotNull(pParse, pList->a[0].pExpr, pNN, iTab, seenNot)
|| exprImpliesNotNull(pParse, pList->a[1].pExpr, pNN, iTab, seenNot)
){
return 1;
}
return exprImpliesNotNull(pParse, p->pLeft, pNN, iTab, seenNot);
}
case TK_EQ:
case TK_NE:
case TK_LT:
case TK_LE:
case TK_GT:
case TK_GE:
case TK_PLUS:
case TK_MINUS:
case TK_STAR:
case TK_REM:
case TK_BITAND:
case TK_BITOR:
case TK_SLASH:
case TK_LSHIFT:
case TK_RSHIFT:
case TK_CONCAT: {
if( exprImpliesNotNull(pParse, p->pRight, pNN, iTab, seenNot) ) return 1;
/* Fall thru into the next case */
}
case TK_SPAN:
case TK_COLLATE:
case TK_BITNOT:
case TK_UPLUS:
case TK_UMINUS: {
return exprImpliesNotNull(pParse, p->pLeft, pNN, iTab, seenNot);
}
case TK_TRUTH: {
if( seenNot ) return 0;
if( p->op2!=TK_IS ) return 0;
return exprImpliesNotNull(pParse, p->pLeft, pNN, iTab, seenNot);
}
case TK_NOT: {
return exprImpliesNotNull(pParse, p->pLeft, pNN, iTab, 1);
}
}
return 0;
}
/*
** Return true if we can prove the pE2 will always be true if pE1 is
** true. Return false if we cannot complete the proof or if pE2 might
@@ -4935,10 +5028,10 @@ int sqlite3ExprImpliesExpr(Parse *pParse, Expr *pE1, Expr *pE2, int iTab){
){
return 1;
}
if( pE2->op==TK_NOTNULL && pE1->op!=TK_ISNULL && pE1->op!=TK_IS ){
Expr *pX = sqlite3ExprSkipCollate(pE1->pLeft);
testcase( pX!=pE1->pLeft );
if( sqlite3ExprCompare(pParse, pX, pE2->pLeft, iTab)==0 ) return 1;
if( pE2->op==TK_NOTNULL
&& exprImpliesNotNull(pParse, pE1, pE2->pLeft, iTab, 0)
){
return 1;
}
return 0;
}
+5 -5
View File
@@ -591,7 +591,7 @@ static void fkScanChildren(
zCol = pFKey->pFrom->aCol[iCol].zName;
pRight = sqlite3Expr(db, TK_ID, zCol);
pEq = sqlite3PExpr(pParse, TK_EQ, pLeft, pRight);
pWhere = sqlite3ExprAnd(db, pWhere, pEq);
pWhere = sqlite3ExprAnd(pParse, pWhere, pEq);
}
/* If the child table is the same as the parent table, then add terms
@@ -625,11 +625,11 @@ static void fkScanChildren(
pLeft = exprTableRegister(pParse, pTab, regData, iCol);
pRight = sqlite3Expr(db, TK_ID, pTab->aCol[iCol].zName);
pEq = sqlite3PExpr(pParse, TK_IS, pLeft, pRight);
pAll = sqlite3ExprAnd(db, pAll, pEq);
pAll = sqlite3ExprAnd(pParse, pAll, pEq);
}
pNe = sqlite3PExpr(pParse, TK_NOT, pAll, 0);
}
pWhere = sqlite3ExprAnd(db, pWhere, pNe);
pWhere = sqlite3ExprAnd(pParse, pWhere, pNe);
}
/* Resolve the references in the WHERE clause. */
@@ -1235,7 +1235,7 @@ static Trigger *fkActionTrigger(
sqlite3ExprAlloc(db, TK_ID, &tToCol, 0)),
sqlite3ExprAlloc(db, TK_ID, &tFromCol, 0)
);
pWhere = sqlite3ExprAnd(db, pWhere, pEq);
pWhere = sqlite3ExprAnd(pParse, pWhere, pEq);
/* For ON UPDATE, construct the next term of the WHEN clause.
** The final WHEN clause will be like this:
@@ -1251,7 +1251,7 @@ static Trigger *fkActionTrigger(
sqlite3ExprAlloc(db, TK_ID, &tNew, 0),
sqlite3ExprAlloc(db, TK_ID, &tToCol, 0))
);
pWhen = sqlite3ExprAnd(db, pWhen, pEq);
pWhen = sqlite3ExprAnd(pParse, pWhen, pEq);
}
if( action!=OE_Restrict && (action!=OE_Cascade || pChanges) ){
+14 -30
View File
@@ -16,6 +16,7 @@
#include "sqliteInt.h"
#include <stdlib.h>
#include <assert.h>
#include <math.h>
#include "vdbeInt.h"
/*
@@ -386,10 +387,10 @@ static void roundFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
** handle the rounding directly,
** otherwise use printf.
*/
if( n==0 && r>=0 && r<LARGEST_INT64-1 ){
r = (double)((sqlite_int64)(r+0.5));
}else if( n==0 && r<0 && (-r)<LARGEST_INT64-1 ){
r = -(double)((sqlite_int64)((-r)+0.5));
if( r<-4503599627370496.0 || r>+4503599627370496.0 ){
/* The value has no fractional part so there is nothing to round */
}else if( n==0 ){
r = (double)((sqlite_int64)(r+(r<0?-0.5:+0.5)));
}else{
zBuf = sqlite3_mprintf("%.*f",n,r);
if( zBuf==0 ){
@@ -843,8 +844,6 @@ static void likeFunc(
return;
}
#endif
zB = sqlite3_value_text(argv[0]);
zA = sqlite3_value_text(argv[1]);
/* Limit the length of the LIKE or GLOB pattern to avoid problems
** of deep recursion and N*N behavior in patternCompare().
@@ -856,8 +855,6 @@ static void likeFunc(
sqlite3_result_error(context, "LIKE or GLOB pattern too complex", -1);
return;
}
assert( zB==sqlite3_value_text(argv[0]) ); /* Encoding did not change */
if( argc==3 ){
/* The escape character string must consist of a single UTF-8 character.
** Otherwise, return an error.
@@ -873,6 +870,8 @@ static void likeFunc(
}else{
escape = pInfo->matchSet;
}
zB = sqlite3_value_text(argv[0]);
zA = sqlite3_value_text(argv[1]);
if( zA && zB ){
#ifdef SQLITE_TEST
sqlite3_like_count++;
@@ -1811,39 +1810,24 @@ void sqlite3RegisterPerConnectionBuiltinFunctions(sqlite3 *db){
}
/*
** Set the LIKEOPT flag on the 2-argument function with the given name.
*/
static void setLikeOptFlag(sqlite3 *db, const char *zName, u8 flagVal){
FuncDef *pDef;
pDef = sqlite3FindFunction(db, zName, 2, SQLITE_UTF8, 0);
if( ALWAYS(pDef) ){
pDef->funcFlags |= flagVal;
}
pDef = sqlite3FindFunction(db, zName, 3, SQLITE_UTF8, 0);
if( pDef ){
pDef->funcFlags |= flagVal;
}
}
/*
** Register the built-in LIKE and GLOB functions. The caseSensitive
** Re-register the built-in LIKE functions. The caseSensitive
** parameter determines whether or not the LIKE operator is case
** sensitive. GLOB is always case sensitive.
** sensitive.
*/
void sqlite3RegisterLikeFunctions(sqlite3 *db, int caseSensitive){
struct compareInfo *pInfo;
int flags;
if( caseSensitive ){
pInfo = (struct compareInfo*)&likeInfoAlt;
flags = SQLITE_FUNC_LIKE | SQLITE_FUNC_CASE;
}else{
pInfo = (struct compareInfo*)&likeInfoNorm;
flags = SQLITE_FUNC_LIKE;
}
sqlite3CreateFunc(db, "like", 2, SQLITE_UTF8, pInfo, likeFunc, 0, 0, 0, 0, 0);
sqlite3CreateFunc(db, "like", 3, SQLITE_UTF8, pInfo, likeFunc, 0, 0, 0, 0, 0);
sqlite3CreateFunc(db, "glob", 2, SQLITE_UTF8,
(struct compareInfo*)&globInfo, likeFunc, 0, 0, 0, 0, 0);
setLikeOptFlag(db, "glob", SQLITE_FUNC_LIKE | SQLITE_FUNC_CASE);
setLikeOptFlag(db, "like",
caseSensitive ? (SQLITE_FUNC_LIKE | SQLITE_FUNC_CASE) : SQLITE_FUNC_LIKE);
sqlite3FindFunction(db, "like", 2, SQLITE_UTF8, 0)->funcFlags |= flags;
sqlite3FindFunction(db, "like", 3, SQLITE_UTF8, 0)->funcFlags |= flags;
}
/*
+8 -1
View File
@@ -153,8 +153,15 @@ const unsigned char sqlite3CtypeMap[256] = {
** SQLITE_ALLOW_COVERING_INDEX_SCAN compile-time option, or is "on" if
** that compile-time option is omitted.
*/
#ifndef SQLITE_ALLOW_COVERING_INDEX_SCAN
#if !defined(SQLITE_ALLOW_COVERING_INDEX_SCAN)
# define SQLITE_ALLOW_COVERING_INDEX_SCAN 1
#else
# if !SQLITE_ALLOW_COVERING_INDEX_SCAN
# error "Compile-time disabling of covering index scan using the\
-DSQLITE_ALLOW_COVERING_INDEX_SCAN=0 option is deprecated.\
Contact SQLite developers if this is a problem for you, and\
delete this #error macro to continue with your build."
# endif
#endif
/* The minimum PMA size is set to this value multiplied by the database
+22 -14
View File
@@ -814,7 +814,7 @@ void sqlite3Insert(
int nIdx;
nIdx = sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenWrite, 0, -1, 0,
&iDataCur, &iIdxCur);
aRegIdx = sqlite3DbMallocRawNN(db, sizeof(int)*(nIdx+1));
aRegIdx = sqlite3DbMallocRawNN(db, sizeof(int)*(nIdx+2));
if( aRegIdx==0 ){
goto insert_cleanup;
}
@@ -823,6 +823,7 @@ void sqlite3Insert(
aRegIdx[i] = ++pParse->nMem;
pParse->nMem += pIdx->nColumn;
}
aRegIdx[i] = ++pParse->nMem; /* Register to store the table record */
}
#ifndef SQLITE_OMIT_UPSERT
if( pUpsert ){
@@ -1226,6 +1227,14 @@ int sqlite3ExprReferencesUpdatedColumn(
** the same as the order of indices on the linked list of indices
** at pTab->pIndex.
**
** (2019-05-07) The generated code also creates a new record for the
** main table, if pTab is a rowid table, and stores that record in the
** register identified by aRegIdx[nIdx] - in other words in the first
** entry of aRegIdx[] past the last index. It is important that the
** record be generated during constraint checks to avoid affinity changes
** to the register content that occur after constraint checks but before
** the new record is inserted.
**
** The caller must have already opened writeable cursors on the main
** table and all applicable indices (that is to say, all indices for which
** aRegIdx[] is not zero). iDataCur is the cursor for the main table when
@@ -1416,7 +1425,7 @@ void sqlite3GenerateConstraintChecks(
}else{
char *zName = pCheck->a[i].zName;
if( zName==0 ) zName = pTab->zName;
if( onError==OE_Replace ) onError = OE_Abort; /* IMP: R-15569-63625 */
if( onError==OE_Replace ) onError = OE_Abort; /* IMP: R-26383-51744 */
sqlite3HaltConstraint(pParse, SQLITE_CONSTRAINT_CHECK,
onError, zName, P4_TRANSIENT,
P5_ConstraintCheck);
@@ -1845,6 +1854,16 @@ void sqlite3GenerateConstraintChecks(
sqlite3VdbeJumpHere(v, ipkBottom);
}
/* Generate the table record */
if( HasRowid(pTab) ){
int regRec = aRegIdx[ix];
sqlite3VdbeAddOp3(v, OP_MakeRecord, regNewData+1, pTab->nCol, regRec);
sqlite3SetMakeRecordP5(v, pTab);
if( !bAffinityDone ){
sqlite3TableAffinity(v, pTab, 0);
}
}
*pbMayReplace = seenReplace;
VdbeModuleComment((v, "END: GenCnstCks(%d)", seenReplace));
}
@@ -1894,10 +1913,7 @@ void sqlite3CompleteInsertion(
Vdbe *v; /* Prepared statements under construction */
Index *pIdx; /* An index being inserted or updated */
u8 pik_flags; /* flag values passed to the btree insert */
int regData; /* Content registers (after the rowid) */
int regRec; /* Register holding assembled record for the table */
int i; /* Loop counter */
u8 bAffinityDone = 0; /* True if OP_Affinity has been run already */
assert( update_flags==0
|| update_flags==OPFLAG_ISUPDATE
@@ -1909,7 +1925,6 @@ void sqlite3CompleteInsertion(
assert( pTab->pSelect==0 ); /* This table is not a VIEW */
for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
if( aRegIdx[i]==0 ) continue;
bAffinityDone = 1;
if( pIdx->pPartIdxWhere ){
sqlite3VdbeAddOp2(v, OP_IsNull, aRegIdx[i], sqlite3VdbeCurrentAddr(v)+2);
VdbeCoverage(v);
@@ -1937,13 +1952,6 @@ void sqlite3CompleteInsertion(
sqlite3VdbeChangeP5(v, pik_flags);
}
if( !HasRowid(pTab) ) return;
regData = regNewData + 1;
regRec = sqlite3GetTempReg(pParse);
sqlite3VdbeAddOp3(v, OP_MakeRecord, regData, pTab->nCol, regRec);
sqlite3SetMakeRecordP5(v, pTab);
if( !bAffinityDone ){
sqlite3TableAffinity(v, pTab, 0);
}
if( pParse->nested ){
pik_flags = 0;
}else{
@@ -1956,7 +1964,7 @@ void sqlite3CompleteInsertion(
if( useSeekResult ){
pik_flags |= OPFLAG_USESEEKRESULT;
}
sqlite3VdbeAddOp3(v, OP_Insert, iDataCur, regRec, regNewData);
sqlite3VdbeAddOp3(v, OP_Insert, iDataCur, aRegIdx[i], regNewData);
if( !pParse->nested ){
sqlite3VdbeAppendP4(v, pTab, P4_TABLE);
}
+70 -30
View File
@@ -845,6 +845,9 @@ int sqlite3_db_config(sqlite3 *db, int op, ...){
{ SQLITE_DBCONFIG_DEFENSIVE, SQLITE_Defensive },
{ SQLITE_DBCONFIG_WRITABLE_SCHEMA, SQLITE_WriteSchema|
SQLITE_NoSchemaError },
{ SQLITE_DBCONFIG_LEGACY_ALTER_TABLE, SQLITE_LegacyAlter },
{ SQLITE_DBCONFIG_DQS_DDL, SQLITE_DqsDDL },
{ SQLITE_DBCONFIG_DQS_DML, SQLITE_DqsDML },
};
unsigned int i;
rc = SQLITE_ERROR; /* IMP: R-42790-23372 */
@@ -875,28 +878,17 @@ int sqlite3_db_config(sqlite3 *db, int op, ...){
return rc;
}
/*
** Return true if the buffer z[0..n-1] contains all spaces.
*/
static int allSpaces(const char *z, int n){
while( n>0 && z[n-1]==' ' ){ n--; }
return n==0;
}
/*
** This is the default collating function named "BINARY" which is always
** available.
**
** If the padFlag argument is not NULL then space padding at the end
** of strings is ignored. This implements the RTRIM collation.
*/
static int binCollFunc(
void *padFlag,
void *NotUsed,
int nKey1, const void *pKey1,
int nKey2, const void *pKey2
){
int rc, n;
UNUSED_PARAMETER(NotUsed);
n = nKey1<nKey2 ? nKey1 : nKey2;
/* EVIDENCE-OF: R-65033-28449 The built-in BINARY collation compares
** strings byte by byte using the memcmp() function from the standard C
@@ -904,29 +896,33 @@ static int binCollFunc(
assert( pKey1 && pKey2 );
rc = memcmp(pKey1, pKey2, n);
if( rc==0 ){
if( padFlag
&& allSpaces(((char*)pKey1)+n, nKey1-n)
&& allSpaces(((char*)pKey2)+n, nKey2-n)
){
/* EVIDENCE-OF: R-31624-24737 RTRIM is like BINARY except that extra
** spaces at the end of either string do not change the result. In other
** words, strings will compare equal to one another as long as they
** differ only in the number of spaces at the end.
*/
}else{
rc = nKey1 - nKey2;
}
rc = nKey1 - nKey2;
}
return rc;
}
/*
** This is the collating function named "RTRIM" which is always
** available. Ignore trailing spaces.
*/
static int rtrimCollFunc(
void *pUser,
int nKey1, const void *pKey1,
int nKey2, const void *pKey2
){
const u8 *pK1 = (const u8*)pKey1;
const u8 *pK2 = (const u8*)pKey2;
while( nKey1 && pK1[nKey1-1]==' ' ) nKey1--;
while( nKey2 && pK2[nKey2-1]==' ' ) nKey2--;
return binCollFunc(pUser, nKey1, pKey1, nKey2, pKey2);
}
/*
** Return true if CollSeq is the default built-in BINARY.
*/
int sqlite3IsBinary(const CollSeq *p){
assert( p==0 || p->xCmp!=binCollFunc || p->pUser!=0
|| strcmp(p->zName,"BINARY")==0 );
return p==0 || (p->xCmp==binCollFunc && p->pUser==0);
assert( p==0 || p->xCmp!=binCollFunc || strcmp(p->zName,"BINARY")==0 );
return p==0 || p->xCmp==binCollFunc;
}
/*
@@ -3077,7 +3073,35 @@ static int openDatabase(
db->szMmap = sqlite3GlobalConfig.szMmap;
db->nextPagesize = 0;
db->nMaxSorterMmap = 0x7FFFFFFF;
db->flags |= SQLITE_ShortColNames | SQLITE_EnableTrigger | SQLITE_CacheSpill
db->flags |= SQLITE_ShortColNames
| SQLITE_EnableTrigger
| SQLITE_CacheSpill
/* The SQLITE_DQS compile-time option determines the default settings
** for SQLITE_DBCONFIG_DQS_DDL and SQLITE_DBCONFIG_DQS_DML.
**
** SQLITE_DQS SQLITE_DBCONFIG_DQS_DDL SQLITE_DBCONFIG_DQS_DML
** ---------- ----------------------- -----------------------
** undefined on on
** 3 on on
** 2 on off
** 1 off on
** 0 off off
**
** Legacy behavior is 3 (double-quoted string literals are allowed anywhere)
** and so that is the default. But developers are encouranged to use
** -DSQLITE_DQS=0 (best) or -DSQLITE_DQS=1 (second choice) if possible.
*/
#if !defined(SQLITE_DQS)
# define SQLITE_DQS 3
#endif
#if (SQLITE_DQS&1)==1
| SQLITE_DqsDML
#endif
#if (SQLITE_DQS&2)==2
| SQLITE_DqsDDL
#endif
#if !defined(SQLITE_DEFAULT_AUTOMATIC_INDEX) || SQLITE_DEFAULT_AUTOMATIC_INDEX
| SQLITE_AutoIndex
#endif
@@ -3128,7 +3152,7 @@ static int openDatabase(
createCollation(db, sqlite3StrBINARY, SQLITE_UTF16BE, 0, binCollFunc, 0);
createCollation(db, sqlite3StrBINARY, SQLITE_UTF16LE, 0, binCollFunc, 0);
createCollation(db, "NOCASE", SQLITE_UTF8, 0, nocaseCollatingFunc, 0);
createCollation(db, "RTRIM", SQLITE_UTF8, (void*)1, binCollFunc, 0);
createCollation(db, "RTRIM", SQLITE_UTF8, 0, rtrimCollFunc, 0);
if( db->mallocFailed ){
goto opendb_out;
}
@@ -4111,6 +4135,22 @@ int sqlite3_test_control(int op, ...){
break;
}
#endif /* defined(YYCOVERAGE) */
/* sqlite3_test_control(SQLITE_TESTCTRL_RESULT_INTREAL, sqlite3_context*);
**
** This test-control causes the most recent sqlite3_result_int64() value
** to be interpreted as a MEM_IntReal instead of as an MEM_Int. Normally,
** MEM_IntReal values only arise during an INSERT operation of integer
** values into a REAL column, so they can be challenging to test. This
** test-control enables us to write an intreal() SQL function that can
** inject an intreal() value at arbitrary places in an SQL statement,
** for testing purposes.
*/
case SQLITE_TESTCTRL_RESULT_INTREAL: {
sqlite3_context *pCtx = va_arg(ap, sqlite3_context*);
sqlite3ResultIntReal(pCtx);
break;
}
}
va_end(ap);
#endif /* SQLITE_UNTESTABLE */
+5
View File
@@ -33,4 +33,9 @@
#pragma warning(disable : 4706)
#endif /* defined(_MSC_VER) */
#if defined(_MSC_VER) && !defined(_WIN64)
#undef SQLITE_4_BYTE_ALIGNED_MALLOC
#define SQLITE_4_BYTE_ALIGNED_MALLOC
#endif /* defined(_MSC_VER) && !defined(_WIN64) */
#endif /* SQLITE_MSVC_H */
+14 -12
View File
@@ -301,6 +301,10 @@ scanpt(A) ::= . {
assert( yyLookahead!=YYNOCODE );
A = yyLookaheadToken.z;
}
scantok(A) ::= . {
assert( yyLookahead!=YYNOCODE );
A = yyLookaheadToken;
}
// "carglist" is a list of additional constraints that come after the
// column name and column type in a CREATE TABLE statement.
@@ -308,17 +312,17 @@ scanpt(A) ::= . {
carglist ::= carglist ccons.
carglist ::= .
ccons ::= CONSTRAINT nm(X). {pParse->constraintName = X;}
ccons ::= DEFAULT scanpt(A) term(X) scanpt(Z).
{sqlite3AddDefaultValue(pParse,X,A,Z);}
ccons ::= DEFAULT scantok(A) term(X).
{sqlite3AddDefaultValue(pParse,X,A.z,&A.z[A.n]);}
ccons ::= DEFAULT LP(A) expr(X) RP(Z).
{sqlite3AddDefaultValue(pParse,X,A.z+1,Z.z);}
ccons ::= DEFAULT PLUS(A) term(X) scanpt(Z).
{sqlite3AddDefaultValue(pParse,X,A.z,Z);}
ccons ::= DEFAULT MINUS(A) term(X) scanpt(Z). {
ccons ::= DEFAULT PLUS(A) scantok(Z) term(X).
{sqlite3AddDefaultValue(pParse,X,A.z,&Z.z[Z.n]);}
ccons ::= DEFAULT MINUS(A) scantok(Z) term(X). {
Expr *p = sqlite3PExpr(pParse, TK_UMINUS, X, 0);
sqlite3AddDefaultValue(pParse,p,A.z,Z);
sqlite3AddDefaultValue(pParse,p,A.z,&Z.z[Z.n]);
}
ccons ::= DEFAULT scanpt id(X). {
ccons ::= DEFAULT scantok id(X). {
Expr *p = tokenExpr(pParse, TK_STRING, X);
if( p ){
sqlite3ExprIdToTrueFalse(p);
@@ -1064,7 +1068,7 @@ expr(A) ::= LP nexprlist(X) COMMA expr(Y) RP. {
}
}
expr(A) ::= expr(A) AND(OP) expr(Y). {A=sqlite3PExpr(pParse,@OP,A,Y);}
expr(A) ::= expr(A) AND expr(Y). {A=sqlite3ExprAnd(pParse,A,Y);}
expr(A) ::= expr(A) OR(OP) expr(Y). {A=sqlite3PExpr(pParse,@OP,A,Y);}
expr(A) ::= expr(A) LT|GT|GE|LE(OP) expr(Y).
{A=sqlite3PExpr(pParse,@OP,A,Y);}
@@ -1169,10 +1173,8 @@ expr(A) ::= expr(A) between_op(N) expr(X) AND expr(Y). [BETWEEN] {
** simplify to constants 0 (false) and 1 (true), respectively,
** regardless of the value of expr1.
*/
if( IN_RENAME_OBJECT==0 ){
sqlite3ExprDelete(pParse->db, A);
A = sqlite3ExprAlloc(pParse->db, TK_INTEGER,&sqlite3IntTokens[N],1);
}
sqlite3ExprUnmapAndDelete(pParse, A);
A = sqlite3ExprAlloc(pParse->db, TK_INTEGER,&sqlite3IntTokens[N],1);
}else if( Y->nExpr==1 ){
/* Expressions of the form:
**
+4 -3
View File
@@ -243,9 +243,10 @@ static int numberOfCachePages(PCache *p){
** suggested cache size is set to N. */
return p->szCache;
}else{
/* IMPLEMENTATION-OF: R-61436-13639 If the argument N is negative, then
** the number of cache pages is adjusted to use approximately abs(N*1024)
** bytes of memory. */
/* IMPLEMANTATION-OF: R-59858-46238 If the argument N is negative, then the
** number of cache pages is adjusted to be a number of pages that would
** use approximately abs(N*1024) bytes of memory based on the current
** page size. */
return (int)((-1024*(i64)p->szCache)/(p->szPage+p->szExtra));
}
}
+1 -1
View File
@@ -778,6 +778,7 @@ static sqlite3_pcache *pcache1Create(int szPage, int szExtra, int bPurgeable){
}else{
pGroup = &pcache1.grp;
}
pcache1EnterMutex(pGroup);
if( pGroup->lru.isAnchor==0 ){
pGroup->lru.isAnchor = 1;
pGroup->lru.pLruPrev = pGroup->lru.pLruNext = &pGroup->lru;
@@ -787,7 +788,6 @@ static sqlite3_pcache *pcache1Create(int szPage, int szExtra, int bPurgeable){
pCache->szExtra = szExtra;
pCache->szAlloc = szPage + szExtra + ROUND8(sizeof(PgHdr1));
pCache->bPurgeable = (bPurgeable ? 1 : 0);
pcache1EnterMutex(pGroup);
pcache1ResizeHash(pCache);
if( bPurgeable ){
pCache->nMin = 10;
+27 -18
View File
@@ -659,6 +659,11 @@ void sqlite3Pragma(
** then do a query */
eMode = PAGER_JOURNALMODE_QUERY;
}
if( eMode==PAGER_JOURNALMODE_OFF && (db->flags & SQLITE_Defensive)!=0 ){
/* Do not allow journal-mode "OFF" in defensive since the database
** can become corrupted using ordinary SQL when the journal is off */
eMode = PAGER_JOURNALMODE_QUERY;
}
}
if( eMode==PAGER_JOURNALMODE_QUERY && pId2->n==0 ){
/* Convert "PRAGMA journal_mode" into "PRAGMA main.journal_mode" */
@@ -1436,6 +1441,7 @@ void sqlite3Pragma(
#endif /* !defined(SQLITE_OMIT_TRIGGER) */
#endif /* !defined(SQLITE_OMIT_FOREIGN_KEY) */
#ifndef SQLITE_OMIT_CASE_SENSITIVE_LIKE_PRAGMA
/* Reinstall the LIKE and GLOB functions. The variant of LIKE
** used will be case sensitive or not depending on the RHS.
*/
@@ -1445,6 +1451,7 @@ void sqlite3Pragma(
}
}
break;
#endif /* SQLITE_OMIT_CASE_SENSITIVE_LIKE_PRAGMA */
#ifndef SQLITE_INTEGRITY_CHECK_ERROR_MAX
# define SQLITE_INTEGRITY_CHECK_ERROR_MAX 100
@@ -2138,28 +2145,30 @@ void sqlite3Pragma(
*/
case PragTyp_KEY: {
if( zRight ){
int n = pPragma->iArg<4 ? sqlite3Strlen30(zRight) : -1;
if( (pPragma->iArg & 1)==0 ){
sqlite3_key_v2(db, zDb, zRight, n);
char zBuf[40];
const char *zKey = zRight;
int n;
if( pPragma->iArg==2 || pPragma->iArg==3 ){
u8 iByte;
int i;
for(i=0, iByte=0; i<sizeof(zBuf)*2 && sqlite3Isxdigit(zRight[i]); i++){
iByte = (iByte<<4) + sqlite3HexToInt(zRight[i]);
if( (i&1)!=0 ) zBuf[i/2] = iByte;
}
zKey = zBuf;
n = i/2;
}else{
sqlite3_rekey_v2(db, zDb, zRight, n);
}
}
break;
}
case PragTyp_HEXKEY: {
if( zRight ){
u8 iByte;
int i;
char zKey[40];
for(i=0, iByte=0; i<sizeof(zKey)*2 && sqlite3Isxdigit(zRight[i]); i++){
iByte = (iByte<<4) + sqlite3HexToInt(zRight[i]);
if( (i&1)!=0 ) zKey[i/2] = iByte;
n = pPragma->iArg<4 ? sqlite3Strlen30(zRight) : -1;
}
if( (pPragma->iArg & 1)==0 ){
sqlite3_key_v2(db, zDb, zKey, i/2);
rc = sqlite3_key_v2(db, zDb, zKey, n);
}else{
sqlite3_rekey_v2(db, zDb, zKey, i/2);
rc = sqlite3_rekey_v2(db, zDb, zKey, n);
}
if( rc==SQLITE_OK && n!=0 ){
sqlite3VdbeSetNumCols(v, 1);
sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "ok", SQLITE_STATIC);
returnSingleText(v, "ok");
}
}
break;
+7 -6
View File
@@ -46,10 +46,9 @@
#define PragTyp_WAL_AUTOCHECKPOINT 38
#define PragTyp_WAL_CHECKPOINT 39
#define PragTyp_ACTIVATE_EXTENSIONS 40
#define PragTyp_HEXKEY 41
#define PragTyp_KEY 42
#define PragTyp_LOCK_STATUS 43
#define PragTyp_STATS 44
#define PragTyp_KEY 41
#define PragTyp_LOCK_STATUS 42
#define PragTyp_STATS 43
/* Property flags associated with various pragma. */
#define PragFlg_NeedSchema 0x01 /* Force schema load before running */
@@ -178,11 +177,13 @@ static const PragmaName aPragmaName[] = {
/* ColNames: */ 0, 0,
/* iArg: */ 0 },
#endif
#if !defined(SQLITE_OMIT_CASE_SENSITIVE_LIKE_PRAGMA)
{/* zName: */ "case_sensitive_like",
/* ePragTyp: */ PragTyp_CASE_SENSITIVE_LIKE,
/* ePragFlg: */ PragFlg_NoColumns,
/* ColNames: */ 0, 0,
/* iArg: */ 0 },
#endif
{/* zName: */ "cell_size_check",
/* ePragTyp: */ PragTyp_FLAG,
/* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
@@ -320,12 +321,12 @@ static const PragmaName aPragmaName[] = {
#endif
#if defined(SQLITE_HAS_CODEC)
{/* zName: */ "hexkey",
/* ePragTyp: */ PragTyp_HEXKEY,
/* ePragTyp: */ PragTyp_KEY,
/* ePragFlg: */ 0,
/* ColNames: */ 0, 0,
/* iArg: */ 2 },
{/* zName: */ "hexrekey",
/* ePragTyp: */ PragTyp_HEXKEY,
/* ePragTyp: */ PragTyp_KEY,
/* ePragFlg: */ 0,
/* ColNames: */ 0, 0,
/* iArg: */ 3 },
+18 -2
View File
@@ -99,6 +99,12 @@ static const et_info fmtinfo[] = {
{ 'r', 10, 1, etORDINAL, 0, 0 },
};
/* Floating point constants used for rounding */
static const double arRound[] = {
5.0e-01, 5.0e-02, 5.0e-03, 5.0e-04, 5.0e-05,
5.0e-06, 5.0e-07, 5.0e-08, 5.0e-09, 5.0e-10,
};
/*
** If SQLITE_OMIT_FLOATING_POINT is defined, then none of the floating point
** conversions will work.
@@ -517,8 +523,18 @@ void sqlite3_str_vappendf(
}
if( xtype==etGENERIC && precision>0 ) precision--;
testcase( precision>0xfff );
for(idx=precision&0xfff, rounder=0.5; idx>0; idx--, rounder*=0.1){}
if( xtype==etFLOAT ) realvalue += rounder;
idx = precision & 0xfff;
rounder = arRound[idx%10];
while( idx>=10 ){ rounder *= 1.0e-10; idx -= 10; }
if( xtype==etFLOAT ){
double rx = (double)realvalue;
sqlite3_uint64 u;
int ex;
memcpy(&u, &rx, sizeof(u));
ex = -1023 + (int)((u>>52)&0x7ff);
if( precision+(ex/3) < 15 ) rounder += realvalue*3e-16;
realvalue += rounder;
}
/* Normalize realvalue to within 10.0 > realvalue >= 1.0 */
exp = 0;
if( sqlite3IsNaN((double)realvalue) ){
+28 -7
View File
@@ -148,6 +148,23 @@ int sqlite3MatchSpanName(
return 1;
}
/*
** Return TRUE if the double-quoted string mis-feature should be supported.
*/
static int areDoubleQuotedStringsEnabled(sqlite3 *db, NameContext *pTopNC){
if( db->init.busy ) return 1; /* Always support for legacy schemas */
if( pTopNC->ncFlags & NC_IsDDL ){
/* Currently parsing a DDL statement */
if( sqlite3WritableSchema(db) && (db->flags & SQLITE_DqsDML)!=0 ){
return 1;
}
return (db->flags & SQLITE_DqsDDL)!=0;
}else{
/* Currently parsing a DML statement */
return (db->flags & SQLITE_DqsDML)!=0;
}
}
/*
** 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
@@ -476,7 +493,9 @@ static int lookupName(
*/
if( cnt==0 && zTab==0 ){
assert( pExpr->op==TK_ID );
if( ExprHasProperty(pExpr,EP_DblQuoted) ){
if( ExprHasProperty(pExpr,EP_DblQuoted)
&& areDoubleQuotedStringsEnabled(db, pTopNC)
){
/* If a double-quoted identifier does not match any known column name,
** then treat it as a string.
**
@@ -745,7 +764,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
}else{
is_agg = pDef->xFinalize!=0;
if( pDef->funcFlags & SQLITE_FUNC_UNLIKELY ){
ExprSetProperty(pExpr, EP_Unlikely|EP_Skip);
ExprSetProperty(pExpr, EP_Unlikely);
if( n==2 ){
pExpr->iTable = exprProbability(pList->a[1].pExpr);
if( pExpr->iTable<0 ){
@@ -866,7 +885,9 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
#ifndef SQLITE_OMIT_WINDOWFUNC
if( pExpr->y.pWin ){
Select *pSel = pNC->pWinSelect;
sqlite3WindowUpdate(pParse, pSel->pWinDefn, pExpr->y.pWin, pDef);
if( IN_RENAME_OBJECT==0 ){
sqlite3WindowUpdate(pParse, pSel->pWinDefn, pExpr->y.pWin, pDef);
}
sqlite3WalkExprList(pWalker, pExpr->y.pWin->pPartition);
sqlite3WalkExprList(pWalker, pExpr->y.pWin->pOrderBy);
sqlite3WalkExpr(pWalker, pExpr->y.pWin->pFilter);
@@ -926,11 +947,11 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
}
case TK_IS:
case TK_ISNOT: {
Expr *pRight;
Expr *pRight = sqlite3ExprSkipCollate(pExpr->pRight);
assert( !ExprHasProperty(pExpr, EP_Reduced) );
/* Handle special cases of "x IS TRUE", "x IS FALSE", "x IS NOT TRUE",
** and "x IS NOT FALSE". */
if( (pRight = pExpr->pRight)->op==TK_ID ){
if( pRight->op==TK_ID ){
int rc = resolveExprStep(pWalker, pRight);
if( rc==WRC_Abort ) return WRC_Abort;
if( pRight->op==TK_TRUEFALSE ){
@@ -1652,7 +1673,7 @@ int sqlite3ResolveExprNames(
NameContext *pNC, /* Namespace to resolve expressions in. */
Expr *pExpr /* The expression to be analyzed. */
){
u16 savedHasAgg;
int savedHasAgg;
Walker w;
if( pExpr==0 ) return SQLITE_OK;
@@ -1766,7 +1787,7 @@ int sqlite3ResolveSelfReference(
}
sNC.pParse = pParse;
sNC.pSrcList = &sSrc;
sNC.ncFlags = type;
sNC.ncFlags = type | NC_IsDDL;
if( (rc = sqlite3ResolveExprNames(&sNC, pExpr))!=SQLITE_OK ) return rc;
if( pList ) rc = sqlite3ResolveExprListNames(&sNC, pList);
return rc;
+31 -18
View File
@@ -355,7 +355,7 @@ static void addWhereTerm(
ExprSetVVAProperty(pEq, EP_NoReduce);
pEq->iRightJoinTable = (i16)pE2->iTable;
}
*ppWhere = sqlite3ExprAnd(db, *ppWhere, pEq);
*ppWhere = sqlite3ExprAnd(pParse, *ppWhere, pEq);
}
/*
@@ -489,7 +489,7 @@ static int sqliteProcessJoin(Parse *pParse, Select *p){
*/
if( pRight->pOn ){
if( isOuter ) setJoinExpr(pRight->pOn, pRight->iCursor);
p->pWhere = sqlite3ExprAnd(pParse->db, p->pWhere, pRight->pOn);
p->pWhere = sqlite3ExprAnd(pParse, p->pWhere, pRight->pOn);
pRight->pOn = 0;
}
@@ -2096,9 +2096,6 @@ Table *sqlite3ResultSetOfSelect(Parse *pParse, Select *pSelect){
if( pTab==0 ){
return 0;
}
/* The sqlite3ResultSetOfSelect() is only used n contexts where lookaside
** is disabled */
assert( db->lookaside.bDisable );
pTab->nTabRef = 1;
pTab->zName = 0;
pTab->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) );
@@ -2540,6 +2537,7 @@ static int multiSelect(
*/
assert( p && p->pPrior ); /* Calling function guarantees this much */
assert( (p->selFlags & SF_Recursive)==0 || p->op==TK_ALL || p->op==TK_UNION );
assert( p->selFlags & SF_Compound );
db = pParse->db;
pPrior = p->pPrior;
dest = *pDest;
@@ -4034,7 +4032,7 @@ static int flattenSubquery(
if( isLeftJoin>0 ){
setJoinExpr(pWhere, iNewParent);
}
pParent->pWhere = sqlite3ExprAnd(db, pWhere, pParent->pWhere);
pParent->pWhere = sqlite3ExprAnd(pParse, pWhere, pParent->pWhere);
if( db->mallocFailed==0 ){
SubstContext x;
x.pParse = pParse;
@@ -4045,10 +4043,10 @@ static int flattenSubquery(
substSelect(&x, pParent, 0);
}
/* The flattened query is distinct if either the inner or the
** outer query is distinct.
*/
pParent->selFlags |= pSub->selFlags & SF_Distinct;
/* The flattened query is a compound if either the inner or the
** outer query is a compound. */
pParent->selFlags |= pSub->selFlags & SF_Compound;
assert( (pSub->selFlags & SF_Distinct)==0 ); /* restriction (17b) */
/*
** SELECT ... FROM (SELECT ... LIMIT a OFFSET b) LIMIT x OFFSET y;
@@ -4369,9 +4367,9 @@ static int pushDownWhereTerms(
x.pEList = pSubq->pEList;
pNew = substExpr(&x, pNew);
if( pSubq->selFlags & SF_Aggregate ){
pSubq->pHaving = sqlite3ExprAnd(pParse->db, pSubq->pHaving, pNew);
pSubq->pHaving = sqlite3ExprAnd(pParse, pSubq->pHaving, pNew);
}else{
pSubq->pWhere = sqlite3ExprAnd(pParse->db, pSubq->pWhere, pNew);
pSubq->pWhere = sqlite3ExprAnd(pParse, pSubq->pWhere, pNew);
}
pSubq = pSubq->pPrior;
}
@@ -4797,7 +4795,7 @@ int sqlite3ExpandSubquery(Parse *pParse, struct SrcList_item *pFrom){
pTab->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) );
pTab->tabFlags |= TF_Ephemeral;
return SQLITE_OK;
return pParse->nErr ? SQLITE_ERROR : SQLITE_OK;
}
/*
@@ -4843,6 +4841,10 @@ static int selectExpander(Walker *pWalker, Select *p){
if( (selFlags & SF_Expanded)!=0 ){
return WRC_Prune;
}
if( pWalker->eCode ){
/* Renumber selId because it has been copied from a view */
p->selId = ++pParse->nSelect;
}
pTabList = p->pSrc;
pEList = p->pEList;
sqlite3WithPush(pParse, p->pWith, 0);
@@ -4892,12 +4894,15 @@ static int selectExpander(Walker *pWalker, Select *p){
#if !defined(SQLITE_OMIT_VIEW) || !defined (SQLITE_OMIT_VIRTUALTABLE)
if( IsVirtual(pTab) || pTab->pSelect ){
i16 nCol;
u8 eCodeOrig = pWalker->eCode;
if( sqlite3ViewGetColumnNames(pParse, pTab) ) return WRC_Abort;
assert( pFrom->pSelect==0 );
pFrom->pSelect = sqlite3SelectDup(db, pTab->pSelect, 0);
nCol = pTab->nCol;
pTab->nCol = -1;
pWalker->eCode = 1; /* Turn on Select.selId renumbering */
sqlite3WalkSelect(pWalker, pFrom->pSelect);
pWalker->eCode = eCodeOrig;
pTab->nCol = nCol;
}
#endif
@@ -5147,6 +5152,7 @@ static void sqlite3SelectExpand(Parse *pParse, Select *pSelect){
}
w.xSelectCallback = selectExpander;
w.xSelectCallback2 = selectPopWith;
w.eCode = 0;
sqlite3WalkSelect(&w, pSelect);
}
@@ -5418,7 +5424,7 @@ static int havingToWhereExprCb(Walker *pWalker, Expr *pExpr){
if( pNew ){
Expr *pWhere = pS->pWhere;
SWAP(Expr, *pNew, *pExpr);
pNew = sqlite3ExprAnd(db, pWhere, pNew);
pNew = sqlite3ExprAnd(pWalker->pParse, pWhere, pNew);
pS->pWhere = pNew;
pWalker->eCode = 1;
}
@@ -5473,15 +5479,19 @@ static struct SrcList_item *isSelfJoinView(
if( pItem->pSelect==0 ) continue;
if( pItem->fg.viaCoroutine ) continue;
if( pItem->zName==0 ) continue;
if( sqlite3_stricmp(pItem->zDatabase, pThis->zDatabase)!=0 ) continue;
assert( pItem->pTab!=0 );
assert( pThis->pTab!=0 );
if( pItem->pTab->pSchema!=pThis->pTab->pSchema ) continue;
if( sqlite3_stricmp(pItem->zName, pThis->zName)!=0 ) continue;
pS1 = pItem->pSelect;
if( pThis->pSelect->selId!=pS1->selId ){
if( pItem->pTab->pSchema==0 && pThis->pSelect->selId!=pS1->selId ){
/* The query flattener left two different CTE tables with identical
** names in the same FROM clause. */
continue;
}
if( sqlite3ExprCompare(0, pThis->pSelect->pWhere, pS1->pWhere, -1) ){
if( sqlite3ExprCompare(0, pThis->pSelect->pWhere, pS1->pWhere, -1)
|| sqlite3ExprCompare(0, pThis->pSelect->pHaving, pS1->pHaving, -1)
){
/* The view was modified by some other optimization such as
** pushDownWhereTerms() */
continue;
@@ -5506,7 +5516,8 @@ static struct SrcList_item *isSelfJoinView(
** * The subquery is a UNION ALL of two or more terms
** * The subquery does not have a LIMIT clause
** * There is no WHERE or GROUP BY or HAVING clauses on the subqueries
** * The outer query is a simple count(*)
** * The outer query is a simple count(*) with no WHERE clause or other
** extraneous syntax.
**
** Return TRUE if the optimization is undertaken.
*/
@@ -5517,6 +5528,8 @@ static int countOfViewOptimization(Parse *pParse, Select *p){
sqlite3 *db;
if( (p->selFlags & SF_Aggregate)==0 ) return 0; /* This is an aggregate */
if( p->pEList->nExpr!=1 ) return 0; /* Single result column */
if( p->pWhere ) return 0;
if( p->pGroupBy ) return 0;
pExpr = p->pEList->a[0].pExpr;
if( pExpr->op!=TK_AGG_FUNCTION ) return 0; /* Result is an aggregate */
if( sqlite3_stricmp(pExpr->u.zToken,"count") ) return 0; /* Is count() */
+953 -26
View File
File diff suppressed because it is too large Load Diff
+43 -4
View File
@@ -1296,8 +1296,14 @@ typedef struct sqlite3_api_routines sqlite3_api_routines;
** ^The flags argument to xAccess() may be [SQLITE_ACCESS_EXISTS]
** to test for the existence of a file, or [SQLITE_ACCESS_READWRITE] to
** test whether a file is readable and writable, or [SQLITE_ACCESS_READ]
** to test whether a file is at least readable. The file can be a
** directory.
** to test whether a file is at least readable. The SQLITE_ACCESS_READ
** flag is never actually used and is not implemented in the built-in
** VFSes of SQLite. The file is named by the second argument and can be a
** directory. The xAccess method returns [SQLITE_OK] on success or some
** non-zero error code if there is an I/O error or if the name of
** the file given in the second argument is illegal. If SQLITE_OK
** is returned, then non-zero or zero is written into *pResOut to indicate
** whether or not the file is accessible.
**
** ^SQLite will always allocate at least mxPathname+1 bytes for the
** output buffer xFullPathname. The exact size of the output buffer
@@ -2198,6 +2204,7 @@ struct sqlite3_mem_methods {
** features include but are not limited to the following:
** <ul>
** <li> The [PRAGMA writable_schema=ON] statement.
** <li> The [PRAGMA journal_mode=OFF] statement.
** <li> Writes to the [sqlite_dbpage] virtual table.
** <li> Direct writes to [shadow tables].
** </ul>
@@ -2213,6 +2220,34 @@ struct sqlite3_mem_methods {
** integer into which is written 0 or 1 to indicate whether the writable_schema
** is enabled or disabled following this call.
** </dd>
**
** [[SQLITE_DBCONFIG_LEGACY_ALTER_TABLE]]
** <dt>SQLITE_DBCONFIG_LEGACY_ALTER_TABLE</dt>
** <dd>The SQLITE_DBCONFIG_LEGACY_ALTER_TABLE option activates or deactivates
** the legacy behavior of the [ALTER TABLE RENAME] command such it
** behaves as it did prior to [version 3.24.0] (2018-06-04). See the
** "Compatibility Notice" on the [ALTER TABLE RENAME documentation] for
** additional information. This feature can also be turned on and off
** using the [PRAGMA legacy_alter_table] statement.
** </dd>
**
** [[SQLITE_DBCONFIG_DQS_DML]]
** <dt>SQLITE_DBCONFIG_DQS_DML</td>
** <dd>The SQLITE_DBCONFIG_DQS_DML option activates or deactivates
** the legacy [double-quoted string literal] misfeature for DML statement
** only, that is DELETE, INSERT, SELECT, and UPDATE statements. The
** default value of this setting is determined by the [-DSQLITE_DQS]
** compile-time option.
** </dd>
**
** [[SQLITE_DBCONFIG_DQS_DDL]]
** <dt>SQLITE_DBCONFIG_DQS_DDL</td>
** <dd>The SQLITE_DBCONFIG_DQS option activates or deactivates
** the legacy [double-quoted string literal] misfeature for DDL statements,
** such as CREATE TABLE and CREATE INDEX. The
** default value of this setting is determined by the [-DSQLITE_DQS]
** compile-time option.
** </dd>
** </dl>
*/
#define SQLITE_DBCONFIG_MAINDBNAME 1000 /* const char* */
@@ -2227,7 +2262,10 @@ struct sqlite3_mem_methods {
#define SQLITE_DBCONFIG_RESET_DATABASE 1009 /* int int* */
#define SQLITE_DBCONFIG_DEFENSIVE 1010 /* int int* */
#define SQLITE_DBCONFIG_WRITABLE_SCHEMA 1011 /* int int* */
#define SQLITE_DBCONFIG_MAX 1011 /* Largest DBCONFIG */
#define SQLITE_DBCONFIG_LEGACY_ALTER_TABLE 1012 /* int int* */
#define SQLITE_DBCONFIG_DQS_DML 1013 /* int int* */
#define SQLITE_DBCONFIG_DQS_DDL 1014 /* int int* */
#define SQLITE_DBCONFIG_MAX 1014 /* Largest DBCONFIG */
/*
** CAPI3REF: Enable Or Disable Extended Result Codes
@@ -7335,7 +7373,8 @@ int sqlite3_test_control(int op, ...);
#define SQLITE_TESTCTRL_SORTER_MMAP 24
#define SQLITE_TESTCTRL_IMPOSTER 25
#define SQLITE_TESTCTRL_PARSER_COVERAGE 26
#define SQLITE_TESTCTRL_LAST 26 /* Largest TESTCTRL */
#define SQLITE_TESTCTRL_RESULT_INTREAL 27
#define SQLITE_TESTCTRL_LAST 27 /* Largest TESTCTRL */
/*
** CAPI3REF: SQL Keyword Checking
+28 -9
View File
@@ -830,12 +830,13 @@ typedef INT16_TYPE LogEst;
** at run-time.
*/
#ifndef SQLITE_BYTEORDER
# if defined(i386) || defined(__i386__) || defined(_M_IX86) || \
defined(__x86_64) || defined(__x86_64__) || defined(_M_X64) || \
defined(_M_AMD64) || defined(_M_ARM) || defined(__x86) || \
defined(__arm__) || defined(_M_ARM64)
# if defined(i386) || defined(__i386__) || defined(_M_IX86) || \
defined(__x86_64) || defined(__x86_64__) || defined(_M_X64) || \
defined(_M_AMD64) || defined(_M_ARM) || defined(__x86) || \
defined(__ARMEL__) || defined(__AARCH64EL__) || defined(_M_ARM64)
# define SQLITE_BYTEORDER 1234
# elif defined(sparc) || defined(__ppc__)
# elif defined(sparc) || defined(__ppc__) || \
defined(__ARMEB__) || defined(__AARCH64EB__)
# define SQLITE_BYTEORDER 4321
# else
# define SQLITE_BYTEORDER 0
@@ -1547,6 +1548,8 @@ struct sqlite3 {
#define SQLITE_LegacyAlter 0x04000000 /* Legacy ALTER TABLE behaviour */
#define SQLITE_NoSchemaError 0x08000000 /* Do not report schema parse errors*/
#define SQLITE_Defensive 0x10000000 /* Input SQL is likely hostile */
#define SQLITE_DqsDDL 0x20000000 /* dbl-quoted strings allowed in DDL*/
#define SQLITE_DqsDML 0x40000000 /* dbl-quoted strings allowed in DML*/
/* Flags used only if debugging */
#define HI(X) ((u64)(X)<<32)
@@ -2253,6 +2256,7 @@ struct Index {
unsigned noSkipScan:1; /* Do not try to use skip-scan if true */
unsigned hasStat1:1; /* aiRowLogEst values come from sqlite_stat1 */
unsigned bNoQuery:1; /* Do not use this index to optimize queries */
unsigned bAscKeyBug:1; /* True if the bba7b69f9849b5bf bug applies */
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
int nSample; /* Number of elements in aSample[] */
int nSampleCol; /* Size of IndexSample.anEq[] and so on */
@@ -2480,7 +2484,7 @@ struct Expr {
** TK_SELECT_COLUMN: column of the result vector */
i16 iAgg; /* Which entry in pAggInfo->aCol[] or ->aFunc[] */
i16 iRightJoinTable; /* If EP_FromJoin, the right table of the join */
u8 op2; /* TK_REGISTER: original value of Expr.op
u8 op2; /* TK_REGISTER/TK_TRUTH: original value of Expr.op
** TK_COLUMN: the value of p5 for OP_Column
** TK_AGG_FUNCTION: nesting depth */
AggInfo *pAggInfo; /* Used by TK_AGG_COLUMN and TK_AGG_FUNCTION */
@@ -2514,7 +2518,7 @@ struct Expr {
#define EP_Generic 0x000200 /* Ignore COLLATE or affinity on this tree */
#define EP_IntValue 0x000400 /* Integer value contained in u.iValue */
#define EP_xIsSelect 0x000800 /* x.pSelect is valid (otherwise x.pList is) */
#define EP_Skip 0x001000 /* COLLATE, AS, or UNLIKELY */
#define EP_Skip 0x001000 /* Operator does not contribute to affinity */
#define EP_Reduced 0x002000 /* Expr struct EXPR_REDUCEDSIZE bytes only */
#define EP_TokenOnly 0x004000 /* Expr struct EXPR_TOKENONLYSIZE bytes only */
#define EP_Win 0x008000 /* Contains window functions */
@@ -2530,6 +2534,8 @@ struct Expr {
#define EP_Subrtn 0x2000000 /* Uses Expr.y.sub. TK_IN, _SELECT, or _EXISTS */
#define EP_Quoted 0x4000000 /* TK_ID was originally quoted */
#define EP_Static 0x8000000 /* Held in memory not obtained from malloc() */
#define EP_IsTrue 0x10000000 /* Always has boolean value of TRUE */
#define EP_IsFalse 0x20000000 /* Always has boolean value of FALSE */
/*
** The EP_Propagate mask is a set of properties that automatically propagate
@@ -2545,6 +2551,8 @@ struct Expr {
#define ExprHasAllProperty(E,P) (((E)->flags&(P))==(P))
#define ExprSetProperty(E,P) (E)->flags|=(P)
#define ExprClearProperty(E,P) (E)->flags&=~(P)
#define ExprAlwaysTrue(E) (((E)->flags&(EP_FromJoin|EP_IsTrue))==EP_IsTrue)
#define ExprAlwaysFalse(E) (((E)->flags&(EP_FromJoin|EP_IsFalse))==EP_IsFalse)
/* The ExprSetVVAProperty() macro is used for Verification, Validation,
** and Accreditation only. It works like ExprSetProperty() during VVA
@@ -2761,7 +2769,7 @@ struct NameContext {
NameContext *pNext; /* Next outer name context. NULL for outermost */
int nRef; /* Number of names resolved by this context */
int nErr; /* Number of errors encountered while resolving names */
u16 ncFlags; /* Zero or more NC_* flags defined below */
int ncFlags; /* Zero or more NC_* flags defined below */
Select *pWinSelect; /* SELECT statement for any window functions */
};
@@ -2788,6 +2796,7 @@ struct NameContext {
#define NC_Complex 0x2000 /* True if a function or subquery seen */
#define NC_AllowWin 0x4000 /* Window functions are allowed here */
#define NC_HasWin 0x8000 /* One or more window functions seen */
#define NC_IsDDL 0x10000 /* Resolving names in a CREATE statement */
/*
** An instance of the following object describes a single ON CONFLICT
@@ -3794,8 +3803,12 @@ void sqlite3MutexWarnOnContention(sqlite3_mutex*);
#endif
#ifndef SQLITE_OMIT_FLOATING_POINT
# define EXP754 (((u64)0x7ff)<<52)
# define MAN754 ((((u64)1)<<52)-1)
# define IsNaN(X) (((X)&EXP754)==EXP754 && ((X)&MAN754)!=0)
int sqlite3IsNaN(double);
#else
# define IsNaN(X) 0
# define sqlite3IsNaN(X) 0
#endif
@@ -3854,10 +3867,12 @@ Expr *sqlite3Expr(sqlite3*,int,const char*);
void sqlite3ExprAttachSubtrees(sqlite3*,Expr*,Expr*,Expr*);
Expr *sqlite3PExpr(Parse*, int, Expr*, Expr*);
void sqlite3PExprAddSelect(Parse*, Expr*, Select*);
Expr *sqlite3ExprAnd(sqlite3*,Expr*, Expr*);
Expr *sqlite3ExprAnd(Parse*,Expr*, Expr*);
Expr *sqlite3ExprSimplifiedAndOr(Expr*);
Expr *sqlite3ExprFunction(Parse*,ExprList*, Token*, int);
void sqlite3ExprAssignVarNumber(Parse*, Expr*, u32);
void sqlite3ExprDelete(sqlite3*, Expr*);
void sqlite3ExprUnmapAndDelete(Parse*, Expr*);
ExprList *sqlite3ExprListAppend(Parse*,ExprList*,Expr*);
ExprList *sqlite3ExprListAppendVector(Parse*,ExprList*,IdList*,Expr*);
void sqlite3ExprListSetSortOrder(ExprList*,int);
@@ -4166,6 +4181,7 @@ int sqlite3FixSelect(DbFixer*, Select*);
int sqlite3FixExpr(DbFixer*, Expr*);
int sqlite3FixExprList(DbFixer*, ExprList*);
int sqlite3FixTriggerStep(DbFixer*, TriggerStep*);
int sqlite3RealSameAsInt(double,sqlite3_int64);
int sqlite3AtoF(const char *z, double*, int, u8);
int sqlite3GetInt32(const char *, int*);
int sqlite3Atoi(const char*);
@@ -4267,6 +4283,9 @@ void sqlite3ValueSetStr(sqlite3_value*, int, const void *,u8,
void(*)(void*));
void sqlite3ValueSetNull(sqlite3_value*);
void sqlite3ValueFree(sqlite3_value*);
#ifndef SQLITE_UNTESTABLE
void sqlite3ResultIntReal(sqlite3_context*);
#endif
sqlite3_value *sqlite3ValueNew(sqlite3 *);
#ifndef SQLITE_OMIT_UTF16
char *sqlite3Utf16to8(sqlite3 *, const void*, int, u8);
+39 -13
View File
@@ -998,6 +998,20 @@ static void nondeterministicFunction(
sqlite3_result_int(context, cnt++);
}
/*
** This SQL function returns the integer value of its argument as a MEM_IntReal
** value.
*/
static void intrealFunction(
sqlite3_context *context,
int argc,
sqlite3_value **argv
){
sqlite3_int64 v = sqlite3_value_int64(argv[0]);
sqlite3_result_int64(context, v);
sqlite3_test_control(SQLITE_TESTCTRL_RESULT_INTREAL, context);
}
/*
** Usage: sqlite3_create_function DB
**
@@ -1062,6 +1076,14 @@ static int SQLITE_TCLAPI test_create_function(
0, nondeterministicFunction, 0, 0);
}
/* The intreal() function converts its argument to an integer and returns
** it as a MEM_IntReal.
*/
if( rc==SQLITE_OK ){
rc = sqlite3_create_function(db, "intreal", 1, SQLITE_UTF8,
0, intrealFunction, 0, 0);
}
#ifndef SQLITE_OMIT_UTF16
/* Use the sqlite3_create_function16() API here. Mainly for fun, but also
** because it is not tested anywhere else. */
@@ -7586,15 +7608,19 @@ static int SQLITE_TCLAPI test_sqlite3_db_config(
const char *zName;
int eVal;
} aSetting[] = {
{ "FKEY", SQLITE_DBCONFIG_ENABLE_FKEY },
{ "TRIGGER", SQLITE_DBCONFIG_ENABLE_TRIGGER },
{ "FTS3_TOKENIZER", SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER },
{ "LOAD_EXTENSION", SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION },
{ "NO_CKPT_ON_CLOSE",SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE },
{ "QPSG", SQLITE_DBCONFIG_ENABLE_QPSG },
{ "TRIGGER_EQP", SQLITE_DBCONFIG_TRIGGER_EQP },
{ "RESET_DB", SQLITE_DBCONFIG_RESET_DATABASE },
{ "DEFENSIVE", SQLITE_DBCONFIG_DEFENSIVE },
{ "FKEY", SQLITE_DBCONFIG_ENABLE_FKEY },
{ "TRIGGER", SQLITE_DBCONFIG_ENABLE_TRIGGER },
{ "FTS3_TOKENIZER", SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER },
{ "LOAD_EXTENSION", SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION },
{ "NO_CKPT_ON_CLOSE", SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE },
{ "QPSG", SQLITE_DBCONFIG_ENABLE_QPSG },
{ "TRIGGER_EQP", SQLITE_DBCONFIG_TRIGGER_EQP },
{ "RESET_DB", SQLITE_DBCONFIG_RESET_DATABASE },
{ "DEFENSIVE", SQLITE_DBCONFIG_DEFENSIVE },
{ "WRITABLE_SCHEMA", SQLITE_DBCONFIG_WRITABLE_SCHEMA },
{ "LEGACY_ALTER_TABLE", SQLITE_DBCONFIG_LEGACY_ALTER_TABLE },
{ "DQS_DML", SQLITE_DBCONFIG_DQS_DML },
{ "DQS_DDL", SQLITE_DBCONFIG_DQS_DDL },
};
int i;
int v;
@@ -7699,7 +7725,7 @@ static int SQLITE_TCLAPI test_decode_hexdb(
int iOffset = 0;
int j, k;
int rc;
unsigned char x[16];
unsigned int x[16];
if( objc!=2 ){
Tcl_WrongNumArgs(interp, 1, objv, "HEXDB");
return TCL_ERROR;
@@ -7731,14 +7757,14 @@ static int SQLITE_TCLAPI test_decode_hexdb(
iOffset = k;
continue;
}
rc = sscanf(zIn+i,"| %d: %hhx %hhx %hhx %hhx %hhx %hhx %hhx %hhx"
" %hhx %hhx %hhx %hhx %hhx %hhx %hhx %hhx",
rc = sscanf(zIn+i,"| %d: %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x",
&j, &x[0], &x[1], &x[2], &x[3], &x[4], &x[5], &x[6], &x[7],
&x[8], &x[9], &x[10], &x[11], &x[12], &x[13], &x[14], &x[15]);
if( rc==17 ){
k = iOffset+j;
if( k+16<=n ){
memcpy(a+k, x, 16);
int ii;
for(ii=0; ii<16; ii++) a[k+ii] = x[ii]&0xff;
}
continue;
}
+4 -1
View File
@@ -240,6 +240,9 @@ static int demoRead(
if( nRead==iAmt ){
return SQLITE_OK;
}else if( nRead>=0 ){
if( nRead<iAmt ){
memset(&((char*)zBuf)[nRead], 0, iAmt-nRead);
}
return SQLITE_IOERR_SHORT_READ;
}
@@ -369,7 +372,7 @@ static int demoCheckReservedLock(sqlite3_file *pFile, int *pResOut){
** No xFileControl() verbs are implemented by this VFS.
*/
static int demoFileControl(sqlite3_file *pFile, int op, void *pArg){
return SQLITE_OK;
return SQLITE_NOTFOUND;
}
/*
+1
View File
@@ -505,6 +505,7 @@ void devsym_register(int iDeviceChar, int iSectorSize){
void devsym_unregister(){
sqlite3_vfs_unregister(&devsym_vfs);
sqlite3_vfs_unregister(&writecrash_vfs);
g.pVfs = 0;
g.iDeviceChar = 0;
g.iSectorSize = 0;
+3 -1
View File
@@ -235,6 +235,7 @@ static int tvfsResultCode(Testvfs *p, int *pRc){
{ SQLITE_BUSY, "SQLITE_BUSY" },
{ SQLITE_READONLY, "SQLITE_READONLY" },
{ SQLITE_READONLY_CANTINIT, "SQLITE_READONLY_CANTINIT" },
{ SQLITE_NOTFOUND, "SQLITE_NOTFOUND" },
{ -1, "SQLITE_OMIT" },
};
@@ -552,6 +553,7 @@ static int tvfsFileControl(sqlite3_file *pFile, int op, void *pArg){
} aF[] = {
{ SQLITE_FCNTL_BEGIN_ATOMIC_WRITE, "BEGIN_ATOMIC_WRITE" },
{ SQLITE_FCNTL_COMMIT_ATOMIC_WRITE, "COMMIT_ATOMIC_WRITE" },
{ SQLITE_FCNTL_ZIPVFS, "ZIPVFS" },
};
int i;
for(i=0; i<sizeof(aF)/sizeof(aF[0]); i++){
@@ -565,7 +567,7 @@ static int tvfsFileControl(sqlite3_file *pFile, int op, void *pArg){
0, 0
);
tvfsResultCode(p, &rc);
if( rc ) return rc;
if( rc ) return (rc<0 ? SQLITE_OK : rc);
}
}
return sqlite3OsFileControl(pFd->pReal, op, pArg);
+1 -1
View File
@@ -514,7 +514,7 @@ void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 moreToFollow){
};
assert( pExpr->op2==TK_IS || pExpr->op2==TK_ISNOT );
assert( pExpr->pRight );
assert( pExpr->pRight->op==TK_TRUEFALSE );
assert( sqlite3ExprSkipCollate(pExpr->pRight)->op==TK_TRUEFALSE );
x = (pExpr->op2==TK_ISNOT)*2 + sqlite3ExprTruthValue(pExpr->pRight);
zUniOp = azOp[x];
break;
+17 -7
View File
@@ -155,11 +155,12 @@ void sqlite3Update(
Index *pIdx; /* For looping over indices */
Index *pPk; /* The PRIMARY KEY index for WITHOUT ROWID tables */
int nIdx; /* Number of indices that need updating */
int nAllIdx; /* Total number of indexes */
int iBaseCur; /* Base cursor number */
int iDataCur; /* Cursor for the canonical data btree */
int iIdxCur; /* Cursor for the first index */
sqlite3 *db; /* The database structure */
int *aRegIdx = 0; /* First register in array assigned to each index */
int *aRegIdx = 0; /* Registers for to each index and the main table */
int *aXRef = 0; /* aXRef[i] is the index in pChanges->a[] of the
** an expression for the i-th column of the table.
** aXRef[i]==-1 if the i-th column is not changed. */
@@ -273,10 +274,10 @@ void sqlite3Update(
/* Allocate space for aXRef[], aRegIdx[], and aToOpen[].
** Initialize aXRef[] and aToOpen[] to their default values.
*/
aXRef = sqlite3DbMallocRawNN(db, sizeof(int) * (pTab->nCol+nIdx) + nIdx+2 );
aXRef = sqlite3DbMallocRawNN(db, sizeof(int) * (pTab->nCol+nIdx+1) + nIdx+2 );
if( aXRef==0 ) goto update_cleanup;
aRegIdx = aXRef+pTab->nCol;
aToOpen = (u8*)(aRegIdx+nIdx);
aToOpen = (u8*)(aRegIdx+nIdx+1);
memset(aToOpen, 1, nIdx+1);
aToOpen[nIdx+1] = 0;
for(i=0; i<pTab->nCol; i++) aXRef[i] = -1;
@@ -355,7 +356,7 @@ void sqlite3Update(
** the key for accessing each index.
*/
if( onError==OE_Replace ) bReplace = 1;
for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
for(nAllIdx=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, nAllIdx++){
int reg;
if( chngKey || hasFK>1 || pIdx==pPk
|| indexWhereClauseMightChange(pIdx,aXRef,chngRowid)
@@ -375,9 +376,10 @@ void sqlite3Update(
}
}
}
if( reg==0 ) aToOpen[j+1] = 0;
aRegIdx[j] = reg;
if( reg==0 ) aToOpen[nAllIdx+1] = 0;
aRegIdx[nAllIdx] = reg;
}
aRegIdx[nAllIdx] = ++pParse->nMem; /* Register storing the table record */
if( bReplace ){
/* If REPLACE conflict resolution might be invoked, open cursors on all
** indexes in case they are needed to delete records. */
@@ -392,7 +394,13 @@ void sqlite3Update(
/* Allocate required registers. */
if( !IsVirtual(pTab) ){
regRowSet = ++pParse->nMem;
/* For now, regRowSet and aRegIdx[nAllIdx] share the same register.
** If regRowSet turns out to be needed, then aRegIdx[nAllIdx] will be
** reallocated. aRegIdx[nAllIdx] is the register in which the main
** table record is written. regRowSet holds the RowSet for the
** two-pass update algorithm. */
assert( aRegIdx[nAllIdx]==pParse->nMem );
regRowSet = aRegIdx[nAllIdx];
regOldRowid = regNewRowid = ++pParse->nMem;
if( chngPk || pTrigger || hasFK ){
regOld = pParse->nMem + 1;
@@ -522,6 +530,8 @@ void sqlite3Update(
** leave it in register regOldRowid. */
sqlite3VdbeAddOp2(v, OP_Rowid, iDataCur, regOldRowid);
if( eOnePass==ONEPASS_OFF ){
/* We need to use regRowSet, so reallocate aRegIdx[nAllIdx] */
aRegIdx[nAllIdx] = ++pParse->nMem;
sqlite3VdbeAddOp2(v, OP_RowSetAdd, regRowSet, regOldRowid);
}
}else{
+65 -87
View File
@@ -17,9 +17,7 @@
*/
#include "sqliteInt.h"
#include <stdarg.h>
#if HAVE_ISNAN || SQLITE_HAVE_ISNAN
# include <math.h>
#endif
#include <math.h>
/*
** Routine needed to support the testcase() macro.
@@ -60,47 +58,11 @@ int sqlite3FaultSim(int iTest){
#ifndef SQLITE_OMIT_FLOATING_POINT
/*
** Return true if the floating point value is Not a Number (NaN).
**
** Use the math library isnan() function if compiled with SQLITE_HAVE_ISNAN.
** Otherwise, we have our own implementation that works on most systems.
*/
int sqlite3IsNaN(double x){
int rc; /* The value return */
#if !SQLITE_HAVE_ISNAN && !HAVE_ISNAN
/*
** Systems that support the isnan() library function should probably
** make use of it by compiling with -DSQLITE_HAVE_ISNAN. But we have
** found that many systems do not have a working isnan() function so
** this implementation is provided as an alternative.
**
** This NaN test sometimes fails if compiled on GCC with -ffast-math.
** On the other hand, the use of -ffast-math comes with the following
** warning:
**
** This option [-ffast-math] should never be turned on by any
** -O option since it can result in incorrect output for programs
** which depend on an exact implementation of IEEE or ISO
** rules/specifications for math functions.
**
** Under MSVC, this NaN test may fail if compiled with a floating-
** point precision mode other than /fp:precise. From the MSDN
** documentation:
**
** The compiler [with /fp:precise] will properly handle comparisons
** involving NaN. For example, x != x evaluates to true if x is NaN
** ...
*/
#ifdef __FAST_MATH__
# error SQLite will not work correctly with the -ffast-math option of GCC.
#endif
volatile double y = x;
volatile double z = y;
rc = (y!=z);
#else /* if HAVE_ISNAN */
rc = isnan(x);
#endif /* HAVE_ISNAN */
testcase( rc );
return rc;
u64 y;
memcpy(&y,&x,sizeof(y));
return IsNaN(y);
}
#endif /* SQLITE_OMIT_FLOATING_POINT */
@@ -322,12 +284,18 @@ int sqlite3_stricmp(const char *zLeft, const char *zRight){
}
int sqlite3StrICmp(const char *zLeft, const char *zRight){
unsigned char *a, *b;
int c;
int c, x;
a = (unsigned char *)zLeft;
b = (unsigned char *)zRight;
for(;;){
c = (int)UpperToLower[*a] - (int)UpperToLower[*b];
if( c || *a==0 ) break;
c = *a;
x = *b;
if( c==x ){
if( c==0 ) break;
}else{
c = (int)UpperToLower[c] - (int)UpperToLower[x];
if( c ) break;
}
a++;
b++;
}
@@ -355,15 +323,15 @@ int sqlite3_strnicmp(const char *zLeft, const char *zRight, int N){
static LONGDOUBLE_TYPE sqlite3Pow10(int E){
#if defined(_MSC_VER)
static const LONGDOUBLE_TYPE x[] = {
1.0e+001,
1.0e+002,
1.0e+004,
1.0e+008,
1.0e+016,
1.0e+032,
1.0e+064,
1.0e+128,
1.0e+256
1.0e+001L,
1.0e+002L,
1.0e+004L,
1.0e+008L,
1.0e+016L,
1.0e+032L,
1.0e+064L,
1.0e+128L,
1.0e+256L
};
LONGDOUBLE_TYPE r = 1.0;
int i;
@@ -393,8 +361,15 @@ static LONGDOUBLE_TYPE sqlite3Pow10(int E){
** uses the encoding enc. The string is not necessarily zero-terminated.
**
** Return TRUE if the result is a valid real number (or integer) and FALSE
** if the string is empty or contains extraneous text. Valid numbers
** are in one of these formats:
** if the string is empty or contains extraneous text. More specifically
** return
** 1 => The input string is a pure integer
** 2 or more => The input has a decimal point or eNNN clause
** 0 or less => The input string is not a valid number
** -1 => Not a valid number, but has a valid prefix which
** includes a decimal point and/or an eNNN clause
**
** Valid numbers are in one of these formats:
**
** [+-]digits[E[+-]digits]
** [+-]digits.[digits][E[+-]digits]
@@ -419,8 +394,8 @@ int sqlite3AtoF(const char *z, double *pResult, int length, u8 enc){
int e = 0; /* exponent */
int eValid = 1; /* True exponent is either not used or is well-formed */
double result;
int nDigits = 0;
int nonNum = 0; /* True if input contains UTF16 with high byte non-zero */
int nDigit = 0; /* Number of digits processed */
int eType = 1; /* 1: pure integer, 2+: fractional -1 or less: bad UTF16 */
assert( enc==SQLITE_UTF8 || enc==SQLITE_UTF16LE || enc==SQLITE_UTF16BE );
*pResult = 0.0; /* Default return value, in case of an error */
@@ -431,8 +406,10 @@ int sqlite3AtoF(const char *z, double *pResult, int length, u8 enc){
int i;
incr = 2;
assert( SQLITE_UTF16LE==2 && SQLITE_UTF16BE==3 );
testcase( enc==SQLITE_UTF16LE );
testcase( enc==SQLITE_UTF16BE );
for(i=3-enc; i<length && z[i]==0; i+=2){}
nonNum = i<length;
if( i<length ) eType = -100;
zEnd = &z[i^1];
z += (enc&1);
}
@@ -450,27 +427,30 @@ int sqlite3AtoF(const char *z, double *pResult, int length, u8 enc){
}
/* copy max significant digits to significand */
while( z<zEnd && sqlite3Isdigit(*z) && s<((LARGEST_INT64-9)/10) ){
while( z<zEnd && sqlite3Isdigit(*z) ){
s = s*10 + (*z - '0');
z+=incr; nDigits++;
z+=incr; nDigit++;
if( s>=((LARGEST_INT64-9)/10) ){
/* skip non-significant significand digits
** (increase exponent by d to shift decimal left) */
while( z<zEnd && sqlite3Isdigit(*z) ){ z+=incr; d++; }
}
}
/* skip non-significant significand digits
** (increase exponent by d to shift decimal left) */
while( z<zEnd && sqlite3Isdigit(*z) ){ z+=incr; nDigits++; d++; }
if( z>=zEnd ) goto do_atof_calc;
/* if decimal point is present */
if( *z=='.' ){
z+=incr;
eType++;
/* copy digits from after decimal to significand
** (decrease exponent by d to shift decimal right) */
while( z<zEnd && sqlite3Isdigit(*z) ){
if( s<((LARGEST_INT64-9)/10) ){
s = s*10 + (*z - '0');
d--;
nDigit++;
}
z+=incr; nDigits++;
z+=incr;
}
}
if( z>=zEnd ) goto do_atof_calc;
@@ -479,6 +459,7 @@ int sqlite3AtoF(const char *z, double *pResult, int length, u8 enc){
if( *z=='e' || *z=='E' ){
z+=incr;
eValid = 0;
eType++;
/* This branch is needed to avoid a (harmless) buffer overread. The
** special comment alerts the mutation tester that the correct answer
@@ -577,7 +558,13 @@ do_atof_calc:
*pResult = result;
/* return true if number and no extra non-whitespace chracters after */
return z==zEnd && nDigits>0 && eValid && nonNum==0;
if( z==zEnd && nDigit>0 && eValid && eType>0 ){
return eType;
}else if( eType>=2 && (eType==3 || eValid) && nDigit>0 ){
return -1;
}else{
return 0;
}
#else
return !sqlite3Atoi64(z, pResult, length, enc);
#endif /* SQLITE_OMIT_FLOATING_POINT */
@@ -620,6 +607,7 @@ static int compare2pow63(const char *zNum, int incr){
**
** Returns:
**
** -1 Not even a prefix of the input text looks like an integer
** 0 Successful transformation. Fits in a 64-bit signed integer.
** 1 Excess non-space text after the integer value
** 2 Integer too large for a 64-bit signed integer or is malformed
@@ -679,9 +667,9 @@ int sqlite3Atoi64(const char *zNum, i64 *pNum, int length, u8 enc){
*pNum = (i64)u;
}
rc = 0;
if( (i==0 && zStart==zNum) /* No digits */
|| nonNum /* UTF16 with high-order bytes non-zero */
){
if( i==0 && zStart==zNum ){ /* No digits */
rc = -1;
}else if( nonNum ){ /* UTF16 with high-order bytes non-zero */
rc = 1;
}else if( &zNum[i]<zEnd ){ /* Extra bytes at the end */
int jj = i;
@@ -912,23 +900,12 @@ int sqlite3PutVarint(unsigned char *p, u64 v){
u8 sqlite3GetVarint(const unsigned char *p, u64 *v){
u32 a,b,s;
a = *p;
/* a: p0 (unmasked) */
if (!(a&0x80))
{
*v = a;
if( ((signed char*)p)[0]>=0 ){
*v = *p;
return 1;
}
p++;
b = *p;
/* b: p1 (unmasked) */
if (!(b&0x80))
{
a &= 0x7f;
a = a<<7;
a |= b;
*v = a;
if( ((signed char*)p)[1]>=0 ){
*v = ((u32)(p[0]&0x7f)<<7) | p[1];
return 2;
}
@@ -936,8 +913,9 @@ u8 sqlite3GetVarint(const unsigned char *p, u64 *v){
assert( SLOT_2_0 == ((0x7f<<14) | (0x7f)) );
assert( SLOT_4_2_0 == ((0xfU<<28) | (0x7f<<14) | (0x7f)) );
p++;
a = a<<14;
a = ((u32)p[0])<<14;
b = p[1];
p += 2;
a |= *p;
/* a: p0<<14 | p2 (unmasked) */
if (!(a&0x80))
+1
View File
@@ -106,6 +106,7 @@ void sqlite3Vacuum(Parse *pParse, Token *pNm, Expr *pInto){
Vdbe *v = sqlite3GetVdbe(pParse);
int iDb = 0;
if( v==0 ) goto build_vacuum_end;
if( pParse->nErr ) goto build_vacuum_end;
if( pNm ){
#ifndef SQLITE_BUG_COMPATIBLE_20160819
/* Default behavior: Report an error if the argument to VACUUM is
+161 -84
View File
@@ -195,14 +195,6 @@ int sqlite3_found_count = 0;
}
#endif
/*
** Convert the given register into a string if it isn't one
** already. Return non-zero if a malloc() fails.
*/
#define Stringify(P, enc) \
if(((P)->flags&(MEM_Str|MEM_Blob))==0 && sqlite3VdbeMemStringify(P,enc,0)) \
{ goto no_mem; }
/*
** An ephemeral string value (signified by the MEM_Ephem flag) contains
** a pointer to a dynamically allocated string where some other entity
@@ -264,7 +256,7 @@ static VdbeCursor *allocateCursor(
** is clear. Otherwise, if this is an ephemeral cursor created by
** OP_OpenDup, the cursor will not be closed and will still be part
** of a BtShared.pCursor list. */
p->apCsr[iCur]->isEphemeral = 0;
if( p->apCsr[iCur]->pBtx==0 ) p->apCsr[iCur]->isEphemeral = 0;
sqlite3VdbeFreeCursor(p, p->apCsr[iCur]);
p->apCsr[iCur] = 0;
}
@@ -284,6 +276,21 @@ static VdbeCursor *allocateCursor(
return pCx;
}
/*
** The string in pRec is known to look like an integer and to have a
** floating point value of rValue. Return true and set *piValue to the
** integer value if the string is in range to be an integer. Otherwise,
** return false.
*/
static int alsoAnInt(Mem *pRec, double rValue, i64 *piValue){
i64 iValue = (double)rValue;
if( sqlite3RealSameAsInt(rValue,iValue) ){
*piValue = iValue;
return 1;
}
return 0==sqlite3Atoi64(pRec->z, piValue, pRec->n, pRec->enc);
}
/*
** Try to convert a value into a numeric representation if we can
** do so without loss of information. In other words, if the string
@@ -301,12 +308,12 @@ static VdbeCursor *allocateCursor(
*/
static void applyNumericAffinity(Mem *pRec, int bTryForInt){
double rValue;
i64 iValue;
u8 enc = pRec->enc;
assert( (pRec->flags & (MEM_Str|MEM_Int|MEM_Real))==MEM_Str );
if( sqlite3AtoF(pRec->z, &rValue, pRec->n, enc)==0 ) return;
if( 0==sqlite3Atoi64(pRec->z, &iValue, pRec->n, enc) ){
pRec->u.i = iValue;
int rc;
assert( (pRec->flags & (MEM_Str|MEM_Int|MEM_Real|MEM_IntReal))==MEM_Str );
rc = sqlite3AtoF(pRec->z, &rValue, pRec->n, enc);
if( rc<=0 ) return;
if( rc==1 && alsoAnInt(pRec, rValue, &pRec->u.i) ){
pRec->flags |= MEM_Int;
}else{
pRec->u.r = rValue;
@@ -360,11 +367,14 @@ static void applyAffinity(
** there is already a string rep, but it is pointless to waste those
** CPU cycles. */
if( 0==(pRec->flags&MEM_Str) ){ /*OPTIMIZATION-IF-FALSE*/
if( (pRec->flags&(MEM_Real|MEM_Int)) ){
if( (pRec->flags&(MEM_Real|MEM_Int|MEM_IntReal)) ){
testcase( pRec->flags & MEM_Int );
testcase( pRec->flags & MEM_Real );
testcase( pRec->flags & MEM_IntReal );
sqlite3VdbeMemStringify(pRec, enc, 1);
}
}
pRec->flags &= ~(MEM_Real|MEM_Int);
pRec->flags &= ~(MEM_Real|MEM_Int|MEM_IntReal);
}
}
@@ -403,13 +413,21 @@ void sqlite3ValueApplyAffinity(
** accordingly.
*/
static u16 SQLITE_NOINLINE computeNumericType(Mem *pMem){
assert( (pMem->flags & (MEM_Int|MEM_Real))==0 );
int rc;
sqlite3_int64 ix;
assert( (pMem->flags & (MEM_Int|MEM_Real|MEM_IntReal))==0 );
assert( (pMem->flags & (MEM_Str|MEM_Blob))!=0 );
ExpandBlob(pMem);
if( sqlite3AtoF(pMem->z, &pMem->u.r, pMem->n, pMem->enc)==0 ){
return 0;
}
if( sqlite3Atoi64(pMem->z, &pMem->u.i, pMem->n, pMem->enc)==0 ){
rc = sqlite3AtoF(pMem->z, &pMem->u.r, pMem->n, pMem->enc);
if( rc<=0 ){
if( rc==0 && sqlite3Atoi64(pMem->z, &ix, pMem->n, pMem->enc)<=1 ){
pMem->u.i = ix;
return MEM_Int;
}else{
return MEM_Real;
}
}else if( rc==1 && sqlite3Atoi64(pMem->z, &ix, pMem->n, pMem->enc)==0 ){
pMem->u.i = ix;
return MEM_Int;
}
return MEM_Real;
@@ -423,10 +441,15 @@ static u16 SQLITE_NOINLINE computeNumericType(Mem *pMem){
** But it does set pMem->u.r and pMem->u.i appropriately.
*/
static u16 numericType(Mem *pMem){
if( pMem->flags & (MEM_Int|MEM_Real) ){
return pMem->flags & (MEM_Int|MEM_Real);
if( pMem->flags & (MEM_Int|MEM_Real|MEM_IntReal) ){
testcase( pMem->flags & MEM_Int );
testcase( pMem->flags & MEM_Real );
testcase( pMem->flags & MEM_IntReal );
return pMem->flags & (MEM_Int|MEM_Real|MEM_IntReal);
}
if( pMem->flags & (MEM_Str|MEM_Blob) ){
testcase( pMem->flags & MEM_Str );
testcase( pMem->flags & MEM_Blob );
return computeNumericType(pMem);
}
return 0;
@@ -522,6 +545,8 @@ static void memTracePrint(Mem *p){
printf(p->flags & MEM_Zero ? " NULL-nochng" : " NULL");
}else if( (p->flags & (MEM_Int|MEM_Str))==(MEM_Int|MEM_Str) ){
printf(" si:%lld", p->u.i);
}else if( (p->flags & (MEM_IntReal))!=0 ){
printf(" ir:%lld", p->u.i);
}else if( p->flags & MEM_Int ){
printf(" i:%lld", p->u.i);
#ifndef SQLITE_OMIT_FLOATING_POINT
@@ -1463,33 +1488,57 @@ case OP_ResultRow: {
** to avoid a memcpy().
*/
case OP_Concat: { /* same as TK_CONCAT, in1, in2, out3 */
i64 nByte;
i64 nByte; /* Total size of the output string or blob */
u16 flags1; /* Initial flags for P1 */
u16 flags2; /* Initial flags for P2 */
pIn1 = &aMem[pOp->p1];
pIn2 = &aMem[pOp->p2];
pOut = &aMem[pOp->p3];
testcase( pIn1==pIn2 );
testcase( pOut==pIn2 );
assert( pIn1!=pOut );
if( (pIn1->flags | pIn2->flags) & MEM_Null ){
flags1 = pIn1->flags;
testcase( flags1 & MEM_Null );
testcase( pIn2->flags & MEM_Null );
if( (flags1 | pIn2->flags) & MEM_Null ){
sqlite3VdbeMemSetNull(pOut);
break;
}
if( ExpandBlob(pIn1) || ExpandBlob(pIn2) ) goto no_mem;
Stringify(pIn1, encoding);
Stringify(pIn2, encoding);
if( (flags1 & (MEM_Str|MEM_Blob))==0 ){
if( sqlite3VdbeMemStringify(pIn1,encoding,0) ) goto no_mem;
flags1 = pIn1->flags & ~MEM_Str;
}else if( (flags1 & MEM_Zero)!=0 ){
if( sqlite3VdbeMemExpandBlob(pIn1) ) goto no_mem;
flags1 = pIn1->flags & ~MEM_Str;
}
flags2 = pIn2->flags;
if( (flags2 & (MEM_Str|MEM_Blob))==0 ){
if( sqlite3VdbeMemStringify(pIn2,encoding,0) ) goto no_mem;
flags2 = pIn2->flags & ~MEM_Str;
}else if( (flags2 & MEM_Zero)!=0 ){
if( sqlite3VdbeMemExpandBlob(pIn2) ) goto no_mem;
flags2 = pIn2->flags & ~MEM_Str;
}
nByte = pIn1->n + pIn2->n;
if( nByte>db->aLimit[SQLITE_LIMIT_LENGTH] ){
goto too_big;
}
if( sqlite3VdbeMemGrow(pOut, (int)nByte+2, pOut==pIn2) ){
if( sqlite3VdbeMemGrow(pOut, (int)nByte+3, pOut==pIn2) ){
goto no_mem;
}
MemSetTypeFlag(pOut, MEM_Str);
if( pOut!=pIn2 ){
memcpy(pOut->z, pIn2->z, pIn2->n);
assert( (pIn2->flags & MEM_Dyn) == (flags2 & MEM_Dyn) );
pIn2->flags = flags2;
}
memcpy(&pOut->z[pIn2->n], pIn1->z, pIn1->n);
assert( (pIn1->flags & MEM_Dyn) == (flags1 & MEM_Dyn) );
pIn1->flags = flags1;
pOut->z[nByte]=0;
pOut->z[nByte+1] = 0;
pOut->z[nByte+2] = 0;
pOut->flags |= MEM_Term;
pOut->n = (int)nByte;
pOut->enc = encoding;
@@ -1540,7 +1589,6 @@ case OP_Subtract: /* same as TK_MINUS, in1, in2, out3 */
case OP_Multiply: /* same as TK_STAR, in1, in2, out3 */
case OP_Divide: /* same as TK_SLASH, in1, in2, out3 */
case OP_Remainder: { /* same as TK_REM, in1, in2, out3 */
char bIntint; /* Started out as two integer operands */
u16 flags; /* Combined MEM_* flags from both inputs */
u16 type1; /* Numeric type of left operand */
u16 type2; /* Numeric type of right operand */
@@ -1558,7 +1606,6 @@ case OP_Remainder: { /* same as TK_REM, in1, in2, out3 */
if( (type1 & type2 & MEM_Int)!=0 ){
iA = pIn1->u.i;
iB = pIn2->u.i;
bIntint = 1;
switch( pOp->opcode ){
case OP_Add: if( sqlite3AddInt64(&iB,iA) ) goto fp_math; break;
case OP_Subtract: if( sqlite3SubInt64(&iB,iA) ) goto fp_math; break;
@@ -1581,7 +1628,6 @@ case OP_Remainder: { /* same as TK_REM, in1, in2, out3 */
}else if( (flags & MEM_Null)!=0 ){
goto arithmetic_result_is_null;
}else{
bIntint = 0;
fp_math:
rA = sqlite3VdbeRealValue(pIn1);
rB = sqlite3VdbeRealValue(pIn2);
@@ -1613,9 +1659,6 @@ fp_math:
}
pOut->u.r = rB;
MemSetTypeFlag(pOut, MEM_Real);
if( ((type1|type2)&MEM_Real)==0 && !bIntint ){
sqlite3VdbeIntegerAffinity(pOut);
}
#endif
}
break;
@@ -1784,7 +1827,9 @@ case OP_MustBeInt: { /* jump, in1 */
*/
case OP_RealAffinity: { /* in1 */
pIn1 = &aMem[pOp->p1];
if( pIn1->flags & MEM_Int ){
if( pIn1->flags & (MEM_Int|MEM_IntReal) ){
testcase( pIn1->flags & MEM_Int );
testcase( pIn1->flags & MEM_IntReal );
sqlite3VdbeMemRealify(pIn1);
}
break;
@@ -1976,7 +2021,7 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
affinity = pOp->p5 & SQLITE_AFF_MASK;
if( affinity>=SQLITE_AFF_NUMERIC ){
if( (flags1 | flags3)&MEM_Str ){
if( (flags1 & (MEM_Int|MEM_Real|MEM_Str))==MEM_Str ){
if( (flags1 & (MEM_Int|MEM_IntReal|MEM_Real|MEM_Str))==MEM_Str ){
applyNumericAffinity(pIn1,0);
assert( flags3==pIn3->flags );
/* testcase( flags3!=pIn3->flags );
@@ -1986,7 +2031,7 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
** in case our analysis is incorrect, so it is left in. */
flags3 = pIn3->flags;
}
if( (flags3 & (MEM_Int|MEM_Real|MEM_Str))==MEM_Str ){
if( (flags3 & (MEM_Int|MEM_IntReal|MEM_Real|MEM_Str))==MEM_Str ){
applyNumericAffinity(pIn3,0);
}
}
@@ -1999,17 +2044,19 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
goto compare_op;
}
}else if( affinity==SQLITE_AFF_TEXT ){
if( (flags1 & MEM_Str)==0 && (flags1 & (MEM_Int|MEM_Real))!=0 ){
if( (flags1 & MEM_Str)==0 && (flags1&(MEM_Int|MEM_Real|MEM_IntReal))!=0 ){
testcase( pIn1->flags & MEM_Int );
testcase( pIn1->flags & MEM_Real );
testcase( pIn1->flags & MEM_IntReal );
sqlite3VdbeMemStringify(pIn1, encoding, 1);
testcase( (flags1&MEM_Dyn) != (pIn1->flags&MEM_Dyn) );
flags1 = (pIn1->flags & ~MEM_TypeMask) | (flags1 & MEM_TypeMask);
assert( pIn1!=pIn3 );
}
if( (flags3 & MEM_Str)==0 && (flags3 & (MEM_Int|MEM_Real))!=0 ){
if( (flags3 & MEM_Str)==0 && (flags3&(MEM_Int|MEM_Real|MEM_IntReal))!=0 ){
testcase( pIn3->flags & MEM_Int );
testcase( pIn3->flags & MEM_Real );
testcase( pIn3->flags & MEM_IntReal );
sqlite3VdbeMemStringify(pIn3, encoding, 1);
testcase( (flags3&MEM_Dyn) != (pIn3->flags&MEM_Dyn) );
flags3 = (pIn3->flags & ~MEM_TypeMask) | (flags3 & MEM_TypeMask);
@@ -2765,12 +2812,21 @@ case OP_Affinity: {
assert( pOp->p2>0 );
assert( zAffinity[pOp->p2]==0 );
pIn1 = &aMem[pOp->p1];
do{
while( 1 /*edit-by-break*/ ){
assert( pIn1 <= &p->aMem[(p->nMem+1 - p->nCursor)] );
assert( memIsValid(pIn1) );
applyAffinity(pIn1, *(zAffinity++), encoding);
applyAffinity(pIn1, zAffinity[0], encoding);
if( zAffinity[0]==SQLITE_AFF_REAL && (pIn1->flags & MEM_Int)!=0 ){
/* When applying REAL affinity, if the result is still MEM_Int,
** indicate that REAL is actually desired */
pIn1->flags |= MEM_IntReal;
pIn1->flags &= ~MEM_Int;
}
REGISTER_TRACE((int)(pIn1-aMem), pIn1);
zAffinity++;
if( zAffinity[0]==0 ) break;
pIn1++;
}while( zAffinity[0] );
}
break;
}
@@ -2791,7 +2847,6 @@ case OP_Affinity: {
** If P4 is NULL then all index fields have the affinity BLOB.
*/
case OP_MakeRecord: {
u8 *zNewRecord; /* A buffer to hold the data for the new record */
Mem *pRec; /* The new record */
u64 nData; /* Number of bytes of data space */
int nHdr; /* Number of bytes of header space */
@@ -2804,9 +2859,9 @@ case OP_MakeRecord: {
int nField; /* Number of fields in the record */
char *zAffinity; /* The affinity string for the record */
int file_format; /* File format to use for encoding */
int i; /* Space used in zNewRecord[] header */
int j; /* Space used in zNewRecord[] content */
u32 len; /* Length of a field */
u8 *zHdr; /* Where to write next byte of the header */
u8 *zPayload; /* Where to write next byte of the payload */
/* Assuming the record contains N fields, the record format looks
** like this:
@@ -2845,7 +2900,14 @@ case OP_MakeRecord: {
if( zAffinity ){
pRec = pData0;
do{
applyAffinity(pRec++, *(zAffinity++), encoding);
applyAffinity(pRec, zAffinity[0], encoding);
if( zAffinity[0]==SQLITE_AFF_REAL && (pRec->flags & MEM_Int) ){
pRec->flags |= MEM_IntReal;
pRec->flags &= ~(MEM_Int);
}
REGISTER_TRACE((int)(pRec-aMem), pRec);
zAffinity++;
pRec++;
assert( zAffinity[0]==0 || pRec<=pLast );
}while( zAffinity[0] );
}
@@ -2933,34 +2995,34 @@ case OP_MakeRecord: {
goto no_mem;
}
}
zNewRecord = (u8 *)pOut->z;
/* Write the record */
i = putVarint32(zNewRecord, nHdr);
j = nHdr;
assert( pData0<=pLast );
pRec = pData0;
do{
serial_type = pRec->uTemp;
/* EVIDENCE-OF: R-06529-47362 Following the size varint are one or more
** additional varints, one per column. */
i += putVarint32(&zNewRecord[i], serial_type); /* serial type */
/* EVIDENCE-OF: R-64536-51728 The values for each column in the record
** immediately follow the header. */
j += sqlite3VdbeSerialPut(&zNewRecord[j], pRec, serial_type); /* content */
}while( (++pRec)<=pLast );
assert( i==nHdr );
assert( j==nByte );
assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) );
pOut->n = (int)nByte;
pOut->flags = MEM_Blob;
if( nZero ){
pOut->u.nZero = nZero;
pOut->flags |= MEM_Zero;
}
REGISTER_TRACE(pOp->p3, pOut);
UPDATE_MAX_BLOBSIZE(pOut);
zHdr = (u8 *)pOut->z;
zPayload = zHdr + nHdr;
/* Write the record */
zHdr += putVarint32(zHdr, nHdr);
assert( pData0<=pLast );
pRec = pData0;
do{
serial_type = pRec->uTemp;
/* EVIDENCE-OF: R-06529-47362 Following the size varint are one or more
** additional varints, one per column. */
zHdr += putVarint32(zHdr, serial_type); /* serial type */
/* EVIDENCE-OF: R-64536-51728 The values for each column in the record
** immediately follow the header. */
zPayload += sqlite3VdbeSerialPut(zPayload, pRec, serial_type); /* content */
}while( (++pRec)<=pLast );
assert( nHdr==(int)(zHdr - (u8*)pOut->z) );
assert( nByte==(int)(zPayload - (u8*)pOut->z) );
assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) );
REGISTER_TRACE(pOp->p3, pOut);
break;
}
@@ -2990,8 +3052,9 @@ case OP_Count: { /* out2 */
/* Opcode: Savepoint P1 * * P4 *
**
** Open, release or rollback the savepoint named by parameter P4, depending
** on the value of P1. To open a new savepoint, P1==0. To release (commit) an
** existing savepoint, P1==1, or to rollback an existing savepoint P1==2.
** on the value of P1. To open a new savepoint set P1==0 (SAVEPOINT_BEGIN).
** To release (commit) an existing savepoint set P1==1 (SAVEPOINT_RELEASE).
** To rollback an existing savepoint set P1==2 (SAVEPOINT_ROLLBACK).
*/
case OP_Savepoint: {
int p1; /* Value of P1 operand */
@@ -3059,6 +3122,7 @@ case OP_Savepoint: {
}
}
}else{
assert( p1==SAVEPOINT_RELEASE || p1==SAVEPOINT_ROLLBACK );
iSavepoint = 0;
/* Find the named savepoint. If there is no such savepoint, then an
@@ -3112,6 +3176,7 @@ case OP_Savepoint: {
if( rc!=SQLITE_OK ) goto abort_due_to_error;
}
}else{
assert( p1==SAVEPOINT_RELEASE );
isSchemaChange = 0;
}
for(ii=0; ii<db->nDb; ii++){
@@ -3148,6 +3213,7 @@ case OP_Savepoint: {
db->nSavepoint--;
}
}else{
assert( p1==SAVEPOINT_ROLLBACK );
db->nDeferredCons = pSavepoint->nDeferredCons;
db->nDeferredImmCons = pSavepoint->nDeferredImmCons;
}
@@ -3686,11 +3752,15 @@ case OP_OpenEphemeral: {
if( pCx ){
/* If the ephermeral table is already open, erase all existing content
** so that the table is empty again, rather than creating a new table. */
rc = sqlite3BtreeClearTable(pCx->pBtx, pCx->pgnoRoot, 0);
assert( pCx->isEphemeral );
pCx->seqCount = 0;
pCx->cacheStatus = CACHE_STALE;
if( pCx->pBtx ){
rc = sqlite3BtreeClearTable(pCx->pBtx, pCx->pgnoRoot, 0);
}
}else{
pCx = allocateCursor(p, pOp->p1, pOp->p2, -1, CURTYPE_BTREE);
if( pCx==0 ) goto no_mem;
pCx->nullRow = 1;
pCx->isEphemeral = 1;
rc = sqlite3BtreeOpen(db->pVfs, 0, db, &pCx->pBtx,
BTREE_OMIT_JOURNAL | BTREE_SINGLE | pOp->p5,
@@ -3726,6 +3796,7 @@ case OP_OpenEphemeral: {
pCx->isOrdered = (pOp->p5!=BTREE_UNORDERED);
}
if( rc ) goto abort_due_to_error;
pCx->nullRow = 1;
break;
}
@@ -3954,6 +4025,8 @@ case OP_SeekGT: { /* jump, in3, group */
pC->seekOp = pOp->opcode;
#endif
pC->deferredMoveto = 0;
pC->cacheStatus = CACHE_STALE;
if( pC->isTable ){
/* The BTREE_SEEK_EQ flag is only set on index cursors */
assert( sqlite3BtreeCursorHasHint(pC->uc.pCursor, BTREE_SEEK_EQ)==0
@@ -3963,20 +4036,24 @@ case OP_SeekGT: { /* jump, in3, group */
** blob, or NULL. But it needs to be an integer before we can do
** the seek, so convert it. */
pIn3 = &aMem[pOp->p3];
if( (pIn3->flags & (MEM_Int|MEM_Real|MEM_Str))==MEM_Str ){
if( (pIn3->flags & (MEM_Int|MEM_Real|MEM_IntReal|MEM_Str))==MEM_Str ){
applyNumericAffinity(pIn3, 0);
}
iKey = sqlite3VdbeIntValue(pIn3);
/* If the P3 value could not be converted into an integer without
** loss of information, then special processing is required... */
if( (pIn3->flags & MEM_Int)==0 ){
if( (pIn3->flags & (MEM_Int|MEM_IntReal))==0 ){
if( (pIn3->flags & MEM_Real)==0 ){
/* If the P3 value cannot be converted into any kind of a number,
** then the seek is not possible, so jump to P2 */
VdbeBranchTaken(1,2); goto jump_to_p2;
break;
}
if( (pIn3->flags & MEM_Null) || oc>=OP_SeekGE ){
VdbeBranchTaken(1,2); goto jump_to_p2;
break;
}else{
rc = sqlite3BtreeLast(pC->uc.pCursor, &res);
if( rc!=SQLITE_OK ) goto abort_due_to_error;
goto seek_not_found;
}
}else
/* If the approximation iKey is larger than the actual real search
** term, substitute >= for > and < for <=. e.g. if the search term
@@ -4000,7 +4077,7 @@ case OP_SeekGT: { /* jump, in3, group */
assert( (OP_SeekLT & 0x0001)==(OP_SeekGE & 0x0001) );
if( (oc & 0x0001)==(OP_SeekLT & 0x0001) ) oc++;
}
}
}
rc = sqlite3BtreeMovetoUnpacked(pC->uc.pCursor, 0, (u64)iKey, 0, &res);
pC->movetoTarget = iKey; /* Used by OP_Delete */
if( rc!=SQLITE_OK ){
@@ -4054,8 +4131,6 @@ case OP_SeekGT: { /* jump, in3, group */
goto seek_not_found;
}
}
pC->deferredMoveto = 0;
pC->cacheStatus = CACHE_STALE;
#ifdef SQLITE_TEST
sqlite3_search_count++;
#endif
@@ -4355,7 +4430,9 @@ case OP_SeekRowid: { /* jump, in3 */
u64 iKey;
pIn3 = &aMem[pOp->p3];
if( (pIn3->flags & MEM_Int)==0 ){
testcase( pIn3->flags & MEM_Int );
testcase( pIn3->flags & MEM_IntReal );
if( (pIn3->flags & (MEM_Int|MEM_IntReal))==0 ){
/* Make sure pIn3->u.i contains a valid integer representation of
** the key value, but do not change the datatype of the register, as
** other parts of the perpared statement might be depending on the
@@ -4730,7 +4807,7 @@ case OP_Delete: {
** OP_Delete will have also set the pC->movetoTarget field to the rowid of
** the row that is being deleted */
i64 iKey = sqlite3BtreeIntegerKey(pC->uc.pCursor);
assert( pC->movetoTarget==iKey );
assert( CORRUPT_DB || pC->movetoTarget==iKey );
}
#endif
+4 -4
View File
@@ -245,12 +245,12 @@ struct sqlite3_value {
#define MEM_Int 0x0004 /* Value is an integer */
#define MEM_Real 0x0008 /* Value is a real number */
#define MEM_Blob 0x0010 /* Value is a BLOB */
#define MEM_AffMask 0x001f /* Mask of affinity bits */
#define MEM_FromBind 0x0020 /* Value originates from sqlite3_bind() */
/* Available 0x0040 */
#define MEM_IntReal 0x0020 /* MEM_Int that stringifies like MEM_Real */
#define MEM_AffMask 0x003f /* Mask of affinity bits */
#define MEM_FromBind 0x0040 /* Value originates from sqlite3_bind() */
#define MEM_Undefined 0x0080 /* Value is undefined */
#define MEM_Cleared 0x0100 /* NULL set by OP_Null, not from data */
#define MEM_TypeMask 0xc1df /* Mask of type bits */
#define MEM_TypeMask 0xc1bf /* Mask of type bits */
/* Whenever Mem contains a valid string or blob representation, one of
+97 -33
View File
@@ -234,39 +234,86 @@ const void *sqlite3_value_text16le(sqlite3_value *pVal){
*/
int sqlite3_value_type(sqlite3_value* pVal){
static const u8 aType[] = {
SQLITE_BLOB, /* 0x00 */
SQLITE_NULL, /* 0x01 */
SQLITE_TEXT, /* 0x02 */
SQLITE_NULL, /* 0x03 */
SQLITE_INTEGER, /* 0x04 */
SQLITE_NULL, /* 0x05 */
SQLITE_INTEGER, /* 0x06 */
SQLITE_NULL, /* 0x07 */
SQLITE_FLOAT, /* 0x08 */
SQLITE_NULL, /* 0x09 */
SQLITE_FLOAT, /* 0x0a */
SQLITE_NULL, /* 0x0b */
SQLITE_INTEGER, /* 0x0c */
SQLITE_NULL, /* 0x0d */
SQLITE_INTEGER, /* 0x0e */
SQLITE_NULL, /* 0x0f */
SQLITE_BLOB, /* 0x10 */
SQLITE_NULL, /* 0x11 */
SQLITE_TEXT, /* 0x12 */
SQLITE_NULL, /* 0x13 */
SQLITE_INTEGER, /* 0x14 */
SQLITE_NULL, /* 0x15 */
SQLITE_INTEGER, /* 0x16 */
SQLITE_NULL, /* 0x17 */
SQLITE_FLOAT, /* 0x18 */
SQLITE_NULL, /* 0x19 */
SQLITE_FLOAT, /* 0x1a */
SQLITE_NULL, /* 0x1b */
SQLITE_INTEGER, /* 0x1c */
SQLITE_NULL, /* 0x1d */
SQLITE_INTEGER, /* 0x1e */
SQLITE_NULL, /* 0x1f */
SQLITE_BLOB, /* 0x00 (not possible) */
SQLITE_NULL, /* 0x01 NULL */
SQLITE_TEXT, /* 0x02 TEXT */
SQLITE_NULL, /* 0x03 (not possible) */
SQLITE_INTEGER, /* 0x04 INTEGER */
SQLITE_NULL, /* 0x05 (not possible) */
SQLITE_INTEGER, /* 0x06 INTEGER + TEXT */
SQLITE_NULL, /* 0x07 (not possible) */
SQLITE_FLOAT, /* 0x08 FLOAT */
SQLITE_NULL, /* 0x09 (not possible) */
SQLITE_FLOAT, /* 0x0a FLOAT + TEXT */
SQLITE_NULL, /* 0x0b (not possible) */
SQLITE_INTEGER, /* 0x0c (not possible) */
SQLITE_NULL, /* 0x0d (not possible) */
SQLITE_INTEGER, /* 0x0e (not possible) */
SQLITE_NULL, /* 0x0f (not possible) */
SQLITE_BLOB, /* 0x10 BLOB */
SQLITE_NULL, /* 0x11 (not possible) */
SQLITE_TEXT, /* 0x12 (not possible) */
SQLITE_NULL, /* 0x13 (not possible) */
SQLITE_INTEGER, /* 0x14 INTEGER + BLOB */
SQLITE_NULL, /* 0x15 (not possible) */
SQLITE_INTEGER, /* 0x16 (not possible) */
SQLITE_NULL, /* 0x17 (not possible) */
SQLITE_FLOAT, /* 0x18 FLOAT + BLOB */
SQLITE_NULL, /* 0x19 (not possible) */
SQLITE_FLOAT, /* 0x1a (not possible) */
SQLITE_NULL, /* 0x1b (not possible) */
SQLITE_INTEGER, /* 0x1c (not possible) */
SQLITE_NULL, /* 0x1d (not possible) */
SQLITE_INTEGER, /* 0x1e (not possible) */
SQLITE_NULL, /* 0x1f (not possible) */
SQLITE_FLOAT, /* 0x20 INTREAL */
SQLITE_NULL, /* 0x21 (not possible) */
SQLITE_TEXT, /* 0x22 INTREAL + TEXT */
SQLITE_NULL, /* 0x23 (not possible) */
SQLITE_FLOAT, /* 0x24 (not possible) */
SQLITE_NULL, /* 0x25 (not possible) */
SQLITE_FLOAT, /* 0x26 (not possible) */
SQLITE_NULL, /* 0x27 (not possible) */
SQLITE_FLOAT, /* 0x28 (not possible) */
SQLITE_NULL, /* 0x29 (not possible) */
SQLITE_FLOAT, /* 0x2a (not possible) */
SQLITE_NULL, /* 0x2b (not possible) */
SQLITE_FLOAT, /* 0x2c (not possible) */
SQLITE_NULL, /* 0x2d (not possible) */
SQLITE_FLOAT, /* 0x2e (not possible) */
SQLITE_NULL, /* 0x2f (not possible) */
SQLITE_BLOB, /* 0x30 (not possible) */
SQLITE_NULL, /* 0x31 (not possible) */
SQLITE_TEXT, /* 0x32 (not possible) */
SQLITE_NULL, /* 0x33 (not possible) */
SQLITE_FLOAT, /* 0x34 (not possible) */
SQLITE_NULL, /* 0x35 (not possible) */
SQLITE_FLOAT, /* 0x36 (not possible) */
SQLITE_NULL, /* 0x37 (not possible) */
SQLITE_FLOAT, /* 0x38 (not possible) */
SQLITE_NULL, /* 0x39 (not possible) */
SQLITE_FLOAT, /* 0x3a (not possible) */
SQLITE_NULL, /* 0x3b (not possible) */
SQLITE_FLOAT, /* 0x3c (not possible) */
SQLITE_NULL, /* 0x3d (not possible) */
SQLITE_FLOAT, /* 0x3e (not possible) */
SQLITE_NULL, /* 0x3f (not possible) */
};
#ifdef SQLITE_DEBUG
{
int eType = SQLITE_BLOB;
if( pVal->flags & MEM_Null ){
eType = SQLITE_NULL;
}else if( pVal->flags & (MEM_Real|MEM_IntReal) ){
eType = SQLITE_FLOAT;
}else if( pVal->flags & MEM_Int ){
eType = SQLITE_INTEGER;
}else if( pVal->flags & MEM_Str ){
eType = SQLITE_TEXT;
}
assert( eType == aType[pVal->flags&MEM_AffMask] );
}
#endif
return aType[pVal->flags&MEM_AffMask];
}
@@ -516,6 +563,21 @@ void sqlite3_result_error_nomem(sqlite3_context *pCtx){
sqlite3OomFault(pCtx->pOut->db);
}
#ifndef SQLITE_UNTESTABLE
/* Force the INT64 value currently stored as the result to be
** a MEM_IntReal value. See the SQLITE_TESTCTRL_RESULT_INTREAL
** test-control.
*/
void sqlite3ResultIntReal(sqlite3_context *pCtx){
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
if( pCtx->pOut->flags & MEM_Int ){
pCtx->pOut->flags &= ~MEM_Int;
pCtx->pOut->flags |= MEM_IntReal;
}
}
#endif
/*
** This function is called after a transaction has been committed. It
** invokes callbacks registered with sqlite3_wal_hook() as required.
@@ -1802,7 +1864,9 @@ int sqlite3_preupdate_old(sqlite3 *db, int iIdx, sqlite3_value **ppValue){
}else if( iIdx>=p->pUnpacked->nField ){
*ppValue = (sqlite3_value *)columnNullValue();
}else if( p->pTab->aCol[iIdx].affinity==SQLITE_AFF_REAL ){
if( pMem->flags & MEM_Int ){
if( pMem->flags & (MEM_Int|MEM_IntReal) ){
testcase( pMem->flags & MEM_Int );
testcase( pMem->flags & MEM_IntReal );
sqlite3VdbeMemRealify(pMem);
}
}
+52 -12
View File
@@ -629,6 +629,7 @@ int sqlite3VdbeAssertMayAbort(Vdbe *v, int mayAbort){
int hasAbort = 0;
int hasFkCounter = 0;
int hasCreateTable = 0;
int hasCreateIndex = 0;
int hasInitCoroutine = 0;
Op *pOp;
VdbeOpIter sIter;
@@ -647,6 +648,14 @@ int sqlite3VdbeAssertMayAbort(Vdbe *v, int mayAbort){
break;
}
if( opcode==OP_CreateBtree && pOp->p3==BTREE_INTKEY ) hasCreateTable = 1;
if( mayAbort ){
/* hasCreateIndex may also be set for some DELETE statements that use
** OP_Clear. So this routine may end up returning true in the case
** where a "DELETE FROM tbl" has a statement-journal but does not
** require one. This is not so bad - it is an inefficiency, not a bug. */
if( opcode==OP_CreateBtree && pOp->p3==BTREE_BLOBKEY ) hasCreateIndex = 1;
if( opcode==OP_Clear ) hasCreateIndex = 1;
}
if( opcode==OP_InitCoroutine ) hasInitCoroutine = 1;
#ifndef SQLITE_OMIT_FOREIGN_KEY
if( opcode==OP_FkCounter && pOp->p1==0 && pOp->p2==1 ){
@@ -662,7 +671,8 @@ int sqlite3VdbeAssertMayAbort(Vdbe *v, int mayAbort){
** true for this case to prevent the assert() in the callers frame
** from failing. */
return ( v->db->mallocFailed || hasAbort==mayAbort || hasFkCounter
|| (hasCreateTable && hasInitCoroutine) );
|| (hasCreateTable && hasInitCoroutine) || hasCreateIndex
);
}
#endif /* SQLITE_DEBUG - the sqlite3AssertMayAbort() function */
@@ -1534,7 +1544,7 @@ static char *displayP4(Op *pOp, char *zTemp, int nTemp){
Mem *pMem = pOp->p4.pMem;
if( pMem->flags & MEM_Str ){
zP4 = pMem->z;
}else if( pMem->flags & MEM_Int ){
}else if( pMem->flags & (MEM_Int|MEM_IntReal) ){
sqlite3_str_appendf(&x, "%lld", pMem->u.i);
}else if( pMem->flags & MEM_Real ){
sqlite3_str_appendf(&x, "%.16g", pMem->u.r);
@@ -2896,7 +2906,7 @@ int sqlite3VdbeHalt(Vdbe *p){
}
/* Check for immediate foreign key violations. */
if( p->rc==SQLITE_OK ){
if( p->rc==SQLITE_OK || (p->errorAction==OE_Fail && !isSpecialError) ){
sqlite3VdbeCheckFk(p, 0);
}
@@ -3422,6 +3432,8 @@ int sqlite3VdbeCursorMoveto(VdbeCursor **pp, int *piCol){
/*
** Return the serial-type for the value stored in pMem.
**
** This routine might convert a large MEM_IntReal value into MEM_Real.
*/
u32 sqlite3VdbeSerialType(Mem *pMem, int file_format, u32 *pLen){
int flags = pMem->flags;
@@ -3432,11 +3444,13 @@ u32 sqlite3VdbeSerialType(Mem *pMem, int file_format, u32 *pLen){
*pLen = 0;
return 0;
}
if( flags&MEM_Int ){
if( flags&(MEM_Int|MEM_IntReal) ){
/* Figure out whether to use 1, 2, 4, 6 or 8 bytes. */
# define MAX_6BYTE ((((i64)0x00008000)<<32)-1)
i64 i = pMem->u.i;
u64 u;
testcase( flags & MEM_Int );
testcase( flags & MEM_IntReal );
if( i<0 ){
u = ~i;
}else{
@@ -3456,6 +3470,15 @@ u32 sqlite3VdbeSerialType(Mem *pMem, int file_format, u32 *pLen){
if( u<=2147483647 ){ *pLen = 4; return 4; }
if( u<=MAX_6BYTE ){ *pLen = 6; return 5; }
*pLen = 8;
if( flags&MEM_IntReal ){
/* If the value is IntReal and is going to take up 8 bytes to store
** as an integer, then we might as well make it an 8-byte floating
** point value */
pMem->u.r = (double)pMem->u.i;
pMem->flags &= ~MEM_IntReal;
pMem->flags |= MEM_Real;
return 7;
}
return 6;
}
if( flags&MEM_Real ){
@@ -3629,7 +3652,7 @@ u32 sqlite3VdbeSerialPut(u8 *buf, Mem *pMem, u32 serial_type){
** routine so that in most cases the overhead of moving the stack pointer
** is avoided.
*/
static u32 SQLITE_NOINLINE serialGet(
static u32 serialGet(
const unsigned char *buf, /* Buffer to deserialize from */
u32 serial_type, /* Serial type to deserialize */
Mem *pMem /* Memory cell to write value into */
@@ -3661,7 +3684,7 @@ static u32 SQLITE_NOINLINE serialGet(
assert( sizeof(x)==8 && sizeof(pMem->u.r)==8 );
swapMixedEndianFloat(x);
memcpy(&pMem->u.r, &x, sizeof(x));
pMem->flags = sqlite3IsNaN(pMem->u.r) ? MEM_Null : MEM_Real;
pMem->flags = IsNaN(x) ? MEM_Null : MEM_Real;
}
return 8;
}
@@ -4111,8 +4134,13 @@ int sqlite3MemCompare(const Mem *pMem1, const Mem *pMem2, const CollSeq *pColl){
/* At least one of the two values is a number
*/
if( combined_flags&(MEM_Int|MEM_Real) ){
if( (f1 & f2 & MEM_Int)!=0 ){
if( combined_flags&(MEM_Int|MEM_Real|MEM_IntReal) ){
testcase( combined_flags & MEM_Int );
testcase( combined_flags & MEM_Real );
testcase( combined_flags & MEM_IntReal );
if( (f1 & f2 & (MEM_Int|MEM_IntReal))!=0 ){
testcase( f1 & f2 & MEM_Int );
testcase( f1 & f2 & MEM_IntReal );
if( pMem1->u.i < pMem2->u.i ) return -1;
if( pMem1->u.i > pMem2->u.i ) return +1;
return 0;
@@ -4122,15 +4150,23 @@ int sqlite3MemCompare(const Mem *pMem1, const Mem *pMem2, const CollSeq *pColl){
if( pMem1->u.r > pMem2->u.r ) return +1;
return 0;
}
if( (f1&MEM_Int)!=0 ){
if( (f1&(MEM_Int|MEM_IntReal))!=0 ){
testcase( f1 & MEM_Int );
testcase( f1 & MEM_IntReal );
if( (f2&MEM_Real)!=0 ){
return sqlite3IntFloatCompare(pMem1->u.i, pMem2->u.r);
}else if( (f2&(MEM_Int|MEM_IntReal))!=0 ){
if( pMem1->u.i < pMem2->u.i ) return -1;
if( pMem1->u.i > pMem2->u.i ) return +1;
return 0;
}else{
return -1;
}
}
if( (f1&MEM_Real)!=0 ){
if( (f2&MEM_Int)!=0 ){
if( (f2&(MEM_Int|MEM_IntReal))!=0 ){
testcase( f2 & MEM_Int );
testcase( f2 & MEM_IntReal );
return -sqlite3IntFloatCompare(pMem2->u.i, pMem1->u.r);
}else{
return -1;
@@ -4279,7 +4315,9 @@ int sqlite3VdbeRecordCompareWithSkip(
u32 serial_type;
/* RHS is an integer */
if( pRhs->flags & MEM_Int ){
if( pRhs->flags & (MEM_Int|MEM_IntReal) ){
testcase( pRhs->flags & MEM_Int );
testcase( pRhs->flags & MEM_IntReal );
serial_type = aKey1[idx1];
testcase( serial_type==12 );
if( serial_type>=10 ){
@@ -4624,7 +4662,9 @@ RecordCompare sqlite3VdbeFindCompare(UnpackedRecord *p){
testcase( flags & MEM_Real );
testcase( flags & MEM_Null );
testcase( flags & MEM_Blob );
if( (flags & (MEM_Real|MEM_Null|MEM_Blob))==0 && p->pKeyInfo->aColl[0]==0 ){
if( (flags & (MEM_Real|MEM_IntReal|MEM_Null|MEM_Blob))==0
&& p->pKeyInfo->aColl[0]==0
){
assert( flags & MEM_Str );
return vdbeRecordCompareString;
}
+100 -59
View File
@@ -18,6 +18,11 @@
#include "sqliteInt.h"
#include "vdbeInt.h"
/* True if X is a power of two. 0 is considered a power of two here.
** In other words, return true if X has at most one bit set.
*/
#define ISPOWEROF2(X) (((X)&((X)-1))==0)
#ifdef SQLITE_DEBUG
/*
** Check invariants on a Mem object.
@@ -37,8 +42,8 @@ int sqlite3VdbeCheckMemInvariants(Mem *p){
** That saves a few cycles in inner loops. */
assert( (p->flags & MEM_Dyn)==0 || p->szMalloc==0 );
/* Cannot be both MEM_Int and MEM_Real at the same time */
assert( (p->flags & (MEM_Int|MEM_Real))!=(MEM_Int|MEM_Real) );
/* Cannot have more than one of MEM_Int, MEM_Real, or MEM_IntReal */
assert( ISPOWEROF2(p->flags & (MEM_Int|MEM_Real|MEM_IntReal)) );
if( p->flags & MEM_Null ){
/* Cannot be both MEM_Null and some other type */
@@ -92,9 +97,31 @@ int sqlite3VdbeCheckMemInvariants(Mem *p){
}
#endif
/*
** Render a Mem object which is one of MEM_Int, MEM_Real, or MEM_IntReal
** into a buffer.
*/
static void vdbeMemRenderNum(int sz, char *zBuf, Mem *p){
StrAccum acc;
assert( p->flags & (MEM_Int|MEM_Real|MEM_IntReal) );
sqlite3StrAccumInit(&acc, 0, zBuf, sz, 0);
if( p->flags & MEM_Int ){
sqlite3_str_appendf(&acc, "%lld", p->u.i);
}else if( p->flags & MEM_IntReal ){
sqlite3_str_appendf(&acc, "%!.15g", (double)p->u.i);
}else{
sqlite3_str_appendf(&acc, "%!.15g", p->u.r);
}
assert( acc.zText==zBuf && acc.mxAlloc<=0 );
zBuf[acc.nChar] = 0; /* Fast version of sqlite3StrAccumFinish(&acc) */
}
#ifdef SQLITE_DEBUG
/*
** Check that string value of pMem agrees with its integer or real value.
** Validity checks on pMem. pMem holds a string.
**
** (1) Check that string value of pMem agrees with its integer or real value.
** (2) Check that the string is correctly zero terminated
**
** A single int or real value always converts to the same strings. But
** many different strings can be converted into the same int or real.
@@ -112,17 +139,24 @@ int sqlite3VdbeCheckMemInvariants(Mem *p){
**
** This routine is for use inside of assert() statements only.
*/
int sqlite3VdbeMemConsistentDualRep(Mem *p){
int sqlite3VdbeMemValidStrRep(Mem *p){
char zBuf[100];
char *z;
int i, j, incr;
if( (p->flags & MEM_Str)==0 ) return 1;
if( (p->flags & (MEM_Int|MEM_Real))==0 ) return 1;
if( p->flags & MEM_Int ){
sqlite3_snprintf(sizeof(zBuf),zBuf,"%lld",p->u.i);
}else{
sqlite3_snprintf(sizeof(zBuf),zBuf,"%!.15g",p->u.r);
if( p->flags & MEM_Term ){
/* Insure that the string is properly zero-terminated. Pay particular
** attention to the case where p->n is odd */
if( p->szMalloc>0 && p->z==p->zMalloc ){
assert( p->enc==SQLITE_UTF8 || p->szMalloc >= ((p->n+1)&~1)+2 );
assert( p->enc!=SQLITE_UTF8 || p->szMalloc >= p->n+1 );
}
assert( p->z[p->n]==0 );
assert( p->enc==SQLITE_UTF8 || p->z[(p->n+1)&~1]==0 );
assert( p->enc==SQLITE_UTF8 || p->z[((p->n+1)&~1)+1]==0 );
}
if( (p->flags & (MEM_Int|MEM_Real|MEM_IntReal))==0 ) return 1;
vdbeMemRenderNum(sizeof(zBuf), zBuf, p);
z = p->z;
i = j = 0;
incr = 1;
@@ -234,8 +268,8 @@ SQLITE_NOINLINE int sqlite3VdbeMemGrow(Mem *pMem, int n, int bPreserve){
**
** Any prior string or blob content in the pMem object may be discarded.
** The pMem->xDel destructor is called, if it exists. Though MEM_Str
** and MEM_Blob values may be discarded, MEM_Int, MEM_Real, and MEM_Null
** values are preserved.
** and MEM_Blob values may be discarded, MEM_Int, MEM_Real, MEM_IntReal,
** and MEM_Null values are preserved.
**
** Return SQLITE_OK on success or an error code (probably SQLITE_NOMEM)
** if unable to complete the resizing.
@@ -248,20 +282,26 @@ int sqlite3VdbeMemClearAndResize(Mem *pMem, int szNew){
}
assert( (pMem->flags & MEM_Dyn)==0 );
pMem->z = pMem->zMalloc;
pMem->flags &= (MEM_Null|MEM_Int|MEM_Real);
pMem->flags &= (MEM_Null|MEM_Int|MEM_Real|MEM_IntReal);
return SQLITE_OK;
}
/*
** It is already known that pMem contains an unterminated string.
** Add the zero terminator.
**
** Three bytes of zero are added. In this way, there is guaranteed
** to be a double-zero byte at an even byte boundary in order to
** terminate a UTF16 string, even if the initial size of the buffer
** is an odd number of bytes.
*/
static SQLITE_NOINLINE int vdbeMemAddTerminator(Mem *pMem){
if( sqlite3VdbeMemGrow(pMem, pMem->n+2, 1) ){
if( sqlite3VdbeMemGrow(pMem, pMem->n+3, 1) ){
return SQLITE_NOMEM_BKPT;
}
pMem->z[pMem->n] = 0;
pMem->z[pMem->n+1] = 0;
pMem->z[pMem->n+2] = 0;
pMem->flags |= MEM_Term;
return SQLITE_OK;
}
@@ -335,12 +375,12 @@ int sqlite3VdbeMemNulTerminate(Mem *pMem){
}
/*
** Add MEM_Str to the set of representations for the given Mem. Numbers
** are converted using sqlite3_snprintf(). Converting a BLOB to a string
** is a no-op.
** Add MEM_Str to the set of representations for the given Mem. This
** routine is only called if pMem is a number of some kind, not a NULL
** or a BLOB.
**
** Existing representations MEM_Int and MEM_Real are invalidated if
** bForce is true but are retained if bForce is false.
** Existing representations MEM_Int, MEM_Real, or MEM_IntReal are invalidated
** if bForce is true but are retained if bForce is false.
**
** A MEM_Null value will never be passed to this function. This function is
** used for converting values to text for returning to the user (i.e. via
@@ -349,13 +389,12 @@ int sqlite3VdbeMemNulTerminate(Mem *pMem){
** user and the latter is an internal programming error.
*/
int sqlite3VdbeMemStringify(Mem *pMem, u8 enc, u8 bForce){
int fg = pMem->flags;
const int nByte = 32;
assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
assert( !(fg&MEM_Zero) );
assert( !(fg&(MEM_Str|MEM_Blob)) );
assert( fg&(MEM_Int|MEM_Real) );
assert( !(pMem->flags&MEM_Zero) );
assert( !(pMem->flags&(MEM_Str|MEM_Blob)) );
assert( pMem->flags&(MEM_Int|MEM_Real|MEM_IntReal) );
assert( !sqlite3VdbeMemIsRowSet(pMem) );
assert( EIGHT_BYTE_ALIGNMENT(pMem) );
@@ -365,23 +404,12 @@ int sqlite3VdbeMemStringify(Mem *pMem, u8 enc, u8 bForce){
return SQLITE_NOMEM_BKPT;
}
/* For a Real or Integer, use sqlite3_snprintf() to produce the UTF-8
** string representation of the value. Then, if the required encoding
** is UTF-16le or UTF-16be do a translation.
**
** FIX ME: It would be better if sqlite3_snprintf() could do UTF-16.
*/
if( fg & MEM_Int ){
sqlite3_snprintf(nByte, pMem->z, "%lld", pMem->u.i);
}else{
assert( fg & MEM_Real );
sqlite3_snprintf(nByte, pMem->z, "%!.15g", pMem->u.r);
}
vdbeMemRenderNum(nByte, pMem->z, pMem);
assert( pMem->z!=0 );
pMem->n = sqlite3Strlen30NN(pMem->z);
pMem->enc = SQLITE_UTF8;
pMem->flags |= MEM_Str|MEM_Term;
if( bForce ) pMem->flags &= ~(MEM_Int|MEM_Real);
if( bForce ) pMem->flags &= ~(MEM_Int|MEM_Real|MEM_IntReal);
sqlite3VdbeChangeEncoding(pMem, enc);
return SQLITE_OK;
}
@@ -555,7 +583,8 @@ i64 sqlite3VdbeIntValue(Mem *pMem){
assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
assert( EIGHT_BYTE_ALIGNMENT(pMem) );
flags = pMem->flags;
if( flags & MEM_Int ){
if( flags & (MEM_Int|MEM_IntReal) ){
testcase( flags & MEM_IntReal );
return pMem->u.i;
}else if( flags & MEM_Real ){
return doubleToInt64(pMem->u.r);
@@ -584,7 +613,8 @@ double sqlite3VdbeRealValue(Mem *pMem){
assert( EIGHT_BYTE_ALIGNMENT(pMem) );
if( pMem->flags & MEM_Real ){
return pMem->u.r;
}else if( pMem->flags & MEM_Int ){
}else if( pMem->flags & (MEM_Int|MEM_IntReal) ){
testcase( pMem->flags & MEM_IntReal );
return (double)pMem->u.i;
}else if( pMem->flags & (MEM_Str|MEM_Blob) ){
return memRealValue(pMem);
@@ -599,7 +629,8 @@ double sqlite3VdbeRealValue(Mem *pMem){
** Return the value ifNull if pMem is NULL.
*/
int sqlite3VdbeBooleanValue(Mem *pMem, int ifNull){
if( pMem->flags & MEM_Int ) return pMem->u.i!=0;
testcase( pMem->flags & MEM_IntReal );
if( pMem->flags & (MEM_Int|MEM_IntReal) ) return pMem->u.i!=0;
if( pMem->flags & MEM_Null ) return ifNull;
return sqlite3VdbeRealValue(pMem)!=0.0;
}
@@ -662,17 +693,21 @@ int sqlite3VdbeMemRealify(Mem *pMem){
/* Compare a floating point value to an integer. Return true if the two
** values are the same within the precision of the floating point value.
**
** This function assumes that i was obtained by assignment from r1.
**
** For some versions of GCC on 32-bit machines, if you do the more obvious
** comparison of "r1==(double)i" you sometimes get an answer of false even
** though the r1 and (double)i values are bit-for-bit the same.
*/
static int sqlite3RealSameAsInt(double r1, sqlite3_int64 i){
int sqlite3RealSameAsInt(double r1, sqlite3_int64 i){
double r2 = (double)i;
return memcmp(&r1, &r2, sizeof(r1))==0;
return r1==0.0
|| (memcmp(&r1, &r2, sizeof(r1))==0
&& i >= -2251799813685248LL && i < 2251799813685248LL);
}
/*
** Convert pMem so that it has types MEM_Real or MEM_Int or both.
** Convert pMem so that it has type MEM_Real or MEM_Int.
** Invalidate any prior representations.
**
** Every effort is made to force the conversion, even if the input
@@ -680,25 +715,26 @@ static int sqlite3RealSameAsInt(double r1, sqlite3_int64 i){
** as much of the string as we can and ignore the rest.
*/
int sqlite3VdbeMemNumerify(Mem *pMem){
if( (pMem->flags & (MEM_Int|MEM_Real|MEM_Null))==0 ){
testcase( pMem->flags & MEM_Int );
testcase( pMem->flags & MEM_Real );
testcase( pMem->flags & MEM_IntReal );
testcase( pMem->flags & MEM_Null );
if( (pMem->flags & (MEM_Int|MEM_Real|MEM_IntReal|MEM_Null))==0 ){
int rc;
sqlite3_int64 ix;
assert( (pMem->flags & (MEM_Blob|MEM_Str))!=0 );
assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
rc = sqlite3Atoi64(pMem->z, &pMem->u.i, pMem->n, pMem->enc);
if( rc==0 ){
rc = sqlite3AtoF(pMem->z, &pMem->u.r, pMem->n, pMem->enc);
if( ((rc==0 || rc==1) && sqlite3Atoi64(pMem->z, &ix, pMem->n, pMem->enc)<=1)
|| sqlite3RealSameAsInt(pMem->u.r, (ix = (i64)pMem->u.r))
){
pMem->u.i = ix;
MemSetTypeFlag(pMem, MEM_Int);
}else{
i64 i = pMem->u.i;
sqlite3AtoF(pMem->z, &pMem->u.r, pMem->n, pMem->enc);
if( rc==1 && sqlite3RealSameAsInt(pMem->u.r, i) ){
pMem->u.i = i;
MemSetTypeFlag(pMem, MEM_Int);
}else{
MemSetTypeFlag(pMem, MEM_Real);
}
MemSetTypeFlag(pMem, MEM_Real);
}
}
assert( (pMem->flags & (MEM_Int|MEM_Real|MEM_Null))!=0 );
assert( (pMem->flags & (MEM_Int|MEM_Real|MEM_IntReal|MEM_Null))!=0 );
pMem->flags &= ~(MEM_Str|MEM_Blob|MEM_Zero);
return SQLITE_OK;
}
@@ -741,7 +777,7 @@ void sqlite3VdbeMemCast(Mem *pMem, u8 aff, u8 encoding){
pMem->flags |= (pMem->flags&MEM_Blob)>>3;
sqlite3ValueApplyAffinity(pMem, SQLITE_AFF_TEXT, encoding);
assert( pMem->flags & MEM_Str || pMem->db->mallocFailed );
pMem->flags &= ~(MEM_Int|MEM_Real|MEM_Blob|MEM_Zero);
pMem->flags &= ~(MEM_Int|MEM_Real|MEM_IntReal|MEM_Blob|MEM_Zero);
break;
}
}
@@ -925,7 +961,7 @@ void sqlite3VdbeMemAboutToChange(Vdbe *pVdbe, Mem *pMem){
** dual type, are allowed, as long as the underlying value is the
** same. */
u16 mFlags = pMem->flags & pX->flags & pX->mScopyFlags;
assert( (mFlags&MEM_Int)==0 || pMem->u.i==pX->u.i );
assert( (mFlags&(MEM_Int|MEM_IntReal))==0 || pMem->u.i==pX->u.i );
assert( (mFlags&MEM_Real)==0 || pMem->u.r==pX->u.r );
assert( (mFlags&MEM_Str)==0 || (pMem->n==pX->n && pMem->z==pX->z) );
assert( (mFlags&MEM_Blob)==0 || sqlite3BlobCompare(pMem,pX)==0 );
@@ -1200,7 +1236,7 @@ static SQLITE_NOINLINE const void *valueToText(sqlite3_value* pVal, u8 enc){
assert(pVal->enc==(enc & ~SQLITE_UTF16_ALIGNED) || pVal->db==0
|| pVal->db->mallocFailed );
if( pVal->enc==(enc & ~SQLITE_UTF16_ALIGNED) ){
assert( sqlite3VdbeMemConsistentDualRep(pVal) );
assert( sqlite3VdbeMemValidStrRep(pVal) );
return pVal->z;
}else{
return 0;
@@ -1223,7 +1259,7 @@ const void *sqlite3ValueText(sqlite3_value* pVal, u8 enc){
assert( (enc&3)==(enc&~SQLITE_UTF16_ALIGNED) );
assert( !sqlite3VdbeMemIsRowSet(pVal) );
if( (pVal->flags&(MEM_Str|MEM_Term))==(MEM_Str|MEM_Term) && pVal->enc==enc ){
assert( sqlite3VdbeMemConsistentDualRep(pVal) );
assert( sqlite3VdbeMemValidStrRep(pVal) );
return pVal->z;
}
if( pVal->flags&MEM_Null ){
@@ -1488,7 +1524,12 @@ static int valueFromExpr(
}else{
sqlite3ValueApplyAffinity(pVal, affinity, SQLITE_UTF8);
}
if( pVal->flags & (MEM_Int|MEM_Real) ) pVal->flags &= ~MEM_Str;
assert( (pVal->flags & MEM_IntReal)==0 );
if( pVal->flags & (MEM_Int|MEM_IntReal|MEM_Real) ){
testcase( pVal->flags & MEM_Int );
testcase( pVal->flags & MEM_Real );
pVal->flags &= ~MEM_Str;
}
if( enc!=SQLITE_UTF8 ){
rc = sqlite3VdbeChangeEncoding(pVal, enc);
}
@@ -1511,7 +1552,7 @@ static int valueFromExpr(
}else if( op==TK_NULL ){
pVal = valueNew(db, pCtx);
if( pVal==0 ) goto no_mem;
sqlite3VdbeMemNumerify(pVal);
sqlite3VdbeMemSetNull(pVal);
}
#ifndef SQLITE_OMIT_BLOB_LITERAL
else if( op==TK_BLOB ){
+1 -1
View File
@@ -130,7 +130,7 @@ char *sqlite3VdbeExpandSql(
pVar = &p->aVar[idx-1];
if( pVar->flags & MEM_Null ){
sqlite3_str_append(&out, "NULL", 4);
}else if( pVar->flags & MEM_Int ){
}else if( pVar->flags & (MEM_Int|MEM_IntReal) ){
sqlite3_str_appendf(&out, "%lld", pVar->u.i);
}else if( pVar->flags & MEM_Real ){
sqlite3_str_appendf(&out, "%!.15g", pVar->u.r);
+2
View File
@@ -841,6 +841,7 @@ int sqlite3VtabCallDestroy(sqlite3 *db, int iDb, const char *zTab){
p = vtabDisconnectAll(db, pTab);
xDestroy = p->pMod->pModule->xDestroy;
assert( xDestroy!=0 ); /* Checked before the virtual table is created */
pTab->nTabRef++;
rc = xDestroy(p->pVtab);
/* Remove the sqlite3_vtab* from the aVTrans[] array, if applicable */
if( rc==SQLITE_OK ){
@@ -849,6 +850,7 @@ int sqlite3VtabCallDestroy(sqlite3 *db, int iDb, const char *zTab){
pTab->pVTable = 0;
sqlite3VtabUnlock(p);
}
sqlite3DeleteTable(db, pTab);
}
return rc;
+3 -3
View File
@@ -2908,9 +2908,9 @@ int sqlite3WalFindFrame(
}
nCollide = HASHTABLE_NSLOT;
for(iKey=walHash(pgno); sLoc.aHash[iKey]; iKey=walNextHash(iKey)){
u32 iFrame = sLoc.aHash[iKey] + sLoc.iZero;
if( iFrame<=iLast && iFrame>=pWal->minFrame
&& sLoc.aPgno[sLoc.aHash[iKey]]==pgno ){
u32 iH = sLoc.aHash[iKey];
u32 iFrame = iH + sLoc.iZero;
if( iFrame<=iLast && iFrame>=pWal->minFrame && sLoc.aPgno[iH]==pgno ){
assert( iFrame>iRead || CORRUPT_DB );
iRead = iFrame;
}
+11 -12
View File
@@ -562,17 +562,17 @@ static LogEst estLog(LogEst N){
** opcodes into OP_Copy when the table is being accessed via co-routine
** instead of via table lookup.
**
** If the bIncrRowid parameter is 0, then any OP_Rowid instructions on
** cursor iTabCur are transformed into OP_Null. Or, if bIncrRowid is non-zero,
** then each OP_Rowid is transformed into an instruction to increment the
** value stored in its output register.
** If the iAutoidxCur is not zero, then any OP_Rowid instructions on
** cursor iTabCur are transformed into OP_Sequence opcode for the
** iAutoidxCur cursor, in order to generate unique rowids for the
** automatic index being generated.
*/
static void translateColumnToCopy(
Parse *pParse, /* Parsing context */
int iStart, /* Translate from this opcode to the end */
int iTabCur, /* OP_Column/OP_Rowid references to this table */
int iRegister, /* The first column is in this register */
int bIncrRowid /* If non-zero, transform OP_rowid to OP_AddImm(1) */
int iAutoidxCur /* If non-zero, cursor of autoindex being generated */
){
Vdbe *v = pParse->pVdbe;
VdbeOp *pOp = sqlite3VdbeGetOp(v, iStart);
@@ -586,11 +586,9 @@ static void translateColumnToCopy(
pOp->p2 = pOp->p3;
pOp->p3 = 0;
}else if( pOp->opcode==OP_Rowid ){
if( bIncrRowid ){
/* Increment the value stored in the P2 operand of the OP_Rowid. */
pOp->opcode = OP_AddImm;
pOp->p1 = pOp->p2;
pOp->p2 = 1;
if( iAutoidxCur ){
pOp->opcode = OP_Sequence;
pOp->p1 = iAutoidxCur;
}else{
pOp->opcode = OP_Null;
pOp->p1 = 0;
@@ -737,7 +735,7 @@ static void constructAutomaticIndex(
&& (pTerm->wtFlags & TERM_VIRTUAL)==0
&& !ExprHasProperty(pExpr, EP_FromJoin)
&& sqlite3ExprIsTableConstant(pExpr, pSrc->iCursor) ){
pPartial = sqlite3ExprAnd(pParse->db, pPartial,
pPartial = sqlite3ExprAnd(pParse, pPartial,
sqlite3ExprDup(pParse->db, pExpr, 0));
}
if( termCanDriveIndex(pTerm, pSrc, notReady) ){
@@ -864,8 +862,9 @@ static void constructAutomaticIndex(
if( pTabItem->fg.viaCoroutine ){
sqlite3VdbeChangeP2(v, addrCounter, regBase+n);
testcase( pParse->db->mallocFailed );
assert( pLevel->iIdxCur>0 );
translateColumnToCopy(pParse, addrTop, pLevel->iTabCur,
pTabItem->regResult, 1);
pTabItem->regResult, pLevel->iIdxCur);
sqlite3VdbeGoto(v, addrTop);
pTabItem->fg.viaCoroutine = 0;
}else{
+4
View File
@@ -14,6 +14,8 @@
** planner logic in "where.c". These definitions are broken out into
** a separate source file for easier editing.
*/
#ifndef SQLITE_WHEREINT_H
#define SQLITE_WHEREINT_H
/*
** Trace output macros
@@ -584,3 +586,5 @@ void sqlite3WhereTabFuncArgs(Parse*, struct SrcList_item*, WhereClause*);
#define WHERE_UNQ_WANTED 0x00010000 /* WHERE_ONEROW would have been helpful*/
#define WHERE_PARTIALIDX 0x00020000 /* The automatic index is partial */
#define WHERE_IN_EARLYOUT 0x00040000 /* Perhaps quit IN loops early */
#endif /* !defined(SQLITE_WHEREINT_H) */
+3 -3
View File
@@ -999,7 +999,7 @@ static void codeCursorHint(
}
/* If we survive all prior tests, that means this term is worth hinting */
pExpr = sqlite3ExprAnd(db, pExpr, sqlite3ExprDup(db, pTerm->pExpr, 0));
pExpr = sqlite3ExprAnd(pParse, pExpr, sqlite3ExprDup(db, pTerm->pExpr, 0));
}
if( pExpr!=0 ){
sWalker.xExprCallback = codeCursorHintFixExpr;
@@ -1964,7 +1964,7 @@ Bitmask sqlite3WhereCodeOneLoopStart(
if( (pWC->a[iTerm].eOperator & WO_ALL)==0 ) continue;
testcase( pWC->a[iTerm].wtFlags & TERM_ORINFO );
pExpr = sqlite3ExprDup(db, pExpr, 0);
pAndExpr = sqlite3ExprAnd(db, pAndExpr, pExpr);
pAndExpr = sqlite3ExprAnd(pParse, pAndExpr, pExpr);
}
if( pAndExpr ){
/* The extra 0x10000 bit on the opcode is masked off and does not
@@ -2115,7 +2115,7 @@ Bitmask sqlite3WhereCodeOneLoopStart(
sqlite3VdbeGoto(v, pLevel->addrBrk);
sqlite3VdbeResolveLabel(v, iLoopBody);
if( pWInfo->nLevel>1 ) sqlite3StackFree(db, pOrTab);
if( pWInfo->nLevel>1 ){ sqlite3StackFree(db, pOrTab); }
if( !untestedTerms ) disableTerm(pLevel, pTerm);
}else
#endif /* SQLITE_OMIT_OR_OPTIMIZATION */
+23 -17
View File
@@ -262,27 +262,33 @@ static int isLikeOrGlob(
zNew[iTo++] = zNew[iFrom];
}
zNew[iTo] = 0;
assert( iTo>0 );
/* If the RHS begins with a digit or a minus sign, then the LHS must be
** an ordinary column (not a virtual table column) with TEXT affinity.
** Otherwise the LHS might be numeric and "lhs >= rhs" would be false
** even though "lhs LIKE rhs" is true. But if the RHS does not start
** with a digit or '-', then "lhs LIKE rhs" will always be false if
** the LHS is numeric and so the optimization still works.
/* If the LHS is not an ordinary column with TEXT affinity, then the
** pattern prefix boundaries (both the start and end boundaries) must
** not look like a number. Otherwise the pattern might be treated as
** a number, which will invalidate the LIKE optimization.
**
** 2018-09-10 ticket c94369cae9b561b1f996d0054bfab11389f9d033
** The RHS pattern must not be '/%' because the termination condition
** will then become "x<'0'" and if the affinity is numeric, will then
** be converted into "x<0", which is incorrect.
** Getting this right has been a persistent source of bugs in the
** LIKE optimization. See, for example:
** 2018-09-10 https://sqlite.org/src/info/c94369cae9b561b1
** 2019-05-02 https://sqlite.org/src/info/b043a54c3de54b28
** 2019-06-10 https://sqlite.org/src/info/fd76310a5e843e07
** 2019-06-14 https://sqlite.org/src/info/ce8717f0885af975
*/
if( sqlite3Isdigit(zNew[0])
|| zNew[0]=='-'
|| (zNew[0]+1=='0' && iTo==1)
if( pLeft->op!=TK_COLUMN
|| sqlite3ExprAffinity(pLeft)!=SQLITE_AFF_TEXT
|| IsVirtual(pLeft->y.pTab) /* Value might be numeric */
){
if( pLeft->op!=TK_COLUMN
|| sqlite3ExprAffinity(pLeft)!=SQLITE_AFF_TEXT
|| IsVirtual(pLeft->y.pTab) /* Value might be numeric */
){
int isNum;
double rDummy;
isNum = sqlite3AtoF(zNew, &rDummy, iTo, SQLITE_UTF8);
if( isNum<=0 ){
zNew[iTo-1]++;
isNum = sqlite3AtoF(zNew, &rDummy, iTo, SQLITE_UTF8);
zNew[iTo-1]--;
}
if( isNum>0 ){
sqlite3ExprDelete(db, pPrefix);
sqlite3ValueFree(pVal);
return 0;
+32 -12
View File
@@ -736,6 +736,7 @@ struct WindowRewrite {
Window *pWin;
SrcList *pSrc;
ExprList *pSub;
Table *pTab;
Select *pSubSelect; /* Current sub-select, if any */
};
@@ -796,6 +797,7 @@ static int selectWindowRewriteExprCb(Walker *pWalker, Expr *pExpr){
pExpr->op = TK_COLUMN;
pExpr->iColumn = p->pSub->nExpr-1;
pExpr->iTable = p->pWin->iEphCsr;
pExpr->y.pTab = p->pTab;
}
break;
@@ -839,6 +841,7 @@ static void selectWindowRewriteEList(
Window *pWin,
SrcList *pSrc,
ExprList *pEList, /* Rewrite expressions in this list */
Table *pTab,
ExprList **ppSub /* IN/OUT: Sub-select expression-list */
){
Walker sWalker;
@@ -850,6 +853,7 @@ static void selectWindowRewriteEList(
sRewrite.pSub = *ppSub;
sRewrite.pWin = pWin;
sRewrite.pSrc = pSrc;
sRewrite.pTab = pTab;
sWalker.pParse = pParse;
sWalker.xExprCallback = selectWindowRewriteExprCb;
@@ -868,13 +872,18 @@ static void selectWindowRewriteEList(
static ExprList *exprListAppendList(
Parse *pParse, /* Parsing context */
ExprList *pList, /* List to which to append. Might be NULL */
ExprList *pAppend /* List of values to append. Might be NULL */
ExprList *pAppend, /* List of values to append. Might be NULL */
int bIntToNull
){
if( pAppend ){
int i;
int nInit = pList ? pList->nExpr : 0;
for(i=0; i<pAppend->nExpr; i++){
Expr *pDup = sqlite3ExprDup(pParse->db, pAppend->a[i].pExpr, 0);
if( bIntToNull && pDup && pDup->op==TK_INTEGER ){
pDup->op = TK_NULL;
pDup->flags &= ~(EP_IntValue|EP_IsTrue|EP_IsFalse);
}
pList = sqlite3ExprListAppend(pParse, pList, pDup);
if( pList ) pList->a[nInit+i].sortOrder = pAppend->a[i].sortOrder;
}
@@ -904,17 +913,24 @@ int sqlite3WindowRewrite(Parse *pParse, Select *p){
ExprList *pSublist = 0; /* Expression list for sub-query */
Window *pMWin = p->pWin; /* Master window object */
Window *pWin; /* Window object iterator */
Table *pTab;
pTab = sqlite3DbMallocZero(db, sizeof(Table));
if( pTab==0 ){
return SQLITE_NOMEM;
}
p->pSrc = 0;
p->pWhere = 0;
p->pGroupBy = 0;
p->pHaving = 0;
p->selFlags &= ~SF_Aggregate;
/* Create the ORDER BY clause for the sub-select. This is the concatenation
** of the window PARTITION and ORDER BY clauses. Then, if this makes it
** redundant, remove the ORDER BY from the parent SELECT. */
pSort = sqlite3ExprListDup(db, pMWin->pPartition, 0);
pSort = exprListAppendList(pParse, pSort, pMWin->pOrderBy);
pSort = exprListAppendList(pParse, pSort, pMWin->pOrderBy, 1);
if( pSort && p->pOrderBy ){
if( sqlite3ExprListCompare(pSort, p->pOrderBy, -1)==0 ){
sqlite3ExprListDelete(db, p->pOrderBy);
@@ -928,15 +944,15 @@ int sqlite3WindowRewrite(Parse *pParse, Select *p){
pMWin->iEphCsr = pParse->nTab++;
pParse->nTab += 3;
selectWindowRewriteEList(pParse, pMWin, pSrc, p->pEList, &pSublist);
selectWindowRewriteEList(pParse, pMWin, pSrc, p->pOrderBy, &pSublist);
selectWindowRewriteEList(pParse, pMWin, pSrc, p->pEList, pTab, &pSublist);
selectWindowRewriteEList(pParse, pMWin, pSrc, p->pOrderBy, pTab, &pSublist);
pMWin->nBufferCol = (pSublist ? pSublist->nExpr : 0);
/* Append the PARTITION BY and ORDER BY expressions to the to the
** sub-select expression list. They are required to figure out where
** boundaries for partitions and sets of peer rows lie. */
pSublist = exprListAppendList(pParse, pSublist, pMWin->pPartition);
pSublist = exprListAppendList(pParse, pSublist, pMWin->pOrderBy);
pSublist = exprListAppendList(pParse, pSublist, pMWin->pPartition, 0);
pSublist = exprListAppendList(pParse, pSublist, pMWin->pOrderBy, 0);
/* Append the arguments passed to each window function to the
** sub-select expression list. Also allocate two registers for each
@@ -944,7 +960,7 @@ int sqlite3WindowRewrite(Parse *pParse, Select *p){
** results. */
for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
pWin->iArgCol = (pSublist ? pSublist->nExpr : 0);
pSublist = exprListAppendList(pParse, pSublist, pWin->pOwner->x.pList);
pSublist = exprListAppendList(pParse, pSublist, pWin->pOwner->x.pList, 0);
if( pWin->pFilter ){
Expr *pFilter = sqlite3ExprDup(db, pWin->pFilter, 0);
pSublist = sqlite3ExprListAppend(pParse, pSublist, pFilter);
@@ -971,16 +987,19 @@ int sqlite3WindowRewrite(Parse *pParse, Select *p){
);
p->pSrc = sqlite3SrcListAppend(pParse, 0, 0, 0);
if( p->pSrc ){
Table *pTab2;
p->pSrc->a[0].pSelect = pSub;
sqlite3SrcListAssignCursors(pParse, p->pSrc);
if( sqlite3ExpandSubquery(pParse, &p->pSrc->a[0]) ){
pSub->selFlags |= SF_Expanded;
pTab2 = sqlite3ResultSetOfSelect(pParse, pSub);
if( pTab2==0 ){
rc = SQLITE_NOMEM;
}else{
pSub->selFlags |= SF_Expanded;
p->selFlags &= ~SF_Aggregate;
sqlite3SelectPrep(pParse, pSub, 0);
memcpy(pTab, pTab2, sizeof(Table));
pTab->tabFlags |= TF_Ephemeral;
p->pSrc->a[0].pTab = pTab;
pTab = pTab2;
}
sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pMWin->iEphCsr, pSublist->nExpr);
sqlite3VdbeAddOp2(v, OP_OpenDup, pMWin->iEphCsr+1, pMWin->iEphCsr);
sqlite3VdbeAddOp2(v, OP_OpenDup, pMWin->iEphCsr+2, pMWin->iEphCsr);
@@ -989,6 +1008,7 @@ int sqlite3WindowRewrite(Parse *pParse, Select *p){
sqlite3SelectDelete(db, pSub);
}
if( db->mallocFailed ) rc = SQLITE_NOMEM;
sqlite3DbFree(db, pTab);
}
return rc;
+35
View File
@@ -559,4 +559,39 @@ ifcapable fts3 {
}
}
#-------------------------------------------------------------------------
reset_db
do_execsql_test 17.0 {
CREATE TABLE sqlite1234 (id integer);
ALTER TABLE sqlite1234 RENAME TO User;
SELECT name, sql FROM sqlite_master WHERE sql IS NOT NULL;
} {
User {CREATE TABLE "User" (id integer)}
}
#-------------------------------------------------------------------------
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;
}
do_execsql_test 18.1.2 {
SELECT sql FROM sqlite_master;
} {{CREATE TABLE t0 (c1 INTEGER, PRIMARY KEY(c1)) WITHOUT ROWID}}
reset_db
do_execsql_test 18.2.0 {
CREATE TABLE t0 (c0 INTEGER, PRIMARY KEY(c0));
}
do_execsql_test 18.2.1 {
ALTER TABLE t0 RENAME COLUMN c0 TO c1;
}
do_execsql_test 18.2.2 {
SELECT sql FROM sqlite_master;
} {{CREATE TABLE t0 (c1 INTEGER, PRIMARY KEY(c1))}}
finish_test
+17 -5
View File
@@ -338,15 +338,27 @@ do_execsql_test 8.3 {
INSERT INTO t3 VALUES(4, 5, 6);
}
do_execsql_test 8.1 {
do_execsql_test 8.4 {
CREATE TABLE t4(a, b);
CREATE VIEW v4 AS SELECT * FROM t4 WHERE (a=1 AND 0) OR b=2;
}
do_execsql_test 8.2 {
# Do not rename branches of an expression tree that is optimized out by
# the AND optimization.
#
do_execsql_test 8.5 {
ALTER TABLE t4 RENAME a TO c;
SELECT sql FROM sqlite_master WHERE name = 'v4'
} {{CREATE VIEW v4 AS SELECT * FROM t4 WHERE (c=1 AND 0) OR b=2}}
} {{CREATE VIEW v4 AS SELECT * FROM t4 WHERE (a=1 AND 0) OR b=2}}
# "a" is not renamed to "c" ---^
# 2019-06-10 https://www.sqlite.org/src/info/533010b8cacebe82
reset_db
do_execsql_test 8.6 {
CREATE TABLE t0(c0);
CREATE INDEX i0 ON t0(LIKELIHOOD(1,2) AND 0);
ALTER TABLE t0 RENAME TO t1;
SELECT sql FROM sqlite_master WHERE name='i0';
} {{CREATE INDEX i0 ON "t1"(LIKELIHOOD(1,2) AND 0)}}
finish_test
+97 -3
View File
@@ -79,7 +79,7 @@ do_execsql_test 3.1 {
do_execsql_test 3.2 {
SELECT sql FROM sqlite_master WHERE name = 'v1'
} {{CREATE VIEW v1 AS SELECT * FROM t1 WHERE a=1 OR (bbb IN ())}}
} {{CREATE VIEW v1 AS SELECT * FROM t1 WHERE a=1 OR (b IN ())}}
#-------------------------------------------------------------------------
reset_db
@@ -142,6 +142,100 @@ do_execsql_test 6.1 {
ALTER TABLE Table0 RENAME Col0 TO Col0;
}
#-------------------------------------------------------------------------
reset_db
do_execsql_test 7.1.0 {
CREATE TABLE t1(a,b,c);
CREATE TRIGGER AFTER INSERT ON t1 BEGIN
SELECT a, rank() OVER w1 FROM t1
WINDOW w1 AS (PARTITION BY b, percent_rank() OVER w1);
END;
}
do_execsql_test 7.1.2 {
ALTER TABLE t1 RENAME TO t1x;
SELECT sql FROM sqlite_master;
} {
{CREATE TABLE "t1x"(a,b,c)}
{CREATE TRIGGER AFTER INSERT ON "t1x" BEGIN
SELECT a, rank() OVER w1 FROM "t1x"
WINDOW w1 AS (PARTITION BY b, percent_rank() OVER w1);
END}
}
do_execsql_test 7.2.1 {
DROP TRIGGER after;
CREATE TRIGGER AFTER INSERT ON t1x BEGIN
SELECT a, rank() OVER w1 FROM t1x
WINDOW w1 AS (PARTITION BY b, percent_rank() OVER w1 ORDER BY d);
END;
}
do_catchsql_test 7.2.2 {
ALTER TABLE t1x RENAME TO t1;
} {1 {error in trigger AFTER: no such column: d}}
#-------------------------------------------------------------------------
reset_db
do_execsql_test 8.0 {
CREATE TABLE t0(c0);
CREATE INDEX i0 ON t0('1' IN ());
}
do_execsql_test 8.1 {
ALTER TABLE t0 RENAME TO t1;
SELECT sql FROM sqlite_master;
} {
{CREATE TABLE "t1"(c0)}
{CREATE INDEX i0 ON "t1"('1' IN ())}
}
do_execsql_test 8.2.1 {
CREATE TABLE t2 (c0);
CREATE INDEX i2 ON t2((LIKELIHOOD(c0, 100) IN ()));
ALTER TABLE t2 RENAME COLUMN c0 TO c1;
}
do_execsql_test 8.2.2 {
SELECT sql FROM sqlite_master WHERE tbl_name = 't2';
} {
{CREATE TABLE t2 (c1)}
{CREATE INDEX i2 ON t2((LIKELIHOOD(c0, 100) IN ()))}
}
do_test 8.2.3 {
sqlite3 db2 test.db
db2 eval { INSERT INTO t2 VALUES (1), (2), (3) }
db close
} {}
db2 close
#-------------------------------------------------------------------------
reset_db
do_execsql_test 9.1 {
CREATE TABLE t1(a,b,c);
CREATE TRIGGER AFTER INSERT ON t1 WHEN new.a NOT NULL BEGIN
SELECT true WHERE (SELECT a, b FROM (t1)) IN ();
END;
}
do_execsql_test 9.2 {
ALTER TABLE t1 RENAME TO t1x;
}
#-------------------------------------------------------------------------
reset_db
do_execsql_test 10.1 {
CREATE TABLE t1(a, b, c);
CREATE TABLE t2(a, b, c);
CREATE VIEW v1 AS SELECT * FROM t1 WHERE (
SELECT t1.a FROM t1, t2
) IN () OR t1.a=5;
}
do_execsql_test 10.2 {
ALTER TABLE t2 RENAME TO t3;
SELECT sql FROM sqlite_master WHERE name='v1';
} {
{CREATE VIEW v1 AS SELECT * FROM t1 WHERE (
SELECT t1.a FROM t1, t2
) IN () OR t1.a=5}
}
finish_test
+14
View File
@@ -123,6 +123,20 @@ do_execsql_test 2.1 {
SELECT sum(z) FROM vvv WHERE x='aaa'
) FROM one;
} {8.0}
do_execsql_test 2.2 {
DROP TABLE t1;
CREATE TABLE t1(aaa);
INSERT INTO t1(aaa) VALUES(9);
SELECT (
SELECT aaa FROM t1 GROUP BY (
SELECT bbb FROM (
SELECT ccc AS bbb FROM (
SELECT 1 ccc
) WHERE rowid IS NOT 1
) WHERE bbb = 1
)
);
} {9}
# Ticket https://www.sqlite.org/src/info/787fa716be3a7f65
# Segfault due to multiple uses of the same subquery where the
+20
View File
@@ -119,5 +119,25 @@ do_test between-1.5.3 {
}
} {4 2 25 27 sort t1 *}
#-------------------------------------------------------------------------
reset_db
do_execsql_test between-2.0 {
CREATE TABLE t1(x TEXT, y TEXT COLLATE nocase);
INSERT INTO t1 VALUES('0', 'abc');
}
foreach {tn expr res} {
1 "x BETWEEN 1 AND '5'" 0
2 "x COLLATE binary BETWEEN 1 AND '5'" 0
3 "x COLLATE nocase BETWEEN 1 AND '5'" 0
4 "y BETWEEN 'A' AND 'B'" 1
5 "y COLLATE nocase BETWEEN 'A' AND 'B'" 1
6 "y COLLATE binary BETWEEN 'A' AND 'B'" 0
7 "(y COLLATE binary) BETWEEN 'A' AND 'B'" 0
} {
set sql "SELECT $expr FROM t1"
do_execsql_test between-2.1.$tn $sql $res
}
finish_test
+89 -14
View File
@@ -183,34 +183,34 @@ do_test cast-1.53 {
execsql {SELECT CAST('123.5abc' AS integer)}
} 123
do_test case-1.60 {
do_test cast-1.60 {
execsql {SELECT CAST(null AS REAL)}
} {{}}
do_test case-1.61 {
do_test cast-1.61 {
execsql {SELECT typeof(CAST(null AS REAL))}
} {null}
do_test case-1.62 {
do_test cast-1.62 {
execsql {SELECT CAST(1 AS REAL)}
} {1.0}
do_test case-1.63 {
do_test cast-1.63 {
execsql {SELECT typeof(CAST(1 AS REAL))}
} {real}
do_test case-1.64 {
do_test cast-1.64 {
execsql {SELECT CAST('1' AS REAL)}
} {1.0}
do_test case-1.65 {
do_test cast-1.65 {
execsql {SELECT typeof(CAST('1' AS REAL))}
} {real}
do_test case-1.66 {
do_test cast-1.66 {
execsql {SELECT CAST('abc' AS REAL)}
} {0.0}
do_test case-1.67 {
do_test cast-1.67 {
execsql {SELECT typeof(CAST('abc' AS REAL))}
} {real}
do_test case-1.68 {
do_test cast-1.68 {
execsql {SELECT CAST(x'31' AS REAL)}
} {1.0}
do_test case-1.69 {
do_test cast-1.69 {
execsql {SELECT typeof(CAST(x'31' AS REAL))}
} {real}
@@ -299,7 +299,7 @@ if {[db eval {PRAGMA encoding}]=="UTF-8"} {
} 9223372036854774784
}
}
do_test case-3.31 {
do_test cast-3.31 {
execsql {SELECT CAST(NULL AS numeric)}
} {{}}
@@ -368,16 +368,17 @@ do_execsql_test cast-5.2 {
# ignored because it is no part of the integer prefix.
# EVIDENCE-OF: R-24225-46995 For example, "(CAST '123e+5' AS INTEGER)"
# results in 123, not in 12300000.
do_execsql_test case-5.3 {
do_execsql_test cast-5.3 {
SELECT CAST('123e+5' AS INTEGER);
SELECT CAST('123e+5' AS NUMERIC);
} {123 12300000.0}
SELECT CAST('123e+5' AS REAL);
} {123 12300000 12300000.0}
# The following does not have anything to do with the CAST operator,
# but it does deal with affinity transformations.
#
do_execsql_test case-6.1 {
do_execsql_test cast-6.1 {
DROP TABLE IF EXISTS t1;
CREATE TABLE t1(a NUMERIC);
INSERT INTO t1 VALUES
@@ -388,4 +389,78 @@ do_execsql_test case-6.1 {
SELECT * FROM t1;
} {9000000000000000001 9000000000000000001 9000000000000000001 9000000000000000001}
# 2019-06-07
# https://www.sqlite.org/src/info/4c2d7639f076aa7c
do_execsql_test cast-7.1 {
SELECT CAST('-' AS NUMERIC);
} {0}
do_execsql_test cast-7.2 {
SELECT CAST('-0' AS NUMERIC);
} {0}
do_execsql_test cast-7.3 {
SELECT CAST('+' AS NUMERIC);
} {0}
do_execsql_test cast-7.4 {
SELECT CAST('/' AS NUMERIC);
} {0}
# 2019-06-07
# https://www.sqlite.org/src/info/e8bedb2a184001bb
do_execsql_test cast-7.10 {
SELECT '' - 2851427734582196970;
} {-2851427734582196970}
do_execsql_test cast-7.11 {
SELECT 0 - 2851427734582196970;
} {-2851427734582196970}
do_execsql_test cast-7.12 {
SELECT '' - 1;
} {-1}
# 2019-06-10
# https://www.sqlite.org/src/info/dd6bffbfb6e61db9
#
# EVIDENCE-OF: R-55084-10555 Casting a TEXT or BLOB value into NUMERIC
# yields either an INTEGER or a REAL result.
#
do_execsql_test cast-7.20 {
DROP TABLE IF EXISTS t0;
CREATE TABLE t0 (c0 TEXT);
INSERT INTO t0(c0) VALUES ('1.0');
SELECT CAST(c0 AS NUMERIC) FROM t0;
} {1}
# 2019-06-10
# https://sqlite.org/src/info/27de823723a41df45af3
#
do_execsql_test cast-7.30 {
SELECT -'.';
} 0
do_execsql_test cast-7.31 {
SELECT '.'+0;
} 0
do_execsql_test cast-7.32 {
SELECT CAST('.' AS numeric);
} 0
do_execsql_test cast-7.33 {
SELECT -CAST('.' AS numeric);
} 0
# 2019-06-12
# https://www.sqlite.org/src/info/674385aeba91c774
#
do_execsql_test cast-7.40 {
SELECT CAST('-0.0' AS numeric);
} 0
do_execsql_test cast-7.41 {
SELECT CAST('0.0' AS numeric);
} 0
do_execsql_test cast-7.42 {
SELECT CAST('+0.0' AS numeric);
} 0
do_execsql_test cast-7.43 {
SELECT CAST('-1.0' AS numeric);
} -1
finish_test
+2
View File
@@ -117,11 +117,13 @@ do_test check-1.17 {
do_test check-2.1 {
execsql {
PRAGMA writable_schema = 1;
CREATE TABLE t2(
x INTEGER CONSTRAINT one CHECK( typeof(coalesce(x,0))=="integer" ),
y REAL CONSTRAINT two CHECK( typeof(coalesce(y,0.1))=='real' ),
z TEXT CONSTRAINT three CHECK( typeof(coalesce(z,''))=='text' )
);
PRAGMA writable_schema = 0;
}
} {}
do_test check-2.2 {
+41
View File
@@ -0,0 +1,41 @@
# 2019 June 5
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# May you do good and not evil.
# May you find forgiveness for yourself and forgive others.
# May you share freely, never taking more than you give.
#
#***********************************************************************
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix chunksize
if {$::tcl_platform(platform)!="unix"} {
finish_test
return
}
foreach {tn jrnlmode} {
1 delete
2 wal
} {
reset_db
file_control_chunksize_test db main 32768
do_execsql_test $tn.0 " PRAGMA journal_mode = $jrnlmode " $jrnlmode
do_execsql_test $tn.1 {
CREATE TABLE t1(a, b);
INSERT INTO t1 VALUES(1, 2);
}
execsql { PRAGMA wal_checkpoint }
do_test $tn.2 {
file size test.db
} 32768
}
finish_test
+16
View File
@@ -400,5 +400,21 @@ do_execsql_test 7.2 {
ORDER BY 1 COLLATE binary COLLATE binary COLLATE binary COLLATE nocase;
} {abc DEF}
# 2019-06-14
# https://sqlite.org/src/info/f1580ba1b574e9e9
#
do_execsql_test 8.0 {
SELECT ' ' > char(20) COLLATE rtrim;
} 0
do_execsql_test 8.1 {
SELECT '' < char(20) COLLATE rtrim;
} 1
do_execsql_test 8.2 {
DROP TABLE IF EXISTS t0;
CREATE TABLE t0(c0 COLLATE RTRIM, c1 BLOB UNIQUE,
PRIMARY KEY (c0, c1)) WITHOUT ROWID;
INSERT INTO t0 VALUES (123, 3), (' ', 1), (' ', 2), ('', 4);
SELECT * FROM t0 WHERE c1 = 1;
} {{ } 1}
finish_test
+222
View File
@@ -838,4 +838,226 @@ do_catchsql_test 8.1 {
INSERT INTO t3 SELECT * FROM t2;
} {1 {database disk image is malformed}}
#-------------------------------------------------------------------------
reset_db
do_test 9.0 {
sqlite3 db {}
db deserialize [decode_hexdb {
| size 8192 pagesize 4096 filename crash-ab10597e4e1c32.db
| page 1 offset 0
| 0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00 SQLite format 3.
| 16: 10 00 01 01 00 40 20 20 00 00 00 00 00 00 00 00 .....@ ........
| 96: 00 00 00 00 0d 00 00 00 01 0f d6 00 0f d6 00 00 ................
| 4048: 00 00 00 00 00 00 28 01 06 17 11 11 01 3d 74 61 ......(......=ta
| 4064: 62 6c 65 74 31 74 31 02 43 52 45 41 54 45 20 54 blet1t1.CREATE T
| 4080: 41 42 4c 45 20 74 31 28 61 2c 62 2c 63 2c 64 29 ABLE t1(a,b,c,d)
| page 2 offset 4096
| 0: 0d 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
| end crash-ab10597e4e1c32.db
}]} {}
do_execsql_test 9.1 {
SAVEPOINT one;
}
do_catchsql_test 9.3 {
INSERT INTO t1(b,c) VALUES(5,6);
} {1 {database disk image is malformed}}
do_execsql_test 9.3 {
ROLLBACK TO one;
}
#-------------------------------------------------------------------------
reset_db
do_test 10.0 {
sqlite3 db {}
db deserialize [decode_hexdb {
| size 180224 pagesize 4096 filename crash-41390d95d613b6.db
| page 1 offset 0
| 0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00 SQLite format 3.
| 16: 10 00 01 01 00 40 20 20 00 00 00 00 00 00 00 00 .....@ ........
| 96: 00 00 00 00 0d 00 00 00 04 0e e2 00 0f 96 0f 44 ...............D
| 112: 0f 10 0e e2 00 00 00 00 00 00 00 00 00 00 00 00 ................
| 3808: 00 00 2c 14 06 17 15 11 01 41 69 6e 64 65 78 74 ..,......Aindext
| 3824: 41 78 33 74 31 06 43 52 45 41 54 45 20 49 4e 44 Ax3t1.CREATE IND
| 3840: 45 58 20 74 31 78 32 20 4f 4e 20 74 31 28 62 29 EX t1x2 ON t1(b)
| 3856: 32 03 06 17 15 11 01 4d 69 6e 64 65 78 74 31 88 2......Mindext1.
| 3872: 31 74 31 05 43 52 45 41 54 45 20 49 4e 44 45 58 1t1.CREATE INDEX
| 3888: 20 74 31 78 31 20 4f 4e 20 74 31 28 67 2b 68 2c t1x1 ON t1(g+h,
| 3904: 6a 2d 6b 29 50 02 06 17 2b 2b 01 59 74 61 62 6c j-k)P...++.Ytabl
| 3920: 65 73 71 6c 69 74 65 5e 73 65 71 74 65 6e 63 65 esqlite^seqtence
| 3936: 73 71 6c 69 74 65 5f 73 65 71 75 65 6e 63 65 04 sqlite_sequence.
| 3952: 43 52 45 41 54 45 20 54 41 42 4c 45 20 73 71 6c CREATE TABLE sql
| 3968: 69 74 65 5f 73 65 71 75 65 6e 63 65 28 6e 61 6d ite_sequence(nam
| 3984: 65 2c 73 65 71 29 68 00 07 17 11 11 01 81 3b 74 e,seq)h.......;t
| 4000: 61 62 6c 65 74 31 74 31 03 43 52 45 41 54 45 20 ablet1t1.CREATE
| 4016: 54 41 42 4c 45 20 74 31 28 61 20 49 4e 54 45 47 TABLE t1(a INTEG
| 4032: 45 52 20 50 52 49 4d 41 52 59 20 4b 45 59 20 41 ER PRIMARY KEY A
| 4048: 55 54 4f 49 4e 43 52 45 4d 45 4e 54 2c 0a 62 2c UTOINCREMENT,.b,
| 4064: 63 2c 64 2c 65 2c 66 2c 67 2c 68 2c 6a 2c 6b 2c c,d,e,f,g,h,j,k,
| 4080: 6c 2c 6d 2c 6e 2c 6f 2c 70 2c 71 2c 72 2c 73 29 l,m,n,o,p,q,r,s)
| page 2 offset 4096
| 0: 01 00 00 00 00 01 00 00 10 00 01 00 00 00 00 01 ................
| 16: 00 00 00 00 02 00 0f f0 00 15 00 00 00 03 02 00 ................
| 32: 00 00 d9 05 00 00 00 03 02 00 00 00 00 05 00 00 ................
| 48: 10 03 02 00 00 00 00 05 00 00 00 03 02 00 00 00 ................
| 64: 00 05 00 00 00 02 62 00 00 00 00 05 00 00 00 03 ......b.........
| 80: 02 00 00 00 00 05 00 00 00 03 02 00 00 00 00 05 ................
| 96: 00 00 00 03 02 00 00 00 00 05 00 00 00 03 05 00 ................
| 112: 00 00 03 03 01 00 00 23 02 00 00 4f 00 02 00 00 .......#...O....
| 128: 10 25 02 00 00 00 00 03 00 00 00 23 02 00 00 00 .%.........#....
| 144: 00 03 00 00 00 23 02 00 00 00 00 03 00 00 00 23 .....#.........#
| 160: 05 00 08 90 06 05 00 00 00 06 01 ff 00 00 00 03 ................
| 176: 00 00 00 06 02 00 00 00 00 02 ff 00 00 00 00 00 ................
| page 3 offset 8192
| 0: 05 00 00 00 09 0f d0 00 00 00 00 19 0f fb 0f f6 ................
| 16: 0f f1 10 ec ec e7 0f e2 0f dc 0f d6 0f 00 00 00 ................
| 1072: 00 97 4c 0a 24 00 ae 00 00 00 00 00 00 00 00 00 ..L.$...........
| 4048: 00 00 00 16 83 39 ff ff ff 14 81 16 00 00 00 12 .....9..........
| 4064: 81 02 00 00 00 10 6e 00 00 00 0e 5a 00 00 00 0c ......n....Z....
| 4080: 46 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 F...............
| page 4 offset 12288
| 1072: 97 4d 32 14 00 ae 00 00 00 00 00 00 00 00 00 00 .M2.............
| 4080: 00 00 00 00 00 00 00 07 01 03 11 02 74 31 00 bd ............t1..
| page 5 offset 16384
| 0: fa 0f 7c 00 0a 0f 74 00 0f f9 0f eb 0f dd 0f cf ..|...t.........
| 16: 0f c1 0f b3 0f a4 0e 94 0f 84 0f 74 0f 74 0f 74 ...........t.t.t
| 32: 0f 74 0f 64 0f 00 00 00 00 00 00 00 00 00 00 00 .t.d............
| 3952: 00 00 00 00 07 05 00 00 00 02 00 be 0f 8c 10 07 ................
| 3968: ff ff 00 00 07 05 00 00 00 02 00 aa 0f 9b f0 08 ................
| 3984: c8 00 00 00 37 06 00 00 00 01 00 96 0f ac 00 08 ....7...........
| 4000: 00 00 00 b3 07 15 00 10 00 02 00 82 0f ba 00 07 ................
| 4016: 00 00 00 06 05 00 00 00 01 6e 0f c8 00 07 00 00 .........n......
| 4032: 00 06 05 00 00 00 01 5a 03 f6 00 07 00 00 00 06 .......Z........
| 4048: 05 00 00 00 01 46 0f e4 00 07 00 00 10 06 05 00 .....F..........
| 4064: 00 00 01 32 10 02 00 07 00 00 00 07 05 00 00 00 ...2............
| 4080: 01 1d ff ff ff 07 10 00 00 06 05 00 00 00 01 0a ................
| page 6 offset 20480
| 624: 00 00 00 00 00 21 97 00 00 00 00 00 00 00 00 00 .....!..........
| 1120: 00 00 00 00 00 24 57 3e 00 00 00 00 00 00 00 00 .....$W>........
| 1616: 00 00 00 00 1f 97 00 00 00 00 00 00 00 00 00 00 ................
| 2112: 00 00 00 1e 97 3d 00 00 00 00 00 00 00 00 00 00 .....=..........
| 2608: 00 1d 97 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
| page 8 offset 28672
| 1184: 00 00 00 00 00 00 00 00 00 97 4d 1e 13 ff ae 7c ..........M....|
| 4080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90 ................
| page 9 offset 32768
| 256: 0d 01 c0 00 01 04 30 00 04 30 00 00 00 00 00 00 ......0..0......
| page 10 offset 36864
| 0: 0d 00 22 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
| 4080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 05 ................
| page 12 offset 45056
| 0: 0d 00 00 00 01 04 30 00 00 00 00 00 00 00 00 00 ......0.........
| page 14 offset 53248
| 0: 0d 00 00 00 01 04 30 00 04 30 00 00 00 00 00 00 ......0..0......
| 1072: 96 4d 5a 14 00 00 00 00 00 00 00 00 00 00 00 00 .MZ.............
| page 16 offset 61440
| 0: 0d 00 00 00 01 04 30 00 04 30 00 00 00 00 00 00 ......0..0......
| 1072: 97 4d 6e 14 00 ae 7b ff ff ff ff 00 00 00 00 00 .Mn.............
| page 18 offset 69632
| 1056: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 97 ................
| 1072: 4d 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 M...............
| 4080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0d ................
| page 20 offset 77824
| 1056: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 97 ................
| 1072: 4d 81 16 14 00 ae 00 00 00 00 00 00 00 00 00 00 M...............
| 4080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0f ................
| page 22 offset 86016
| 0: 0d 00 00 00 01 04 2f 00 04 2f 01 00 00 00 00 00 ....../../......
| 1056: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 97 ................
| 1072: 4d 81 2a 14 00 00 00 00 00 00 00 00 00 00 00 00 M.*.............
| page 24 offset 94208
| 1072: 00 97 4c 0a 14 00 ae 7c 00 00 00 00 00 00 00 00 ..L....|........
| page 25 offset 98304
| 1056: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 97 ................
| 1072: 4d 81 3e 14 00 ae 7c 00 00 18 ff 00 00 00 00 00 M.>...|.........
| page 27 offset 106496
| 0: 00 00 00 00 00 00 00 12 00 00 00 07 00 00 00 1d ................
| 16: 00 00 00 09 00 00 00 1f 00 00 00 0b 00 00 00 21 ...............!
| 32: 00 00 00 0d 00 10 00 25 00 00 00 0f 00 00 00 27 .......%.......'
| 48: 00 00 00 11 00 00 00 00 00 00 00 00 00 00 00 00 ................
| page 32 offset 126976
| 2512: 00 00 00 00 00 00 00 45 21 00 00 00 00 00 00 00 .......E!.......
| page 35 offset 139264
| 0: 00 0a 08 44 00 05 02 77 00 0e 11 0a 92 00 00 00 ...D...w........
| 1120: 00 00 00 00 00 20 97 00 00 00 00 00 00 00 00 00 ..... ..........
| 1616: 00 00 00 00 22 00 00 00 00 00 00 00 00 00 00 00 ................
| 2608: 00 00 00 97 3d 04 00 00 00 00 00 00 00 00 00 00 ....=...........
| 3104: 00 1c 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
| 3600: 00 97 3d 04 ae 7c 00 00 00 00 00 00 00 00 00 00 ..=..|..........
| 4080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 1a ................
| page 36 offset 143360
| 0: 0a 08 44 00 04 02 00 00 00 00 00 00 00 00 00 00 ..D.............
| 1120: 00 00 00 00 00 2a 97 3e 04 00 00 00 00 00 00 00 .....*.>........
| 1616: 00 00 00 00 2c 97 3e 00 00 00 00 00 00 00 00 00 ....,.>.........
| 2112: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 38 ...............8
| 2128: 00 00 05 cd 00 00 00 00 00 00 00 00 00 00 00 00 ................
| 3600: 00 97 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
| page 38 offset 151552
| 2464: 00 00 00 00 00 00 00 00 00 6e 00 00 00 00 00 00 .........n......
| page 40 offset 159744
| 2512: 00 00 00 00 00 00 00 00 82 00 00 00 00 00 00 00 ................
| page 42 offset 167936
| 2512: 00 00 00 00 00 00 00 96 00 00 00 00 00 00 00 00 ................
| page 44 offset 176128
| 2512: 00 00 00 00 00 00 00 00 aa 00 00 00 00 00 00 00 ................
| end crash-41390d95d613b6.db
}]} {}
do_catchsql_test 10.1 {
SELECT * FROM t1 WHERE a<='2019-05-09' ORDER BY a DESC;
} {1 {database disk image is malformed}}
#-------------------------------------------------------------------------
reset_db
do_test 11.0 {
sqlite3 db {}
db deserialize [decode_hexdb {
| size 595 pagesize 512 filename x.db
| page 1 offset 0
| 0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00 SQLite format 3.
| 16: 02 00 00 01 00 40 20 20 00 01 00 0c 00 00 00 07 .....@ ........
| 32: 00 00 00 05 07 a1 1f fa 00 00 00 08 00 00 00 04 ................
| 48: 00 00 01 00 00 49 00 00 00 00 00 05 00 00 00 00 .....I..........
| 80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 1c ................
| 96: 00 2e 2c 50 0d 00 00 00 06 01 06 00 01 da 01 b0 ..,P............
| 112: 01 56 01 86 01 2a 01 06 00 00 62 00 00 00 00 00 .V...*....b.....
| 128: 00 ed e2 78 74 64 33 ff 43 52 45 41 54 45 20 49 ...xtd3.CREATE I
| 144: 4e 44 45 58 20 74 33 78 20 4f 4e 20 74 33 28 38 NDEX t3x ON t3(8
| 160: 29 2e 04 06 17 15 11 01 45 69 6e 64 65 68 74 32 ).......Eindeht2
| 176: 63 64 74 31 e5 43 52 45 41 54 45 20 49 4e 44 45 cdt1.CREATE INDE
| 192: 58 20 74 32 63 c4 20 4f 4e 20 74 32 28 63 2c 64 X t2c. ON t2(c,d
| 208: 29 28 05 06 17 01 11 11 3d 74 61 6c 36 74 62 74 )(......=tal6tbt
| 224: 65 32 04 43 52 45 41 54 45 20 54 41 42 4c 45 20 e2.CREATE TABLE
| 240: 74 00 04 00 00 00 00 00 00 00 00 00 00 00 00 00 t...............
| 256: 00 00 00 00 00 00 22 07 06 17 11 11 01 30 e8 03 .............0..
| 272: 62 6c 65 74 34 74 35 02 43 52 45 41 54 45 20 54 blet4t5.CREATE T
| 288: 41 42 4c 45 20 74 34 28 94 29 2a 06 06 17 13 11 ABLE t4(.)*.....
| 304: 01 3f 69 33 74 6e 65 78 78 74 64 33 ff 43 52 45 .?i3tnexxtd3.CRE
| 320: 41 54 45 20 49 4e 44 45 58 20 74 33 78 20 4f 4e ATE INDEX t3x ON
| 336: 20 74 31 28 38 29 2e 04 06 17 15 11 01 45 69 6e t1(8).......Ein
| 352: 64 65 68 74 32 63 64 74 31 e5 43 52 45 41 54 45 deht2cdt1.CREATE
| 368: 20 49 4e 44 45 58 20 74 32 63 c4 20 4f 4e 20 74 INDEX t2c. ON t
| 384: 32 28 63 2c 64 29 28 05 06 17 01 11 11 3d 74 61 2(c,d)(......=ta
| 400: 6c 32 74 62 74 65 32 04 43 52 45 41 54 45 20 54 l2tbte2.CREATE T
| 416: 41 42 4c 45 20 74 33 28 63 2c 78 2c 65 2c 66 29 ABLE t3(c,x,e,f)
| 432: 28 02 06 17 11 11 01 3d 74 61 9e 93 65 74 32 74 (......=ta..et2t
| 448: 32 03 43 52 45 41 54 45 20 54 41 42 4c 45 20 74 2.CREATE TABLE t
| 464: 32 28 63 2c 64 2c 65 2c 66 29 24 01 06 17 11 11 2(c,d,e,f)$.....
| 480: 01 35 55 61 62 6c 88 74 31 74 31 02 43 52 45 41 .5Uabl.t1t1.CREA
| 496: 54 45 20 54 41 42 4c 45 20 74 31 28 61 2c 62 29 TE TABLE t1(a,b)
| page 2 offset 512
| 0: 0d 00 00 00 0d 25 00 01 cf 00 01 fa 01 f3 01 de .....%..........
| 16: 01 00 00 00 fd 00 00 0d 00 00 00 00 45 20 54 41 ............E TA
| 32: 42 4c 45 20 74 34 28 94 29 2a 06 06 17 13 11 01 BLE t4(.)*......
| 48: 3f 69 33 74 6e 65 78 78 74 64 33 ff 43 52 45 a0 ?i3tnexxtd3.CRE.
| 64: a0 a0 a0 a0 a0 a0 a0 a0 a0 a0 a0 a0 74 13 11 01 ............t...
| 80: 49 45 74 00 00 00 00 00 00 00 00 00 00 00 00 00 IEt.............
| end x.db
}]} {}
do_catchsql_test 11.1 {
DELETE FROM t3 WHERE x IN (SELECT x FROM t4);
} {1 {database disk image is malformed}}
finish_test
+13
View File
@@ -40,4 +40,17 @@ do_execsql_test 1.3 {
)
} {3}
# 2019-05-15
do_execsql_test 2.0 {
CREATE TABLE t1(x);
INSERT INTO t1 VALUES(1),(99),('abc');
CREATE VIEW v1(x,y) AS SELECT x,1 FROM t1 UNION ALL SELECT x,2 FROM t1;
SELECT count(*) FROM v1 WHERE x<>1;
} {4}
do_execsql_test 2.1 {
SELECT count(*) FROM v1 GROUP BY y;
} {3 3}
finish_test
+115
View File
@@ -0,0 +1,115 @@
# 2019-04-11
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# May you do good and not evil.
# May you find forgiveness for yourself and forgive others.
# May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library. The
# focus of this file is testing the sqlite_dbpage virtual table.
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix dbdata
ifcapable !vtab||!compound {
finish_test
return
}
if { [catch { db enable_load_extension 1 }]
|| [catch { db eval { SELECT load_extension('../dbdata') } }]
} {
finish_test
return
}
do_execsql_test 1.0 {
CREATE TABLE T1(a, b);
INSERT INTO t1(rowid, a ,b) VALUES(5, 'v', 'five');
INSERT INTO t1(rowid, a, b) VALUES(10, 'x', 'ten');
}
do_execsql_test 1.1 {
SELECT pgno, cell, field, quote(value) FROM sqlite_dbdata WHERE pgno=2;
} {
2 0 -1 5
2 0 0 'v'
2 0 1 'five'
2 1 -1 10
2 1 0 'x'
2 1 1 'ten'
}
breakpoint
do_execsql_test 1.2 {
SELECT pgno, cell, field, quote(value) FROM sqlite_dbdata;
} {
1 0 -1 1
1 0 0 'table'
1 0 1 'T1'
1 0 2 'T1'
1 0 3 2
1 0 4 {'CREATE TABLE T1(a, b)'}
2 0 -1 5
2 0 0 'v'
2 0 1 'five'
2 1 -1 10
2 1 0 'x'
2 1 1 'ten'
}
set big [string repeat big 2000]
do_execsql_test 1.3 {
INSERT INTO t1 VALUES(NULL, $big);
SELECT value FROM sqlite_dbdata WHERE pgno=2 AND cell=2 AND field=1;
} $big
do_execsql_test 1.4 {
DELETE FROM t1;
INSERT INTO t1 VALUES(NULL, randomblob(5050));
}
do_test 1.5 {
execsql {
SELECT quote(value) FROM sqlite_dbdata WHERE pgno=2 AND cell=0 AND field=1;
}
} [db one {SELECT quote(b) FROM t1}]
#-------------------------------------------------------------------------
reset_db
db enable_load_extension 1
db eval { SELECT load_extension('../dbdata') }
do_execsql_test 2.0 {
CREATE TABLE t1(a);
CREATE INDEX i1 ON t1(a);
WITH s(i) AS (
SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<10
)
INSERT INTO t1 SELECT randomblob(900) FROM s;
}
do_execsql_test 2.1 {
SELECT * FROM sqlite_dbptr WHERE pgno=2;
} {
2 25 2 6 2 7 2 9 2 11 2 13 2 15 2 17 2 19 2 21
}
do_execsql_test 2.2 {
SELECT * FROM sqlite_dbptr WHERE pgno=3;
} {
3 24 3 23
}
do_execsql_test 2.3 {
SELECT * FROM sqlite_dbptr
} {
2 25 2 6 2 7 2 9 2 11 2 13 2 15 2 17 2 19 2 21
3 24 3 23
}
finish_test
+2
View File
@@ -377,6 +377,7 @@ int main(int argc, char **argv){
free(pIn);
}
}
#ifdef RUSAGE_SELF
if( eVerbosity>0 ){
struct rusage x;
printf("SQLite %s\n", sqlite3_sourceid());
@@ -385,6 +386,7 @@ int main(int argc, char **argv){
printf("Maximum RSS = %ld KB\n", x.ru_maxrss);
}
}
#endif
return 0;
}
#endif /*STANDALONE*/
+43 -14
View File
@@ -1013,13 +1013,18 @@ sqlite3 db test.db
# EVIDENCE-OF: R-22868-25880 The LIKE operator can be made case
# sensitive using the case_sensitive_like pragma.
#
do_execsql_test e_expr-16.1.1 { SELECT 'abcxyz' LIKE 'ABC%' } 1
do_execsql_test e_expr-16.1.2 { PRAGMA case_sensitive_like = 1 } {}
do_execsql_test e_expr-16.1.3 { SELECT 'abcxyz' LIKE 'ABC%' } 0
do_execsql_test e_expr-16.1.4 { SELECT 'ABCxyz' LIKE 'ABC%' } 1
do_execsql_test e_expr-16.1.5 { PRAGMA case_sensitive_like = 0 } {}
do_execsql_test e_expr-16.1.6 { SELECT 'abcxyz' LIKE 'ABC%' } 1
do_execsql_test e_expr-16.1.7 { SELECT 'ABCxyz' LIKE 'ABC%' } 1
do_execsql_test e_expr-16.1.1 { SELECT 'abcxyz' LIKE 'ABC%' } 1
do_execsql_test e_expr-16.1.1b { SELECT 'abc%xyz' LIKE 'ABC\%x%' ESCAPE '\' } 1
do_execsql_test e_expr-16.1.2 { PRAGMA case_sensitive_like = 1 } {}
do_execsql_test e_expr-16.1.3 { SELECT 'abcxyz' LIKE 'ABC%' } 0
do_execsql_test e_expr-16.1.3b { SELECT 'abc%xyz' LIKE 'ABC\%X%' ESCAPE '\' } 0
do_execsql_test e_expr-16.1.4 { SELECT 'ABCxyz' LIKE 'ABC%' } 1
do_execsql_test e_expr-16.1.4b { SELECT 'ABC%xyz' LIKE 'ABC\%x%' ESCAPE '\' } 1
do_execsql_test e_expr-16.1.5 { PRAGMA case_sensitive_like = 0 } {}
do_execsql_test e_expr-16.1.6 { SELECT 'abcxyz' LIKE 'ABC%' } 1
do_execsql_test e_expr-16.1.6b { SELECT 'abc%xyz' LIKE 'ABC\%X%' ESCAPE '\' } 1
do_execsql_test e_expr-16.1.7 { SELECT 'ABCxyz' LIKE 'ABC%' } 1
do_execsql_test e_expr-16.1.7b { SELECT 'ABC%xyz' LIKE 'ABC\%X%' ESCAPE '\' } 1
# EVIDENCE-OF: R-52087-12043 The GLOB operator is similar to LIKE but
# uses the Unix file globbing syntax for its wildcards.
@@ -1639,16 +1644,40 @@ do_expr_test e_expr-31.2.4 {
} integer 9223372036854775807
# EVIDENCE-OF: R-09295-61337 Casting a TEXT or BLOB value into NUMERIC
# first does a forced conversion into REAL but then further converts the
# result into INTEGER if and only if the conversion from REAL to INTEGER
# is lossless and reversible.
# EVIDENCE-OF: R-55084-10555 Casting a TEXT or BLOB value into NUMERIC
# yields either an INTEGER or a REAL result.
#
# EVIDENCE-OF: R-48945-04866 If the input text looks like an integer
# (there is no decimal point nor exponent) and the value is small enough
# to fit in a 64-bit signed integer, then the result will be INTEGER.
#
# EVIDENCE-OF: R-47045-23194 Input text that looks like floating point
# (there is a decimal point and/or an exponent) and the text describes a
# value that can be losslessly converted back and forth between IEEE 754
# 64-bit float and a 51-bit signed integer, then the result is INTEGER.
#
do_expr_test e_expr-32.1.1 { CAST('45' AS NUMERIC) } integer 45
do_expr_test e_expr-32.1.2 { CAST('45.0' AS NUMERIC) } integer 45
do_expr_test e_expr-32.1.3 { CAST('45.2' AS NUMERIC) } real 45.2
do_expr_test e_expr-32.1.4 { CAST('11abc' AS NUMERIC) } integer 11
do_expr_test e_expr-32.1.5 { CAST('11.1abc' AS NUMERIC) } real 11.1
do_expr_test e_expr-32.1.6 {CAST( '9.223372036e14' AS NUMERIC)} integer 922337203600000
do_expr_test e_expr-32.1.7 {CAST('-9.223372036e14' AS NUMERIC)} integer -922337203600000
do_expr_test e_expr-32.1.8 {CAST( '9.223372036e15' AS NUMERIC)} real 9223372036000000.0
do_expr_test e_expr-32.1.9 {CAST('-9.223372036e15' AS NUMERIC)} real -9223372036000000.0
# EVIDENCE-OF: R-50300-26941 Any text input that describes a value
# outside the range of a 64-bit signed integer yields a REAL result.
#
do_expr_test e_expr-32.1.20 { CAST('9223372036854775807' AS numeric) } \
integer 9223372036854775807
do_expr_test e_expr-32.1.21 { CAST('9223372036854775808' AS numeric) } \
real 9.22337203685478e+18
do_expr_test e_expr-32.1.22 { CAST('-9223372036854775808' AS numeric) } \
integer -9223372036854775808
do_expr_test e_expr-32.1.23 { CAST('-9223372036854775809' AS numeric) } \
real -9.22337203685478e+18
# EVIDENCE-OF: R-30347-18702 Casting a REAL or INTEGER value to NUMERIC
# is a no-op, even if a real value could be losslessly converted to an
@@ -1696,14 +1725,14 @@ do_execsql_test e_expr-32.2.8 {
integer 9000000000000000001 \
integer 9000000000000000001 \
integer 9000000000000000001 \
integer 9000000000000000001 \
real 9.0e+18 \
integer 9223372036854775807 \
integer 9223372036854775807 \
integer 9223372036854775807 \
real 9.22337203685478e+18 \
real 9.22337203685478e+18 \
integer 9223372036854775807 \
integer 9223372036854775807 \
real 9.22337203685478e+18 \
real 9.22337203685478e+18 \
integer -5 \
integer -5 \
]
+54
View File
@@ -0,0 +1,54 @@
# 2019 May 20
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# May you do good and not evil.
# May you find forgiveness for yourself and forgive others.
# May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library. The
# focus of this file is testing expressions.
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix expr2
do_execsql_test 1.0 {
CREATE TABLE t0(c0);
INSERT INTO t0(c0) VALUES ('val');
}
do_execsql_test 1.1 {
SELECT * FROM t0 WHERE (
( (0 IS NOT FALSE) OR NOT (0 IS FALSE OR (t0.c0 = 1)) ) IS 0
)
} {val}
do_execsql_test 1.2.1 {
SELECT
( (0 IS NOT FALSE) OR NOT (0 IS FALSE OR (t0.c0 = 1)) ) IS 0
FROM t0
} {1}
do_execsql_test 1.2.2 {
SELECT
( (0 IS NOT FALSE) OR NOT (0 IS 0 OR (t0.c0 = 1)) ) IS 0
FROM t0
} {1}
do_execsql_test 1.3 {
SELECT ( (0 IS NOT FALSE) OR NOT (0 IS FALSE OR (t0.c0 = 1)) ) FROM t0
} {0}
do_execsql_test 1.4.1 {
SELECT (0 IS NOT FALSE) FROM t0
} {0}
do_execsql_test 1.4.2 {
SELECT NOT (0 IS FALSE OR (t0.c0 = 1)) FROM t0
} {0}
finish_test
+36
View File
@@ -82,4 +82,40 @@ ifcapable stat4 {
}
}
do_execsql_test 4.0 {
PRAGMA foreign_keys = true;
CREATE TABLE parent(
p PRIMARY KEY
);
CREATE TABLE child(
c UNIQUE REFERENCES parent(p)
);
}
do_catchsql_test 4.1 {
INSERT OR FAIL INTO child VALUES(123), (123);
} {1 {FOREIGN KEY constraint failed}}
do_execsql_test 4.2 {
SELECT * FROM child;
} {}
do_execsql_test 4.3 {
PRAGMA foreign_key_check;
} {}
do_catchsql_test 4.4 {
INSERT INTO parent VALUES(123);
INSERT OR FAIL INTO child VALUES(123), (123);
} {1 {UNIQUE constraint failed: child.c}}
do_execsql_test 4.5 {
SELECT * FROM child;
} {123}
do_execsql_test 4.6 {
PRAGMA foreign_key_check;
} {}
finish_test
+31
View File
@@ -197,5 +197,36 @@ do_execsql_test 4.2 {
INSERT OR REPLACE INTO t1 VALUES(20000, 20000);
}
#-------------------------------------------------------------------------
reset_db
do_execsql_test 5.0 {
PRAGMA foreign_keys = true;
CREATE TABLE parent(
p TEXT PRIMARY KEY
);
CREATE TABLE child(
c INTEGER UNIQUE,
FOREIGN KEY(c) REFERENCES parent(p) DEFERRABLE INITIALLY DEFERRED
);
BEGIN;
INSERT INTO child VALUES(123);
INSERT INTO parent VALUES('123');
COMMIT;
}
do_execsql_test 5.1 {
PRAGMA integrity_check;
} {ok}
do_execsql_test 5.2 {
INSERT INTO parent VALUES(1200);
BEGIN;
INSERT INTO child VALUES(456);
UPDATE parent SET p = '456' WHERE p=1200;
COMMIT;
}
do_execsql_test 5.3 {
PRAGMA integrity_check;
} {ok}
finish_test
+1181 -2
View File
File diff suppressed because it is too large Load Diff
+60
View File
@@ -0,0 +1,60 @@
# 2019 May 22
#
# 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 fts3corrupt5
# If SQLITE_ENABLE_FTS3 is defined, omit this file.
ifcapable !fts3 {
finish_test
return
}
sqlite3_fts3_may_be_corrupt 1
do_execsql_test 1.0 {
BEGIN;
CREATE VIRTUAL TABLE ft USING fts3(a, b, c);
INSERT INTO ft VALUES('one', 'one', 'one');
COMMIT;
}
do_execsql_test 1.1 {
SELECT * FROM ft WHERE ft MATCH 'b:one'
} {one one one}
do_execsql_test 1.2 {
SELECT quote(root) FROM ft_segdir;
} {X'00036F6E6509010201010201020200'}
breakpoint
foreach {tn val q bCorrupt} {
1 X'00036F6E650901' 'b:one' 1
2 X'00036F6E6509010201010201FFFFFF' 'c:one' 1
3 X'00036F6E6501' 'b:one' 1
4 X'00036F6E650101' 'b:one' 1
5 X'00036F6E650100' 'b:one' 0
} {
do_execsql_test 1.3.$tn.1 "UPDATE ft_segdir SET root = $val"
set res {0 {}}
if {$bCorrupt} { set res {1 {database disk image is malformed}}}
do_catchsql_test 1.3.$tn.2 {
SELECT * FROM ft WHERE ft MATCH $q
} $res
}
finish_test
+44
View File
@@ -0,0 +1,44 @@
# 2019 April 30
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# May you do good and not evil.
# May you find forgiveness for yourself and forgive others.
# May you share freely, never taking more than you give.
#
#*************************************************************************
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
source $testdir/fts3_common.tcl
set ::testprefix fts4rename
# If SQLITE_ENABLE_FTS3 is defined, omit this file.
ifcapable !fts3 {
finish_test
return
}
do_execsql_test 1.0 {
CREATE VIRTUAL TABLE temp.t1 USING fts3(a);
BEGIN;
CREATE TABLE t2(x);
} {}
do_catchsql_test 1.1 {
ALTER TABLE t1_content RENAME c0a TO docid;
} {1 {duplicate column name: docid}}
do_catchsql_test 1.2 {
UPDATE t1 SET Col0 = 1 ;
} {1 {no such column: Col0}}
do_catchsql_test 1.3 {
ROLLBACK;
DROP TABLE t1;
} {0 {}}
finish_test
+3
View File
@@ -315,6 +315,9 @@ ifcapable floatingpoint {
do_test func-4.38 {
execsql {SELECT round(9999999999999.556,2);}
} {9999999999999.56}
do_execsql_test func-4.39 {
SELECT round(1e500), round(-1e500);
} {Inf -Inf}
}
# Test the upper() and lower() functions
+13
View File
@@ -153,6 +153,19 @@ do_test func3-5.39 {
db eval {EXPLAIN SELECT unlikely(min(1.0+'2.0',4*11))}
} [db eval {EXPLAIN SELECT min(1.0+'2.0',4*11)}]
# Unlikely() does not preserve the affinity of X.
# ticket https://www.sqlite.org/src/tktview/0c620df60b
#
do_execsql_test func3-5.40 {
SELECT likely(CAST(1 AS INT))=='1';
} 0
do_execsql_test func3-5.41 {
SELECT unlikely(CAST(1 AS INT))=='1';
} 0
do_execsql_test func3-5.41 {
SELECT likelihood(CAST(1 AS INT),0.5)=='1';
} 0
# EVIDENCE-OF: R-23735-03107 The likely(X) function returns the argument
# X unchanged.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
+15 -1
View File
@@ -734,6 +734,20 @@ do_execsql_test in-16.2 {
ORDER BY a DESC, b;
} {}
# 2019-06-11
# https://www.sqlite.org/src/info/57353f8243c637c0
#
do_execsql_test in-17.1 {
SELECT 1 IN ('1');
} 0
do_execsql_test in-17.2 {
SELECT 1 IN ('1' COLLATE nocase);
} 0
do_execsql_test in-17.3 {
SELECT 1 IN (CAST('1' AS text));
} 0
do_execsql_test in-17.4 {
SELECT 1 IN (CAST('1' AS text) COLLATE nocase);
} 0
finish_test
+27 -1
View File
@@ -738,6 +738,32 @@ do_test index-21.2 {
}
} {0 {9 5 1}}
# 2019-05-01 ticket https://www.sqlite.org/src/info/3be1295b264be2fa
do_execsql_test index-22.0 {
DROP TABLE IF EXISTS t1;
CREATE TABLE t1(a, b TEXT);
CREATE UNIQUE INDEX IF NOT EXISTS x1 ON t1(b==0);
CREATE INDEX IF NOT EXISTS x2 ON t1(a || 0) WHERE b;
INSERT INTO t1(a,b) VALUES('a',1),('a',0);
SELECT a, b, '|' FROM t1;
} {a 1 | a 0 |}
# 2019-05-10 ticket https://www.sqlite.org/src/info/ae0f637bddc5290b
do_execsql_test index-23.0 {
DROP TABLE t1;
CREATE TABLE t1(a TEXT, b REAL);
CREATE UNIQUE INDEX t1x1 ON t1(a GLOB b);
INSERT INTO t1(a,b) VALUES('0.0','1'),('1.0','1');
SELECT * FROM t1;
REINDEX;
} {0.0 1.0 1.0 1.0}
do_execsql_test index-23.1 {
DROP TABLE t1;
CREATE TABLE t1(a REAL);
CREATE UNIQUE INDEX index_0 ON t1(TYPEOF(a));
INSERT OR IGNORE INTO t1(a) VALUES (0.1),(FALSE);
SELECT * FROM t1;
REINDEX;
} {0.1}
finish_test
+28
View File
@@ -410,4 +410,32 @@ do_execsql_test index6-12.1 {
do_execsql_test index6-12.2 {
SELECT x FROM t2 WHERE x IN (SELECT a FROM t1) ORDER BY +x;
} {1 2}
# 2019-05-04
# Ticket https://www.sqlite.org/src/tktview/5c6955204c392ae763a95
# Theorem prover error
#
do_execsql_test index6-13.1 {
DROP TABLE IF EXISTS t0;
CREATE TABLE t0(c0);
CREATE INDEX index_0 ON t0(c0) WHERE c0 NOT NULL;
INSERT INTO t0(c0) VALUES (NULL);
SELECT * FROM t0 WHERE c0 OR 1;
} {{}}
# 2019-05-11
# Ticket https://sqlite.org/src/tktview/8025674847
reset_db
do_execsql_test index6-14.1 {
CREATE TABLE IF NOT EXISTS t0 (c0, c1);
CREATE INDEX IF NOT EXISTS i0 ON t0(c0, c1) WHERE c0 NOT NULL;
INSERT INTO t0(c0, c1) VALUES(NULL, 'row');
SELECT * FROM t0 WHERE t0.c0 IS NOT 1;
} {{} row}
do_execsql_test index6-14.2 {
SELECT * FROM t0 WHERE CASE c0 WHEN 0 THEN 0 ELSE 1 END;
} {{} row}
finish_test

Some files were not shown because too many files have changed in this diff Show More