mirror of
https://github.com/status-im/sqlcipher.git
synced 2026-08-30 22:11:14 +00:00
Merge sqlite-release(3.29.0) into prerelease-integration
This commit is contained in:
@@ -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
|
||||
|
||||
Vendored
+732
-608
File diff suppressed because it is too large
Load Diff
Vendored
+1417
-1263
File diff suppressed because it is too large
Load Diff
@@ -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
@@ -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
@@ -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
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
+1039
-7
File diff suppressed because it is too large
Load Diff
@@ -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
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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
@@ -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;
|
||||
|
||||
@@ -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}]
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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}
|
||||
}]
|
||||
}
|
||||
|
||||
|
||||
@@ -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]
|
||||
|
||||
@@ -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
@@ -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
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -1 +1 @@
|
||||
884b4b7e502b4e991677b53971277adfaf0a04a284f8e483e2553d0f83156b50
|
||||
fc82b73eaac8b36950e527f12c4b5dc1e147e6f4ad2217ae43ad82882a88bfa6
|
||||
|
||||
+31
-5
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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, ®Free1);
|
||||
@@ -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, ®Free1);
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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 */
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
File diff suppressed because it is too large
Load Diff
+43
-4
@@ -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
@@ -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
@@ -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
@@ -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;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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))
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
@@ -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{
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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;
|
||||
|
||||
@@ -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
@@ -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
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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
@@ -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 \
|
||||
]
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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
File diff suppressed because it is too large
Load Diff
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
Binary file not shown.
Binary file not shown.
+15
-1
@@ -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
@@ -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
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user