# # add_file "sqlite/callback.c" # # add_file "sqlite/prepare.c" # # add_file "tests/t_cvsimport_drepper2.at" # # add_file "tests/t_db_kill_branch_locally.at" # # add_file "tests/t_existsonpath.at" # # patch "AUTHORS" # from [ff466bec33fb81e11e8f7dc8cc425e89ee70f745] # to [7a3afb6e49bc3428635204b2eed5f39c7375c950] # # patch "ChangeLog" # from [25e008239fd5cad9a208851b8bcd0d7f3be03de5] # to [acc813649d4cffb7939260314cc6d26ae1f7f789] # # patch "INSTALL" # from [400eaf8e798d44fce8b0622c88bc324fd31830c2] # to [347e0770a3316aa30c3e9d1519db0ca66988781e] # # patch "Makefile.am" # from [cbd9fbc3d73a88f56a538bc5050a2ce3a2ffee31] # to [ca602dd61d7c6f3c4a1b290c56ae7ac1a67f0451] # # patch "NEWS" # from [542138ab98bf754cb1b2f2d86652f9abf2b438e3] # to [412bb443772db09ff7dd1ce53414fc98bd90bb5c] # # patch "app_state.cc" # from [1e2cfd4af8c4ccc2b721c758469659dc3d7f4131] # to [d4bde5580532bd066167f9ece19ac0410398fdde] # # patch "automate.cc" # from [646411d161574bb13a8cb76ff8f8abd28de310ba] # to [7492b76019ac6578ecc8e1fec67025cff1ffbc39] # # patch "basic_io.hh" # from [b61d8da0f80ba7017e11e68e91809c95f4415b43] # to [ddf2b4dbcf7bedb37aa96ef1634c41d2d58a249e] # # patch "cert.cc" # from [07be077e4c0d53abd9cac0bbdf201e808cf221a5] # to [0c6926cd5d66887e8449302640c57f94d95eaa00] # # patch "change_set.cc" # from [803ba53c5e9aafcbc72169471fec66bcee20e14d] # to [140b7e4eaf348923275c40452cf25c0264966dfb] # # patch "commands.cc" # from [c9dd7afdabd028f1a9ec18da9aa1a9de1670765d] # to [d155ea587e6ee57f7057e497579cf08a4882fb8c] # # patch "contrib/monotone-import.pl" # from [936971f03dcd0f03c175973cddb9387c2bf1cb59] # to [d51a87380e1d820c4311a361a155bd56f50afa24] # # patch "contrib/mtbrowse.sh" # from [9ad2130061d1372f803e9b59e3f45bf38609c31a] # to [a97e1412853098d6472fc5747bb659dca3bfdbe3] # # patch "cryptopp/config.h" # from [e6a83896c58c998e79adebed9dd975cae332523d] # to [cffb39ab0c2b4b02984adc4f024b5192a2851a8e] # # patch "cryptopp/integer.cpp" # from [103774f8fdc7bba70d9c8c36c12278fdfbdddff1] # to [f21803a0c45376b1be12f49c04cbd13cdefc4951] # # patch "database.cc" # from [1ce26993177acbeb3e3d18aba17f43700372fa3c] # to [31bf34b9a9899ae714bd8cb34c880d49f851ca69] # # patch "database.hh" # from [402c6310d759c4934fc19ba823f2536ca3251d46] # to [8eff7740768dec012533217d6771853b705a3254] # # patch "main.cc" # from [24910dffe664f34ffa8bb09e201ed03631dec629] # to [0f905ade02dd9188922f3c04700501c6f7d4b57d] # # patch "merkle_tree.cc" # from [b0a8cacb8d29ab4a8500c0f2cb34509783dca4c8] # to [2088ec84695cc4d4290728085f3e5d7900e9a9ba] # # patch "merkle_tree.hh" # from [79d95a4f0dc25d93faae1a64544dca80adce5d76] # to [aa4d5bed0d7dee09fd72c2068c626061c30a6937] # # patch "monotone.cc" # from [8469a8de748e5eb3958f74fc204703a041b1a86c] # to [21b832dddae51e882d8df1c744b159f1a7642c22] # # patch "monotone.texi" # from [18fdc4eac00664cacf2ca7e151a07c8ece75a479] # to [aea7f0c2241348081d1c31ab77cdab0cbe18d6fe] # # patch "netcmd.cc" # from [672a3694248e09ec47f64929e99411c1a35ae745] # to [844f0f7559a6415ef30a28d99fa6ea76a1c71a0c] # # patch "netsync.cc" # from [f1056e86785d18c2a7da04c76086fd3c5106ab9c] # to [e9786aaaad7990675f952101b544f35fd168df4c] # # patch "netxx/osutil.h" # from [410b3050e6da00aca1cbe528773bc33cb1465060] # to [d852d45641d2b6a72f9627b9ef3b3517247e1693] # # patch "packet.cc" # from [bd0eb9d56a0d3845911aa49ed31353a9e40f9fe5] # to [e51ed2792c8751cf45a0344503d3860c0d38d3f1] # # patch "rcs_file.cc" # from [888ba309a3a161cddb6f63f510e1e9bfb7b7da63] # to [8f2bc1920dfa4a94fd265b03e081da13b3a171a8] # # patch "rcs_import.cc" # from [12affac881ab416406a9b81ec4700242bb5a0829] # to [b90ec8325f19892896d9692fc01893c9d8816594] # # patch "rcs_import.hh" # from [6b3bc7d569e1f4fb65238ad258c11793c9dbca82] # to [eba99da6a1751f001de5a9937f8f71852836553b] # # patch "revision.cc" # from [dab8f8c33fc1b34f01958d267e98164a96e52738] # to [f9c7fd64e999ea82f190e9f67fd27caabce6e5b4] # # patch "sqlite/alter.c" # from [9570af388bc99471ea6e1258817fbf06e3120030] # to [03041f2464e22532601254f87cb49997fa21dcdf] # # patch "sqlite/btree.c" # from [25770f8cf1fe778757b69cbe0b84c02615c6e1f5] # to [d2e09ebf755bfd665727133361b22c6a915b12d7] # # patch "sqlite/build.c" # from [8afb06c791adcde7787f157bbc55aeef27fb27c1] # to [593d8fda0576a72e6f1fbf8f1a61db110dde9264] # # patch "sqlite/callback.c" # from [] # to [0910b611e0c158f107ee3ff86f8a371654971e2b] # # patch "sqlite/delete.c" # from [d70d54a84695de92efc05b9db7d3684cd21d9094] # to [4b68127f55971c7fb459146e0b6cf3bd70cfffe9] # # patch "sqlite/expr.c" # from [bf7253cd2d828ec8bf321321c2598e4b8918d79b] # to [6d7058944c5f4b7e4304be3fe63ada91dac221a1] # # patch "sqlite/func.c" # from [ff0673a25ec6216934e664bf9f480ae8b2c66936] # to [f208d71f741d47b63277530939f552815af8ce35] # # patch "sqlite/insert.c" # from [34c25c33f51a43644a42cc091ac967b070c6b6d5] # to [8c0868a975fe37366ed92e1b976853be96284607] # # patch "sqlite/keywordhash.h" # from [e8949ba18076ed0333bfcec91ca2f75372a318c8] # to [9f753ca12591e9ac7d627850e28217bf1fb96c26] # # patch "sqlite/main.c" # from [531fab947f72d3b6e86476ed4594838a2fa277f5] # to [16ab37b7b3aa57bcfb6b687474b2553c67b1a7fe] # # patch "sqlite/opcodes.c" # from [92970dd49bab22c37e0aa4306379015aa8493d93] # to [09ba45fa2716974a205f0514fda43e0d52c50ecc] # # patch "sqlite/opcodes.h" # from [90bdbb426dc13fbec8ac93f59de8f23d5f271db7] # to [c350694b63ef80daafa7d04f71a6d921aa4935e2] # # patch "sqlite/os.h" # from [0c805df3df02b98eb78a7a86756c3cbd4e190939] # to [c4b34bd4d6fea51a420f337468b907f4edecb161] # # patch "sqlite/os_unix.c" # from [fba0167576f09e242afd4c4978e1d2944b1da8b5] # to [45540d7ee5095566da6685d584598edee5be857c] # # patch "sqlite/os_unix.h" # from [40b2fd1d02cfa45d6c3dea25316fd019cf9fcb0c] # to [39a393252e69e72b06715c9958df05ddbc4aa971] # # patch "sqlite/os_win.c" # from [2bbbe6fbb010763c3fa79d5e951afca9b138c6b5] # to [fe7b99cfcfb61d9bf54493ddf5857885a657fb89] # # patch "sqlite/pager.c" # from [95e24c9134a00613ca87b963a84ad62d85d5b979] # to [841a2cdddd4275de36cda26ed9dc54ae942660ce] # # patch "sqlite/pager.h" # from [9a417a1e04737c227ebbba3bdf8597d6dd51513a] # to [0d9153d6269d60d04af3dd84a0cc0a96253cf4a4] # # patch "sqlite/parse.c" # from [bf752a2b845b64014c51c32f478edda7fbe0b63f] # to [6671523c392fcf8287c08e5896cc2513987fc5cb] # # patch "sqlite/parse.h" # from [c22a7a5d0ddf7da1a1a36cbc677489e69d4e5f3f] # to [55c238b9c97ae9a71722f2fabf3e0d23660e4e63] # # patch "sqlite/pragma.c" # from [845c8ab0ab7d09ed2115d3dfc859ba2364b365a7] # to [5ea2ba0e43f6a83968a936b071b77bd4516d11f0] # # patch "sqlite/prepare.c" # from [] # to [d53602d2f8e097225ae7c76ec764ae68f759ba47] # # patch "sqlite/random.c" # from [eff68e3f257e05e81eae6c4d50a51eb88beb4ff3] # to [90adff4e73a3b249eb4f1fc2a6ff9cf78c7233a4] # # patch "sqlite/select.c" # from [a324af36afe5f050a1e070806ad3ededf1d58f50] # to [28b752e58955c7920711fbdbfdcd369a2bd09448] # # patch "sqlite/sqlite3.h" # from [cc5e1e2dfeb2a834e420412da25a92b742d76711] # to [97fec5750fa71f8b162c9571a7e08413de9886ed] # # patch "sqlite/sqliteInt.h" # from [474c20597ee66bb3a666bed0abd76e7be579184a] # to [0722b47bae7acb182bf43be3585537027c63f741] # # patch "sqlite/tokenize.c" # from [103cbaa932c790f540f8eceb63cd3010e117bdff] # to [4b45f8c000202c877bcc567688c2ec21a01984b3] # # patch "sqlite/trigger.c" # from [1a6d0c7c51b70bdc58d5068be72034071eff23ad] # to [f51dec15921629591cb98bf2e350018e268b109a] # # patch "sqlite/update.c" # from [42823d00865c9fe4f01b3c62647858726345a28e] # to [e96c7b342cd8903c672162f4cf84d2c737943347] # # patch "sqlite/util.c" # from [02bc2750336b021b3f10e61538f665c4b0033b5d] # to [96008b52604d08b9cc57ed37350149d6ac8a1bf3] # # patch "sqlite/vacuum.c" # from [5cf598003191bd91c17a64742bad8e46241698a8] # to [829d9e1a6d7c094b80e0899686670932eafd768c] # # patch "sqlite/vdbe.c" # from [cb701319876cb1332a7372feaaa1310cd463c9f6] # to [c2511f392598928254504e3b2c5ec47f4fef2b53] # # patch "sqlite/vdbe.h" # from [7f586cb6d6b57764e5aac1f87107d6a95ddce24c] # to [75e466d84d362b0c4498978a9d6b1e6bd32ecf3b] # # patch "sqlite/vdbeInt.h" # from [97b62807bd001efd82006460ad8a8d72d1c8d36d] # to [4312faf41630a6c215924b6c7c2f39ebb1af8ffb] # # patch "sqlite/vdbeapi.c" # from [467caa6e6fb9247528b1c7ab9132ae1b4748e8ac] # to [3f858d2236df0d127249a6a166e0e25b5de650ed] # # patch "sqlite/vdbeaux.c" # from [278ac982f1f64ee14c49aac127d9ddc6ee30cac6] # to [c99e32abeba4b7522e3922afff2c32ff4bd17eb5] # # patch "sqlite/vdbemem.c" # from [4e853ce3151eaf7906150da85a1b3ce1fe5e8da8] # to [48a64ae95a9edc6e8d940300dad15d70d1670398] # # patch "sqlite/where.c" # from [c4b227458e8993decb515ed9a2fe2d4f5f8e3125] # to [3a9a2258ab3364655e9ea215ad5ae7bf41813f54] # # patch "std_hooks.lua" # from [9b1a27e30129929aa366223e51f1c11ec918fc93] # to [072c95bc58425ade43dc08e8361c7aca49275dd4] # # patch "tests/t_automate_stdio.at" # from [82905ef9235da9d20dc5c56e9e0b3e0a55a919d4] # to [e86f5d0e9f49172d5948e6131a8de64b5ff20bb1] # # patch "tests/t_cvsimport_drepper.at" # from [fa1e2cb90749522674c28871a9a9971c7984c34c] # to [5b803327cc8752bab50ced9a0efc4ce59a5244ef] # # patch "tests/t_cvsimport_drepper2.at" # from [] # to [c0d315c7c6fd5077592b8d81ecbc8a801acc3e41] # # patch "tests/t_db_kill_branch_locally.at" # from [] # to [dc67769b12aea0c26b6d4e3b2347c56ee99cde4b] # # patch "tests/t_db_kill_rev_locally.at" # from [7833b3652bf45b72b9fb6490b86fe2b66d7105ee] # to [a5043ae56c1d9ab1897594010d21b5e0851e572c] # # patch "tests/t_existsonpath.at" # from [] # to [3bbd717c0872f45e088cd95b692a1fc0c649583f] # # patch "tests/t_selector_later_earlier.at" # from [8e3a1438e23b7c4b562d254c55c2f2d4b0a75bd5] # to [b3e5d9771d979375e79b8506d7b08b4aaa6fc18d] # # patch "testsuite.at" # from [3d2b4ab8782f8c58fb72a8a12793ba102105e2c7] # to [4cbb082cf10749231aaffa05b12dfdd51e8e2096] # # patch "unix/process.cc" # from [c30edf9e74742079e4229bc8cfb0d44054e8c5c3] # to [ac04438936f36fcf7a9eaeaffb60abd9f4dfe5d5] # --- AUTHORS +++ AUTHORS @@ -59,6 +59,7 @@ Timothy Brownawell Matthew Gregan Riccardo Ghetta + Brian Campbell Ethan Blanton Eric Anderson --- ChangeLog +++ ChangeLog @@ -1,5 +1,147 @@ 2005-07-05 Nathaniel Smith + * NEWS: First cut at 0.20 release notes. + +2005-07-03 Matthew Gregan + + * sqlite/*, Makefile.am: Import SQLite 3.2.2 from upstream. + * sqlite/main.c: Compile fix. + * sqlite/{callback.c,prepare.c}: Add new files. + +2005-07-03 Matthew Gregan + + * sqlite/{sqlite3.h,tokenize.c} (sqlite3_complete_last): New + function to find the last valid SQL statement in a string; based + on sqlite3_complete. This change should be offered upstream, but + probably not before sqlite3_complete_last16 is implemented. + * database.cc (database::load): Load and execute dump in chunks, + fixes bug 13570. + +2005-07-01 Matthew Gregan + + * tests/t_cvsimport_drepper2.at: Canonicalise monotone output so + that the test passes on Win32. + +2005-06-30 Eric Kidd + + * contrib/monotone-import.pl: Changed $branch to + $user_branch. This script may need more work, but at least Perl + compiles it now. + +2005-06-30 Patrick Mauritz + + * automate.cc, basic_io.hh, cert.cc, change_set.cc, + cryptopp/config.h, cryptopp/integer.cpp, main.cc, merkle_tree.cc, + merkle_tree.hh, monotone.cc, netcmd.cc, netsync.cc, + netxx/osutil.h, packet.cc: Namespace and include file cleanup. + +2005-06-29 graydon hoare + + * tests/t_cvsimport_drepper2.at: New test. + * testsuite.at: Call it. + +2005-06-23 graydon hoare + + * rcs_import.cc (import_cvs_repo): Put branch imports inside + transaction blocks, add a couple tickers. + +2005-06-22 graydon hoare + + * rcs_file.cc: Track file:line numbers, accept files which violate + some lies in rcs file format. + * rcs_import.cc (cvs_tree_walker): + Warn rather than crash on parse errors. + (cvs_history) + (cvs_commit) + (cvs_cluster) + (prepared_revision) + (import_branch) + (import_cvs_repo): Support non-branch tags. + +2005-06-21 graydon hoare + + * rcs_import.{cc,hh} (import_rcs_file): Rename to test_parse_rcs_file. + * commands.cc (rcs_import): rename call. + +2005-06-19 graydon hoare + + * rcs_import.cc: Rewrite change set inference logic. + +2005-06-28 Roland Illig + + * app_state.cc: #include , needed on NetBSD. + +2005-06-28 Nathaniel Smith + + * std_hooks.lua (ignore_file): Ignore vim swap files and emacs + temp files. + +2005-06-27 Nathaniel Smith + + * INSTALL: Bump required version of Boost to 1.32. + +2005-06-26 Matthew Gregan + + * app_state.cc (app_state::app_state()): Initialise no_merges to + false so that 'log' will show merges by default (the recently + added --no-merges option provides a means to disable the merge + entries). + +2005-06-26 Matthew Gregan + + * commands.cc (CMD(db)): Added db kill_branch_locally command. + * database.cc, database.hh (delete_branch_named): New function to + delete all branch certs with a given branch name. + * monotone.texi (Database): Added documentation for db + kill_branch_locally. + * tests/t_db_kill_branch_locally.at: New test for db + kill_branch_locally. + * testsuite.at: Add the test. + * AUTHORS: Add myself. + * ChangeLog: Change my email address on an old contribution to + match my pubkey. + +2005-06-24 Nathaniel Smith + + * tests/t_db_kill_rev_locally.at: Clean up style. + +2005-06-24 Nathaniel Smith + + * unix/process.cc (process_spawn): Format log output correctly. + +2005-06-24 Nathaniel Smith + + * unix/process.cc (existsonpath): Reindent. Add logging, and use + 'command -v' instead of 'which' (as per Matt Johnston's discovery + that it is more portable). + (process_spawn): Handle exec failure more properly. + * tests/t_existsonpath.at: New test. + * testsuite.at: Add it. + +2005-06-25 Matthew Gregan + + * monotone.cc: Log correct locale set for LC_MESSAGES. + +2005-06-24 Nathaniel Smith + + * unix/process.cc: Remove tabs. + +2005-06-24 Nathaniel Smith + + * std_hooks.lua (get_preferred_merge2_command) + (get_preferred_merge3_command): Move meld to the bottom of the + default merge tool search order. Also, use xemacs if it appears + in $EDITOR, otherwise use emacs. + * revision.cc (check_sane_history): Remove stale comment. + +2005-07-05 Nathaniel Smith + * globish.cc (combine_and_check_globish): Don't add unnecessary {}'s. * tests/t_netsync_globs.at, testsuite.at: New test. @@ -1219,7 +1361,7 @@ * work.cc: Use attr_file_name rather than hardcoded strings. -2005-05-04 Brian Campbell +2005-05-04 Brian Campbell * contrib/monotone.el (monotone-vc-register): Fix arguments to monotone-cmd-buf, to make work. --- INSTALL +++ INSTALL @@ -13,7 +13,7 @@ * software prerequisites: - a supported C++ compiler: g++ 3.2 or later. - - an installed copy of boost 1.31.0 or later. + - an installed copy of boost 1.32.0 or later. on debian: @@ -49,9 +49,9 @@ assembled this abbreviated bourne shell sequence for advanced users who do not need all the preamble: - wget http://aleron.dl.sourceforge.net/sourceforge/boost/boost_1_31_0.tar.gz - tar -xzf boost_1_31_0.tar.gz - cd boost_1_31_0 + wget http://aleron.dl.sourceforge.net/sourceforge/boost/boost_1_32_0.tar.gz + tar -xzf boost_1_32_0.tar.gz + cd boost_1_32_0 (cd tools/build/jam_src && ./build.sh) BJAM=`find tools/build/jam_src/ -name bjam -a -type f` $BJAM "-sBUILD=release single speed static" @@ -63,13 +63,13 @@ ranlib libs/*.a if this completes successfully, you will have a selection of boost - libraries in boost_1_31_0/libs and boost headers in - boost_1_31_0/boost. you can then either copy the .a files to your - standard library path and the directory "boost_1_31_0/boost" to your + libraries in boost_1_32_0/libs and boost headers in + boost_1_32_0/boost. you can then either copy the .a files to your + standard library path and the directory "boost_1_32_0/boost" to your standard include path, or you can pass additional configuration options to your monotone configure build, such as: - ./configure CPPFLAGS="-Iboost_1_31_0" LDFLAGS="-Lboost_1_31_0/libs" + ./configure CPPFLAGS="-Iboost_1_32_0" LDFLAGS="-Lboost_1_32_0/libs" monotone does not use all of boost -- for instance, people often have trouble building boost.python, which we do not use. you don't --- Makefile.am +++ Makefile.am @@ -111,6 +111,7 @@ sqlite/util.c sqlite/vacuum.c \ sqlite/vdbe.c sqlite/vdbeapi.c sqlite/vdbeaux.c \ sqlite/vdbemem.c sqlite/where.c \ + sqlite/prepare.c sqlite/callback.c \ \ sqlite/btree.h sqlite/config.h sqlite/hash.h sqlite/opcodes.h sqlite/os.h \ sqlite/os_common.h sqlite/os_unix.h sqlite/os_win.h \ --- NEWS +++ NEWS @@ -1,3 +1,92 @@ +???????????????????????????? + + 0.20 release. features, ui improvements, performance + improvements, and bug fixes. + + - major changes in netsync UI: serve/sync/push/pull now take a + list of globs; clients can request arbitrary sets of + branches, not just predefined "collections". write + permissions are now granted on a per-db level (they were + before anyway). + - where you used to say, e.g., "monotone pull + net.venge.monotone", you should instead say + "monotone pull net.venge.monotone*". This may + require shell-quoting. + - 'get_netsync_write_permitted' hooks must be changed + to take only one argument, the 'identity'. + 'get_netsync_{read,anonymous_read}_permitted' hooks + now take a branch argument instead of a collection, + and will be called for each branch that a client + requests. + - 0.19 clients cannot talk to 0.20 servers, and vice-versa. + - special thanks to Timothy Brownawell + , Richard Levitte + . + - other major changes: + - cvs_import re-written; many bugs fixed. now + supports tags. + - many minor netsync changes: + - netsync traffic is now cryptographically authenticated + against corruption and man-in-the-middle attacks. + special thanks to Ethan Blanton , + Matt Johnston . + - new hooks that are called when server receives data: + note_netsync_*_received. special thanks to Timothy + Brownawell . + - ancestry graphs that pass outside the given branch + are now synchronized correctly. special thanks to + Timothy Brownawell . + - UI improvements: + - 'log' options changed: --depth has become --last; + new options --no-merges, --diffs, --brief. + - 'status' has new option --brief. special thanks to + Derek Scherger . + - 'serve' has new option --pid-file. special thanks + to Matthew Gregan . + - all commands taking restrictions now take option + --depth, to limit recursion through subdirectories. + special thanks to Joel Reed . + - merge command all take --author, --date now. + - 'checkout', 'update' take --revision, instead of + using positional arguments. special thanks to Derek + Scherger , Richard Levitte + . + - 'commit' takes new --message-file option. + - new features: + - new commands: "db kill_branch_locally", "db + kill_revision_locally", useful for correcting some + mistakes. special thanks to Brian Campbell + , Sebastian Spaeth + . + - new file attribute 'manual_merge', to prevent invocation of + merger on binary files. hook added to guess correct + value at 'add' time. special thanks to Riccardo + Ghetta . + - new 'earlier than', 'later than' selectors. special + thanks to Riccardo Ghetta . + - new automate commands: + - 'stdio', for efficient use by + front-ends. special thanks to Timothy Brownawell + . + - 'select', for requesting the set of revisions + matching a selector. special thanks to Richard + Levitte . + - 'certs', for fetching certs on a revision in a + parseable (basic io-based) format. special thanks + to Grahame Bowland . + - 'inventory' output changed incompatibly; should be + much more usable now, and stable. special thanks to + Derek Scherger . + - better memory/performance when handling large files. + special thanks to Eric Anderson + , Timothy Brownawell + , Matt Johnston , + Matthew Gregan . + - new text mode browser in contrib/mtbrowse.sh, by Henry + Nestler . + - improved zsh completion in contrib/monotone.zsh_completion, + by Joel Reed . + Tue May 3 00:31:37 PDT 2005 0.19 release. performance improvements, features, ui --- app_state.cc +++ app_state.cc @@ -1,8 +1,10 @@ #include #include #include #ifdef WIN32 #include /* for chdir() */ +#else +#include /* for chdir() on POSIX */ #endif #include // for strtoul() @@ -31,7 +33,7 @@ app_state::app_state() : branch_name(""), db(""), stdhooks(true), rcfiles(true), diffs(false), - verbose(false), search_root("/"), depth(-1), last(-1) + no_merges(false), verbose(false), search_root("/"), depth(-1), last(-1) { db.set_app(this); } --- automate.cc +++ automate.cc @@ -856,7 +856,7 @@ // Make the output deterministic; this is useful for the test suite, in // particular. - sort(certs.begin(), certs.end()); + std::sort(certs.begin(), certs.end()); basic_io::printer pr(output); --- basic_io.hh +++ basic_io.hh @@ -24,7 +24,7 @@ TOK_SYMBOL, TOK_STRING, TOK_HEX, - TOK_NONE, + TOK_NONE } token_type; struct --- cert.cc +++ cert.cc @@ -27,7 +27,10 @@ #include using namespace std; -using namespace boost; +using boost::shared_ptr; +using boost::get; +using boost::tuple; +using boost::lexical_cast; // FIXME: the bogus-cert family of functions is ridiculous // and needs to be replaced, or at least factored. @@ -86,7 +89,7 @@ vector< manifest > tmp_certs; // sorry, this is a crazy data structure - typedef tuple< hexenc, cert_name, base64 > trust_key; + typedef boost::tuple< hexenc, cert_name, base64 > trust_key; typedef map< trust_key, pair< shared_ptr< set >, it > > trust_map; trust_map trust; --- change_set.cc +++ change_set.cc @@ -13,7 +13,6 @@ #include #include #include -#include #include #include --- commands.cc +++ commands.cc @@ -2106,7 +2106,8 @@ "load\n" "migrate\n" "execute\n" - "kill_rev_locally \n" + "kill_rev_locally ID\n" + "kill_branch_locally BRANCH\n" "check\n" "changesetify\n" "rebuild\n" @@ -2145,6 +2146,8 @@ kill_rev_locally(app,idx(args, 1)()); else if (idx(args, 0)() == "clear_epoch") app.db.clear_epoch(cert_value(idx(args, 1)())); + else if (idx(args, 0)() == "kill_branch_locally") + app.db.delete_branch_named(cert_value(idx(args, 1)())); else throw usage(name); } @@ -3448,20 +3451,18 @@ CMD(rcs_import, "debug", "RCSFILE...", - "import all versions in RCS files\n" - "this command doesn't reconstruct revisions. you probably want cvs_import", + "parse versions in RCS files\n" + "this command doesn't reconstruct or import revisions. you probably want cvs_import", OPT_BRANCH_NAME) { if (args.size() < 1) throw usage(name); - transaction_guard guard(app.db); for (vector::const_iterator i = args.begin(); i != args.end(); ++i) { - import_rcs_file(mkpath((*i)()), app.db); + test_parse_rcs_file(mkpath((*i)()), app.db); } - guard.commit(); } --- contrib/monotone-import.pl +++ contrib/monotone-import.pl @@ -198,7 +198,7 @@ print "If you want the changes that come with the import to appear in\n"; print "another branch (like your development branch), do the following\n"; print "\n"; -print "monotone$database propagate $branch {your-chosen-branch}\n"; +print "monotone$database propagate $user_branch {your-chosen-branch}\n"; print "**************************************\n"; ###################################################################### --- contrib/mtbrowse.sh +++ contrib/mtbrowse.sh @@ -18,9 +18,8 @@ # - Change your configuration # Delete the "VISUAL", to use the "PAGER", deleto both for internal viewer. # Save configuration. -# Please "Reload DB", to see the new configuration # - Begin with menu "S Select revision" -# - Browse in branches, revisions, diff files, view logs .... +# - Browse in branches, revisions, diff files, view logs ... # # Needed tools: # monotone 0.19 or compatible @@ -35,7 +34,7 @@ # 2005/5/9 Version 0.1.2 address@hidden # Update for MT 0.19 # Diff from parent. -# Topsort or Date/Time sort, config via TOPSORT +# Toposort or Date/Time sort, config via TOPOSORT # # 2005/5/13 Version 0.1.3 address@hidden # Diff from 'parent' mistaken HEAD/REVISION usage. @@ -72,17 +71,46 @@ # Selectable format for Date, Branch, Author, ChangeLog. Coloring author. # Current marker is asterix before date/time. # +# 2005/6/23 Version 0.1.9 address@hidden +# Cancel is "EXIT" in main menu. +# Meter alongwith --gauge for reading certs :-) +# Config with menu and def.item, instand radiolist and the test on/off thingy. +# Don't remove some old files at exit. +# Branch and head not in Main background title. +# +# 2005/6/24 Version 0.1.10 address@hidden +# Remove TAB's from ChangeLog. +# Some cat as stdin pipe. +# Typofix topsort/toposort. +# +# 2005-06-26 Version 0.1.11 address@hidden +# No double Date/Branch/Author with CR in selection list. +# Short Author and no branch as default. +# Set default revision for first selection to head. +# "automate ancestors" without cut (have only one field). +# Internal function for "automate ancestors" with depth limit. Speedup. +# real user sys +# 19.925s 6.780s 13.030s automate ancestors (net.venge.monotone) +# 6.067s 2.920s 3.120s automate parents as loop, depth 30 +# 4.226s 2.280s 1.910s automate parents as loop, depth 20 +# 1.384s 0.680s 0.700s automate parents as loop, depth 10 +# +# 2005-06-29 Version 0.1.12 address@hidden +# Automatic author color. +# Date have inverse color for last selection. +# Expand revision after input, if not 40 chars. (parents don't allow short rev) + # Known Bugs / ToDo-List: # * For Monotone Version >0.19 s/--depth/--last/, remove the fallback # * better make "sed -n -e '1p'" for merge two different branches. -VERSION="0.1.8" +VERSION="0.1.12" # Save users settings # Default values, can overwrite on .mtbrowserc CONFIGFILE="$HOME/.mtbrowserc" -# Store lists for menue here +# Store lists for menu here TEMPDIR="$HOME/.mtbrowse" TEMPFILE="$TEMPDIR/.tmp" @@ -97,8 +125,8 @@ # 1=Certs Cached, 0=Clean at end (slow and save mode) CACHE="1" -# T=Topsort revisions, D=Date sort (reverse topsort) -TOPSORT="T" +# T=Toposort revisions, D=Date sort (reverse toposort) +TOPOSORT="T" # count of certs to get from DB, "0" for all CERTS_MAX="20" @@ -106,14 +134,14 @@ # Trim hash code HASH_TRIM="10" -# Format Date/Time +# Format for Date/Time FORMAT_DATE="L" # Format Branch Full,Short,None -FORMAT_BRANCH="F" +FORMAT_BRANCH="N" # Format author (strip domain from mail address) -FORMAT_AUTHOR="F" +FORMAT_AUTHOR="S" # Changelog format FORMAT_LOG="F" @@ -127,6 +155,9 @@ # TODO: Remove in future DEPTH_LAST="--last" +# automate ancestors (I)nteral function, (M)onotone +ANCESTORS="I" + # read saved settings if [ -f $CONFIGFILE ] then @@ -141,9 +172,9 @@ #database "/home/hn/mtbrowse.db" # key "" - eval `cat MT/options | sed -n -r \ + eval `sed -n -r \ -e 's/^[ ]*(branch) \"([^\"]+)\"$/\1=\2/p' \ - -e 's/^[ ]*(database) \"([^\"]+)\"$/\1=\2/p'` + -e 's/^[ ]*(database) \"([^\"]+)\"$/\1=\2/p' < MT/options` if [ -n "$database" ] then @@ -174,8 +205,9 @@ if [ -f MT/options ] then - if ! dialog --cr-wrap --title " *********** WARNING! ********** " \ - --defaultno --colors --yesno " + if ! dialog --cr-wrap \ + --title " *********** WARNING! ********** " \ + --defaultno --colors --yesno " Your \Zb\Z1MT/options\Zn will be overwrite, if continue with different DB file or branch in exist working directory! @@ -194,7 +226,7 @@ # Clear cached files do_clear_cache() { - rm -f $TEMPFILE.agraph $TEMPFILE.certs.$BRANCH \ + rm -f $TEMPFILE.certs.$BRANCH \ $TEMPFILE.changelog.$BRANCH } @@ -202,8 +234,9 @@ # clear temp files do_clear_on_exit() { - rm -f $TEMPFILE.dlg-branches $TEMPFILE.agraph \ - $TEMPFILE.action-select $TEMPFILE.menu $TEMPFILE.input + rm -f $TEMPFILE.branches $TEMPFILE.ancestors $TEMPFILE.toposort \ + $TEMPFILE.action-select $TEMPFILE.menu $TEMPFILE.input \ + $TEMPFILE.ncolor $TEMPFILE.c if [ "$CACHE" != "1" ] then @@ -228,106 +261,159 @@ } -# Add the date and user-key to the list of revisions +# Add the date, author and changlog to the list of revisions + +# Scanning for: +# Key : address@hidden +# Sig : ok +# Name : date +# Value : 2005-05-31T22:29:50 <<--- +# -------------------------------------- +# Key : address@hidden +# Sig : ok +# Name : changelog +# Value : Handle merged parents <<--- + +# Output +# 123456 "2005-05-31 22:29 address@hidden Handle merged parents" + fill_date_key() { local in_file=$1 local out_file=$2 - local short_hash dat bra aut log + local short_hash dat bra aut log lineno color count + line_count=`wc -l < $in_file` + if [ "$line_count" -eq 0 ] + then + unset line_count + fi + + lineno=0 rm -f $out_file # Read Key and Date value from certs cat $in_file | \ - while read hash ; do - echo -n "." + while read hash + do + if [ -n "$line_count" ] + then + let lineno++ + echo "$(( 100*$lineno/line_count ))" + else + echo -n "." 1>&2 + fi - # Scanning for - # Key : address@hidden - # Sig : ok - # Name : date - # Value : 2005-05-31T22:29:50 <<--- - - # Output - # 123456 "2005-05-31 22:29 address@hidden" - short_hash=`echo $hash | cut -c 1-$HASH_TRIM` - # get all certs of revision - monotone --db=$DB list certs $hash > $TEMPFILE.c.tmp + # get all certs of revision, check cached first + tfc=$TEMPFILE.c + monotone --db=$DB list certs $hash > $tfc # Date format case $FORMAT_DATE in F) # 2005-12-31T23:59:59 - dat=`cat $TEMPFILE.c.tmp | sed -n -r -e \ - '/^Name : date/,+1s/Value : (.+)$/ \1/p'` + dat=`sed -n -r -e \ + '/^Name : date/,+1s/Value : (.+)$/\1 /p' \ + < $tfc | sed -n -e '1p'` ;; L) # 2005-12-31 23:59 - dat=`cat $TEMPFILE.c.tmp | sed -n -r -e \ - '/^Name : date/,+1s/Value : (.{10})T(.{5}).+$/ \1 \2/p'` + dat=`sed -n -r -e \ + '/^Name : date/,+1s/Value : (.{10})T(.{5}).+$/\1 \2 /p' \ + < $tfc | sed -n -e '1p'` ;; D) # 2005-12-31 - dat=`cat $TEMPFILE.c.tmp | sed -n -r -e \ - '/^Name : date/,+1s/Value : (.+)T.+$/ \1/p'` + dat=`sed -n -r -e \ + '/^Name : date/,+1s/Value : (.+)T.+$/\1 /p' \ + < $tfc | sed -n -e '1p'` ;; S) # 12-31 23:59 - dat=`cat $TEMPFILE.c.tmp | sed -n -r -e \ - '/^Name : date/,+1s/Value : .{4}-(.+)T(.{5}).+$/ \1 \2/p'` + dat=`sed -n -r -e \ + '/^Name : date/,+1s/Value : .{4}-(.+)T(.{5}).+$/\1 \2 /p' \ + < $tfc | sed -n -e '1p'` ;; T) # 23:59:59 - dat=`cat $TEMPFILE.c.tmp | sed -n -r -e \ - '/^Name : date/,+1s/Value : .{10}T(.+{8})$/ \1/p'` + dat=`sed -n -r -e \ + '/^Name : date/,+1s/Value : .{10}T(.+{8})$/\1 /p' \ + < $tfc | sed -n -e '1p'` ;; esac # Branch format case $FORMAT_BRANCH in F) # full - bra=`cat $TEMPFILE.c.tmp | sed -n -r -e \ - '/^Name : branch/,+1s/Value : (.+)$/ \1/p' | \ - sed -n -e '1p'` + bra=`sed -n -r -e \ + '/^Name : branch/,+1s/Value :(.+)$/\1 /p' \ + < $tfc | sed -n -e '1p'` ;; S) # short - bra=`cat $TEMPFILE.c.tmp | sed -n -r -e \ - '/^Name : branch/,+1s/Value : .*\.([^\.]+)$/ \1/p' | \ - sed -n -e '1p'` + bra=`sed -n -r -e \ + '/^Name : branch/,+1s/Value :.*\.([^\.]+)$/\1 /p' \ + < $tfc | sed -n -e '1p'` ;; esac # Author format case $FORMAT_AUTHOR in F) # full - aut=`cat $TEMPFILE.c.tmp | sed -n -r -e \ - '/^Name : author/,+1s/Value : (.+)$/\1/p'` + aut=`sed -n -r -e \ + '/^Name : author/,+1s/Value : (.+)$/\1/p' \ + < $tfc | sed -n -e '1p'` ;; S) # short - aut=`cat $TEMPFILE.c.tmp | sed -n -r -e \ - '/^Name : author/,+1s/Value : (.{1,10})address@hidden/\1/p'` + aut=`sed -n -r -e \ + '/^Name : author/,+1s/Value : (.{1,10})address@hidden/\1/p' \ + < $tfc | sed -n -e '1p'` ;; esac # Changelog format case $FORMAT_LOG in - F) # full - log=`cat $TEMPFILE.c.tmp | sed -n -r -e "y/\"/'/" -e \ - '/^Name : changelog/,+1s/Value : (.+)$/ \1/p'` + F) # full TAB here ----v + log=`sed -n -r -e "y/\" /' /" -e \ + '/^Name : changelog/,+1s/Value : (.+)$/ \1/p' \ + < $tfc` ;; S) # short - log=`cat $TEMPFILE.c.tmp | sed -n -r -e "y/\"/'/" -e \ - '/^Name : changelog/,+1s/Value : (.{1,20}).*$/ \1/p'` + log=`sed -n -r -e "y/\" /' /" -e \ + '/^Name : changelog/,+1s/Value : (.{1,20}).*$/ \1/p' \ + < $tfc` ;; esac - # Coloring? + # Author coloring? if [ -n "$FORMAT_COLOR" -a "$FORMAT_AUTHOR" != "N" ] then # Bug in dialog: Don't allow empty string after \\Zn test -z "$log" && log=" " - echo "$short_hash \"$dat$bra $FORMAT_COLOR$aut\\Zn$log\"" \ + if [ "$last_aut" != "$aut" ] + then + # Automatic color by author? + if [ "$FORMAT_COLOR" = "A" ] + then + color=`grep -n "$aut" $TEMPFILE.ncolor | cut -d ':' -f 1` + if [ -z "$color" ] + then + color=$(( `wc -l < $TEMPFILE.ncolor` % 16 + 1 )) + echo "$aut" >> $TEMPFILE.ncolor + fi + + if [ $color -le 8 ] + then + color="\\Zb\\Z$color" + else + color="\\Z$color" + fi + else + color="$FORMAT_COLOR" + fi + last_aut="$aut" + fi + echo "$short_hash \"$dat$bra\\ZR$color$aut\\Zn$log\"" \ >> $out_file else - echo "$short_hash \"$dat$bra $aut$log\"" >> $out_file + echo "$short_hash \"$dat$bra\\ZR$aut$log\"" >> $out_file fi - done + done | dialog --gauge "$line_count certs reading" 6 60 rm $TEMPFILE.c.tmp } @@ -368,15 +454,15 @@ OLD_BRANCH=$BRANCH # Get branches from DB - if [ ! -f $TEMPFILE.dlg-branches -o $DB -nt $TEMPFILE.dlg-branches \ + if [ ! -f $TEMPFILE.branches -o $DB -nt $TEMPFILE.branches \ -o "$CACHE" != "1" ] then monotone --db=$DB list branches \ - | sed -n -r -e 's/^(.+)$/\1\t-/p' > $TEMPFILE.dlg-branches \ + | sed -n -r -e 's/^(.+)$/\1\t-/p' > $TEMPFILE.branches \ || exit 200 fi - if [ ! -s $TEMPFILE.dlg-branches ] + if [ ! -s $TEMPFILE.branches ] then echo "Error: No branches found." exit 1 @@ -385,7 +471,7 @@ dialog --begin 1 2 \ --default-item "$OLD_BRANCH" \ --menu "Select branch" 0 0 0 \ - `cat $TEMPFILE.dlg-branches` \ + `cat $TEMPFILE.branches` \ 2> $TEMPFILE.input BRANCH=`cat $TEMPFILE.input` @@ -415,7 +501,7 @@ # Only one head ? if [ `wc -l < $TEMPFILE.heads` -eq 1 -a -n "$1" ] then - HEAD=`cat $TEMPFILE.heads | head -n 1` + HEAD=`head -n 1 < $TEMPFILE.heads` else # List heads with author and date. Select by user. monotone --db=$DB heads --branch=$BRANCH \ @@ -486,6 +572,7 @@ --menu "Select parent for $REVISION" 0 0 0 \ 2> $TEMPFILE.input \ && PARENT=`cat $TEMPFILE.input` + rm $TEMPFILE.certs3tmp else # Single parent only PARENT=`cat $TEMPFILE.parents` @@ -529,7 +616,7 @@ # DIFF2: from other revision (not working dir) # Select second revision if cat $TEMPFILE.certs.$BRANCH | \ - xargs dialog --default-item "$REV2" --menu \ + xargs dialog --default-item "$REV2" --colors --menu \ "Select _older_ revision for branch:$BRANCH\nrev:$REVISION" \ 0 0 0 2> $TEMPFILE.revision-select then @@ -563,7 +650,43 @@ done } +# Get parents recursive. +# Same as automate ancestors, but limit the depth +# Function called recursive! +do_automate_ancestors_depth() +{ + locale depth head rev + depth=$1 + head=$2 + + # Empty parm? + if [ -z "$depth" -o -z "$depth" ] + then + return 0 + fi + + # Limit by depth? + if [ "$depth" -gt $CERTS_MAX -o "$depth" -gt 200 ] + then + return 0 + fi + + let depth++ + monotone --db=$DB automate parents $head |\ + while read rev + do + if ! grep -q -l -e "$rev" $TEMPFILE.ancestors + then + echo "$rev" >> $TEMPFILE.ancestors + do_automate_ancestors_depth $depth $rev || return $? + fi + done + let depth-- + + return 0 +} + # Select a revision do_revision_sel() { @@ -578,33 +701,42 @@ # Building revisions list if [ ! -f $TEMPFILE.certs.$BRANCH -o $DB -nt $TEMPFILE.certs.$BRANCH ] then + # Name color new + rm -f $TEMPFILE.ncolor + touch $TEMPFILE.ncolor + echo "Reading ancestors ($HEAD)" echo "$HEAD" > $TEMPFILE.ancestors - monotone --db=$DB automate ancestors $HEAD | cut -c 1-40 \ - >> $TEMPFILE.ancestors || exit 200 - if [ "$TOPSORT" = "T" -o "$CERTS_MAX" -gt 0 ] + if [ "$ANCESTORS" = "I" -a "$CERTS_MAX" -gt 0 ] then - echo "Topsort..." + do_automate_ancestors_depth 1 $HEAD || exit 200 + else + monotone --db=$DB automate ancestors $HEAD \ + >> $TEMPFILE.ancestors || exit 200 + fi + + if [ "$TOPOSORT" = "T" -o "$CERTS_MAX" -gt 0 ] + then + echo "Toposort..." monotone --db=$DB automate toposort `cat $TEMPFILE.ancestors` \ - > $TEMPFILE.topsort || exit 200 + > $TEMPFILE.toposort || exit 200 if [ "$CERTS_MAX" -gt 0 ] then # Only last certs. Remember: Last line is newest! - tail -n "$CERTS_MAX" < $TEMPFILE.topsort \ - > $TEMPFILE.topsort2 - mv $TEMPFILE.topsort2 $TEMPFILE.topsort + tail -n "$CERTS_MAX" < $TEMPFILE.toposort \ + > $TEMPFILE.toposort2 + mv $TEMPFILE.toposort2 $TEMPFILE.toposort fi else - mv $TEMPFILE.ancestors $TEMPFILE.topsort + mv $TEMPFILE.ancestors $TEMPFILE.toposort fi # Reading revisions and fill with date - echo -n "Reading certs" - fill_date_key $TEMPFILE.topsort $TEMPFILE.certs3tmp + fill_date_key $TEMPFILE.toposort $TEMPFILE.certs3tmp - if [ "$TOPSORT" != "T" ] + if [ "$TOPOSORT" != "T" ] then # Sort by date+time sort -k 2 -r < $TEMPFILE.certs3tmp > $TEMPFILE.certs.$BRANCH @@ -614,7 +746,13 @@ fi fi - SHORT_REV=`echo $REVISION | cut -c 1-$HASH_TRIM` + # if first rev is empty, use head instand + if [ -z "$REVISION" ] + then + SHORT_REV=`echo $HEAD | cut -c 1-$HASH_TRIM` + else + SHORT_REV=`echo $REVISION | cut -c 1-$HASH_TRIM` + fi # Select revision while cat $TEMPFILE.certs.$BRANCH | \ @@ -626,17 +764,24 @@ --menu "Select revision for branch:$BRANCH" \ 0 0 0 2> $TEMPFILE.revision-select do - SHORT_REV=`cat $TEMPFILE.revision-select` # Remove old marker, set new marker - cat $TEMPFILE.certs.$BRANCH | sed -r \ - -e "s/^(.+\")\*(.+)\$/\1 \2/" \ - -e "s/^($SHORT_REV.* \") (.+)\$/\1\*\2/" \ - > $TEMPFILE.certs.$BRANCH.base - mv $TEMPFILE.certs.$BRANCH.base $TEMPFILE.certs.$BRANCH + if [ "$FORMAT_DATE" = "N" -a "$FORMAT_BRANCH" = "N" ] + then + sed -r \ + -e "s/^(.+\")\*(.+)\$/\1\2/" \ + -e "s/^($SHORT_REV.* \")(.+)\$/\1\*\2/" \ + < $TEMPFILE.certs.$BRANCH > $TEMPFILE.marker + else + sed -r \ + -e "s/^(.+\")\\\\Zr(.+)\$/\1\2/" \ + -e "s/^($SHORT_REV.* \")(.+)\$/\1\\\\Zr\2/" \ + < $TEMPFILE.certs.$BRANCH > $TEMPFILE.marker + fi + mv $TEMPFILE.marker $TEMPFILE.certs.$BRANCH - # Error, on "monotone automate parent XXXXXX", if short revision. :-( + # Error, on "monotone automate parents XXXXXX", if short revision. :-( # Expand revision here, if short revision (is alway short now) REVISION=`monotone --db=$DB complete revision $SHORT_REV` @@ -650,30 +795,37 @@ # Menu for configuration do_config() { - while dialog --menu "Configuration" 0 0 0 \ + local item + + while dialog --default-item "$item" \ + --menu "Configuration" 0 0 0 \ "V" "VISUAL [$VISUAL]" \ "Vd" "Set VISUAL default to vim -R" \ "P" "PAGER [$PAGER]" \ "Pd" "set PAGER default to less" \ - "S" "Sort by Topsort or Date [$TOPSORT]" \ + "S" "Sort by Toposort or Date [$TOPOSORT]" \ "T" "Time and date format [$FORMAT_DATE]" \ "B" "Branch format [$FORMAT_BRANCH]" \ "A" "Author format [$FORMAT_AUTHOR]" \ "Ac" "Author Color format [$FORMAT_COLOR]" \ "L" "changeLog format [$FORMAT_LOG]" \ + "D" "Depth limit for ancestors [$ANCESTORS]" \ "C" "Certs limit in Select-List [$CERTS_MAX]" \ "-" "-" \ "W" "Write configuration file" \ "R" "Return to main menu" \ 2> $TEMPFILE.menu do - case `cat $TEMPFILE.menu` in + item=`cat $TEMPFILE.menu` + case $item in V) # Setup for VISUAL - dialog --inputbox \ - "Config for file viewer\nused in sample \"vim -R changes.diff\"" \ - 8 70 "$VISUAL" 2> $TEMPFILE.input \ - && VISUAL=`cat $TEMPFILE.input` + if dialog --inputbox \ + "Config for file viewer\nuse in sample: \"vim -R changes.diff\"" \ + 8 70 "$VISUAL" 2> $TEMPFILE.input + then + VISUAL=`cat $TEMPFILE.input` + fi ;; Vd) # set Visual default @@ -681,81 +833,82 @@ ;; P) # Setup for PAGER - dialog --inputbox \ - "Config for pipe pager\nused in sample \"monotone log | less\"" \ - 8 70 "$PAGER" 2> $TEMPFILE.input \ - && PAGER=`cat $TEMPFILE.input` + if dialog --inputbox \ + "Config for pipe pager\nuse in sample: \"monotone log | less\"" \ + 8 70 "$PAGER" 2> $TEMPFILE.input + then + PAGER=`cat $TEMPFILE.input` + fi ;; Pd) # set Pager default PAGER="less" ;; S) - # change T=Topsort revisions, D=Date sort (reverse topsort) - dialog --radiolist "Sort revisions by" 0 0 0 \ - "T" "Topsort, oldest top (from Monotone)" \ - `test "$TOPSORT" = "T" && echo "on" || echo "off"` \ - "D" "Date/Time (reverse topsort)" \ - `test "$TOPSORT" = "D" && echo "on" || echo "off"` \ - 2> $TEMPFILE.input \ - && TOPSORT=`cat $TEMPFILE.input` + # change T=Toposort revisions, D=Date sort (reverse toposort) + if dialog --default-item "$TOPOSORT" \ + --menu "Sort revisions by" 0 0 0 \ + "T" "Toposort, oldest top (from Monotone)" \ + "D" "Date/Time (reverse toposort)" \ + 2> $TEMPFILE.input + then + TOPOSORT=`cat $TEMPFILE.input` + fi ;; T) # change date/time format - dialog --radiolist "Format for date" 0 0 0 \ - "F" "2005-12-31T23:59:59 -- Full date and time" \ - `test "$FORMAT_DATE" = "F" && echo "on" || echo "off"` \ - "L" "2005-12-31 23:59 -- Long date and time" \ - `test "$FORMAT_DATE" = "L" && echo "on" || echo "off"` \ - "D" "2005-21-31 -- Date only" \ - `test "$FORMAT_DATE" = "D" && echo "on" || echo "off"` \ - "S" "12-31 23:59:59 -- Short date and time" \ - `test "$FORMAT_DATE" = "S" && echo "on" || echo "off"` \ - "T" "23:59:59 -- Time only" \ - `test "$FORMAT_DATE" = "T" && echo "on" || echo "off"` \ - "N" "no date and no time" \ - `test "$FORMAT_DATE" = "N" && echo "on" || echo "off"` \ - 2> $TEMPFILE.input \ - && FORMAT_DATE=`cat $TEMPFILE.input` + if dialog --default-item "$FORMAT_DATE" \ + --menu "Format for date and time" 0 0 0 \ + "F" "2005-12-31T23:59:59 -- Full date and time" \ + "L" "2005-12-31 23:59 -- Long date and time" \ + "D" "2005-21-31 -- Date only" \ + "S" "12-31 23:59:59 -- Short date and time" \ + "T" "23:59:59 -- Time only" \ + "N" "no date and no time" \ + 2> $TEMPFILE.input + then + FORMAT_DATE=`cat $TEMPFILE.input` + fi ;; B) # change branch format - dialog --radiolist "Format for branch" 0 0 0 \ - "F" "Full author" \ - `test "$FORMAT_BRANCH" = "F" && echo "on" || echo "off"` \ - "S" "Short author, strip domain from email address" \ - `test "$FORMAT_BRANCH" = "S" && echo "on" || echo "off"` \ - "N" "no author" \ - `test "$FORMAT_BRANCH" = "N" && echo "on" || echo "off"` \ - 2> $TEMPFILE.input \ - && FORMAT_BRANCH=`cat $TEMPFILE.input` + if dialog --default-item "$FORMAT_BRANCH" \ + --menu "Format for branch" 0 0 0 \ + "F" "Full branch" \ + "S" "Short branch, right side only" \ + "N" "no branch" \ + 2> $TEMPFILE.input + then + FORMAT_BRANCH=`cat $TEMPFILE.input` + fi ;; A) # change author's format - dialog --radiolist "Format for author" 0 0 0 \ - "F" "Full author" \ - `test "$FORMAT_AUTHOR" = "F" && echo "on" || echo "off"` \ - "S" "Short author, strip domain from email address" \ - `test "$FORMAT_AUTHOR" = "S" && echo "on" || echo "off"` \ - "N" "no author" \ - `test "$FORMAT_AUTHOR" = "N" && echo "on" || echo "off"` \ - 2> $TEMPFILE.input \ - && FORMAT_AUTHOR=`cat $TEMPFILE.input` + if dialog --default-item "$FORMAT_AUTHOR" \ + --menu "Format for author" 0 0 0 \ + "F" "Full author" \ + "S" "Short author, strip domain from email address" \ + "N" "no author" \ + 2> $TEMPFILE.input + then + FORMAT_AUTHOR=`cat $TEMPFILE.input` + fi ;; Ac) # Author coloring - dialog --radiolist "Color author in selecetion" 0 0 0 \ - "yes" "author is color" \ - `test -n "$FORMAT_COLOR" && echo "on" || echo "off"` \ - "no" "author has no special color" \ - `test -z "$FORMAT_COLOR" && echo "on" || echo "off"` \ - 2> $TEMPFILE.input \ - && { + if dialog --default-item \ + "`test -n \"$FORMAT_COLOR\" && echo \"yes\" || echo \"no\"`" \ + --menu "Color author in selecetion" 0 0 0 \ + "yes" "author is color" \ + "no" "author has no special color" \ + 2> $TEMPFILE.input + then if [ "`cat $TEMPFILE.input`" = "yes" ] then dialog --colors \ --default-item "$FORMAT_COLOR" \ --menu "Selecet color for author" 0 0 0 \ + "A" "Automatic color" \ "\\Z0" "\Z0Color\Zn 0" \ "\\Z1" "\Z1Color\Zn 1" \ "\\Z2" "\Z2Color\Zn 2" \ @@ -779,24 +932,34 @@ else FORMAT_COLOR="" fi - } + fi ;; L) # Changelog format - dialog --radiolist "Format for ChangeLog in selcetion" 0 0 0 \ - "F" "Full changelog line" \ - `test "$FORMAT_LOG" = "F" && echo "on" || echo "off"` \ - "S" "Short changelog" \ - `test "$FORMAT_LOG" = "S" && echo "on" || echo "off"` \ - "N" "no changelog in selection" \ - `test "$FORMAT_LOG" = "N" && echo "on" || echo "off"` \ - 2> $TEMPFILE.input \ - && FORMAT_LOG=`cat $TEMPFILE.input` + dialog \ + --default-item "$FORMAT_LOG" \ + --menu "Format for ChangeLog in selection" 0 0 0 \ + "F" "Full changelog line" \ + "S" "Short changelog" \ + "N" "no changelog in selection" \ + 2> $TEMPFILE.input \ + && FORMAT_LOG=`cat $TEMPFILE.input` ;; + D) + # automate ancestors (I)nteral function, (M)onotone + if dialog --default-item "$ANCESTORS" \ + --menu "Get ancestors by using" 0 0 0 \ + "M" "Monotone \"automate ancestor\" (save mode)" \ + "I" "Internal function with depth limit (faster)" \ + 2> $TEMPFILE.input + then + ANCESTORS=`cat $TEMPFILE.input` + fi + ;; C) # Change CERTS_MAX dialog --inputbox \ - "Set maximum lines for revision selction menu\n(default: 0, disabled)" \ + "Set maximum lines for revision selction menu\n(0=disabled)" \ 9 70 "$CERTS_MAX" 2> $TEMPFILE.input \ && CERTS_MAX=`cat $TEMPFILE.input` ;; @@ -811,7 +974,7 @@ PAGER="$PAGER" TEMPDIR="$TEMPDIR" TEMPFILE="$TEMPFILE" -TOPSORT="$TOPSORT" +TOPOSORT="$TOPOSORT" CACHE="$CACHE" CERTS_MAX="$CERTS_MAX" DEPTH_LAST="$DEPTH_LAST" @@ -820,6 +983,7 @@ FORMAT_AUTHOR="$FORMAT_AUTHOR" FORMAT_LOG="$FORMAT_LOG" FORMAT_COLOR="$FORMAT_COLOR" +ANCESTORS="$ANCESTORS" EOF dialog --title " Info " --sleep 2 --infobox \ "Configration wrote to\n$CONFIGFILE" 0 0 @@ -848,7 +1012,8 @@ mkdir -p $TEMPDIR while dialog \ - --backtitle "h:$HEAD b:$BRANCH f:$DB" \ + --cancel-label "Exit" \ + --backtitle "$DB" \ --menu "Main - mtbrowse v$VERSION" 0 0 0 \ "S" "Select revision" \ "I" "Input revision" \ @@ -880,6 +1045,13 @@ then REVISION=`cat $TEMPFILE.input` + if [ `echo "$REVISION" | wc -L` -lt 40 ] + then + # Error, on "monotone automate parents XXXXXX", if short revision. :-( + # Expand revision here, if short revision + REVISION=`monotone --db=$DB complete revision $REVISION` + fi + do_action_sel do_revision_sel fi @@ -891,7 +1063,7 @@ ;; B) # Branch config - rm -f $TEMPFILE.dlg-branches + rm -f $TEMPFILE.branches do_branch_sel ;; H) --- cryptopp/config.h +++ cryptopp/config.h @@ -103,7 +103,7 @@ typedef uint16_t word16; typedef uint32_t word32; -#if defined(__GNUC__) || defined(__MWERKS__) +#if defined(__GNUC__) || defined(__MWERKS__) || defined(__SUNPRO_CC) #define WORD64_AVAILABLE typedef uint64_t word64; #define W64LIT(x) x##LL @@ -203,7 +203,7 @@ #define CRYPTOPP_WIN32_AVAILABLE #endif -#if defined(__unix__) || defined(__MACH__) || defined(__NetBSD__) +#if defined(__unix__) || defined(__MACH__) || defined(__sun) || defined(__NetBSD__) #define CRYPTOPP_UNIX_AVAILABLE #endif @@ -255,7 +255,7 @@ # define CRYPTOPP_MALLOC_ALIGNMENT_IS_16 #endif -#if defined(__linux__) || defined(__sun__) || defined(__CYGWIN__) +#if defined(__linux__) || defined(__sun) || defined(__CYGWIN__) # define CRYPTOPP_MEMALIGN_AVAILABLE #endif --- cryptopp/integer.cpp +++ cryptopp/integer.cpp @@ -3956,7 +3956,7 @@ return r; } -word Integer::InverseMod(const word mod) const +word Integer::InverseMod(word mod) const { word g0 = mod, g1 = *this % mod; word v0 = 0, v1 = 1; --- database.cc +++ database.cc @@ -345,11 +345,19 @@ if (error) throw oops(string("could not open database: ") + filename.string() + (string(sqlite3_errmsg(__sql)))); - + while(in) { in.read(buf, constants::bufsz); tmp.append(buf, in.gcount()); + + const char* last_statement = 0; + sqlite3_complete_last(tmp.c_str(), &last_statement); + if (last_statement == 0) + continue; + string::size_type len = last_statement + 1 - tmp.c_str(); + execute(tmp.substr(0, len).c_str()); + tmp.erase(0, len); } execute(tmp.c_str()); @@ -1505,6 +1513,19 @@ execute("DELETE from revisions WHERE id = '%s'",rid.inner()().c_str()); } +/// Deletes all certs referring to a particular branch. +void +database::delete_branch_named(cert_value const & branch) +{ + base64 encoded; + encode_base64(branch, encoded); + L(F("Deleting all references to branch %s\n") % branch); + execute("DELETE FROM revision_certs WHERE name='branch' AND value ='%s'", + encoded().c_str()); + execute("DELETE FROM branch_epochs WHERE branch='%s'", + encoded().c_str()); +} + // crypto key management void --- database.hh +++ database.hh @@ -289,6 +289,8 @@ void delete_existing_revs_and_certs(); void delete_existing_rev_and_certs(revision_id const & rid); + + void delete_branch_named(cert_value const & branch); // crypto key / cert operations --- main.cc +++ main.cc @@ -22,6 +22,8 @@ #include #include #include +#include +#include // Microsoft + other compatible compilers such as Intel #if defined(_MSC_VER) || (defined(__MWERKS__) && __MWERKS__ >= 0x3000) --- merkle_tree.cc +++ merkle_tree.cc @@ -19,7 +19,7 @@ #include "sanity.hh" #include "transforms.hh" -using namespace boost; +using boost::dynamic_bitset; using namespace std; using namespace CryptoPP; --- merkle_tree.hh +++ merkle_tree.hh @@ -38,7 +38,7 @@ key_item = 3, revision_item = 4, cert_item = 5, - epoch_item = 6, + epoch_item = 6 } netcmd_item_type; --- monotone.cc +++ monotone.cc @@ -8,6 +8,7 @@ #include "popt/popt.h" #include +#include #include #include #include @@ -247,7 +248,7 @@ L(F("set locale: LC_CTYPE=%s, LC_MESSAGES=%s\n") % (setlocale(LC_CTYPE, NULL) == NULL ? "n/a" : setlocale(LC_CTYPE, NULL)) - % (setlocale(LC_MESSAGES, NULL) == NULL ? "n/a" : setlocale(LC_CTYPE, NULL))); + % (setlocale(LC_MESSAGES, NULL) == NULL ? "n/a" : setlocale(LC_MESSAGES, NULL))); // decode all argv values into a UTF-8 array --- monotone.texi +++ monotone.texi @@ -4409,6 +4409,21 @@ work you can extract @var{id}'s data. @end itemize address@hidden monotone db kill_branch_locally @var{branch} + +This command ``kills'' a branch by deleting all branch certs with that +branch name. You should consider carefully whether you want to use it, +because it can irrevocably delete important information. It does not +modify or delete any revisions or any of the other certificates on +revisions in the branch; it simply removes the branch certificates +matching the given branch name. Because of this, it can leave +revisions without any branch certificate at all. As with @command{db +kill_rev_locally}, it only deletes the information from your local +database; if there are other databases that you sync with which have +revisions in this branch, the branch certificates will reappear when +you sync, unless the owners of those databases also delete those +certificates locally. + @item monotone db execute @var{sql-statement} This is a debugging command which executes @var{sql-statement} against --- netcmd.cc +++ netcmd.cc @@ -17,7 +17,6 @@ #include "hmac.hh" using namespace std; -using namespace boost; static netcmd_item_type read_netcmd_item_type(string const & in, --- netsync.cc +++ netsync.cc @@ -212,8 +212,9 @@ // material that you wouldn't have a hope of typing in manually anyways) // -using namespace boost; using namespace std; +using boost::shared_ptr; +using boost::lexical_cast; static inline void require(bool check, string const & context) --- netxx/osutil.h +++ netxx/osutil.h @@ -74,6 +74,10 @@ # include # include # include + +# include +# include + #endif #include "config.h" --- packet.cc +++ packet.cc @@ -18,8 +18,12 @@ #include "sanity.hh" #include "transforms.hh" -using namespace boost; using namespace std; +using boost::shared_ptr; +using boost::lexical_cast; +using boost::match_default; +using boost::match_results; +using boost::regex; // --- packet db writer -- // --- rcs_file.cc +++ rcs_file.cc @@ -196,9 +196,23 @@ } token_type; +static inline void +adv(char i, size_t & line, size_t & col) +{ + if (i == '\n') + { + col = 0; + ++line; + } + else + ++col; +} + static token_type get_token(file_source & ist, - std::string & str) + std::string & str, + size_t & line, + size_t & col) { bool saw_idchar = false; int i = ist.peek(); @@ -210,6 +224,7 @@ { if (i == EOF) return TOK_NONE; + adv(i, line, col); if (!isspace(i)) break; ist.get(c); @@ -220,27 +235,33 @@ { case ';': ist.get(c); + ++col; return TOK_SEMI; break; case ':': ist.get(c); + ++col; return TOK_COLON; break; case '@': ist.get(c); + ++col; while (ist.get(c)) { if (c == '@') { if (ist.peek() == '@') - { ist.get(c); str += c; } + { ist.get(c); str += c; ++col; } else break; } else - str += c; + { + adv(i, line, col); + str += c; + } } return TOK_STRING; break; @@ -252,6 +273,7 @@ && !isspace(i)) { ist.get(c); + ++col; if (! isdigit(c) && c != '.') saw_idchar = true; str += c; @@ -275,9 +297,11 @@ std::string token; token_type ttype; + size_t line, col; + parser(file_source & s, rcs_file & r) - : ist(s), r(r) + : ist(s), r(r), line(1), col(1) {} std::string tt2str(token_type tt) @@ -302,7 +326,7 @@ void advance() { - ttype = get_token(ist, token); + ttype = get_token(ist, token, line, col); // std::cerr << tt2str(ttype) << ": " << token << std::endl; } @@ -316,12 +340,8 @@ void eat(token_type want) { if (ttype != want) - throw oops("parse failure: expecting " - + tt2str(want) - + " got " - + tt2str(ttype) - + " with value: " - + token); + throw oops((F("parse failure %d:%d: expecting %s, got %s with value '%s'\n") + % line % col % tt2str(want) % tt2str(ttype) % token).str()); advance(); } @@ -339,10 +359,8 @@ { std::string tmp; if (!symp(expected)) - throw oops(std::string("parse failure: ") - + "expecting word '" - + expected - + "'"); + throw oops((F("parse failure %d:%d: expecting word '%s'\n") + % line % col % expected).str()); advance(); } @@ -356,7 +374,8 @@ void word() { if (!wordp()) - throw oops("expecting word"); + throw oops((F("parse failure %d:%d: expecting word\n") + % line % col).str()); advance(); } @@ -376,10 +395,23 @@ if (symp("branch")) { sym(r.admin.branch); if (nump()) num(); semi(); } expect("access"); while(symp()) { sym(); } semi(); expect("symbols"); - while(symp()) + + // "man rcsfile" lies: there are real files in the wild which use + // num tokens as the key value in a symbols entry. for example + // "3.1:1.1.0.2" is a real sym:num specification, despite "3.1" + // being a num itself, not a sym. + + while(symp() || nump()) { std::string stmp, ntmp; - sym(stmp); colon(); num(ntmp); + if (symp()) + { + sym(stmp); colon(); num(ntmp); + } + else + { + num(stmp); colon(); num(ntmp); + } r.admin.symbols.insert(make_pair(ntmp, stmp)); } semi(); --- rcs_import.cc +++ rcs_import.cc @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -41,6 +42,8 @@ #include "transforms.hh" #include "ui.hh" +int window = 3600 * 3; + using namespace std; using boost::shared_ptr; using boost::scoped_ptr; @@ -52,161 +55,74 @@ typedef unsigned long cvs_changelog; typedef unsigned long cvs_version; typedef unsigned long cvs_path; +typedef unsigned long cvs_tag; struct cvs_history; -struct -cvs_key +struct +cvs_commit { - cvs_key() {} - cvs_key(rcs_file const & r, - string const & version, - cvs_history & cvs); + cvs_commit(rcs_file const & r, + string const & rcs_version, + file_id const & ident, + cvs_history & cvs); - inline bool similar_enough(cvs_key const & other) const + time_t time; + bool alive; + cvs_author author; + cvs_changelog changelog; + cvs_version version; + cvs_path path; + vector tags; + + bool operator<(cvs_commit const & other) const { - L(F("Checking similarity of %d and %d\n") % id % other.id); - if (changelog != other.changelog) - return false; - if (author != other.author) - return false; - if (labs(time - other.time) > constants::cvs_window) - return false; - for (map::const_iterator it = files.begin(); it!=files.end(); it++) - { - map::const_iterator otherit; - - L(F("checking %s %s\n") % it->first % it->second); - otherit = other.files.find(it->first); - if (otherit != other.files.end() && it->second!=otherit->second) - { - L(F("!similar_enough: %d/%d\n") % id % other.id); - return false; - } - else if (otherit != other.files.end()) - { - L(F("Same file, different version: %s and %s\n") % it->second % otherit->second); - } - } - L(F("similar_enough: %d/%d\n") % id % other.id); - return true; + return time < other.time; } +}; - inline bool operator==(cvs_key const & other) const - { - L(F("Checking equality of %d and %d\n") % id % other.id); - return is_synthetic_branch_founding_commit == other.is_synthetic_branch_founding_commit && - branch == other.branch && - changelog == other.changelog && - author == other.author && - time == other.time; - } - inline bool operator<(cvs_key const & other) const - { - // nb: this must sort as > to construct the edges in the right direction +struct +cvs_branch +{ + bool has_a_branchpoint; + bool has_a_commit; + time_t last_branchpoint; + time_t first_commit; - if (is_synthetic_branch_founding_commit) - { - I(!other.is_synthetic_branch_founding_commit); - return false; - } + map live_at_beginning; + vector lineage; - if (other.is_synthetic_branch_founding_commit) - { - I(!is_synthetic_branch_founding_commit); - return true; - } - - return time > other.time || - - (time == other.time - && author > other.author) || - - (time == other.time - && author == other.author - && changelog > other.changelog) || - - (time == other.time - && author == other.author - && changelog == other.changelog - && branch > other.branch); + void note_commit(time_t now) + { + has_a_commit = true; + if (now < first_commit) + first_commit = now; } - inline void add_file(file_path const &file, string const &version) + void note_branchpoint(time_t now) { - L(F("Adding file %s version %s to CVS key %d\n") % file % version % id); - files.insert( make_pair(file, version) ); + has_a_branchpoint = true; + if (now > last_branchpoint) + last_branchpoint = now; } - bool is_synthetic_branch_founding_commit; - cvs_branchname branch; - cvs_changelog changelog; - cvs_author author; - time_t time; - map files; // Maps file to version - int id; // Only used for debug output - - static int nextid; // Used to initialise id -}; - -int cvs_key::nextid = 0; - -struct -cvs_file_edge -{ - cvs_file_edge (file_id const & pv, - file_path const & pp, - bool pl, - file_id const & cv, - file_path const & cp, - bool cl, - cvs_history & cvs); - cvs_version parent_version; - cvs_path parent_path; - bool parent_live_p; - cvs_version child_version; - cvs_path child_path; - bool child_live_p; - inline bool operator<(cvs_file_edge const & other) const + time_t beginning() const { -#if 0 - return (parent_path < other.parent_path) - || ((parent_path == other.parent_path) - && ((parent_version < other.parent_version) - || ((parent_version == other.parent_version) - && ((parent_live_p < other.parent_live_p) - || ((parent_live_p == other.parent_live_p) - && ((child_path < other.child_path) - || ((child_path == other.child_path) - && ((child_version < other.child_version) - || ((child_version == other.child_version) - && (child_live_p < other.child_live_p) ))))))))); -#else - return (parent_path < other.parent_path) - || ((parent_path == other.parent_path) - && ((parent_version < other.parent_version) - || ((parent_version == other.parent_version) - && ((parent_live_p < other.parent_live_p) - || ((parent_live_p == other.parent_live_p) - && ((child_path < other.child_path) - || ((child_path == other.child_path) - && ((child_version < other.child_version) - || ((child_version == other.child_version) - && (child_live_p < other.child_live_p) ))))))))); -#endif + I(has_a_branchpoint || has_a_commit); + if (has_a_commit) + return first_commit; + else + return last_branchpoint; } + + void append_commit(cvs_commit const & c) + { + note_commit(c.time); + lineage.push_back(c); + } }; struct -cvs_state -{ - set in_edges; -}; - -typedef map > -cvs_branch; - -struct cvs_history { @@ -215,16 +131,11 @@ interner changelog_interner; interner file_version_interner; interner path_interner; + interner tag_interner; interner manifest_version_interner; cycle_detector manifest_cycle_detector; - bool find_key_and_state(rcs_file const & r, - string const & version, - cvs_key & key, - shared_ptr & state); - - // assume admin has foo:X.Y.0.N in it, then // this multimap contains entries of the form // X.Y -> foo @@ -236,16 +147,20 @@ // branch name -> branch map > branches; + shared_ptr trunk; - // branch name -> whether there are any commits on the - // branch (as opposed to just branchpoints) - map branch_has_commit; - // stack of branches we're injecting states into stack< shared_ptr > stk; stack< cvs_branchname > bstk; + // tag -> time, revision + // + // used to resolve the *last* revision which has a given tag + // applied; this is the revision which wins the tag. + map > resolved_tags; + file_path curr_file; + cvs_path curr_file_interned; string base_branch; @@ -262,24 +177,66 @@ enum note_type { note_branchpoint, note_branch_first_commit }; - void note_state_at_branch_beginning(rcs_file const & r, - string const & branchname, - string const & version, - file_id const & ident, - note_type nt); + void push_branch(string const & branch_name, bool private_branch); + void pop_branch(); +}; - void push_branch(string const & branch_name, bool private_branch); - void note_file_edge(rcs_file const & r, - string const & prev_rcs_version_num, - string const & next_rcs_version_num, - file_id const & prev_version, - file_id const & next_version); +cvs_commit::cvs_commit(rcs_file const & r, + string const & rcs_version, + file_id const & ident, + cvs_history & cvs) +{ + map >::const_iterator delta = + r.deltas.find(rcs_version); + I(delta != r.deltas.end()); + + map >::const_iterator deltatext = + r.deltatexts.find(rcs_version); + I(deltatext != r.deltatexts.end()); + + struct tm t; + // We need to initialize t to all zeros, because strptime has a habit of + // leaving bits of the data structure alone, letting garbage sneak into + // our output. + memset(&t, 0, sizeof(t)); + char const * dp = delta->second->date.c_str(); + L(F("Calculating time of %s\n") % dp); +#ifdef WIN32 + I(sscanf(dp, "%d.%d.%d.%d.%d.%d", &(t.tm_year), &(t.tm_mon), + &(t.tm_mday), &(t.tm_hour), &(t.tm_min), &(t.tm_sec))==6); + t.tm_mon--; + // Apparently some RCS files have 2 digit years, others four; tm always + // wants a 2 (or 3) digit year (years since 1900). + if (t.tm_year > 1900) + t.tm_year-=1900; +#else + if (strptime(dp, "%y.%m.%d.%H.%M.%S", &t) == NULL) + I(strptime(dp, "%Y.%m.%d.%H.%M.%S", &t) != NULL); +#endif + time = mktime(&t); + L(F("= %i\n") % time); - void pop_branch(); -}; + alive = delta->second->state != "dead"; + changelog = cvs.changelog_interner.intern(deltatext->second->log); + author = cvs.author_interner.intern(delta->second->author); + path = cvs.curr_file_interned; + version = cvs.file_version_interner.intern(ident.inner()()); + typedef multimap::const_iterator ity; + pair range = r.admin.symbols.equal_range(rcs_version); + for (ity i = range.first; i != range.second; ++i) + { + if (i->first == rcs_version) + { + L(F("version %s -> tag %s\n") % rcs_version % i->second); + tags.push_back(cvs.tag_interner.intern(i->second)); + } + } +} + + // piece table stuff struct piece; @@ -505,6 +462,65 @@ rcs_put_raw_file_edge(next_id, curr_id, del, db); } + + +/* + +please read this exhaustingly long comment and understand it +before mucking with the branch inference logic. + +we are processing a file version. a branch might begin here. if +the current version is X.Y, then there is a branch B starting +here iff there is a symbol in the admin section called X.Y.0.Z, +where Z is the branch number (or if there is a private branch +called X.Y.Z, which is either an import branch or some private +RCS cruft). + +the version X.Y is then considered the branchpoint of B in the +current file. this does *not* mean that the CVS key -- an +abstraction representing whole-tree operations -- of X.Y is the +branchpoint across the CVS archive we're processing. + +in fact, CVS does not record the occurrence of a branching +action (tag -b). we have no idea who executed that command and +when. what we know instead is the commit X.Y immediately +preceeding the branch -- CVS consideres this the branchpoint -- +in this file's reduced view of history. we also know the first +commit X.Y.Z.1 inside the branch (which might not exist). + +our old strategy was to consider all branches nested in a +hierarchy, which was a super-tree of all the branch trees in all +the CVS files in a repository. this involved considering X.Y as +the parent version of branch X.Y.Z, an selecting "the" +branchpoint connecting the two as the least CVS key X.Y.Z.1 +committed inside the branch B. + +this was a mistake, for two significant reasons. + +first, some files do not *have* any commit inside the branch B, +only a branchpoint X.Y.0.Z. this branchpoint is actually the +last commit *before* the user branched, and could be a very old +commit, long before the branch was formed, so it is useless in +determining the branch structure. + +second, some files do not have a branch B, or worse, have +branched into B from an "ancestor" branch A, where a different +file branches into B from a different ancestor branch C. in +other words, while there *is* a tree structure within the X.Y.Z +branches of each file, there is *no* shared tree structure +between the branch names across a repository. in one file A can +be an ancestor of B, in another file B can be an ancestor of A. + +thus, we give up on establishing a hierarchy between branches +altogether. all branches exist in a flat namespace, and all are +direct descendents of the empty revision at the root of +history. each branchpoint symbol mentioned in the +administrative section of a file is considered the root of a new +lineage. + +*/ + + static void process_branch(string const & begin_version, vector< piece > const & begin_lines, @@ -525,10 +541,15 @@ while(! (r.deltas.find(curr_version) == r.deltas.end())) { L(F("version %s has %d lines\n") % curr_version % curr_lines->size()); + + cvs_commit curr_commit(r, curr_version, curr_id, cvs); + cvs.stk.top()->append_commit(curr_commit); + ++cvs.n_versions; string next_version = r.deltas.find(curr_version)->second->next; - if (!next_version.empty()) - { // construct this edge on our own branch + + if (! next_version.empty()) + { L(F("following RCS edge %s -> %s\n") % curr_version % next_version); construct_version(*curr_lines, next_version, *next_lines, r); @@ -537,100 +558,26 @@ insert_into_db(curr_data, curr_id, *next_lines, next_data, next_id, db); - - cvs.note_file_edge (r, curr_version, next_version, - file_id(curr_id), file_id(next_id)); } - else - { L(F("revision %s has no successor\n") % curr_version); - if (curr_version=="1.1") - { // mark this file as newly present since this commit - // (and as not present before) - - // perhaps this should get a member function of cvs_history ? - L(F("marking %s as not present in older manifests\n") % curr_version); - cvs_key k; - shared_ptr s; - cvs.find_key_and_state(r, curr_version, k, s); - I(r.deltas.find(curr_version) != r.deltas.end()); - bool live_p = r.deltas.find(curr_version)->second->state != "dead"; - s->in_edges.insert(cvs_file_edge(curr_id, cvs.curr_file, false, - curr_id, cvs.curr_file, live_p, - cvs)); - ++cvs.n_versions; - } - } - - /* - - please read this exhaustingly long comment and understand it - before mucking with the branch inference logic. - - we are processing a file version. a branch might begin here. if - the current version is X.Y, then there is a branch B starting - here iff there is a symbol in the admin section called X.Y.0.Z, - where Z is the branch number (or if there is a private branch - called X.Y.Z, which is either an import branch or some private - RCS cruft). - - the version X.Y is then considered the branchpoint of B in the - current file. this does *not* mean that the CVS key -- an - abstraction representing whole-tree operations -- of X.Y is the - branchpoint across the CVS archive we're processing. - - in fact, CVS does not record the occurrence of a branching - action (tag -b). we have no idea who executed that command and - when. what we know instead is the commit X.Y immediately - preceeding the branch -- CVS consideres this the branchpoint -- - in this file's reduced view of history. we also know the first - commit X.Y.Z.1 inside the branch (which might not exist). - - our old strategy was to consider all branches nested in a - hierarchy, which was a super-tree of all the branch trees in all - the CVS files in a repository. this involved considering X.Y as - the parent version of branch X.Y.Z, an selecting "the" - branchpoint connecting the two as the least CVS key X.Y.Z.1 - committed inside the branch B. - - this was a mistake, for two significant reasons. - - first, some files do not *have* any commit inside the branch B, - only a branchpoint X.Y.0.Z. this branchpoint is actually the - last commit *before* the user branched, and could be a very old - commit, long before the branch was formed, so it is useless in - determining the branch structure. - - second, some files do not have a branch B, or worse, have - branched into B from an "ancestor" branch A, where a different - file branches into B from a different ancestor branch C. in - other words, while there *is* a tree structure within the X.Y.Z - branches of each file, there is *no* shared tree structure - between the branch names across a repository. in one file A can - be an ancestor of B, in another file B can be an ancestor of A. - - thus, we give up on establishing a hierarchy between branches - altogether. all branches exist in a flat namespace, and all are - direct descendents of the empty revision at the root of - history. each branchpoint symbol mentioned in the - administrative section of a file is considered the root of a new - lineage. - - */ - + // mark the beginning-of-branch time and state of this file if + // we're at a branchpoint typedef multimap::const_iterator ity; pair range = cvs.branchpoints.equal_range(curr_version); if (range.first != cvs.branchpoints.end() - && range.first->first == curr_version) - { - for (ity branch = range.first; branch != range.second; ++branch) - { - cvs.note_state_at_branch_beginning(r, branch->second, - curr_version, - curr_id, - cvs_history::note_branchpoint); - } - } + && range.first->first == curr_version) + { + for (ity i = range.first; i != range.second; ++i) + { + shared_ptr b = cvs.stk.top(); + cvs.push_branch(i->second, false); + if (curr_commit.alive) + b->live_at_beginning[cvs.curr_file_interned] = curr_commit.version; + b->note_branchpoint(curr_commit.time); + cvs.pop_branch(); + } + } + // recursively follow any branch commits coming from the branchpoint boost::shared_ptr curr_delta = r.deltas.find(curr_version)->second; @@ -638,50 +585,41 @@ i != curr_delta->branches.end(); ++i) { string branch; + data branch_data; + hexenc branch_id; + vector< piece > branch_lines; bool priv = false; map::const_iterator be = cvs.branch_first_entries.find(*i); - + if (be != cvs.branch_first_entries.end()) branch = be->second; else priv = true; L(F("following RCS branch %s = '%s'\n") % (*i) % branch); - vector< piece > branch_lines; - construct_version(*curr_lines, *i, branch_lines, r); - - data branch_data; - hexenc branch_id; + + construct_version(*curr_lines, *i, branch_lines, r); insert_into_db(curr_data, curr_id, - branch_lines, branch_data, branch_id, db); - - // update the branch beginning time to reflect improved - // information, if there was a commit on the branch - if (!priv) - cvs.note_state_at_branch_beginning(r, branch, - *i, - branch_id, - cvs_history::note_branch_first_commit); - - cvs.push_branch (branch, priv); - cvs.note_file_edge (r, curr_version, *i, - file_id(curr_id), file_id(branch_id)); + branch_lines, branch_data, branch_id, db); + + cvs.push_branch(branch, priv); process_branch(*i, branch_lines, branch_data, branch_id, r, db, cvs); cvs.pop_branch(); L(F("finished RCS branch %s = '%s'\n") % (*i) % branch); } - + if (!r.deltas.find(curr_version)->second->next.empty()) - { // advance - curr_data = next_data; - curr_id = next_id; - curr_version = next_version; - swap(next_lines, curr_lines); - next_lines->clear(); - } + { + // advance + curr_data = next_data; + curr_id = next_id; + curr_version = next_version; + swap(next_lines, curr_lines); + next_lines->clear(); + } else break; - } + } } @@ -713,10 +651,10 @@ { // create the head state in case it is a loner - cvs_key k; - shared_ptr s; - L(F("noting head version %s : %s\n") % cvs.curr_file % r.admin.head); - cvs.find_key_and_state (r, r.admin.head, k, s); + // cvs_key k; + // shared_ptr s; + // L(F("noting head version %s : %s\n") % cvs.curr_file % r.admin.head); + // cvs.find_key_and_state (r, r.admin.head, k, s); } global_pieces.reset(); @@ -730,67 +668,24 @@ void -import_rcs_file(fs::path const & filename, database & db) +test_parse_rcs_file(fs::path const & filename, database & db) { cvs_history cvs; - I(! fs::is_directory(filename)); I(! filename.empty()); + I(fs::exists(filename)); + I(! fs::is_directory(filename)); - fs::path leaf = mkpath(filename.leaf()); - fs::path branch = mkpath(filename.branch_path().string()); - - I(! branch.empty()); - I(! leaf.empty()); - I( fs::is_directory(branch)); - I( fs::exists(branch)); - - I(chdir(filename.branch_path().native_directory_string().c_str()) == 0); - - I(fs::exists(leaf)); - - import_rcs_file_with_cvs(leaf.native_file_string(), db, cvs); + P(F("parsing RCS file %s\n") % filename.string()); + rcs_file r; + parse_rcs_file(filename.string(), r); + P(F("parsed RCS file %s OK\n") % filename.string()); } // CVS importing stuff follows -/* - we define a "cvs key" as a triple of author, commit time and - changelog. the equality of keys is a bit blurry due to a window of time - in which "the same" commit may begin and end. the window is evaluated - during the multimap walk though; for insertion in the multimap a true > - is used. a key identifies a particular commit. - - we reconstruct the history of a CVS archive by accumulating file edges - into archive nodes. each node is called a "cvs_state", but it is really a - collection of file *edges* leading into that archive state. we accumulate - file edges by walking up the trunk and down the branches of each RCS file. - - once we've got all the edges accumulated into archive nodes, we walk the - tree of cvs_states, up through the trunk and down through the branches, - carrying a manifest_map with us during the walk. for each edge, we - construct either the parent or child state of the edge (depending on - which way we're walking) and then calculate and write out a manifest - delta for the difference between the previous and current manifest map. we - also write out manifest certs, though the direction of ancestry changes - depending on whether we're going up the trunk or down the branches. - - */ - -cvs_file_edge::cvs_file_edge (file_id const & pv, file_path const & pp, bool pl, - file_id const & cv, file_path const & cp, bool cl, - cvs_history & cvs) : - parent_version(cvs.file_version_interner.intern(pv.inner()())), - parent_path(cvs.path_interner.intern(pp())), - parent_live_p(pl), - child_version(cvs.file_version_interner.intern(cv.inner()())), - child_path(cvs.path_interner.intern(cp())), - child_live_p(cl) -{ -} - static void split_version(string const & v, vector & vs) { @@ -814,49 +709,6 @@ } } -cvs_key::cvs_key(rcs_file const & r, string const & version, - cvs_history & cvs) : - is_synthetic_branch_founding_commit(false) -{ - map >::const_iterator delta = - r.deltas.find(version); - I(delta != r.deltas.end()); - - map >::const_iterator deltatext = - r.deltatexts.find(version); - I(deltatext != r.deltatexts.end()); - - { - struct tm t; - // We need to initialize t to all zeros, because strptime has a habit of - // leaving bits of the data structure alone, letting garbage sneak into - // our output. - memset(&t, 0, sizeof(t)); - char const * dp = delta->second->date.c_str(); - L(F("Calculating time of %s\n") % dp); -#ifdef WIN32 - I(sscanf(dp, "%d.%d.%d.%d.%d.%d", &(t.tm_year), &(t.tm_mon), - &(t.tm_mday), &(t.tm_hour), &(t.tm_min), &(t.tm_sec))==6); - t.tm_mon--; - // Apparently some RCS files have 2 digit years, others four; tm always - // wants a 2 (or 3) digit year (years since 1900). - if (t.tm_year > 1900) - t.tm_year-=1900; -#else - if (strptime(dp, "%y.%m.%d.%H.%M.%S", &t) == NULL) - I(strptime(dp, "%Y.%m.%d.%H.%M.%S", &t) != NULL); -#endif - time=mktime(&t); - L(F("= %i\n") % time); - id = nextid++; - } - - branch = cvs.bstk.top(); - changelog = cvs.changelog_interner.intern(deltatext->second->log); - author = cvs.author_interner.intern(delta->second->author); -} - - cvs_history::cvs_history() : n_versions("versions", "v", 1), n_tree_branches("branches", "b", 1) @@ -879,6 +731,7 @@ && ss.substr(last_slash-5,6)=="Attic/") ss.erase(last_slash-5,6); curr_file = file_path(ss); + curr_file_interned = path_interner.intern(ss); } void cvs_history::index_branchpoint_symbols(rcs_file const & r) @@ -917,308 +770,535 @@ } } -void -cvs_history::note_state_at_branch_beginning(rcs_file const & r, - string const & branchname, - string const & version, - file_id const & ident, - note_type nt) + + +void +cvs_history::push_branch(string const & branch_name, bool private_branch) { - // here we manufacture a single synthetic commit -- the "branch - // birth" commit -- representing the cumulative affect of all the - // tag -b operations the user once performed. it has a synthetic - // author ("cvs_import") and a synthetic log message ("beginning of - // branch foo"), and occurs at the time of the *last* branchpoint of - // any files which entered this branch. - // - // note that this does not establish a revision-ancestry - // relationship between the branchpoint and the branch. the branch - // is considered a child of the null revision, as far as monotone is - // concerned. + shared_ptr branch; + + string bname = base_branch + "." + branch_name; + I(stk.size() > 0); - L(F("noting branchpoint for %s = %s\n") % branchname % version); + if (private_branch) + { + stk.push(stk.top()); + bstk.push(bstk.top()); + return; + } + else + { + map >::const_iterator b = branches.find(bname); + if (b == branches.end()) + { + branch = shared_ptr(new cvs_branch()); + branches.insert(make_pair(bname, branch)); + ++n_tree_branches; + } + else + branch = b->second; + + stk.push(branch); + bstk.push(branch_interner.intern(bname)); + } +} - push_branch(branchname, false); +void +cvs_history::pop_branch() +{ + I(stk.size() > 1); + stk.pop(); + bstk.pop(); +} - cvs_key k; - shared_ptr s; - I(stk.size() > 0); - shared_ptr branch = stk.top(); - string branch_birth_message = "beginning of branch " + branchname; - string branch_birth_author = "cvs_import"; +class +cvs_tree_walker + : public tree_walker +{ + cvs_history & cvs; + database & db; +public: + cvs_tree_walker(cvs_history & c, database & d) : + cvs(c), db(d) + { + } + virtual void visit_file(file_path const & path) + { + string file = path(); + if (file.substr(file.size() - 2) == string(",v")) + { + try + { + import_rcs_file_with_cvs(file, db, cvs); + } + catch (oops const & o) + { + W(F("error reading RCS file %s: %s\n") % file % o.what()); + } + } + else + L(F("skipping non-RCS file %s\n") % file); + } + virtual ~cvs_tree_walker() {} +}; - cvs_changelog clog = changelog_interner.intern(branch_birth_message); - cvs_author auth = author_interner.intern(branch_birth_author); - // note: SBFC is short for "synthetic branch-founding commit" - if (branch->empty()) - { - I(nt == note_branchpoint); - find_key_and_state (r, version, k, s); - branch->erase(k); - k.changelog = clog; - k.author = auth; - k.add_file(curr_file, version); - k.is_synthetic_branch_founding_commit = true; - branch->insert(make_pair(k, s)); - L(F("added SBFC for %s at id %d, time %d\n") - % branchname % k.id % k.time); - } - else - { - cvs_key nk(r, version, *this); - - cvs_branch::iterator i = branch->end(); - i--; - I(i->first.is_synthetic_branch_founding_commit); - I(i->first.author == auth); - I(i->first.changelog == clog); - - k = i->first; - s = i->second; - L(F("found existing SBFC at id %d, time %d\n") - % k.id % k.time); - if (nt == note_branchpoint - && nk.time > k.time - && branch_has_commit[branchname] == false) - { - L(F("moving SBFC for %s to later branchpoint at %d\n") - % branchname % nk.time); - branch->erase(i); - k.time = nk.time; - k.add_file(curr_file, version); - branch->insert(make_pair(k, s)); - } - else if (nt == note_branch_first_commit - && nk.time < k.time) - { - L(F("moving SBFC for %s to earlier branch commit at %d\n") - % branchname % nk.time); - branch->erase(i); - k.time = nk.time; - branch->insert(make_pair(k, s)); - branch_has_commit[branchname] = true; - } +// +// our task here is to produce a sequence of revision descriptions +// from the per-file commit records we have. we do this by rolling +// forwards through the temporally sorted file-commit list +// accumulating file-commits into revisions and flushing the +// revisions when we feel they are "complete". +// +// revisions have to have a time associated with them. this time +// will be the first time of any commit associated with the +// revision. they have an author and a changelog, which is shared +// by all the file-commits in the revision. +// +// there might be multiple revisions overlapping in time. this is +// legal wrt. CVS. we keep a set, and search all members of the set +// for the best match. +// +// consider this situation of overlapping revisions: +// +// +---------------+ +---------------+ +---------------+ +// | rev #1 @ 0011 | | rev #2 @ 0012 | | rev #3 @ 0013 | +// |~~~~~~~~~~~~~~~| |~~~~~~~~~~~~~~~| |~~~~~~~~~~~~~~~| +// | patch foo.txt | | patch bar.txt | | patch baz.txt | +// +---------------+ +---------------+ +---------------+ +// +// suppose you have this situation and you run across a "patch +// bar.txt" commit at timestamp 0014. what do you do? +// +// - you know that rev #2 cannot accept this commit, simply because +// two commits on the same file makes *two* revisions, not one. +// +// - perhaps rev #3 could accept it; after all, it could be that the +// commit associated with rev #2 released its commit lock, and the +// commit associated with rev #3 quickly updated and committed at +// 0013, finishing off at 0014. +// +// - can rev #1 accept it? no. because CVS calcualted the version it +// expected to see in bar.txt before calling up the server, when +// committing rev #1. the version it expected to see was the version +// in bar.txt *before* time 0012; that is, before rev #2 had any affect +// on bar.txt. when it contacted the server, the commit associated +// with rev #1 would have aborted if it had seen any other number. +// so rev #1 could not start before an edit to bar.txt and then +// include its own edit to bar.txt. +// +// so we have only one case where bar.txt can be accepted. if the +// commit is not accepted into a legal rev (outside the window, +// wrong changelog/author) it starts a new revision. +// +// as we scan forwards, if we hit timestamps which lie beyond rev #n's +// window, we flush rev #n. +// +// if there are multiple coincident and legal revs to direct a +// commit to (all with the same author/changelog), we direct the +// commit to the rev with the closest initial timestamp. that is, +// the *latest* beginning time. - } +struct +cvs_cluster +{ + time_t first_time; + cvs_author author; + cvs_changelog changelog; + set tags; - if (nt == note_branchpoint) - { - map >::const_iterator del; - del = r.deltas.find(version); - I(del != r.deltas.end()); - bool alive = del->second->state != "dead"; - - s->in_edges.insert(cvs_file_edge(file_id(), curr_file, alive, - ident, curr_file, alive, - *this)); - } + cvs_cluster(time_t t, + cvs_author a, + cvs_changelog c) + : first_time(t), + author(a), + changelog(c) + {} - pop_branch(); -} + struct entry + { + bool live; + cvs_version version; + time_t time; + entry(bool l, cvs_version v, time_t t) + : live(l), + version(v), + time(t) + {} + }; -bool -cvs_history::find_key_and_state(rcs_file const & r, - string const & version, - cvs_key & key, - shared_ptr & state) + typedef map entry_map; + entry_map entries; +}; + + +struct +cluster_consumer { - I(stk.size() > 0); - shared_ptr branch = stk.top(); - cvs_key nk(r, version, *this); + cvs_history & cvs; + app_state & app; + string const & branchname; + cvs_branch const & branch; + map live_files; + ticker & n_manifests; + ticker & n_revisions; - nk.add_file(curr_file, version); - // key+(window/2) is in the future, key-(window/2) is in the past. the - // past is considered "greater than" the future in this map, so we take: - // - // - new, the lower bound of key+(window/2) in the map - // - old, the upper bound of key-(window/2) in the map - // - // and search all the nodes inside this section, from new to old bound. + struct prepared_revision + { + prepared_revision(revision_id i, + shared_ptr r, + cvs_cluster const & c); + revision_id rid; + shared_ptr rev; + time_t time; + cvs_author author; + cvs_changelog changelog; + vector tags; + }; - map< cvs_key, shared_ptr >::iterator i_new, i_old, i; - cvs_key k_new(nk), k_old(nk); + vector preps; - if (static_cast(k_new.time + constants::cvs_window / 2) > k_new.time) - k_new.time += constants::cvs_window / 2; + manifest_map parent_map, child_map; + manifest_id parent_mid, child_mid; + revision_id parent_rid, child_rid; - if (static_cast(k_old.time - constants::cvs_window / 2) < k_old.time) - k_old.time -= constants::cvs_window / 2; - - i_new = branch->lower_bound(k_new); - i_old = branch->upper_bound(k_old); + cluster_consumer(cvs_history & cvs, + app_state & app, + string const & branchname, + cvs_branch const & branch, + ticker & n_manifests, + ticker & n_revs); - for (i = i_new; i != i_old; ++i) - { - if (i->first.similar_enough(nk)) + void consume_cluster(cvs_cluster const & c, + bool head_p); + void build_change_set(cvs_cluster const & c, + change_set & cs); + void store_manifest_edge(bool head_p); + void store_auxiliary_certs(prepared_revision const & p); + void store_revisions(); +}; + +typedef shared_ptr +cluster_ptr; + +struct +cluster_ptr_lt +{ + bool operator()(cluster_ptr const & a, + cluster_ptr const & b) const + { + return a->first_time < b->first_time; + } +}; + +typedef set +cluster_set; + +void +import_branch(cvs_history & cvs, + app_state & app, + string const & branchname, + shared_ptr const & branch, + ticker & n_manifests, + ticker & n_revs) +{ + cluster_set clusters; + cluster_consumer cons(cvs, app, branchname, *branch, n_manifests, n_revs); + unsigned long commits_remaining = branch->lineage.size(); + + // step 1: sort the lineage + sort(branch->lineage.begin(), branch->lineage.end()); + + for (vector::const_iterator i = branch->lineage.begin(); + i != branch->lineage.end(); ++i) + { + commits_remaining--; + + L(F("examining next commit [t:%d] [a:%d] [c:%d]\n") + % i->time % i->author % i->changelog); + + // step 2: expire all clusters from the beginning of the set which + // have passed the window size + while (!clusters.empty()) { - key = i->first; - state = i->second; - branch->erase(i); - key.add_file(curr_file, version); - branch->insert(make_pair(key,state)); - return true; + cluster_set::const_iterator j = clusters.begin(); + if ((*j)->first_time + window < i->time) + { + L(F("expiring cluster\n")); + cons.consume_cluster(**j, false); + clusters.erase(j); + } + else + break; } + + // step 3: find the last still-live cluster to have touched this + // file + time_t last_modify_time = 0; + for (cluster_set::const_iterator j = clusters.begin(); + j != clusters.end(); ++j) + { + cvs_cluster::entry_map::const_iterator k = (*j)->entries.find(i->path); + if (k != (*j)->entries.end() && + k->second.time > last_modify_time) + last_modify_time = k->second.time; + } + L(F("last modification time is %d\n") % last_modify_time); + + // step 4: find a cluster which starts after the + // last_modify_time, which doesn't modify the file in question, + // and which contains the same author and changelog as our + // commit + cluster_ptr target; + for (cluster_set::const_iterator j = clusters.begin(); + j != clusters.end(); ++j) + { + if (((*j)->first_time > last_modify_time) + && ((*j)->author == i->author) + && ((*j)->changelog == i->changelog) + && ((*j)->entries.find(i->path) == (*j)->entries.end())) + { + L(F("picked existing cluster target\n")); + target = (*j); + } + } + + // if we're still not finding an active cluster, + // this is probably the first commit in it. make + // a new one. + if (!target) + { + L(F("building new cluster [t:%d] [a:%d] [c:%d]\n") + % i->time % i->author % i->changelog); + target = cluster_ptr(new cvs_cluster(i->time, + i->author, + i->changelog)); + clusters.insert(target); + } + + I(target); + target->entries.insert(make_pair(i->path, + cvs_cluster::entry(i->alive, + i->version, + i->time))); + for (vector::const_iterator j = i->tags.begin(); + j != i->tags.end(); ++j) + { + target->tags.insert(*j); + } } - key = nk; - state = shared_ptr(new cvs_state()); - branch->insert(make_pair(key, state)); - return false; -} -void -cvs_history::push_branch(string const & branch_name, bool private_branch) -{ - shared_ptr branch; - I(stk.size() > 0); - - map >::const_iterator b = branches.find(branch_name); - if (b == branches.end()) + // now we are done this lineage; flush all remaining clusters + L(F("finished branch commits, writing all pending clusters\n")); + while (!clusters.empty()) { - branch = shared_ptr(new cvs_branch()); - if (!private_branch) - branches.insert(make_pair(branch_name, branch)); + cons.consume_cluster(**clusters.begin(), clusters.size() == 1); + clusters.erase(clusters.begin()); } - else - branch = b->second; + L(F("finished writing pending clusters\n")); - stk.push(branch); + cons.store_revisions(); - if (private_branch) - bstk.push(bstk.top()); - else - bstk.push(branch_interner.intern(base_branch + "." + branch_name)); } + void -cvs_history::note_file_edge(rcs_file const & r, - string const & prev_rcs_version_num, - string const & next_rcs_version_num, - file_id const & prev_version, - file_id const & next_version) +import_cvs_repo(fs::path const & cvsroot, + app_state & app) { + N(!fs::exists(cvsroot / "CVSROOT"), + F("%s appears to be a CVS repository root directory\n" + "try importing a module instead, with 'cvs_import %s/") + % cvsroot.native_directory_string() % cvsroot.native_directory_string()); + + { + // early short-circuit to avoid failure after lots of work + rsa_keypair_id key; + N(guess_default_key(key,app), + F("no unique private key for cert construction")); + require_password(key, app); + } - cvs_key k; - shared_ptr s; + cvs_history cvs; + N(app.branch_name() != "", F("need base --branch argument for importing")); + cvs.base_branch = app.branch_name(); - I(stk.size() > 0); - I(! curr_file().empty()); + // push the trunk + cvs.trunk = shared_ptr(new cvs_branch()); + cvs.stk.push(cvs.trunk); + cvs.bstk.push(cvs.branch_interner.intern(cvs.base_branch)); - L(F("noting file edge %s -> %s\n") % prev_rcs_version_num % next_rcs_version_num); + { + transaction_guard guard(app.db); + cvs_tree_walker walker(cvs, app.db); + N( fs::exists(cvsroot), + F("path %s does not exist") % cvsroot.string()); + N( fs::is_directory(cvsroot), + F("path %s is not a directory") % cvsroot.string()); + app.db.ensure_open(); + N(chdir(cvsroot.native_directory_string().c_str()) == 0, + F("could not change directory to %s") % cvsroot.string()); + walk_tree(walker); + guard.commit(); + } - // we can't use operator[] since it is non-const - std::map >::const_iterator - prev_delta = r.deltas.find(prev_rcs_version_num), - next_delta = r.deltas.find(next_rcs_version_num); - I(prev_delta!=r.deltas.end()); - I(next_delta!=r.deltas.end()); - bool prev_alive = prev_delta->second->state!="dead"; - bool next_alive = next_delta->second->state!="dead"; - - L(F("note_file_edge %s %d -> %s %d\n") - % prev_rcs_version_num % prev_alive - % next_rcs_version_num % next_alive); + I(cvs.stk.size() == 1); - // we always aggregate in-edges in children, but we will also create - // parents as we encounter them. - if (stk.size() == 1) - { - // we are on the trunk, prev is child, next is parent. - L(F("noting trunk edge %s : %s -> %s\n") % curr_file - % next_rcs_version_num - % prev_rcs_version_num); - find_key_and_state (r, next_rcs_version_num, k, s); // just to create it if necessary - find_key_and_state (r, prev_rcs_version_num, k, s); + ticker n_revs("revisions", "r", 1); + ticker n_manifests("manifests", "m", 1); - L(F("trunk edge entering key state %d\n") % k.id); - s->in_edges.insert(cvs_file_edge(next_version, curr_file, next_alive, - prev_version, curr_file, prev_alive, - *this)); - } - else + while (cvs.branches.size() > 0) { - // we are on a branch, prev is parent, next is child. - L(F("noting branch edge %s : %s -> %s\n") % curr_file - % prev_rcs_version_num - % next_rcs_version_num); - find_key_and_state (r, next_rcs_version_num, k, s); - L(F("branch edge on %s entering key state %d\n") - % branch_interner.lookup(k.branch) % k.id); - s->in_edges.insert(cvs_file_edge(prev_version, curr_file, prev_alive, - next_version, curr_file, next_alive, - *this)); - } - - ++n_versions; -} + transaction_guard guard(app.db); + map >::const_iterator i = cvs.branches.begin(); + string branchname = i->first; + shared_ptr branch = i->second; + L(F("branch %s has %d entries\n") % branchname % branch->lineage.size()); + import_branch(cvs, app, branchname, branch, n_manifests, n_revs); -void -cvs_history::pop_branch() -{ - I(stk.size() > 1); - stk.pop(); - bstk.pop(); -} + // free up some memory + cvs.branches.erase(branchname); + guard.commit(); + } - -class -cvs_tree_walker - : public tree_walker -{ - cvs_history & cvs; - database & db; -public: - cvs_tree_walker(cvs_history & c, database & d) : - cvs(c), db(d) { + transaction_guard guard(app.db); + L(F("trunk has %d entries\n") % cvs.trunk->lineage.size()); + import_branch(cvs, app, cvs.base_branch, cvs.trunk, n_manifests, n_revs); + guard.commit(); } - virtual void visit_file(file_path const & path) + + // now we have a "last" rev for each tag { - string file = path(); - if (file.substr(file.size() - 2) == string(",v")) + ticker n_tags("tags", "t", 1); + packet_db_writer dbw(app); + transaction_guard guard(app.db); + for (map >::const_iterator i = cvs.resolved_tags.begin(); + i != cvs.resolved_tags.end(); ++i) { - import_rcs_file_with_cvs(file, db, cvs); + string tag = cvs.tag_interner.lookup(i->first); + ui.set_tick_trailer("marking tag " + tag); + cert_revision_tag(i->second.second, tag, app, dbw); + ++n_tags; } - else - L(F("skipping non-RCS file %s\n") % file); + guard.commit(); } - virtual ~cvs_tree_walker() {} -}; -static void -store_manifest_edge(manifest_map const & parent, - manifest_map const & child, - manifest_id const & parent_mid, - manifest_id const & child_mid, - app_state & app, - cvs_history & cvs, - bool head_manifest_p) + return; + +} + +cluster_consumer::cluster_consumer(cvs_history & cvs, + app_state & app, + string const & branchname, + cvs_branch const & branch, + ticker & n_mans, + ticker & n_revs) + : cvs(cvs), + app(app), + branchname(branchname), + branch(branch), + n_manifests(n_mans), + n_revisions(n_revs) { + if (!branch.live_at_beginning.empty()) + { + cvs_author synthetic_author = + cvs.author_interner.intern("cvs_import"); + + cvs_changelog synthetic_cl = + cvs.changelog_interner.intern("beginning of branch " + + branchname); + + time_t synthetic_time = branch.beginning(); + cvs_cluster initial_cluster(synthetic_time, + synthetic_author, + synthetic_cl); + + L(F("initial cluster on branch %s has %d live entries\n") % + branchname % branch.live_at_beginning.size()); - L(F("storing manifest %s (base %s)\n") % parent_mid % child_mid); + for (map::const_iterator i = branch.live_at_beginning.begin(); + i != branch.live_at_beginning.end(); ++i) + { + cvs_cluster::entry e(true, i->second, synthetic_time); + L(F("initial cluster contains %s at %s\n") % + cvs.path_interner.lookup(i->first) % + cvs.file_version_interner.lookup(i->second)); + initial_cluster.entries.insert(make_pair(i->first, e)); + } + consume_cluster(initial_cluster, false); + } +} + +cluster_consumer::prepared_revision::prepared_revision(revision_id i, + shared_ptr r, + cvs_cluster const & c) + : rid(i), + rev(r), + time(c.first_time), + author(c.author), + changelog(c.changelog) +{ + for (set::const_iterator i = c.tags.begin(); + i != c.tags.end(); ++i) + { + tags.push_back(*i); + } +} - if (head_manifest_p) + +void +cluster_consumer::store_revisions() +{ + for (vector::const_iterator i = preps.begin(); + i != preps.end(); ++i) { + if (! app.db.revision_exists(i->rid)) + { + data tmp; + write_revision_set(*(i->rev), tmp); + /* + cout << "+++WRITING REVISION" << endl; + cout << tmp << endl; + cout << "---WRITING REVISION" << endl; + */ + app.db.put_revision(i->rid, *(i->rev)); + store_auxiliary_certs(*i); + ++n_revisions; + } + } +} + +void +cluster_consumer::store_manifest_edge(bool head_p) +{ + L(F("storing manifest '%s' (base %s)\n") % parent_mid % child_mid); + ++n_manifests; + + if (head_p) + { L(F("storing head %s\n") % child_mid); // a branch has one very important manifest: the head. this is // the "newest" of all manifests within the branch (including - // the trunk), and we store it in its entirety. + // the trunk), and we store it in its entirety, before the + // cluster consumer is destroyed. if (! app.db.manifest_version_exists(child_mid)) { manifest_data mdat; - write_manifest_map(child, mdat); + write_manifest_map(child_map, mdat); app.db.put_manifest(child_mid, mdat); } } if (null_id(parent_mid)) { - L(F("skipping null manifest\n")); + L(F("skipping delta to null manifest\n")); return; } @@ -1238,7 +1318,7 @@ { L(F("writing full manifest %s\n") % parent_mid); manifest_data mdat; - write_manifest_map(parent, mdat); + write_manifest_map(parent_map, mdat); app.db.put_manifest(parent_mid, mdat); } return; @@ -1256,214 +1336,106 @@ // run from child (new) -> parent (old). delta del; - diff(child, parent, del); + diff(child_map, parent_map, del); rcs_put_raw_manifest_edge(parent_mid.inner(), child_mid.inner(), del, app.db); } - -static void -store_auxiliary_certs(cvs_key const & key, - revision_id const & id, - app_state & app, - cvs_history const & cvs) +void +cluster_consumer::store_auxiliary_certs(prepared_revision const & p) { packet_db_writer dbw(app); - cert_revision_in_branch(id, cert_value(cvs.branch_interner.lookup(key.branch)), app, dbw); - cert_revision_author(id, cvs.author_interner.lookup(key.author), app, dbw); - cert_revision_changelog(id, cvs.changelog_interner.lookup(key.changelog), app, dbw); - cert_revision_date_time(id, key.time, app, dbw); -} -static void -build_change_set(shared_ptr state, - manifest_map const & state_map, - cvs_history & cvs, - change_set & cs) -{ - change_set empty; - cs = empty; + for (vector::const_iterator i = p.tags.begin(); + i != p.tags.end(); ++i) + { + map >::const_iterator j + = cvs.resolved_tags.find(*i); - for (set::const_iterator f = state->in_edges.begin(); - f != state->in_edges.end(); ++f) - { - file_id fid(cvs.file_version_interner.lookup(f->child_version)); - file_path pth(cvs.path_interner.lookup(f->child_path)); - if (!f->child_live_p) - { - if (f->parent_live_p) + if (j != cvs.resolved_tags.end()) + { + if (j->second.first < p.time) { - L(F("deleting entry state '%s' on '%s'\n") % fid % pth); - cs.delete_file(pth); + // move the tag forwards + cvs.resolved_tags.erase(*i); + cvs.resolved_tags.insert(make_pair(*i, make_pair(p.time, p.rid))); } - else - { - // it can actually happen that we have a file that went from - // dead to dead. when a file is created on a branch, cvs first - // _commits a deleted file_ on mainline, and then branches from - // it and resurrects it. In such cases, we should just ignore - // the file, it doesn't actually exist. So, in this block, we - // do nothing. - } } - else + else { - manifest_map::const_iterator i = state_map.find(pth); - if (i == state_map.end()) + cvs.resolved_tags.insert(make_pair(*i, make_pair(p.time, p.rid))); + } + } + + cert_revision_in_branch(p.rid, cert_value(branchname), app, dbw); + cert_revision_author(p.rid, cvs.author_interner.lookup(p.author), app, dbw); + cert_revision_changelog(p.rid, cvs.changelog_interner.lookup(p.changelog), app, dbw); + cert_revision_date_time(p.rid, p.time, app, dbw); +} + +void +cluster_consumer::build_change_set(cvs_cluster const & c, + change_set & cs) +{ + for (cvs_cluster::entry_map::const_iterator i = c.entries.begin(); + i != c.entries.end(); ++i) + { + file_path pth(cvs.path_interner.lookup(i->first)); + file_id fid(cvs.file_version_interner.lookup(i->second.version)); + if (i->second.live) + { + map::const_iterator e = live_files.find(i->first); + if (e == live_files.end()) { L(F("adding entry state '%s' on '%s'\n") % fid % pth); - cs.add_file(pth, fid); + cs.add_file(pth, fid); + live_files[i->first] = i->second.version; } - else if (manifest_entry_id(i) == fid) + else if (e->second != i->second.version) { - L(F("skipping preserved entry state '%s' on '%s'\n") - % fid % pth); + file_id old_fid(cvs.file_version_interner.lookup(e->second)); + L(F("applying state delta on '%s' : '%s' -> '%s'\n") + % pth % old_fid % fid); + cs.apply_delta(pth, old_fid, fid); + live_files[i->first] = i->second.version; } - else + } + else + { + map::const_iterator e = live_files.find(i->first); + if (e != live_files.end()) { - L(F("applying state delta on '%s' : '%s' -> '%s'\n") - % pth % manifest_entry_id(i) % fid); - cs.apply_delta(pth, manifest_entry_id(i), fid); + L(F("deleting entry state '%s' on '%s'\n") % fid % pth); + cs.delete_file(pth); + live_files.erase(i->first); } - } + } } - L(F("logical changeset from parent -> child has %d file state changes\n") - % state->in_edges.size()); } -static void -import_branch_states(ticker & n_edges, - cvs_branch & branch, - cvs_history & cvs, - app_state & app, - vector< pair > & revisions) -{ - manifest_map parent_map, child_map; - manifest_id parent_mid, child_mid; - revision_id parent_rid, child_rid; - - // we look through the branch temporally *backwards* from oldest to - // newest +void +cluster_consumer::consume_cluster(cvs_cluster const & c, + bool head_p) +{ + shared_ptr rev(new revision_set()); + boost::shared_ptr cs(new change_set()); + build_change_set(c, *cs); - for (cvs_branch::reverse_iterator i = branch.rbegin(); - i != branch.rend(); ++i) - { - L(F("importing branch %s, state [%d: %s @ %d]\n") - % cvs.branch_interner.lookup(i->first.branch) - % i->first.id - % cvs.author_interner.lookup(i->first.author) - % i->first.time); + apply_change_set(*cs, child_map); + calculate_ident(child_map, child_mid); - revision_set rev; - boost::shared_ptr cs(new change_set()); - build_change_set(i->second, parent_map, cvs, *cs); + rev->new_manifest = child_mid; + rev->edges.insert(make_pair(parent_rid, make_pair(parent_mid, cs))); + calculate_ident(*rev, child_rid); - apply_change_set(*cs, child_map); - calculate_ident(child_map, child_mid); + store_manifest_edge(head_p); - rev.new_manifest = child_mid; - rev.edges.insert(make_pair(parent_rid, make_pair(parent_mid, cs))); - calculate_ident(rev, child_rid); + L(F("consumed cluster %s (parent '%s')\n") % child_rid % rev->edges.begin()->first); + preps.push_back(prepared_revision(child_rid, rev, c)); - revisions.push_back(make_pair(i->first, rev)); - - store_manifest_edge(parent_map, child_map, - parent_mid, child_mid, - app, cvs, i->first == branch.begin()->first); - - // now apply same change set to parent_map, making parent_map == child_map - apply_change_set(*cs, parent_map); - parent_mid = child_mid; - parent_rid = child_rid; - ++n_edges; - } + // now apply same change set to parent_map, making parent_map == child_map + apply_change_set(*cs, parent_map); + parent_mid = child_mid; + parent_rid = child_rid; } - -void -import_cvs_repo(fs::path const & cvsroot, - app_state & app) -{ - N(!fs::exists(cvsroot / "CVSROOT"), - F("%s appears to be a CVS repository root directory\n" - "try importing a module instead, with 'cvs_import %s/") - % cvsroot.native_directory_string() % cvsroot.native_directory_string()); - - { - // early short-circuit to avoid failure after lots of work - rsa_keypair_id key; - N(guess_default_key(key,app), - F("no unique private key for cert construction")); - require_password(key, app); - } - - cvs_history cvs; - N(app.branch_name() != "", F("need base --branch argument for importing")); - cvs.base_branch = app.branch_name(); - - // push the trunk - cvs.stk.push(shared_ptr(new cvs_branch())); - cvs.bstk.push(cvs.branch_interner.intern(cvs.base_branch)); - - { - transaction_guard guard(app.db); - cvs_tree_walker walker(cvs, app.db); - N( fs::exists(cvsroot), - F("path %s does not exist") % cvsroot.string()); - N( fs::is_directory(cvsroot), - F("path %s is not a directory") % cvsroot.string()); - app.db.ensure_open(); - N(chdir(cvsroot.native_directory_string().c_str()) == 0, - F("could not change directory to %s") % cvsroot.string()); - walk_tree(walker); - guard.commit(); - } - - P(F("phase 1 (version import) complete\n")); - - I(cvs.stk.size() == 1); - - vector< pair > revisions; - { - ticker n_branches("finished branches", "b", 1); - ticker n_edges("finished edges", "e", 1); - transaction_guard guard(app.db); - manifest_map root_manifest; - manifest_id root_mid; - revision_id root_rid; - - - ui.set_tick_trailer("building trunk"); - import_branch_states(n_edges, *cvs.stk.top(), cvs, app, revisions); - - for(map >::const_iterator branch = cvs.branches.begin(); - branch != cvs.branches.end(); ++branch) - { - ui.set_tick_trailer("building branch " + branch->first); - ++n_branches; - import_branch_states(n_edges, *(branch->second), cvs, app, revisions); - } - - P(F("phase 2 (ancestry reconstruction) complete\n")); - guard.commit(); - } - - { - ticker n_revisions("written revisions", "r", 1); - ui.set_tick_trailer(""); - transaction_guard guard(app.db); - for (vector< pair >::const_iterator - i = revisions.begin(); i != revisions.end(); ++i) - { - revision_id rid; - calculate_ident(i->second, rid); - if (! app.db.revision_exists(rid)) - app.db.put_revision(rid, i->second); - store_auxiliary_certs(i->first, rid, app, cvs); - ++n_revisions; - } - P(F("phase 3 (writing revisions) complete\n")); - guard.commit(); - } -} - --- rcs_import.hh +++ rcs_import.hh @@ -9,7 +9,7 @@ #include "vocab.hh" #include "database.hh" -void import_rcs_file(fs::path const & filename, database & db); +void test_parse_rcs_file(fs::path const & filename, database & db); void import_cvs_repo(fs::path const & cvsroot, app_state & app); #endif // __RCS_IMPORT_HH__ --- revision.cc +++ revision.cc @@ -137,8 +137,6 @@ std::set frontier; frontier.insert(child_id); - // FIXME: if we don't check the LCA already, check it. - while (depth-- > 0) { std::set next_frontier; --- sqlite/alter.c +++ sqlite/alter.c @@ -12,7 +12,7 @@ ** This file contains C code routines that used to generate VDBE code ** that implements the ALTER TABLE command. ** -** $Id: alter.c,v 1.6 2005/03/28 00:07:16 danielk1977 Exp $ +** $Id: alter.c,v 1.7 2005/06/06 21:19:57 drh Exp $ */ #include "sqliteInt.h" #include @@ -538,6 +538,7 @@ } pNew->iDb = iDb; pNew->addColOffset = pTab->addColOffset; + pNew->nRef = 1; /* Begin a transaction and increment the schema cookie. */ sqlite3BeginWriteOperation(pParse, 0, iDb); --- sqlite/btree.c +++ sqlite/btree.c @@ -9,7 +9,7 @@ ** May you share freely, never taking more than you give. ** ************************************************************************* -** $Id: btree.c,v 1.256 2005/03/29 13:17:46 drh Exp $ +** $Id: btree.c,v 1.261 2005/05/24 20:19:58 drh Exp $ ** ** This file implements a external (disk-based) database using BTrees. ** For a detailed discussion of BTrees, refer to @@ -211,12 +211,12 @@ #include "os.h" #include -/* -** This macro rounds values up so that if the value is an address it -** is guaranteed to be an address that is aligned to an 8-byte boundary. +/* Round up a number to the next larger multiple of 8. This is used +** to force 8-byte alignment on 64-bit architectures. */ -#define FORCE_ALIGNMENT(X) (((X)+7)&~7) +#define ROUND8(x) ((x+7)&~7) + /* The following value is the maximum cell size assuming a maximum page ** size give above. */ @@ -308,7 +308,6 @@ u8 autoVacuum; /* True if database supports auto-vacuum */ #endif u16 pageSize; /* Total number of bytes on a page */ - u16 psAligned; /* pageSize rounded up to a multiple of 8 */ u16 usableSize; /* Number of usable bytes on each page */ int maxLocal; /* Maximum local payload in non-LEAFDATA tables */ int minLocal; /* Minimum local payload in non-LEAFDATA tables */ @@ -714,7 +713,7 @@ used = sqliteMallocRaw( pPage->pBt->pageSize ); if( used==0 ) return; usableSize = pPage->pBt->usableSize; - assert( pPage->aData==&((unsigned char*)pPage)[-pPage->pBt->psAligned] ); + assert( pPage->aData==&((unsigned char*)pPage)[-pPage->pBt->pageSize] ); hdr = pPage->hdrOffset; assert( hdr==(pPage->pgno==1 ? 100 : 0) ); assert( pPage->pgno==sqlite3pager_pagenumber(pPage->aData) ); @@ -1017,7 +1016,7 @@ assert( pBt!=0 ); assert( pParent==0 || pParent->pBt==pBt ); assert( pPage->pgno==sqlite3pager_pagenumber(pPage->aData) ); - assert( pPage->aData == &((unsigned char*)pPage)[-pBt->psAligned] ); + assert( pPage->aData == &((unsigned char*)pPage)[-pBt->pageSize] ); if( pPage->pParent!=pParent && (pPage->pParent!=0 || pPage->isInit) ){ /* The parent page should never change unless the file is corrupt */ return SQLITE_CORRUPT; /* bkpt-CORRUPT */ @@ -1085,7 +1084,7 @@ int first; assert( sqlite3pager_pagenumber(data)==pPage->pgno ); - assert( &data[pBt->psAligned] == (unsigned char*)pPage ); + assert( &data[pBt->pageSize] == (unsigned char*)pPage ); assert( sqlite3pager_iswriteable(data) ); memset(&data[hdr], 0, pBt->usableSize - hdr); data[hdr] = flags; @@ -1114,7 +1113,7 @@ MemPage *pPage; rc = sqlite3pager_get(pBt->pPager, pgno, (void**)&aData); if( rc ) return rc; - pPage = (MemPage*)&aData[pBt->psAligned]; + pPage = (MemPage*)&aData[pBt->pageSize]; pPage->aData = aData; pPage->pBt = pBt; pPage->pgno = pgno; @@ -1153,7 +1152,7 @@ if( pPage ){ assert( pPage->aData ); assert( pPage->pBt ); - assert( &pPage->aData[pPage->pBt->psAligned]==(unsigned char*)pPage ); + assert( &pPage->aData[pPage->pBt->pageSize]==(unsigned char*)pPage ); sqlite3pager_unref(pPage->aData); } } @@ -1164,7 +1163,9 @@ ** happens. */ static void pageDestructor(void *pData, int pageSize){ - MemPage *pPage = (MemPage*)&((char*)pData)[FORCE_ALIGNMENT(pageSize)]; + MemPage *pPage; + assert( (pageSize & 7)==0 ); + pPage = (MemPage*)&((char*)pData)[pageSize]; if( pPage->pParent ){ MemPage *pParent = pPage->pParent; pPage->pParent = 0; @@ -1182,7 +1183,9 @@ ** page to agree with the restored data. */ static void pageReinit(void *pData, int pageSize){ - MemPage *pPage = (MemPage*)&((char*)pData)[FORCE_ALIGNMENT(pageSize)]; + MemPage *pPage; + assert( (pageSize & 7)==0 ); + pPage = (MemPage*)&((char*)pData)[pageSize]; if( pPage->isInit ){ pPage->isInit = 0; initPage(pPage, pPage->pParent); @@ -1216,8 +1219,6 @@ assert( sizeof(u32)==4 ); assert( sizeof(u16)==2 ); assert( sizeof(Pgno)==4 ); - assert( sizeof(ptr)==sizeof(char*) ); - assert( sizeof(uptr)==sizeof(ptr) ); pBt = sqliteMalloc( sizeof(*pBt) ); if( pBt==0 ){ @@ -1238,7 +1239,8 @@ pBt->readOnly = sqlite3pager_isreadonly(pBt->pPager); sqlite3pager_read_fileheader(pBt->pPager, sizeof(zDbHeader), zDbHeader); pBt->pageSize = get2byte(&zDbHeader[16]); - if( pBt->pageSize<512 || pBt->pageSize>SQLITE_MAX_PAGE_SIZE ){ + if( pBt->pageSize<512 || pBt->pageSize>SQLITE_MAX_PAGE_SIZE + || ((pBt->pageSize-1)&pBt->pageSize)!=0 ){ pBt->pageSize = SQLITE_DEFAULT_PAGE_SIZE; pBt->maxEmbedFrac = 64; /* 25% */ pBt->minEmbedFrac = 32; /* 12.5% */ @@ -1270,7 +1272,7 @@ #endif } pBt->usableSize = pBt->pageSize - nReserve; - pBt->psAligned = FORCE_ALIGNMENT(pBt->pageSize); + assert( (pBt->pageSize & 7)==0 ); /* 8-byte alignment of pageSize */ sqlite3pager_set_pagesize(pBt->pPager, pBt->pageSize); *ppBtree = pBt; return SQLITE_OK; @@ -1357,9 +1359,8 @@ } if( pageSize>=512 && pageSize<=SQLITE_MAX_PAGE_SIZE && ((pageSize-1)&pageSize)==0 ){ - pBt->pageSize = pageSize; - pBt->psAligned = FORCE_ALIGNMENT(pageSize); - sqlite3pager_set_pagesize(pBt->pPager, pageSize); + assert( (pageSize & 7)==0 ); + pBt->pageSize = sqlite3pager_set_pagesize(pBt->pPager, pageSize); } pBt->usableSize = pBt->pageSize - nReserve; return SQLITE_OK; @@ -1418,7 +1419,7 @@ ** if there is a locking protocol violation. */ static int lockBtree(Btree *pBt){ - int rc; + int rc, pageSize; MemPage *pPage1; if( pBt->pPage1 ) return SQLITE_OK; rc = getPage(pBt, 1, &pPage1); @@ -1437,12 +1438,16 @@ if( page1[18]>1 || page1[19]>1 ){ goto page1_init_failed; } - pBt->pageSize = get2byte(&page1[16]); - pBt->usableSize = pBt->pageSize - page1[20]; + pageSize = get2byte(&page1[16]); + if( ((pageSize-1)&pageSize)!=0 ){ + goto page1_init_failed; + } + assert( (pageSize & 7)==0 ); + pBt->pageSize = pageSize; + pBt->usableSize = pageSize - page1[20]; if( pBt->usableSize<500 ){ goto page1_init_failed; } - pBt->psAligned = FORCE_ALIGNMENT(pBt->pageSize); pBt->maxEmbedFrac = page1[21]; pBt->minEmbedFrac = page1[22]; pBt->minLeafFrac = page1[23]; @@ -1509,7 +1514,7 @@ if( pBt->inTrans==TRANS_NONE && pBt->pCursor==0 && pBt->pPage1!=0 ){ if( pBt->pPage1->aData==0 ){ MemPage *pPage = pBt->pPage1; - pPage->aData = &((char*)pPage)[-pBt->psAligned]; + pPage->aData = &((char*)pPage)[-pBt->pageSize]; pPage->pBt = pBt; pPage->pgno = 1; } @@ -3381,7 +3386,7 @@ assert( pBt->pPager!=0 ); aData = sqlite3pager_lookup(pBt->pPager, pgno); if( aData ){ - pThis = (MemPage*)&aData[pBt->psAligned]; + pThis = (MemPage*)&aData[pBt->pageSize]; assert( pThis->aData==aData ); if( pThis->isInit ){ if( pThis->pParent!=pNewParent ){ @@ -3888,15 +3893,19 @@ nMaxCells += 1+apOld[i]->nCell+apOld[i]->nOverflow; } + /* Make nMaxCells a multiple of 2 in order to preserve 8-byte + ** alignment */ + nMaxCells = (nMaxCells + 1)&~1; + /* ** Allocate space for memory structures */ apCell = sqliteMallocRaw( nMaxCells*sizeof(u8*) /* apCell */ + nMaxCells*sizeof(int) /* szCell */ - + sizeof(MemPage)*NB /* aCopy */ - + pBt->psAligned*(5+NB) /* aSpace */ - + (ISAUTOVACUUM ? nMaxCells : 0) /* aFrom */ + + ROUND8(sizeof(MemPage))*NB /* aCopy */ + + pBt->pageSize*(5+NB) /* aSpace */ + + (ISAUTOVACUUM ? nMaxCells : 0) /* aFrom */ ); if( apCell==0 ){ rc = SQLITE_NOMEM; @@ -3904,13 +3913,16 @@ } szCell = (int*)&apCell[nMaxCells]; aCopy[0] = (u8*)&szCell[nMaxCells]; + assert( ((aCopy[0] - (u8*)apCell) & 7)==0 ); /* 8-byte alignment required */ for(i=1; ipsAligned+sizeof(MemPage)]; + aCopy[i] = &aCopy[i-1][pBt->pageSize+ROUND8(sizeof(MemPage))]; + assert( ((aCopy[i] - (u8*)apCell) & 7)==0 ); /* 8-byte alignment required */ } - aSpace = &aCopy[NB-1][pBt->psAligned+sizeof(MemPage)]; + aSpace = &aCopy[NB-1][pBt->pageSize+ROUND8(sizeof(MemPage))]; + assert( ((aSpace - (u8*)apCell) & 7)==0 ); /* 8-byte alignment required */ #ifndef SQLITE_OMIT_AUTOVACUUM if( pBt->autoVacuum ){ - aFrom = &aSpace[5*pBt->psAligned]; + aFrom = &aSpace[5*pBt->pageSize]; } #endif @@ -3921,10 +3933,12 @@ ** process of being overwritten. */ for(i=0; ipsAligned]; - p->aData = &((u8*)p)[-pBt->psAligned]; - memcpy(p->aData, apOld[i]->aData, pBt->psAligned + sizeof(MemPage)); - p->aData = &((u8*)p)[-pBt->psAligned]; + MemPage *p = apCopy[i] = (MemPage*)&aCopy[i][pBt->pageSize]; + p->aData = &((u8*)p)[-pBt->pageSize]; + memcpy(p->aData, apOld[i]->aData, pBt->pageSize + sizeof(MemPage)); + /* The memcpy() above changes the value of p->aData so we have to + ** set it again. */ + p->aData = &((u8*)p)[-pBt->pageSize]; } /* @@ -3982,7 +3996,7 @@ szCell[nCell] = sz; pTemp = &aSpace[iSpace]; iSpace += sz; - assert( iSpace<=pBt->psAligned*5 ); + assert( iSpace<=pBt->pageSize*5 ); memcpy(pTemp, apDiv[i], sz); apCell[nCell] = pTemp+leafCorrection; #ifndef SQLITE_OMIT_AUTOVACUUM @@ -4207,13 +4221,13 @@ pCell = &aSpace[iSpace]; fillInCell(pParent, pCell, 0, info.nKey, 0, 0, &sz); iSpace += sz; - assert( iSpace<=pBt->psAligned*5 ); + assert( iSpace<=pBt->pageSize*5 ); pTemp = 0; }else{ pCell -= 4; pTemp = &aSpace[iSpace]; iSpace += sz; - assert( iSpace<=pBt->psAligned*5 ); + assert( iSpace<=pBt->pageSize*5 ); } rc = insertCell(pParent, nxDiv, pCell, sz, pTemp, 4); if( rc!=SQLITE_OK ) goto balance_cleanup; --- sqlite/build.c +++ sqlite/build.c @@ -22,7 +22,7 @@ ** COMMIT ** ROLLBACK ** -** $Id: build.c,v 1.318 2005/03/29 03:10:59 danielk1977 Exp $ +** $Id: build.c,v 1.326 2005/06/12 21:35:52 drh Exp $ */ #include "sqliteInt.h" #include @@ -266,9 +266,10 @@ } /* -** Unlink the given index from its table, then remove -** the index from the index hash table and free its memory -** structures. +** For the index called zIdxName which is found in the database iDb, +** unlike that index from its Table then remove the index from +** the index hash table and free all memory structures associated +** with the index. */ void sqlite3UnlinkAndDeleteIndex(sqlite3 *db, int iDb, const char *zIdxName){ Index *pIndex; @@ -426,6 +427,13 @@ if( pTable==0 ) return; + /* Do not delete the table until the reference count reaches zero. */ + pTable->nRef--; + if( pTable->nRef>0 ){ + return; + } + assert( pTable->nRef==0 ); + /* Delete all indices associated with this table */ for(pIndex = pTable->pIndex; pIndex; pIndex=pNext){ @@ -496,7 +504,7 @@ ** is obtained from sqliteMalloc() and must be freed by the calling ** function. ** -** Tokens are really just pointers into the original SQL text and so +** Tokens are often just pointers into the original SQL text and so ** are not \000 terminated and are not persistent. The returned string ** is \000 terminated and is persistent. */ @@ -598,6 +606,7 @@ */ int sqlite3CheckObjectName(Parse *pParse, const char *zName){ if( !pParse->db->init.busy && pParse->nested==0 + && (pParse->db->flags & SQLITE_WriteSchema)==0 && 0==sqlite3StrNICmp(zName, "sqlite_", 7) ){ sqlite3ErrorMsg(pParse, "object name reserved for internal use: %s", zName); return SQLITE_ERROR; @@ -727,6 +736,7 @@ pTable->iPKey = -1; pTable->pIndex = 0; pTable->iDb = iDb; + pTable->nRef = 1; if( pParse->pNewTable ) sqlite3DeleteTable(db, pParse->pNewTable); pParse->pNewTable = pTable; @@ -781,10 +791,10 @@ sqlite3VdbeAddOp(v, OP_CreateTable, iDb, 0); } sqlite3OpenMasterTable(v, iDb); - sqlite3VdbeAddOp(v, OP_NewRecno, 0, 0); + sqlite3VdbeAddOp(v, OP_NewRowid, 0, 0); sqlite3VdbeAddOp(v, OP_Dup, 0, 0); - sqlite3VdbeAddOp(v, OP_String8, 0, 0); - sqlite3VdbeAddOp(v, OP_PutIntKey, 0, 0); + sqlite3VdbeAddOp(v, OP_Null, 0, 0); + sqlite3VdbeAddOp(v, OP_Insert, 0, 0); sqlite3VdbeAddOp(v, OP_Close, 0, 0); sqlite3VdbeAddOp(v, OP_Pull, 1, 0); } @@ -1076,154 +1086,6 @@ } /* -** Locate and return an entry from the db.aCollSeq hash table. If the entry -** specified by zName and nName is not found and parameter 'create' is -** true, then create a new entry. Otherwise return NULL. -** -** Each pointer stored in the sqlite3.aCollSeq hash table contains an -** array of three CollSeq structures. The first is the collation sequence -** prefferred for UTF-8, the second UTF-16le, and the third UTF-16be. -** -** Stored immediately after the three collation sequences is a copy of -** the collation sequence name. A pointer to this string is stored in -** each collation sequence structure. -*/ -static CollSeq * findCollSeqEntry( - sqlite3 *db, - const char *zName, - int nName, - int create -){ - CollSeq *pColl; - if( nName<0 ) nName = strlen(zName); - pColl = sqlite3HashFind(&db->aCollSeq, zName, nName); - - if( 0==pColl && create ){ - pColl = sqliteMalloc( 3*sizeof(*pColl) + nName + 1 ); - if( pColl ){ - CollSeq *pDel = 0; - pColl[0].zName = (char*)&pColl[3]; - pColl[0].enc = SQLITE_UTF8; - pColl[1].zName = (char*)&pColl[3]; - pColl[1].enc = SQLITE_UTF16LE; - pColl[2].zName = (char*)&pColl[3]; - pColl[2].enc = SQLITE_UTF16BE; - memcpy(pColl[0].zName, zName, nName); - pColl[0].zName[nName] = 0; - pDel = sqlite3HashInsert(&db->aCollSeq, pColl[0].zName, nName, pColl); - - /* If a malloc() failure occured in sqlite3HashInsert(), it will - ** return the pColl pointer to be deleted (because it wasn't added - ** to the hash table). - */ - assert( !pDel || (sqlite3_malloc_failed && pDel==pColl) ); - sqliteFree(pDel); - } - } - return pColl; -} - -/* -** Parameter zName points to a UTF-8 encoded string nName bytes long. -** Return the CollSeq* pointer for the collation sequence named zName -** for the encoding 'enc' from the database 'db'. -** -** If the entry specified is not found and 'create' is true, then create a -** new entry. Otherwise return NULL. -*/ -CollSeq *sqlite3FindCollSeq( - sqlite3 *db, - u8 enc, - const char *zName, - int nName, - int create -){ - CollSeq *pColl = findCollSeqEntry(db, zName, nName, create); - assert( SQLITE_UTF8==1 && SQLITE_UTF16LE==2 && SQLITE_UTF16BE==3 ); - assert( enc>=SQLITE_UTF8 && enc<=SQLITE_UTF16BE ); - if( pColl ) pColl += enc-1; - return pColl; -} - -/* -** Invoke the 'collation needed' callback to request a collation sequence -** in the database text encoding of name zName, length nName. -** If the collation sequence -*/ -static void callCollNeeded(sqlite3 *db, const char *zName, int nName){ - assert( !db->xCollNeeded || !db->xCollNeeded16 ); - if( nName<0 ) nName = strlen(zName); - if( db->xCollNeeded ){ - char *zExternal = sqliteStrNDup(zName, nName); - if( !zExternal ) return; - db->xCollNeeded(db->pCollNeededArg, db, (int)db->enc, zExternal); - sqliteFree(zExternal); - } -#ifndef SQLITE_OMIT_UTF16 - if( db->xCollNeeded16 ){ - char const *zExternal; - sqlite3_value *pTmp = sqlite3GetTransientValue(db); - sqlite3ValueSetStr(pTmp, -1, zName, SQLITE_UTF8, SQLITE_STATIC); - zExternal = sqlite3ValueText(pTmp, SQLITE_UTF16NATIVE); - if( !zExternal ) return; - db->xCollNeeded16(db->pCollNeededArg, db, (int)db->enc, zExternal); - } -#endif -} - -/* -** This routine is called if the collation factory fails to deliver a -** collation function in the best encoding but there may be other versions -** of this collation function (for other text encodings) available. Use one -** of these instead if they exist. Avoid a UTF-8 <-> UTF-16 conversion if -** possible. -*/ -static int synthCollSeq(Parse *pParse, CollSeq *pColl){ - CollSeq *pColl2; - char *z = pColl->zName; - int n = strlen(z); - sqlite3 *db = pParse->db; - int i; - static const u8 aEnc[] = { SQLITE_UTF16BE, SQLITE_UTF16LE, SQLITE_UTF8 }; - for(i=0; i<3; i++){ - pColl2 = sqlite3FindCollSeq(db, aEnc[i], z, n, 0); - if( pColl2->xCmp!=0 ){ - memcpy(pColl, pColl2, sizeof(CollSeq)); - return SQLITE_OK; - } - } - if( pParse->nErr==0 ){ - sqlite3ErrorMsg(pParse, "no such collation sequence: %.*s", n, z); - } - pParse->nErr++; - return SQLITE_ERROR; -} - -/* -** This routine is called on a collation sequence before it is used to -** check that it is defined. An undefined collation sequence exists when -** a database is loaded that contains references to collation sequences -** that have not been defined by sqlite3_create_collation() etc. -** -** If required, this routine calls the 'collation needed' callback to -** request a definition of the collating sequence. If this doesn't work, -** an equivalent collating sequence that uses a text encoding different -** from the main database is substituted, if one is available. -*/ -int sqlite3CheckCollSeq(Parse *pParse, CollSeq *pColl){ - if( pColl && !pColl->xCmp ){ - /* No collation sequence of this type for this encoding is registered. - ** Call the collation factory to see if it can supply us with one. - */ - callCollNeeded(pParse->db, pColl->zName, strlen(pColl->zName)); - if( !pColl->xCmp && synthCollSeq(pParse, pColl) ){ - return SQLITE_ERROR; - } - } - return SQLITE_OK; -} - -/* ** Call sqlite3CheckCollSeq() for all collating sequences in an index, ** in order to verify that all the necessary collating sequences are ** loaded. @@ -1255,33 +1117,22 @@ ** pParse. */ CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char *zName, int nName){ - u8 enc = pParse->db->enc; - u8 initbusy = pParse->db->init.busy; - CollSeq *pColl = sqlite3FindCollSeq(pParse->db, enc, zName, nName, initbusy); - if( nName<0 ) nName = strlen(zName); + sqlite3 *db = pParse->db; + u8 enc = db->enc; + u8 initbusy = db->init.busy; + + CollSeq *pColl = sqlite3FindCollSeq(db, enc, zName, nName, initbusy); if( !initbusy && (!pColl || !pColl->xCmp) ){ - /* No collation sequence of this type for this encoding is registered. - ** Call the collation factory to see if it can supply us with one. - */ - callCollNeeded(pParse->db, zName, nName); - pColl = sqlite3FindCollSeq(pParse->db, enc, zName, nName, 0); - if( pColl && !pColl->xCmp ){ - /* There may be a version of the collation sequence that requires - ** translation between encodings. Search for it with synthCollSeq(). - */ - if( synthCollSeq(pParse, pColl) ){ - return 0; + pColl = sqlite3GetCollSeq(db, pColl, zName, nName); + if( !pColl ){ + if( nName<0 ){ + nName = strlen(zName); } + sqlite3ErrorMsg(pParse, "no such collation sequence: %.*s", nName, zName); + pColl = 0; } } - /* If nothing has been found, write the error message into pParse */ - if( !initbusy && (!pColl || !pColl->xCmp) ){ - if( pParse->nErr==0 ){ - sqlite3ErrorMsg(pParse, "no such collation sequence: %.*s", nName, zName); - } - pColl = 0; - } return pColl; } @@ -1510,7 +1361,7 @@ if( pSelect ){ zStmt = createTableStmt(p); }else{ - n = Addr(pEnd->z) - Addr(pParse->sNameToken.z) + 1; + n = pEnd->z - pParse->sNameToken.z + 1; zStmt = sqlite3MPrintf("CREATE %s %.*s", zType2, n, pParse->sNameToken.z); } @@ -1605,6 +1456,11 @@ DbFixer sFix; Token *pName; + if( pParse->nVar>0 ){ + sqlite3ErrorMsg(pParse, "parameters are not allowed in views"); + sqlite3SelectDelete(pSelect); + return; + } sqlite3StartTable(pParse, pBegin, pName1, pName2, isTemp, 1); p = pParse->pNewTable; if( p==0 || pParse->nErr ){ @@ -2152,7 +2008,7 @@ addr1 = sqlite3VdbeAddOp(v, OP_Rewind, iTab, 0); sqlite3GenerateIndexKey(v, pIndex, iTab); isUnique = pIndex->onError!=OE_None; - sqlite3VdbeAddOp(v, OP_IdxPut, iIdx, isUnique); + sqlite3VdbeAddOp(v, OP_IdxInsert, iIdx, isUnique); if( isUnique ){ sqlite3VdbeChangeP3(v, -1, "indexed columns are not unique", P3_STATIC); } @@ -2463,7 +2319,7 @@ /* A named index with an explicit CREATE INDEX statement */ zStmt = sqlite3MPrintf("CREATE%s INDEX %.*s", onError==OE_None ? "" : " UNIQUE", - Addr(pEnd->z) - Addr(pName->z) + 1, + pEnd->z - pName->z + 1, pName->z); }else{ /* An automatic index created by a PRIMARY KEY or UNIQUE constraint */ @@ -2737,9 +2593,7 @@ sqliteFree(pItem->zDatabase); sqliteFree(pItem->zName); sqliteFree(pItem->zAlias); - if( pItem->pTab && pItem->pTab->isTransient ){ - sqlite3DeleteTable(0, pItem->pTab); - } + sqlite3DeleteTable(0, pItem->pTab); sqlite3SelectDelete(pItem->pSelect); sqlite3ExprDelete(pItem->pOn); sqlite3IdListDelete(pItem->pUsing); @@ -2909,19 +2763,6 @@ } } -#ifndef SQLITE_OMIT_UTF16 -/* -** Return the transient sqlite3_value object used for encoding conversions -** during SQL compilation. -*/ -sqlite3_value *sqlite3GetTransientValue(sqlite3 *db){ - if( !db->pValue ){ - db->pValue = sqlite3ValueNew(); - } - return db->pValue; -} -#endif - /* ** Check to see if pIndex uses the collating sequence pColl. Return ** true if it does and false if it does not. --- sqlite/callback.c +++ sqlite/callback.c @@ -0,0 +1,306 @@ +/* +** 2005 May 23 +** +** 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 contains functions used to access the internal hash tables +** of user defined functions and collation sequences. +** +** $Id: callback.c,v 1.2 2005/05/25 10:45:10 danielk1977 Exp $ +*/ + +#include "sqliteInt.h" + +/* +** Invoke the 'collation needed' callback to request a collation sequence +** in the database text encoding of name zName, length nName. +** If the collation sequence +*/ +static void callCollNeeded(sqlite3 *db, const char *zName, int nName){ + assert( !db->xCollNeeded || !db->xCollNeeded16 ); + if( nName<0 ) nName = strlen(zName); + if( db->xCollNeeded ){ + char *zExternal = sqliteStrNDup(zName, nName); + if( !zExternal ) return; + db->xCollNeeded(db->pCollNeededArg, db, (int)db->enc, zExternal); + sqliteFree(zExternal); + } +#ifndef SQLITE_OMIT_UTF16 + if( db->xCollNeeded16 ){ + char const *zExternal; + sqlite3_value *pTmp = sqlite3GetTransientValue(db); + sqlite3ValueSetStr(pTmp, -1, zName, SQLITE_UTF8, SQLITE_STATIC); + zExternal = sqlite3ValueText(pTmp, SQLITE_UTF16NATIVE); + if( !zExternal ) return; + db->xCollNeeded16(db->pCollNeededArg, db, (int)db->enc, zExternal); + } +#endif +} + +/* +** This routine is called if the collation factory fails to deliver a +** collation function in the best encoding but there may be other versions +** of this collation function (for other text encodings) available. Use one +** of these instead if they exist. Avoid a UTF-8 <-> UTF-16 conversion if +** possible. +*/ +static int synthCollSeq(sqlite3 *db, CollSeq *pColl){ + CollSeq *pColl2; + char *z = pColl->zName; + int n = strlen(z); + int i; + static const u8 aEnc[] = { SQLITE_UTF16BE, SQLITE_UTF16LE, SQLITE_UTF8 }; + for(i=0; i<3; i++){ + pColl2 = sqlite3FindCollSeq(db, aEnc[i], z, n, 0); + if( pColl2->xCmp!=0 ){ + memcpy(pColl, pColl2, sizeof(CollSeq)); + return SQLITE_OK; + } + } + return SQLITE_ERROR; +} + +/* +** This function is responsible for invoking the collation factory callback +** or substituting a collation sequence of a different encoding when the +** requested collation sequence is not available in the database native +** encoding. +** +** If it is not NULL, then pColl must point to the database native encoding +** collation sequence with name zName, length nName. +** +** The return value is either the collation sequence to be used in database +** db for collation type name zName, length nName, or NULL, if no collation +** sequence can be found. +*/ +CollSeq *sqlite3GetCollSeq( + sqlite3* db, + CollSeq *pColl, + const char *zName, + int nName +){ + CollSeq *p; + + p = pColl; + if( !p ){ + p = sqlite3FindCollSeq(db, db->enc, zName, nName, 0); + } + if( !p || !p->xCmp ){ + /* No collation sequence of this type for this encoding is registered. + ** Call the collation factory to see if it can supply us with one. + */ + callCollNeeded(db, zName, nName); + p = sqlite3FindCollSeq(db, db->enc, zName, nName, 0); + } + if( p && !p->xCmp && synthCollSeq(db, p) ){ + p = 0; + } + assert( !p || p->xCmp ); + return p; +} + +/* +** This routine is called on a collation sequence before it is used to +** check that it is defined. An undefined collation sequence exists when +** a database is loaded that contains references to collation sequences +** that have not been defined by sqlite3_create_collation() etc. +** +** If required, this routine calls the 'collation needed' callback to +** request a definition of the collating sequence. If this doesn't work, +** an equivalent collating sequence that uses a text encoding different +** from the main database is substituted, if one is available. +*/ +int sqlite3CheckCollSeq(Parse *pParse, CollSeq *pColl){ + if( pColl ){ + const char *zName = pColl->zName; + CollSeq *p = sqlite3GetCollSeq(pParse->db, pColl, zName, -1); + if( !p ){ + if( pParse->nErr==0 ){ + sqlite3ErrorMsg(pParse, "no such collation sequence: %s", zName); + } + pParse->nErr++; + return SQLITE_ERROR; + } + } + return SQLITE_OK; +} + + + +/* +** Locate and return an entry from the db.aCollSeq hash table. If the entry +** specified by zName and nName is not found and parameter 'create' is +** true, then create a new entry. Otherwise return NULL. +** +** Each pointer stored in the sqlite3.aCollSeq hash table contains an +** array of three CollSeq structures. The first is the collation sequence +** prefferred for UTF-8, the second UTF-16le, and the third UTF-16be. +** +** Stored immediately after the three collation sequences is a copy of +** the collation sequence name. A pointer to this string is stored in +** each collation sequence structure. +*/ +static CollSeq * findCollSeqEntry( + sqlite3 *db, + const char *zName, + int nName, + int create +){ + CollSeq *pColl; + if( nName<0 ) nName = strlen(zName); + pColl = sqlite3HashFind(&db->aCollSeq, zName, nName); + + if( 0==pColl && create ){ + pColl = sqliteMalloc( 3*sizeof(*pColl) + nName + 1 ); + if( pColl ){ + CollSeq *pDel = 0; + pColl[0].zName = (char*)&pColl[3]; + pColl[0].enc = SQLITE_UTF8; + pColl[1].zName = (char*)&pColl[3]; + pColl[1].enc = SQLITE_UTF16LE; + pColl[2].zName = (char*)&pColl[3]; + pColl[2].enc = SQLITE_UTF16BE; + memcpy(pColl[0].zName, zName, nName); + pColl[0].zName[nName] = 0; + pDel = sqlite3HashInsert(&db->aCollSeq, pColl[0].zName, nName, pColl); + + /* If a malloc() failure occured in sqlite3HashInsert(), it will + ** return the pColl pointer to be deleted (because it wasn't added + ** to the hash table). + */ + assert( !pDel || (sqlite3_malloc_failed && pDel==pColl) ); + sqliteFree(pDel); + } + } + return pColl; +} + +/* +** Parameter zName points to a UTF-8 encoded string nName bytes long. +** Return the CollSeq* pointer for the collation sequence named zName +** for the encoding 'enc' from the database 'db'. +** +** If the entry specified is not found and 'create' is true, then create a +** new entry. Otherwise return NULL. +*/ +CollSeq *sqlite3FindCollSeq( + sqlite3 *db, + u8 enc, + const char *zName, + int nName, + int create +){ + CollSeq *pColl = findCollSeqEntry(db, zName, nName, create); + assert( SQLITE_UTF8==1 && SQLITE_UTF16LE==2 && SQLITE_UTF16BE==3 ); + assert( enc>=SQLITE_UTF8 && enc<=SQLITE_UTF16BE ); + if( pColl ) pColl += enc-1; + return pColl; +} + +/* +** Locate a user function given a name, a number of arguments and a flag +** indicating whether the function prefers UTF-16 over UTF-8. Return a +** pointer to the FuncDef structure that defines that function, or return +** NULL if the function does not exist. +** +** If the createFlag argument is true, then a new (blank) FuncDef +** structure is created and liked into the "db" structure if a +** no matching function previously existed. When createFlag is true +** and the nArg parameter is -1, then only a function that accepts +** any number of arguments will be returned. +** +** If createFlag is false and nArg is -1, then the first valid +** function found is returned. A function is valid if either xFunc +** or xStep is non-zero. +** +** If createFlag is false, then a function with the required name and +** number of arguments may be returned even if the eTextRep flag does not +** match that requested. +*/ +FuncDef *sqlite3FindFunction( + sqlite3 *db, /* An open database */ + const char *zName, /* Name of the function. Not null-terminated */ + int nName, /* Number of characters in the name */ + int nArg, /* Number of arguments. -1 means any number */ + u8 enc, /* Preferred text encoding */ + int createFlag /* Create new entry if true and does not otherwise exist */ +){ + FuncDef *p; /* Iterator variable */ + FuncDef *pFirst; /* First function with this name */ + FuncDef *pBest = 0; /* Best match found so far */ + int bestmatch = 0; + + + assert( enc==SQLITE_UTF8 || enc==SQLITE_UTF16LE || enc==SQLITE_UTF16BE ); + if( nArg<-1 ) nArg = -1; + + pFirst = (FuncDef*)sqlite3HashFind(&db->aFunc, zName, nName); + for(p=pFirst; p; p=p->pNext){ + /* During the search for the best function definition, bestmatch is set + ** as follows to indicate the quality of the match with the definition + ** pointed to by pBest: + ** + ** 0: pBest is NULL. No match has been found. + ** 1: A variable arguments function that prefers UTF-8 when a UTF-16 + ** encoding is requested, or vice versa. + ** 2: A variable arguments function that uses UTF-16BE when UTF-16LE is + ** requested, or vice versa. + ** 3: A variable arguments function using the same text encoding. + ** 4: A function with the exact number of arguments requested that + ** prefers UTF-8 when a UTF-16 encoding is requested, or vice versa. + ** 5: A function with the exact number of arguments requested that + ** prefers UTF-16LE when UTF-16BE is requested, or vice versa. + ** 6: An exact match. + ** + ** A larger value of 'matchqual' indicates a more desirable match. + */ + if( p->nArg==-1 || p->nArg==nArg || nArg==-1 ){ + int match = 1; /* Quality of this match */ + if( p->nArg==nArg || nArg==-1 ){ + match = 4; + } + if( enc==p->iPrefEnc ){ + match += 2; + } + else if( (enc==SQLITE_UTF16LE && p->iPrefEnc==SQLITE_UTF16BE) || + (enc==SQLITE_UTF16BE && p->iPrefEnc==SQLITE_UTF16LE) ){ + match += 1; + } + + if( match>bestmatch ){ + pBest = p; + bestmatch = match; + } + } + } + + /* If the createFlag parameter is true, and the seach did not reveal an + ** exact match for the name, number of arguments and encoding, then add a + ** new entry to the hash table and return it. + */ + if( createFlag && bestmatch<6 && + (pBest = sqliteMalloc(sizeof(*pBest)+nName+1)) ){ + pBest->nArg = nArg; + pBest->pNext = pFirst; + pBest->zName = (char*)&pBest[1]; + pBest->iPrefEnc = enc; + memcpy(pBest->zName, zName, nName); + pBest->zName[nName] = 0; + if( pBest==sqlite3HashInsert(&db->aFunc,pBest->zName,nName,(void*)pBest) ){ + sqliteFree(pBest); + return 0; + } + } + + if( pBest && (pBest->xStep || pBest->xFunc || createFlag) ){ + return pBest; + } + return 0; +} --- sqlite/delete.c +++ sqlite/delete.c @@ -12,7 +12,7 @@ ** This file contains C code routines that are called by the parser ** in order to generate code for DELETE FROM statements. ** -** $Id: delete.c,v 1.102 2005/03/16 12:15:21 danielk1977 Exp $ +** $Id: delete.c,v 1.106 2005/06/12 21:35:52 drh Exp $ */ #include "sqliteInt.h" @@ -27,7 +27,11 @@ struct SrcList_item *pItem; for(i=0, pItem=pSrc->a; inSrc; i++, pItem++){ pTab = sqlite3LocateTable(pParse, pItem->zName, pItem->zDatabase); + sqlite3DeleteTable(pParse->db, pItem->pTab); pItem->pTab = pTab; + if( pTab ){ + pTab->nRef++; + } } return pTab; } @@ -230,12 +234,12 @@ /* Begin the database scan */ - pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0, 0); + pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0); if( pWInfo==0 ) goto delete_from_cleanup; /* Remember the rowid of every item to be deleted. */ - sqlite3VdbeAddOp(v, OP_Recno, iCur, 0); + sqlite3VdbeAddOp(v, OP_Rowid, iCur, 0); sqlite3VdbeAddOp(v, OP_ListWrite, 0, 0); if( db->flags & SQLITE_CountRows ){ sqlite3VdbeAddOp(v, OP_AddImm, 1, 0); @@ -264,21 +268,21 @@ */ if( triggers_exist ){ addr = sqlite3VdbeAddOp(v, OP_ListRead, 0, end); - sqlite3VdbeAddOp(v, OP_Dup, 0, 0); if( !isView ){ + sqlite3VdbeAddOp(v, OP_Dup, 0, 0); sqlite3OpenTableForReading(v, iCur, pTab); } sqlite3VdbeAddOp(v, OP_MoveGe, iCur, 0); - sqlite3VdbeAddOp(v, OP_Recno, iCur, 0); + sqlite3VdbeAddOp(v, OP_Rowid, iCur, 0); sqlite3VdbeAddOp(v, OP_RowData, iCur, 0); - sqlite3VdbeAddOp(v, OP_PutIntKey, oldIdx, 0); + sqlite3VdbeAddOp(v, OP_Insert, oldIdx, 0); if( !isView ){ sqlite3VdbeAddOp(v, OP_Close, iCur, 0); } (void)sqlite3CodeRowTrigger(pParse, TK_DELETE, 0, TRIGGER_BEFORE, pTab, -1, oldIdx, (pParse->trigStack)?pParse->trigStack->orconf:OE_Default, - addr); + addr); } if( !isView ){ @@ -312,7 +316,7 @@ } (void)sqlite3CodeRowTrigger(pParse, TK_DELETE, 0, TRIGGER_AFTER, pTab, -1, oldIdx, (pParse->trigStack)?pParse->trigStack->orconf:OE_Default, - addr); + addr); } /* End of the delete loop */ @@ -428,7 +432,7 @@ int j; Table *pTab = pIdx->pTable; - sqlite3VdbeAddOp(v, OP_Recno, iCur, 0); + sqlite3VdbeAddOp(v, OP_Rowid, iCur, 0); for(j=0; jnColumn; j++){ int idx = pIdx->aiColumn[j]; if( idx==pTab->iPKey ){ --- sqlite/expr.c +++ sqlite/expr.c @@ -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.197 2005/03/21 03:53:38 danielk1977 Exp $ +** $Id: expr.c,v 1.206 2005/06/12 21:35:52 drh Exp $ */ #include "sqliteInt.h" #include @@ -138,7 +138,7 @@ */ static int binaryCompareP1(Expr *pExpr1, Expr *pExpr2, int jumpIfNull){ char aff = sqlite3ExprAffinity(pExpr2); - return (((int)sqlite3CompareAffinity(pExpr1, aff))<<8)+(jumpIfNull?1:0); + return ((int)sqlite3CompareAffinity(pExpr1, aff))+(jumpIfNull?0x100:0); } /* @@ -265,7 +265,7 @@ assert( pLeft->dyn==0 || pLeft->z[pLeft->n]==0 ); if( pLeft->dyn==0 && pRight->dyn==0 ){ pExpr->span.z = pLeft->z; - pExpr->span.n = pRight->n + Addr(pRight->z) - Addr(pLeft->z); + pExpr->span.n = pRight->n + (pRight->z - pLeft->z); }else{ pExpr->span.z = 0; } @@ -474,14 +474,15 @@ for(i=0; inSrc; i++){ struct SrcList_item *pNewItem = &pNew->a[i]; struct SrcList_item *pOldItem = &p->a[i]; + Table *pTab; pNewItem->zDatabase = sqliteStrDup(pOldItem->zDatabase); pNewItem->zName = sqliteStrDup(pOldItem->zName); pNewItem->zAlias = sqliteStrDup(pOldItem->zAlias); pNewItem->jointype = pOldItem->jointype; pNewItem->iCursor = pOldItem->iCursor; - pNewItem->pTab = pOldItem->pTab; - if( pNewItem->pTab ){ - pNewItem->pTab->isTransient = 0; + pTab = pNewItem->pTab = pOldItem->pTab; + if( pTab ){ + pTab->nRef++; } pNewItem->pSelect = sqlite3SelectDup(pOldItem->pSelect); pNewItem->pOn = sqlite3ExprDup(pOldItem->pOn); @@ -529,7 +530,6 @@ pNew->iLimit = -1; pNew->iOffset = -1; pNew->ppOpenTemp = 0; - pNew->pFetch = 0; pNew->isResolved = p->isResolved; pNew->isAgg = p->isAgg; return pNew; @@ -791,7 +791,6 @@ SrcList *pSrcList = pNC->pSrcList; ExprList *pEList = pNC->pEList; - pNC->nRef++; /* assert( zTab==0 || pEList==0 ); */ if( pSrcList ){ for(i=0, pItem=pSrcList->a; inSrc; i++, pItem++){ @@ -819,6 +818,7 @@ } for(j=0, pCol=pTab->aCol; jnCol; j++, pCol++){ if( sqlite3StrICmp(pCol->zName, zCol)==0 ){ + IdList *pUsing; cnt++; pExpr->iTable = pItem->iCursor; pMatch = pItem; @@ -827,6 +827,25 @@ pExpr->iColumn = j==pTab->iPKey ? -1 : j; pExpr->affinity = pTab->aCol[j].affinity; pExpr->pColl = pTab->aCol[j].pColl; + if( pItem->jointype & JT_NATURAL ){ + /* If this match occurred in the left table of a natural join, + ** then skip the right table to avoid a duplicate match */ + pItem++; + i++; + } + if( (pUsing = pItem->pUsing)!=0 ){ + /* If this match occurs on a column that is in the USING clause + ** of a join, skip the search of the right table of the join + ** to avoid a duplicate match there. */ + int k; + for(k=0; knId; k++){ + if( sqlite3StrICmp(pUsing->a[k].zName, zCol)==0 ){ + pItem++; + i++; + break; + } + } + } break; } } @@ -899,9 +918,9 @@ pExpr->op = TK_AS; pExpr->iColumn = j; pExpr->pLeft = sqlite3ExprDup(pEList->a[j].pExpr); - sqliteFree(zCol); + cnt = 1; assert( zTab==0 && zDb==0 ); - return 0; + goto lookupname_end_2; } } } @@ -920,6 +939,9 @@ ** Z is a string literal if it doesn't match any column names. In that ** case, we need to return right away and not make any changes to ** pExpr. + ** + ** Because no reference was made to outer contexts, the pNC->nRef + ** fields are not changed in any context. */ if( cnt==0 && zTab==0 && pColumnToken->z[0]=='"' ){ sqliteFree(zCol); @@ -966,62 +988,30 @@ */ sqliteFree(zDb); sqliteFree(zTab); - sqliteFree(zCol); sqlite3ExprDelete(pExpr->pLeft); pExpr->pLeft = 0; sqlite3ExprDelete(pExpr->pRight); pExpr->pRight = 0; pExpr->op = TK_COLUMN; +lookupname_end_2: + sqliteFree(zCol); if( cnt==1 ){ assert( pNC!=0 ); sqlite3AuthRead(pParse, pExpr, pNC->pSrcList); if( pMatch && !pMatch->pSelect ){ pExpr->pTab = pMatch->pTab; } - } - return cnt!=1; -} - -/* -** pExpr is a node that defines a function of some kind. It might -** be a syntactic function like "count(x)" or it might be a function -** that implements an operator, like "a LIKE b". -** -** This routine makes *pzName point to the name of the function and -** *pnName hold the number of characters in the function name. -*/ -static void getFunctionName(Expr *pExpr, const char **pzName, int *pnName){ - switch( pExpr->op ){ - case TK_FUNCTION: { - *pzName = pExpr->token.z; - *pnName = pExpr->token.n; - break; + /* Increment the nRef value on all name contexts from TopNC up to + ** the point where the name matched. */ + for(;;){ + assert( pTopNC!=0 ); + pTopNC->nRef++; + if( pTopNC==pNC ) break; + pTopNC = pTopNC->pNext; } - case TK_LIKE: { - *pzName = "like"; - *pnName = 4; - break; - } - case TK_GLOB: { - *pzName = "glob"; - *pnName = 4; - break; - } - case TK_CTIME: { - *pzName = "current_time"; - *pnName = 12; - break; - } - case TK_CDATE: { - *pzName = "current_date"; - *pnName = 12; - break; - } - case TK_CTIMESTAMP: { - *pzName = "current_timestamp"; - *pnName = 17; - break; - } + return 0; + } else { + return 1; } } @@ -1099,11 +1089,7 @@ /* Resolve function names */ - case TK_CTIME: - case TK_CTIMESTAMP: - case TK_CDATE: - case TK_GLOB: - case TK_LIKE: + case TK_CONST_FUNC: case TK_FUNCTION: { ExprList *pList = pExpr->pList; /* The argument list */ int n = pList ? pList->nExpr : 0; /* Number of arguments */ @@ -1116,7 +1102,8 @@ FuncDef *pDef; /* Information about the function */ int enc = pParse->db->enc; /* The database encoding */ - getFunctionName(pExpr, &zId, &nId); + zId = pExpr->token.z; + nId = pExpr->token.n; pDef = sqlite3FindFunction(pParse->db, zId, nId, n, enc, 0); if( pDef==0 ){ pDef = sqlite3FindFunction(pParse->db, zId, nId, -1, enc, 0); @@ -1322,8 +1309,7 @@ /* Evaluate the expression and insert it into the temp table */ sqlite3ExprCode(pParse, pE2); sqlite3VdbeOp3(v, OP_MakeRecord, 1, 0, &affinity, 1); - sqlite3VdbeAddOp(v, OP_String8, 0, 0); - sqlite3VdbeAddOp(v, OP_PutStrKey, pExpr->iTable, 0); + sqlite3VdbeAddOp(v, OP_IdxInsert, pExpr->iTable, 0); } } sqlite3VdbeChangeP3(v, addr, (void *)&keyInfo, P3_KEYINFO); @@ -1395,7 +1381,7 @@ int op; if( v==0 ) return; if( pExpr==0 ){ - sqlite3VdbeAddOp(v, OP_String8, 0, 0); /* Empty expression evals to NULL */ + sqlite3VdbeAddOp(v, OP_Null, 0, 0); return; } op = pExpr->op; @@ -1407,7 +1393,7 @@ sqlite3VdbeAddOp(v, OP_Column, pExpr->iTable, pExpr->iColumn); sqlite3ColumnDefault(v, pExpr->pTab, pExpr->iColumn); }else{ - sqlite3VdbeAddOp(v, OP_Recno, pExpr->iTable, 0); + sqlite3VdbeAddOp(v, OP_Rowid, pExpr->iTable, 0); } break; } @@ -1423,6 +1409,10 @@ sqlite3VdbeDequoteP3(v, -1); break; } + case TK_NULL: { + sqlite3VdbeAddOp(v, OP_Null, 0, 0); + break; + } #ifndef SQLITE_OMIT_BLOB_LITERAL case TK_BLOB: { assert( TK_BLOB==OP_HexBlob ); @@ -1431,10 +1421,6 @@ break; } #endif - case TK_NULL: { - sqlite3VdbeAddOp(v, OP_String8, 0, 0); - break; - } case TK_VARIABLE: { sqlite3VdbeAddOp(v, OP_Variable, pExpr->iTable, 0); if( pExpr->token.n>1 ){ @@ -1532,11 +1518,7 @@ sqlite3VdbeAddOp(v, OP_AggGet, 0, pExpr->iAgg); break; } - case TK_CDATE: - case TK_CTIME: - case TK_CTIMESTAMP: - case TK_GLOB: - case TK_LIKE: + case TK_CONST_FUNC: case TK_FUNCTION: { ExprList *pList = pExpr->pList; int nExpr = pList ? pList->nExpr : 0; @@ -1547,7 +1529,8 @@ int i; u8 enc = pParse->db->enc; CollSeq *pColl = 0; - getFunctionName(pExpr, &zId, &nId); + zId = pExpr->token.z; + nId = pExpr->token.n; pDef = sqlite3FindFunction(pParse->db, zId, nId, nExpr, enc, 0); assert( pDef!=0 ); nExpr = sqlite3ExprCodeExprList(pParse, pList); @@ -1594,7 +1577,7 @@ addr = sqlite3VdbeCurrentAddr(v); sqlite3VdbeAddOp(v, OP_NotNull, -1, addr+4); /* addr + 0 */ sqlite3VdbeAddOp(v, OP_Pop, 2, 0); - sqlite3VdbeAddOp(v, OP_String8, 0, 0); + sqlite3VdbeAddOp(v, OP_Null, 0, 0); sqlite3VdbeAddOp(v, OP_Goto, 0, addr+7); sqlite3VdbeOp3(v, OP_MakeRecord, 1, 0, &affinity, 1); /* addr + 4 */ sqlite3VdbeAddOp(v, OP_Found, pExpr->iTable, addr+7); @@ -1664,7 +1647,7 @@ if( pExpr->pRight ){ sqlite3ExprCode(pParse, pExpr->pRight); }else{ - sqlite3VdbeAddOp(v, OP_String8, 0, 0); + sqlite3VdbeAddOp(v, OP_Null, 0, 0); } sqlite3VdbeResolveLabel(v, expr_end_label); break; @@ -2086,104 +2069,3 @@ walkExprTree(pExpr, analyzeAggregate, pNC); return pNC->pParse->nErr - nErr; } - -/* -** Locate a user function given a name, a number of arguments and a flag -** indicating whether the function prefers UTF-16 over UTF-8. Return a -** pointer to the FuncDef structure that defines that function, or return -** NULL if the function does not exist. -** -** If the createFlag argument is true, then a new (blank) FuncDef -** structure is created and liked into the "db" structure if a -** no matching function previously existed. When createFlag is true -** and the nArg parameter is -1, then only a function that accepts -** any number of arguments will be returned. -** -** If createFlag is false and nArg is -1, then the first valid -** function found is returned. A function is valid if either xFunc -** or xStep is non-zero. -** -** If createFlag is false, then a function with the required name and -** number of arguments may be returned even if the eTextRep flag does not -** match that requested. -*/ -FuncDef *sqlite3FindFunction( - sqlite3 *db, /* An open database */ - const char *zName, /* Name of the function. Not null-terminated */ - int nName, /* Number of characters in the name */ - int nArg, /* Number of arguments. -1 means any number */ - u8 enc, /* Preferred text encoding */ - int createFlag /* Create new entry if true and does not otherwise exist */ -){ - FuncDef *p; /* Iterator variable */ - FuncDef *pFirst; /* First function with this name */ - FuncDef *pBest = 0; /* Best match found so far */ - int bestmatch = 0; - - - assert( enc==SQLITE_UTF8 || enc==SQLITE_UTF16LE || enc==SQLITE_UTF16BE ); - if( nArg<-1 ) nArg = -1; - - pFirst = (FuncDef*)sqlite3HashFind(&db->aFunc, zName, nName); - for(p=pFirst; p; p=p->pNext){ - /* During the search for the best function definition, bestmatch is set - ** as follows to indicate the quality of the match with the definition - ** pointed to by pBest: - ** - ** 0: pBest is NULL. No match has been found. - ** 1: A variable arguments function that prefers UTF-8 when a UTF-16 - ** encoding is requested, or vice versa. - ** 2: A variable arguments function that uses UTF-16BE when UTF-16LE is - ** requested, or vice versa. - ** 3: A variable arguments function using the same text encoding. - ** 4: A function with the exact number of arguments requested that - ** prefers UTF-8 when a UTF-16 encoding is requested, or vice versa. - ** 5: A function with the exact number of arguments requested that - ** prefers UTF-16LE when UTF-16BE is requested, or vice versa. - ** 6: An exact match. - ** - ** A larger value of 'matchqual' indicates a more desirable match. - */ - if( p->nArg==-1 || p->nArg==nArg || nArg==-1 ){ - int match = 1; /* Quality of this match */ - if( p->nArg==nArg || nArg==-1 ){ - match = 4; - } - if( enc==p->iPrefEnc ){ - match += 2; - } - else if( (enc==SQLITE_UTF16LE && p->iPrefEnc==SQLITE_UTF16BE) || - (enc==SQLITE_UTF16BE && p->iPrefEnc==SQLITE_UTF16LE) ){ - match += 1; - } - - if( match>bestmatch ){ - pBest = p; - bestmatch = match; - } - } - } - - /* If the createFlag parameter is true, and the seach did not reveal an - ** exact match for the name, number of arguments and encoding, then add a - ** new entry to the hash table and return it. - */ - if( createFlag && bestmatch<6 && - (pBest = sqliteMalloc(sizeof(*pBest)+nName+1)) ){ - pBest->nArg = nArg; - pBest->pNext = pFirst; - pBest->zName = (char*)&pBest[1]; - pBest->iPrefEnc = enc; - memcpy(pBest->zName, zName, nName); - pBest->zName[nName] = 0; - if( pBest==sqlite3HashInsert(&db->aFunc,pBest->zName,nName,(void*)pBest) ){ - sqliteFree(pBest); - return 0; - } - } - - if( pBest && (pBest->xStep || pBest->xFunc || createFlag) ){ - return pBest; - } - return 0; -} --- sqlite/func.c +++ sqlite/func.c @@ -16,7 +16,7 @@ ** sqliteRegisterBuildinFunctions() found at the bottom of the file. ** All other code has file scope. ** -** $Id: func.c,v 1.96 2005/02/15 21:36:18 drh Exp $ +** $Id: func.c,v 1.98 2005/05/24 12:01:02 danielk1977 Exp $ */ #include "sqliteInt.h" #include @@ -1035,4 +1035,9 @@ } } sqlite3RegisterDateTimeFunctions(db); +#ifdef SQLITE_SSE + { + sqlite3SseFunctions(db); + } +#endif } --- sqlite/insert.c +++ sqlite/insert.c @@ -12,7 +12,7 @@ ** This file contains C code routines that are called by the parser ** to handle INSERT statements in SQLite. ** -** $Id: insert.c,v 1.138 2005/03/21 01:20:58 drh Exp $ +** $Id: insert.c,v 1.139 2005/06/12 21:35:52 drh Exp $ */ #include "sqliteInt.h" @@ -308,7 +308,7 @@ sqlite3VdbeAddOp(v, OP_Column, iCur, 0); sqlite3VdbeOp3(v, OP_String8, 0, 0, pTab->zName, 0); sqlite3VdbeAddOp(v, OP_Ne, 28417, base+12); - sqlite3VdbeAddOp(v, OP_Recno, iCur, 0); + sqlite3VdbeAddOp(v, OP_Rowid, iCur, 0); sqlite3VdbeAddOp(v, OP_MemStore, counterRowid, 1); sqlite3VdbeAddOp(v, OP_Column, iCur, 1); sqlite3VdbeAddOp(v, OP_MemStore, counterMem, 1); @@ -363,9 +363,9 @@ sqlite3VdbeResolveLabel(v, iInsertBlock); sqlite3VdbeAddOp(v, OP_MakeRecord, nColumn, 0); sqlite3TableAffinityStr(v, pTab); - sqlite3VdbeAddOp(v, OP_NewRecno, srcTab, 0); + sqlite3VdbeAddOp(v, OP_NewRowid, srcTab, 0); sqlite3VdbeAddOp(v, OP_Pull, 1, 0); - sqlite3VdbeAddOp(v, OP_PutIntKey, srcTab, 0); + sqlite3VdbeAddOp(v, OP_Insert, srcTab, 0); sqlite3VdbeAddOp(v, OP_Return, 0, 0); /* The following code runs first because the GOTO at the very top @@ -547,7 +547,7 @@ if( !isView ){ sqlite3TableAffinityStr(v, pTab); } - sqlite3VdbeAddOp(v, OP_PutIntKey, newIdx, 0); + sqlite3VdbeAddOp(v, OP_Insert, newIdx, 0); /* Fire BEFORE or INSTEAD OF triggers */ if( sqlite3CodeRowTrigger(pParse, TK_INSERT, 0, TRIGGER_BEFORE, pTab, @@ -565,7 +565,7 @@ } /* Push the record number for the new entry onto the stack. The - ** record number is a randomly generate integer created by NewRecno + ** record number is a randomly generate integer created by NewRowid ** except when the table has an INTEGER PRIMARY KEY column, in which ** case the record number is the same as that column. */ @@ -578,15 +578,15 @@ }else{ sqlite3ExprCode(pParse, pList->a[keyColumn].pExpr); } - /* If the PRIMARY KEY expression is NULL, then use OP_NewRecno + /* If the PRIMARY KEY expression is NULL, then use OP_NewRowid ** to generate a unique primary key value. */ sqlite3VdbeAddOp(v, OP_NotNull, -1, sqlite3VdbeCurrentAddr(v)+3); sqlite3VdbeAddOp(v, OP_Pop, 1, 0); - sqlite3VdbeAddOp(v, OP_NewRecno, base, counterMem); + sqlite3VdbeAddOp(v, OP_NewRowid, base, counterMem); sqlite3VdbeAddOp(v, OP_MustBeInt, 0, 0); }else{ - sqlite3VdbeAddOp(v, OP_NewRecno, base, counterMem); + sqlite3VdbeAddOp(v, OP_NewRowid, base, counterMem); } #ifndef SQLITE_OMIT_AUTOINCREMENT if( pTab->autoInc ){ @@ -603,7 +603,7 @@ ** Whenever this column is read, the record number will be substituted ** in its place. So will fill this column with a NULL to avoid ** taking up data space with information that will never be used. */ - sqlite3VdbeAddOp(v, OP_String8, 0, 0); + sqlite3VdbeAddOp(v, OP_Null, 0, 0); continue; } if( pColumn==0 ){ @@ -690,11 +690,11 @@ sqlite3VdbeAddOp(v, OP_MemLoad, counterRowid, 0); sqlite3VdbeAddOp(v, OP_NotNull, -1, base+7); sqlite3VdbeAddOp(v, OP_Pop, 1, 0); - sqlite3VdbeAddOp(v, OP_NewRecno, iCur, 0); + sqlite3VdbeAddOp(v, OP_NewRowid, iCur, 0); sqlite3VdbeOp3(v, OP_String8, 0, 0, pTab->zName, 0); sqlite3VdbeAddOp(v, OP_MemLoad, counterMem, 0); sqlite3VdbeAddOp(v, OP_MakeRecord, 2, 0); - sqlite3VdbeAddOp(v, OP_PutIntKey, iCur, 0); + sqlite3VdbeAddOp(v, OP_Insert, iCur, 0); sqlite3VdbeAddOp(v, OP_Close, iCur, 0); } #endif @@ -724,11 +724,11 @@ ** When this routine is called, the stack contains (from bottom to top) ** the following values: ** -** 1. The recno of the row to be updated before the update. This +** 1. The rowid of the row to be updated before the update. This ** value is omitted unless we are doing an UPDATE that involves a ** change to the record number. ** -** 2. The recno of the row after the update. +** 2. The rowid of the row after the update. ** ** 3. The data in the first column of the entry after the update. ** @@ -736,9 +736,9 @@ ** ** N. The data in the last column of the entry after the update. ** -** The old recno shown as entry (1) above is omitted unless both isUpdate -** and recnoChng are 1. isUpdate is true for UPDATEs and false for -** INSERTs and recnoChng is true if the record number is being changed. +** The old rowid shown as entry (1) above is omitted unless both isUpdate +** and rowidChng are 1. isUpdate is true for UPDATEs and false for +** INSERTs and rowidChng is true if the record number is being changed. ** ** The code generated by this routine pushes additional entries onto ** the stack which are the keys for new index entries for the new record. @@ -802,7 +802,7 @@ Table *pTab, /* the table into which we are inserting */ int base, /* Index of a read/write cursor pointing at pTab */ char *aIdxUsed, /* Which indices are used. NULL means all are used */ - int recnoChng, /* True if the record number will change */ + int rowidChng, /* True if the record number will change */ int isUpdate, /* True for UPDATE, False for INSERT */ int overrideError, /* Override onError to this if not OE_Default */ int ignoreDest /* Jump to this label on an OE_Ignore resolution */ @@ -818,7 +818,7 @@ int seenReplace = 0; int jumpInst1=0, jumpInst2; int contAddr; - int hasTwoRecnos = (isUpdate && recnoChng); + int hasTwoRowids = (isUpdate && rowidChng); v = sqlite3GetVdbe(pParse); assert( v!=0 ); @@ -857,7 +857,7 @@ break; } case OE_Ignore: { - sqlite3VdbeAddOp(v, OP_Pop, nCol+1+hasTwoRecnos, 0); + sqlite3VdbeAddOp(v, OP_Pop, nCol+1+hasTwoRowids, 0); sqlite3VdbeAddOp(v, OP_Goto, 0, ignoreDest); break; } @@ -878,7 +878,7 @@ ** of the new record does not previously exist. Except, if this ** is an UPDATE and the primary key is not changing, that is OK. */ - if( recnoChng ){ + if( rowidChng ){ onError = pTab->keyConf; if( overrideError!=OE_Default ){ onError = overrideError; @@ -908,7 +908,7 @@ case OE_Replace: { sqlite3GenerateRowIndexDelete(pParse->db, v, pTab, base, 0); if( isUpdate ){ - sqlite3VdbeAddOp(v, OP_Dup, nCol+hasTwoRecnos, 1); + sqlite3VdbeAddOp(v, OP_Dup, nCol+hasTwoRowids, 1); sqlite3VdbeAddOp(v, OP_MoveGe, base, 0); } seenReplace = 1; @@ -916,7 +916,7 @@ } case OE_Ignore: { assert( seenReplace==0 ); - sqlite3VdbeAddOp(v, OP_Pop, nCol+1+hasTwoRecnos, 0); + sqlite3VdbeAddOp(v, OP_Pop, nCol+1+hasTwoRowids, 0); sqlite3VdbeAddOp(v, OP_Goto, 0, ignoreDest); break; } @@ -967,7 +967,7 @@ /* Check to see if the new index entry will be unique */ - sqlite3VdbeAddOp(v, OP_Dup, extra+nCol+1+hasTwoRecnos, 1); + sqlite3VdbeAddOp(v, OP_Dup, extra+nCol+1+hasTwoRowids, 1); jumpInst2 = sqlite3VdbeAddOp(v, OP_IsUnique, base+iCur+1, 0); /* Generate code that executes if the new index entry is not unique */ @@ -1004,14 +1004,14 @@ } case OE_Ignore: { assert( seenReplace==0 ); - sqlite3VdbeAddOp(v, OP_Pop, nCol+extra+3+hasTwoRecnos, 0); + sqlite3VdbeAddOp(v, OP_Pop, nCol+extra+3+hasTwoRowids, 0); sqlite3VdbeAddOp(v, OP_Goto, 0, ignoreDest); break; } case OE_Replace: { sqlite3GenerateRowDelete(pParse->db, v, pTab, base, 0); if( isUpdate ){ - sqlite3VdbeAddOp(v, OP_Dup, nCol+extra+1+hasTwoRecnos, 1); + sqlite3VdbeAddOp(v, OP_Dup, nCol+extra+1+hasTwoRowids, 1); sqlite3VdbeAddOp(v, OP_MoveGe, base, 0); } seenReplace = 1; @@ -1031,7 +1031,7 @@ ** This routine generates code to finish the INSERT or UPDATE operation ** that was started by a prior call to sqlite3GenerateConstraintChecks. ** The stack must contain keys for all active indices followed by data -** and the recno for the new entry. This routine creates the new +** and the rowid for the new entry. This routine creates the new ** entries in all indices and in the main table. ** ** The arguments to this routine should be the same as the first six @@ -1042,7 +1042,7 @@ Table *pTab, /* the table into which we are inserting */ int base, /* Index of a read/write cursor pointing at pTab */ char *aIdxUsed, /* Which indices are used. NULL means all are used */ - int recnoChng, /* True if the record number will change */ + int rowidChng, /* True if the record number will change */ int isUpdate, /* True for UPDATE, False for INSERT */ int newIdx /* Index of NEW table for triggers. -1 if none */ ){ @@ -1058,7 +1058,7 @@ for(nIdx=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, nIdx++){} for(i=nIdx-1; i>=0; i--){ if( aIdxUsed && aIdxUsed[i]==0 ) continue; - sqlite3VdbeAddOp(v, OP_IdxPut, base+i+1, 0); + sqlite3VdbeAddOp(v, OP_IdxInsert, base+i+1, 0); } sqlite3VdbeAddOp(v, OP_MakeRecord, pTab->nCol, 0); sqlite3TableAffinityStr(v, pTab); @@ -1066,7 +1066,7 @@ if( newIdx>=0 ){ sqlite3VdbeAddOp(v, OP_Dup, 1, 0); sqlite3VdbeAddOp(v, OP_Dup, 1, 0); - sqlite3VdbeAddOp(v, OP_PutIntKey, newIdx, 0); + sqlite3VdbeAddOp(v, OP_Insert, newIdx, 0); } #endif if( pParse->nested ){ @@ -1074,9 +1074,9 @@ }else{ pik_flags = (OPFLAG_NCHANGE|(isUpdate?0:OPFLAG_LASTROWID)); } - sqlite3VdbeAddOp(v, OP_PutIntKey, base, pik_flags); + sqlite3VdbeAddOp(v, OP_Insert, base, pik_flags); - if( isUpdate && recnoChng ){ + if( isUpdate && rowidChng ){ sqlite3VdbeAddOp(v, OP_Pop, 1, 0); } } --- sqlite/keywordhash.h +++ sqlite/keywordhash.h @@ -1,83 +1,83 @@ -/* Hash score: 151 */ +/* Hash score: 153 */ static int keywordCode(const char *z, int n){ - static const char zText[510] = + static const char zText[515] = "ABORTABLEFTEMPORARYADDATABASELECTHENDEFAULTRANSACTIONATURALTER" - "AISEACHECKEYAFTEREFERENCESCAPELSEXCEPTRIGGEREINDEXCLUSIVEXISTS" - "TATEMENTANDEFERRABLEXPLAINITIALLYATTACHAVINGLOBEFOREIGNORENAME" - "AUTOINCREMENTBEGINNEREPLACEBETWEENOTNULLIKEBYCASCADEFERREDELETE" - "CASECOLLATECOLUMNCOMMITCONFLICTCONSTRAINTERSECTCREATECROSSCURRENT_DATE" - "CURRENT_TIMESTAMPRAGMATCHDESCDETACHDISTINCTDROPRIMARYFAILIMIT" - "FROMFULLGROUPDATEIMMEDIATEINSERTINSTEADINTOFFSETISNULLJOINORDER" - "ESTRICTOUTERIGHTROLLBACKROWHENUNIONUNIQUEUSINGVACUUMVALUESVIEW" - "HERE"; + "AISEACHECKEYAFTEREFERENCESCAPELSEXCEPTRIGGEREGEXPLAINITIALLYAND" + "EFERRABLEXCLUSIVEXISTSTATEMENTATTACHAVINGLOBEFOREIGNOREINDEXAUTOINCREMENT" + "BEGINNERENAMEBETWEENOTNULLIKEBYCASCADEFERREDELETECASECOLLATECOLUMN" + "COMMITCONFLICTCONSTRAINTERSECTCREATECROSSCURRENT_DATECURRENT_TIMESTAMP" + "RAGMATCHDESCDETACHDISTINCTDROPRIMARYFAILIMITFROMFULLGROUPDATE" + "IMMEDIATEINSERTINSTEADINTOFFSETISNULLJOINORDEREPLACEOUTERESTRICT" + "RIGHTROLLBACKROWHENUNIONUNIQUEUSINGVACUUMVALUESVIEWHERE"; static const unsigned char aHash[127] = { - 89, 79, 101, 88, 0, 4, 0, 0, 108, 0, 75, 0, 0, - 92, 44, 0, 90, 0, 100, 103, 94, 0, 0, 10, 0, 0, - 107, 0, 104, 98, 0, 11, 47, 0, 41, 0, 0, 63, 69, - 0, 62, 19, 0, 0, 33, 81, 0, 102, 72, 0, 0, 30, - 0, 60, 34, 0, 8, 0, 109, 38, 12, 0, 76, 40, 25, - 64, 0, 0, 37, 80, 52, 36, 49, 20, 86, 0, 31, 0, - 73, 26, 0, 70, 0, 0, 0, 0, 46, 65, 22, 85, 35, - 67, 84, 0, 1, 0, 9, 51, 57, 18, 0, 106, 74, 96, + 89, 79, 102, 88, 0, 4, 0, 0, 109, 0, 75, 0, 0, + 92, 43, 0, 90, 0, 101, 104, 94, 0, 0, 10, 0, 0, + 108, 0, 105, 100, 0, 28, 47, 0, 40, 0, 0, 63, 69, + 0, 62, 19, 0, 0, 32, 81, 0, 103, 72, 0, 0, 34, + 0, 60, 33, 0, 8, 0, 110, 37, 12, 0, 76, 39, 25, + 64, 0, 0, 31, 80, 52, 30, 49, 20, 86, 0, 35, 0, + 73, 26, 0, 70, 0, 0, 0, 0, 46, 65, 22, 85, 29, + 67, 84, 0, 1, 0, 9, 98, 57, 18, 0, 107, 74, 96, 53, 6, 83, 0, 0, 48, 91, 0, 99, 0, 68, 0, 0, - 15, 0, 110, 50, 55, 0, 2, 54, 0, 105, + 15, 0, 111, 50, 55, 0, 2, 54, 0, 106, }; - static const unsigned char aNext[110] = { + static const unsigned char aNext[111] = { 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, - 0, 0, 0, 5, 13, 0, 7, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 43, 0, 0, 0, 0, 0, 0, - 0, 16, 0, 23, 45, 0, 0, 0, 0, 28, 58, 0, 0, - 0, 0, 0, 0, 0, 0, 71, 42, 0, 0, 24, 59, 21, - 0, 78, 0, 66, 0, 0, 82, 29, 0, 0, 0, 0, 0, - 0, 0, 39, 93, 95, 0, 0, 97, 14, 27, 77, 0, 56, - 87, 0, 32, 0, 61, 0, + 0, 11, 0, 0, 0, 7, 0, 5, 13, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 42, 0, 0, 0, 0, 0, 0, + 0, 16, 0, 23, 51, 0, 0, 0, 0, 44, 58, 0, 0, + 0, 0, 0, 0, 0, 0, 71, 41, 0, 0, 24, 59, 21, + 0, 78, 0, 66, 0, 0, 82, 45, 0, 0, 0, 0, 0, + 0, 0, 38, 93, 95, 0, 0, 97, 0, 14, 27, 77, 0, + 56, 87, 0, 36, 0, 61, 0, }; - static const unsigned char aLen[110] = { + static const unsigned char aLen[111] = { 5, 5, 4, 4, 9, 2, 3, 8, 2, 6, 4, 3, 7, 11, 2, 7, 5, 5, 4, 5, 3, 5, 10, 6, 4, 6, - 7, 7, 5, 9, 6, 9, 3, 10, 7, 9, 3, 6, 6, - 4, 6, 3, 7, 6, 6, 13, 2, 2, 5, 5, 7, 7, + 7, 6, 7, 9, 3, 3, 10, 9, 6, 9, 6, 6, 4, + 6, 3, 7, 6, 7, 5, 13, 2, 2, 5, 5, 6, 7, 3, 7, 4, 4, 2, 7, 3, 8, 6, 4, 7, 6, 6, 8, 10, 9, 6, 5, 12, 12, 17, 6, 5, 4, 6, 8, 2, 4, 7, 4, 5, 4, 4, 5, 6, 9, 6, 7, 4, - 2, 6, 3, 6, 4, 5, 8, 5, 5, 8, 3, 4, 5, - 6, 5, 6, 6, 4, 5, + 2, 6, 3, 6, 4, 5, 7, 5, 8, 5, 8, 3, 4, + 5, 6, 5, 6, 6, 4, 5, }; - static const unsigned short int aOffset[110] = { + static const unsigned short int aOffset[111] = { 0, 4, 7, 10, 10, 14, 19, 21, 26, 27, 32, 34, 36, 42, 51, 52, 57, 61, 65, 67, 71, 74, 78, 86, 91, 94, - 99, 105, 107, 110, 118, 123, 132, 134, 143, 148, 153, 157, 162, - 167, 170, 172, 172, 176, 180, 186, 188, 190, 199, 202, 206, 213, - 219, 219, 222, 225, 229, 231, 232, 236, 243, 249, 253, 260, 266, - 272, 280, 287, 296, 302, 307, 319, 319, 335, 339, 344, 348, 354, - 355, 362, 365, 372, 375, 380, 384, 388, 391, 397, 406, 412, 419, - 422, 422, 425, 428, 434, 438, 442, 450, 454, 459, 467, 469, 473, - 478, 484, 489, 495, 501, 504, + 99, 105, 108, 113, 118, 122, 124, 133, 141, 146, 155, 160, 165, + 168, 170, 170, 174, 178, 180, 185, 187, 189, 198, 201, 205, 211, + 217, 217, 220, 223, 227, 229, 230, 234, 241, 247, 251, 258, 264, + 270, 278, 285, 294, 300, 305, 317, 317, 333, 337, 342, 346, 352, + 353, 360, 363, 370, 373, 378, 382, 386, 389, 395, 404, 410, 417, + 420, 420, 423, 426, 432, 436, 440, 447, 451, 459, 464, 472, 474, + 478, 483, 489, 494, 500, 506, 509, }; - static const unsigned char aCode[110] = { + static const unsigned char aCode[111] = { TK_ABORT, TK_TABLE, TK_JOIN_KW, TK_TEMP, TK_TEMP, TK_OR, TK_ADD, TK_DATABASE, TK_AS, TK_SELECT, TK_THEN, TK_END, TK_DEFAULT, TK_TRANSACTION,TK_ON, TK_JOIN_KW, TK_ALTER, TK_RAISE, TK_EACH, TK_CHECK, TK_KEY, TK_AFTER, TK_REFERENCES, TK_ESCAPE, TK_ELSE, - TK_EXCEPT, TK_TRIGGER, TK_REINDEX, TK_INDEX, TK_EXCLUSIVE, - TK_EXISTS, TK_STATEMENT, TK_AND, TK_DEFERRABLE, TK_EXPLAIN, - TK_INITIALLY, TK_ALL, TK_ATTACH, TK_HAVING, TK_GLOB, - TK_BEFORE, TK_FOR, TK_FOREIGN, TK_IGNORE, TK_RENAME, + TK_EXCEPT, TK_TRIGGER, TK_LIKE_KW, TK_EXPLAIN, TK_INITIALLY, + TK_ALL, TK_AND, TK_DEFERRABLE, TK_EXCLUSIVE, TK_EXISTS, + TK_STATEMENT, TK_ATTACH, TK_HAVING, TK_LIKE_KW, TK_BEFORE, + TK_FOR, TK_FOREIGN, TK_IGNORE, TK_REINDEX, TK_INDEX, TK_AUTOINCR, TK_TO, TK_IN, TK_BEGIN, TK_JOIN_KW, - TK_REPLACE, TK_BETWEEN, TK_NOT, TK_NOTNULL, TK_NULL, - TK_LIKE, TK_BY, TK_CASCADE, TK_ASC, TK_DEFERRED, + TK_RENAME, TK_BETWEEN, TK_NOT, TK_NOTNULL, TK_NULL, + TK_LIKE_KW, TK_BY, TK_CASCADE, TK_ASC, TK_DEFERRED, TK_DELETE, TK_CASE, TK_COLLATE, TK_COLUMNKW, TK_COMMIT, TK_CONFLICT, TK_CONSTRAINT, TK_INTERSECT, TK_CREATE, TK_JOIN_KW, - TK_CDATE, TK_CTIME, TK_CTIMESTAMP, TK_PRAGMA, TK_MATCH, + TK_CTIME_KW, TK_CTIME_KW, TK_CTIME_KW, TK_PRAGMA, TK_MATCH, TK_DESC, TK_DETACH, TK_DISTINCT, TK_IS, TK_DROP, TK_PRIMARY, TK_FAIL, TK_LIMIT, TK_FROM, TK_JOIN_KW, TK_GROUP, TK_UPDATE, TK_IMMEDIATE, TK_INSERT, TK_INSTEAD, TK_INTO, TK_OF, TK_OFFSET, TK_SET, TK_ISNULL, - TK_JOIN, TK_ORDER, TK_RESTRICT, TK_JOIN_KW, TK_JOIN_KW, - TK_ROLLBACK, TK_ROW, TK_WHEN, TK_UNION, TK_UNIQUE, - TK_USING, TK_VACUUM, TK_VALUES, TK_VIEW, TK_WHERE, + TK_JOIN, TK_ORDER, TK_REPLACE, TK_JOIN_KW, TK_RESTRICT, + TK_JOIN_KW, TK_ROLLBACK, TK_ROW, TK_WHEN, TK_UNION, + TK_UNIQUE, TK_USING, TK_VACUUM, TK_VALUES, TK_VIEW, + TK_WHERE, }; int h, i; if( n<2 ) return TK_ID; --- sqlite/main.c +++ sqlite/main.c @@ -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.284 2005/03/29 03:10:59 danielk1977 Exp $ +** $Id: main.c,v 1.293 2005/05/26 16:23:34 drh Exp $ */ #include "sqliteInt.h" #include "os.h" @@ -35,367 +35,20 @@ static sqlite3 *pDbList = 0; #endif - -/* -** Fill the InitData structure with an error message that indicates -** that the database is corrupt. +#ifndef SQLITE_OMIT_UTF16 +/* +** Return the transient sqlite3_value object used for encoding conversions +** during SQL compilation. */ -static void corruptSchema(InitData *pData, const char *zExtra){ - if( !sqlite3_malloc_failed ){ - sqlite3SetString(pData->pzErrMsg, "malformed database schema", - zExtra!=0 && zExtra[0]!=0 ? " - " : (char*)0, zExtra, (char*)0); +sqlite3_value *sqlite3GetTransientValue(sqlite3 *db){ + if( !db->pValue ){ + db->pValue = sqlite3ValueNew(); } + return db->pValue; } - -/* -** This is the callback routine for the code that initializes the -** database. See sqlite3Init() below for additional information. -** This routine is also called from the OP_ParseSchema opcode of the VDBE. -** -** Each callback contains the following information: -** -** argv[0] = name of thing being created -** argv[1] = root page number for table or index. NULL for trigger or view. -** argv[2] = SQL text for the CREATE statement. -** argv[3] = "1" for temporary files, "0" for main database, "2" or more -** for auxiliary database files. -** -*/ -int sqlite3InitCallback(void *pInit, int argc, char **argv, char **azColName){ - InitData *pData = (InitData*)pInit; - sqlite3 *db = pData->db; - int iDb; - - assert( argc==4 ); - if( argv==0 ) return 0; /* Might happen if EMPTY_RESULT_CALLBACKS are on */ - if( argv[1]==0 || argv[3]==0 ){ - corruptSchema(pData, 0); - return 1; - } - iDb = atoi(argv[3]); - assert( iDb>=0 && iDbnDb ); - if( argv[2] && argv[2][0] ){ - /* Call the parser to process a CREATE TABLE, INDEX or VIEW. - ** But because db->init.busy is set to 1, no VDBE code is generated - ** or executed. All the parser does is build the internal data - ** structures that describe the table, index, or view. - */ - char *zErr; - int rc; - assert( db->init.busy ); - db->init.iDb = iDb; - db->init.newTnum = atoi(argv[1]); - rc = sqlite3_exec(db, argv[2], 0, 0, &zErr); - db->init.iDb = 0; - if( SQLITE_OK!=rc ){ - corruptSchema(pData, zErr); - sqlite3_free(zErr); - return rc; - } - }else{ - /* If the SQL column is blank it means this is an index that - ** was created to be the PRIMARY KEY or to fulfill a UNIQUE - ** constraint for a CREATE TABLE. The index should have already - ** been created when we processed the CREATE TABLE. All we have - ** to do here is record the root page number for that index. - */ - Index *pIndex; - pIndex = sqlite3FindIndex(db, argv[0], db->aDb[iDb].zName); - if( pIndex==0 || pIndex->tnum!=0 ){ - /* This can occur if there exists an index on a TEMP table which - ** has the same name as another index on a permanent index. Since - ** the permanent table is hidden by the TEMP table, we can also - ** safely ignore the index on the permanent table. - */ - /* Do Nothing */; - }else{ - pIndex->tnum = atoi(argv[1]); - } - } - return 0; -} - -/* -** Attempt to read the database schema and initialize internal -** data structures for a single database file. The index of the -** database file is given by iDb. iDb==0 is used for the main -** database. iDb==1 should never be used. iDb>=2 is used for -** auxiliary databases. Return one of the SQLITE_ error codes to -** indicate success or failure. -*/ -static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){ - int rc; - BtCursor *curMain; - int size; - Table *pTab; - char const *azArg[5]; - char zDbNum[30]; - int meta[10]; - InitData initData; - char const *zMasterSchema; - char const *zMasterName = SCHEMA_TABLE(iDb); - - /* - ** The master database table has a structure like this - */ - static const char master_schema[] = - "CREATE TABLE sqlite_master(\n" - " type text,\n" - " name text,\n" - " tbl_name text,\n" - " rootpage integer,\n" - " sql text\n" - ")" - ; -#ifndef SQLITE_OMIT_TEMPDB - static const char temp_master_schema[] = - "CREATE TEMP TABLE sqlite_temp_master(\n" - " type text,\n" - " name text,\n" - " tbl_name text,\n" - " rootpage integer,\n" - " sql text\n" - ")" - ; -#else - #define temp_master_schema 0 #endif - assert( iDb>=0 && iDbnDb ); - - /* 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. - */ - if( !OMIT_TEMPDB && iDb==1 ){ - zMasterSchema = temp_master_schema; - }else{ - zMasterSchema = master_schema; - } - zMasterName = SCHEMA_TABLE(iDb); - - /* Construct the schema tables. */ - sqlite3SafetyOff(db); - azArg[0] = zMasterName; - azArg[1] = "1"; - azArg[2] = zMasterSchema; - sprintf(zDbNum, "%d", iDb); - azArg[3] = zDbNum; - azArg[4] = 0; - initData.db = db; - initData.pzErrMsg = pzErrMsg; - rc = sqlite3InitCallback(&initData, 4, (char **)azArg, 0); - if( rc!=SQLITE_OK ){ - sqlite3SafetyOn(db); - return rc; - } - pTab = sqlite3FindTable(db, zMasterName, db->aDb[iDb].zName); - if( pTab ){ - pTab->readOnly = 1; - } - sqlite3SafetyOn(db); - - /* Create a cursor to hold the database open - */ - if( db->aDb[iDb].pBt==0 ){ - if( !OMIT_TEMPDB && iDb==1 ) DbSetProperty(db, 1, DB_SchemaLoaded); - return SQLITE_OK; - } - rc = sqlite3BtreeCursor(db->aDb[iDb].pBt, MASTER_ROOT, 0, 0, 0, &curMain); - if( rc!=SQLITE_OK && rc!=SQLITE_EMPTY ){ - sqlite3SetString(pzErrMsg, sqlite3ErrStr(rc), (char*)0); - return rc; - } - - /* Get the database meta information. - ** - ** Meta values are as follows: - ** meta[0] Schema cookie. Changes with each schema change. - ** meta[1] File format of schema layer. - ** meta[2] Size of the page cache. - ** meta[3] Use freelist if 0. Autovacuum if greater than zero. - ** meta[4] Db text encoding. 1:UTF-8 3:UTF-16 LE 4:UTF-16 BE - ** meta[5] The user cookie. Used by the application. - ** meta[6] - ** meta[7] - ** meta[8] - ** meta[9] - ** - ** Note: The hash defined SQLITE_UTF* symbols in sqliteInt.h correspond to - ** the possible values of meta[4]. - */ - if( rc==SQLITE_OK ){ - int i; - for(i=0; rc==SQLITE_OK && iaDb[iDb].pBt, i+1, (u32 *)&meta[i]); - } - if( rc ){ - sqlite3SetString(pzErrMsg, sqlite3ErrStr(rc), (char*)0); - sqlite3BtreeCloseCursor(curMain); - return rc; - } - }else{ - memset(meta, 0, sizeof(meta)); - } - db->aDb[iDb].schema_cookie = meta[0]; - - /* If opening a non-empty database, check the text encoding. For the - ** main database, set sqlite3.enc to the encoding of the main database. - ** For an attached db, it is an error if the encoding is not the same - ** as sqlite3.enc. - */ - if( meta[4] ){ /* text encoding */ - if( iDb==0 ){ - /* If opening the main database, set db->enc. */ - db->enc = (u8)meta[4]; - db->pDfltColl = sqlite3FindCollSeq(db, db->enc, "BINARY", 6, 0); - }else{ - /* If opening an attached database, the encoding much match db->enc */ - if( meta[4]!=db->enc ){ - sqlite3BtreeCloseCursor(curMain); - sqlite3SetString(pzErrMsg, "attached databases must use the same" - " text encoding as main database", (char*)0); - return SQLITE_ERROR; - } - } - } - - size = meta[2]; - if( size==0 ){ size = MAX_PAGES; } - db->aDb[iDb].cache_size = size; - - if( iDb==0 ){ - db->file_format = meta[1]; - if( db->file_format==0 ){ - /* This happens if the database was initially empty */ - db->file_format = 1; - } - - if( db->file_format==2 || db->file_format==3 ){ - /* File format 2 is treated exactly as file format 1. New - ** databases are created with file format 1. - */ - db->file_format = 1; - } - } - - /* - ** file_format==1 Version 3.0.0. - ** file_format==2 Version 3.1.3. - ** file_format==3 Version 3.1.4. - ** - ** Version 3.0 can only use files with file_format==1. Version 3.1.3 - ** can read and write files with file_format==1 or file_format==2. - ** Version 3.1.4 can read and write file formats 1, 2 and 3. - */ - if( meta[1]>3 ){ - sqlite3BtreeCloseCursor(curMain); - sqlite3SetString(pzErrMsg, "unsupported file format", (char*)0); - return SQLITE_ERROR; - } - - sqlite3BtreeSetCacheSize(db->aDb[iDb].pBt, db->aDb[iDb].cache_size); - - /* Read the schema information out of the schema tables - */ - assert( db->init.busy ); - if( rc==SQLITE_EMPTY ){ - /* For an empty database, there is nothing to read */ - rc = SQLITE_OK; - }else{ - char *zSql; - zSql = sqlite3MPrintf( - "SELECT name, rootpage, sql, '%s' FROM '%q'.%s", - zDbNum, db->aDb[iDb].zName, zMasterName); - sqlite3SafetyOff(db); - rc = sqlite3_exec(db, zSql, sqlite3InitCallback, &initData, 0); - sqlite3SafetyOn(db); - sqliteFree(zSql); - sqlite3BtreeCloseCursor(curMain); - } - if( sqlite3_malloc_failed ){ - sqlite3SetString(pzErrMsg, "out of memory", (char*)0); - rc = SQLITE_NOMEM; - sqlite3ResetInternalSchema(db, 0); - } - if( rc==SQLITE_OK ){ - DbSetProperty(db, iDb, DB_SchemaLoaded); - }else{ - sqlite3ResetInternalSchema(db, iDb); - } - return rc; -} - /* -** Initialize all database files - the main database file, the file -** used to store temporary tables, and any additional database files -** created using ATTACH statements. Return a success code. If an -** error occurs, write an error message into *pzErrMsg. -** -** After the database is initialized, the SQLITE_Initialized -** bit is set in the flags field of the sqlite structure. -*/ -int sqlite3Init(sqlite3 *db, char **pzErrMsg){ - int i, rc; - - if( db->init.busy ) return SQLITE_OK; - assert( (db->flags & SQLITE_Initialized)==0 ); - rc = SQLITE_OK; - db->init.busy = 1; - for(i=0; rc==SQLITE_OK && inDb; i++){ - if( DbHasProperty(db, i, DB_SchemaLoaded) || i==1 ) continue; - rc = sqlite3InitOne(db, i, pzErrMsg); - if( rc ){ - sqlite3ResetInternalSchema(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. - */ -#ifndef SQLITE_OMIT_TEMPDB - if( rc==SQLITE_OK && db->nDb>1 && !DbHasProperty(db, 1, DB_SchemaLoaded) ){ - rc = sqlite3InitOne(db, 1, pzErrMsg); - if( rc ){ - sqlite3ResetInternalSchema(db, 1); - } - } -#endif - - db->init.busy = 0; - if( rc==SQLITE_OK ){ - db->flags |= SQLITE_Initialized; - sqlite3CommitInternalChanges(db); - } - - if( rc!=SQLITE_OK ){ - db->flags &= ~SQLITE_Initialized; - } - return rc; -} - -/* -** This routine is a no-op if the database schema is already initialised. -** Otherwise, the schema is loaded. An error code is returned. -*/ -int sqlite3ReadSchema(Parse *pParse){ - int rc = SQLITE_OK; - sqlite3 *db = pParse->db; - if( !db->init.busy ){ - if( (db->flags & SQLITE_Initialized)==0 ){ - rc = sqlite3Init(db, &pParse->zErrMsg); - } - } - assert( rc!=SQLITE_OK || (db->flags & SQLITE_Initialized)||db->init.busy ); - if( rc!=SQLITE_OK ){ - pParse->rc = rc; - pParse->nErr++; - } - return rc; -} - -/* ** The version of the library */ const char rcsid3[] = "@(#) \044Id: SQLite version " SQLITE_VERSION " $"; @@ -478,6 +131,10 @@ return SQLITE_MISUSE; } +#ifdef SQLITE_SSE + sqlite3_finalize(db->pFetch); +#endif + /* If there are any outstanding VMs, return SQLITE_BUSY. */ if( db->pVdbe ){ sqlite3Error(db, SQLITE_BUSY, @@ -531,8 +188,9 @@ #ifndef SQLITE_OMIT_GLOBALRECOVER { - sqlite3 *pPrev = pDbList; + sqlite3 *pPrev; sqlite3OsEnterMutex(); + pPrev = pDbList; while( pPrev && pPrev->pNext!=db ){ pPrev = pPrev->pNext; } @@ -613,24 +271,25 @@ ** argument. */ static int sqliteDefaultBusyCallback( - void *Timeout, /* Maximum amount of time to wait */ + void *ptr, /* Database connection */ int count /* Number of times table has been busy */ ){ #if SQLITE_MIN_SLEEP_MS==1 - static const char delays[] = - { 1, 2, 5, 10, 15, 20, 25, 25, 25, 50, 50, 50, 100}; - static const short int totals[] = - { 0, 1, 3, 8, 18, 33, 53, 78, 103, 128, 178, 228, 287}; + static const u8 delays[] = + { 1, 2, 5, 10, 15, 20, 25, 25, 25, 50, 50, 100 }; + static const u8 totals[] = + { 0, 1, 3, 8, 18, 33, 53, 78, 103, 128, 178, 228 }; # define NDELAY (sizeof(delays)/sizeof(delays[0])) - ptr timeout = (ptr)Timeout; - ptr delay, prior; + int timeout = ((sqlite3 *)ptr)->busyTimeout; + int delay, prior; - if( count <= NDELAY ){ - delay = delays[count-1]; - prior = totals[count-1]; + assert( count>=0 ); + if( count < NDELAY ){ + delay = delays[count]; + prior = totals[count]; }else{ delay = delays[NDELAY-1]; - prior = totals[NDELAY-1] + delay*(count-NDELAY-1); + prior = totals[NDELAY-1] + delay*(count-(NDELAY-1)); } if( prior + delay > timeout ){ delay = timeout - prior; @@ -639,7 +298,7 @@ sqlite3OsSleep(delay); return 1; #else - int timeout = (int)Timeout; + int timeout = ((sqlite3 *)ptr)->busyTimeout; if( (count+1)*1000 > timeout ){ return 0; } @@ -698,7 +357,8 @@ */ int sqlite3_busy_timeout(sqlite3 *db, int ms){ if( ms>0 ){ - sqlite3_busy_handler(db, sqliteDefaultBusyCallback, (void*)(ptr)ms); + db->busyTimeout = ms; + sqlite3_busy_handler(db, sqliteDefaultBusyCallback, (void*)db); }else{ sqlite3_busy_handler(db, 0, 0); } @@ -1006,160 +666,9 @@ } /* -** Check schema cookies in all databases. If any cookie is out -** of date, return 0. If all schema cookies are current, return 1. -*/ -static int schemaIsValid(sqlite3 *db){ - int iDb; - int rc; - BtCursor *curTemp; - int cookie; - int allOk = 1; - - for(iDb=0; allOk && iDbnDb; iDb++){ - Btree *pBt; - pBt = db->aDb[iDb].pBt; - if( pBt==0 ) continue; - rc = sqlite3BtreeCursor(pBt, MASTER_ROOT, 0, 0, 0, &curTemp); - if( rc==SQLITE_OK ){ - rc = sqlite3BtreeGetMeta(pBt, 1, (u32 *)&cookie); - if( rc==SQLITE_OK && cookie!=db->aDb[iDb].schema_cookie ){ - allOk = 0; - } - sqlite3BtreeCloseCursor(curTemp); - } - } - return allOk; -} - -/* -** Compile the UTF-8 encoded SQL statement zSql into a statement handle. -*/ -int sqlite3_prepare( - sqlite3 *db, /* Database handle. */ - const char *zSql, /* UTF-8 encoded SQL statement. */ - int nBytes, /* Length of zSql in bytes. */ - sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */ - const char** pzTail /* OUT: End of parsed string */ -){ - Parse sParse; - char *zErrMsg = 0; - int rc = SQLITE_OK; - - if( sqlite3_malloc_failed ){ - return SQLITE_NOMEM; - } - - assert( ppStmt ); - *ppStmt = 0; - if( sqlite3SafetyOn(db) ){ - return SQLITE_MISUSE; - } - - memset(&sParse, 0, sizeof(sParse)); - sParse.db = db; - sqlite3RunParser(&sParse, zSql, &zErrMsg); - - if( sqlite3_malloc_failed ){ - rc = SQLITE_NOMEM; - sqlite3RollbackAll(db); - sqlite3ResetInternalSchema(db, 0); - db->flags &= ~SQLITE_InTrans; - goto prepare_out; - } - if( sParse.rc==SQLITE_DONE ) sParse.rc = SQLITE_OK; - if( sParse.rc!=SQLITE_OK && sParse.checkSchema && !schemaIsValid(db) ){ - sParse.rc = SQLITE_SCHEMA; - } - if( sParse.rc==SQLITE_SCHEMA ){ - sqlite3ResetInternalSchema(db, 0); - } - if( pzTail ) *pzTail = sParse.zTail; - rc = sParse.rc; - -#ifndef SQLITE_OMIT_EXPLAIN - if( rc==SQLITE_OK && sParse.pVdbe && sParse.explain ){ - sqlite3VdbeSetNumCols(sParse.pVdbe, 5); - sqlite3VdbeSetColName(sParse.pVdbe, 0, "addr", P3_STATIC); - sqlite3VdbeSetColName(sParse.pVdbe, 1, "opcode", P3_STATIC); - sqlite3VdbeSetColName(sParse.pVdbe, 2, "p1", P3_STATIC); - sqlite3VdbeSetColName(sParse.pVdbe, 3, "p2", P3_STATIC); - sqlite3VdbeSetColName(sParse.pVdbe, 4, "p3", P3_STATIC); - } -#endif - -prepare_out: - if( sqlite3SafetyOff(db) ){ - rc = SQLITE_MISUSE; - } - if( rc==SQLITE_OK ){ - *ppStmt = (sqlite3_stmt*)sParse.pVdbe; - }else if( sParse.pVdbe ){ - sqlite3_finalize((sqlite3_stmt*)sParse.pVdbe); - } - - if( zErrMsg ){ - sqlite3Error(db, rc, "%s", zErrMsg); - sqliteFree(zErrMsg); - }else{ - sqlite3Error(db, rc, 0); - } - return rc; -} - -#ifndef SQLITE_OMIT_UTF16 -/* -** Compile the UTF-16 encoded SQL statement zSql into a statement handle. -*/ -int sqlite3_prepare16( - sqlite3 *db, /* Database handle. */ - const void *zSql, /* UTF-8 encoded SQL statement. */ - int nBytes, /* Length of zSql in bytes. */ - sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */ - const void **pzTail /* OUT: End of parsed string */ -){ - /* This function currently works by first transforming the UTF-16 - ** encoded string to UTF-8, then invoking sqlite3_prepare(). The - ** tricky bit is figuring out the pointer to return in *pzTail. - */ - char const *zSql8 = 0; - char const *zTail8 = 0; - int rc; - sqlite3_value *pTmp; - - if( sqlite3SafetyCheck(db) ){ - return SQLITE_MISUSE; - } - pTmp = sqlite3GetTransientValue(db); - sqlite3ValueSetStr(pTmp, -1, zSql, SQLITE_UTF16NATIVE, SQLITE_STATIC); - zSql8 = sqlite3ValueText(pTmp, SQLITE_UTF8); - if( !zSql8 ){ - sqlite3Error(db, SQLITE_NOMEM, 0); - return SQLITE_NOMEM; - } - rc = sqlite3_prepare(db, zSql8, -1, ppStmt, &zTail8); - - if( zTail8 && pzTail ){ - /* If sqlite3_prepare returns a tail pointer, we calculate the - ** equivalent pointer into the UTF-16 string by counting the unicode - ** characters between zSql8 and zTail8, and then returning a pointer - ** the same number of characters into the UTF-16 string. - */ - int chars_parsed = sqlite3utf8CharLen(zSql8, zTail8-zSql8); - *pzTail = (u8 *)zSql + sqlite3utf16ByteLen(zSql, chars_parsed); - } - - return rc; -} -#endif /* SQLITE_OMIT_UTF16 */ - -/* ** This routine does the work of opening a database on behalf of ** sqlite3_open() and sqlite3_open16(). The database filename "zFilename" -** is UTF-8 encoded. The fourth argument, "def_enc" is one of the TEXT_* -** macros from sqliteInt.h. If we end up creating a new database file -** (not opening an existing one), the text encoding of the database -** will be set to this value. +** is UTF-8 encoded. */ static int openDatabase( const char *zFilename, /* Database filename UTF-8 encoded */ @@ -1480,3 +989,15 @@ return rc; } #endif + +/* +** Test to see whether or not the database connection is in autocommit +** mode. Return TRUE if it is and FALSE if not. Autocommit mode is on +** by default. Autocommit is disabled by a BEGIN statement and reenabled +** by the next COMMIT or ROLLBACK. +** +******* THIS IS AN EXPERIMENTAL API AND IS SUBJECT TO CHANGE ****** +*/ +int sqlite3_get_autocommit(sqlite3 *db){ + return db->autoCommit; +} --- sqlite/opcodes.c +++ sqlite/opcodes.c @@ -9,129 +9,127 @@ /* 5 */ "MoveGt", /* 6 */ "AggFocus", /* 7 */ "RowKey", - /* 8 */ "IdxRecno", - /* 9 */ "AggNext", - /* 10 */ "OpenWrite", - /* 11 */ "If", - /* 12 */ "PutStrKey", - /* 13 */ "Pop", - /* 14 */ "SortPut", - /* 15 */ "AggContextPush", - /* 16 */ "CollSeq", - /* 17 */ "OpenRead", - /* 18 */ "Expire", - /* 19 */ "SortReset", - /* 20 */ "AutoCommit", - /* 21 */ "Sort", - /* 22 */ "ListRewind", - /* 23 */ "IntegrityCk", - /* 24 */ "Function", - /* 25 */ "Noop", - /* 26 */ "Return", - /* 27 */ "Variable", - /* 28 */ "String", - /* 29 */ "ParseSchema", - /* 30 */ "PutIntKey", - /* 31 */ "AggFunc", - /* 32 */ "Close", - /* 33 */ "ListWrite", - /* 34 */ "CreateIndex", - /* 35 */ "IsUnique", - /* 36 */ "IdxIsNull", - /* 37 */ "NotFound", - /* 38 */ "MustBeInt", - /* 39 */ "Halt", - /* 40 */ "IdxLT", - /* 41 */ "AddImm", - /* 42 */ "Statement", - /* 43 */ "RowData", - /* 44 */ "MemMax", - /* 45 */ "Push", - /* 46 */ "KeyAsData", - /* 47 */ "NotExists", - /* 48 */ "OpenTemp", - /* 49 */ "MemIncr", - /* 50 */ "Gosub", - /* 51 */ "AggSet", - /* 52 */ "Integer", - /* 53 */ "SortNext", - /* 54 */ "Prev", - /* 55 */ "CreateTable", - /* 56 */ "Last", - /* 57 */ "ResetCount", - /* 58 */ "Callback", - /* 59 */ "ContextPush", - /* 60 */ "DropTrigger", - /* 61 */ "DropIndex", - /* 62 */ "FullKey", - /* 63 */ "IdxGE", - /* 64 */ "Or", - /* 65 */ "And", - /* 66 */ "Not", - /* 67 */ "IdxDelete", - /* 68 */ "Vacuum", - /* 69 */ "MoveLe", - /* 70 */ "IsNull", - /* 71 */ "NotNull", - /* 72 */ "Ne", - /* 73 */ "Eq", - /* 74 */ "Gt", - /* 75 */ "Le", - /* 76 */ "Lt", - /* 77 */ "Ge", - /* 78 */ "IfNot", - /* 79 */ "BitAnd", - /* 80 */ "BitOr", - /* 81 */ "ShiftLeft", - /* 82 */ "ShiftRight", - /* 83 */ "Add", - /* 84 */ "Subtract", - /* 85 */ "Multiply", - /* 86 */ "Divide", - /* 87 */ "Remainder", - /* 88 */ "Concat", - /* 89 */ "Negative", - /* 90 */ "DropTable", - /* 91 */ "BitNot", - /* 92 */ "String8", - /* 93 */ "MakeRecord", - /* 94 */ "Delete", - /* 95 */ "AggContextPop", - /* 96 */ "ListRead", - /* 97 */ "ListReset", - /* 98 */ "Dup", - /* 99 */ "Goto", - /* 100 */ "Clear", - /* 101 */ "IdxGT", - /* 102 */ "MoveLt", - /* 103 */ "VerifyCookie", - /* 104 */ "Pull", - /* 105 */ "SetNumColumns", - /* 106 */ "AbsValue", - /* 107 */ "Transaction", - /* 108 */ "AggGet", - /* 109 */ "ContextPop", - /* 110 */ "Next", - /* 111 */ "AggInit", - /* 112 */ "Distinct", - /* 113 */ "NewRecno", - /* 114 */ "AggReset", - /* 115 */ "Destroy", - /* 116 */ "ReadCookie", - /* 117 */ "ForceInt", - /* 118 */ "Recno", - /* 119 */ "OpenPseudo", - /* 120 */ "Blob", - /* 121 */ "MemStore", - /* 122 */ "Rewind", - /* 123 */ "MoveGe", - /* 124 */ "IdxPut", - /* 125 */ "Found", - /* 126 */ "NullRow", + /* 8 */ "AggNext", + /* 9 */ "OpenWrite", + /* 10 */ "If", + /* 11 */ "Pop", + /* 12 */ "AggContextPush", + /* 13 */ "CollSeq", + /* 14 */ "OpenRead", + /* 15 */ "Expire", + /* 16 */ "SortReset", + /* 17 */ "AutoCommit", + /* 18 */ "Sort", + /* 19 */ "ListRewind", + /* 20 */ "IntegrityCk", + /* 21 */ "SortInsert", + /* 22 */ "Function", + /* 23 */ "Noop", + /* 24 */ "Return", + /* 25 */ "NewRowid", + /* 26 */ "Variable", + /* 27 */ "String", + /* 28 */ "ParseSchema", + /* 29 */ "AggFunc", + /* 30 */ "Close", + /* 31 */ "ListWrite", + /* 32 */ "CreateIndex", + /* 33 */ "IsUnique", + /* 34 */ "IdxIsNull", + /* 35 */ "NotFound", + /* 36 */ "MustBeInt", + /* 37 */ "Halt", + /* 38 */ "Rowid", + /* 39 */ "IdxLT", + /* 40 */ "AddImm", + /* 41 */ "Statement", + /* 42 */ "RowData", + /* 43 */ "MemMax", + /* 44 */ "Push", + /* 45 */ "NotExists", + /* 46 */ "OpenTemp", + /* 47 */ "MemIncr", + /* 48 */ "Gosub", + /* 49 */ "AggSet", + /* 50 */ "Integer", + /* 51 */ "SortNext", + /* 52 */ "Prev", + /* 53 */ "CreateTable", + /* 54 */ "Last", + /* 55 */ "IdxRowid", + /* 56 */ "ResetCount", + /* 57 */ "Callback", + /* 58 */ "ContextPush", + /* 59 */ "DropTrigger", + /* 60 */ "DropIndex", + /* 61 */ "IdxGE", + /* 62 */ "Or", + /* 63 */ "And", + /* 64 */ "Not", + /* 65 */ "IdxDelete", + /* 66 */ "Vacuum", + /* 67 */ "MoveLe", + /* 68 */ "IsNull", + /* 69 */ "NotNull", + /* 70 */ "Ne", + /* 71 */ "Eq", + /* 72 */ "Gt", + /* 73 */ "Le", + /* 74 */ "Lt", + /* 75 */ "Ge", + /* 76 */ "IfNot", + /* 77 */ "BitAnd", + /* 78 */ "BitOr", + /* 79 */ "ShiftLeft", + /* 80 */ "ShiftRight", + /* 81 */ "Add", + /* 82 */ "Subtract", + /* 83 */ "Multiply", + /* 84 */ "Divide", + /* 85 */ "Remainder", + /* 86 */ "Concat", + /* 87 */ "Negative", + /* 88 */ "DropTable", + /* 89 */ "BitNot", + /* 90 */ "String8", + /* 91 */ "MakeRecord", + /* 92 */ "Delete", + /* 93 */ "AggContextPop", + /* 94 */ "ListRead", + /* 95 */ "ListReset", + /* 96 */ "Dup", + /* 97 */ "Goto", + /* 98 */ "Clear", + /* 99 */ "IdxGT", + /* 100 */ "MoveLt", + /* 101 */ "VerifyCookie", + /* 102 */ "Pull", + /* 103 */ "SetNumColumns", + /* 104 */ "AbsValue", + /* 105 */ "Transaction", + /* 106 */ "AggGet", + /* 107 */ "ContextPop", + /* 108 */ "Next", + /* 109 */ "AggInit", + /* 110 */ "IdxInsert", + /* 111 */ "Distinct", + /* 112 */ "AggReset", + /* 113 */ "Insert", + /* 114 */ "Destroy", + /* 115 */ "ReadCookie", + /* 116 */ "ForceInt", + /* 117 */ "OpenPseudo", + /* 118 */ "Null", + /* 119 */ "Blob", + /* 120 */ "MemStore", + /* 121 */ "Rewind", + /* 122 */ "MoveGe", + /* 123 */ "Found", + /* 124 */ "NullRow", + /* 125 */ "NotUsed_125", + /* 126 */ "NotUsed_126", /* 127 */ "NotUsed_127", - /* 128 */ "NotUsed_128", - /* 129 */ "NotUsed_129", - /* 130 */ "Real", - /* 131 */ "HexBlob", + /* 128 */ "Real", + /* 129 */ "HexBlob", }; #endif --- sqlite/opcodes.h +++ sqlite/opcodes.h @@ -1,146 +1,144 @@ /* Automatically generated. Do not edit */ /* See the mkopcodeh.awk script for details */ #define OP_MemLoad 1 -#define OP_HexBlob 131 /* same as TK_BLOB */ +#define OP_HexBlob 129 /* same as TK_BLOB */ #define OP_Column 2 #define OP_SetCookie 3 #define OP_IfMemPos 4 -#define OP_Real 130 /* same as TK_FLOAT */ +#define OP_Real 128 /* same as TK_FLOAT */ #define OP_MoveGt 5 -#define OP_Ge 77 /* same as TK_GE */ +#define OP_Ge 75 /* same as TK_GE */ #define OP_AggFocus 6 #define OP_RowKey 7 -#define OP_IdxRecno 8 -#define OP_AggNext 9 -#define OP_Eq 73 /* same as TK_EQ */ -#define OP_OpenWrite 10 -#define OP_NotNull 71 /* same as TK_NOTNULL */ -#define OP_If 11 -#define OP_PutStrKey 12 -#define OP_String8 92 /* same as TK_STRING */ -#define OP_Pop 13 -#define OP_SortPut 14 -#define OP_AggContextPush 15 -#define OP_CollSeq 16 -#define OP_OpenRead 17 -#define OP_Expire 18 -#define OP_SortReset 19 -#define OP_AutoCommit 20 -#define OP_Gt 74 /* same as TK_GT */ -#define OP_Sort 21 -#define OP_ListRewind 22 -#define OP_IntegrityCk 23 -#define OP_Function 24 -#define OP_Subtract 84 /* same as TK_MINUS */ -#define OP_And 65 /* same as TK_AND */ -#define OP_Noop 25 -#define OP_Return 26 -#define OP_Remainder 87 /* same as TK_REM */ -#define OP_Multiply 85 /* same as TK_STAR */ -#define OP_Variable 27 -#define OP_String 28 -#define OP_ParseSchema 29 -#define OP_PutIntKey 30 -#define OP_AggFunc 31 -#define OP_Close 32 -#define OP_ListWrite 33 -#define OP_CreateIndex 34 -#define OP_IsUnique 35 -#define OP_IdxIsNull 36 -#define OP_NotFound 37 -#define OP_MustBeInt 38 -#define OP_Halt 39 -#define OP_IdxLT 40 -#define OP_AddImm 41 -#define OP_Statement 42 -#define OP_RowData 43 -#define OP_MemMax 44 -#define OP_Push 45 -#define OP_Or 64 /* same as TK_OR */ -#define OP_KeyAsData 46 -#define OP_NotExists 47 -#define OP_OpenTemp 48 -#define OP_MemIncr 49 -#define OP_Gosub 50 -#define OP_Divide 86 /* same as TK_SLASH */ -#define OP_AggSet 51 -#define OP_Integer 52 -#define OP_SortNext 53 -#define OP_Prev 54 -#define OP_Concat 88 /* same as TK_CONCAT */ -#define OP_BitAnd 79 /* same as TK_BITAND */ -#define OP_CreateTable 55 -#define OP_Last 56 -#define OP_IsNull 70 /* same as TK_ISNULL */ -#define OP_ShiftRight 82 /* same as TK_RSHIFT */ -#define OP_ResetCount 57 -#define OP_Callback 58 -#define OP_ContextPush 59 -#define OP_DropTrigger 60 -#define OP_DropIndex 61 -#define OP_FullKey 62 -#define OP_IdxGE 63 -#define OP_IdxDelete 67 -#define OP_Vacuum 68 -#define OP_MoveLe 69 -#define OP_IfNot 78 -#define OP_DropTable 90 -#define OP_MakeRecord 93 -#define OP_Delete 94 -#define OP_AggContextPop 95 -#define OP_ListRead 96 -#define OP_ListReset 97 -#define OP_ShiftLeft 81 /* same as TK_LSHIFT */ -#define OP_Dup 98 -#define OP_Goto 99 -#define OP_Clear 100 -#define OP_IdxGT 101 -#define OP_MoveLt 102 -#define OP_Le 75 /* same as TK_LE */ -#define OP_VerifyCookie 103 -#define OP_Pull 104 -#define OP_Not 66 /* same as TK_NOT */ -#define OP_SetNumColumns 105 -#define OP_AbsValue 106 -#define OP_Transaction 107 -#define OP_Negative 89 /* same as TK_UMINUS */ -#define OP_Ne 72 /* same as TK_NE */ -#define OP_AggGet 108 -#define OP_ContextPop 109 -#define OP_BitOr 80 /* same as TK_BITOR */ -#define OP_Next 110 -#define OP_AggInit 111 -#define OP_Distinct 112 -#define OP_NewRecno 113 -#define OP_Lt 76 /* same as TK_LT */ -#define OP_AggReset 114 -#define OP_Destroy 115 -#define OP_ReadCookie 116 -#define OP_ForceInt 117 -#define OP_Recno 118 -#define OP_OpenPseudo 119 -#define OP_Blob 120 -#define OP_Add 83 /* same as TK_PLUS */ -#define OP_MemStore 121 -#define OP_Rewind 122 -#define OP_MoveGe 123 -#define OP_IdxPut 124 -#define OP_BitNot 91 /* same as TK_BITNOT */ -#define OP_Found 125 -#define OP_NullRow 126 +#define OP_AggNext 8 +#define OP_Eq 71 /* same as TK_EQ */ +#define OP_OpenWrite 9 +#define OP_NotNull 69 /* same as TK_NOTNULL */ +#define OP_If 10 +#define OP_String8 90 /* same as TK_STRING */ +#define OP_Pop 11 +#define OP_AggContextPush 12 +#define OP_CollSeq 13 +#define OP_OpenRead 14 +#define OP_Expire 15 +#define OP_SortReset 16 +#define OP_AutoCommit 17 +#define OP_Gt 72 /* same as TK_GT */ +#define OP_Sort 18 +#define OP_ListRewind 19 +#define OP_IntegrityCk 20 +#define OP_SortInsert 21 +#define OP_Function 22 +#define OP_And 63 /* same as TK_AND */ +#define OP_Subtract 82 /* same as TK_MINUS */ +#define OP_Noop 23 +#define OP_Return 24 +#define OP_Remainder 85 /* same as TK_REM */ +#define OP_NewRowid 25 +#define OP_Multiply 83 /* same as TK_STAR */ +#define OP_Variable 26 +#define OP_String 27 +#define OP_ParseSchema 28 +#define OP_AggFunc 29 +#define OP_Close 30 +#define OP_ListWrite 31 +#define OP_CreateIndex 32 +#define OP_IsUnique 33 +#define OP_IdxIsNull 34 +#define OP_NotFound 35 +#define OP_MustBeInt 36 +#define OP_Halt 37 +#define OP_Rowid 38 +#define OP_IdxLT 39 +#define OP_AddImm 40 +#define OP_Statement 41 +#define OP_RowData 42 +#define OP_MemMax 43 +#define OP_Push 44 +#define OP_Or 62 /* same as TK_OR */ +#define OP_NotExists 45 +#define OP_OpenTemp 46 +#define OP_MemIncr 47 +#define OP_Gosub 48 +#define OP_Divide 84 /* same as TK_SLASH */ +#define OP_AggSet 49 +#define OP_Integer 50 +#define OP_SortNext 51 +#define OP_Prev 52 +#define OP_Concat 86 /* same as TK_CONCAT */ +#define OP_BitAnd 77 /* same as TK_BITAND */ +#define OP_CreateTable 53 +#define OP_Last 54 +#define OP_IsNull 68 /* same as TK_ISNULL */ +#define OP_IdxRowid 55 +#define OP_ShiftRight 80 /* same as TK_RSHIFT */ +#define OP_ResetCount 56 +#define OP_Callback 57 +#define OP_ContextPush 58 +#define OP_DropTrigger 59 +#define OP_DropIndex 60 +#define OP_IdxGE 61 +#define OP_IdxDelete 65 +#define OP_Vacuum 66 +#define OP_MoveLe 67 +#define OP_IfNot 76 +#define OP_DropTable 88 +#define OP_MakeRecord 91 +#define OP_Delete 92 +#define OP_AggContextPop 93 +#define OP_ListRead 94 +#define OP_ListReset 95 +#define OP_ShiftLeft 79 /* same as TK_LSHIFT */ +#define OP_Dup 96 +#define OP_Goto 97 +#define OP_Clear 98 +#define OP_IdxGT 99 +#define OP_MoveLt 100 +#define OP_Le 73 /* same as TK_LE */ +#define OP_VerifyCookie 101 +#define OP_Pull 102 +#define OP_Not 64 /* same as TK_NOT */ +#define OP_SetNumColumns 103 +#define OP_AbsValue 104 +#define OP_Transaction 105 +#define OP_Negative 87 /* same as TK_UMINUS */ +#define OP_Ne 70 /* same as TK_NE */ +#define OP_AggGet 106 +#define OP_ContextPop 107 +#define OP_BitOr 78 /* same as TK_BITOR */ +#define OP_Next 108 +#define OP_AggInit 109 +#define OP_IdxInsert 110 +#define OP_Distinct 111 +#define OP_Lt 74 /* same as TK_LT */ +#define OP_AggReset 112 +#define OP_Insert 113 +#define OP_Destroy 114 +#define OP_ReadCookie 115 +#define OP_ForceInt 116 +#define OP_OpenPseudo 117 +#define OP_Null 118 +#define OP_Blob 119 +#define OP_Add 81 /* same as TK_PLUS */ +#define OP_MemStore 120 +#define OP_Rewind 121 +#define OP_MoveGe 122 +#define OP_BitNot 89 /* same as TK_BITNOT */ +#define OP_Found 123 +#define OP_NullRow 124 /* The following opcode values are never used */ +#define OP_NotUsed_125 125 +#define OP_NotUsed_126 126 #define OP_NotUsed_127 127 -#define OP_NotUsed_128 128 -#define OP_NotUsed_129 129 -#define NOPUSH_MASK_0 65144 -#define NOPUSH_MASK_1 59007 -#define NOPUSH_MASK_2 63483 -#define NOPUSH_MASK_3 48975 +#define NOPUSH_MASK_0 65400 +#define NOPUSH_MASK_1 61871 +#define NOPUSH_MASK_2 64446 +#define NOPUSH_MASK_3 65363 #define NOPUSH_MASK_4 65535 -#define NOPUSH_MASK_5 52991 -#define NOPUSH_MASK_6 60410 -#define NOPUSH_MASK_7 32421 +#define NOPUSH_MASK_5 46015 +#define NOPUSH_MASK_6 64254 +#define NOPUSH_MASK_7 7987 #define NOPUSH_MASK_8 0 #define NOPUSH_MASK_9 0 --- sqlite/os.h +++ sqlite/os.h @@ -23,7 +23,8 @@ ** N.B. MacOS means Mac Classic (or Carbon). Treat Darwin (OS X) as Unix. ** The MacOS build is designed to use CodeWarrior (tested with v8) */ -#if !defined(OS_UNIX) && !defined(OS_TEST) +#if !defined(OS_UNIX) && !defined(OS_TEST) && !defined(OS_OTHER) +# define OS_OTHER 0 # ifndef OS_WIN # if defined(_WIN32) || defined(WIN32) || defined(__CYGWIN__) || defined(__MINGW32__) || defined(__BORLANDC__) # define OS_WIN 1 @@ -54,6 +55,14 @@ # include "os_win.h" #endif +/* os_other.c and os_other.h are not delivered with SQLite. These files +** are place-holders that can be filled in by third-party developers to +** implement backends to their on proprietary operating systems. +*/ +#if OS_OTHER +# include "os_other.h" +#endif + /* If the SET_FULLSYNC macro is not defined above, then make it ** a no-op */ @@ -175,15 +184,19 @@ int sqlite3OsSync(OsFile*); int sqlite3OsTruncate(OsFile*, i64 size); int sqlite3OsFileSize(OsFile*, i64 *pSize); +char *sqlite3OsFullPathname(const char*); +int sqlite3OsLock(OsFile*, int); +int sqlite3OsUnlock(OsFile*, int); +int sqlite3OsCheckReservedLock(OsFile *id); + + +/* The interface for file I/O is above. Other miscellaneous functions +** are below */ + int sqlite3OsRandomSeed(char*); int sqlite3OsSleep(int ms); int sqlite3OsCurrentTime(double*); -int sqlite3OsFileModTime(OsFile*, double*); void sqlite3OsEnterMutex(void); void sqlite3OsLeaveMutex(void); -char *sqlite3OsFullPathname(const char*); -int sqlite3OsLock(OsFile*, int); -int sqlite3OsUnlock(OsFile*, int); -int sqlite3OsCheckReservedLock(OsFile *id); #endif /* _SQLITE_OS_H_ */ --- sqlite/os_unix.c +++ sqlite/os_unix.c @@ -20,6 +20,18 @@ #include #include #include + +/* +** Do not include any of the File I/O interface procedures if the +** SQLITE_OMIT_DISKIO macro is defined (indicating that there database +** will be in-memory only) +*/ +#ifndef SQLITE_OMIT_DISKIO + + +/* +** Define various macros that are missing from some systems. +*/ #ifndef O_LARGEFILE # define O_LARGEFILE 0 #endif @@ -34,7 +46,6 @@ # define O_BINARY 0 #endif - /* ** The DJGPP compiler environment looks mostly like Unix, but it ** lacks the fcntl() system call. So redefine fcntl() to be something @@ -432,7 +443,8 @@ int rc; assert( !id->isOpen ); id->dirfd = -1; - id->h = open(zFilename, O_RDWR|O_CREAT|O_LARGEFILE|O_BINARY, 0644); + id->h = open(zFilename, O_RDWR|O_CREAT|O_LARGEFILE|O_BINARY, + SQLITE_DEFAULT_FILE_PERMISSIONS); if( id->h<0 ){ #ifdef EISDIR if( errno==EISDIR ){ @@ -561,7 +573,7 @@ return SQLITE_CANTOPEN; } assert( id->dirfd<0 ); - id->dirfd = open(zDirname, O_RDONLY|O_BINARY, 0644); + id->dirfd = open(zDirname, O_RDONLY|O_BINARY, 0); if( id->dirfd<0 ){ return SQLITE_CANTOPEN; } @@ -784,7 +796,7 @@ int fd; int r; SimulateIOError(SQLITE_IOERR); - fd = open(zDirname, O_RDONLY|O_BINARY, 0644); + fd = open(zDirname, O_RDONLY|O_BINARY, 0); TRACE3("DIRSYNC %-3d (%s)\n", fd, zDirname); if( fd<0 ){ return SQLITE_CANTOPEN; @@ -1199,6 +1211,33 @@ } /* +** Turn a relative pathname into a full pathname. Return a pointer +** to the full pathname stored in space obtained from sqliteMalloc(). +** The calling function is responsible for freeing this space once it +** is no longer needed. +*/ +char *sqlite3OsFullPathname(const char *zRelative){ + char *zFull = 0; + if( zRelative[0]=='/' ){ + sqlite3SetString(&zFull, zRelative, (char*)0); + }else{ + char zBuf[5000]; + zBuf[0] = 0; + sqlite3SetString(&zFull, getcwd(zBuf, sizeof(zBuf)), "/", zRelative, + (char*)0); + } + return zFull; +} + + +#endif /* SQLITE_OMIT_DISKIO */ +/*************************************************************************** +** Everything above deals with file I/O. Everything that follows deals +** with other miscellanous aspects of the operating system interface +****************************************************************************/ + + +/* ** Get information to seed the random number generator. The seed ** is written into the buffer zBuf[256]. The calling function must ** supply a sufficiently large buffer. @@ -1279,24 +1318,6 @@ } /* -** Turn a relative pathname into a full pathname. Return a pointer -** to the full pathname stored in space obtained from sqliteMalloc(). -** The calling function is responsible for freeing this space once it -** is no longer needed. -*/ -char *sqlite3OsFullPathname(const char *zRelative){ - char *zFull = 0; - if( zRelative[0]=='/' ){ - sqlite3SetString(&zFull, zRelative, (char*)0); - }else{ - char zBuf[5000]; - sqlite3SetString(&zFull, getcwd(zBuf, sizeof(zBuf)), "/", zRelative, - (char*)0); - } - return zFull; -} - -/* ** The following variable, if set to a non-zero value, becomes the result ** returned from sqlite3OsCurrentTime(). This is used for testing. */ @@ -1321,24 +1342,4 @@ return 0; } -#if 0 /* NOT USED */ -/* -** Find the time that the file was last modified. Write the -** modification time and date as a Julian Day number into *prNow and -** return SQLITE_OK. Return SQLITE_ERROR if the modification -** time cannot be found. -*/ -int sqlite3OsFileModTime(OsFile *id, double *prNow){ - int rc; - struct stat statbuf; - if( fstat(id->h, &statbuf)==0 ){ - *prNow = statbuf.st_mtime/86400.0 + 2440587.5; - rc = SQLITE_OK; - }else{ - rc = SQLITE_ERROR; - } - return rc; -} -#endif /* NOT USED */ - #endif /* OS_UNIX */ --- sqlite/os_unix.h +++ sqlite/os_unix.h @@ -91,5 +91,12 @@ # define SQLITE_MIN_SLEEP_MS 1000 #endif +/* +** Default permissions when creating a new file +*/ +#ifndef SQLITE_DEFAULT_FILE_PERMISSIONS +# define SQLITE_DEFAULT_FILE_PERMISSIONS 0644 +#endif + #endif /* _SQLITE_OS_UNIX_H_ */ --- sqlite/os_win.c +++ sqlite/os_win.c @@ -35,6 +35,13 @@ #include "os_common.h" /* +** Do not include any of the File I/O interface procedures if the +** SQLITE_OMIT_DISKIO macro is defined (indicating that there database +** will be in-memory only) +*/ +#ifndef SQLITE_OMIT_DISKIO + +/* ** Delete the named file */ int sqlite3OsDelete(const char *zFilename){ @@ -626,6 +633,36 @@ } /* +** Turn a relative pathname into a full pathname. Return a pointer +** to the full pathname stored in space obtained from sqliteMalloc(). +** The calling function is responsible for freeing this space once it +** is no longer needed. +*/ +char *sqlite3OsFullPathname(const char *zRelative){ + char *zNotUsed; + char *zFull; + int nByte; +#ifdef __CYGWIN__ + nByte = strlen(zRelative) + MAX_PATH + 1001; + zFull = sqliteMalloc( nByte ); + if( zFull==0 ) return 0; + if( cygwin_conv_to_full_win32_path(zRelative, zFull) ) return 0; +#else + nByte = GetFullPathNameA(zRelative, 0, 0, &zNotUsed) + 1; + zFull = sqliteMalloc( nByte ); + if( zFull==0 ) return 0; + GetFullPathNameA(zRelative, nByte, zFull, &zNotUsed); +#endif + return zFull; +} + +#endif /* SQLITE_OMIT_DISKIO */ +/*************************************************************************** +** Everything above deals with file I/O. Everything that follows deals +** with other miscellanous aspects of the operating system interface +****************************************************************************/ + +/* ** Get information to seed the random number generator. The seed ** is written into the buffer zBuf[256]. The calling function must ** supply a sufficiently large buffer. @@ -698,30 +735,6 @@ } /* -** Turn a relative pathname into a full pathname. Return a pointer -** to the full pathname stored in space obtained from sqliteMalloc(). -** The calling function is responsible for freeing this space once it -** is no longer needed. -*/ -char *sqlite3OsFullPathname(const char *zRelative){ - char *zNotUsed; - char *zFull; - int nByte; -#ifdef __CYGWIN__ - nByte = strlen(zRelative) + MAX_PATH + 1001; - zFull = sqliteMalloc( nByte ); - if( zFull==0 ) return 0; - if( cygwin_conv_to_full_win32_path(zRelative, zFull) ) return 0; -#else - nByte = GetFullPathNameA(zRelative, 0, 0, &zNotUsed) + 1; - zFull = sqliteMalloc( nByte ); - if( zFull==0 ) return 0; - GetFullPathNameA(zRelative, nByte, zFull, &zNotUsed); -#endif - return zFull; -} - -/* ** The following variable, if set to a non-zero value, becomes the result ** returned from sqlite3OsCurrentTime(). This is used for testing. */ @@ -751,27 +764,4 @@ return 0; } -/* -** Find the time that the file was last modified. Write the -** modification time and date as a Julian Day number into *prNow and -** return SQLITE_OK. Return SQLITE_ERROR if the modification -** time cannot be found. -*/ -int sqlite3OsFileModTime(OsFile *id, double *prMTime){ - int rc; - FILETIME ft; - /* FILETIME structure is a 64-bit value representing the number of - ** 100-nanosecond intervals since January 1, 1601 (= JD 2305813.5). - */ - if( GetFileTime(id->h, 0, 0, &ft) ){ - double t; - t = ((double)ft.dwHighDateTime) * 4294967296.0; - *prMTime = (t + ft.dwLowDateTime)/864000000000.0 + 2305813.5; - rc = SQLITE_OK; - }else{ - rc = SQLITE_ERROR; - } - return rc; -} - #endif /* OS_WIN */ --- sqlite/pager.c +++ sqlite/pager.c @@ -18,8 +18,9 @@ ** file simultaneously, or one process from reading the database while ** another is writing. ** -** @(#) $Id: pager.c,v 1.201 2005/03/28 18:04:28 drh Exp $ +** @(#) $Id: pager.c,v 1.207 2005/06/07 02:12:30 drh Exp $ */ +#ifndef SQLITE_OMIT_DISKIO #include "sqliteInt.h" #include "os.h" #include "pager.h" @@ -171,7 +172,7 @@ #ifdef SQLITE_CHECK_PAGES u32 pageHash; #endif - /* pPager->psAligned bytes of page data follow this header */ + /* pPager->pageSize bytes of page data follow this header */ /* Pager.nExtra bytes of local data follow the page data */ }; @@ -207,9 +208,9 @@ */ #define PGHDR_TO_DATA(P) ((void*)(&(P)[1])) #define DATA_TO_PGHDR(D) (&((PgHdr*)(D))[-1]) -#define PGHDR_TO_EXTRA(G,P) ((void*)&((char*)(&(G)[1]))[(P)->psAligned]) +#define PGHDR_TO_EXTRA(G,P) ((void*)&((char*)(&(G)[1]))[(P)->pageSize]) #define PGHDR_TO_HIST(P,PGR) \ - ((PgHistory*)&((char*)(&(P)[1]))[(PGR)->psAligned+(PGR)->nExtra]) + ((PgHistory*)&((char*)(&(P)[1]))[(PGR)->pageSize+(PGR)->nExtra]) /* ** How big to make the hash table used for locating in-memory pages @@ -233,31 +234,6 @@ ** A open page cache is an instance of the following structure. */ struct Pager { - char *zFilename; /* Name of the database file */ - char *zJournal; /* Name of the journal file */ - char *zDirectory; /* Directory hold database and journal files */ - OsFile fd, jfd; /* File descriptors for database and journal */ - OsFile stfd; /* File descriptor for the statement subjournal*/ - int dbSize; /* Number of pages in the file */ - int origDbSize; /* dbSize before the current change */ - int stmtSize; /* Size of database (in pages) at stmt_begin() */ - i64 stmtJSize; /* Size of journal at stmt_begin() */ - int nRec; /* Number of pages written to the journal */ - u32 cksumInit; /* Quasi-random value added to every checksum */ - int stmtNRec; /* Number of records in stmt subjournal */ - int nExtra; /* Add this many bytes to each in-memory page */ - void (*xDestructor)(void*,int); /* Call this routine when freeing pages */ - void (*xReiniter)(void*,int); /* Call this routine when reloading pages */ - int pageSize; /* Number of bytes in a page */ - int psAligned; /* pageSize rounded up to a multiple of 8 */ - int nPage; /* Total number of in-memory pages */ - int nMaxPage; /* High water mark of nPage */ - int nRef; /* Number of in-memory pages with PgHdr.nRef>0 */ - int mxPage; /* Maximum number of pages to hold in cache */ - int nHit, nMiss, nOvfl; /* Cache hits, missing, and LRU overflows */ - int nRead,nWrite; /* Database pages read/written */ - void (*xCodec)(void*,void*,Pgno,int); /* Routine for en/decoding data */ - void *pCodecArg; /* First argument to xCodec() */ u8 journalOpen; /* True if journal file descriptors is valid */ u8 journalStarted; /* True if header of journal is synced */ u8 useJournal; /* Use a rollback journal on this file */ @@ -275,9 +251,26 @@ u8 dirtyCache; /* True if cached pages have changed */ u8 alwaysRollback; /* Disable dont_rollback() for all pages */ u8 memDb; /* True to inhibit all file I/O */ + u8 setMaster; /* True if a m-j name has been written to jrnl */ + int dbSize; /* Number of pages in the file */ + int origDbSize; /* dbSize before the current change */ + int stmtSize; /* Size of database (in pages) at stmt_begin() */ + int nRec; /* Number of pages written to the journal */ + u32 cksumInit; /* Quasi-random value added to every checksum */ + int stmtNRec; /* Number of records in stmt subjournal */ + int nExtra; /* Add this many bytes to each in-memory page */ + int pageSize; /* Number of bytes in a page */ + int nPage; /* Total number of in-memory pages */ + int nMaxPage; /* High water mark of nPage */ + int nRef; /* Number of in-memory pages with PgHdr.nRef>0 */ + int mxPage; /* Maximum number of pages to hold in cache */ u8 *aInJournal; /* One bit for each page in the database file */ u8 *aInStmt; /* One bit for each page in the database */ - u8 setMaster; /* True if a m-j name has been written to jrnl */ + char *zFilename; /* Name of the database file */ + char *zJournal; /* Name of the journal file */ + char *zDirectory; /* Directory hold database and journal files */ + OsFile fd, jfd; /* File descriptors for database and journal */ + OsFile stfd; /* File descriptor for the statement subjournal*/ BusyHandler *pBusyHandler; /* Pointer to sqlite.busyHandler */ PgHdr *pFirst, *pLast; /* List of free pages */ PgHdr *pFirstSynced; /* First free page with PgHdr.needSync==0 */ @@ -287,11 +280,30 @@ i64 journalHdr; /* Byte offset to previous journal header */ i64 stmtHdrOff; /* First journal header written this statement */ i64 stmtCksum; /* cksumInit when statement was started */ + i64 stmtJSize; /* Size of journal at stmt_begin() */ int sectorSize; /* Assumed sector size during rollback */ +#ifdef SQLITE_TEST + int nHit, nMiss, nOvfl; /* Cache hits, missing, and LRU overflows */ + int nRead,nWrite; /* Database pages read/written */ +#endif + void (*xDestructor)(void*,int); /* Call this routine when freeing pages */ + void (*xReiniter)(void*,int); /* Call this routine when reloading pages */ + void (*xCodec)(void*,void*,Pgno,int); /* Routine for en/decoding data */ + void *pCodecArg; /* First argument to xCodec() */ PgHdr *aHash[N_PG_HASH]; /* Hash table to map page number to PgHdr */ }; /* +** If SQLITE_TEST is defined then increment the variable given in +** the argument +*/ +#ifdef SQLITE_TEST +# define TEST_INCR(x) x++ +#else +# define TEST_INCR(x) +#endif + +/* ** These are bits that can be set in Pager.errMask. */ #define PAGER_ERR_FULL 0x01 /* a write() failed */ @@ -1483,22 +1495,8 @@ /* ** Change the maximum number of in-memory pages that are allowed. -** -** The maximum number is the absolute value of the mxPage parameter. -** If mxPage is negative, the noSync flag is also set. noSync bypasses -** calls to sqlite3OsSync(). The pager runs much faster with noSync on, -** but if the operating system crashes or there is an abrupt power -** failure, the database file might be left in an inconsistent and -** unrepairable state. */ void sqlite3pager_set_cachesize(Pager *pPager, int mxPage){ - if( mxPage>=0 ){ - pPager->noSync = pPager->tempFile; - if( pPager->noSync ) pPager->needSync = 0; - }else{ - pPager->noSync = 1; - mxPage = -mxPage; - } if( mxPage>10 ){ pPager->mxPage = mxPage; }else{ @@ -1541,8 +1539,15 @@ #endif /* -** Open a temporary file. Write the name of the file into zName -** (zName must be at least SQLITE_TEMPNAME_SIZE bytes long.) Write +** The following global variable is incremented whenever the library +** attempts to open a temporary file. This information is used for +** testing and analysis only. +*/ +int sqlite3_opentemp_count = 0; + +/* +** Open a temporary file. Write the name of the file into zFile +** (zFile must be at least SQLITE_TEMPNAME_SIZE bytes long.) Write ** the file descriptor into *fd. Return SQLITE_OK on success or some ** other error code if we fail. ** @@ -1552,6 +1557,7 @@ static int sqlite3pager_opentemp(char *zFile, OsFile *fd){ int cnt = 8; int rc; + sqlite3_opentemp_count++; /* Used for testing and analysis only */ do{ cnt--; sqlite3OsTempFileName(zFile); @@ -1659,7 +1665,6 @@ pPager->nRef = 0; pPager->dbSize = memDb-1; pPager->pageSize = SQLITE_DEFAULT_PAGE_SIZE; - pPager->psAligned = FORCE_ALIGNMENT(pPager->pageSize); pPager->stmtSize = 0; pPager->stmtJSize = 0; pPager->nPage = 0; @@ -1715,14 +1720,16 @@ } /* -** Set the page size. -** -** The page size must only be changed when the cache is empty. +** Set the page size. Return the new size. If the suggest new page +** size is inappropriate, then an alternative page size is selected +** and returned. */ -void sqlite3pager_set_pagesize(Pager *pPager, int pageSize){ +int sqlite3pager_set_pagesize(Pager *pPager, int pageSize){ assert( pageSize>=512 && pageSize<=SQLITE_MAX_PAGE_SIZE ); - pPager->pageSize = pageSize; - pPager->psAligned = FORCE_ALIGNMENT(pageSize); + if( !pPager->memDb ){ + pPager->pageSize = pageSize; + } + return pPager->pageSize; } /* @@ -2201,7 +2208,7 @@ TRACE3("STORE %d page %d\n", PAGERID(pPager), pList->pgno); rc = sqlite3OsWrite(&pPager->fd, PGHDR_TO_DATA(pList), pPager->pageSize); CODEC(pPager, PGHDR_TO_DATA(pList), pList->pgno, 0); - pPager->nWrite++; + TEST_INCR(pPager->nWrite); } #ifndef NDEBUG else{ @@ -2372,10 +2379,10 @@ if( pPg==0 ){ /* The requested page is not in the page cache. */ int h; - pPager->nMiss++; + TEST_INCR(pPager->nMiss); if( pPager->nPagemxPage || pPager->pFirst==0 || MEMDB ){ /* Create a new page */ - pPg = sqliteMallocRaw( sizeof(*pPg) + pPager->psAligned + pPg = sqliteMallocRaw( sizeof(*pPg) + pPager->pageSize + sizeof(u32) + pPager->nExtra + MEMDB*sizeof(PgHistory) ); if( pPg==0 ){ @@ -2458,7 +2465,7 @@ /* Unlink the old page from the free list and the hash table */ unlinkPage(pPg); - pPager->nOvfl++; + TEST_INCR(pPager->nOvfl); } pPg->pgno = pgno; if( pPager->aInJournal && (int)pgno<=pPager->origDbSize ){ @@ -2514,7 +2521,7 @@ memset(PGHDR_TO_DATA(pPg), 0, pPager->pageSize); } }else{ - pPager->nRead++; + TEST_INCR(pPager->nRead); } } #ifdef SQLITE_CHECK_PAGES @@ -2522,7 +2529,7 @@ #endif }else{ /* The requested page is in the page cache. */ - pPager->nHit++; + TEST_INCR(pPager->nHit); page_ref(pPg); } *ppPage = PGHDR_TO_DATA(pPg); @@ -3191,11 +3198,13 @@ a[3] = pPager->dbSize; a[4] = pPager->state; a[5] = pPager->errMask; +#ifdef SQLITE_TEST a[6] = pPager->nHit; a[7] = pPager->nMiss; a[8] = pPager->nOvfl; a[9] = pPager->nRead; a[10] = pPager->nWrite; +#endif return a; } @@ -3591,3 +3600,5 @@ } } #endif + +#endif /* SQLITE_OMIT_DISKIO */ --- sqlite/pager.h +++ sqlite/pager.h @@ -13,7 +13,7 @@ ** subsystem. The page cache subsystem reads and writes a file a page ** at a time and provides a journal for rollback. ** -** @(#) $Id: pager.h,v 1.42 2005/03/21 04:04:03 danielk1977 Exp $ +** @(#) $Id: pager.h,v 1.44 2005/05/20 20:01:56 drh Exp $ */ /* @@ -23,12 +23,15 @@ # define SQLITE_DEFAULT_PAGE_SIZE 1024 #endif -/* Maximum page size. The upper bound on this value is 65536 (a limit -** imposed by the 2-byte size of cell array pointers.) The -** maximum page size determines the amount of stack space allocated -** by many of the routines in pager.c and btree.c On embedded architectures -** or any machine where memory and especially stack memory is limited, -** one may wish to chose a smaller value for the maximum page size. +/* Maximum page size. The upper bound on this value is 32768. This a limit +** imposed by necessity of storing the value in a 2-byte unsigned integer +** and the fact that the page size must be a power of 2. +** +** This value is used to initialize certain arrays on the stack at +** various places in the code. On embedded machines where stack space +** is limited and the flexibility of having large pages is not needed, +** it makes good sense to reduce the maximum page size to something more +** reasonable, like 1024. */ #ifndef SQLITE_MAX_PAGE_SIZE # define SQLITE_MAX_PAGE_SIZE 8192 @@ -68,7 +71,7 @@ void sqlite3pager_set_busyhandler(Pager*, BusyHandler *pBusyHandler); void sqlite3pager_set_destructor(Pager*, void(*)(void*,int)); void sqlite3pager_set_reiniter(Pager*, void(*)(void*,int)); -void sqlite3pager_set_pagesize(Pager*, int); +int sqlite3pager_set_pagesize(Pager*, int); void sqlite3pager_read_fileheader(Pager*, int, unsigned char*); void sqlite3pager_set_cachesize(Pager*, int); int sqlite3pager_close(Pager *pPager); --- sqlite/parse.c +++ sqlite/parse.c @@ -23,8 +23,8 @@ ** GLOB, NOT LIKE, and NOT GLOB operators. */ struct LikeOp { - int opcode; /* Either TK_GLOB or TK_LIKE */ - int not; /* True if the NOT keyword is present */ + Token operator; /* "like" or "glob" or "regexp" */ + int not; /* True if the NOT keyword is present */ }; /* @@ -93,35 +93,35 @@ ** defined, then do no error processing. */ #define YYCODETYPE unsigned char -#define YYNOCODE 243 +#define YYNOCODE 241 #define YYACTIONTYPE unsigned short int #define sqlite3ParserTOKENTYPE Token typedef union { sqlite3ParserTOKENTYPE yy0; - struct LikeOp yy30; - Select* yy91; - struct AttachKey yy92; - IdList* yy232; - struct {int value; int mask;} yy319; - ExprList* yy322; - int yy328; - struct TrigEvent yy378; - struct LimitVal yy388; - Expr* yy418; - Token yy430; - SrcList* yy439; - TriggerStep* yy451; - int yy485; + Expr* yy2; + struct {int value; int mask;} yy47; + SrcList* yy67; + ExprList* yy82; + struct AttachKey yy132; + struct TrigEvent yy210; + IdList* yy240; + struct LimitVal yy244; + Token yy258; + TriggerStep* yy347; + int yy412; + struct LikeOp yy438; + Select* yy459; + int yy481; } YYMINORTYPE; #define YYSTACKDEPTH 100 #define sqlite3ParserARG_SDECL Parse *pParse; #define sqlite3ParserARG_PDECL ,Parse *pParse #define sqlite3ParserARG_FETCH Parse *pParse = yypParser->pParse #define sqlite3ParserARG_STORE yypParser->pParse = pParse -#define YYNSTATE 569 -#define YYNRULE 309 -#define YYERRORSYMBOL 143 -#define YYERRSYMDT yy485 +#define YYNSTATE 565 +#define YYNRULE 305 +#define YYERRORSYMBOL 141 +#define YYERRSYMDT yy481 #define YYFALLBACK 1 #define YY_NO_ACTION (YYNSTATE+YYNRULE+2) #define YY_ACCEPT_ACTION (YYNSTATE+YYNRULE+1) @@ -175,481 +175,467 @@ ** yy_default[] Default action for each state. */ static const YYACTIONTYPE yy_action[] = { - /* 0 */ 263, 9, 261, 154, 124, 126, 128, 130, 132, 134, - /* 10 */ 136, 138, 140, 142, 406, 2, 145, 646, 4, 369, - /* 20 */ 144, 114, 116, 112, 118, 849, 124, 126, 128, 130, - /* 30 */ 132, 134, 136, 138, 140, 142, 136, 138, 140, 142, - /* 40 */ 110, 94, 146, 157, 162, 167, 156, 161, 120, 122, - /* 50 */ 114, 116, 112, 118, 572, 124, 126, 128, 130, 132, - /* 60 */ 134, 136, 138, 140, 142, 579, 223, 533, 262, 124, - /* 70 */ 126, 128, 130, 132, 134, 136, 138, 140, 142, 7, - /* 80 */ 96, 145, 13, 535, 536, 144, 442, 78, 371, 92, - /* 90 */ 453, 373, 380, 385, 132, 134, 136, 138, 140, 142, - /* 100 */ 75, 3, 567, 388, 296, 110, 94, 146, 157, 162, - /* 110 */ 167, 156, 161, 120, 122, 114, 116, 112, 118, 77, - /* 120 */ 124, 126, 128, 130, 132, 134, 136, 138, 140, 142, - /* 130 */ 145, 10, 578, 13, 144, 11, 279, 569, 371, 6, - /* 140 */ 5, 373, 380, 385, 358, 25, 3, 567, 14, 15, - /* 150 */ 426, 507, 233, 388, 110, 94, 146, 157, 162, 167, - /* 160 */ 156, 161, 120, 122, 114, 116, 112, 118, 77, 124, - /* 170 */ 126, 128, 130, 132, 134, 136, 138, 140, 142, 577, - /* 180 */ 280, 258, 407, 77, 159, 281, 107, 106, 108, 107, - /* 190 */ 106, 108, 879, 1, 568, 172, 295, 4, 670, 14, - /* 200 */ 15, 371, 175, 145, 373, 380, 385, 144, 518, 343, - /* 210 */ 346, 16, 17, 18, 158, 367, 388, 415, 345, 410, - /* 220 */ 28, 345, 95, 402, 33, 95, 807, 110, 94, 146, - /* 230 */ 157, 162, 167, 156, 161, 120, 122, 114, 116, 112, - /* 240 */ 118, 51, 124, 126, 128, 130, 132, 134, 136, 138, - /* 250 */ 140, 142, 44, 45, 805, 101, 102, 103, 101, 102, - /* 260 */ 103, 852, 152, 222, 163, 168, 188, 261, 72, 37, - /* 270 */ 341, 40, 59, 67, 69, 305, 336, 145, 265, 36, - /* 280 */ 340, 144, 806, 338, 171, 13, 173, 174, 335, 27, - /* 290 */ 171, 403, 173, 174, 12, 460, 51, 313, 320, 322, - /* 300 */ 197, 110, 94, 146, 157, 162, 167, 156, 161, 120, - /* 310 */ 122, 114, 116, 112, 118, 288, 124, 126, 128, 130, - /* 320 */ 132, 134, 136, 138, 140, 142, 40, 59, 67, 69, - /* 330 */ 305, 336, 152, 262, 163, 168, 580, 263, 338, 261, - /* 340 */ 96, 145, 364, 362, 387, 144, 52, 170, 494, 466, - /* 350 */ 456, 14, 15, 645, 171, 31, 173, 174, 54, 81, - /* 360 */ 75, 331, 534, 601, 176, 110, 94, 146, 157, 162, - /* 370 */ 167, 156, 161, 120, 122, 114, 116, 112, 118, 77, - /* 380 */ 124, 126, 128, 130, 132, 134, 136, 138, 140, 142, - /* 390 */ 152, 367, 163, 168, 325, 57, 58, 48, 297, 32, - /* 400 */ 33, 195, 213, 207, 96, 262, 49, 96, 26, 96, - /* 410 */ 13, 83, 96, 13, 217, 145, 265, 50, 286, 144, - /* 420 */ 46, 169, 368, 401, 75, 13, 367, 75, 176, 75, - /* 430 */ 47, 235, 75, 235, 565, 33, 176, 332, 211, 110, - /* 440 */ 94, 146, 157, 162, 167, 156, 161, 120, 122, 114, - /* 450 */ 116, 112, 118, 266, 124, 126, 128, 130, 132, 134, - /* 460 */ 136, 138, 140, 142, 303, 13, 298, 229, 227, 236, - /* 470 */ 96, 692, 292, 48, 243, 96, 14, 15, 217, 14, - /* 480 */ 15, 145, 49, 822, 278, 144, 217, 455, 13, 20, - /* 490 */ 75, 14, 15, 50, 190, 75, 201, 13, 65, 176, - /* 500 */ 13, 250, 593, 253, 66, 110, 94, 146, 157, 162, - /* 510 */ 167, 156, 161, 120, 122, 114, 116, 112, 118, 77, - /* 520 */ 124, 126, 128, 130, 132, 134, 136, 138, 140, 142, - /* 530 */ 665, 14, 15, 693, 585, 250, 351, 356, 357, 871, - /* 540 */ 152, 191, 163, 168, 479, 628, 145, 327, 34, 216, - /* 550 */ 144, 366, 349, 22, 14, 15, 13, 331, 255, 171, - /* 560 */ 461, 173, 174, 14, 15, 463, 14, 15, 857, 252, - /* 570 */ 110, 94, 146, 157, 162, 167, 156, 161, 120, 122, - /* 580 */ 114, 116, 112, 118, 850, 124, 126, 128, 130, 132, - /* 590 */ 134, 136, 138, 140, 142, 251, 855, 273, 358, 187, - /* 600 */ 354, 356, 357, 252, 171, 310, 173, 174, 39, 42, - /* 610 */ 350, 399, 309, 145, 261, 829, 335, 144, 398, 455, - /* 620 */ 586, 294, 14, 15, 64, 293, 397, 667, 537, 251, - /* 630 */ 499, 77, 171, 328, 173, 174, 731, 110, 94, 146, - /* 640 */ 157, 162, 167, 156, 161, 120, 122, 114, 116, 112, - /* 650 */ 118, 77, 124, 126, 128, 130, 132, 134, 136, 138, - /* 660 */ 140, 142, 358, 312, 96, 505, 96, 501, 338, 96, - /* 670 */ 171, 96, 173, 174, 441, 845, 479, 24, 145, 532, - /* 680 */ 262, 275, 144, 331, 75, 214, 75, 215, 493, 75, - /* 690 */ 302, 75, 465, 493, 272, 91, 273, 463, 171, 694, - /* 700 */ 173, 174, 110, 94, 146, 157, 162, 167, 156, 161, - /* 710 */ 120, 122, 114, 116, 112, 118, 376, 124, 126, 128, - /* 720 */ 130, 132, 134, 136, 138, 140, 142, 587, 96, 171, - /* 730 */ 489, 173, 174, 96, 96, 525, 96, 246, 171, 271, - /* 740 */ 173, 174, 96, 145, 432, 434, 433, 144, 75, 503, - /* 750 */ 588, 452, 93, 75, 75, 348, 75, 109, 111, 332, - /* 760 */ 113, 265, 75, 342, 248, 258, 115, 110, 165, 146, - /* 770 */ 157, 162, 167, 156, 161, 120, 122, 114, 116, 112, - /* 780 */ 118, 29, 124, 126, 128, 130, 132, 134, 136, 138, - /* 790 */ 140, 142, 815, 96, 96, 96, 96, 299, 283, 215, - /* 800 */ 310, 96, 96, 96, 96, 364, 362, 219, 145, 317, - /* 810 */ 316, 275, 144, 75, 75, 75, 75, 117, 119, 121, - /* 820 */ 123, 75, 75, 75, 75, 125, 127, 129, 131, 352, - /* 830 */ 247, 353, 404, 94, 146, 157, 162, 167, 156, 161, - /* 840 */ 120, 122, 114, 116, 112, 118, 96, 124, 126, 128, - /* 850 */ 130, 132, 134, 136, 138, 140, 142, 96, 312, 96, - /* 860 */ 96, 331, 96, 331, 77, 96, 75, 96, 96, 436, - /* 870 */ 133, 30, 261, 96, 145, 96, 38, 75, 144, 75, - /* 880 */ 75, 135, 75, 137, 139, 75, 141, 75, 75, 143, - /* 890 */ 592, 153, 155, 75, 382, 75, 391, 164, 331, 166, - /* 900 */ 146, 157, 162, 167, 156, 161, 120, 122, 114, 116, - /* 910 */ 112, 118, 725, 124, 126, 128, 130, 132, 134, 136, - /* 920 */ 138, 140, 142, 76, 96, 96, 438, 71, 471, 437, - /* 930 */ 96, 449, 96, 96, 326, 96, 327, 332, 262, 332, - /* 940 */ 96, 439, 148, 42, 75, 75, 147, 35, 178, 180, - /* 950 */ 75, 199, 75, 75, 182, 75, 184, 196, 694, 198, - /* 960 */ 75, 107, 106, 108, 208, 430, 431, 177, 421, 657, - /* 970 */ 150, 151, 360, 361, 332, 96, 96, 548, 383, 421, - /* 980 */ 327, 96, 725, 318, 183, 181, 300, 96, 96, 450, - /* 990 */ 96, 327, 179, 73, 74, 75, 75, 95, 149, 210, - /* 1000 */ 212, 75, 290, 319, 96, 224, 558, 75, 75, 76, - /* 1010 */ 75, 240, 245, 71, 277, 275, 435, 423, 96, 96, - /* 1020 */ 96, 96, 75, 392, 75, 327, 287, 457, 386, 244, - /* 1030 */ 101, 102, 103, 104, 105, 185, 189, 199, 75, 75, - /* 1040 */ 75, 75, 427, 474, 478, 491, 694, 107, 106, 108, - /* 1050 */ 559, 219, 414, 177, 81, 484, 562, 273, 315, 486, - /* 1060 */ 219, 458, 45, 42, 492, 476, 490, 487, 421, 421, - /* 1070 */ 183, 181, 844, 483, 421, 421, 421, 421, 179, 73, - /* 1080 */ 74, 476, 81, 95, 77, 421, 526, 865, 490, 43, - /* 1090 */ 659, 77, 41, 53, 522, 523, 56, 55, 60, 244, - /* 1100 */ 61, 76, 81, 62, 64, 71, 500, 502, 70, 602, - /* 1110 */ 68, 63, 504, 506, 510, 514, 101, 102, 103, 104, - /* 1120 */ 105, 185, 189, 520, 546, 603, 77, 81, 470, 199, - /* 1130 */ 79, 80, 875, 244, 82, 239, 241, 84, 225, 107, - /* 1140 */ 106, 108, 85, 87, 516, 177, 86, 88, 90, 98, - /* 1150 */ 89, 97, 99, 100, 142, 160, 218, 671, 672, 673, - /* 1160 */ 186, 209, 183, 181, 194, 200, 203, 202, 192, 206, - /* 1170 */ 179, 73, 74, 204, 205, 95, 221, 193, 219, 220, - /* 1180 */ 226, 228, 232, 230, 231, 233, 242, 237, 234, 238, - /* 1190 */ 215, 249, 254, 76, 257, 260, 276, 71, 256, 259, - /* 1200 */ 264, 267, 269, 268, 270, 274, 282, 291, 101, 102, - /* 1210 */ 103, 104, 105, 185, 189, 808, 285, 301, 304, 306, - /* 1220 */ 284, 199, 324, 311, 355, 330, 307, 374, 308, 329, - /* 1230 */ 375, 107, 106, 108, 333, 309, 337, 177, 314, 334, - /* 1240 */ 372, 321, 344, 323, 378, 347, 381, 379, 365, 359, - /* 1250 */ 339, 389, 377, 400, 183, 181, 289, 384, 363, 390, - /* 1260 */ 370, 393, 179, 73, 74, 394, 395, 95, 54, 396, - /* 1270 */ 408, 409, 411, 412, 413, 416, 420, 417, 422, 76, - /* 1280 */ 428, 837, 429, 71, 443, 440, 444, 842, 843, 445, - /* 1290 */ 446, 447, 451, 448, 813, 454, 814, 459, 462, 732, - /* 1300 */ 101, 102, 103, 104, 105, 185, 189, 199, 836, 464, - /* 1310 */ 851, 457, 467, 418, 468, 733, 469, 107, 106, 108, - /* 1320 */ 424, 419, 475, 177, 473, 853, 472, 477, 425, 480, - /* 1330 */ 481, 482, 488, 485, 854, 495, 497, 856, 496, 664, - /* 1340 */ 183, 181, 666, 821, 863, 509, 511, 724, 179, 73, - /* 1350 */ 74, 513, 727, 95, 517, 515, 519, 730, 521, 524, - /* 1360 */ 8, 823, 528, 530, 824, 19, 21, 23, 405, 531, - /* 1370 */ 825, 826, 827, 539, 538, 828, 549, 542, 543, 540, - /* 1380 */ 541, 864, 544, 547, 866, 550, 101, 102, 103, 104, - /* 1390 */ 105, 185, 189, 545, 867, 552, 870, 872, 529, 557, - /* 1400 */ 460, 551, 555, 560, 554, 527, 873, 553, 561, 563, - /* 1410 */ 564, 566, 556, 874, 553, 553, 553, 553, 553, 553, - /* 1420 */ 553, 553, 553, 553, 553, 553, 553, 553, 553, 553, - /* 1430 */ 553, 553, 553, 553, 553, 553, 553, 553, 553, 553, - /* 1440 */ 553, 553, 553, 553, 553, 553, 553, 553, 553, 553, - /* 1450 */ 553, 553, 553, 508, 512, 456, 553, 553, 553, 498, - /* 1460 */ 553, 553, 553, 553, 81, + /* 0 */ 259, 65, 257, 112, 114, 110, 116, 66, 122, 124, + /* 10 */ 126, 128, 130, 132, 134, 136, 138, 140, 568, 142, + /* 20 */ 150, 122, 124, 126, 128, 130, 132, 134, 136, 138, + /* 30 */ 140, 130, 132, 134, 136, 138, 140, 108, 94, 143, + /* 40 */ 153, 158, 163, 152, 157, 118, 120, 112, 114, 110, + /* 50 */ 116, 72, 122, 124, 126, 128, 130, 132, 134, 136, + /* 60 */ 138, 140, 7, 106, 219, 258, 122, 124, 126, 128, + /* 70 */ 130, 132, 134, 136, 138, 140, 367, 13, 9, 369, + /* 80 */ 376, 381, 142, 871, 1, 564, 92, 27, 4, 399, + /* 90 */ 363, 384, 844, 341, 291, 28, 10, 95, 398, 33, + /* 100 */ 108, 94, 143, 153, 158, 163, 152, 157, 118, 120, + /* 110 */ 112, 114, 110, 116, 96, 122, 124, 126, 128, 130, + /* 120 */ 132, 134, 136, 138, 140, 456, 565, 142, 395, 305, + /* 130 */ 101, 102, 103, 288, 75, 394, 3, 563, 231, 275, + /* 140 */ 14, 15, 575, 597, 437, 108, 94, 143, 153, 158, + /* 150 */ 163, 152, 157, 118, 120, 112, 114, 110, 116, 13, + /* 160 */ 122, 124, 126, 128, 130, 132, 134, 136, 138, 140, + /* 170 */ 573, 77, 142, 223, 232, 13, 490, 462, 452, 167, + /* 180 */ 306, 169, 170, 276, 254, 3, 563, 81, 277, 183, + /* 190 */ 108, 94, 143, 153, 158, 163, 152, 157, 118, 120, + /* 200 */ 112, 114, 110, 116, 52, 122, 124, 126, 128, 130, + /* 210 */ 132, 134, 136, 138, 140, 48, 54, 799, 448, 51, + /* 220 */ 797, 77, 14, 15, 49, 363, 134, 136, 138, 140, + /* 230 */ 16, 17, 18, 32, 33, 50, 308, 197, 14, 15, + /* 240 */ 367, 261, 13, 369, 376, 381, 142, 37, 337, 40, + /* 250 */ 59, 67, 69, 301, 332, 384, 364, 397, 259, 807, + /* 260 */ 257, 334, 51, 193, 108, 94, 143, 153, 158, 163, + /* 270 */ 152, 157, 118, 120, 112, 114, 110, 116, 262, 122, + /* 280 */ 124, 126, 128, 130, 132, 134, 136, 138, 140, 13, + /* 290 */ 171, 142, 40, 59, 67, 69, 301, 332, 642, 148, + /* 300 */ 365, 159, 164, 261, 334, 14, 15, 44, 45, 108, + /* 310 */ 94, 143, 153, 158, 163, 152, 157, 118, 120, 112, + /* 320 */ 114, 110, 116, 258, 122, 124, 126, 128, 130, 132, + /* 330 */ 134, 136, 138, 140, 148, 218, 159, 164, 184, 12, + /* 340 */ 284, 417, 48, 360, 358, 293, 290, 347, 352, 353, + /* 350 */ 289, 49, 14, 15, 688, 2, 96, 148, 4, 159, + /* 360 */ 164, 257, 50, 530, 46, 142, 367, 155, 165, 369, + /* 370 */ 376, 381, 13, 576, 47, 167, 75, 169, 170, 554, + /* 380 */ 172, 384, 207, 108, 94, 143, 153, 158, 163, 152, + /* 390 */ 157, 118, 120, 112, 114, 110, 116, 154, 122, 124, + /* 400 */ 126, 128, 130, 132, 134, 136, 138, 140, 299, 354, + /* 410 */ 350, 352, 353, 96, 96, 13, 34, 20, 294, 362, + /* 420 */ 345, 144, 581, 167, 258, 169, 170, 821, 142, 558, + /* 430 */ 213, 244, 254, 75, 75, 14, 15, 172, 186, 167, + /* 440 */ 533, 169, 170, 146, 147, 417, 108, 94, 143, 153, + /* 450 */ 158, 163, 152, 157, 118, 120, 112, 114, 110, 116, + /* 460 */ 96, 122, 124, 126, 128, 130, 132, 134, 136, 138, + /* 470 */ 140, 145, 354, 142, 22, 239, 383, 589, 14, 15, + /* 480 */ 75, 36, 336, 419, 172, 187, 842, 213, 528, 582, + /* 490 */ 331, 108, 94, 143, 153, 158, 163, 152, 157, 118, + /* 500 */ 120, 112, 114, 110, 116, 249, 122, 124, 126, 128, + /* 510 */ 130, 132, 134, 136, 138, 140, 306, 661, 142, 327, + /* 520 */ 574, 849, 148, 11, 159, 164, 309, 316, 318, 168, + /* 530 */ 42, 327, 666, 327, 212, 393, 108, 94, 143, 153, + /* 540 */ 158, 163, 152, 157, 118, 120, 112, 114, 110, 116, + /* 550 */ 96, 122, 124, 126, 128, 130, 132, 134, 136, 138, + /* 560 */ 140, 847, 83, 142, 321, 641, 372, 31, 663, 282, + /* 570 */ 75, 242, 308, 689, 231, 246, 167, 334, 169, 170, + /* 580 */ 269, 108, 94, 143, 153, 158, 163, 152, 157, 118, + /* 590 */ 120, 112, 114, 110, 116, 324, 122, 124, 126, 128, + /* 600 */ 130, 132, 134, 136, 138, 140, 246, 328, 142, 328, + /* 610 */ 225, 434, 24, 39, 433, 210, 167, 211, 169, 170, + /* 620 */ 167, 331, 169, 170, 583, 435, 108, 161, 143, 153, + /* 630 */ 158, 163, 152, 157, 118, 120, 112, 114, 110, 116, + /* 640 */ 248, 122, 124, 126, 128, 130, 132, 134, 136, 138, + /* 650 */ 140, 57, 58, 142, 624, 837, 323, 727, 271, 261, + /* 660 */ 167, 243, 169, 170, 313, 312, 247, 167, 798, 169, + /* 670 */ 170, 248, 94, 143, 153, 158, 163, 152, 157, 118, + /* 680 */ 120, 112, 114, 110, 116, 96, 122, 124, 126, 128, + /* 690 */ 130, 132, 134, 136, 138, 140, 279, 247, 142, 360, + /* 700 */ 358, 6, 5, 363, 346, 75, 274, 25, 257, 489, + /* 710 */ 13, 561, 33, 503, 13, 268, 267, 269, 143, 153, + /* 720 */ 158, 163, 152, 157, 118, 120, 112, 114, 110, 116, + /* 730 */ 64, 122, 124, 126, 128, 130, 132, 134, 136, 138, + /* 740 */ 140, 26, 76, 96, 400, 77, 71, 584, 96, 451, + /* 750 */ 166, 485, 29, 76, 402, 78, 167, 71, 169, 170, + /* 760 */ 295, 451, 211, 75, 30, 257, 314, 172, 75, 195, + /* 770 */ 514, 258, 292, 14, 15, 690, 77, 14, 15, 106, + /* 780 */ 195, 77, 77, 173, 191, 315, 203, 77, 344, 215, + /* 790 */ 106, 690, 327, 77, 173, 495, 338, 588, 529, 403, + /* 800 */ 179, 177, 296, 453, 251, 209, 475, 327, 175, 73, + /* 810 */ 74, 179, 177, 95, 531, 532, 35, 213, 475, 175, + /* 820 */ 73, 74, 457, 38, 95, 378, 438, 459, 258, 501, + /* 830 */ 449, 497, 841, 411, 461, 406, 653, 76, 311, 459, + /* 840 */ 387, 71, 322, 81, 323, 42, 101, 102, 103, 104, + /* 850 */ 105, 181, 185, 96, 356, 357, 96, 101, 102, 103, + /* 860 */ 104, 105, 181, 185, 195, 76, 655, 544, 328, 71, + /* 870 */ 96, 271, 431, 75, 106, 354, 75, 489, 173, 327, + /* 880 */ 298, 215, 410, 328, 428, 430, 429, 426, 427, 96, + /* 890 */ 75, 721, 195, 76, 91, 179, 177, 71, 348, 379, + /* 900 */ 349, 323, 106, 175, 73, 74, 173, 467, 95, 75, + /* 910 */ 271, 499, 445, 93, 77, 388, 446, 323, 323, 521, + /* 920 */ 195, 454, 45, 179, 177, 285, 836, 42, 41, 432, + /* 930 */ 106, 175, 73, 74, 173, 480, 95, 269, 488, 43, + /* 940 */ 486, 101, 102, 103, 104, 105, 181, 185, 800, 721, + /* 950 */ 417, 179, 177, 229, 422, 328, 96, 96, 96, 175, + /* 960 */ 73, 74, 814, 96, 95, 522, 53, 486, 479, 101, + /* 970 */ 102, 103, 104, 105, 181, 185, 75, 75, 75, 13, + /* 980 */ 107, 109, 423, 75, 55, 8, 106, 111, 496, 857, + /* 990 */ 19, 21, 23, 401, 96, 472, 56, 101, 102, 103, + /* 1000 */ 104, 105, 181, 185, 536, 240, 81, 339, 342, 863, + /* 1010 */ 546, 61, 96, 96, 75, 96, 341, 482, 113, 483, + /* 1020 */ 95, 96, 525, 417, 456, 542, 13, 96, 96, 523, + /* 1030 */ 417, 549, 75, 75, 552, 75, 115, 117, 472, 119, + /* 1040 */ 96, 75, 14, 15, 81, 121, 96, 75, 75, 77, + /* 1050 */ 417, 123, 125, 101, 102, 103, 60, 519, 466, 96, + /* 1060 */ 75, 498, 417, 240, 127, 417, 75, 64, 500, 62, + /* 1070 */ 129, 96, 63, 690, 96, 504, 508, 452, 68, 75, + /* 1080 */ 417, 494, 96, 131, 96, 96, 81, 96, 502, 14, + /* 1090 */ 15, 75, 96, 96, 75, 133, 555, 70, 135, 96, + /* 1100 */ 506, 512, 75, 510, 75, 75, 137, 75, 139, 141, + /* 1110 */ 96, 149, 75, 75, 81, 96, 151, 160, 516, 75, + /* 1120 */ 96, 96, 96, 162, 598, 80, 599, 96, 96, 82, + /* 1130 */ 75, 240, 221, 84, 174, 75, 96, 96, 96, 176, + /* 1140 */ 75, 75, 75, 96, 178, 180, 192, 75, 75, 518, + /* 1150 */ 96, 194, 204, 96, 79, 286, 75, 75, 75, 237, + /* 1160 */ 206, 208, 220, 75, 96, 96, 96, 236, 85, 235, + /* 1170 */ 75, 96, 87, 75, 241, 75, 867, 273, 215, 283, + /* 1180 */ 86, 77, 90, 97, 75, 75, 75, 88, 382, 470, + /* 1190 */ 474, 75, 89, 98, 99, 487, 100, 140, 156, 214, + /* 1200 */ 667, 668, 669, 182, 205, 188, 190, 189, 196, 199, + /* 1210 */ 198, 201, 215, 200, 202, 216, 217, 224, 222, 228, + /* 1220 */ 227, 229, 230, 226, 234, 238, 211, 245, 233, 253, + /* 1230 */ 250, 252, 255, 272, 260, 263, 265, 256, 264, 266, + /* 1240 */ 270, 278, 287, 280, 297, 281, 300, 320, 303, 302, + /* 1250 */ 305, 307, 304, 325, 333, 329, 310, 317, 326, 351, + /* 1260 */ 355, 370, 359, 330, 319, 340, 343, 368, 371, 361, + /* 1270 */ 374, 377, 385, 335, 375, 373, 396, 386, 380, 389, + /* 1280 */ 390, 54, 366, 391, 404, 392, 407, 405, 409, 408, + /* 1290 */ 412, 413, 418, 416, 829, 414, 424, 425, 415, 834, + /* 1300 */ 420, 439, 835, 421, 436, 440, 441, 442, 443, 444, + /* 1310 */ 447, 805, 450, 806, 455, 458, 828, 460, 728, 464, + /* 1320 */ 729, 843, 453, 465, 468, 471, 463, 845, 476, 469, + /* 1330 */ 481, 478, 473, 477, 484, 846, 493, 491, 848, 492, + /* 1340 */ 660, 662, 813, 855, 505, 507, 720, 509, 511, 723, + /* 1350 */ 513, 726, 515, 815, 524, 526, 527, 520, 517, 816, + /* 1360 */ 817, 818, 819, 534, 535, 820, 856, 539, 858, 540, + /* 1370 */ 545, 538, 543, 859, 862, 548, 551, 864, 553, 550, + /* 1380 */ 537, 557, 541, 547, 865, 556, 866, 560, 559, 547, + /* 1390 */ 562, }; static const YYCODETYPE yy_lookahead[] = { - /* 0 */ 24, 150, 26, 78, 79, 80, 81, 82, 83, 84, - /* 10 */ 85, 86, 87, 88, 155, 146, 40, 23, 149, 25, - /* 20 */ 44, 74, 75, 76, 77, 11, 79, 80, 81, 82, - /* 30 */ 83, 84, 85, 86, 87, 88, 85, 86, 87, 88, - /* 40 */ 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, - /* 50 */ 74, 75, 76, 77, 9, 79, 80, 81, 82, 83, - /* 60 */ 84, 85, 86, 87, 88, 9, 25, 152, 92, 79, - /* 70 */ 80, 81, 82, 83, 84, 85, 86, 87, 88, 9, - /* 80 */ 152, 40, 26, 168, 169, 44, 227, 159, 94, 48, - /* 90 */ 231, 97, 98, 99, 83, 84, 85, 86, 87, 88, - /* 100 */ 172, 9, 10, 109, 176, 64, 65, 66, 67, 68, - /* 110 */ 69, 70, 71, 72, 73, 74, 75, 76, 77, 191, - /* 120 */ 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, - /* 130 */ 40, 151, 9, 26, 44, 12, 159, 0, 94, 147, - /* 140 */ 148, 97, 98, 99, 229, 153, 9, 10, 92, 93, - /* 150 */ 136, 159, 26, 109, 64, 65, 66, 67, 68, 69, - /* 160 */ 70, 71, 72, 73, 74, 75, 76, 77, 191, 79, - /* 170 */ 80, 81, 82, 83, 84, 85, 86, 87, 88, 9, - /* 180 */ 203, 204, 20, 191, 66, 208, 60, 61, 62, 60, - /* 190 */ 61, 62, 144, 145, 146, 112, 23, 149, 115, 92, - /* 200 */ 93, 94, 23, 40, 97, 98, 99, 44, 216, 83, - /* 210 */ 84, 13, 14, 15, 96, 152, 109, 55, 92, 57, - /* 220 */ 157, 92, 96, 160, 161, 96, 136, 64, 65, 66, - /* 230 */ 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, - /* 240 */ 77, 66, 79, 80, 81, 82, 83, 84, 85, 86, - /* 250 */ 87, 88, 188, 189, 17, 129, 130, 131, 129, 130, - /* 260 */ 131, 17, 219, 220, 221, 222, 23, 26, 22, 94, - /* 270 */ 95, 96, 97, 98, 99, 100, 101, 40, 165, 170, - /* 280 */ 171, 44, 17, 108, 111, 26, 113, 114, 179, 22, - /* 290 */ 111, 24, 113, 114, 152, 51, 66, 104, 105, 106, - /* 300 */ 137, 64, 65, 66, 67, 68, 69, 70, 71, 72, - /* 310 */ 73, 74, 75, 76, 77, 202, 79, 80, 81, 82, - /* 320 */ 83, 84, 85, 86, 87, 88, 96, 97, 98, 99, - /* 330 */ 100, 101, 219, 92, 221, 222, 9, 24, 108, 26, - /* 340 */ 152, 40, 83, 84, 173, 44, 96, 159, 104, 105, - /* 350 */ 106, 92, 93, 23, 111, 25, 113, 114, 108, 115, - /* 360 */ 172, 152, 103, 117, 176, 64, 65, 66, 67, 68, - /* 370 */ 69, 70, 71, 72, 73, 74, 75, 76, 77, 191, - /* 380 */ 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, - /* 390 */ 219, 152, 221, 222, 185, 13, 14, 18, 23, 160, - /* 400 */ 161, 136, 214, 138, 152, 92, 27, 152, 154, 152, - /* 410 */ 26, 194, 152, 26, 226, 40, 165, 38, 201, 44, - /* 420 */ 41, 22, 183, 184, 172, 26, 152, 172, 176, 172, - /* 430 */ 51, 176, 172, 176, 160, 161, 176, 228, 137, 64, - /* 440 */ 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, - /* 450 */ 75, 76, 77, 202, 79, 80, 81, 82, 83, 84, - /* 460 */ 85, 86, 87, 88, 23, 26, 214, 212, 211, 212, - /* 470 */ 152, 23, 85, 18, 214, 152, 92, 93, 226, 92, - /* 480 */ 93, 40, 27, 9, 22, 44, 226, 159, 26, 151, - /* 490 */ 172, 92, 93, 38, 176, 172, 41, 26, 29, 176, - /* 500 */ 26, 25, 9, 119, 35, 64, 65, 66, 67, 68, - /* 510 */ 69, 70, 71, 72, 73, 74, 75, 76, 77, 191, - /* 520 */ 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, - /* 530 */ 9, 92, 93, 23, 9, 25, 167, 168, 169, 9, - /* 540 */ 219, 223, 221, 222, 216, 23, 40, 25, 162, 226, - /* 550 */ 44, 165, 166, 151, 92, 93, 26, 152, 119, 111, - /* 560 */ 232, 113, 114, 92, 93, 237, 92, 93, 9, 93, - /* 570 */ 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, - /* 580 */ 74, 75, 76, 77, 11, 79, 80, 81, 82, 83, - /* 590 */ 84, 85, 86, 87, 88, 119, 9, 25, 229, 159, - /* 600 */ 167, 168, 169, 93, 111, 45, 113, 114, 171, 103, - /* 610 */ 22, 179, 180, 40, 26, 9, 179, 44, 186, 159, - /* 620 */ 9, 112, 92, 93, 102, 116, 66, 9, 22, 119, - /* 630 */ 20, 191, 111, 228, 113, 114, 9, 64, 65, 66, - /* 640 */ 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, - /* 650 */ 77, 191, 79, 80, 81, 82, 83, 84, 85, 86, - /* 660 */ 87, 88, 229, 103, 152, 55, 152, 57, 108, 152, - /* 670 */ 111, 152, 113, 114, 21, 103, 216, 151, 40, 73, - /* 680 */ 92, 152, 44, 152, 172, 23, 172, 25, 176, 172, - /* 690 */ 176, 172, 232, 176, 23, 176, 25, 237, 111, 9, - /* 700 */ 113, 114, 64, 65, 66, 67, 68, 69, 70, 71, - /* 710 */ 72, 73, 74, 75, 76, 77, 185, 79, 80, 81, - /* 720 */ 82, 83, 84, 85, 86, 87, 88, 9, 152, 111, - /* 730 */ 218, 113, 114, 152, 152, 218, 152, 25, 111, 210, - /* 740 */ 113, 114, 152, 40, 104, 105, 106, 44, 172, 139, - /* 750 */ 9, 98, 176, 172, 172, 164, 172, 176, 176, 228, - /* 760 */ 176, 165, 172, 172, 203, 204, 176, 64, 65, 66, - /* 770 */ 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, - /* 780 */ 77, 158, 79, 80, 81, 82, 83, 84, 85, 86, - /* 790 */ 87, 88, 139, 152, 152, 152, 152, 23, 202, 25, - /* 800 */ 45, 152, 152, 152, 152, 83, 84, 117, 40, 95, - /* 810 */ 96, 152, 44, 172, 172, 172, 172, 176, 176, 176, - /* 820 */ 176, 172, 172, 172, 172, 176, 176, 176, 176, 23, - /* 830 */ 118, 25, 159, 65, 66, 67, 68, 69, 70, 71, - /* 840 */ 72, 73, 74, 75, 76, 77, 152, 79, 80, 81, - /* 850 */ 82, 83, 84, 85, 86, 87, 88, 152, 103, 152, - /* 860 */ 152, 152, 152, 152, 191, 152, 172, 152, 152, 210, - /* 870 */ 176, 23, 26, 152, 40, 152, 152, 172, 44, 172, - /* 880 */ 172, 176, 172, 176, 176, 172, 176, 172, 172, 176, - /* 890 */ 9, 176, 176, 172, 185, 172, 185, 176, 152, 176, - /* 900 */ 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, - /* 910 */ 76, 77, 9, 79, 80, 81, 82, 83, 84, 85, - /* 920 */ 86, 87, 88, 22, 152, 152, 28, 26, 25, 31, - /* 930 */ 152, 185, 152, 152, 23, 152, 25, 228, 92, 228, - /* 940 */ 152, 43, 40, 103, 172, 172, 44, 163, 176, 176, - /* 950 */ 172, 50, 172, 172, 176, 172, 176, 176, 24, 176, - /* 960 */ 172, 60, 61, 62, 176, 53, 54, 66, 152, 9, - /* 970 */ 68, 69, 129, 130, 228, 152, 152, 131, 23, 152, - /* 980 */ 25, 152, 9, 32, 83, 84, 85, 152, 152, 23, - /* 990 */ 152, 25, 91, 92, 93, 172, 172, 96, 96, 176, - /* 1000 */ 176, 172, 152, 52, 152, 176, 190, 172, 172, 22, - /* 1010 */ 172, 176, 176, 26, 176, 152, 47, 190, 152, 152, - /* 1020 */ 152, 152, 172, 23, 172, 25, 176, 64, 176, 126, - /* 1030 */ 129, 130, 131, 132, 133, 134, 135, 50, 172, 172, - /* 1040 */ 172, 172, 176, 176, 176, 176, 103, 60, 61, 62, - /* 1050 */ 59, 117, 159, 66, 115, 23, 240, 25, 107, 159, - /* 1060 */ 117, 188, 189, 103, 23, 152, 25, 128, 152, 152, - /* 1070 */ 83, 84, 103, 210, 152, 152, 152, 152, 91, 92, - /* 1080 */ 93, 152, 115, 96, 191, 152, 23, 9, 25, 33, - /* 1090 */ 127, 191, 173, 173, 159, 128, 42, 182, 46, 126, - /* 1100 */ 174, 22, 115, 173, 102, 26, 190, 190, 22, 117, - /* 1110 */ 173, 175, 190, 190, 190, 190, 129, 130, 131, 132, - /* 1120 */ 133, 134, 135, 190, 46, 117, 191, 115, 215, 50, - /* 1130 */ 192, 191, 141, 126, 193, 124, 123, 195, 121, 60, - /* 1140 */ 61, 62, 196, 198, 215, 66, 197, 199, 125, 152, - /* 1150 */ 200, 117, 117, 152, 88, 96, 152, 115, 115, 115, - /* 1160 */ 22, 136, 83, 84, 17, 22, 189, 23, 224, 23, - /* 1170 */ 91, 92, 93, 25, 152, 96, 156, 225, 117, 152, - /* 1180 */ 122, 25, 101, 213, 174, 26, 122, 213, 164, 174, - /* 1190 */ 25, 205, 152, 22, 119, 156, 103, 26, 152, 152, - /* 1200 */ 152, 206, 120, 207, 22, 152, 23, 117, 129, 130, - /* 1210 */ 131, 132, 133, 134, 135, 136, 207, 23, 173, 152, - /* 1220 */ 206, 50, 22, 152, 23, 174, 177, 46, 178, 213, - /* 1230 */ 22, 60, 61, 62, 213, 180, 164, 66, 181, 174, - /* 1240 */ 152, 181, 172, 181, 23, 172, 22, 173, 165, 230, - /* 1250 */ 182, 46, 175, 184, 83, 84, 85, 173, 230, 22, - /* 1260 */ 184, 100, 91, 92, 93, 152, 177, 96, 108, 178, - /* 1270 */ 152, 156, 152, 156, 24, 152, 103, 156, 156, 22, - /* 1280 */ 39, 11, 37, 26, 139, 47, 152, 103, 103, 156, - /* 1290 */ 103, 152, 173, 22, 9, 11, 139, 187, 17, 127, - /* 1300 */ 129, 130, 131, 132, 133, 134, 135, 50, 9, 9, - /* 1310 */ 17, 64, 187, 233, 152, 127, 107, 60, 61, 62, - /* 1320 */ 235, 234, 196, 66, 73, 9, 152, 73, 236, 127, - /* 1330 */ 152, 22, 22, 217, 9, 118, 196, 9, 152, 9, - /* 1340 */ 83, 84, 9, 9, 9, 118, 196, 9, 91, 92, - /* 1350 */ 93, 187, 9, 96, 196, 107, 127, 9, 217, 22, - /* 1360 */ 11, 9, 152, 152, 9, 16, 17, 18, 19, 156, - /* 1370 */ 9, 9, 9, 23, 152, 9, 34, 165, 24, 30, - /* 1380 */ 238, 9, 152, 165, 9, 36, 129, 130, 131, 132, - /* 1390 */ 133, 134, 135, 239, 9, 152, 9, 9, 49, 20, - /* 1400 */ 51, 238, 156, 140, 152, 56, 9, 58, 152, 141, - /* 1410 */ 241, 142, 63, 9, 242, 242, 242, 242, 242, 242, - /* 1420 */ 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, - /* 1430 */ 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, - /* 1440 */ 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, - /* 1450 */ 242, 242, 242, 104, 105, 106, 242, 242, 242, 110, - /* 1460 */ 242, 242, 242, 242, 115, + /* 0 */ 25, 30, 27, 72, 73, 74, 75, 36, 77, 78, + /* 10 */ 79, 80, 81, 82, 83, 84, 85, 86, 10, 44, + /* 20 */ 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, + /* 30 */ 86, 81, 82, 83, 84, 85, 86, 62, 63, 64, + /* 40 */ 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, + /* 50 */ 75, 23, 77, 78, 79, 80, 81, 82, 83, 84, + /* 60 */ 85, 86, 10, 60, 26, 90, 77, 78, 79, 80, + /* 70 */ 81, 82, 83, 84, 85, 86, 92, 27, 148, 95, + /* 80 */ 96, 97, 44, 142, 143, 144, 48, 23, 147, 25, + /* 90 */ 150, 107, 18, 90, 24, 155, 149, 94, 158, 159, + /* 100 */ 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, + /* 110 */ 72, 73, 74, 75, 150, 77, 78, 79, 80, 81, + /* 120 */ 82, 83, 84, 85, 86, 51, 0, 44, 177, 178, + /* 130 */ 127, 128, 129, 83, 170, 184, 10, 11, 174, 157, + /* 140 */ 90, 91, 10, 115, 22, 62, 63, 64, 65, 66, + /* 150 */ 67, 68, 69, 70, 71, 72, 73, 74, 75, 27, + /* 160 */ 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, + /* 170 */ 10, 189, 44, 209, 210, 27, 102, 103, 104, 109, + /* 180 */ 45, 111, 112, 201, 202, 10, 11, 113, 206, 157, + /* 190 */ 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, + /* 200 */ 72, 73, 74, 75, 94, 77, 78, 79, 80, 81, + /* 210 */ 82, 83, 84, 85, 86, 19, 106, 134, 96, 64, + /* 220 */ 18, 189, 90, 91, 28, 150, 83, 84, 85, 86, + /* 230 */ 14, 15, 16, 158, 159, 39, 101, 41, 90, 91, + /* 240 */ 92, 163, 27, 95, 96, 97, 44, 92, 93, 94, + /* 250 */ 95, 96, 97, 98, 99, 107, 181, 182, 25, 137, + /* 260 */ 27, 106, 64, 135, 62, 63, 64, 65, 66, 67, + /* 270 */ 68, 69, 70, 71, 72, 73, 74, 75, 200, 77, + /* 280 */ 78, 79, 80, 81, 82, 83, 84, 85, 86, 27, + /* 290 */ 24, 44, 94, 95, 96, 97, 98, 99, 24, 217, + /* 300 */ 26, 219, 220, 163, 106, 90, 91, 186, 187, 62, + /* 310 */ 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, + /* 320 */ 73, 74, 75, 90, 77, 78, 79, 80, 81, 82, + /* 330 */ 83, 84, 85, 86, 217, 218, 219, 220, 24, 150, + /* 340 */ 200, 150, 19, 81, 82, 24, 110, 165, 166, 167, + /* 350 */ 114, 28, 90, 91, 24, 144, 150, 217, 147, 219, + /* 360 */ 220, 27, 39, 101, 41, 44, 92, 64, 23, 95, + /* 370 */ 96, 97, 27, 10, 51, 109, 170, 111, 112, 188, + /* 380 */ 174, 107, 135, 62, 63, 64, 65, 66, 67, 68, + /* 390 */ 69, 70, 71, 72, 73, 74, 75, 94, 77, 78, + /* 400 */ 79, 80, 81, 82, 83, 84, 85, 86, 24, 227, + /* 410 */ 165, 166, 167, 150, 150, 27, 160, 149, 212, 163, + /* 420 */ 164, 44, 10, 109, 90, 111, 112, 10, 44, 238, + /* 430 */ 224, 201, 202, 170, 170, 90, 91, 174, 174, 109, + /* 440 */ 23, 111, 112, 66, 67, 150, 62, 63, 64, 65, + /* 450 */ 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, + /* 460 */ 150, 77, 78, 79, 80, 81, 82, 83, 84, 85, + /* 470 */ 86, 94, 227, 44, 149, 212, 171, 10, 90, 91, + /* 480 */ 170, 168, 169, 188, 174, 221, 12, 224, 71, 10, + /* 490 */ 177, 62, 63, 64, 65, 66, 67, 68, 69, 70, + /* 500 */ 71, 72, 73, 74, 75, 117, 77, 78, 79, 80, + /* 510 */ 81, 82, 83, 84, 85, 86, 45, 10, 44, 150, + /* 520 */ 10, 10, 217, 13, 219, 220, 102, 103, 104, 110, + /* 530 */ 101, 150, 113, 150, 224, 64, 62, 63, 64, 65, + /* 540 */ 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, + /* 550 */ 150, 77, 78, 79, 80, 81, 82, 83, 84, 85, + /* 560 */ 86, 10, 192, 44, 183, 24, 183, 26, 10, 199, + /* 570 */ 170, 26, 101, 24, 174, 26, 109, 106, 111, 112, + /* 580 */ 26, 62, 63, 64, 65, 66, 67, 68, 69, 70, + /* 590 */ 71, 72, 73, 74, 75, 226, 77, 78, 79, 80, + /* 600 */ 81, 82, 83, 84, 85, 86, 26, 226, 44, 226, + /* 610 */ 210, 29, 149, 169, 32, 24, 109, 26, 111, 112, + /* 620 */ 109, 177, 111, 112, 10, 43, 62, 63, 64, 65, + /* 630 */ 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, + /* 640 */ 91, 77, 78, 79, 80, 81, 82, 83, 84, 85, + /* 650 */ 86, 14, 15, 44, 24, 101, 26, 10, 150, 163, + /* 660 */ 109, 116, 111, 112, 93, 94, 117, 109, 18, 111, + /* 670 */ 112, 91, 63, 64, 65, 66, 67, 68, 69, 70, + /* 680 */ 71, 72, 73, 74, 75, 150, 77, 78, 79, 80, + /* 690 */ 81, 82, 83, 84, 85, 86, 200, 117, 44, 81, + /* 700 */ 82, 145, 146, 150, 23, 170, 23, 151, 27, 174, + /* 710 */ 27, 158, 159, 157, 27, 24, 208, 26, 64, 65, + /* 720 */ 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, + /* 730 */ 100, 77, 78, 79, 80, 81, 82, 83, 84, 85, + /* 740 */ 86, 152, 23, 150, 157, 189, 27, 10, 150, 157, + /* 750 */ 157, 216, 156, 23, 153, 157, 109, 27, 111, 112, + /* 760 */ 24, 157, 26, 170, 24, 27, 33, 174, 170, 50, + /* 770 */ 214, 90, 174, 90, 91, 101, 189, 90, 91, 60, + /* 780 */ 50, 189, 189, 64, 134, 52, 136, 189, 162, 115, + /* 790 */ 60, 25, 150, 189, 64, 21, 170, 10, 150, 21, + /* 800 */ 81, 82, 83, 62, 117, 212, 214, 150, 89, 90, + /* 810 */ 91, 81, 82, 94, 166, 167, 161, 224, 214, 89, + /* 820 */ 90, 91, 230, 150, 94, 183, 225, 235, 90, 55, + /* 830 */ 229, 57, 12, 55, 230, 57, 10, 23, 105, 235, + /* 840 */ 183, 27, 24, 113, 26, 101, 127, 128, 129, 130, + /* 850 */ 131, 132, 133, 150, 127, 128, 150, 127, 128, 129, + /* 860 */ 130, 131, 132, 133, 50, 23, 125, 129, 226, 27, + /* 870 */ 150, 150, 47, 170, 60, 227, 170, 174, 64, 150, + /* 880 */ 174, 115, 157, 226, 102, 103, 104, 53, 54, 150, + /* 890 */ 170, 10, 50, 23, 174, 81, 82, 27, 24, 24, + /* 900 */ 26, 26, 60, 89, 90, 91, 64, 26, 94, 170, + /* 910 */ 150, 137, 183, 174, 189, 24, 24, 26, 26, 216, + /* 920 */ 50, 186, 187, 81, 82, 83, 101, 101, 171, 208, + /* 930 */ 60, 89, 90, 91, 64, 24, 94, 26, 24, 34, + /* 940 */ 26, 127, 128, 129, 130, 131, 132, 133, 134, 10, + /* 950 */ 150, 81, 82, 27, 134, 226, 150, 150, 150, 89, + /* 960 */ 90, 91, 10, 150, 94, 24, 171, 26, 208, 127, + /* 970 */ 128, 129, 130, 131, 132, 133, 170, 170, 170, 27, + /* 980 */ 174, 174, 174, 170, 180, 12, 60, 174, 188, 10, + /* 990 */ 17, 18, 19, 20, 150, 150, 42, 127, 128, 129, + /* 1000 */ 130, 131, 132, 133, 31, 124, 113, 81, 82, 10, + /* 1010 */ 37, 172, 150, 150, 170, 150, 90, 157, 174, 126, + /* 1020 */ 94, 150, 49, 150, 51, 46, 27, 150, 150, 56, + /* 1030 */ 150, 58, 170, 170, 61, 170, 174, 174, 150, 174, + /* 1040 */ 150, 170, 90, 91, 113, 174, 150, 170, 170, 189, + /* 1050 */ 150, 174, 174, 127, 128, 129, 46, 126, 213, 150, + /* 1060 */ 170, 188, 150, 124, 174, 150, 170, 100, 188, 171, + /* 1070 */ 174, 150, 173, 10, 150, 102, 103, 104, 171, 170, + /* 1080 */ 150, 108, 150, 174, 150, 150, 113, 150, 188, 90, + /* 1090 */ 91, 170, 150, 150, 170, 174, 59, 23, 174, 150, + /* 1100 */ 188, 213, 170, 188, 170, 170, 174, 170, 174, 174, + /* 1110 */ 150, 174, 170, 170, 113, 150, 174, 174, 188, 170, + /* 1120 */ 150, 150, 150, 174, 115, 189, 115, 150, 150, 191, + /* 1130 */ 170, 124, 119, 193, 174, 170, 150, 150, 150, 174, + /* 1140 */ 170, 170, 170, 150, 174, 174, 174, 170, 170, 157, + /* 1150 */ 150, 174, 174, 150, 190, 150, 170, 170, 170, 121, + /* 1160 */ 174, 174, 174, 170, 150, 150, 150, 174, 194, 122, + /* 1170 */ 170, 150, 196, 170, 174, 170, 139, 174, 115, 174, + /* 1180 */ 195, 189, 123, 115, 170, 170, 170, 197, 174, 174, + /* 1190 */ 174, 170, 198, 150, 115, 174, 150, 86, 94, 150, + /* 1200 */ 113, 113, 113, 23, 134, 222, 18, 223, 23, 187, + /* 1210 */ 24, 150, 115, 26, 24, 150, 154, 26, 120, 99, + /* 1220 */ 172, 27, 162, 211, 172, 120, 26, 203, 211, 117, + /* 1230 */ 150, 150, 150, 101, 150, 204, 118, 154, 205, 23, + /* 1240 */ 150, 24, 115, 204, 24, 205, 171, 23, 175, 150, + /* 1250 */ 178, 150, 176, 211, 162, 211, 179, 179, 172, 24, + /* 1260 */ 228, 46, 228, 172, 179, 170, 170, 150, 23, 163, + /* 1270 */ 24, 23, 46, 180, 171, 173, 182, 23, 171, 98, + /* 1280 */ 150, 106, 182, 175, 150, 176, 150, 154, 25, 154, + /* 1290 */ 150, 154, 154, 101, 12, 231, 40, 38, 232, 101, + /* 1300 */ 233, 137, 101, 234, 47, 150, 154, 101, 150, 23, + /* 1310 */ 171, 10, 12, 137, 185, 18, 10, 10, 125, 150, + /* 1320 */ 125, 18, 62, 105, 150, 194, 185, 10, 125, 71, + /* 1330 */ 215, 23, 71, 150, 23, 10, 194, 116, 10, 150, + /* 1340 */ 10, 10, 10, 10, 116, 194, 10, 185, 105, 10, + /* 1350 */ 194, 10, 125, 10, 150, 150, 154, 23, 215, 10, + /* 1360 */ 10, 10, 10, 150, 24, 10, 10, 25, 10, 150, + /* 1370 */ 35, 163, 163, 10, 10, 150, 154, 10, 21, 150, + /* 1380 */ 236, 150, 237, 236, 10, 138, 10, 239, 139, 240, + /* 1390 */ 140, }; -#define YY_SHIFT_USE_DFLT (-76) +#define YY_SHIFT_USE_DFLT (-70) static const short yy_shift_ofst[] = { - /* 0 */ 92, 137, -76, -76, 1349, 45, 70, -76, 198, 123, - /* 10 */ 170, 56, 327, -76, -76, -76, -76, -76, -76, 123, - /* 20 */ 525, 123, 611, 123, 718, 267, 741, 471, 330, 848, - /* 30 */ 881, 107, -76, 241, -76, 175, -76, 471, 230, -76, - /* 40 */ 840, -76, 1056, 379, -76, -76, -76, -76, -76, -76, - /* 50 */ -76, 250, 840, -76, 1054, -76, 382, -76, -76, 1052, - /* 60 */ 469, 840, 1002, -76, -76, -76, -76, 840, -76, 1086, - /* 70 */ 1257, 246, 901, 992, 1008, -76, 987, -76, 173, 1012, - /* 80 */ -76, 509, -76, 712, 1007, 1013, 1011, 1017, 1023, -76, - /* 90 */ 1257, 41, 1257, 638, 1257, -76, 1034, 471, 1035, 471, - /* 100 */ -76, -76, -76, -76, -76, -76, -76, -76, -76, 834, - /* 110 */ 1257, 768, 1257, -10, 1257, -10, 1257, -10, 1257, -10, - /* 120 */ 1257, -53, 1257, -53, 1257, 11, 1257, 11, 1257, 11, - /* 130 */ 1257, 11, 1257, -49, 1257, -49, 1257, 1066, 1257, 1066, - /* 140 */ 1257, 1066, 1257, -76, -76, -76, 902, -76, -76, -76, - /* 150 */ -76, -76, 1257, -75, 1257, -10, -76, 118, -76, 1059, - /* 160 */ -76, -76, -76, 1257, 703, 1257, -53, -76, 399, 987, - /* 170 */ 179, 83, 1042, 1043, 1044, -76, 638, 1257, 834, 1257, - /* 180 */ -76, 1257, -76, 1257, -76, 1138, 1012, 243, -76, 1079, - /* 190 */ 90, 1025, 265, 1147, -76, 1257, 163, 1257, 638, 1143, - /* 200 */ 455, 1144, -76, 1148, 471, 1146, -76, 1257, 237, 1257, - /* 210 */ 301, 1257, 638, 662, -76, 1257, -76, -76, 1061, 471, - /* 220 */ -76, -76, -76, 1257, 638, 1058, 1257, 1156, 1257, 1081, - /* 230 */ 469, -76, 1159, -76, -76, 638, 1081, 469, -76, 1257, - /* 240 */ 638, 1064, 1257, 1165, 1257, 638, -76, -76, 476, -76, - /* 250 */ -76, -76, 384, -76, 439, -76, 1075, -76, 462, 1061, - /* 260 */ 313, -76, -76, 471, -76, -76, 1093, 1082, -76, 1182, - /* 270 */ 471, 671, -76, 471, -76, -76, 1257, 638, 1012, 448, - /* 280 */ 510, 1183, 313, 1093, 1082, -76, 1171, -24, -76, -76, - /* 290 */ 1090, 387, -76, -76, -76, -76, 375, -76, 774, -76, - /* 300 */ 1194, -76, 441, 840, -76, 471, 1200, -76, 755, -76, - /* 310 */ 471, -76, 193, 951, -76, 714, -76, -76, -76, -76, - /* 320 */ 951, -76, 951, -76, 471, 911, -76, 471, 1081, 469, - /* 330 */ -76, -76, 1081, 469, -76, -76, 1159, -76, 1054, -76, - /* 340 */ -76, 126, -76, 129, -76, -76, 129, -76, -76, 588, - /* 350 */ 722, 806, -76, 722, 1201, -76, -76, -76, 843, -76, - /* 360 */ -76, -76, 843, -76, -76, -76, -76, -76, -6, 44, - /* 370 */ -76, 471, -76, 1181, 1208, 471, 522, 1221, 840, -76, - /* 380 */ 1224, 471, 955, 840, -76, 1257, 506, -76, 1205, 1237, - /* 390 */ 471, 1000, 1161, 471, 1200, -76, 560, 1160, -76, -76, - /* 400 */ -76, -76, -76, 1012, 493, 653, 162, 471, 1061, -76, - /* 410 */ 471, 934, 1250, 1012, 521, 471, 1061, 898, 640, 1173, - /* 420 */ 471, 1061, -76, 1241, 14, 1270, 1257, 573, 1245, 912, - /* 430 */ -76, -76, 1184, 1185, 969, 471, 572, -76, -76, 1238, - /* 440 */ -76, -76, 1145, 471, 943, 1187, 471, 1271, 471, 966, - /* 450 */ 960, 1285, 1157, 1284, 244, 559, 963, 379, -76, 1172, - /* 460 */ 1188, 1281, 1299, 1300, 244, 1293, 1247, 471, 1209, 471, - /* 470 */ 903, 471, 1251, 1257, 638, 1316, 1254, 1257, 638, 1202, - /* 480 */ 471, 1309, 471, 1032, -76, 939, 587, 1310, 1257, 1041, - /* 490 */ 1257, 638, 1325, 638, 1217, 471, 973, 1328, 610, 471, - /* 500 */ 1330, 471, 1333, 471, 1334, 471, 1335, 618, 1227, 471, - /* 510 */ 973, 1338, 1247, 471, 1248, 471, 903, 1343, 1229, 471, - /* 520 */ 1309, 967, 627, 1337, 1257, 1063, 1348, 474, 1352, 471, - /* 530 */ 1061, 606, 259, 1355, 1361, 1362, 1363, 471, 1350, 1366, - /* 540 */ 1342, 241, 1354, 471, 1078, 1372, 846, 1375, 1385, -76, - /* 550 */ 1342, 471, 1387, 530, 690, 1388, 1379, 471, 991, 1263, - /* 560 */ 471, 1397, 1268, 1269, 471, 1404, -76, -76, -76, + /* 0 */ 175, 126, -70, -70, 973, 8, 52, -70, 216, 510, + /* 10 */ 160, 132, 363, -70, -70, -70, -70, -70, -70, 510, + /* 20 */ 412, 510, 479, 510, 614, 64, 737, 215, 541, 740, + /* 30 */ 787, 148, -70, 334, -70, 155, -70, 215, 198, -70, + /* 40 */ 744, -70, 905, 323, -70, -70, -70, -70, -70, -70, + /* 50 */ -70, 110, 744, -70, 954, -70, 637, -70, -70, 1010, + /* 60 */ -29, 744, 967, -70, -70, -70, -70, 744, -70, 1074, + /* 70 */ 870, 28, 719, 1009, 1011, -70, 730, -70, 70, 1001, + /* 80 */ -70, 236, -70, 545, 1007, 1038, 1047, 1013, 1059, -70, + /* 90 */ 870, 38, 870, 519, 870, -70, 1068, 215, 1079, 215, + /* 100 */ -70, -70, -70, -70, -70, -70, -70, 654, 870, 609, + /* 110 */ 870, -11, 870, -11, 870, -11, 870, -11, 870, -69, + /* 120 */ 870, -69, 870, -50, 870, -50, 870, -50, 870, -50, + /* 130 */ 870, 143, 870, 143, 870, 1111, 870, 1111, 870, 1111, + /* 140 */ 870, -70, -70, 377, -70, -70, -70, -70, 870, -56, + /* 150 */ 870, -11, -70, 303, -70, 1104, -70, -70, -70, 870, + /* 160 */ 564, 870, -69, -70, 345, 730, 266, 419, 1087, 1088, + /* 170 */ 1089, -70, 519, 870, 654, 870, -70, 870, -70, 870, + /* 180 */ -70, 1180, 1001, 314, -70, 814, 83, 1070, 650, 1188, + /* 190 */ -70, 870, 128, 870, 519, 1185, 196, 1186, -70, 1187, + /* 200 */ 215, 1190, -70, 870, 202, 870, 247, 870, 519, 591, + /* 210 */ -70, 870, -70, -70, 1097, 215, -70, -70, -70, 870, + /* 220 */ 519, 1098, 870, 1191, 870, 1120, -29, -70, 1194, -70, + /* 230 */ -70, 519, 1120, -29, -70, 870, 519, 1105, 870, 1200, + /* 240 */ 870, 519, -70, -70, 580, -70, -70, -70, 388, -70, + /* 250 */ 687, -70, 1112, -70, 683, 1097, 233, -70, -70, 215, + /* 260 */ -70, -70, 1132, 1118, -70, 1216, 215, 691, -70, 215, + /* 270 */ -70, -70, 870, 519, 1001, 330, 549, 1217, 233, 1132, + /* 280 */ 1118, -70, 842, -25, -70, -70, 1127, 50, -70, -70, + /* 290 */ -70, -70, 321, -70, 736, -70, 1220, -70, 384, 744, + /* 300 */ -70, 215, 1224, -70, 135, -70, 215, -70, 424, 733, + /* 310 */ -70, 571, -70, -70, -70, -70, 733, -70, 733, -70, + /* 320 */ 215, 818, -70, 215, 1120, -29, -70, -70, 1120, -29, + /* 330 */ -70, -70, 1194, -70, 954, -70, -70, 926, -70, 3, + /* 340 */ -70, -70, 3, -70, -70, 681, 618, 874, -70, 618, + /* 350 */ 1235, -70, -70, -70, 727, -70, -70, -70, 727, -70, + /* 360 */ -70, -70, -70, -70, 274, -16, -70, 215, -70, 1215, + /* 370 */ 1245, 215, 630, 1246, 744, -70, 1248, 215, 875, 744, + /* 380 */ -70, 870, 429, -70, 1226, 1254, 215, 891, 1181, 215, + /* 390 */ 1224, -70, 471, 1175, -70, -70, -70, -70, -70, 1001, + /* 400 */ 467, 122, 778, 215, 1097, -70, 215, 766, 1263, 1001, + /* 410 */ 507, 215, 1097, 582, 782, 1192, 215, 1097, -70, 1256, + /* 420 */ 820, 1282, 870, 474, 1259, 834, -70, -70, 1198, 1201, + /* 430 */ 825, 215, 554, -70, -70, 1257, -70, -70, 1164, 215, + /* 440 */ 674, 1206, 215, 1286, 215, 892, 826, 1301, 1176, 1300, + /* 450 */ 74, 511, 741, 323, -70, 1193, 1195, 1297, 1306, 1307, + /* 460 */ 74, 1303, 1260, 215, 1218, 215, 881, 215, 1258, 870, + /* 470 */ 519, 1317, 1261, 870, 519, 1203, 215, 1308, 215, 911, + /* 480 */ -70, 893, 551, 1311, 870, 914, 870, 519, 1325, 519, + /* 490 */ 1221, 215, 939, 1328, 774, 215, 1330, 215, 1331, 215, + /* 500 */ 1332, 215, 1333, 558, 1228, 215, 939, 1336, 1260, 215, + /* 510 */ 1243, 215, 881, 1339, 1227, 215, 1308, 931, 647, 1334, + /* 520 */ 870, 941, 1341, 952, 1343, 215, 1097, 417, 262, 1349, + /* 530 */ 1350, 1351, 1352, 215, 1340, 1355, 1335, 334, 1342, 215, + /* 540 */ 979, 1356, 738, 1358, 1363, -70, 1335, 215, 1364, 999, + /* 550 */ 1063, 1367, 1357, 215, 1037, 1247, 215, 1374, 1249, 1250, + /* 560 */ 215, 1376, -70, -70, -70, }; -#define YY_REDUCE_USE_DFLT (-150) +#define YY_REDUCE_USE_DFLT (-71) static const short yy_reduce_ofst[] = { - /* 0 */ 48, -131, -150, -150, -8, -150, -150, -150, -149, -20, - /* 10 */ -150, 142, -150, -150, -150, -150, -150, -150, -150, 338, - /* 20 */ -150, 402, -150, 526, -150, 254, -150, 63, 623, -150, - /* 30 */ -150, 239, -150, 386, 784, 109, -150, 724, 437, -150, - /* 40 */ 919, -150, -150, 64, -150, -150, -150, -150, -150, -150, - /* 50 */ -150, -150, 920, -150, 915, -150, -150, -150, -150, -150, - /* 60 */ 926, 930, 936, -150, -150, -150, -150, 937, -150, -150, - /* 70 */ 514, -150, 252, -150, -150, -150, -72, -150, 938, 940, - /* 80 */ -150, 941, 217, 942, 946, 949, 945, 948, 950, -150, - /* 90 */ 519, 321, 576, 321, 581, -150, -150, 997, -150, 1001, - /* 100 */ -150, -150, -150, -150, -150, -150, -150, -150, -150, 321, - /* 110 */ 582, 321, 584, 321, 590, 321, 641, 321, 642, 321, - /* 120 */ 643, 321, 644, 321, 649, 321, 650, 321, 651, 321, - /* 130 */ 652, 321, 694, 321, 705, 321, 707, 321, 708, 321, - /* 140 */ 710, 321, 713, 321, -150, -150, -150, -150, -150, -150, - /* 150 */ -150, -150, 715, 43, 716, 321, -150, -150, -150, -150, - /* 160 */ -150, -150, -150, 721, 321, 723, 321, -150, 1004, 188, - /* 170 */ 938, -150, -150, -150, -150, -150, 321, 772, 321, 773, - /* 180 */ 321, 778, 321, 780, 321, -150, 440, 938, -150, 318, - /* 190 */ 321, 944, 952, -150, -150, 781, 321, 783, 321, -150, - /* 200 */ 977, -150, -150, -150, 1022, -150, -150, 788, 321, 823, - /* 210 */ 321, 824, 321, -150, -150, 323, -150, -150, 1020, 1027, - /* 220 */ -150, -150, -150, 829, 321, -150, 257, -150, 255, 970, - /* 230 */ 1010, -150, 1024, -150, -150, 321, 974, 1015, -150, 835, - /* 240 */ 321, -150, 260, -150, 836, 321, -150, 561, 986, -150, - /* 250 */ -150, -150, 1040, -150, 1046, -150, -150, -150, 1047, 1039, - /* 260 */ 251, -150, -150, 1048, -150, -150, 995, 996, -150, -150, - /* 270 */ 529, -150, -150, 1053, -150, -150, 838, 321, -23, 938, - /* 280 */ 986, -150, 596, 1014, 1009, -150, 850, 113, -150, -150, - /* 290 */ -150, 997, -150, -150, -150, -150, 321, -150, -150, -150, - /* 300 */ -150, -150, 321, 1045, -150, 1067, 1049, 1050, 1055, -150, - /* 310 */ 1071, -150, -150, 1057, -150, -150, -150, -150, -150, -150, - /* 320 */ 1060, -150, 1062, -150, 209, -150, -150, 405, 1016, 1051, - /* 330 */ -150, -150, 1021, 1065, -150, -150, 1072, -150, 1068, -150, - /* 340 */ -150, 591, -150, 1070, -150, -150, 1073, -150, -150, 1083, - /* 350 */ 369, -150, -150, 433, -150, -150, -150, -150, 1019, -150, - /* 360 */ -150, -150, 1028, -150, -150, -150, -150, -150, 1069, 1076, - /* 370 */ -150, 1088, -150, -150, -150, 531, 1077, -150, 1074, -150, - /* 380 */ -150, 709, -150, 1084, -150, 852, 171, -150, -150, -150, - /* 390 */ 711, -150, -150, 1113, 1089, 1091, 432, -150, -150, -150, - /* 400 */ -150, -150, -150, 673, 938, -141, -150, 1118, 1115, -150, - /* 410 */ 1120, 1117, -150, 893, 938, 1123, 1121, 1080, 1087, -150, - /* 420 */ 827, 1122, -150, 1085, 1092, -150, 866, 321, -150, -150, - /* 430 */ -150, -150, -150, -150, -150, 659, -150, -150, -150, -150, - /* 440 */ -150, -150, -150, 1134, 1133, -150, 1139, -150, 746, -150, - /* 450 */ 1119, -150, -150, -150, 328, 938, 1110, 873, -150, -150, - /* 460 */ -150, -150, -150, -150, 460, -150, 1125, 1162, -150, 913, - /* 470 */ 1126, 1174, -150, 867, 321, -150, -150, 868, 321, -150, - /* 480 */ 1178, 1116, 863, -150, -150, 900, 938, -150, 512, -150, - /* 490 */ 869, 321, -150, 321, -150, 1186, 1140, -150, -150, 916, - /* 500 */ -150, 917, -150, 922, -150, 923, -150, 938, -150, 924, - /* 510 */ 1150, -150, 1164, 925, -150, 929, 1158, -150, -150, 933, - /* 520 */ 1141, 935, 938, -150, 517, -150, -150, 1210, -150, 1211, - /* 530 */ 1213, -150, -85, -150, -150, -150, -150, 1222, -150, -150, - /* 540 */ 1142, 1212, -150, 1230, 1154, -150, 1218, -150, -150, -150, - /* 550 */ 1163, 1243, -150, 1252, 1246, -150, -150, 816, -150, -150, - /* 560 */ 1256, -150, -150, 1169, 274, -150, -150, -150, -150, + /* 0 */ -59, 211, -71, -71, 556, -71, -71, -71, -70, -53, + /* 10 */ -71, 189, -71, -71, -71, -71, -71, -71, -71, 268, + /* 20 */ -71, 325, -71, 463, -71, 589, -71, -60, 596, -71, + /* 30 */ -71, 75, -71, 256, 655, 313, -71, 673, 444, -71, + /* 40 */ 757, -71, -71, 121, -71, -71, -71, -71, -71, -71, + /* 50 */ -71, -71, 795, -71, 804, -71, -71, -71, -71, -71, + /* 60 */ 839, 898, 899, -71, -71, -71, -71, 907, -71, -71, + /* 70 */ 706, -71, 206, -71, -71, -71, 598, -71, 964, 936, + /* 80 */ -71, 938, 370, 940, 974, 985, 976, 990, 994, -71, + /* 90 */ 720, 82, 739, 82, 806, -71, -71, 1043, -71, 1046, + /* 100 */ -71, -71, -71, -71, -71, -71, -71, 82, 807, 82, + /* 110 */ 813, 82, 844, 82, 862, 82, 863, 82, 865, 82, + /* 120 */ 871, 82, 877, 82, 878, 82, 890, 82, 896, 82, + /* 130 */ 909, 82, 921, 82, 924, 82, 932, 82, 934, 82, + /* 140 */ 935, 82, -71, -71, -71, -71, -71, -71, 937, 117, + /* 150 */ 942, 82, -71, -71, -71, -71, -71, -71, -71, 943, + /* 160 */ 82, 949, 82, -71, 1049, 593, 964, -71, -71, -71, + /* 170 */ -71, -71, 82, 960, 82, 965, 82, 970, 82, 971, + /* 180 */ 82, -71, 32, 964, -71, 264, 82, 983, 984, -71, + /* 190 */ -71, 972, 82, 977, 82, -71, 1022, -71, -71, -71, + /* 200 */ 1061, -71, -71, 978, 82, 986, 82, 987, 82, -71, + /* 210 */ -71, 310, -71, -71, 1062, 1065, -71, -71, -71, 988, + /* 220 */ 82, -71, -36, -71, 400, 1012, 1048, -71, 1060, -71, + /* 230 */ -71, 82, 1017, 1052, -71, 993, 82, -71, 263, -71, + /* 240 */ 1000, 82, -71, 230, 1024, -71, -71, -71, 1080, -71, + /* 250 */ 1081, -71, -71, -71, 1082, 1083, 78, -71, -71, 1084, + /* 260 */ -71, -71, 1031, 1033, -71, -71, 508, -71, -71, 1090, + /* 270 */ -71, -71, 1003, 82, -18, 964, 1024, -71, 496, 1039, + /* 280 */ 1040, -71, 1005, 140, -71, -71, -71, 1043, -71, -71, + /* 290 */ -71, -71, 82, -71, -71, -71, -71, -71, 82, 1075, + /* 300 */ -71, 1099, 1073, 1076, 1072, -71, 1101, -71, -71, 1077, + /* 310 */ -71, -71, -71, -71, -71, -71, 1078, -71, 1085, -71, + /* 320 */ 381, -71, -71, 369, 1042, 1086, -71, -71, 1044, 1091, + /* 330 */ -71, -71, 1092, -71, 1093, -71, -71, 626, -71, 1095, + /* 340 */ -71, -71, 1096, -71, -71, 1106, 182, -71, -71, 245, + /* 350 */ -71, -71, -71, -71, 1032, -71, -71, -71, 1034, -71, + /* 360 */ -71, -71, -71, -71, 1094, 1100, -71, 1117, -71, -71, + /* 370 */ -71, 383, 1102, -71, 1103, -71, -71, 642, -71, 1107, + /* 380 */ -71, 1014, 305, -71, -71, -71, 657, -71, -71, 1130, + /* 390 */ 1108, 1109, -49, -71, -71, -71, -71, -71, -71, 587, + /* 400 */ 964, 601, -71, 1134, 1133, -71, 1136, 1135, -71, 725, + /* 410 */ 964, 1140, 1137, 1064, 1066, -71, 295, 1138, -71, 1067, + /* 420 */ 1069, -71, 808, 82, -71, -71, -71, -71, -71, -71, + /* 430 */ -71, 721, -71, -71, -71, -71, -71, -71, -71, 1155, + /* 440 */ 1152, -71, 1158, -71, 729, -71, 1139, -71, -71, -71, + /* 450 */ 592, 964, 1129, 735, -71, -71, -71, -71, -71, -71, + /* 460 */ 604, -71, 1141, 1169, -71, 845, 1131, 1174, -71, 1015, + /* 470 */ 82, -71, -71, 1016, 82, -71, 1183, 1115, 760, -71, + /* 480 */ -71, 860, 964, -71, 535, -71, 1021, 82, -71, 82, + /* 490 */ -71, 1189, 1142, -71, -71, 800, -71, 873, -71, 880, + /* 500 */ -71, 900, -71, 964, -71, 912, 1151, -71, 1162, 915, + /* 510 */ -71, 888, 1156, -71, -71, 930, 1143, 992, 964, -71, + /* 520 */ 703, -71, -71, 1204, -71, 1205, 1202, -71, 648, -71, + /* 530 */ -71, -71, -71, 1213, -71, -71, 1144, 1208, -71, 1219, + /* 540 */ 1145, -71, 1209, -71, -71, -71, 1147, 1225, -71, 1229, + /* 550 */ 1222, -71, -71, 191, -71, -71, 1231, -71, -71, 1148, + /* 560 */ 553, -71, -71, -71, -71, }; static const YYACTIONTYPE yy_default[] = { - /* 0 */ 575, 575, 570, 573, 878, 878, 878, 574, 581, 878, - /* 10 */ 878, 878, 878, 601, 602, 603, 582, 583, 584, 878, - /* 20 */ 878, 878, 878, 878, 878, 878, 878, 878, 878, 878, - /* 30 */ 878, 878, 594, 604, 613, 596, 612, 878, 878, 614, - /* 40 */ 657, 620, 878, 878, 658, 661, 662, 663, 860, 861, - /* 50 */ 862, 878, 657, 621, 642, 640, 878, 643, 644, 878, - /* 60 */ 713, 657, 628, 622, 629, 711, 712, 657, 623, 878, - /* 70 */ 878, 743, 812, 749, 744, 740, 878, 668, 878, 878, - /* 80 */ 669, 677, 679, 686, 725, 716, 718, 706, 720, 674, - /* 90 */ 878, 721, 878, 722, 878, 742, 878, 878, 745, 878, - /* 100 */ 746, 747, 748, 750, 751, 752, 755, 756, 757, 758, - /* 110 */ 878, 759, 878, 760, 878, 761, 878, 762, 878, 763, - /* 120 */ 878, 764, 878, 765, 878, 766, 878, 767, 878, 768, - /* 130 */ 878, 769, 878, 770, 878, 771, 878, 772, 878, 773, - /* 140 */ 878, 774, 878, 775, 776, 777, 878, 778, 779, 786, - /* 150 */ 793, 796, 878, 781, 878, 780, 783, 878, 784, 878, - /* 160 */ 787, 785, 792, 878, 878, 878, 794, 795, 878, 812, - /* 170 */ 878, 878, 878, 878, 878, 799, 811, 878, 788, 878, - /* 180 */ 789, 878, 790, 878, 791, 878, 878, 878, 801, 878, - /* 190 */ 878, 878, 878, 878, 802, 878, 878, 878, 803, 878, - /* 200 */ 878, 878, 858, 878, 878, 878, 859, 878, 878, 878, - /* 210 */ 878, 878, 804, 878, 797, 812, 809, 810, 694, 878, - /* 220 */ 695, 800, 782, 878, 723, 878, 878, 707, 878, 714, - /* 230 */ 713, 708, 878, 598, 715, 710, 714, 713, 709, 878, - /* 240 */ 719, 878, 812, 717, 878, 726, 678, 689, 687, 688, - /* 250 */ 697, 698, 878, 699, 878, 700, 878, 701, 878, 694, - /* 260 */ 685, 599, 600, 878, 683, 684, 703, 705, 690, 878, - /* 270 */ 878, 878, 704, 878, 738, 739, 878, 702, 689, 878, - /* 280 */ 878, 878, 685, 703, 705, 691, 878, 685, 680, 681, - /* 290 */ 878, 878, 682, 675, 676, 798, 878, 741, 878, 753, - /* 300 */ 878, 754, 878, 657, 624, 878, 816, 630, 625, 631, - /* 310 */ 878, 632, 878, 878, 633, 878, 636, 637, 638, 639, - /* 320 */ 878, 634, 878, 635, 878, 878, 817, 878, 714, 713, - /* 330 */ 818, 820, 714, 713, 819, 626, 878, 627, 642, 641, - /* 340 */ 615, 878, 616, 878, 617, 749, 878, 618, 619, 605, - /* 350 */ 835, 878, 606, 835, 878, 607, 610, 611, 878, 830, - /* 360 */ 832, 833, 878, 831, 834, 609, 608, 597, 878, 878, - /* 370 */ 647, 878, 650, 878, 878, 878, 878, 878, 657, 651, - /* 380 */ 878, 878, 878, 657, 652, 878, 657, 653, 878, 878, - /* 390 */ 878, 878, 878, 878, 816, 630, 655, 878, 654, 656, - /* 400 */ 648, 649, 595, 878, 878, 591, 878, 878, 694, 589, - /* 410 */ 878, 878, 878, 878, 878, 878, 694, 841, 878, 878, - /* 420 */ 878, 694, 696, 846, 878, 878, 878, 878, 878, 878, - /* 430 */ 847, 848, 878, 878, 878, 878, 878, 838, 839, 878, - /* 440 */ 840, 590, 878, 878, 878, 878, 878, 878, 878, 878, - /* 450 */ 878, 878, 878, 878, 878, 878, 878, 878, 660, 878, - /* 460 */ 878, 878, 878, 878, 878, 878, 659, 878, 878, 878, - /* 470 */ 878, 878, 878, 878, 728, 878, 878, 878, 729, 878, - /* 480 */ 878, 736, 878, 878, 737, 878, 878, 878, 878, 878, - /* 490 */ 878, 734, 878, 735, 878, 878, 878, 878, 878, 878, - /* 500 */ 878, 878, 878, 878, 878, 878, 878, 878, 878, 878, - /* 510 */ 878, 878, 659, 878, 878, 878, 878, 878, 878, 878, - /* 520 */ 736, 878, 878, 878, 878, 878, 878, 878, 878, 878, - /* 530 */ 694, 878, 835, 878, 878, 878, 878, 878, 878, 878, - /* 540 */ 869, 878, 878, 878, 878, 878, 878, 878, 878, 868, - /* 550 */ 869, 878, 878, 878, 878, 878, 878, 878, 878, 878, - /* 560 */ 878, 878, 878, 876, 878, 878, 877, 576, 571, + /* 0 */ 571, 571, 566, 569, 870, 870, 870, 570, 577, 870, + /* 10 */ 870, 870, 870, 597, 598, 599, 578, 579, 580, 870, + /* 20 */ 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, + /* 30 */ 870, 870, 590, 600, 609, 592, 608, 870, 870, 610, + /* 40 */ 653, 616, 870, 870, 654, 657, 658, 659, 852, 853, + /* 50 */ 854, 870, 653, 617, 638, 636, 870, 639, 640, 870, + /* 60 */ 709, 653, 624, 618, 625, 707, 708, 653, 619, 870, + /* 70 */ 870, 739, 804, 745, 740, 736, 870, 664, 870, 870, + /* 80 */ 665, 673, 675, 682, 721, 712, 714, 702, 716, 670, + /* 90 */ 870, 717, 870, 718, 870, 738, 870, 870, 741, 870, + /* 100 */ 742, 743, 744, 746, 747, 748, 751, 752, 870, 753, + /* 110 */ 870, 754, 870, 755, 870, 756, 870, 757, 870, 758, + /* 120 */ 870, 759, 870, 760, 870, 761, 870, 762, 870, 763, + /* 130 */ 870, 764, 870, 765, 870, 766, 870, 767, 870, 768, + /* 140 */ 870, 769, 770, 870, 771, 778, 785, 788, 870, 773, + /* 150 */ 870, 772, 775, 870, 776, 870, 779, 777, 784, 870, + /* 160 */ 870, 870, 786, 787, 870, 804, 870, 870, 870, 870, + /* 170 */ 870, 791, 803, 870, 780, 870, 781, 870, 782, 870, + /* 180 */ 783, 870, 870, 870, 793, 870, 870, 870, 870, 870, + /* 190 */ 794, 870, 870, 870, 795, 870, 870, 870, 850, 870, + /* 200 */ 870, 870, 851, 870, 870, 870, 870, 870, 796, 870, + /* 210 */ 789, 804, 801, 802, 690, 870, 691, 792, 774, 870, + /* 220 */ 719, 870, 870, 703, 870, 710, 709, 704, 870, 594, + /* 230 */ 711, 706, 710, 709, 705, 870, 715, 870, 804, 713, + /* 240 */ 870, 722, 674, 685, 683, 684, 693, 694, 870, 695, + /* 250 */ 870, 696, 870, 697, 870, 690, 681, 595, 596, 870, + /* 260 */ 679, 680, 699, 701, 686, 870, 870, 870, 700, 870, + /* 270 */ 734, 735, 870, 698, 685, 870, 870, 870, 681, 699, + /* 280 */ 701, 687, 870, 681, 676, 677, 870, 870, 678, 671, + /* 290 */ 672, 790, 870, 737, 870, 749, 870, 750, 870, 653, + /* 300 */ 620, 870, 808, 626, 621, 627, 870, 628, 870, 870, + /* 310 */ 629, 870, 632, 633, 634, 635, 870, 630, 870, 631, + /* 320 */ 870, 870, 809, 870, 710, 709, 810, 812, 710, 709, + /* 330 */ 811, 622, 870, 623, 638, 637, 611, 870, 612, 870, + /* 340 */ 613, 745, 870, 614, 615, 601, 827, 870, 602, 827, + /* 350 */ 870, 603, 606, 607, 870, 822, 824, 825, 870, 823, + /* 360 */ 826, 605, 604, 593, 870, 870, 643, 870, 646, 870, + /* 370 */ 870, 870, 870, 870, 653, 647, 870, 870, 870, 653, + /* 380 */ 648, 870, 653, 649, 870, 870, 870, 870, 870, 870, + /* 390 */ 808, 626, 651, 870, 650, 652, 644, 645, 591, 870, + /* 400 */ 870, 587, 870, 870, 690, 585, 870, 870, 870, 870, + /* 410 */ 870, 870, 690, 833, 870, 870, 870, 690, 692, 838, + /* 420 */ 870, 870, 870, 870, 870, 870, 839, 840, 870, 870, + /* 430 */ 870, 870, 870, 830, 831, 870, 832, 586, 870, 870, + /* 440 */ 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, + /* 450 */ 870, 870, 870, 870, 656, 870, 870, 870, 870, 870, + /* 460 */ 870, 870, 655, 870, 870, 870, 870, 870, 870, 870, + /* 470 */ 724, 870, 870, 870, 725, 870, 870, 732, 870, 870, + /* 480 */ 733, 870, 870, 870, 870, 870, 870, 730, 870, 731, + /* 490 */ 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, + /* 500 */ 870, 870, 870, 870, 870, 870, 870, 870, 655, 870, + /* 510 */ 870, 870, 870, 870, 870, 870, 732, 870, 870, 870, + /* 520 */ 870, 870, 870, 870, 870, 870, 690, 870, 827, 870, + /* 530 */ 870, 870, 870, 870, 870, 870, 861, 870, 870, 870, + /* 540 */ 870, 870, 870, 870, 870, 860, 861, 870, 870, 870, + /* 550 */ 870, 870, 870, 870, 870, 870, 870, 870, 870, 868, + /* 560 */ 870, 870, 869, 572, 567, }; #define YY_SZ_ACTTAB (sizeof(yy_action)/sizeof(yy_action[0])) @@ -674,61 +660,59 @@ 0, /* FUNCTION => nothing */ 0, /* COLUMN => nothing */ 0, /* AGG_FUNCTION => nothing */ + 0, /* CONST_FUNC => nothing */ 0, /* SEMI => nothing */ - 26, /* EXPLAIN => ID */ - 26, /* BEGIN => ID */ + 27, /* EXPLAIN => ID */ + 27, /* BEGIN => ID */ 0, /* TRANSACTION => nothing */ - 26, /* DEFERRED => ID */ - 26, /* IMMEDIATE => ID */ - 26, /* EXCLUSIVE => ID */ + 27, /* DEFERRED => ID */ + 27, /* IMMEDIATE => ID */ + 27, /* EXCLUSIVE => ID */ 0, /* COMMIT => nothing */ - 26, /* END => ID */ + 27, /* END => ID */ 0, /* ROLLBACK => nothing */ 0, /* CREATE => nothing */ 0, /* TABLE => nothing */ - 26, /* TEMP => ID */ + 27, /* TEMP => ID */ 0, /* LP => nothing */ 0, /* RP => nothing */ 0, /* AS => nothing */ 0, /* COMMA => nothing */ 0, /* ID => nothing */ - 26, /* ABORT => ID */ - 26, /* AFTER => ID */ - 26, /* ASC => ID */ - 26, /* ATTACH => ID */ - 26, /* BEFORE => ID */ - 26, /* CASCADE => ID */ - 26, /* CONFLICT => ID */ - 26, /* DATABASE => ID */ - 26, /* DESC => ID */ - 26, /* DETACH => ID */ - 26, /* EACH => ID */ - 26, /* FAIL => ID */ - 26, /* FOR => ID */ - 26, /* GLOB => ID */ - 26, /* IGNORE => ID */ - 26, /* INITIALLY => ID */ - 26, /* INSTEAD => ID */ - 26, /* LIKE => ID */ - 26, /* MATCH => ID */ - 26, /* KEY => ID */ - 26, /* OF => ID */ - 26, /* OFFSET => ID */ - 26, /* PRAGMA => ID */ - 26, /* RAISE => ID */ - 26, /* REPLACE => ID */ - 26, /* RESTRICT => ID */ - 26, /* ROW => ID */ - 26, /* STATEMENT => ID */ - 26, /* TRIGGER => ID */ - 26, /* VACUUM => ID */ - 26, /* VIEW => ID */ - 26, /* REINDEX => ID */ - 26, /* RENAME => ID */ - 26, /* CDATE => ID */ - 26, /* CTIME => ID */ - 26, /* CTIMESTAMP => ID */ - 26, /* ALTER => ID */ + 27, /* ABORT => ID */ + 27, /* AFTER => ID */ + 27, /* ASC => ID */ + 27, /* ATTACH => ID */ + 27, /* BEFORE => ID */ + 27, /* CASCADE => ID */ + 27, /* CONFLICT => ID */ + 27, /* DATABASE => ID */ + 27, /* DESC => ID */ + 27, /* DETACH => ID */ + 27, /* EACH => ID */ + 27, /* FAIL => ID */ + 27, /* FOR => ID */ + 27, /* IGNORE => ID */ + 27, /* INITIALLY => ID */ + 27, /* INSTEAD => ID */ + 27, /* LIKE_KW => ID */ + 27, /* MATCH => ID */ + 27, /* KEY => ID */ + 27, /* OF => ID */ + 27, /* OFFSET => ID */ + 27, /* PRAGMA => ID */ + 27, /* RAISE => ID */ + 27, /* REPLACE => ID */ + 27, /* RESTRICT => ID */ + 27, /* ROW => ID */ + 27, /* STATEMENT => ID */ + 27, /* TRIGGER => ID */ + 27, /* VACUUM => ID */ + 27, /* VIEW => ID */ + 27, /* REINDEX => ID */ + 27, /* RENAME => ID */ + 27, /* CTIME_KW => ID */ + 27, /* ALTER => ID */ 0, /* OR => nothing */ 0, /* AND => nothing */ 0, /* NOT => nothing */ @@ -880,65 +864,64 @@ static const char *const yyTokenName[] = { "$", "END_OF_FILE", "ILLEGAL", "SPACE", "UNCLOSED_STRING", "COMMENT", "FUNCTION", "COLUMN", - "AGG_FUNCTION", "SEMI", "EXPLAIN", "BEGIN", - "TRANSACTION", "DEFERRED", "IMMEDIATE", "EXCLUSIVE", - "COMMIT", "END", "ROLLBACK", "CREATE", - "TABLE", "TEMP", "LP", "RP", - "AS", "COMMA", "ID", "ABORT", - "AFTER", "ASC", "ATTACH", "BEFORE", - "CASCADE", "CONFLICT", "DATABASE", "DESC", - "DETACH", "EACH", "FAIL", "FOR", - "GLOB", "IGNORE", "INITIALLY", "INSTEAD", - "LIKE", "MATCH", "KEY", "OF", + "AGG_FUNCTION", "CONST_FUNC", "SEMI", "EXPLAIN", + "BEGIN", "TRANSACTION", "DEFERRED", "IMMEDIATE", + "EXCLUSIVE", "COMMIT", "END", "ROLLBACK", + "CREATE", "TABLE", "TEMP", "LP", + "RP", "AS", "COMMA", "ID", + "ABORT", "AFTER", "ASC", "ATTACH", + "BEFORE", "CASCADE", "CONFLICT", "DATABASE", + "DESC", "DETACH", "EACH", "FAIL", + "FOR", "IGNORE", "INITIALLY", "INSTEAD", + "LIKE_KW", "MATCH", "KEY", "OF", "OFFSET", "PRAGMA", "RAISE", "REPLACE", "RESTRICT", "ROW", "STATEMENT", "TRIGGER", "VACUUM", "VIEW", "REINDEX", "RENAME", - "CDATE", "CTIME", "CTIMESTAMP", "ALTER", - "OR", "AND", "NOT", "IS", - "BETWEEN", "IN", "ISNULL", "NOTNULL", - "NE", "EQ", "GT", "LE", - "LT", "GE", "ESCAPE", "BITAND", - "BITOR", "LSHIFT", "RSHIFT", "PLUS", - "MINUS", "STAR", "SLASH", "REM", - "CONCAT", "UMINUS", "UPLUS", "BITNOT", - "STRING", "JOIN_KW", "CONSTRAINT", "DEFAULT", - "NULL", "PRIMARY", "UNIQUE", "CHECK", - "REFERENCES", "COLLATE", "AUTOINCR", "ON", - "DELETE", "UPDATE", "INSERT", "SET", - "DEFERRABLE", "FOREIGN", "DROP", "UNION", - "ALL", "INTERSECT", "EXCEPT", "SELECT", - "DISTINCT", "DOT", "FROM", "JOIN", - "USING", "ORDER", "BY", "GROUP", - "HAVING", "LIMIT", "WHERE", "INTO", - "VALUES", "INTEGER", "FLOAT", "BLOB", - "REGISTER", "VARIABLE", "EXISTS", "CASE", - "WHEN", "THEN", "ELSE", "INDEX", - "TO", "ADD", "COLUMNKW", "error", - "input", "cmdlist", "ecmd", "cmdx", - "cmd", "explain", "transtype", "trans_opt", - "nm", "create_table", "create_table_args", "temp", - "dbnm", "columnlist", "conslist_opt", "select", - "column", "columnid", "type", "carglist", - "id", "ids", "typename", "signed", - "plus_num", "minus_num", "carg", "ccons", - "term", "onconf", "sortorder", "autoinc", - "expr", "idxlist_opt", "refargs", "defer_subclause", - "refarg", "refact", "init_deferred_pred_opt", "conslist", - "tcons", "idxlist", "defer_subclause_opt", "orconf", - "resolvetype", "raisetype", "fullname", "oneselect", - "multiselect_op", "distinct", "selcollist", "from", - "where_opt", "groupby_opt", "having_opt", "orderby_opt", - "limit_opt", "sclp", "as", "seltablist", - "stl_prefix", "joinop", "on_opt", "using_opt", - "seltablist_paren", "joinop2", "inscollist", "sortlist", - "sortitem", "collate", "exprlist", "setlist", - "insert_cmd", "inscollist_opt", "itemlist", "likeop", - "escape", "between_op", "in_op", "case_operand", - "case_exprlist", "case_else", "expritem", "uniqueflag", - "idxitem", "plus_opt", "number", "trigger_decl", - "trigger_cmd_list", "trigger_time", "trigger_event", "foreach_clause", - "when_clause", "trigger_cmd", "database_kw_opt", "key_opt", - "add_column_fullname", "kwcolumn_opt", + "CTIME_KW", "ALTER", "OR", "AND", + "NOT", "IS", "BETWEEN", "IN", + "ISNULL", "NOTNULL", "NE", "EQ", + "GT", "LE", "LT", "GE", + "ESCAPE", "BITAND", "BITOR", "LSHIFT", + "RSHIFT", "PLUS", "MINUS", "STAR", + "SLASH", "REM", "CONCAT", "UMINUS", + "UPLUS", "BITNOT", "STRING", "JOIN_KW", + "CONSTRAINT", "DEFAULT", "NULL", "PRIMARY", + "UNIQUE", "CHECK", "REFERENCES", "COLLATE", + "AUTOINCR", "ON", "DELETE", "UPDATE", + "INSERT", "SET", "DEFERRABLE", "FOREIGN", + "DROP", "UNION", "ALL", "INTERSECT", + "EXCEPT", "SELECT", "DISTINCT", "DOT", + "FROM", "JOIN", "USING", "ORDER", + "BY", "GROUP", "HAVING", "LIMIT", + "WHERE", "INTO", "VALUES", "INTEGER", + "FLOAT", "BLOB", "REGISTER", "VARIABLE", + "EXISTS", "CASE", "WHEN", "THEN", + "ELSE", "INDEX", "TO", "ADD", + "COLUMNKW", "error", "input", "cmdlist", + "ecmd", "cmdx", "cmd", "explain", + "transtype", "trans_opt", "nm", "create_table", + "create_table_args", "temp", "dbnm", "columnlist", + "conslist_opt", "select", "column", "columnid", + "type", "carglist", "id", "ids", + "typename", "signed", "plus_num", "minus_num", + "carg", "ccons", "term", "onconf", + "sortorder", "autoinc", "expr", "idxlist_opt", + "refargs", "defer_subclause", "refarg", "refact", + "init_deferred_pred_opt", "conslist", "tcons", "idxlist", + "defer_subclause_opt", "orconf", "resolvetype", "raisetype", + "fullname", "oneselect", "multiselect_op", "distinct", + "selcollist", "from", "where_opt", "groupby_opt", + "having_opt", "orderby_opt", "limit_opt", "sclp", + "as", "seltablist", "stl_prefix", "joinop", + "on_opt", "using_opt", "seltablist_paren", "joinop2", + "inscollist", "sortlist", "sortitem", "collate", + "exprlist", "setlist", "insert_cmd", "inscollist_opt", + "itemlist", "likeop", "escape", "between_op", + "in_op", "case_operand", "case_exprlist", "case_else", + "expritem", "uniqueflag", "idxitem", "plus_opt", + "number", "trigger_decl", "trigger_cmd_list", "trigger_time", + "trigger_event", "foreach_clause", "when_clause", "trigger_cmd", + "database_kw_opt", "key_opt", "add_column_fullname", "kwcolumn_opt", }; #endif /* NDEBUG */ @@ -1132,129 +1115,125 @@ /* 183 */ "expr ::= VARIABLE", /* 184 */ "expr ::= ID LP exprlist RP", /* 185 */ "expr ::= ID LP STAR RP", - /* 186 */ "term ::= CTIME", - /* 187 */ "term ::= CDATE", - /* 188 */ "term ::= CTIMESTAMP", - /* 189 */ "expr ::= expr AND expr", - /* 190 */ "expr ::= expr OR expr", - /* 191 */ "expr ::= expr LT expr", - /* 192 */ "expr ::= expr GT expr", - /* 193 */ "expr ::= expr LE expr", - /* 194 */ "expr ::= expr GE expr", - /* 195 */ "expr ::= expr NE expr", - /* 196 */ "expr ::= expr EQ expr", - /* 197 */ "expr ::= expr BITAND expr", - /* 198 */ "expr ::= expr BITOR expr", - /* 199 */ "expr ::= expr LSHIFT expr", - /* 200 */ "expr ::= expr RSHIFT expr", - /* 201 */ "expr ::= expr PLUS expr", - /* 202 */ "expr ::= expr MINUS expr", - /* 203 */ "expr ::= expr STAR expr", - /* 204 */ "expr ::= expr SLASH expr", - /* 205 */ "expr ::= expr REM expr", - /* 206 */ "expr ::= expr CONCAT expr", - /* 207 */ "likeop ::= LIKE", - /* 208 */ "likeop ::= GLOB", - /* 209 */ "likeop ::= NOT LIKE", - /* 210 */ "likeop ::= NOT GLOB", - /* 211 */ "escape ::= ESCAPE expr", - /* 212 */ "escape ::=", - /* 213 */ "expr ::= expr likeop expr escape", - /* 214 */ "expr ::= expr ISNULL", - /* 215 */ "expr ::= expr IS NULL", - /* 216 */ "expr ::= expr NOTNULL", - /* 217 */ "expr ::= expr NOT NULL", - /* 218 */ "expr ::= expr IS NOT NULL", - /* 219 */ "expr ::= NOT expr", - /* 220 */ "expr ::= BITNOT expr", - /* 221 */ "expr ::= MINUS expr", - /* 222 */ "expr ::= PLUS expr", - /* 223 */ "between_op ::= BETWEEN", - /* 224 */ "between_op ::= NOT BETWEEN", - /* 225 */ "expr ::= expr between_op expr AND expr", - /* 226 */ "in_op ::= IN", - /* 227 */ "in_op ::= NOT IN", - /* 228 */ "expr ::= expr in_op LP exprlist RP", - /* 229 */ "expr ::= LP select RP", - /* 230 */ "expr ::= expr in_op LP select RP", - /* 231 */ "expr ::= expr in_op nm dbnm", - /* 232 */ "expr ::= EXISTS LP select RP", - /* 233 */ "expr ::= CASE case_operand case_exprlist case_else END", - /* 234 */ "case_exprlist ::= case_exprlist WHEN expr THEN expr", - /* 235 */ "case_exprlist ::= WHEN expr THEN expr", - /* 236 */ "case_else ::= ELSE expr", - /* 237 */ "case_else ::=", - /* 238 */ "case_operand ::= expr", - /* 239 */ "case_operand ::=", - /* 240 */ "exprlist ::= exprlist COMMA expritem", - /* 241 */ "exprlist ::= expritem", - /* 242 */ "expritem ::= expr", - /* 243 */ "expritem ::=", - /* 244 */ "cmd ::= CREATE uniqueflag INDEX nm dbnm ON nm LP idxlist RP onconf", - /* 245 */ "uniqueflag ::= UNIQUE", - /* 246 */ "uniqueflag ::=", - /* 247 */ "idxlist_opt ::=", - /* 248 */ "idxlist_opt ::= LP idxlist RP", - /* 249 */ "idxlist ::= idxlist COMMA idxitem collate sortorder", - /* 250 */ "idxlist ::= idxitem collate sortorder", - /* 251 */ "idxitem ::= nm", - /* 252 */ "cmd ::= DROP INDEX fullname", - /* 253 */ "cmd ::= VACUUM", - /* 254 */ "cmd ::= VACUUM nm", - /* 255 */ "cmd ::= PRAGMA nm dbnm EQ nm", - /* 256 */ "cmd ::= PRAGMA nm dbnm EQ ON", - /* 257 */ "cmd ::= PRAGMA nm dbnm EQ plus_num", - /* 258 */ "cmd ::= PRAGMA nm dbnm EQ minus_num", - /* 259 */ "cmd ::= PRAGMA nm dbnm LP nm RP", - /* 260 */ "cmd ::= PRAGMA nm dbnm", - /* 261 */ "plus_num ::= plus_opt number", - /* 262 */ "minus_num ::= MINUS number", - /* 263 */ "number ::= INTEGER", - /* 264 */ "number ::= FLOAT", - /* 265 */ "plus_opt ::= PLUS", - /* 266 */ "plus_opt ::=", - /* 267 */ "cmd ::= CREATE trigger_decl BEGIN trigger_cmd_list END", - /* 268 */ "trigger_decl ::= temp TRIGGER nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause", - /* 269 */ "trigger_time ::= BEFORE", - /* 270 */ "trigger_time ::= AFTER", - /* 271 */ "trigger_time ::= INSTEAD OF", - /* 272 */ "trigger_time ::=", - /* 273 */ "trigger_event ::= DELETE", - /* 274 */ "trigger_event ::= INSERT", - /* 275 */ "trigger_event ::= UPDATE", - /* 276 */ "trigger_event ::= UPDATE OF inscollist", - /* 277 */ "foreach_clause ::=", - /* 278 */ "foreach_clause ::= FOR EACH ROW", - /* 279 */ "foreach_clause ::= FOR EACH STATEMENT", - /* 280 */ "when_clause ::=", - /* 281 */ "when_clause ::= WHEN expr", - /* 282 */ "trigger_cmd_list ::= trigger_cmd SEMI trigger_cmd_list", - /* 283 */ "trigger_cmd_list ::=", - /* 284 */ "trigger_cmd ::= UPDATE orconf nm SET setlist where_opt", - /* 285 */ "trigger_cmd ::= insert_cmd INTO nm inscollist_opt VALUES LP itemlist RP", - /* 286 */ "trigger_cmd ::= insert_cmd INTO nm inscollist_opt select", - /* 287 */ "trigger_cmd ::= DELETE FROM nm where_opt", - /* 288 */ "trigger_cmd ::= select", - /* 289 */ "expr ::= RAISE LP IGNORE RP", - /* 290 */ "expr ::= RAISE LP raisetype COMMA nm RP", - /* 291 */ "raisetype ::= ROLLBACK", - /* 292 */ "raisetype ::= ABORT", - /* 293 */ "raisetype ::= FAIL", - /* 294 */ "cmd ::= DROP TRIGGER fullname", - /* 295 */ "cmd ::= ATTACH database_kw_opt ids AS nm key_opt", - /* 296 */ "key_opt ::=", - /* 297 */ "key_opt ::= KEY ids", - /* 298 */ "key_opt ::= KEY BLOB", - /* 299 */ "database_kw_opt ::= DATABASE", - /* 300 */ "database_kw_opt ::=", - /* 301 */ "cmd ::= DETACH database_kw_opt nm", - /* 302 */ "cmd ::= REINDEX", - /* 303 */ "cmd ::= REINDEX nm dbnm", - /* 304 */ "cmd ::= ALTER TABLE fullname RENAME TO nm", - /* 305 */ "cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt column", - /* 306 */ "add_column_fullname ::= fullname", - /* 307 */ "kwcolumn_opt ::=", - /* 308 */ "kwcolumn_opt ::= COLUMNKW", + /* 186 */ "term ::= CTIME_KW", + /* 187 */ "expr ::= expr AND expr", + /* 188 */ "expr ::= expr OR expr", + /* 189 */ "expr ::= expr LT expr", + /* 190 */ "expr ::= expr GT expr", + /* 191 */ "expr ::= expr LE expr", + /* 192 */ "expr ::= expr GE expr", + /* 193 */ "expr ::= expr NE expr", + /* 194 */ "expr ::= expr EQ expr", + /* 195 */ "expr ::= expr BITAND expr", + /* 196 */ "expr ::= expr BITOR expr", + /* 197 */ "expr ::= expr LSHIFT expr", + /* 198 */ "expr ::= expr RSHIFT expr", + /* 199 */ "expr ::= expr PLUS expr", + /* 200 */ "expr ::= expr MINUS expr", + /* 201 */ "expr ::= expr STAR expr", + /* 202 */ "expr ::= expr SLASH expr", + /* 203 */ "expr ::= expr REM expr", + /* 204 */ "expr ::= expr CONCAT expr", + /* 205 */ "likeop ::= LIKE_KW", + /* 206 */ "likeop ::= NOT LIKE_KW", + /* 207 */ "escape ::= ESCAPE expr", + /* 208 */ "escape ::=", + /* 209 */ "expr ::= expr likeop expr escape", + /* 210 */ "expr ::= expr ISNULL", + /* 211 */ "expr ::= expr IS NULL", + /* 212 */ "expr ::= expr NOTNULL", + /* 213 */ "expr ::= expr NOT NULL", + /* 214 */ "expr ::= expr IS NOT NULL", + /* 215 */ "expr ::= NOT expr", + /* 216 */ "expr ::= BITNOT expr", + /* 217 */ "expr ::= MINUS expr", + /* 218 */ "expr ::= PLUS expr", + /* 219 */ "between_op ::= BETWEEN", + /* 220 */ "between_op ::= NOT BETWEEN", + /* 221 */ "expr ::= expr between_op expr AND expr", + /* 222 */ "in_op ::= IN", + /* 223 */ "in_op ::= NOT IN", + /* 224 */ "expr ::= expr in_op LP exprlist RP", + /* 225 */ "expr ::= LP select RP", + /* 226 */ "expr ::= expr in_op LP select RP", + /* 227 */ "expr ::= expr in_op nm dbnm", + /* 228 */ "expr ::= EXISTS LP select RP", + /* 229 */ "expr ::= CASE case_operand case_exprlist case_else END", + /* 230 */ "case_exprlist ::= case_exprlist WHEN expr THEN expr", + /* 231 */ "case_exprlist ::= WHEN expr THEN expr", + /* 232 */ "case_else ::= ELSE expr", + /* 233 */ "case_else ::=", + /* 234 */ "case_operand ::= expr", + /* 235 */ "case_operand ::=", + /* 236 */ "exprlist ::= exprlist COMMA expritem", + /* 237 */ "exprlist ::= expritem", + /* 238 */ "expritem ::= expr", + /* 239 */ "expritem ::=", + /* 240 */ "cmd ::= CREATE uniqueflag INDEX nm dbnm ON nm LP idxlist RP onconf", + /* 241 */ "uniqueflag ::= UNIQUE", + /* 242 */ "uniqueflag ::=", + /* 243 */ "idxlist_opt ::=", + /* 244 */ "idxlist_opt ::= LP idxlist RP", + /* 245 */ "idxlist ::= idxlist COMMA idxitem collate sortorder", + /* 246 */ "idxlist ::= idxitem collate sortorder", + /* 247 */ "idxitem ::= nm", + /* 248 */ "cmd ::= DROP INDEX fullname", + /* 249 */ "cmd ::= VACUUM", + /* 250 */ "cmd ::= VACUUM nm", + /* 251 */ "cmd ::= PRAGMA nm dbnm EQ nm", + /* 252 */ "cmd ::= PRAGMA nm dbnm EQ ON", + /* 253 */ "cmd ::= PRAGMA nm dbnm EQ plus_num", + /* 254 */ "cmd ::= PRAGMA nm dbnm EQ minus_num", + /* 255 */ "cmd ::= PRAGMA nm dbnm LP nm RP", + /* 256 */ "cmd ::= PRAGMA nm dbnm", + /* 257 */ "plus_num ::= plus_opt number", + /* 258 */ "minus_num ::= MINUS number", + /* 259 */ "number ::= INTEGER", + /* 260 */ "number ::= FLOAT", + /* 261 */ "plus_opt ::= PLUS", + /* 262 */ "plus_opt ::=", + /* 263 */ "cmd ::= CREATE trigger_decl BEGIN trigger_cmd_list END", + /* 264 */ "trigger_decl ::= temp TRIGGER nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause", + /* 265 */ "trigger_time ::= BEFORE", + /* 266 */ "trigger_time ::= AFTER", + /* 267 */ "trigger_time ::= INSTEAD OF", + /* 268 */ "trigger_time ::=", + /* 269 */ "trigger_event ::= DELETE", + /* 270 */ "trigger_event ::= INSERT", + /* 271 */ "trigger_event ::= UPDATE", + /* 272 */ "trigger_event ::= UPDATE OF inscollist", + /* 273 */ "foreach_clause ::=", + /* 274 */ "foreach_clause ::= FOR EACH ROW", + /* 275 */ "foreach_clause ::= FOR EACH STATEMENT", + /* 276 */ "when_clause ::=", + /* 277 */ "when_clause ::= WHEN expr", + /* 278 */ "trigger_cmd_list ::= trigger_cmd SEMI trigger_cmd_list", + /* 279 */ "trigger_cmd_list ::=", + /* 280 */ "trigger_cmd ::= UPDATE orconf nm SET setlist where_opt", + /* 281 */ "trigger_cmd ::= insert_cmd INTO nm inscollist_opt VALUES LP itemlist RP", + /* 282 */ "trigger_cmd ::= insert_cmd INTO nm inscollist_opt select", + /* 283 */ "trigger_cmd ::= DELETE FROM nm where_opt", + /* 284 */ "trigger_cmd ::= select", + /* 285 */ "expr ::= RAISE LP IGNORE RP", + /* 286 */ "expr ::= RAISE LP raisetype COMMA nm RP", + /* 287 */ "raisetype ::= ROLLBACK", + /* 288 */ "raisetype ::= ABORT", + /* 289 */ "raisetype ::= FAIL", + /* 290 */ "cmd ::= DROP TRIGGER fullname", + /* 291 */ "cmd ::= ATTACH database_kw_opt ids AS nm key_opt", + /* 292 */ "key_opt ::=", + /* 293 */ "key_opt ::= KEY ids", + /* 294 */ "key_opt ::= KEY BLOB", + /* 295 */ "database_kw_opt ::= DATABASE", + /* 296 */ "database_kw_opt ::=", + /* 297 */ "cmd ::= DETACH database_kw_opt nm", + /* 298 */ "cmd ::= REINDEX", + /* 299 */ "cmd ::= REINDEX nm dbnm", + /* 300 */ "cmd ::= ALTER TABLE fullname RENAME TO nm", + /* 301 */ "cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt column", + /* 302 */ "add_column_fullname ::= fullname", + /* 303 */ "kwcolumn_opt ::=", + /* 304 */ "kwcolumn_opt ::= COLUMNKW", }; #endif /* NDEBUG */ @@ -1312,72 +1291,72 @@ ** which appear on the RHS of the rule, but which are not used ** inside the C code. */ - case 159: - case 191: - case 208: + case 157: + case 189: + case 206: #line 334 "parse.y" -{sqlite3SelectDelete((yypminor->yy91));} -#line 1322 "parse.c" +{sqlite3SelectDelete((yypminor->yy459));} +#line 1301 "parse.c" break; - case 172: - case 176: + case 170: + case 174: + case 194: case 196: - case 198: - case 206: - case 212: - case 226: + case 204: + case 210: + case 224: #line 593 "parse.y" -{sqlite3ExprDelete((yypminor->yy418));} -#line 1333 "parse.c" +{sqlite3ExprDelete((yypminor->yy2));} +#line 1312 "parse.c" break; - case 177: - case 185: - case 194: + case 175: + case 183: + case 192: + case 195: case 197: case 199: - case 201: - case 211: - case 214: - case 215: - case 218: - case 224: + case 209: + case 212: + case 213: + case 216: + case 222: #line 812 "parse.y" -{sqlite3ExprListDelete((yypminor->yy322));} -#line 1348 "parse.c" +{sqlite3ExprListDelete((yypminor->yy82));} +#line 1327 "parse.c" break; - case 190: - case 195: - case 203: - case 204: + case 188: + case 193: + case 201: + case 202: #line 463 "parse.y" -{sqlite3SrcListDelete((yypminor->yy439));} -#line 1356 "parse.c" +{sqlite3SrcListDelete((yypminor->yy67));} +#line 1335 "parse.c" break; - case 200: + case 198: #line 525 "parse.y" { - sqlite3ExprDelete((yypminor->yy388).pLimit); - sqlite3ExprDelete((yypminor->yy388).pOffset); + sqlite3ExprDelete((yypminor->yy244).pLimit); + sqlite3ExprDelete((yypminor->yy244).pOffset); } -#line 1364 "parse.c" +#line 1343 "parse.c" break; - case 207: - case 210: - case 217: + case 205: + case 208: + case 215: #line 481 "parse.y" -{sqlite3IdListDelete((yypminor->yy232));} -#line 1371 "parse.c" +{sqlite3IdListDelete((yypminor->yy240));} +#line 1350 "parse.c" break; - case 232: - case 237: + case 230: + case 235: #line 905 "parse.y" -{sqlite3DeleteTriggerStep((yypminor->yy451));} -#line 1377 "parse.c" +{sqlite3DeleteTriggerStep((yypminor->yy347));} +#line 1356 "parse.c" break; - case 234: + case 232: #line 889 "parse.y" -{sqlite3IdListDelete((yypminor->yy378).b);} -#line 1382 "parse.c" +{sqlite3IdListDelete((yypminor->yy210).b);} +#line 1361 "parse.c" break; default: break; /* If no destructor action specified: do nothing */ } @@ -1553,315 +1532,311 @@ YYCODETYPE lhs; /* Symbol on the left-hand side of the rule */ unsigned char nrhs; /* Number of right-hand side symbols in the rule */ } yyRuleInfo[] = { + { 142, 1 }, + { 143, 2 }, + { 143, 1 }, + { 145, 1 }, { 144, 1 }, - { 145, 2 }, - { 145, 1 }, + { 144, 3 }, + { 147, 0 }, { 147, 1 }, - { 146, 1 }, { 146, 3 }, { 149, 0 }, { 149, 1 }, - { 148, 3 }, - { 151, 0 }, - { 151, 1 }, - { 151, 2 }, - { 150, 0 }, + { 149, 2 }, + { 148, 0 }, + { 148, 1 }, + { 148, 1 }, + { 148, 1 }, + { 146, 2 }, + { 146, 2 }, + { 146, 2 }, + { 146, 2 }, + { 151, 5 }, + { 153, 1 }, + { 153, 0 }, + { 152, 4 }, + { 152, 2 }, + { 155, 3 }, + { 155, 1 }, + { 158, 3 }, + { 159, 1 }, + { 162, 1 }, + { 163, 1 }, + { 163, 1 }, { 150, 1 }, { 150, 1 }, { 150, 1 }, - { 148, 2 }, - { 148, 2 }, - { 148, 2 }, - { 148, 2 }, - { 153, 5 }, - { 155, 1 }, - { 155, 0 }, - { 154, 4 }, - { 154, 2 }, - { 157, 3 }, - { 157, 1 }, - { 160, 3 }, - { 161, 1 }, + { 160, 0 }, + { 160, 1 }, + { 160, 4 }, + { 160, 6 }, { 164, 1 }, + { 164, 2 }, { 165, 1 }, { 165, 1 }, - { 152, 1 }, - { 152, 1 }, - { 152, 1 }, - { 162, 0 }, - { 162, 1 }, - { 162, 4 }, - { 162, 6 }, - { 166, 1 }, - { 166, 2 }, - { 167, 1 }, - { 167, 1 }, - { 163, 2 }, - { 163, 0 }, - { 170, 3 }, - { 170, 1 }, - { 170, 2 }, - { 170, 3 }, - { 170, 3 }, - { 170, 2 }, - { 171, 2 }, - { 171, 3 }, - { 171, 5 }, - { 171, 2 }, - { 171, 5 }, - { 171, 4 }, - { 171, 1 }, - { 171, 2 }, - { 175, 0 }, - { 175, 1 }, - { 178, 0 }, + { 161, 2 }, + { 161, 0 }, + { 168, 3 }, + { 168, 1 }, + { 168, 2 }, + { 168, 3 }, + { 168, 3 }, + { 168, 2 }, + { 169, 2 }, + { 169, 3 }, + { 169, 5 }, + { 169, 2 }, + { 169, 5 }, + { 169, 4 }, + { 169, 1 }, + { 169, 2 }, + { 173, 0 }, + { 173, 1 }, + { 176, 0 }, + { 176, 2 }, { 178, 2 }, + { 178, 3 }, + { 178, 3 }, + { 178, 3 }, + { 179, 2 }, + { 179, 2 }, + { 179, 1 }, + { 179, 1 }, + { 177, 3 }, + { 177, 2 }, + { 180, 0 }, { 180, 2 }, - { 180, 3 }, - { 180, 3 }, - { 180, 3 }, + { 180, 2 }, + { 156, 0 }, + { 156, 2 }, + { 181, 3 }, { 181, 2 }, - { 181, 2 }, { 181, 1 }, - { 181, 1 }, - { 179, 3 }, - { 179, 2 }, - { 182, 0 }, { 182, 2 }, - { 182, 2 }, - { 158, 0 }, - { 158, 2 }, - { 183, 3 }, - { 183, 2 }, - { 183, 1 }, - { 184, 2 }, - { 184, 7 }, - { 184, 5 }, - { 184, 3 }, - { 184, 10 }, - { 186, 0 }, + { 182, 7 }, + { 182, 5 }, + { 182, 3 }, + { 182, 10 }, + { 184, 0 }, + { 184, 1 }, + { 171, 0 }, + { 171, 3 }, + { 185, 0 }, + { 185, 2 }, { 186, 1 }, - { 173, 0 }, - { 173, 3 }, - { 187, 0 }, - { 187, 2 }, - { 188, 1 }, - { 188, 1 }, - { 188, 1 }, - { 148, 3 }, - { 148, 7 }, - { 148, 3 }, - { 148, 1 }, - { 159, 1 }, - { 159, 3 }, - { 192, 1 }, + { 186, 1 }, + { 186, 1 }, + { 146, 3 }, + { 146, 7 }, + { 146, 3 }, + { 146, 1 }, + { 157, 1 }, + { 157, 3 }, + { 190, 1 }, + { 190, 2 }, + { 190, 1 }, + { 190, 1 }, + { 189, 9 }, + { 191, 1 }, + { 191, 1 }, + { 191, 0 }, + { 199, 2 }, + { 199, 0 }, + { 192, 3 }, { 192, 2 }, - { 192, 1 }, - { 192, 1 }, - { 191, 9 }, - { 193, 1 }, - { 193, 1 }, + { 192, 4 }, + { 200, 2 }, + { 200, 1 }, + { 200, 0 }, { 193, 0 }, - { 201, 2 }, - { 201, 0 }, - { 194, 3 }, - { 194, 2 }, - { 194, 4 }, + { 193, 2 }, { 202, 2 }, - { 202, 1 }, { 202, 0 }, - { 195, 0 }, - { 195, 2 }, + { 201, 6 }, + { 201, 7 }, + { 206, 1 }, + { 206, 1 }, + { 154, 0 }, + { 154, 2 }, + { 188, 2 }, + { 203, 1 }, + { 203, 1 }, + { 203, 2 }, + { 203, 3 }, + { 203, 4 }, { 204, 2 }, { 204, 0 }, - { 203, 6 }, - { 203, 7 }, - { 208, 1 }, - { 208, 1 }, - { 156, 0 }, - { 156, 2 }, - { 190, 2 }, - { 205, 1 }, - { 205, 1 }, - { 205, 2 }, - { 205, 3 }, { 205, 4 }, - { 206, 2 }, - { 206, 0 }, - { 207, 4 }, - { 207, 0 }, - { 199, 0 }, - { 199, 3 }, - { 211, 5 }, - { 211, 3 }, - { 212, 1 }, - { 174, 1 }, - { 174, 1 }, - { 174, 0 }, - { 213, 0 }, - { 213, 2 }, + { 205, 0 }, { 197, 0 }, { 197, 3 }, + { 209, 5 }, + { 209, 3 }, + { 210, 1 }, + { 172, 1 }, + { 172, 1 }, + { 172, 0 }, + { 211, 0 }, + { 211, 2 }, + { 195, 0 }, + { 195, 3 }, + { 196, 0 }, + { 196, 2 }, { 198, 0 }, { 198, 2 }, - { 200, 0 }, - { 200, 2 }, - { 200, 4 }, - { 200, 4 }, - { 148, 4 }, - { 196, 0 }, - { 196, 2 }, - { 148, 6 }, - { 215, 5 }, - { 215, 3 }, - { 148, 8 }, - { 148, 5 }, - { 216, 2 }, + { 198, 4 }, + { 198, 4 }, + { 146, 4 }, + { 194, 0 }, + { 194, 2 }, + { 146, 6 }, + { 213, 5 }, + { 213, 3 }, + { 146, 8 }, + { 146, 5 }, + { 214, 2 }, + { 214, 1 }, + { 216, 3 }, { 216, 1 }, - { 218, 3 }, - { 218, 1 }, - { 217, 0 }, - { 217, 3 }, - { 210, 3 }, - { 210, 1 }, - { 176, 1 }, - { 176, 3 }, - { 172, 1 }, - { 176, 1 }, - { 176, 1 }, - { 176, 3 }, - { 176, 5 }, - { 172, 1 }, - { 172, 1 }, - { 172, 1 }, - { 172, 1 }, - { 176, 1 }, - { 176, 1 }, - { 176, 4 }, - { 176, 4 }, - { 172, 1 }, - { 172, 1 }, - { 172, 1 }, - { 176, 3 }, - { 176, 3 }, - { 176, 3 }, - { 176, 3 }, - { 176, 3 }, - { 176, 3 }, - { 176, 3 }, - { 176, 3 }, - { 176, 3 }, - { 176, 3 }, - { 176, 3 }, - { 176, 3 }, - { 176, 3 }, - { 176, 3 }, - { 176, 3 }, - { 176, 3 }, - { 176, 3 }, - { 176, 3 }, + { 215, 0 }, + { 215, 3 }, + { 208, 3 }, + { 208, 1 }, + { 174, 1 }, + { 174, 3 }, + { 170, 1 }, + { 174, 1 }, + { 174, 1 }, + { 174, 3 }, + { 174, 5 }, + { 170, 1 }, + { 170, 1 }, + { 170, 1 }, + { 170, 1 }, + { 174, 1 }, + { 174, 1 }, + { 174, 4 }, + { 174, 4 }, + { 170, 1 }, + { 174, 3 }, + { 174, 3 }, + { 174, 3 }, + { 174, 3 }, + { 174, 3 }, + { 174, 3 }, + { 174, 3 }, + { 174, 3 }, + { 174, 3 }, + { 174, 3 }, + { 174, 3 }, + { 174, 3 }, + { 174, 3 }, + { 174, 3 }, + { 174, 3 }, + { 174, 3 }, + { 174, 3 }, + { 174, 3 }, + { 217, 1 }, + { 217, 2 }, + { 218, 2 }, + { 218, 0 }, + { 174, 4 }, + { 174, 2 }, + { 174, 3 }, + { 174, 2 }, + { 174, 3 }, + { 174, 4 }, + { 174, 2 }, + { 174, 2 }, + { 174, 2 }, + { 174, 2 }, { 219, 1 }, - { 219, 1 }, { 219, 2 }, - { 219, 2 }, + { 174, 5 }, + { 220, 1 }, { 220, 2 }, - { 220, 0 }, - { 176, 4 }, - { 176, 2 }, - { 176, 3 }, - { 176, 2 }, - { 176, 3 }, - { 176, 4 }, - { 176, 2 }, - { 176, 2 }, - { 176, 2 }, - { 176, 2 }, + { 174, 5 }, + { 174, 3 }, + { 174, 5 }, + { 174, 4 }, + { 174, 4 }, + { 174, 5 }, + { 222, 5 }, + { 222, 4 }, + { 223, 2 }, + { 223, 0 }, { 221, 1 }, - { 221, 2 }, - { 176, 5 }, - { 222, 1 }, - { 222, 2 }, - { 176, 5 }, - { 176, 3 }, - { 176, 5 }, - { 176, 4 }, - { 176, 4 }, - { 176, 5 }, - { 224, 5 }, - { 224, 4 }, - { 225, 2 }, + { 221, 0 }, + { 212, 3 }, + { 212, 1 }, + { 224, 1 }, + { 224, 0 }, + { 146, 11 }, + { 225, 1 }, { 225, 0 }, - { 223, 1 }, - { 223, 0 }, - { 214, 3 }, - { 214, 1 }, + { 175, 0 }, + { 175, 3 }, + { 183, 5 }, + { 183, 3 }, { 226, 1 }, - { 226, 0 }, - { 148, 11 }, + { 146, 3 }, + { 146, 1 }, + { 146, 2 }, + { 146, 5 }, + { 146, 5 }, + { 146, 5 }, + { 146, 5 }, + { 146, 6 }, + { 146, 3 }, + { 166, 2 }, + { 167, 2 }, + { 228, 1 }, + { 228, 1 }, { 227, 1 }, { 227, 0 }, - { 177, 0 }, - { 177, 3 }, - { 185, 5 }, - { 185, 3 }, - { 228, 1 }, - { 148, 3 }, - { 148, 1 }, - { 148, 2 }, - { 148, 5 }, - { 148, 5 }, - { 148, 5 }, - { 148, 5 }, - { 148, 6 }, - { 148, 3 }, - { 168, 2 }, - { 169, 2 }, - { 230, 1 }, - { 230, 1 }, - { 229, 1 }, - { 229, 0 }, - { 148, 5 }, - { 231, 10 }, - { 233, 1 }, - { 233, 1 }, - { 233, 2 }, + { 146, 5 }, + { 229, 10 }, + { 231, 1 }, + { 231, 1 }, + { 231, 2 }, + { 231, 0 }, + { 232, 1 }, + { 232, 1 }, + { 232, 1 }, + { 232, 3 }, { 233, 0 }, - { 234, 1 }, - { 234, 1 }, - { 234, 1 }, - { 234, 3 }, - { 235, 0 }, - { 235, 3 }, - { 235, 3 }, + { 233, 3 }, + { 233, 3 }, + { 234, 0 }, + { 234, 2 }, + { 230, 3 }, + { 230, 0 }, + { 235, 6 }, + { 235, 8 }, + { 235, 5 }, + { 235, 4 }, + { 235, 1 }, + { 174, 4 }, + { 174, 6 }, + { 187, 1 }, + { 187, 1 }, + { 187, 1 }, + { 146, 3 }, + { 146, 6 }, + { 237, 0 }, + { 237, 2 }, + { 237, 2 }, + { 236, 1 }, { 236, 0 }, - { 236, 2 }, - { 232, 3 }, - { 232, 0 }, - { 237, 6 }, - { 237, 8 }, - { 237, 5 }, - { 237, 4 }, - { 237, 1 }, - { 176, 4 }, - { 176, 6 }, - { 189, 1 }, - { 189, 1 }, - { 189, 1 }, - { 148, 3 }, - { 148, 6 }, - { 239, 0 }, - { 239, 2 }, - { 239, 2 }, + { 146, 3 }, + { 146, 1 }, + { 146, 3 }, + { 146, 6 }, + { 146, 6 }, { 238, 1 }, - { 238, 0 }, - { 148, 3 }, - { 148, 1 }, - { 148, 3 }, - { 148, 6 }, - { 148, 6 }, - { 240, 1 }, - { 241, 0 }, - { 241, 1 }, + { 239, 0 }, + { 239, 1 }, }; static void yy_accept(yyParser*); /* Forward Declaration */ @@ -1913,27 +1888,27 @@ case 3: #line 84 "parse.y" { sqlite3FinishCoding(pParse); } -#line 1918 "parse.c" +#line 1893 "parse.c" break; case 6: #line 87 "parse.y" { sqlite3BeginParse(pParse, 0); } -#line 1923 "parse.c" +#line 1898 "parse.c" break; case 7: #line 89 "parse.y" { sqlite3BeginParse(pParse, 1); } -#line 1928 "parse.c" +#line 1903 "parse.c" break; case 8: #line 95 "parse.y" -{sqlite3BeginTransaction(pParse, yymsp[-1].minor.yy328);} -#line 1933 "parse.c" +{sqlite3BeginTransaction(pParse, yymsp[-1].minor.yy412);} +#line 1908 "parse.c" break; case 12: #line 100 "parse.y" -{yygotominor.yy328 = TK_DEFERRED;} -#line 1938 "parse.c" +{yygotominor.yy412 = TK_DEFERRED;} +#line 1913 "parse.c" break; case 13: case 14: @@ -1942,36 +1917,36 @@ case 103: case 104: #line 101 "parse.y" -{yygotominor.yy328 = yymsp[0].major;} -#line 1948 "parse.c" +{yygotominor.yy412 = yymsp[0].major;} +#line 1923 "parse.c" break; case 16: case 17: #line 104 "parse.y" {sqlite3CommitTransaction(pParse);} -#line 1954 "parse.c" +#line 1929 "parse.c" break; case 18: #line 106 "parse.y" {sqlite3RollbackTransaction(pParse);} -#line 1959 "parse.c" +#line 1934 "parse.c" break; case 20: #line 111 "parse.y" { - sqlite3StartTable(pParse,&yymsp[-4].minor.yy0,&yymsp[-1].minor.yy430,&yymsp[0].minor.yy430,yymsp[-3].minor.yy328,0); + sqlite3StartTable(pParse,&yymsp[-4].minor.yy0,&yymsp[-1].minor.yy258,&yymsp[0].minor.yy258,yymsp[-3].minor.yy412,0); } -#line 1966 "parse.c" +#line 1941 "parse.c" break; case 21: case 60: case 74: case 106: - case 224: - case 227: + case 220: + case 223: #line 116 "parse.y" -{yygotominor.yy328 = 1;} -#line 1976 "parse.c" +{yygotominor.yy412 = 1;} +#line 1951 "parse.c" break; case 22: case 59: @@ -1980,42 +1955,42 @@ case 86: case 107: case 108: - case 223: - case 226: + case 219: + case 222: #line 118 "parse.y" -{yygotominor.yy328 = 0;} -#line 1989 "parse.c" +{yygotominor.yy412 = 0;} +#line 1964 "parse.c" break; case 23: #line 119 "parse.y" { - sqlite3EndTable(pParse,&yymsp[-1].minor.yy430,&yymsp[0].minor.yy0,0); + sqlite3EndTable(pParse,&yymsp[-1].minor.yy258,&yymsp[0].minor.yy0,0); } -#line 1996 "parse.c" +#line 1971 "parse.c" break; case 24: #line 122 "parse.y" { - sqlite3EndTable(pParse,0,0,yymsp[0].minor.yy91); - sqlite3SelectDelete(yymsp[0].minor.yy91); + sqlite3EndTable(pParse,0,0,yymsp[0].minor.yy459); + sqlite3SelectDelete(yymsp[0].minor.yy459); } -#line 2004 "parse.c" +#line 1979 "parse.c" break; case 27: #line 133 "parse.y" { - yygotominor.yy430.z = yymsp[-2].minor.yy430.z; - yygotominor.yy430.n = (pParse->sLastToken.z-yymsp[-2].minor.yy430.z) + pParse->sLastToken.n; + yygotominor.yy258.z = yymsp[-2].minor.yy258.z; + yygotominor.yy258.n = (pParse->sLastToken.z-yymsp[-2].minor.yy258.z) + pParse->sLastToken.n; } -#line 2012 "parse.c" +#line 1987 "parse.c" break; case 28: #line 137 "parse.y" { - sqlite3AddColumn(pParse,&yymsp[0].minor.yy430); - yygotominor.yy430 = yymsp[0].minor.yy430; + sqlite3AddColumn(pParse,&yymsp[0].minor.yy258); + yygotominor.yy258 = yymsp[0].minor.yy258; } -#line 2020 "parse.c" +#line 1995 "parse.c" break; case 29: case 30: @@ -2023,160 +1998,160 @@ case 32: case 33: case 34: - case 263: - case 264: + case 259: + case 260: #line 147 "parse.y" -{yygotominor.yy430 = yymsp[0].minor.yy0;} -#line 2032 "parse.c" +{yygotominor.yy258 = yymsp[0].minor.yy0;} +#line 2007 "parse.c" break; case 36: #line 202 "parse.y" -{sqlite3AddColumnType(pParse,&yymsp[0].minor.yy430,&yymsp[0].minor.yy430);} -#line 2037 "parse.c" +{sqlite3AddColumnType(pParse,&yymsp[0].minor.yy258,&yymsp[0].minor.yy258);} +#line 2012 "parse.c" break; case 37: #line 203 "parse.y" -{sqlite3AddColumnType(pParse,&yymsp[-3].minor.yy430,&yymsp[0].minor.yy0);} -#line 2042 "parse.c" +{sqlite3AddColumnType(pParse,&yymsp[-3].minor.yy258,&yymsp[0].minor.yy0);} +#line 2017 "parse.c" break; case 38: #line 205 "parse.y" -{sqlite3AddColumnType(pParse,&yymsp[-5].minor.yy430,&yymsp[0].minor.yy0);} -#line 2047 "parse.c" +{sqlite3AddColumnType(pParse,&yymsp[-5].minor.yy258,&yymsp[0].minor.yy0);} +#line 2022 "parse.c" break; case 39: case 114: case 115: case 126: case 146: - case 251: - case 261: - case 262: + case 247: + case 257: + case 258: #line 207 "parse.y" -{yygotominor.yy430 = yymsp[0].minor.yy430;} -#line 2059 "parse.c" +{yygotominor.yy258 = yymsp[0].minor.yy258;} +#line 2034 "parse.c" break; case 40: #line 208 "parse.y" -{yygotominor.yy430.z=yymsp[-1].minor.yy430.z; yygotominor.yy430.n=yymsp[0].minor.yy430.n+(yymsp[0].minor.yy430.z-yymsp[-1].minor.yy430.z);} -#line 2064 "parse.c" +{yygotominor.yy258.z=yymsp[-1].minor.yy258.z; yygotominor.yy258.n=yymsp[0].minor.yy258.n+(yymsp[0].minor.yy258.z-yymsp[-1].minor.yy258.z);} +#line 2039 "parse.c" break; case 41: #line 210 "parse.y" -{ yygotominor.yy328 = atoi(yymsp[0].minor.yy430.z); } -#line 2069 "parse.c" +{ yygotominor.yy412 = atoi(yymsp[0].minor.yy258.z); } +#line 2044 "parse.c" break; case 42: #line 211 "parse.y" -{ yygotominor.yy328 = -atoi(yymsp[0].minor.yy430.z); } -#line 2074 "parse.c" +{ yygotominor.yy412 = -atoi(yymsp[0].minor.yy258.z); } +#line 2049 "parse.c" break; case 47: case 48: #line 216 "parse.y" -{sqlite3AddDefaultValue(pParse,yymsp[0].minor.yy418);} -#line 2080 "parse.c" +{sqlite3AddDefaultValue(pParse,yymsp[0].minor.yy2);} +#line 2055 "parse.c" break; case 49: #line 218 "parse.y" { - Expr *p = sqlite3Expr(TK_UMINUS, yymsp[0].minor.yy418, 0, 0); + Expr *p = sqlite3Expr(TK_UMINUS, yymsp[0].minor.yy2, 0, 0); sqlite3AddDefaultValue(pParse,p); } -#line 2088 "parse.c" +#line 2063 "parse.c" break; case 50: #line 222 "parse.y" { - Expr *p = sqlite3Expr(TK_STRING, 0, 0, &yymsp[0].minor.yy430); + Expr *p = sqlite3Expr(TK_STRING, 0, 0, &yymsp[0].minor.yy258); sqlite3AddDefaultValue(pParse,p); } -#line 2096 "parse.c" +#line 2071 "parse.c" break; case 52: #line 231 "parse.y" -{sqlite3AddNotNull(pParse, yymsp[0].minor.yy328);} -#line 2101 "parse.c" +{sqlite3AddNotNull(pParse, yymsp[0].minor.yy412);} +#line 2076 "parse.c" break; case 53: #line 233 "parse.y" -{sqlite3AddPrimaryKey(pParse,0,yymsp[-1].minor.yy328,yymsp[0].minor.yy328);} -#line 2106 "parse.c" +{sqlite3AddPrimaryKey(pParse,0,yymsp[-1].minor.yy412,yymsp[0].minor.yy412);} +#line 2081 "parse.c" break; case 54: #line 234 "parse.y" -{sqlite3CreateIndex(pParse,0,0,0,0,yymsp[0].minor.yy328,0,0);} -#line 2111 "parse.c" +{sqlite3CreateIndex(pParse,0,0,0,0,yymsp[0].minor.yy412,0,0);} +#line 2086 "parse.c" break; case 55: #line 235 "parse.y" -{sqlite3ExprDelete(yymsp[-2].minor.yy418);} -#line 2116 "parse.c" +{sqlite3ExprDelete(yymsp[-2].minor.yy2);} +#line 2091 "parse.c" break; case 56: #line 237 "parse.y" -{sqlite3CreateForeignKey(pParse,0,&yymsp[-2].minor.yy430,yymsp[-1].minor.yy322,yymsp[0].minor.yy328);} -#line 2121 "parse.c" +{sqlite3CreateForeignKey(pParse,0,&yymsp[-2].minor.yy258,yymsp[-1].minor.yy82,yymsp[0].minor.yy412);} +#line 2096 "parse.c" break; case 57: #line 238 "parse.y" -{sqlite3DeferForeignKey(pParse,yymsp[0].minor.yy328);} -#line 2126 "parse.c" +{sqlite3DeferForeignKey(pParse,yymsp[0].minor.yy412);} +#line 2101 "parse.c" break; case 58: #line 239 "parse.y" -{sqlite3AddCollateType(pParse, yymsp[0].minor.yy430.z, yymsp[0].minor.yy430.n);} -#line 2131 "parse.c" +{sqlite3AddCollateType(pParse, yymsp[0].minor.yy258.z, yymsp[0].minor.yy258.n);} +#line 2106 "parse.c" break; case 61: #line 252 "parse.y" -{ yygotominor.yy328 = OE_Restrict * 0x010101; } -#line 2136 "parse.c" +{ yygotominor.yy412 = OE_Restrict * 0x010101; } +#line 2111 "parse.c" break; case 62: #line 253 "parse.y" -{ yygotominor.yy328 = (yymsp[-1].minor.yy328 & yymsp[0].minor.yy319.mask) | yymsp[0].minor.yy319.value; } -#line 2141 "parse.c" +{ yygotominor.yy412 = (yymsp[-1].minor.yy412 & yymsp[0].minor.yy47.mask) | yymsp[0].minor.yy47.value; } +#line 2116 "parse.c" break; case 63: #line 255 "parse.y" -{ yygotominor.yy319.value = 0; yygotominor.yy319.mask = 0x000000; } -#line 2146 "parse.c" +{ yygotominor.yy47.value = 0; yygotominor.yy47.mask = 0x000000; } +#line 2121 "parse.c" break; case 64: #line 256 "parse.y" -{ yygotominor.yy319.value = yymsp[0].minor.yy328; yygotominor.yy319.mask = 0x0000ff; } -#line 2151 "parse.c" +{ yygotominor.yy47.value = yymsp[0].minor.yy412; yygotominor.yy47.mask = 0x0000ff; } +#line 2126 "parse.c" break; case 65: #line 257 "parse.y" -{ yygotominor.yy319.value = yymsp[0].minor.yy328<<8; yygotominor.yy319.mask = 0x00ff00; } -#line 2156 "parse.c" +{ yygotominor.yy47.value = yymsp[0].minor.yy412<<8; yygotominor.yy47.mask = 0x00ff00; } +#line 2131 "parse.c" break; case 66: #line 258 "parse.y" -{ yygotominor.yy319.value = yymsp[0].minor.yy328<<16; yygotominor.yy319.mask = 0xff0000; } -#line 2161 "parse.c" +{ yygotominor.yy47.value = yymsp[0].minor.yy412<<16; yygotominor.yy47.mask = 0xff0000; } +#line 2136 "parse.c" break; case 67: #line 260 "parse.y" -{ yygotominor.yy328 = OE_SetNull; } -#line 2166 "parse.c" +{ yygotominor.yy412 = OE_SetNull; } +#line 2141 "parse.c" break; case 68: #line 261 "parse.y" -{ yygotominor.yy328 = OE_SetDflt; } -#line 2171 "parse.c" +{ yygotominor.yy412 = OE_SetDflt; } +#line 2146 "parse.c" break; case 69: #line 262 "parse.y" -{ yygotominor.yy328 = OE_Cascade; } -#line 2176 "parse.c" +{ yygotominor.yy412 = OE_Cascade; } +#line 2151 "parse.c" break; case 70: #line 263 "parse.y" -{ yygotominor.yy328 = OE_Restrict; } -#line 2181 "parse.c" +{ yygotominor.yy412 = OE_Restrict; } +#line 2156 "parse.c" break; case 71: case 72: @@ -2186,398 +2161,398 @@ case 92: case 163: #line 265 "parse.y" -{yygotominor.yy328 = yymsp[0].minor.yy328;} -#line 2192 "parse.c" +{yygotominor.yy412 = yymsp[0].minor.yy412;} +#line 2167 "parse.c" break; case 76: #line 275 "parse.y" -{yygotominor.yy430.n = 0; yygotominor.yy430.z = 0;} -#line 2197 "parse.c" +{yygotominor.yy258.n = 0; yygotominor.yy258.z = 0;} +#line 2172 "parse.c" break; case 77: #line 276 "parse.y" -{yygotominor.yy430 = yymsp[-1].minor.yy0;} -#line 2202 "parse.c" +{yygotominor.yy258 = yymsp[-1].minor.yy0;} +#line 2177 "parse.c" break; case 82: #line 282 "parse.y" -{sqlite3AddPrimaryKey(pParse,yymsp[-3].minor.yy322,yymsp[0].minor.yy328,yymsp[-2].minor.yy328);} -#line 2207 "parse.c" +{sqlite3AddPrimaryKey(pParse,yymsp[-3].minor.yy82,yymsp[0].minor.yy412,yymsp[-2].minor.yy412);} +#line 2182 "parse.c" break; case 83: #line 284 "parse.y" -{sqlite3CreateIndex(pParse,0,0,0,yymsp[-2].minor.yy322,yymsp[0].minor.yy328,0,0);} -#line 2212 "parse.c" +{sqlite3CreateIndex(pParse,0,0,0,yymsp[-2].minor.yy82,yymsp[0].minor.yy412,0,0);} +#line 2187 "parse.c" break; case 85: #line 287 "parse.y" { - sqlite3CreateForeignKey(pParse, yymsp[-6].minor.yy322, &yymsp[-3].minor.yy430, yymsp[-2].minor.yy322, yymsp[-1].minor.yy328); - sqlite3DeferForeignKey(pParse, yymsp[0].minor.yy328); + sqlite3CreateForeignKey(pParse, yymsp[-6].minor.yy82, &yymsp[-3].minor.yy258, yymsp[-2].minor.yy82, yymsp[-1].minor.yy412); + sqlite3DeferForeignKey(pParse, yymsp[0].minor.yy412); } -#line 2220 "parse.c" +#line 2195 "parse.c" break; case 88: case 90: #line 301 "parse.y" -{yygotominor.yy328 = OE_Default;} -#line 2226 "parse.c" +{yygotominor.yy412 = OE_Default;} +#line 2201 "parse.c" break; case 93: #line 306 "parse.y" -{yygotominor.yy328 = OE_Ignore;} -#line 2231 "parse.c" +{yygotominor.yy412 = OE_Ignore;} +#line 2206 "parse.c" break; case 94: case 164: #line 307 "parse.y" -{yygotominor.yy328 = OE_Replace;} -#line 2237 "parse.c" +{yygotominor.yy412 = OE_Replace;} +#line 2212 "parse.c" break; case 95: #line 311 "parse.y" { - sqlite3DropTable(pParse, yymsp[0].minor.yy439, 0); + sqlite3DropTable(pParse, yymsp[0].minor.yy67, 0); } -#line 2244 "parse.c" +#line 2219 "parse.c" break; case 96: #line 318 "parse.y" { - sqlite3CreateView(pParse, &yymsp[-6].minor.yy0, &yymsp[-3].minor.yy430, &yymsp[-2].minor.yy430, yymsp[0].minor.yy91, yymsp[-5].minor.yy328); + sqlite3CreateView(pParse, &yymsp[-6].minor.yy0, &yymsp[-3].minor.yy258, &yymsp[-2].minor.yy258, yymsp[0].minor.yy459, yymsp[-5].minor.yy412); } -#line 2251 "parse.c" +#line 2226 "parse.c" break; case 97: #line 321 "parse.y" { - sqlite3DropTable(pParse, yymsp[0].minor.yy439, 1); + sqlite3DropTable(pParse, yymsp[0].minor.yy67, 1); } -#line 2258 "parse.c" +#line 2233 "parse.c" break; case 98: #line 328 "parse.y" { - sqlite3Select(pParse, yymsp[0].minor.yy91, SRT_Callback, 0, 0, 0, 0, 0); - sqlite3SelectDelete(yymsp[0].minor.yy91); + sqlite3Select(pParse, yymsp[0].minor.yy459, SRT_Callback, 0, 0, 0, 0, 0); + sqlite3SelectDelete(yymsp[0].minor.yy459); } -#line 2266 "parse.c" +#line 2241 "parse.c" break; case 99: case 123: #line 338 "parse.y" -{yygotominor.yy91 = yymsp[0].minor.yy91;} -#line 2272 "parse.c" +{yygotominor.yy459 = yymsp[0].minor.yy459;} +#line 2247 "parse.c" break; case 100: #line 340 "parse.y" { - if( yymsp[0].minor.yy91 ){ - yymsp[0].minor.yy91->op = yymsp[-1].minor.yy328; - yymsp[0].minor.yy91->pPrior = yymsp[-2].minor.yy91; + if( yymsp[0].minor.yy459 ){ + yymsp[0].minor.yy459->op = yymsp[-1].minor.yy412; + yymsp[0].minor.yy459->pPrior = yymsp[-2].minor.yy459; } - yygotominor.yy91 = yymsp[0].minor.yy91; + yygotominor.yy459 = yymsp[0].minor.yy459; } -#line 2283 "parse.c" +#line 2258 "parse.c" break; case 102: #line 349 "parse.y" -{yygotominor.yy328 = TK_ALL;} -#line 2288 "parse.c" +{yygotominor.yy412 = TK_ALL;} +#line 2263 "parse.c" break; case 105: #line 354 "parse.y" { - yygotominor.yy91 = sqlite3SelectNew(yymsp[-6].minor.yy322,yymsp[-5].minor.yy439,yymsp[-4].minor.yy418,yymsp[-3].minor.yy322,yymsp[-2].minor.yy418,yymsp[-1].minor.yy322,yymsp[-7].minor.yy328,yymsp[0].minor.yy388.pLimit,yymsp[0].minor.yy388.pOffset); + yygotominor.yy459 = sqlite3SelectNew(yymsp[-6].minor.yy82,yymsp[-5].minor.yy67,yymsp[-4].minor.yy2,yymsp[-3].minor.yy82,yymsp[-2].minor.yy2,yymsp[-1].minor.yy82,yymsp[-7].minor.yy412,yymsp[0].minor.yy244.pLimit,yymsp[0].minor.yy244.pOffset); } -#line 2295 "parse.c" +#line 2270 "parse.c" break; case 109: - case 248: + case 244: #line 375 "parse.y" -{yygotominor.yy322 = yymsp[-1].minor.yy322;} -#line 2301 "parse.c" +{yygotominor.yy82 = yymsp[-1].minor.yy82;} +#line 2276 "parse.c" break; case 110: case 137: case 147: - case 247: + case 243: #line 376 "parse.y" -{yygotominor.yy322 = 0;} -#line 2309 "parse.c" +{yygotominor.yy82 = 0;} +#line 2284 "parse.c" break; case 111: #line 377 "parse.y" { - yygotominor.yy322 = sqlite3ExprListAppend(yymsp[-2].minor.yy322,yymsp[-1].minor.yy418,yymsp[0].minor.yy430.n?&yymsp[0].minor.yy430:0); + yygotominor.yy82 = sqlite3ExprListAppend(yymsp[-2].minor.yy82,yymsp[-1].minor.yy2,yymsp[0].minor.yy258.n?&yymsp[0].minor.yy258:0); } -#line 2316 "parse.c" +#line 2291 "parse.c" break; case 112: #line 380 "parse.y" { - yygotominor.yy322 = sqlite3ExprListAppend(yymsp[-1].minor.yy322, sqlite3Expr(TK_ALL, 0, 0, 0), 0); + yygotominor.yy82 = sqlite3ExprListAppend(yymsp[-1].minor.yy82, sqlite3Expr(TK_ALL, 0, 0, 0), 0); } -#line 2323 "parse.c" +#line 2298 "parse.c" break; case 113: #line 383 "parse.y" { Expr *pRight = sqlite3Expr(TK_ALL, 0, 0, 0); - Expr *pLeft = sqlite3Expr(TK_ID, 0, 0, &yymsp[-2].minor.yy430); - yygotominor.yy322 = sqlite3ExprListAppend(yymsp[-3].minor.yy322, sqlite3Expr(TK_DOT, pLeft, pRight, 0), 0); + Expr *pLeft = sqlite3Expr(TK_ID, 0, 0, &yymsp[-2].minor.yy258); + yygotominor.yy82 = sqlite3ExprListAppend(yymsp[-3].minor.yy82, sqlite3Expr(TK_DOT, pLeft, pRight, 0), 0); } -#line 2332 "parse.c" +#line 2307 "parse.c" break; case 116: #line 395 "parse.y" -{yygotominor.yy430.n = 0;} -#line 2337 "parse.c" +{yygotominor.yy258.n = 0;} +#line 2312 "parse.c" break; case 117: #line 407 "parse.y" -{yygotominor.yy439 = sqliteMalloc(sizeof(*yygotominor.yy439));} -#line 2342 "parse.c" +{yygotominor.yy67 = sqliteMalloc(sizeof(*yygotominor.yy67));} +#line 2317 "parse.c" break; case 118: #line 408 "parse.y" -{yygotominor.yy439 = yymsp[0].minor.yy439;} -#line 2347 "parse.c" +{yygotominor.yy67 = yymsp[0].minor.yy67;} +#line 2322 "parse.c" break; case 119: #line 413 "parse.y" { - yygotominor.yy439 = yymsp[-1].minor.yy439; - if( yygotominor.yy439 && yygotominor.yy439->nSrc>0 ) yygotominor.yy439->a[yygotominor.yy439->nSrc-1].jointype = yymsp[0].minor.yy328; + yygotominor.yy67 = yymsp[-1].minor.yy67; + if( yygotominor.yy67 && yygotominor.yy67->nSrc>0 ) yygotominor.yy67->a[yygotominor.yy67->nSrc-1].jointype = yymsp[0].minor.yy412; } -#line 2355 "parse.c" +#line 2330 "parse.c" break; case 120: #line 417 "parse.y" -{yygotominor.yy439 = 0;} -#line 2360 "parse.c" +{yygotominor.yy67 = 0;} +#line 2335 "parse.c" break; case 121: #line 418 "parse.y" { - yygotominor.yy439 = sqlite3SrcListAppend(yymsp[-5].minor.yy439,&yymsp[-4].minor.yy430,&yymsp[-3].minor.yy430); - if( yymsp[-2].minor.yy430.n ) sqlite3SrcListAddAlias(yygotominor.yy439,&yymsp[-2].minor.yy430); - if( yymsp[-1].minor.yy418 ){ - if( yygotominor.yy439 && yygotominor.yy439->nSrc>1 ){ yygotominor.yy439->a[yygotominor.yy439->nSrc-2].pOn = yymsp[-1].minor.yy418; } - else { sqlite3ExprDelete(yymsp[-1].minor.yy418); } + yygotominor.yy67 = sqlite3SrcListAppend(yymsp[-5].minor.yy67,&yymsp[-4].minor.yy258,&yymsp[-3].minor.yy258); + if( yymsp[-2].minor.yy258.n ) sqlite3SrcListAddAlias(yygotominor.yy67,&yymsp[-2].minor.yy258); + if( yymsp[-1].minor.yy2 ){ + if( yygotominor.yy67 && yygotominor.yy67->nSrc>1 ){ yygotominor.yy67->a[yygotominor.yy67->nSrc-2].pOn = yymsp[-1].minor.yy2; } + else { sqlite3ExprDelete(yymsp[-1].minor.yy2); } } - if( yymsp[0].minor.yy232 ){ - if( yygotominor.yy439 && yygotominor.yy439->nSrc>1 ){ yygotominor.yy439->a[yygotominor.yy439->nSrc-2].pUsing = yymsp[0].minor.yy232; } - else { sqlite3IdListDelete(yymsp[0].minor.yy232); } + if( yymsp[0].minor.yy240 ){ + if( yygotominor.yy67 && yygotominor.yy67->nSrc>1 ){ yygotominor.yy67->a[yygotominor.yy67->nSrc-2].pUsing = yymsp[0].minor.yy240; } + else { sqlite3IdListDelete(yymsp[0].minor.yy240); } } } -#line 2376 "parse.c" +#line 2351 "parse.c" break; case 122: #line 432 "parse.y" { - yygotominor.yy439 = sqlite3SrcListAppend(yymsp[-6].minor.yy439,0,0); - yygotominor.yy439->a[yygotominor.yy439->nSrc-1].pSelect = yymsp[-4].minor.yy91; - if( yymsp[-2].minor.yy430.n ) sqlite3SrcListAddAlias(yygotominor.yy439,&yymsp[-2].minor.yy430); - if( yymsp[-1].minor.yy418 ){ - if( yygotominor.yy439 && yygotominor.yy439->nSrc>1 ){ yygotominor.yy439->a[yygotominor.yy439->nSrc-2].pOn = yymsp[-1].minor.yy418; } - else { sqlite3ExprDelete(yymsp[-1].minor.yy418); } + yygotominor.yy67 = sqlite3SrcListAppend(yymsp[-6].minor.yy67,0,0); + yygotominor.yy67->a[yygotominor.yy67->nSrc-1].pSelect = yymsp[-4].minor.yy459; + if( yymsp[-2].minor.yy258.n ) sqlite3SrcListAddAlias(yygotominor.yy67,&yymsp[-2].minor.yy258); + if( yymsp[-1].minor.yy2 ){ + if( yygotominor.yy67 && yygotominor.yy67->nSrc>1 ){ yygotominor.yy67->a[yygotominor.yy67->nSrc-2].pOn = yymsp[-1].minor.yy2; } + else { sqlite3ExprDelete(yymsp[-1].minor.yy2); } } - if( yymsp[0].minor.yy232 ){ - if( yygotominor.yy439 && yygotominor.yy439->nSrc>1 ){ yygotominor.yy439->a[yygotominor.yy439->nSrc-2].pUsing = yymsp[0].minor.yy232; } - else { sqlite3IdListDelete(yymsp[0].minor.yy232); } + if( yymsp[0].minor.yy240 ){ + if( yygotominor.yy67 && yygotominor.yy67->nSrc>1 ){ yygotominor.yy67->a[yygotominor.yy67->nSrc-2].pUsing = yymsp[0].minor.yy240; } + else { sqlite3IdListDelete(yymsp[0].minor.yy240); } } } -#line 2393 "parse.c" +#line 2368 "parse.c" break; case 124: #line 453 "parse.y" { - yygotominor.yy91 = sqlite3SelectNew(0,yymsp[0].minor.yy439,0,0,0,0,0,0,0); + yygotominor.yy459 = sqlite3SelectNew(0,yymsp[0].minor.yy67,0,0,0,0,0,0,0); } -#line 2400 "parse.c" +#line 2375 "parse.c" break; case 125: #line 459 "parse.y" -{yygotominor.yy430.z=0; yygotominor.yy430.n=0;} -#line 2405 "parse.c" +{yygotominor.yy258.z=0; yygotominor.yy258.n=0;} +#line 2380 "parse.c" break; case 127: #line 464 "parse.y" -{yygotominor.yy439 = sqlite3SrcListAppend(0,&yymsp[-1].minor.yy430,&yymsp[0].minor.yy430);} -#line 2410 "parse.c" +{yygotominor.yy67 = sqlite3SrcListAppend(0,&yymsp[-1].minor.yy258,&yymsp[0].minor.yy258);} +#line 2385 "parse.c" break; case 128: case 129: #line 468 "parse.y" -{ yygotominor.yy328 = JT_INNER; } -#line 2416 "parse.c" +{ yygotominor.yy412 = JT_INNER; } +#line 2391 "parse.c" break; case 130: #line 470 "parse.y" -{ yygotominor.yy328 = sqlite3JoinType(pParse,&yymsp[-1].minor.yy0,0,0); } -#line 2421 "parse.c" +{ yygotominor.yy412 = sqlite3JoinType(pParse,&yymsp[-1].minor.yy0,0,0); } +#line 2396 "parse.c" break; case 131: #line 471 "parse.y" -{ yygotominor.yy328 = sqlite3JoinType(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy430,0); } -#line 2426 "parse.c" +{ yygotominor.yy412 = sqlite3JoinType(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy258,0); } +#line 2401 "parse.c" break; case 132: #line 473 "parse.y" -{ yygotominor.yy328 = sqlite3JoinType(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy430,&yymsp[-1].minor.yy430); } -#line 2431 "parse.c" +{ yygotominor.yy412 = sqlite3JoinType(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy258,&yymsp[-1].minor.yy258); } +#line 2406 "parse.c" break; case 133: case 141: case 150: case 157: case 171: - case 211: - case 236: + case 207: + case 232: + case 234: case 238: - case 242: #line 477 "parse.y" -{yygotominor.yy418 = yymsp[0].minor.yy418;} -#line 2444 "parse.c" +{yygotominor.yy2 = yymsp[0].minor.yy2;} +#line 2419 "parse.c" break; case 134: case 149: case 156: - case 212: - case 237: + case 208: + case 233: + case 235: case 239: - case 243: #line 478 "parse.y" -{yygotominor.yy418 = 0;} -#line 2455 "parse.c" +{yygotominor.yy2 = 0;} +#line 2430 "parse.c" break; case 135: case 168: #line 482 "parse.y" -{yygotominor.yy232 = yymsp[-1].minor.yy232;} -#line 2461 "parse.c" +{yygotominor.yy240 = yymsp[-1].minor.yy240;} +#line 2436 "parse.c" break; case 136: case 167: #line 483 "parse.y" -{yygotominor.yy232 = 0;} -#line 2467 "parse.c" +{yygotominor.yy240 = 0;} +#line 2442 "parse.c" break; case 138: case 148: #line 494 "parse.y" -{yygotominor.yy322 = yymsp[0].minor.yy322;} -#line 2473 "parse.c" +{yygotominor.yy82 = yymsp[0].minor.yy82;} +#line 2448 "parse.c" break; case 139: #line 495 "parse.y" { - yygotominor.yy322 = sqlite3ExprListAppend(yymsp[-4].minor.yy322,yymsp[-2].minor.yy418,yymsp[-1].minor.yy430.n>0?&yymsp[-1].minor.yy430:0); - if( yygotominor.yy322 ) yygotominor.yy322->a[yygotominor.yy322->nExpr-1].sortOrder = yymsp[0].minor.yy328; + yygotominor.yy82 = sqlite3ExprListAppend(yymsp[-4].minor.yy82,yymsp[-2].minor.yy2,yymsp[-1].minor.yy258.n>0?&yymsp[-1].minor.yy258:0); + if( yygotominor.yy82 ) yygotominor.yy82->a[yygotominor.yy82->nExpr-1].sortOrder = yymsp[0].minor.yy412; } -#line 2481 "parse.c" +#line 2456 "parse.c" break; case 140: #line 499 "parse.y" { - yygotominor.yy322 = sqlite3ExprListAppend(0,yymsp[-2].minor.yy418,yymsp[-1].minor.yy430.n>0?&yymsp[-1].minor.yy430:0); - if( yygotominor.yy322 && yygotominor.yy322->a ) yygotominor.yy322->a[0].sortOrder = yymsp[0].minor.yy328; + yygotominor.yy82 = sqlite3ExprListAppend(0,yymsp[-2].minor.yy2,yymsp[-1].minor.yy258.n>0?&yymsp[-1].minor.yy258:0); + if( yygotominor.yy82 && yygotominor.yy82->a ) yygotominor.yy82->a[0].sortOrder = yymsp[0].minor.yy412; } -#line 2489 "parse.c" +#line 2464 "parse.c" break; case 142: case 144: #line 508 "parse.y" -{yygotominor.yy328 = SQLITE_SO_ASC;} -#line 2495 "parse.c" +{yygotominor.yy412 = SQLITE_SO_ASC;} +#line 2470 "parse.c" break; case 143: #line 509 "parse.y" -{yygotominor.yy328 = SQLITE_SO_DESC;} -#line 2500 "parse.c" +{yygotominor.yy412 = SQLITE_SO_DESC;} +#line 2475 "parse.c" break; case 145: #line 511 "parse.y" -{yygotominor.yy430.z = 0; yygotominor.yy430.n = 0;} -#line 2505 "parse.c" +{yygotominor.yy258.z = 0; yygotominor.yy258.n = 0;} +#line 2480 "parse.c" break; case 151: #line 529 "parse.y" -{yygotominor.yy388.pLimit = 0; yygotominor.yy388.pOffset = 0;} -#line 2510 "parse.c" +{yygotominor.yy244.pLimit = 0; yygotominor.yy244.pOffset = 0;} +#line 2485 "parse.c" break; case 152: #line 530 "parse.y" -{yygotominor.yy388.pLimit = yymsp[0].minor.yy418; yygotominor.yy388.pOffset = 0;} -#line 2515 "parse.c" +{yygotominor.yy244.pLimit = yymsp[0].minor.yy2; yygotominor.yy244.pOffset = 0;} +#line 2490 "parse.c" break; case 153: #line 532 "parse.y" -{yygotominor.yy388.pLimit = yymsp[-2].minor.yy418; yygotominor.yy388.pOffset = yymsp[0].minor.yy418;} -#line 2520 "parse.c" +{yygotominor.yy244.pLimit = yymsp[-2].minor.yy2; yygotominor.yy244.pOffset = yymsp[0].minor.yy2;} +#line 2495 "parse.c" break; case 154: #line 534 "parse.y" -{yygotominor.yy388.pOffset = yymsp[-2].minor.yy418; yygotominor.yy388.pLimit = yymsp[0].minor.yy418;} -#line 2525 "parse.c" +{yygotominor.yy244.pOffset = yymsp[-2].minor.yy2; yygotominor.yy244.pLimit = yymsp[0].minor.yy2;} +#line 2500 "parse.c" break; case 155: #line 538 "parse.y" -{sqlite3DeleteFrom(pParse,yymsp[-1].minor.yy439,yymsp[0].minor.yy418);} -#line 2530 "parse.c" +{sqlite3DeleteFrom(pParse,yymsp[-1].minor.yy67,yymsp[0].minor.yy2);} +#line 2505 "parse.c" break; case 158: -#line 552 "parse.y" -{sqlite3Update(pParse,yymsp[-3].minor.yy439,yymsp[-1].minor.yy322,yymsp[0].minor.yy418,yymsp[-4].minor.yy328);} -#line 2535 "parse.c" +#line 549 "parse.y" +{sqlite3Update(pParse,yymsp[-3].minor.yy67,yymsp[-1].minor.yy82,yymsp[0].minor.yy2,yymsp[-4].minor.yy412);} +#line 2510 "parse.c" break; case 159: #line 555 "parse.y" -{yygotominor.yy322 = sqlite3ExprListAppend(yymsp[-4].minor.yy322,yymsp[0].minor.yy418,&yymsp[-2].minor.yy430);} -#line 2540 "parse.c" +{yygotominor.yy82 = sqlite3ExprListAppend(yymsp[-4].minor.yy82,yymsp[0].minor.yy2,&yymsp[-2].minor.yy258);} +#line 2515 "parse.c" break; case 160: #line 556 "parse.y" -{yygotominor.yy322 = sqlite3ExprListAppend(0,yymsp[0].minor.yy418,&yymsp[-2].minor.yy430);} -#line 2545 "parse.c" +{yygotominor.yy82 = sqlite3ExprListAppend(0,yymsp[0].minor.yy2,&yymsp[-2].minor.yy258);} +#line 2520 "parse.c" break; case 161: #line 562 "parse.y" -{sqlite3Insert(pParse, yymsp[-5].minor.yy439, yymsp[-1].minor.yy322, 0, yymsp[-4].minor.yy232, yymsp[-7].minor.yy328);} -#line 2550 "parse.c" +{sqlite3Insert(pParse, yymsp[-5].minor.yy67, yymsp[-1].minor.yy82, 0, yymsp[-4].minor.yy240, yymsp[-7].minor.yy412);} +#line 2525 "parse.c" break; case 162: #line 564 "parse.y" -{sqlite3Insert(pParse, yymsp[-2].minor.yy439, 0, yymsp[0].minor.yy91, yymsp[-1].minor.yy232, yymsp[-4].minor.yy328);} -#line 2555 "parse.c" +{sqlite3Insert(pParse, yymsp[-2].minor.yy67, 0, yymsp[0].minor.yy459, yymsp[-1].minor.yy240, yymsp[-4].minor.yy412);} +#line 2530 "parse.c" break; case 165: - case 240: + case 236: #line 574 "parse.y" -{yygotominor.yy322 = sqlite3ExprListAppend(yymsp[-2].minor.yy322,yymsp[0].minor.yy418,0);} -#line 2561 "parse.c" +{yygotominor.yy82 = sqlite3ExprListAppend(yymsp[-2].minor.yy82,yymsp[0].minor.yy2,0);} +#line 2536 "parse.c" break; case 166: - case 241: + case 237: #line 575 "parse.y" -{yygotominor.yy322 = sqlite3ExprListAppend(0,yymsp[0].minor.yy418,0);} -#line 2567 "parse.c" +{yygotominor.yy82 = sqlite3ExprListAppend(0,yymsp[0].minor.yy2,0);} +#line 2542 "parse.c" break; case 169: #line 584 "parse.y" -{yygotominor.yy232 = sqlite3IdListAppend(yymsp[-2].minor.yy232,&yymsp[0].minor.yy430);} -#line 2572 "parse.c" +{yygotominor.yy240 = sqlite3IdListAppend(yymsp[-2].minor.yy240,&yymsp[0].minor.yy258);} +#line 2547 "parse.c" break; case 170: #line 585 "parse.y" -{yygotominor.yy232 = sqlite3IdListAppend(0,&yymsp[0].minor.yy430);} -#line 2577 "parse.c" +{yygotominor.yy240 = sqlite3IdListAppend(0,&yymsp[0].minor.yy258);} +#line 2552 "parse.c" break; case 172: #line 596 "parse.y" -{yygotominor.yy418 = yymsp[-1].minor.yy418; sqlite3ExprSpan(yygotominor.yy418,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); } -#line 2582 "parse.c" +{yygotominor.yy2 = yymsp[-1].minor.yy2; sqlite3ExprSpan(yygotominor.yy2,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); } +#line 2557 "parse.c" break; case 173: case 178: @@ -2585,72 +2560,77 @@ case 180: case 181: #line 597 "parse.y" -{yygotominor.yy418 = sqlite3Expr(yymsp[0].major, 0, 0, &yymsp[0].minor.yy0);} -#line 2591 "parse.c" +{yygotominor.yy2 = sqlite3Expr(yymsp[0].major, 0, 0, &yymsp[0].minor.yy0);} +#line 2566 "parse.c" break; case 174: case 175: #line 598 "parse.y" -{yygotominor.yy418 = sqlite3Expr(TK_ID, 0, 0, &yymsp[0].minor.yy0);} -#line 2597 "parse.c" +{yygotominor.yy2 = sqlite3Expr(TK_ID, 0, 0, &yymsp[0].minor.yy0);} +#line 2572 "parse.c" break; case 176: #line 600 "parse.y" { - Expr *temp1 = sqlite3Expr(TK_ID, 0, 0, &yymsp[-2].minor.yy430); - Expr *temp2 = sqlite3Expr(TK_ID, 0, 0, &yymsp[0].minor.yy430); - yygotominor.yy418 = sqlite3Expr(TK_DOT, temp1, temp2, 0); + Expr *temp1 = sqlite3Expr(TK_ID, 0, 0, &yymsp[-2].minor.yy258); + Expr *temp2 = sqlite3Expr(TK_ID, 0, 0, &yymsp[0].minor.yy258); + yygotominor.yy2 = sqlite3Expr(TK_DOT, temp1, temp2, 0); } -#line 2606 "parse.c" +#line 2581 "parse.c" break; case 177: #line 605 "parse.y" { - Expr *temp1 = sqlite3Expr(TK_ID, 0, 0, &yymsp[-4].minor.yy430); - Expr *temp2 = sqlite3Expr(TK_ID, 0, 0, &yymsp[-2].minor.yy430); - Expr *temp3 = sqlite3Expr(TK_ID, 0, 0, &yymsp[0].minor.yy430); + Expr *temp1 = sqlite3Expr(TK_ID, 0, 0, &yymsp[-4].minor.yy258); + Expr *temp2 = sqlite3Expr(TK_ID, 0, 0, &yymsp[-2].minor.yy258); + Expr *temp3 = sqlite3Expr(TK_ID, 0, 0, &yymsp[0].minor.yy258); Expr *temp4 = sqlite3Expr(TK_DOT, temp2, temp3, 0); - yygotominor.yy418 = sqlite3Expr(TK_DOT, temp1, temp4, 0); + yygotominor.yy2 = sqlite3Expr(TK_DOT, temp1, temp4, 0); } -#line 2617 "parse.c" +#line 2592 "parse.c" break; case 182: #line 616 "parse.y" -{yygotominor.yy418 = sqlite3RegisterExpr(pParse, &yymsp[0].minor.yy0);} -#line 2622 "parse.c" +{yygotominor.yy2 = sqlite3RegisterExpr(pParse, &yymsp[0].minor.yy0);} +#line 2597 "parse.c" break; case 183: #line 617 "parse.y" { Token *pToken = &yymsp[0].minor.yy0; - Expr *pExpr = yygotominor.yy418 = sqlite3Expr(TK_VARIABLE, 0, 0, pToken); + Expr *pExpr = yygotominor.yy2 = sqlite3Expr(TK_VARIABLE, 0, 0, pToken); sqlite3ExprAssignVarNumber(pParse, pExpr); } -#line 2631 "parse.c" +#line 2606 "parse.c" break; case 184: #line 622 "parse.y" { - yygotominor.yy418 = sqlite3ExprFunction(yymsp[-1].minor.yy322, &yymsp[-3].minor.yy0); - sqlite3ExprSpan(yygotominor.yy418,&yymsp[-3].minor.yy0,&yymsp[0].minor.yy0); + yygotominor.yy2 = sqlite3ExprFunction(yymsp[-1].minor.yy82, &yymsp[-3].minor.yy0); + sqlite3ExprSpan(yygotominor.yy2,&yymsp[-3].minor.yy0,&yymsp[0].minor.yy0); } -#line 2639 "parse.c" +#line 2614 "parse.c" break; case 185: #line 626 "parse.y" { - yygotominor.yy418 = sqlite3ExprFunction(0, &yymsp[-3].minor.yy0); - sqlite3ExprSpan(yygotominor.yy418,&yymsp[-3].minor.yy0,&yymsp[0].minor.yy0); + yygotominor.yy2 = sqlite3ExprFunction(0, &yymsp[-3].minor.yy0); + sqlite3ExprSpan(yygotominor.yy2,&yymsp[-3].minor.yy0,&yymsp[0].minor.yy0); } -#line 2647 "parse.c" +#line 2622 "parse.c" break; case 186: - case 187: - case 188: #line 630 "parse.y" -{yygotominor.yy418 = sqlite3Expr(yymsp[0].major,0,0,0);} -#line 2654 "parse.c" +{ + /* The CURRENT_TIME, CURRENT_DATE, and CURRENT_TIMESTAMP values are + ** treated as functions that return constants */ + yygotominor.yy2 = sqlite3ExprFunction(0,&yymsp[0].minor.yy0); + if( yygotominor.yy2 ) yygotominor.yy2->op = TK_CONST_FUNC; +} +#line 2632 "parse.c" break; + case 187: + case 188: case 189: case 190: case 191: @@ -2667,489 +2647,476 @@ case 202: case 203: case 204: - case 205: - case 206: -#line 633 "parse.y" -{yygotominor.yy418 = sqlite3Expr(yymsp[-1].major, yymsp[-2].minor.yy418, yymsp[0].minor.yy418, 0);} -#line 2676 "parse.c" +#line 636 "parse.y" +{yygotominor.yy2 = sqlite3Expr(yymsp[-1].major, yymsp[-2].minor.yy2, yymsp[0].minor.yy2, 0);} +#line 2654 "parse.c" break; - case 207: -#line 652 "parse.y" -{yygotominor.yy30.opcode = TK_LIKE; yygotominor.yy30.not = 0;} -#line 2681 "parse.c" + case 205: +#line 655 "parse.y" +{yygotominor.yy438.operator = yymsp[0].minor.yy0; yygotominor.yy438.not = 0;} +#line 2659 "parse.c" break; - case 208: -#line 653 "parse.y" -{yygotominor.yy30.opcode = TK_GLOB; yygotominor.yy30.not = 0;} -#line 2686 "parse.c" + case 206: +#line 656 "parse.y" +{yygotominor.yy438.operator = yymsp[0].minor.yy0; yygotominor.yy438.not = 1;} +#line 2664 "parse.c" break; case 209: -#line 654 "parse.y" -{yygotominor.yy30.opcode = TK_LIKE; yygotominor.yy30.not = 1;} -#line 2691 "parse.c" - break; - case 210: -#line 655 "parse.y" -{yygotominor.yy30.opcode = TK_GLOB; yygotominor.yy30.not = 1;} -#line 2696 "parse.c" - break; - case 213: -#line 659 "parse.y" +#line 660 "parse.y" { - ExprList *pList = sqlite3ExprListAppend(0, yymsp[-1].minor.yy418, 0); - pList = sqlite3ExprListAppend(pList, yymsp[-3].minor.yy418, 0); - if( yymsp[0].minor.yy418 ){ - pList = sqlite3ExprListAppend(pList, yymsp[0].minor.yy418, 0); + ExprList *pList = sqlite3ExprListAppend(0, yymsp[-1].minor.yy2, 0); + pList = sqlite3ExprListAppend(pList, yymsp[-3].minor.yy2, 0); + if( yymsp[0].minor.yy2 ){ + pList = sqlite3ExprListAppend(pList, yymsp[0].minor.yy2, 0); } - yygotominor.yy418 = sqlite3ExprFunction(pList, 0); - if( yygotominor.yy418 ) yygotominor.yy418->op = yymsp[-2].minor.yy30.opcode; - if( yymsp[-2].minor.yy30.not ) yygotominor.yy418 = sqlite3Expr(TK_NOT, yygotominor.yy418, 0, 0); - sqlite3ExprSpan(yygotominor.yy418, &yymsp[-3].minor.yy418->span, &yymsp[-1].minor.yy418->span); + yygotominor.yy2 = sqlite3ExprFunction(pList, &yymsp[-2].minor.yy438.operator); + if( yymsp[-2].minor.yy438.not ) yygotominor.yy2 = sqlite3Expr(TK_NOT, yygotominor.yy2, 0, 0); + sqlite3ExprSpan(yygotominor.yy2, &yymsp[-3].minor.yy2->span, &yymsp[-1].minor.yy2->span); } -#line 2711 "parse.c" +#line 2678 "parse.c" break; - case 214: + case 210: #line 671 "parse.y" { - yygotominor.yy418 = sqlite3Expr(TK_ISNULL, yymsp[-1].minor.yy418, 0, 0); - sqlite3ExprSpan(yygotominor.yy418,&yymsp[-1].minor.yy418->span,&yymsp[0].minor.yy0); + yygotominor.yy2 = sqlite3Expr(TK_ISNULL, yymsp[-1].minor.yy2, 0, 0); + sqlite3ExprSpan(yygotominor.yy2,&yymsp[-1].minor.yy2->span,&yymsp[0].minor.yy0); } -#line 2719 "parse.c" +#line 2686 "parse.c" break; - case 215: + case 211: #line 675 "parse.y" { - yygotominor.yy418 = sqlite3Expr(TK_ISNULL, yymsp[-2].minor.yy418, 0, 0); - sqlite3ExprSpan(yygotominor.yy418,&yymsp[-2].minor.yy418->span,&yymsp[0].minor.yy0); + yygotominor.yy2 = sqlite3Expr(TK_ISNULL, yymsp[-2].minor.yy2, 0, 0); + sqlite3ExprSpan(yygotominor.yy2,&yymsp[-2].minor.yy2->span,&yymsp[0].minor.yy0); } -#line 2727 "parse.c" +#line 2694 "parse.c" break; - case 216: + case 212: #line 679 "parse.y" { - yygotominor.yy418 = sqlite3Expr(TK_NOTNULL, yymsp[-1].minor.yy418, 0, 0); - sqlite3ExprSpan(yygotominor.yy418,&yymsp[-1].minor.yy418->span,&yymsp[0].minor.yy0); + yygotominor.yy2 = sqlite3Expr(TK_NOTNULL, yymsp[-1].minor.yy2, 0, 0); + sqlite3ExprSpan(yygotominor.yy2,&yymsp[-1].minor.yy2->span,&yymsp[0].minor.yy0); } -#line 2735 "parse.c" +#line 2702 "parse.c" break; - case 217: + case 213: #line 683 "parse.y" { - yygotominor.yy418 = sqlite3Expr(TK_NOTNULL, yymsp[-2].minor.yy418, 0, 0); - sqlite3ExprSpan(yygotominor.yy418,&yymsp[-2].minor.yy418->span,&yymsp[0].minor.yy0); + yygotominor.yy2 = sqlite3Expr(TK_NOTNULL, yymsp[-2].minor.yy2, 0, 0); + sqlite3ExprSpan(yygotominor.yy2,&yymsp[-2].minor.yy2->span,&yymsp[0].minor.yy0); } -#line 2743 "parse.c" +#line 2710 "parse.c" break; - case 218: + case 214: #line 687 "parse.y" { - yygotominor.yy418 = sqlite3Expr(TK_NOTNULL, yymsp[-3].minor.yy418, 0, 0); - sqlite3ExprSpan(yygotominor.yy418,&yymsp[-3].minor.yy418->span,&yymsp[0].minor.yy0); + yygotominor.yy2 = sqlite3Expr(TK_NOTNULL, yymsp[-3].minor.yy2, 0, 0); + sqlite3ExprSpan(yygotominor.yy2,&yymsp[-3].minor.yy2->span,&yymsp[0].minor.yy0); } -#line 2751 "parse.c" +#line 2718 "parse.c" break; - case 219: - case 220: + case 215: + case 216: #line 691 "parse.y" { - yygotominor.yy418 = sqlite3Expr(yymsp[-1].major, yymsp[0].minor.yy418, 0, 0); - sqlite3ExprSpan(yygotominor.yy418,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy418->span); + yygotominor.yy2 = sqlite3Expr(yymsp[-1].major, yymsp[0].minor.yy2, 0, 0); + sqlite3ExprSpan(yygotominor.yy2,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy2->span); } -#line 2760 "parse.c" +#line 2727 "parse.c" break; - case 221: + case 217: #line 699 "parse.y" { - yygotominor.yy418 = sqlite3Expr(TK_UMINUS, yymsp[0].minor.yy418, 0, 0); - sqlite3ExprSpan(yygotominor.yy418,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy418->span); + yygotominor.yy2 = sqlite3Expr(TK_UMINUS, yymsp[0].minor.yy2, 0, 0); + sqlite3ExprSpan(yygotominor.yy2,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy2->span); } -#line 2768 "parse.c" +#line 2735 "parse.c" break; - case 222: + case 218: #line 703 "parse.y" { - yygotominor.yy418 = sqlite3Expr(TK_UPLUS, yymsp[0].minor.yy418, 0, 0); - sqlite3ExprSpan(yygotominor.yy418,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy418->span); + yygotominor.yy2 = sqlite3Expr(TK_UPLUS, yymsp[0].minor.yy2, 0, 0); + sqlite3ExprSpan(yygotominor.yy2,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy2->span); } -#line 2776 "parse.c" +#line 2743 "parse.c" break; - case 225: + case 221: #line 710 "parse.y" { - ExprList *pList = sqlite3ExprListAppend(0, yymsp[-2].minor.yy418, 0); - pList = sqlite3ExprListAppend(pList, yymsp[0].minor.yy418, 0); - yygotominor.yy418 = sqlite3Expr(TK_BETWEEN, yymsp[-4].minor.yy418, 0, 0); - if( yygotominor.yy418 ) yygotominor.yy418->pList = pList; - if( yymsp[-3].minor.yy328 ) yygotominor.yy418 = sqlite3Expr(TK_NOT, yygotominor.yy418, 0, 0); - sqlite3ExprSpan(yygotominor.yy418,&yymsp[-4].minor.yy418->span,&yymsp[0].minor.yy418->span); + ExprList *pList = sqlite3ExprListAppend(0, yymsp[-2].minor.yy2, 0); + pList = sqlite3ExprListAppend(pList, yymsp[0].minor.yy2, 0); + yygotominor.yy2 = sqlite3Expr(TK_BETWEEN, yymsp[-4].minor.yy2, 0, 0); + if( yygotominor.yy2 ) yygotominor.yy2->pList = pList; + if( yymsp[-3].minor.yy412 ) yygotominor.yy2 = sqlite3Expr(TK_NOT, yygotominor.yy2, 0, 0); + sqlite3ExprSpan(yygotominor.yy2,&yymsp[-4].minor.yy2->span,&yymsp[0].minor.yy2->span); } -#line 2788 "parse.c" +#line 2755 "parse.c" break; - case 228: + case 224: #line 722 "parse.y" { - yygotominor.yy418 = sqlite3Expr(TK_IN, yymsp[-4].minor.yy418, 0, 0); - if( yygotominor.yy418 ){ - yygotominor.yy418->pList = yymsp[-1].minor.yy322; + yygotominor.yy2 = sqlite3Expr(TK_IN, yymsp[-4].minor.yy2, 0, 0); + if( yygotominor.yy2 ){ + yygotominor.yy2->pList = yymsp[-1].minor.yy82; }else{ - sqlite3ExprListDelete(yymsp[-1].minor.yy322); + sqlite3ExprListDelete(yymsp[-1].minor.yy82); } - if( yymsp[-3].minor.yy328 ) yygotominor.yy418 = sqlite3Expr(TK_NOT, yygotominor.yy418, 0, 0); - sqlite3ExprSpan(yygotominor.yy418,&yymsp[-4].minor.yy418->span,&yymsp[0].minor.yy0); + if( yymsp[-3].minor.yy412 ) yygotominor.yy2 = sqlite3Expr(TK_NOT, yygotominor.yy2, 0, 0); + sqlite3ExprSpan(yygotominor.yy2,&yymsp[-4].minor.yy2->span,&yymsp[0].minor.yy0); } -#line 2802 "parse.c" +#line 2769 "parse.c" break; - case 229: + case 225: #line 732 "parse.y" { - yygotominor.yy418 = sqlite3Expr(TK_SELECT, 0, 0, 0); - if( yygotominor.yy418 ) yygotominor.yy418->pSelect = yymsp[-1].minor.yy91; - if( !yygotominor.yy418 ) sqlite3SelectDelete(yymsp[-1].minor.yy91); - sqlite3ExprSpan(yygotominor.yy418,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); + yygotominor.yy2 = sqlite3Expr(TK_SELECT, 0, 0, 0); + if( yygotominor.yy2 ) yygotominor.yy2->pSelect = yymsp[-1].minor.yy459; + if( !yygotominor.yy2 ) sqlite3SelectDelete(yymsp[-1].minor.yy459); + sqlite3ExprSpan(yygotominor.yy2,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); } -#line 2812 "parse.c" +#line 2779 "parse.c" break; - case 230: + case 226: #line 738 "parse.y" { - yygotominor.yy418 = sqlite3Expr(TK_IN, yymsp[-4].minor.yy418, 0, 0); - if( yygotominor.yy418 ) yygotominor.yy418->pSelect = yymsp[-1].minor.yy91; - if( !yygotominor.yy418 ) sqlite3SelectDelete(yymsp[-1].minor.yy91); - if( yymsp[-3].minor.yy328 ) yygotominor.yy418 = sqlite3Expr(TK_NOT, yygotominor.yy418, 0, 0); - sqlite3ExprSpan(yygotominor.yy418,&yymsp[-4].minor.yy418->span,&yymsp[0].minor.yy0); + yygotominor.yy2 = sqlite3Expr(TK_IN, yymsp[-4].minor.yy2, 0, 0); + if( yygotominor.yy2 ) yygotominor.yy2->pSelect = yymsp[-1].minor.yy459; + if( !yygotominor.yy2 ) sqlite3SelectDelete(yymsp[-1].minor.yy459); + if( yymsp[-3].minor.yy412 ) yygotominor.yy2 = sqlite3Expr(TK_NOT, yygotominor.yy2, 0, 0); + sqlite3ExprSpan(yygotominor.yy2,&yymsp[-4].minor.yy2->span,&yymsp[0].minor.yy0); } -#line 2823 "parse.c" +#line 2790 "parse.c" break; - case 231: + case 227: #line 745 "parse.y" { - SrcList *pSrc = sqlite3SrcListAppend(0,&yymsp[-1].minor.yy430,&yymsp[0].minor.yy430); - yygotominor.yy418 = sqlite3Expr(TK_IN, yymsp[-3].minor.yy418, 0, 0); - if( yygotominor.yy418 ) yygotominor.yy418->pSelect = sqlite3SelectNew(0,pSrc,0,0,0,0,0,0,0); - if( yymsp[-2].minor.yy328 ) yygotominor.yy418 = sqlite3Expr(TK_NOT, yygotominor.yy418, 0, 0); - sqlite3ExprSpan(yygotominor.yy418,&yymsp[-3].minor.yy418->span,yymsp[0].minor.yy430.z?&yymsp[0].minor.yy430:&yymsp[-1].minor.yy430); + SrcList *pSrc = sqlite3SrcListAppend(0,&yymsp[-1].minor.yy258,&yymsp[0].minor.yy258); + yygotominor.yy2 = sqlite3Expr(TK_IN, yymsp[-3].minor.yy2, 0, 0); + if( yygotominor.yy2 ) yygotominor.yy2->pSelect = sqlite3SelectNew(0,pSrc,0,0,0,0,0,0,0); + if( yymsp[-2].minor.yy412 ) yygotominor.yy2 = sqlite3Expr(TK_NOT, yygotominor.yy2, 0, 0); + sqlite3ExprSpan(yygotominor.yy2,&yymsp[-3].minor.yy2->span,yymsp[0].minor.yy258.z?&yymsp[0].minor.yy258:&yymsp[-1].minor.yy258); } -#line 2834 "parse.c" +#line 2801 "parse.c" break; - case 232: + case 228: #line 752 "parse.y" { - Expr *p = yygotominor.yy418 = sqlite3Expr(TK_EXISTS, 0, 0, 0); + Expr *p = yygotominor.yy2 = sqlite3Expr(TK_EXISTS, 0, 0, 0); if( p ){ - p->pSelect = yymsp[-1].minor.yy91; + p->pSelect = yymsp[-1].minor.yy459; sqlite3ExprSpan(p,&yymsp[-3].minor.yy0,&yymsp[0].minor.yy0); } - if( !p ) sqlite3SelectDelete(yymsp[-1].minor.yy91); + if( !p ) sqlite3SelectDelete(yymsp[-1].minor.yy459); } -#line 2846 "parse.c" +#line 2813 "parse.c" break; - case 233: + case 229: #line 763 "parse.y" { - yygotominor.yy418 = sqlite3Expr(TK_CASE, yymsp[-3].minor.yy418, yymsp[-1].minor.yy418, 0); - if( yygotominor.yy418 ) yygotominor.yy418->pList = yymsp[-2].minor.yy322; - sqlite3ExprSpan(yygotominor.yy418, &yymsp[-4].minor.yy0, &yymsp[0].minor.yy0); + yygotominor.yy2 = sqlite3Expr(TK_CASE, yymsp[-3].minor.yy2, yymsp[-1].minor.yy2, 0); + if( yygotominor.yy2 ) yygotominor.yy2->pList = yymsp[-2].minor.yy82; + sqlite3ExprSpan(yygotominor.yy2, &yymsp[-4].minor.yy0, &yymsp[0].minor.yy0); } -#line 2855 "parse.c" +#line 2822 "parse.c" break; - case 234: + case 230: #line 770 "parse.y" { - yygotominor.yy322 = sqlite3ExprListAppend(yymsp[-4].minor.yy322, yymsp[-2].minor.yy418, 0); - yygotominor.yy322 = sqlite3ExprListAppend(yygotominor.yy322, yymsp[0].minor.yy418, 0); + yygotominor.yy82 = sqlite3ExprListAppend(yymsp[-4].minor.yy82, yymsp[-2].minor.yy2, 0); + yygotominor.yy82 = sqlite3ExprListAppend(yygotominor.yy82, yymsp[0].minor.yy2, 0); } -#line 2863 "parse.c" +#line 2830 "parse.c" break; - case 235: + case 231: #line 774 "parse.y" { - yygotominor.yy322 = sqlite3ExprListAppend(0, yymsp[-2].minor.yy418, 0); - yygotominor.yy322 = sqlite3ExprListAppend(yygotominor.yy322, yymsp[0].minor.yy418, 0); + yygotominor.yy82 = sqlite3ExprListAppend(0, yymsp[-2].minor.yy2, 0); + yygotominor.yy82 = sqlite3ExprListAppend(yygotominor.yy82, yymsp[0].minor.yy2, 0); } -#line 2871 "parse.c" +#line 2838 "parse.c" break; - case 244: + case 240: #line 799 "parse.y" { - if( yymsp[-9].minor.yy328!=OE_None ) yymsp[-9].minor.yy328 = yymsp[0].minor.yy328; - if( yymsp[-9].minor.yy328==OE_Default) yymsp[-9].minor.yy328 = OE_Abort; - sqlite3CreateIndex(pParse, &yymsp[-7].minor.yy430, &yymsp[-6].minor.yy430, sqlite3SrcListAppend(0,&yymsp[-4].minor.yy430,0),yymsp[-2].minor.yy322,yymsp[-9].minor.yy328, &yymsp[-10].minor.yy0, &yymsp[-1].minor.yy0); + if( yymsp[-9].minor.yy412!=OE_None ) yymsp[-9].minor.yy412 = yymsp[0].minor.yy412; + if( yymsp[-9].minor.yy412==OE_Default) yymsp[-9].minor.yy412 = OE_Abort; + sqlite3CreateIndex(pParse, &yymsp[-7].minor.yy258, &yymsp[-6].minor.yy258, sqlite3SrcListAppend(0,&yymsp[-4].minor.yy258,0),yymsp[-2].minor.yy82,yymsp[-9].minor.yy412, &yymsp[-10].minor.yy0, &yymsp[-1].minor.yy0); } -#line 2880 "parse.c" +#line 2847 "parse.c" break; - case 245: - case 292: + case 241: + case 288: #line 806 "parse.y" -{yygotominor.yy328 = OE_Abort;} -#line 2886 "parse.c" +{yygotominor.yy412 = OE_Abort;} +#line 2853 "parse.c" break; - case 246: + case 242: #line 807 "parse.y" -{yygotominor.yy328 = OE_None;} -#line 2891 "parse.c" +{yygotominor.yy412 = OE_None;} +#line 2858 "parse.c" break; - case 249: + case 245: #line 817 "parse.y" { Expr *p = 0; - if( yymsp[-1].minor.yy430.n>0 ){ + if( yymsp[-1].minor.yy258.n>0 ){ p = sqlite3Expr(TK_COLUMN, 0, 0, 0); - if( p ) p->pColl = sqlite3LocateCollSeq(pParse, yymsp[-1].minor.yy430.z, yymsp[-1].minor.yy430.n); + if( p ) p->pColl = sqlite3LocateCollSeq(pParse, yymsp[-1].minor.yy258.z, yymsp[-1].minor.yy258.n); } - yygotominor.yy322 = sqlite3ExprListAppend(yymsp[-4].minor.yy322, p, &yymsp[-2].minor.yy430); + yygotominor.yy82 = sqlite3ExprListAppend(yymsp[-4].minor.yy82, p, &yymsp[-2].minor.yy258); } -#line 2903 "parse.c" +#line 2870 "parse.c" break; - case 250: + case 246: #line 825 "parse.y" { Expr *p = 0; - if( yymsp[-1].minor.yy430.n>0 ){ + if( yymsp[-1].minor.yy258.n>0 ){ p = sqlite3Expr(TK_COLUMN, 0, 0, 0); - if( p ) p->pColl = sqlite3LocateCollSeq(pParse, yymsp[-1].minor.yy430.z, yymsp[-1].minor.yy430.n); + if( p ) p->pColl = sqlite3LocateCollSeq(pParse, yymsp[-1].minor.yy258.z, yymsp[-1].minor.yy258.n); } - yygotominor.yy322 = sqlite3ExprListAppend(0, p, &yymsp[-2].minor.yy430); + yygotominor.yy82 = sqlite3ExprListAppend(0, p, &yymsp[-2].minor.yy258); } -#line 2915 "parse.c" +#line 2882 "parse.c" break; - case 252: + case 248: #line 838 "parse.y" -{sqlite3DropIndex(pParse, yymsp[0].minor.yy439);} -#line 2920 "parse.c" +{sqlite3DropIndex(pParse, yymsp[0].minor.yy67);} +#line 2887 "parse.c" break; - case 253: - case 254: + case 249: + case 250: #line 842 "parse.y" {sqlite3Vacuum(pParse,0);} -#line 2926 "parse.c" +#line 2893 "parse.c" break; - case 255: - case 257: + case 251: + case 253: #line 848 "parse.y" -{sqlite3Pragma(pParse,&yymsp[-3].minor.yy430,&yymsp[-2].minor.yy430,&yymsp[0].minor.yy430,0);} -#line 2932 "parse.c" +{sqlite3Pragma(pParse,&yymsp[-3].minor.yy258,&yymsp[-2].minor.yy258,&yymsp[0].minor.yy258,0);} +#line 2899 "parse.c" break; - case 256: + case 252: #line 849 "parse.y" -{sqlite3Pragma(pParse,&yymsp[-3].minor.yy430,&yymsp[-2].minor.yy430,&yymsp[0].minor.yy0,0);} -#line 2937 "parse.c" +{sqlite3Pragma(pParse,&yymsp[-3].minor.yy258,&yymsp[-2].minor.yy258,&yymsp[0].minor.yy0,0);} +#line 2904 "parse.c" break; - case 258: + case 254: #line 851 "parse.y" { - sqlite3Pragma(pParse,&yymsp[-3].minor.yy430,&yymsp[-2].minor.yy430,&yymsp[0].minor.yy430,1); + sqlite3Pragma(pParse,&yymsp[-3].minor.yy258,&yymsp[-2].minor.yy258,&yymsp[0].minor.yy258,1); } -#line 2944 "parse.c" +#line 2911 "parse.c" break; - case 259: + case 255: #line 854 "parse.y" -{sqlite3Pragma(pParse,&yymsp[-4].minor.yy430,&yymsp[-3].minor.yy430,&yymsp[-1].minor.yy430,0);} -#line 2949 "parse.c" +{sqlite3Pragma(pParse,&yymsp[-4].minor.yy258,&yymsp[-3].minor.yy258,&yymsp[-1].minor.yy258,0);} +#line 2916 "parse.c" break; - case 260: + case 256: #line 855 "parse.y" -{sqlite3Pragma(pParse,&yymsp[-1].minor.yy430,&yymsp[0].minor.yy430,0,0);} -#line 2954 "parse.c" +{sqlite3Pragma(pParse,&yymsp[-1].minor.yy258,&yymsp[0].minor.yy258,0,0);} +#line 2921 "parse.c" break; - case 267: + case 263: #line 868 "parse.y" { Token all; - all.z = yymsp[-3].minor.yy430.z; - all.n = (yymsp[0].minor.yy0.z - yymsp[-3].minor.yy430.z) + yymsp[0].minor.yy0.n; - sqlite3FinishTrigger(pParse, yymsp[-1].minor.yy451, &all); + all.z = yymsp[-3].minor.yy258.z; + all.n = (yymsp[0].minor.yy0.z - yymsp[-3].minor.yy258.z) + yymsp[0].minor.yy0.n; + sqlite3FinishTrigger(pParse, yymsp[-1].minor.yy347, &all); } -#line 2964 "parse.c" +#line 2931 "parse.c" break; - case 268: + case 264: #line 877 "parse.y" { - sqlite3BeginTrigger(pParse, &yymsp[-7].minor.yy430, &yymsp[-6].minor.yy430, yymsp[-5].minor.yy328, yymsp[-4].minor.yy378.a, yymsp[-4].minor.yy378.b, yymsp[-2].minor.yy439, yymsp[-1].minor.yy328, yymsp[0].minor.yy418, yymsp[-9].minor.yy328); - yygotominor.yy430 = (yymsp[-6].minor.yy430.n==0?yymsp[-7].minor.yy430:yymsp[-6].minor.yy430); + sqlite3BeginTrigger(pParse, &yymsp[-7].minor.yy258, &yymsp[-6].minor.yy258, yymsp[-5].minor.yy412, yymsp[-4].minor.yy210.a, yymsp[-4].minor.yy210.b, yymsp[-2].minor.yy67, yymsp[-1].minor.yy412, yymsp[0].minor.yy2, yymsp[-9].minor.yy412); + yygotominor.yy258 = (yymsp[-6].minor.yy258.n==0?yymsp[-7].minor.yy258:yymsp[-6].minor.yy258); } -#line 2972 "parse.c" +#line 2939 "parse.c" break; - case 269: - case 272: + case 265: + case 268: #line 883 "parse.y" -{ yygotominor.yy328 = TK_BEFORE; } -#line 2978 "parse.c" +{ yygotominor.yy412 = TK_BEFORE; } +#line 2945 "parse.c" break; - case 270: + case 266: #line 884 "parse.y" -{ yygotominor.yy328 = TK_AFTER; } -#line 2983 "parse.c" +{ yygotominor.yy412 = TK_AFTER; } +#line 2950 "parse.c" break; - case 271: + case 267: #line 885 "parse.y" -{ yygotominor.yy328 = TK_INSTEAD;} -#line 2988 "parse.c" +{ yygotominor.yy412 = TK_INSTEAD;} +#line 2955 "parse.c" break; - case 273: - case 274: - case 275: + case 269: + case 270: + case 271: #line 890 "parse.y" -{yygotominor.yy378.a = yymsp[0].major; yygotominor.yy378.b = 0;} -#line 2995 "parse.c" +{yygotominor.yy210.a = yymsp[0].major; yygotominor.yy210.b = 0;} +#line 2962 "parse.c" break; - case 276: + case 272: #line 893 "parse.y" -{yygotominor.yy378.a = TK_UPDATE; yygotominor.yy378.b = yymsp[0].minor.yy232;} -#line 3000 "parse.c" +{yygotominor.yy210.a = TK_UPDATE; yygotominor.yy210.b = yymsp[0].minor.yy240;} +#line 2967 "parse.c" break; - case 277: - case 278: + case 273: + case 274: #line 896 "parse.y" -{ yygotominor.yy328 = TK_ROW; } -#line 3006 "parse.c" +{ yygotominor.yy412 = TK_ROW; } +#line 2973 "parse.c" break; - case 279: + case 275: #line 898 "parse.y" -{ yygotominor.yy328 = TK_STATEMENT; } -#line 3011 "parse.c" +{ yygotominor.yy412 = TK_STATEMENT; } +#line 2978 "parse.c" break; - case 280: + case 276: #line 901 "parse.y" -{ yygotominor.yy418 = 0; } -#line 3016 "parse.c" +{ yygotominor.yy2 = 0; } +#line 2983 "parse.c" break; - case 281: + case 277: #line 902 "parse.y" -{ yygotominor.yy418 = yymsp[0].minor.yy418; } -#line 3021 "parse.c" +{ yygotominor.yy2 = yymsp[0].minor.yy2; } +#line 2988 "parse.c" break; - case 282: + case 278: #line 906 "parse.y" { - yymsp[-2].minor.yy451->pNext = yymsp[0].minor.yy451; - yygotominor.yy451 = yymsp[-2].minor.yy451; + yymsp[-2].minor.yy347->pNext = yymsp[0].minor.yy347; + yygotominor.yy347 = yymsp[-2].minor.yy347; } -#line 3029 "parse.c" +#line 2996 "parse.c" break; - case 283: + case 279: #line 910 "parse.y" -{ yygotominor.yy451 = 0; } -#line 3034 "parse.c" +{ yygotominor.yy347 = 0; } +#line 3001 "parse.c" break; - case 284: + case 280: #line 916 "parse.y" -{ yygotominor.yy451 = sqlite3TriggerUpdateStep(&yymsp[-3].minor.yy430, yymsp[-1].minor.yy322, yymsp[0].minor.yy418, yymsp[-4].minor.yy328); } -#line 3039 "parse.c" +{ yygotominor.yy347 = sqlite3TriggerUpdateStep(&yymsp[-3].minor.yy258, yymsp[-1].minor.yy82, yymsp[0].minor.yy2, yymsp[-4].minor.yy412); } +#line 3006 "parse.c" break; - case 285: + case 281: #line 921 "parse.y" -{yygotominor.yy451 = sqlite3TriggerInsertStep(&yymsp[-5].minor.yy430, yymsp[-4].minor.yy232, yymsp[-1].minor.yy322, 0, yymsp[-7].minor.yy328);} -#line 3044 "parse.c" +{yygotominor.yy347 = sqlite3TriggerInsertStep(&yymsp[-5].minor.yy258, yymsp[-4].minor.yy240, yymsp[-1].minor.yy82, 0, yymsp[-7].minor.yy412);} +#line 3011 "parse.c" break; - case 286: + case 282: #line 924 "parse.y" -{yygotominor.yy451 = sqlite3TriggerInsertStep(&yymsp[-2].minor.yy430, yymsp[-1].minor.yy232, 0, yymsp[0].minor.yy91, yymsp[-4].minor.yy328);} -#line 3049 "parse.c" +{yygotominor.yy347 = sqlite3TriggerInsertStep(&yymsp[-2].minor.yy258, yymsp[-1].minor.yy240, 0, yymsp[0].minor.yy459, yymsp[-4].minor.yy412);} +#line 3016 "parse.c" break; - case 287: + case 283: #line 928 "parse.y" -{yygotominor.yy451 = sqlite3TriggerDeleteStep(&yymsp[-1].minor.yy430, yymsp[0].minor.yy418);} -#line 3054 "parse.c" +{yygotominor.yy347 = sqlite3TriggerDeleteStep(&yymsp[-1].minor.yy258, yymsp[0].minor.yy2);} +#line 3021 "parse.c" break; - case 288: + case 284: #line 931 "parse.y" -{yygotominor.yy451 = sqlite3TriggerSelectStep(yymsp[0].minor.yy91); } -#line 3059 "parse.c" +{yygotominor.yy347 = sqlite3TriggerSelectStep(yymsp[0].minor.yy459); } +#line 3026 "parse.c" break; - case 289: + case 285: #line 934 "parse.y" { - yygotominor.yy418 = sqlite3Expr(TK_RAISE, 0, 0, 0); - yygotominor.yy418->iColumn = OE_Ignore; - sqlite3ExprSpan(yygotominor.yy418, &yymsp[-3].minor.yy0, &yymsp[0].minor.yy0); + yygotominor.yy2 = sqlite3Expr(TK_RAISE, 0, 0, 0); + yygotominor.yy2->iColumn = OE_Ignore; + sqlite3ExprSpan(yygotominor.yy2, &yymsp[-3].minor.yy0, &yymsp[0].minor.yy0); } -#line 3068 "parse.c" +#line 3035 "parse.c" break; - case 290: + case 286: #line 939 "parse.y" { - yygotominor.yy418 = sqlite3Expr(TK_RAISE, 0, 0, &yymsp[-1].minor.yy430); - yygotominor.yy418->iColumn = yymsp[-3].minor.yy328; - sqlite3ExprSpan(yygotominor.yy418, &yymsp[-5].minor.yy0, &yymsp[0].minor.yy0); + yygotominor.yy2 = sqlite3Expr(TK_RAISE, 0, 0, &yymsp[-1].minor.yy258); + yygotominor.yy2->iColumn = yymsp[-3].minor.yy412; + sqlite3ExprSpan(yygotominor.yy2, &yymsp[-5].minor.yy0, &yymsp[0].minor.yy0); } -#line 3077 "parse.c" +#line 3044 "parse.c" break; - case 291: + case 287: #line 947 "parse.y" -{yygotominor.yy328 = OE_Rollback;} -#line 3082 "parse.c" +{yygotominor.yy412 = OE_Rollback;} +#line 3049 "parse.c" break; - case 293: + case 289: #line 949 "parse.y" -{yygotominor.yy328 = OE_Fail;} -#line 3087 "parse.c" +{yygotominor.yy412 = OE_Fail;} +#line 3054 "parse.c" break; - case 294: + case 290: #line 954 "parse.y" { - sqlite3DropTrigger(pParse,yymsp[0].minor.yy439); + sqlite3DropTrigger(pParse,yymsp[0].minor.yy67); } -#line 3094 "parse.c" +#line 3061 "parse.c" break; - case 295: + case 291: #line 960 "parse.y" { - sqlite3Attach(pParse, &yymsp[-3].minor.yy430, &yymsp[-1].minor.yy430, yymsp[0].minor.yy92.type, &yymsp[0].minor.yy92.key); + sqlite3Attach(pParse, &yymsp[-3].minor.yy258, &yymsp[-1].minor.yy258, yymsp[0].minor.yy132.type, &yymsp[0].minor.yy132.key); } -#line 3101 "parse.c" +#line 3068 "parse.c" break; - case 296: + case 292: #line 964 "parse.y" -{ yygotominor.yy92.type = 0; } -#line 3106 "parse.c" +{ yygotominor.yy132.type = 0; } +#line 3073 "parse.c" break; - case 297: + case 293: #line 965 "parse.y" -{ yygotominor.yy92.type=1; yygotominor.yy92.key = yymsp[0].minor.yy430; } -#line 3111 "parse.c" +{ yygotominor.yy132.type=1; yygotominor.yy132.key = yymsp[0].minor.yy258; } +#line 3078 "parse.c" break; - case 298: + case 294: #line 966 "parse.y" -{ yygotominor.yy92.type=2; yygotominor.yy92.key = yymsp[0].minor.yy0; } -#line 3116 "parse.c" +{ yygotominor.yy132.type=2; yygotominor.yy132.key = yymsp[0].minor.yy0; } +#line 3083 "parse.c" break; - case 301: + case 297: #line 972 "parse.y" { - sqlite3Detach(pParse, &yymsp[0].minor.yy430); + sqlite3Detach(pParse, &yymsp[0].minor.yy258); } -#line 3123 "parse.c" +#line 3090 "parse.c" break; - case 302: + case 298: #line 978 "parse.y" {sqlite3Reindex(pParse, 0, 0);} -#line 3128 "parse.c" +#line 3095 "parse.c" break; - case 303: + case 299: #line 979 "parse.y" -{sqlite3Reindex(pParse, &yymsp[-1].minor.yy430, &yymsp[0].minor.yy430);} -#line 3133 "parse.c" +{sqlite3Reindex(pParse, &yymsp[-1].minor.yy258, &yymsp[0].minor.yy258);} +#line 3100 "parse.c" break; - case 304: + case 300: #line 984 "parse.y" { - sqlite3AlterRenameTable(pParse,yymsp[-3].minor.yy439,&yymsp[0].minor.yy430); + sqlite3AlterRenameTable(pParse,yymsp[-3].minor.yy67,&yymsp[0].minor.yy258); } -#line 3140 "parse.c" +#line 3107 "parse.c" break; - case 305: + case 301: #line 987 "parse.y" { - sqlite3AlterFinishAddColumn(pParse, &yymsp[0].minor.yy430); + sqlite3AlterFinishAddColumn(pParse, &yymsp[0].minor.yy258); } -#line 3147 "parse.c" +#line 3114 "parse.c" break; - case 306: + case 302: #line 990 "parse.y" { - sqlite3AlterBeginAddColumn(pParse, yymsp[0].minor.yy439); + sqlite3AlterBeginAddColumn(pParse, yymsp[0].minor.yy67); } -#line 3154 "parse.c" +#line 3121 "parse.c" break; }; yygoto = yyRuleInfo[yyruleno].lhs; @@ -3215,7 +3182,7 @@ sqlite3ErrorMsg(pParse, "incomplete SQL statement"); } } -#line 3221 "parse.c" +#line 3188 "parse.c" sqlite3ParserARG_STORE; /* Suppress warning about unused %extra_argument variable */ } @@ -3271,7 +3238,7 @@ /* (re)initialize the parser, if necessary */ yypParser = (yyParser*)yyp; if( yypParser->yyidx<0 ){ - if( yymajor==0 ) return; + /* if( yymajor==0 ) return; // not sure why this was here... */ yypParser->yyidx = 0; yypParser->yyerrcnt = -1; yypParser->yystack[0].stateno = 0; --- sqlite/parse.h +++ sqlite/parse.h @@ -6,42 +6,42 @@ #define TK_FUNCTION 6 #define TK_COLUMN 7 #define TK_AGG_FUNCTION 8 -#define TK_SEMI 9 -#define TK_EXPLAIN 10 -#define TK_BEGIN 11 -#define TK_TRANSACTION 12 -#define TK_DEFERRED 13 -#define TK_IMMEDIATE 14 -#define TK_EXCLUSIVE 15 -#define TK_COMMIT 16 -#define TK_END 17 -#define TK_ROLLBACK 18 -#define TK_CREATE 19 -#define TK_TABLE 20 -#define TK_TEMP 21 -#define TK_LP 22 -#define TK_RP 23 -#define TK_AS 24 -#define TK_COMMA 25 -#define TK_ID 26 -#define TK_ABORT 27 -#define TK_AFTER 28 -#define TK_ASC 29 -#define TK_ATTACH 30 -#define TK_BEFORE 31 -#define TK_CASCADE 32 -#define TK_CONFLICT 33 -#define TK_DATABASE 34 -#define TK_DESC 35 -#define TK_DETACH 36 -#define TK_EACH 37 -#define TK_FAIL 38 -#define TK_FOR 39 -#define TK_GLOB 40 +#define TK_CONST_FUNC 9 +#define TK_SEMI 10 +#define TK_EXPLAIN 11 +#define TK_BEGIN 12 +#define TK_TRANSACTION 13 +#define TK_DEFERRED 14 +#define TK_IMMEDIATE 15 +#define TK_EXCLUSIVE 16 +#define TK_COMMIT 17 +#define TK_END 18 +#define TK_ROLLBACK 19 +#define TK_CREATE 20 +#define TK_TABLE 21 +#define TK_TEMP 22 +#define TK_LP 23 +#define TK_RP 24 +#define TK_AS 25 +#define TK_COMMA 26 +#define TK_ID 27 +#define TK_ABORT 28 +#define TK_AFTER 29 +#define TK_ASC 30 +#define TK_ATTACH 31 +#define TK_BEFORE 32 +#define TK_CASCADE 33 +#define TK_CONFLICT 34 +#define TK_DATABASE 35 +#define TK_DESC 36 +#define TK_DETACH 37 +#define TK_EACH 38 +#define TK_FAIL 39 +#define TK_FOR 40 #define TK_IGNORE 41 #define TK_INITIALLY 42 #define TK_INSTEAD 43 -#define TK_LIKE 44 +#define TK_LIKE_KW 44 #define TK_MATCH 45 #define TK_KEY 46 #define TK_OF 47 @@ -57,86 +57,84 @@ #define TK_VIEW 57 #define TK_REINDEX 58 #define TK_RENAME 59 +#define TK_CTIME_KW 60 +#define TK_ALTER 61 +#define TK_OR 62 +#define TK_AND 63 +#define TK_NOT 64 +#define TK_IS 65 +#define TK_BETWEEN 66 +#define TK_IN 67 +#define TK_ISNULL 68 +#define TK_NOTNULL 69 +#define TK_NE 70 +#define TK_EQ 71 +#define TK_GT 72 +#define TK_LE 73 +#define TK_LT 74 +#define TK_GE 75 +#define TK_ESCAPE 76 +#define TK_BITAND 77 +#define TK_BITOR 78 +#define TK_LSHIFT 79 +#define TK_RSHIFT 80 +#define TK_PLUS 81 +#define TK_MINUS 82 +#define TK_STAR 83 +#define TK_SLASH 84 +#define TK_REM 85 +#define TK_CONCAT 86 +#define TK_UMINUS 87 +#define TK_UPLUS 88 +#define TK_BITNOT 89 +#define TK_STRING 90 +#define TK_JOIN_KW 91 +#define TK_CONSTRAINT 92 +#define TK_DEFAULT 93 +#define TK_NULL 94 +#define TK_PRIMARY 95 +#define TK_UNIQUE 96 +#define TK_CHECK 97 +#define TK_REFERENCES 98 +#define TK_COLLATE 99 +#define TK_AUTOINCR 100 +#define TK_ON 101 +#define TK_DELETE 102 +#define TK_UPDATE 103 +#define TK_INSERT 104 +#define TK_SET 105 +#define TK_DEFERRABLE 106 +#define TK_FOREIGN 107 +#define TK_DROP 108 +#define TK_UNION 109 +#define TK_ALL 110 +#define TK_INTERSECT 111 +#define TK_EXCEPT 112 +#define TK_SELECT 113 +#define TK_DISTINCT 114 +#define TK_DOT 115 +#define TK_FROM 116 +#define TK_JOIN 117 +#define TK_USING 118 +#define TK_ORDER 119 +#define TK_BY 120 +#define TK_GROUP 121 +#define TK_HAVING 122 +#define TK_LIMIT 123 +#define TK_WHERE 124 +#define TK_INTO 125 +#define TK_VALUES 126 +#define TK_INTEGER 127 +#define TK_FLOAT 128 +#define TK_BLOB 129 +#define TK_REGISTER 130 +#define TK_VARIABLE 131 +#define TK_EXISTS 132 +#define TK_CASE 133 +#define TK_WHEN 134 +#define TK_THEN 135 +#define TK_ELSE 136 +#define TK_INDEX 137 +#define TK_TO 138 +#define TK_ADD 139 +#define TK_COLUMNKW 140 -#define TK_CDATE 60 -#define TK_CTIME 61 -#define TK_CTIMESTAMP 62 -#define TK_ALTER 63 -#define TK_OR 64 -#define TK_AND 65 -#define TK_NOT 66 -#define TK_IS 67 -#define TK_BETWEEN 68 -#define TK_IN 69 -#define TK_ISNULL 70 -#define TK_NOTNULL 71 -#define TK_NE 72 -#define TK_EQ 73 -#define TK_GT 74 -#define TK_LE 75 -#define TK_LT 76 -#define TK_GE 77 -#define TK_ESCAPE 78 -#define TK_BITAND 79 -#define TK_BITOR 80 -#define TK_LSHIFT 81 -#define TK_RSHIFT 82 -#define TK_PLUS 83 -#define TK_MINUS 84 -#define TK_STAR 85 -#define TK_SLASH 86 -#define TK_REM 87 -#define TK_CONCAT 88 -#define TK_UMINUS 89 -#define TK_UPLUS 90 -#define TK_BITNOT 91 -#define TK_STRING 92 -#define TK_JOIN_KW 93 -#define TK_CONSTRAINT 94 -#define TK_DEFAULT 95 -#define TK_NULL 96 -#define TK_PRIMARY 97 -#define TK_UNIQUE 98 -#define TK_CHECK 99 -#define TK_REFERENCES 100 -#define TK_COLLATE 101 -#define TK_AUTOINCR 102 -#define TK_ON 103 -#define TK_DELETE 104 -#define TK_UPDATE 105 -#define TK_INSERT 106 -#define TK_SET 107 -#define TK_DEFERRABLE 108 -#define TK_FOREIGN 109 -#define TK_DROP 110 -#define TK_UNION 111 -#define TK_ALL 112 -#define TK_INTERSECT 113 -#define TK_EXCEPT 114 -#define TK_SELECT 115 -#define TK_DISTINCT 116 -#define TK_DOT 117 -#define TK_FROM 118 -#define TK_JOIN 119 -#define TK_USING 120 -#define TK_ORDER 121 -#define TK_BY 122 -#define TK_GROUP 123 -#define TK_HAVING 124 -#define TK_LIMIT 125 -#define TK_WHERE 126 -#define TK_INTO 127 -#define TK_VALUES 128 -#define TK_INTEGER 129 -#define TK_FLOAT 130 -#define TK_BLOB 131 -#define TK_REGISTER 132 -#define TK_VARIABLE 133 -#define TK_EXISTS 134 -#define TK_CASE 135 -#define TK_WHEN 136 -#define TK_THEN 137 -#define TK_ELSE 138 -#define TK_INDEX 139 -#define TK_TO 140 -#define TK_ADD 141 -#define TK_COLUMNKW 142 --- sqlite/pragma.c +++ sqlite/pragma.c @@ -11,7 +11,7 @@ ************************************************************************* ** This file contains code used to implement the PRAGMA command. ** -** $Id: pragma.c,v 1.91 2005/03/29 03:10:59 danielk1977 Exp $ +** $Id: pragma.c,v 1.95 2005/06/12 21:35:52 drh Exp $ */ #include "sqliteInt.h" #include "os.h" @@ -19,7 +19,7 @@ /* Ignore this whole file if pragmas are disabled */ -#ifndef SQLITE_OMIT_PRAGMA +#if !defined(SQLITE_OMIT_PRAGMA) && !defined(SQLITE_OMIT_PARSER) #if defined(SQLITE_DEBUG) || defined(SQLITE_TEST) # include "pager.h" @@ -693,7 +693,7 @@ static const VdbeOpList idxErr[] = { { OP_MemIncr, 0, 0, 0}, { OP_String8, 0, 0, "rowid "}, - { OP_Recno, 1, 0, 0}, + { OP_Rowid, 1, 0, 0}, { OP_String8, 0, 0, " missing from index "}, { OP_String8, 0, 0, 0}, /* 4 */ { OP_Concat, 2, 0, 0}, @@ -905,6 +905,17 @@ }else #endif +#ifdef SQLITE_SSE + /* + ** Check to see if the sqlite_statements table exists. Create it + ** if it does not. + */ + if( sqlite3StrICmp(zLeft, "create_sqlite_statement_table")==0 ){ + extern int sqlite3CreateStatementsTable(Parse*); + sqlite3CreateStatementsTable(pParse); + }else +#endif + {} if( v ){ @@ -919,4 +930,4 @@ sqliteFree(zRight); } +#endif /* SQLITE_OMIT_PRAGMA || SQLITE_OMIT_PARSER */ -#endif /* SQLITE_OMIT_PRAGMA */ --- sqlite/prepare.c +++ sqlite/prepare.c @@ -0,0 +1,529 @@ +/* +** 2005 May 25 +** +** 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 contains the implementation of the sqlite3_prepare() +** interface, and routines that contribute to loading the database schema +** from disk. +** +** $Id: prepare.c,v 1.1 2005/05/25 04:11:56 danielk1977 Exp $ +*/ +#include "sqliteInt.h" +#include "os.h" +#include + +/* +** Fill the InitData structure with an error message that indicates +** that the database is corrupt. +*/ +static void corruptSchema(InitData *pData, const char *zExtra){ + if( !sqlite3_malloc_failed ){ + sqlite3SetString(pData->pzErrMsg, "malformed database schema", + zExtra!=0 && zExtra[0]!=0 ? " - " : (char*)0, zExtra, (char*)0); + } +} + +/* +** This is the callback routine for the code that initializes the +** database. See sqlite3Init() below for additional information. +** This routine is also called from the OP_ParseSchema opcode of the VDBE. +** +** Each callback contains the following information: +** +** argv[0] = name of thing being created +** argv[1] = root page number for table or index. NULL for trigger or view. +** argv[2] = SQL text for the CREATE statement. +** argv[3] = "1" for temporary files, "0" for main database, "2" or more +** for auxiliary database files. +** +*/ +int sqlite3InitCallback(void *pInit, int argc, char **argv, char **azColName){ + InitData *pData = (InitData*)pInit; + sqlite3 *db = pData->db; + int iDb; + + assert( argc==4 ); + if( argv==0 ) return 0; /* Might happen if EMPTY_RESULT_CALLBACKS are on */ + if( argv[1]==0 || argv[3]==0 ){ + corruptSchema(pData, 0); + return 1; + } + iDb = atoi(argv[3]); + assert( iDb>=0 && iDbnDb ); + if( argv[2] && argv[2][0] ){ + /* Call the parser to process a CREATE TABLE, INDEX or VIEW. + ** But because db->init.busy is set to 1, no VDBE code is generated + ** or executed. All the parser does is build the internal data + ** structures that describe the table, index, or view. + */ + char *zErr; + int rc; + assert( db->init.busy ); + db->init.iDb = iDb; + db->init.newTnum = atoi(argv[1]); + rc = sqlite3_exec(db, argv[2], 0, 0, &zErr); + db->init.iDb = 0; + if( SQLITE_OK!=rc ){ + corruptSchema(pData, zErr); + sqlite3_free(zErr); + return rc; + } + }else{ + /* If the SQL column is blank it means this is an index that + ** was created to be the PRIMARY KEY or to fulfill a UNIQUE + ** constraint for a CREATE TABLE. The index should have already + ** been created when we processed the CREATE TABLE. All we have + ** to do here is record the root page number for that index. + */ + Index *pIndex; + pIndex = sqlite3FindIndex(db, argv[0], db->aDb[iDb].zName); + if( pIndex==0 || pIndex->tnum!=0 ){ + /* This can occur if there exists an index on a TEMP table which + ** has the same name as another index on a permanent index. Since + ** the permanent table is hidden by the TEMP table, we can also + ** safely ignore the index on the permanent table. + */ + /* Do Nothing */; + }else{ + pIndex->tnum = atoi(argv[1]); + } + } + return 0; +} + +/* +** Attempt to read the database schema and initialize internal +** data structures for a single database file. The index of the +** database file is given by iDb. iDb==0 is used for the main +** database. iDb==1 should never be used. iDb>=2 is used for +** auxiliary databases. Return one of the SQLITE_ error codes to +** indicate success or failure. +*/ +static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){ + int rc; + BtCursor *curMain; + int size; + Table *pTab; + char const *azArg[5]; + char zDbNum[30]; + int meta[10]; + InitData initData; + char const *zMasterSchema; + char const *zMasterName = SCHEMA_TABLE(iDb); + + /* + ** The master database table has a structure like this + */ + static const char master_schema[] = + "CREATE TABLE sqlite_master(\n" + " type text,\n" + " name text,\n" + " tbl_name text,\n" + " rootpage integer,\n" + " sql text\n" + ")" + ; +#ifndef SQLITE_OMIT_TEMPDB + static const char temp_master_schema[] = + "CREATE TEMP TABLE sqlite_temp_master(\n" + " type text,\n" + " name text,\n" + " tbl_name text,\n" + " rootpage integer,\n" + " sql text\n" + ")" + ; +#else + #define temp_master_schema 0 +#endif + + assert( iDb>=0 && iDbnDb ); + + /* 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. + */ + if( !OMIT_TEMPDB && iDb==1 ){ + zMasterSchema = temp_master_schema; + }else{ + zMasterSchema = master_schema; + } + zMasterName = SCHEMA_TABLE(iDb); + + /* Construct the schema tables. */ + sqlite3SafetyOff(db); + azArg[0] = zMasterName; + azArg[1] = "1"; + azArg[2] = zMasterSchema; + sprintf(zDbNum, "%d", iDb); + azArg[3] = zDbNum; + azArg[4] = 0; + initData.db = db; + initData.pzErrMsg = pzErrMsg; + rc = sqlite3InitCallback(&initData, 4, (char **)azArg, 0); + if( rc!=SQLITE_OK ){ + sqlite3SafetyOn(db); + return rc; + } + pTab = sqlite3FindTable(db, zMasterName, db->aDb[iDb].zName); + if( pTab ){ + pTab->readOnly = 1; + } + sqlite3SafetyOn(db); + + /* Create a cursor to hold the database open + */ + if( db->aDb[iDb].pBt==0 ){ + if( !OMIT_TEMPDB && iDb==1 ) DbSetProperty(db, 1, DB_SchemaLoaded); + return SQLITE_OK; + } + rc = sqlite3BtreeCursor(db->aDb[iDb].pBt, MASTER_ROOT, 0, 0, 0, &curMain); + if( rc!=SQLITE_OK && rc!=SQLITE_EMPTY ){ + sqlite3SetString(pzErrMsg, sqlite3ErrStr(rc), (char*)0); + return rc; + } + + /* Get the database meta information. + ** + ** Meta values are as follows: + ** meta[0] Schema cookie. Changes with each schema change. + ** meta[1] File format of schema layer. + ** meta[2] Size of the page cache. + ** meta[3] Use freelist if 0. Autovacuum if greater than zero. + ** meta[4] Db text encoding. 1:UTF-8 3:UTF-16 LE 4:UTF-16 BE + ** meta[5] The user cookie. Used by the application. + ** meta[6] + ** meta[7] + ** meta[8] + ** meta[9] + ** + ** Note: The hash defined SQLITE_UTF* symbols in sqliteInt.h correspond to + ** the possible values of meta[4]. + */ + if( rc==SQLITE_OK ){ + int i; + for(i=0; rc==SQLITE_OK && iaDb[iDb].pBt, i+1, (u32 *)&meta[i]); + } + if( rc ){ + sqlite3SetString(pzErrMsg, sqlite3ErrStr(rc), (char*)0); + sqlite3BtreeCloseCursor(curMain); + return rc; + } + }else{ + memset(meta, 0, sizeof(meta)); + } + db->aDb[iDb].schema_cookie = meta[0]; + + /* If opening a non-empty database, check the text encoding. For the + ** main database, set sqlite3.enc to the encoding of the main database. + ** For an attached db, it is an error if the encoding is not the same + ** as sqlite3.enc. + */ + if( meta[4] ){ /* text encoding */ + if( iDb==0 ){ + /* If opening the main database, set db->enc. */ + db->enc = (u8)meta[4]; + db->pDfltColl = sqlite3FindCollSeq(db, db->enc, "BINARY", 6, 0); + }else{ + /* If opening an attached database, the encoding much match db->enc */ + if( meta[4]!=db->enc ){ + sqlite3BtreeCloseCursor(curMain); + sqlite3SetString(pzErrMsg, "attached databases must use the same" + " text encoding as main database", (char*)0); + return SQLITE_ERROR; + } + } + } + + size = meta[2]; + if( size==0 ){ size = MAX_PAGES; } + db->aDb[iDb].cache_size = size; + + if( iDb==0 ){ + db->file_format = meta[1]; + if( db->file_format==0 ){ + /* This happens if the database was initially empty */ + db->file_format = 1; + } + + if( db->file_format==2 || db->file_format==3 ){ + /* File format 2 is treated exactly as file format 1. New + ** databases are created with file format 1. + */ + db->file_format = 1; + } + } + + /* + ** file_format==1 Version 3.0.0. + ** file_format==2 Version 3.1.3. + ** file_format==3 Version 3.1.4. + ** + ** Version 3.0 can only use files with file_format==1. Version 3.1.3 + ** can read and write files with file_format==1 or file_format==2. + ** Version 3.1.4 can read and write file formats 1, 2 and 3. + */ + if( meta[1]>3 ){ + sqlite3BtreeCloseCursor(curMain); + sqlite3SetString(pzErrMsg, "unsupported file format", (char*)0); + return SQLITE_ERROR; + } + + sqlite3BtreeSetCacheSize(db->aDb[iDb].pBt, db->aDb[iDb].cache_size); + + /* Read the schema information out of the schema tables + */ + assert( db->init.busy ); + if( rc==SQLITE_EMPTY ){ + /* For an empty database, there is nothing to read */ + rc = SQLITE_OK; + }else{ + char *zSql; + zSql = sqlite3MPrintf( + "SELECT name, rootpage, sql, '%s' FROM '%q'.%s", + zDbNum, db->aDb[iDb].zName, zMasterName); + sqlite3SafetyOff(db); + rc = sqlite3_exec(db, zSql, sqlite3InitCallback, &initData, 0); + sqlite3SafetyOn(db); + sqliteFree(zSql); + sqlite3BtreeCloseCursor(curMain); + } + if( sqlite3_malloc_failed ){ + sqlite3SetString(pzErrMsg, "out of memory", (char*)0); + rc = SQLITE_NOMEM; + sqlite3ResetInternalSchema(db, 0); + } + if( rc==SQLITE_OK ){ + DbSetProperty(db, iDb, DB_SchemaLoaded); + }else{ + sqlite3ResetInternalSchema(db, iDb); + } + return rc; +} + +/* +** Initialize all database files - the main database file, the file +** used to store temporary tables, and any additional database files +** created using ATTACH statements. Return a success code. If an +** error occurs, write an error message into *pzErrMsg. +** +** After the database is initialized, the SQLITE_Initialized +** bit is set in the flags field of the sqlite structure. +*/ +int sqlite3Init(sqlite3 *db, char **pzErrMsg){ + int i, rc; + + if( db->init.busy ) return SQLITE_OK; + assert( (db->flags & SQLITE_Initialized)==0 ); + rc = SQLITE_OK; + db->init.busy = 1; + for(i=0; rc==SQLITE_OK && inDb; i++){ + if( DbHasProperty(db, i, DB_SchemaLoaded) || i==1 ) continue; + rc = sqlite3InitOne(db, i, pzErrMsg); + if( rc ){ + sqlite3ResetInternalSchema(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. + */ +#ifndef SQLITE_OMIT_TEMPDB + if( rc==SQLITE_OK && db->nDb>1 && !DbHasProperty(db, 1, DB_SchemaLoaded) ){ + rc = sqlite3InitOne(db, 1, pzErrMsg); + if( rc ){ + sqlite3ResetInternalSchema(db, 1); + } + } +#endif + + db->init.busy = 0; + if( rc==SQLITE_OK ){ + db->flags |= SQLITE_Initialized; + sqlite3CommitInternalChanges(db); + } + + if( rc!=SQLITE_OK ){ + db->flags &= ~SQLITE_Initialized; + } + return rc; +} + +/* +** This routine is a no-op if the database schema is already initialised. +** Otherwise, the schema is loaded. An error code is returned. +*/ +int sqlite3ReadSchema(Parse *pParse){ + int rc = SQLITE_OK; + sqlite3 *db = pParse->db; + if( !db->init.busy ){ + if( (db->flags & SQLITE_Initialized)==0 ){ + rc = sqlite3Init(db, &pParse->zErrMsg); + } + } + assert( rc!=SQLITE_OK || (db->flags & SQLITE_Initialized)||db->init.busy ); + if( rc!=SQLITE_OK ){ + pParse->rc = rc; + pParse->nErr++; + } + return rc; +} + + +/* +** Check schema cookies in all databases. If any cookie is out +** of date, return 0. If all schema cookies are current, return 1. +*/ +static int schemaIsValid(sqlite3 *db){ + int iDb; + int rc; + BtCursor *curTemp; + int cookie; + int allOk = 1; + + for(iDb=0; allOk && iDbnDb; iDb++){ + Btree *pBt; + pBt = db->aDb[iDb].pBt; + if( pBt==0 ) continue; + rc = sqlite3BtreeCursor(pBt, MASTER_ROOT, 0, 0, 0, &curTemp); + if( rc==SQLITE_OK ){ + rc = sqlite3BtreeGetMeta(pBt, 1, (u32 *)&cookie); + if( rc==SQLITE_OK && cookie!=db->aDb[iDb].schema_cookie ){ + allOk = 0; + } + sqlite3BtreeCloseCursor(curTemp); + } + } + return allOk; +} + +/* +** Compile the UTF-8 encoded SQL statement zSql into a statement handle. +*/ +int sqlite3_prepare( + sqlite3 *db, /* Database handle. */ + const char *zSql, /* UTF-8 encoded SQL statement. */ + int nBytes, /* Length of zSql in bytes. */ + sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */ + const char** pzTail /* OUT: End of parsed string */ +){ + Parse sParse; + char *zErrMsg = 0; + int rc = SQLITE_OK; + + if( sqlite3_malloc_failed ){ + return SQLITE_NOMEM; + } + + assert( ppStmt ); + *ppStmt = 0; + if( sqlite3SafetyOn(db) ){ + return SQLITE_MISUSE; + } + + memset(&sParse, 0, sizeof(sParse)); + sParse.db = db; + sqlite3RunParser(&sParse, zSql, &zErrMsg); + + if( sqlite3_malloc_failed ){ + rc = SQLITE_NOMEM; + sqlite3RollbackAll(db); + sqlite3ResetInternalSchema(db, 0); + db->flags &= ~SQLITE_InTrans; + goto prepare_out; + } + if( sParse.rc==SQLITE_DONE ) sParse.rc = SQLITE_OK; + if( sParse.rc!=SQLITE_OK && sParse.checkSchema && !schemaIsValid(db) ){ + sParse.rc = SQLITE_SCHEMA; + } + if( sParse.rc==SQLITE_SCHEMA ){ + sqlite3ResetInternalSchema(db, 0); + } + if( pzTail ) *pzTail = sParse.zTail; + rc = sParse.rc; + +#ifndef SQLITE_OMIT_EXPLAIN + if( rc==SQLITE_OK && sParse.pVdbe && sParse.explain ){ + sqlite3VdbeSetNumCols(sParse.pVdbe, 5); + sqlite3VdbeSetColName(sParse.pVdbe, 0, "addr", P3_STATIC); + sqlite3VdbeSetColName(sParse.pVdbe, 1, "opcode", P3_STATIC); + sqlite3VdbeSetColName(sParse.pVdbe, 2, "p1", P3_STATIC); + sqlite3VdbeSetColName(sParse.pVdbe, 3, "p2", P3_STATIC); + sqlite3VdbeSetColName(sParse.pVdbe, 4, "p3", P3_STATIC); + } +#endif + +prepare_out: + if( sqlite3SafetyOff(db) ){ + rc = SQLITE_MISUSE; + } + if( rc==SQLITE_OK ){ + *ppStmt = (sqlite3_stmt*)sParse.pVdbe; + }else if( sParse.pVdbe ){ + sqlite3_finalize((sqlite3_stmt*)sParse.pVdbe); + } + + if( zErrMsg ){ + sqlite3Error(db, rc, "%s", zErrMsg); + sqliteFree(zErrMsg); + }else{ + sqlite3Error(db, rc, 0); + } + return rc; +} + +#ifndef SQLITE_OMIT_UTF16 +/* +** Compile the UTF-16 encoded SQL statement zSql into a statement handle. +*/ +int sqlite3_prepare16( + sqlite3 *db, /* Database handle. */ + const void *zSql, /* UTF-8 encoded SQL statement. */ + int nBytes, /* Length of zSql in bytes. */ + sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */ + const void **pzTail /* OUT: End of parsed string */ +){ + /* This function currently works by first transforming the UTF-16 + ** encoded string to UTF-8, then invoking sqlite3_prepare(). The + ** tricky bit is figuring out the pointer to return in *pzTail. + */ + char const *zSql8 = 0; + char const *zTail8 = 0; + int rc; + sqlite3_value *pTmp; + + if( sqlite3SafetyCheck(db) ){ + return SQLITE_MISUSE; + } + pTmp = sqlite3GetTransientValue(db); + sqlite3ValueSetStr(pTmp, -1, zSql, SQLITE_UTF16NATIVE, SQLITE_STATIC); + zSql8 = sqlite3ValueText(pTmp, SQLITE_UTF8); + if( !zSql8 ){ + sqlite3Error(db, SQLITE_NOMEM, 0); + return SQLITE_NOMEM; + } + rc = sqlite3_prepare(db, zSql8, -1, ppStmt, &zTail8); + + if( zTail8 && pzTail ){ + /* If sqlite3_prepare returns a tail pointer, we calculate the + ** equivalent pointer into the UTF-16 string by counting the unicode + ** characters between zSql8 and zTail8, and then returning a pointer + ** the same number of characters into the UTF-16 string. + */ + int chars_parsed = sqlite3utf8CharLen(zSql8, zTail8-zSql8); + *pzTail = (u8 *)zSql + sqlite3utf16ByteLen(zSql, chars_parsed); + } + + return rc; +} +#endif /* SQLITE_OMIT_UTF16 */ + --- sqlite/random.c +++ sqlite/random.c @@ -15,7 +15,7 @@ ** Random numbers are used by some of the database backends in order ** to generate random integer keys for tables or random filenames. ** -** $Id: random.c,v 1.12 2004/05/08 08:23:32 danielk1977 Exp $ +** $Id: random.c,v 1.13 2005/06/12 21:35:52 drh Exp $ */ #include "sqliteInt.h" #include "os.h" @@ -26,13 +26,16 @@ ** must be held while executing this routine. ** ** Why not just use a library random generator like lrand48() for this? -** Because the OP_NewRecno opcode in the VDBE depends on having a very +** Because the OP_NewRowid opcode in the VDBE depends on having a very ** good source of random numbers. The lrand48() library function may ** well be good enough. But maybe not. Or maybe lrand48() has some ** subtle problems on some systems that could cause problems. It is hard ** to know. To minimize the risk of problems due to bad lrand48() ** implementations, SQLite uses this random number generator based ** on RC4, which we know works very well. +** +** (Later): Actually, OP_NewRowid does not depend on a good source of +** randomness any more. But we will leave this code in all the same. */ static int randomByte(){ unsigned char t; @@ -95,6 +98,3 @@ } sqlite3OsLeaveMutex(); } - - - --- sqlite/select.c +++ sqlite/select.c @@ -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.243 2005/03/28 03:39:56 drh Exp $ +** $Id: select.c,v 1.252 2005/06/12 21:35:52 drh Exp $ */ #include "sqliteInt.h" @@ -326,7 +326,7 @@ sqlite3ExprCode(pParse, pOrderBy->a[i].pExpr); } sqlite3VdbeAddOp(v, OP_MakeRecord, pOrderBy->nExpr, 0); - sqlite3VdbeAddOp(v, OP_SortPut, 0, 0); + sqlite3VdbeAddOp(v, OP_SortInsert, 0, 0); } /* @@ -422,8 +422,7 @@ sqlite3VdbeAddOp(v, OP_Pop, pEList->nExpr+1, 0); sqlite3VdbeAddOp(v, OP_Goto, 0, iContinue); VdbeComment((v, "# skip indistinct records")); - sqlite3VdbeAddOp(v, OP_String8, 0, 0); - sqlite3VdbeAddOp(v, OP_PutStrKey, distinct, 0); + sqlite3VdbeAddOp(v, OP_IdxInsert, distinct, 0); if( pOrderBy==0 ){ codeLimiter(v, p, iContinue, iBreak, nColumn); } @@ -437,8 +436,7 @@ case SRT_Union: { sqlite3VdbeAddOp(v, OP_MakeRecord, nColumn, NULL_ALWAYS_DISTINCT); sqlite3VdbeChangeP3(v, -1, aff, P3_STATIC); - sqlite3VdbeAddOp(v, OP_String8, 0, 0); - sqlite3VdbeAddOp(v, OP_PutStrKey, iParm, 0); + sqlite3VdbeAddOp(v, OP_IdxInsert, iParm, 0); break; } @@ -464,9 +462,9 @@ if( pOrderBy ){ pushOntoSorter(pParse, v, pOrderBy); }else{ - sqlite3VdbeAddOp(v, OP_NewRecno, iParm, 0); + sqlite3VdbeAddOp(v, OP_NewRowid, iParm, 0); sqlite3VdbeAddOp(v, OP_Pull, 1, 0); - sqlite3VdbeAddOp(v, OP_PutIntKey, iParm, 0); + sqlite3VdbeAddOp(v, OP_Insert, iParm, 0); } break; } @@ -490,8 +488,7 @@ char aff = (iParm>>16)&0xFF; aff = sqlite3CompareAffinity(pEList->a[0].pExpr, aff); sqlite3VdbeOp3(v, OP_MakeRecord, 1, 0, &aff, 1); - sqlite3VdbeAddOp(v, OP_String8, 0, 0); - sqlite3VdbeAddOp(v, OP_PutStrKey, (iParm&0x0000FFFF), 0); + sqlite3VdbeAddOp(v, OP_IdxInsert, (iParm&0x0000FFFF), 0); } sqlite3VdbeChangeP2(v, addr2, sqlite3VdbeCurrentAddr(v)); break; @@ -603,9 +600,9 @@ switch( eDest ){ case SRT_Table: case SRT_TempTable: { - sqlite3VdbeAddOp(v, OP_NewRecno, iParm, 0); + sqlite3VdbeAddOp(v, OP_NewRowid, iParm, 0); sqlite3VdbeAddOp(v, OP_Pull, 1, 0); - sqlite3VdbeAddOp(v, OP_PutIntKey, iParm, 0); + sqlite3VdbeAddOp(v, OP_Insert, iParm, 0); break; } #ifndef SQLITE_OMIT_SUBQUERY @@ -615,8 +612,7 @@ sqlite3VdbeAddOp(v, OP_Pop, 1, 0); sqlite3VdbeAddOp(v, OP_Goto, 0, sqlite3VdbeCurrentAddr(v)+3); sqlite3VdbeOp3(v, OP_MakeRecord, 1, 0, "n", P3_STATIC); - sqlite3VdbeAddOp(v, OP_String8, 0, 0); - sqlite3VdbeAddOp(v, OP_PutStrKey, (iParm&0x0000FFFF), 0); + sqlite3VdbeAddOp(v, OP_IdxInsert, (iParm&0x0000FFFF), 0); break; } case SRT_Exists: @@ -689,6 +685,20 @@ pNC = pNC->pNext; } } + if( pTab==0 ){ + /* FIX ME: + ** This can occurs if you have something like "SELECT new.x;" inside + ** a trigger. In other words, if you reference the special "new" + ** table in the result set of a select. We do not have a good way + ** to find the actual table type, so call it "TEXT". This is really + ** something of a bug, but I do not know how to fix it. + ** + ** This code does not produce the correct answer - it just prevents + ** a segfault. See ticket #1229. + */ + zType = "TEXT"; + break; + } assert( pTab ); if( iCol<0 ) iCol = pTab->iPKey; assert( iCol==-1 || (iCol>=0 && iColnCol) ); @@ -858,6 +868,7 @@ if( pTab==0 ){ return 0; } + pTab->nRef = 1; pTab->zName = zTabName ? sqliteStrDup(zTabName) : 0; pEList = pSelect->pEList; pTab->nCol = pEList->nExpr; @@ -915,6 +926,7 @@ /* Get the typename, type affinity, and collating sequence for the ** column. */ + memset(&sNC, 0, sizeof(sNC)); sNC.pSrcList = pSelect->pSrc; zType = sqliteStrDup(columnType(&sNC, p)); pCol->zType = zType; @@ -989,6 +1001,7 @@ pFrom->zAlias = sqlite3MPrintf("sqlite_subquery_%p_", (void*)pFrom->pSelect); } + assert( pFrom->pTab==0 ); pFrom->pTab = pTab = sqlite3ResultSetOfSelect(pParse, pFrom->zAlias, pFrom->pSelect); if( pTab==0 ){ @@ -1002,11 +1015,13 @@ #endif }else{ /* An ordinary table or view name in the FROM clause */ + assert( pFrom->pTab==0 ); pFrom->pTab = pTab = sqlite3LocateTable(pParse,pFrom->zName,pFrom->zDatabase); if( pTab==0 ){ return 1; } + pTab->nRef++; #ifndef SQLITE_OMIT_VIEW if( pTab->pSelect ){ /* We reach here if the named table is a really a view */ @@ -1055,6 +1070,10 @@ */ struct ExprList_item *a = pEList->a; ExprList *pNew = 0; + int flags = pParse->db->flags; + int longNames = (flags & SQLITE_FullColNames)!=0 && + (flags & SQLITE_ShortColNames)==0; + for(k=0; knExpr; k++){ Expr *pE = a[k].pExpr; if( pE->op!=TK_ALL && @@ -1107,7 +1126,7 @@ pRight = sqlite3Expr(TK_ID, 0, 0, 0); if( pRight==0 ) break; setToken(&pRight->token, zName); - if( zTabName && pTabList->nSrc>1 ){ + if( zTabName && (longNames || pTabList->nSrc>1) ){ pLeft = sqlite3Expr(TK_ID, 0, 0, 0); pExpr = sqlite3Expr(TK_DOT, pLeft, pRight, 0); if( pExpr==0 ) break; @@ -1121,7 +1140,11 @@ pExpr = pRight; pExpr->span = pExpr->token; } - pNew = sqlite3ExprListAppend(pNew, pExpr, &pRight->token); + if( longNames ){ + pNew = sqlite3ExprListAppend(pNew, pExpr, &pExpr->span); + }else{ + pNew = sqlite3ExprListAppend(pNew, pExpr, &pRight->token); + } } } if( !tableSeen ){ @@ -1141,40 +1164,6 @@ return rc; } -/* -** This routine recursively unlinks the Select.pSrc.a[].pTab pointers -** in a select structure. It just sets the pointers to NULL. This -** routine is recursive in the sense that if the Select.pSrc.a[].pSelect -** pointer is not NULL, this routine is called recursively on that pointer. -** -** This routine is called on the Select structure that defines a -** VIEW in order to undo any bindings to tables. This is necessary -** because those tables might be DROPed by a subsequent SQL command. -** If the bindings are not removed, then the Select.pSrc->a[].pTab field -** will be left pointing to a deallocated Table structure after the -** DROP and a coredump will occur the next time the VIEW is used. -*/ -#if 0 -void sqlite3SelectUnbind(Select *p){ - int i; - SrcList *pSrc = p->pSrc; - struct SrcList_item *pItem; - Table *pTab; - if( p==0 ) return; - for(i=0, pItem=pSrc->a; inSrc; i++, pItem++){ - if( (pTab = pItem->pTab)!=0 ){ - if( pTab->isTransient ){ - sqlite3DeleteTable(0, pTab); - } - pItem->pTab = 0; - if( pItem->pSelect ){ - sqlite3SelectUnbind(pItem->pSelect); - } - } - } -} -#endif - #ifndef SQLITE_OMIT_COMPOUND_SELECT /* ** This routine associates entries in an ORDER BY expression list with @@ -1333,11 +1322,9 @@ ** DISTINCT, UNION, INTERSECT and EXCEPT select statements (but not ** UNION ALL). ** -** Make the new table a KeyAsData table if keyAsData is true. -** ** The value returned is the address of the OP_OpenTemp instruction. */ -static int openTempIndex(Parse *pParse, Select *p, int iTab, int keyAsData){ +static int openTempIndex(Parse *pParse, Select *p, int iTab){ KeyInfo *pKeyInfo; int nColumn; sqlite3 *db = pParse->db; @@ -1361,9 +1348,6 @@ } addr = sqlite3VdbeOp3(v, OP_OpenTemp, iTab, 0, (char*)pKeyInfo, P3_KEYINFO_HANDOFF); - if( keyAsData ){ - sqlite3VdbeAddOp(v, OP_KeyAsData, iTab, 1); - } return addr; } @@ -1558,7 +1542,6 @@ if( rc!=SQLITE_OK ){ goto multi_select_end; } - sqlite3VdbeAddOp(v, OP_KeyAsData, unionTab, 1); } assert( nAddrpEList ); @@ -1669,7 +1651,6 @@ if( rc!=SQLITE_OK ){ goto multi_select_end; } - sqlite3VdbeAddOp(v, OP_KeyAsData, tab2, 1); assert( nAddrpPrior = 0; @@ -1697,7 +1678,7 @@ iCont = sqlite3VdbeMakeLabel(v); sqlite3VdbeAddOp(v, OP_Rewind, tab1, iBreak); computeLimitRegisters(pParse, p); - iStart = sqlite3VdbeAddOp(v, OP_FullKey, tab1, 0); + iStart = sqlite3VdbeAddOp(v, OP_RowKey, tab1, 0); sqlite3VdbeAddOp(v, OP_NotFound, tab2, iCont); rc = selectInnerLoop(pParse, p, p->pEList, tab1, p->pEList->nExpr, p->pOrderBy, -1, eDest, iParm, @@ -2025,11 +2006,8 @@ { int nSubSrc = pSubSrc->nSrc; int jointype = pSubitem->jointype; - Table *pTab = pSubitem->pTab; - if( pTab && pTab->isTransient ){ - sqlite3DeleteTable(0, pSubitem->pTab); - } + sqlite3DeleteTable(0, pSubitem->pTab); sqliteFree(pSubitem->zDatabase); sqliteFree(pSubitem->zName); sqliteFree(pSubitem->zAlias); @@ -2236,12 +2214,12 @@ sqlite3VdbeOp3(v, OP_OpenRead, iIdx, pIdx->tnum, (char*)&pIdx->keyInfo, P3_KEYINFO); if( seekOp==OP_Rewind ){ - sqlite3VdbeAddOp(v, OP_String, 0, 0); + sqlite3VdbeAddOp(v, OP_Null, 0, 0); sqlite3VdbeAddOp(v, OP_MakeRecord, 1, 0); seekOp = OP_MoveGt; } sqlite3VdbeAddOp(v, seekOp, iIdx, 0); - sqlite3VdbeAddOp(v, OP_IdxRecno, iIdx, 0); + sqlite3VdbeAddOp(v, OP_IdxRowid, iIdx, 0); sqlite3VdbeAddOp(v, OP_Close, iIdx, 0); sqlite3VdbeAddOp(v, OP_MoveGe, base, 0); } @@ -2720,7 +2698,14 @@ for(i=0; inAgg; i++){ FuncDef *pFunc; if( (pFunc = pParse->aAgg[i].pFunc)!=0 && pFunc->xFinalize!=0 ){ - sqlite3VdbeOp3(v, OP_AggInit, 0, i, (char*)pFunc, P3_FUNCDEF); + int nExpr = 0; +#ifdef SQLITE_SSE + Expr *pAggExpr = pParse->aAgg[i].pExpr; + if( pAggExpr && pAggExpr->pList ){ + nExpr = pAggExpr->pList->nExpr; + } +#endif + sqlite3VdbeOp3(v, OP_AggInit, nExpr, i, (char*)pFunc, P3_FUNCDEF); } } if( pGroupBy ){ @@ -2744,7 +2729,7 @@ /* Initialize the memory cell to NULL for SRT_Mem or 0 for SRT_Exists */ if( eDest==SRT_Mem || eDest==SRT_Exists ){ - sqlite3VdbeAddOp(v, eDest==SRT_Mem ? OP_String8 : OP_Integer, 0, 0); + sqlite3VdbeAddOp(v, eDest==SRT_Mem ? OP_Null : OP_Integer, 0, 0); sqlite3VdbeAddOp(v, OP_MemStore, iParm, 1); } @@ -2752,7 +2737,7 @@ */ if( isDistinct ){ distinct = pParse->nTab++; - openTempIndex(pParse, p, distinct, 0); + openTempIndex(pParse, p, distinct); }else{ distinct = -1; } @@ -2760,7 +2745,7 @@ /* Begin the database scan */ pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, - pGroupBy ? 0 : &pOrderBy, p->pFetch); + pGroupBy ? 0 : &pOrderBy); if( pWInfo==0 ) goto select_end; /* Use the standard inner loop if we are not dealing with @@ -2821,7 +2806,7 @@ if( !pColl ) pColl = pParse->db->pDfltColl; sqlite3VdbeOp3(v, OP_CollSeq, 0, 0, (char *)pColl, P3_COLLSEQ); } - sqlite3VdbeOp3(v, OP_AggFunc, 0, nExpr, (char*)pDef, P3_POINTER); + sqlite3VdbeOp3(v, OP_AggFunc, 0, nExpr, (char*)pDef, P3_FUNCDEF); } } --- sqlite/sqlite3.h +++ sqlite/sqlite3.h @@ -12,7 +12,7 @@ ** This header file defines the interface that the SQLite library ** presents to client programs. ** -** @(#) $Id: sqlite.h.in,v 1.131 2005/03/21 04:04:03 danielk1977 Exp $ +** @(#) $Id: sqlite.h.in,v 1.136 2005/06/12 22:12:39 drh Exp $ */ #ifndef _SQLITE3_H_ #define _SQLITE3_H_ @@ -31,7 +31,7 @@ #ifdef SQLITE_VERSION # undef SQLITE_VERSION #endif -#define SQLITE_VERSION "3.2.1" +#define SQLITE_VERSION "3.2.2" /* ** The format of the version string is "X.Y.Z", where @@ -48,7 +48,7 @@ #ifdef SQLITE_VERSION_NUMBER # undef SQLITE_VERSION_NUMBER #endif -#define SQLITE_VERSION_NUMBER 3002001 +#define SQLITE_VERSION_NUMBER 3002002 /* ** The version string is also compiled into the library so that a program @@ -257,8 +257,10 @@ ** false. */ int sqlite3_complete(const char *sql); +int sqlite3_complete_last(const char *sql, const char **last); int sqlite3_complete16(const void *sql); + /* ** This routine identifies a callback function that is invoked ** whenever an attempt is made to open a database table that is @@ -688,8 +690,6 @@ /* ** Set all the parameters in the compiled SQL statement to NULL. -** -******* THIS IS AN EXPERIMENTAL API AND IS SUBJECT TO CHANGE ****** */ int sqlite3_clear_bindings(sqlite3_stmt*); @@ -1191,24 +1191,30 @@ ** milisecond time resolution, then the time will be rounded up to ** the nearest second. The number of miliseconds of sleep actually ** requested from the operating system is returned. -** -******* THIS IS AN EXPERIMENTAL API AND IS SUBJECT TO CHANGE ****** */ int sqlite3_sleep(int); /* -** Return TRUE (non-zero) of the statement supplied as an argument needs +** Return TRUE (non-zero) if the statement supplied as an argument needs ** to be recompiled. A statement needs to be recompiled whenever the ** execution environment changes in a way that would alter the program ** that sqlite3_prepare() generates. For example, if new functions or ** collating sequences are registered or if an authorizer function is ** added or changed. ** -******* THIS IS AN EXPERIMENTAL API AND IS SUBJECT TO CHANGE ****** */ int sqlite3_expired(sqlite3_stmt*); /* +** Move all bindings from the first prepared statement over to the second. +** This routine is useful, for example, if the first prepared statement +** fails with an SQLITE_SCHEMA error. The same SQL can be prepared into +** the second prepared statement then all of the bindings transfered over +** to the second statement before the first statement is finalized. +*/ +int sqlite3_transfer_bindings(sqlite3_stmt*, sqlite3_stmt*); + +/* ** If the following global variable is made to point to a ** string which is the name of a directory, then all temporary files ** created by SQLite will be placed in that directory. If this variable @@ -1224,7 +1230,7 @@ ** This function is called to recover from a malloc() failure that occured ** within the SQLite library. Normally, after a single malloc() fails the ** library refuses to function (all major calls return SQLITE_NOMEM). -** This function library state so that it can be used again. +** This function restores the library state so that it can be used again. ** ** All existing statements (sqlite3_stmt pointers) must be finalized or ** reset before this call is made. Otherwise, SQLITE_BUSY is returned. @@ -1241,6 +1247,22 @@ */ int sqlite3_global_recover(); +/* +** Test to see whether or not the database connection is in autocommit +** mode. Return TRUE if it is and FALSE if not. Autocommit mode is on +** by default. Autocommit is disabled by a BEGIN statement and reenabled +** by the next COMMIT or ROLLBACK. +*/ +int sqlite3_get_autocommit(sqlite3*); + +/* +** Return the sqlite3* database handle to which the prepared statement given +** in the argument belongs. This is the same database handle that was +** the first argument to the sqlite3_prepare() that was used to create +** the statement in the first place. +*/ +sqlite3 *sqlite3_db_handle(sqlite3_stmt*); + #ifdef __cplusplus } /* End of the 'extern "C"' block */ #endif --- sqlite/sqliteInt.h +++ sqlite/sqliteInt.h @@ -11,7 +11,7 @@ ************************************************************************* ** Internal interface definitions for SQLite. ** -** @(#) $Id: sqliteInt.h,v 1.375 2005/03/29 03:10:59 danielk1977 Exp $ +** @(#) $Id: sqliteInt.h,v 1.387 2005/06/12 21:35:52 drh Exp $ */ #ifndef _SQLITEINT_H_ #define _SQLITEINT_H_ @@ -180,20 +180,6 @@ #ifndef LONGDOUBLE_TYPE # define LONGDOUBLE_TYPE long double #endif -#ifndef INTPTR_TYPE -# if SQLITE_PTR_SZ==4 -# define INTPTR_TYPE int -# else -# define INTPTR_TYPE sqlite_int64 -# endif -#endif -#ifndef UINTPTR_TYPE -# if SQLITE_PTR_SZ==4 -# define UINTPTR_TYPE unsigned int -# else -# define UINTPTR_TYPE sqlite_uint64 -# endif -#endif typedef sqlite_int64 i64; /* 8-byte signed integer */ typedef UINT64_TYPE u64; /* 8-byte unsigned integer */ typedef UINT32_TYPE u32; /* 4-byte unsigned integer */ @@ -201,8 +187,6 @@ 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 */ -typedef UINTPTR_TYPE uptr; /* Big enough to hold a pointer */ /* ** Macros to determine whether the machine is big or little endian, @@ -317,7 +301,6 @@ typedef struct Column Column; typedef struct Table Table; typedef struct Index Index; -typedef struct Instruction Instruction; typedef struct Expr Expr; typedef struct ExprList ExprList; typedef struct Parse Parse; @@ -339,7 +322,6 @@ typedef struct CollSeq CollSeq; typedef struct KeyInfo KeyInfo; typedef struct NameContext NameContext; -typedef struct Fetch Fetch; /* ** Each database file to be accessed by the system is an instance @@ -418,16 +400,13 @@ struct sqlite3 { int nDb; /* Number of backends currently in use */ Db *aDb; /* All backends */ - Db aDbStatic[2]; /* Static space for the 2 default backends */ int flags; /* Miscellanous flags. See below */ + int errCode; /* Most recent error code (SQLITE_*) */ + u8 enc; /* Text encoding for this database. */ + u8 autoCommit; /* The auto-commit flag. */ u8 file_format; /* What file format version is this database? */ u8 temp_store; /* 1: file 2: memory 0: default */ int nTable; /* Number of tables in the database */ - BusyHandler busyHandler; /* Busy callback */ - void *pCommitArg; /* Argument to xCommitCallback() */ - int (*xCommitCallback)(void*);/* Invoked at every commit. */ - Hash aFunc; /* All functions that can be in SQL exprs */ - Hash aCollSeq; /* All collating sequences */ CollSeq *pDfltColl; /* The default collating sequence (BINARY) */ i64 lastRowid; /* ROWID of most recent insert (see above) */ i64 priorNewRowid; /* Last randomly generated ROWID */ @@ -443,6 +422,15 @@ int activeVdbeCnt; /* Number of vdbes currently executing */ void (*xTrace)(void*,const char*); /* Trace function */ void *pTraceArg; /* Argument to the trace function */ + void *pCommitArg; /* Argument to xCommitCallback() */ + int (*xCommitCallback)(void*);/* Invoked at every commit. */ + void(*xCollNeeded)(void*,sqlite3*,int eTextRep,const char*); + void(*xCollNeeded16)(void*,sqlite3*,int eTextRep,const void*); + void *pCollNeededArg; + sqlite3_value *pValue; /* Value used for transient conversions */ + sqlite3_value *pErr; /* Most recent error message */ + char *zErrMsg; /* Most recent error message (UTF-8 encoded) */ + char *zErrMsg16; /* Most recent error message (UTF-16 encoded) */ #ifndef SQLITE_OMIT_AUTHORIZATION int (*xAuth)(void*,int,const char*,const char*,const char*,const char*); /* Access authorization function */ @@ -453,19 +441,17 @@ void *pProgressArg; /* Argument to the progress callback */ int nProgressOps; /* Number of opcodes for progress callback */ #endif - int errCode; /* Most recent error code (SQLITE_*) */ - u8 enc; /* Text encoding for this database. */ - u8 autoCommit; /* The auto-commit flag. */ - void(*xCollNeeded)(void*,sqlite3*,int eTextRep,const char*); - void(*xCollNeeded16)(void*,sqlite3*,int eTextRep,const void*); - void *pCollNeededArg; - sqlite3_value *pValue; /* Value used for transient conversions */ - sqlite3_value *pErr; /* Most recent error message */ - char *zErrMsg; /* Most recent error message (UTF-8 encoded) */ - char *zErrMsg16; /* Most recent error message (UTF-16 encoded) */ #ifndef SQLITE_OMIT_GLOBALRECOVER sqlite3 *pNext; /* Linked list of open db handles. */ #endif + Hash aFunc; /* All functions that can be in SQL exprs */ + Hash aCollSeq; /* All collating sequences */ + BusyHandler busyHandler; /* Busy callback */ + int busyTimeout; /* Busy handler timeout, in msec */ + Db aDbStatic[2]; /* Static space for the 2 default backends */ +#ifdef SQLITE_SSE + sqlite3_stmt *pFetch; /* Used by SSE to fetch stored statements */ +#endif }; /* @@ -622,6 +608,7 @@ u8 hasPrimKey; /* True if there exists a primary key */ u8 keyConf; /* What to do in case of uniqueness conflict on iPKey */ u8 autoInc; /* True if the integer primary key is autoincrement */ + int nRef; /* Number of pointers to this Table */ Trigger *pTrigger; /* List of SQL triggers on this table */ FKey *pFKey; /* Linked list of all foreign keys in this table */ char *zColAff; /* String defining the affinity of each column */ @@ -717,7 +704,8 @@ ** comparison of the two index keys. ** ** If the KeyInfo.incrKey value is true and the comparison would -** otherwise be equal, then return a result as if the second key larger. +** otherwise be equal, then return a result as if the second key +** were larger. */ struct KeyInfo { u8 enc; /* Text encoding - one of the TEXT_Utf* values */ @@ -1049,7 +1037,6 @@ Expr *pOffset; /* OFFSET expression. NULL means not used. */ int iLimit, iOffset; /* Memory registers holding LIMIT & OFFSET counters */ IdList **ppOpenTemp; /* OP_OpenTemp addresses used by multi-selects */ - Fetch *pFetch; /* If this stmt is part of a FETCH command */ u8 isResolved; /* True once sqlite3SelectResolve() has run. */ u8 isAgg; /* True if this is an aggregate query */ }; @@ -1113,15 +1100,15 @@ u8 nameClash; /* A permanent table name clashes with temp table name */ u8 checkSchema; /* Causes schema cookie check after an error */ u8 nested; /* Number of nested calls to the parser/code generator */ + u8 fillAgg; /* If true, ignore the Expr.iAgg field. Normally false */ int nErr; /* Number of errors seen */ int nTab; /* Number of previously allocated VDBE cursors */ int nMem; /* Number of memory cells used so far */ int nSet; /* Number of sets used so far */ + u32 writeMask; /* Start a write transaction on these databases */ u32 cookieMask; /* Bitmask of schema verified databases */ - int cookieValue[MAX_ATTACHED+2]; /* Values of cookies to verify */ int cookieGoto; /* Address of OP_Goto to cookie verifier subroutine */ - u32 writeMask; /* Start a write transaction on these databases */ - u8 fillAgg; /* If true, ignore the Expr.iAgg field. Normally false */ + int cookieValue[MAX_ATTACHED+2]; /* Values of cookies to verify */ /* Above is constant between recursions. Below is reset before and after ** each recursion */ @@ -1155,7 +1142,7 @@ }; /* -** Bitfield flags for P2 value in OP_PutIntKey and OP_Delete +** Bitfield flags for P2 value in OP_Insert and OP_Delete */ #define OPFLAG_NCHANGE 1 /* Set to update db->nChange */ #define OPFLAG_LASTROWID 2 /* Set to update db->lastRowid */ @@ -1347,13 +1334,15 @@ char *sqlite3StrDup(const char*); char *sqlite3StrNDup(const char*, int); # define sqlite3CheckMemory(a,b) +# define sqlite3MallocX sqlite3Malloc #endif void sqlite3FreeX(void*); +void *sqlite3MallocX(int); char *sqlite3MPrintf(const char*, ...); char *sqlite3VMPrintf(const char*, va_list); void sqlite3DebugPrintf(const char*, ...); void *sqlite3TextToPtr(const char*); -void sqlite3SetString(char **, const char *, ...); +void sqlite3SetString(char **, ...); void sqlite3ErrorMsg(Parse*, const char*, ...); void sqlite3Dequote(char*); int sqlite3KeywordCode(const char*, int); @@ -1419,7 +1408,7 @@ void sqlite3OpenTable(Vdbe*, int iCur, Table*, int); void sqlite3DeleteFrom(Parse*, SrcList*, Expr*); void sqlite3Update(Parse*, SrcList*, ExprList*, Expr*, int); -WhereInfo *sqlite3WhereBegin(Parse*, SrcList*, Expr*, ExprList**, Fetch*); +WhereInfo *sqlite3WhereBegin(Parse*, SrcList*, Expr*, ExprList**); void sqlite3WhereEnd(WhereInfo*); void sqlite3ExprCode(Parse*, Expr*); void sqlite3ExprCodeAndCache(Parse*, Expr*); @@ -1573,5 +1562,11 @@ void sqlite3ColumnDefault(Vdbe *, Table *, int); void sqlite3AlterFinishAddColumn(Parse *, Token *); void sqlite3AlterBeginAddColumn(Parse *, SrcList *); +const char *sqlite3TestErrorName(int); +CollSeq *sqlite3GetCollSeq(sqlite3*, CollSeq *, const char *, int); +#ifdef SQLITE_SSE +#include "sseInt.h" #endif + +#endif --- sqlite/tokenize.c +++ sqlite/tokenize.c @@ -15,7 +15,7 @@ ** individual tokens and sends those tokens one-by-one over to the ** parser for analysis. ** -** $Id: tokenize.c,v 1.101 2005/02/26 17:31:27 drh Exp $ +** $Id: tokenize.c,v 1.103 2005/06/06 14:45:43 drh Exp $ */ #include "sqliteInt.h" #include "os.h" @@ -341,10 +341,10 @@ db->flags &= ~SQLITE_Interrupt; pParse->rc = SQLITE_OK; i = 0; - pEngine = sqlite3ParserAlloc((void*(*)(int))malloc); + pEngine = sqlite3ParserAlloc((void*(*)(int))sqlite3MallocX); if( pEngine==0 ){ sqlite3SetString(pzErrMsg, "out of memory", (char*)0); - return 1; + return SQLITE_NOMEM; } assert( pParse->sLastToken.dyn==0 ); assert( pParse->pNewTable==0 ); @@ -401,7 +401,7 @@ } sqlite3Parser(pEngine, 0, pParse->sLastToken, pParse); } - sqlite3ParserFree(pEngine, free); + sqlite3ParserFree(pEngine, sqlite3FreeX); if( sqlite3_malloc_failed ){ pParse->rc = SQLITE_NOMEM; } @@ -500,8 +500,14 @@ ** is look for a semicolon that is not part of an string or comment. */ int sqlite3_complete(const char *zSql){ + const char *tmp; + return sqlite3_complete_last(zSql, &tmp); +} + +int sqlite3_complete_last(const char *zSql, const char **last){ u8 state = 0; /* Current state, using numbers defined in header comment */ u8 token; /* Value of the next token */ + const char* lastseen = 0; #ifndef SQLITE_OMIT_TRIGGER /* A complex statement machine used to detect the end of a CREATE TRIGGER @@ -551,7 +557,7 @@ } zSql += 2; while( zSql[0] && (zSql[0]!='*' || zSql[1]!='/') ){ zSql++; } - if( zSql[0]==0 ) return 0; + if( zSql[0]==0 ) { *last = lastseen; return 0; } zSql++; token = tkWS; break; @@ -562,14 +568,14 @@ break; } while( *zSql && *zSql!='\n' ){ zSql++; } - if( *zSql==0 ) return state==0; + if( *zSql==0 ) { *last = lastseen; return state==0; } token = tkWS; break; } case '[': { /* Microsoft-style identifiers in [...] */ zSql++; while( *zSql && *zSql!=']' ){ zSql++; } - if( *zSql==0 ) return 0; + if( *zSql==0 ) { *last = lastseen; return 0; } token = tkOTHER; break; } @@ -578,7 +584,7 @@ int c = *zSql; zSql++; while( *zSql && *zSql!=c ){ zSql++; } - if( *zSql==0 ) return 0; + if( *zSql==0 ) { *last = lastseen; return 0; } token = tkOTHER; break; } @@ -641,8 +647,11 @@ } } state = trans[state][token]; + if (state == 0) + lastseen = zSql; zSql++; } + *last = lastseen; return state==0; } --- sqlite/trigger.c +++ sqlite/trigger.c @@ -215,7 +215,7 @@ */ if( !db->init.busy ){ static const VdbeOpList insertTrig[] = { - { OP_NewRecno, 0, 0, 0 }, + { OP_NewRowid, 0, 0, 0 }, { OP_String8, 0, 0, "trigger" }, { OP_String8, 0, 0, 0 }, /* 2: trigger name */ { OP_String8, 0, 0, 0 }, /* 3: table name */ @@ -224,7 +224,7 @@ { OP_String8, 0, 0, 0 }, /* 6: SQL */ { OP_Concat, 0, 0, 0 }, { OP_MakeRecord, 5, 0, "tttit" }, - { OP_PutIntKey, 0, 0, 0 }, + { OP_Insert, 0, 0, 0 }, }; int addr; Vdbe *v; --- sqlite/update.c +++ sqlite/update.c @@ -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.105 2005/03/09 12:26:51 danielk1977 Exp $ +** $Id: update.c,v 1.108 2005/06/12 21:35:53 drh Exp $ */ #include "sqliteInt.h" @@ -80,8 +80,8 @@ int *aXRef = 0; /* aXRef[i] is the index in pChanges->a[] of the ** an expression for the i-th column of the table. ** aXRef[i]==-1 if the i-th column is not changed. */ - int chngRecno; /* True if the record number is being changed */ - Expr *pRecnoExpr = 0; /* Expression defining the new record number */ + int chngRowid; /* True if the record number is being changed */ + Expr *pRowidExpr = 0; /* Expression defining the new record number */ int openAll = 0; /* True if all indices need to be opened */ AuthContext sContext; /* The authorization context */ NameContext sNC; /* The name-context to resolve expressions in */ @@ -160,7 +160,7 @@ ** column to be updated, make sure we have authorization to change ** that column. */ - chngRecno = 0; + chngRowid = 0; for(i=0; inExpr; i++){ if( sqlite3ExprResolveNames(&sNC, pChanges->a[i].pExpr) ){ goto update_cleanup; @@ -168,8 +168,8 @@ for(j=0; jnCol; j++){ if( sqlite3StrICmp(pTab->aCol[j].zName, pChanges->a[i].zName)==0 ){ if( j==pTab->iPKey ){ - chngRecno = 1; - pRecnoExpr = pChanges->a[i].pExpr; + chngRowid = 1; + pRowidExpr = pChanges->a[i].pExpr; } aXRef[j] = i; break; @@ -177,8 +177,8 @@ } if( j>=pTab->nCol ){ if( sqlite3IsRowid(pChanges->a[i].zName) ){ - chngRecno = 1; - pRecnoExpr = pChanges->a[i].pExpr; + chngRowid = 1; + pRowidExpr = pChanges->a[i].pExpr; }else{ sqlite3ErrorMsg(pParse, "no such column: %s", pChanges->a[i].zName); goto update_cleanup; @@ -204,7 +204,7 @@ ** number of the original table entry is changing. */ for(nIdx=nIdxTotal=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, nIdxTotal++){ - if( chngRecno ){ + if( chngRowid ){ i = 0; }else { for(i=0; inColumn; i++){ @@ -219,7 +219,7 @@ aIdxUsed = (char*)&apIdx[nIdx]; } for(nIdx=j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){ - if( chngRecno ){ + if( chngRowid ){ i = 0; }else{ for(i=0; inColumn; i++){ @@ -267,12 +267,12 @@ /* Begin the database scan */ - pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0, 0); + pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0); if( pWInfo==0 ) goto update_cleanup; /* Remember the index of every item to be updated. */ - sqlite3VdbeAddOp(v, OP_Recno, iCur, 0); + sqlite3VdbeAddOp(v, OP_Rowid, iCur, 0); sqlite3VdbeAddOp(v, OP_ListWrite, 0, 0); /* End the database scan loop. @@ -297,33 +297,33 @@ */ sqlite3VdbeAddOp(v, OP_ListRewind, 0, 0); addr = sqlite3VdbeAddOp(v, OP_ListRead, 0, 0); - sqlite3VdbeAddOp(v, OP_Dup, 0, 0); - /* Open a cursor and make it point to the record that is - ** being updated. - */ - sqlite3VdbeAddOp(v, OP_Dup, 0, 0); if( !isView ){ + sqlite3VdbeAddOp(v, OP_Dup, 0, 0); + sqlite3VdbeAddOp(v, OP_Dup, 0, 0); + /* Open a cursor and make it point to the record that is + ** being updated. + */ sqlite3OpenTableForReading(v, iCur, pTab); } sqlite3VdbeAddOp(v, OP_MoveGe, iCur, 0); /* Generate the OLD table */ - sqlite3VdbeAddOp(v, OP_Recno, iCur, 0); + sqlite3VdbeAddOp(v, OP_Rowid, iCur, 0); sqlite3VdbeAddOp(v, OP_RowData, iCur, 0); - sqlite3VdbeAddOp(v, OP_PutIntKey, oldIdx, 0); + sqlite3VdbeAddOp(v, OP_Insert, oldIdx, 0); /* Generate the NEW table */ - if( chngRecno ){ - sqlite3ExprCodeAndCache(pParse, pRecnoExpr); + if( chngRowid ){ + sqlite3ExprCodeAndCache(pParse, pRowidExpr); }else{ - sqlite3VdbeAddOp(v, OP_Recno, iCur, 0); + sqlite3VdbeAddOp(v, OP_Rowid, iCur, 0); } for(i=0; inCol; i++){ if( i==pTab->iPKey ){ - sqlite3VdbeAddOp(v, OP_String8, 0, 0); + sqlite3VdbeAddOp(v, OP_Null, 0, 0); continue; } j = aXRef[i]; @@ -339,7 +339,7 @@ sqlite3TableAffinityStr(v, pTab); } if( pParse->nErr ) goto update_cleanup; - sqlite3VdbeAddOp(v, OP_PutIntKey, newIdx, 0); + sqlite3VdbeAddOp(v, OP_Insert, newIdx, 0); if( !isView ){ sqlite3VdbeAddOp(v, OP_Close, iCur, 0); } @@ -399,8 +399,8 @@ ** will be after the update. (The old record number is currently ** on top of the stack.) */ - if( chngRecno ){ - sqlite3ExprCode(pParse, pRecnoExpr); + if( chngRowid ){ + sqlite3ExprCode(pParse, pRowidExpr); sqlite3VdbeAddOp(v, OP_MustBeInt, 0, 0); } @@ -408,7 +408,7 @@ */ for(i=0; inCol; i++){ if( i==pTab->iPKey ){ - sqlite3VdbeAddOp(v, OP_String8, 0, 0); + sqlite3VdbeAddOp(v, OP_Null, 0, 0); continue; } j = aXRef[i]; @@ -422,7 +422,7 @@ /* Do constraint checks */ - sqlite3GenerateConstraintChecks(pParse, pTab, iCur, aIdxUsed, chngRecno, 1, + sqlite3GenerateConstraintChecks(pParse, pTab, iCur, aIdxUsed, chngRowid, 1, onError, addr); /* Delete the old indices for the current record. @@ -431,13 +431,13 @@ /* If changing the record number, delete the old record. */ - if( chngRecno ){ + if( chngRowid ){ sqlite3VdbeAddOp(v, OP_Delete, iCur, 0); } /* Create the new index entries and the new record. */ - sqlite3CompleteInsertion(pParse, pTab, iCur, aIdxUsed, chngRecno, 1, -1); + sqlite3CompleteInsertion(pParse, pTab, iCur, aIdxUsed, chngRowid, 1, -1); } /* Increment the row counter --- sqlite/util.c +++ sqlite/util.c @@ -14,7 +14,7 @@ ** This file contains functions for allocating memory, comparing ** strings, and stuff like that. ** -** $Id: util.c,v 1.132 2005/03/18 14:03:15 drh Exp $ +** $Id: util.c,v 1.136 2005/06/06 15:06:39 drh Exp $ */ #include "sqliteInt.h" #include @@ -65,9 +65,11 @@ #endif /* -** Number of 32-bit guard words +** Number of 32-bit guard words. This should probably be a multiple of +** 2 since on 64-bit machines we want the value returned by sqliteMalloc() +** to be 8-byte aligned. */ -#define N_GUARD 1 +#define N_GUARD 2 /* ** Allocate new memory and set it to zero. Return NULL if @@ -111,6 +113,13 @@ } /* +** This version of malloc is always a real function, never a macro +*/ +void *sqlite3MallocX(int n){ + return sqlite3Malloc_(n, 0, __FILE__, __LINE__); +} + +/* ** Check to see if the given pointer was obtained from sqliteMalloc() ** and is able to hold at least N bytes. Raise an exception if this ** is not the case. @@ -338,15 +347,15 @@ ** point to that string. The 1st argument must either be NULL or ** point to memory obtained from sqliteMalloc(). */ -void sqlite3SetString(char **pz, const char *zFirst, ...){ +void sqlite3SetString(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); } @@ -356,9 +365,8 @@ 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); @@ -388,7 +396,7 @@ ** zFormat and any string tokens that follow it are assumed to be ** encoded in UTF-8. ** -** To clear the most recent error for slqite handle "db", sqlite3Error +** To clear the most recent error for sqlite handle "db", sqlite3Error ** should be called with err_code set to SQLITE_OK and zFormat set ** to NULL. */ --- sqlite/vacuum.c +++ sqlite/vacuum.c @@ -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.40 2005/02/16 03:27:05 drh Exp $ +** $Id: vacuum.c,v 1.45 2005/06/07 09:21:07 danielk1977 Exp $ */ #include "sqliteInt.h" #include "os.h" @@ -100,7 +100,12 @@ Btree *pMain; /* The database being vacuumed */ Btree *pTemp; char *zSql = 0; + int writeschema_flag; /* Saved value of the write-schema flag */ + /* Save the current value of the write-schema flag before setting it. */ + writeschema_flag = db->flags&SQLITE_WriteSchema; + db->flags |= SQLITE_WriteSchema; + if( !db->autoCommit ){ sqlite3SetString(pzErrMsg, "cannot VACUUM from within a transaction", (char*)0); @@ -276,6 +281,10 @@ } end_of_vacuum: + /* Restore the original value of the write-schema flag. */ + db->flags &= ~SQLITE_WriteSchema; + db->flags |= writeschema_flag; + /* Currently there is an SQL level transaction open on the vacuum ** database. No locks are held on any other files (since the main file ** was committed at the btree level). So it safe to end the transaction @@ -296,5 +305,6 @@ if( zSql ) sqliteFree( zSql ); sqlite3ResetInternalSchema(db, 0); #endif + return rc; } --- sqlite/vdbe.c +++ sqlite/vdbe.c @@ -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.463 2005/03/29 13:07:00 danielk1977 Exp $ +** $Id: vdbe.c,v 1.469 2005/06/12 21:35:53 drh Exp $ */ #include "sqliteInt.h" #include "os.h" @@ -717,7 +717,8 @@ #ifndef SQLITE_OMIT_UTF16 pOp->opcode = OP_String; - if( db->enc!=SQLITE_UTF8 && pOp->p3 ){ + assert( pOp->p3!=0 ); + if( db->enc!=SQLITE_UTF8 ){ pTos++; sqlite3VdbeMemSetStr(pTos, pOp->p3, -1, SQLITE_UTF8, SQLITE_STATIC); if( SQLITE_OK!=sqlite3VdbeChangeEncoding(pTos, db->enc) ) goto no_mem; @@ -743,26 +744,34 @@ */ case OP_String: { pTos++; - if( pOp->p3 ){ - pTos->flags = MEM_Str|MEM_Static|MEM_Term; - pTos->z = pOp->p3; + assert( pOp->p3!=0 ); + pTos->flags = MEM_Str|MEM_Static|MEM_Term; + pTos->z = pOp->p3; #ifndef SQLITE_OMIT_UTF16 - if( db->enc==SQLITE_UTF8 ){ - pTos->n = strlen(pTos->z); - }else{ - pTos->n = sqlite3utf16ByteLen(pTos->z, -1); - } -#else - assert( db->enc==SQLITE_UTF8 ); + if( db->enc==SQLITE_UTF8 ){ pTos->n = strlen(pTos->z); -#endif - pTos->enc = db->enc; }else{ - pTos->flags = MEM_Null; + pTos->n = sqlite3utf16ByteLen(pTos->z, -1); } +#else + assert( db->enc==SQLITE_UTF8 ); + pTos->n = strlen(pTos->z); +#endif + pTos->enc = db->enc; break; } +/* Opcode: Null * * * +** +** Push a NULL onto the stack. +*/ +case OP_Null: { + pTos++; + pTos->flags = MEM_Null; + break; +} + + #ifndef SQLITE_OMIT_BLOB_LITERAL /* Opcode: HexBlob * * P3 ** @@ -1316,7 +1325,7 @@ ** greater than its current value if P1==1. */ case OP_ForceInt: { /* no-push */ - int v; + i64 v; assert( pTos>=p->aStack ); applyAffinity(pTos, SQLITE_AFF_INTEGER, db->enc); if( (pTos->flags & (MEM_Int|MEM_Real))==0 ){ @@ -1373,11 +1382,11 @@ ** Pop the top two elements from the stack. If they are equal, then ** jump to instruction P2. Otherwise, continue to the next instruction. ** -** The least significant byte of P1 may be either 0x00 or 0x01. If either -** operand is NULL (and thus if the result is unknown) then take the jump -** only if the least significant byte of P1 is 0x01. +** If the 0x100 bit of P1 is true and either operand is NULL then take the +** jump. If the 0x100 bit of P1 is false then fall thru if either operand +** is NULL. ** -** The second least significant byte of P1 must be an affinity character - +** The least significant byte of P1 (mask 0xff) must be an affinity character - ** 'n', 't', 'i' or 'o' - or 0x00. An attempt is made to coerce both values ** according to the affinity before the comparison is made. If the byte is ** 0x00, then numeric affinity is used. @@ -1446,7 +1455,7 @@ if( flags&MEM_Null ){ popStack(&pTos, 2); if( pOp->p2 ){ - if( (pOp->p1&0xFF) ) pc = pOp->p2-1; + if( pOp->p1 & 0x100 ) pc = pOp->p2-1; }else{ pTos++; pTos->flags = MEM_Null; @@ -1454,7 +1463,7 @@ break; } - affinity = (pOp->p1>>8)&0xFF; + affinity = pOp->p1 & 0xFF; if( affinity ){ applyAffinity(pNos, affinity, db->enc); applyAffinity(pTos, affinity, db->enc); @@ -1639,7 +1648,11 @@ if( pTos->flags & MEM_Null ){ c = pOp->p1; }else{ +#ifdef SQLITE_OMIT_FLOATING_POINT c = sqlite3VdbeIntValue(pTos); +#else + c = sqlite3VdbeRealValue(pTos)!=0.0; +#endif if( pOp->opcode==OP_IfNot ) c = !c; } Release(pTos); @@ -1704,10 +1717,6 @@ assert( p->apCsr[pOp->p1]!=0 ); pC = p->apCsr[pOp->p1]; pC->nField = pOp->p2; - if( (!pC->keyAsData && pC->zeroData) || (pC->keyAsData && pC->intKey) ){ - rc = SQLITE_CORRUPT; - goto abort_due_to_error; - } break; } @@ -1791,7 +1800,7 @@ }else if( pC->cacheValid ){ payloadSize = pC->payloadSize; zRec = pC->aRow; - }else if( pC->keyAsData ){ + }else if( pC->isIndex ){ i64 payloadSize64; sqlite3BtreeKeySize(pCrsr, &payloadSize64); payloadSize = payloadSize64; @@ -1846,7 +1855,7 @@ if( zRec ){ zData = zRec; }else{ - if( pC->keyAsData ){ + if( pC->isIndex ){ zData = (char*)sqlite3BtreeKeyFetch(pCrsr, &avail); }else{ zData = (char*)sqlite3BtreeDataFetch(pCrsr, &avail); @@ -1872,7 +1881,7 @@ ** acquire the complete header text. */ if( !zRec && availkeyAsData, &sMem); + rc = sqlite3VdbeMemFromBtree(pCrsr, 0, szHdr, pC->isIndex, &sMem); if( rc!=SQLITE_OK ){ goto op_column_out; } @@ -1936,7 +1945,7 @@ zData = &zRec[aOffset[p2]]; }else{ len = sqlite3VdbeSerialTypeLen(aType[p2]); - rc = sqlite3VdbeMemFromBtree(pCrsr, aOffset[p2], len,pC->keyAsData,&sMem); + rc = sqlite3VdbeMemFromBtree(pCrsr, aOffset[p2], len, pC->isIndex,&sMem); if( rc!=SQLITE_OK ){ goto op_column_out; } @@ -2436,11 +2445,12 @@ rc = sqlite3BtreeCursor(pX, p2, wrFlag, sqlite3VdbeRecordCompare, pOp->p3, &pCur->pCursor); - pCur->pKeyInfo = (KeyInfo*)pOp->p3; - if( pCur->pKeyInfo ){ + if( pOp->p3type==P3_KEYINFO ){ + pCur->pKeyInfo = (KeyInfo*)pOp->p3; pCur->pIncrKey = &pCur->pKeyInfo->incrKey; pCur->pKeyInfo->enc = p->db->enc; }else{ + pCur->pKeyInfo = 0; pCur->pIncrKey = &pCur->bogusIncrKey; } switch( rc ){ @@ -2452,11 +2462,32 @@ } case SQLITE_OK: { int flags = sqlite3BtreeFlags(pCur->pCursor); - pCur->intKey = (flags & BTREE_INTKEY)!=0; - pCur->zeroData = (flags & BTREE_ZERODATA)!=0; + /* Sanity checking. Only the lower four bits of the flags byte should + ** be used. Bit 3 (mask 0x08) is unpreditable. The lower 3 bits + ** (mask 0x07) should be either 5 (intkey+leafdata for tables) or + ** 2 (zerodata for indices). If these conditions are not met it can + ** only mean that we are dealing with a corrupt database file + */ + if( (flags & 0xf0)!=0 || ((flags & 0x07)!=5 && (flags & 0x07)!=2) ){ + rc = SQLITE_CORRUPT; + goto abort_due_to_error; + } + pCur->isTable = (flags & BTREE_INTKEY)!=0; + pCur->isIndex = (flags & BTREE_ZERODATA)!=0; + /* If P3==0 it means we are expected to open a table. If P3!=0 then + ** we expect to be opening an index. If this is not what happened, + ** then the database is corrupt + */ + if( (pCur->isTable && pOp->p3type==P3_KEYINFO) + || (pCur->isIndex && pOp->p3type!=P3_KEYINFO) ){ + rc = SQLITE_CORRUPT; + goto abort_due_to_error; + } break; } case SQLITE_EMPTY: { + pCur->isTable = pOp->p3type!=P3_KEYINFO; + pCur->isIndex = !pCur->isTable; rc = SQLITE_OK; break; } @@ -2514,12 +2545,14 @@ pCx->pKeyInfo->enc = p->db->enc; pCx->pIncrKey = &pCx->pKeyInfo->incrKey; } + pCx->isTable = 0; }else{ rc = sqlite3BtreeCursor(pCx->pBt, MASTER_ROOT, 1, 0, 0, &pCx->pCursor); - pCx->intKey = 1; + pCx->isTable = 1; pCx->pIncrKey = &pCx->bogusIncrKey; } } + pCx->isIndex = !pCx->isTable; break; } @@ -2543,6 +2576,8 @@ pCx->nullRow = 1; pCx->pseudoTable = 1; pCx->pIncrKey = &pCx->bogusIncrKey; + pCx->isTable = 1; + pCx->isIndex = 0; break; } #endif @@ -2617,7 +2652,7 @@ oc = pOp->opcode; pC->nullRow = 0; *pC->pIncrKey = oc==OP_MoveGt || oc==OP_MoveLe; - if( pC->intKey ){ + if( pC->isTable ){ i64 iKey; Integerify(pTos); iKey = intToKey(pTos->i); @@ -2632,15 +2667,15 @@ if( rc!=SQLITE_OK ){ goto abort_due_to_error; } - pC->lastRecno = pTos->i; - pC->recnoIsValid = res==0; + pC->lastRowid = pTos->i; + pC->rowidIsValid = res==0; }else{ Stringify(pTos, db->enc); rc = sqlite3BtreeMoveto(pC->pCursor, pTos->z, pTos->n, &res); if( rc!=SQLITE_OK ){ goto abort_due_to_error; } - pC->recnoIsValid = 0; + pC->rowidIsValid = 0; } pC->deferredMoveto = 0; pC->cacheValid = 0; @@ -2650,7 +2685,7 @@ if( res<0 ){ rc = sqlite3BtreeNext(pC->pCursor, &res); if( rc!=SQLITE_OK ) goto abort_due_to_error; - pC->recnoIsValid = 0; + pC->rowidIsValid = 0; }else{ res = 0; } @@ -2659,7 +2694,7 @@ if( res>=0 ){ rc = sqlite3BtreePrevious(pC->pCursor, &res); if( rc!=SQLITE_OK ) goto abort_due_to_error; - pC->recnoIsValid = 0; + pC->rowidIsValid = 0; }else{ /* res might be negative because the table is empty. Check to ** see if this is the case. @@ -2682,31 +2717,46 @@ /* Opcode: Distinct P1 P2 * ** -** Use the top of the stack as a string key. If a record with that key does -** not exist in the table of cursor P1, then jump to P2. If the record -** does already exist, then fall thru. The cursor is left pointing -** at the record if it exists. The key is not popped from the stack. +** Use the top of the stack as a record created using MakeRecord. P1 is a +** cursor on a table that declared as an index. If that table contains an +** entry that matches the top of the stack fall thru. If the top of the stack +** matches no entry in P1 then jump to P2. ** -** This operation is similar to NotFound except that this operation +** The cursor is left pointing at the matching entry if it exists. The +** record on the top of the stack is not popped. +** +** This instruction is similar to NotFound except that this operation ** does not pop the key from the stack. ** +** The instruction is used to implement the DISTINCT operator on SELECT +** statements. The P1 table is not a true index but rather a record of +** all results that have produced so far. +** ** See also: Found, NotFound, MoveTo, IsUnique, NotExists */ /* Opcode: Found P1 P2 * ** -** Use the top of the stack as a string key. If a record with that key -** does exist in table of P1, then jump to P2. If the record -** does not exist, then fall thru. The cursor is left pointing -** to the record if it exists. The key is popped from the stack. +** Top of the stack holds a blob constructed by MakeRecord. P1 is an index. +** If an entry that matches the top of the stack exists in P1 then +** jump to P2. If the top of the stack does not match any entry in P1 +** then fall thru. The P1 cursor is left pointing at the matching entry +** if it exists. The blob is popped off the top of the stack. ** +** This instruction is used to implement the IN operator where the +** left-hand side is a SELECT statement. P1 is not a true index but +** is instead a temporary index that holds the results of the SELECT +** statement. This instruction just checks to see if the left-hand side +** of the IN operator (stored on the top of the stack) exists in the +** result of the SELECT statement. +** ** See also: Distinct, NotFound, MoveTo, IsUnique, NotExists */ /* Opcode: NotFound P1 P2 * ** -** Use the top of the stack as a string key. If a record with that key -** does not exist in table of P1, then jump to P2. If the record -** does exist, then fall thru. The cursor is left pointing to the -** record if it exists. The key is popped from the stack. +** The top of the stack holds a blob constructed by MakeRecord. P1 is +** an index. If no entry exists in P1 that matches the blob then jump +** to P1. If an entry does existing, fall through. The cursor is left +** pointing to the entry that matches. The blob is popped from the stack. ** ** The difference between this operation and Distinct is that ** Distinct does not pop the key from the stack. @@ -2724,7 +2774,7 @@ assert( p->apCsr[i]!=0 ); if( (pC = p->apCsr[i])->pCursor!=0 ){ int res, rx; - assert( pC->intKey==0 ); + assert( pC->isTable==0 ); Stringify(pTos, db->enc); rx = sqlite3BtreeMoveto(pC->pCursor, pTos->z, pTos->n, &res); alreadyExists = rx==SQLITE_OK && res==0; @@ -2751,8 +2801,8 @@ ** stack but it leaves K unchanged. ** ** P1 is an index. So it has no data and its key consists of a -** record generated by OP_MakeIdxKey. This key contains one or more -** fields followed by a ROWID field. +** record generated by OP_MakeRecord where the last field is the +** rowid of the entry that the index refers to. ** ** This instruction asks if there is an entry in P1 where the ** fields matches K but the rowid is different from R. @@ -2853,8 +2903,9 @@ ** record if it exists. The integer key is popped from the stack. ** ** The difference between this operation and NotFound is that this -** operation assumes the key is an integer and NotFound assumes it -** is a string. +** operation assumes the key is an integer and that P1 is a table whereas +** NotFound assumes key is a blob constructed from MakeRecord and +** P1 is an index. ** ** See also: Distinct, Found, MoveTo, NotFound, IsUnique */ @@ -2869,16 +2920,16 @@ int res; u64 iKey; assert( pTos->flags & MEM_Int ); - assert( p->apCsr[i]->intKey ); + assert( p->apCsr[i]->isTable ); iKey = intToKey(pTos->i); rc = sqlite3BtreeMoveto(pCrsr, 0, iKey, &res); - pC->lastRecno = pTos->i; - pC->recnoIsValid = res==0; + pC->lastRowid = pTos->i; + pC->rowidIsValid = res==0; pC->nullRow = 0; pC->cacheValid = 0; if( res!=0 ){ pc = pOp->p2 - 1; - pC->recnoIsValid = 0; + pC->rowidIsValid = 0; } } Release(pTos); @@ -2886,9 +2937,9 @@ break; } -/* Opcode: NewRecno P1 P2 * +/* Opcode: NewRowid P1 P2 * ** -** Get a new integer record number used as the key to a table. +** Get a new integer record number (a.k.a "rowid") used as the key to a table. ** The record number is not previously used as a key in the database ** table that cursor P1 points to. The new record number is pushed ** onto the stack. @@ -2900,7 +2951,7 @@ ** record number. This P2 mechanism is used to help implement the ** AUTOINCREMENT feature. */ -case OP_NewRecno: { +case OP_NewRowid: { int i = pOp->p1; i64 v = 0; Cursor *pC; @@ -3028,7 +3079,7 @@ goto abort_due_to_error; } } - pC->recnoIsValid = 0; + pC->rowidIsValid = 0; pC->deferredMoveto = 0; pC->cacheValid = 0; } @@ -3038,7 +3089,7 @@ break; } -/* Opcode: PutIntKey P1 P2 * +/* Opcode: Insert P1 P2 * ** ** Write an entry into the table of cursor P1. A new entry is ** created if it doesn't already exist or the data for an existing @@ -3050,19 +3101,11 @@ ** incremented (otherwise not). If the OPFLAG_LASTROWID flag of P2 is set, ** then rowid is stored for subsequent return by the ** sqlite3_last_insert_rowid() function (otherwise it's unmodified). -*/ -/* Opcode: PutStrKey P1 * * ** -** Write an entry into the table of cursor P1. A new entry is -** created if it doesn't already exist or the data for an existing -** entry is overwritten. The data is the value on the top of the -** stack. The key is the next value down on the stack. The key must -** be a string. The stack is popped twice by this instruction. -** -** P1 may not be a pseudo-table opened using the OpenPseudo opcode. +** This instruction only works on tables. The equivalent instruction +** for indices is OP_IdxInsert. */ -case OP_PutIntKey: /* no-push */ -case OP_PutStrKey: { /* no-push */ +case OP_Insert: { /* no-push */ Mem *pNos = &pTos[-1]; int i = pOp->p1; Cursor *pC; @@ -3070,35 +3113,16 @@ assert( i>=0 && inCursor ); assert( p->apCsr[i]!=0 ); if( ((pC = p->apCsr[i])->pCursor!=0 || pC->pseudoTable) ){ - char *zKey; - i64 nKey; - i64 iKey; - if( pOp->opcode==OP_PutStrKey ){ - Stringify(pNos, db->enc); - nKey = pNos->n; - zKey = pNos->z; - }else{ - assert( pNos->flags & MEM_Int ); + i64 iKey; /* The integer ROWID or key for the record to be inserted */ - /* If the table is an INTKEY table, set nKey to the value of - ** the integer key, and zKey to NULL. Otherwise, set nKey to - ** sizeof(i64) and point zKey at iKey. iKey contains the integer - ** key in the on-disk byte order. - */ - iKey = intToKey(pNos->i); - if( pC->intKey ){ - nKey = intToKey(pNos->i); - zKey = 0; - }else{ - nKey = sizeof(i64); - zKey = (char*)&iKey; - } + assert( pNos->flags & MEM_Int ); + assert( pC->isTable ); + iKey = intToKey(pNos->i); - if( pOp->p2 & OPFLAG_NCHANGE ) p->nChange++; - if( pOp->p2 & OPFLAG_LASTROWID ) db->lastRowid = pNos->i; - if( pC->nextRowidValid && pTos->i>=pC->nextRowid ){ - pC->nextRowidValid = 0; - } + if( pOp->p2 & OPFLAG_NCHANGE ) p->nChange++; + if( pOp->p2 & OPFLAG_LASTROWID ) db->lastRowid = pNos->i; + if( pC->nextRowidValid && pTos->i>=pC->nextRowid ){ + pC->nextRowidValid = 0; } if( pTos->flags & MEM_Null ){ pTos->z = 0; @@ -3108,11 +3132,6 @@ } #ifndef SQLITE_OMIT_TRIGGER if( pC->pseudoTable ){ - /* PutStrKey does not work for pseudo-tables. - ** The following assert makes sure we are not trying to use - ** PutStrKey on a pseudo-table - */ - assert( pOp->opcode==OP_PutIntKey ); sqliteFree(pC->pData); pC->iKey = iKey; pC->nData = pTos->n; @@ -3129,12 +3148,12 @@ pC->nullRow = 0; }else{ #endif - rc = sqlite3BtreeInsert(pC->pCursor, zKey, nKey, pTos->z, pTos->n); + rc = sqlite3BtreeInsert(pC->pCursor, 0, iKey, pTos->z, pTos->n); #ifndef SQLITE_OMIT_TRIGGER } #endif - pC->recnoIsValid = 0; + pC->rowidIsValid = 0; pC->deferredMoveto = 0; pC->cacheValid = 0; } @@ -3188,23 +3207,6 @@ break; } -/* Opcode: KeyAsData P1 P2 * -** -** Turn the key-as-data mode for cursor P1 either on (if P2==1) or -** off (if P2==0). In key-as-data mode, the OP_Column opcode pulls -** data off of the key rather than the data. This is used for -** processing compound selects. -*/ -case OP_KeyAsData: { /* no-push */ - int i = pOp->p1; - Cursor *pC; - assert( i>=0 && inCursor ); - pC = p->apCsr[i]; - assert( pC!=0 ); - pC->keyAsData = pOp->p2; - break; -} - /* Opcode: RowData P1 * * ** ** Push onto the stack the complete row data for cursor P1. @@ -3229,9 +3231,12 @@ Cursor *pC; u32 n; + /* Note that RowKey and RowData are really exactly the same instruction */ pTos++; assert( i>=0 && inCursor ); pC = p->apCsr[i]; + assert( pC->isTable || pOp->opcode==OP_RowKey ); + assert( pC->isIndex || pOp->opcode==OP_RowData ); assert( pC!=0 ); if( pC->nullRow ){ pTos->flags = MEM_Null; @@ -3242,9 +3247,9 @@ if( pC->nullRow ){ pTos->flags = MEM_Null; break; - }else if( pC->keyAsData || pOp->opcode==OP_RowKey ){ + }else if( pC->isIndex ){ i64 n64; - assert( !pC->intKey ); + assert( !pC->isTable ); sqlite3BtreeKeySize(pCrsr, &n64); n = n64; }else{ @@ -3261,7 +3266,7 @@ pTos->xDel = 0; pTos->z = z; } - if( pC->keyAsData || pOp->opcode==OP_RowKey ){ + if( pC->isIndex ){ sqlite3BtreeKey(pCrsr, 0, n, pTos->z); }else{ sqlite3BtreeData(pCrsr, 0, n, pTos->z); @@ -3278,14 +3283,12 @@ break; } -/* Opcode: Recno P1 * * +/* Opcode: Rowid P1 * * ** -** Push onto the stack an integer which is the first 4 bytes of the -** the key to the current entry in a sequential scan of the database -** file P1. The sequential scan should have been started using the -** Next opcode. +** Push onto the stack an integer which is the key of the table entry that +** P1 is currently point to. */ -case OP_Recno: { +case OP_Rowid: { int i = pOp->p1; Cursor *pC; i64 v; @@ -3296,8 +3299,8 @@ rc = sqlite3VdbeCursorMoveto(pC); if( rc ) goto abort_due_to_error; pTos++; - if( pC->recnoIsValid ){ - v = pC->lastRecno; + if( pC->rowidIsValid ){ + v = pC->lastRowid; }else if( pC->pseudoTable ){ v = keyToInt(pC->iKey); }else if( pC->nullRow || pC->pCursor==0 ){ @@ -3313,58 +3316,6 @@ break; } -#ifndef SQLITE_OMIT_COMPOUND_SELECT -/* Opcode: FullKey P1 * * -** -** Extract the complete key from the record that cursor P1 is currently -** pointing to and push the key onto the stack as a string. -** -** Compare this opcode to Recno. The Recno opcode extracts the first -** 4 bytes of the key and pushes those bytes onto the stack as an -** integer. This instruction pushes the entire key as a string. -** -** This opcode may not be used on a pseudo-table. -*/ -case OP_FullKey: { - int i = pOp->p1; - BtCursor *pCrsr; - Cursor *pC; - - assert( i>=0 && inCursor ); - assert( p->apCsr[i]!=0 ); - assert( p->apCsr[i]->keyAsData ); - assert( !p->apCsr[i]->pseudoTable ); - pTos++; - pTos->flags = MEM_Null; - if( (pCrsr = (pC = p->apCsr[i])->pCursor)!=0 ){ - i64 amt; - char *z; - - rc = sqlite3VdbeCursorMoveto(pC); - if( rc ) goto abort_due_to_error; - assert( pC->intKey==0 ); - sqlite3BtreeKeySize(pCrsr, &amt); - if( amt<=0 ){ - rc = SQLITE_CORRUPT; - goto abort_due_to_error; - } - if( amt>NBFS ){ - z = sqliteMallocRaw( amt ); - if( z==0 ) goto no_mem; - pTos->flags = MEM_Blob | MEM_Dyn; - pTos->xDel = 0; - }else{ - z = pTos->zShort; - pTos->flags = MEM_Blob | MEM_Short; - } - sqlite3BtreeKey(pCrsr, 0, amt, z); - pTos->z = z; - pTos->n = amt; - } - break; -} -#endif - /* Opcode: NullRow P1 * * ** ** Move the cursor P1 to a null row. Any OP_Column operations @@ -3379,13 +3330,13 @@ pC = p->apCsr[i]; assert( pC!=0 ); pC->nullRow = 1; - pC->recnoIsValid = 0; + pC->rowidIsValid = 0; break; } /* Opcode: Last P1 P2 * ** -** The next use of the Recno or Column or Next instruction for P1 +** The next use of the Rowid or Column or Next instruction for P1 ** will refer to the last entry in the database table or index. ** If the table or index is empty and P2>0, then jump immediately to P2. ** If P2 is 0 or if the table or index is not empty, fall through @@ -3416,7 +3367,7 @@ /* Opcode: Rewind P1 P2 * ** -** The next use of the Recno or Column or Next instruction for P1 +** The next use of the Rowid or Column or Next instruction for P1 ** will refer to the first entry in the database table or index. ** If the table or index is empty and P2>0, then jump immediately to P2. ** If P2 is 0 or if the table or index is not empty, fall through @@ -3489,11 +3440,11 @@ }else{ pC->nullRow = 1; } - pC->recnoIsValid = 0; + pC->rowidIsValid = 0; break; } -/* Opcode: IdxPut P1 P2 P3 +/* Opcode: IdxInsert P1 P2 P3 ** ** The top of the stack holds a SQL index key made using the ** MakeIdxKey instruction. This opcode writes that key into the @@ -3503,8 +3454,11 @@ ** the program aborts with a SQLITE_CONSTRAINT error and the database ** is rolled back. If P3 is not null, then it becomes part of the ** error message returned with the SQLITE_CONSTRAINT. +** +** This instruction only works for indices. The equivalent instruction +** for tables is OP_Insert. */ -case OP_IdxPut: { /* no-push */ +case OP_IdxInsert: { /* no-push */ int i = pOp->p1; Cursor *pC; BtCursor *pCrsr; @@ -3541,7 +3495,7 @@ } } } - assert( pC->intKey==0 ); + assert( pC->isTable==0 ); rc = sqlite3BtreeInsert(pCrsr, zKey, nKey, "", 0); assert( pC->deferredMoveto==0 ); pC->cacheValid = 0; @@ -3578,15 +3532,15 @@ break; } -/* Opcode: IdxRecno P1 * * +/* Opcode: IdxRowid P1 * * ** -** Push onto the stack an integer which is the varint located at the -** end of the index key pointed to by cursor P1. This integer should be -** the record number of the table entry to which this index entry points. +** Push onto the stack an integer which is the last entry in the record at +** the end of the index key pointed to by cursor P1. This integer should be +** the rowid of the table entry to which this index entry points. ** -** See also: Recno, MakeIdxKey. +** See also: Rowid, MakeIdxKey. */ -case OP_IdxRecno: { +case OP_IdxRowid: { int i = pOp->p1; BtCursor *pCrsr; Cursor *pC; @@ -3599,7 +3553,7 @@ i64 rowid; assert( pC->deferredMoveto==0 ); - assert( pC->intKey==0 ); + assert( pC->isTable==0 ); if( pC->nullRow ){ pTos->flags = MEM_Null; }else{ @@ -4104,21 +4058,26 @@ } #endif /* #ifndef SQLITE_OMIT_TRIGGER */ -/* Opcode: SortPut * * * +/* Opcode: SortInsert * * * ** ** The TOS is the key and the NOS is the data. Pop both from the stack ** and put them on the sorter. The key and data should have been ** made using the MakeRecord opcode. */ -case OP_SortPut: { /* no-push */ +case OP_SortInsert: { /* no-push */ Mem *pNos = &pTos[-1]; Sorter *pSorter; assert( pNos>=p->aStack ); if( Dynamicify(pTos, db->enc) ) goto no_mem; pSorter = sqliteMallocRaw( sizeof(Sorter) ); if( pSorter==0 ) goto no_mem; - pSorter->pNext = p->pSort; - p->pSort = pSorter; + pSorter->pNext = 0; + if( p->pSortTail ){ + p->pSortTail->pNext = pSorter; + }else{ + p->pSort = pSorter; + } + p->pSortTail = pSorter; assert( pTos->flags & MEM_Dyn ); pSorter->nKey = pTos->n; pSorter->zKey = pTos->z; @@ -4332,11 +4291,16 @@ break; } -/* Opcode: AggInit * P2 P3 +/* Opcode: AggInit P1 P2 P3 ** ** Initialize the function parameters for an aggregate function. ** The aggregate will operate out of aggregate column P2. ** P3 is a pointer to the FuncDef structure for the function. +** +** The P1 argument is not used by this opcode. However if the SSE +** extension is compiled in, P1 is set to the number of arguments that +** will be passed to the aggregate function, if any. This is used +** by SSE to select the correct function when (de)serializing statements. */ case OP_AggInit: { /* no-push */ int i = pOp->p2; --- sqlite/vdbe.h +++ sqlite/vdbe.h @@ -15,7 +15,7 @@ ** or VDBE. The VDBE implements an abstract machine that runs a ** simple program to access and modify the underlying database. ** -** $Id: vdbe.h,v 1.94 2005/03/23 01:48:48 drh Exp $ +** $Id: vdbe.h,v 1.95 2005/05/19 08:43:00 danielk1977 Exp $ */ #ifndef _SQLITE_VDBE_H_ #define _SQLITE_VDBE_H_ @@ -38,7 +38,7 @@ int p1; /* First operand */ int p2; /* Second parameter (often the jump destination) */ char *p3; /* Third parameter */ - int p3type; /* P3_STATIC, P3_DYNAMIC or P3_POINTER */ + int p3type; /* One of the P3_xxx constants defined below */ #ifdef VDBE_PROFILE int cnt; /* Number of times this instruction was executed */ long long cycles; /* Total time spend executing this instruction */ @@ -64,7 +64,6 @@ #define P3_NOTUSED 0 /* The P3 parameter is not used */ #define P3_DYNAMIC (-1) /* Pointer to a string obtained from sqliteMalloc() */ #define P3_STATIC (-2) /* Pointer to a static string */ -#define P3_POINTER (-3) /* P3 is a pointer to some structure or object */ #define P3_COLLSEQ (-4) /* P3 is a pointer to a CollSeq structure */ #define P3_FUNCDEF (-5) /* P3 is a pointer to a FuncDef structure */ #define P3_KEYINFO (-6) /* P3 is a pointer to a KeyInfo structure */ --- sqlite/vdbeInt.h +++ sqlite/vdbeInt.h @@ -60,19 +60,18 @@ */ struct Cursor { BtCursor *pCursor; /* The cursor structure of the backend */ - i64 lastRecno; /* Last recno from a Next or NextIdx operation */ + i64 lastRowid; /* Last rowid from a Next or NextIdx operation */ i64 nextRowid; /* Next rowid returned by OP_NewRowid */ Bool zeroed; /* True if zeroed out and ready for reuse */ - Bool recnoIsValid; /* True if lastRecno is valid */ - Bool keyAsData; /* The OP_Column command works on key instead of data */ + Bool rowidIsValid; /* True if lastRowid is valid */ Bool atFirst; /* True if pointing to first entry */ Bool useRandomRowid; /* Generate new record numbers semi-randomly */ Bool nullRow; /* True if pointing to a row with no data */ Bool nextRowidValid; /* True if the nextRowid field is valid */ Bool pseudoTable; /* This is a NEW or OLD pseudo-tables of a trigger */ Bool deferredMoveto; /* A call to sqlite3BtreeMoveto() is needed */ - Bool intKey; /* True if the table requires integer keys */ - Bool zeroData; /* True if table contains keys only - no data */ + Bool isTable; /* True if a table requiring integer keys */ + Bool isIndex; /* True if an index containing keys only - no data */ u8 bogusIncrKey; /* Something for pIncrKey to point to if pKeyInfo==0 */ i64 movetoTarget; /* Argument to the deferred sqlite3BtreeMoveto() */ Btree *pBt; /* Separate file holding temporary table */ @@ -314,6 +313,7 @@ int nCursor; /* Number of slots in apCsr[] */ Cursor **apCsr; /* One element of this array for each open cursor */ Sorter *pSort; /* A linked list of objects to be sorted */ + Sorter *pSortTail; /* Last element on the pSort list */ int nVar; /* Number of entries in aVar[] */ Mem *aVar; /* Values for the OP_Variable opcode. */ char **azVar; /* Name of variables */ --- sqlite/vdbeapi.c +++ sqlite/vdbeapi.c @@ -23,8 +23,6 @@ ** that sqlite3_prepare() generates. For example, if new functions or ** collating sequences are registered or if an authorizer function is ** added or changed. -** -***** EXPERIMENTAL ****** */ int sqlite3_expired(sqlite3_stmt *pStmt){ Vdbe *p = (Vdbe*)pStmt; @@ -383,8 +381,18 @@ /* ** Convert the N-th element of pStmt->pColName[] into a string using ** xFunc() then return that string. If N is out of range, return 0. -** If useType is 1, then use the second set of N elements (the datatype -** names) instead of the first set. +** +** There are up to 5 names for each column. useType determines which +** name is returned. Here are the names: +** +** 0 The column name as it should be displayed for output +** 1 The datatype name for the column +** 2 The name of the database that the column derives from +** 3 The name of the table that the column derives from +** 4 The name of the table column that the result column derives from +** +** If the result is not a simple column reference (if it is an expression +** or a constant) then useTypes 2, 3, and 4 return NULL. */ static const void *columnName( sqlite3_stmt *pStmt, @@ -398,9 +406,7 @@ if( p==0 || N>=n || N<0 ){ return 0; } - if( useType ){ - N += n; - } + N += useType*n; return xFunc(&p->aColName[N]); } @@ -412,33 +418,72 @@ const char *sqlite3_column_name(sqlite3_stmt *pStmt, int N){ return columnName(pStmt, N, (const void*(*)(Mem*))sqlite3_value_text, 0); } +#ifndef SQLITE_OMIT_UTF16 +const void *sqlite3_column_name16(sqlite3_stmt *pStmt, int N){ + return columnName(pStmt, N, (const void*(*)(Mem*))sqlite3_value_text16, 0); +} +#endif /* ** Return the column declaration type (if applicable) of the 'i'th column -** of the result set of SQL statement pStmt, encoded as UTF-8. +** of the result set of SQL statement pStmt. */ const char *sqlite3_column_decltype(sqlite3_stmt *pStmt, int N){ return columnName(pStmt, N, (const void*(*)(Mem*))sqlite3_value_text, 1); } +#ifndef SQLITE_OMIT_UTF16 +const void *sqlite3_column_decltype16(sqlite3_stmt *pStmt, int N){ + return columnName(pStmt, N, (const void*(*)(Mem*))sqlite3_value_text16, 1); +} +#endif /* SQLITE_OMIT_UTF16 */ +#if !defined(SQLITE_OMIT_ORIGIN_NAMES) && 0 +/* +** Return the name of the database from which a result column derives. +** NULL is returned if the result column is an expression or constant or +** anything else which is not an unabiguous reference to a database column. +*/ +const char *sqlite3_column_database_name(sqlite3_stmt *pStmt, int N){ + return columnName(pStmt, N, (const void*(*)(Mem*))sqlite3_value_text, 2); +} #ifndef SQLITE_OMIT_UTF16 +const void *sqlite3_column_database_name16(sqlite3_stmt *pStmt, int N){ + return columnName(pStmt, N, (const void*(*)(Mem*))sqlite3_value_text16, 2); +} +#endif /* SQLITE_OMIT_UTF16 */ + /* -** Return the name of the 'i'th column of the result set of SQL statement -** pStmt, encoded as UTF-16. +** Return the name of the table from which a result column derives. +** NULL is returned if the result column is an expression or constant or +** anything else which is not an unabiguous reference to a database column. */ -const void *sqlite3_column_name16(sqlite3_stmt *pStmt, int N){ - return columnName(pStmt, N, (const void*(*)(Mem*))sqlite3_value_text16, 0); +const char *sqlite3_column_table_name(sqlite3_stmt *pStmt, int N){ + return columnName(pStmt, N, (const void*(*)(Mem*))sqlite3_value_text, 3); } +#ifndef SQLITE_OMIT_UTF16 +const void *sqlite3_column_table_name16(sqlite3_stmt *pStmt, int N){ + return columnName(pStmt, N, (const void*(*)(Mem*))sqlite3_value_text16, 3); +} +#endif /* SQLITE_OMIT_UTF16 */ /* -** Return the column declaration type (if applicable) of the 'i'th column -** of the result set of SQL statement pStmt, encoded as UTF-16. +** Return the name of the table column from which a result column derives. +** NULL is returned if the result column is an expression or constant or +** anything else which is not an unabiguous reference to a database column. */ -const void *sqlite3_column_decltype16(sqlite3_stmt *pStmt, int N){ - return columnName(pStmt, N, (const void*(*)(Mem*))sqlite3_value_text16, 1); +const char *sqlite3_column_origin_name(sqlite3_stmt *pStmt, int N){ + return columnName(pStmt, N, (const void*(*)(Mem*))sqlite3_value_text, 4); } +#ifndef SQLITE_OMIT_UTF16 +const void *sqlite3_column_origin_name16(sqlite3_stmt *pStmt, int N){ + return columnName(pStmt, N, (const void*(*)(Mem*))sqlite3_value_text16, 4); +} #endif /* SQLITE_OMIT_UTF16 */ +#endif /* SQLITE_OMIT_ORIGIN_NAMES */ + + + /******************************* sqlite3_bind_ *************************** ** ** Routines used to attach values to wildcards in a compiled SQL statement. @@ -454,7 +499,7 @@ static int vdbeUnbind(Vdbe *p, int i){ Mem *pVar; if( p==0 || p->magic!=VDBE_MAGIC_RUN || p->pc>=0 ){ - sqlite3Error(p->db, SQLITE_MISUSE, 0); + if( p ) sqlite3Error(p->db, SQLITE_MISUSE, 0); return SQLITE_MISUSE; } if( i<1 || i>p->nVar ){ @@ -622,3 +667,35 @@ } return 0; } + +/* +** Transfer all bindings from the first statement over to the second. +** If the two statements contain a different number of bindings, then +** an SQLITE_ERROR is returned. +*/ +int sqlite3_transfer_bindings(sqlite3_stmt *pFromStmt, sqlite3_stmt *pToStmt){ + Vdbe *pFrom = (Vdbe*)pFromStmt; + Vdbe *pTo = (Vdbe*)pToStmt; + int i, rc = SQLITE_OK; + if( (pFrom->magic!=VDBE_MAGIC_RUN && pFrom->magic!=VDBE_MAGIC_HALT) + || (pTo->magic!=VDBE_MAGIC_RUN && pTo->magic!=VDBE_MAGIC_HALT) ){ + return SQLITE_MISUSE; + } + if( pFrom->nVar!=pTo->nVar ){ + return SQLITE_ERROR; + } + for(i=0; rc==SQLITE_OK && inVar; i++){ + rc = sqlite3VdbeMemMove(&pTo->aVar[i], &pFrom->aVar[i]); + } + return rc; +} + +/* +** Return the sqlite3* database handle to which the prepared statement given +** in the argument belongs. This is the same database handle that was +** the first argument to the sqlite3_prepare() that was used to create +** the statement in the first place. +*/ +sqlite3 *sqlite3_db_handle(sqlite3_stmt *pStmt){ + return pStmt ? ((Vdbe*)pStmt)->db : 0; +} --- sqlite/vdbeaux.c +++ sqlite/vdbeaux.c @@ -191,7 +191,7 @@ ** error if someone builds with an awk that uses (for example) 32-bit ** IEEE floats. */ - static u32 masks[5] = { + static const u32 masks[5] = { NOPUSH_MASK_0 + (NOPUSH_MASK_1<<16), NOPUSH_MASK_2 + (NOPUSH_MASK_3<<16), NOPUSH_MASK_4 + (NOPUSH_MASK_5<<16), @@ -220,6 +220,12 @@ ** ** The integer *pMaxStack is set to the maximum number of vdbe stack ** entries that static analysis reveals this program might need. +** +** This routine also does the following optimization: It scans for +** Halt instructions where P1==SQLITE_CONSTRAINT or P2==OE_Abort or for +** IdxInsert instructions where P2!=0. If no such instruction is +** found, then every Statement instruction is changed to a Noop. In +** this way, we avoid creating the statement journal file unnecessarily. */ static void resolveP2Values(Vdbe *p, int *pMaxFuncArgs, int *pMaxStack){ int i; @@ -227,6 +233,8 @@ int nMaxStack = p->nOp; Op *pOp; int *aLabel = p->aLabel; + int doesStatementRollback = 0; + int hasStatementBegin = 0; for(pOp=p->aOp, i=p->nOp-1; i>=0; i--, pOp++){ u8 opcode = pOp->opcode; @@ -237,6 +245,16 @@ if( pOp->p1>nMaxArgs ) nMaxArgs = pOp->p1; }else if( opcode==OP_AggFunc ){ if( pOp->p2>nMaxArgs ) nMaxArgs = pOp->p2; + }else if( opcode==OP_Halt ){ + if( pOp->p1==SQLITE_CONSTRAINT && pOp->p2==OE_Abort ){ + doesStatementRollback = 1; + } + }else if( opcode==OP_IdxInsert ){ + if( pOp->p2 ){ + doesStatementRollback = 1; + } + }else if( opcode==OP_Statement ){ + hasStatementBegin = 1; } if( opcodeNoPush(opcode) ){ @@ -252,6 +270,19 @@ *pMaxFuncArgs = nMaxArgs; *pMaxStack = nMaxStack; + + /* If we never rollback a statement transaction, then statement + ** transactions are not needed. So change every OP_Statement + ** opcode into an OP_Noop. This avoid a call to sqlite3OsOpenExclusive() + ** which can be expensive on some platforms. + */ + if( hasStatementBegin && !doesStatementRollback ){ + for(pOp=p->aOp, i=p->nOp-1; i>=0; i--, pOp++){ + if( pOp->opcode==OP_Statement ){ + pOp->opcode = OP_Noop; + } + } + } } /* @@ -332,12 +363,17 @@ ** A value of n==0 means copy bytes of zP3 up to and including the ** first null byte. If n>0 then copy n+1 bytes of zP3. ** -** If n==P3_STATIC it means that zP3 is a pointer to a constant static -** string and we can just copy the pointer. n==P3_POINTER means zP3 is -** a pointer to some object other than a string. n==P3_COLLSEQ and -** n==P3_KEYINFO mean that zP3 is a pointer to a CollSeq or KeyInfo -** structure. A copy is made of KeyInfo structures into memory obtained -** from sqliteMalloc. +** If n==P3_KEYINFO it means that zP3 is a pointer to a KeyInfo structure. +** A copy is made of the KeyInfo structure into memory obtained from +** sqliteMalloc, to be freed when the Vdbe is finalized. +** n==P3_KEYINFO_HANDOFF indicates that zP3 points to a KeyInfo structure +** stored in memory that the caller has obtained from sqliteMalloc. The +** caller should not free the allocation, it will be freed when the Vdbe is +** finalized. +** +** Other values of n (P3_STATIC, P3_COLLSEQ etc.) indicate that zP3 points +** to a string or structure that is guaranteed to exist for the lifetime of +** the Vdbe. In these cases we can just copy the pointer. ** ** If addr<0 then change P3 on the most recently inserted instruction. */ @@ -348,6 +384,9 @@ if( n==P3_DYNAMIC || n==P3_KEYINFO_HANDOFF ){ sqliteFree((void*)zP3); } + if( n==P3_MEM ){ + sqlite3ValueFree((sqlite3_value *)zP3); + } return; } if( addr<0 || addr>=p->nOp ){ @@ -463,11 +502,6 @@ char *zP3; assert( nTemp>=20 ); switch( pOp->p3type ){ - case P3_POINTER: { - sprintf(zTemp, "ptr(%#x)", (int)pOp->p3); - zP3 = zTemp; - break; - } case P3_KEYINFO: { int i, j; KeyInfo *pKeyInfo = (KeyInfo*)pOp->p3; @@ -686,7 +720,9 @@ /* No instruction ever pushes more than a single element onto the ** stack. And the stack never grows on successive executions of the ** same loop. So the total number of instructions is an upper bound - ** on the maximum stack depth required. + ** on the maximum stack depth required. (Added later:) The + ** resolveP2Values() call computes a tighter upper bound on the + ** stack size. ** ** Allocation all the stack space we will ever need. */ @@ -779,6 +815,7 @@ sqlite3VdbeMemRelease(&pSorter->data); sqliteFree(pSorter); } + p->pSortTail = 0; } /* @@ -1106,6 +1143,7 @@ ** This requires a master journal file to ensure the transaction is ** committed atomicly. */ +#ifndef SQLITE_OMIT_DISKIO else{ char *zMaster = 0; /* File-name for the master journal */ char const *zMainFile = sqlite3BtreeGetFilename(db->aDb[0].pBt); @@ -1222,6 +1260,7 @@ } } } +#endif return rc; } @@ -1533,8 +1572,8 @@ if( p->deferredMoveto ){ int res, rc; extern int sqlite3_search_count; - assert( p->intKey ); - if( p->intKey ){ + assert( p->isTable ); + if( p->isTable ){ rc = sqlite3BtreeMoveto(p->pCursor, 0, p->movetoTarget, &res); }else{ rc = sqlite3BtreeMoveto(p->pCursor,(char*)&p->movetoTarget, @@ -1542,8 +1581,8 @@ } if( rc ) return rc; *p->pIncrKey = 0; - p->lastRecno = keyToInt(p->movetoTarget); - p->recnoIsValid = res==0; + p->lastRowid = keyToInt(p->movetoTarget); + p->rowidIsValid = res==0; if( res<0 ){ rc = sqlite3BtreeNext(p->pCursor, &res); if( rc ) return rc; @@ -1687,61 +1726,71 @@ u32 serial_type, /* Serial type to deserialize */ Mem *pMem /* Memory cell to write value into */ ){ - int len; - - if( serial_type==0 ){ - /* NULL */ - pMem->flags = MEM_Null; - return 0; - } - len = sqlite3VdbeSerialTypeLen(serial_type); - if( serial_type<=7 ){ - /* Integer and Real */ - if( serial_type<=4 ){ - /* 32-bit integer type. This is handled by a special case for - ** performance reasons. */ - int v = buf[0]; - int n; - if( v&0x80 ){ - v |= -256; - } - for(n=1; nflags = MEM_Null; + break; + } + case 1: { /* 1-byte signed integer */ + pMem->i = (signed char)buf[0]; pMem->flags = MEM_Int; - pMem->i = v; - return n; - }else{ - u64 v = 0; - int n; - - if( buf[0]&0x80 ){ - v = -1; - } - for(n=0; nflags = MEM_Real; - pMem->r = *(double*)&v; + return 1; + } + case 2: { /* 2-byte signed integer */ + pMem->i = (((signed char)buf[0])<<8) | buf[1]; + pMem->flags = MEM_Int; + return 2; + } + case 3: { /* 3-byte signed integer */ + pMem->i = (((signed char)buf[0])<<16) | (buf[1]<<8) | buf[2]; + pMem->flags = MEM_Int; + return 3; + } + case 4: { /* 4-byte signed integer */ + pMem->i = (buf[0]<<24) | (buf[1]<<16) | (buf[2]<<8) | buf[3]; + pMem->flags = MEM_Int; + return 4; + } + case 5: { /* 6-byte signed integer */ + u64 x = (((signed char)buf[0])<<8) | buf[1]; + u32 y = (buf[2]<<24) | (buf[3]<<16) | (buf[4]<<8) | buf[5]; + x = (x<<32) | y; + pMem->i = *(i64*)&x; + pMem->flags = MEM_Int; + return 6; + } + case 6: /* 6-byte signed integer */ + case 7: { /* IEEE floating point */ + u64 x = (buf[0]<<24) | (buf[1]<<16) | (buf[2]<<8) | buf[3]; + u32 y = (buf[4]<<24) | (buf[5]<<16) | (buf[6]<<8) | buf[7]; + x = (x<<32) | y; + if( serial_type==6 ){ + pMem->i = *(i64*)&x; + pMem->flags = MEM_Int; }else{ - pMem->flags = MEM_Int; - pMem->i = *(i64*)&v; + pMem->r = *(double*)&x; + pMem->flags = MEM_Real; } + return 8; } - }else{ - /* String or blob */ - assert( serial_type>=12 ); - pMem->z = (char *)buf; - pMem->n = len; - pMem->xDel = 0; - if( serial_type&0x01 ){ - pMem->flags = MEM_Str | MEM_Ephem; - }else{ - pMem->flags = MEM_Blob | MEM_Ephem; + default: { + int len = (serial_type-12)/2; + pMem->z = (char *)buf; + pMem->n = len; + pMem->xDel = 0; + if( serial_type&0x01 ){ + pMem->flags = MEM_Str | MEM_Ephem; + }else{ + pMem->flags = MEM_Blob | MEM_Ephem; + } + return len; } } - return len; + return 0; } /* @@ -1795,8 +1844,8 @@ d2 += sqlite3VdbeSerialGet(&aKey2[d2], serial_type2, &mem2); rc = sqlite3MemCompare(&mem1, &mem2, iaColl[i] : 0); - sqlite3VdbeMemRelease(&mem1); - sqlite3VdbeMemRelease(&mem2); + if( mem1.flags & MEM_Dyn ) sqlite3VdbeMemRelease(&mem1); + if( mem2.flags & MEM_Dyn ) sqlite3VdbeMemRelease(&mem2); if( rc!=0 ){ break; } --- sqlite/vdbemem.c +++ sqlite/vdbemem.c @@ -608,8 +608,13 @@ zData[amt] = 0; zData[amt+1] = 0; if( rc!=SQLITE_OK ){ - if( amt>NBFS ){ + if( amt>NBFS-2 ){ + assert( zData!=pMem->zShort ); + assert( pMem->flags & MEM_Dyn ); sqliteFree(zData); + } else { + assert( zData==pMem->zShort ); + assert( pMem->flags & MEM_Short ); } return rc; } --- sqlite/where.c +++ sqlite/where.c @@ -16,7 +16,7 @@ ** so is applicable. Because this module is responsible for selecting ** indices, you might also think of this module as the "query optimizer". ** -** $Id: where.c,v 1.136 2005/03/16 12:15:21 danielk1977 Exp $ +** $Id: where.c,v 1.139 2005/06/12 21:35:53 drh Exp $ */ #include "sqliteInt.h" @@ -497,7 +497,6 @@ sqlite3CodeSubselect(pParse, pX); iTab = pX->iTable; sqlite3VdbeAddOp(v, OP_Rewind, iTab, brk); - sqlite3VdbeAddOp(v, OP_KeyAsData, iTab, 1); VdbeComment((v, "# %.*s", pX->span.n, pX->span.z)); pLevel->inP2 = sqlite3VdbeAddOp(v, OP_Column, iTab, 0); pLevel->inOp = OP_Next; @@ -546,7 +545,7 @@ ** ** The code that sqlite3WhereBegin() generates leaves the cursors named ** in pTabList pointing at their appropriate entries. The [...] code -** can use OP_Column and OP_Recno opcodes on these cursors to extract +** can use OP_Column and OP_Rowid opcodes on these cursors to extract ** data from the various tables of the loop. ** ** If the WHERE clause is empty, the foreach loops must each scan their @@ -599,8 +598,7 @@ Parse *pParse, /* The parser context */ SrcList *pTabList, /* A list of all tables to be scanned */ Expr *pWhere, /* The WHERE clause */ - ExprList **ppOrderBy, /* An ORDER BY clause, or NULL */ - Fetch *pFetch /* Initial location of cursors. NULL otherwise */ + ExprList **ppOrderBy /* An ORDER BY clause, or NULL */ ){ int i; /* Loop counter */ WhereInfo *pWInfo; /* Will become the return value of this function */ @@ -794,7 +792,7 @@ && (pTerm->prereqRight & loopMask)==pTerm->prereqRight ){ int iColumn = pX->pLeft->iColumn; int k; - char idxaff = pIdx->pTable->aCol[iColumn].affinity; + char idxaff = iColumn>=0 ? pIdx->pTable->aCol[iColumn].affinity : 0; for(k=0; knColumn; k++){ /* If the collating sequences or affinities don't match, ** ignore this index. */ @@ -950,7 +948,6 @@ (char*)&pIx->keyInfo, P3_KEYINFO); } if( (pLevel->score & 1)!=0 ){ - sqlite3VdbeAddOp(v, OP_KeyAsData, iIdxCur, 1); sqlite3VdbeAddOp(v, OP_SetNumColumns, iIdxCur, pIx->nColumn+1); } sqlite3CodeVerifySchema(pParse, pTab->iDb); @@ -985,7 +982,7 @@ if( i>0 && (pTabList->a[i-1].jointype & JT_LEFT)!=0 ){ if( !pParse->nMem ) pParse->nMem++; pLevel->iLeftJoin = pParse->nMem++; - sqlite3VdbeAddOp(v, OP_String8, 0, 0); + sqlite3VdbeAddOp(v, OP_Null, 0, 0); sqlite3VdbeAddOp(v, OP_MemStore, pLevel->iLeftJoin, 1); VdbeComment((v, "# init LEFT JOIN no-match flag")); } @@ -1062,7 +1059,7 @@ sqlite3VdbeAddOp(v, OP_RowKey, iIdxCur, 0); sqlite3VdbeAddOp(v, OP_IdxIsNull, nColumn, cont); if( !omitTable ){ - sqlite3VdbeAddOp(v, OP_IdxRecno, iIdxCur, 0); + sqlite3VdbeAddOp(v, OP_IdxRowid, iIdxCur, 0); sqlite3VdbeAddOp(v, OP_MoveGe, iCur, 0); } pLevel->p1 = iIdxCur; @@ -1121,9 +1118,9 @@ pLevel->p1 = iCur; pLevel->p2 = start; if( testOp!=OP_Noop ){ - sqlite3VdbeAddOp(v, OP_Recno, iCur, 0); + sqlite3VdbeAddOp(v, OP_Rowid, iCur, 0); sqlite3VdbeAddOp(v, OP_MemLoad, pLevel->iMem, 0); - sqlite3VdbeAddOp(v, testOp, (int)(('n'<<8)&0x0000FF00), brk); + sqlite3VdbeAddOp(v, testOp, 'n', brk); } }else if( pIdx==0 ){ /* Case 4: There is no usable index. We must do a complete @@ -1296,7 +1293,7 @@ sqlite3VdbeAddOp(v, OP_RowKey, iIdxCur, 0); sqlite3VdbeAddOp(v, OP_IdxIsNull, nEqColumn + ((score&4)!=0), cont); if( !omitTable ){ - sqlite3VdbeAddOp(v, OP_IdxRecno, iIdxCur, 0); + sqlite3VdbeAddOp(v, OP_IdxRowid, iIdxCur, 0); sqlite3VdbeAddOp(v, OP_MoveGe, iCur, 0); } @@ -1425,9 +1422,9 @@ break; } } - }else if( pOp->opcode==OP_Recno ){ + }else if( pOp->opcode==OP_Rowid ){ pOp->p1 = pLevel->iIdxCur; - pOp->opcode = OP_IdxRecno; + pOp->opcode = OP_IdxRowid; }else if( pOp->opcode==OP_NullRow ){ pOp->opcode = OP_Noop; } --- std_hooks.lua +++ std_hooks.lua @@ -81,6 +81,11 @@ if (string.find(name, "%.orig$")) then return true end if (string.find(name, "%.rej$")) then return true end if (string.find(name, "%~$")) then return true end + -- editor temp files + -- vim creates .foo.swp files + if (string.find(name, "%.[^/]*%.swp$")) then return true end + -- emacs creates #foo# files + if (string.find(name, "%#[^/]*%#$")) then return true end -- autotools detritus: if (string.find(name, "^autom4te.cache/")) then return true end if (string.find(name, "/autom4te.cache/")) then return true end @@ -349,28 +354,26 @@ if program_exists_in_path("kdiff3") then cmd = merge2_kdiff3_cmd (left_path, right_path, merged_path, lfile, rfile, outfile) + elseif program_exists_in_path ("xxdiff") then + cmd = merge2_xxdiff_cmd (left_path, right_path, merged_path, lfile, rfile, outfile) + elseif string.find(editor, "emacs") ~= nil or string.find(editor, "gnu") ~= nil then + if string.find(editor, "xemacs") and program_exists_in_path("xemacs") then + cmd = merge2_emacs_cmd ("xemacs", lfile, rfile, outfile) + elseif program_exists_in_path("emacs") then + cmd = merge2_emacs_cmd ("emacs", lfile, rfile, outfile) + end + elseif string.find(editor, "vim") ~= nil then + if os.getenv ("DISPLAY") ~= nil and program_exists_in_path ("gvim") then + cmd = merge2_vim_cmd ("gvim", lfile, rfile, outfile) + elseif program_exists_in_path ("vim") then + cmd = merge2_vim_cmd ("vim", lfile, rfile, outfile) + end elseif program_exists_in_path ("meld") then tbl.meld_exists = true io.write (string.format("\nWARNING: 'meld' was choosen to perform external 2-way merge.\n".. "You should merge all changes to *LEFT* file due to limitation of program\n".. "arguments.\n\n")) cmd = merge2_meld_cmd (lfile, rfile) - elseif program_exists_in_path ("xxdiff") then - cmd = merge2_xxdiff_cmd (left_path, right_path, merged_path, lfile, rfile, outfile) - else - if string.find(editor, "emacs") ~= nil or string.find(editor, "gnu") ~= nil then - if program_exists_in_path ("emacs") then - cmd = merge2_emacs_cmd ("emacs", lfile, rfile, outfile) - elseif program_exists_in_path ("xemacs") then - cmd = merge2_emacs_cmd ("xemacs", lfile, rfile, outfile) - end - elseif string.find(editor, "vim") ~= nil then - if os.getenv ("DISPLAY") ~= nil and program_exists_in_path ("gvim") then - cmd = merge2_vim_cmd ("gvim", lfile, rfile, outfile) - elseif program_exists_in_path ("vim") then - cmd = merge2_vim_cmd ("vim", lfile, rfile, outfile) - end - end end return cmd end @@ -438,29 +441,26 @@ if program_exists_in_path("kdiff3") then cmd = merge3_kdiff3_cmd (left_path, anc_path, right_path, merged_path, lfile, afile, rfile, outfile) + elseif program_exists_in_path ("xxdiff") then + cmd = merge3_xxdiff_cmd (left_path, anc_path, right_path, merged_path, lfile, afile, rfile, outfile) + elseif string.find(editor, "emacs") ~= nil or string.find(editor, "gnu") ~= nil then + if string.find(editor, "xemacs") and program_exists_in_path ("xemacs") then + cmd = merge3_emacs_cmd ("xemacs", lfile, afile, rfile, outfile) + elseif program_exists_in_path ("emacs") then + cmd = merge3_emacs_cmd ("emacs", lfile, afile, rfile, outfile) + end + elseif string.find(editor, "vim") ~= nil then + if os.getenv ("DISPLAY") ~= nil and program_exists_in_path ("gvim") then + cmd = merge3_vim_cmd ("gvim", lfile, afile, rfile, outfile) + elseif program_exists_in_path ("vim") then + cmd = merge3_vim_cmd ("vim", lfile, afile, rfile, outfile) + end elseif program_exists_in_path ("meld") then tbl.meld_exists = true io.write (string.format("\nWARNING: 'meld' was choosen to perform external 3-way merge.\n".. "You should merge all changes to *CENTER* file due to limitation of program\n".. "arguments.\n\n")) cmd = merge3_meld_cmd (lfile, afile, rfile) - elseif program_exists_in_path ("xxdiff") then - cmd = merge3_xxdiff_cmd (left_path, anc_path, right_path, merged_path, lfile, afile, rfile, outfile) - else - -- prefer emacs/xemacs - if string.find(editor, "emacs") ~= nil or string.find(editor, "gnu") ~= nil then - if program_exists_in_path ("xemacs") then - cmd = merge3_emacs_cmd ("xemacs", lfile, afile, rfile, outfile) - elseif program_exists_in_path ("emacs") then - cmd = merge3_emacs_cmd ("emacs", lfile, afile, rfile, outfile) - end - elseif string.find(editor, "vim") ~= nil then -- prefer vim - if os.getenv ("DISPLAY") ~= nil and program_exists_in_path ("gvim") then - cmd = merge3_vim_cmd ("gvim", lfile, afile, rfile, outfile) - elseif program_exists_in_path ("vim") then - cmd = merge3_vim_cmd ("vim", lfile, afile, rfile, outfile) - end - end end return cmd @@ -569,7 +569,7 @@ return os.date("%FT%T", t) end - -- today don't uses the time + -- today don't uses the time if str == "today" then local t = os.time(os.date('!*t')) @@ -599,7 +599,7 @@ if trans[type] <= 3600 then return os.date("%FT%T", t - (n * trans[type])) - else + else return os.date("%F", t - (n * trans[type])) end end --- tests/t_automate_stdio.at +++ tests/t_automate_stdio.at @@ -28,8 +28,10 @@ ]) AT_CHECK(MONOTONE automate inventory, [], [stdout], [ignore]) +AT_CHECK(CANONICALISE(stdout)) AT_CHECK(mv stdout output) AT_CHECK(echo "l9:inventorye"|MONOTONE automate stdio, [], [stdout], [ignore]) +AT_CHECK(CANONICALISE(stdout)) AT_CHECK(chmod u+x get_stdio.pl) CHECK_SAME_STDOUT(./get_stdio.pl stdout 0, cat output) --- tests/t_cvsimport_drepper.at +++ tests/t_cvsimport_drepper.at @@ -186,6 +186,7 @@ AT_CHECK(MONOTONE --branch=foo.bar cvs_import e, [], [ignore], [ignore]) AT_CHECK(MONOTONE --branch=foo.bar.disasm-branch co) AT_CHECK(cd foo.bar.disasm-branch && MONOTONE cat manifest, [], [stdout]) +AT_CHECK(CANONICALISE(stdout)) AT_CHECK(cmp test.manifest stdout) AT_CLEANUP --- tests/t_cvsimport_drepper2.at +++ tests/t_cvsimport_drepper2.at @@ -0,0 +1,76 @@ +# -*- Autoconf -*- + +AT_SETUP([a tricky CVS repository with tags]) + +MONOTONE_SETUP + +NEED_UNGZB64 + +AT_DATA(test.manifest, [73c0eabf76cc611c33d821d203a52670b8f6265a t/libasm/ChangeLog +411cfd008f4a72e433b48d6421733b6a792ca3b7 t/libelf-po/POTFILES.in +]) + +AT_DATA(test.tags, [initial f137764bdcf393ecb68b44ed2accd3e574681fcb address@hidden +portable-branch-base d57a26278cb758d02ee64d1c633008bfedc4cefd address@hidden +portable-branch-fork-20050601T0139 d57a26278cb758d02ee64d1c633008bfedc4cefd address@hidden +]) + +AT_DATA(e.tar.gz.enc, [H4sIAEJyw0IAA+1YbW/bOBLOV+tXEOiHSw+xqhdKTuq9g4u03SuQbIumub1vAS3R +lhBZEkgqL/frb0jJtiTK26htens4ThvZHlIPZzjD4czQV0fPTg7QbBbUnyHufDZ0 +5Dpe6IQz+XHkuK7n4CMUPL9oR0cVF4QhdLRm5DEu8oPzvjb+P0r0lXh2D3ii/QNg +Op6Ppf0xDo39fwZJ+2fpkvDN87nBKPu7DtjfmzkzY/+fQS37nyckX9OLYn1y92PX +kAbGGB+yfxgEyv54hgPHxeAnLp75cP6dHyvGMP2f2z+hJJ64tuvPLRJFlPO5xR83 +yyLj1gT8Ir5fZdMlI3mUvJazbGy7tmN71qQsmCDLjDaj01XBbqee4wRO6LhfHNc/ +Uy9oE2sYx8Y6BHghbV6KUw4u2XvFm1tZEd3yOeKCpZGYW1Gx2dBcTBYv0GJuWZZ6 +OSaCTqQktuPZLjzPbHxqu958QiqRFAzFjJYlZfMJmF5Q9O6hnFv1ShS03qo5t3L6 +IORPWFcie11kJ5TIzqntBU9C3uO5NZ6r47lSUjwWz6nxnB5eYHuO+j8bh3em4M40 +NBf2EZYZKd2pQjvV0KSu7mjZZgpttkPD0gaeks3DdoDHoYUKLWyjgUjg4DPbBTuE +49AChRZ00QDHA3cCfx8pG1ZouIc2U97s2f7IffMV2v5s+NJxwc/deveedjZ2aPWB +8IbQQEJ/5L41x6GH5sl980G2UWg1lDq/bY9TR0vuH9jhbIfHiozk8VfgrJjyyFos +ttElK9bWwrYWloAJ1kLiTx1v6gYIXWcQlRL0thYToV8agRcLRuOECBvC1d8ta/JX +dElu6SrNKDp+c3lz/v7iza9XL1+jN3GMpr9XecWp/AL4jMAnRNYNEX/zbPUqhMUb +msd2hI6lBPI7vHpJ2C0qCSMbKmBpwlFZcJ4us0dU48HLW1Gd8FtEtcnmNfpMN8Ud +RVmaCwTZQgxf1m3kUZvQ0mSZ5oQ9Nrq8LfK/CARqbIALhrlPRYIoYwU7fonSHEVw +TVgTXoCqCayP1gXl6J4VSpS+xOcJjW4RbCGSu4UYhRuEiLTIuYKCT8GqSMCGv736 +qL3ftc9lwUAawnJYlduottdqU8WrjJRqjcvrtzD5k2apjn7NJvKExMW9VOCOsFTe +g9y2JhepEOAXUUZJXpV8j5TTe7iY7QjcJFM6ULQBIPZYK5dQdSkC2s4L2obBYw0j +l4vyGwBkpdSgzwM9rjlFH377cn31DokCdnZFGc0jMM1+bi0CnjpnU2+8b0iTS4Wl +QcBUm1KeGOUN6yhCEBB38C5kHt/s1FdVKTMRtKzSLJY7qJZozNpawj0ds0SdVH+y +E3R802wWzVaVSDOO4mJD0rwNPXtO6f2pczp1/W9aIs3hQNISPBcVuVSKLjObnKC8 +ENtfvGgv445aBg5CLL3n/J9XiLAoSe+ojK2tKK7i7WUKwQx0ax9NcU/JLT9BpCwh +yi35PahbEhElu9hMHBQ0RyCY+iDYZxXw0WX0KyOwSeiX+gb4wx1Gx7+/+9eXz2/A +hr/R+91ZPUG8WnKRikrGjuWjDCWrdF0xkH/SiRrS8qmQ0abMSERRsdrGdti2RlWv +f63ELgq3g+7AIN4OOtqgj/xm8GxgzGvGTgdAIeXzZ8i1iHqihv7YSrMa57qUt20H +LWhmhPWMFwNTtloEB0G2M/BXZzQ38/v0AYnHshic4x1ACaTS8gHO4ozz4sYMNfCu +gtZX/2/XeYeoqf8hNE3L4plaQGP6P9jzof73fdf0f34Kde3/6eOX9x8u3l1B2P+B +TaCv9H+C0A1b/R/Z/w98bPo/P4Wa/g9+SvtHZlzhEzs/enunATjc98F62wfXvaY0 +T0VKMtkHkv+sSR2B699PaArhoU5LAF/876ui230bKH3Pvq+KVhU+lL6y+sU2dn5M +FQ3iYUA7fXr3q97UVjltfzfugXIa95OQF+gi5UKmSDL7gqoukVcwpFYC8mWZAELW +lPOMKPdpCh6okV6g86J8ZOk6Eej4/CWS1/iJfAZQbMXoH0ScoA95BPmWXACEgqqJ +FxUDh7fq4PcK/rYFRzehkEVencsjmTuqQyFzvzhlW4y9/JBEeFbTTm+VMJZ661UM +tWN/lSYl+ZhDDptTELYlSCuL8GSGIh9DqvaUjMNdltfkJR/q8wM12l3Kofbdy4uR +57e2wPduVjz9N61F3jPXUE8mMRtgl8NsPsCGknAIBNhDIJVK0lQSPjiSV1nWH3kA +z6CiWB3gbzr8EA/oCswhXWu2JmbN1nQF9pCuNXsI5ICuuxFNVxgZ1HXP7+p6s6Rr +KDg7rCgXXdC6WSET4dBts0Gu3kQoLdcgF9G5mtI1N1vpTG0jFFc2DXSmNhW2nbBh +ruqS9LjyhtGYugbATGO4OjSuJpUye17pK/EEolIeP3QHEsKTLuc2VZvd4tTdnC4P +gLSlwYd0yZt2S4/3IHSONg0iatznDKwATM1BbxhkD6TvHbABpehZpvbjLu+OMhmM +9sy1snf3TK6bfY0ywrnOjh/772vHd8uVTTedWw7OZTQjg1ydyQcBOk7YYqb5qhgc +AG9qO812BPYoJtWBAboa5OeHXpD3y+CALq0Wv7bcgf2qbXujm6IZGABqRgZM0owc +XmbANPuR4YEBE21HNMX3AwOm2g8OmUtF3j0vzyCV2d3zdRJV3/Vwe6c5XMfpRmbC ++1t+8aftEhgyZMiQIUOGDBkyZMiQIUOGDBkyZMiQIUOGDBkyZMiQIUOGDBkyZMiQ +IUOGDBn6s9B/AByaqK8AUAAA +]) + +UNGZB64(e.tar.gz.enc, e.tar) +AT_CHECK(tar -xf e.tar) + +AT_CHECK(MONOTONE --branch=foo.bar cvs_import e, [], [ignore], [ignore]) +AT_CHECK(MONOTONE --branch=foo.bar co) +AT_CHECK(cd foo.bar && MONOTONE cat manifest, [], [stdout]) +AT_CHECK(CANONICALISE(stdout)) +AT_CHECK(cmp test.manifest stdout) +AT_CHECK(cd foo.bar && MONOTONE list tags, [], [stdout]) +AT_CHECK(CANONICALISE(stdout)) +AT_CHECK(cmp test.tags stdout) + +AT_CLEANUP --- tests/t_db_kill_branch_locally.at +++ tests/t_db_kill_branch_locally.at @@ -0,0 +1,26 @@ +AT_SETUP([db kill_branch_locally command]) +MONOTONE_SETUP + +# This tests the db kill_branch_locally command + +# Prepare a db with a couple of branches +ADD_FILE(foo, [file named foo +]) +COMMIT(good) +REVISION=`BASE_REVISION` +AT_CHECK(MONOTONE cert $REVISION branch bad, [], ignore, ignore) +AT_CHECK(MONOTONE ls branches, [], stdout, ignore) +AT_CHECK(grep -q good stdout) +AT_CHECK(grep -q bad stdout) + +# Now we delete the branch, and make sure it's gone +AT_CHECK(MONOTONE db kill_branch_locally bad, [], ignore, ignore) +AT_CHECK(MONOTONE ls branches, [], stdout, ignore) +AT_CHECK(grep -q good stdout) +AT_CHECK(grep -q bad stdout, [1]) + +# And lets make sure our database is still OK +AT_CHECK(MONOTONE db check, [], ignore, ignore) + +AT_CLEANUP +(END) --- tests/t_db_kill_rev_locally.at +++ tests/t_db_kill_rev_locally.at @@ -1,24 +1,28 @@ AT_SETUP([db kill_rev_locally command]) MONOTONE_SETUP # This tests the db kill_rev_locally command # Prepare a db with two revisions -AT_CHECK(echo "test">tmp, [], ignore, ignore) -AT_CHECK(MONOTONE add tmp, [], ignore, ignore) -AT_CHECK(MONOTONE --branch="test" --message="logtext" commit, [], ignore, stderr) -ANCESTOR=`cat stderr|awk '/committed revision/ {print $4}'` -AT_CHECK(echo "test2">>tmp, [], ignore, ignore) -AT_CHECK(MONOTONE --message="logtext" commit, [], ignore, stderr) -CHILD=`cat stderr|awk '/committed revision/ {print $4}'` +ADD_FILE(testfile, [blah blah +]) +COMMIT(testbranch) +ANCESTOR=`BASE_REVISION` +SET_FILE(testfile, [stuff stuff +]) +COMMIT(testbranch) +CHILD=`BASE_REVISION` + # trying to kill the ancestor. This *is supposed to fail* -AT_CHECK(MONOTONE db kill_rev_locally $ANCESTOR, [1], ignore, ignore) -AT_CHECK(MONOTONE db check, [], ignore, ignore) +AT_CHECK(MONOTONE db kill_rev_locally $ANCESTOR, [1], [ignore], [ignore]) +AT_CHECK(MONOTONE cat revision $ANCESTOR, [], [ignore], [ignore]) +AT_CHECK(MONOTONE db check, [], [ignore], [ignore]) # killing children is ok, though :) -AT_CHECK(MONOTONE db kill_rev_locally $CHILD, [], ignore, ignore) +AT_CHECK(MONOTONE cat revision $CHILD, [], [ignore], [ignore]) +AT_CHECK(MONOTONE db kill_rev_locally $CHILD, [], [ignore], [ignore]) +AT_CHECK(MONOTONE cat revision $CHILD, [1], [ignore], [ignore]) AT_CHECK(MONOTONE db check, [], ignore, ignore) AT_CLEANUP -(END) --- tests/t_existsonpath.at +++ tests/t_existsonpath.at @@ -0,0 +1,22 @@ +AT_SETUP([lua function existsonpath]) +MONOTONE_SETUP + +# Need a way to break into the lua interpreter; our strategy is to +# redefine the use_inodeprints function to run our code, and then +# create a new working copy. + +AT_DATA(test.lua, [function use_inodeprints() + if (existsonpath("ls") == 0) then + io.write("asdfghjkl\n") + end + if (existsonpath("weaohriosfaoisd") ~= 0) then + io.write("qwertyuiop\n") + end + return false +end +]) +AT_CHECK(MONOTONE setup --rcfile=test.lua subdir, [], [stdout], [ignore]) +AT_CHECK(grep -q asdfghjkl stdout, []) +AT_CHECK(grep -q qwertyuiop stdout, []) + +AT_CLEANUP --- tests/t_selector_later_earlier.at +++ tests/t_selector_later_earlier.at @@ -49,11 +49,13 @@ AT_CHECK(RAW_MONOTONE automate select "e:2005-04-30", [], [stdout], [ignore]) AT_CHECK(CANONICALISE(stdout)) AT_CHECK(mv stdout a_s) -AT_CHECK(test 3 -eq "`wc -l /dev/null 2>&1") % exe).str(); + const char * const args[] = {"sh", "-c", cmd_str.c_str(), NULL}; + int pid; + int res; + pid = process_spawn(args); + if (pid==-1) + { + L(F("error in process_spawn\n")); + return -1; + } + if (process_wait(pid, &res)) + { + L(F("error in process_wait\n")); + return -1; + } + if (res==0) + { + L(F("successful return; %s exists\n") % exe); + return 0; + } + L(F("failure; %s does not exist\n") % exe); + return -1; } bool is_executable(const char *path) { - struct stat s; + struct stat s; - int rc = stat(path, &s); - N(rc != -1, F("stat() error on file %s)") % path); + int rc = stat(path, &s); + N(rc != -1, F("stat() error on file %s)") % path); - return s.st_mode & S_IXUSR; + return s.st_mode & S_IXUSR; } int make_executable(const char *path) { - mode_t mode; - struct stat s; - if (stat(path, &s)) - return -1; - mode = s.st_mode; - mode |= S_IXUSR; - return chmod(path, mode); + mode_t mode; + struct stat s; + if (stat(path, &s)) + return -1; + mode = s.st_mode; + mode |= S_IXUSR; + return chmod(path, mode); } pid_t process_spawn(const char * const argv[]) { - { - std::ostringstream cmdline_ss; - for (const char *const *i = argv; *i; ++i) - { - if (i) - cmdline_ss << ", "; - cmdline_ss << "'" << *i << "'"; - } - L(F("spawning command: %s\n") % cmdline_ss.str()); - } - pid_t pid; - pid = fork(); - switch (pid) - { - case -1: /* Error */ - return -1; - case 0: /* Child */ - execvp(argv[0], (char * const *)argv); - return -1; - default: /* Parent */ - return pid; - } + { + std::ostringstream cmdline_ss; + for (const char *const *i = argv; *i; ++i) + { + if (i != argv) + cmdline_ss << ", "; + cmdline_ss << "'" << *i << "'"; + } + L(F("spawning command: %s\n") % cmdline_ss.str()); + } + pid_t pid; + pid = fork(); + switch (pid) + { + case -1: /* Error */ + return -1; + case 0: /* Child */ + execvp(argv[0], (char * const *)argv); + raise(SIGKILL); + default: /* Parent */ + return pid; + } } int process_wait(pid_t pid, int *res) { - int status; - pid = waitpid(pid, &status, 0); - if (WIFEXITED(status)) - *res = WEXITSTATUS(status); - else - *res = -1; - return 0; + int status; + pid = waitpid(pid, &status, 0); + if (WIFEXITED(status)) + *res = WEXITSTATUS(status); + else + *res = -1; + return 0; } int process_kill(pid_t pid, int signal) { - return kill(pid, signal); + return kill(pid, signal); } int process_sleep(unsigned int seconds) { - return sleep(seconds); + return sleep(seconds); } pid_t get_process_id() { - return getpid(); + return getpid(); }