Compare commits
15 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 3b2ede1f03 | |||
| e6d065a81e | |||
| bda4cb876c | |||
| 24d772cc27 | |||
| bd1d270ec9 | |||
| 6bd166b81e | |||
| 66accfc56b | |||
| 8b174f2916 | |||
| 8a284dcefe | |||
| 1325adf5e9 | |||
| f0e808c60b | |||
| e324782254 | |||
| 4689956b9e | |||
| 5e6710ab65 | |||
| 7e84b377a9 |
+13
-2
@@ -1110,7 +1110,10 @@ static int fts5ExprNodeNext_OR(
|
||||
|| (bFromValid && fts5RowidCmp(pExpr, p1->iRowid, iFrom)<0)
|
||||
){
|
||||
int rc = fts5ExprNodeNext(pExpr, p1, bFromValid, iFrom);
|
||||
if( rc!=SQLITE_OK ) return rc;
|
||||
if( rc!=SQLITE_OK ){
|
||||
pNode->bNomatch = 0;
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1141,7 +1144,10 @@ static int fts5ExprNodeTest_AND(
|
||||
if( cmp>0 ){
|
||||
/* Advance pChild until it points to iLast or laster */
|
||||
rc = fts5ExprNodeNext(pExpr, pChild, 1, iLast);
|
||||
if( rc!=SQLITE_OK ) return rc;
|
||||
if( rc!=SQLITE_OK ){
|
||||
pAnd->bNomatch = 0;
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
/* If the child node is now at EOF, so is the parent AND node. Otherwise,
|
||||
@@ -1180,6 +1186,8 @@ static int fts5ExprNodeNext_AND(
|
||||
int rc = fts5ExprNodeNext(pExpr, pNode->apChild[0], bFromValid, iFrom);
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = fts5ExprNodeTest_AND(pExpr, pNode);
|
||||
}else{
|
||||
pNode->bNomatch = 0;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
@@ -1222,6 +1230,9 @@ static int fts5ExprNodeNext_NOT(
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = fts5ExprNodeTest_NOT(pExpr, pNode);
|
||||
}
|
||||
if( rc!=SQLITE_OK ){
|
||||
pNode->bNomatch = 0;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,87 @@
|
||||
# 2016 February 2
|
||||
#
|
||||
# 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 is focused on OOM errors.
|
||||
#
|
||||
|
||||
source [file join [file dirname [info script]] fts5_common.tcl]
|
||||
source $testdir/malloc_common.tcl
|
||||
set testprefix fts5faultA
|
||||
|
||||
# If SQLITE_ENABLE_FTS3 is defined, omit this file.
|
||||
ifcapable !fts5 {
|
||||
finish_test
|
||||
return
|
||||
}
|
||||
|
||||
foreach_detail_mode $testprefix {
|
||||
if {"%DETAIL%"=="none"} continue
|
||||
|
||||
do_execsql_test 1.0 {
|
||||
CREATE VIRTUAL TABLE o1 USING fts5(a, b, c, detail=%DETAIL%);
|
||||
INSERT INTO o1(o1, rank) VALUES('pgsz', 32);
|
||||
|
||||
WITH s(i) AS ( SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<60 )
|
||||
INSERT INTO o1 SELECT 'A', 'B', 'C' FROM s;
|
||||
|
||||
WITH s(i) AS ( SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<60 )
|
||||
INSERT INTO o1 SELECT 'C', 'A', 'B' FROM s;
|
||||
|
||||
WITH s(i) AS ( SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<60 )
|
||||
INSERT INTO o1 SELECT 'B', 'C', 'A' FROM s;
|
||||
}
|
||||
|
||||
do_faultsim_test 1 -faults int* -prep {
|
||||
sqlite3 db test.db
|
||||
} -body {
|
||||
execsql { SELECT count(*) FROM o1('a') }
|
||||
} -test {
|
||||
faultsim_test_result {0 180} {1 {vtable constructor failed: o1}}
|
||||
}
|
||||
|
||||
do_faultsim_test 2 -faults int* -prep {
|
||||
sqlite3 db test.db
|
||||
} -body {
|
||||
execsql { SELECT * FROM o1('a:a AND {b c}:b') ORDER BY rank }
|
||||
expr 1
|
||||
} -test {
|
||||
faultsim_test_result {0 1} {1 {vtable constructor failed: o1}}
|
||||
}
|
||||
|
||||
do_faultsim_test 3 -faults int* -prep {
|
||||
sqlite3 db test.db
|
||||
} -body {
|
||||
execsql { SELECT * FROM o1('{b c}:b NOT a:a') ORDER BY rank }
|
||||
expr 1
|
||||
} -test {
|
||||
faultsim_test_result {0 1} {1 {vtable constructor failed: o1}}
|
||||
}
|
||||
|
||||
do_faultsim_test 4 -faults int* -prep {
|
||||
sqlite3 db test.db
|
||||
} -body {
|
||||
execsql { SELECT * FROM o1('b:b OR a:a') }
|
||||
expr 1
|
||||
} -test {
|
||||
faultsim_test_result {0 1} {1 {vtable constructor failed: o1}}
|
||||
}
|
||||
|
||||
do_faultsim_test 5 -faults int* -prep {
|
||||
sqlite3 db test.db
|
||||
} -body {
|
||||
execsql { SELECT count(*) FROM o1('c:b') }
|
||||
expr 1
|
||||
} -test {
|
||||
faultsim_test_result {0 1} {1 {vtable constructor failed: o1}}
|
||||
}
|
||||
}
|
||||
|
||||
finish_test
|
||||
@@ -1,5 +1,5 @@
|
||||
C Add\sthe\sSQLITE_BUG_COMPATIBLE_20160819\scompile-time\soption\sto\somit\sthe\serror\nmessage\swhen\san\sunrecognized\sargument\sis\sprovided\sto\sthe\sVACUUM\scommand.
|
||||
D 2017-02-18T13:47:11.181
|
||||
C Tweak\sthe\scode\son\sthis\sbranch\sto\sdetect\sb-tree\spage\scorruption\sin\sthe\ssame\scases\sas\sthe\strunk.
|
||||
D 2017-02-25T16:24:02.032
|
||||
F Makefile.in edb6bcdd37748d2b1c3422ff727c748df7ffe918
|
||||
F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
|
||||
F Makefile.msc a89ea37ab5928026001569f056973b9059492fe2
|
||||
@@ -102,7 +102,7 @@ F ext/fts5/fts5Int.h c629b24d2b92b99596f3b8e82289fddca06df6e1
|
||||
F ext/fts5/fts5_aux.c 67acf8d51723cf28ffc3828210ba662df4b8d267
|
||||
F ext/fts5/fts5_buffer.c 4c1502d4c956cd092c89ce4480867f9d8bf325cd
|
||||
F ext/fts5/fts5_config.c 5af9c360e99669d29f06492c370892394aba0857
|
||||
F ext/fts5/fts5_expr.c 33f0e8063ac7360bcd71c0ff0dcbacdc05fffe50
|
||||
F ext/fts5/fts5_expr.c c6ecc2280162a3714d15dce2a8f2299f748b627c
|
||||
F ext/fts5/fts5_hash.c 880998e596b60f078348d48732ca4ad9a90caad2
|
||||
F ext/fts5/fts5_index.c f67032a9a529ba52a545e6e3ab970764199c05d4
|
||||
F ext/fts5/fts5_main.c f85281445dcf8be32d18841c93a6f90fe27dbfe2
|
||||
@@ -160,6 +160,7 @@ F ext/fts5/test/fts5fault8.test 6785af34bd1760de74e2824ea9c161965af78f85
|
||||
F ext/fts5/test/fts5fault9.test e10e395428a9ea0596ebe752ff7123d16ab78e08
|
||||
F ext/fts5/test/fts5faultA.test fa5d59c0ff62b7125cd14eee38ded1c46e15a7ea
|
||||
F ext/fts5/test/fts5faultB.test 7f3bba790fa172073ac314f9b8ed197390b61eca
|
||||
F ext/fts5/test/fts5faultD.test cc5d1225556e356615e719c612e845d41bff7d5a
|
||||
F ext/fts5/test/fts5full.test 6f6143af0c6700501d9fd597189dfab1555bb741
|
||||
F ext/fts5/test/fts5fuzz1.test bece4695fc169b61ab236ada7931c6e4942cbef9
|
||||
F ext/fts5/test/fts5hash.test 06f9309ccb4d5050a131594e9e47d0b21456837d
|
||||
@@ -331,16 +332,16 @@ F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b
|
||||
F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786
|
||||
F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a
|
||||
F src/alter.c 3b23977620ce9662ac54443f65b87ba996e36121
|
||||
F src/analyze.c ac7a5d7e3cee07d074697904e00e4a8ab7b2b4f5
|
||||
F src/analyze.c 8a2af8a16e4d95ec2327d3f180cb0bab4b2074c1
|
||||
F src/attach.c 8c476f8bd5d2afe11d925f890d30e527e5b0ce43
|
||||
F src/auth.c 930b376a9c56998557367e6f7f8aaeac82a2a792
|
||||
F src/backup.c faf17e60b43233c214aae6a8179d24503a61e83b
|
||||
F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33
|
||||
F src/btmutex.c 0e9ce2d56159b89b9bc8e197e023ee11e39ff8ca
|
||||
F src/btree.c 3ae66974881e74df9909093818b4c3428f8d7982
|
||||
F src/btree.c 03149b0f3fec3c1aa3c50a17e997bb442b867632
|
||||
F src/btree.h e6d352808956ec163a17f832193a3e198b3fb0ac
|
||||
F src/btreeInt.h cd55d39d9916270837a88c12e701047cba0729b0
|
||||
F src/build.c 9e799f1edd910dfa8a0bc29bd390d35d310596af
|
||||
F src/build.c 51b473eec465f471d607b54e8dbc00751c3f8a1f
|
||||
F src/callback.c 2e76147783386374bf01b227f752c81ec872d730
|
||||
F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e
|
||||
F src/ctime.c a9984df73898c042a5cfc8f9d8e7723d02bc35c9
|
||||
@@ -379,15 +380,15 @@ F src/os.h 8e976e59eb4ca1c0fca6d35ee803e38951cb0343
|
||||
F src/os_common.h b2f4707a603e36811d9b1a13278bffd757857b85
|
||||
F src/os_setup.h 0dbaea40a7d36bf311613d31342e0b99e2536586
|
||||
F src/os_unix.c 30e2c43e4955db990e5b5a81e901f8aa74cc8820
|
||||
F src/os_win.c cf90abd4e50d9f56d2c20ce8e005aff55d7bd8e9
|
||||
F src/os_win.c 2a6c73eef01c51a048cc4ddccd57f981afbec18a
|
||||
F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a
|
||||
F src/pager.c ff1232b3088a39806035ecfac4fffeb22717d80b
|
||||
F src/pager.h f2a99646c5533ffe11afa43e9e0bea74054e4efa
|
||||
F src/parse.y 591704fce84f814d9a3642774c1f011d38f4149c
|
||||
F src/parse.y af8830094f4aecb91cb69721f3601ad10c36abc4
|
||||
F src/pcache.c 62835bed959e2914edd26afadfecce29ece0e870
|
||||
F src/pcache.h 2cedcd8407eb23017d92790b112186886e179490
|
||||
F src/pcache1.c e3967219b2a92b9edcb9324a4ba75009090d3953
|
||||
F src/pragma.c 7831956012f5d764761fbd023e59b0ffc08f5e8d
|
||||
F src/pragma.c b127edeb54c744a101b371cfa2e221fd741bcd72
|
||||
F src/pragma.h 61aa5389118594bebb28120a6720401aee34ce1a
|
||||
F src/prepare.c b1140c3d0cf59bc85ace00ce363153041b424b7a
|
||||
F src/printf.c 67427bbee66d891fc6f6f5aada857e9cdb368c1c
|
||||
@@ -399,7 +400,7 @@ F src/shell.c bf976d5301be9d8a4c52852c97909cc9a41ee20d
|
||||
F src/sqlite.h.in 751ff125eb159c8f92c182b8df980a5e4f50e966
|
||||
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
|
||||
F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae
|
||||
F src/sqliteInt.h 46fe8e5aee3825d77fa771216ef263dc947030e7
|
||||
F src/sqliteInt.h a23e18aebdd0d851c2956a74a3a4f12ff202b472
|
||||
F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247
|
||||
F src/status.c a9e66593dfb28a9e746cba7153f84d49c1ddc4b1
|
||||
F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34
|
||||
@@ -461,11 +462,11 @@ F src/update.c 456d4a4656f8a03c2abc88a51b19172197400e58
|
||||
F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c
|
||||
F src/util.c ca8440ede81e155d15cff7c101654f60b55a9ae6
|
||||
F src/vacuum.c 1fe4555cd8c9b263afb85b5b4ee3a4a4181ad569
|
||||
F src/vdbe.c 16f378640570c24442fd7191b136b5d6380f5c7b
|
||||
F src/vdbe.c 83f387d9e6842b1dc99f6e85bb577c5bbc4e397d
|
||||
F src/vdbe.h 59998ffd71d7caa8886bc78dafaf8caeccd4c13c
|
||||
F src/vdbeInt.h 4e4b15b2e1330e1636e4e01974eab2b0b985092f
|
||||
F src/vdbeapi.c 3e4a8893feeb78620f4aac4ac5b85d92255b97e1
|
||||
F src/vdbeaux.c 4122458d33318ab039c4b5da1ca4e7c9221c38e4
|
||||
F src/vdbeapi.c 70aabe108c411e529a59d8800445513965334062
|
||||
F src/vdbeaux.c 031422c66e272c7f1027070e7f0858f4c418dfbc
|
||||
F src/vdbeblob.c 359891617358deefc85bef7bcf787fa6b77facb9
|
||||
F src/vdbemem.c 3b5a9a5b375458d3e12a50ae1aaa41eeec2175fd
|
||||
F src/vdbesort.c eda25cb2d1727efca6f7862fea32b8aa33c0face
|
||||
@@ -575,7 +576,7 @@ F test/capi3d.test 485048dc5cd07bc68011e4917ad035ad6047ab82
|
||||
F test/capi3e.test 3d49c01ef2a1a55f41d73cba2b23b5059ec460fe
|
||||
F test/cast.test 4c275cbdc8202d6f9c54a3596701719868ac7dc3
|
||||
F test/cffault.test 9d6b20606afe712374952eec4f8fd74b1a8097ef
|
||||
F test/check.test 85a84bfc4be0e83f668747211c7cd45a6721d485
|
||||
F test/check.test 92b23a91fb7be12fba7ee9ce518217e2919a21da
|
||||
F test/close.test 83947daf3b700631f90f4850ddaab455be4af73d
|
||||
F test/closure01.test b1703ba40639cfc9b295cf478d70739415eec6a4
|
||||
F test/coalesce.test cee0dccb9fbd2d494b77234bccf9dc6c6786eb91
|
||||
@@ -1556,7 +1557,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
|
||||
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
|
||||
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
||||
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
||||
P 8cc9d74c176a78aeebfbb39198c21b5dd547ff52
|
||||
R 57839b570efd132c834489fe34d93e5e
|
||||
U drh
|
||||
Z 38cfd439ab0cfeae01cbf1d291727475
|
||||
P 202b1c0276aec6b8da64d3277de1ad91c9d62d80
|
||||
R 7a56121f7b6bd4c4a315ae4d10cd07e6
|
||||
U dan
|
||||
Z 0eab51f3ee55bc511deac00d1a02232c
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
491814272dce7e937b4734fcbc2ad69e12377b56
|
||||
f9863b39d96dce6cb5e49a5f3a445ff3d897a951
|
||||
+21
-3
@@ -290,6 +290,7 @@ struct Stat4Accum {
|
||||
Stat4Sample *aBest; /* Array of nCol best samples */
|
||||
int iMin; /* Index in a[] of entry with minimum score */
|
||||
int nSample; /* Current number of samples */
|
||||
int nMaxEqZero; /* Max leading 0 in anEq[] for any a[] entry */
|
||||
int iGet; /* Index of current sample accessed by stat_get() */
|
||||
Stat4Sample *a; /* Array of mxSample Stat4Sample objects */
|
||||
sqlite3 *db; /* Database connection, for malloc() */
|
||||
@@ -554,6 +555,13 @@ static void sampleInsert(Stat4Accum *p, Stat4Sample *pNew, int nEqZero){
|
||||
assert( IsStat4 || nEqZero==0 );
|
||||
|
||||
#ifdef SQLITE_ENABLE_STAT4
|
||||
/* Stat4Accum.nMaxEqZero is set to the maximum number of leading 0
|
||||
** values in the anEq[] array of any sample in Stat4Accum.a[]. In
|
||||
** other words, if nMaxEqZero is n, then it is guaranteed that there
|
||||
** are no samples with Stat4Sample.anEq[m]==0 for (m>=n). */
|
||||
if( nEqZero>p->nMaxEqZero ){
|
||||
p->nMaxEqZero = nEqZero;
|
||||
}
|
||||
if( pNew->isPSample==0 ){
|
||||
Stat4Sample *pUpgrade = 0;
|
||||
assert( pNew->anEq[pNew->iCol]>0 );
|
||||
@@ -651,12 +659,22 @@ static void samplePushPrevious(Stat4Accum *p, int iChng){
|
||||
}
|
||||
}
|
||||
|
||||
/* Update the anEq[] fields of any samples already collected. */
|
||||
/* Check that no sample contains an anEq[] entry with an index of
|
||||
** p->nMaxEqZero or greater set to zero. */
|
||||
for(i=p->nSample-1; i>=0; i--){
|
||||
int j;
|
||||
for(j=iChng; j<p->nCol; j++){
|
||||
if( p->a[i].anEq[j]==0 ) p->a[i].anEq[j] = p->current.anEq[j];
|
||||
for(j=p->nMaxEqZero; j<p->nCol; j++) assert( p->a[i].anEq[j]>0 );
|
||||
}
|
||||
|
||||
/* Update the anEq[] fields of any samples already collected. */
|
||||
if( iChng<p->nMaxEqZero ){
|
||||
for(i=p->nSample-1; i>=0; i--){
|
||||
int j;
|
||||
for(j=iChng; j<p->nCol; j++){
|
||||
if( p->a[i].anEq[j]==0 ) p->a[i].anEq[j] = p->current.anEq[j];
|
||||
}
|
||||
}
|
||||
p->nMaxEqZero = iChng;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
+50
-14
@@ -1317,17 +1317,18 @@ static void ptrmapPutOvflPtr(MemPage *pPage, u8 *pCell, int *pRC){
|
||||
|
||||
|
||||
/*
|
||||
** Defragment the page given. All Cells are moved to the
|
||||
** end of the page and all free space is collected into one
|
||||
** big FreeBlk that occurs in between the header and cell
|
||||
** pointer array and the cell content area.
|
||||
** Defragment the page given. This routine reorganizes cells within the
|
||||
** page so that there are no free-blocks on the free-block list.
|
||||
**
|
||||
** Parameter nMaxFrag is the maximum amount of fragmented space that may be
|
||||
** present in the page after this routine returns.
|
||||
**
|
||||
** EVIDENCE-OF: R-44582-60138 SQLite may from time to time reorganize a
|
||||
** b-tree page so that there are no freeblocks or fragment bytes, all
|
||||
** unused bytes are contained in the unallocated space region, and all
|
||||
** cells are packed tightly at the end of the page.
|
||||
*/
|
||||
static int defragmentPage(MemPage *pPage){
|
||||
static int defragmentPage(MemPage *pPage, int nMaxFrag){
|
||||
int i; /* Loop counter */
|
||||
int pc; /* Address of the i-th cell */
|
||||
int hdr; /* Offset to the page header */
|
||||
@@ -1342,7 +1343,6 @@ static int defragmentPage(MemPage *pPage){
|
||||
int iCellFirst; /* First allowable cell index */
|
||||
int iCellLast; /* Last possible cell index */
|
||||
|
||||
|
||||
assert( sqlite3PagerIswriteable(pPage->pDbPage) );
|
||||
assert( pPage->pBt!=0 );
|
||||
assert( pPage->pBt->usableSize <= SQLITE_MAX_PAGE_SIZE );
|
||||
@@ -1354,10 +1354,44 @@ static int defragmentPage(MemPage *pPage){
|
||||
cellOffset = pPage->cellOffset;
|
||||
nCell = pPage->nCell;
|
||||
assert( nCell==get2byte(&data[hdr+3]) );
|
||||
iCellFirst = cellOffset + 2*nCell;
|
||||
|
||||
/* This block handles pages with two or fewer free blocks and nMaxFrag
|
||||
** or fewer fragmented bytes. In this case it is faster to move the
|
||||
** two (or one) blocks of cells using memmove() and add the required
|
||||
** offsets to each pointer in the cell-pointer array than it is to
|
||||
** reconstruct the entire page. */
|
||||
if( (int)data[hdr+7]<=nMaxFrag ){
|
||||
int iFree = get2byte(&data[hdr+1]);
|
||||
if( iFree ){
|
||||
int iFree2 = get2byte(&data[iFree]);
|
||||
if( 0==iFree2 || (data[iFree2]==0 && data[iFree2+1]==0) ){
|
||||
u8 *pEnd = &data[cellOffset + nCell*2];
|
||||
u8 *pAddr;
|
||||
int sz2 = 0;
|
||||
int sz = get2byte(&data[iFree+2]);
|
||||
int top = get2byte(&data[hdr+5]);
|
||||
if( iFree2 ){
|
||||
sz2 = get2byte(&data[iFree2+2]);
|
||||
memmove(&data[iFree+sz+sz2], &data[iFree+sz], iFree2-(iFree+sz));
|
||||
sz += sz2;
|
||||
}
|
||||
cbrk = top+sz;
|
||||
memmove(&data[cbrk], &data[top], iFree-top);
|
||||
for(pAddr=&data[cellOffset]; pAddr<pEnd; pAddr+=2){
|
||||
pc = get2byte(pAddr);
|
||||
if( pc<iFree ){ put2byte(pAddr, pc+sz); }
|
||||
else if( pc<iFree2 ){ put2byte(pAddr, pc+sz2); }
|
||||
}
|
||||
goto defragment_out;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
usableSize = pPage->pBt->usableSize;
|
||||
cbrk = usableSize;
|
||||
iCellFirst = cellOffset + 2*nCell;
|
||||
iCellLast = usableSize - 4;
|
||||
|
||||
for(i=0; i<nCell; i++){
|
||||
u8 *pAddr; /* The i-th cell pointer */
|
||||
pAddr = &data[cellOffset + i*2];
|
||||
@@ -1390,16 +1424,18 @@ static int defragmentPage(MemPage *pPage){
|
||||
}
|
||||
memcpy(&data[cbrk], &src[pc], size);
|
||||
}
|
||||
data[hdr+7] = 0;
|
||||
|
||||
defragment_out:
|
||||
if( data[hdr+7]+cbrk-iCellFirst!=pPage->nFree ){
|
||||
return SQLITE_CORRUPT_BKPT;
|
||||
}
|
||||
assert( cbrk>=iCellFirst );
|
||||
put2byte(&data[hdr+5], cbrk);
|
||||
data[hdr+1] = 0;
|
||||
data[hdr+2] = 0;
|
||||
data[hdr+7] = 0;
|
||||
memset(&data[iCellFirst], 0, cbrk-iCellFirst);
|
||||
assert( sqlite3PagerIswriteable(pPage->pDbPage) );
|
||||
if( cbrk-iCellFirst!=pPage->nFree ){
|
||||
return SQLITE_CORRUPT_BKPT;
|
||||
}
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
@@ -1537,10 +1573,10 @@ static int allocateSpace(MemPage *pPage, int nByte, int *pIdx){
|
||||
testcase( gap+2+nByte==top );
|
||||
if( gap+2+nByte>top ){
|
||||
assert( pPage->nCell>0 || CORRUPT_DB );
|
||||
rc = defragmentPage(pPage);
|
||||
rc = defragmentPage(pPage, MIN(4, pPage->nFree - (2+nByte)));
|
||||
if( rc ) return rc;
|
||||
top = get2byteNotZero(&data[hdr+5]);
|
||||
assert( gap+nByte<=top );
|
||||
assert( gap+2+nByte<=top );
|
||||
}
|
||||
|
||||
|
||||
@@ -7689,7 +7725,7 @@ static int balance_nonroot(
|
||||
** free space needs to be up front.
|
||||
*/
|
||||
assert( nNew==1 || CORRUPT_DB );
|
||||
rc = defragmentPage(apNew[0]);
|
||||
rc = defragmentPage(apNew[0], -1);
|
||||
testcase( rc!=SQLITE_OK );
|
||||
assert( apNew[0]->nFree ==
|
||||
(get2byte(&apNew[0]->aData[5])-apNew[0]->cellOffset-apNew[0]->nCell*2)
|
||||
|
||||
@@ -1115,6 +1115,7 @@ void sqlite3AddNotNull(Parse *pParse, int onError){
|
||||
p = pParse->pNewTable;
|
||||
if( p==0 || NEVER(p->nCol<1) ) return;
|
||||
p->aCol[p->nCol-1].notNull = (u8)onError;
|
||||
p->tabFlags |= TF_HasNotNull;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
+45
-7
@@ -352,7 +352,34 @@ struct winVfsAppData {
|
||||
******************************************************************************
|
||||
*/
|
||||
#ifndef SQLITE_WIN32_HEAP_CREATE
|
||||
# define SQLITE_WIN32_HEAP_CREATE (TRUE)
|
||||
# define SQLITE_WIN32_HEAP_CREATE (TRUE)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This is the maximum possible initial size of the Win32-specific heap, in
|
||||
* bytes.
|
||||
*/
|
||||
#ifndef SQLITE_WIN32_HEAP_MAX_INIT_SIZE
|
||||
# define SQLITE_WIN32_HEAP_MAX_INIT_SIZE (4294967295U)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This is the extra space for the initial size of the Win32-specific heap,
|
||||
* in bytes. This value may be zero.
|
||||
*/
|
||||
#ifndef SQLITE_WIN32_HEAP_INIT_EXTRA
|
||||
# define SQLITE_WIN32_HEAP_INIT_EXTRA (4194304)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Calculate the maximum legal cache size, in pages, based on the maximum
|
||||
* possible initial heap size and the default page size, setting aside the
|
||||
* needed extra space.
|
||||
*/
|
||||
#ifndef SQLITE_WIN32_MAX_CACHE_SIZE
|
||||
# define SQLITE_WIN32_MAX_CACHE_SIZE (((SQLITE_WIN32_HEAP_MAX_INIT_SIZE) - \
|
||||
(SQLITE_WIN32_HEAP_INIT_EXTRA)) / \
|
||||
(SQLITE_DEFAULT_PAGE_SIZE))
|
||||
#endif
|
||||
|
||||
/*
|
||||
@@ -361,25 +388,36 @@ struct winVfsAppData {
|
||||
*/
|
||||
#ifndef SQLITE_WIN32_CACHE_SIZE
|
||||
# if SQLITE_DEFAULT_CACHE_SIZE>=0
|
||||
# define SQLITE_WIN32_CACHE_SIZE (SQLITE_DEFAULT_CACHE_SIZE)
|
||||
# define SQLITE_WIN32_CACHE_SIZE (SQLITE_DEFAULT_CACHE_SIZE)
|
||||
# else
|
||||
# define SQLITE_WIN32_CACHE_SIZE (-(SQLITE_DEFAULT_CACHE_SIZE))
|
||||
# define SQLITE_WIN32_CACHE_SIZE (-(SQLITE_DEFAULT_CACHE_SIZE))
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Make sure that the calculated cache size, in pages, cannot cause the
|
||||
* initial size of the Win32-specific heap to exceed the maximum amount
|
||||
* of memory that can be specified in the call to HeapCreate.
|
||||
*/
|
||||
#if SQLITE_WIN32_CACHE_SIZE>SQLITE_WIN32_MAX_CACHE_SIZE
|
||||
# undef SQLITE_WIN32_CACHE_SIZE
|
||||
# define SQLITE_WIN32_CACHE_SIZE (2000)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The initial size of the Win32-specific heap. This value may be zero.
|
||||
*/
|
||||
#ifndef SQLITE_WIN32_HEAP_INIT_SIZE
|
||||
# define SQLITE_WIN32_HEAP_INIT_SIZE ((SQLITE_WIN32_CACHE_SIZE) * \
|
||||
(SQLITE_DEFAULT_PAGE_SIZE) + 4194304)
|
||||
# define SQLITE_WIN32_HEAP_INIT_SIZE ((SQLITE_WIN32_CACHE_SIZE) * \
|
||||
(SQLITE_DEFAULT_PAGE_SIZE) + \
|
||||
(SQLITE_WIN32_HEAP_INIT_EXTRA))
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The maximum size of the Win32-specific heap. This value may be zero.
|
||||
*/
|
||||
#ifndef SQLITE_WIN32_HEAP_MAX_SIZE
|
||||
# define SQLITE_WIN32_HEAP_MAX_SIZE (0)
|
||||
# define SQLITE_WIN32_HEAP_MAX_SIZE (0)
|
||||
#endif
|
||||
|
||||
/*
|
||||
@@ -387,7 +425,7 @@ struct winVfsAppData {
|
||||
* zero for the default behavior.
|
||||
*/
|
||||
#ifndef SQLITE_WIN32_HEAP_FLAGS
|
||||
# define SQLITE_WIN32_HEAP_FLAGS (0)
|
||||
# define SQLITE_WIN32_HEAP_FLAGS (0)
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
+1
-1
@@ -1000,7 +1000,7 @@ expr(A) ::= expr(A) STAR|SLASH|REM(OP) expr(Y).
|
||||
{spanBinaryExpr(pParse,@OP,&A,&Y);}
|
||||
expr(A) ::= expr(A) CONCAT(OP) expr(Y). {spanBinaryExpr(pParse,@OP,&A,&Y);}
|
||||
%type likeop {Token}
|
||||
likeop(A) ::= LIKE_KW|MATCH(X). {A=X;/*A-overwrites-X*/}
|
||||
likeop(A) ::= LIKE_KW|MATCH(A).
|
||||
likeop(A) ::= NOT LIKE_KW|MATCH(X). {A=X; A.n|=0x80000000; /*A-overwrite-X*/}
|
||||
expr(A) ::= expr(A) likeop(OP) expr(Y). [LIKE_KW] {
|
||||
ExprList *pList;
|
||||
|
||||
+75
-41
@@ -295,6 +295,22 @@ static const PragmaName *pragmaLocate(const char *zName){
|
||||
return lwr>upr ? 0 : &aPragmaName[mid];
|
||||
}
|
||||
|
||||
/*
|
||||
** Helper subroutine for PRAGMA integrity_check:
|
||||
**
|
||||
** Generate code to output a single-column result row with the result
|
||||
** held in register regResult. Decrement the result count and halt if
|
||||
** the maximum number of result rows have been issued.
|
||||
*/
|
||||
static int integrityCheckResultRow(Vdbe *v, int regResult){
|
||||
int addr;
|
||||
sqlite3VdbeAddOp2(v, OP_ResultRow, regResult, 1);
|
||||
addr = sqlite3VdbeAddOp3(v, OP_IfPos, 1, sqlite3VdbeCurrentAddr(v)+2, 1);
|
||||
VdbeCoverage(v);
|
||||
sqlite3VdbeAddOp2(v, OP_Halt, 0, 0);
|
||||
return addr;
|
||||
}
|
||||
|
||||
/*
|
||||
** Process a pragma statement.
|
||||
**
|
||||
@@ -1377,9 +1393,17 @@ void sqlite3Pragma(
|
||||
#endif
|
||||
|
||||
#ifndef SQLITE_OMIT_INTEGRITY_CHECK
|
||||
/* Pragma "quick_check" is reduced version of
|
||||
/* PRAGMA integrity_check
|
||||
** PRAGMA integrity_check(N)
|
||||
** PRAGMA quick_check
|
||||
** PRAGMA quick_check(N)
|
||||
**
|
||||
** Verify the integrity of the database.
|
||||
**
|
||||
** The "quick_check" is reduced version of
|
||||
** integrity_check designed to detect most database corruption
|
||||
** without most of the overhead of a full integrity-check.
|
||||
** without the overhead of cross-checking indexes. Quick_check
|
||||
** is linear time wherease integrity_check is O(NlogN).
|
||||
*/
|
||||
case PragTyp_INTEGRITY_CHECK: {
|
||||
int i, j, addr, mxErr;
|
||||
@@ -1410,7 +1434,7 @@ void sqlite3Pragma(
|
||||
mxErr = SQLITE_INTEGRITY_CHECK_ERROR_MAX;
|
||||
}
|
||||
}
|
||||
sqlite3VdbeAddOp2(v, OP_Integer, mxErr, 1); /* reg[1] holds errors left */
|
||||
sqlite3VdbeAddOp2(v, OP_Integer, mxErr-1, 1); /* reg[1] holds errors left */
|
||||
|
||||
/* Do an integrity check on each database file */
|
||||
for(i=0; i<db->nDb; i++){
|
||||
@@ -1425,10 +1449,6 @@ void sqlite3Pragma(
|
||||
if( iDb>=0 && i!=iDb ) continue;
|
||||
|
||||
sqlite3CodeVerifySchema(pParse, i);
|
||||
addr = sqlite3VdbeAddOp1(v, OP_IfPos, 1); /* Halt if out of errors */
|
||||
VdbeCoverage(v);
|
||||
sqlite3VdbeAddOp2(v, OP_Halt, 0, 0);
|
||||
sqlite3VdbeJumpHere(v, addr);
|
||||
|
||||
/* Do an integrity check of the B-Tree
|
||||
**
|
||||
@@ -1468,12 +1488,12 @@ void sqlite3Pragma(
|
||||
P4_DYNAMIC);
|
||||
sqlite3VdbeAddOp3(v, OP_Move, 2, 4, 1);
|
||||
sqlite3VdbeAddOp3(v, OP_Concat, 4, 3, 2);
|
||||
sqlite3VdbeAddOp2(v, OP_ResultRow, 2, 1);
|
||||
integrityCheckResultRow(v, 2);
|
||||
sqlite3VdbeJumpHere(v, addr);
|
||||
|
||||
/* Make sure all the indices are constructed correctly.
|
||||
*/
|
||||
for(x=sqliteHashFirst(pTbls); x && !isQuick; x=sqliteHashNext(x)){
|
||||
for(x=sqliteHashFirst(pTbls); x; x=sqliteHashNext(x)){
|
||||
Table *pTab = sqliteHashData(x);
|
||||
Index *pIdx, *pPk;
|
||||
Index *pPrior = 0;
|
||||
@@ -1481,12 +1501,13 @@ void sqlite3Pragma(
|
||||
int iDataCur, iIdxCur;
|
||||
int r1 = -1;
|
||||
|
||||
if( pTab->pIndex==0 ) continue;
|
||||
if( pTab->pCheck==0
|
||||
&& (pTab->tabFlags & TF_HasNotNull)==0
|
||||
&& (pTab->pIndex==0 || isQuick)
|
||||
){
|
||||
continue; /* No additional checks needed for this table */
|
||||
}
|
||||
pPk = HasRowid(pTab) ? 0 : sqlite3PrimaryKeyIndex(pTab);
|
||||
addr = sqlite3VdbeAddOp1(v, OP_IfPos, 1); /* Stop if out of errors */
|
||||
VdbeCoverage(v);
|
||||
sqlite3VdbeAddOp2(v, OP_Halt, 0, 0);
|
||||
sqlite3VdbeJumpHere(v, addr);
|
||||
sqlite3ExprCacheClear(pParse);
|
||||
sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenRead, 0,
|
||||
1, 0, &iDataCur, &iIdxCur);
|
||||
@@ -1501,24 +1522,42 @@ void sqlite3Pragma(
|
||||
/* Verify that all NOT NULL columns really are NOT NULL */
|
||||
for(j=0; j<pTab->nCol; j++){
|
||||
char *zErr;
|
||||
int jmp2, jmp3;
|
||||
int jmp2;
|
||||
if( j==pTab->iPKey ) continue;
|
||||
if( pTab->aCol[j].notNull==0 ) continue;
|
||||
sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, j, 3);
|
||||
sqlite3VdbeChangeP5(v, OPFLAG_TYPEOFARG);
|
||||
jmp2 = sqlite3VdbeAddOp1(v, OP_NotNull, 3); VdbeCoverage(v);
|
||||
sqlite3VdbeAddOp2(v, OP_AddImm, 1, -1); /* Decrement error limit */
|
||||
zErr = sqlite3MPrintf(db, "NULL value in %s.%s", pTab->zName,
|
||||
pTab->aCol[j].zName);
|
||||
sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, zErr, P4_DYNAMIC);
|
||||
sqlite3VdbeAddOp2(v, OP_ResultRow, 3, 1);
|
||||
jmp3 = sqlite3VdbeAddOp1(v, OP_IfPos, 1); VdbeCoverage(v);
|
||||
sqlite3VdbeAddOp0(v, OP_Halt);
|
||||
integrityCheckResultRow(v, 3);
|
||||
sqlite3VdbeJumpHere(v, jmp2);
|
||||
sqlite3VdbeJumpHere(v, jmp3);
|
||||
}
|
||||
/* Verify CHECK constraints */
|
||||
if( pTab->pCheck && (db->flags & SQLITE_IgnoreChecks)==0 ){
|
||||
int addrCkFault = sqlite3VdbeMakeLabel(v);
|
||||
int addrCkOk = sqlite3VdbeMakeLabel(v);
|
||||
ExprList *pCheck = pTab->pCheck;
|
||||
char *zErr;
|
||||
int k;
|
||||
pParse->iSelfTab = iDataCur;
|
||||
sqlite3ExprCachePush(pParse);
|
||||
for(k=pCheck->nExpr-1; k>0; k--){
|
||||
sqlite3ExprIfFalse(pParse, pCheck->a[k].pExpr, addrCkFault, 0);
|
||||
}
|
||||
sqlite3ExprIfTrue(pParse, pCheck->a[0].pExpr, addrCkOk,
|
||||
SQLITE_JUMPIFNULL);
|
||||
sqlite3VdbeResolveLabel(v, addrCkFault);
|
||||
zErr = sqlite3MPrintf(db, "CHECK constraint failed in %s",
|
||||
pTab->zName);
|
||||
sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, zErr, P4_DYNAMIC);
|
||||
integrityCheckResultRow(v, 3);
|
||||
sqlite3VdbeResolveLabel(v, addrCkOk);
|
||||
sqlite3ExprCachePop(pParse);
|
||||
}
|
||||
/* Validate index entries for the current row */
|
||||
for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
|
||||
for(j=0, pIdx=pTab->pIndex; pIdx && !isQuick; pIdx=pIdx->pNext, j++){
|
||||
int jmp2, jmp3, jmp4, jmp5;
|
||||
int ckUniq = sqlite3VdbeMakeLabel(v);
|
||||
if( pPk==pIdx ) continue;
|
||||
@@ -1529,16 +1568,13 @@ void sqlite3Pragma(
|
||||
/* Verify that an index entry exists for the current table row */
|
||||
jmp2 = sqlite3VdbeAddOp4Int(v, OP_Found, iIdxCur+j, ckUniq, r1,
|
||||
pIdx->nColumn); VdbeCoverage(v);
|
||||
sqlite3VdbeAddOp2(v, OP_AddImm, 1, -1); /* Decrement error limit */
|
||||
sqlite3VdbeLoadString(v, 3, "row ");
|
||||
sqlite3VdbeAddOp3(v, OP_Concat, 7, 3, 3);
|
||||
sqlite3VdbeLoadString(v, 4, " missing from index ");
|
||||
sqlite3VdbeAddOp3(v, OP_Concat, 4, 3, 3);
|
||||
jmp5 = sqlite3VdbeLoadString(v, 4, pIdx->zName);
|
||||
sqlite3VdbeAddOp3(v, OP_Concat, 4, 3, 3);
|
||||
sqlite3VdbeAddOp2(v, OP_ResultRow, 3, 1);
|
||||
jmp4 = sqlite3VdbeAddOp1(v, OP_IfPos, 1); VdbeCoverage(v);
|
||||
sqlite3VdbeAddOp0(v, OP_Halt);
|
||||
jmp4 = integrityCheckResultRow(v, 3);
|
||||
sqlite3VdbeJumpHere(v, jmp2);
|
||||
/* For UNIQUE indexes, verify that only one entry exists with the
|
||||
** current key. The entry is unique if (1) any column is NULL
|
||||
@@ -1559,7 +1595,6 @@ void sqlite3Pragma(
|
||||
sqlite3VdbeJumpHere(v, jmp6);
|
||||
sqlite3VdbeAddOp4Int(v, OP_IdxGT, iIdxCur+j, uniqOk, r1,
|
||||
pIdx->nKeyCol); VdbeCoverage(v);
|
||||
sqlite3VdbeAddOp2(v, OP_AddImm, 1, -1); /* Decrement error limit */
|
||||
sqlite3VdbeLoadString(v, 3, "non-unique entry in index ");
|
||||
sqlite3VdbeGoto(v, jmp5);
|
||||
sqlite3VdbeResolveLabel(v, uniqOk);
|
||||
@@ -1570,19 +1605,18 @@ void sqlite3Pragma(
|
||||
sqlite3VdbeAddOp2(v, OP_Next, iDataCur, loopTop); VdbeCoverage(v);
|
||||
sqlite3VdbeJumpHere(v, loopTop-1);
|
||||
#ifndef SQLITE_OMIT_BTREECOUNT
|
||||
sqlite3VdbeLoadString(v, 2, "wrong # of entries in index ");
|
||||
for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
|
||||
if( pPk==pIdx ) continue;
|
||||
addr = sqlite3VdbeCurrentAddr(v);
|
||||
sqlite3VdbeAddOp2(v, OP_IfPos, 1, addr+2); VdbeCoverage(v);
|
||||
sqlite3VdbeAddOp2(v, OP_Halt, 0, 0);
|
||||
sqlite3VdbeAddOp2(v, OP_Count, iIdxCur+j, 3);
|
||||
sqlite3VdbeAddOp3(v, OP_Eq, 8+j, addr+8, 3); VdbeCoverage(v);
|
||||
sqlite3VdbeChangeP5(v, SQLITE_NOTNULL);
|
||||
sqlite3VdbeAddOp2(v, OP_AddImm, 1, -1);
|
||||
sqlite3VdbeLoadString(v, 3, pIdx->zName);
|
||||
sqlite3VdbeAddOp3(v, OP_Concat, 3, 2, 7);
|
||||
sqlite3VdbeAddOp2(v, OP_ResultRow, 7, 1);
|
||||
if( !isQuick ){
|
||||
sqlite3VdbeLoadString(v, 2, "wrong # of entries in index ");
|
||||
for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
|
||||
if( pPk==pIdx ) continue;
|
||||
sqlite3VdbeAddOp2(v, OP_Count, iIdxCur+j, 3);
|
||||
addr = sqlite3VdbeAddOp3(v, OP_Eq, 8+j, 0, 3); VdbeCoverage(v);
|
||||
sqlite3VdbeChangeP5(v, SQLITE_NOTNULL);
|
||||
sqlite3VdbeLoadString(v, 3, pIdx->zName);
|
||||
sqlite3VdbeAddOp3(v, OP_Concat, 3, 2, 7);
|
||||
integrityCheckResultRow(v, 7);
|
||||
sqlite3VdbeJumpHere(v, addr);
|
||||
}
|
||||
}
|
||||
#endif /* SQLITE_OMIT_BTREECOUNT */
|
||||
}
|
||||
@@ -1591,7 +1625,7 @@ void sqlite3Pragma(
|
||||
static const int iLn = VDBE_OFFSET_LINENO(2);
|
||||
static const VdbeOpList endCode[] = {
|
||||
{ OP_AddImm, 1, 0, 0}, /* 0 */
|
||||
{ OP_If, 1, 4, 0}, /* 1 */
|
||||
{ OP_IfNotZero, 1, 4, 0}, /* 1 */
|
||||
{ OP_String8, 0, 3, 0}, /* 2 */
|
||||
{ OP_ResultRow, 3, 1, 0}, /* 3 */
|
||||
};
|
||||
@@ -1599,7 +1633,7 @@ void sqlite3Pragma(
|
||||
|
||||
aOp = sqlite3VdbeAddOpList(v, ArraySize(endCode), endCode, iLn);
|
||||
if( aOp ){
|
||||
aOp[0].p2 = -mxErr;
|
||||
aOp[0].p2 = 1-mxErr;
|
||||
aOp[2].p4type = P4_STATIC;
|
||||
aOp[2].p4.z = "ok";
|
||||
}
|
||||
|
||||
+9
-8
@@ -1879,14 +1879,15 @@ struct Table {
|
||||
** the TF_OOOHidden attribute would apply in this case. Such tables require
|
||||
** special handling during INSERT processing.
|
||||
*/
|
||||
#define TF_Readonly 0x01 /* Read-only system table */
|
||||
#define TF_Ephemeral 0x02 /* An ephemeral table */
|
||||
#define TF_HasPrimaryKey 0x04 /* Table has a primary key */
|
||||
#define TF_Autoincrement 0x08 /* Integer primary key is autoincrement */
|
||||
/* available for reuse: 0x10 */
|
||||
#define TF_WithoutRowid 0x20 /* No rowid. PRIMARY KEY is the key */
|
||||
#define TF_NoVisibleRowid 0x40 /* No user-visible "rowid" column */
|
||||
#define TF_OOOHidden 0x80 /* Out-of-Order hidden columns */
|
||||
#define TF_Readonly 0x0001 /* Read-only system table */
|
||||
#define TF_Ephemeral 0x0002 /* An ephemeral table */
|
||||
#define TF_HasPrimaryKey 0x0004 /* Table has a primary key */
|
||||
#define TF_Autoincrement 0x0008 /* Integer primary key is autoincrement */
|
||||
/* available for reuse: 0x0010 */
|
||||
#define TF_WithoutRowid 0x0020 /* No rowid. PRIMARY KEY is the key */
|
||||
#define TF_NoVisibleRowid 0x0040 /* No user-visible "rowid" column */
|
||||
#define TF_OOOHidden 0x0080 /* Out-of-Order hidden columns */
|
||||
#define TF_HasNotNull 0x0100 /* Contains NOT NULL constraints */
|
||||
|
||||
|
||||
/*
|
||||
|
||||
+10
-10
@@ -1669,21 +1669,21 @@ case OP_Function: {
|
||||
for(i=pCtx->argc-1; i>=0; i--) pCtx->argv[i] = &aMem[pOp->p2+i];
|
||||
}
|
||||
|
||||
memAboutToChange(p, pCtx->pOut);
|
||||
memAboutToChange(p, pOut);
|
||||
#ifdef SQLITE_DEBUG
|
||||
for(i=0; i<pCtx->argc; i++){
|
||||
assert( memIsValid(pCtx->argv[i]) );
|
||||
REGISTER_TRACE(pOp->p2+i, pCtx->argv[i]);
|
||||
}
|
||||
#endif
|
||||
MemSetTypeFlag(pCtx->pOut, MEM_Null);
|
||||
MemSetTypeFlag(pOut, MEM_Null);
|
||||
pCtx->fErrorOrAux = 0;
|
||||
(*pCtx->pFunc->xSFunc)(pCtx, pCtx->argc, pCtx->argv);/* IMP: R-24505-23230 */
|
||||
|
||||
/* If the function returned an error, throw an exception */
|
||||
if( pCtx->fErrorOrAux ){
|
||||
if( pCtx->isError ){
|
||||
sqlite3VdbeError(p, "%s", sqlite3_value_text(pCtx->pOut));
|
||||
sqlite3VdbeError(p, "%s", sqlite3_value_text(pOut));
|
||||
rc = pCtx->isError;
|
||||
}
|
||||
sqlite3VdbeDeleteAuxData(db, &p->pAuxData, pCtx->iOp, pOp->p1);
|
||||
@@ -1692,12 +1692,12 @@ case OP_Function: {
|
||||
|
||||
/* Copy the result of the function into register P3 */
|
||||
if( pOut->flags & (MEM_Str|MEM_Blob) ){
|
||||
sqlite3VdbeChangeEncoding(pCtx->pOut, encoding);
|
||||
if( sqlite3VdbeMemTooBig(pCtx->pOut) ) goto too_big;
|
||||
sqlite3VdbeChangeEncoding(pOut, encoding);
|
||||
if( sqlite3VdbeMemTooBig(pOut) ) goto too_big;
|
||||
}
|
||||
|
||||
REGISTER_TRACE(pOp->p3, pCtx->pOut);
|
||||
UPDATE_MAX_BLOBSIZE(pCtx->pOut);
|
||||
REGISTER_TRACE(pOp->p3, pOut);
|
||||
UPDATE_MAX_BLOBSIZE(pOut);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -5611,7 +5611,7 @@ case OP_DropTrigger: {
|
||||
** register P1 the text of an error message describing any problems.
|
||||
** If no problems are found, store a NULL in register P1.
|
||||
**
|
||||
** The register P3 contains the maximum number of allowed errors.
|
||||
** The register P3 contains one less than the maximum number of allowed errors.
|
||||
** At most reg(P3) errors will be reported.
|
||||
** In other words, the analysis stops as soon as reg(P1) errors are
|
||||
** seen. Reg(P1) is updated with the number of errors remaining.
|
||||
@@ -5644,14 +5644,14 @@ case OP_IntegrityCk: {
|
||||
assert( pOp->p5<db->nDb );
|
||||
assert( DbMaskTest(p->btreeMask, pOp->p5) );
|
||||
z = sqlite3BtreeIntegrityCheck(db->aDb[pOp->p5].pBt, aRoot, nRoot,
|
||||
(int)pnErr->u.i, &nErr);
|
||||
pnErr->u.i -= nErr;
|
||||
(int)pnErr->u.i+1, &nErr);
|
||||
sqlite3VdbeMemSetNull(pIn1);
|
||||
if( nErr==0 ){
|
||||
assert( z==0 );
|
||||
}else if( z==0 ){
|
||||
goto no_mem;
|
||||
}else{
|
||||
pnErr->u.i -= nErr-1;
|
||||
sqlite3VdbeMemSetStr(pIn1, z, -1, SQLITE_UTF8, sqlite3_free);
|
||||
}
|
||||
UPDATE_MAX_BLOBSIZE(pIn1);
|
||||
|
||||
+8
-6
@@ -154,7 +154,8 @@ int sqlite3_clear_bindings(sqlite3_stmt *pStmt){
|
||||
sqlite3VdbeMemRelease(&p->aVar[i]);
|
||||
p->aVar[i].flags = MEM_Null;
|
||||
}
|
||||
if( p->isPrepareV2 && p->expmask ){
|
||||
assert( p->isPrepareV2 || p->expmask==0 );
|
||||
if( p->expmask ){
|
||||
p->expired = 1;
|
||||
}
|
||||
sqlite3_mutex_leave(mutex);
|
||||
@@ -1258,9 +1259,8 @@ static int vdbeUnbind(Vdbe *p, int i){
|
||||
** as if there had been a schema change, on the first sqlite3_step() call
|
||||
** following any change to the bindings of that parameter.
|
||||
*/
|
||||
if( p->isPrepareV2 &&
|
||||
((i<32 && p->expmask & ((u32)1 << i)) || p->expmask==0xffffffff)
|
||||
){
|
||||
assert( p->isPrepareV2 || p->expmask==0 );
|
||||
if( p->expmask & ((u32)1 << (i&0x001F)) && (i<32 || p->expmask==0xffffffff) ){
|
||||
p->expired = 1;
|
||||
}
|
||||
return SQLITE_OK;
|
||||
@@ -1523,10 +1523,12 @@ int sqlite3_transfer_bindings(sqlite3_stmt *pFromStmt, sqlite3_stmt *pToStmt){
|
||||
if( pFrom->nVar!=pTo->nVar ){
|
||||
return SQLITE_ERROR;
|
||||
}
|
||||
if( pTo->isPrepareV2 && pTo->expmask ){
|
||||
assert( pTo->isPrepareV2 || pTo->expmask==0 );
|
||||
if( pTo->expmask ){
|
||||
pTo->expired = 1;
|
||||
}
|
||||
if( pFrom->isPrepareV2 && pFrom->expmask ){
|
||||
assert( pFrom->isPrepareV2 || pFrom->expmask==0 );
|
||||
if( pFrom->expmask ){
|
||||
pFrom->expired = 1;
|
||||
}
|
||||
return sqlite3TransferBindings(pFromStmt, pToStmt);
|
||||
|
||||
+4
-3
@@ -57,6 +57,7 @@ void sqlite3VdbeError(Vdbe *p, const char *zFormat, ...){
|
||||
void sqlite3VdbeSetSql(Vdbe *p, const char *z, int n, int isPrepareV2){
|
||||
assert( isPrepareV2==1 || isPrepareV2==0 );
|
||||
if( p==0 ) return;
|
||||
if( !isPrepareV2 ) p->expmask = 0;
|
||||
#if defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_ENABLE_SQLLOG)
|
||||
if( !isPrepareV2 ) return;
|
||||
#endif
|
||||
@@ -2609,13 +2610,13 @@ int sqlite3VdbeHalt(Vdbe *p){
|
||||
** one, or the complete transaction if there is no statement transaction.
|
||||
*/
|
||||
|
||||
if( p->magic!=VDBE_MAGIC_RUN ){
|
||||
return SQLITE_OK;
|
||||
}
|
||||
if( db->mallocFailed ){
|
||||
p->rc = SQLITE_NOMEM_BKPT;
|
||||
}
|
||||
closeAllCursors(p);
|
||||
if( p->magic!=VDBE_MAGIC_RUN ){
|
||||
return SQLITE_OK;
|
||||
}
|
||||
checkActiveVdbeCnt(db);
|
||||
|
||||
/* No commit or rollback needed if the program never started or if the
|
||||
|
||||
+6
-2
@@ -309,11 +309,15 @@ do_test check-4.8 {
|
||||
PRAGMA ignore_check_constraints=ON;
|
||||
UPDATE t4 SET x=0, y=1;
|
||||
SELECT * FROM t4;
|
||||
PRAGMA integrity_check;
|
||||
}
|
||||
} {0 1}
|
||||
} {0 1 ok}
|
||||
do_execsql_test check-4.8.1 {
|
||||
PRAGMA ignore_check_constraints=OFF;
|
||||
PRAGMA integrity_check;
|
||||
} {{CHECK constraint failed in t4}}
|
||||
do_test check-4.9 {
|
||||
catchsql {
|
||||
PRAGMA ignore_check_constraints=OFF;
|
||||
UPDATE t4 SET x=0, y=2;
|
||||
}
|
||||
} {1 {CHECK constraint failed: t4}}
|
||||
|
||||
Reference in New Issue
Block a user