Merge all recent trunk enhancements and fixes into the apple-osx branch.

FossilOrigin-Name: 74b7bf17446bc21a73fa5b75c2942b5660b0ad7e
This commit is contained in:
drh
2015-04-20 01:25:56 +00:00
48 changed files with 951 additions and 194 deletions
+3
View File
@@ -552,6 +552,9 @@ sqlite3$(TEXE): $(TOP)/src/shell.c libsqlite3.la sqlite3.h
sqldiff$(EXE): $(TOP)/tool/sqldiff.c sqlite3.c sqlite3.h
$(LTLINK) -o $@ $(TOP)/tool/sqldiff.c sqlite3.c $(TLIBS)
fuzzershell$(EXE): $(TOP)/tool/fuzzershell.c sqlite3.c sqlite3.h
$(LTLINK) -o $@ $(TOP)/tool/fuzzershell.c sqlite3.c $(TLIBS)
mptester$(EXE): sqlite3.c $(TOP)/mptest/mptest.c
$(LTLINK) -o $@ -I. $(TOP)/mptest/mptest.c sqlite3.c \
$(TLIBS) -rpath "$(libdir)"
+8 -2
View File
@@ -1159,12 +1159,15 @@ sqlite3.exe: $(TOP)\src\shell.c $(SHELL_CORE_DEP) $(LIBRESOBJS) sqlite3.h
sqldiff.exe: $(TOP)\tool\sqldiff.c sqlite3.c sqlite3.h
$(LTLINK) $(TOP)\tool\sqldiff.c sqlite3.c
fuzzershell.exe: $(TOP)\tool\fuzzershell.c sqlite3.c sqlite3.h
$(LTLINK) $(TOP)\tool\fuzzershell.c sqlite3.c
mptester.exe: $(TOP)\mptest\mptest.c $(SHELL_CORE_DEP) $(LIBRESOBJS) sqlite3.h
$(LTLINK) $(SHELL_COMPILE_OPTS) $(TOP)\mptest\mptest.c \
/link $(LTLINKOPTS) $(LTLIBPATHS) $(SHELL_LINK_OPTS) $(LIBRESOBJS) $(LIBREADLINE) $(LTLIBS) $(TLIBS)
MPTEST1 = mptester mptest.db $(TOP)/mptest/crash01.test --repeat 20
MPTEST2 = mptester mptest.db $(TOP)/mptest/multiwrite01.test --repeat 20
MPTEST1 = mptester mptest.db $(TOP)\mptest\crash01.test --repeat 20
MPTEST2 = mptester mptest.db $(TOP)\mptest\multiwrite01.test --repeat 20
mptest: mptester.exe
del /Q mptest.db 2>NUL
@@ -1613,6 +1616,9 @@ queryplantest: testfixture.exe sqlite3.exe
test: testfixture.exe sqlite3.exe
.\testfixture.exe $(TOP)\test\veryquick.test
smoketest: testfixture.exe
.\testfixture.exe $(TOP)\test\main.test
sqlite3_analyzer.c: $(SQLITE3C) $(TOP)\src\test_stat.c $(TOP)\src\tclsqlite.c $(TOP)\tool\spaceanal.tcl
copy $(SQLITE3C) + $(TOP)\src\test_stat.c + $(TOP)\src\tclsqlite.c $@
echo static const char *tclsh_main_loop(void){ >> $@
+23 -2
View File
@@ -3459,11 +3459,31 @@ static void fts3ReversePoslist(char *pStart, char **ppPoslist){
char *p = &(*ppPoslist)[-2];
char c = 0;
/* Skip backwards passed any trailing 0x00 bytes added by NearTrim() */
while( p>pStart && (c=*p--)==0 );
/* Search backwards for a varint with value zero (the end of the previous
** poslist). This is an 0x00 byte preceded by some byte that does not
** have the 0x80 bit set. */
while( p>pStart && (*p & 0x80) | c ){
c = *p--;
}
if( p>pStart ){ p = &p[2]; }
assert( p==pStart || c==0 );
/* At this point p points to that preceding byte without the 0x80 bit
** set. So to find the start of the poslist, skip forward 2 bytes then
** over a varint.
**
** Normally. The other case is that p==pStart and the poslist to return
** is the first in the doclist. In this case do not skip forward 2 bytes.
** The second part of the if condition (c==0 && *ppPoslist>&p[2])
** is required for cases where the first byte of a doclist and the
** doclist is empty. For example, if the first docid is 10, a doclist
** that begins with:
**
** 0x0A 0x00 <next docid delta varint>
*/
if( p>pStart || (c==0 && *ppPoslist>&p[2]) ){ p = &p[2]; }
while( *p++&0x80 );
*ppPoslist = p;
}
@@ -5765,7 +5785,8 @@ int sqlite3Fts3EvalPhrasePoslist(
pIter = pPhrase->pOrPoslist;
iDocid = pPhrase->iOrDocid;
if( pCsr->bDesc==bDescDoclist ){
bEof = (pIter >= (pPhrase->doclist.aAll + pPhrase->doclist.nAll));
bEof = !pPhrase->doclist.nAll ||
(pIter >= (pPhrase->doclist.aAll + pPhrase->doclist.nAll));
while( (pIter==0 || DOCID_CMP(iDocid, pCsr->iPrevId)<0 ) && bEof==0 ){
sqlite3Fts3DoclistNext(
bDescDoclist, pPhrase->doclist.aAll, pPhrase->doclist.nAll,
+4
View File
@@ -395,6 +395,10 @@ sqldiff$(EXE): $(TOP)/tool/sqldiff.c sqlite3.c sqlite3.h
$(TCCX) -o sqldiff$(EXE) -DSQLITE_THREADSAFE=0 \
$(TOP)/tool/sqldiff.c sqlite3.c $(TLIBS) $(THREADLIB)
fuzzershell$(EXE): $(TOP)/tool/fuzzershell.c sqlite3.c sqlite3.h
$(TCCX) -o fuzzershell$(EXE) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION\
$(TOP)/tool/fuzzershell.c sqlite3.c $(TLIBS) $(THREADLIB)
mptester$(EXE): sqlite3.c $(TOP)/mptest/mptest.c
$(TCCX) -o $@ -I. $(TOP)/mptest/mptest.c sqlite3.c \
$(TLIBS) $(THREADLIB)
+51 -50
View File
@@ -1,9 +1,9 @@
C Merge\srecent\strunk\sfixes\sand\senhancements\sinto\sthe\sapple-osx\sbranch.
D 2015-04-15T13:51:38.292
C Merge\sall\srecent\strunk\senhancements\sand\sfixes\sinto\sthe\sapple-osx\sbranch.
D 2015-04-20T01:25:56.443
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in d4fe123ecc0734164d927b3946bc69c98c579528
F Makefile.in 0dc7ac539680061505b2a3516299ae9a7e4595cd
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
F Makefile.msc 0078f5781538e07ea38683439f38d5f5ab79ab6e
F Makefile.msc a19bceec468fa18bb54df52257b1a2211e69172d
F Makefile.vxworks e1b65dea203f054e71653415bd8f96dcaed47858
F README.md d58e3bebc0a4145e0f2a87994015fdb575a8e866
F VERSION 2e244662b71e6e68a5c29b014ebc5b7564f4cc5a
@@ -78,7 +78,7 @@ F ext/fts3/README.content fdc666a70d5257a64fee209f97cf89e0e6e32b51
F ext/fts3/README.syntax a19711dc5458c20734b8e485e75fb1981ec2427a
F ext/fts3/README.tokenizers e0a8b81383ea60d0334d274fadf305ea14a8c314
F ext/fts3/README.txt 8c18f41574404623b76917b9da66fcb0ab38328d
F ext/fts3/fts3.c 4bd75289875b63c04f943d6ed7c31737da99cd74
F ext/fts3/fts3.c 29300a76fabbbb8fc30bb261c27d421df9f40c76
F ext/fts3/fts3.h 3a10a0af180d502cecc50df77b1b22df142817fe
F ext/fts3/fts3Int.h 3626655d6ba903a3919bb44e1c38e5f0f9d6be82
F ext/fts3/fts3_aux.c 5c211e17a64885faeb16b9ba7772f9d5445c2365
@@ -155,7 +155,7 @@ F ext/userauth/userauth.c 5fa3bdb492f481bbc1709fc83c91ebd13460c69e
F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x
F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8
F magic.txt 8273bf49ba3b0c8559cb2774495390c31fd61c60
F main.mk 5fcef49677a2ba6c1f2e9eb3dbae3e41c91f549d
F main.mk 2dcfa4c8133f4a3aad763fd00d4cf39ee35a084a
F mkopcodec.awk c2ff431854d702cdd2d779c9c0d1f58fa16fa4ea
F mkopcodeh.awk d5e22023b5238985bb54a72d33e0ac71fe4f8a32
F mkso.sh fd21c06b063bb16a5d25deea1752c2da6ac3ed83
@@ -163,7 +163,7 @@ F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271
F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504
F mptest/crash01.test 61e61469e257df0850df4293d7d4d6c2af301421
F mptest/crash02.subtest f4ef05adcd15d60e5d2bd654204f2c008b519df8
F mptest/mptest.c dae6de83eddac3ef97fc4111632f6066760f939a
F mptest/mptest.c fca59f0a922e03f95ed17c44b1515ed37a841c81
F mptest/multiwrite01.test dab5c5f8f9534971efce679152c5146da265222d
F spec.template 86a4a43b99ebb3e75e6b9a735d5fd293a24e90ca
F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b
@@ -171,21 +171,21 @@ F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786
F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a
F src/alter.c d23d6b6991f66b383934f137fd4384d93fb98c81
F src/analyze.c 91540f835163d5369ccbae78e2e6c74d0dd53c1d
F src/attach.c 3c1053a4cf1c3ca05c8c1d74a94cb688d763cef2
F src/attach.c c38ac5a520a231d5d0308fd7f2ad95191c867bae
F src/auth.c b56c78ebe40a2110fd361379f7e8162d23f92240
F src/backup.c ff743689c4d6c5cb55ad42ed9d174b2b3e71f1e3
F src/bitvec.c 19a4ba637bd85f8f63fc8c9bae5ade9fb05ec1cb
F src/btmutex.c 45a968cc85afed9b5e6cf55bf1f42f8d18107f79
F src/btree.c 66bb78f5a2d38e27b933848e70a97483ebbbe796
F src/btree.c d061b108bed81feeac24703a5b5a91153cabafb6
F src/btree.h 969adc948e89e449220ff0ff724c94bb2a52e9f1
F src/btreeInt.h 973a22a6fd61350b454ad614832b1f0a5e25a1e4
F src/build.c 01b969b20a44a3d9620e597d9af8242348123540
F src/build.c e246c2cea69c8f6fc825a156ea2de9dd4a17f18b
F src/callback.c 7b44ce59674338ad48b0e84e7b72f935ea4f68b0
F src/complete.c a5cf5b4b56390cfb7b8636e8f7ddef90258dd575
F src/ctime.c 98f89724adc891a1a4c655bee04e33e716e05887
F src/date.c e4d50b3283696836ec1036b695ead9a19e37a5ac
F src/delete.c 37964e6c1d73ff49cbea9ff690c9605fb15f600e
F src/expr.c 8800584340a9b4f4c0ca55c360de751c6da0b11a
F src/expr.c 5555f768c05d7d4a7840c6c2e72ad7aecbe0fe54
F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
F src/fkey.c 3343d551a8d810782257244fb33f2ce191493c39
F src/func.c 1414c24c873c48796ad45942257a179a423ba42f
@@ -193,7 +193,7 @@ F src/global.c 4f77cadbc5427d00139ba43d0f3979804cbb700e
F src/hash.c 4263fbc955f26c2e8cdc0cf214bc42435aa4e4f5
F src/hash.h c8f3c31722cf3277d03713909761e152a5b81094
F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08
F src/insert.c 305dd3f9539d0affa4bf1c14cc7dffb34867e040
F src/insert.c b152e71457c40a3967ceafa9e7cbbb52e9ead2c1
F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d
F src/legacy.c 9c17d86e06522c261307f0eb6bcb1254c8b04a59
F src/lempar.c 7274c97d24bb46631e504332ccd3bd1b37841770
@@ -222,24 +222,24 @@ F src/os_win.c 93f8662844dc935280a1851d15c823f1e6857408
F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca
F src/pager.c 694caffb16891a96608193968d7c9a8fa9a71240
F src/pager.h 5ead19acf64a16b7b663476bd36c60d26f03a696
F src/parse.y 1299c66e7b1707322ccd8af43a359b8fb0d46d72
F src/parse.y c4e0387bc88c8e21e5ba653e2578959a1f3cdbc7
F src/pcache.c 10539fb959849ad6efff80050541cab3d25089d4
F src/pcache.h b44658c9c932d203510279439d891a2a83e12ba8
F src/pcache1.c 69d137620a305f814398bd29a0c998038c0695e9
F src/pragma.c db44f204be8289e43d6a7f728bbfe3cdf0c9c906
F src/pragma.c 17e0049780fee7594233d627ad8da19a81a335c7
F src/pragma.h 09c89bca58e9a44de2116cc8272b8d454657129f
F src/prepare.c 01740b0d6b8f5c6da421a86c300464ff5b53e167
F src/prepare.c 5be49833da7f82806a4957cb91ad4e8f2453808f
F src/printf.c 08fa675c200aac29e561c6153f91f909ed17612f
F src/random.c ba2679f80ec82c4190062d756f22d0c358180696
F src/resolve.c 66cfe49a9c3b449ef13b89a8c47036a4ed167eab
F src/resolve.c 53486a98c17b7ae09b8c2b398013e973ce4c1aae
F src/rowset.c eccf6af6d620aaa4579bd3b72c1b6395d9e9fa1e
F src/select.c ee49a7bf39b9ba7ada6d944c1a11fecb7157551e
F src/shell.c 84a1593bd86aaa14f4da8a8f9b16fbc239d262aa
F src/select.c 217d181aaf31e12c4a94905dd12c21e1ca76c67d
F src/shell.c 28b3e1174a7fc00155d7d00880a33589a88508c9
F src/sqlite.h.in a57fba23bfa1b17e60e6bd682f9614ab59272390
F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad
F src/sqlite3_private.h a81a9c5f97c095cc3e86914a05f8fabe0011f4a1
F src/sqlite3ext.h 17d487c3c91b0b8c584a32fbeb393f6f795eea7d
F src/sqliteInt.h 92d2e2925bb33a29ef7cebd251afec81081411db
F src/sqliteInt.h 892e58b816cb9588e4ff0e39628372b628a3e1cf
F src/sqliteLimit.h 216557999cb45f2e3578ed53ebefe228d779cb46
F src/status.c f266ad8a2892d659b74f0f50cb6a88b6e7c12179
F src/table.c e7a09215315a978057fb42c640f890160dbcc45e
@@ -291,22 +291,22 @@ F src/test_vfs.c b7e6831e6fcf04c5090accff30640ec5c9630739
F src/test_vfstrace.c bab9594adc976cbe696ff3970728830b4c5ed698
F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9
F src/threads.c 6bbcc9fe50c917864d48287b4792d46d6e873481
F src/tokenize.c a8234a67577308935cdf13e618cd66556f5f45d1
F src/trigger.c 69a91bed7c94e46223e37ffccfeeb35e34b999ac
F src/tokenize.c b7fb584c2be5ec39b6fdf04b185e7c6f33f8dc15
F src/trigger.c bc647c712454c9b209fac082bb82870b5fd6fa54
F src/update.c 3c4ecc282accf12d39edb8d524cf089645e55a13
F src/utf.c fc6b889ba0779b7722634cdeaa25f1930d93820c
F src/util.c 98a7627ca48ad3265b6940915a1d08355eb3fc7e
F src/util.c a6431c92803b975b7322724a7b433e538d243539
F src/vacuum.c 2ddd5cad2a7b9cef7f9e431b8c7771634c6b1701
F src/vdbe.c 7b63a9dfdae77949cd41f1ce6f0eaa9af78609e6
F src/vdbe.c 32e165d7a3b701ad7ec251176dc64a357740d8f8
F src/vdbe.h 7e538ecf47dccb307ea2d087c3ddc2dd8d70e79d
F src/vdbeInt.h 9cbaa84f53ddd2d09a0cf61a94337a3a035d08a0
F src/vdbeapi.c 36861a49fcb11325e2fce937418b06ce1e3de1a8
F src/vdbeaux.c 8d4b5165fbf4fed0ed7fd0f657368965383d2d55
F src/vdbeaux.c 85b76767552077c3f4d169cefb74833bc60cdb1a
F src/vdbeblob.c 4f2e8e075d238392df98c5e03a64342465b03f90
F src/vdbemem.c c0dc81285b7571b0a31c40f17846fe2397ec1cd9
F src/vdbesort.c 2e7f683464fd5db3be4beaa1ff2d39e24fcb64b8
F src/vdbetrace.c 7e4222955e07dd707a2f360c0eb73452be1cb010
F src/vtab.c 9ca557215e8591ceb66e0b7c0a579c6df1e54b2d
F src/vdbetrace.c f95c2dff9041fcf07f871789c22ebb0648ea0b7c
F src/vtab.c 5f81f8a59c1f5ddb94c918f25ed5d83578fcc633
F src/vxworks.h c18586c8edc1bddbc15c004fa16aeb1e1342b4fb
F src/wal.c de15f46df1161b925a9a509b39bc750f1951cdd7
F src/wal.h 6b3a67ecd7172dcc9f18fc9cd4d76dc4c2166e68
@@ -324,7 +324,7 @@ F test/alter3.test 49c9d9fba2b8fcdce2dedeca97bbf1f369cc548d
F test/alter4.test c461150723ac957f3b2214aa0b11552cd72023ec
F test/altermalloc.test e81ac9657ed25c6c5bb09bebfa5a047cd8e4acfc
F test/amatch1.test b5ae7065f042b7f4c1c922933f4700add50cdb9f
F test/analyze.test 1772936d66471c65221e437b6d1999c3a03166c4
F test/analyze.test 3eb35a4af972f98422e5dc0586501b17d103d321
F test/analyze3.test 75b9e42ea1e4edc919250450dc5762186965d4e6
F test/analyze4.test eff2df19b8dd84529966420f29ea52edc6b56213
F test/analyze5.test 765c4e284aa69ca172772aa940946f55629bc8c4
@@ -430,7 +430,7 @@ F test/corrupt8.test 2399dfe40d2c0c63af86706e30f3e6302a8d0516
F test/corrupt9.test 730a3db08d4ab9aa43392ea30d9c2b4879cbff85
F test/corruptA.test 53e56dafd180addcdadb402244b8cb9771d2ba26
F test/corruptB.test 73a8d6c0b9833697ecf16b63e3c5c05c945b5dec
F test/corruptC.test 02405cf7ed0c1e989060e1aab6d02ffbc3906fbb
F test/corruptC.test 3fcc0f73d2cf2d69befe2d96332b942426a6aae2
F test/corruptD.test b3c205fac7952b1de645ce44bb02335cd9e3e040
F test/corruptE.test 193b4ca4e927e77c1d5f4f56203ddc998432a7ee
F test/corruptF.test be9fde98e4c93648f1ba52b74e5318edc8f59fe4
@@ -480,7 +480,7 @@ F test/e_expr.test 8f5fdd7261e2d746813b0c6a1c0e34824ad3c5ad
F test/e_fkey.test a1783fe1f759e1990e6a11adfcf0702dac4d0707
F test/e_fts3.test 5c02288842e4f941896fd44afdef564dd5fc1459
F test/e_insert.test 0e63edc037afe738bb81a626a676811ed7862c90
F test/e_reindex.test 396b7b4f0a66863b4e95116a67d93b227193e589
F test/e_reindex.test 57d439f6c644befc8274ac93cf2f5449cf2736c1
F test/e_resolve.test dcce9308fb13b934ce29591105d031d3e14fbba6
F test/e_select.test 52692ff3849541e828ad4661fe3773a9b8711763
F test/e_select2.test aceb80ab927d46fba5ce7586ebabf23e2bb0604f
@@ -503,13 +503,13 @@ F test/exclusive.test c0d5e3c0756ac6ccd4d45e0b21ff9f01b963fa61
F test/exclusive2.test 32798111aae78a5deec980eee383213f189df308
F test/exec.test e949714dc127eaa5ecc7d723efec1ec27118fdd7
F test/exists.test 8f7b27b61c2fbe5822f0a1f899c715d14e416e30
F test/expr.test c4b9bf0cc60b26862475e19999fbd2609ca8259c
F test/expr.test 79c3e7502d9e571553b85f0ecc8ff2ac7d0e4931
F test/extension01.test 00d13cec817f331a687a243e0e5a2d87b0e358c9
F test/fallocate.test fe52076a43ff99da8411990dbb4f374e81e88c85
F test/filectrl.test 14fa712e42c4cb791e09dfd58a6a03efb47ef13a
F test/filefmt.test cb34663f126cbc2d358af552dcaf5c72769b0146
F test/fkey1.test e1d1fa84cde579185ea01358436839703e415a5b
F test/fkey2.test 223c624e7eccee21e89c98d4d127ac88d774b940
F test/fkey2.test f3d27ecba480a348c328965d154214719bb158a9
F test/fkey3.test 76d475c80b84ee7a5d062e56ccb6ea68882e2b49
F test/fkey4.test 86446017011273aad8f9a99c1a65019e7bd9ca9d
F test/fkey5.test 56bcb5a6e8b725b17febc267fb041a6695e86853
@@ -555,7 +555,7 @@ F test/fts2r.test b154c30b63061d8725e320fba1a39e2201cadd5e
F test/fts2token.test d8070b241a15ff13592a9ae4a8b7c171af6f445a
F test/fts3.test 672a040ea57036fb4b6fdc09027c18d7d24ab654
F test/fts3_common.tcl 99cf6659b87c0f74f55963c2aea03b3a7d66ceb0
F test/fts3aa.test edd20ddbbc5b6015ab340abf2ca278ae11ec387d
F test/fts3aa.test 6c263a6f8845205ee02550981a94c2e8dc1e7058
F test/fts3ab.test 7f6cf260ae80dda064023df8e8e503e9a412b91f
F test/fts3ac.test 636ed7486043055d4f126a0e385f2d5a82ebbf63
F test/fts3ad.test e40570cb6f74f059129ad48bcef3d7cbc20dda49
@@ -659,18 +659,18 @@ F test/incrvacuum3.test 75256fb1377e7c39ef2de62bfc42bbff67be295a
F test/incrvacuum_ioerr.test 6ae2f783424e47a0033304808fe27789cf93e635
F test/index.test 4d990005a67a36984e4f1a5f1bdccea8d08da4ee
F test/index2.test ee83c6b5e3173a3d7137140d945d9a5d4fdfb9d6
F test/index3.test 55a90cff99834305e8141df7afaef39674b57062
F test/index3.test b6ec456cf3b81d9a32123fe7e449bde434db338b
F test/index4.test ab92e736d5946840236cd61ac3191f91a7856bf6
F test/index5.test 25b0b451aceed4ac5f7d49f856f6de7257470b3e
F test/index6.test 3ae54e53c53f2adcacda269237d8e52bdb05a481
F test/index7.test 3d54dce09344c4530ea39a458aa304da044c887a
F test/index7.test 9c6765a74fc3fcde7aebc5b3bd40d98df14a527c
F test/indexedby.test 5f527a78bae74c61b8046ae3037f9dfb0bf0c353
F test/indexfault.test 31d4ab9a7d2f6e9616933eb079722362a883eb1d
F test/init.test 15c823093fdabbf7b531fe22cf037134d09587a7
F test/insert.test 38742b5e9601c8f8d76e9b7555f7270288c2d371
F test/insert2.test 4f3a04d168c728ed5ec2c88842e772606c7ce435
F test/insert3.test 1b7db95a03ad9c5013fdf7d6722b6cd66ee55e30
F test/insert4.test 4791662c50518bdd37d394cae9a7a8014e845bb3
F test/insert4.test a20432f1c0fbbcff8f11d0e6ab4acb8c9db58023
F test/insert5.test 394f96728d1258f406fe5f5aeb0aaf29487c39a6
F test/instr.test 737bbf80685232033f3abedc6ae92f75860b5dd2
F test/intarray.test 066b7d7ac38d25bf96f87f1b017bfc687551cdd4
@@ -748,11 +748,11 @@ F test/minmax.test 42fbad0e81afaa6e0de41c960329f2b2c3526efd
F test/minmax2.test b44bae787fc7b227597b01b0ca5575c7cb54d3bc
F test/minmax3.test cc1e8b010136db0d01a6f2a29ba5a9f321034354
F test/minmax4.test 936941484ebdceb8adec7c86b6cd9b6e5e897c1f
F test/misc1.test 9abcae9a0b8785d6fa92925dbb19c309ae9ea077
F test/misc1.test 783ba75743b2cf71e0f646bf540a6cef57264811
F test/misc2.test 00d7de54eda90e237fc9a38b9e5ccc769ebf6d4d
F test/misc3.test cf3dda47d5dda3e53fc5804a100d3c82be736c9d
F test/misc4.test 9c078510fbfff05a9869a0b6d8b86a623ad2c4f6
F test/misc5.test 528468b26d03303b1f047146e5eefc941b9069f5
F test/misc5.test f96428ea95b3820aafc6f1c50cf48a09e4597ee1
F test/misc6.test 953cc693924d88e6117aeba16f46f0bf5abede91
F test/misc7.test edd0b63e2ee29a256900b0514f6fff27e19e9bb2
F test/misc8.test fc2754d38892f7dac30c22db3616c2764f117d66
@@ -799,7 +799,7 @@ F test/pcache.test 488061b5dd685df2234d690370285c9b4813377b
F test/pcache2.test a83efe2dec0d392f814bfc998def1d1833942025
F test/percentile.test 4243af26b8f3f4555abe166f723715a1f74c77ff
F test/permutations.test f9cc1dd987986c9d4949211c7a4ed55ec9aecba1
F test/pragma.test 28748a49b4213aeeae9939257ae486fef09b005a
F test/pragma.test 69cc5c349f86bd06ca52f73c501ff1cee940126f
F test/pragma2.test f624a496a95ee878e81e59961eade66d5c00c028
F test/pragma3.test 6f849ccffeee7e496d2f2b5e74152306c0b8757c
F test/printf.test b3ff34e73d59124140eaf89f7672e21bc2ca5fcc
@@ -817,7 +817,7 @@ F test/randexpr1.test eda062a97e60f9c38ae8d806b03b0ddf23d796df
F test/rdonly.test 64e2696c322e3538df0b1ed624e21f9a23ed9ff8
F test/regexp1.test 497ea812f264d12b6198d6e50a76be4a1973a9d8
F test/reindex.test 44edd3966b474468b823d481eafef0c305022254
F test/releasetest.tcl 13f401c10dd4fe1a2fb811ae6ed27fd7d1300d3c
F test/releasetest.tcl a37cd82092c8be438255d65804b5951d6e3ecdae
F test/resolver01.test 33abf37ff8335e6bf98f2b45a0af3e06996ccd9a
F test/rollback.test 458fe73eb3ffdfdf9f6ba3e9b7350a6220414dea
F test/rollback2.test fc14cf6d1a2b250d2735ef16124b971bce152f14
@@ -841,10 +841,10 @@ F test/schema4.test e6a66e20cc69f0e306667c08be7fda3d11707dc5
F test/schema5.test 29699b4421f183c8f0e88bd28ce7d75d13ea653e
F test/securedel.test 21749c32ccc30f1ea9e4b9f33295a6521ec20fa0
F test/securedel2.test 2d54c28e46eb1fd6902089958b20b1b056c6f1c5
F test/select1.test fc2a61f226a649393664ad54bc5376631801517c
F test/select1.test be62204d2bd9a5a8a149e9974cfddce893d8f686
F test/select2.test 352480e0e9c66eda9c3044e412abdf5be0215b56
F test/select3.test 2ce595f8fb8e2ac10071d3b4e424cadd4634a054
F test/select4.test 16fa1cafb942f42294ec85cbb78954c2f2d15a44
F test/select4.test a3201fa921fdfc1397cc629e78c7a976e198a40d
F test/select5.test e758b8ef94f69b111df4cb819008856655dcd535
F test/select6.test 39eac4a5c03650b2b473c532882273283ee8b7a0
F test/select7.test 7fd2ef598cfabb6b9ff6ac13973b91d0527df49d
@@ -913,7 +913,7 @@ F test/superlock.test 2b27b4ae7c6b9d534b0412e0d99f989aa1f3b9cf
F test/sync.test a34cd43e98b7fb84eabbf38f7ed8f7349b3f3d85
F test/syscall.test d2fdaad713f103ac611fe7ef9b724c7b69f8149c
F test/sysfault.test fa776e60bf46bdd3ae69f0b73e46ee3977a58ae6
F test/table.test 06271d61eb13871490d38168433c1ef3dd82bb2a
F test/table.test bd841e8df69b99172ce9c7d53587463913d711ca
F test/tableapi.test 2674633fa95d80da917571ebdd759a14d9819126
F test/tableopts.test dba698ba97251017b7c80d738c198d39ab747930
F test/tclsqlite.test 7fb866443c7deceed22b63948ccd6f76b52ad054
@@ -1087,7 +1087,7 @@ F test/trigger3.test aa640bb2bbb03edd5ff69c055117ea088f121945
F test/trigger4.test 74700b76ebf3947b2f7a92405141eb2cf2a5d359
F test/trigger5.test 619391a3e9fc194081d22cefd830d811e7badf83
F test/trigger6.test 0e411654f122552da6590f0b4e6f781048a4a9b9
F test/trigger7.test b39e6dee1debe0ff9c2ef66326668f149f07c9c4
F test/trigger7.test 200dd51e728c9cdc20c72d99d9e9d45c667248f8
F test/trigger8.test 30cb0530bd7c4728055420e3f739aa00412eafa4
F test/trigger9.test 2226ec795a33b0460ab5cf8891e9054cc7edef41
F test/triggerA.test fe5597f47ee21bacb4936dc827994ed94161e332
@@ -1118,7 +1118,7 @@ F test/vacuum4.test d3f8ecff345f166911568f397d2432c16d2867d9
F test/varint.test ab7b110089a08b9926ed7390e7e97bdefeb74102
F test/veryquick.test 57ab846bacf7b90cf4e9a672721ea5c5b669b661
F test/view.test f311691d696a5cc27e3c1b875cec1b0866b4ccd9
F test/vtab1.test c9dc2a73e93331d70b37ce4b246ef6dc18412fef
F test/vtab1.test d1e5ec7a818f1d3f0402382b6a1d0c06071b770f
F test/vtab2.test 3644649aa8d1daac57fd541f6a5f914cac59203e
F test/vtab3.test b45f47d20f225ccc9c28dc915d92740c2dee311e
F test/vtab4.test 942f8b8280b3ea8a41dae20e7822d065ca1cb275
@@ -1127,7 +1127,7 @@ F test/vtab6.test 5f5380c425e52993560ab4763db4f826d2ba7b09
F test/vtab7.test ae560ebea870ed04e9aa4177cc302f910faaabb5
F test/vtab8.test e19fa4a538fcd1bb66c22825fa8f71618fb13583
F test/vtab9.test ea58d2b95d61955f87226381716b2d0b1d4e4f9b
F test/vtabA.test c86e1990b7e1e2bb34602a06fffa4c69f2b516dc
F test/vtabA.test 1317f06a03597eee29f40a49b6c21e1aaba4285f
F test/vtabB.test 04df5dc531b9f44d9ca65b9c1b79f12b5922a796
F test/vtabC.test 4528f459a13136f982e75614d120aef165f17292
F test/vtabD.test 05b3f1d77117271671089e48719524b676842e96
@@ -1208,6 +1208,7 @@ F tool/diffdb.c 7524b1b5df217c20cd0431f6789851a4e0cb191b
F tool/extract.c 054069d81b095fbdc189a6f5d4466e40380505e2
F tool/fast_vacuum.c 5ba0d6f5963a0a63bdc42840f678bad75b2ebce1
F tool/fragck.tcl 5265a95126abcf6ab357f7efa544787e5963f439
F tool/fuzzershell.c 9e7e273da203037154b433bb67f10b0d9772b370
F tool/genfkey.README cf68fddd4643bbe3ff8e31b8b6d8b0a1b85e20f4
F tool/genfkey.test 4196a8928b78f51d54ef58e99e99401ab2f0a7e5
F tool/getlock.c f4c39b651370156cae979501a7b156bdba50e7ce
@@ -1230,7 +1231,7 @@ F tool/opcodeDoc.awk b3a2a3d5d3075b8bd90b7afe24283efdd586659c
F tool/pagesig.c ff0ca355fd3c2398e933da5e22439bbff89b803b
F tool/restore_jrnl.tcl 6957a34f8f1f0f8285e07536225ec3b292a9024a
F tool/rollback-test.c 9fc98427d1e23e84429d7e6d07d9094fbdec65a5
F tool/showdb.c 63cdef19e7fbca0c164b096ef8aef3bb9e9dd222
F tool/showdb.c 3b5d335d537e4dc44d0c86967023819453c87dc6
F tool/showjournal.c 053eb1cc774710c6890b7dd6293300cc297b16a5
F tool/showlocks.c 9920bcc64f58378ff1118caead34147201f48c68
F tool/showstat4.c 9515faa8ec176599d4a8288293ba8ec61f7b728a
@@ -1244,7 +1245,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
F tool/split-sqlite3c.tcl d9be87f1c340285a3e081eb19b4a247981ed290c
F tool/sqldiff.c 5c16cf3a1f566873abbdecac0d13a6691437564f
F tool/sqldiff.c 393b0f5b17ef29341664563a90d40ee63a0a18f7
F tool/stack_usage.tcl f8e71b92cdb099a147dad572375595eae55eca43
F tool/symbols-mingw.sh 4dbcea7e74768305384c9fd2ed2b41bbf9f0414d
F tool/symbols.sh fec58532668296d7c7dc48be9c87f75ccdb5814f
@@ -1255,7 +1256,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
P e709d3b4e7b91331f58ed8319f98790cfb190cb1 bd06eeb8d06237dc2d54d8a03e8bf525cb811c9e
R f034ab8024215b05e2d8221a81ae3b34
P bfc7142ad295c4b04078f9c01030bdbd15f024e8 592c010478fba7410424f011a62e019c826f1ac3
R 65a49022ceca7cc6e1f2dfc581f9ff77
U drh
Z 8ae6163cdf4d66ea49f55e3eb7c94bf7
Z 2ba0195ba41fcb8cc4ac8903189d5cd1
+1 -1
View File
@@ -1 +1 @@
bfc7142ad295c4b04078f9c01030bdbd15f024e8
74b7bf17446bc21a73fa5b75c2942b5660b0ad7e
+12 -5
View File
@@ -53,6 +53,13 @@
# define GETPID getpid
#endif
/* The directory separator character(s) */
#if defined(_WIN32)
# define isDirSep(c) (((c) == '/') || ((c) == '\\'))
#else
# define isDirSep(c) ((c) == '/')
#endif
/* Mark a parameter as unused to suppress compiler warnings */
#define UNUSED_PARAMETER(x) (void)x
@@ -824,7 +831,7 @@ static void waitForClient(int iClient, int iTimeout, char *zErrPrefix){
*/
static char *filenameTail(char *z){
int i, j;
for(i=j=0; z[i]; i++) if( z[i]=='/' ) j = i+1;
for(i=j=0; z[i]; i++) if( isDirSep(z[i]) ) j = i+1;
return z+j;
}
@@ -1021,9 +1028,9 @@ static void runScript(
char *zNewFile, *zNewScript;
char *zToDel = 0;
zNewFile = azArg[0];
if( zNewFile[0]!='/' ){
if( !isDirSep(zNewFile[0]) ){
int k;
for(k=(int)strlen(zFilename)-1; k>=0 && zFilename[k]!='/'; k--){}
for(k=(int)strlen(zFilename)-1; k>=0 && !isDirSep(zFilename[k]); k--){}
if( k>0 ){
zNewFile = zToDel = sqlite3_mprintf("%.*s/%s", k,zFilename,zNewFile);
}
@@ -1231,7 +1238,7 @@ static void usage(const char *argv0){
int i;
const char *zTail = argv0;
for(i=0; argv0[i]; i++){
if( argv0[i]=='/' ) zTail = argv0+i+1;
if( isDirSep(argv0[i]) ) zTail = argv0+i+1;
}
fprintf(stderr,"Usage: %s DATABASE ?OPTIONS? ?SCRIPT?\n", zTail);
exit(1);
@@ -1338,6 +1345,7 @@ int SQLITE_CDECL main(int argc, char **argv){
#endif
runSql("PRAGMA journal_mode=%Q;", zJMode);
}
if( !g.bSync ) trySql("PRAGMA synchronous=OFF");
sqlite3_enable_load_extension(g.db, 1);
sqlite3_busy_handler(g.db, busyHandler, 0);
sqlite3_create_function(g.db, "vfsname", 0, SQLITE_UTF8, 0,
@@ -1346,7 +1354,6 @@ int SQLITE_CDECL main(int argc, char **argv){
evalFunc, 0, 0);
g.iTimeout = DEFAULT_TIMEOUT;
if( g.bSqlTrace ) sqlite3_trace(g.db, sqlTraceCallback, 0);
if( !g.bSync ) trySql("PRAGMA synchronous=OFF");
if( iClient>0 ){
if( n>0 ) unrecognizedArguments(argv[0], n, argv+2);
if( g.iTrace ) logMessage("start-client");
-1
View File
@@ -332,7 +332,6 @@ static void codeAttach(
SQLITE_OK!=(rc = resolveAttachExpr(&sName, pDbname)) ||
SQLITE_OK!=(rc = resolveAttachExpr(&sName, pKey))
){
pParse->nErr++;
goto attach_end;
}
+78 -16
View File
@@ -4478,13 +4478,18 @@ static const void *fetchPayload(
BtCursor *pCur, /* Cursor pointing to entry to read from */
u32 *pAmt /* Write the number of available bytes here */
){
u32 amt;
assert( pCur!=0 && pCur->iPage>=0 && pCur->apPage[pCur->iPage]);
assert( pCur->eState==CURSOR_VALID );
assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) );
assert( cursorHoldsMutex(pCur) );
assert( pCur->aiIdx[pCur->iPage]<pCur->apPage[pCur->iPage]->nCell );
assert( pCur->info.nSize>0 );
*pAmt = pCur->info.nLocal;
assert( pCur->info.pPayload>pCur->apPage[pCur->iPage]->aData || CORRUPT_DB );
assert( pCur->info.pPayload<pCur->apPage[pCur->iPage]->aDataEnd ||CORRUPT_DB);
amt = (int)(pCur->apPage[pCur->iPage]->aDataEnd - pCur->info.pPayload);
if( pCur->info.nLocal<amt ) amt = pCur->info.nLocal;
*pAmt = amt;
return (void*)pCur->info.pPayload;
}
@@ -8550,6 +8555,57 @@ static void checkList(
}
#endif /* SQLITE_OMIT_INTEGRITY_CHECK */
/*
** An implementation of a min-heap.
**
** aHeap[0] is the number of elements on the heap. aHeap[1] is the
** root element. The daughter nodes of aHeap[N] are aHeap[N*2]
** and aHeap[N*2+1].
**
** The heap property is this: Every node is less than or equal to both
** of its daughter nodes. A consequence of the heap property is that the
** root node aHeap[1] is always the minimum value current in the heap.
**
** The btreeHeapInsert() routine inserts an unsigned 32-bit number onto
** the heap, preserving the heap property. The btreeHeapPull() routine
** removes the root element from the heap (the minimum value in the heap)
** and then move other nodes around as necessary to preserve the heap
** property.
**
** This heap is used for cell overlap and coverage testing. Each u32
** entry represents the span of a cell or freeblock on a btree page.
** The upper 16 bits are the index of the first byte of a range and the
** lower 16 bits are the index of the last byte of that range.
*/
static void btreeHeapInsert(u32 *aHeap, u32 x){
u32 j, i = ++aHeap[0];
aHeap[i] = x;
while( (j = i/2)>0 && aHeap[j]>aHeap[i] ){
x = aHeap[j];
aHeap[j] = aHeap[i];
aHeap[i] = x;
i = j;
}
}
static int btreeHeapPull(u32 *aHeap, u32 *pOut){
u32 j, i, x;
if( (x = aHeap[0])==0 ) return 0;
*pOut = aHeap[1];
aHeap[1] = aHeap[x];
aHeap[x] = 0xffffffff;
aHeap[0]--;
i = 1;
while( (j = i*2)<=aHeap[0] ){
if( aHeap[j]>aHeap[j+1] ) j++;
if( aHeap[i]<aHeap[j] ) break;
x = aHeap[i];
aHeap[i] = aHeap[j];
aHeap[j] = x;
i = j;
}
return 1;
}
#ifndef SQLITE_OMIT_INTEGRITY_CHECK
/*
** Do various sanity checks on a single page of a tree. Return
@@ -8582,7 +8638,8 @@ static int checkTreePage(
u8 *data;
BtShared *pBt;
int usableSize;
char *hit = 0;
u32 *heap = 0;
u32 x, prev = 0;
i64 nMinKey = 0;
i64 nMaxKey = 0;
const char *saved_zPfx = pCheck->zPfx;
@@ -8727,15 +8784,15 @@ static int checkTreePage(
*/
data = pPage->aData;
hdr = pPage->hdrOffset;
hit = sqlite3PageMalloc( pBt->pageSize );
heap = (u32*)sqlite3PageMalloc( pBt->pageSize );
pCheck->zPfx = 0;
if( hit==0 ){
if( heap==0 ){
pCheck->mallocFailed = 1;
}else{
int contentOffset = get2byteNotZero(&data[hdr+5]);
assert( contentOffset<=usableSize ); /* Enforced by btreeInitPage() */
memset(hit+contentOffset, 0, usableSize-contentOffset);
memset(hit, 1, contentOffset);
heap[0] = 0;
btreeHeapInsert(heap, contentOffset-1);
/* EVIDENCE-OF: R-37002-32774 The two-byte integer at offset 3 gives the
** number of cells on the page. */
nCell = get2byte(&data[hdr+3]);
@@ -8747,7 +8804,6 @@ static int checkTreePage(
for(i=0; i<nCell; i++){
int pc = get2byte(&data[cellStart+i*2]);
u32 size = 65536;
int j;
if( pc<=usableSize-4 ){
size = cellSizePtr(pPage, &data[pc]);
}
@@ -8756,7 +8812,7 @@ static int checkTreePage(
checkAppendMsg(pCheck,
"Corruption detected in cell %d on page %d",i,iPage);
}else{
for(j=pc+size-1; j>=pc; j--) hit[j]++;
btreeHeapInsert(heap, (pc<<16)|(pc+size-1));
}
}
/* EVIDENCE-OF: R-20690-50594 The second field of the b-tree page header
@@ -8768,7 +8824,7 @@ static int checkTreePage(
assert( i<=usableSize-4 ); /* Enforced by btreeInitPage() */
size = get2byte(&data[i+2]);
assert( i+size<=usableSize ); /* Enforced by btreeInitPage() */
for(j=i+size-1; j>=i; j--) hit[j]++;
btreeHeapInsert(heap, (i<<16)|(i+size-1));
/* EVIDENCE-OF: R-58208-19414 The first 2 bytes of a freeblock are a
** big-endian integer which is the offset in the b-tree page of the next
** freeblock in the chain, or zero if the freeblock is the last on the
@@ -8780,27 +8836,33 @@ static int checkTreePage(
assert( j<=usableSize-4 ); /* Enforced by btreeInitPage() */
i = j;
}
for(i=cnt=0; i<usableSize; i++){
if( hit[i]==0 ){
cnt++;
}else if( hit[i]>1 ){
cnt = 0;
assert( heap[0]>0 );
assert( (heap[1]>>16)==0 );
btreeHeapPull(heap,&prev);
while( btreeHeapPull(heap,&x) ){
if( (prev&0xffff)+1>(x>>16) ){
checkAppendMsg(pCheck,
"Multiple uses for byte %d of page %d", i, iPage);
"Multiple uses for byte %u of page %d", x>>16, iPage);
break;
}else{
cnt += (x>>16) - (prev&0xffff) - 1;
prev = x;
}
}
cnt += usableSize - (prev&0xffff) - 1;
/* EVIDENCE-OF: R-43263-13491 The total number of bytes in all fragments
** is stored in the fifth field of the b-tree page header.
** EVIDENCE-OF: R-07161-27322 The one-byte integer at offset 7 gives the
** number of fragmented free bytes within the cell content area.
*/
if( cnt!=data[hdr+7] ){
if( heap[0]==0 && cnt!=data[hdr+7] ){
checkAppendMsg(pCheck,
"Fragmentation of %d bytes reported as %d on page %d",
cnt, data[hdr+7], iPage);
}
}
sqlite3PageFree(hit);
sqlite3PageFree(heap);
releasePage(pPage);
end_of_check:
+9 -8
View File
@@ -142,9 +142,11 @@ void sqlite3FinishCoding(Parse *pParse){
assert( pParse->pToplevel==0 );
db = pParse->db;
if( db->mallocFailed ) return;
if( pParse->nested ) return;
if( pParse->nErr ) return;
if( db->mallocFailed || pParse->nErr ){
if( pParse->rc==SQLITE_OK ) pParse->rc = SQLITE_ERROR;
return;
}
/* Begin by generating some termination code at the end of the
** vdbe program
@@ -761,14 +763,12 @@ int sqlite3TwoPartName(
if( ALWAYS(pName2!=0) && pName2->n>0 ){
if( db->init.busy ) {
sqlite3ErrorMsg(pParse, "corrupt database");
pParse->nErr++;
return -1;
}
*pUnqual = pName2;
iDb = sqlite3FindDb(db, pName1);
if( iDb<0 ){
sqlite3ErrorMsg(pParse, "unknown database %T", pName1);
pParse->nErr++;
return -1;
}
}else{
@@ -927,7 +927,7 @@ void sqlite3StartTable(
if( !noErr ){
sqlite3ErrorMsg(pParse, "table %T already exists", pName);
}else{
assert( !db->init.busy );
assert( !db->init.busy || CORRUPT_DB );
sqlite3CodeVerifySchema(pParse, iDb);
}
goto begin_table_error;
@@ -1216,7 +1216,8 @@ void sqlite3AddColumnType(Parse *pParse, Token *pType){
p = pParse->pNewTable;
if( p==0 || NEVER(p->nCol<1) ) return;
pCol = &p->aCol[p->nCol-1];
assert( pCol->zType==0 );
assert( pCol->zType==0 || CORRUPT_DB );
sqlite3DbFree(pParse->db, pCol->zType);
pCol->zType = sqlite3NameFromToken(pParse->db, pType);
pCol->affinity = sqlite3AffinityType(pCol->zType, &pCol->szEst);
}
@@ -2450,6 +2451,7 @@ void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView, int noErr){
}
assert( pParse->nErr==0 );
assert( pName->nSrc==1 );
if( sqlite3ReadSchema(pParse) ) goto exit_drop_table;
if( noErr ) db->suppressErr++;
pTab = sqlite3LocateTableItem(pParse, isView, &pName->a[0]);
if( noErr ) db->suppressErr--;
@@ -2857,8 +2859,7 @@ Index *sqlite3CreateIndex(
char *zExtra = 0; /* Extra space after the Index object */
Index *pPk = 0; /* PRIMARY KEY index for WITHOUT ROWID tables */
assert( pParse->nErr==0 ); /* Never called with prior errors */
if( db->mallocFailed || IN_DECLARE_VTAB ){
if( db->mallocFailed || IN_DECLARE_VTAB || pParse->nErr>0 ){
goto exit_create_index;
}
if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){
+4 -3
View File
@@ -1251,7 +1251,8 @@ u32 sqlite3ExprListFlags(const ExprList *pList){
u32 m = 0;
if( pList ){
for(i=0; i<pList->nExpr; i++){
m |= pList->a[i].pExpr->flags;
Expr *pExpr = pList->a[i].pExpr;
if( ALWAYS(pExpr) ) m |= pList->a[i].pExpr->flags;
}
}
return m;
@@ -2016,7 +2017,7 @@ int sqlite3CodeSubselect(
pSel->pLimit = sqlite3PExpr(pParse, TK_INTEGER, 0, 0,
&sqlite3IntTokens[1]);
pSel->iLimit = 0;
pSel->selFlags &= ~SF_AllValues;
pSel->selFlags &= ~SF_MultiValue;
if( sqlite3Select(pParse, pSel, &dest) ){
return 0;
}
@@ -4017,7 +4018,7 @@ int sqlite3ExprCompare(Expr *pA, Expr *pB, int iTab){
if( sqlite3ExprCompare(pA->pLeft, pB->pLeft, iTab) ) return 2;
if( sqlite3ExprCompare(pA->pRight, pB->pRight, iTab) ) return 2;
if( sqlite3ExprListCompare(pA->x.pList, pB->x.pList, iTab) ) return 2;
if( ALWAYS((combinedFlags & EP_Reduced)==0) ){
if( ALWAYS((combinedFlags & EP_Reduced)==0) && pA->op!=TK_STRING ){
if( pA->iColumn!=pB->iColumn ) return 2;
if( pA->iTable!=pB->iTable
&& (pA->iTable!=iTab || NEVER(pB->iTable>=0)) ) return 2;
+20 -16
View File
@@ -342,20 +342,23 @@ static int xferOptimization(
/*
** This routine is called to handle SQL of the following forms:
**
** insert into TABLE (IDLIST) values(EXPRLIST)
** insert into TABLE (IDLIST) values(EXPRLIST),(EXPRLIST),...
** insert into TABLE (IDLIST) select
** insert into TABLE (IDLIST) default values
**
** The IDLIST following the table name is always optional. If omitted,
** then a list of all columns for the table is substituted. The IDLIST
** appears in the pColumn parameter. pColumn is NULL if IDLIST is omitted.
** then a list of all (non-hidden) columns for the table is substituted.
** The IDLIST appears in the pColumn parameter. pColumn is NULL if IDLIST
** is omitted.
**
** The pList parameter holds EXPRLIST in the first form of the INSERT
** statement above, and pSelect is NULL. For the second form, pList is
** NULL and pSelect is a pointer to the select statement used to generate
** data for the insert.
** For the pSelect parameter holds the values to be inserted for the
** first two forms shown above. A VALUES clause is really just short-hand
** for a SELECT statement that omits the FROM clause and everything else
** that follows. If the pSelect parameter is NULL, that means that the
** DEFAULT VALUES form of the INSERT statement is intended.
**
** The code generated follows one of four templates. For a simple
** insert with data coming from a VALUES clause, the code executes
** insert with data coming from a single-row VALUES clause, the code executes
** once straight down through. Pseudo-code follows (we call this
** the "1st template"):
**
@@ -462,7 +465,7 @@ void sqlite3Insert(
u8 useTempTable = 0; /* Store SELECT results in intermediate table */
u8 appendFlag = 0; /* True if the insert is likely to be an append */
u8 withoutRowid; /* 0 for normal table. 1 for WITHOUT ROWID table */
u8 bIdListInOrder = 1; /* True if IDLIST is in table order */
u8 bIdListInOrder; /* True if IDLIST is in table order */
ExprList *pList = 0; /* List of VALUES() to be inserted */
/* Register allocations */
@@ -487,8 +490,8 @@ void sqlite3Insert(
}
/* If the Select object is really just a simple VALUES() list with a
** single row values (the common case) then keep that one row of values
** and go ahead and discard the Select object
** single row (the common case) then keep that one row of values
** and discard the other (unused) parts of the pSelect object
*/
if( pSelect && (pSelect->selFlags & SF_Values)!=0 && pSelect->pPrior==0 ){
pList = pSelect->pEList;
@@ -596,6 +599,7 @@ void sqlite3Insert(
** is appears in the original table. (The index of the INTEGER
** PRIMARY KEY in the original table is pTab->iPKey.)
*/
bIdListInOrder = (pTab->tabFlags & TF_OOOHidden)==0;
if( pColumn ){
for(i=0; i<pColumn->nId; i++){
pColumn->a[i].idx = -1;
@@ -631,7 +635,8 @@ void sqlite3Insert(
** co-routine is the common header to the 3rd and 4th templates.
*/
if( pSelect ){
/* Data is coming from a SELECT. Generate a co-routine to run the SELECT */
/* Data is coming from a SELECT or from a multi-row VALUES clause.
** Generate a co-routine to run the SELECT. */
int regYield; /* Register holding co-routine entry-point */
int addrTop; /* Top of the co-routine */
int rc; /* Result code */
@@ -644,8 +649,7 @@ void sqlite3Insert(
dest.nSdst = pTab->nCol;
rc = sqlite3Select(pParse, pSelect, &dest);
regFromSelect = dest.iSdst;
assert( pParse->nErr==0 || rc );
if( rc || db->mallocFailed ) goto insert_cleanup;
if( rc || db->mallocFailed || pParse->nErr ) goto insert_cleanup;
sqlite3VdbeAddOp1(v, OP_EndCoroutine, regYield);
sqlite3VdbeJumpHere(v, addrTop - 1); /* label B: */
assert( pSelect->pEList );
@@ -693,8 +697,8 @@ void sqlite3Insert(
sqlite3ReleaseTempReg(pParse, regTempRowid);
}
}else{
/* This is the case if the data for the INSERT is coming from a VALUES
** clause
/* This is the case if the data for the INSERT is coming from a
** single-row VALUES clause
*/
NameContext sNC;
memset(&sNC, 0, sizeof(sNC));
+28 -16
View File
@@ -409,28 +409,35 @@ cmd ::= select(X). {
%type oneselect {Select*}
%destructor oneselect {sqlite3SelectDelete(pParse->db, $$);}
select(A) ::= with(W) selectnowith(X). {
Select *p = X, *pNext, *pLoop;
if( p ){
int cnt = 0, mxSelect;
p->pWith = W;
%include {
/*
** For a compound SELECT statement, make sure p->pPrior->pNext==p for
** all elements in the list. And make sure list length does not exceed
** SQLITE_LIMIT_COMPOUND_SELECT.
*/
static void parserDoubleLinkSelect(Parse *pParse, Select *p){
if( p->pPrior ){
u16 allValues = SF_Values;
pNext = 0;
Select *pNext = 0, *pLoop;
int mxSelect, cnt = 0;
for(pLoop=p; pLoop; pNext=pLoop, pLoop=pLoop->pPrior, cnt++){
pLoop->pNext = pNext;
pLoop->selFlags |= SF_Compound;
allValues &= pLoop->selFlags;
}
if( allValues ){
p->selFlags |= SF_AllValues;
}else if(
(mxSelect = pParse->db->aLimit[SQLITE_LIMIT_COMPOUND_SELECT])>0
&& cnt>mxSelect
if( (p->selFlags & SF_MultiValue)==0 &&
(mxSelect = pParse->db->aLimit[SQLITE_LIMIT_COMPOUND_SELECT])>0 &&
cnt>mxSelect
){
sqlite3ErrorMsg(pParse, "too many terms in compound SELECT");
}
}
}
}
select(A) ::= with(W) selectnowith(X). {
Select *p = X;
if( p ){
p->pWith = W;
parserDoubleLinkSelect(pParse, p);
}else{
sqlite3WithDelete(pParse->db, W);
}
@@ -445,12 +452,14 @@ selectnowith(A) ::= selectnowith(X) multiselect_op(Y) oneselect(Z). {
SrcList *pFrom;
Token x;
x.n = 0;
parserDoubleLinkSelect(pParse, pRhs);
pFrom = sqlite3SrcListAppendFromTerm(pParse,0,0,0,&x,pRhs,0,0);
pRhs = sqlite3SelectNew(pParse,0,pFrom,0,0,0,0,0,0,0);
}
if( pRhs ){
pRhs->op = (u8)Y;
pRhs->pPrior = X;
pRhs->selFlags &= ~SF_MultiValue;
if( Y!=TK_ALL ) pParse->hasCompound = 1;
}else{
sqlite3SelectDelete(pParse->db, X);
@@ -498,13 +507,16 @@ values(A) ::= VALUES LP nexprlist(X) RP. {
A = sqlite3SelectNew(pParse,X,0,0,0,0,0,SF_Values,0,0);
}
values(A) ::= values(X) COMMA LP exprlist(Y) RP. {
Select *pRight = sqlite3SelectNew(pParse,Y,0,0,0,0,0,SF_Values,0,0);
Select *pRight, *pLeft = X;
pRight = sqlite3SelectNew(pParse,Y,0,0,0,0,0,SF_Values|SF_MultiValue,0,0);
if( ALWAYS(pLeft) ) pLeft->selFlags &= ~SF_MultiValue;
if( pRight ){
pRight->op = TK_ALL;
pRight->pPrior = X;
pLeft = X;
pRight->pPrior = pLeft;
A = pRight;
}else{
A = X;
A = pLeft;
}
}
+4 -1
View File
@@ -961,8 +961,11 @@ void sqlite3Pragma(
sqlite3ErrorMsg(pParse,
"Safety level may not be changed inside a transaction");
}else{
pDb->safety_level = (getSafetyLevel(zRight,0,1)+1)
int iLevel = (getSafetyLevel(zRight,0,1)+1)
| SQLITE_SAFETYLEVEL_FIXED;
iLevel &= PAGER_SYNCHRONOUS_MASK;
if( iLevel==0 ) iLevel = 1;
pDb->safety_level = iLevel;
setAllPagerFlags(db);
}
}
+3 -3
View File
@@ -70,7 +70,7 @@ int sqlite3InitCallback(void *pInit, int argc, char **argv, char **NotUsed){
if( argv==0 ) return 0; /* Might happen if EMPTY_RESULT_CALLBACKS are on */
if( argv[1]==0 ){
corruptSchema(pData, argv[0], 0);
}else if( argv[2] && argv[2][0] ){
}else if( sqlite3_strnicmp(argv[2],"create ",7)==0 ){
/* Call the parser to process a CREATE TABLE, INDEX or VIEW.
** But because db->init.busy is set to 1, no VDBE code is generated
** or executed. All the parser does is build the internal data
@@ -101,8 +101,8 @@ int sqlite3InitCallback(void *pInit, int argc, char **argv, char **NotUsed){
}
}
sqlite3_finalize(pStmt);
}else if( argv[0]==0 ){
corruptSchema(pData, 0, 0);
}else if( argv[0]==0 || (argv[2]!=0 && argv[2][0]!=0) ){
corruptSchema(pData, argv[0], 0);
}else{
/* If the SQL column is blank it means this is an index that
** was created to be the PRIMARY KEY or to fulfill a UNIQUE
+8 -2
View File
@@ -460,7 +460,6 @@ static int lookupName(
if( cnt==0 && zTab==0 && ExprHasProperty(pExpr,EP_DblQuoted) ){
pExpr->op = TK_STRING;
pExpr->pTab = 0;
pExpr->iTable = -1;
return WRC_Prune;
}
@@ -1300,8 +1299,15 @@ static int resolveSelectStep(Walker *pWalker, Select *p){
** The ORDER BY clause for compounds SELECT statements is handled
** below, after all of the result-sets for all of the elements of
** the compound have been resolved.
**
** If there is an ORDER BY clause on a term of a compound-select other
** than the right-most term, then that is a syntax error. But the error
** is not detected until much later, and so we need to go ahead and
** resolve those symbols on the incorrect ORDER BY for consistency.
*/
if( !isCompound && resolveOrderGroupBy(&sNC, p, p->pOrderBy, "ORDER") ){
if( isCompound<=nCompound /* Defer right-most ORDER BY of a compound */
&& resolveOrderGroupBy(&sNC, p, p->pOrderBy, "ORDER")
){
return WRC_Abort;
}
if( db->mallocFailed ){
+13 -14
View File
@@ -111,7 +111,6 @@ Select *sqlite3SelectNew(
Select standin;
sqlite3 *db = pParse->db;
pNew = sqlite3DbMallocZero(db, sizeof(*pNew) );
assert( db->mallocFailed || !pOffset || pLimit ); /* OFFSET implies LIMIT */
if( pNew==0 ){
assert( db->mallocFailed );
pNew = &standin;
@@ -131,7 +130,7 @@ Select *sqlite3SelectNew(
pNew->op = TK_SELECT;
pNew->pLimit = pLimit;
pNew->pOffset = pOffset;
assert( pOffset==0 || pLimit!=0 );
assert( pOffset==0 || pLimit!=0 || pParse->nErr>0 || db->mallocFailed!=0 );
pNew->addrOpenEphm[0] = -1;
pNew->addrOpenEphm[1] = -1;
if( db->mallocFailed ) {
@@ -1381,7 +1380,7 @@ static const char *columnTypeImpl(
** of the SELECT statement. Return the declaration type and origin
** data for the result-set column of the sub-select.
*/
if( iCol>=0 && ALWAYS(iCol<pS->pEList->nExpr) ){
if( iCol>=0 && iCol<pS->pEList->nExpr ){
/* If iCol is less than zero, then the expression requests the
** rowid of the sub-select or view. This expression is legal (see
** test case misc2.2.2) - it always evaluates to NULL.
@@ -2108,8 +2107,7 @@ static int multiSelectValues(
int nExpr = p->pEList->nExpr;
int nRow = 1;
int rc = 0;
assert( p->pNext==0 );
assert( p->selFlags & SF_AllValues );
assert( p->selFlags & SF_MultiValue );
do{
assert( p->selFlags & SF_Values );
assert( p->op==TK_ALL || (p->op==TK_SELECT && p->pPrior==0) );
@@ -2218,7 +2216,7 @@ static int multiSelect(
/* Special handling for a compound-select that originates as a VALUES clause.
*/
if( p->selFlags & SF_AllValues ){
if( p->selFlags & SF_MultiValue ){
rc = multiSelectValues(pParse, p, &dest);
goto multi_select_end;
}
@@ -2629,7 +2627,7 @@ static int generateOutputSubroutine(
** of the scan loop.
*/
case SRT_Mem: {
assert( pIn->nSdst==1 );
assert( pIn->nSdst==1 || pParse->nErr>0 ); testcase( pIn->nSdst!=1 );
sqlite3ExprCodeMove(pParse, pIn->iSdst, pDest->iSDParm, 1);
/* The LIMIT clause will jump out of the loop for us */
break;
@@ -2860,8 +2858,10 @@ static int multiSelectOrderBy(
if( aPermute ){
struct ExprList_item *pItem;
for(i=0, pItem=pOrderBy->a; i<nOrderBy; i++, pItem++){
assert( pItem->u.x.iOrderByCol>0
&& pItem->u.x.iOrderByCol<=p->pEList->nExpr );
assert( pItem->u.x.iOrderByCol>0 );
/* assert( pItem->u.x.iOrderByCol<=p->pEList->nExpr ) is also true
** but only for well-formed SELECT statements. */
testcase( pItem->u.x.iOrderByCol > p->pEList->nExpr );
aPermute[i] = pItem->u.x.iOrderByCol - 1;
}
pKeyMerge = multiSelectOrderByKeyInfo(pParse, p, 1);
@@ -4422,7 +4422,7 @@ static void sqlite3SelectExpand(Parse *pParse, Select *pSelect){
sqlite3WalkSelect(&w, pSelect);
}
w.xSelectCallback = selectExpander;
if( (pSelect->selFlags & SF_AllValues)==0 ){
if( (pSelect->selFlags & SF_MultiValue)==0 ){
w.xSelectCallback2 = selectPopWith;
}
sqlite3WalkSelect(&w, pSelect);
@@ -5483,10 +5483,9 @@ int sqlite3Select(
*/
sqlite3VdbeResolveLabel(v, iEnd);
/* The SELECT was successfully coded. Set the return code to 0
** to indicate no errors.
*/
rc = 0;
/* The SELECT has been coded. If there is an error in the Parse structure,
** set the return code to 1. Otherwise 0. */
rc = (pParse->nErr>0);
/* Control jumps to here if an error is encountered above, or upon
** successful coding of the SELECT.
+10 -1
View File
@@ -527,6 +527,7 @@ struct ShellState {
int autoEQP; /* Run EXPLAIN QUERY PLAN prior to seach SQL stmt */
int statsOn; /* True to display memory stats before each finalize */
int scanstatsOn; /* True to display scan stats before each finalize */
int backslashOn; /* Resolve C-style \x escapes in SQL input text */
int outCount; /* Revert to stdout when reaching zero */
int cnt; /* Number of records displayed so far */
FILE *out; /* Write results here */
@@ -1944,7 +1945,7 @@ static void resolve_backslashes(char *z){
char c;
while( *z && *z!='\\' ) z++;
for(i=j=0; (c = z[i])!=0; i++, j++){
if( c=='\\' ){
if( c=='\\' && z[i+1]!=0 ){
c = z[++i];
if( c=='n' ){
c = '\n';
@@ -4111,6 +4112,7 @@ static int process_input(ShellState *p, FILE *in){
&& sqlite3_complete(zSql) ){
p->cnt = 0;
open_db(p, 0);
if( p->backslashOn ) resolve_backslashes(zSql);
BEGIN_TIMER;
rc = shell_exec(p->db, zSql, shell_callback, p, &zErrMsg);
END_TIMER;
@@ -4577,6 +4579,13 @@ int SQLITE_CDECL main(int argc, char **argv){
data.statsOn = 1;
}else if( strcmp(z,"-scanstats")==0 ){
data.scanstatsOn = 1;
}else if( strcmp(z,"-backslash")==0 ){
/* Undocumented command-line option: -backslash
** Causes C-style backslash escapes to be evaluated in SQL statements
** prior to sending the SQL into SQLite. Useful for injecting
** crazy bytes in the middle of SQL statements for testing and debugging.
*/
data.backslashOn = 1;
}else if( strcmp(z,"-bail")==0 ){
bail_on_error = 1;
}else if( strcmp(z,"-version")==0 ){
+8 -1
View File
@@ -1632,6 +1632,12 @@ struct Table {
/*
** Allowed values for Table.tabFlags.
**
** TF_OOOHidden applies to virtual tables that have hidden columns that are
** followed by non-hidden columns. Example: "CREATE VIRTUAL TABLE x USING
** vtab1(a HIDDEN, b);". Since "b" is a non-hidden column but "a" is hidden,
** 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 */
@@ -1639,6 +1645,7 @@ struct Table {
#define TF_Autoincrement 0x08 /* Integer primary key is autoincrement */
#define TF_Virtual 0x10 /* Is a virtual table */
#define TF_WithoutRowid 0x20 /* No rowid used. PRIMARY KEY is the key */
#define TF_OOOHidden 0x40 /* Out-of-Order hidden columns */
/*
@@ -2395,7 +2402,7 @@ struct Select {
#define SF_HasTypeInfo 0x0020 /* FROM subqueries have Table metadata */
#define SF_Compound 0x0040 /* Part of a compound query */
#define SF_Values 0x0080 /* Synthesized from VALUES clause */
#define SF_AllValues 0x0100 /* All terms of compound are VALUES */
#define SF_MultiValue 0x0100 /* Single VALUES term with multiple rows */
#define SF_NestedFrom 0x0200 /* Part of a parenthesized FROM clause */
#define SF_MaybeConvert 0x0400 /* Need convertCompoundSelectToSubquery() */
#define SF_Recursive 0x0800 /* The recursive part of a recursive CTE */
+1 -3
View File
@@ -516,8 +516,6 @@ abort_parse:
pParse->pZombieTab = p->pNextZombie;
sqlite3DeleteTable(db, p);
}
if( nErr>0 && pParse->rc==SQLITE_OK ){
pParse->rc = SQLITE_ERROR;
}
assert( nErr==0 || pParse->rc!=SQLITE_OK );
return nErr;
}
+1 -1
View File
@@ -193,7 +193,6 @@ void sqlite3BeginTrigger(
/* Do not create a trigger on a system table */
if( sqlite3StrNICmp(pTab->zName, "sqlite_", 7)==0 ){
sqlite3ErrorMsg(pParse, "cannot create trigger on system table");
pParse->nErr++;
goto trigger_cleanup;
}
@@ -795,6 +794,7 @@ static void transferParseError(Parse *pTo, Parse *pFrom){
if( pTo->nErr==0 ){
pTo->zErrMsg = pFrom->zErrMsg;
pTo->nErr = pFrom->nErr;
pTo->rc = pFrom->rc;
}else{
sqlite3DbFree(pFrom->db, pFrom->zErrMsg);
}
+1
View File
@@ -655,6 +655,7 @@ int sqlite3GetInt32(const char *zNum, int *pValue){
}
}
#endif
while( zNum[0]=='0' ) zNum++;
for(i=0; i<11 && (c = zNum[i] - '0')>=0 && c<=9; i++){
v = v*10 + c;
}
+14 -8
View File
@@ -539,6 +539,9 @@ int sqlite3VdbeExec(
){
Op *aOp = p->aOp; /* Copy of p->aOp */
Op *pOp = aOp; /* Current operation */
#if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE)
Op *pOrigOp; /* Value of pOp at the top of the loop */
#endif
int rc = SQLITE_OK; /* Value to return */
sqlite3 *db = p->db; /* The database */
u8 resetSchemaOnFault = 0; /* Reset schema after an error if positive */
@@ -681,6 +684,9 @@ int sqlite3VdbeExec(
memAboutToChange(p, &aMem[pOp->p3]);
}
#endif
#if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE)
pOrigOp = pOp;
#endif
switch( pOp->opcode ){
@@ -2919,7 +2925,7 @@ case OP_Savepoint: {
db->nDeferredImmCons = pSavepoint->nDeferredImmCons;
}
if( !isTransaction ){
if( !isTransaction || p1==SAVEPOINT_ROLLBACK ){
rc = sqlite3VtabSavepoint(db, p1, iSavepoint);
if( rc!=SQLITE_OK ) goto abort_due_to_error;
}
@@ -6489,8 +6495,8 @@ default: { /* This is really OP_Noop and OP_Explain */
#ifdef VDBE_PROFILE
{
u64 endTime = sqlite3Hwtime();
if( endTime>start ) pOp->cycles += endTime - start;
pOp->cnt++;
if( endTime>start ) pOrigOp->cycles += endTime - start;
pOrigOp->cnt++;
}
#endif
@@ -6500,16 +6506,16 @@ default: { /* This is really OP_Noop and OP_Explain */
** the evaluator loop. So we can leave it out when NDEBUG is defined.
*/
#ifndef NDEBUG
assert( pOp>=&aOp[-1] && pOp<&aOp[p->nOp] );
assert( pOp>=&aOp[-1] && pOp<&aOp[p->nOp-1] );
#ifdef SQLITE_DEBUG
if( db->flags & SQLITE_VdbeTrace ){
if( rc!=0 ) printf("rc=%d\n",rc);
if( pOp->opflags & (OPFLG_OUT2) ){
registerTrace(pOp->p2, &aMem[pOp->p2]);
if( pOrigOp->opflags & (OPFLG_OUT2) ){
registerTrace(pOrigOp->p2, &aMem[pOrigOp->p2]);
}
if( pOp->opflags & OPFLG_OUT3 ){
registerTrace(pOp->p3, &aMem[pOp->p3]);
if( pOrigOp->opflags & OPFLG_OUT3 ){
registerTrace(pOrigOp->p3, &aMem[pOrigOp->p3]);
}
}
#endif /* SQLITE_DEBUG */
+18 -11
View File
@@ -1791,6 +1791,22 @@ void sqlite3VdbeFreeCursor(Vdbe *p, VdbeCursor *pCx){
#endif
}
/*
** Close all cursors in the current frame.
*/
static void closeCursorsInFrame(Vdbe *p){
if( p->apCsr ){
int i;
for(i=0; i<p->nCursor; i++){
VdbeCursor *pC = p->apCsr[i];
if( pC ){
sqlite3VdbeFreeCursor(p, pC);
p->apCsr[i] = 0;
}
}
}
}
/*
** Copy the values stored in the VdbeFrame structure to its Vdbe. This
** is used, for example, when a trigger sub-program is halted to restore
@@ -1798,6 +1814,7 @@ void sqlite3VdbeFreeCursor(Vdbe *p, VdbeCursor *pCx){
*/
int sqlite3VdbeFrameRestore(VdbeFrame *pFrame){
Vdbe *v = pFrame->v;
closeCursorsInFrame(v);
#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
v->anExec = pFrame->anExec;
#endif
@@ -1832,17 +1849,7 @@ static void closeAllCursors(Vdbe *p){
p->nFrame = 0;
}
assert( p->nFrame==0 );
if( p->apCsr ){
int i;
for(i=0; i<p->nCursor; i++){
VdbeCursor *pC = p->apCsr[i];
if( pC ){
sqlite3VdbeFreeCursor(p, pC);
p->apCsr[i] = 0;
}
}
}
closeCursorsInFrame(p);
if( p->aMem ){
releaseMemArray(&p->aMem[1], p->nMem);
}
+5 -1
View File
@@ -95,6 +95,8 @@ char *sqlite3VdbeExpandSql(
assert( (zRawSql - zStart) > 0 );
sqlite3StrAccumAppend(&out, zStart, (int)(zRawSql-zStart));
}
}else if( p->nVar==0 ){
sqlite3StrAccumAppend(&out, zRawSql, sqlite3Strlen30(zRawSql));
}else{
while( zRawSql[0] ){
n = findNextHostParameter(zRawSql, &nToken);
@@ -111,10 +113,12 @@ char *sqlite3VdbeExpandSql(
idx = nextIndex;
}
}else{
assert( zRawSql[0]==':' || zRawSql[0]=='$' || zRawSql[0]=='@' );
assert( zRawSql[0]==':' || zRawSql[0]=='$' ||
zRawSql[0]=='@' || zRawSql[0]=='#' );
testcase( zRawSql[0]==':' );
testcase( zRawSql[0]=='$' );
testcase( zRawSql[0]=='@' );
testcase( zRawSql[0]=='#' );
idx = sqlite3VdbeParameterIndex(p, zRawSql, nToken);
assert( idx>0 );
}
+10 -3
View File
@@ -472,7 +472,7 @@ void sqlite3VtabArgExtend(Parse *pParse, Token *p){
pArg->z = p->z;
pArg->n = p->n;
}else{
assert(pArg->z < p->z);
assert(pArg->z <= p->z);
pArg->n = (int)(&p->z[p->n] - pArg->z);
}
}
@@ -559,6 +559,7 @@ static int vtabCallConstructor(
rc = SQLITE_ERROR;
}else{
int iCol;
u8 oooHidden = 0;
/* If everything went according to plan, link the new VTable structure
** into the linked list headed by pTab->pVTable. Then loop through the
** columns of the table to see if any of them contain the token "hidden".
@@ -571,7 +572,10 @@ static int vtabCallConstructor(
char *zType = pTab->aCol[iCol].zType;
int nType;
int i = 0;
if( !zType ) continue;
if( !zType ){
pTab->tabFlags |= oooHidden;
continue;
}
nType = sqlite3Strlen30(zType);
if( sqlite3StrNICmp("hidden", zType, 6)||(zType[6] && zType[6]!=' ') ){
for(i=0; i<nType; i++){
@@ -594,6 +598,9 @@ static int vtabCallConstructor(
zType[i-1] = '\0';
}
pTab->aCol[iCol].colFlags |= COLFLAG_HIDDEN;
oooHidden = TF_OOOHidden;
}else{
pTab->tabFlags |= oooHidden;
}
}
}
@@ -957,7 +964,7 @@ int sqlite3VtabSavepoint(sqlite3 *db, int op, int iSavepoint){
int rc = SQLITE_OK;
assert( op==SAVEPOINT_RELEASE||op==SAVEPOINT_ROLLBACK||op==SAVEPOINT_BEGIN );
assert( iSavepoint>=0 );
assert( iSavepoint>=-1 );
if( db->aVTrans ){
int i;
for(i=0; rc==SQLITE_OK && i<db->nVTrans; i++){
+1 -1
View File
@@ -359,6 +359,6 @@ do_test analyze-99.1 {
catchsql {
ANALYZE
}
} {1 {malformed database schema (sqlite_stat1) - near "nonsense": syntax error}}
} {1 {malformed database schema (sqlite_stat1)}}
finish_test
+1 -1
View File
@@ -292,7 +292,7 @@ do_test corruptC-2.15 {
hexio_write test.db 986 b9
sqlite3 db test.db
catchsql {SELECT count(*) FROM sqlite_master;}
} {1 {malformed database schema (t1i1) - no such table: main.t1}}
} {1 {database disk image is malformed}}
#
# Now test for a series of quasi-random seeds.
+6 -2
View File
@@ -48,8 +48,11 @@ do_execsql_test e_reindex-1.1 {
INSERT INTO t1 VALUES(1, 2);
INSERT INTO t1 VALUES(3, 4);
INSERT INTO t1 VALUES(5, 6);
CREATE TABLE saved(a,b,c,d,e);
INSERT INTO saved SELECT * FROM sqlite_master WHERE type = 'index';
PRAGMA writable_schema = 1;
UPDATE sqlite_master SET sql = '-- ' || sql WHERE type = 'index';
DELETE FROM sqlite_master WHERE type = 'index';
} {}
db close
@@ -59,7 +62,8 @@ do_execsql_test e_reindex-1.2 {
INSERT INTO t1 VALUES(7, 8);
INSERT INTO t1 VALUES(9, 10);
PRAGMA writable_schema = 1;
UPDATE sqlite_master SET sql = substr(sql, 4) WHERE type = 'index';
INSERT INTO sqlite_master SELECT * FROM saved;
DROP TABLE saved;
} {}
db close
+8
View File
@@ -943,5 +943,13 @@ do_realnum_test expr-13.7 {
}
} {9.22337203685478e+18}
do_execsql_test expr-13.8 {
SELECT "" <= '';
} {1}
do_execsql_test expr-13.9 {
SELECT '' <= "";
} {1}
finish_test
+19
View File
@@ -676,6 +676,11 @@ do_test fkey2-9.2.3 {
SELECT * FROM cc;
}
} {{} A {} {} B {} 3 A 2 3 B 2}
do_execsql_test fkey2-9.3.0 {
CREATE TABLE t3(x PRIMARY KEY REFERENCES t3 ON DELETE SET NULL);
INSERT INTO t3(x) VALUES(12345);
DROP TABLE t3;
} {}
#-------------------------------------------------------------------------
# The following tests, fkey2-10.*, test "foreign key mismatch" and
@@ -2014,4 +2019,18 @@ do_test fkey2-ce7c13.1.6 {
}
} {1 {FOREIGN KEY constraint failed}}
# 2015-04-16: Foreign key errors propagate back up to the parser.
#
do_test fkey2-20150416-100 {
db close
sqlite3 db :memory:
catchsql {
PRAGMA foreign_keys=1;
CREATE TABLE t1(x PRIMARY KEY);
CREATE TABLE t(y REFERENCES t0(x)ON DELETE SET DEFAULT);
CREATE TABLE t0(y REFERENCES t1 ON DELETE SET NULL);
REPLACE INTO t1 SELECT(0);CREATE TABLE t2(x);CREATE TABLE t3;
}
} {1 {foreign key mismatch - "t" referencing "t0"}}
finish_test
+22
View File
@@ -16,6 +16,7 @@
set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix fts3aa
# If SQLITE_ENABLE_FTS3 is defined, omit this file.
ifcapable !fts3 {
@@ -221,5 +222,26 @@ do_catchsql_test fts3aa-7.5 {
CREATE VIRTUAL TABLE t4 USING fts4(tokenize=simple, tokenize=simple);
} {1 {unrecognized parameter: tokenize=simple}}
do_execsql_test 8.0 {
CREATE VIRTUAL TABLE t0 USING fts4(order=desc);
BEGIN;
INSERT INTO t0(rowid, content) VALUES(1, 'abc');
UPDATE t0 SET docid=5 WHERE docid=1;
INSERT INTO t0(rowid, content) VALUES(6, 'abc');
}
do_execsql_test 8.1 {
SELECT docid FROM t0 WHERE t0 MATCH 'abc';
} {6 5}
do_execsql_test 8.2 {
SELECT docid FROM t0 WHERE t0 MATCH '"abc abc"';
} {}
do_execsql_test 8.3 { COMMIT }
do_execsql_test 8.4 {
SELECT docid FROM t0 WHERE t0 MATCH 'abc';
} {6 5}
do_execsql_test 8.5 {
SELECT docid FROM t0 WHERE t0 MATCH '"abc abc"';
} {}
finish_test
+1 -1
View File
@@ -51,6 +51,6 @@ do_test index3-99.1 {
db close
catch { sqlite3 db test.db }
catchsql { DROP INDEX i1 }
} {1 {malformed database schema (t1) - near "nonsense": syntax error}}
} {1 {malformed database schema (t1)}}
finish_test
+4
View File
@@ -311,5 +311,9 @@ do_eqp_test index7-6.4 {
} {
0 0 0 {SEARCH TABLE t4 USING INDEX i4 (c=?)}
}
do_catchsql_test index7-6.5 {
CREATE INDEX t5a ON t5(a) WHERE a=#1;
} {1 {near "#1": syntax error}}
finish_test
+5
View File
@@ -560,5 +560,10 @@ do_test insert4-8.25 {
}
} {1 3}
do_catchsql_test insert4-9.1 {
DROP TABLE IF EXISTS t1;
CREATE TABLE t1(x);
INSERT INTO t1(x) VALUES(5 COLLATE xyzzy) UNION SELECT 0;
} {1 {no such collation sequence: xyzzy}}
finish_test
+40
View File
@@ -644,4 +644,44 @@ do_execsql_test misc1-22.1 {
SELECT ""+3 FROM (SELECT ""+5);
} {3}
# 2015-04-19: NULL pointer dereference on a corrupt schema
#
db close
sqlite3 db :memory:
do_execsql_test misc1-23.1 {
CREATE TABLE t1(x);
PRAGMA writable_schema=ON;
UPDATE sqlite_master SET sql='CREATE table t(d CHECK(T(#0)';
BEGIN;
CREATE TABLE t2(y);
ROLLBACK;
DROP TABLE IF EXISTS t3;
} {}
# 2015-04-19: Faulty assert() statement
#
db close
database_may_be_corrupt
sqlite3 db :memory:
do_catchsql_test misc1-23.2 {
CREATE TABLE t1(x UNIQUE);
PRAGMA writable_schema=ON;
UPDATE sqlite_master SET sql='CREATE TABLE IF not EXISTS t(c)';
BEGIN;
CREATE TABLE t2(x);
ROLLBACK;
DROP TABLE F;
} {1 {no such table: F}}
db close
sqlite3 db :memory:
do_catchsql_test misc1-23.3 {
CREATE TABLE t1(x UNIQUE);
PRAGMA writable_schema=ON;
UPDATE sqlite_master SET sql='CREATE table y(a TEXT, a TEXT)';
BEGIN;
CREATE TABLE t2(y);
ROLLBACK;
DROP TABLE IF EXISTS t;
} {0 {}}
finish_test
+18
View File
@@ -583,6 +583,24 @@ do_test misc5-7.1 {
catchsql $sql
} {1 {parser stack overflow}}
# Parser stack overflow is silently ignored when it occurs while parsing the
# schema and PRAGMA writable_schema is turned on.
#
do_test misc5-7.2 {
sqlite3 db2 :memory:
catchsql {
CREATE TABLE t1(x UNIQUE);
PRAGMA writable_schema=ON;
UPDATE sqlite_master SET sql='CREATE table t(o CHECK(((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((;VALUES(o)';
BEGIN;
CREATE TABLE t2(y);
ROLLBACK;
DROP TABLE IF EXISTS D;
} db2
} {0 {}}
db2 close
# Ticket #1911
#
ifcapable compound {
+18
View File
@@ -219,6 +219,24 @@ do_test pragma-1.14 {
PRAGMA synchronous;
}
} {2}
do_test pragma-1.14.1 {
execsql {
PRAGMA synchronous=4;
PRAGMA synchronous;
}
} {0}
do_test pragma-1.14.2 {
execsql {
PRAGMA synchronous=3;
PRAGMA synchronous;
}
} {0}
do_test pragma-1.14.3 {
execsql {
PRAGMA synchronous=10;
PRAGMA synchronous;
}
} {2}
} ;# ifcapable pager_pragmas
# Test turning "flag" pragmas on and off.
+66 -9
View File
@@ -14,6 +14,7 @@ optional) are:
--config CONFIGNAME (Run only CONFIGNAME)
--quick (Run "veryquick.test" only)
--veryquick (Run "make smoketest" only)
--msvc (Use MSVC as the compiler)
--buildonly (Just build testfixture - do not run)
--dryrun (Print what would have happened)
--info (Show diagnostic info)
@@ -22,8 +23,9 @@ The default value for --srcdir is the parent of the directory holding
this script.
The script determines the default value for --platform using the
$tcl_platform(os) and $tcl_platform(machine) variables. Supported
platforms are "Linux-x86", "Linux-x86_64" and "Darwin-i386".
$tcl_platform(os) and $tcl_platform(machine) variables. Supported
platforms are "Linux-x86", "Linux-x86_64", "Darwin-i386",
"Darwin-x86_64", "Windows NT-intel", and "Windows NT-amd64".
Every test begins with a fresh run of the configure script at the top
of the SQLite source tree.
@@ -238,6 +240,10 @@ array set ::Platforms [strip_comments {
"Default" "mptest fulltestonly"
"Have-Not" test
}
"Windows NT-amd64" {
"Default" "mptest fulltestonly"
"Have-Not" test
}
# The Failure-Detection platform runs various tests that deliberately
# fail. This is used as a test of this script to verify that this script
@@ -296,6 +302,13 @@ proc count_tests_and_errors {logfile rcVar errmsgVar} {
set errmsg $msg
}
}
if {[regexp {fatal error +(.*)} $line all msg]} {
incr ::NERRCASE
if {$rc==0} {
set rc 1
set errmsg $msg
}
}
if {[regexp {ERROR SUMMARY: (\d+) errors.*} $line all cnt] && $cnt>0} {
incr ::NERRCASE
if {$rc==0} {
@@ -314,7 +327,13 @@ proc count_tests_and_errors {logfile rcVar errmsgVar} {
}
}
close $fd
if {!$seen} {
if {$::BUILDONLY} {
if {$rc==0} {
set errmsg "Build complete"
} else {
set errmsg "Build failed"
}
} elseif {!$seen} {
set rc 1
set errmsg "Test did not complete"
if {[file readable core]} {
@@ -329,7 +348,7 @@ proc run_test_suite {name testtarget config} {
# CFLAGS. The makefile will pass OPTS to both gcc and lemon, but
# CFLAGS is only passed to gcc.
#
set cflags "-g"
set cflags [expr {$::MSVC ? "-Zi" : "-g"}]
set opts ""
set title ${name}($testtarget)
set configOpts ""
@@ -349,7 +368,14 @@ proc run_test_suite {name testtarget config} {
set cflags [join $cflags " "]
set opts [join $opts " "]
append opts " -DSQLITE_NO_SYNC=1 -DHAVE_USLEEP"
append opts " -DSQLITE_NO_SYNC=1"
# Some configurations already set HAVE_USLEEP; in that case, skip it.
#
if {![regexp { -DHAVE_USLEEP$} $opts]
&& ![regexp { -DHAVE_USLEEP[ =]+} $opts]} {
append opts " -DHAVE_USLEEP=1"
}
# Set the sub-directory to use.
#
@@ -390,10 +416,10 @@ proc run_test_suite {name testtarget config} {
if {$rc} {
puts " FAIL $tm"
incr ::NERR
if {$errmsg!=""} {puts " $errmsg"}
} else {
puts " Ok $tm"
}
if {$errmsg!=""} {puts " $errmsg"}
}
}
@@ -401,6 +427,7 @@ proc run_test_suite {name testtarget config} {
# the current platform, which may be Windows (via MinGW, etc).
#
proc configureCommand {opts} {
if {$::MSVC} return [list]; # This is not needed for MSVC.
set result [list trace_cmd exec]
if {$::tcl_platform(platform)=="windows"} {
lappend result sh
@@ -414,7 +441,14 @@ proc configureCommand {opts} {
# specified targets, compiler flags, and options.
#
proc makeCommand { targets cflags opts } {
set result [list trace_cmd exec make clean]
set result [list trace_cmd exec]
if {$::MSVC} {
set nmakeDir [file nativename $::SRCDIR]
set nmakeFile [file join $nmakeDir Makefile.msc]
lappend result nmake /f $nmakeFile TOP=$nmakeDir clean
} else {
lappend result make clean
}
foreach target $targets {
lappend result $target
}
@@ -443,6 +477,7 @@ proc trace_cmd {args} {
proc process_options {argv} {
set ::SRCDIR [file normalize [file dirname [file dirname $::argv0]]]
set ::QUICK 0
set ::MSVC 0
set ::BUILDONLY 0
set ::DRYRUN 0
set ::EXEC exec
@@ -476,6 +511,10 @@ proc process_options {argv} {
set config [lindex $argv $i]
}
-msvc {
set ::MSVC 1
}
-buildonly {
set ::BUILDONLY 1
}
@@ -494,6 +533,7 @@ proc process_options {argv} {
puts " --platform [list $platform]"
puts " --config [list $config]"
if {$::QUICK} {puts " --quick"}
if {$::MSVC} {puts " --msvc"}
if {$::BUILDONLY} {puts " --buildonly"}
if {$::DRYRUN} {puts " --dryrun"}
if {$::TRACE} {puts " --trace"}
@@ -507,7 +547,15 @@ proc process_options {argv} {
}
exit
}
-g -
-g {
if {$::MSVC} {
lappend ::EXTRACONFIG -Zi
} else {
lappend ::EXTRACONFIG [lindex $argv $i]
}
}
-D* -
-O* -
-enable-* -
@@ -547,6 +595,7 @@ proc process_options {argv} {
puts -nonewline "Flags:"
if {$::DRYRUN} {puts -nonewline " --dryrun"}
if {$::BUILDONLY} {puts -nonewline " --buildonly"}
if {$::MSVC} {puts -nonewline " --msvc"}
switch -- $::QUICK {
1 {puts -nonewline " --quick"}
2 {puts -nonewline " --veryquick"}
@@ -570,12 +619,20 @@ proc main {argv} {
set ::SQLITE_VERSION {}
set STARTTIME [clock seconds]
foreach {zConfig target} $::CONFIGLIST {
if {$::MSVC && ($zConfig eq "Sanitize" || "checksymbols" in $target
|| "valgrindtest" in $target)} {
puts "Skipping $zConfig / $target for MSVC..."
continue
}
if {$target ne "checksymbols"} {
switch -- $::QUICK {
1 {set target test}
2 {set target smoketest}
}
if {$::BUILDONLY} {set target testfixture}
if {$::BUILDONLY} {
set target testfixture
if {$::MSVC} {append target .exe}
}
}
set config_options [concat $::Configs($zConfig) $::EXTRACONFIG]
+8
View File
@@ -307,6 +307,9 @@ do_test select1-4.4 {
set v [catch {execsql {SELECT f1 FROM test1 ORDER BY min(f1)}} msg]
lappend v $msg
} {1 {misuse of aggregate: min()}}
do_catchsql_test select1-4.5 {
INSERT INTO test1(f1) SELECT f1 FROM test1 ORDER BY min(f1);
} {1 {misuse of aggregate: min()}}
# The restriction not allowing constants in the ORDER BY clause
# has been removed. See ticket #1768
@@ -1072,5 +1075,10 @@ if {[db one {PRAGMA locking_mode}]=="normal"} {
do_test select1-16.1 {
catchsql {SELECT 1 FROM (SELECT *)}
} {1 {no tables specified}}
# 2015-04-17: assertion fix.
do_catchsql_test select1-16.2 {
SELECT 1 FROM sqlite_master LIMIT 1,#1;
} {1 {near "#1": syntax error}}
finish_test
+19 -1
View File
@@ -118,6 +118,10 @@ do_test select4-1.3 {
}} msg]
lappend v $msg
} {1 {ORDER BY clause should come after UNION ALL not before}}
do_catchsql_test select4-1.4 {
SELECT (VALUES(0) INTERSECT SELECT(0) UNION SELECT(0) ORDER BY 1 UNION
SELECT 0 UNION SELECT 0 ORDER BY 1);
} {1 {ORDER BY clause should come after UNION not before}}
# Union operator
#
@@ -148,6 +152,12 @@ do_test select4-2.3 {
}} msg]
lappend v $msg
} {1 {ORDER BY clause should come after UNION not before}}
do_test select4-2.4 {
set v [catch {execsql {
SELECT 0 ORDER BY (SELECT 0) UNION SELECT 0;
}} msg]
lappend v $msg
} {1 {ORDER BY clause should come after UNION not before}}
# Except operator
#
@@ -874,6 +884,14 @@ do_execsql_test select4-14.10 {
do_execsql_test select4-14.11 {
SELECT (SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4)
} {1}
do_execsql_test select4-14.12 {
VALUES(1) UNION VALUES(2);
} {1 2}
do_execsql_test select4-14.13 {
VALUES(1),(2),(3) EXCEPT VALUES(2);
} {1 3}
do_execsql_test select4-14.14 {
VALUES(1),(2),(3) EXCEPT VALUES(1),(3);
} {2}
finish_test
+19
View File
@@ -272,6 +272,25 @@ do_test table-5.2.1 {
}
} {}
do_test table-5.2.2 {
db close
forcedelete test.db
sqlite3 db test.db
db eval {
CREATE TABLE t0(a,b);
CREATE INDEX t ON t0(a);
PRAGMA writable_schema=ON;
UPDATE sqlite_master SET sql='CREATE TABLE a.b(a UNIQUE';
BEGIN;
CREATE TABLE t1(x);
ROLLBACK;
DROP TABLE IF EXISTS t99;
}
} {}
db close
forcedelete test.db
sqlite3 db test.db
# Make sure an EXPLAIN does not really create a new table
#
do_test table-5.3 {
+1 -1
View File
@@ -114,6 +114,6 @@ do_test trigger7-99.1 {
db close
catch { sqlite3 db test.db }
catchsql { DROP TRIGGER t2r5 }
} {1 {malformed database schema (t2r12) - near "nonsense": syntax error}}
} {1 {malformed database schema (t2r12)}}
finish_test
+37
View File
@@ -1491,4 +1491,41 @@ do_test 23.3.1 {
} {1 {database table is locked}}
do_execsql_test 23.3.2 { SELECT * FROM t1e } {1 2 3 4}
#-------------------------------------------------------------------------
# At one point SQL like this:
#
# SAVEPOINT xyz; -- Opens SQL transaction
# INSERT INTO vtab -- Write to virtual table
# ROLLBACK TO xyz;
# RELEASE xyz;
#
# was not invoking the xRollbackTo() callback for the ROLLBACK TO
# operation. Which meant that virtual tables like FTS3 would incorrectly
# commit the results of the INSERT as part of the "RELEASE xyz" command.
#
# The following tests check that this has been fixed.
#
ifcapable fts3 {
do_execsql_test 24.0 {
CREATE VIRTUAL TABLE t4 USING fts3();
SAVEPOINT a;
INSERT INTO t4 VALUES('a b c');
ROLLBACK TO a;
RELEASE a;
SELECT * FROM t4;
} {}
do_execsql_test 24.1 { SELECT * FROM t4 WHERE t4 MATCH 'b' } {}
do_execsql_test 24.2 { INSERT INTO t4(t4) VALUES('integrity-check') } {}
do_execsql_test 24.3 {
SAVEPOINT a;
CREATE VIRTUAL TABLE t5 USING fts3();
SAVEPOINT b;
ROLLBACK TO a;
SAVEPOINT c;
RELEASE a;
}
}
finish_test
+17 -6
View File
@@ -74,28 +74,39 @@ do_test vtabA-1.6 {
SELECT * FROM t1e;
}
} {{value a} {value c}}
do_execsql_test vtabA-1.7 {
DELETE FROM t1e;
INSERT INTO t1e SELECT 'abc','def';
} {}
do_execsql_test vtabA-1.8 {
INSERT INTO t1e VALUES('ghi','jkl'),('mno','pqr'),('stu','vwx');
} {}
do_execsql_test vtabA-1.9 {
SELECT a,b,c, '|' FROM t1e ORDER BY 1;
} {abc {} def | ghi {} jkl | mno {} pqr | stu {} vwx |}
# Test that the expansion of a '*' expression in the result set of
# a SELECT does not include the hidden column.
#
do_test vtabA-1.7 {
do_test vtabA-1.20 {
execsql {
INSERT INTO t1e SELECT * FROM t1e;
}
} {}
do_test vtabA-1.8 {
do_test vtabA-1.21 {
execsql {
SELECT * FROM t1e;
SELECT * FROM t1e ORDER BY 1;
}
} {{value a} {value c} {value a} {value c}}
} {abc def abc def ghi jkl ghi jkl mno pqr mno pqr stu vwx stu vwx}
# Test that the declaration type of the hidden column does not include
# the token "HIDDEN".
#
do_test vtabA-1.9 {
do_test vtabA-1.22 {
get_decltype t1e b
} {VARCHAR}
do_test vtabA-1.10 {
do_test vtabA-1.23 {
get_collist t1e
} {a c}
+294
View File
@@ -0,0 +1,294 @@
/*
** 2015-04-17
**
** The author disclaims copyright to this source code. In place of
** a legal notice, here is a blessing:
**
** May you do good and not evil.
** May you find forgiveness for yourself and forgive others.
** May you share freely, never taking more than you give.
**
*************************************************************************
**
** This is a utility program designed to aid running the SQLite library
** against an external fuzzer, such as American Fuzzy Lop (AFL)
** (http://lcamtuf.coredump.cx/afl/). Basically, this program reads
** SQL text from standard input and passes it through to SQLite for evaluation,
** just like the "sqlite3" command-line shell. Differences from the
** command-line shell:
**
** (1) The complex "dot-command" extensions are omitted. This
** prevents the fuzzer from discovering that it can run things
** like ".shell rm -rf ~"
**
** (2) The database is opened with the SQLITE_OPEN_MEMORY flag so that
** no disk I/O from the database is permitted. The ATTACH command
** with a filename still uses an in-memory database.
**
** (3) The main in-memory database can be initialized from a template
** disk database so that the fuzzer starts with a database containing
** content.
**
** (4) The eval() SQL function is added, allowing the fuzzer to do
** interesting recursive operations.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include "sqlite3.h"
/*
** All global variables are gathered into the "g" singleton.
*/
struct GlobalVars {
const char *zArgv0; /* Name of program */
} g;
/*
** Print an error message and abort in such a way to indicate to the
** fuzzer that this counts as a crash.
*/
static void abendError(const char *zFormat, ...){
va_list ap;
fprintf(stderr, "%s: ", g.zArgv0);
va_start(ap, zFormat);
vfprintf(stderr, zFormat, ap);
va_end(ap);
fprintf(stderr, "\n");
abort();
}
/*
** Print an error message and quit, but not in a way that would look
** like a crash.
*/
static void fatalError(const char *zFormat, ...){
va_list ap;
fprintf(stderr, "%s: ", g.zArgv0);
va_start(ap, zFormat);
vfprintf(stderr, zFormat, ap);
va_end(ap);
fprintf(stderr, "\n");
exit(1);
}
/*
** This callback is invoked by sqlite3_log().
*/
static void shellLog(void *pNotUsed, int iErrCode, const char *zMsg){
printf("LOG: (%d) %s\n", iErrCode, zMsg);
}
/*
** This callback is invoked by sqlite3_exec() to return query results.
*/
static int execCallback(void *NotUsed, int argc, char **argv, char **colv){
int i;
static unsigned cnt = 0;
printf("ROW #%u:\n", ++cnt);
for(i=0; i<argc; i++){
printf(" %s=", colv[i]);
if( argv[i] ){
printf("[%s]\n", argv[i]);
}else{
printf("NULL\n");
}
}
return 0;
}
/*
** This callback is invoked by sqlite3_trace() as each SQL statement
** starts.
*/
static void traceCallback(void *NotUsed, const char *zMsg){
printf("TRACE: %s\n", zMsg);
}
/***************************************************************************
** eval() implementation copied from ../ext/misc/eval.c
*/
/*
** Structure used to accumulate the output
*/
struct EvalResult {
char *z; /* Accumulated output */
const char *zSep; /* Separator */
int szSep; /* Size of the separator string */
sqlite3_int64 nAlloc; /* Number of bytes allocated for z[] */
sqlite3_int64 nUsed; /* Number of bytes of z[] actually used */
};
/*
** Callback from sqlite_exec() for the eval() function.
*/
static int callback(void *pCtx, int argc, char **argv, char **colnames){
struct EvalResult *p = (struct EvalResult*)pCtx;
int i;
for(i=0; i<argc; i++){
const char *z = argv[i] ? argv[i] : "";
size_t sz = strlen(z);
if( (sqlite3_int64)sz+p->nUsed+p->szSep+1 > p->nAlloc ){
char *zNew;
p->nAlloc = p->nAlloc*2 + sz + p->szSep + 1;
/* Using sqlite3_realloc64() would be better, but it is a recent
** addition and will cause a segfault if loaded by an older version
** of SQLite. */
zNew = p->nAlloc<=0x7fffffff ? sqlite3_realloc(p->z, (int)p->nAlloc) : 0;
if( zNew==0 ){
sqlite3_free(p->z);
memset(p, 0, sizeof(*p));
return 1;
}
p->z = zNew;
}
if( p->nUsed>0 ){
memcpy(&p->z[p->nUsed], p->zSep, p->szSep);
p->nUsed += p->szSep;
}
memcpy(&p->z[p->nUsed], z, sz);
p->nUsed += sz;
}
return 0;
}
/*
** Implementation of the eval(X) and eval(X,Y) SQL functions.
**
** Evaluate the SQL text in X. Return the results, using string
** Y as the separator. If Y is omitted, use a single space character.
*/
static void sqlEvalFunc(
sqlite3_context *context,
int argc,
sqlite3_value **argv
){
const char *zSql;
sqlite3 *db;
char *zErr = 0;
int rc;
struct EvalResult x;
memset(&x, 0, sizeof(x));
x.zSep = " ";
zSql = (const char*)sqlite3_value_text(argv[0]);
if( zSql==0 ) return;
if( argc>1 ){
x.zSep = (const char*)sqlite3_value_text(argv[1]);
if( x.zSep==0 ) return;
}
x.szSep = (int)strlen(x.zSep);
db = sqlite3_context_db_handle(context);
rc = sqlite3_exec(db, zSql, callback, &x, &zErr);
if( rc!=SQLITE_OK ){
sqlite3_result_error(context, zErr, -1);
sqlite3_free(zErr);
}else if( x.zSep==0 ){
sqlite3_result_error_nomem(context);
sqlite3_free(x.z);
}else{
sqlite3_result_text(context, x.z, (int)x.nUsed, sqlite3_free);
}
}
/* End of the eval() implementation
******************************************************************************/
/*
** Print sketchy documentation for this utility program
*/
static void showHelp(void){
printf("Usage: %s [options]\n", g.zArgv0);
printf(
"Read SQL text from standard input and evaluate it.\n"
"Options:\n"
" -f FILE Read SQL text from FILE instead of standard input\n"
" --help Show this help text\n"
" --initdb DBFILE Initialize the in-memory database using template DBFILE\n"
);
}
int main(int argc, char **argv){
char *zIn = 0; /* Input text */
int nAlloc = 0; /* Number of bytes allocated for zIn[] */
int nIn = 0; /* Number of bytes of zIn[] used */
size_t got; /* Bytes read from input */
FILE *in = stdin; /* Where to read SQL text from */
int rc = SQLITE_OK; /* Result codes from API functions */
int i; /* Loop counter */
sqlite3 *db; /* Open database */
sqlite3 *dbInit; /* On-disk database used to initialize the in-memory db */
const char *zInitDb = 0;/* Name of the initialization database file */
char *zErrMsg = 0; /* Error message returned from sqlite3_exec() */
g.zArgv0 = argv[0];
for(i=1; i<argc; i++){
const char *z = argv[i];
if( z[0]=='-' ){
z++;
if( z[0]=='-' ) z++;
if( strcmp(z,"help")==0 ){
showHelp();
return 0;
}else
if( strcmp(z, "f")==0 && i+1<argc ){
if( in!=stdin ) abendError("only one -f allowed");
in = fopen(argv[++i],"rb");
if( in==0 ) abendError("cannot open input file \"%s\"", argv[i]);
}else
if( strcmp(z, "initdb")==0 && i+1<argc ){
if( zInitDb!=0 ) abendError("only one --initdb allowed");
zInitDb = argv[++i];
}else
{
abendError("unknown option: %s", argv[i]);
}
}else{
abendError("unknown argument: %s", argv[i]);
}
}
sqlite3_config(SQLITE_CONFIG_LOG, shellLog, 0);
rc = sqlite3_open_v2(
"main.db", &db,
SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_MEMORY,
0);
if( rc!=SQLITE_OK ){
abendError("Unable to open the in-memory database");
}
if( zInitDb ){
sqlite3_backup *pBackup;
rc = sqlite3_open_v2(zInitDb, &dbInit, SQLITE_OPEN_READONLY, 0);
if( rc!=SQLITE_OK ){
abendError("unable to open initialization database \"%s\"", zInitDb);
}
pBackup = sqlite3_backup_init(db, "main", dbInit, "main");
rc = sqlite3_backup_step(pBackup, -1);
if( rc!=SQLITE_DONE ){
abendError("attempt to initialize the in-memory database failed (rc=%d)",rc);
}
sqlite3_backup_finish(pBackup);
sqlite3_close(dbInit);
}
sqlite3_trace(db, traceCallback, 0);
sqlite3_create_function(db, "eval", 1, SQLITE_UTF8, 0, sqlEvalFunc, 0, 0);
sqlite3_create_function(db, "eval", 2, SQLITE_UTF8, 0, sqlEvalFunc, 0, 0);
while( !feof(in) ){
nAlloc += 1000;
zIn = sqlite3_realloc(zIn, nAlloc);
if( zIn==0 ) fatalError("out of memory");
got = fread(zIn+nIn, 1, nAlloc-nIn-1, in);
nIn += (int)got;
zIn[nIn] = 0;
if( got==0 ) break;
}
printf("INPUT (%d bytes): [%s]\n", nIn, zIn);
rc = sqlite3_exec(db, zIn, execCallback, 0, &zErrMsg);
printf("RESULT-CODE: %d\n", rc);
if( zErrMsg ){
printf("ERROR-MSG: [%s]\n", zErrMsg);
sqlite3_free(zErrMsg);
}
return rc!=SQLITE_OK;
}
+4 -2
View File
@@ -64,11 +64,13 @@ static void out_of_memory(void){
*/
static unsigned char *getContent(int ofst, int nByte){
unsigned char *aData;
int got;
aData = malloc(nByte+32);
if( aData==0 ) out_of_memory();
memset(aData, 0, nByte+32);
lseek(db, ofst, SEEK_SET);
if( read(db, aData, nByte)<nByte ) memset(aData, 0, nByte);
got = read(db, aData, nByte);
if( got>0 && got<nByte ) memset(aData+got, 0, nByte-got);
return aData;
}
@@ -981,7 +983,7 @@ int main(int argc, char **argv){
if( pagesize==0 ) pagesize = 1024;
printf("Pagesize: %d\n", pagesize);
fstat(db, &sbuf);
mxPage = sbuf.st_size/pagesize;
mxPage = (sbuf.st_size+pagesize-1)/pagesize;
printf("Available pages: 1..%d\n", mxPage);
if( argc==2 ){
int i;
+6 -1
View File
@@ -10,8 +10,13 @@
**
*************************************************************************
**
** This is a utility problem that computes the differences in content
** This is a utility program that computes the differences in content
** between two SQLite databases.
**
** To compile, simply link against SQLite.
**
** See the showHelp() routine below for a brief description of how to
** run the utility.
*/
#include <stdio.h>
#include <stdlib.h>