mirror of
https://github.com/tursodatabase/libsql.git
synced 2025-03-13 08:28:02 +00:00
Add the pcache module from the experimental branch. Also change things so that most of the built-in SQL functions are kept in single static hash-table, rather than creating and populating a separate hash table for each open database connection. (CVS 5566)
FossilOrigin-Name: cb494e10d71852024647aaa254203579ad438ea9
This commit is contained in:
21
Makefile.in
21
Makefile.in
@ -157,12 +157,12 @@ NAWK = @AWK@
|
||||
#
|
||||
OBJS0 = alter.lo analyze.lo attach.lo auth.lo bitvec.lo btmutex.lo \
|
||||
btree.lo build.lo callback.lo complete.lo date.lo \
|
||||
delete.lo expr.lo fault.lo func.lo global.lo \
|
||||
delete.lo expr.lo fault.lo func2.lo global.lo \
|
||||
hash.lo journal.lo insert.lo loadext.lo \
|
||||
main.lo malloc.lo mem1.lo mem2.lo mem3.lo mem4.lo mem5.lo mem6.lo \
|
||||
mutex.lo mutex_os2.lo mutex_unix.lo mutex_w32.lo \
|
||||
opcodes.lo os.lo os_unix.lo os_win.lo os_os2.lo \
|
||||
pager.lo parse.lo pragma.lo prepare.lo printf.lo random.lo \
|
||||
pager.lo parse.lo pcache.lo pragma.lo prepare.lo printf.lo random.lo \
|
||||
select.lo status.lo table.lo tokenize.lo trigger.lo update.lo \
|
||||
util.lo vacuum.lo \
|
||||
vdbe.lo vdbeapi.lo vdbeaux.lo vdbeblob.lo vdbefifo.lo vdbemem.lo \
|
||||
@ -197,7 +197,6 @@ SRC = \
|
||||
$(TOP)/src/delete.c \
|
||||
$(TOP)/src/expr.c \
|
||||
$(TOP)/src/fault.c \
|
||||
$(TOP)/src/func.c \
|
||||
$(TOP)/src/global.c \
|
||||
$(TOP)/src/hash.c \
|
||||
$(TOP)/src/hash.h \
|
||||
@ -228,6 +227,8 @@ SRC = \
|
||||
$(TOP)/src/pager.c \
|
||||
$(TOP)/src/pager.h \
|
||||
$(TOP)/src/parse.y \
|
||||
$(TOP)/src/pcache.c \
|
||||
$(TOP)/src/pcache.h \
|
||||
$(TOP)/src/pragma.c \
|
||||
$(TOP)/src/prepare.c \
|
||||
$(TOP)/src/printf.c \
|
||||
@ -261,6 +262,7 @@ SRC = \
|
||||
# Generated source code files
|
||||
#
|
||||
SRC += \
|
||||
func2.c \
|
||||
keywordhash.h \
|
||||
opcodes.c \
|
||||
opcodes.h \
|
||||
@ -322,6 +324,7 @@ TESTSRC2 = \
|
||||
$(TOP)/src/os_unix.c \
|
||||
$(TOP)/src/os_win.c \
|
||||
$(TOP)/src/pager.c \
|
||||
$(TOP)/src/pcache.c \
|
||||
$(TOP)/src/pragma.c \
|
||||
$(TOP)/src/prepare.c \
|
||||
$(TOP)/src/printf.c \
|
||||
@ -515,8 +518,8 @@ expr.lo: $(TOP)/src/expr.c $(HDR)
|
||||
fault.lo: $(TOP)/src/fault.c $(HDR)
|
||||
$(LTCOMPILE) -c $(TOP)/src/fault.c
|
||||
|
||||
func.lo: $(TOP)/src/func.c $(HDR)
|
||||
$(LTCOMPILE) -c $(TOP)/src/func.c
|
||||
func2.lo: func2.c $(HDR)
|
||||
$(LTCOMPILE) -c func2.c
|
||||
|
||||
global.lo: $(TOP)/src/global.c $(HDR)
|
||||
$(LTCOMPILE) -c $(TOP)/src/global.c
|
||||
@ -575,6 +578,9 @@ mutex_w32.lo: $(TOP)/src/mutex_w32.c $(HDR)
|
||||
pager.lo: $(TOP)/src/pager.c $(HDR) $(TOP)/src/pager.h
|
||||
$(LTCOMPILE) -c $(TOP)/src/pager.c
|
||||
|
||||
pcache.lo: $(TOP)/src/pcache.c $(HDR) $(TOP)/src/pcache.h
|
||||
$(LTCOMPILE) -c $(TOP)/src/pcache.c
|
||||
|
||||
opcodes.lo: opcodes.c
|
||||
$(LTCOMPILE) -c opcodes.c
|
||||
|
||||
@ -607,6 +613,11 @@ parse.c: $(TOP)/src/parse.y lemon$(BEXE) $(TOP)/addopcodes.awk
|
||||
mv parse.h parse.h.temp
|
||||
$(NAWK) -f $(TOP)/addopcodes.awk parse.h.temp >parse.h
|
||||
|
||||
func2.c: $(TOP)/src/func.c $(HDR)
|
||||
$(BCC) -o mkfunction$(BEXE) $(OPTS) $(TOP)/tool/mkfunction.c -I$(TOP)/src -I.
|
||||
cat $(TOP)/src/func.c > func2.c
|
||||
./mkfunction$(BEXE) >> func2.c
|
||||
|
||||
pragma.lo: $(TOP)/src/pragma.c $(HDR)
|
||||
$(LTCOMPILE) -c $(TOP)/src/pragma.c
|
||||
|
||||
|
18
main.mk
18
main.mk
@ -50,7 +50,7 @@ TCCX = $(TCC) $(OPTS) -I. -I$(TOP)/src -I$(TOP) -I$(TOP)/ext/rtree
|
||||
#
|
||||
LIBOBJ+= alter.o analyze.o attach.o auth.o bitvec.o btmutex.o btree.o build.o \
|
||||
callback.o complete.o date.o delete.o \
|
||||
expr.o fault.o func.o global.o hash.o insert.o journal.o loadext.o \
|
||||
expr.o fault.o func2.o global.o hash.o insert.o journal.o loadext.o \
|
||||
main.o malloc.o mem1.o mem2.o mem3.o mem4.o mem5.o mem6.o \
|
||||
mutex.o mutex_os2.o mutex_unix.o mutex_w32.o \
|
||||
opcodes.o os.o os_os2.o os_unix.o os_win.o \
|
||||
@ -58,7 +58,7 @@ LIBOBJ+= alter.o analyze.o attach.o auth.o bitvec.o btmutex.o btree.o build.o \
|
||||
select.o status.o table.o $(TCLOBJ) tokenize.o trigger.o \
|
||||
update.o util.o vacuum.o \
|
||||
vdbe.o vdbeapi.o vdbeaux.o vdbeblob.o vdbefifo.o vdbemem.o \
|
||||
where.o utf.o legacy.o vtab.o rtree.o icu.o
|
||||
where.o utf.o legacy.o vtab.o rtree.o icu.o pcache.o
|
||||
|
||||
EXTOBJ = icu.o
|
||||
EXTOBJ += fts1.o \
|
||||
@ -98,7 +98,6 @@ SRC = \
|
||||
$(TOP)/src/delete.c \
|
||||
$(TOP)/src/expr.c \
|
||||
$(TOP)/src/fault.c \
|
||||
$(TOP)/src/func.c \
|
||||
$(TOP)/src/global.c \
|
||||
$(TOP)/src/hash.c \
|
||||
$(TOP)/src/hash.h \
|
||||
@ -155,6 +154,7 @@ SRC = \
|
||||
$(TOP)/src/vdbeblob.c \
|
||||
$(TOP)/src/vdbefifo.c \
|
||||
$(TOP)/src/vdbemem.c \
|
||||
$(TOP)/src/pcache.c \
|
||||
$(TOP)/src/vdbeInt.h \
|
||||
$(TOP)/src/vtab.c \
|
||||
$(TOP)/src/where.c
|
||||
@ -204,6 +204,7 @@ SRC += \
|
||||
opcodes.h \
|
||||
parse.c \
|
||||
parse.h \
|
||||
func2.c \
|
||||
sqlite3.h
|
||||
|
||||
|
||||
@ -241,10 +242,10 @@ TESTSRC = \
|
||||
|
||||
TESTSRC2 = \
|
||||
$(TOP)/src/attach.c $(TOP)/src/btree.c $(TOP)/src/build.c $(TOP)/src/date.c \
|
||||
$(TOP)/src/expr.c $(TOP)/src/func.c $(TOP)/src/insert.c $(TOP)/src/os.c \
|
||||
$(TOP)/src/expr.c func2.c $(TOP)/src/insert.c $(TOP)/src/os.c \
|
||||
$(TOP)/src/os_os2.c $(TOP)/src/os_unix.c $(TOP)/src/os_win.c \
|
||||
$(TOP)/src/pager.c $(TOP)/src/pragma.c $(TOP)/src/prepare.c \
|
||||
$(TOP)/src/printf.c $(TOP)/src/random.c \
|
||||
$(TOP)/src/printf.c $(TOP)/src/random.c $(TOP)/src/pcache.c \
|
||||
$(TOP)/src/select.c $(TOP)/src/tokenize.c \
|
||||
$(TOP)/src/utf.c $(TOP)/src/util.c $(TOP)/src/vdbeapi.c $(TOP)/src/vdbeaux.c \
|
||||
$(TOP)/src/vdbe.c $(TOP)/src/vdbemem.c $(TOP)/src/where.c parse.c
|
||||
@ -262,6 +263,7 @@ HDR = \
|
||||
$(TOP)/src/os.h \
|
||||
$(TOP)/src/os_common.h \
|
||||
$(TOP)/src/pager.h \
|
||||
$(TOP)/src/pcache.h \
|
||||
parse.h \
|
||||
sqlite3.h \
|
||||
$(TOP)/src/sqlite3ext.h \
|
||||
@ -360,6 +362,10 @@ opcodes.c: opcodes.h $(TOP)/mkopcodec.awk
|
||||
opcodes.h: parse.h $(TOP)/src/vdbe.c $(TOP)/mkopcodeh.awk
|
||||
cat parse.h $(TOP)/src/vdbe.c |$(NAWK) -f $(TOP)/mkopcodeh.awk >opcodes.h
|
||||
|
||||
func2.c: $(TOP)/src/func.c $(HDR)
|
||||
$(BCC) -o mkfunction $(OPTS) $(TOP)/tool/mkfunction.c -I$(TOP)/src -I.
|
||||
cat $(TOP)/src/func.c > func2.c
|
||||
./mkfunction >> func2.c
|
||||
|
||||
# Rules to build parse.c and parse.h - the outputs of lemon.
|
||||
#
|
||||
@ -502,4 +508,4 @@ clean:
|
||||
rm -f *.da *.bb *.bbg gmon.out
|
||||
rm -rf tsrc target_source
|
||||
rm -f testloadext.dll libtestloadext.so
|
||||
rm -f sqlite3.c fts?amal.c
|
||||
rm -f sqlite3.c fts?amal.c tclsqlite3.c func2.c
|
||||
|
63
manifest
63
manifest
@ -1,7 +1,7 @@
|
||||
C Do\snot\sflatten\sthe\sright\sterm\sof\sa\sLEFT\sjoin.\s\sTicket\s#3300.\s(CVS\s5565)
|
||||
D 2008-08-14T00:19:49
|
||||
C Add\sthe\spcache\smodule\sfrom\sthe\sexperimental\sbranch.\sAlso\schange\sthings\sso\sthat\smost\sof\sthe\sbuilt-in\sSQL\sfunctions\sare\skept\sin\ssingle\sstatic\shash-table,\srather\sthan\screating\sand\spopulating\sa\sseparate\shash\stable\sfor\seach\sopen\sdatabase\sconnection.\s(CVS\s5566)
|
||||
D 2008-08-20T14:49:24
|
||||
F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
|
||||
F Makefile.in 2713ea64947be3b35f35d9a3158bb8299c90b019
|
||||
F Makefile.in e277c1f6dee97c18ef2f64db608da63eea4cc933
|
||||
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
|
||||
F README b974cdc3f9f12b87e851b04e75996d720ebf81ac
|
||||
F VERSION 1d5b2c9192236ed2c6bad659a7c2d1662e39e7b9
|
||||
@ -76,7 +76,7 @@ F ext/rtree/rtree_util.tcl ee0a0311eb12175319d78bfb37302320496cee6e
|
||||
F ext/rtree/viewrtree.tcl 09526398dae87a5a87c5aac2b3854dbaf8376869
|
||||
F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895
|
||||
F ltmain.sh 09fe5815427dc7d0abb188bbcdf0e34896577210
|
||||
F main.mk eace65a99d12045ca496069dc707405a63197006
|
||||
F main.mk ec8a5d47c4cb447dc666472528a7e8da91384a57
|
||||
F mkdll.sh 79d1ed6ae221c10589dd969f130f8a3cccfffbb7
|
||||
F mkextu.sh 416f9b7089d80e5590a29692c9d9280a10dbad9f
|
||||
F mkextw.sh 4123480947681d9b434a5e7b1ee08135abe409ac
|
||||
@ -96,17 +96,17 @@ F src/attach.c a85c14612e7e3410e0c3d2e0241832fa9688bd14
|
||||
F src/auth.c c8b2ab5c8bad4bd90ed7c294694f48269162c627
|
||||
F src/bitvec.c 95c86bd18d8fedf0533f5af196192546e10a7e7d
|
||||
F src/btmutex.c 709cad2cdca0afd013f0f612363810e53f59ec53
|
||||
F src/btree.c c38431aed9dcdf62916c9009d6f9971e588189fe
|
||||
F src/btree.c c536edea3dd8a9f5f56101ca66cd5dfe699a5d7b
|
||||
F src/btree.h 6371c5e599fab391a150c96afbc10062b276d107
|
||||
F src/btreeInt.h ab18c7b4980314e9e4b402e5dcde09f3c2545576
|
||||
F src/build.c 931ed94fd3bbd67b6ac9d5ac6a45dc01e9f01726
|
||||
F src/callback.c c9f75a4c403f166af3761df47d78a806587d63af
|
||||
F src/callback.c 1b1a5c580cdf7d83db24001bf8e5c09e2b08658f
|
||||
F src/complete.c cb14e06dbe79dee031031f0d9e686ff306afe07c
|
||||
F src/date.c 52a54811218a76da6235420f532ece841159a96d
|
||||
F src/delete.c 0d115c173863b3c688c3083ef7857c7f2e9f7a18
|
||||
F src/expr.c 278d3950f55e04a2486e7b8dede3713a2ed6c0e1
|
||||
F src/fault.c 3638519d1e0b82bccfafcb9f5ff491918b28f8e1
|
||||
F src/func.c 54efe220cc1ef3859a4b738011621b63a0d697c5
|
||||
F src/func.c d97ff7b72f3ddcd88970048e2894954a3f5b01d8
|
||||
F src/global.c b9c96ee2317a6e1391763c7db1098a6473a91863
|
||||
F src/hash.c eb64e48f3781100e5934f759fbe72a63a8fe78cb
|
||||
F src/hash.h 031cd9f915aff27e12262cb9eb570ac1b8326b53
|
||||
@ -115,8 +115,8 @@ F src/insert.c 89cd9af52a5ea6fb7d0cfc9c3b935d6406c360c4
|
||||
F src/journal.c cffd2cd214e58c0e99c3ff632b3bee6c7cbb260e
|
||||
F src/legacy.c aac57bd984e666059011ea01ec4383892a253be3
|
||||
F src/loadext.c eb1fe4f44d7c8ff53fc0c6a4388ab79fbd34cd64
|
||||
F src/main.c c5ed24ad2b27bc93aea580a17f370a19897165f6
|
||||
F src/malloc.c 22c68fc62f0c2df0f1deb8cd9a5ea968f995cac2
|
||||
F src/main.c c900d0f46ddb127866ba272a2124ce56dd8592dd
|
||||
F src/malloc.c 56918cddc4da7a0590eef4a2497e97b781f5c25f
|
||||
F src/md5.c 008216bbb5d34c6fbab5357aa68575ad8a31516a
|
||||
F src/mem1.c 3a7fe31d8290baa3bb203af72f7dfd6323966bcd
|
||||
F src/mem2.c 7256327b96927020824e06ffb3443b99a28da047
|
||||
@ -135,9 +135,11 @@ F src/os_common.h 24525d8b7bce66c374dfc1810a6c9043f3359b60
|
||||
F src/os_os2.c 676ed273b17bd260f905df81375c9f9950d85517
|
||||
F src/os_unix.c fe0dbc35bcd3de49e46b132abfc0f45d6dd6a864
|
||||
F src/os_win.c aefe9ee26430678a19a058a874e4e2bd91398142
|
||||
F src/pager.c b6a366f2343e7f127d7e70dbe76cd664336143cd
|
||||
F src/pager.h 588c1ac195228b2da45c4e5f7ab6c2fd253d1751
|
||||
F src/pager.c 9f813a8f26680ff510335e2bbd01910b2a77277b
|
||||
F src/pager.h fb9376af5ba8e1eb78ee3b4f15eb0f60658ffd65
|
||||
F src/parse.y 84003422b2862f82bd187dfa2399557fd1f4ecbe
|
||||
F src/pcache.c c1a9abb5e2aa3d1d52a2995c8e0a36535d4d1bc2
|
||||
F src/pcache.h 71ade7a84ed87d9d20507315260b1d91808d7c9a
|
||||
F src/pragma.c 6e207b4f69901089758c02c02e0bf86ed12a4d8f
|
||||
F src/prepare.c fceb567b359daaa6c6e2a4d04a01dec01ac0c907
|
||||
F src/printf.c 2e984b2507291a7e16d89dc9bb60582904f6247d
|
||||
@ -146,19 +148,19 @@ F src/select.c defdb8cdf7d2d8e1e0df117e50af6378fdaf1329
|
||||
F src/shell.c d83b578a8ccdd3e0e7fef4388a0887ce9f810967
|
||||
F src/sqlite.h.in 54e51c22e2294c5989156b0aec87aa44168ac1f0
|
||||
F src/sqlite3ext.h 1e3887c9bd3ae66cb599e922824b04cd0d0f2c3e
|
||||
F src/sqliteInt.h 7c68cacc760e8038ba6221c4d9ee3a7f0580e181
|
||||
F src/sqliteInt.h e49782bc45092732795297d83331b1855eb234b3
|
||||
F src/sqliteLimit.h f435e728c6b620ef7312814d660a81f9356eb5c8
|
||||
F src/status.c 8caa772cd9310bc297280f7cf0ede4d69ed5b801
|
||||
F src/table.c 22744786199c9195720c15a7a42cb97b2e2728d8
|
||||
F src/tclsqlite.c ec46084184f033ba396a9ee7b5514b695083d0f3
|
||||
F src/test1.c 0ae2203b03dec8ecf8ad731038df47ba27bfe68c
|
||||
F src/test2.c 7a634c1e044be3ea5845e65155fdd1cab13936cb
|
||||
F src/test1.c f92039530f6a6253ec8d3bfeaa54205a0036bbb6
|
||||
F src/test2.c 9601907ac0bab60f2f81695c3a6e9249621ae741
|
||||
F src/test3.c e85b7ce5c28c3ce7fbdbf7f98e1467b19786c62b
|
||||
F src/test4.c 41056378671e7b00e6305fa9ac6fa27e6f96f406
|
||||
F src/test5.c 162a1cea2105a2c460a3f39fa6919617b562a288
|
||||
F src/test6.c 0a0304a69cfa4962a429d084c6d451ff9e4fb572
|
||||
F src/test7.c 475b1fa7e3275408b40a3cbdc9508cbdc41ffa02
|
||||
F src/test8.c 7da151778887275c7f62b972363c78a5609f2bd8
|
||||
F src/test8.c 2f821eabefc73e4fd90ea24501d105e74b8e76d2
|
||||
F src/test9.c 904ebe0ed1472d6bad17a81e2ecbfc20017dc237
|
||||
F src/test_async.c da9f58f49faccd3a26ba89f58de125862351b6e2
|
||||
F src/test_autoext.c f53b0cdf7bf5f08100009572a5d65cdb540bd0ad
|
||||
@ -191,7 +193,7 @@ F src/vdbeaux.c 3e2e1f36c25eae32bdd605456c8be99f73e71eaf
|
||||
F src/vdbeblob.c f93110888ddc246215e9ba1f831d3d375bfd8355
|
||||
F src/vdbefifo.c 20fda2a7c4c0bcee1b90eb7e545fefcdbf2e1de7
|
||||
F src/vdbemem.c c37b2a266a49eaf0c0f5080157f9f1a908fdaac3
|
||||
F src/vtab.c 9c1bbb54d8b29a3412bff4eee32e9be309d85727
|
||||
F src/vtab.c edf8edb55dc93ec4bfe8b3f10213cf6c025edb9c
|
||||
F src/where.c a800184a2d023b15d6f2758b7a6c7ab011258fee
|
||||
F tclinstaller.tcl 4356d9d94d2b5ed5e68f9f0c80c4df3048dd7617
|
||||
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
|
||||
@ -368,9 +370,9 @@ F test/insert4.test 6e382eaf7295a4463e6f29ea20fcd8e63d097eeb
|
||||
F test/insert5.test 1f93cbe9742110119133d7e8e3ccfe6d7c249766
|
||||
F test/interrupt.test 42e7cf98646fd9cb4a3b131a93ed3c50b9e149f1
|
||||
F test/intpkey.test 537669fd535f62632ca64828e435b9e54e8d677f
|
||||
F test/io.test 23c52939ebf90f00d9cbd819ced6daa9f21445fa
|
||||
F test/io.test 92cedb5eff70064f9fcf4ec51e86591b1f0ad130
|
||||
F test/ioerr.test b42f249c9181b5864e53fdae38ef75475d71c66f
|
||||
F test/ioerr2.test 5598405c48842c6c0187daad9eb49eff2c54f80d
|
||||
F test/ioerr2.test 988bda4d8d6fa1593765a514bf7a24adb3240da9
|
||||
F test/ioerr3.test d3cec5e1a11ad6d27527d0d38573fbff14c71bdd
|
||||
F test/ioerr4.test fc6eddfec2efc2f1ed217b9eae4c1c1d3516ce86
|
||||
F test/ioerr5.test fe59ee3e3d45a121bcdb8f462b718076e66b4ca7
|
||||
@ -417,7 +419,7 @@ F test/malloc_common.tcl e082fe4791dad22b49d2ad3f7dcf1dcbee1a4cec
|
||||
F test/manydb.test 8de36b8d33aab5ef295b11d9e95310aeded31af8
|
||||
F test/memdb.test a67bda4ff90a38f2b19f6c7f95aa7289e051d893
|
||||
F test/memleak.test d2d2a1ff7105d32dc3fdf691458cf6cba58c7217
|
||||
F test/memsubsys1.test 3cfd3237dbbceaf65673be7265c58d8a34d63cbb
|
||||
F test/memsubsys1.test bd578712272a3c327873b388396e351586d29e61
|
||||
F test/memsubsys2.test 72a731225997ad5e8df89fdbeae9224616b6aecc
|
||||
F test/minmax.test 722d80816f7e096bf2c04f4111f1a6c1ba65453d
|
||||
F test/minmax2.test 33504c01a03bd99226144e4b03f7631a274d66e0
|
||||
@ -430,16 +432,16 @@ F test/misc5.test 6a5c1e3217a95b0db05ff9a0f1ecb5ce9043ffef
|
||||
F test/misc6.test 953cc693924d88e6117aeba16f46f0bf5abede91
|
||||
F test/misc7.test fd424ff93a83bb6a31463eb043c588777d8215a8
|
||||
F test/misuse.test 30b3a458e5a70c31e74c291937b6c82204c59f33
|
||||
F test/mutex1.test 7f5e21fd11fe22de079e5dcd394ee4f6c257e68e
|
||||
F test/mutex1.test 3f7c86418b85404f5c5d921f5d8023684bb3ac49
|
||||
F test/mutex2.test 56f282f436596e9febdc6e0db2c507432b6724bb
|
||||
F test/nan.test 14c41572ff52dbc740b1c3303dd313a90dc6084c
|
||||
F test/notnull.test 44d600f916b770def8b095a9962dbe3be5a70d82
|
||||
F test/null.test a8b09b8ed87852742343b33441a9240022108993
|
||||
F test/openv2.test f5dd6b23e4dce828eb211649b600763c42a668df
|
||||
F test/pager.test 60303481b22b240c18d6dd1b64edcecc2f4b5a97
|
||||
F test/pager2.test c025f91b75fe65e85febda64d9416428b8a5cab5
|
||||
F test/pager.test 1e1832795e9e07a359c959ffdddcf7275a88f54c
|
||||
F test/pager2.test 070983b89a308adaba525a2f9c1ba0592c72fa3d
|
||||
F test/pager3.test 2323bf27fd5bd887b580247e5bce500ceee994b4
|
||||
F test/pageropt.test 6df72c441db0a037b7ec6990d16311c24fbea77b
|
||||
F test/pageropt.test 3ee6578891baaca967f0bd349e4abfa736229e1a
|
||||
F test/pagesize.test e0a8b3fe80f8b8e808d94a00734c7a18c76c407e
|
||||
F test/permutations.test 4ad59e4489255b025aac0cc661789d35a83d87ec
|
||||
F test/pragma.test 2c675ed9a288094ed62bf55b35fbc749e25670fb
|
||||
@ -471,7 +473,7 @@ F test/selectB.test 31e81ac9af7d224850e0706350f070ecb92fcbc7
|
||||
F test/server1.test f5b790d4c0498179151ca8a7715a65a7802c859c
|
||||
F test/shared.test b9f3bbd3ba727c5f1f8c815b7d0199262aacf214
|
||||
F test/shared2.test 0ee9de8964d70e451936a48c41cb161d9134ccf4
|
||||
F test/shared3.test 987316be601e2349e6a340a6d5f8ed981e507931
|
||||
F test/shared3.test 9c880afc081d797da514ef64bccf36f3fce2f09c
|
||||
F test/shared4.test d0fadacb50bb6981b2fb9dc6d1da30fa1edddf83
|
||||
F test/shared_err.test 776ab7196ecda8b07a075e115b0725806991e151
|
||||
F test/shortread1.test bb591ef20f0fd9ed26d0d12e80eee6d7ac8897a3
|
||||
@ -527,7 +529,7 @@ F test/tkt2285.test cca17be61cf600b397188e77e7143844d2b977e9
|
||||
F test/tkt2332.test fc955609b958ca86dfa102832243370a0cc84070
|
||||
F test/tkt2339.test 73bd17818924cd2ac442e5fd9916b58565739450
|
||||
F test/tkt2391.test ab7a11be7402da8b51a5be603425367aa0684567
|
||||
F test/tkt2409.test 20318bf6acd9b834b4420548f277b8e3a7420cd1
|
||||
F test/tkt2409.test 695269f90bbd30285fb1dd1499e8cc0d827a647d
|
||||
F test/tkt2450.test 77ed94863f2049c1420288ddfea2d41e5e0971d6
|
||||
F test/tkt2640.test 28134f5d1e05658ef182520cf0b680fa3de5211b
|
||||
F test/tkt2643.test 3f3ebb743da00d4fed4fcf6daed92a0e18e57813
|
||||
@ -601,9 +603,10 @@ F tool/lempar.c 4d115ee7c0c8a749d5b22abed731abb4e6546a5f
|
||||
F tool/memleak.awk 4e7690a51bf3ed757e611273d43fe3f65b510133
|
||||
F tool/memleak2.awk 9cc20c8e8f3c675efac71ea0721ee6874a1566e8
|
||||
F tool/memleak3.tcl 7707006ee908cffff210c98158788d85bb3fcdbf
|
||||
F tool/mkfunction.c a785a1970027bc7a833aa8afb43d6786a33c11ae
|
||||
F tool/mkkeywordhash.c ef93810fc41fb3d3dbacf9a33a29be88ea99ffa9
|
||||
F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e x
|
||||
F tool/mksqlite3c.tcl bc5a951735e78eb37cd47f539b2400318c436872
|
||||
F tool/mksqlite3c.tcl 5b4b6f974d9d761477dfb24e2a0c578b27419ef5
|
||||
F tool/mksqlite3internalh.tcl 7b43894e21bcb1bb39e11547ce7e38a063357e87
|
||||
F tool/omittest.tcl 5a25ea687df5da8dd9b94bf1683f5cf2c210e51d
|
||||
F tool/opcodeDoc.awk b3a2a3d5d3075b8bd90b7afe24283efdd586659c
|
||||
@ -618,7 +621,7 @@ F tool/speedtest16.c c8a9c793df96db7e4933f0852abb7a03d48f2e81
|
||||
F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
|
||||
F tool/speedtest8.c 1dbced29de5f59ba2ebf877edcadf171540374d1
|
||||
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
|
||||
P a519cdb2f46fffe16e666f161479a22463616cb3
|
||||
R 4f817c5e785c5409dbaded5f21e587f1
|
||||
U drh
|
||||
Z 3d91f3841f779b95c0adaebee822ab63
|
||||
P 8947c72f93d0b79c8061a3bfd5ab595edfb155a5
|
||||
R 10a01c477903bc3de835b14e423b9901
|
||||
U danielk1977
|
||||
Z 0dd70edbac3b8ebacf6c1d5a239b80f0
|
||||
|
@ -1 +1 @@
|
||||
8947c72f93d0b79c8061a3bfd5ab595edfb155a5
|
||||
cb494e10d71852024647aaa254203579ad438ea9
|
26
src/btree.c
26
src/btree.c
@ -9,7 +9,7 @@
|
||||
** May you share freely, never taking more than you give.
|
||||
**
|
||||
*************************************************************************
|
||||
** $Id: btree.c,v 1.497 2008/08/13 19:11:48 drh Exp $
|
||||
** $Id: btree.c,v 1.498 2008/08/20 14:49:24 danielk1977 Exp $
|
||||
**
|
||||
** This file implements a external (disk-based) database using BTrees.
|
||||
** See the header comment on "btreeInt.h" for additional information.
|
||||
@ -1132,18 +1132,19 @@ static void releasePage(MemPage *pPage){
|
||||
** reaches zero. We need to unref the pParent pointer when that
|
||||
** happens.
|
||||
*/
|
||||
static void pageDestructor(DbPage *pData, int pageSize){
|
||||
static void pageDestructor(DbPage *pData){
|
||||
MemPage *pPage;
|
||||
assert( (pageSize & 7)==0 );
|
||||
pPage = (MemPage *)sqlite3PagerGetExtra(pData);
|
||||
assert( pPage->isInit==0 || sqlite3_mutex_held(pPage->pBt->mutex) );
|
||||
if( pPage->pParent ){
|
||||
MemPage *pParent = pPage->pParent;
|
||||
assert( pParent->pBt==pPage->pBt );
|
||||
pPage->pParent = 0;
|
||||
releasePage(pParent);
|
||||
if( pPage ){
|
||||
assert( pPage->isInit==0 || sqlite3_mutex_held(pPage->pBt->mutex) );
|
||||
if( pPage->pParent ){
|
||||
MemPage *pParent = pPage->pParent;
|
||||
assert( pParent->pBt==pPage->pBt );
|
||||
pPage->pParent = 0;
|
||||
releasePage(pParent);
|
||||
}
|
||||
pPage->isInit = 0;
|
||||
}
|
||||
pPage->isInit = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1287,7 +1288,7 @@ int sqlite3BtreeOpen(
|
||||
}
|
||||
pBt->busyHdr.xFunc = sqlite3BtreeInvokeBusyHandler;
|
||||
pBt->busyHdr.pArg = pBt;
|
||||
rc = sqlite3PagerOpen(pVfs, &pBt->pPager, zFilename,
|
||||
rc = sqlite3PagerOpen(pVfs, &pBt->pPager, zFilename, pageDestructor,
|
||||
EXTRA_SIZE, flags, vfsFlags);
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = sqlite3PagerReadFileheader(pBt->pPager,sizeof(zDbHeader),zDbHeader);
|
||||
@ -1298,7 +1299,7 @@ int sqlite3BtreeOpen(
|
||||
sqlite3PagerSetBusyhandler(pBt->pPager, &pBt->busyHdr);
|
||||
p->pBt = pBt;
|
||||
|
||||
sqlite3PagerSetDestructor(pBt->pPager, pageDestructor);
|
||||
/* sqlite3PagerSetDestructor(pBt->pPager, pageDestructor); */
|
||||
sqlite3PagerSetReiniter(pBt->pPager, pageReinit);
|
||||
pBt->pCursor = 0;
|
||||
pBt->pPage1 = 0;
|
||||
@ -3488,6 +3489,7 @@ void sqlite3BtreeMoveToParent(BtCursor *pCur){
|
||||
assert( !sqlite3BtreeIsRootPage(pPage) );
|
||||
pParent = pPage->pParent;
|
||||
assert( pParent!=0 );
|
||||
assert( pPage->pDbPage->nRef>0 );
|
||||
idxParent = pPage->idxParent;
|
||||
sqlite3PagerRef(pParent->pDbPage);
|
||||
releasePage(pPage);
|
||||
|
@ -13,7 +13,7 @@
|
||||
** This file contains functions used to access the internal hash tables
|
||||
** of user defined functions and collation sequences.
|
||||
**
|
||||
** $Id: callback.c,v 1.26 2008/07/28 19:34:53 drh Exp $
|
||||
** $Id: callback.c,v 1.27 2008/08/20 14:49:24 danielk1977 Exp $
|
||||
*/
|
||||
|
||||
#include "sqliteInt.h"
|
||||
@ -222,6 +222,44 @@ CollSeq *sqlite3FindCollSeq(
|
||||
return pColl;
|
||||
}
|
||||
|
||||
/* During the search for the best function definition, this procedure
|
||||
** is called to test how well the function passed as the first argument
|
||||
** matches the request for a function with nArg arguments in a system
|
||||
** that uses encoding enc. The value returned indicates how well the
|
||||
** request is matched. A higher value indicates a better match.
|
||||
**
|
||||
** The returned value is always between 1 and 6, as follows:
|
||||
**
|
||||
** 1: A variable arguments function that prefers UTF-8 when a UTF-16
|
||||
** encoding is requested, or vice versa.
|
||||
** 2: A variable arguments function that uses UTF-16BE when UTF-16LE is
|
||||
** requested, or vice versa.
|
||||
** 3: A variable arguments function using the same text encoding.
|
||||
** 4: A function with the exact number of arguments requested that
|
||||
** prefers UTF-8 when a UTF-16 encoding is requested, or vice versa.
|
||||
** 5: A function with the exact number of arguments requested that
|
||||
** prefers UTF-16LE when UTF-16BE is requested, or vice versa.
|
||||
** 6: An exact match.
|
||||
**
|
||||
*/
|
||||
static int matchQuality(FuncDef *p, int nArg, u8 enc){
|
||||
int match = 0;
|
||||
if( p->nArg==-1 || p->nArg==nArg || nArg==-1 ){
|
||||
match = 1;
|
||||
if( p->nArg==nArg || nArg==-1 ){
|
||||
match = 4;
|
||||
}
|
||||
if( enc==p->iPrefEnc ){
|
||||
match += 2;
|
||||
}
|
||||
else if( (enc==SQLITE_UTF16LE && p->iPrefEnc==SQLITE_UTF16BE) ||
|
||||
(enc==SQLITE_UTF16BE && p->iPrefEnc==SQLITE_UTF16LE) ){
|
||||
match += 1;
|
||||
}
|
||||
}
|
||||
return match;
|
||||
}
|
||||
|
||||
/*
|
||||
** Locate a user function given a name, a number of arguments and a flag
|
||||
** indicating whether the function prefers UTF-16 over UTF-8. Return a
|
||||
@ -261,39 +299,26 @@ FuncDef *sqlite3FindFunction(
|
||||
|
||||
pFirst = (FuncDef*)sqlite3HashFind(&db->aFunc, zName, nName);
|
||||
for(p=pFirst; p; p=p->pNext){
|
||||
/* During the search for the best function definition, bestmatch is set
|
||||
** as follows to indicate the quality of the match with the definition
|
||||
** pointed to by pBest:
|
||||
**
|
||||
** 0: pBest is NULL. No match has been found.
|
||||
** 1: A variable arguments function that prefers UTF-8 when a UTF-16
|
||||
** encoding is requested, or vice versa.
|
||||
** 2: A variable arguments function that uses UTF-16BE when UTF-16LE is
|
||||
** requested, or vice versa.
|
||||
** 3: A variable arguments function using the same text encoding.
|
||||
** 4: A function with the exact number of arguments requested that
|
||||
** prefers UTF-8 when a UTF-16 encoding is requested, or vice versa.
|
||||
** 5: A function with the exact number of arguments requested that
|
||||
** prefers UTF-16LE when UTF-16BE is requested, or vice versa.
|
||||
** 6: An exact match.
|
||||
**
|
||||
** A larger value of 'matchqual' indicates a more desirable match.
|
||||
*/
|
||||
if( p->nArg==-1 || p->nArg==nArg || nArg==-1 ){
|
||||
int match = 1; /* Quality of this match */
|
||||
if( p->nArg==nArg || nArg==-1 ){
|
||||
match = 4;
|
||||
}
|
||||
if( enc==p->iPrefEnc ){
|
||||
match += 2;
|
||||
}
|
||||
else if( (enc==SQLITE_UTF16LE && p->iPrefEnc==SQLITE_UTF16BE) ||
|
||||
(enc==SQLITE_UTF16BE && p->iPrefEnc==SQLITE_UTF16LE) ){
|
||||
match += 1;
|
||||
}
|
||||
int match = matchQuality(p, nArg, enc);
|
||||
if( match>bestmatch ){
|
||||
pBest = p;
|
||||
bestmatch = match;
|
||||
}
|
||||
}
|
||||
|
||||
/* If the createFlag parameter is false and no match was found amongst
|
||||
** the custom functions stored in sqlite3.aFunc, try to find a built-in
|
||||
** function to use.
|
||||
*/
|
||||
if( !createFlag && !pBest ){
|
||||
FuncDef *aFunc;
|
||||
int nFunc;
|
||||
int i;
|
||||
nFunc = sqlite3GetBuiltinFunction(zName, nName, &aFunc);
|
||||
for(i=0; i<nFunc; i++){
|
||||
int match = matchQuality(&aFunc[i], nArg, enc);
|
||||
if( match>bestmatch ){
|
||||
pBest = p;
|
||||
pBest = &aFunc[i];
|
||||
bestmatch = match;
|
||||
}
|
||||
}
|
||||
@ -304,7 +329,8 @@ FuncDef *sqlite3FindFunction(
|
||||
** new entry to the hash table and return it.
|
||||
*/
|
||||
if( createFlag && bestmatch<6 &&
|
||||
(pBest = sqlite3DbMallocZero(db, sizeof(*pBest)+nName))!=0 ){
|
||||
(pBest = sqlite3DbMallocZero(db, sizeof(*pBest)+nName+1))!=0 ){
|
||||
pBest->zName = (char *)&pBest[1];
|
||||
pBest->nArg = nArg;
|
||||
pBest->pNext = pFirst;
|
||||
pBest->iPrefEnc = enc;
|
||||
|
229
src/func.c
229
src/func.c
@ -16,15 +16,17 @@
|
||||
** sqliteRegisterBuildinFunctions() found at the bottom of the file.
|
||||
** All other code has file scope.
|
||||
**
|
||||
** $Id: func.c,v 1.196 2008/07/28 19:34:53 drh Exp $
|
||||
** $Id: func.c,v 1.197 2008/08/20 14:49:24 danielk1977 Exp $
|
||||
*/
|
||||
|
||||
#ifndef CREATE_BUILTIN_HASHTABLE
|
||||
|
||||
#include "sqliteInt.h"
|
||||
#include <ctype.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include "vdbeInt.h"
|
||||
|
||||
|
||||
/*
|
||||
** Return the collating function associated with a function.
|
||||
*/
|
||||
@ -1214,107 +1216,12 @@ static void groupConcatFinalize(sqlite3_context *context){
|
||||
** external linkage.
|
||||
*/
|
||||
void sqlite3RegisterBuiltinFunctions(sqlite3 *db){
|
||||
static const struct {
|
||||
char *zName;
|
||||
signed char nArg;
|
||||
u8 argType; /* 1: 0, 2: 1, 3: 2,... N: N-1. */
|
||||
u8 eTextRep; /* 1: UTF-16. 0: UTF-8 */
|
||||
u8 needCollSeq;
|
||||
void (*xFunc)(sqlite3_context*,int,sqlite3_value **);
|
||||
} aFuncs[] = {
|
||||
{ "min", -1, 0, SQLITE_UTF8, 1, minmaxFunc },
|
||||
{ "min", 0, 0, SQLITE_UTF8, 1, 0 },
|
||||
{ "max", -1, 1, SQLITE_UTF8, 1, minmaxFunc },
|
||||
{ "max", 0, 1, SQLITE_UTF8, 1, 0 },
|
||||
{ "typeof", 1, 0, SQLITE_UTF8, 0, typeofFunc },
|
||||
{ "length", 1, 0, SQLITE_UTF8, 0, lengthFunc },
|
||||
{ "substr", 2, 0, SQLITE_UTF8, 0, substrFunc },
|
||||
{ "substr", 3, 0, SQLITE_UTF8, 0, substrFunc },
|
||||
{ "abs", 1, 0, SQLITE_UTF8, 0, absFunc },
|
||||
{ "round", 1, 0, SQLITE_UTF8, 0, roundFunc },
|
||||
{ "round", 2, 0, SQLITE_UTF8, 0, roundFunc },
|
||||
{ "upper", 1, 0, SQLITE_UTF8, 0, upperFunc },
|
||||
{ "lower", 1, 0, SQLITE_UTF8, 0, lowerFunc },
|
||||
{ "coalesce", -1, 0, SQLITE_UTF8, 0, ifnullFunc },
|
||||
{ "coalesce", 0, 0, SQLITE_UTF8, 0, 0 },
|
||||
{ "coalesce", 1, 0, SQLITE_UTF8, 0, 0 },
|
||||
{ "hex", 1, 0, SQLITE_UTF8, 0, hexFunc },
|
||||
{ "ifnull", 2, 0, SQLITE_UTF8, 1, ifnullFunc },
|
||||
{ "random", -1, 0, SQLITE_UTF8, 0, randomFunc },
|
||||
{ "randomblob", 1, 0, SQLITE_UTF8, 0, randomBlob },
|
||||
{ "nullif", 2, 0, SQLITE_UTF8, 1, nullifFunc },
|
||||
{ "sqlite_version", 0, 0, SQLITE_UTF8, 0, versionFunc},
|
||||
{ "quote", 1, 0, SQLITE_UTF8, 0, quoteFunc },
|
||||
{ "last_insert_rowid", 0, 0, SQLITE_UTF8, 0, last_insert_rowid },
|
||||
{ "changes", 0, 0, SQLITE_UTF8, 0, changes },
|
||||
{ "total_changes", 0, 0, SQLITE_UTF8, 0, total_changes },
|
||||
{ "replace", 3, 0, SQLITE_UTF8, 0, replaceFunc },
|
||||
{ "ltrim", 1, 1, SQLITE_UTF8, 0, trimFunc },
|
||||
{ "ltrim", 2, 1, SQLITE_UTF8, 0, trimFunc },
|
||||
{ "rtrim", 1, 2, SQLITE_UTF8, 0, trimFunc },
|
||||
{ "rtrim", 2, 2, SQLITE_UTF8, 0, trimFunc },
|
||||
{ "trim", 1, 3, SQLITE_UTF8, 0, trimFunc },
|
||||
{ "trim", 2, 3, SQLITE_UTF8, 0, trimFunc },
|
||||
{ "zeroblob", 1, 0, SQLITE_UTF8, 0, zeroblobFunc },
|
||||
#ifdef SQLITE_SOUNDEX
|
||||
{ "soundex", 1, 0, SQLITE_UTF8, 0, soundexFunc},
|
||||
#endif
|
||||
#ifndef SQLITE_OMIT_LOAD_EXTENSION
|
||||
{ "load_extension", 1, 0, SQLITE_UTF8, 0, loadExt },
|
||||
{ "load_extension", 2, 0, SQLITE_UTF8, 0, loadExt },
|
||||
#endif
|
||||
};
|
||||
static const struct {
|
||||
char *zName;
|
||||
signed char nArg;
|
||||
u8 argType;
|
||||
u8 needCollSeq;
|
||||
void (*xStep)(sqlite3_context*,int,sqlite3_value**);
|
||||
void (*xFinalize)(sqlite3_context*);
|
||||
} aAggs[] = {
|
||||
{ "min", 1, 0, 1, minmaxStep, minMaxFinalize },
|
||||
{ "max", 1, 1, 1, minmaxStep, minMaxFinalize },
|
||||
{ "sum", 1, 0, 0, sumStep, sumFinalize },
|
||||
{ "total", 1, 0, 0, sumStep, totalFinalize },
|
||||
{ "avg", 1, 0, 0, sumStep, avgFinalize },
|
||||
{ "count", 0, 0, 0, countStep, countFinalize },
|
||||
{ "count", 1, 0, 0, countStep, countFinalize },
|
||||
{ "group_concat", -1, 0, 0, groupConcatStep, groupConcatFinalize },
|
||||
};
|
||||
int i;
|
||||
|
||||
for(i=0; i<sizeof(aFuncs)/sizeof(aFuncs[0]); i++){
|
||||
void *pArg;
|
||||
u8 argType = aFuncs[i].argType;
|
||||
pArg = SQLITE_INT_TO_PTR(argType);
|
||||
sqlite3CreateFunc(db, aFuncs[i].zName, aFuncs[i].nArg,
|
||||
aFuncs[i].eTextRep, pArg, aFuncs[i].xFunc, 0, 0);
|
||||
if( aFuncs[i].needCollSeq ){
|
||||
FuncDef *pFunc = sqlite3FindFunction(db, aFuncs[i].zName,
|
||||
strlen(aFuncs[i].zName), aFuncs[i].nArg, aFuncs[i].eTextRep, 0);
|
||||
if( pFunc && aFuncs[i].needCollSeq ){
|
||||
pFunc->needCollSeq = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
#ifndef SQLITE_OMIT_ALTERTABLE
|
||||
sqlite3AlterFunctions(db);
|
||||
#endif
|
||||
#ifndef SQLITE_OMIT_PARSER
|
||||
sqlite3AttachFunctions(db);
|
||||
#endif
|
||||
for(i=0; i<sizeof(aAggs)/sizeof(aAggs[0]); i++){
|
||||
void *pArg = SQLITE_INT_TO_PTR(aAggs[i].argType);
|
||||
sqlite3CreateFunc(db, aAggs[i].zName, aAggs[i].nArg, SQLITE_UTF8,
|
||||
pArg, 0, aAggs[i].xStep, aAggs[i].xFinalize);
|
||||
if( aAggs[i].needCollSeq ){
|
||||
FuncDef *pFunc = sqlite3FindFunction( db, aAggs[i].zName,
|
||||
strlen(aAggs[i].zName), aAggs[i].nArg, SQLITE_UTF8, 0);
|
||||
if( pFunc && aAggs[i].needCollSeq ){
|
||||
pFunc->needCollSeq = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
sqlite3RegisterDateTimeFunctions(db);
|
||||
if( !db->mallocFailed ){
|
||||
int rc = sqlite3_overload_function(db, "MATCH", 2);
|
||||
@ -1326,11 +1233,6 @@ void sqlite3RegisterBuiltinFunctions(sqlite3 *db){
|
||||
#ifdef SQLITE_SSE
|
||||
(void)sqlite3SseFunctions(db);
|
||||
#endif
|
||||
#ifdef SQLITE_CASE_SENSITIVE_LIKE
|
||||
sqlite3RegisterLikeFunctions(db, 1);
|
||||
#else
|
||||
sqlite3RegisterLikeFunctions(db, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1397,3 +1299,126 @@ int sqlite3IsLikeFunction(sqlite3 *db, Expr *pExpr, int *pIsNocase, char *aWc){
|
||||
*pIsNocase = (pDef->flags & SQLITE_FUNC_CASE)==0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
** The following three macros, FUNCTION(), LIKEFUNC() and AGGREGATE() are
|
||||
** used to create the literal values used for the FuncDef structures in
|
||||
** the global aBuiltinFunc[] array (see below).
|
||||
**
|
||||
** FUNCTION(zName, nArg, iArg, bNC, xFunc)
|
||||
** Used to create a scalar function definition of a function zName
|
||||
** implemented by C function xFunc that accepts nArg arguments. The
|
||||
** value passed as iArg is cast to a (void*) and made available
|
||||
** as the user-data (sqlite3_user_data()) for the function. If
|
||||
** argument bNC is true, then the FuncDef.needCollate flag is set.
|
||||
**
|
||||
** AGGREGATE(zName, nArg, iArg, bNC, xStep, xFinal)
|
||||
** Used to create an aggregate function definition implemented by
|
||||
** the C functions xStep and xFinal. The first four parameters
|
||||
** are interpreted in the same way as the first 4 parameters to
|
||||
** FUNCTION().
|
||||
**
|
||||
** LIKEFUNC(zName, nArg, pArg, flags)
|
||||
** Used to create a scalar function definition of a function zName
|
||||
** that accepts nArg arguments and is implemented by a call to C
|
||||
** function likeFunc. Argument pArg is cast to a (void *) and made
|
||||
** available as the function user-data (sqlite3_user_data()). The
|
||||
** FuncDef.flags variable is set to the value passed as the flags
|
||||
** parameter.
|
||||
**
|
||||
** See below for examples.
|
||||
*/
|
||||
#define FUNCTION(zName, nArg, iArg, bNC, xFunc) \
|
||||
{nArg, SQLITE_UTF8, bNC, 0, SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, #zName}
|
||||
|
||||
#define LIKEFUNC(zName, nArg, arg, flags) \
|
||||
{nArg, SQLITE_UTF8, 0, flags, (void *)arg, 0, likeFunc, 0, 0, #zName}
|
||||
|
||||
#define AGGREGATE(zName, nArg, arg, nc, xStep, xFinal) \
|
||||
{nArg, SQLITE_UTF8, nc, 0, SQLITE_INT_TO_PTR(arg), 0, 0, xStep,xFinal, #zName}
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
** This array of FuncDef structures contains most of the "built-in" functions
|
||||
** and aggregates. Function users (the other routines in the SQL compiler)
|
||||
** call the following function to access the FuncDef structures stored in
|
||||
** this array:
|
||||
**
|
||||
** int sqlite3GetBuiltinFunction(const char *z, int n, FuncDef **paFunc);
|
||||
**
|
||||
** The caller passes the name of the required function and its length
|
||||
** in parameters z and n, respectively. The value returned is the number
|
||||
** of FuncDef structures found in the aBuiltinFunc[] array that match
|
||||
** the requested name. If no match is found, 0 is returned. *paFunc is
|
||||
** set to point at a static array containing that subset of aBuiltinFunc[]
|
||||
** before returning.
|
||||
**
|
||||
** The implementation of sqlite3GetBuiltinFunction() is generated by
|
||||
** the program found in tool/mkfunction.c, which is compiled and executed
|
||||
** as part of the build process. The routine generated by this program
|
||||
** assumes that if there are two or more entries in the aBuiltinFunc[]
|
||||
** array with the same name (i.e. two versions of the "max" function),
|
||||
** then they must be stored in adjacent slots.
|
||||
*/
|
||||
static FuncDef aBuiltinFunc[] = {
|
||||
FUNCTION(ltrim, 1, 1, 0, trimFunc ),
|
||||
FUNCTION(ltrim, 2, 1, 0, trimFunc ),
|
||||
FUNCTION(rtrim, 1, 2, 0, trimFunc ),
|
||||
FUNCTION(rtrim, 2, 2, 0, trimFunc ),
|
||||
FUNCTION(trim, 1, 3, 0, trimFunc ),
|
||||
FUNCTION(trim, 2, 3, 0, trimFunc ),
|
||||
FUNCTION(min, -1, 0, 1, minmaxFunc ),
|
||||
FUNCTION(min, 0, 0, 1, 0 ),
|
||||
AGGREGATE(min, 1, 0, 1, minmaxStep, minMaxFinalize ),
|
||||
FUNCTION(max, -1, 1, 1, minmaxFunc ),
|
||||
FUNCTION(max, 0, 1, 1, 0 ),
|
||||
AGGREGATE(max, 1, 1, 1, minmaxStep, minMaxFinalize ),
|
||||
FUNCTION(typeof, 1, 0, 0, typeofFunc ),
|
||||
FUNCTION(length, 1, 0, 0, lengthFunc ),
|
||||
FUNCTION(substr, 2, 0, 0, substrFunc ),
|
||||
FUNCTION(substr, 3, 0, 0, substrFunc ),
|
||||
FUNCTION(abs, 1, 0, 0, absFunc ),
|
||||
FUNCTION(round, 1, 0, 0, roundFunc ),
|
||||
FUNCTION(round, 2, 0, 0, roundFunc ),
|
||||
FUNCTION(upper, 1, 0, 0, upperFunc ),
|
||||
FUNCTION(lower, 1, 0, 0, lowerFunc ),
|
||||
FUNCTION(coalesce, 1, 0, 0, 0 ),
|
||||
FUNCTION(coalesce, -1, 0, 0, ifnullFunc ),
|
||||
FUNCTION(coalesce, 0, 0, 0, 0 ),
|
||||
FUNCTION(hex, 1, 0, 0, hexFunc ),
|
||||
FUNCTION(ifnull, 2, 0, 1, ifnullFunc ),
|
||||
FUNCTION(random, -1, 0, 0, randomFunc ),
|
||||
FUNCTION(randomblob, 1, 0, 0, randomBlob ),
|
||||
FUNCTION(nullif, 2, 0, 1, nullifFunc ),
|
||||
FUNCTION(sqlite_version, 0, 0, 0, versionFunc ),
|
||||
FUNCTION(quote, 1, 0, 0, quoteFunc ),
|
||||
FUNCTION(last_insert_rowid, 0, 0, 0, last_insert_rowid),
|
||||
FUNCTION(changes, 0, 0, 0, changes ),
|
||||
FUNCTION(total_changes, 0, 0, 0, total_changes ),
|
||||
FUNCTION(replace, 3, 0, 0, replaceFunc ),
|
||||
FUNCTION(zeroblob, 1, 0, 0, zeroblobFunc ),
|
||||
#ifdef SQLITE_SOUNDEX
|
||||
FUNCTION(soundex, 1, 0, 0, soundexFunc ),
|
||||
#endif
|
||||
#ifndef SQLITE_OMIT_LOAD_EXTENSION
|
||||
FUNCTION(load_extension, 1, 0, 0, loadExt ),
|
||||
FUNCTION(load_extension, 2, 0, 0, loadExt ),
|
||||
#endif
|
||||
AGGREGATE(sum, 1, 0, 0, sumStep, sumFinalize ),
|
||||
AGGREGATE(total, 1, 0, 0, sumStep, totalFinalize ),
|
||||
AGGREGATE(avg, 1, 0, 0, sumStep, avgFinalize ),
|
||||
AGGREGATE(count, 0, 0, 0, countStep, countFinalize ),
|
||||
AGGREGATE(count, 1, 0, 0, countStep, countFinalize ),
|
||||
AGGREGATE(group_concat, -1, 0, 0, groupConcatStep, groupConcatFinalize),
|
||||
|
||||
LIKEFUNC(glob, 2, &globInfo, SQLITE_FUNC_LIKE|SQLITE_FUNC_CASE),
|
||||
#ifdef SQLITE_CASE_SENSITIVE_LIKE
|
||||
LIKEFUNC(like, 2, &likeInfoAlt, SQLITE_FUNC_LIKE|SQLITE_FUNC_CASE),
|
||||
LIKEFUNC(like, 3, &likeInfoAlt, SQLITE_FUNC_LIKE|SQLITE_FUNC_CASE),
|
||||
#else
|
||||
LIKEFUNC(like, 2, &likeInfoNorm, SQLITE_FUNC_LIKE),
|
||||
LIKEFUNC(like, 3, &likeInfoNorm, SQLITE_FUNC_LIKE),
|
||||
#endif
|
||||
};
|
||||
|
||||
|
@ -14,7 +14,7 @@
|
||||
** other files are for internal use by SQLite and should not be
|
||||
** accessed by users of the library.
|
||||
**
|
||||
** $Id: main.c,v 1.488 2008/08/12 15:21:12 drh Exp $
|
||||
** $Id: main.c,v 1.489 2008/08/20 14:49:24 danielk1977 Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
#include <ctype.h>
|
||||
@ -148,6 +148,11 @@ int sqlite3_initialize(void){
|
||||
if( sqlite3Config.isInit==0 && inProgress==0 ){
|
||||
inProgress = 1;
|
||||
rc = sqlite3_os_init();
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = sqlite3PcacheInitialize();
|
||||
sqlite3PCacheBufferSetup(sqlite3Config.pPage, sqlite3Config.szPage,
|
||||
sqlite3Config.nPage);
|
||||
}
|
||||
inProgress = 0;
|
||||
sqlite3Config.isInit = (rc==SQLITE_OK ? 1 : 0);
|
||||
}
|
||||
@ -193,6 +198,7 @@ int sqlite3_initialize(void){
|
||||
*/
|
||||
int sqlite3_shutdown(void){
|
||||
sqlite3Config.isMallocInit = 0;
|
||||
sqlite3PcacheShutdown();
|
||||
if( sqlite3Config.isInit ){
|
||||
sqlite3_os_end();
|
||||
}
|
||||
|
@ -12,7 +12,7 @@
|
||||
**
|
||||
** Memory allocation functions used throughout sqlite.
|
||||
**
|
||||
** $Id: malloc.c,v 1.34 2008/08/05 17:53:23 drh Exp $
|
||||
** $Id: malloc.c,v 1.35 2008/08/20 14:49:24 danielk1977 Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
#include <stdarg.h>
|
||||
@ -382,6 +382,7 @@ void sqlite3ScratchFree(void *p){
|
||||
** and that memory is of the right size and is not completely
|
||||
** consumed. Otherwise, failover to sqlite3Malloc().
|
||||
*/
|
||||
#if 0
|
||||
void *sqlite3PageMalloc(int n){
|
||||
void *p;
|
||||
assert( n>0 );
|
||||
@ -462,6 +463,7 @@ void sqlite3PageFree(void *p){
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
** TRUE if p is a lookaside memory allocation from db
|
||||
|
1688
src/pager.c
1688
src/pager.c
File diff suppressed because it is too large
Load Diff
@ -13,7 +13,7 @@
|
||||
** subsystem. The page cache subsystem reads and writes a file a page
|
||||
** at a time and provides a journal for rollback.
|
||||
**
|
||||
** @(#) $Id: pager.h,v 1.77 2008/07/16 18:17:56 danielk1977 Exp $
|
||||
** @(#) $Id: pager.h,v 1.78 2008/08/20 14:49:25 danielk1977 Exp $
|
||||
*/
|
||||
|
||||
#ifndef _PAGER_H_
|
||||
@ -70,7 +70,7 @@ typedef struct PgHdr DbPage;
|
||||
** See source code comments for a detailed description of the following
|
||||
** routines:
|
||||
*/
|
||||
int sqlite3PagerOpen(sqlite3_vfs *, Pager **ppPager, const char*, int,int,int);
|
||||
int sqlite3PagerOpen(sqlite3_vfs *, Pager **ppPager, const char*, void(*)(DbPage*), int,int,int);
|
||||
void sqlite3PagerSetBusyhandler(Pager*, BusyHandler *pBusyHandler);
|
||||
void sqlite3PagerSetDestructor(Pager*, void(*)(DbPage*,int));
|
||||
void sqlite3PagerSetReiniter(Pager*, void(*)(DbPage*,int));
|
||||
@ -113,6 +113,7 @@ int sqlite3PagerJournalMode(Pager *, int);
|
||||
i64 sqlite3PagerJournalSizeLimit(Pager *, i64);
|
||||
void *sqlite3PagerTempSpace(Pager*);
|
||||
int sqlite3PagerSync(Pager *pPager);
|
||||
void sqlite3PagerAlwaysRollback(Pager *pPager);
|
||||
|
||||
#if defined(SQLITE_ENABLE_MEMORY_MANAGEMENT) && !defined(SQLITE_OMIT_DISKIO)
|
||||
int sqlite3PagerReleaseMemory(int);
|
||||
|
1132
src/pcache.c
Normal file
1132
src/pcache.c
Normal file
File diff suppressed because it is too large
Load Diff
175
src/pcache.h
Normal file
175
src/pcache.h
Normal file
@ -0,0 +1,175 @@
|
||||
/*
|
||||
** 2008 August 05
|
||||
**
|
||||
** 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 header file defines the interface that the sqlite page cache
|
||||
** subsystem.
|
||||
**
|
||||
** @(#) $Id: pcache.h,v 1.1 2008/08/20 14:49:25 danielk1977 Exp $
|
||||
*/
|
||||
|
||||
#ifndef _PCACHE_H_
|
||||
|
||||
typedef struct PgHdr PgHdr;
|
||||
typedef struct PCache PCache;
|
||||
|
||||
/*
|
||||
** Every page in the cache is controlled by an instance of the following
|
||||
** structure.
|
||||
*/
|
||||
struct PgHdr {
|
||||
u32 flags; /* PGHDR flags defined below */
|
||||
void *pData; /* Content of this page */
|
||||
void *pExtra; /* Extra content */
|
||||
PgHdr *pDirty; /* Transient list of dirty pages */
|
||||
Pgno pgno; /* Page number for this page */
|
||||
Pager *pPager;
|
||||
#ifdef SQLITE_CHECK_PAGES
|
||||
u32 pageHash;
|
||||
#endif
|
||||
/*** Public data is above. All that follows is private to pcache.c ***/
|
||||
PCache *pCache; /* Cache that owns this page */
|
||||
PgHdr *pNextHash, *pPrevHash; /* Hash collision chain for PgHdr.pgno */
|
||||
PgHdr *pNext, *pPrev; /* List of clean or dirty pages */
|
||||
PgHdr *pNextLru, *pPrevLru; /* Part of global LRU list */
|
||||
int nRef; /* Number of users of this page */
|
||||
void *apSave[2]; /* Journal entries for in-memory databases */
|
||||
};
|
||||
|
||||
/* Bit values for PgHdr.flags */
|
||||
#define PGHDR_IN_JOURNAL 0x001 /* Page is in rollback journal */
|
||||
#define PGHDR_IN_STMTJRNL 0x002 /* Page is in the statement journal */
|
||||
#define PGHDR_DIRTY 0x004 /* Page has changed */
|
||||
#define PGHDR_NEED_SYNC 0x008 /* Peed to fsync this page */
|
||||
#define PGHDR_ALWAYS_ROLLBACK 0x010 /* Force writing to journal */
|
||||
#define PGHDR_NEED_READ 0x020 /* Content is unread */
|
||||
#define PGHDR_IS_INIT 0x040 /* pData is initialized */
|
||||
#define PGHDR_REUSE_UNLIKELY 0x080 /* Hint: Reuse is unlikely */
|
||||
|
||||
|
||||
/* Initialize and shutdown the page cache subsystem */
|
||||
int sqlite3PcacheInitialize(void);
|
||||
void sqlite3PcacheShutdown(void);
|
||||
|
||||
/* Page cache buffer management:
|
||||
** These routines implement SQLITE_CONFIG_PAGECACHE.
|
||||
*/
|
||||
void sqlite3PCacheBufferSetup(void *, int sz, int n);
|
||||
void *sqlite3PCacheMalloc(int sz);
|
||||
void sqlite3PCacheFree(void*);
|
||||
|
||||
/* Create a new pager cache.
|
||||
** Under memory stress, invoke xStress to try to make pages clean.
|
||||
** Only clean and unpinned pages can be reclaimed.
|
||||
*/
|
||||
void sqlite3PcacheOpen(
|
||||
int szPage, /* Size of every page */
|
||||
int szExtra, /* Extra space associated with each page */
|
||||
int bPurgeable, /* True if pages are on backing store */
|
||||
void (*xDestroy)(PgHdr *), /* Called to destroy a page */
|
||||
int (*xStress)(void*), /* Call to try to make pages clean */
|
||||
void *pStress, /* Argument to xStress */
|
||||
PCache *pToInit /* Preallocated space for the PCache */
|
||||
);
|
||||
|
||||
/* Modify the page-size after the cache has been created. */
|
||||
void sqlite3PcacheSetPageSize(PCache *, int);
|
||||
|
||||
/* Return the size in bytes of a PCache object. Used to preallocate
|
||||
** storage space.
|
||||
*/
|
||||
int sqlite3PcacheSize(void);
|
||||
|
||||
/* One release per successful fetch. Page is pinned until released.
|
||||
** Reference counted.
|
||||
*/
|
||||
int sqlite3PcacheFetch(PCache*, Pgno, int createFlag, PgHdr**);
|
||||
void sqlite3PcacheRelease(PgHdr*);
|
||||
|
||||
void sqlite3PcacheDrop(PgHdr*); /* Remove page from cache */
|
||||
void sqlite3PcacheMakeDirty(PgHdr*); /* Make sure page is marked dirty */
|
||||
void sqlite3PcacheMakeClean(PgHdr*); /* Mark a single page as clean */
|
||||
void sqlite3PcacheCleanAll(PCache*); /* Mark all dirty list pages as clean */
|
||||
|
||||
/* Change a page number. Used by incr-vacuum. */
|
||||
void sqlite3PcacheMove(PgHdr*, Pgno);
|
||||
|
||||
/* Set a global maximum page count for all page caches.
|
||||
** If the sum of individual cache maxes exceed the global max, the
|
||||
** individuals are scaled down proportionally.
|
||||
*/
|
||||
void sqlite3PcacheGlobalMax(int N);
|
||||
|
||||
/* Remove all pages with pgno>x. Reset the cache if x==0 */
|
||||
void sqlite3PcacheTruncate(PCache*, Pgno x);
|
||||
|
||||
/* Routines used to implement transactions on memory-only databases. */
|
||||
int sqlite3PcachePreserve(PgHdr*, int); /* Preserve current page content */
|
||||
void sqlite3PcacheCommit(PCache*, int); /* Drop preserved copy */
|
||||
void sqlite3PcacheRollback(PCache*, int); /* Rollback to preserved copy */
|
||||
|
||||
/* Get a list of all dirty pages in the cache, sorted by page number */
|
||||
PgHdr *sqlite3PcacheDirtyList(PCache*);
|
||||
|
||||
/* Query the cache for a dirty page with a zero ref-count */
|
||||
PgHdr *sqlite3PcacheDirtyPage(PCache *);
|
||||
|
||||
/* Reset and close the cache object */
|
||||
void sqlite3PcacheClose(PCache*);
|
||||
|
||||
/* Set flags on all pages in the page cache */
|
||||
void sqlite3PcacheSetFlags(PCache*, int andMask, int orMask);
|
||||
|
||||
/* Assert flags settings on all pages. Debugging only */
|
||||
void sqlite3PcacheAssertFlags(PCache*, int trueMask, int falseMask);
|
||||
|
||||
/* Return true if the number of dirty pages is 0 or 1 */
|
||||
int sqlite3PcacheZeroOrOneDirtyPages(PCache*);
|
||||
|
||||
/* Discard the contents of the cache */
|
||||
int sqlite3PcacheClear(PCache*);
|
||||
|
||||
/* Return the total number of outstanding page references */
|
||||
int sqlite3PcacheRefCount(PCache*);
|
||||
|
||||
/* Increment the reference count of an existing page */
|
||||
void sqlite3PcacheRef(PgHdr*);
|
||||
|
||||
/* Return the total number of pages stored in the cache */
|
||||
int sqlite3PcachePagecount(PCache*);
|
||||
|
||||
/* Iterate through all pages currently stored in the cache. This interface
|
||||
** is only available if SQLITE_CHECK_PAGES is defined when the library is
|
||||
** built.
|
||||
*/
|
||||
void sqlite3PcacheIterate(PCache *pCache, void (*xIter)(PgHdr *));
|
||||
|
||||
/* Set and get the suggested cache-size for the specified pager-cache. If
|
||||
** a global maximum on the number of pages cached by the system is
|
||||
** configured via the sqlite3PcacheGlobalMax() API, then the suggested
|
||||
** cache-sizes are not used at all.
|
||||
**
|
||||
** If no global maximum is configured, then the system attempts to limit
|
||||
** the total number of pages cached by purgeable pager-caches to the sum
|
||||
** of the suggested cache-sizes.
|
||||
*/
|
||||
int sqlite3PcacheGetCachesize(PCache *);
|
||||
void sqlite3PcacheSetCachesize(PCache *, int);
|
||||
|
||||
/* Lock and unlock a pager-cache object. The PcacheLock() function may
|
||||
** block if the lock is temporarily available. While a pager-cache is locked,
|
||||
** the system guarantees that any configured xStress() callback will not
|
||||
** be invoked by any thread other than the one holding the lock.
|
||||
*/
|
||||
void sqlite3PcacheLock(PCache *);
|
||||
void sqlite3PcacheUnlock(PCache *);
|
||||
|
||||
#endif /* _PCACHE_H_ */
|
||||
|
@ -11,7 +11,7 @@
|
||||
*************************************************************************
|
||||
** Internal interface definitions for SQLite.
|
||||
**
|
||||
** @(#) $Id: sqliteInt.h,v 1.755 2008/08/13 19:11:48 drh Exp $
|
||||
** @(#) $Id: sqliteInt.h,v 1.756 2008/08/20 14:49:25 danielk1977 Exp $
|
||||
*/
|
||||
#ifndef _SQLITEINT_H_
|
||||
#define _SQLITEINT_H_
|
||||
@ -482,6 +482,7 @@ typedef struct WhereLevel WhereLevel;
|
||||
#include "btree.h"
|
||||
#include "vdbe.h"
|
||||
#include "pager.h"
|
||||
#include "pcache.h"
|
||||
|
||||
#include "os.h"
|
||||
#include "mutex.h"
|
||||
@ -757,7 +758,7 @@ struct FuncDef {
|
||||
void (*xFunc)(sqlite3_context*,int,sqlite3_value**); /* Regular function */
|
||||
void (*xStep)(sqlite3_context*,int,sqlite3_value**); /* Aggregate step */
|
||||
void (*xFinalize)(sqlite3_context*); /* Aggregate finializer */
|
||||
char zName[1]; /* SQL name of the function. MUST BE LAST */
|
||||
char *zName; /* SQL name of the function. */
|
||||
};
|
||||
|
||||
/*
|
||||
@ -1932,6 +1933,7 @@ int sqlite3IsNaN(double);
|
||||
|
||||
void sqlite3VXPrintf(StrAccum*, int, const char*, va_list);
|
||||
char *sqlite3MPrintf(sqlite3*,const char*, ...);
|
||||
char *sqlite3MAppendf(sqlite3 *, char *, const char *, ...);
|
||||
char *sqlite3VMPrintf(sqlite3*,const char*, va_list);
|
||||
char *sqlite3MAppendf(sqlite3*,char*,const char*,...);
|
||||
#if defined(SQLITE_TEST) || defined(SQLITE_DEBUG)
|
||||
@ -2081,6 +2083,7 @@ Select *sqlite3SelectDup(sqlite3*,Select*);
|
||||
FuncDef *sqlite3FindFunction(sqlite3*,const char*,int,int,u8,int);
|
||||
void sqlite3RegisterBuiltinFunctions(sqlite3*);
|
||||
void sqlite3RegisterDateTimeFunctions(sqlite3*);
|
||||
int sqlite3GetBuiltinFunction(const char *, int, FuncDef **);
|
||||
#ifdef SQLITE_DEBUG
|
||||
int sqlite3SafetyOn(sqlite3*);
|
||||
int sqlite3SafetyOff(sqlite3*);
|
||||
|
@ -13,7 +13,7 @@
|
||||
** is not included in the SQLite library. It is used for automated
|
||||
** testing of the SQLite library.
|
||||
**
|
||||
** $Id: test1.c,v 1.318 2008/08/12 15:04:59 danielk1977 Exp $
|
||||
** $Id: test1.c,v 1.319 2008/08/20 14:49:25 danielk1977 Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
#include "tcl.h"
|
||||
@ -4686,7 +4686,6 @@ int Sqlitetest1_Init(Tcl_Interp *interp){
|
||||
extern int sqlite3_pager_readdb_count;
|
||||
extern int sqlite3_pager_writedb_count;
|
||||
extern int sqlite3_pager_writej_count;
|
||||
extern int sqlite3_pager_pgfree_count;
|
||||
#if SQLITE_OS_UNIX && defined(SQLITE_TEST) && SQLITE_THREADSAFE
|
||||
extern int threadsOverrideEachOthersLocks;
|
||||
#endif
|
||||
@ -4733,8 +4732,6 @@ int Sqlitetest1_Init(Tcl_Interp *interp){
|
||||
(char*)&sqlite3_pager_writedb_count, TCL_LINK_INT);
|
||||
Tcl_LinkVar(interp, "sqlite3_pager_writej_count",
|
||||
(char*)&sqlite3_pager_writej_count, TCL_LINK_INT);
|
||||
Tcl_LinkVar(interp, "sqlite3_pager_pgfree_count",
|
||||
(char*)&sqlite3_pager_pgfree_count, TCL_LINK_INT);
|
||||
#ifndef SQLITE_OMIT_UTF16
|
||||
Tcl_LinkVar(interp, "unaligned_string_counter",
|
||||
(char*)&unaligned_string_counter, TCL_LINK_INT);
|
||||
|
25
src/test2.c
25
src/test2.c
@ -13,7 +13,7 @@
|
||||
** is not included in the SQLite library. It is used for automated
|
||||
** testing of the SQLite library.
|
||||
**
|
||||
** $Id: test2.c,v 1.59 2008/07/12 14:52:20 drh Exp $
|
||||
** $Id: test2.c,v 1.60 2008/08/20 14:49:25 danielk1977 Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
#include "tcl.h"
|
||||
@ -78,7 +78,7 @@ static int pager_open(
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if( Tcl_GetInt(interp, argv[2], &nPage) ) return TCL_ERROR;
|
||||
rc = sqlite3PagerOpen(sqlite3_vfs_find(0), &pPager, argv[1], 0, 0,
|
||||
rc = sqlite3PagerOpen(sqlite3_vfs_find(0), &pPager, argv[1], 0, 0, 0,
|
||||
SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_MAIN_DB);
|
||||
if( rc!=SQLITE_OK ){
|
||||
Tcl_AppendResult(interp, errorName(rc), 0);
|
||||
@ -382,6 +382,26 @@ static int page_lookup(
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Usage: pcache_global_max NPAGE
|
||||
*/
|
||||
static int pcache_global_max(
|
||||
void *NotUsed,
|
||||
Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
|
||||
int argc, /* Number of arguments */
|
||||
const char **argv /* Text of each argument */
|
||||
){
|
||||
int nPage;
|
||||
if( argc!=2 ){
|
||||
Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
|
||||
" NPAGE\"", 0);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if( Tcl_GetInt(interp, argv[1], &nPage) ) return TCL_ERROR;
|
||||
sqlite3PcacheGlobalMax(nPage);
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Usage: pager_truncate ID PGNO
|
||||
*/
|
||||
@ -630,6 +650,7 @@ int Sqlitetest2_Init(Tcl_Interp *interp){
|
||||
{ "page_write", (Tcl_CmdProc*)page_write },
|
||||
{ "page_number", (Tcl_CmdProc*)page_number },
|
||||
{ "pager_truncate", (Tcl_CmdProc*)pager_truncate },
|
||||
{ "pcache_global_max", (Tcl_CmdProc*)pcache_global_max },
|
||||
#ifndef SQLITE_OMIT_DISKIO
|
||||
{ "fake_big_file", (Tcl_CmdProc*)fake_big_file },
|
||||
#endif
|
||||
|
@ -13,7 +13,7 @@
|
||||
** is not included in the SQLite library. It is used for automated
|
||||
** testing of the SQLite library.
|
||||
**
|
||||
** $Id: test8.c,v 1.73 2008/08/12 14:48:41 danielk1977 Exp $
|
||||
** $Id: test8.c,v 1.74 2008/08/20 14:49:25 danielk1977 Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
#include "tcl.h"
|
||||
@ -96,8 +96,7 @@ static int simulateVtabError(echo_vtab *p, const char *zMethod){
|
||||
const char *zErr;
|
||||
char zVarname[128];
|
||||
zVarname[127] = '\0';
|
||||
sqlite3_snprintf(127, zVarname,
|
||||
"echo_module_fail(%s,%s)", zMethod, p->zTableName);
|
||||
snprintf(zVarname, 127, "echo_module_fail(%s,%s)", zMethod, p->zTableName);
|
||||
zErr = Tcl_GetVar(p->interp, zVarname, TCL_GLOBAL_ONLY);
|
||||
if( zErr ){
|
||||
p->base.zErrMsg = sqlite3_mprintf("echo-vtab-error: %s", zErr);
|
||||
|
@ -11,7 +11,7 @@
|
||||
*************************************************************************
|
||||
** This file contains code used to help implement virtual tables.
|
||||
**
|
||||
** $Id: vtab.c,v 1.74 2008/08/02 03:50:39 drh Exp $
|
||||
** $Id: vtab.c,v 1.75 2008/08/20 14:49:25 danielk1977 Exp $
|
||||
*/
|
||||
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
||||
#include "sqliteInt.h"
|
||||
@ -807,6 +807,7 @@ FuncDef *sqlite3VtabOverloadFunction(
|
||||
return pDef;
|
||||
}
|
||||
*pNew = *pDef;
|
||||
pNew->zName = (char *)&pNew[1];
|
||||
memcpy(pNew->zName, pDef->zName, strlen(pDef->zName)+1);
|
||||
pNew->xFunc = xFunc;
|
||||
pNew->pUserData = pArg;
|
||||
|
@ -13,7 +13,7 @@
|
||||
# IO traffic generated by SQLite (making sure SQLite is not writing out
|
||||
# more database pages than it has to, stuff like that).
|
||||
#
|
||||
# $Id: io.test,v 1.17 2008/07/30 17:28:04 drh Exp $
|
||||
# $Id: io.test,v 1.18 2008/08/20 14:49:25 danielk1977 Exp $
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
@ -383,6 +383,7 @@ ifcapable pager_pragmas {
|
||||
execsql { CREATE TABLE abc(a, b) }
|
||||
nSync
|
||||
execsql {
|
||||
PRAGMA temp_store = memory;
|
||||
PRAGMA cache_size = 10;
|
||||
BEGIN;
|
||||
INSERT INTO abc VALUES('hello', 'world');
|
||||
|
@ -15,7 +15,7 @@
|
||||
# The tests in this file use special facilities that are only
|
||||
# available in the SQLite test fixture.
|
||||
#
|
||||
# $Id: ioerr2.test,v 1.8 2008/07/08 15:59:52 danielk1977 Exp $
|
||||
# $Id: ioerr2.test,v 1.9 2008/08/20 14:49:25 danielk1977 Exp $
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
@ -115,11 +115,12 @@ foreach bPersist [list 0 1] {
|
||||
do_test ioerr2-5 {
|
||||
execsql {
|
||||
CREATE TABLE t2 AS SELECT * FROM t1;
|
||||
PRAGMA temp_store = memory;
|
||||
}
|
||||
set ::sqlite_io_error_persist 0
|
||||
set ::go 1
|
||||
set rc [catch {
|
||||
for {set ::N 1} {$::N<200} {incr ::N} {
|
||||
for {set ::N 2} {$::N<200} {incr ::N} {
|
||||
db eval {SELECT * FROM t1 WHERE rowid IN (1, 5, 10, 15, 20)} {
|
||||
set ::sqlite_io_error_hit 0
|
||||
set ::sqlite_io_error_pending $::N
|
||||
|
@ -11,7 +11,7 @@
|
||||
#
|
||||
# This file contains tests of the memory allocation subsystem
|
||||
#
|
||||
# $Id: memsubsys1.test,v 1.9 2008/08/12 15:21:12 drh Exp $
|
||||
# $Id: memsubsys1.test,v 1.10 2008/08/20 14:49:25 danielk1977 Exp $
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
@ -60,6 +60,8 @@ proc reset_highwater_marks {} {
|
||||
sqlite3_status SQLITE_STATUS_PARSER_STACK 1
|
||||
}
|
||||
|
||||
set xtra_size 256
|
||||
|
||||
# Test 1: Both PAGECACHE and SCRATCH are shut down.
|
||||
#
|
||||
db close
|
||||
@ -81,7 +83,7 @@ set max_pagecache [lindex [sqlite3_status SQLITE_STATUS_PAGECACHE_OVERFLOW 0] 2]
|
||||
#
|
||||
db close
|
||||
sqlite3_shutdown
|
||||
sqlite3_config_pagecache 1024 20
|
||||
sqlite3_config_pagecache [expr 1024+$xtra_size] 20
|
||||
sqlite3_initialize
|
||||
reset_highwater_marks
|
||||
build_test_db memsubsys1-2 {PRAGMA page_size=1024}
|
||||
@ -89,8 +91,11 @@ build_test_db memsubsys1-2 {PRAGMA page_size=1024}
|
||||
do_test memsubsys1-2.3 {
|
||||
set pg_ovfl [lindex [sqlite3_status SQLITE_STATUS_PAGECACHE_OVERFLOW 0] 2]
|
||||
set pg_used [lindex [sqlite3_status SQLITE_STATUS_PAGECACHE_USED 0] 2]
|
||||
expr {$pg_used*1024 + $pg_ovfl}
|
||||
} $max_pagecache
|
||||
expr {
|
||||
($pg_used*1024 + $pg_ovfl) < $max_pagecache &&
|
||||
($pg_used*(1024+$xtra_size) + $pg_ovfl) >= $max_pagecache
|
||||
}
|
||||
} 1
|
||||
do_test memsubsys1-2.4 {
|
||||
set pg_used [lindex [sqlite3_status SQLITE_STATUS_PAGECACHE_USED 0] 2]
|
||||
} 19
|
||||
@ -103,7 +108,7 @@ do_test memsubsys1-2.5 {
|
||||
#
|
||||
db close
|
||||
sqlite3_shutdown
|
||||
sqlite3_config_pagecache 512 20
|
||||
sqlite3_config_pagecache [expr 512+$xtra_size] 20
|
||||
sqlite3_initialize
|
||||
reset_highwater_marks
|
||||
build_test_db memsubsys1-3.1 {PRAGMA page_size=1024}
|
||||
@ -119,7 +124,7 @@ do_test memsubsys1-3.1.5 {
|
||||
} 0
|
||||
db close
|
||||
sqlite3_shutdown
|
||||
sqlite3_config_pagecache 2048 20
|
||||
sqlite3_config_pagecache [expr 2048+$xtra_size] 20
|
||||
sqlite3_initialize
|
||||
reset_highwater_marks
|
||||
build_test_db memsubsys1-3.2 {PRAGMA page_size=2048}
|
||||
@ -138,7 +143,7 @@ do_test memsubsys1-3.2.5 {
|
||||
#
|
||||
db close
|
||||
sqlite3_shutdown
|
||||
sqlite3_config_pagecache 1024 50
|
||||
sqlite3_config_pagecache [expr 1024+$xtra_size] 50
|
||||
sqlite3_config_scratch 6000 2
|
||||
sqlite3_initialize
|
||||
reset_highwater_marks
|
||||
@ -150,8 +155,11 @@ do_test memsubsys1-4.3 {
|
||||
do_test memsubsys1-4.4 {
|
||||
set pg_ovfl [lindex [sqlite3_status SQLITE_STATUS_PAGECACHE_OVERFLOW 0] 2]
|
||||
set pg_used [lindex [sqlite3_status SQLITE_STATUS_PAGECACHE_USED 0] 2]
|
||||
expr {$pg_used*1024 + $pg_ovfl}
|
||||
} $max_pagecache
|
||||
expr {
|
||||
($pg_used*1024 + $pg_ovfl) < $max_pagecache &&
|
||||
($pg_used*(1024+$xtra_size) + $pg_ovfl) >= $max_pagecache
|
||||
}
|
||||
} 1
|
||||
do_test memsubsys1-4.5 {
|
||||
set maxreq [lindex [sqlite3_status SQLITE_STATUS_MALLOC_SIZE 0] 2]
|
||||
expr {$maxreq<7000}
|
||||
@ -165,7 +173,7 @@ do_test memsubsys1-4.6 {
|
||||
#
|
||||
db close
|
||||
sqlite3_shutdown
|
||||
sqlite3_config_pagecache 4096 24
|
||||
sqlite3_config_pagecache [expr 4096+$xtra_size] 24
|
||||
sqlite3_config_scratch 6000 2
|
||||
sqlite3_initialize
|
||||
reset_highwater_marks
|
||||
@ -191,7 +199,7 @@ do_test memsubsys1-5.6 {
|
||||
#
|
||||
db close
|
||||
sqlite3_shutdown
|
||||
sqlite3_config_pagecache 4096 24
|
||||
sqlite3_config_pagecache [expr 4096+$xtra_size] 24
|
||||
sqlite3_config_scratch 25000 1
|
||||
sqlite3_initialize
|
||||
reset_highwater_marks
|
||||
@ -202,7 +210,8 @@ do_test memsubsys1-6.3 {
|
||||
} 23
|
||||
do_test memsubsys1-6.4 {
|
||||
set maxreq [lindex [sqlite3_status SQLITE_STATUS_MALLOC_SIZE 0] 2]
|
||||
} 4096
|
||||
expr {$maxreq>4096 && $maxreq<(4096+$xtra_size)}
|
||||
} 1
|
||||
do_test memsubsys1-6.5 {
|
||||
set s_used [lindex [sqlite3_status SQLITE_STATUS_SCRATCH_USED 0] 2]
|
||||
} 1
|
||||
@ -216,14 +225,13 @@ do_test memsubsys1-6.6 {
|
||||
#
|
||||
db close
|
||||
sqlite3_shutdown
|
||||
sqlite3_config_pagecache 4096 24
|
||||
sqlite3_config_pagecache [expr 4096+$xtra_size] 24
|
||||
sqlite3_config_scratch 25000 1
|
||||
sqlite3_initialize
|
||||
pcache_global_max 15
|
||||
reset_highwater_marks
|
||||
build_test_db memsubsys1-7 {
|
||||
PRAGMA page_size=4096;
|
||||
PRAGMA cache_size=10;
|
||||
PRAGMA temp_cache_size=10;
|
||||
}
|
||||
#show_memstats
|
||||
do_test memsubsys1-7.3 {
|
||||
@ -243,6 +251,7 @@ do_test memsubsys1-7.6 {
|
||||
do_test memsubsys1-7.7 {
|
||||
set s_ovfl [lindex [sqlite3_status SQLITE_STATUS_SCRATCH_OVERFLOW 0] 2]
|
||||
} 0
|
||||
pcache_global_max 0
|
||||
|
||||
db close
|
||||
sqlite3_shutdown
|
||||
|
@ -9,7 +9,7 @@
|
||||
#
|
||||
#***********************************************************************
|
||||
#
|
||||
# $Id: mutex1.test,v 1.10 2008/07/15 00:27:35 drh Exp $
|
||||
# $Id: mutex1.test,v 1.11 2008/08/20 14:49:25 danielk1977 Exp $
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
@ -96,8 +96,8 @@ set enable_shared_cache [sqlite3_enable_shared_cache 1]
|
||||
ifcapable threadsafe {
|
||||
foreach {mode mutexes} {
|
||||
singlethread {}
|
||||
multithread {fast static_master static_mem static_prng}
|
||||
serialized {fast recursive static_master static_mem static_prng}
|
||||
multithread {fast static_lru static_master static_mem static_mem2 static_prng }
|
||||
serialized {fast recursive static_lru static_master static_mem static_mem2 static_prng }
|
||||
} {
|
||||
ifcapable memorymanage {
|
||||
if {$mode ne "singlethread"} {
|
||||
|
@ -11,7 +11,7 @@
|
||||
# This file implements regression tests for SQLite library. The
|
||||
# focus of this script is page cache subsystem.
|
||||
#
|
||||
# $Id: pager.test,v 1.30 2007/08/24 16:29:24 drh Exp $
|
||||
# $Id: pager.test,v 1.31 2008/08/20 14:49:25 danielk1977 Exp $
|
||||
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
@ -76,13 +76,13 @@ do_test pager-2.3.4 {
|
||||
expr {$::gx!=""}
|
||||
} {1}
|
||||
do_test pager-2.3.5 {
|
||||
page_unref $::gx
|
||||
pager_stats $::p1
|
||||
} {ref 1 page 1 max 10 size 0 state 1 err 0 hit 0 miss 1 ovfl 0}
|
||||
do_test pager-2.3.6 {
|
||||
expr {$::g1==$::gx}
|
||||
} {1}
|
||||
do_test pager-2.3.7 {
|
||||
page_unref $::gx
|
||||
pager_stats $::p1
|
||||
} {ref 1 page 1 max 10 size 0 state 1 err 0 hit 0 miss 1 ovfl 0}
|
||||
do_test pager-2.4 {
|
||||
@ -184,6 +184,7 @@ do_test pager-2.29 {
|
||||
page_read $::g1
|
||||
} {Page-One}
|
||||
do_test pager-2.99 {
|
||||
page_unref $::g1
|
||||
pager_close $::p1
|
||||
} {}
|
||||
|
||||
@ -214,6 +215,7 @@ do_test pager-3.5 {
|
||||
page_unref $gx
|
||||
}
|
||||
pager_commit $::p1
|
||||
page_unref $::g(1)
|
||||
} {}
|
||||
for {set i 2} {$i<=20} {incr i} {
|
||||
do_test pager-3.6.[expr {$i-1}] [subst {
|
||||
@ -427,6 +429,7 @@ ifcapable memorydb {
|
||||
}
|
||||
|
||||
do_test pager-4.99 {
|
||||
page_unref $::g1
|
||||
pager_close $::p1
|
||||
} {}
|
||||
|
||||
|
@ -11,7 +11,7 @@
|
||||
# This file implements regression tests for SQLite library. The
|
||||
# focus of this script is page cache subsystem.
|
||||
#
|
||||
# $Id: pager2.test,v 1.6 2007/03/23 18:12:07 danielk1977 Exp $
|
||||
# $Id: pager2.test,v 1.7 2008/08/20 14:49:25 danielk1977 Exp $
|
||||
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
@ -75,6 +75,7 @@ do_test pager2-2.3.3 {
|
||||
} {ref 1 page 1 max 10 size 0 state 1 err 0 hit 0 miss 1 ovfl 0}
|
||||
do_test pager2-2.3.4 {
|
||||
set ::gx [page_lookup $::p1 1]
|
||||
page_unref $::gx
|
||||
expr {$::gx!=""}
|
||||
} {1}
|
||||
do_test pager2-2.3.5 {
|
||||
@ -84,7 +85,6 @@ do_test pager2-2.3.6 {
|
||||
expr {$::g1==$::gx}
|
||||
} {1}
|
||||
do_test pager2-2.3.7 {
|
||||
page_unref $::gx
|
||||
pager_stats $::p1
|
||||
} {ref 1 page 1 max 10 size 0 state 1 err 0 hit 0 miss 1 ovfl 0}
|
||||
do_test pager2-2.4 {
|
||||
@ -181,9 +181,9 @@ do_test pager2-2.29 {
|
||||
set ::g1 [page_get $::p1 1]
|
||||
page_read $::g1
|
||||
} {Page-One}
|
||||
#do_test pager2-2.99 {
|
||||
# pager_close $::p1
|
||||
#} {}
|
||||
do_test pager2-2.99 {
|
||||
page_unref $::g1
|
||||
} {}
|
||||
|
||||
#do_test pager2-3.1 {
|
||||
# set v [catch {
|
||||
@ -212,6 +212,7 @@ do_test pager2-3.5 {
|
||||
page_unref $gx
|
||||
}
|
||||
pager_commit $::p1
|
||||
page_unref $::g(1)
|
||||
} {}
|
||||
for {set i 2} {$i<=20} {incr i} {
|
||||
do_test pager2-3.6.[expr {$i-1}] [subst {
|
||||
@ -337,6 +338,7 @@ for {set i 1} {$i<20} {incr i} {
|
||||
}
|
||||
set res
|
||||
} {}
|
||||
breakpoint
|
||||
do_test pager2-4.5.$i.5 {
|
||||
page_write $g1 "Page-1 v$i"
|
||||
lrange [pager_stats $p1] 8 9
|
||||
@ -398,6 +400,7 @@ for {set i 1} {$i<20} {incr i} {
|
||||
}
|
||||
|
||||
do_test pager2-4.99 {
|
||||
page_unref $::g1
|
||||
pager_close $::p1
|
||||
} {}
|
||||
|
||||
|
@ -12,7 +12,7 @@
|
||||
# The focus of the tests in this file are to verify that the
|
||||
# pager optimizations implemented in version 3.3.14 work.
|
||||
#
|
||||
# $Id: pageropt.test,v 1.4 2008/04/14 01:00:58 drh Exp $
|
||||
# $Id: pageropt.test,v 1.5 2008/08/20 14:49:25 danielk1977 Exp $
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
@ -39,12 +39,10 @@ proc pagercount_sql {sql {db db}} {
|
||||
set sqlite3_pager_readdb_count 0
|
||||
set sqlite3_pager_writedb_count 0
|
||||
set sqlite3_pager_writej_count 0
|
||||
set sqlite3_pager_pgfree_count 0
|
||||
set r [$db eval $sql]
|
||||
set cnt [list $sqlite3_pager_readdb_count \
|
||||
$sqlite3_pager_writedb_count \
|
||||
$sqlite3_pager_writej_count \
|
||||
$sqlite3_pager_pgfree_count]
|
||||
$sqlite3_pager_writej_count ]
|
||||
return [concat $cnt $r]
|
||||
}
|
||||
|
||||
@ -59,12 +57,12 @@ do_test pageropt-1.1 {
|
||||
pagercount_sql {
|
||||
CREATE TABLE t1(x);
|
||||
}
|
||||
} {0 2 0 0}
|
||||
} {0 2 0}
|
||||
do_test pageropt-1.2 {
|
||||
pagercount_sql {
|
||||
INSERT INTO t1 VALUES(randomblob(5000));
|
||||
}
|
||||
} {0 6 2 0}
|
||||
} {0 6 2}
|
||||
|
||||
# Verify that values remain in cache on for subsequent reads.
|
||||
# We should not have to go back to disk.
|
||||
@ -73,7 +71,7 @@ do_test pageropt-1.3 {
|
||||
pagercount_sql {
|
||||
SELECT length(x) FROM t1
|
||||
}
|
||||
} {0 0 0 0 5000}
|
||||
} {0 0 0 5000}
|
||||
|
||||
# If another thread reads the database, the original cache
|
||||
# remains valid.
|
||||
@ -84,7 +82,7 @@ do_test pageropt-1.4 {
|
||||
pagercount_sql {
|
||||
SELECT hex(x) FROM t1
|
||||
}
|
||||
} [list 0 0 0 0 $blobcontent]
|
||||
} [list 0 0 0 $blobcontent]
|
||||
|
||||
# But if the other thread modifies the database, then the cache
|
||||
# must refill.
|
||||
@ -94,12 +92,12 @@ do_test pageropt-1.5 {
|
||||
pagercount_sql {
|
||||
SELECT hex(x) FROM t1
|
||||
}
|
||||
} [list 6 0 0 6 $blobcontent]
|
||||
} [list 6 0 0 $blobcontent]
|
||||
do_test pageropt-1.6 {
|
||||
pagercount_sql {
|
||||
SELECT hex(x) FROM t1
|
||||
}
|
||||
} [list 0 0 0 0 $blobcontent]
|
||||
} [list 0 0 0 $blobcontent]
|
||||
|
||||
# Verify that the last page of an overflow chain is not read from
|
||||
# disk when deleting a row. The one row of t1(x) has four pages
|
||||
@ -117,7 +115,7 @@ do_test pageropt-2.1 {
|
||||
pagercount_sql {
|
||||
DELETE FROM t1 WHERE rowid=1
|
||||
}
|
||||
} {5 3 3 0}
|
||||
} {5 3 3}
|
||||
|
||||
# When pulling pages off of the freelist, there is no reason
|
||||
# to actually bring in the old content.
|
||||
@ -128,12 +126,12 @@ do_test pageropt-2.2 {
|
||||
pagercount_sql {
|
||||
INSERT INTO t1 VALUES(randomblob(1500));
|
||||
}
|
||||
} {3 4 3 0}
|
||||
} {3 4 3}
|
||||
do_test pageropt-2.3 {
|
||||
pagercount_sql {
|
||||
INSERT INTO t1 VALUES(randomblob(1500));
|
||||
}
|
||||
} {0 4 3 0}
|
||||
} {0 4 3}
|
||||
|
||||
# Note the new optimization that when pulling the very last page off of the
|
||||
# freelist we do not read the content of that page.
|
||||
@ -142,7 +140,7 @@ do_test pageropt-2.4 {
|
||||
pagercount_sql {
|
||||
INSERT INTO t1 VALUES(randomblob(1500));
|
||||
}
|
||||
} {0 5 3 0}
|
||||
} {0 5 3}
|
||||
|
||||
# Appending a large quantity of data does not involve writing much
|
||||
# to the journal file.
|
||||
@ -151,7 +149,7 @@ do_test pageropt-3.1 {
|
||||
pagercount_sql {
|
||||
INSERT INTO t2 SELECT * FROM t1;
|
||||
}
|
||||
} {1 7 2 0}
|
||||
} {1 7 2}
|
||||
|
||||
# Once again, we do not need to read the last page of an overflow chain
|
||||
# while deleting.
|
||||
@ -160,12 +158,12 @@ do_test pageropt-3.2 {
|
||||
pagercount_sql {
|
||||
DROP TABLE t2;
|
||||
}
|
||||
} {0 2 3 0}
|
||||
} {0 2 3}
|
||||
do_test pageropt-3.3 {
|
||||
pagercount_sql {
|
||||
DELETE FROM t1;
|
||||
}
|
||||
} {0 3 3 0}
|
||||
} {0 3 3}
|
||||
|
||||
# There are now 11 pages on the freelist. Move them all into an
|
||||
# overflow chain by inserting a single large record. Starting from
|
||||
@ -180,7 +178,7 @@ do_test pageropt-4.1 {
|
||||
pagercount_sql {
|
||||
INSERT INTO t1 VALUES(randomblob(11300))
|
||||
}
|
||||
} {3 13 3 0}
|
||||
} {3 13 3}
|
||||
|
||||
# Now we delete that big entries starting from a cold cache and an
|
||||
# empty freelist. The first 10 of the 11 pages overflow chain have
|
||||
@ -194,7 +192,7 @@ do_test pageropt-4.2 {
|
||||
pagercount_sql {
|
||||
DELETE FROM t1
|
||||
}
|
||||
} {12 3 3 0}
|
||||
} {12 3 3}
|
||||
|
||||
sqlite3_soft_heap_limit $soft_limit
|
||||
catch {db2 close}
|
||||
|
@ -9,7 +9,7 @@
|
||||
#
|
||||
#***********************************************************************
|
||||
#
|
||||
# $Id: shared3.test,v 1.3 2008/06/23 09:50:52 danielk1977 Exp $
|
||||
# $Id: shared3.test,v 1.4 2008/08/20 14:49:25 danielk1977 Exp $
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
@ -86,9 +86,11 @@ do_test shared3-2.7 {
|
||||
catchsql {select count(*) from sqlite_master} db3
|
||||
} {0 1}
|
||||
do_test shared3-2.8 {
|
||||
db3 close
|
||||
execsql {
|
||||
INSERT INTO t1 VALUES(10, randomblob(10000))
|
||||
} db1
|
||||
sqlite3 db3 $alternative_name
|
||||
|
||||
# If the pager-cache is really still limited to 10 pages, then the INSERT
|
||||
# statement above should have caused the pager to grab an exclusive lock
|
||||
|
@ -16,7 +16,7 @@
|
||||
# any statement other than a COMMIT, an I/O error is returned instead
|
||||
# of SQLITE_BUSY.
|
||||
#
|
||||
# $Id: tkt2409.test,v 1.3 2007/09/12 17:01:45 danielk1977 Exp $
|
||||
# $Id: tkt2409.test,v 1.4 2008/08/20 14:49:25 danielk1977 Exp $
|
||||
|
||||
# Test Outline:
|
||||
#
|
||||
@ -25,6 +25,11 @@
|
||||
# Verify that the transaction is automatically rolled back
|
||||
# and SQLITE_IOERR_BLOCKED is returned
|
||||
#
|
||||
# UPDATE: As of the pcache modifications, failing to upgrade to
|
||||
# an exclusive lock when attempting a cache-spill is no longer an
|
||||
# error. The pcache module allocates more space and keeps working
|
||||
# in memory if this occurs.
|
||||
#
|
||||
# tkt-2409-2.*: Cause a cache-spill while updating the change-counter
|
||||
# during a database COMMIT. Verify that the transaction is not
|
||||
# rolled back and SQLITE_BUSY is returned.
|
||||
@ -32,9 +37,14 @@
|
||||
# tkt-2409-3.*: Similar to 2409-1.*, but using many INSERT statements
|
||||
# within a transaction instead of just one.
|
||||
#
|
||||
# UPDATE: Again, pcache now just keeps working in main memory.
|
||||
#
|
||||
# tkt-2409-4.*: Similar to 2409-1.*, but rig it so that the
|
||||
# INSERT statement starts a statement transaction. Verify that
|
||||
# SQLOTE_BUSY is returned and the transaction is not rolled back.
|
||||
# SQLITE_BUSY is returned and the transaction is not rolled back.
|
||||
#
|
||||
# UPDATE: This time, SQLITE_BUSY is not returned. pcache just uses
|
||||
# more malloc()'d memory.
|
||||
#
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
@ -69,6 +79,8 @@ proc unread_lock_db {} {
|
||||
}
|
||||
}
|
||||
|
||||
pcache_global_max 10
|
||||
|
||||
# Open the db handle used by [read_lock_db].
|
||||
#
|
||||
sqlite3 db2 test.db
|
||||
@ -86,11 +98,11 @@ do_test tkt2409-1.1 {
|
||||
BEGIN;
|
||||
INSERT INTO t1 VALUES($::zShort, $::zLong);
|
||||
}
|
||||
} {1 {disk I/O error}}
|
||||
} {0 {}}
|
||||
|
||||
do_test tkt2409-1.2 {
|
||||
sqlite3_errcode $::DB
|
||||
} {SQLITE_IOERR+11}
|
||||
} {SQLITE_OK}
|
||||
|
||||
# Check the integrity of the cache.
|
||||
#
|
||||
@ -103,8 +115,7 @@ integrity_check tkt2409-1.3
|
||||
do_test tkt2409-1.4 {
|
||||
unread_lock_db
|
||||
catchsql { ROLLBACK }
|
||||
} {1 {cannot rollback - no transaction is active}}
|
||||
|
||||
} {0 {}}
|
||||
|
||||
set ::zShort [string repeat 0123456789 1]
|
||||
set ::zLong [string repeat 0123456789 1500]
|
||||
@ -139,6 +150,7 @@ do_test tkt2409-2.3 {
|
||||
}
|
||||
} {0 {}}
|
||||
|
||||
|
||||
do_test tkt2409-3.1 {
|
||||
db close
|
||||
set ::DB [sqlite3 db test.db; sqlite3_connection_pointer db]
|
||||
@ -154,11 +166,11 @@ do_test tkt2409-3.1 {
|
||||
BEGIN;
|
||||
INSERT INTO t1 SELECT $::zShort, $::zLong;
|
||||
}
|
||||
} {1 {database is locked}}
|
||||
} {0 {}}
|
||||
|
||||
do_test tkt2409-3.2 {
|
||||
sqlite3_errcode $::DB
|
||||
} {SQLITE_BUSY}
|
||||
} {SQLITE_OK}
|
||||
|
||||
# Check the integrity of the cache.
|
||||
#
|
||||
@ -197,11 +209,11 @@ do_test tkt2409-4.1 {
|
||||
read_lock_db
|
||||
execsql BEGIN
|
||||
catchsql $sql
|
||||
} {1 {disk I/O error}}
|
||||
} {0 {}}
|
||||
|
||||
do_test tkt2409-4.2 {
|
||||
sqlite3_errcode $::DB
|
||||
} {SQLITE_IOERR+11}
|
||||
} {SQLITE_OK}
|
||||
|
||||
# Check the integrity of the cache.
|
||||
#
|
||||
@ -209,8 +221,9 @@ integrity_check tkt2409-4.3
|
||||
|
||||
do_test tkt2409-4.4 {
|
||||
catchsql { ROLLBACK }
|
||||
} {1 {cannot rollback - no transaction is active}}
|
||||
} {0 {}}
|
||||
|
||||
pcache_global_max 0
|
||||
|
||||
unread_lock_db
|
||||
db2 close
|
||||
|
181
tool/mkfunction.c
Normal file
181
tool/mkfunction.c
Normal file
@ -0,0 +1,181 @@
|
||||
|
||||
/*
|
||||
** This file contains a standalone program used to generate C code that
|
||||
** implements a static hash table to store the definitions of built-in
|
||||
** SQL functions in SQLite.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
/*
|
||||
** The SQLite source file "func.c" is included below.
|
||||
**
|
||||
** By defining the 4 macros and typedef below before including "func.c",
|
||||
** most of the code is excluded. What is left is an array of constant
|
||||
** strings, aBuiltinFunc[], containing the names of SQLite's built-in
|
||||
** SQL functions. i.e.:
|
||||
**
|
||||
** const char aBuiltinFunc[] = { "like", "glob", "min", "max" ... };
|
||||
**
|
||||
** The data from aBuiltinFunc[] is used by this program to create the
|
||||
** static hash table.
|
||||
*/
|
||||
#define CREATE_BUILTIN_HASHTABLE 1
|
||||
#define FUNCTION(zName,w,x,y,z) #zName
|
||||
#define AGGREGATE(zName,v,w,x,y,z) #zName
|
||||
#define LIKEFUNC(zName,x,y,z) #zName
|
||||
#define FuncDef const char *
|
||||
|
||||
#include "func.c"
|
||||
|
||||
/* The number of buckets in the static hash table. */
|
||||
#define HASHSIZE 127
|
||||
|
||||
typedef unsigned char u8;
|
||||
|
||||
/* An array to map all upper-case characters into their corresponding
|
||||
** lower-case character.
|
||||
*/
|
||||
static const u8 sqlite3UpperToLower[] = {
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
|
||||
18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
|
||||
36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
|
||||
54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 97, 98, 99,100,101,102,103,
|
||||
104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,
|
||||
122, 91, 92, 93, 94, 95, 96, 97, 98, 99,100,101,102,103,104,105,106,107,
|
||||
108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,
|
||||
126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,
|
||||
144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,
|
||||
162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,
|
||||
180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,
|
||||
198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,
|
||||
216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,
|
||||
234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,
|
||||
252,253,254,255
|
||||
};
|
||||
#define UpperToLower sqlite3UpperToLower
|
||||
|
||||
int sqlite3StrICmp(const char *zLeft, const char *zRight){
|
||||
register unsigned char *a, *b;
|
||||
a = (unsigned char *)zLeft;
|
||||
b = (unsigned char *)zRight;
|
||||
while( *a!=0 && UpperToLower[*a]==UpperToLower[*b]){ a++; b++; }
|
||||
return UpperToLower[*a] - UpperToLower[*b];
|
||||
}
|
||||
|
||||
static int hashstring(const char *zName){
|
||||
int ii;
|
||||
unsigned int iKey = 0;
|
||||
for(ii=0; zName[ii]; ii++){
|
||||
iKey = (iKey<<3) + (u8)sqlite3UpperToLower[(u8)zName[ii]];
|
||||
}
|
||||
iKey = iKey%HASHSIZE;
|
||||
return iKey;
|
||||
}
|
||||
|
||||
static void printarray(const char *zName, u8 *aArray, int nArray){
|
||||
int ii;
|
||||
printf(" static u8 %s[%d] = {", zName, nArray);
|
||||
for(ii=0; ii<nArray; ii++){
|
||||
if( (ii%16)==0 ){
|
||||
printf("\n ");
|
||||
}
|
||||
printf("%d, ", aArray[ii]);
|
||||
}
|
||||
printf("\n };\n");
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char **argv){
|
||||
int nFunc; /* Number of entries in the aBuiltinFunc array */
|
||||
|
||||
u8 anFunc[256];
|
||||
u8 aHash[HASHSIZE];
|
||||
u8 aNext[256];
|
||||
int ii;
|
||||
int iHead;
|
||||
|
||||
nFunc = (sizeof(aBuiltinFunc)/sizeof(const char *));
|
||||
assert(nFunc<256);
|
||||
|
||||
memset(aHash, (unsigned char)nFunc, sizeof(aHash));
|
||||
memset(aNext, (unsigned char)nFunc, sizeof(aNext));
|
||||
memset(anFunc, 0, sizeof(anFunc));
|
||||
|
||||
iHead = -1;
|
||||
for(ii=0; ii<nFunc; ii++){
|
||||
int iHash;
|
||||
|
||||
if( iHead>=0 && 0==sqlite3StrICmp(aBuiltinFunc[ii], aBuiltinFunc[iHead]) ){
|
||||
anFunc[iHead]++;
|
||||
continue;
|
||||
}else{
|
||||
/* The routine generated by this program assumes that if there are
|
||||
** two or more entries in the aBuiltinFunc[] array with the same
|
||||
** name (i.e. two versions of the "max" function), then they must
|
||||
** be stored in adjacent slots. The following block detects the
|
||||
** problem if this is not the case.
|
||||
*/
|
||||
int jj;
|
||||
for(jj=0; jj<ii; jj++){
|
||||
if( 0==sqlite3StrICmp(aBuiltinFunc[ii], aBuiltinFunc[jj]) ){
|
||||
fprintf(stderr, "Error in func.c\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
iHead = ii;
|
||||
anFunc[iHead] = 1;
|
||||
}
|
||||
|
||||
iHash = hashstring(aBuiltinFunc[ii]);
|
||||
if( aHash[iHash]!=nFunc ){
|
||||
int iNext = aHash[iHash];
|
||||
while( aNext[iNext]!=nFunc ){
|
||||
iNext = aNext[iNext];
|
||||
}
|
||||
aNext[iNext] = ii;
|
||||
}else{
|
||||
aHash[iHash] = ii;
|
||||
}
|
||||
}
|
||||
|
||||
printf(
|
||||
"int sqlite3GetBuiltinFunction(\n"
|
||||
" const char *zName, \n"
|
||||
" int nName, \n"
|
||||
" FuncDef **paFunc\n"
|
||||
"){\n"
|
||||
);
|
||||
|
||||
printarray("aHash", aHash, HASHSIZE);
|
||||
printarray("anFunc", anFunc, nFunc);
|
||||
printarray("aNext", aNext, nFunc);
|
||||
printf(" FuncDef *pNoFunc = &aBuiltinFunc[%d];\n", nFunc);
|
||||
|
||||
printf(
|
||||
" unsigned int iKey = 0; /* Hash of case-insensitive string zName. */\n"
|
||||
" int ii;\n"
|
||||
" FuncDef *pFunc;\n"
|
||||
"\n"
|
||||
" /* Generate the hash of zName */\n"
|
||||
" for(ii=0; ii<nName; ii++){\n"
|
||||
" iKey = (iKey<<3) + (u8)sqlite3UpperToLower[(u8)zName[ii]];\n"
|
||||
" }\n"
|
||||
" iKey = iKey%%127;\n"
|
||||
"\n"
|
||||
" pFunc = &aBuiltinFunc[iKey = aHash[iKey]];\n"
|
||||
" while( pFunc!=pNoFunc && sqlite3StrNICmp(pFunc->zName, zName, nName) ){\n"
|
||||
" pFunc = &aBuiltinFunc[iKey = aNext[iKey]];\n"
|
||||
" }\n"
|
||||
"\n"
|
||||
" *paFunc = pFunc;\n"
|
||||
" return anFunc[iKey];\n"
|
||||
"}\n"
|
||||
);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -101,6 +101,7 @@ foreach hdr {
|
||||
os_os2.h
|
||||
pager.h
|
||||
parse.h
|
||||
pcache.h
|
||||
rtree.h
|
||||
sqlite3ext.h
|
||||
sqlite3.h
|
||||
@ -231,6 +232,7 @@ foreach file {
|
||||
os_win.c
|
||||
|
||||
bitvec.c
|
||||
pcache.c
|
||||
pager.c
|
||||
|
||||
btmutex.c
|
||||
@ -252,7 +254,7 @@ foreach file {
|
||||
build.c
|
||||
callback.c
|
||||
delete.c
|
||||
func.c
|
||||
func2.c
|
||||
insert.c
|
||||
legacy.c
|
||||
loadext.c
|
||||
|
Reference in New Issue
Block a user