Merged in trunk for pending tree refactoring.
FossilOrigin-Name: c3a3cb0103126210692bbeb703e7b8793974042e1fc2473be6d0a0d9b07d5770
This commit is contained in:
+1
-1
@@ -4376,7 +4376,7 @@ static int fts3EvalDeferredPhrase(Fts3Cursor *pCsr, Fts3Phrase *pPhrase){
|
||||
nDistance = iPrev - nMaxUndeferred;
|
||||
}
|
||||
|
||||
aOut = (char *)sqlite3_malloc(nPoslist+8);
|
||||
aOut = (char *)sqlite3Fts3MallocZero(nPoslist+FTS3_BUFFER_PADDING);
|
||||
if( !aOut ){
|
||||
sqlite3_free(aPoslist);
|
||||
return SQLITE_NOMEM;
|
||||
|
||||
+1
-1
@@ -286,7 +286,7 @@ void sqlite3Fts5BufferAppendPrintf(int *, Fts5Buffer*, char *zFmt, ...);
|
||||
char *sqlite3Fts5Mprintf(int *pRc, const char *zFmt, ...);
|
||||
|
||||
#define fts5BufferZero(x) sqlite3Fts5BufferZero(x)
|
||||
#define fts5BufferAppendVarint(a,b,c) sqlite3Fts5BufferAppendVarint(a,b,c)
|
||||
#define fts5BufferAppendVarint(a,b,c) sqlite3Fts5BufferAppendVarint(a,b,(i64)c)
|
||||
#define fts5BufferFree(a) sqlite3Fts5BufferFree(a)
|
||||
#define fts5BufferAppendBlob(a,b,c,d) sqlite3Fts5BufferAppendBlob(a,b,c,d)
|
||||
#define fts5BufferSet(a,b,c,d) sqlite3Fts5BufferSet(a,b,c,d)
|
||||
|
||||
+12
-10
@@ -4087,7 +4087,9 @@ static void fts5WriteAppendRowid(
|
||||
fts5BufferAppendVarint(&p->rc, &pPage->buf, iRowid);
|
||||
}else{
|
||||
assert_nc( p->rc || iRowid>pWriter->iPrevRowid );
|
||||
fts5BufferAppendVarint(&p->rc, &pPage->buf, iRowid - pWriter->iPrevRowid);
|
||||
fts5BufferAppendVarint(&p->rc, &pPage->buf,
|
||||
(u64)iRowid - (u64)pWriter->iPrevRowid
|
||||
);
|
||||
}
|
||||
pWriter->iPrevRowid = iRowid;
|
||||
pWriter->bFirstRowidInDoclist = 0;
|
||||
@@ -4851,7 +4853,7 @@ int sqlite3Fts5IndexMerge(Fts5Index *p, int nMerge){
|
||||
|
||||
static void fts5AppendRowid(
|
||||
Fts5Index *p,
|
||||
i64 iDelta,
|
||||
u64 iDelta,
|
||||
Fts5Iter *pUnused,
|
||||
Fts5Buffer *pBuf
|
||||
){
|
||||
@@ -4861,7 +4863,7 @@ static void fts5AppendRowid(
|
||||
|
||||
static void fts5AppendPoslist(
|
||||
Fts5Index *p,
|
||||
i64 iDelta,
|
||||
u64 iDelta,
|
||||
Fts5Iter *pMulti,
|
||||
Fts5Buffer *pBuf
|
||||
){
|
||||
@@ -4936,10 +4938,10 @@ static void fts5MergeAppendDocid(
|
||||
}
|
||||
#endif
|
||||
|
||||
#define fts5MergeAppendDocid(pBuf, iLastRowid, iRowid) { \
|
||||
assert( (pBuf)->n!=0 || (iLastRowid)==0 ); \
|
||||
fts5BufferSafeAppendVarint((pBuf), (iRowid) - (iLastRowid)); \
|
||||
(iLastRowid) = (iRowid); \
|
||||
#define fts5MergeAppendDocid(pBuf, iLastRowid, iRowid) { \
|
||||
assert( (pBuf)->n!=0 || (iLastRowid)==0 ); \
|
||||
fts5BufferSafeAppendVarint((pBuf), (u64)(iRowid) - (u64)(iLastRowid)); \
|
||||
(iLastRowid) = (iRowid); \
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -5210,7 +5212,7 @@ static void fts5SetupPrefixIter(
|
||||
int nMerge = 1;
|
||||
|
||||
void (*xMerge)(Fts5Index*, Fts5Buffer*, int, Fts5Buffer*);
|
||||
void (*xAppend)(Fts5Index*, i64, Fts5Iter*, Fts5Buffer*);
|
||||
void (*xAppend)(Fts5Index*, u64, Fts5Iter*, Fts5Buffer*);
|
||||
if( p->pConfig->eDetail==FTS5_DETAIL_NONE ){
|
||||
xMerge = fts5MergeRowidLists;
|
||||
xAppend = fts5AppendRowid;
|
||||
@@ -5249,7 +5251,7 @@ static void fts5SetupPrefixIter(
|
||||
Fts5SegIter *pSeg = &p1->aSeg[ p1->aFirst[1].iFirst ];
|
||||
p1->xSetOutputs(p1, pSeg);
|
||||
if( p1->base.nData ){
|
||||
xAppend(p, p1->base.iRowid-iLastRowid, p1, &doclist);
|
||||
xAppend(p, (u64)p1->base.iRowid-(u64)iLastRowid, p1, &doclist);
|
||||
iLastRowid = p1->base.iRowid;
|
||||
}
|
||||
}
|
||||
@@ -5297,7 +5299,7 @@ static void fts5SetupPrefixIter(
|
||||
iLastRowid = 0;
|
||||
}
|
||||
|
||||
xAppend(p, p1->base.iRowid-iLastRowid, p1, &doclist);
|
||||
xAppend(p, (u64)p1->base.iRowid-(u64)iLastRowid, p1, &doclist);
|
||||
iLastRowid = p1->base.iRowid;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
# 2022 August 9
|
||||
#
|
||||
# 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 test is focused on edge cases that cause ubsan errors.
|
||||
#
|
||||
|
||||
source [file join [file dirname [info script]] fts5_common.tcl]
|
||||
set testprefix fts5ubsan
|
||||
|
||||
# If SQLITE_ENABLE_FTS5 is defined, omit this file.
|
||||
ifcapable !fts5 {
|
||||
finish_test
|
||||
return
|
||||
}
|
||||
|
||||
do_execsql_test 1.0 {
|
||||
CREATE VIRTUAL TABLE x1 USING fts5(x);
|
||||
}
|
||||
|
||||
set BIG 9000000000000000000
|
||||
set SMALL -9000000000000000000
|
||||
|
||||
do_execsql_test 1.1 {
|
||||
BEGIN;
|
||||
INSERT INTO x1 (rowid, x) VALUES($BIG, 'aaa aba acc');
|
||||
INSERT INTO x1 (rowid, x) VALUES($SMALL, 'aaa abc acb');
|
||||
COMMIT;
|
||||
}
|
||||
|
||||
do_execsql_test 1.2 {
|
||||
SELECT rowid, x FROM x1('ab*');
|
||||
} [list $SMALL {aaa abc acb} $BIG {aaa aba acc}]
|
||||
|
||||
do_execsql_test 1.3 {
|
||||
SELECT rowid, x FROM x1('ac*');
|
||||
} [list $SMALL {aaa abc acb} $BIG {aaa aba acc}]
|
||||
|
||||
reset_db
|
||||
do_execsql_test 2.0 {
|
||||
CREATE VIRTUAL TABLE x1 USING fts5(x);
|
||||
}
|
||||
|
||||
do_execsql_test 2.1 {
|
||||
INSERT INTO x1 (rowid, x) VALUES($BIG, 'aaa aba acc');
|
||||
INSERT INTO x1 (rowid, x) VALUES($SMALL, 'aaa abc acb');
|
||||
}
|
||||
|
||||
do_execsql_test 2.2 {
|
||||
INSERT INTO x1 (x1) VALUES('optimize');
|
||||
}
|
||||
|
||||
finish_test
|
||||
+1
-1
@@ -825,7 +825,7 @@ static void re_bytecode_func(
|
||||
}
|
||||
sqlite3_str_appendf(pStr, "\n");
|
||||
}
|
||||
for(i=0; i<pRe->nState; i++){
|
||||
for(i=0; (unsigned)i<pRe->nState; i++){
|
||||
sqlite3_str_appendf(pStr, "%-8s %4d\n",
|
||||
ReOpName[(unsigned char)pRe->aOp[i]], pRe->aArg[i]);
|
||||
}
|
||||
|
||||
+1
-1
@@ -1695,7 +1695,7 @@ static int geopolyUpdate(
|
||||
sqlite3_free(p);
|
||||
nChange = 1;
|
||||
}
|
||||
for(jj=1; jj<pRtree->nAux; jj++){
|
||||
for(jj=1; jj<nData-2; jj++){
|
||||
nChange++;
|
||||
sqlite3_bind_value(pUp, jj+2, aData[jj+2]);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
C Merged\sin\strunk.
|
||||
D 2022-07-20T10:09:19.404
|
||||
C Merged\sin\strunk\sfor\spending\stree\srefactoring.
|
||||
D 2022-08-10T07:58:57.865
|
||||
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
|
||||
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
|
||||
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
|
||||
@@ -103,7 +103,7 @@ F ext/fts3/README.content b9078d0843a094d86af0d48dffbff13c906702b4c3558012e67b9c
|
||||
F ext/fts3/README.syntax a19711dc5458c20734b8e485e75fb1981ec2427a
|
||||
F ext/fts3/README.tokenizers b92bdeb8b46503f0dd301d364efc5ef59ef9fa8e2758b8e742f39fa93a2e422d
|
||||
F ext/fts3/README.txt 8c18f41574404623b76917b9da66fcb0ab38328d
|
||||
F ext/fts3/fts3.c 8cd361bd8612de3e5ec451d33ced8575cbc5af6744e7efc05d54bde4d2df3cd0
|
||||
F ext/fts3/fts3.c b20bd583991e740c1e14371896f3ab61d7b6c033740646366bbf6667191bc4e2
|
||||
F ext/fts3/fts3.h 3a10a0af180d502cecc50df77b1b22df142817fe
|
||||
F ext/fts3/fts3Int.h dafdc371f9fbab175744b06cfe019d5f040cdfdbd11fea752f5dc28d45b04c05
|
||||
F ext/fts3/fts3_aux.c f0dc9bd98582615b7750218899bd0c729879b6bbf94d1be57ca1833ff49afc6f
|
||||
@@ -131,13 +131,13 @@ F ext/fts3/unicode/mkunicode.tcl d5aebf022fa4577ee8cdf27468f0d847879993959101f6d
|
||||
F ext/fts3/unicode/parseunicode.tcl a981bd6466d12dd17967515801c3ff23f74a281be1a03cf1e6f52a6959fc77eb
|
||||
F ext/fts5/extract_api_docs.tcl a36e54ec777172ddd3f9a88daf593b00848368e0
|
||||
F ext/fts5/fts5.h c132a9323f22a972c4c93a8d5a3d901113a6e612faf30ca8e695788438c5ca2a
|
||||
F ext/fts5/fts5Int.h 36fd4a05e6e6307e3bac359a589d5f090b903afe0e7ae15db84f0ff90c79676a
|
||||
F ext/fts5/fts5Int.h c0d46e399e345e35985b72a1c1af025973bfaa5b1e3563b0ce3bb0ce144a7ca3
|
||||
F ext/fts5/fts5_aux.c f558e1fb9f0f86a4f7489e258c162e1f947de5ff2709087fbb465fddb7092f98
|
||||
F ext/fts5/fts5_buffer.c 3001fbabb585d6de52947b44b455235072b741038391f830d6b729225eeaf6a5
|
||||
F ext/fts5/fts5_config.c 501e7d3566bc92766b0e11c0109a7c5a6146bc41144195459af5422f6c2078aa
|
||||
F ext/fts5/fts5_expr.c 40174a64829d30cc86e8266306ad24980f6911edd5ca0b8c1ce7821ea1341b88
|
||||
F ext/fts5/fts5_hash.c d4fb70940359f2120ccd1de7ffe64cc3efe65de9e8995b822cd536ff64c96982
|
||||
F ext/fts5/fts5_index.c 3e47d9c56e4e9a6dee78bc32e006d6a28a3b5ec9ff84f3b8c381c78323201720
|
||||
F ext/fts5/fts5_index.c 4b1ac44c665667be970df780bd8e734748047bd30a971d0bb7e884af8ac6e62c
|
||||
F ext/fts5/fts5_main.c 6078ae86d3b813753a4f1201054550aff21a3f660e97b30f200d2b1472874151
|
||||
F ext/fts5/fts5_storage.c 76c6085239eb44424004c022e9da17a5ecd5aaec859fba90ad47d3b08f4c8082
|
||||
F ext/fts5/fts5_tcl.c b1445cbe69908c411df8084a10b2485500ac70a9c747cdc8cda175a3da59d8ae
|
||||
@@ -240,6 +240,7 @@ F ext/fts5/test/fts5tok1.test 1f7817499f5971450d8c4a652114b3d833393c8134e32422d0
|
||||
F ext/fts5/test/fts5tok2.test dcacb32d4a2a3f0dd3215d4a3987f78ae4be21a2
|
||||
F ext/fts5/test/fts5tokenizer.test ac3c9112b263a639fb0508ae73a3ee886bf4866d2153771a8e8a20c721305a43
|
||||
F ext/fts5/test/fts5trigram.test 5b4feb53a4d5aca70c841f6919c8719b5a9c805474727dda99285fccdd2e9cce
|
||||
F ext/fts5/test/fts5ubsan.test 783d5a8d13ebfa169e634940228db54540780e3ba7a87ad1e4510e61440bf64b
|
||||
F ext/fts5/test/fts5umlaut.test a42fe2fe6387c40c49ab27ccbd070e1ae38e07f38d05926482cc0bccac9ad602
|
||||
F ext/fts5/test/fts5unicode.test 17056f4efe6b0a5d4f41fdf7a7dc9af2873004562eaa899d40633b93dc95f5a9
|
||||
F ext/fts5/test/fts5unicode2.test 9b3df486de05fb4bde4aa7ee8de2e6dae1df6eb90e3f2e242c9383b95d314e3e
|
||||
@@ -335,7 +336,7 @@ F ext/misc/normalize.c bd84355c118e297522aba74de34a4fd286fc775524e0499b14473918d
|
||||
F ext/misc/percentile.c b9086e223d583bdaf8cb73c98a6539d501a2fc4282654adbfea576453d82e691
|
||||
F ext/misc/prefixes.c 0f4f8cff5aebc00a7e3ac4021fd59cfe1a8e17c800ceaf592859ecb9cbc38196
|
||||
F ext/misc/qpvtab.c 09738419e25f603a35c0ac8bd0a04daab794f48d08a9bc07a6085b9057b99009
|
||||
F ext/misc/regexp.c 1459fe1452b61aafb25b11d7144f3dabfaf890b566c4ef9cfa4dc270451a8f02
|
||||
F ext/misc/regexp.c 5abed0ace2d9340b42b9ab1dbe64db9c276e4e8eba38a903232b6253e05ccdaf
|
||||
F ext/misc/remember.c add730f0f7e7436cd15ea3fd6a90fd83c3f706ab44169f7f048438b7d6baa69c
|
||||
F ext/misc/rot13.c 51ac5f51e9d5fd811db58a9c23c628ad5f333c173f1fc53c8491a3603d38556c
|
||||
F ext/misc/scrub.c 2a44b0d44c69584c0580ad2553f6290a307a49df4668941d2812135bfb96a946
|
||||
@@ -414,7 +415,7 @@ F ext/repair/test/checkfreelist01.test 3e8aa6aeb4007680c94a8d07b41c339aa635cc782
|
||||
F ext/repair/test/checkindex01.test b530f141413b587c9eb78ff734de6bb79bc3515c335096108c12c01bddbadcec
|
||||
F ext/repair/test/test.tcl 686d76d888dffd021f64260abf29a55c57b2cedfa7fc69150b42b1d6119aac3c
|
||||
F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761
|
||||
F ext/rtree/geopoly.c cc3f89c11abcf114fa60d74709ae8b5bc1eae5a261b30bc1bb7085089c03bfab
|
||||
F ext/rtree/geopoly.c bb0dcd013dbb3fe0335b6bbae0d9c29fcfffda93d5ef6c31daa47e802132e435
|
||||
F ext/rtree/rtree.c d7b4b8b81d8d54376a7f81de5be85ec58b37c11604bcf42984a8418b34158d93
|
||||
F ext/rtree/rtree.h 4a690463901cb5e6127cf05eb8e642f127012fd5003830dbc974eca5802d9412
|
||||
F ext/rtree/rtree1.test d47f58832145fcfed9067bc457ca8664962196c4566c17a1ebd679367db55d11
|
||||
@@ -511,18 +512,18 @@ F src/auth.c f4fa91b6a90bbc8e0d0f738aa284551739c9543a367071f55574681e0f24f8cf
|
||||
F src/backup.c a2891172438e385fdbe97c11c9745676bec54f518d4447090af97189fd8e52d7
|
||||
F src/bitvec.c 7c849aac407230278445cb069bebc5f89bf2ddd87c5ed9459b070a9175707b3d
|
||||
F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6
|
||||
F src/btree.c 1307d57f65023c9f37c2b6c62253343fca63877f161f694a593b14c0883cedda
|
||||
F src/btree.c 4a8d349b9ed4dc6d252c535227699d75319b633058a56432ebf43c9f56f9085e
|
||||
F src/btree.h 74d64b8f28cfa4a894d14d4ed64fa432cd697b98b61708d4351482ae15913e22
|
||||
F src/btreeInt.h 8ce1332edd89dfd2461d561ac10a0ab5601c8e06200cb5230596c3caaf54482e
|
||||
F src/build.c 29fcc97af5197511788a571ed35a001eea472cbe3bcdbae88178e17fcafd4341
|
||||
F src/build.c 1e96f35d5912a1606c9c9463dfd8eaffc76b2bc01207ee372cb3249eef5173c4
|
||||
F src/callback.c 4c19af69835787bfe790ac560f3071a824eb629f34e41f97b52ce5235c77de1c
|
||||
F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e
|
||||
F src/ctime.c 026dbdcdbd8c3cde98a88483ee88310ff43150ab164ad768f12cc700a11495ad
|
||||
F src/date.c 272162554168e7af4976213850e1c4c5f33b964d299ceb0983f3d5cceba01d05
|
||||
F src/ctime.c 93e4b5f4faf6d3f688988a116773259a4fbfb4ddac0e9bf9d0ae0429390c2543
|
||||
F src/date.c 94ce83b4cd848a387680a5f920c9018c16655db778c4d36525af0a0f34679ac5
|
||||
F src/dbpage.c 5808e91bc27fa3981b028000f8fadfdc10ce9e59a34ce7dc4e035a69be3906ec
|
||||
F src/dbstat.c 861e08690fcb0f2ee1165eff0060ea8d4f3e2ea10f80dab7d32ad70443a6ff2d
|
||||
F src/delete.c a8e844af211a48b13b5b358be77a12c860c6a557c21990ad51a548e2536500ce
|
||||
F src/expr.c 4907afcb86d72b5525d8767515ce425ec53c7a2d3664441b46cef5b376ee0cba
|
||||
F src/delete.c 13eca2beee5b758ed033a11230971310cc4a58fcd8f6bc33cad4f677c985e96c
|
||||
F src/expr.c 0f72468b64eef40c280fd6b273c19f3b221444b00f535c7ba6f34faa657e63da
|
||||
F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007
|
||||
F src/fkey.c d965ede15d8360c09ed59348940649ee647b192e784466837d7aefa836d1d91e
|
||||
F src/func.c 8f72e88cccdee22185133c10f96ccd61dc34c5ea4b1fa9a73c237ef59b2e64f1
|
||||
@@ -531,7 +532,7 @@ F src/hash.c 8d7dda241d0ebdafb6ffdeda3149a412d7df75102cecfc1021c98d6219823b19
|
||||
F src/hash.h 3340ab6e1d13e725571d7cee6d3e3135f0779a7d8e76a9ce0a85971fa3953c51
|
||||
F src/hwtime.h cb1d7e3e1ed94b7aa6fde95ae2c2daccc3df826be26fc9ed7fd90d1750ae6144
|
||||
F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71
|
||||
F src/insert.c 173845e5a6bac96ae937409e4f876b631f26b31dabb9df8fd0eb3b130b2bb3a7
|
||||
F src/insert.c a8c994e3c3b8b08f61745bedabdf5affc79584a2b3c80ee2e4f038817838bd0a
|
||||
F src/json.c 7749b98c62f691697c7ee536b570c744c0583cab4a89200fdd0fc2aa8cc8cbd6
|
||||
F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa
|
||||
F src/loadext.c 853385cc7a604157e137585097949252d5d0c731768e16b044608e5c95c3614b
|
||||
@@ -563,20 +564,20 @@ F src/pager.h f82e9844166e1585f5786837ddc7709966138ced17f568c16af7ccf946c2baa3
|
||||
F src/parse.y 8e67d820030d2655b9942ffe61c1e7e6b96cea2f2f72183533299393907d0564
|
||||
F src/pcache.c 084e638432c610f95aea72b8509f0845d2791293f39d1b82f0c0a7e089c3bb6b
|
||||
F src/pcache.h 4f87acd914cef5016fae3030343540d75f5b85a1877eed1a2a19b9f284248586
|
||||
F src/pcache1.c 54881292a9a5db202b2c0ac541c5e3ef9a5e8c4f1c1383adb2601d5499a60e65
|
||||
F src/pragma.c d1aead03e8418ff586c7cfca344c50a914b8eb06abd841e8e91a982d823671da
|
||||
F src/pcache1.c 0b4245cd4964e635f2630908c2533cd8e9da7af3ca592e23ae8730aa25ae5eb9
|
||||
F src/pragma.c 6637d624c37a8909d3edfa9d7cf694d79b49d2a0827d8c52ef15dceb641783fa
|
||||
F src/pragma.h e690a356c18e98414d2e870ea791c1be1545a714ba623719deb63f7f226d8bb7
|
||||
F src/prepare.c c62820c15dcb63013519c8e41d9f928d7478672cc902cfd0581c733c271dbf45
|
||||
F src/printf.c e99ee9741e79ae3873458146f59644276657340385ade4e76a5f5d1c25793764
|
||||
F src/random.c 097dc8b31b8fba5a9aca1697aeb9fd82078ec91be734c16bffda620ced7ab83c
|
||||
F src/resolve.c 84a8443e3723e908730d754f54df4e1dacc1eb7073c0bd79c9d5efe977a9f5b9
|
||||
F src/resolve.c efea4e5fbecfd6d0a9071b0be0d952620991673391b6ffaaf4c277b0bb674633
|
||||
F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92
|
||||
F src/select.c 45b93eee3c349f46240ddc14344365bbf34579ec332bd4c7bc061945e38172e2
|
||||
F src/select.c 4750fbe9d8ecb7236baf7a9bea4299bb87126e08c209645666a0ae8f0efbe0fc
|
||||
F src/shell.c.in 29749b34bbd19d0004fdb6f61f62659096e1c0b4dfb1ad2314e7fafbe9dd8d37
|
||||
F src/sqlite.h.in 01573eae96721f2a8ee2a9e3b7140ceeba2e9c44350911890b89b8ff0dcf6781
|
||||
F src/sqlite.h.in be265991edca9aea69986758b58ba81cbf5ae403fe0c4ea1d0c9df0cdc8f25ed
|
||||
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
|
||||
F src/sqlite3ext.h a988810c9b21c0dc36dc7a62735012339dc76fc7ab448fb0792721d30eacb69d
|
||||
F src/sqliteInt.h 059d5a017ebf488c7484f79ea507f56b2bf4bb700f340abf91c5d2227869f275
|
||||
F src/sqliteInt.h 3ae1d20f579149c18ddd995bbeffabf036cad9f4359dc2f27dc1b778d108ff35
|
||||
F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a31657
|
||||
F src/status.c 4a3da6d77eeb3531cb0dbdf7047772a2a1b99f98c69e90ce009c75fe6328b2c0
|
||||
F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1
|
||||
@@ -643,13 +644,13 @@ F src/upsert.c 8789047a8f0a601ea42fa0256d1ba3190c13746b6ba940fe2d25643a7e991937
|
||||
F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0
|
||||
F src/util.c 602fe229f32a96ceccae4f40824129669582096f7c355f53dbac156c9fecef23
|
||||
F src/vacuum.c bb346170b0b54c6683bba4a5983aea40485597fdf605c87ec8bc2e199fe88cd8
|
||||
F src/vdbe.c 1266f3a4744224253dd74f0080014be8056b062c6f2f6a81e229fa0d306d4102
|
||||
F src/vdbe.h 07641758ca8b4f4c6d81ea667ea167c541e6ece21f5574da11e3d21ec37e2662
|
||||
F src/vdbe.c 81e2febe73f3db6d1ce5be29d30c4667d5fab9f6eae892ad7c80808f1af0c2bb
|
||||
F src/vdbe.h 64619af62603dc3c4f5ff6ff6d2c8f389abd667a29ce6007ed44bd22b3211cd0
|
||||
F src/vdbeInt.h 2cad0aeeb106371ed0e0946bab89f60627087068847afc2451c05056961c18da
|
||||
F src/vdbeapi.c d68267db6e6641994e17c70670c40fd67ceb2352e42188815ed8c05d4d6502cb
|
||||
F src/vdbeaux.c 444c399df547e003be52cc51b460fed3b63e1f18939e6b773ff99c584954b726
|
||||
F src/vdbeapi.c 4cfbf7ec3ed60366a38655f3f10316c5a3d68f6d4d06e462f88679392611c756
|
||||
F src/vdbeaux.c 8584f4a20997fd918f0d957ab4f73d7411159772297c5020c188973bdc41dbf0
|
||||
F src/vdbeblob.c 5e61ce31aca17db8fb60395407457a8c1c7fb471dde405e0cd675974611dcfcd
|
||||
F src/vdbemem.c 5ebf05c0182addedb1607ade848e1c83cef40981df94d1abfab0c59288c6064f
|
||||
F src/vdbemem.c c3ce80af15e2ff5c2824a8db881681cbf511376f13613da020bac6d320c535b1
|
||||
F src/vdbesort.c 43756031ca7430f7aec3ef904824a7883c4ede783e51f280d99b9b65c0796e35
|
||||
F src/vdbetrace.c fe0bc29ebd4e02c8bc5c1945f1d2e6be5927ec12c06d89b03ef2a4def34bf823
|
||||
F src/vdbevtab.c f99b275366c5fc5e2d99f734729880994ab9500bdafde7fae3b02d562b9d323c
|
||||
@@ -658,11 +659,11 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9
|
||||
F src/wal.c b9df133a705093da8977da5eb202eaadb844839f1c7297c08d33471f5491843d
|
||||
F src/wal.h c3aa7825bfa2fe0d85bef2db94655f99870a285778baa36307c0a16da32b226a
|
||||
F src/walker.c f890a3298418d7cba3b69b8803594fdc484ea241206a8dfa99db6dd36f8cbb3b
|
||||
F src/where.c 1049685e84bd74692ad76984a3411a21c5a1e6ddd08c981ec94d2f11f769e07f
|
||||
F src/where.c 8bfe41220558a03be393d064ef3d942cd1ceaf57cd88a85b6cb59b7dda555202
|
||||
F src/whereInt.h b48ca529ffe293c18cbfa8326af18a09e39910de66fb3e96ef788c7cbf8ef3a7
|
||||
F src/wherecode.c 0b09abfcb88c61c6a6984a3e065786631ff35495e9bdf865e6b74ab0a1299c5b
|
||||
F src/wherecode.c 719a5bb0102711a6ebed8d4385b831a27ce679172f3ae8e9aaec0dc1e415a95a
|
||||
F src/whereexpr.c 55a39f42aaf982574fbf52906371a84cceed98a994422198dfd03db4fce4cc46
|
||||
F src/window.c fff1b51757438c664e471d5184634e48dcdf8ea34b640f3b1b0810b1e06de18c
|
||||
F src/window.c 928e215840e2f2d9a2746e018c9643ef42c66c4ab6630ef0df7fa388fa145e86
|
||||
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
|
||||
F test/affinity2.test ce1aafc86e110685b324e9a763eab4f2a73f737842ec3b687bd965867de90627
|
||||
F test/affinity3.test b5c19d504dec222c0dc66642673d23dce915d35737b68e74d9f237b80493eb53
|
||||
@@ -1287,7 +1288,7 @@ F test/null.test b7ff206a1c60fe01aa2abd33ef9ea83c93727d993ca8a613de86e925c9f2bc6
|
||||
F test/nulls1.test 7a5e4346ee4285034100b4cd20e6784f16a9d6c927e44ecdf10034086bbee9c9
|
||||
F test/numcast.test 5d126f7f581432e86a90d1e35cac625164aec4a1
|
||||
F test/numindex1.test 20a5450d4b056e48cd5db30e659f13347a099823
|
||||
F test/offset1.test f06b83657bcf26f9ce805e67450e189e282143b2
|
||||
F test/offset1.test 72cca52482cbd5bc687cfa67aa2566c859081b5a353fd2f9da9bbd3914dea1ef
|
||||
F test/openv2.test 0d3040974bf402e19b7df4b783e447289d7ab394
|
||||
F test/optfuzz-db01.c 9f2fa80b8f84ebbf1f2e8b13421a4e0477fe300f6686fbd76cac1d2db66e0fdc
|
||||
F test/optfuzz-db01.txt 21f6bdeadc701cf11528276e2a55c70bfcb846ba42df327f979bd9e7b6ce7041
|
||||
@@ -1392,7 +1393,7 @@ F test/securedel.test 2f70b2449186a1921bd01ec9da407fbfa98c3a7a5521854c300c194b2f
|
||||
F test/securedel2.test 2d54c28e46eb1fd6902089958b20b1b056c6f1c5
|
||||
F test/select1.test 692e84cfa29c405854c69e8a4027183d64c22952866a123fabbce741a379e889
|
||||
F test/select2.test 352480e0e9c66eda9c3044e412abdf5be0215b56
|
||||
F test/select3.test ce4f78bbc809b0513f960f1ee84cdbc5af50ba112c343d5266558a8b2468f656
|
||||
F test/select3.test 8d04b66df7475275a65f7e4a786d6a724c30bd9929f8ae5bd59c8d3d6e75e6cd
|
||||
F test/select4.test f0684d3da3bccacbe2a1ebadf6fb49d9df6f53acb4c6ebc228a88d0d6054cc7b
|
||||
F test/select5.test 8afc5e5dcdebc2be54472e73ebd9cd1adef1225fd15d37a1c62f969159f390ae
|
||||
F test/select6.test 9b2fb4ffedf52e1b5703cfcae1212e7a4a063f014c0458d78d29aca3db766d1f
|
||||
@@ -1798,7 +1799,7 @@ F test/walprotocol2.test 7d3b6b4bf0b12f8007121b1e6ef714bc99101fb3b48e46371df1db8
|
||||
F test/walro.test cb438d05ba0d191f10b688e39c4f0cd5b71569a1d1f4440e5bdf3c6880e08c20
|
||||
F test/walro2.test 33955a6fd874dd9724005e17f77fef89d334b3171454a1256fe4941a96766cdc
|
||||
F test/walrofault.test c70cb6e308c443867701856cce92ad8288cd99488fa52afab77cca6cfd51af68
|
||||
F test/walsetlk.test c084796fc1d908957eaeba00caf85a575565be17e3333a60d5b72fe75c150387
|
||||
F test/walsetlk.test 34c901443b31ab720afc463f5b236c86ca5c4134402573dce91aa0761de8db5a
|
||||
F test/walshared.test 0befc811dcf0b287efae21612304d15576e35417
|
||||
F test/walslow.test c05c68d4dc2700a982f89133ce103a1a84cc285f
|
||||
F test/walthread.test 14b20fcfa6ae152f5d8e12f5dc8a8a724b7ef189f5d8ef1e2ceab79f2af51747
|
||||
@@ -1909,7 +1910,7 @@ F tool/max-limits.c cbb635fbb37ae4d05f240bfb5b5270bb63c54439
|
||||
F tool/merge-test.tcl de76b62f2de2a92d4c1ca4f976bce0aea6899e0229e250479b229b2a1914b176
|
||||
F tool/mkautoconfamal.sh f62353eb6c06ab264da027fd4507d09914433dbdcab9cb011cdc18016f1ab3b8
|
||||
F tool/mkccode.tcl 86463e68ce9c15d3041610fedd285ce32a5cf7a58fc88b3202b8b76837650dbe x
|
||||
F tool/mkctimec.tcl ac96a74f5e6d9dac672d5229f79c583d3357a50e7d098e473e6b2ce2f8ae1704 x
|
||||
F tool/mkctimec.tcl 8f472681f6041cf0ec26a1799feda39e55370614a6090d66fa5044f9f52d22c6 x
|
||||
F tool/mkkeywordhash.c 35bfc41adacc4aa6ef6fca7fd0c63e0ec0534b78daf4d0cfdebe398216bbffc3
|
||||
F tool/mkmsvcmin.tcl 6ecab9fe22c2c8de4d82d4c46797bda3d2deac8e763885f5a38d0c44a895ab33
|
||||
F tool/mkopcodec.tcl 33d20791e191df43209b77d37f0ff0904620b28465cca6990cf8d60da61a07ef
|
||||
@@ -1982,8 +1983,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
|
||||
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
|
||||
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
||||
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
||||
P 7223f4bb588b6c759754ef26cbefbb172e767eaa80989b8f9ef104d4e8b9d856 e5e9311863544ef30dccd3bd0b3a048a864a650e69cdf9aab13dbe32a4777b51
|
||||
R 54d568f7dd2b6d64e94dfc8d2608eacb
|
||||
P d662796c658997be13fdc3b77ad97101b9513da53fd0b824d7a4050cac3f7eba f963c2523872b59b8a7a14971f703f2eb0d021501b288597a958f6596885d0de
|
||||
R 32a46e2655367bd84dca87f379c92af7
|
||||
U stephan
|
||||
Z 375c5b8cc4c764d044f949cc6f3c9796
|
||||
Z ae9739b616b9feb7c2ad647c284be5e7
|
||||
# Remove this line to create a well-formed Fossil manifest.
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
d662796c658997be13fdc3b77ad97101b9513da53fd0b824d7a4050cac3f7eba
|
||||
c3a3cb0103126210692bbeb703e7b8793974042e1fc2473be6d0a0d9b07d5770
|
||||
+1
-1
@@ -1513,7 +1513,7 @@ static int defragmentPage(MemPage *pPage, int nMaxFrag){
|
||||
assert( pPage->pBt->usableSize <= SQLITE_MAX_PAGE_SIZE );
|
||||
assert( pPage->nOverflow==0 );
|
||||
assert( sqlite3_mutex_held(pPage->pBt->mutex) );
|
||||
src = data = pPage->aData;
|
||||
data = pPage->aData;
|
||||
hdr = pPage->hdrOffset;
|
||||
cellOffset = pPage->cellOffset;
|
||||
nCell = pPage->nCell;
|
||||
|
||||
+67
-68
@@ -140,6 +140,7 @@ int sqlite3DbMaskAllZero(yDbMask m){
|
||||
void sqlite3FinishCoding(Parse *pParse){
|
||||
sqlite3 *db;
|
||||
Vdbe *v;
|
||||
int iDb, i;
|
||||
|
||||
assert( pParse->pToplevel==0 );
|
||||
db = pParse->db;
|
||||
@@ -169,7 +170,6 @@ void sqlite3FinishCoding(Parse *pParse){
|
||||
if( pParse->bReturning ){
|
||||
Returning *pReturning = pParse->u1.pReturning;
|
||||
int addrRewind;
|
||||
int i;
|
||||
int reg;
|
||||
|
||||
if( pReturning->nRetCol ){
|
||||
@@ -206,76 +206,69 @@ void sqlite3FinishCoding(Parse *pParse){
|
||||
** transaction on each used database and to verify the schema cookie
|
||||
** on each used database.
|
||||
*/
|
||||
if( db->mallocFailed==0
|
||||
&& (DbMaskNonZero(pParse->cookieMask) || pParse->pConstExpr)
|
||||
){
|
||||
int iDb, i;
|
||||
assert( sqlite3VdbeGetOp(v, 0)->opcode==OP_Init );
|
||||
sqlite3VdbeJumpHere(v, 0);
|
||||
assert( db->nDb>0 );
|
||||
iDb = 0;
|
||||
do{
|
||||
Schema *pSchema;
|
||||
if( DbMaskTest(pParse->cookieMask, iDb)==0 ) continue;
|
||||
sqlite3VdbeUsesBtree(v, iDb);
|
||||
pSchema = db->aDb[iDb].pSchema;
|
||||
sqlite3VdbeAddOp4Int(v,
|
||||
OP_Transaction, /* Opcode */
|
||||
iDb, /* P1 */
|
||||
DbMaskTest(pParse->writeMask,iDb), /* P2 */
|
||||
pSchema->schema_cookie, /* P3 */
|
||||
pSchema->iGeneration /* P4 */
|
||||
);
|
||||
if( db->init.busy==0 ) sqlite3VdbeChangeP5(v, 1);
|
||||
VdbeComment((v,
|
||||
"usesStmtJournal=%d", pParse->mayAbort && pParse->isMultiWrite));
|
||||
}while( ++iDb<db->nDb );
|
||||
assert( pParse->nErr>0 || sqlite3VdbeGetOp(v, 0)->opcode==OP_Init );
|
||||
sqlite3VdbeJumpHere(v, 0);
|
||||
assert( db->nDb>0 );
|
||||
iDb = 0;
|
||||
do{
|
||||
Schema *pSchema;
|
||||
if( DbMaskTest(pParse->cookieMask, iDb)==0 ) continue;
|
||||
sqlite3VdbeUsesBtree(v, iDb);
|
||||
pSchema = db->aDb[iDb].pSchema;
|
||||
sqlite3VdbeAddOp4Int(v,
|
||||
OP_Transaction, /* Opcode */
|
||||
iDb, /* P1 */
|
||||
DbMaskTest(pParse->writeMask,iDb), /* P2 */
|
||||
pSchema->schema_cookie, /* P3 */
|
||||
pSchema->iGeneration /* P4 */
|
||||
);
|
||||
if( db->init.busy==0 ) sqlite3VdbeChangeP5(v, 1);
|
||||
VdbeComment((v,
|
||||
"usesStmtJournal=%d", pParse->mayAbort && pParse->isMultiWrite));
|
||||
}while( ++iDb<db->nDb );
|
||||
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
||||
for(i=0; i<pParse->nVtabLock; i++){
|
||||
char *vtab = (char *)sqlite3GetVTable(db, pParse->apVtabLock[i]);
|
||||
sqlite3VdbeAddOp4(v, OP_VBegin, 0, 0, 0, vtab, P4_VTAB);
|
||||
}
|
||||
pParse->nVtabLock = 0;
|
||||
for(i=0; i<pParse->nVtabLock; i++){
|
||||
char *vtab = (char *)sqlite3GetVTable(db, pParse->apVtabLock[i]);
|
||||
sqlite3VdbeAddOp4(v, OP_VBegin, 0, 0, 0, vtab, P4_VTAB);
|
||||
}
|
||||
pParse->nVtabLock = 0;
|
||||
#endif
|
||||
|
||||
/* Once all the cookies have been verified and transactions opened,
|
||||
** obtain the required table-locks. This is a no-op unless the
|
||||
** shared-cache feature is enabled.
|
||||
*/
|
||||
codeTableLocks(pParse);
|
||||
/* Once all the cookies have been verified and transactions opened,
|
||||
** obtain the required table-locks. This is a no-op unless the
|
||||
** shared-cache feature is enabled.
|
||||
*/
|
||||
codeTableLocks(pParse);
|
||||
|
||||
/* Initialize any AUTOINCREMENT data structures required.
|
||||
*/
|
||||
sqlite3AutoincrementBegin(pParse);
|
||||
/* Initialize any AUTOINCREMENT data structures required.
|
||||
*/
|
||||
sqlite3AutoincrementBegin(pParse);
|
||||
|
||||
/* Code constant expressions that where factored out of inner loops.
|
||||
**
|
||||
** The pConstExpr list might also contain expressions that we simply
|
||||
** want to keep around until the Parse object is deleted. Such
|
||||
** expressions have iConstExprReg==0. Do not generate code for
|
||||
** those expressions, of course.
|
||||
*/
|
||||
if( pParse->pConstExpr ){
|
||||
ExprList *pEL = pParse->pConstExpr;
|
||||
pParse->okConstFactor = 0;
|
||||
for(i=0; i<pEL->nExpr; i++){
|
||||
int iReg = pEL->a[i].u.iConstExprReg;
|
||||
if( iReg>0 ){
|
||||
sqlite3ExprCode(pParse, pEL->a[i].pExpr, iReg);
|
||||
}
|
||||
}
|
||||
/* Code constant expressions that where factored out of inner loops.
|
||||
**
|
||||
** The pConstExpr list might also contain expressions that we simply
|
||||
** want to keep around until the Parse object is deleted. Such
|
||||
** expressions have iConstExprReg==0. Do not generate code for
|
||||
** those expressions, of course.
|
||||
*/
|
||||
if( pParse->pConstExpr ){
|
||||
ExprList *pEL = pParse->pConstExpr;
|
||||
pParse->okConstFactor = 0;
|
||||
for(i=0; i<pEL->nExpr; i++){
|
||||
int iReg = pEL->a[i].u.iConstExprReg;
|
||||
sqlite3ExprCode(pParse, pEL->a[i].pExpr, iReg);
|
||||
}
|
||||
|
||||
if( pParse->bReturning ){
|
||||
Returning *pRet = pParse->u1.pReturning;
|
||||
if( pRet->nRetCol ){
|
||||
sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pRet->iRetCur, pRet->nRetCol);
|
||||
}
|
||||
}
|
||||
|
||||
/* Finally, jump back to the beginning of the executable code. */
|
||||
sqlite3VdbeGoto(v, 1);
|
||||
}
|
||||
|
||||
if( pParse->bReturning ){
|
||||
Returning *pRet = pParse->u1.pReturning;
|
||||
if( pRet->nRetCol ){
|
||||
sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pRet->iRetCur, pRet->nRetCol);
|
||||
}
|
||||
}
|
||||
|
||||
/* Finally, jump back to the beginning of the executable code. */
|
||||
sqlite3VdbeGoto(v, 1);
|
||||
}
|
||||
|
||||
/* Get the VDBE program ready for execution
|
||||
@@ -3049,7 +3042,7 @@ create_view_fail:
|
||||
** the columns of the view in the pTable structure. Return the number
|
||||
** of errors. If an error is seen leave an error message in pParse->zErrMsg.
|
||||
*/
|
||||
int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){
|
||||
static SQLITE_NOINLINE int viewGetColumnNames(Parse *pParse, Table *pTable){
|
||||
Table *pSelTab; /* A fake table from which we get the result set */
|
||||
Select *pSel; /* Copy of the SELECT that implements the view */
|
||||
int nErr = 0; /* Number of errors encountered */
|
||||
@@ -3074,9 +3067,10 @@ int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){
|
||||
|
||||
#ifndef SQLITE_OMIT_VIEW
|
||||
/* A positive nCol means the columns names for this view are
|
||||
** already known.
|
||||
** already known. This routine is not called unless either the
|
||||
** table is virtual or nCol is zero.
|
||||
*/
|
||||
if( pTable->nCol>0 ) return 0;
|
||||
assert( pTable->nCol<=0 );
|
||||
|
||||
/* A negative nCol is a special marker meaning that we are currently
|
||||
** trying to compute the column names. If we enter this routine with
|
||||
@@ -3172,6 +3166,11 @@ int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){
|
||||
#endif /* SQLITE_OMIT_VIEW */
|
||||
return nErr;
|
||||
}
|
||||
int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){
|
||||
assert( pTable!=0 );
|
||||
if( !IsVirtual(pTable) && pTable->nCol>0 ) return 0;
|
||||
return viewGetColumnNames(pParse, pTable);
|
||||
}
|
||||
#endif /* !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE) */
|
||||
|
||||
#ifndef SQLITE_OMIT_VIEW
|
||||
@@ -4037,7 +4036,7 @@ void sqlite3CreateIndex(
|
||||
}
|
||||
if( !IN_RENAME_OBJECT ){
|
||||
if( !db->init.busy ){
|
||||
if( sqlite3FindTable(db, zName, 0)!=0 ){
|
||||
if( sqlite3FindTable(db, zName, pDb->zDbSName)!=0 ){
|
||||
sqlite3ErrorMsg(pParse, "there is already a table named %s", zName);
|
||||
goto exit_create_index;
|
||||
}
|
||||
|
||||
@@ -683,9 +683,6 @@ static const char * const sqlite3azCompileOpt[] = {
|
||||
#ifdef SQLITE_OMIT_XFER_OPT
|
||||
"OMIT_XFER_OPT",
|
||||
#endif
|
||||
#ifdef SQLITE_PCACHE_SEPARATE_HEADER
|
||||
"PCACHE_SEPARATE_HEADER",
|
||||
#endif
|
||||
#ifdef SQLITE_PERFORMANCE_TRACE
|
||||
"PERFORMANCE_TRACE",
|
||||
#endif
|
||||
|
||||
+1
-1
@@ -785,7 +785,7 @@ static int parseModifier(
|
||||
*/
|
||||
if( sqlite3_strnicmp(z, "weekday ", 8)==0
|
||||
&& sqlite3AtoF(&z[8], &r, sqlite3Strlen30(&z[8]), SQLITE_UTF8)>0
|
||||
&& (n=(int)r)==r && n>=0 && r<7 ){
|
||||
&& r>=0.0 && r<7.0 && (n=(int)r)==r ){
|
||||
sqlite3_int64 Z;
|
||||
computeYMD_HMS(p);
|
||||
p->validTZ = 0;
|
||||
|
||||
+3
-2
@@ -447,9 +447,10 @@ void sqlite3DeleteFrom(
|
||||
}
|
||||
for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
|
||||
assert( pIdx->pSchema==pTab->pSchema );
|
||||
sqlite3VdbeAddOp2(v, OP_Clear, pIdx->tnum, iDb);
|
||||
if( IsPrimaryKeyIndex(pIdx) && !HasRowid(pTab) ){
|
||||
sqlite3VdbeChangeP3(v, -1, memCnt ? memCnt : -1);
|
||||
sqlite3VdbeAddOp3(v, OP_Clear, pIdx->tnum, iDb, memCnt ? memCnt : -1);
|
||||
}else{
|
||||
sqlite3VdbeAddOp2(v, OP_Clear, pIdx->tnum, iDb);
|
||||
}
|
||||
}
|
||||
}else
|
||||
|
||||
+56
-23
@@ -770,7 +770,9 @@ static void heightOfSelect(const Select *pSelect, int *pnHeight){
|
||||
*/
|
||||
static void exprSetHeight(Expr *p){
|
||||
int nHeight = p->pLeft ? p->pLeft->nHeight : 0;
|
||||
if( p->pRight && p->pRight->nHeight>nHeight ) nHeight = p->pRight->nHeight;
|
||||
if( NEVER(p->pRight) && p->pRight->nHeight>nHeight ){
|
||||
nHeight = p->pRight->nHeight;
|
||||
}
|
||||
if( ExprUseXSelect(p) ){
|
||||
heightOfSelect(p->x.pSelect, &nHeight);
|
||||
}else if( p->x.pList ){
|
||||
@@ -913,15 +915,26 @@ void sqlite3ExprAttachSubtrees(
|
||||
sqlite3ExprDelete(db, pLeft);
|
||||
sqlite3ExprDelete(db, pRight);
|
||||
}else{
|
||||
assert( ExprUseXList(pRoot) );
|
||||
assert( pRoot->x.pSelect==0 );
|
||||
if( pRight ){
|
||||
pRoot->pRight = pRight;
|
||||
pRoot->flags |= EP_Propagate & pRight->flags;
|
||||
#if SQLITE_MAX_EXPR_DEPTH>0
|
||||
pRoot->nHeight = pRight->nHeight+1;
|
||||
}else{
|
||||
pRoot->nHeight = 1;
|
||||
#endif
|
||||
}
|
||||
if( pLeft ){
|
||||
pRoot->pLeft = pLeft;
|
||||
pRoot->flags |= EP_Propagate & pLeft->flags;
|
||||
#if SQLITE_MAX_EXPR_DEPTH>0
|
||||
if( pLeft->nHeight>=pRoot->nHeight ){
|
||||
pRoot->nHeight = pLeft->nHeight+1;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
exprSetHeight(pRoot);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1238,10 +1251,6 @@ static SQLITE_NOINLINE void sqlite3ExprDeleteNN(sqlite3 *db, Expr *p){
|
||||
#endif
|
||||
}
|
||||
}
|
||||
if( ExprHasProperty(p, EP_MemToken) ){
|
||||
assert( !ExprHasProperty(p, EP_IntValue) );
|
||||
sqlite3DbFree(db, p->u.zToken);
|
||||
}
|
||||
if( !ExprHasProperty(p, EP_Static) ){
|
||||
sqlite3DbFreeNN(db, p);
|
||||
}
|
||||
@@ -1274,8 +1283,9 @@ void sqlite3ClearOnOrUsing(sqlite3 *db, OnOrUsing *p){
|
||||
** pExpr to the pParse->pConstExpr list with a register number of 0.
|
||||
*/
|
||||
void sqlite3ExprDeferredDelete(Parse *pParse, Expr *pExpr){
|
||||
pParse->pConstExpr =
|
||||
sqlite3ExprListAppend(pParse, pParse->pConstExpr, pExpr);
|
||||
sqlite3ParserAddCleanup(pParse,
|
||||
(void(*)(sqlite3*,void*))sqlite3ExprDelete,
|
||||
pExpr);
|
||||
}
|
||||
|
||||
/* Invoke sqlite3RenameExprUnmap() and sqlite3ExprDelete() on the
|
||||
@@ -1349,7 +1359,6 @@ static int dupedExprStructSize(const Expr *p, int flags){
|
||||
}else{
|
||||
assert( !ExprHasProperty(p, EP_TokenOnly|EP_Reduced) );
|
||||
assert( !ExprHasProperty(p, EP_OuterON) );
|
||||
assert( !ExprHasProperty(p, EP_MemToken) );
|
||||
assert( !ExprHasVVAProperty(p, EP_NoReduce) );
|
||||
if( p->pLeft || p->x.pList ){
|
||||
nSize = EXPR_REDUCEDSIZE | EP_Reduced;
|
||||
@@ -1453,7 +1462,7 @@ static Expr *exprDup(sqlite3 *db, const Expr *p, int dupFlags, u8 **pzBuffer){
|
||||
}
|
||||
|
||||
/* Set the EP_Reduced, EP_TokenOnly, and EP_Static flags appropriately. */
|
||||
pNew->flags &= ~(EP_Reduced|EP_TokenOnly|EP_Static|EP_MemToken);
|
||||
pNew->flags &= ~(EP_Reduced|EP_TokenOnly|EP_Static);
|
||||
pNew->flags |= nStructSize & (EP_Reduced|EP_TokenOnly);
|
||||
pNew->flags |= staticFlag;
|
||||
ExprClearVVAProperties(pNew);
|
||||
@@ -3325,7 +3334,7 @@ int sqlite3CodeSubselect(Parse *pParse, Expr *pExpr){
|
||||
pLimit = sqlite3PExpr(pParse, TK_NE,
|
||||
sqlite3ExprDup(db, pSel->pLimit->pLeft, 0), pLimit);
|
||||
}
|
||||
sqlite3ExprDelete(db, pSel->pLimit->pLeft);
|
||||
sqlite3ExprDeferredDelete(pParse, pSel->pLimit->pLeft);
|
||||
pSel->pLimit->pLeft = pLimit;
|
||||
}else{
|
||||
/* If there is no pre-existing limit add a limit of 1 */
|
||||
@@ -3839,7 +3848,7 @@ int sqlite3ExprCodeGetColumn(
|
||||
assert( pParse->pVdbe!=0 );
|
||||
sqlite3ExprCodeGetColumnOfTable(pParse->pVdbe, pTab, iTable, iColumn, iReg);
|
||||
if( p5 ){
|
||||
VdbeOp *pOp = sqlite3VdbeGetOp(pParse->pVdbe,-1);
|
||||
VdbeOp *pOp = sqlite3VdbeGetLastOp(pParse->pVdbe);
|
||||
if( pOp->opcode==OP_Column ) pOp->p5 = p5;
|
||||
}
|
||||
return iReg;
|
||||
@@ -3908,7 +3917,7 @@ static int exprCodeVector(Parse *pParse, Expr *p, int *piFreeable){
|
||||
** so that a subsequent copy will not be merged into this one.
|
||||
*/
|
||||
static void setDoNotMergeFlagOnCopy(Vdbe *v){
|
||||
if( sqlite3VdbeGetOp(v, -1)->opcode==OP_Copy ){
|
||||
if( sqlite3VdbeGetLastOp(v)->opcode==OP_Copy ){
|
||||
sqlite3VdbeChangeP5(v, 1); /* Tag trailing OP_Copy as not mergable */
|
||||
}
|
||||
}
|
||||
@@ -4079,7 +4088,7 @@ expr_code_doover:
|
||||
pCol->iSorterColumn, target);
|
||||
if( pCol->iColumn<0 ){
|
||||
VdbeComment((v,"%s.rowid",pTab->zName));
|
||||
}else{
|
||||
}else if( ALWAYS(pTab!=0) ){
|
||||
VdbeComment((v,"%s.%s",
|
||||
pTab->zName, pTab->aCol[pCol->iColumn].zCnName));
|
||||
if( pTab->aCol[pCol->iColumn].affinity==SQLITE_AFF_REAL ){
|
||||
@@ -4674,6 +4683,21 @@ expr_code_doover:
|
||||
case TK_IF_NULL_ROW: {
|
||||
int addrINR;
|
||||
u8 okConstFactor = pParse->okConstFactor;
|
||||
AggInfo *pAggInfo = pExpr->pAggInfo;
|
||||
if( pAggInfo ){
|
||||
assert( pExpr->iAgg>=0 && pExpr->iAgg<pAggInfo->nColumn );
|
||||
if( !pAggInfo->directMode ){
|
||||
inReg = pAggInfo->aCol[pExpr->iAgg].iMem;
|
||||
break;
|
||||
}
|
||||
if( pExpr->pAggInfo->useSortingIdx ){
|
||||
sqlite3VdbeAddOp3(v, OP_Column, pAggInfo->sortingIdxPTab,
|
||||
pAggInfo->aCol[pExpr->iAgg].iSorterColumn,
|
||||
target);
|
||||
inReg = target;
|
||||
break;
|
||||
}
|
||||
}
|
||||
addrINR = sqlite3VdbeAddOp1(v, OP_IfNullRow, pExpr->iTable);
|
||||
/* Temporarily disable factoring of constant expressions, since
|
||||
** even though expressions may appear to be constant, they are not
|
||||
@@ -5015,7 +5039,7 @@ int sqlite3ExprCodeExprList(
|
||||
if( inReg!=target+i ){
|
||||
VdbeOp *pOp;
|
||||
if( copyOp==OP_Copy
|
||||
&& (pOp=sqlite3VdbeGetOp(v, -1))->opcode==OP_Copy
|
||||
&& (pOp=sqlite3VdbeGetLastOp(v))->opcode==OP_Copy
|
||||
&& pOp->p1+pOp->p3+1==inReg
|
||||
&& pOp->p2+pOp->p3+1==target+i
|
||||
&& pOp->p5==0 /* The do-not-merge flag must be clear */
|
||||
@@ -6098,8 +6122,8 @@ static int agginfoPersistExprCb(Walker *pWalker, Expr *pExpr){
|
||||
int iAgg = pExpr->iAgg;
|
||||
Parse *pParse = pWalker->pParse;
|
||||
sqlite3 *db = pParse->db;
|
||||
assert( pExpr->op==TK_AGG_COLUMN || pExpr->op==TK_AGG_FUNCTION );
|
||||
if( pExpr->op==TK_AGG_COLUMN ){
|
||||
if( pExpr->op!=TK_AGG_FUNCTION ){
|
||||
assert( pExpr->op==TK_AGG_COLUMN || pExpr->op==TK_IF_NULL_ROW );
|
||||
assert( iAgg>=0 && iAgg<pAggInfo->nColumn );
|
||||
if( pAggInfo->aCol[iAgg].pCExpr==pExpr ){
|
||||
pExpr = sqlite3ExprDup(db, pExpr, 0);
|
||||
@@ -6109,6 +6133,7 @@ static int agginfoPersistExprCb(Walker *pWalker, Expr *pExpr){
|
||||
}
|
||||
}
|
||||
}else{
|
||||
assert( pExpr->op==TK_AGG_FUNCTION );
|
||||
assert( iAgg>=0 && iAgg<pAggInfo->nFunc );
|
||||
if( pAggInfo->aFunc[iAgg].pFExpr==pExpr ){
|
||||
pExpr = sqlite3ExprDup(db, pExpr, 0);
|
||||
@@ -6179,10 +6204,12 @@ static int analyzeAggregate(Walker *pWalker, Expr *pExpr){
|
||||
|
||||
assert( pNC->ncFlags & NC_UAggInfo );
|
||||
switch( pExpr->op ){
|
||||
case TK_IF_NULL_ROW:
|
||||
case TK_AGG_COLUMN:
|
||||
case TK_COLUMN: {
|
||||
testcase( pExpr->op==TK_AGG_COLUMN );
|
||||
testcase( pExpr->op==TK_COLUMN );
|
||||
testcase( pExpr->op==TK_IF_NULL_ROW );
|
||||
/* Check to see if the column is in one of the tables in the FROM
|
||||
** clause of the aggregate query */
|
||||
if( ALWAYS(pSrcList!=0) ){
|
||||
@@ -6200,8 +6227,10 @@ static int analyzeAggregate(Walker *pWalker, Expr *pExpr){
|
||||
int k;
|
||||
pCol = pAggInfo->aCol;
|
||||
for(k=0; k<pAggInfo->nColumn; k++, pCol++){
|
||||
if( pCol->iTable==pExpr->iTable &&
|
||||
pCol->iColumn==pExpr->iColumn ){
|
||||
if( pCol->iTable==pExpr->iTable
|
||||
&& pCol->iColumn==pExpr->iColumn
|
||||
&& pExpr->op!=TK_IF_NULL_ROW
|
||||
){
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -6216,15 +6245,17 @@ static int analyzeAggregate(Walker *pWalker, Expr *pExpr){
|
||||
pCol->iMem = ++pParse->nMem;
|
||||
pCol->iSorterColumn = -1;
|
||||
pCol->pCExpr = pExpr;
|
||||
if( pAggInfo->pGroupBy ){
|
||||
if( pAggInfo->pGroupBy && pExpr->op!=TK_IF_NULL_ROW ){
|
||||
int j, n;
|
||||
ExprList *pGB = pAggInfo->pGroupBy;
|
||||
struct ExprList_item *pTerm = pGB->a;
|
||||
n = pGB->nExpr;
|
||||
for(j=0; j<n; j++, pTerm++){
|
||||
Expr *pE = pTerm->pExpr;
|
||||
if( pE->op==TK_COLUMN && pE->iTable==pExpr->iTable &&
|
||||
pE->iColumn==pExpr->iColumn ){
|
||||
if( pE->op==TK_COLUMN
|
||||
&& pE->iTable==pExpr->iTable
|
||||
&& pE->iColumn==pExpr->iColumn
|
||||
){
|
||||
pCol->iSorterColumn = j;
|
||||
break;
|
||||
}
|
||||
@@ -6241,7 +6272,9 @@ static int analyzeAggregate(Walker *pWalker, Expr *pExpr){
|
||||
*/
|
||||
ExprSetVVAProperty(pExpr, EP_NoReduce);
|
||||
pExpr->pAggInfo = pAggInfo;
|
||||
pExpr->op = TK_AGG_COLUMN;
|
||||
if( pExpr->op==TK_COLUMN ){
|
||||
pExpr->op = TK_AGG_COLUMN;
|
||||
}
|
||||
pExpr->iAgg = (i16)k;
|
||||
break;
|
||||
} /* endif pExpr->iTable==pItem->iCursor */
|
||||
|
||||
+12
-5
@@ -159,7 +159,7 @@ void sqlite3TableAffinity(Vdbe *v, Table *pTab, int iReg){
|
||||
** OP_MakeRecord is found */
|
||||
VdbeOp *pPrev;
|
||||
sqlite3VdbeAppendP4(v, pTab, P4_TABLE);
|
||||
pPrev = sqlite3VdbeGetOp(v, -1);
|
||||
pPrev = sqlite3VdbeGetLastOp(v);
|
||||
assert( pPrev!=0 );
|
||||
assert( pPrev->opcode==OP_MakeRecord || sqlite3VdbeDb(v)->mallocFailed );
|
||||
pPrev->opcode = OP_TypeCheck;
|
||||
@@ -197,7 +197,7 @@ void sqlite3TableAffinity(Vdbe *v, Table *pTab, int iReg){
|
||||
if( iReg ){
|
||||
sqlite3VdbeAddOp4(v, OP_Affinity, iReg, i, 0, zColAff, i);
|
||||
}else{
|
||||
assert( sqlite3VdbeGetOp(v, -1)->opcode==OP_MakeRecord
|
||||
assert( sqlite3VdbeGetLastOp(v)->opcode==OP_MakeRecord
|
||||
|| sqlite3VdbeDb(v)->mallocFailed );
|
||||
sqlite3VdbeChangeP4(v, -1, zColAff, i);
|
||||
}
|
||||
@@ -283,7 +283,7 @@ void sqlite3ComputeGeneratedColumns(
|
||||
*/
|
||||
sqlite3TableAffinity(pParse->pVdbe, pTab, iRegStore);
|
||||
if( (pTab->tabFlags & TF_HasStored)!=0 ){
|
||||
pOp = sqlite3VdbeGetOp(pParse->pVdbe,-1);
|
||||
pOp = sqlite3VdbeGetLastOp(pParse->pVdbe);
|
||||
if( pOp->opcode==OP_Affinity ){
|
||||
/* Change the OP_Affinity argument to '@' (NONE) for all stored
|
||||
** columns. '@' is the no-op affinity and those columns have not
|
||||
@@ -1189,7 +1189,12 @@ void sqlite3Insert(
|
||||
sqlite3VdbeAddOp2(v, OP_SCopy, regFromSelect+k, iRegStore);
|
||||
}
|
||||
}else{
|
||||
sqlite3ExprCode(pParse, pList->a[k].pExpr, iRegStore);
|
||||
Expr *pX = pList->a[k].pExpr;
|
||||
int y = sqlite3ExprCodeTarget(pParse, pX, iRegStore);
|
||||
if( y!=iRegStore ){
|
||||
sqlite3VdbeAddOp2(v,
|
||||
ExprHasProperty(pX, EP_Subquery) ? OP_Copy : OP_SCopy, y, iRegStore);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1326,7 +1331,9 @@ void sqlite3Insert(
|
||||
sqlite3GenerateConstraintChecks(pParse, pTab, aRegIdx, iDataCur, iIdxCur,
|
||||
regIns, 0, ipkColumn>=0, onError, endOfLoop, &isReplace, 0, pUpsert
|
||||
);
|
||||
sqlite3FkCheck(pParse, pTab, 0, regIns, 0, 0);
|
||||
if( db->flags & SQLITE_ForeignKeys ){
|
||||
sqlite3FkCheck(pParse, pTab, 0, regIns, 0, 0);
|
||||
}
|
||||
|
||||
/* Set the OPFLAG_USESEEKRESULT flag if either (a) there are no REPLACE
|
||||
** constraints or (b) there are no triggers and this table is not a
|
||||
|
||||
+16
-28
@@ -39,12 +39,13 @@
|
||||
** size can vary according to architecture, compile-time options, and
|
||||
** SQLite library version number.
|
||||
**
|
||||
** If SQLITE_PCACHE_SEPARATE_HEADER is defined, then the extension is obtained
|
||||
** using a separate memory allocation from the database page content. This
|
||||
** seeks to overcome the "clownshoe" problem (also called "internal
|
||||
** fragmentation" in academic literature) of allocating a few bytes more
|
||||
** than a power of two with the memory allocator rounding up to the next
|
||||
** power of two, and leaving the rounded-up space unused.
|
||||
** Historical note: It used to be that if the SQLITE_PCACHE_SEPARATE_HEADER
|
||||
** was defined, then the page content would be held in a separate memory
|
||||
** allocation from the PgHdr1. This was intended to avoid clownshoe memory
|
||||
** allocations. However, the btree layer needs a small (16-byte) overrun
|
||||
** area after the page content buffer. The header serves as that overrun
|
||||
** area. Therefore SQLITE_PCACHE_SEPARATE_HEADER was discontinued to avoid
|
||||
** any possibility of a memory error.
|
||||
**
|
||||
** This module tracks pointers to PgHdr1 objects. Only pcache.c communicates
|
||||
** with this module. Information is passed back and forth as PgHdr1 pointers.
|
||||
@@ -89,11 +90,16 @@ typedef struct PGroup PGroup;
|
||||
|
||||
/*
|
||||
** Each cache entry is represented by an instance of the following
|
||||
** structure. Unless SQLITE_PCACHE_SEPARATE_HEADER is defined, a buffer of
|
||||
** PgHdr1.pCache->szPage bytes is allocated directly before this structure
|
||||
** in memory.
|
||||
** structure. A buffer of PgHdr1.pCache->szPage bytes is allocated
|
||||
** directly before this structure and is used to cache the page content.
|
||||
**
|
||||
** Note: Variables isBulkLocal and isAnchor were once type "u8". That works,
|
||||
** When reading a corrupt database file, it is possible that SQLite might
|
||||
** read a few bytes (no more than 16 bytes) past the end of the page buffer.
|
||||
** It will only read past the end of the page buffer, never write. This
|
||||
** object is positioned immediately after the page buffer to serve as an
|
||||
** overrun area, so that overreads are harmless.
|
||||
**
|
||||
** Variables isBulkLocal and isAnchor were once type "u8". That works,
|
||||
** but causes a 2-byte gap in the structure for most architectures (since
|
||||
** pointers must be either 4 or 8-byte aligned). As this structure is located
|
||||
** in memory directly after the associated page data, if the database is
|
||||
@@ -438,25 +444,13 @@ static PgHdr1 *pcache1AllocPage(PCache1 *pCache, int benignMalloc){
|
||||
pcache1LeaveMutex(pCache->pGroup);
|
||||
#endif
|
||||
if( benignMalloc ){ sqlite3BeginBenignMalloc(); }
|
||||
#ifdef SQLITE_PCACHE_SEPARATE_HEADER
|
||||
pPg = pcache1Alloc(pCache->szPage);
|
||||
p = sqlite3Malloc(sizeof(PgHdr1) + pCache->szExtra);
|
||||
if( !pPg || !p ){
|
||||
pcache1Free(pPg);
|
||||
sqlite3_free(p);
|
||||
pPg = 0;
|
||||
}
|
||||
#else
|
||||
pPg = pcache1Alloc(pCache->szAlloc);
|
||||
#endif
|
||||
if( benignMalloc ){ sqlite3EndBenignMalloc(); }
|
||||
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
|
||||
pcache1EnterMutex(pCache->pGroup);
|
||||
#endif
|
||||
if( pPg==0 ) return 0;
|
||||
#ifndef SQLITE_PCACHE_SEPARATE_HEADER
|
||||
p = (PgHdr1 *)&((u8 *)pPg)[pCache->szPage];
|
||||
#endif
|
||||
p->page.pBuf = pPg;
|
||||
p->page.pExtra = &p[1];
|
||||
p->isBulkLocal = 0;
|
||||
@@ -480,9 +474,6 @@ static void pcache1FreePage(PgHdr1 *p){
|
||||
pCache->pFree = p;
|
||||
}else{
|
||||
pcache1Free(p->page.pBuf);
|
||||
#ifdef SQLITE_PCACHE_SEPARATE_HEADER
|
||||
sqlite3_free(p);
|
||||
#endif
|
||||
}
|
||||
(*pCache->pnPurgeable)--;
|
||||
}
|
||||
@@ -1246,9 +1237,6 @@ int sqlite3PcacheReleaseMemory(int nReq){
|
||||
&& p->isAnchor==0
|
||||
){
|
||||
nFree += pcache1MemSize(p->page.pBuf);
|
||||
#ifdef SQLITE_PCACHE_SEPARATE_HEADER
|
||||
nFree += sqlite3MemSize(p);
|
||||
#endif
|
||||
assert( PAGE_IS_UNPINNED(p) );
|
||||
pcache1PinPage(p);
|
||||
pcache1RemoveFromHash(p, 1);
|
||||
|
||||
+1
-1
@@ -1781,7 +1781,7 @@ void sqlite3Pragma(
|
||||
if( pCol->notNull==0 && !bStrict ) continue;
|
||||
doError = bStrict ? sqlite3VdbeMakeLabel(pParse) : 0;
|
||||
sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, j, 3);
|
||||
if( sqlite3VdbeGetOp(v,-1)->opcode==OP_Column ){
|
||||
if( sqlite3VdbeGetLastOp(v)->opcode==OP_Column ){
|
||||
sqlite3VdbeChangeP5(v, OPFLAG_TYPEOFARG);
|
||||
}
|
||||
if( pCol->notNull ){
|
||||
|
||||
+5
-17
@@ -85,33 +85,21 @@ static void resolveAlias(
|
||||
sqlite3ExprDelete(db, pDup);
|
||||
pDup = 0;
|
||||
}else{
|
||||
Expr temp;
|
||||
incrAggFunctionDepth(pDup, nSubquery);
|
||||
if( pExpr->op==TK_COLLATE ){
|
||||
assert( !ExprHasProperty(pExpr, EP_IntValue) );
|
||||
pDup = sqlite3ExprAddCollateString(pParse, pDup, pExpr->u.zToken);
|
||||
}
|
||||
|
||||
/* Before calling sqlite3ExprDelete(), set the EP_Static flag. This
|
||||
** prevents ExprDelete() from deleting the Expr structure itself,
|
||||
** allowing it to be repopulated by the memcpy() on the following line.
|
||||
** The pExpr->u.zToken might point into memory that will be freed by the
|
||||
** sqlite3DbFree(db, pDup) on the last line of this block, so be sure to
|
||||
** make a copy of the token before doing the sqlite3DbFree().
|
||||
*/
|
||||
ExprSetProperty(pExpr, EP_Static);
|
||||
sqlite3ExprDelete(db, pExpr);
|
||||
memcpy(pExpr, pDup, sizeof(*pExpr));
|
||||
if( !ExprHasProperty(pExpr, EP_IntValue) && pExpr->u.zToken!=0 ){
|
||||
assert( (pExpr->flags & (EP_Reduced|EP_TokenOnly))==0 );
|
||||
pExpr->u.zToken = sqlite3DbStrDup(db, pExpr->u.zToken);
|
||||
pExpr->flags |= EP_MemToken;
|
||||
}
|
||||
memcpy(&temp, pDup, sizeof(Expr));
|
||||
memcpy(pDup, pExpr, sizeof(Expr));
|
||||
memcpy(pExpr, &temp, sizeof(Expr));
|
||||
if( ExprHasProperty(pExpr, EP_WinFunc) ){
|
||||
if( ALWAYS(pExpr->y.pWin!=0) ){
|
||||
pExpr->y.pWin->pOwner = pExpr;
|
||||
}
|
||||
}
|
||||
sqlite3DbFree(db, pDup);
|
||||
sqlite3ExprDeferredDelete(pParse, pDup);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+18
-10
@@ -1688,7 +1688,7 @@ static void generateSortTail(
|
||||
if( addrOnce ) sqlite3VdbeJumpHere(v, addrOnce);
|
||||
addr = 1 + sqlite3VdbeAddOp2(v, OP_SorterSort, iTab, addrBreak);
|
||||
VdbeCoverage(v);
|
||||
codeOffset(v, p->iOffset, addrContinue);
|
||||
assert( p->iLimit==0 && p->iOffset==0 );
|
||||
sqlite3VdbeAddOp3(v, OP_SorterData, iTab, regSortOut, iSortTab);
|
||||
bSeq = 0;
|
||||
}else{
|
||||
@@ -1696,6 +1696,9 @@ static void generateSortTail(
|
||||
codeOffset(v, p->iOffset, addrContinue);
|
||||
iSortTab = iTab;
|
||||
bSeq = 1;
|
||||
if( p->iOffset>0 ){
|
||||
sqlite3VdbeAddOp2(v, OP_AddImm, p->iLimit, -1);
|
||||
}
|
||||
}
|
||||
for(i=0, iCol=nKey+bSeq-1; i<nColumn; i++){
|
||||
#ifdef SQLITE_ENABLE_SORTER_REFERENCES
|
||||
@@ -3798,6 +3801,7 @@ static Expr *substExpr(
|
||||
ifNullRow.op = TK_IF_NULL_ROW;
|
||||
ifNullRow.pLeft = pCopy;
|
||||
ifNullRow.iTable = pSubst->iNewTable;
|
||||
ifNullRow.iColumn = -99;
|
||||
ifNullRow.flags = EP_IfNullRow;
|
||||
pCopy = &ifNullRow;
|
||||
}
|
||||
@@ -4065,8 +4069,8 @@ static void renumberCursors(
|
||||
** (3a) the subquery may not be a join and
|
||||
** (3b) the FROM clause of the subquery may not contain a virtual
|
||||
** table and
|
||||
** (3c) The outer query may not have a GROUP BY. (This limitation is
|
||||
** due to how TK_IF_NULL_ROW works. FIX ME!)
|
||||
** (**) Was: "The outer query may not have a GROUP BY." This case
|
||||
** is now managed correctly
|
||||
** (3d) the outer query may not be DISTINCT.
|
||||
** See also (26) for restrictions on RIGHT JOIN.
|
||||
**
|
||||
@@ -4284,7 +4288,6 @@ static int flattenSubquery(
|
||||
if( pSubSrc->nSrc>1 /* (3a) */
|
||||
|| IsVirtual(pSubSrc->a[0].pTab) /* (3b) */
|
||||
|| (p->selFlags & SF_Distinct)!=0 /* (3d) */
|
||||
|| (p->pGroupBy!=0) /* (3c) */
|
||||
|| (pSubitem->fg.jointype & JT_RIGHT)!=0 /* (26) */
|
||||
){
|
||||
return 0;
|
||||
@@ -7197,7 +7200,7 @@ int sqlite3Select(
|
||||
if( (p->selFlags & SF_FixedLimit)==0 ){
|
||||
p->nSelectRow = 320; /* 4 billion rows */
|
||||
}
|
||||
computeLimitRegisters(pParse, p, iEnd);
|
||||
if( p->pLimit ) computeLimitRegisters(pParse, p, iEnd);
|
||||
if( p->iLimit==0 && sSort.addrSortIndex>=0 ){
|
||||
sqlite3VdbeChangeOpcode(v, sSort.addrSortIndex, OP_SorterOpen);
|
||||
sSort.sortFlags |= SORTFLAG_UseSorter;
|
||||
@@ -7419,8 +7422,13 @@ int sqlite3Select(
|
||||
sqlite3TreeViewExprList(0, pMinMaxOrderBy, 0, "ORDERBY");
|
||||
}
|
||||
for(ii=0; ii<pAggInfo->nColumn; ii++){
|
||||
sqlite3DebugPrintf("agg-column[%d] iMem=%d\n",
|
||||
ii, pAggInfo->aCol[ii].iMem);
|
||||
struct AggInfo_col *pCol = &pAggInfo->aCol[ii];
|
||||
sqlite3DebugPrintf(
|
||||
"agg-column[%d] pTab=%s iTable=%d iColumn=%d iMem=%d"
|
||||
" iSorterColumn=%d\n",
|
||||
ii, pCol->pTab ? pCol->pTab->zName : "NULL",
|
||||
pCol->iTable, pCol->iColumn, pCol->iMem,
|
||||
pCol->iSorterColumn);
|
||||
sqlite3TreeViewExpr(0, pAggInfo->aCol[ii].pCExpr, 0);
|
||||
}
|
||||
for(ii=0; ii<pAggInfo->nFunc; ii++){
|
||||
@@ -7541,15 +7549,15 @@ int sqlite3Select(
|
||||
regBase = sqlite3GetTempRange(pParse, nCol);
|
||||
sqlite3ExprCodeExprList(pParse, pGroupBy, regBase, 0, 0);
|
||||
j = nGroupBy;
|
||||
pAggInfo->directMode = 1;
|
||||
for(i=0; i<pAggInfo->nColumn; i++){
|
||||
struct AggInfo_col *pCol = &pAggInfo->aCol[i];
|
||||
if( pCol->iSorterColumn>=j ){
|
||||
int r1 = j + regBase;
|
||||
sqlite3ExprCodeGetColumnOfTable(v,
|
||||
pCol->pTab, pCol->iTable, pCol->iColumn, r1);
|
||||
sqlite3ExprCode(pParse, pCol->pCExpr, j + regBase);
|
||||
j++;
|
||||
}
|
||||
}
|
||||
pAggInfo->directMode = 0;
|
||||
regRecord = sqlite3GetTempReg(pParse);
|
||||
sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase, nCol, regRecord);
|
||||
sqlite3VdbeAddOp2(v, OP_SorterInsert, pAggInfo->sortingIdx, regRecord);
|
||||
|
||||
+1
-1
@@ -3439,7 +3439,7 @@ void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*);
|
||||
** to return an extended result code.</dd>
|
||||
**
|
||||
** [[OPEN_NOFOLLOW]] ^(<dt>[SQLITE_OPEN_NOFOLLOW]</dt>
|
||||
** <dd>The database filename is not allowed to be a symbolic link</dd>
|
||||
** <dd>The database filename is not allowed to contain a symbolic link</dd>
|
||||
** </dl>)^
|
||||
**
|
||||
** If the 3rd parameter to sqlite3_open_v2() is not one of the
|
||||
|
||||
+2
-1
@@ -2886,7 +2886,7 @@ struct Expr {
|
||||
#define EP_Reduced 0x004000 /* Expr struct EXPR_REDUCEDSIZE bytes only */
|
||||
#define EP_Win 0x008000 /* Contains window functions */
|
||||
#define EP_TokenOnly 0x010000 /* Expr struct EXPR_TOKENONLYSIZE bytes only */
|
||||
#define EP_MemToken 0x020000 /* Need to sqlite3DbFree() Expr.zToken */
|
||||
/* 0x020000 // Available for reuse */
|
||||
#define EP_IfNullRow 0x040000 /* The TK_IF_NULL_ROW opcode */
|
||||
#define EP_Unlikely 0x080000 /* unlikely() or likelihood() function */
|
||||
#define EP_ConstFunc 0x100000 /* A SQLITE_FUNC_CONSTANT or _SLOCHNG function */
|
||||
@@ -4888,6 +4888,7 @@ int sqlite3FixSelect(DbFixer*, Select*);
|
||||
int sqlite3FixExpr(DbFixer*, Expr*);
|
||||
int sqlite3FixTriggerStep(DbFixer*, TriggerStep*);
|
||||
int sqlite3RealSameAsInt(double,sqlite3_int64);
|
||||
i64 sqlite3RealToI64(double);
|
||||
void sqlite3Int64ToText(i64,char*);
|
||||
int sqlite3AtoF(const char *z, double*, int, u8);
|
||||
int sqlite3GetInt32(const char *, int*);
|
||||
|
||||
+18
-14
@@ -314,7 +314,8 @@ static VdbeCursor *allocateCursor(
|
||||
** return false.
|
||||
*/
|
||||
static int alsoAnInt(Mem *pRec, double rValue, i64 *piValue){
|
||||
i64 iValue = (double)rValue;
|
||||
i64 iValue;
|
||||
iValue = sqlite3RealToI64(rValue);
|
||||
if( sqlite3RealSameAsInt(rValue,iValue) ){
|
||||
*piValue = iValue;
|
||||
return 1;
|
||||
@@ -476,17 +477,18 @@ 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|MEM_IntReal) ){
|
||||
assert( (pMem->flags & MEM_Null)==0
|
||||
|| pMem->db==0 || pMem->db->mallocFailed );
|
||||
if( pMem->flags & (MEM_Int|MEM_Real|MEM_IntReal|MEM_Null) ){
|
||||
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 pMem->flags & (MEM_Int|MEM_Real|MEM_IntReal|MEM_Null);
|
||||
}
|
||||
assert( pMem->flags & (MEM_Str|MEM_Blob) );
|
||||
testcase( pMem->flags & MEM_Str );
|
||||
testcase( pMem->flags & MEM_Blob );
|
||||
return computeNumericType(pMem);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1731,7 +1733,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 */
|
||||
u16 flags; /* Combined MEM_* flags from both inputs */
|
||||
u16 type1; /* Numeric type of left operand */
|
||||
u16 type2; /* Numeric type of right operand */
|
||||
i64 iA; /* Integer value of left operand */
|
||||
@@ -1740,12 +1741,12 @@ case OP_Remainder: { /* same as TK_REM, in1, in2, out3 */
|
||||
double rB; /* Real value of right operand */
|
||||
|
||||
pIn1 = &aMem[pOp->p1];
|
||||
type1 = numericType(pIn1);
|
||||
type1 = pIn1->flags;
|
||||
pIn2 = &aMem[pOp->p2];
|
||||
type2 = numericType(pIn2);
|
||||
type2 = pIn2->flags;
|
||||
pOut = &aMem[pOp->p3];
|
||||
flags = pIn1->flags | pIn2->flags;
|
||||
if( (type1 & type2 & MEM_Int)!=0 ){
|
||||
int_math:
|
||||
iA = pIn1->u.i;
|
||||
iB = pIn2->u.i;
|
||||
switch( pOp->opcode ){
|
||||
@@ -1767,9 +1768,12 @@ case OP_Remainder: { /* same as TK_REM, in1, in2, out3 */
|
||||
}
|
||||
pOut->u.i = iB;
|
||||
MemSetTypeFlag(pOut, MEM_Int);
|
||||
}else if( (flags & MEM_Null)!=0 ){
|
||||
}else if( ((type1 | type2) & MEM_Null)!=0 ){
|
||||
goto arithmetic_result_is_null;
|
||||
}else{
|
||||
type1 = numericType(pIn1);
|
||||
type2 = numericType(pIn2);
|
||||
if( (type1 & type2 & MEM_Int)!=0 ) goto int_math;
|
||||
fp_math:
|
||||
rA = sqlite3VdbeRealValue(pIn1);
|
||||
rB = sqlite3VdbeRealValue(pIn2);
|
||||
@@ -7214,7 +7218,7 @@ case OP_IfPos: { /* jump, in1 */
|
||||
** Synopsis: if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1)
|
||||
**
|
||||
** This opcode performs a commonly used computation associated with
|
||||
** LIMIT and OFFSET process. r[P1] holds the limit counter. r[P3]
|
||||
** LIMIT and OFFSET processing. r[P1] holds the limit counter. r[P3]
|
||||
** holds the offset counter. The opcode computes the combined value
|
||||
** of the LIMIT and OFFSET and stores that value in r[P2]. The r[P2]
|
||||
** value computed is the total number of rows that will need to be
|
||||
|
||||
@@ -242,6 +242,7 @@ void sqlite3VdbeAppendP4(Vdbe*, void *pP4, int p4type);
|
||||
void sqlite3VdbeSetP4KeyInfo(Parse*, Index*);
|
||||
void sqlite3VdbeUsesBtree(Vdbe*, int);
|
||||
VdbeOp *sqlite3VdbeGetOp(Vdbe*, int);
|
||||
VdbeOp *sqlite3VdbeGetLastOp(Vdbe*);
|
||||
int sqlite3VdbeMakeLabel(Parse*);
|
||||
void sqlite3VdbeRunOnlyOnce(Vdbe*);
|
||||
void sqlite3VdbeReusable(Vdbe*);
|
||||
|
||||
+8
-9
@@ -1432,7 +1432,7 @@ const void *sqlite3_column_origin_name16(sqlite3_stmt *pStmt, int N){
|
||||
** The error code stored in database p->db is overwritten with the return
|
||||
** value in any case.
|
||||
*/
|
||||
static int vdbeUnbind(Vdbe *p, int i){
|
||||
static int vdbeUnbind(Vdbe *p, unsigned int i){
|
||||
Mem *pVar;
|
||||
if( vdbeSafetyNotNull(p) ){
|
||||
return SQLITE_MISUSE_BKPT;
|
||||
@@ -1445,12 +1445,11 @@ static int vdbeUnbind(Vdbe *p, int i){
|
||||
"bind on a busy prepared statement: [%s]", p->zSql);
|
||||
return SQLITE_MISUSE_BKPT;
|
||||
}
|
||||
if( i<1 || i>p->nVar ){
|
||||
if( i>=(unsigned int)p->nVar ){
|
||||
sqlite3Error(p->db, SQLITE_RANGE);
|
||||
sqlite3_mutex_leave(p->db->mutex);
|
||||
return SQLITE_RANGE;
|
||||
}
|
||||
i--;
|
||||
pVar = &p->aVar[i];
|
||||
sqlite3VdbeMemRelease(pVar);
|
||||
pVar->flags = MEM_Null;
|
||||
@@ -1487,7 +1486,7 @@ static int bindText(
|
||||
Mem *pVar;
|
||||
int rc;
|
||||
|
||||
rc = vdbeUnbind(p, i);
|
||||
rc = vdbeUnbind(p, (u32)(i-1));
|
||||
if( rc==SQLITE_OK ){
|
||||
if( zData!=0 ){
|
||||
pVar = &p->aVar[i-1];
|
||||
@@ -1536,7 +1535,7 @@ int sqlite3_bind_blob64(
|
||||
int sqlite3_bind_double(sqlite3_stmt *pStmt, int i, double rValue){
|
||||
int rc;
|
||||
Vdbe *p = (Vdbe *)pStmt;
|
||||
rc = vdbeUnbind(p, i);
|
||||
rc = vdbeUnbind(p, (u32)(i-1));
|
||||
if( rc==SQLITE_OK ){
|
||||
sqlite3VdbeMemSetDouble(&p->aVar[i-1], rValue);
|
||||
sqlite3_mutex_leave(p->db->mutex);
|
||||
@@ -1549,7 +1548,7 @@ int sqlite3_bind_int(sqlite3_stmt *p, int i, int iValue){
|
||||
int sqlite3_bind_int64(sqlite3_stmt *pStmt, int i, sqlite_int64 iValue){
|
||||
int rc;
|
||||
Vdbe *p = (Vdbe *)pStmt;
|
||||
rc = vdbeUnbind(p, i);
|
||||
rc = vdbeUnbind(p, (u32)(i-1));
|
||||
if( rc==SQLITE_OK ){
|
||||
sqlite3VdbeMemSetInt64(&p->aVar[i-1], iValue);
|
||||
sqlite3_mutex_leave(p->db->mutex);
|
||||
@@ -1559,7 +1558,7 @@ int sqlite3_bind_int64(sqlite3_stmt *pStmt, int i, sqlite_int64 iValue){
|
||||
int sqlite3_bind_null(sqlite3_stmt *pStmt, int i){
|
||||
int rc;
|
||||
Vdbe *p = (Vdbe*)pStmt;
|
||||
rc = vdbeUnbind(p, i);
|
||||
rc = vdbeUnbind(p, (u32)(i-1));
|
||||
if( rc==SQLITE_OK ){
|
||||
sqlite3_mutex_leave(p->db->mutex);
|
||||
}
|
||||
@@ -1574,7 +1573,7 @@ int sqlite3_bind_pointer(
|
||||
){
|
||||
int rc;
|
||||
Vdbe *p = (Vdbe*)pStmt;
|
||||
rc = vdbeUnbind(p, i);
|
||||
rc = vdbeUnbind(p, (u32)(i-1));
|
||||
if( rc==SQLITE_OK ){
|
||||
sqlite3VdbeMemSetPointer(&p->aVar[i-1], pPtr, zPTtype, xDestructor);
|
||||
sqlite3_mutex_leave(p->db->mutex);
|
||||
@@ -1652,7 +1651,7 @@ int sqlite3_bind_value(sqlite3_stmt *pStmt, int i, const sqlite3_value *pValue){
|
||||
int sqlite3_bind_zeroblob(sqlite3_stmt *pStmt, int i, int n){
|
||||
int rc;
|
||||
Vdbe *p = (Vdbe *)pStmt;
|
||||
rc = vdbeUnbind(p, i);
|
||||
rc = vdbeUnbind(p, (u32)(i-1));
|
||||
if( rc==SQLITE_OK ){
|
||||
#ifndef SQLITE_OMIT_INCRBLOB
|
||||
sqlite3VdbeMemSetZeroBlob(&p->aVar[i-1], n);
|
||||
|
||||
+15
-8
@@ -456,7 +456,7 @@ void sqlite3VdbeExplain(Parse *pParse, u8 bPush, const char *zFmt, ...){
|
||||
iThis = v->nOp;
|
||||
sqlite3VdbeAddOp4(v, OP_Explain, iThis, pParse->addrExplain, 0,
|
||||
zMsg, P4_DYNAMIC);
|
||||
sqlite3ExplainBreakpoint(bPush?"PUSH":"", sqlite3VdbeGetOp(v,-1)->p4.z);
|
||||
sqlite3ExplainBreakpoint(bPush?"PUSH":"", sqlite3VdbeGetLastOp(v)->p4.z);
|
||||
if( bPush){
|
||||
pParse->addrExplain = iThis;
|
||||
}
|
||||
@@ -1133,15 +1133,19 @@ void sqlite3VdbeScanStatus(
|
||||
** for a specific instruction.
|
||||
*/
|
||||
void sqlite3VdbeChangeOpcode(Vdbe *p, int addr, u8 iNewOpcode){
|
||||
assert( addr>=0 );
|
||||
sqlite3VdbeGetOp(p,addr)->opcode = iNewOpcode;
|
||||
}
|
||||
void sqlite3VdbeChangeP1(Vdbe *p, int addr, int val){
|
||||
assert( addr>=0 );
|
||||
sqlite3VdbeGetOp(p,addr)->p1 = val;
|
||||
}
|
||||
void sqlite3VdbeChangeP2(Vdbe *p, int addr, int val){
|
||||
assert( addr>=0 || p->db->mallocFailed );
|
||||
sqlite3VdbeGetOp(p,addr)->p2 = val;
|
||||
}
|
||||
void sqlite3VdbeChangeP3(Vdbe *p, int addr, int val){
|
||||
assert( addr>=0 );
|
||||
sqlite3VdbeGetOp(p,addr)->p3 = val;
|
||||
}
|
||||
void sqlite3VdbeChangeP5(Vdbe *p, u16 p5){
|
||||
@@ -1177,7 +1181,7 @@ void sqlite3VdbeJumpHereOrPopInst(Vdbe *p, int addr){
|
||||
|| p->aOp[addr].opcode==OP_FkIfZero );
|
||||
assert( p->aOp[addr].p4type==0 );
|
||||
#ifdef SQLITE_VDBE_COVERAGE
|
||||
sqlite3VdbeGetOp(p,-1)->iSrcLine = 0; /* Erase VdbeCoverage() macros */
|
||||
sqlite3VdbeGetLastOp(p)->iSrcLine = 0; /* Erase VdbeCoverage() macros */
|
||||
#endif
|
||||
p->nOp--;
|
||||
}else{
|
||||
@@ -1498,13 +1502,13 @@ void sqlite3VdbeNoopComment(Vdbe *p, const char *zFormat, ...){
|
||||
** Set the value if the iSrcLine field for the previously coded instruction.
|
||||
*/
|
||||
void sqlite3VdbeSetLineNumber(Vdbe *v, int iLine){
|
||||
sqlite3VdbeGetOp(v,-1)->iSrcLine = iLine;
|
||||
sqlite3VdbeGetLastOp(v)->iSrcLine = iLine;
|
||||
}
|
||||
#endif /* SQLITE_VDBE_COVERAGE */
|
||||
|
||||
/*
|
||||
** Return the opcode for a given address. If the address is -1, then
|
||||
** return the most recently inserted opcode.
|
||||
** Return the opcode for a given address. The address must be non-negative.
|
||||
** See sqlite3VdbeGetLastOp() to get the most recently added opcode.
|
||||
**
|
||||
** If a memory allocation error has occurred prior to the calling of this
|
||||
** routine, then a pointer to a dummy VdbeOp will be returned. That opcode
|
||||
@@ -1520,9 +1524,6 @@ VdbeOp *sqlite3VdbeGetOp(Vdbe *p, int addr){
|
||||
** zeros, which is correct. MSVC generates a warning, nevertheless. */
|
||||
static VdbeOp dummy; /* Ignore the MSVC warning about no initializer */
|
||||
assert( p->eVdbeState==VDBE_INIT_STATE );
|
||||
if( addr<0 ){
|
||||
addr = p->nOp - 1;
|
||||
}
|
||||
assert( (addr>=0 && addr<p->nOp) || p->db->mallocFailed );
|
||||
if( p->db->mallocFailed ){
|
||||
return (VdbeOp*)&dummy;
|
||||
@@ -1531,6 +1532,12 @@ VdbeOp *sqlite3VdbeGetOp(Vdbe *p, int addr){
|
||||
}
|
||||
}
|
||||
|
||||
/* Return the most recently added opcode
|
||||
*/
|
||||
VdbeOp * sqlite3VdbeGetLastOp(Vdbe *p){
|
||||
return sqlite3VdbeGetOp(p, p->nOp - 1);
|
||||
}
|
||||
|
||||
#if defined(SQLITE_ENABLE_EXPLAIN_COMMENTS)
|
||||
/*
|
||||
** Return an integer value for one of the parameters to the opcode pOp
|
||||
|
||||
+11
-1
@@ -749,6 +749,16 @@ int sqlite3RealSameAsInt(double r1, sqlite3_int64 i){
|
||||
&& i >= -2251799813685248LL && i < 2251799813685248LL);
|
||||
}
|
||||
|
||||
/* Convert a floating point value to its closest integer. Do so in
|
||||
** a way that avoids 'outside the range of representable values' warnings
|
||||
** from UBSAN.
|
||||
*/
|
||||
i64 sqlite3RealToI64(double r){
|
||||
if( r<=(double)SMALLEST_INT64 ) return SMALLEST_INT64;
|
||||
if( r>=(double)LARGEST_INT64) return LARGEST_INT64;
|
||||
return (i64)r;
|
||||
}
|
||||
|
||||
/*
|
||||
** Convert pMem so that it has type MEM_Real or MEM_Int.
|
||||
** Invalidate any prior representations.
|
||||
@@ -770,7 +780,7 @@ int sqlite3VdbeMemNumerify(Mem *pMem){
|
||||
assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
|
||||
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))
|
||||
|| sqlite3RealSameAsInt(pMem->u.r, (ix = sqlite3RealToI64(pMem->u.r)))
|
||||
){
|
||||
pMem->u.i = ix;
|
||||
MemSetTypeFlag(pMem, MEM_Int);
|
||||
|
||||
+1
-1
@@ -1567,7 +1567,7 @@ static int whereKeyStats(
|
||||
** is larger than all samples in the array. */
|
||||
tRowcnt iUpper, iGap;
|
||||
if( i>=pIdx->nSample ){
|
||||
iUpper = sqlite3LogEstToInt(pIdx->aiRowLogEst[0]);
|
||||
iUpper = pIdx->nRowEst0;
|
||||
}else{
|
||||
iUpper = aSample[i].anLt[iCol];
|
||||
}
|
||||
|
||||
+3
-2
@@ -622,7 +622,8 @@ static int codeEqualityTerm(
|
||||
}
|
||||
sqlite3ExprDelete(db, pX);
|
||||
}else{
|
||||
aiMap = (int*)sqlite3DbMallocZero(pParse->db, sizeof(int)*nEq);
|
||||
int n = sqlite3ExprVectorSize(pX->pLeft);
|
||||
aiMap = (int*)sqlite3DbMallocZero(pParse->db, sizeof(int)*MAX(nEq,n));
|
||||
eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, aiMap, &iTab);
|
||||
}
|
||||
pX = pExpr;
|
||||
@@ -892,7 +893,7 @@ static void whereLikeOptimizationStringFixup(
|
||||
if( pTerm->wtFlags & TERM_LIKEOPT ){
|
||||
VdbeOp *pOp;
|
||||
assert( pLevel->iLikeRepCntr>0 );
|
||||
pOp = sqlite3VdbeGetOp(v, -1);
|
||||
pOp = sqlite3VdbeGetLastOp(v);
|
||||
assert( pOp!=0 );
|
||||
assert( pOp->opcode==OP_String8
|
||||
|| pTerm->pWC->pWInfo->pParse->db->mallocFailed );
|
||||
|
||||
+3
-5
@@ -900,7 +900,6 @@ static ExprList *exprListAppendList(
|
||||
for(i=0; i<pAppend->nExpr; i++){
|
||||
sqlite3 *db = pParse->db;
|
||||
Expr *pDup = sqlite3ExprDup(db, pAppend->a[i].pExpr, 0);
|
||||
assert( pDup==0 || !ExprHasProperty(pDup, EP_MemToken) );
|
||||
if( db->mallocFailed ){
|
||||
sqlite3ExprDelete(db, pDup);
|
||||
break;
|
||||
@@ -2171,10 +2170,9 @@ static void windowCodeRangeTest(
|
||||
|
||||
/* This block runs if reg1 is not NULL, but reg2 is. */
|
||||
sqlite3VdbeJumpHere(v, addr);
|
||||
sqlite3VdbeAddOp2(v, OP_IsNull, reg2, lbl); VdbeCoverage(v);
|
||||
if( op==OP_Gt || op==OP_Ge ){
|
||||
sqlite3VdbeChangeP2(v, -1, addrDone);
|
||||
}
|
||||
sqlite3VdbeAddOp2(v, OP_IsNull, reg2,
|
||||
(op==OP_Gt || op==OP_Ge) ? addrDone : lbl);
|
||||
VdbeCoverage(v);
|
||||
}
|
||||
|
||||
/* Register reg1 currently contains csr1.peerVal (the peer-value from csr1).
|
||||
|
||||
+42
-1
@@ -156,6 +156,47 @@ do_execsql_test offset1-1.4.9 {
|
||||
LIMIT 9 OFFSET 1;
|
||||
} {2 b 3 c 4 d 5 e 6 w 7 x 8 y 9 z}
|
||||
|
||||
|
||||
# 2022-08-04
|
||||
# https://sqlite.org/forum/forumpost/6b5e9188f0657616
|
||||
#
|
||||
do_execsql_test offset1-2.0 {
|
||||
CREATE TABLE employees (
|
||||
id integer primary key,
|
||||
name text,
|
||||
city text,
|
||||
department text,
|
||||
salary integer
|
||||
);
|
||||
INSERT INTO employees VALUES
|
||||
(11,'Diane','London','hr',70),
|
||||
(12,'Bob','London','hr',78),
|
||||
(21,'Emma','London','it',84),
|
||||
(22,'Grace','Berlin','it',90),
|
||||
(23,'Henry','London','it',104),
|
||||
(24,'Irene','Berlin','it',104),
|
||||
(25,'Frank','Berlin','it',120),
|
||||
(31,'Cindy','Berlin','sales',96),
|
||||
(32,'Dave','London','sales',96),
|
||||
(33,'Alice','Berlin','sales',100);
|
||||
CREATE VIEW v AS
|
||||
SELECT * FROM (
|
||||
SELECT * FROM employees
|
||||
WHERE salary < 100
|
||||
ORDER BY salary desc)
|
||||
UNION ALL
|
||||
SELECT * FROM (
|
||||
SELECT * FROM employees
|
||||
WHERE salary >= 100
|
||||
ORDER BY salary asc);
|
||||
} {}
|
||||
do_execsql_test offset1-2.1 {
|
||||
SELECT * FROM v LIMIT 5 OFFSET 2;
|
||||
} {
|
||||
22 Grace Berlin it 90
|
||||
21 Emma London it 84
|
||||
12 Bob London hr 78
|
||||
11 Diane London hr 70
|
||||
33 Alice Berlin sales 100
|
||||
}
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -330,4 +330,108 @@ do_execsql_test select3.10.100 {
|
||||
FROM t1;
|
||||
} {{} {}}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# dbsqlfuzz crash-8e17857db2c5a9294c975123ac807156a6559f13.txt
|
||||
# Associated with the flatten-left-join branch circa 2022-06-23.
|
||||
#
|
||||
foreach {tn sql} {
|
||||
1 {
|
||||
CREATE TABLE t1(a TEXT);
|
||||
CREATE TABLE t2(x INT);
|
||||
CREATE INDEX t2x ON t2(x);
|
||||
INSERT INTO t1 VALUES('abc');
|
||||
}
|
||||
2 {
|
||||
CREATE TABLE t1(a TEXT);
|
||||
CREATE TABLE t2(x INT);
|
||||
INSERT INTO t1 VALUES('abc');
|
||||
}
|
||||
3 {
|
||||
CREATE TABLE t1(a TEXT);
|
||||
CREATE TABLE t2(x INT);
|
||||
INSERT INTO t1 VALUES('abc');
|
||||
PRAGMA automatic_index=OFF;
|
||||
}
|
||||
} {
|
||||
reset_db
|
||||
do_execsql_test select3-11.$tn.1 $sql
|
||||
do_execsql_test select3.11.$tn.2 {
|
||||
SELECT max(a), val FROM t1 LEFT JOIN (
|
||||
SELECT 'constant' AS val FROM t2 WHERE x=1234
|
||||
)
|
||||
} {abc {}}
|
||||
do_execsql_test select3.11.$tn.3 {
|
||||
INSERT INTO t2 VALUES(123);
|
||||
SELECT max(a), val FROM t1 LEFT JOIN (
|
||||
SELECT 'constant' AS val FROM t2 WHERE x=1234
|
||||
)
|
||||
} {abc {}}
|
||||
do_execsql_test select3.11.$tn.4 {
|
||||
INSERT INTO t2 VALUES(1234);
|
||||
SELECT max(a), val FROM t1 LEFT JOIN (
|
||||
SELECT 'constant' AS val FROM t2 WHERE x=1234
|
||||
)
|
||||
} {abc constant}
|
||||
}
|
||||
|
||||
reset_db
|
||||
do_execsql_test 12.0 {
|
||||
CREATE TABLE t1(a);
|
||||
CREATE TABLE t2(x);
|
||||
}
|
||||
do_execsql_test 12.1 {
|
||||
SELECT count(x), m FROM t1 LEFT JOIN (SELECT x, 59 AS m FROM t2) GROUP BY a;
|
||||
}
|
||||
do_execsql_test 12.2 {
|
||||
INSERT INTO t1 VALUES(1), (1), (2), (3);
|
||||
SELECT count(x), m FROM t1 LEFT JOIN (SELECT x, 59 AS m FROM t2) GROUP BY a;
|
||||
} {
|
||||
0 {}
|
||||
0 {}
|
||||
0 {}
|
||||
}
|
||||
do_execsql_test 12.3 {
|
||||
INSERT INTO t2 VALUES(45);
|
||||
SELECT count(x), m FROM t1 LEFT JOIN (SELECT x, 59 AS m FROM t2) GROUP BY a;
|
||||
} {
|
||||
2 59
|
||||
1 59
|
||||
1 59
|
||||
}
|
||||
do_execsql_test 12.4 {
|
||||
INSERT INTO t2 VALUES(210);
|
||||
SELECT count(x), m FROM t1 LEFT JOIN (SELECT x, 59 AS m FROM t2) GROUP BY a;
|
||||
} {
|
||||
4 59
|
||||
2 59
|
||||
2 59
|
||||
}
|
||||
do_execsql_test 12.5 {
|
||||
INSERT INTO t2 VALUES(NULL);
|
||||
SELECT count(x), m FROM t1 LEFT JOIN (SELECT x, 59 AS m FROM t2) GROUP BY a;
|
||||
} {
|
||||
4 59
|
||||
2 59
|
||||
2 59
|
||||
}
|
||||
do_execsql_test 12.6 {
|
||||
DELETE FROM t2;
|
||||
DELETE FROM t1;
|
||||
INSERT INTO t1 VALUES('value');
|
||||
INSERT INTO t2 VALUES('hello');
|
||||
} {}
|
||||
do_execsql_test 12.7 {
|
||||
SELECT group_concat(x), m FROM t1
|
||||
LEFT JOIN (SELECT x, 59 AS m FROM t2) GROUP BY a;
|
||||
} {
|
||||
hello 59
|
||||
}
|
||||
do_execsql_test 12.8 {
|
||||
SELECT group_concat(x), m, n FROM t1
|
||||
LEFT JOIN (SELECT x, 59 AS m, 60 AS n FROM t2) GROUP BY a;
|
||||
} {
|
||||
hello 59 60
|
||||
}
|
||||
|
||||
finish_test
|
||||
|
||||
|
||||
+1
-1
@@ -88,7 +88,7 @@ do_multiclient_test tn {
|
||||
INSERT INTO t1 VALUES(3, 4);
|
||||
INSERT INTO t1 VALUES(5, 6);
|
||||
}
|
||||
code1 { db timeout 2000 }
|
||||
code1 { db timeout 1100 }
|
||||
} {}
|
||||
|
||||
do_test 2.$tn.2 {
|
||||
|
||||
@@ -254,7 +254,6 @@ set boolean_defnil_options {
|
||||
SQLITE_OMIT_WAL
|
||||
SQLITE_OMIT_WSD
|
||||
SQLITE_OMIT_XFER_OPT
|
||||
SQLITE_PCACHE_SEPARATE_HEADER
|
||||
SQLITE_PERFORMANCE_TRACE
|
||||
SQLITE_PREFER_PROXY_LOCKING
|
||||
SQLITE_PROXY_DEBUG
|
||||
|
||||
Reference in New Issue
Block a user