Compare commits

...

57 Commits

Author SHA1 Message Date
drh 56e4b6f968 Fix a date round-off problem in strftime(). Ticket #2153. (CVS 3575)
FossilOrigin-Name: 47fee16ba9bd8ab2820fe97e89480528114825cd
2007-01-08 16:20:28 +00:00
drh 7ee841f506 Fix a round-off error in the %W conversion of strftime(). Ticket #2150. (CVS 3572)
FossilOrigin-Name: e6a18741a47a4288fa9c4fef93443b19aff20fb9
2007-01-08 13:43:37 +00:00
drh 80b1ff487f Fix a bad variable reference. The reference is actually in unreachable
code and is therefore harmless.  The fix is to remove the code. (CVS 3483)

FossilOrigin-Name: 46b91807f72d65bf24257426bdbee27acff87661
2006-10-24 11:26:44 +00:00
drh a34b0794e0 Version 2.8.17 (CVS 2836)
FossilOrigin-Name: 50d7e50a96907eeb1705687f7e54ed993b7a47c2
2005-12-19 17:56:44 +00:00
drh 058d3c4477 Bump the version number of the 2.8 branch to 2.8.17. (CVS 2833)
FossilOrigin-Name: 94dfb4bd5d037353dc96656ccee5477e78fbbe74
2005-12-19 17:38:35 +00:00
drh fdd4af7e7b Backport the fix for ticket #1567 to version 2.8. (CVS 2832)
FossilOrigin-Name: 3f5f358f826be8f9ad2b723a58f4a8a0d9b90ccc
2005-12-19 17:37:09 +00:00
drh d7ae9475a8 Handle failures of getcwd() without segfaulting. Ticket #1274. (CVS 2491)
FossilOrigin-Name: c1bd0a150c2c734b1ef991361f4eb41feb2ec578
2005-06-06 15:07:02 +00:00
drh dd71a0753e The ".dump" method in the shell for version 2 should not sort tables by
name because this can put views out of dependency order.   Ticket #1124. (CVS 2347)

FossilOrigin-Name: b82c06fdd143fde6678003a0f3fc66e10c21a65b
2005-02-16 03:53:10 +00:00
drh 6ebcbcd48b Update the publish.sh script so that it grabs the correct source tree. (CVS 2339)
FossilOrigin-Name: 74684507a0a2bda67b6cfa899ccabf99da515899
2005-02-15 16:04:46 +00:00
drh 9b9a61f715 Version 2.8.16 (CVS 2336)
FossilOrigin-Name: 2efbbba55a851a5b83726720aaa9e59b8387556c
2005-02-15 13:07:51 +00:00
drh fb7b4f204b Modifications to the publish.sh script prior to 2.8.16. (CVS 2328)
FossilOrigin-Name: affde4431749e0c57e786cec926895b3c0f8a04f
2005-02-14 05:47:33 +00:00
drh b3dc0431c7 Cleanup the vacuum bug fixes in version 2.8. (CVS 2327)
FossilOrigin-Name: 5658da7e5ae2ee4dc7ec45a1914f766dfb4be323
2005-02-14 00:25:48 +00:00
drh 66a01c4554 Fix the vacuum bug in version 2.8. Also prepare for release 2.8.16. (CVS 2326)
FossilOrigin-Name: 0eaebad5a0242bbdc9c205bf9efeda93bb0a2de9
2005-02-14 00:21:38 +00:00
drh 6f65beb084 Avoid excess heap usage when copying expressions. Ticket #979. (CVS 2126)
FossilOrigin-Name: 0f444c032dded0ea4c5bf47516f37cbd44767689
2004-11-20 20:42:10 +00:00
drh 7a5b729aa7 Preserve the default_temp_store pragma across VACUUM in version 2.8.
(Version 3.0 already does this.)  Ticket #1008. (CVS 2120)

FossilOrigin-Name: 7fa623f24a6c566cb149cfb6515faf489280db97
2004-11-20 19:01:44 +00:00
drh ec88191019 Disable trigger tests that use ATTACH in version 2.8 when there is a
codec enabled. (CVS 2042)

FossilOrigin-Name: f77f7753aaca0b4a147f91e538691cb4ee8995a8
2004-11-02 18:30:44 +00:00
drh e1b6c821d6 Fix naming conflict between sqlite.h and sqlite3.h. Ticket #946. (CVS 2008)
FossilOrigin-Name: e750ae5ab8ed9a2cd38548c63008cc7d2576e26d
2004-10-06 15:52:35 +00:00
drh b2292faf9c Fix for ticket #905. (CVS 1995)
FossilOrigin-Name: bf90799d889ccc88ed7e3635b041d5f38865d447
2004-10-01 15:11:13 +00:00
drh 5cfe9a78f9 Fix a segfault in the authorizer when it is given a SELECT statement with
no FROM clause.  Ticket #896. (CVS 1953)

FossilOrigin-Name: 205d85d77e8f0c9a1d841129601847235052d59f
2004-09-09 13:54:29 +00:00
drh 19aca9eddb Correct handling of quoted names in CREATE INDEX. Ticket #869. (CVS 1907)
FossilOrigin-Name: b01d566580b151db0e1c95d124f20ea0bc889250
2004-08-28 14:53:34 +00:00
drh 85a5dfef26 More fixes to the publish.sh script. (CVS 1863)
FossilOrigin-Name: 022e3f56ac5a29f8449d98630c673edda372d221
2004-07-23 01:10:57 +00:00
drh 82ab315f73 Version 2.8.15 (CVS 1859)
FossilOrigin-Name: 102ab94167448e062333e15159d8199d08ac2677
2004-07-22 18:53:52 +00:00
drh 3ec28d5d81 Fix the publish.sh script so that it builds and packages windows DLLs
correctly. (CVS 1856)

FossilOrigin-Name: 81aa41e7d4e36ba3ecc5ce66c73dae5a607a3963
2004-07-22 18:08:33 +00:00
drh e1175bd650 Another attempt at fixing the memory allocation problem in sqliteExprListDup(). (CVS 1855)
FossilOrigin-Name: 49c2ad8a754daebfdad230dc84e417e3d728c083
2004-07-22 17:10:10 +00:00
drh 0c3ab2d6ac Bug fix in allocation of expression lists after a malloc() failure. (CVS 1854)
FossilOrigin-Name: 09494cab4f53a90e0d84abfec6806b4b2b3e118b
2004-07-22 16:32:13 +00:00
drh 73003316a2 Add join tests to the 2.8 branch. (CVS 1850)
FossilOrigin-Name: e5546f49c79155ed2695a1d58ca8044e79d60802
2004-07-22 16:08:38 +00:00
drh bde845ce70 Update the version number for release 2.8.15. (CVS 1849)
FossilOrigin-Name: 9b3c3ca4aff10c7e395d195cd76a1f3c038cb066
2004-07-22 15:53:37 +00:00
drh 4cf73f61fb Fix an obscure memory leak in the expression list allocator. (CVS 1835)
FossilOrigin-Name: 5c77b332bd7704b754edf6876ae668136b05876f
2004-07-20 02:05:11 +00:00
drh 5d7f6e84f1 Handle quotes on table names in TABLE.* terms in SELECT. Ticket #680. (CVS 1834)
FossilOrigin-Name: 9937ffb08e6eb3a11344d880cade9975e8dc9d5b
2004-07-20 01:45:49 +00:00
drh 8c8ec4fd3e Fix the handling of indices with quoted names. Ticket #695. (CVS 1830)
FossilOrigin-Name: 467309975f40bdc1ac0ed1c9c34d187e91217e12
2004-07-20 00:50:29 +00:00
drh 2d97242175 Comment out all of date/time functions with SQLITE_OMIT_DATETIME_FUNCS.
Ticket #784. (CVS 1829)

FossilOrigin-Name: 28c01d2ac705923d3210ec2b8906541f42ec6f25
2004-07-20 00:40:01 +00:00
drh 0e93442494 Correct handling of views on tables with quoted column names. Ticket #756. (CVS 1827)
FossilOrigin-Name: ef0d5ebe96b9babe275d62ed6abe95652838de5f
2004-07-20 00:20:46 +00:00
drh 9c46d69216 Limit occurs after DISTINCT. Ticket #749. (CVS 1824)
FossilOrigin-Name: db5ae13db3edec82dd2ead3b76fc9f89f33b2dc2
2004-07-19 23:33:02 +00:00
drh a8734da09b Fix for ticket #813. (CVS 1820)
FossilOrigin-Name: 0cc612f8aa458034d3dc246861c529c57ac5b2b1
2004-07-19 19:30:50 +00:00
drh 90ddc11b77 Correctly handle joins of move than 32 tables. Ticket #806. (CVS 1813)
FossilOrigin-Name: 5ba0acd6c788b6ec07b29dc40c17265f8fb8a337
2004-07-19 02:24:02 +00:00
drh 0aaa1c038e Use only unsigned characters in upper() and lower(). Ticket #708. (CVS 1807)
FossilOrigin-Name: f9b2aa8f8a6c0a7f74af2844a80fe14b85d05a45
2004-07-18 23:03:10 +00:00
drh 6951f39c72 The %W date specifier in strftime should be measured from the first Monday
of the year.  Ticket #758. (CVS 1806)

FossilOrigin-Name: 135e5447f66fcd8ec4350c81707a2e8d3c9fd31c
2004-07-18 22:25:15 +00:00
drh 805e7d5b42 Min() and max() ignore NULL values. Ticket #800. (CVS 1803)
FossilOrigin-Name: 223521c04e8ad39e06fee455f7dbb31ace2d3800
2004-07-18 21:14:05 +00:00
drh 06d55ce8f3 Fix for ticket #812 in the 2.8 branch. (CVS 1801)
FossilOrigin-Name: ea364dffc7dfe7533d6916d63db0a79181440e64
2004-07-17 21:59:18 +00:00
drh 24b8cb36bc Make SrcList.nSrc a signed quantity to avoid problems on AIX. (CVS 1795)
FossilOrigin-Name: 41526d098dcae6def4940cd464d0e1e673c6abb5
2004-07-15 13:37:04 +00:00
drh afcfc0eecb Correct return type on sqliteStrICmp() when argument strings differ.
Ticket #804. (CVS 1793)

FossilOrigin-Name: 296528b281025d86650cf0e4c17e75c296e03310
2004-07-15 13:08:41 +00:00
drh ea024eee62 Fold in changes submitted by the PHP developers. (CVS 1742)
FossilOrigin-Name: a4a2570822f13ece2174438ef8f8a6175aaa4a6b
2004-06-26 14:40:05 +00:00
drh ca69323478 The MIN() aggregate function returns NULL if any element in the result
was NULL.  This makes MIN() consistent with ORDER BY which sorts NULL first.
Ticket #777. (CVS 1679)

FossilOrigin-Name: 78ced6e3092d69e7cb77c5c2acff70f3c92e6523
2004-06-23 21:16:51 +00:00
drh 52e50d6aaa Add the source code to the sqlite_analyzer utility. (CVS 1637)
FossilOrigin-Name: 06bf4c7e41839eb003f3df05a80789a1f2b21b8f
2004-06-19 11:57:39 +00:00
drh 0f156745bd Fix a compiler warning in os.c. (CVS 1636)
FossilOrigin-Name: 28b737b5a0e07a142396809f8a7dbd985d433c0d
2004-06-19 11:57:08 +00:00
danielk1977 f4ed02a34f Backport of (1628) to version 2. (CVS 1631)
FossilOrigin-Name: cce250eaee59eac2d15437b564f049c5b241317c
2004-06-19 04:23:25 +00:00
drh 463ff298d6 Update the publish.sh script so that it no longer generates documentation
pages (that is handled by the version 3.0.0 publish.sh).  Also insert
version numbers in the filenames of all build products. (CVS 1601)

FossilOrigin-Name: f2b8d35825a2137e83419e9aebc9619a9db2ada8
2004-06-16 01:21:00 +00:00
drh 5d5398b089 Do not authenticate statements when reading the schema. Backport of bug
fix in (1588) to version 2. (CVS 1591)

FossilOrigin-Name: 24adf9ed5988d6e110a750f75b767fad163689c6
2004-06-14 11:58:37 +00:00
drh f3a5a57ddb Version 2.8.14 (CVS 1554)
FossilOrigin-Name: 7d3937743f88acad8859fbbbb1c03271a939bc0b
2004-06-09 23:20:05 +00:00
drh 1832890357 Update the version number to 2.8.14. For whatever reason, the version at
the tip of the 2.8 branch fixes ticket #757. (CVS 1552)

FossilOrigin-Name: 7538d2e5297bdeaf07c6d6e37053c654501ef286
2004-06-09 22:49:56 +00:00
drh 97117601d2 Calling sqlite_interrupt() while VACUUM is running should not cause an error. (CVS 1529)
FossilOrigin-Name: 1cf94a7c41b56506251a9964f133e179bd06825f
2004-06-04 19:07:53 +00:00
drh f9ec81c84d Improvements to testing of sqlite_interrupt. More checking for interrupt
inside of VACUUM. (CVS 1344)

FossilOrigin-Name: d596f513c3acfe0d297dc3f5c66f4b0ea2d12a34
2004-05-10 20:27:41 +00:00
drh 45041e263a Fix a memory leak in DETACH when using the codec. (CVS 1317)
FossilOrigin-Name: c4bd99b79c66217140781309ed06e1ff3ef4a206
2004-05-07 01:46:01 +00:00
drh 3e5c826219 Add the sqlite_temp_directory global variable which, if set, defines the
directory in which temporary files are created. (CVS 1316)

FossilOrigin-Name: c90ed20dc4f95eb06a5259578597593f5968bfb7
2004-05-07 00:57:06 +00:00
drh 4e0e4d7a9e Fix a stack overflow problem with INSTEAD OF triggers. (CVS 1310)
FossilOrigin-Name: 5a33e0b06f495628704d0881940a792f342facc7
2004-04-29 16:16:29 +00:00
drh 064cf76bb1 Changes to lemon.c so that it compiles on OpenWatcom 1.3. Ticket #665. (CVS 1307)
FossilOrigin-Name: b8b8ce5c81ef614d488e0f79df8935ef609dc4f2
2004-04-24 12:59:13 +00:00
drh a38518d673 Add some extra debugging logic to lemon.c. Ticket #692. (CVS 1304)
FossilOrigin-Name: 635f674d20ca3e0b534eba54313004e859de16e9
2004-04-23 23:37:56 +00:00
45 changed files with 1416 additions and 370 deletions
+1 -1
View File
@@ -1 +1 @@
2.8.13
2.8.17
+14
View File
@@ -156,6 +156,20 @@ sqlite$(EXE): $(TOP)/src/shell.c libsqlite.a sqlite.h
$(TCCX) $(READLINE_FLAGS) -o sqlite$(EXE) $(TOP)/src/shell.c \
libsqlite.a $(LIBREADLINE) $(THREADLIB)
sqlite_analyzer$(EXE): $(TOP)/src/tclsqlite.c libsqlite.a $(TESTSRC) \
$(TOP)/tool/spaceanal.tcl
sed \
-e '/^#/d' \
-e 's,\\,\\\\,g' \
-e 's,",\\",g' \
-e 's,^,",' \
-e 's,$$,\\n",' \
$(TOP)/tool/spaceanal.tcl >spaceanal_tcl.h
$(TCCX) $(TCL_FLAGS) -DTCLSH=2 -DSQLITE_TEST=1 -static -o \
sqlite_analyzer$(EXE) $(TESTSRC) $(TOP)/src/tclsqlite.c \
libsqlite.a $(LIBTCL)
# This target creates a directory named "tsrc" and fills it with
# copies of all of the C source code and header files needed to
# build on the target system. Some of the C source code and header
+48 -45
View File
@@ -1,9 +1,9 @@
C Get\sthe\stemp_store\sand\sdefault_temp_store\spragmas\sworking.\s\sUpdate\sthe\ndocumentation.\s\sAlso\sfix\sa\smalloc\sproblem\sthat\spopped\sup\sduring\sthe\sregression\ntesting.\s(CVS\s1302)
D 2004-04-23T17:04:44
C Fix\sa\sdate\sround-off\sproblem\sin\sstrftime().\s\sTicket\s#2153.\s(CVS\s3575)
D 2007-01-08T16:20:29
F Makefile.in ab7b0d5118e2da97bac66be8684a1034e3500f5a
F Makefile.linux-gcc b86a99c493a5bfb402d1d9178dcdc4bd4b32f906
F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd
F VERSION 4328de2a5fb5000699b907ca405cb9d84ba4e097
F VERSION 028d738f543b0e6a47f215b2adb7eb90fb5b9f3a
F aclocal.m4 7daea4c35e88de30d5a3f6f7a2ab99720e803bbd
F art/SQLite.eps 9b43cc99cfd2be687d386faea6862ea68d6a72b2
F art/SQLite.gif 1bbb94484963f1382e27e1c5e86dd0c1061eba2b
@@ -15,61 +15,61 @@ F doc/lemon.html f0f682f50210928c07e562621c3b7e8ab912a538
F doc/report1.txt a031aaf37b185e4fa540223cb516d3bccec7eeac
F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895
F ltmain.sh f6b283068efa69f06eb8aa1fe4bddfdbdeb35826
F main.mk 1b27efb94be53a96c4333584a00a59fcc87ddc37
F publish.sh 1cd5c982388560fa91eedf6a338e210f713b35c8
F main.mk 7dfbd08ac90b15debd84ebd2606f0dbab739a4ab
F publish.sh 28c743e8ef922b726a05c84a8e597a6cf04cf554
F spec.template a38492f1c1dd349fc24cb0565e08afc53045304b
F sqlite.1 83f4a9d37bdf2b7ef079a82d54eaf2e3509ee6ea
F sqlite.def fc4f5734786fe4743cfe2aa98eb2da4b089edb5f
F sqlite.pc.in 30552343140c53304c2a658c080fbe810cd09ca2
F src/attach.c b01db0d3211f673d8e670abf7eaad04591d40d14
F src/auth.c 4fa3b05bd19445d1c474d6751c4a508d6ea0abe1
F src/attach.c 026702566f941bf2bb158a0aaa86bfeb65910aa6
F src/auth.c 8d678ab13950801e10fd09781a7c1ed3bfeffb7c
F src/btree.c 08a05b925b348c05d79b9b062b79e50d565678de
F src/btree.h 41cb3ff6ebc3f6da2d0a074e39ff8c7a2287469f
F src/btree_rb.c 99feb3ff835106d018a483a1ce403e5cf9c718bc
F src/build.c 76fbca30081decd6615dee34b48c927ed5063752
F src/btree_rb.c af40501eedd7b673ffd5e02f3a4702c76596d64a
F src/build.c ee7905531ed592bd68b484f0821fc3cd007e1576
F src/copy.c 750e13828c3e4a293123e36aaa7cf0f22466248a
F src/date.c f055419d602bde622c70f831350b6b52f2235de0
F src/date.c 3f080b6f46c6a96891987b439449e4096c98f925
F src/delete.c 82001c74882319f94dab5f6b92a27311b31092ae
F src/encode.c fc8c51f0b61bc803ccdec092e130bebe762b0a2f
F src/expr.c 8c3f5603c3e98b1c146d18076ba3e82cdbb59c11
F src/func.c 34fead7a33e82095f6412d3fafd379d47864b3be
F src/expr.c 6bb3961c0391f2efe788fcfde3c2ff2ff283d5a8
F src/func.c ab5c57f0ebb975e66cc13f09141247c2f7a2c293
F src/hash.c 9b56ef3b291e25168f630d5643a4264ec011c70e
F src/hash.h 3247573ab95b9dd90bcca0307a75d9a16da1ccc7
F src/insert.c c0485ee2d1b99322894e2d1e0b576fd05ed75616
F src/main.c 94dd355768e2a389e184a069b6880f4bac100307
F src/main.c 7802ab78b2f2e66750be2192b2c1334c99bc10a5
F src/md5.c fe4f9c9c6f71dfc26af8da63e4d04489b1430565
F src/os.c 5f11382733805d4529ec2a30800e117f30995ea8
F src/os.c 617db07b13113ec093786b2278767ab46217d140
F src/os.h 250a3789be609adfee5c5aa20137ce8683276f24
F src/pager.c b246986e5ba31b15aa3cf91d3b9ec2e608aceb8e
F src/pager.c e44cb43e9cd2e7a06818c4f8ff5aa697f7edf8cd
F src/pager.h 82332878799280145639a48d88cdb4058925e3f6
F src/parse.y 023720cb8c3bef74e51738bca78335d0dc6d2cfd
F src/pragma.c f9c157b0591419d2d3407dac90222020d2a6d822
F src/printf.c 8c58b7b6d4069eec6ebe2d46bdbc3a89a367bf95
F src/printf.c 378ec63d9303993eef24814a56a9fc7260aacbea
F src/random.c 775913e0b7fbd6295d21f12a7bd35b46387c44b2
F src/select.c 3833e2b64cc6d249385ee44e13bf49c9ae5b903d
F src/shell.c 920af040d3a33ea8919c82cee45b424ad841cee0
F src/sqlite.h.in 35bec264dfb4965bbfeb7e75221f8658f210c30d
F src/sqliteInt.h 235ce244b62bb26cc9ab394fb7a0724dd4e65c83
F src/table.c d845cb101b5afc1f7fea083c99e3d2fa7998d895
F src/tclsqlite.c 819d92d305756c4ea57de023c387d2fa8a256aff
F src/test1.c 9aa62b89d420e6763b5e7ae89a47f6cf87370477
F src/select.c a1c18cab14b49f28ed7629a53fe02adeb13083d2
F src/shell.c 46a1757c152bba687f647b571693bfa223d3354d
F src/sqlite.h.in b1414cc6686c77917024d8196efa4531e76cf194
F src/sqliteInt.h 311de2338da566e996ea3f4846d489e3856be7a3
F src/table.c eea34544be947e4939ba9e46391d5da998f90b84
F src/tclsqlite.c 2daaaa41378fbaf167905363197e1d44464b6eb6
F src/test1.c 4ae20bc125b1a7d7824cccca55d538d81f0b4949
F src/test2.c 75819b0f2c63c6a0fd6995445881f2eb94036996
F src/test3.c 30985ebdfaf3ee1462a9b0652d3efbdc8d9798f5
F src/test4.c 6e3e31acfaf21d66420fc35fda5b17dc0000cc8d
F src/tokenize.c 6676b946fd8825b67ab52140af4fdc57a70bda48
F src/trigger.c a9927b57c865b6f3df3fb5e40c9824d722660ded
F src/update.c 4c50328ebc127852bde8e2950eb8933234802c21
F src/util.c 122bc174f6c8c2eb6a9127d9f13c4c74f83b85e4
F src/vacuum.c a4e8464c9f6d60659c5343e9d62c742463227820
F src/vdbe.c 7c33f761fdc799633468766fb53eda4301daa6b3
F src/update.c bd391079138e67d09c9af34528ca4137c29242d1
F src/util.c c2de22342aae2cc954d3c88ef40a2ece7cee6905
F src/vacuum.c 12de02a8dec2b3f8d30ea496b66a0f989322a2c4
F src/vdbe.c 59100995dae315d1c756a8a754b1dd1a228751d7
F src/vdbe.h ac987945e4dd6f987bca534c6005899f089fc270
F src/vdbeInt.h b40ff02ce39fd076e6ff3369e19c1bbfe1986682
F src/vdbeaux.c e2cdd1ab63604a390612c73e26bdd2ef910e9438
F src/where.c b58764861a96bab3f1d294200f9e53519b92c274
F src/vdbeaux.c 14ff0eb6ed9d5998f927433c91b0a3d13d81f4f6
F src/where.c ce4968e37382808ec76a47385384ee21ad9e979e
F test/all.test 569a92a8ee88f5300c057cc4a8f50fbbc69a3242
F test/attach.test ba8261d38da6b6a7d4f78ec543c548c4418582ef
F test/attach2.test ce61e6185b3cd891cc0e9a4c868fcc65eb92fc55
F test/auth.test 5c4d95cdaf539c0c236e20ce1f71a93e7dde9185
F test/auth.test 3bd865e3069af8aa703158ff69cfc5e57b29033b
F test/bigfile.test ea904b853ce2d703b16c5ce90e2b54951bc1ae81
F test/bigrow.test 8ab252dba108f12ad64e337b0f2ff31a807ac578
F test/bind.test 56a57043b42c4664ca705f6050e56717a8a6699a
@@ -83,37 +83,39 @@ F test/capi2.test ec96e0e235d87b53cbaef3d8e3e0f8ccf32c71ca
F test/conflict.test 0911bb2f079046914a6e9c3341b36658c4e2103e
F test/copy.test f07ea8d60878da7a67416ab62f78e9706b9d3c45
F test/crashtest1.c 09c1c7d728ccf4feb9e481671e29dda5669bbcc2
F test/date.test aed5030482ebc02bd8d386c6c86a29f694ab068d
F test/date.test aa4bc2aae379bed3f838ea73de0cde1c352c5545
F test/delete.test 92256384f1801760180ded129f7427884cf28886
F test/expr.test ad985242e140f87eeef329d98257b8369a2066dc
F test/fkey1.test d65c824459916249bee501532d6154ddab0b5db7
F test/format3.test 149cc166c97923fa60def047e90dd3fb32bba916
F test/func.test 000515779001ac6899eec4b54e65c6e2501279d4
F test/func.test 56b12001d4d8239c6af2864e3d64916cf5dad711
F test/hook.test 1a67ce0cd64a6455d016962542f2822458dccc49
F test/in.test 0de39b02ceeca90993b096822fb5a884661c5b47
F test/index.test 9295deefbdb6dedbe01be8905f0c448fe5bd4079
F test/index.test 491d721e9b442a51b118894323f2885a2187a8dd
F test/insert.test a17b7f7017097afb2727aa5b67ceeb7ab0a120a1
F test/insert2.test c288375a64dad3295044714f0dfed4a193cf067f
F test/interrupt.test 9142ce4448605127640eda5e283952f75f67ed91
F test/interrupt.test 0d50985f1aa6c39fe2cca4cf4a272c79ff1648e8
F test/intpkey.test 9320af48415c594afd4e15f8ef0daa272e05502e
F test/ioerr.test 5dbaf09f96b56ee01cf3edd762b96eb4ad2c9ca4
F test/join.test 9ef6aabaac9de51d5fc41e68d1f4355da05a84cd
F test/join2.test c97e4c5aa65dea462145529e58212a709b4722b8
F test/join3_28.test dbfbca6e102d30205e7c1854b0d4fdfcd04de938
F test/join4_28.test aa3dba47dcc9c835ac505111ff3d925f0657ef15
F test/lastinsert.test 31382f88b9b0270333ac9e4a17f2c2f4732da718
F test/laststmtchanges.test cabd11bdfbaf73a4486c50b58297d9c2038ccc18
F test/limit.test e28ce938ddacefdff860d082be45e1e5e2801441
F test/limit.test c6365450f3180170c0fa1b0bf1ae48522c33b731
F test/lock.test 226ef831dad60ad4d200dc83e25479ba952aac7e
F test/main.test 6a851b5992c4881a725a3d9647e629199df8de9d
F test/malloc.test 2cfcffb7c858640e01e6520ee1cd54ca57d98e80
F test/memdb.test 6ece25c7c0e6500199d3662607a3edca081abb2a
F test/memleak.test 4d5d374c8ea1fc5ac634aed58cac1047848ce65e
F test/minmax.test 9dcf52f713b1b9e61d0a88a51eb8bb2e3c52d0ab
F test/minmax.test 9dc011a23b897718004b38f4f99e0171f9d5a3fe
F test/misc1.test 0b98d493b0cf55cb5f53e1f3df8107c166eecb5a
F test/misc2.test 10c2ce26407d37411b96273e552d5095393732be
F test/misc3.test 3b5e369514a3ba3f919fb7eafa7d027440b5079e
F test/misuse.test 1095f26d1aed406c65e1d2eba651c4bb7c38cbff
F test/notnull.test 7a08117a71e74b0321aaa937dbeb41a09d6eb1d0
F test/null.test c14d0f4739f21e929b8115b72bf0c765b6bb1721
F test/null.test 675e6823d72d4866d2aca6bf5b7259c9cd713703
F test/pager.test 331519008889d45f6df6697395e5bce6ee602fd9
F test/pragma.test 24a3f7a697b45cb90d664ebce5566bec7ac41571
F test/printf.test 46b3d07d59d871d0831b4a657f6dfcafe0574850
@@ -121,7 +123,7 @@ F test/progress.test 701b6115c2613128ececdfe1398a1bd0e1a4cfb3 x
F test/quick.test 5a6bccf5c02f16841a79fbac7409a02138880c10
F test/quote.test 08f23385c685d3dc7914ec760d492cacea7f6e3d
F test/rowid.test 77f7e8c7ca626a15ff91a536595b695cfce7c845
F test/select1.test 0d708cec567104653ec9aa49fecf3444a2e7d150
F test/select1.test 1eab1f8aa85b8d4e3474c0769fb81313548929ab
F test/select2.test aceea74fd895b9d007512f72499db589735bd8e4
F test/select3.test 445a1a3dde4e2fd32541b311f55da5e2f8079d76
F test/select4.test e7e9a32fa745246cb99fadbeb63af4843a17925b
@@ -131,14 +133,14 @@ F test/sort.test ba07b107c16070208e6aab3cadea66ba079d85ba
F test/subselect.test f0fea8cf9f386d416d64d152e3c65f9116d0f50f
F test/table.test 371a1fc1c470982b2f68f9732f903a5d96f949c4
F test/tableapi.test e0c4cce61e58343caa84dab33fa6823cb35fe1e1
F test/tclsqlite.test a684fc191b81e6cded8a81263663d5a130fbb013
F test/tclsqlite.test 0089f84fc4f007d0d396f4d0c231d4c6dd99a48b
F test/temptable.test a770ba6308d7f7332fce985086b8e06bed6430c2
F test/tester.tcl 2f1d43df1311c9dc06acaa7a82e87bfea85dea5f
F test/thread1.test 53f050d5be6932d9430df7756edd379366508ff6
F test/threadtest1.c f7f896e62ed46feae1dc411114a48c15a0f82ee2
F test/threadtest2.c d94ca4114fd1504f7e0ae724bcd83d4b40931d86
F test/trans.test 0cb8256daff1ae0da75321e00125338c6681158d
F test/trigger1.test 4538c1c7d6bbca5dfe619ea6e1682b07ece95b21
F test/trigger1.test d2d38d8a81a2c4a033b27965aaf28a0b7aa99f31
F test/trigger2.test 0767ab30cb5a2c8402c8524f3d566b410b6f5263
F test/trigger3.test a95ccace88291449f5eae7139ec438a42f90654d
F test/trigger4.test 542afce45774e8f8e1130b96b8675f414d6e4bd8
@@ -146,10 +148,10 @@ F test/unique.test 0e38d4cc7affeef2527720d1dafd1f6870f02f2b
F test/update.test b29bd9061a1150426dab6959806fcc73a41b1217
F test/vacuum.test a2a44544df719666efb51afbfeb6062fd59a672a
F test/version.test 92adee5d98cf6e3eb0d1cf5186952e8114931bf6
F test/view.test 1ee12c6f8f4791a2c0655120d5562a49400cfe53
F test/view.test ac151928890d17716d5c1f7acc5924af61a7dacf
F test/where.test cb3a2ed062ce4b5f08aff2d08027c6a46d68c47b
F tool/diffdb.c 7524b1b5df217c20cd0431f6789851a4e0cb191b
F tool/lemon.c 38a39c623df325bcbd67152d6f92e09edbee8b83
F tool/lemon.c db6a3bfaf3388c0f7aea3adb5e05acddcd427016
F tool/lempar.c 0b5e7a58634e0d448929b8e85f7981c2aa708d57
F tool/memleak.awk b744b6109566206c746d826f6ecdba34662216bc
F tool/memleak2.awk 9cc20c8e8f3c675efac71ea0721ee6874a1566e8
@@ -159,6 +161,7 @@ F tool/report1.txt 9eae07f26a8fc53889b45fc833a66a33daa22816
F tool/showdb.c 3559eac5a3b46e9b558d50856946b25e77633236
F tool/showjournal.c ec3b171be148656827c4949fbfb8ab4370822f87
F tool/space_used.tcl f714c41a59e326b8b9042f415b628b561bafa06b
F tool/spaceanal.tcl fec9907072011cd2b8b956fe7322cf6c50429ba9
F tool/speedtest.tcl 06c76698485ccf597b9e7dbb1ac70706eb873355
F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
F www/arch.fig d5f9752a4dbf242e9cfffffd3f5762b6c63b3bcf
@@ -188,7 +191,7 @@ F www/sqlite.tcl 3c83b08cf9f18aa2d69453ff441a36c40e431604
F www/tclsqlite.tcl b9271d44dcf147a93c98f8ecf28c927307abd6da
F www/vdbe.tcl 9b9095d4495f37697fd1935d10e14c6015e80aa1
F www/whentouse.tcl a8335bce47cc2fddb07f19052cb0cb4d9129a8e4
P 1e84f70fb98755651e0c04dc2cf0114e2e6fe39c
R 49661129e558c10c6a80ceab2ff48aff
P e6a18741a47a4288fa9c4fef93443b19aff20fb9
R 9093355d0bd0fe007078e08b28b0c272
U drh
Z 3af77926e38ece4579fe3c33c425d46c
Z 0fe8caf53c43ccf6073cf4d684d73e3a
+1 -1
View File
@@ -1 +1 @@
7ace576215367101904677bd69951755ee9cb1a1
47fee16ba9bd8ab2820fe97e89480528114825cd
+32 -40
View File
@@ -11,42 +11,49 @@
#
srcdir=`echo "$0" | sed 's%\(^.*\)/[^/][^/]*$%\1%'`
# Get the makefile.
# Clear out the build directory "doc"
#
cp $srcdir/Makefile.linux-gcc ./Makefile
chmod +x $srcdir/install-sh
#rm -rf doc
#make doc
# Start building stuff.
# Get the current version number - needed to help build filenames
#
VERS=`cat $srcdir/VERSION`
VERSW=`sed 's/\./_/g' $srcdir/VERSION`
# Start by building an sqlite shell for linux.
#
make clean
make sqlite
strip sqlite
mv sqlite sqlite.bin
mv sqlite sqlite-$VERS.bin
rm -f sqlite.bin.gz
gzip sqlite.bin
gzip sqlite-$VERS.bin
mv sqlite-$VERS.bin.gz doc
# Build the tclsqlite.so shared library for import into tclsh or wish
# under Linux
#
make target_source
rm sqlite_source.zip
rm -f doc/sqlite-source-$VERSW.zip
cd tsrc
zip ../sqlite_source.zip *
zip ../doc/sqlite-source-$VERSW.zip *
rm shell.c
TCLDIR=/home/drh/tcltk/8.2linux
TCLSTUBLIB=$TCLDIR/libtclstub8.2g.a
OPTS='-DUSE_TCL_STUBS=1 -DNDEBUG=1'
gcc -fPIC $OPTS -O2 -I. -I$TCLDIR -shared *.c $TCLSTUBLIB -o tclsqlite.so
strip tclsqlite.so
mv tclsqlite.so ..
mv tclsqlite.so tclsqlite-$VERS.so
gzip tclsqlite-$VERS.so
mv tclsqlite-$VERS.so.gz ../doc
rm tclsqlite.c
gcc -fPIC -DNDEBUG=1 -O2 -I. -shared *.c -o sqlite.so
strip sqlite.so
mv sqlite.so ..
mv sqlite.so sqlite-$VERS.so
gzip sqlite-$VERS.so
mv sqlite-$VERS.so.gz ../doc
cd ..
rm -f tclsqlite.so.gz sqlite.so.gz
gzip tclsqlite.so
gzip sqlite.so
# Build the tclsqlite.dll shared library that can be imported into tclsh
# or wish on windows.
@@ -76,7 +83,7 @@ i386-mingw32msvc-dllwrap \
--target i386-mingw32 \
-dllname tclsqlite.dll -lmsvcrt *.o $TCLSTUBLIB
i386-mingw32msvc-strip tclsqlite.dll
mv tclsqlite.dll ..
#mv tclsqlite.dll ../tclsqlite-$VERSW.dll
rm tclsqlite.o
cat >sqlite.def <<\END_OF_FILE
EXPORTS
@@ -133,11 +140,9 @@ i386-mingw32msvc-dllwrap \
--target i386-mingw32 \
-dllname sqlite.dll -lmsvcrt *.o
i386-mingw32msvc-strip sqlite.dll
mv sqlite.dll sqlite.def ..
zip ../doc/tclsqlite-$VERSW.zip tclsqlite.dll
zip ../doc/sqlitedll-$VERSW.zip sqlite.dll sqlite.def
cd ..
rm -f tclsqlite.zip sqlitedll.zip
zip tclsqlite.zip tclsqlite.dll
zip sqlitedll.zip sqlite.dll sqlite.def
# Build the sqlite.exe executable for windows.
#
@@ -146,22 +151,19 @@ cd tsrc
rm tclsqlite.c
OPTS='-DSTATIC_BUILD=1 -DNDEBUG=1'
i386-mingw32msvc-gcc -O2 $OPTS -I. -I$TCLDIR *.c -o sqlite.exe
mv sqlite.exe ..
zip ../doc/sqlite-$VERSW.zip sqlite.exe
cd ..
rm -f sqlite.zip
zip sqlite.zip sqlite.exe
# Construct a tarball of the source tree
#
ORIGIN=`pwd`
cd $srcdir
cd ..
EXCLUDE=`find sqlite -print | grep CVS | sed 's,sqlite/, --exclude sqlite/,'`
tar czf $ORIGIN/sqlite.tar.gz $EXCLUDE sqlite
mv sqlite_v2 sqlite-$VERS
EXCLUDE=`find sqlite-$VERS -print | grep CVS | sed 's,^, --exclude ,'`
tar czf $ORIGIN/doc/sqlite-$VERS.tar.gz $EXCLUDE sqlite-$VERS
mv sqlite-$VERS sqlite_v2
cd $ORIGIN
vers=`cat $srcdir/VERSION`
rm -f sqlite-$vers.tar.gz
ln sqlite.tar.gz sqlite-$vers.tar.gz
#
# Build RPMS (binary) and Source RPM
@@ -179,24 +181,14 @@ mkdir $HOME/rpm/SRPMS
mkdir $HOME/rpm/SPECS
# create the spec file from the template
sed s/SQLITE_VERSION/$vers/g $srcdir/spec.template > $HOME/rpm/SPECS/sqlite.spec
sed s/SQLITE_VERSION/$VERS/g $srcdir/spec.template > $HOME/rpm/SPECS/sqlite.spec
# copy the source tarball to the rpm directory
cp sqlite-$vers.tar.gz $HOME/rpm/SOURCES/.
cp doc/sqlite-$VERS.tar.gz $HOME/rpm/SOURCES/.
# build all the rpms
rpm -ba $HOME/rpm/SPECS/sqlite.spec >& rpm-$vers.log
# copy the RPMs into the build directory.
ln $HOME/rpm/RPMS/i386/sqlite*-$vers*.rpm .
ln $HOME/rpm/SRPMS/sqlite-$vers*.rpm .
# Build the website
#
cp $srcdir/../historical/* .
rm -rf doc
make doc
ln sqlite.bin.gz sqlite.zip sqlite*.tar.gz tclsqlite.so.gz tclsqlite.zip doc
ln sqlitedll.zip sqlite.so.gz sqlite_source.zip doc
ln *.rpm doc
mv $HOME/rpm/RPMS/i386/sqlite*-$VERS*.rpm doc
mv $HOME/rpm/SRPMS/sqlite-$VERS*.rpm doc
+10 -7
View File
@@ -11,7 +11,7 @@
*************************************************************************
** This file contains code used to implement the ATTACH and DETACH commands.
**
** $Id: attach.c,v 1.10 2004/02/12 18:46:39 drh Exp $
** $Id: attach.c,v 1.10.2.1 2004/05/07 01:46:01 drh Exp $
*/
#include "sqliteInt.h"
@@ -137,15 +137,17 @@ void sqliteDetach(Parse *pParse, Token *pDbname){
int i;
sqlite *db;
Vdbe *v;
Db *pDb;
v = sqliteGetVdbe(pParse);
sqliteVdbeAddOp(v, OP_Halt, 0, 0);
if( pParse->explain ) return;
db = pParse->db;
for(i=0; i<db->nDb; i++){
if( db->aDb[i].pBt==0 || db->aDb[i].zName==0 ) continue;
if( strlen(db->aDb[i].zName)!=pDbname->n ) continue;
if( sqliteStrNICmp(db->aDb[i].zName, pDbname->z, pDbname->n)==0 ) break;
pDb = &db->aDb[i];
if( pDb->pBt==0 || pDb->zName==0 ) continue;
if( strlen(pDb->zName)!=pDbname->n ) continue;
if( sqliteStrNICmp(pDb->zName, pDbname->z, pDbname->n)==0 ) break;
}
if( i>=db->nDb ){
sqliteErrorMsg(pParse, "no such database: %T", pDbname);
@@ -160,10 +162,11 @@ void sqliteDetach(Parse *pParse, Token *pDbname){
return;
}
#endif /* SQLITE_OMIT_AUTHORIZATION */
sqliteBtreeClose(db->aDb[i].pBt);
db->aDb[i].pBt = 0;
sqliteFree(db->aDb[i].zName);
sqliteBtreeClose(pDb->pBt);
pDb->pBt = 0;
sqliteFree(pDb->zName);
sqliteResetInternalSchema(db, i);
if( pDb->pAux && pDb->xFreeAux ) pDb->xFreeAux(pDb->pAux);
db->nDb--;
if( i<db->nDb ){
db->aDb[i] = db->aDb[db->nDb];
+6 -6
View File
@@ -14,7 +14,7 @@
** systems that do not need this facility may omit it by recompiling
** the library with -DSQLITE_OMIT_AUTHORIZATION=1
**
** $Id: auth.c,v 1.12 2004/02/22 18:40:57 drh Exp $
** $Id: auth.c,v 1.12.2.2 2004/09/09 13:54:30 drh Exp $
*/
#include "sqliteInt.h"
@@ -111,6 +111,7 @@ void sqliteAuthRead(
const char *zCol; /* Name of the column of the table */
int iSrc; /* Index in pTabList->a[] of table being read */
const char *zDBase; /* Name of database being accessed */
TriggerStack *pStack; /* The stack of current triggers */
if( db->xAuth==0 ) return;
assert( pExpr->op==TK_COLUMN );
@@ -119,15 +120,14 @@ void sqliteAuthRead(
}
if( iSrc>=0 && iSrc<pTabList->nSrc ){
pTab = pTabList->a[iSrc].pTab;
}else{
}else if( (pStack = pParse->trigStack)!=0 ){
/* This must be an attempt to read the NEW or OLD pseudo-tables
** of a trigger.
*/
TriggerStack *pStack; /* The stack of current triggers */
pStack = pParse->trigStack;
assert( pStack!=0 );
assert( pExpr->iTable==pStack->newIdx || pExpr->iTable==pStack->oldIdx );
pTab = pStack->pTab;
}else{
return;
}
if( pTab==0 ) return;
if( pExpr->iColumn>=0 ){
@@ -174,7 +174,7 @@ int sqliteAuthCheck(
sqlite *db = pParse->db;
int rc;
if( db->xAuth==0 ){
if( db->init.busy || db->xAuth==0 ){
return SQLITE_OK;
}
rc = db->xAuth(db->pAuthArg, code, zArg1, zArg2, zArg3, pParse->zAuthContext);
+2 -2
View File
@@ -9,7 +9,7 @@
** May you share freely, never taking more than you give.
**
*************************************************************************
** $Id: btree_rb.c,v 1.24 2004/02/29 00:11:31 drh Exp $
** $Id: btree_rb.c,v 1.24.2.1 2004/06/26 14:40:05 drh Exp $
**
** This file implements an in-core database using Red-Black balanced
** binary trees.
@@ -311,7 +311,7 @@ static char *append_node(char * orig, BtRbNode *pNode, int indent)
static void print_node(BtRbNode *pNode)
{
char * str = append_node(0, pNode, 0);
printf(str);
printf("%s", str);
/* Suppress a warning message about print_node() being unused */
(void)print_node;
+4 -4
View File
@@ -23,7 +23,7 @@
** ROLLBACK
** PRAGMA
**
** $Id: build.c,v 1.176 2004/04/23 17:04:44 drh Exp $
** $Id: build.c,v 1.176.2.3 2004/08/28 14:53:34 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
@@ -1034,7 +1034,7 @@ void sqliteCreateView(
sEnd.z += sEnd.n;
}
sEnd.n = 0;
n = ((int)sEnd.z) - (int)pBegin->z;
n = sEnd.z - pBegin->z;
z = pBegin->z;
while( n>0 && (z[n-1]==';' || isspace(z[n-1])) ){ n--; }
sEnd.z = &z[n-1];
@@ -1537,7 +1537,7 @@ void sqliteCreateIndex(
if( pName && !db->init.busy ){
Index *pISameName; /* Another index with the same name */
Table *pTSameName; /* A table with same name as the index */
zName = sqliteStrNDup(pName->z, pName->n);
zName = sqliteTableNameFromToken(pName);
if( zName==0 ) goto exit_create_index;
if( (pISameName = sqliteFindIndex(db, zName, 0))!=0 ){
sqliteErrorMsg(pParse, "index %s already exists", zName);
@@ -1557,7 +1557,7 @@ void sqliteCreateIndex(
sqliteSetString(&zName, "(", pTab->zName, " autoindex ", zBuf, (char*)0);
if( zName==0 ) goto exit_create_index;
}else{
zName = sqliteStrNDup(pName->z, pName->n);
zName = sqliteTableNameFromToken(pName);
}
/* Check for authorization to create an index.
+10 -8
View File
@@ -16,7 +16,7 @@
** sqliteRegisterDateTimeFunctions() found at the bottom of the file.
** All other code has file scope.
**
** $Id: date.c,v 1.16 2004/02/29 01:08:18 drh Exp $
** $Id: date.c,v 1.16.2.4 2007/01/08 16:20:29 drh Exp $
**
** NOTES:
**
@@ -800,18 +800,20 @@ static void strftimeFunc(sqlite_func *context, int argc, const char **argv){
case 'H': sprintf(&z[j],"%02d",x.h); j+=2; break;
case 'W': /* Fall thru */
case 'j': {
int n;
int n; /* Number of days since 1st day of year */
DateTime y = x;
y.validJD = 0;
y.M = 1;
y.D = 1;
computeJD(&y);
n = x.rJD - y.rJD + 1;
n = x.rJD - y.rJD + 0.5;
if( zFmt[i]=='W' ){
sprintf(&z[j],"%02d",(n+6)/7);
int wd; /* 0=Monday, 1=Tuesday, ... 6=Sunday */
wd = ((int)(x.rJD+0.5)) % 7;
sprintf(&z[j],"%02d",(n+7-wd)/7);
j += 2;
}else{
sprintf(&z[j],"%03d",n);
sprintf(&z[j],"%03d",n+1);
j += 3;
}
break;
@@ -824,7 +826,7 @@ static void strftimeFunc(sqlite_func *context, int argc, const char **argv){
j += strlen(&z[j]);
break;
}
case 'S': sprintf(&z[j],"%02d",(int)(x.s+0.5)); j+=2; break;
case 'S': sprintf(&z[j],"%02d",(int)x.s); j+=2; break;
case 'w': z[j++] = (((int)(x.rJD+1.5)) % 7) + '0'; break;
case 'Y': sprintf(&z[j],"%04d",x.Y); j+=strlen(&z[j]); break;
case '%': z[j++] = '%'; break;
@@ -847,19 +849,18 @@ static void strftimeFunc(sqlite_func *context, int argc, const char **argv){
** external linkage.
*/
void sqliteRegisterDateTimeFunctions(sqlite *db){
#ifndef SQLITE_OMIT_DATETIME_FUNCS
static struct {
char *zName;
int nArg;
int dataType;
void (*xFunc)(sqlite_func*,int,const char**);
} aFuncs[] = {
#ifndef SQLITE_OMIT_DATETIME_FUNCS
{ "julianday", -1, SQLITE_NUMERIC, juliandayFunc },
{ "date", -1, SQLITE_TEXT, dateFunc },
{ "time", -1, SQLITE_TEXT, timeFunc },
{ "datetime", -1, SQLITE_TEXT, datetimeFunc },
{ "strftime", -1, SQLITE_TEXT, strftimeFunc },
#endif
};
int i;
@@ -870,4 +871,5 @@ void sqliteRegisterDateTimeFunctions(sqlite *db){
sqlite_function_type(db, aFuncs[i].zName, aFuncs[i].dataType);
}
}
#endif
}
+6 -3
View File
@@ -12,7 +12,7 @@
** This file contains routines used for analyzing expressions and
** for generating VDBE code that evaluates expressions in SQLite.
**
** $Id: expr.c,v 1.114 2004/04/23 17:04:45 drh Exp $
** $Id: expr.c,v 1.114.2.4 2004/11/20 20:42:10 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
@@ -124,7 +124,7 @@ Expr *sqliteExprDup(Expr *p){
if( pNew==0 ) return 0;
memcpy(pNew, p, sizeof(*pNew));
if( p->token.z!=0 ){
pNew->token.z = sqliteStrDup(p->token.z);
pNew->token.z = sqliteStrNDup(p->token.z, p->token.n);
pNew->token.dyn = 1;
}else{
assert( pNew->token.z==0 );
@@ -155,7 +155,10 @@ ExprList *sqliteExprListDup(ExprList *p){
if( pNew==0 ) return 0;
pNew->nExpr = pNew->nAlloc = p->nExpr;
pNew->a = pItem = sqliteMalloc( p->nExpr*sizeof(p->a[0]) );
if( pItem==0 ) return 0; /* Leaks memory after a malloc failure */
if( pItem==0 ){
sqliteFree(pNew);
return 0;
}
for(i=0; i<p->nExpr; i++, pItem++){
Expr *pNewExpr, *pOldExpr;
pItem->pExpr = pNewExpr = sqliteExprDup(pOldExpr = p->a[i].pExpr);
+25 -13
View File
@@ -16,7 +16,7 @@
** sqliteRegisterBuildinFunctions() found at the bottom of the file.
** All other code has file scope.
**
** $Id: func.c,v 1.43 2004/02/25 22:51:06 rdc Exp $
** $Id: func.c,v 1.43.2.3 2004/07/18 23:03:11 drh Exp $
*/
#include <ctype.h>
#include <math.h>
@@ -157,20 +157,20 @@ static void roundFunc(sqlite_func *context, int argc, const char **argv){
** Implementation of the upper() and lower() SQL functions.
*/
static void upperFunc(sqlite_func *context, int argc, const char **argv){
char *z;
unsigned char *z;
int i;
if( argc<1 || argv[0]==0 ) return;
z = sqlite_set_result_string(context, argv[0], -1);
z = (unsigned char*)sqlite_set_result_string(context, argv[0], -1);
if( z==0 ) return;
for(i=0; z[i]; i++){
if( islower(z[i]) ) z[i] = toupper(z[i]);
}
}
static void lowerFunc(sqlite_func *context, int argc, const char **argv){
char *z;
unsigned char *z;
int i;
if( argc<1 || argv[0]==0 ) return;
z = sqlite_set_result_string(context, argv[0], -1);
z = (unsigned char*)sqlite_set_result_string(context, argv[0], -1);
if( z==0 ) return;
for(i=0; z[i]; i++){
if( isupper(z[i]) ) z[i] = tolower(z[i]);
@@ -517,26 +517,28 @@ static void minmaxStep(sqlite_func *context, int argc, const char **argv){
int mask; /* 0 for min() or 0xffffffff for max() */
assert( argc==2 );
if( argv[0]==0 ) return; /* Ignore NULL values */
if( argv[1][0]=='n' ){
xCompare = sqliteCompare;
}else{
xCompare = strcmp;
}
mask = (int)sqlite_user_data(context);
assert( mask==0 || mask==-1 );
p = sqlite_aggregate_context(context, sizeof(*p));
if( p==0 || argc<1 || argv[0]==0 ) return;
if( p==0 || argc<1 ) return;
if( p->z==0 || (xCompare(argv[0],p->z)^mask)<0 ){
int len;
if( !p->zBuf[0] ){
if( p->zBuf[0] ){
sqliteFree(p->z);
}
len = strlen(argv[0]);
if( len < sizeof(p->zBuf)-1 ){
p->z = &p->zBuf[1];
p->zBuf[0] = 1;
p->zBuf[0] = 0;
}else{
p->z = sqliteMalloc( len+1 );
p->zBuf[0] = 0;
p->zBuf[0] = 1;
if( p->z==0 ) return;
}
strcpy(p->z, argv[0]);
@@ -545,10 +547,10 @@ static void minmaxStep(sqlite_func *context, int argc, const char **argv){
static void minMaxFinalize(sqlite_func *context){
MinMaxCtx *p;
p = sqlite_aggregate_context(context, sizeof(*p));
if( p && p->z ){
if( p && p->z && p->zBuf[0]<2 ){
sqlite_set_result_string(context, p->z, strlen(p->z));
}
if( p && !p->zBuf[0] ){
if( p && p->zBuf[0] ){
sqliteFree(p->z);
}
}
@@ -621,7 +623,12 @@ void sqliteRegisterBuiltinFunctions(sqlite *db){
int i;
for(i=0; i<sizeof(aFuncs)/sizeof(aFuncs[0]); i++){
void *pArg = aFuncs[i].argType==2 ? (void*)(-1) : db;
void *pArg;
switch( aFuncs[i].argType ){
case 0: pArg = 0; break;
case 1: pArg = db; break;
case 2: pArg = (void*)(-1); break;
}
sqlite_create_function(db, aFuncs[i].zName,
aFuncs[i].nArg, aFuncs[i].xFunc, pArg);
if( aFuncs[i].xFunc ){
@@ -629,7 +636,12 @@ void sqliteRegisterBuiltinFunctions(sqlite *db){
}
}
for(i=0; i<sizeof(aAggs)/sizeof(aAggs[0]); i++){
void *pArg = aAggs[i].argType==2 ? (void*)(-1) : db;
void *pArg;
switch( aAggs[i].argType ){
case 0: pArg = 0; break;
case 1: pArg = db; break;
case 2: pArg = (void*)(-1); break;
}
sqlite_create_aggregate(db, aAggs[i].zName,
aAggs[i].nArg, aAggs[i].xStep, aAggs[i].xFinalize, pArg);
sqlite_function_type(db, aAggs[i].zName, aAggs[i].dataType);
+68 -64
View File
@@ -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.164 2004/04/23 17:04:45 drh Exp $
** $Id: main.c,v 1.164.2.2 2004/06/26 14:40:05 drh Exp $
*/
#include "sqliteInt.h"
#include "os.h"
@@ -189,10 +189,13 @@ static int sqliteInitOne(sqlite *db, int iDb, char **pzErrMsg){
BtCursor *curMain;
int size;
Table *pTab;
char *azArg[6];
char const *azArg[6];
char zDbNum[30];
int meta[SQLITE_N_BTREE_META];
InitData initData;
char const *zMasterSchema;
char const *zMasterName;
char *zSql = 0;
/*
** The master database table has a structure like this
@@ -216,62 +219,38 @@ static int sqliteInitOne(sqlite *db, int iDb, char **pzErrMsg){
")"
;
/* The following SQL will read the schema from the master tables.
** The first version works with SQLite file formats 2 or greater.
** The second version is for format 1 files.
**
** Beginning with file format 2, the rowid for new table entries
** (including entries in sqlite_master) is an increasing integer.
** So for file format 2 and later, we can play back sqlite_master
** and all the CREATE statements will appear in the right order.
** But with file format 1, table entries were random and so we
** have to make sure the CREATE TABLEs occur before their corresponding
** CREATE INDEXs. (We don't have to deal with CREATE VIEW or
** CREATE TRIGGER in file format 1 because those constructs did
** not exist then.)
assert( iDb>=0 && iDb<db->nDb );
/* zMasterSchema and zInitScript are set to point at the master schema
** and initialisation script appropriate for the database being
** initialised. zMasterName is the name of the master table.
*/
static char init_script[] =
"SELECT type, name, rootpage, sql, 1 FROM sqlite_temp_master "
"UNION ALL "
"SELECT type, name, rootpage, sql, 0 FROM sqlite_master";
static char older_init_script[] =
"SELECT type, name, rootpage, sql, 1 FROM sqlite_temp_master "
"UNION ALL "
"SELECT type, name, rootpage, sql, 0 FROM sqlite_master "
"WHERE type='table' "
"UNION ALL "
"SELECT type, name, rootpage, sql, 0 FROM sqlite_master "
"WHERE type='index'";
if( iDb==1 ){
zMasterSchema = temp_master_schema;
zMasterName = TEMP_MASTER_NAME;
}else{
zMasterSchema = master_schema;
zMasterName = MASTER_NAME;
}
assert( iDb>=0 && iDb!=1 && iDb<db->nDb );
/* Construct the schema tables: sqlite_master and sqlite_temp_master
/* Construct the schema table.
*/
sqliteSafetyOff(db);
azArg[0] = "table";
azArg[1] = MASTER_NAME;
azArg[1] = zMasterName;
azArg[2] = "2";
azArg[3] = master_schema;
azArg[3] = zMasterSchema;
sprintf(zDbNum, "%d", iDb);
azArg[4] = zDbNum;
azArg[5] = 0;
initData.db = db;
initData.pzErrMsg = pzErrMsg;
sqliteInitCallback(&initData, 5, azArg, 0);
pTab = sqliteFindTable(db, MASTER_NAME, "main");
sqliteInitCallback(&initData, 5, (char **)azArg, 0);
pTab = sqliteFindTable(db, zMasterName, db->aDb[iDb].zName);
if( pTab ){
pTab->readOnly = 1;
}
if( iDb==0 ){
azArg[1] = TEMP_MASTER_NAME;
azArg[3] = temp_master_schema;
azArg[4] = "1";
sqliteInitCallback(&initData, 5, azArg, 0);
pTab = sqliteFindTable(db, TEMP_MASTER_NAME, "temp");
if( pTab ){
pTab->readOnly = 1;
}
}else{
return SQLITE_NOMEM;
}
sqliteSafetyOn(db);
@@ -320,7 +299,7 @@ static int sqliteInitOne(sqlite *db, int iDb, char **pzErrMsg){
sqliteSetString(pzErrMsg, "unsupported file format", (char*)0);
return SQLITE_ERROR;
}
}else if( db->file_format!=meta[2] || db->file_format<4 ){
}else if( iDb!=1 && (db->file_format!=meta[2] || db->file_format<4) ){
assert( db->file_format>=4 );
if( meta[2]==0 ){
sqliteSetString(pzErrMsg, "cannot attach empty database: ",
@@ -340,18 +319,35 @@ static int sqliteInitOne(sqlite *db, int iDb, char **pzErrMsg){
*/
assert( db->init.busy );
sqliteSafetyOff(db);
if( iDb==0 ){
rc = sqlite_exec(db,
db->file_format>=2 ? init_script : older_init_script,
sqliteInitCallback, &initData, 0);
}else{
char *zSql = 0;
/* The following SQL will read the schema from the master tables.
** The first version works with SQLite file formats 2 or greater.
** The second version is for format 1 files.
**
** Beginning with file format 2, the rowid for new table entries
** (including entries in sqlite_master) is an increasing integer.
** So for file format 2 and later, we can play back sqlite_master
** and all the CREATE statements will appear in the right order.
** But with file format 1, table entries were random and so we
** have to make sure the CREATE TABLEs occur before their corresponding
** CREATE INDEXs. (We don't have to deal with CREATE VIEW or
** CREATE TRIGGER in file format 1 because those constructs did
** not exist then.)
*/
if( db->file_format>=2 ){
sqliteSetString(&zSql,
"SELECT type, name, rootpage, sql, ", zDbNum, " FROM \"",
db->aDb[iDb].zName, "\".sqlite_master", (char*)0);
rc = sqlite_exec(db, zSql, sqliteInitCallback, &initData, 0);
sqliteFree(zSql);
"SELECT type, name, rootpage, sql, ", zDbNum, " FROM \"",
db->aDb[iDb].zName, "\".", zMasterName, (char*)0);
}else{
sqliteSetString(&zSql,
"SELECT type, name, rootpage, sql, ", zDbNum, " FROM \"",
db->aDb[iDb].zName, "\".", zMasterName,
" WHERE type IN ('table', 'index')"
" ORDER BY CASE type WHEN 'table' THEN 0 ELSE 1 END", (char*)0);
}
rc = sqlite_exec(db, zSql, sqliteInitCallback, &initData, 0);
sqliteFree(zSql);
sqliteSafetyOn(db);
sqliteBtreeCloseCursor(curMain);
if( sqlite_malloc_failed ){
@@ -361,9 +357,6 @@ static int sqliteInitOne(sqlite *db, int iDb, char **pzErrMsg){
}
if( rc==SQLITE_OK ){
DbSetProperty(db, iDb, DB_SchemaLoaded);
if( iDb==0 ){
DbSetProperty(db, 1, DB_SchemaLoaded);
}
}else{
sqliteResetInternalSchema(db, iDb);
}
@@ -391,13 +384,24 @@ int sqliteInit(sqlite *db, char **pzErrMsg){
rc = SQLITE_OK;
db->init.busy = 1;
for(i=0; rc==SQLITE_OK && i<db->nDb; i++){
if( DbHasProperty(db, i, DB_SchemaLoaded) ) continue;
assert( i!=1 ); /* Should have been initialized together with 0 */
if( DbHasProperty(db, i, DB_SchemaLoaded) || i==1 ) continue;
rc = sqliteInitOne(db, i, pzErrMsg);
if( rc ){
sqliteResetInternalSchema(db, i);
}
}
/* Once all the other databases have been initialised, load the schema
** for the TEMP database. This is loaded last, as the TEMP database
** schema may contain references to objects in other databases.
*/
if( rc==SQLITE_OK && db->nDb>1 && !DbHasProperty(db, 1, DB_SchemaLoaded) ){
rc = sqliteInitOne(db, 1, pzErrMsg);
if( rc ){
sqliteResetInternalSchema(db, 1);
}
}
db->init.busy = 0;
if( rc==SQLITE_OK ){
db->flags |= SQLITE_Initialized;
@@ -869,7 +873,7 @@ static int sqliteDefaultBusyCallback(
static const short int totals[] =
{ 0, 1, 3, 8, 18, 33, 53, 78, 103, 128, 178, 228, 287};
# define NDELAY (sizeof(delays)/sizeof(delays[0]))
int timeout = (int)Timeout;
int timeout = (int)(long)Timeout;
int delay, prior;
if( count <= NDELAY ){
@@ -886,7 +890,7 @@ static int sqliteDefaultBusyCallback(
sqliteOsSleep(delay);
return 1;
#else
int timeout = (int)Timeout;
int timeout = (int)(long)Timeout;
if( (count+1)*1000 > timeout ){
return 0;
}
@@ -939,7 +943,7 @@ void sqlite_progress_handler(
*/
void sqlite_busy_timeout(sqlite *db, int ms){
if( ms>0 ){
sqlite_busy_handler(db, sqliteDefaultBusyCallback, (void*)ms);
sqlite_busy_handler(db, sqliteDefaultBusyCallback, (void*)(long)ms);
}else{
sqlite_busy_handler(db, 0, 0);
}
+39 -7
View File
@@ -464,6 +464,11 @@ int sqliteOsOpenReadWrite(
id->dirfd = -1;
id->fd = open(zFilename, O_RDWR|O_CREAT|O_LARGEFILE|O_BINARY, 0644);
if( id->fd<0 ){
#ifdef EISDIR
if( errno==EISDIR ){
return SQLITE_CANTOPEN;
}
#endif
id->fd = open(zFilename, O_RDONLY|O_LARGEFILE|O_BINARY);
if( id->fd<0 ){
return SQLITE_CANTOPEN;
@@ -773,6 +778,13 @@ int sqliteOsOpenDirectory(
return SQLITE_OK;
}
/*
** If the following global variable points to a string which is the
** name of a directory, then that directory will be used to store
** temporary files.
*/
const char *sqlite_temp_directory = 0;
/*
** Create a temporary file name in zBuf. zBuf must be big enough to
** hold at least SQLITE_TEMPNAME_SIZE characters.
@@ -780,6 +792,7 @@ int sqliteOsOpenDirectory(
int sqliteOsTempFileName(char *zBuf){
#if OS_UNIX
static const char *azDirs[] = {
0,
"/var/tmp",
"/usr/tmp",
"/tmp",
@@ -792,7 +805,9 @@ int sqliteOsTempFileName(char *zBuf){
int i, j;
struct stat buf;
const char *zDir = ".";
azDirs[0] = sqlite_temp_directory;
for(i=0; i<sizeof(azDirs)/sizeof(azDirs[0]); i++){
if( azDirs[i]==0 ) continue;
if( stat(azDirs[i], &buf) ) continue;
if( !S_ISDIR(buf.st_mode) ) continue;
if( access(azDirs[i], 07) ) continue;
@@ -815,12 +830,18 @@ int sqliteOsTempFileName(char *zBuf){
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"0123456789";
int i, j;
const char *zDir;
char zTempPath[SQLITE_TEMPNAME_SIZE];
GetTempPath(SQLITE_TEMPNAME_SIZE-30, zTempPath);
for(i=strlen(zTempPath); i>0 && zTempPath[i-1]=='\\'; i--){}
zTempPath[i] = 0;
if( sqlite_temp_directory==0 ){
GetTempPath(SQLITE_TEMPNAME_SIZE-30, zTempPath);
for(i=strlen(zTempPath); i>0 && zTempPath[i-1]=='\\'; i--){}
zTempPath[i] = 0;
zDir = zTempPath;
}else{
zDir = sqlite_temp_directory;
}
for(;;){
sprintf(zBuf, "%s\\"TEMP_FILE_PREFIX, zTempPath);
sprintf(zBuf, "%s\\"TEMP_FILE_PREFIX, zDir);
j = strlen(zBuf);
sqliteRandomness(15, &zBuf[j]);
for(i=0; i<15; i++, j++){
@@ -836,13 +857,16 @@ int sqliteOsTempFileName(char *zBuf){
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"0123456789";
int i, j;
char *zDir;
char zTempPath[SQLITE_TEMPNAME_SIZE];
char zdirName[32];
CInfoPBRec infoRec;
Str31 dirName;
memset(&infoRec, 0, sizeof(infoRec));
memset(zTempPath, 0, SQLITE_TEMPNAME_SIZE);
if( FindFolder(kOnSystemDisk, kTemporaryFolderType, kCreateFolder,
if( sqlite_temp_directory!=0 ){
zDir = sqlite_temp_directory;
}else if( FindFolder(kOnSystemDisk, kTemporaryFolderType, kCreateFolder,
&(infoRec.dirInfo.ioVRefNum), &(infoRec.dirInfo.ioDrParID)) == noErr ){
infoRec.dirInfo.ioNamePtr = dirName;
do{
@@ -859,11 +883,14 @@ int sqliteOsTempFileName(char *zBuf){
break;
}
} while( infoRec.dirInfo.ioDrDirID != fsRtDirID );
zDir = zTempPath;
}
if( *zTempPath == 0 )
if( zDir[0]==0 ){
getcwd(zTempPath, SQLITE_TEMPNAME_SIZE-24);
zDir = zTempPath;
}
for(;;){
sprintf(zBuf, "%s"TEMP_FILE_PREFIX, zTempPath);
sprintf(zBuf, "%s"TEMP_FILE_PREFIX, zDir);
j = strlen(zBuf);
sqliteRandomness(15, &zBuf[j]);
for(i=0; i<15; i++, j++){
@@ -1089,6 +1116,10 @@ int sqliteOsSeek(OsFile *id, off_t offset){
#endif
}
#ifdef SQLITE_NOSYNC
# define fsync(X) 0
#endif
/*
** Make sure all writes to a particular file are committed to disk.
**
@@ -1747,6 +1778,7 @@ char *sqliteOsFullPathname(const char *zRelative){
sqliteSetString(&zFull, zRelative, (char*)0);
}else{
char zBuf[5000];
zBuf[0] = 0;
sqliteSetString(&zFull, getcwd(zBuf, sizeof(zBuf)), "/", zRelative,
(char*)0);
}
+2 -2
View File
@@ -18,7 +18,7 @@
** file simultaneously, or one process from reading the database while
** another is writing.
**
** @(#) $Id: pager.c,v 1.101 2004/02/25 02:20:41 drh Exp $
** @(#) $Id: pager.c,v 1.101.2.1 2005/12/19 17:37:10 drh Exp $
*/
#include "os.h" /* Must be first to enable large file support */
#include "sqliteInt.h"
@@ -1929,7 +1929,7 @@ void sqlitepager_dont_write(Pager *pPager, Pgno pgno){
pPg = pager_lookup(pPager, pgno);
pPg->alwaysRollback = 1;
if( pPg && pPg->dirty ){
if( pPg && pPg->dirty && !pPager->ckptInUse ){
if( pPager->dbSize==(int)pPg->pgno && pPager->origDbSize<pPager->dbSize ){
/* If this pages is the last page in the file and the file has grown
** during the current transaction, then do NOT mark the page as clean.
+6 -3
View File
@@ -227,6 +227,7 @@ static int vxprintf(
int nsd; /* Number of significant digits returned */
#endif
func(arg,"",0);
count = length = 0;
bufpt = 0;
for(; (c=(*fmt))!=0; ++fmt){
@@ -673,9 +674,11 @@ static void mout(void *arg, const char *zNewText, int nNewChar){
}
}
}
if( pM->zText && nNewChar>0 ){
memcpy(&pM->zText[pM->nChar], zNewText, nNewChar);
pM->nChar += nNewChar;
if( pM->zText ){
if( nNewChar>0 ){
memcpy(&pM->zText[pM->nChar], zNewText, nNewChar);
pM->nChar += nNewChar;
}
pM->zText[pM->nChar] = 0;
}
}
+50 -28
View File
@@ -12,7 +12,7 @@
** This file contains C code routines that are called by the parser
** to handle SELECT statements in SQLite.
**
** $Id: select.c,v 1.161 2004/03/13 14:00:36 drh Exp $
** $Id: select.c,v 1.161.2.4 2004/07/20 01:45:49 drh Exp $
*/
#include "sqliteInt.h"
@@ -364,6 +364,30 @@ void sqliteAddKeyType(Vdbe *v, ExprList *pEList){
sqliteVdbeChangeP3(v, -1, zType, P3_DYNAMIC);
}
/*
** Add code to implement the OFFSET and LIMIT
*/
static void codeLimiter(
Vdbe *v, /* Generate code into this VM */
Select *p, /* The SELECT statement being coded */
int iContinue, /* Jump here to skip the current record */
int iBreak, /* Jump here to end the loop */
int nPop /* Number of times to pop stack when jumping */
){
if( p->iOffset>=0 ){
int addr = sqliteVdbeCurrentAddr(v) + 2;
if( nPop>0 ) addr++;
sqliteVdbeAddOp(v, OP_MemIncr, p->iOffset, addr);
if( nPop>0 ){
sqliteVdbeAddOp(v, OP_Pop, nPop, 0);
}
sqliteVdbeAddOp(v, OP_Goto, 0, iContinue);
}
if( p->iLimit>=0 ){
sqliteVdbeAddOp(v, OP_MemIncr, p->iLimit, iBreak);
}
}
/*
** This routine generates the code for the inside of the inner loop
** of a SELECT.
@@ -388,6 +412,7 @@ static int selectInnerLoop(
){
Vdbe *v = pParse->pVdbe;
int i;
int hasDistinct; /* True if the DISTINCT keyword is present */
if( v==0 ) return 0;
assert( pEList!=0 );
@@ -395,15 +420,9 @@ static int selectInnerLoop(
/* If there was a LIMIT clause on the SELECT statement, then do the check
** to see if this row should be output.
*/
if( pOrderBy==0 ){
if( p->iOffset>=0 ){
int addr = sqliteVdbeCurrentAddr(v);
sqliteVdbeAddOp(v, OP_MemIncr, p->iOffset, addr+2);
sqliteVdbeAddOp(v, OP_Goto, 0, iContinue);
}
if( p->iLimit>=0 ){
sqliteVdbeAddOp(v, OP_MemIncr, p->iLimit, iBreak);
}
hasDistinct = distinct>=0 && pEList && pEList->nExpr>0;
if( pOrderBy==0 && !hasDistinct ){
codeLimiter(v, p, iContinue, iBreak, 0);
}
/* Pull the requested columns.
@@ -423,7 +442,7 @@ static int selectInnerLoop(
** and this row has been seen before, then do not make this row
** part of the result.
*/
if( distinct>=0 && pEList && pEList->nExpr>0 ){
if( hasDistinct ){
#if NULL_ALWAYS_DISTINCT
sqliteVdbeAddOp(v, OP_IsNull, -pEList->nExpr, sqliteVdbeCurrentAddr(v)+7);
#endif
@@ -434,6 +453,9 @@ static int selectInnerLoop(
sqliteVdbeAddOp(v, OP_Goto, 0, iContinue);
sqliteVdbeAddOp(v, OP_String, 0, 0);
sqliteVdbeAddOp(v, OP_PutStrKey, distinct, 0);
if( pOrderBy==0 ){
codeLimiter(v, p, iContinue, iBreak, nColumn);
}
}
switch( eDest ){
@@ -570,14 +592,7 @@ static void generateSortTail(
if( eDest==SRT_Sorter ) return;
sqliteVdbeAddOp(v, OP_Sort, 0, 0);
addr = sqliteVdbeAddOp(v, OP_SortNext, 0, end1);
if( p->iOffset>=0 ){
sqliteVdbeAddOp(v, OP_MemIncr, p->iOffset, addr+4);
sqliteVdbeAddOp(v, OP_Pop, 1, 0);
sqliteVdbeAddOp(v, OP_Goto, 0, addr);
}
if( p->iLimit>=0 ){
sqliteVdbeAddOp(v, OP_MemIncr, p->iLimit, end2);
}
codeLimiter(v, p, addr, end2, 1);
switch( eDest ){
case SRT_Callback: {
sqliteVdbeAddOp(v, OP_SortCallback, nColumn, 0);
@@ -810,8 +825,9 @@ Table *sqliteResultSetOfSelect(Parse *pParse, char *zTabName, Select *pSelect){
}else{
char zBuf[30];
sprintf(zBuf, "column%d", i+1);
pTab->aCol[i].zName = sqliteStrDup(zBuf);
aCol[i].zName = sqliteStrDup(zBuf);
}
sqliteDequote(aCol[i].zName);
}
pTab->iPKey = -1;
return pTab;
@@ -943,11 +959,11 @@ static int fillInColumnList(Parse *pParse, Select *p){
/* This expression is a "*" or a "TABLE.*" and needs to be
** expanded. */
int tableSeen = 0; /* Set to 1 when TABLE matches */
Token *pName; /* text of name of TABLE */
char *zTName; /* text of name of TABLE */
if( pE->op==TK_DOT && pE->pLeft ){
pName = &pE->pLeft->token;
zTName = sqliteTableNameFromToken(&pE->pLeft->token);
}else{
pName = 0;
zTName = 0;
}
for(i=0; i<pTabList->nSrc; i++){
Table *pTab = pTabList->a[i].pTab;
@@ -955,9 +971,8 @@ static int fillInColumnList(Parse *pParse, Select *p){
if( zTabName==0 || zTabName[0]==0 ){
zTabName = pTab->zName;
}
if( pName && (zTabName==0 || zTabName[0]==0 ||
sqliteStrNICmp(pName->z, zTabName, pName->n)!=0 ||
zTabName[pName->n]!=0) ){
if( zTName && (zTabName==0 || zTabName[0]==0 ||
sqliteStrICmp(zTName, zTabName)!=0) ){
continue;
}
tableSeen = 1;
@@ -1002,13 +1017,14 @@ static int fillInColumnList(Parse *pParse, Select *p){
}
}
if( !tableSeen ){
if( pName ){
sqliteErrorMsg(pParse, "no such table: %T", pName);
if( zTName ){
sqliteErrorMsg(pParse, "no such table: %s", zTName);
}else{
sqliteErrorMsg(pParse, "no tables specified");
}
rc = 1;
}
sqliteFree(zTName);
}
}
sqliteExprListDelete(pEList);
@@ -1916,6 +1932,12 @@ static int simpleMinMaxQuery(Parse *pParse, Select *p, int eDest, int iParm){
}else{
sqliteVdbeAddOp(v, OP_Integer, pIdx->iDb, 0);
sqliteVdbeOp3(v, OP_OpenRead, base+1, pIdx->tnum, pIdx->zName, P3_STATIC);
if( seekOp==OP_Rewind ){
sqliteVdbeAddOp(v, OP_String, 0, 0);
sqliteVdbeAddOp(v, OP_MakeKey, 1, 0);
sqliteVdbeAddOp(v, OP_IncrKey, 0, 0);
seekOp = OP_MoveTo;
}
sqliteVdbeAddOp(v, seekOp, base+1, 0);
sqliteVdbeAddOp(v, OP_IdxRecno, base+1, 0);
sqliteVdbeAddOp(v, OP_Close, base+1, 0);
+3 -3
View File
@@ -12,7 +12,7 @@
** This file contains code to implement the "sqlite" command line
** utility for accessing SQLite databases.
**
** $Id: shell.c,v 1.93 2004/03/17 23:42:13 drh Exp $
** $Id: shell.c,v 1.93.2.1 2005/02/16 03:53:11 drh Exp $
*/
#include <stdlib.h>
#include <string.h>
@@ -591,7 +591,7 @@ static int do_meta_command(char *zLine, struct callback_data *p){
sqlite_exec(p->db,
"SELECT name, type, sql FROM sqlite_master "
"WHERE type!='meta' AND sql NOT NULL "
"ORDER BY substr(type,2,1), name",
"ORDER BY substr(type,2,1), rowid",
dump_callback, p, &zErrMsg
);
}else{
@@ -600,7 +600,7 @@ static int do_meta_command(char *zLine, struct callback_data *p){
sqlite_exec_printf(p->db,
"SELECT name, type, sql FROM sqlite_master "
"WHERE tbl_name LIKE '%q' AND type!='meta' AND sql NOT NULL "
"ORDER BY substr(type,2,1), name",
"ORDER BY substr(type,2,1), rowid",
dump_callback, p, &zErrMsg, azArg[i]
);
}
+21 -3
View File
@@ -12,7 +12,7 @@
** This header file defines the interface that the SQLite library
** presents to client programs.
**
** @(#) $Id: sqlite.h.in,v 1.60 2004/03/14 22:12:35 drh Exp $
** @(#) $Id: sqlite.h.in,v 1.60.2.1 2004/10/06 15:52:36 drh Exp $
*/
#ifndef _SQLITE_H_
#define _SQLITE_H_
@@ -28,7 +28,11 @@ extern "C" {
/*
** The version of the SQLite library.
*/
#define SQLITE_VERSION "--VERS--"
#ifdef SQLITE_VERSION
# undef SQLITE_VERSION
#else
# define SQLITE_VERSION "--VERS--"
#endif
/*
** The version string is also compiled into the library so that a program
@@ -479,9 +483,23 @@ int sqlite_function_type(
int datatype /* The datatype for this function */
);
#define SQLITE_NUMERIC (-1)
#define SQLITE_TEXT (-2)
/* #define SQLITE_TEXT (-2) // See below */
#define SQLITE_ARGS (-3)
/*
** SQLite version 3 defines SQLITE_TEXT differently. To allow both
** version 2 and version 3 to be included, undefine them both if a
** conflict is seen. Define SQLITE2_TEXT to be the version 2 value.
*/
#ifdef SQLITE_TEXT
# undef SQLITE_TEXT
#else
# define SQLITE_TEXT (-2)
#endif
#define SQLITE2_TEXT (-2)
/*
** The user function implementations call one of the following four routines
** in order to return their results. The first parameter to each of these
+8 -4
View File
@@ -11,7 +11,7 @@
*************************************************************************
** Internal interface definitions for SQLite.
**
** @(#) $Id: sqliteInt.h,v 1.220 2004/02/25 13:47:33 drh Exp $
** @(#) $Id: sqliteInt.h,v 1.220.2.2 2005/06/06 15:07:03 drh Exp $
*/
#include "config.h"
#include "sqlite.h"
@@ -102,6 +102,9 @@
#ifndef UINT16_TYPE
# define UINT16_TYPE unsigned short int
#endif
#ifndef INT16_TYPE
# define INT16_TYPE short int
#endif
#ifndef UINT8_TYPE
# define UINT8_TYPE unsigned char
#endif
@@ -117,6 +120,7 @@
#endif
typedef UINT32_TYPE u32; /* 4-byte unsigned integer */
typedef UINT16_TYPE u16; /* 2-byte unsigned integer */
typedef INT16_TYPE i16; /* 2-byte signed integer */
typedef UINT8_TYPE u8; /* 1-byte unsigned integer */
typedef UINT8_TYPE i8; /* 1-byte signed integer */
typedef INTPTR_TYPE ptr; /* Big enough to hold a pointer */
@@ -762,8 +766,8 @@ struct IdList {
** now be identified by a database name, a dot, then the table name: ID.ID.
*/
struct SrcList {
u16 nSrc; /* Number of tables or subqueries in the FROM clause */
u16 nAlloc; /* Number of entries allocated in a[] below */
i16 nSrc; /* Number of tables or subqueries in the FROM clause */
i16 nAlloc; /* Number of entries allocated in a[] below */
struct SrcList_item {
char *zDatabase; /* Name of database holding this table */
char *zName; /* Name of the table */
@@ -1116,7 +1120,7 @@ void sqliteRealToSortable(double r, char *);
#endif
char *sqliteMPrintf(const char*, ...);
char *sqliteVMPrintf(const char*, va_list);
void sqliteSetString(char **, const char *, ...);
void sqliteSetString(char **, ...);
void sqliteSetNString(char **, ...);
void sqliteErrorMsg(Parse*, const char*, ...);
void sqliteDequote(char*);
+2 -2
View File
@@ -31,7 +31,7 @@ typedef struct TabResult {
int nAlloc;
int nRow;
int nColumn;
int nData;
long nData;
int rc;
} TabResult;
@@ -196,7 +196,7 @@ void sqlite_free_table(
int i, n;
azResult--;
if( azResult==0 ) return;
n = (int)azResult[0];
n = (int)(long)azResult[0];
for(i=1; i<n; i++){ if( azResult[i] ) free(azResult[i]); }
free(azResult);
}
+67 -12
View File
@@ -11,7 +11,7 @@
*************************************************************************
** A TCL Interface to SQLite
**
** $Id: tclsqlite.c,v 1.59 2004/02/25 22:51:06 rdc Exp $
** $Id: tclsqlite.c,v 1.59.2.1 2004/06/19 11:57:40 drh Exp $
*/
#ifndef NO_TCL /* Omit this whole file if TCL is unavailable */
@@ -1165,12 +1165,18 @@ int Et_AppInit(Tcl_Interp *interp){
return Sqlite_Init(interp);
}
#endif
/***************************************************************************
** The remaining code is only included if the TCLSH macro is defined to
** be an integer greater than 0
*/
#if defined(TCLSH) && TCLSH>0
/*
** If the macro TCLSH is defined and is one, then put in code for the
** "main" routine that will initialize Tcl.
** "main" routine that implement a interactive shell into which the user
** can type TCL commands.
*/
#if defined(TCLSH) && TCLSH==1
#if TCLSH==1
static char zMainloop[] =
"set line {}\n"
"while {![eof stdin]} {\n"
@@ -1193,27 +1199,39 @@ static char zMainloop[] =
"}\n"
"}\n"
;
#endif /* TCLSH==1 */
#define TCLSH_MAIN main /* Needed to fake out mktclapp */
int TCLSH_MAIN(int argc, char **argv){
Tcl_Interp *interp;
Tcl_FindExecutable(argv[0]);
interp = Tcl_CreateInterp();
int Libsqlite_Init( Tcl_Interp *interp) {
#ifdef TCL_THREADS
if (Thread_Init(interp) == TCL_ERROR) {
return TCL_ERROR;
}
#endif
Sqlite_Init(interp);
#ifdef SQLITE_TEST
{
extern int Sqlitetest1_Init(Tcl_Interp*);
extern int Sqlitetest2_Init(Tcl_Interp*);
extern int Sqlitetest3_Init(Tcl_Interp*);
extern int Sqlitetest4_Init(Tcl_Interp*);
extern int Md5_Init(Tcl_Interp*);
Sqlitetest1_Init(interp);
Sqlitetest2_Init(interp);
Sqlitetest3_Init(interp);
Sqlitetest4_Init(interp);
Md5_Init(interp);
Tcl_StaticPackage(interp, "sqlite", Libsqlite_Init, Libsqlite_Init);
}
#endif
return TCL_OK;
}
#define TCLSH_MAIN main /* Needed to fake out mktclapp */
#if TCLSH==1
int TCLSH_MAIN(int argc, char **argv){
#ifndef TCL_THREADS
Tcl_Interp *interp;
Tcl_FindExecutable(argv[0]);
interp = Tcl_CreateInterp();
Libsqlite_Init(interp);
if( argc>=2 ){
int i;
Tcl_SetVar(interp,"argv0",argv[1],TCL_GLOBAL_ONLY);
@@ -1226,13 +1244,50 @@ int TCLSH_MAIN(int argc, char **argv){
const char *zInfo = Tcl_GetVar(interp, "errorInfo", TCL_GLOBAL_ONLY);
if( zInfo==0 ) zInfo = interp->result;
fprintf(stderr,"%s: %s\n", *argv, zInfo);
return 1;
return TCL_ERROR;
}
}else{
Tcl_GlobalEval(interp, zMainloop);
}
return 0;
#else
Tcl_Main(argc, argv, Libsqlite_Init);
#endif /* TCL_THREADS */
return 0;
}
#endif /* TCLSH==1 */
/*
** If the macro TCLSH is set to 2, then implement a space analysis tool.
*/
#if TCLSH==2
static char zAnalysis[] =
#include "spaceanal_tcl.h"
;
int main(int argc, char **argv){
Tcl_Interp *interp;
int i;
Tcl_FindExecutable(argv[0]);
interp = Tcl_CreateInterp();
Libsqlite_Init(interp);
Tcl_SetVar(interp,"argv0",argv[0],TCL_GLOBAL_ONLY);
Tcl_SetVar(interp,"argv", "", TCL_GLOBAL_ONLY);
for(i=1; i<argc; i++){
Tcl_SetVar(interp, "argv", argv[i],
TCL_GLOBAL_ONLY | TCL_LIST_ELEMENT | TCL_APPEND_VALUE);
}
if( Tcl_GlobalEval(interp, zAnalysis)!=TCL_OK ){
const char *zInfo = Tcl_GetVar(interp, "errorInfo", TCL_GLOBAL_ONLY);
if( zInfo==0 ) zInfo = interp->result;
fprintf(stderr,"%s: %s\n", *argv, zInfo);
return TCL_ERROR;
}
return 0;
}
#endif /* TCLSH==2 */
#endif /* TCLSH */
#endif /* !defined(NO_TCL) */
#endif /* NO_TCL */
+4 -1
View File
@@ -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.36 2004/02/22 17:49:34 drh Exp $
** $Id: test1.c,v 1.36.2.1 2004/05/07 00:57:06 drh Exp $
*/
#include "sqliteInt.h"
#include "tcl.h"
@@ -975,6 +975,7 @@ int Sqlitetest1_Init(Tcl_Interp *interp){
extern int sqlite_interrupt_count;
extern int sqlite_open_file_count;
extern int sqlite_current_time;
extern int sqlite_temp_directory;
static struct {
char *zName;
Tcl_CmdProc *xProc;
@@ -1020,5 +1021,7 @@ int Sqlitetest1_Init(Tcl_Interp *interp){
(char*)&sqlite_current_time, TCL_LINK_INT);
Tcl_LinkVar(interp, "sqlite_static_bind_value",
(char*)&sqlite_static_bind_value, TCL_LINK_STRING);
Tcl_LinkVar(interp, "sqlite_temp_directory",
(char*)&sqlite_temp_directory, TCL_LINK_STRING);
return TCL_OK;
}
+17 -10
View File
@@ -12,7 +12,7 @@
** This file contains C code routines that are called by the parser
** to handle UPDATE statements.
**
** $Id: update.c,v 1.70 2004/02/22 20:05:02 drh Exp $
** $Id: update.c,v 1.70.2.1 2004/04/29 16:16:29 drh Exp $
*/
#include "sqliteInt.h"
@@ -32,7 +32,8 @@ void sqliteUpdate(
){
int i, j; /* Loop counters */
Table *pTab; /* The table to be updated */
int addr; /* VDBE instruction address of the start of the loop */
int loopStart; /* VDBE instruction address of the start of the loop */
int jumpInst; /* Addr of VDBE instruction to jump out of loop */
WhereInfo *pWInfo; /* Information about the WHERE clause */
Vdbe *v; /* The virtual database engine */
Index *pIdx; /* For looping over indices */
@@ -49,6 +50,7 @@ void sqliteUpdate(
Expr *pRecnoExpr; /* Expression defining the new record number */
int openAll; /* True if all indices need to be opened */
int isView; /* Trying to update a view */
int iStackDepth; /* Index of memory cell holding stack depth */
AuthContext sContext; /* The authorization context */
int before_triggers; /* True if there are any BEFORE triggers */
@@ -62,6 +64,7 @@ void sqliteUpdate(
if( pParse->nErr || sqlite_malloc_failed ) goto update_cleanup;
db = pParse->db;
assert( pTabList->nSrc==1 );
iStackDepth = pParse->nMem++;
/* Locate the table which we want to update.
*/
@@ -248,7 +251,11 @@ void sqliteUpdate(
/* The top of the update loop for when there are triggers.
*/
sqliteVdbeAddOp(v, OP_ListRewind, 0, 0);
addr = sqliteVdbeAddOp(v, OP_ListRead, 0, 0);
sqliteVdbeAddOp(v, OP_StackDepth, 0, 0);
sqliteVdbeAddOp(v, OP_MemStore, iStackDepth, 1);
loopStart = sqliteVdbeAddOp(v, OP_MemLoad, iStackDepth, 0);
sqliteVdbeAddOp(v, OP_StackReset, 0, 0);
jumpInst = sqliteVdbeAddOp(v, OP_ListRead, 0, 0);
sqliteVdbeAddOp(v, OP_Dup, 0, 0);
/* Open a cursor and make it point to the record that is
@@ -295,7 +302,7 @@ void sqliteUpdate(
/* Fire the BEFORE and INSTEAD OF triggers
*/
if( sqliteCodeRowTrigger(pParse, TK_UPDATE, pChanges, TK_BEFORE, pTab,
newIdx, oldIdx, onError, addr) ){
newIdx, oldIdx, onError, loopStart) ){
goto update_cleanup;
}
}
@@ -336,10 +343,10 @@ void sqliteUpdate(
*/
if( !row_triggers_exist ){
sqliteVdbeAddOp(v, OP_ListRewind, 0, 0);
addr = sqliteVdbeAddOp(v, OP_ListRead, 0, 0);
jumpInst = loopStart = sqliteVdbeAddOp(v, OP_ListRead, 0, 0);
sqliteVdbeAddOp(v, OP_Dup, 0, 0);
}
sqliteVdbeAddOp(v, OP_NotExists, iCur, addr);
sqliteVdbeAddOp(v, OP_NotExists, iCur, loopStart);
/* If the record number will change, push the record number as it
** will be after the update. (The old record number is currently
@@ -368,7 +375,7 @@ void sqliteUpdate(
/* Do constraint checks
*/
sqliteGenerateConstraintChecks(pParse, pTab, iCur, aIdxUsed, chngRecno, 1,
onError, addr);
onError, loopStart);
/* Delete the old indices for the current record.
*/
@@ -404,7 +411,7 @@ void sqliteUpdate(
pParse->nTab = iCur;
}
if( sqliteCodeRowTrigger(pParse, TK_UPDATE, pChanges, TK_AFTER, pTab,
newIdx, oldIdx, onError, addr) ){
newIdx, oldIdx, onError, loopStart) ){
goto update_cleanup;
}
}
@@ -412,8 +419,8 @@ void sqliteUpdate(
/* Repeat the above with the next record to be updated, until
** all record selected by the WHERE clause have been updated.
*/
sqliteVdbeAddOp(v, OP_Goto, 0, addr);
sqliteVdbeChangeP2(v, addr, sqliteVdbeCurrentAddr(v));
sqliteVdbeAddOp(v, OP_Goto, 0, loopStart);
sqliteVdbeChangeP2(v, jumpInst, sqliteVdbeCurrentAddr(v));
sqliteVdbeAddOp(v, OP_ListReset, 0, 0);
/* Close all tables if there were no FOR EACH ROW triggers */
+8 -9
View File
@@ -14,7 +14,7 @@
** This file contains functions for allocating memory, comparing
** strings, and stuff like that.
**
** $Id: util.c,v 1.74 2004/02/22 17:49:34 drh Exp $
** $Id: util.c,v 1.74.2.2 2005/06/06 15:07:03 drh Exp $
*/
#include "sqliteInt.h"
#include <stdarg.h>
@@ -330,15 +330,15 @@ char *sqliteStrNDup(const char *z, int n){
** point to that string. The 1st argument must either be NULL or
** point to memory obtained from sqliteMalloc().
*/
void sqliteSetString(char **pz, const char *zFirst, ...){
void sqliteSetString(char **pz, ...){
va_list ap;
int nByte;
const char *z;
char *zResult;
if( pz==0 ) return;
nByte = strlen(zFirst) + 1;
va_start(ap, zFirst);
nByte = 1;
va_start(ap, pz);
while( (z = va_arg(ap, const char*))!=0 ){
nByte += strlen(z);
}
@@ -348,9 +348,8 @@ void sqliteSetString(char **pz, const char *zFirst, ...){
if( zResult==0 ){
return;
}
strcpy(zResult, zFirst);
zResult += strlen(zResult);
va_start(ap, zFirst);
*zResult = 0;
va_start(ap, pz);
while( (z = va_arg(ap, const char*))!=0 ){
strcpy(zResult, z);
zResult += strlen(zResult);
@@ -504,14 +503,14 @@ int sqliteStrICmp(const char *zLeft, const char *zRight){
a = (unsigned char *)zLeft;
b = (unsigned char *)zRight;
while( *a!=0 && UpperToLower[*a]==UpperToLower[*b]){ a++; b++; }
return *a - *b;
return UpperToLower[*a] - UpperToLower[*b];
}
int sqliteStrNICmp(const char *zLeft, const char *zRight, int N){
register unsigned char *a, *b;
a = (unsigned char *)zLeft;
b = (unsigned char *)zRight;
while( N-- > 0 && *a!=0 && UpperToLower[*a]==UpperToLower[*b]){ a++; b++; }
return N<0 ? 0 : *a - *b;
return N<0 ? 0 : UpperToLower[*a] - UpperToLower[*b];
}
/*
+20 -35
View File
@@ -14,7 +14,7 @@
** Most of the code in this file may be omitted by defining the
** SQLITE_OMIT_VACUUM macro.
**
** $Id: vacuum.c,v 1.13 2004/03/10 18:57:32 drh Exp $
** $Id: vacuum.c,v 1.13.2.5 2005/02/14 00:25:48 drh Exp $
*/
#include "sqliteInt.h"
#include "os.h"
@@ -163,24 +163,6 @@ static int vacuumCallback1(void *pArg, int argc, char **argv, char **NotUsed){
return rc;
}
/*
** This callback is used to transfer PRAGMA settings from one database
** to the other. The value in argv[0] should be passed to a pragma
** identified by ((vacuumStruct*)pArg)->zPragma.
*/
static int vacuumCallback3(void *pArg, int argc, char **argv, char **NotUsed){
vacuumStruct *p = (vacuumStruct*)pArg;
char zBuf[200];
assert( argc==1 );
if( argv==0 ) return 0;
assert( argv[0]!=0 );
assert( strlen(p->zPragma)<100 );
assert( strlen(argv[0])<30 );
sprintf(zBuf,"PRAGMA %s=%s;", p->zPragma, argv[0]);
p->rc = execsql(p->pzErrMsg, p->dbNew, zBuf);
return p->rc;
}
/*
** Generate a random name of 20 character in length.
*/
@@ -226,19 +208,14 @@ int sqliteRunVacuum(char **pzErrMsg, sqlite *db){
char *zErrMsg; /* Error message */
vacuumStruct sVac; /* Information passed to callbacks */
/* These are all of the pragmas that need to be transferred over
** to the new database */
static const char *zPragma[] = {
"default_synchronous",
"default_cache_size",
/* "default_temp_store", */
};
if( db->flags & SQLITE_InTrans ){
sqliteSetString(pzErrMsg, "cannot VACUUM from within a transaction",
(char*)0);
return SQLITE_ERROR;
}
if( db->flags & SQLITE_Interrupt ){
return SQLITE_INTERRUPT;
}
memset(&sVac, 0, sizeof(sVac));
/* Get the full pathname of the database file and create two
@@ -280,13 +257,6 @@ int sqliteRunVacuum(char **pzErrMsg, sqlite *db){
sVac.dbOld = db;
sVac.dbNew = dbNew;
sVac.pzErrMsg = pzErrMsg;
for(i=0; rc==SQLITE_OK && i<sizeof(zPragma)/sizeof(zPragma[0]); i++){
char zBuf[200];
assert( strlen(zPragma[i])<100 );
sprintf(zBuf, "PRAGMA %s;", zPragma[i]);
sVac.zPragma = zPragma[i];
rc = sqlite_exec(db, zBuf, vacuumCallback3, &sVac, &zErrMsg);
}
if( rc==SQLITE_OK ){
rc = sqlite_exec(db,
"SELECT type, name, sql FROM sqlite_master "
@@ -296,6 +266,17 @@ int sqliteRunVacuum(char **pzErrMsg, sqlite *db){
"WHERE sql NOT NULL AND type=='view'",
vacuumCallback1, &sVac, &zErrMsg);
}
if( rc==SQLITE_OK ){
int meta1[SQLITE_N_BTREE_META];
int meta2[SQLITE_N_BTREE_META];
sqliteBtreeGetMeta(db->aDb[0].pBt, meta1);
sqliteBtreeGetMeta(dbNew->aDb[0].pBt, meta2);
meta2[1] = meta1[1]+1;
meta2[3] = meta1[3];
meta2[4] = meta1[4];
meta2[6] = meta1[6];
rc = sqliteBtreeUpdateMeta(dbNew->aDb[0].pBt, meta2);
}
if( rc==SQLITE_OK ){
rc = sqliteBtreeCopyFile(db->aDb[0].pBt, dbNew->aDb[0].pBt);
sqlite_exec(db, "COMMIT", 0, 0, 0);
@@ -308,13 +289,17 @@ end_of_vacuum:
zErrMsg, (char*)0);
}
sqlite_exec(db, "ROLLBACK", 0, 0, 0);
if( (dbNew && (dbNew->flags & SQLITE_Interrupt))
|| (db->flags & SQLITE_Interrupt) ){
rc = SQLITE_INTERRUPT;
}
if( dbNew ) sqlite_close(dbNew);
sqliteOsDelete(zTemp);
sqliteFree(zTemp);
sqliteFree(sVac.s1.z);
sqliteFree(sVac.s2.z);
if( zErrMsg ) sqlite_freemem(zErrMsg);
if( rc==SQLITE_ABORT ) sVac.rc = SQLITE_ERROR;
if( rc==SQLITE_ABORT && sVac.rc!=SQLITE_INTERRUPT ) sVac.rc = SQLITE_ERROR;
return sVac.rc;
#endif
}
+41 -7
View File
@@ -43,7 +43,7 @@
** in this file for details. If in doubt, do not deviate from existing
** commenting and indentation practices when changing or adding code.
**
** $Id: vdbe.c,v 1.268 2004/03/03 01:51:25 drh Exp $
** $Id: vdbe.c,v 1.268.2.5 2006/10/24 11:26:44 drh Exp $
*/
#include "sqliteInt.h"
#include "os.h"
@@ -62,7 +62,7 @@ int sqlite_search_count = 0;
/*
** When this global variable is positive, it gets decremented once before
** each instruction in the VDBE. When reaches zero, the SQLITE_Interrupt
** of the db.flags field is set in order to simulate and interrupt.
** of the db.flags field is set in order to simulate an interrupt.
**
** This facility is used for testing purposes only. It does not function
** in an ordinary build.
@@ -2937,9 +2937,7 @@ case OP_PutStrKey: {
if( pOp->p2 & OPFLAG_NCHANGE ) db->nChange++;
if( pOp->p2 & OPFLAG_LASTROWID ) db->lastRowid = pNos->i;
if( pOp->p2 & OPFLAG_CSCHANGE ) db->csChange++;
if( pC->nextRowidValid && pTos->i>=pC->nextRowid ){
pC->nextRowidValid = 0;
}
pC->nextRowidValid = 0;
}
if( pTos->flags & MEM_Null ){
pTos->z = 0;
@@ -4545,6 +4543,10 @@ case OP_AggGet: {
pTos->flags &= ~(MEM_Dyn|MEM_Static|MEM_Short);
pTos->flags |= MEM_Ephem;
}
if( pTos->flags & MEM_AggCtx ){
Release(pTos);
pTos->flags = MEM_Null;
}
break;
}
@@ -4695,8 +4697,9 @@ case OP_SetNext: {
break;
}
}else{
assert( pSet->prev );
pSet->prev = sqliteHashNext(pSet->prev);
if( pSet->prev ){
pSet->prev = sqliteHashNext(pSet->prev);
}
if( pSet->prev==0 ){
break;
}else{
@@ -4723,6 +4726,36 @@ case OP_Vacuum: {
break;
}
/* Opcode: StackDepth * * *
**
** Push an integer onto the stack which is the depth of the stack prior
** to that integer being pushed.
*/
case OP_StackDepth: {
int depth = (&pTos[1]) - p->aStack;
pTos++;
pTos->i = depth;
pTos->flags = MEM_Int;
break;
}
/* Opcode: StackReset * * *
**
** Pop a single integer off of the stack. Then pop the stack
** as many times as necessary to get the depth of the stack down
** to the value of the integer that was popped.
*/
case OP_StackReset: {
int depth, goal;
assert( pTos>=p->aStack );
Integerify(pTos);
goal = pTos->i;
depth = (&pTos[1]) - p->aStack;
assert( goal<depth );
popStack(&pTos, depth-goal);
break;
}
/* An other opcode is illegal...
*/
default: {
@@ -4835,6 +4868,7 @@ default: {
/* If we reach this point, it means that execution is finished.
*/
vdbe_halt:
CHECK_FOR_INTERRUPT
if( rc ){
p->rc = rc;
rc = SQLITE_ERROR;
+2 -2
View File
@@ -511,7 +511,7 @@ void sqliteVdbePrintOp(FILE *pOut, int pc, Op *pOp){
char *zP3;
char zPtr[40];
if( pOp->p3type==P3_POINTER ){
sprintf(zPtr, "ptr(%#x)", (int)pOp->p3);
sprintf(zPtr, "ptr(%#lx)", (long)pOp->p3);
zP3 = zPtr;
}else{
zP3 = pOp->p3;
@@ -565,7 +565,7 @@ int sqliteVdbeList(
sprintf(p->zArgv[2],"%d", p->aOp[i].p1);
sprintf(p->zArgv[3],"%d", p->aOp[i].p2);
if( p->aOp[i].p3type==P3_POINTER ){
sprintf(p->aStack[4].zShort, "ptr(%#x)", (int)p->aOp[i].p3);
sprintf(p->aStack[4].zShort, "ptr(%#lx)", (long)p->aOp[i].p3);
p->zArgv[4] = p->aStack[4].zShort;
}else{
p->zArgv[4] = p->aOp[i].p3;
+46 -15
View File
@@ -12,7 +12,7 @@
** This module contains C code that generates VDBE code used to process
** the WHERE clause of SQL statements.
**
** $Id: where.c,v 1.89 2004/02/22 20:05:02 drh Exp $
** $Id: where.c,v 1.89.2.2 2004/07/19 19:30:50 drh Exp $
*/
#include "sqliteInt.h"
@@ -46,7 +46,7 @@ struct ExprInfo {
typedef struct ExprMaskSet ExprMaskSet;
struct ExprMaskSet {
int n; /* Number of assigned cursor values */
int ix[32]; /* Cursor assigned to each bit */
int ix[31]; /* Cursor assigned to each bit */
};
/*
@@ -123,7 +123,9 @@ static int exprTableUsage(ExprMaskSet *pMaskSet, Expr *p){
unsigned int mask = 0;
if( p==0 ) return 0;
if( p->op==TK_COLUMN ){
return getMask(pMaskSet, p->iTable);
mask = getMask(pMaskSet, p->iTable);
if( mask==0 ) mask = -1;
return mask;
}
if( p->pRight ){
mask = exprTableUsage(pMaskSet, p->pRight);
@@ -269,6 +271,35 @@ static Index *findSortingIndex(
return pMatch;
}
/*
** Disable a term in the WHERE clause. Except, do not disable the term
** if it controls a LEFT OUTER JOIN and it did not originate in the ON
** or USING clause of that join.
**
** Consider the term t2.z='ok' in the following queries:
**
** (1) SELECT * FROM t1 LEFT JOIN t2 ON t1.a=t2.x WHERE t2.z='ok'
** (2) SELECT * FROM t1 LEFT JOIN t2 ON t1.a=t2.x AND t2.z='ok'
** (3) SELECT * FROM t1, t2 WHERE t1.a=t2.x AND t2.z='ok'
**
** The t2.z='ok' is disabled in the in (2) because it did not originate
** in the ON clause. The term is disabled in (3) because it is not part
** of a LEFT OUTER JOIN. In (1), the term is not disabled.
**
** Disabling a term causes that term to not be tested in the inner loop
** of the join. Disabling is an optimization. We would get the correct
** results if nothing were ever disabled, but joins might run a little
** slower. The trick is to disable as much as we can without disabling
** too much. If we disabled in (1), we'd get the wrong answer.
** See ticket #813.
*/
static void disableTerm(WhereLevel *pLevel, Expr **ppExpr){
Expr *pExpr = *ppExpr;
if( pLevel->iLeftJoin==0 || ExprHasProperty(pExpr, EP_FromJoin) ){
*ppExpr = 0;
}
}
/*
** Generate the beginning of the loop used for WHERE clause processing.
** The return value is a pointer to an (opaque) structure that contains
@@ -736,7 +767,7 @@ WhereInfo *sqliteWhereBegin(
}else{
sqliteExprCode(pParse, aExpr[k].p->pLeft);
}
aExpr[k].p = 0;
disableTerm(pLevel, &aExpr[k].p);
cont = pLevel->cont = sqliteVdbeMakeLabel(v);
sqliteVdbeAddOp(v, OP_MustBeInt, 1, brk);
haveKey = 0;
@@ -760,7 +791,7 @@ WhereInfo *sqliteWhereBegin(
){
if( pX->op==TK_EQ ){
sqliteExprCode(pParse, pX->pRight);
aExpr[k].p = 0;
disableTerm(pLevel, &aExpr[k].p);
break;
}
if( pX->op==TK_IN && nColumn==1 ){
@@ -777,7 +808,7 @@ WhereInfo *sqliteWhereBegin(
pLevel->inOp = OP_Next;
pLevel->inP1 = pX->iTable;
}
aExpr[k].p = 0;
disableTerm(pLevel, &aExpr[k].p);
break;
}
}
@@ -787,7 +818,7 @@ WhereInfo *sqliteWhereBegin(
&& aExpr[k].p->pRight->iColumn==pIdx->aiColumn[j]
){
sqliteExprCode(pParse, aExpr[k].p->pLeft);
aExpr[k].p = 0;
disableTerm(pLevel, &aExpr[k].p);
break;
}
}
@@ -854,7 +885,7 @@ WhereInfo *sqliteWhereBegin(
sqliteVdbeAddOp(v, OP_ForceInt,
aExpr[k].p->op==TK_LT || aExpr[k].p->op==TK_GT, brk);
sqliteVdbeAddOp(v, OP_MoveTo, iCur, brk);
aExpr[k].p = 0;
disableTerm(pLevel, &aExpr[k].p);
}else{
sqliteVdbeAddOp(v, OP_Rewind, iCur, brk);
}
@@ -876,7 +907,7 @@ WhereInfo *sqliteWhereBegin(
}else{
testOp = OP_Gt;
}
aExpr[k].p = 0;
disableTerm(pLevel, &aExpr[k].p);
}
start = sqliteVdbeCurrentAddr(v);
pLevel->op = OP_Next;
@@ -931,7 +962,7 @@ WhereInfo *sqliteWhereBegin(
&& aExpr[k].p->pLeft->iColumn==pIdx->aiColumn[j]
){
sqliteExprCode(pParse, aExpr[k].p->pRight);
aExpr[k].p = 0;
disableTerm(pLevel, &aExpr[k].p);
break;
}
if( aExpr[k].idxRight==iCur
@@ -940,7 +971,7 @@ WhereInfo *sqliteWhereBegin(
&& aExpr[k].p->pRight->iColumn==pIdx->aiColumn[j]
){
sqliteExprCode(pParse, aExpr[k].p->pLeft);
aExpr[k].p = 0;
disableTerm(pLevel, &aExpr[k].p);
break;
}
}
@@ -977,7 +1008,7 @@ WhereInfo *sqliteWhereBegin(
){
sqliteExprCode(pParse, pExpr->pRight);
leFlag = pExpr->op==TK_LE;
aExpr[k].p = 0;
disableTerm(pLevel, &aExpr[k].p);
break;
}
if( aExpr[k].idxRight==iCur
@@ -987,7 +1018,7 @@ WhereInfo *sqliteWhereBegin(
){
sqliteExprCode(pParse, pExpr->pLeft);
leFlag = pExpr->op==TK_GE;
aExpr[k].p = 0;
disableTerm(pLevel, &aExpr[k].p);
break;
}
}
@@ -1036,7 +1067,7 @@ WhereInfo *sqliteWhereBegin(
){
sqliteExprCode(pParse, pExpr->pRight);
geFlag = pExpr->op==TK_GE;
aExpr[k].p = 0;
disableTerm(pLevel, &aExpr[k].p);
break;
}
if( aExpr[k].idxRight==iCur
@@ -1046,7 +1077,7 @@ WhereInfo *sqliteWhereBegin(
){
sqliteExprCode(pParse, pExpr->pLeft);
geFlag = pExpr->op==TK_LE;
aExpr[k].p = 0;
disableTerm(pLevel, &aExpr[k].p);
break;
}
}
+7 -1
View File
@@ -12,7 +12,7 @@
# focus of this script is testing the ATTACH and DETACH commands
# and related functionality.
#
# $Id: auth.test,v 1.12 2003/12/07 00:24:35 drh Exp $
# $Id: auth.test,v 1.12.2.1 2004/09/09 13:54:31 drh Exp $
#
set testdir [file dirname $argv0]
@@ -36,6 +36,12 @@ do_test auth-1.1.1 {
do_test auth-1.1.2 {
db errorcode
} {23}
do_test auth-1.1.3 {
# Ticket #896.
catchsql {
SELECT x;
}
} {1 {no such column: x}}
do_test auth-1.2 {
execsql {SELECT name FROM sqlite_master}
} {}
+15 -2
View File
@@ -11,7 +11,7 @@
# This file implements regression tests for SQLite library. The
# focus of this file is testing date and time functions.
#
# $Id: date.test,v 1.7 2004/02/29 01:08:18 drh Exp $
# $Id: date.test,v 1.7.2.1 2004/07/18 22:25:16 drh Exp $
set testdir [file dirname $argv0]
source $testdir/tester.tcl
@@ -95,7 +95,20 @@ datetest 3.7 {strftime('%M','2003-10-31 12:34:56.432')} 34
datetest 3.8 {strftime('%s','2003-10-31 12:34:56.432')} 1067603696
datetest 3.9 {strftime('%S','2003-10-31 12:34:56.432')} 56
datetest 3.10 {strftime('%w','2003-10-31 12:34:56.432')} 5
datetest 3.11 {strftime('%W','2003-10-31 12:34:56.432')} 44
datetest 3.11.1 {strftime('%W','2003-10-31 12:34:56.432')} 43
datetest 3.11.2 {strftime('%W','2004-01-01')} 00
datetest 3.11.3 {strftime('%W','2004-01-02')} 00
datetest 3.11.4 {strftime('%W','2004-01-03')} 00
datetest 3.11.5 {strftime('%W','2004-01-04')} 00
datetest 3.11.6 {strftime('%W','2004-01-05')} 01
datetest 3.11.7 {strftime('%W','2004-01-06')} 01
datetest 3.11.8 {strftime('%W','2004-01-07')} 01
datetest 3.11.9 {strftime('%W','2004-01-08')} 01
datetest 3.11.10 {strftime('%W','2004-01-09')} 01
datetest 3.11.11 {strftime('%W','2004-07-18')} 28
datetest 3.11.12 {strftime('%W','2004-12-31')} 52
datetest 3.11.13 {strftime('%W','2007-12-31')} 53
datetest 3.11.14 {strftime('%W','2007-01-01')} 01
datetest 3.12 {strftime('%Y','2003-10-31 12:34:56.432')} 2003
datetest 3.13 {strftime('%%','2003-10-31 12:34:56.432')} %
datetest 3.14 {strftime('%_','2003-10-31 12:34:56.432')} NULL
+6 -1
View File
@@ -11,7 +11,7 @@
# This file implements regression tests for SQLite library. The
# focus of this file is testing built-in functions.
#
# $Id: func.test,v 1.16 2002/11/04 19:32:26 drh Exp $
# $Id: func.test,v 1.16.2.2 2004/07/18 21:14:05 drh Exp $
set testdir [file dirname $argv0]
source $testdir/tester.tcl
@@ -264,6 +264,11 @@ do_test func-8.3 {
SELECT min('z+'||a||'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP') FROM t3;
}
} {z+1abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP}
do_test func-8.4 {
execsql {
SELECT max('z+'||a||'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP') FROM t3;
}
} {z+67890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP}
# How do you test the random() function in a meaningful, deterministic way?
#
+16 -1
View File
@@ -11,7 +11,7 @@
# This file implements regression tests for SQLite library. The
# focus of this file is testing the CREATE INDEX statement.
#
# $Id: index.test,v 1.24 2003/09/27 00:41:28 drh Exp $
# $Id: index.test,v 1.24.2.1 2004/07/20 00:50:30 drh Exp $
set testdir [file dirname $argv0]
source $testdir/tester.tcl
@@ -515,4 +515,19 @@ do_test index-15.2 {
} {8 5 2 1 3 6 11 9 10 4 7}
integrity_check index-15.1
# Drop index with a quoted name. Ticket #695.
#
do_test index-16.1 {
execsql {
CREATE INDEX "t6i2" ON t6(c);
DROP INDEX "t6i2";
}
} {}
do_test index-16.2 {
execsql {
DROP INDEX "t6i1";
}
} {}
finish_test
+9 -7
View File
@@ -11,7 +11,7 @@
# This file implements regression tests for SQLite library. The
# focus of this script is the sqlite_interrupt() API.
#
# $Id: interrupt.test,v 1.4 2004/02/18 16:57:23 drh Exp $
# $Id: interrupt.test,v 1.4.2.1 2004/05/10 20:27:42 drh Exp $
set testdir [file dirname $argv0]
@@ -37,12 +37,13 @@ proc cksum {{db db}} {
# and checks to make sure SQLITE_INTERRUPT is returned. Eventually,
# the routine completes successfully.
#
proc interrupt_test {testid sql result {initcnt 0}} {
proc interrupt_test {testid sql result {initcnt 0} {maxcnt 1000000}} {
set orig_sum [cksum]
set i $initcnt
while 1 {
global sqlite_interrupt_count
while {$i<$maxcnt} {
incr i
set ::sqlite_interrupt_count $i
set sqlite_interrupt_count $i
do_test $testid.$i.1 [format {
set ::r [catchsql %s]
set ::code [db errorcode]
@@ -52,14 +53,14 @@ proc interrupt_test {testid sql result {initcnt 0}} {
do_test $testid.$i.2 {
cksum
} $orig_sum
} else {
} elseif {$sqlite_interrupt_count>0} {
do_test $testid.$i.99 {
set ::r
} [list 0 $result]
break
}
}
set ::sqlite_interrupt_count 0
set sqlite_interrupt_count 0
}
do_test interrupt-1.1 {
@@ -68,7 +69,7 @@ do_test interrupt-1.1 {
SELECT name FROM sqlite_master;
}
} {t1}
interrupt_test interrupt-1.2 {DROP TABLE t1} {}
interrupt_test interrupt-1.2 {DROP TABLE t1} {} 1 14
do_test interrupt-1.3 {
execsql {
SELECT name FROM sqlite_master;
@@ -162,4 +163,5 @@ for {set i 1} {$i<$max_count-5} {incr i 1} {
} {1 interrupted}
}
finish_test
+34
View File
@@ -0,0 +1,34 @@
# 2002 May 24
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# May you do good and not evil.
# May you find forgiveness for yourself and forgive others.
# May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.
#
# This file implements tests for joins, including outer joins, where
# there are a large number of tables involved in the join.
#
# $Id: join3_28.test,v 1.1.2.1 2004/07/22 16:08:39 drh Exp $
set testdir [file dirname $argv0]
source $testdir/tester.tcl
catch {unset result}
set result {}
for {set N 1} {$N<=40} {incr N} {
lappend result $N
do_test join3-1.$N {
execsql "CREATE TABLE t${N}(x);"
execsql "INSERT INTO t$N VALUES($N)"
set sql "SELECT * FROM t1"
for {set i 2} {$i<=$N} {incr i} {append sql ", t$i"}
execsql $sql
} $result
}
finish_test
+77
View File
@@ -0,0 +1,77 @@
# 2002 May 24
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# May you do good and not evil.
# May you find forgiveness for yourself and forgive others.
# May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.
#
# This file implements tests for left outer joins containing WHERE
# clauses that restrict the scope of the left term of the join.
#
# $Id: join4_28.test,v 1.1.2.1 2004/07/22 16:08:39 drh Exp $
set testdir [file dirname $argv0]
source $testdir/tester.tcl
do_test join4-1.1 {
execsql {
create temp table t1(a integer, b varchar(10));
insert into t1 values(1,'one');
insert into t1 values(2,'two');
insert into t1 values(3,'three');
insert into t1 values(4,'four');
create temp table t2(x integer, y varchar(10), z varchar(10));
insert into t2 values(2,'niban','ok');
insert into t2 values(4,'yonban','err');
}
execsql {
select * from t1 left outer join t2 on t1.a=t2.x where t2.z='ok'
}
} {2 two 2 niban ok}
do_test join4-1.2 {
execsql {
select * from t1 left outer join t2 on t1.a=t2.x and t2.z='ok'
}
} {1 one {} {} {} 2 two 2 niban ok 3 three {} {} {} 4 four {} {} {}}
do_test join4-1.3 {
execsql {
create index i2 on t2(z);
}
execsql {
select * from t1 left outer join t2 on t1.a=t2.x where t2.z='ok'
}
} {2 two 2 niban ok}
do_test join4-1.4 {
execsql {
select * from t1 left outer join t2 on t1.a=t2.x and t2.z='ok'
}
} {1 one {} {} {} 2 two 2 niban ok 3 three {} {} {} 4 four {} {} {}}
do_test join4-1.5 {
execsql {
select * from t1 left outer join t2 on t1.a=t2.x where t2.z>='ok'
}
} {2 two 2 niban ok}
do_test join4-1.4 {
execsql {
select * from t1 left outer join t2 on t1.a=t2.x and t2.z>='ok'
}
} {1 one {} {} {} 2 two 2 niban ok 3 three {} {} {} 4 four {} {} {}}
do_test join4-1.6 {
execsql {
select * from t1 left outer join t2 on t1.a=t2.x where t2.z IN ('ok')
}
} {2 two 2 niban ok}
do_test join4-1.7 {
execsql {
select * from t1 left outer join t2 on t1.a=t2.x and t2.z IN ('ok')
}
} {1 one {} {} {} 2 two 2 niban ok 3 three {} {} {} 4 four {} {} {}}
finish_test
+21 -1
View File
@@ -12,7 +12,7 @@
# focus of this file is testing the LIMIT ... OFFSET ... clause
# of SELECT statements.
#
# $Id: limit.test,v 1.11 2004/03/08 13:26:18 drh Exp $
# $Id: limit.test,v 1.11.2.1 2004/07/19 23:33:04 drh Exp $
set testdir [file dirname $argv0]
source $testdir/tester.tcl
@@ -294,4 +294,24 @@ do_test limit-7.12 {
}
} {30}
# Tests for limit in conjunction with distinct. The distinct should
# occur before both the limit and the offset. Ticket #749.
#
do_test limit-8.1 {
execsql {
SELECT DISTINCT round(x/100) FROM t3 LIMIT 5;
}
} {0 1 2 3 4}
do_test limit-8.2 {
execsql {
SELECT DISTINCT round(x/100) FROM t3 LIMIT 5 OFFSET 5;
}
} {5 6 7 8 9}
do_test limit-8.3 {
execsql {
SELECT DISTINCT round(x/100) FROM t3 LIMIT 5 OFFSET 25;
}
} {25 26 27 28 29}
finish_test
+82 -2
View File
@@ -13,7 +13,7 @@
# aggregate min() and max() functions and which are handled as
# as a special case.
#
# $Id: minmax.test,v 1.9 2004/03/13 14:00:37 drh Exp $
# $Id: minmax.test,v 1.9.2.2 2004/07/18 21:14:05 drh Exp $
set testdir [file dirname $argv0]
source $testdir/tester.tcl
@@ -68,7 +68,7 @@ do_test minmax-1.5 {
} {1}
do_test minmax-1.6 {
set sqlite_search_count
} {1}
} {2}
do_test minmax-1.7 {
set sqlite_search_count 0
execsql {SELECT max(x) FROM t1}
@@ -276,4 +276,84 @@ do_test minmax-9.2 {
}
} {{}}
# If there is a NULL in an aggregate max() or min(), ignore it. An
# aggregate min() or max() will only return NULL if all values are NULL.
#
do_test minmax-10.1 {
execsql {
CREATE TABLE t6(x);
INSERT INTO t6 VALUES(1);
INSERT INTO t6 VALUES(2);
INSERT INTO t6 VALUES(NULL);
SELECT coalesce(min(x),-1) FROM t6;
}
} {1}
do_test minmax-10.2 {
execsql {
SELECT max(x) FROM t6;
}
} {2}
do_test minmax-10.3 {
execsql {
CREATE INDEX i6 ON t6(x);
SELECT coalesce(min(x),-1) FROM t6;
}
} {1}
do_test minmax-10.4 {
execsql {
SELECT max(x) FROM t6;
}
} {2}
do_test minmax-10.5 {
execsql {
DELETE FROM t6 WHERE x NOT NULL;
SELECT count(*) FROM t6;
}
} 1
do_test minmax-10.6 {
execsql {
SELECT count(x) FROM t6;
}
} 0
do_test minmax-10.7 {
execsql {
SELECT (SELECT min(x) FROM t6), (SELECT max(x) FROM t6);
}
} {{} {}}
do_test minmax-10.8 {
execsql {
SELECT min(x), max(x) FROM t6;
}
} {{} {}}
do_test minmax-10.9 {
execsql {
INSERT INTO t6 SELECT * FROM t6;
INSERT INTO t6 SELECT * FROM t6;
INSERT INTO t6 SELECT * FROM t6;
INSERT INTO t6 SELECT * FROM t6;
INSERT INTO t6 SELECT * FROM t6;
INSERT INTO t6 SELECT * FROM t6;
INSERT INTO t6 SELECT * FROM t6;
INSERT INTO t6 SELECT * FROM t6;
INSERT INTO t6 SELECT * FROM t6;
INSERT INTO t6 SELECT * FROM t6;
SELECT count(*) FROM t6;
}
} 1024
do_test minmax-10.10 {
execsql {
SELECT count(x) FROM t6;
}
} 0
do_test minmax-10.11 {
execsql {
SELECT (SELECT min(x) FROM t6), (SELECT max(x) FROM t6);
}
} {{} {}}
do_test minmax-10.12 {
execsql {
SELECT min(x), max(x) FROM t6;
}
} {{} {}}
finish_test
+1
View File
@@ -94,6 +94,7 @@ do_test null-2.8 {
} {1 0 0 1 0 0 0}
# Check to see that NULL values are ignored in aggregate functions.
# (except for min().)
#
do_test null-3.1 {
execsql {
+7 -2
View File
@@ -11,7 +11,7 @@
# This file implements regression tests for SQLite library. The
# focus of this file is testing the SELECT statement.
#
# $Id: select1.test,v 1.30 2002/06/02 16:09:03 drh Exp $
# $Id: select1.test,v 1.30.2.3 2004/07/20 01:45:49 drh Exp $
set testdir [file dirname $argv0]
source $testdir/tester.tcl
@@ -612,11 +612,16 @@ do_test select1-11.3 {
SELECT * FROM t3 AS x, t4 AS y;
}
} {x.a 1 x.b 2 y.a 3 y.b 4}
do_test select1-11.4 {
do_test select1-11.4.1 {
execsql {
SELECT t3.*, t4.b FROM t3, t4;
}
} {1 2 4}
do_test select1-11.4.2 {
execsql {
SELECT "t3".*, t4.b FROM t3, t4;
}
} {1 2 4}
do_test select1-11.5 {
execsql2 {
SELECT t3.*, t4.b FROM t3, t4;
+3 -1
View File
@@ -15,7 +15,7 @@
# interface is pretty well tested. This file contains some addition
# tests for fringe issues that the main test suite does not cover.
#
# $Id: tclsqlite.test,v 1.20 2004/02/25 22:51:06 rdc Exp $
# $Id: tclsqlite.test,v 1.20.2.2 2006/10/24 11:26:44 drh Exp $
set testdir [file dirname $argv0]
source $testdir/tester.tcl
@@ -72,6 +72,7 @@ do_test tcl-1.6 {
} {1 {syntax error in expression "x*"}}
if {[sqlite -encoding]=="UTF-8" && [sqlite -tcl-uses-utf]} {
catch {unset ::result}
do_test tcl-2.1 {
execsql "CREATE TABLE t\u0123x(a int, b\u1235 float)"
execsql "PRAGMA table_info(t\u0123x)"
@@ -88,6 +89,7 @@ if {[sqlite -encoding]=="iso8859" && [sqlite -tcl-uses-utf]} {
execsql "CREATE TABLE t\251x(a int, b\306 float)"
execsql "PRAGMA table_info(t\251x)"
} "0 a int 0 {} 0 1 b\306 float 0 {} 0"
unset -nocomplain result
do_test tcl-2.2 {
execsql "INSERT INTO t\251x VALUES(1,2.3)"
db eval "SELECT * FROM t\251x" result break
+111
View File
@@ -412,5 +412,116 @@ do_test trigger-9.2 {
}
} {1 2 1 3 99 99 1 3}
execsql {
DROP TABLE t2;
DROP TABLE t3;
DROP TABLE t4;
}
# Skip the remaining tests if we have a codec. The ATTACH command
# will not work right on these tests when there is a codec.
#
if {[sqlite -has-codec]} {
finish_test
return
}
# Ticket #764. At one stage TEMP triggers would fail to re-install when the
# schema was reloaded. The following tests ensure that TEMP triggers are
# correctly re-installed.
#
# Also verify that references within trigger programs are resolved at
# statement compile time, not trigger installation time. This means, for
# example, that you can drop and re-create tables referenced by triggers.
do_test trigger-10.0 {
file delete -force test2.db
file delete -force test2.db-journal
sqlite db2 test2.db
execsql {CREATE TABLE t3(a, b, c);} db2
db2 close
execsql {
ATTACH 'test2.db' AS aux;
}
} {}
do_test trigger-10.1 {
execsql {
CREATE TABLE t1(a, b, c);
CREATE temp TABLE t2(a, b, c);
CREATE TABLE insert_log(db, a, b, c);
}
} {}
do_test trigger-10.2 {
execsql {
CREATE TEMP TRIGGER trig1 AFTER INSERT ON t1 BEGIN
INSERT INTO insert_log VALUES('main', new.a, new.b, new.c);
END;
CREATE TEMP TRIGGER trig2 AFTER INSERT ON t2 BEGIN
INSERT INTO insert_log VALUES('temp', new.a, new.b, new.c);
END;
CREATE TEMP TRIGGER trig3 AFTER INSERT ON t3 BEGIN
INSERT INTO insert_log VALUES('aux', new.a, new.b, new.c);
END;
}
} {}
do_test trigger-10.3 {
execsql {
INSERT INTO t1 VALUES(1, 2, 3);
INSERT INTO t2 VALUES(4, 5, 6);
INSERT INTO t3 VALUES(7, 8, 9);
}
} {}
do_test trigger-10.4 {
execsql {
SELECT * FROM insert_log;
}
} {main 1 2 3 temp 4 5 6 aux 7 8 9}
do_test trigger-10.5 {
execsql {
BEGIN;
INSERT INTO t1 VALUES(1, 2, 3);
INSERT INTO t2 VALUES(4, 5, 6);
INSERT INTO t3 VALUES(7, 8, 9);
ROLLBACK;
}
} {}
do_test trigger-10.6 {
execsql {
SELECT * FROM insert_log;
}
} {main 1 2 3 temp 4 5 6 aux 7 8 9}
do_test trigger-10.7 {
execsql {
DELETE FROM insert_log;
INSERT INTO t1 VALUES(11, 12, 13);
INSERT INTO t2 VALUES(14, 15, 16);
INSERT INTO t3 VALUES(17, 18, 19);
}
} {}
do_test trigger-10.8 {
execsql {
SELECT * FROM insert_log;
}
} {main 11 12 13 temp 14 15 16 aux 17 18 19}
do_test trigger-10.8 {
# Drop and re-create the insert_log table in a different database. Note
# that we can change the column names because the trigger programs don't
# use them explicitly.
execsql {
DROP TABLE insert_log;
CREATE temp TABLE insert_log(db, d, e, f);
}
} {}
do_test trigger-10.10 {
execsql {
INSERT INTO t1 VALUES(21, 22, 23);
INSERT INTO t2 VALUES(24, 25, 26);
INSERT INTO t3 VALUES(27, 28, 29);
}
} {}
do_test trigger-10.11 {
execsql {
SELECT * FROM insert_log;
}
} {main 21 22 23 temp 24 25 26 aux 27 28 29}
finish_test
+19 -1
View File
@@ -11,7 +11,7 @@
# This file implements regression tests for SQLite library. The
# focus of this file is testing VIEW statements.
#
# $Id: view.test,v 1.16 2003/05/31 16:21:13 drh Exp $
# $Id: view.test,v 1.16.2.1 2004/07/20 00:20:47 drh Exp $
set testdir [file dirname $argv0]
source $testdir/tester.tcl
@@ -385,5 +385,23 @@ do_test view-9.6 {
}
} {3 4 4 2 5 1}
# Tables with columns having peculiar quoted names used in views
# Ticket #756.
#
do_test view-10.1 {
execsql {
CREATE TABLE t3("9" integer, [4] text);
INSERT INTO t3 VALUES(1,2);
CREATE VIEW v_t3_a AS SELECT a.[9] FROM t3 AS a;
CREATE VIEW v_t3_b AS SELECT "4" FROM t3;
SELECT * FROM v_t3_a;
}
} {1}
do_test view-10.2 {
execsql {
SELECT * FROM v_t3_b;
}
} {2}
finish_test
+9 -14
View File
@@ -12,13 +12,6 @@
#include <ctype.h>
#include <stdlib.h>
extern void qsort();
extern double strtod();
extern long strtol();
extern void free();
extern int access();
extern int atoi();
#ifndef __WIN32__
# if defined(_WIN32) || defined(WIN32)
# define __WIN32__
@@ -40,7 +33,6 @@ extern void *malloc();
/******** From the file "action.h" *************************************/
struct action *Action_new();
struct action *Action_sort();
void Action_add();
/********* From the file "assert.h" ************************************/
void myassert();
@@ -374,7 +366,7 @@ struct action *ap2;
struct action *Action_sort(ap)
struct action *ap;
{
ap = (struct action *)msort(ap,&ap->next,actioncmp);
ap = (struct action *)msort((char *)ap,(char **)&ap->next,actioncmp);
return ap;
}
@@ -811,7 +803,7 @@ struct state *stp; /* The state from which successors are computed */
/* The state "newstp" is reached from the state "stp" by a shift action
** on the symbol "sp" */
Action_add(&stp->ap,SHIFT,sp,newstp);
Action_add(&stp->ap,SHIFT,sp,(char *)newstp);
}
}
@@ -912,7 +904,7 @@ struct lemon *lemp;
if( SetFind(cfp->fws,j) ){
/* Add a reduce action to the state "stp" which will reduce by the
** rule "cfp->rp" if the lookahead symbol is "lemp->symbols[j]" */
Action_add(&stp->ap,REDUCE,lemp->symbols[j],cfp->rp);
Action_add(&stp->ap,REDUCE,lemp->symbols[j],(char *)cfp->rp);
}
}
}
@@ -1188,14 +1180,14 @@ struct lemon *lemp;
/* Sort the configuration list */
void Configlist_sort(){
current = (struct config *)msort(current,&(current->next),Configcmp);
current = (struct config *)msort((char *)current,(char **)&(current->next),Configcmp);
currentend = 0;
return;
}
/* Sort the basis configuration list */
void Configlist_sortbasis(){
basis = (struct config *)msort(current,&(current->bp),Configcmp);
basis = (struct config *)msort((char *)current,(char **)&(current->bp),Configcmp);
basisend = 0;
return;
}
@@ -1447,6 +1439,7 @@ char **argv;
fprintf(stderr,"%d parsing conflicts.\n",lem.nconflict);
}
exit(lem.errorcnt + lem.nconflict);
return (lem.errorcnt + lem.nconflict);
}
/******************** From the file "msort.c" *******************************/
/*
@@ -2876,7 +2869,7 @@ struct symbol *sp;
struct lemon *lemp;
int *lineno;
{
char *cp;
char *cp = 0;
int linecnt = 0;
if( sp->type==TERMINAL ){
@@ -2890,6 +2883,8 @@ int *lineno;
cp = lemp->vardest;
if( cp==0 ) return;
fprintf(out,"#line %d \"%s\"\n{",lemp->vardestln,lemp->filename);
}else{
assert( 0 ); /* Cannot happen */
}
for(; *cp; cp++){
if( *cp=='$' && cp[1]=='$' ){
+436
View File
@@ -0,0 +1,436 @@
# Run this TCL script using "testfixture" in order get a report that shows
# how much disk space is used by a particular data to actually store data
# versus how much space is unused.
#
# Get the name of the database to analyze
#
if {[llength $argv]!=1} {
puts stderr "Usage: $argv0 database-name"
exit 1
}
set file_to_analyze [lindex $argv 0]
if {![file exists $file_to_analyze]} {
puts stderr "No such file: $file_to_analyze"
exit 1
}
if {![file readable $file_to_analyze]} {
puts stderr "File is not readable: $file_to_analyze"
exit 1
}
if {[file size $file_to_analyze]<2048} {
puts stderr "Empty or malformed database: $file_to_analyze"
exit 1
}
# Open the database
#
sqlite db [lindex $argv 0]
set DB [btree_open [lindex $argv 0]]
# In-memory database for collecting statistics
#
sqlite mem :memory:
set tabledef\
{CREATE TABLE space_used(
name clob, -- Name of a table or index in the database file
tblname clob, -- Name of associated table
is_index boolean, -- TRUE if it is an index, false for a table
nentry int, -- Number of entries in the BTree
payload int, -- Total amount of data stored in this table or index
mx_payload int, -- Maximum payload size
n_ovfl int, -- Number of entries that overflow
pri_pages int, -- Number of primary pages used
ovfl_pages int, -- Number of overflow pages used
pri_unused int, -- Number of unused bytes on primary pages
ovfl_unused int -- Number of unused bytes on overflow pages
);}
mem eval $tabledef
# This query will be used to find the root page number for every index and
# table in the database.
#
set sql {
SELECT name, tbl_name, type, rootpage
FROM sqlite_master WHERE type IN ('table','index')
UNION ALL
SELECT 'sqlite_master', 'sqlite_master', 'table', 2
ORDER BY 1
}
# Analyze every table in the database, one at a time.
#
foreach {name tblname type rootpage} [db eval $sql] {
puts stderr "Analyzing $name..."
set cursor [btree_cursor $DB $rootpage 0]
set go [btree_first $cursor]
set size 0
catch {unset pg_used}
set unused_ovfl 0
set n_overflow 0
set cnt_ovfl 0
set n_entry 0
set mx_size 0
set pg_used($rootpage) 1016
while {$go==0} {
incr n_entry
set payload [btree_payload_size $cursor]
incr size $payload
set stat [btree_cursor_dump $cursor]
set pgno [lindex $stat 0]
set freebytes [lindex $stat 4]
set pg_used($pgno) $freebytes
if {$payload>236} {
# if {[lindex $stat 8]==0} {error "overflow is empty with $payload"}
set n [expr {($payload-236+1019)/1020}]
incr n_overflow $n
incr cnt_ovfl
incr unused_ovfl [expr {$n*1020+236-$payload}]
} else {
# if {[lindex $stat 8]!=0} {error "overflow not empty with $payload"}
}
if {$payload>$mx_size} {set mx_size $payload}
set go [btree_next $cursor]
}
btree_close_cursor $cursor
set n_primary [llength [array names pg_used]]
set unused_primary 0
foreach x [array names pg_used] {incr unused_primary $pg_used($x)}
regsub -all ' $name '' name
set sql "INSERT INTO space_used VALUES('$name'"
regsub -all ' $tblname '' tblname
append sql ",'$tblname',[expr {$type=="index"}],$n_entry"
append sql ",$size,$mx_size,$cnt_ovfl,"
append sql "$n_primary,$n_overflow,$unused_primary,$unused_ovfl);"
mem eval $sql
}
# Generate a single line of output in the statistics section of the
# report.
#
proc statline {title value {extra {}}} {
set len [string length $title]
set dots [string range {......................................} $len end]
set len [string length $value]
set sp2 [string range { } $len end]
if {$extra ne ""} {
set extra " $extra"
}
puts "$title$dots $value$sp2$extra"
}
# Generate a formatted percentage value for $num/$denom
#
proc percent {num denom} {
if {$denom==0.0} {return ""}
set v [expr {$num*100.0/$denom}]
if {$v>1.0 && $v<99.0} {
return [format %4.1f%% $v]
} elseif {$v<0.1 || $v>99.9} {
return [format %6.3f%% $v]
} else {
return [format %5.2f%% $v]
}
}
# Generate a subreport that covers some subset of the database.
# the $where clause determines which subset to analyze.
#
proc subreport {title where} {
set hit 0
mem eval "SELECT sum(nentry) AS nentry, \
sum(payload) AS payload, \
sum(CASE is_index WHEN 1 THEN 0 ELSE payload-4*nentry END) \
AS data, \
max(mx_payload) AS mx_payload, \
sum(n_ovfl) as n_ovfl, \
sum(pri_pages) AS pri_pages, \
sum(ovfl_pages) AS ovfl_pages, \
sum(pri_unused) AS pri_unused, \
sum(ovfl_unused) AS ovfl_unused \
FROM space_used WHERE $where" {} {set hit 1}
if {!$hit} {return 0}
puts ""
set len [string length $title]
incr len 5
set stars "***********************************"
append stars $stars
set stars [string range $stars $len end]
puts "*** $title $stars"
puts ""
statline "Percentage of total database" \
[percent [expr {$pri_pages+$ovfl_pages}] $::file_pgcnt]
statline "Number of entries" $nentry
set storage [expr {($pri_pages+$ovfl_pages)*1024}]
statline "Bytes of storage consumed" $storage
statline "Bytes of payload" $payload [percent $payload $storage]
statline "Bytes of data" $data [percent $data $storage]
set key [expr {$payload-$data}]
statline "Bytes of key" $key [percent $key $storage]
set avgpay [expr {$nentry>0?$payload/$nentry:0}]
statline "Average payload per entry" $avgpay
set avgunused [expr {$nentry>0?($pri_unused+$ovfl_unused)/$nentry:0}]
statline "Average unused bytes per entry" $avgunused
statline "Average fanout" \
[format %.2f [expr {$pri_pages==0?0:($nentry+0.0)/$pri_pages}]]
statline "Maximum payload per entry" $mx_payload
statline "Entries that use overflow" $n_ovfl [percent $n_ovfl $nentry]
statline "Total pages used" [set allpgs [expr {$pri_pages+$ovfl_pages}]]
statline "Primary pages used" $pri_pages ;# [percent $pri_pages $allpgs]
statline "Overflow pages used" $ovfl_pages ;# [percent $ovfl_pages $allpgs]
statline "Unused bytes on primary pages" $pri_unused \
[percent $pri_unused [expr {$pri_pages*1024}]]
statline "Unused bytes on overflow pages" $ovfl_unused \
[percent $ovfl_unused [expr {$ovfl_pages*1024}]]
set allunused [expr {$ovfl_unused+$pri_unused}]
statline "Unused bytes on all pages" $allunused \
[percent $allunused [expr {$allpgs*1024}]]
return 1
}
# Output summary statistics:
#
puts "/** Disk-Space Utilization Report For $file_to_analyze"
puts "*** As of [clock format [clock seconds] -format {%Y-%b-%d %H:%M:%S}]"
puts ""
set fsize [file size [lindex $argv 0]]
set file_pgcnt [expr {$fsize/1024}]
set usedcnt [mem eval {SELECT sum(pri_pages+ovfl_pages) FROM space_used}]
set freecnt [expr {$file_pgcnt-$usedcnt-1}]
set freecnt2 [lindex [btree_get_meta $DB] 0]
statline {Pages in the whole file (measured)} $file_pgcnt
set file_pgcnt2 [expr {$usedcnt+$freecnt2+1}]
statline {Pages in the whole file (calculated)} $file_pgcnt2
statline {Pages that store data} $usedcnt [percent $usedcnt $file_pgcnt]
statline {Pages on the freelist (per header)}\
$freecnt2 [percent $freecnt2 $file_pgcnt]
statline {Pages on the freelist (calculated)}\
$freecnt [percent $freecnt $file_pgcnt]
statline {Header pages} 1 [percent 1 $file_pgcnt]
set ntable [db eval {SELECT count(*)+1 FROM sqlite_master WHERE type='table'}]
statline {Number of tables in the database} $ntable
set nindex [db eval {SELECT count(*) FROM sqlite_master WHERE type='index'}]
set autoindex [db eval {SELECT count(*) FROM sqlite_master
WHERE type='index' AND name LIKE '(% autoindex %)'}]
set manindex [expr {$nindex-$autoindex}]
statline {Number of indices} $nindex
statline {Number of named indices} $manindex [percent $manindex $nindex]
statline {Automatically generated indices} $autoindex \
[percent $autoindex $nindex]
set bytes_data [mem eval "SELECT sum(payload-4*nentry) FROM space_used
WHERE NOT is_index AND name!='sqlite_master'"]
set total_payload [mem eval "SELECT sum(payload) FROM space_used"]
statline "Size of the file in bytes" $fsize
statline "Bytes of payload stored" $total_payload \
[percent $total_payload $fsize]
statline "Bytes of user data stored" $bytes_data \
[percent $bytes_data $fsize]
# Output table rankings
#
puts ""
puts "*** Page counts for all tables with their indices ********************"
puts ""
mem eval {SELECT tblname, count(*) AS cnt, sum(pri_pages+ovfl_pages) AS size
FROM space_used GROUP BY tblname ORDER BY size DESC, tblname} {} {
statline [string toupper $tblname] $size [percent $size $file_pgcnt]
}
# Output subreports
#
if {$nindex>0} {
subreport {All tables and indices} 1
}
subreport {All tables} {NOT is_index}
if {$nindex>0} {
subreport {All indices} {is_index}
}
foreach tbl [mem eval {SELECT name FROM space_used WHERE NOT is_index
ORDER BY name}] {
regsub ' $tbl '' qn
set name [string toupper $tbl]
set n [mem eval "SELECT count(*) FROM space_used WHERE tblname='$qn'"]
if {$n>1} {
subreport "Table $name and all its indices" "tblname='$qn'"
subreport "Table $name w/o any indices" "name='$qn'"
subreport "Indices of table $name" "tblname='$qn' AND is_index"
} else {
subreport "Table $name" "name='$qn'"
}
}
# Output instructions on what the numbers above mean.
#
puts {
*** Definitions ******************************************************
Number of pages in the whole file
The number of 1024-byte pages that go into forming the complete database
Pages that store data
The number of pages that store data, either as primary B*Tree pages or
as overflow pages. The number at the right is the data pages divided by
the total number of pages in the file.
Pages on the freelist
The number of pages that are not currently in use but are reserved for
future use. The percentage at the right is the number of freelist pages
divided by the total number of pages in the file.
Header pages
The number of pages of header overhead in the database. This value is
always 1. The percentage at the right is the number of header pages
divided by the total number of pages in the file.
Number of tables in the database
The number of tables in the database, including the SQLITE_MASTER table
used to store schema information.
Number of indices
The total number of indices in the database.
Number of named indices
The number of indices created using an explicit CREATE INDEX statement.
Automatically generated indices
The number of indices used to implement PRIMARY KEY or UNIQUE constraints
on tables.
Size of the file in bytes
The total amount of disk space used by the entire database files.
Bytes of payload stored
The total number of bytes of payload stored in the database. Payload
includes both key and data. The content of the SQLITE_MASTER table is
counted when computing this number. The percentage at the right shows
the payload divided by the total file size.
Bytes of user data stored
The total number of bytes of data stored in the database, not counting
the database schema information stored in the SQLITE_MASTER table. The
percentage at the right is the user data size divided by the total file
size.
Percentage of total database
The amount of the complete database file that is devoted to storing
information described by this category.
Number of entries
The total number of B*Tree key/value pairs stored under this category.
Bytes of storage consumed
The total amount of disk space required to store all B*Tree entries
under this category. The is the total number of pages used times
the pages size (1024).
Bytes of payload
The amount of payload stored under this category. Payload is the sum
of keys and data. Each table entry has 4 bytes of key and an arbitrary
amount of data. Each index entry has 4 or more bytes of key and no
data. The percentage at the right is the bytes of payload divided by
the bytes of storage consumed.
Bytes of data
The amount of data stored under this category. The data space reported
includes formatting information such as nul-terminators and field-lengths
that are stored with the data. The percentage at the right is the bytes
of data divided by bytes of storage consumed.
Bytes of key
The sum of the sizes of all keys under this category. The percentage at
the right is the bytes of key divided by the bytes of storage consumed.
Average payload per entry
The average amount of payload on each entry. This is just the bytes of
payload divided by the number of entries.
Average unused bytes per entry
The average amount of free space remaining on all pages under this
category on a per-entry basis. This is the number of unused bytes on
all pages divided by the number of entries.
Maximum payload per entry
The largest payload size of any entry.
Entries that use overflow
Up to 236 bytes of payload for each entry are stored directly in the
primary B*Tree page. Any additional payload is stored on a linked list
of overflow pages. This is the number of entries that exceed 236 bytes
in size. The value to the right is the number of entries that overflow
divided by the total number of entries.
Total pages used
This is the number of 1024 byte pages used to hold all information in
the current category. This is the sum of primary and overflow pages.
Primary pages used
This is the number of primary B*Tree pages used.
Overflow pages used
The total number of overflow pages used for this category.
Unused bytes on primary pages
The total number of bytes of unused space on all primary pages. The
percentage at the right is the number of unused bytes divided by the
total number of bytes on primary pages.
Unused bytes on overflow pages
The total number of bytes of unused space on all overflow pages. The
percentage at the right is the number of unused bytes divided by the
total number of bytes on overflow pages.
Unused bytes on all pages
The total number of bytes of unused space on all primary and overflow
pages. The percentage at the right is the number of unused bytes
divided by the total number of bytes.
}
# Output the database
#
puts "**********************************************************************"
puts "The entire text of this report can be sourced into any SQL database"
puts "engine for further analysis. All of the text above is an SQL comment."
puts "The data used to generate this report follows:"
puts "*/"
puts "BEGIN;"
puts $tabledef
unset -nocomplain x
mem eval {SELECT * FROM space_used} x {
puts -nonewline "INSERT INTO space_used VALUES("
regsub ' $x(name) '' qn
regsub ' $x(tblname) '' qtn
puts -nonewline "'$qn','$qtn',"
puts -nonewline "$x(is_index),$x(nentry),$x(payload),$x(mx_payload),"
puts -nonewline "$x(n_ovfl),$x(pri_pages),$x(ovfl_pages),$x(pri_unused),"
puts "$x(ovfl_unused));"
}
puts "COMMIT;"