mirror of
https://github.com/sqlite/sqlite.git
synced 2025-08-08 14:02:16 +03:00
Merge all recent trunk changes.
FossilOrigin-Name: 3a2a1bd47875e114d8e6f31c1768908f401d2861
This commit is contained in:
38
manifest
38
manifest
@@ -1,5 +1,5 @@
|
|||||||
C Merge\sin\sperformance\senhancements\sfrom\strunk.
|
C Merge\sall\srecent\strunk\schanges.
|
||||||
D 2013-11-26T18:00:29.602
|
D 2013-11-27T21:53:51.759
|
||||||
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
||||||
F Makefile.in 06b851f767034811d4f6e159367c453dc28d3925
|
F Makefile.in 06b851f767034811d4f6e159367c453dc28d3925
|
||||||
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
|
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
|
||||||
@@ -220,7 +220,7 @@ F src/os.c b4ad71336fd96f97776f75587cd9e8218288f5be
|
|||||||
F src/os.h 4a46270a64e9193af4a0aaa3bc2c66dc07c29b3f
|
F src/os.h 4a46270a64e9193af4a0aaa3bc2c66dc07c29b3f
|
||||||
F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04
|
F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04
|
||||||
F src/os_unix.c 143624d9eabb3b997c59cf594e0d06c56edd43e9
|
F src/os_unix.c 143624d9eabb3b997c59cf594e0d06c56edd43e9
|
||||||
F src/os_win.c cb3f26205ea785a63ea5bdc21a9c9f9ae3972d0f
|
F src/os_win.c 4323dd0bac4f7a7037fc4cf87fb4692d17f0b108
|
||||||
F src/pager.c 2aa4444ffe86e9282d03bc349a4a5e49bd77c0e8
|
F src/pager.c 2aa4444ffe86e9282d03bc349a4a5e49bd77c0e8
|
||||||
F src/pager.h f094af9f6ececfaa8a1e93876905a4f34233fb0c
|
F src/pager.h f094af9f6ececfaa8a1e93876905a4f34233fb0c
|
||||||
F src/parse.y acee1a9958539e21263362b194594c5255ad2fca
|
F src/parse.y acee1a9958539e21263362b194594c5255ad2fca
|
||||||
@@ -231,11 +231,11 @@ F src/pragma.c 5ab7279d132143feb77f773688a24ab05da75fd7
|
|||||||
F src/prepare.c 359d1a1e9c9bd4488e4dd3a1aaaf2d2ebb9bb768
|
F src/prepare.c 359d1a1e9c9bd4488e4dd3a1aaaf2d2ebb9bb768
|
||||||
F src/printf.c da9119eb31a187a4b99f60aa4a225141c0ebb74b
|
F src/printf.c da9119eb31a187a4b99f60aa4a225141c0ebb74b
|
||||||
F src/random.c 0b2dbc37fdfbfa6bd455b091dfcef5bdb32dba68
|
F src/random.c 0b2dbc37fdfbfa6bd455b091dfcef5bdb32dba68
|
||||||
F src/resolve.c a70e32ae6ccb7b780f2b6d3e9e21837affc25ee5
|
F src/resolve.c 7eda9097b29fcf3d2b42fdc17d1de672134e09b6
|
||||||
F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0
|
F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0
|
||||||
F src/select.c d41381d80a22d3a83352aeca274cccf264ac277a
|
F src/select.c d41381d80a22d3a83352aeca274cccf264ac277a
|
||||||
F src/shell.c c4d06a9238a515ff4bc86b8626139633c09a00a2
|
F src/shell.c 936a72ff784efff3832cce274a96ed0b036e6758
|
||||||
F src/sqlite.h.in c84ef520934601e4d1a95c6858fef71dc369e940
|
F src/sqlite.h.in e7a96fad3f5a2e96f5b69cf395d3dfa657f4ab59
|
||||||
F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e
|
F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e
|
||||||
F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc
|
F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc
|
||||||
F src/sqliteInt.h dad3dff932c055304fc75b339f2cf68aab9cf19e
|
F src/sqliteInt.h dad3dff932c055304fc75b339f2cf68aab9cf19e
|
||||||
@@ -294,10 +294,10 @@ F src/update.c 046d7df2a4b3d85442a758f484eb2d40a48b5465
|
|||||||
F src/utf.c 6fc6c88d50448c469c5c196acf21617a24f90269
|
F src/utf.c 6fc6c88d50448c469c5c196acf21617a24f90269
|
||||||
F src/util.c cbe054290f780fcd472b89d701c7404c51ec9684
|
F src/util.c cbe054290f780fcd472b89d701c7404c51ec9684
|
||||||
F src/vacuum.c 3728d74919d4fb1356f9e9a13e27773db60b7179
|
F src/vacuum.c 3728d74919d4fb1356f9e9a13e27773db60b7179
|
||||||
F src/vdbe.c 520dcda659ff32e3da7d141e9ac083d3599a2079
|
F src/vdbe.c 9c6fb9ed1b9165427b0fdc812bc9c48c031f77da
|
||||||
F src/vdbe.h b7bfa7b468fcad2cf1890969fe7459325da00385
|
F src/vdbe.h b7bfa7b468fcad2cf1890969fe7459325da00385
|
||||||
F src/vdbeInt.h 1a5c604f33a5d46c839fee0cab16743aa3e1bc2e
|
F src/vdbeInt.h 1a5c604f33a5d46c839fee0cab16743aa3e1bc2e
|
||||||
F src/vdbeapi.c 8ade912f7023a3b35ee64497a94718ddbd7269c3
|
F src/vdbeapi.c e80d6d9dea792bd823cb64ae05cba446a7b3556a
|
||||||
F src/vdbeaux.c 9270db4725c0143e572a2df660fabac7104a9db3
|
F src/vdbeaux.c 9270db4725c0143e572a2df660fabac7104a9db3
|
||||||
F src/vdbeblob.c a2809461743e0b9dd9be871149ac65e8d2c80c08
|
F src/vdbeblob.c a2809461743e0b9dd9be871149ac65e8d2c80c08
|
||||||
F src/vdbemem.c af650c2019dc197f062440cdb4650b7204e648bf
|
F src/vdbemem.c af650c2019dc197f062440cdb4650b7204e648bf
|
||||||
@@ -307,7 +307,7 @@ F src/vtab.c 21b932841e51ebd7d075e2d0ad1415dce8d2d5fd
|
|||||||
F src/wal.c 7dc3966ef98b74422267e7e6e46e07ff6c6eb1b4
|
F src/wal.c 7dc3966ef98b74422267e7e6e46e07ff6c6eb1b4
|
||||||
F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4
|
F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4
|
||||||
F src/walker.c e9e593d5bb798c3e67fc3893dfe7055c9e7d8d74
|
F src/walker.c e9e593d5bb798c3e67fc3893dfe7055c9e7d8d74
|
||||||
F src/where.c e558bfa67009ab7de08a7a1960ae0dd443241cdd
|
F src/where.c e0a9909a58eee7dcde1d1bd5cf6381b0dbc83389
|
||||||
F src/whereInt.h 96a75c61f1d2b9d4a8e4bb17d89deb0cf7cba358
|
F src/whereInt.h 96a75c61f1d2b9d4a8e4bb17d89deb0cf7cba358
|
||||||
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
|
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
|
||||||
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
|
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
|
||||||
@@ -447,11 +447,11 @@ F test/descidx3.test 09ddbe3f5295f482d2f8b687cf6db8bad7acd9a2
|
|||||||
F test/diskfull.test 106391384780753ea6896b7b4f005d10e9866b6e
|
F test/diskfull.test 106391384780753ea6896b7b4f005d10e9866b6e
|
||||||
F test/distinct.test 44028aaf161a5e80a2f229622b3a174d3b352810
|
F test/distinct.test 44028aaf161a5e80a2f229622b3a174d3b352810
|
||||||
F test/distinctagg.test 1a6ef9c87a58669438fc771450d7a72577417376
|
F test/distinctagg.test 1a6ef9c87a58669438fc771450d7a72577417376
|
||||||
F test/e_createtable.test 3b453432cd14a12732ee9467597d2274ca37ce36
|
F test/e_createtable.test ee95d48664503d40f6cc9ef4a7d03216188e2ada
|
||||||
F test/e_delete.test d5186e2f5478b659f16a2c8b66c09892823e542a
|
F test/e_delete.test d5186e2f5478b659f16a2c8b66c09892823e542a
|
||||||
F test/e_droptrigger.test 3cd080807622c13e5bbb61fc9a57bd7754da2412
|
F test/e_droptrigger.test 3cd080807622c13e5bbb61fc9a57bd7754da2412
|
||||||
F test/e_dropview.test 0c9f7f60989164a70a67a9d9c26d1083bc808306
|
F test/e_dropview.test 0c9f7f60989164a70a67a9d9c26d1083bc808306
|
||||||
F test/e_expr.test 0808bc72c7b2a2fab4291418ecd73f4d09d7d671
|
F test/e_expr.test 5c71d183fbf519a4769fd2e2124afdc70b5b1f42
|
||||||
F test/e_fkey.test d83a04478bb9c02d2c513518548a69f818869f41
|
F test/e_fkey.test d83a04478bb9c02d2c513518548a69f818869f41
|
||||||
F test/e_fts3.test 5c02288842e4f941896fd44afdef564dd5fc1459
|
F test/e_fts3.test 5c02288842e4f941896fd44afdef564dd5fc1459
|
||||||
F test/e_insert.test 1e44f84d2abe44d66e4fbf198be4b20e3cc724a0
|
F test/e_insert.test 1e44f84d2abe44d66e4fbf198be4b20e3cc724a0
|
||||||
@@ -601,7 +601,7 @@ F test/fuzz_malloc.test 328f70aaca63adf29b4c6f06505ed0cf57ca7c26
|
|||||||
F test/fuzzer1.test d4c52aaf3ef923da293a2653cfab33d02f718a36
|
F test/fuzzer1.test d4c52aaf3ef923da293a2653cfab33d02f718a36
|
||||||
F test/fuzzerfault.test 8792cd77fd5bce765b05d0c8e01b9edcf8af8536
|
F test/fuzzerfault.test 8792cd77fd5bce765b05d0c8e01b9edcf8af8536
|
||||||
F test/genesis.tcl 1e2e2e8e5cc4058549a154ff1892fe5c9de19f98
|
F test/genesis.tcl 1e2e2e8e5cc4058549a154ff1892fe5c9de19f98
|
||||||
F test/hook.test 777b2541f6dd4f4ca5e8d6b66c1df1b3717aeab6
|
F test/hook.test 5429d34d6e59086175d8efbcd7e14d891375bdfb
|
||||||
F test/icu.test 70df4faca133254c042d02ae342c0a141f2663f4
|
F test/icu.test 70df4faca133254c042d02ae342c0a141f2663f4
|
||||||
F test/in.test 047c4671328e9032ab95666a67021adbbd36e98e
|
F test/in.test 047c4671328e9032ab95666a67021adbbd36e98e
|
||||||
F test/in2.test 5d4c61d17493c832f7d2d32bef785119e87bde75
|
F test/in2.test 5d4c61d17493c832f7d2d32bef785119e87bde75
|
||||||
@@ -657,7 +657,7 @@ F test/jrnlmode.test 9ee3a78f53d52cca737db69293d15dc41c0cbd36
|
|||||||
F test/jrnlmode2.test 81610545a4e6ed239ea8fa661891893385e23a1d
|
F test/jrnlmode2.test 81610545a4e6ed239ea8fa661891893385e23a1d
|
||||||
F test/jrnlmode3.test 556b447a05be0e0963f4311e95ab1632b11c9eaa
|
F test/jrnlmode3.test 556b447a05be0e0963f4311e95ab1632b11c9eaa
|
||||||
F test/keyword1.test a2400977a2e4fde43bf33754c2929fda34dbca05
|
F test/keyword1.test a2400977a2e4fde43bf33754c2929fda34dbca05
|
||||||
F test/lastinsert.test 474d519c68cb79d07ecae56a763aa7f322c72f51
|
F test/lastinsert.test 42e948fd6442f07d60acbd15d33fb86473e0ef63
|
||||||
F test/laststmtchanges.test ae613f53819206b3222771828d024154d51db200
|
F test/laststmtchanges.test ae613f53819206b3222771828d024154d51db200
|
||||||
F test/like.test 935fb4f608e3ea126891496a6e99b9468372bf5c
|
F test/like.test 935fb4f608e3ea126891496a6e99b9468372bf5c
|
||||||
F test/like2.test 3b2ee13149ba4a8a60b59756f4e5d345573852da
|
F test/like2.test 3b2ee13149ba4a8a60b59756f4e5d345573852da
|
||||||
@@ -770,7 +770,7 @@ F test/releasetest.tcl 06d289d8255794073a58d2850742f627924545ce
|
|||||||
F test/resolver01.test 33abf37ff8335e6bf98f2b45a0af3e06996ccd9a
|
F test/resolver01.test 33abf37ff8335e6bf98f2b45a0af3e06996ccd9a
|
||||||
F test/rollback.test e9504a009a202c3ed711da2e6879ff60c5a4669c
|
F test/rollback.test e9504a009a202c3ed711da2e6879ff60c5a4669c
|
||||||
F test/rowhash.test 0bc1d31415e4575d10cacf31e1a66b5cc0f8be81
|
F test/rowhash.test 0bc1d31415e4575d10cacf31e1a66b5cc0f8be81
|
||||||
F test/rowid.test f777404492adb0e00868fd706a3721328fd3af48
|
F test/rowid.test b78b30afb9537a73788ca1233a23a32190a3bb1f
|
||||||
F test/rtree.test 0c8d9dd458d6824e59683c19ab2ffa9ef946f798
|
F test/rtree.test 0c8d9dd458d6824e59683c19ab2ffa9ef946f798
|
||||||
F test/run-wordcount.sh 891e89c4c2d16e629cd45951d4ed899ad12afc09
|
F test/run-wordcount.sh 891e89c4c2d16e629cd45951d4ed899ad12afc09
|
||||||
F test/savepoint.test 6c53f76dffe5df0dd87646efe3e7aa159c36e07b
|
F test/savepoint.test 6c53f76dffe5df0dd87646efe3e7aa159c36e07b
|
||||||
@@ -823,6 +823,7 @@ F test/shortread1.test bb591ef20f0fd9ed26d0d12e80eee6d7ac8897a3
|
|||||||
F test/shrink.test 8c70f62b6e8eb4d54533de6d65bd06b1b9a17868
|
F test/shrink.test 8c70f62b6e8eb4d54533de6d65bd06b1b9a17868
|
||||||
F test/sidedelete.test f0ad71abe6233e3b153100f3b8d679b19a488329
|
F test/sidedelete.test f0ad71abe6233e3b153100f3b8d679b19a488329
|
||||||
F test/skipscan1.test 6bb4891c2cc5efd5690a9da9e7508e53d4a68e10
|
F test/skipscan1.test 6bb4891c2cc5efd5690a9da9e7508e53d4a68e10
|
||||||
|
F test/skipscan2.test 5a4db0799c338ddbacb154aaa5589c0254b36a8d
|
||||||
F test/soak.test 0b5b6375c9f4110c828070b826b3b4b0bb65cd5f
|
F test/soak.test 0b5b6375c9f4110c828070b826b3b4b0bb65cd5f
|
||||||
F test/softheap1.test 40562fe6cac6d9827b7b42b86d45aedf12c15e24
|
F test/softheap1.test 40562fe6cac6d9827b7b42b86d45aedf12c15e24
|
||||||
F test/sort.test 0e4456e729e5a92a625907c63dcdedfbe72c5dc5
|
F test/sort.test 0e4456e729e5a92a625907c63dcdedfbe72c5dc5
|
||||||
@@ -834,7 +835,7 @@ F test/speed3.test d32043614c08c53eafdc80f33191d5bd9b920523
|
|||||||
F test/speed4.test abc0ad3399dcf9703abed2fff8705e4f8e416715
|
F test/speed4.test abc0ad3399dcf9703abed2fff8705e4f8e416715
|
||||||
F test/speed4p.explain 6b5f104ebeb34a038b2f714150f51d01143e59aa
|
F test/speed4p.explain 6b5f104ebeb34a038b2f714150f51d01143e59aa
|
||||||
F test/speed4p.test 0e51908951677de5a969b723e03a27a1c45db38b
|
F test/speed4p.test 0e51908951677de5a969b723e03a27a1c45db38b
|
||||||
F test/speedtest1.c aa08ae8e3591bf5c028be9396a84237640761d8c
|
F test/speedtest1.c 184ded13ffe61df44d6e2ac9985b61a6417d5311
|
||||||
F test/spellfix.test 8c40b169b104086d8795781f670ba3c786d6d8be
|
F test/spellfix.test 8c40b169b104086d8795781f670ba3c786d6d8be
|
||||||
F test/sqllimits1.test b1aae27cc98eceb845e7f7adf918561256e31298
|
F test/sqllimits1.test b1aae27cc98eceb845e7f7adf918561256e31298
|
||||||
F test/stat.test c8eccfe8fcd3f3cfc864ce22d5b9e803a3c69940
|
F test/stat.test c8eccfe8fcd3f3cfc864ce22d5b9e803a3c69940
|
||||||
@@ -1106,6 +1107,7 @@ F test/without_rowid1.test aaa26da19d543cd8d3d2d0e686dfa255556c15c8
|
|||||||
F test/without_rowid2.test af260339f79d13cb220288b67cd287fbcf81ad99
|
F test/without_rowid2.test af260339f79d13cb220288b67cd287fbcf81ad99
|
||||||
F test/without_rowid3.test eac3d5c8a1924725b58503a368f2cbd24fd6c8a0
|
F test/without_rowid3.test eac3d5c8a1924725b58503a368f2cbd24fd6c8a0
|
||||||
F test/without_rowid4.test 4e08bcbaee0399f35d58b5581881e7a6243d458a
|
F test/without_rowid4.test 4e08bcbaee0399f35d58b5581881e7a6243d458a
|
||||||
|
F test/without_rowid5.test b4a639a367f04d382d20e8f44fc1be4f2d57d107
|
||||||
F test/wordcount.c 9915e06cb33d8ca8109b8700791afe80d305afda
|
F test/wordcount.c 9915e06cb33d8ca8109b8700791afe80d305afda
|
||||||
F test/zeroblob.test caaecfb4f908f7bc086ed238668049f96774d688
|
F test/zeroblob.test caaecfb4f908f7bc086ed238668049f96774d688
|
||||||
F test/zerodamage.test 209d7ed441f44cc5299e4ebffbef06fd5aabfefd
|
F test/zerodamage.test 209d7ed441f44cc5299e4ebffbef06fd5aabfefd
|
||||||
@@ -1158,7 +1160,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381
|
|||||||
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
|
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
|
||||||
F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01
|
F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01
|
||||||
F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff
|
F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff
|
||||||
P 7596d1bf8040f7cefc7b22c5e609acc5d66820bf 6f91dca0de908dc2b15130a6593a61c3147a409f
|
P fc9ae839569eb28eb734c52d95676c59b2e27494 81891288d9f281cf2ceb4cd701c0c3231b1bab19
|
||||||
R 4bfa42555a9c1bb80b9d6441159a988c
|
R 82cfa20fdf0a662273b8437808c19755
|
||||||
U drh
|
U drh
|
||||||
Z ab8c142eff787cc8d595e6a709628910
|
Z 5ce6e39b92ce4cf1a9fbbd5b784d1d3b
|
||||||
|
@@ -1 +1 @@
|
|||||||
fc9ae839569eb28eb734c52d95676c59b2e27494
|
3a2a1bd47875e114d8e6f31c1768908f401d2861
|
41
src/os_win.c
41
src/os_win.c
@@ -59,6 +59,34 @@
|
|||||||
must be defined."
|
must be defined."
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Define the required Windows SDK version constants if they are not
|
||||||
|
** already available.
|
||||||
|
*/
|
||||||
|
#ifndef NTDDI_WIN8
|
||||||
|
# define NTDDI_WIN8 0x06020000
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef NTDDI_WINBLUE
|
||||||
|
# define NTDDI_WINBLUE 0x06030000
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Check if the GetVersionEx[AW] functions should be considered deprecated
|
||||||
|
** and avoid using them in that case. It should be noted here that if the
|
||||||
|
** value of the SQLITE_WIN32_GETVERSIONEX pre-processor macro is zero
|
||||||
|
** (whether via this block or via being manually specified), that implies
|
||||||
|
** the underlying operating system will always be based on the Windows NT
|
||||||
|
** Kernel.
|
||||||
|
*/
|
||||||
|
#ifndef SQLITE_WIN32_GETVERSIONEX
|
||||||
|
# if defined(NTDDI_VERSION) && NTDDI_VERSION >= NTDDI_WINBLUE
|
||||||
|
# define SQLITE_WIN32_GETVERSIONEX 0
|
||||||
|
# else
|
||||||
|
# define SQLITE_WIN32_GETVERSIONEX 1
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** This constant should already be defined (in the "WinDef.h" SDK file).
|
** This constant should already be defined (in the "WinDef.h" SDK file).
|
||||||
*/
|
*/
|
||||||
@@ -694,7 +722,8 @@ static struct win_syscall {
|
|||||||
|
|
||||||
#define osGetTickCount ((DWORD(WINAPI*)(VOID))aSyscall[33].pCurrent)
|
#define osGetTickCount ((DWORD(WINAPI*)(VOID))aSyscall[33].pCurrent)
|
||||||
|
|
||||||
#if defined(SQLITE_WIN32_HAS_ANSI)
|
#if defined(SQLITE_WIN32_HAS_ANSI) && defined(SQLITE_WIN32_GETVERSIONEX) && \
|
||||||
|
SQLITE_WIN32_GETVERSIONEX
|
||||||
{ "GetVersionExA", (SYSCALL)GetVersionExA, 0 },
|
{ "GetVersionExA", (SYSCALL)GetVersionExA, 0 },
|
||||||
#else
|
#else
|
||||||
{ "GetVersionExA", (SYSCALL)0, 0 },
|
{ "GetVersionExA", (SYSCALL)0, 0 },
|
||||||
@@ -703,7 +732,8 @@ static struct win_syscall {
|
|||||||
#define osGetVersionExA ((BOOL(WINAPI*)( \
|
#define osGetVersionExA ((BOOL(WINAPI*)( \
|
||||||
LPOSVERSIONINFOA))aSyscall[34].pCurrent)
|
LPOSVERSIONINFOA))aSyscall[34].pCurrent)
|
||||||
|
|
||||||
#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE)
|
#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE) && \
|
||||||
|
defined(SQLITE_WIN32_GETVERSIONEX) && SQLITE_WIN32_GETVERSIONEX
|
||||||
{ "GetVersionExW", (SYSCALL)GetVersionExW, 0 },
|
{ "GetVersionExW", (SYSCALL)GetVersionExW, 0 },
|
||||||
#else
|
#else
|
||||||
{ "GetVersionExW", (SYSCALL)0, 0 },
|
{ "GetVersionExW", (SYSCALL)0, 0 },
|
||||||
@@ -1260,11 +1290,10 @@ void sqlite3_win32_sleep(DWORD milliseconds){
|
|||||||
** WinNT/2K/XP so that we will know whether or not we can safely call
|
** WinNT/2K/XP so that we will know whether or not we can safely call
|
||||||
** the LockFileEx() API.
|
** the LockFileEx() API.
|
||||||
*/
|
*/
|
||||||
#ifndef NTDDI_WIN8
|
|
||||||
# define NTDDI_WIN8 0x06020000
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if SQLITE_OS_WINCE || SQLITE_OS_WINRT || !defined(SQLITE_WIN32_HAS_ANSI)
|
#if !defined(SQLITE_WIN32_GETVERSIONEX) || !SQLITE_WIN32_GETVERSIONEX
|
||||||
|
# define osIsNT() (1)
|
||||||
|
#elif SQLITE_OS_WINCE || SQLITE_OS_WINRT || !defined(SQLITE_WIN32_HAS_ANSI)
|
||||||
# define osIsNT() (1)
|
# define osIsNT() (1)
|
||||||
#elif !defined(SQLITE_WIN32_HAS_WIDE)
|
#elif !defined(SQLITE_WIN32_HAS_WIDE)
|
||||||
# define osIsNT() (0)
|
# define osIsNT() (0)
|
||||||
|
@@ -352,7 +352,9 @@ static int lookupName(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if( iCol>=pTab->nCol && sqlite3IsRowid(zCol) && HasRowid(pTab) ){
|
if( iCol>=pTab->nCol && sqlite3IsRowid(zCol) && HasRowid(pTab) ){
|
||||||
iCol = -1; /* IMP: R-44911-55124 */
|
/* IMP: R-24309-18625 */
|
||||||
|
/* IMP: R-44911-55124 */
|
||||||
|
iCol = -1;
|
||||||
}
|
}
|
||||||
if( iCol<pTab->nCol ){
|
if( iCol<pTab->nCol ){
|
||||||
cnt++;
|
cnt++;
|
||||||
|
@@ -2096,7 +2096,7 @@ static int do_meta_command(char *zLine, struct callback_data *p){
|
|||||||
*/
|
*/
|
||||||
p->mode = MODE_Explain;
|
p->mode = MODE_Explain;
|
||||||
p->showHeader = 1;
|
p->showHeader = 1;
|
||||||
memset(p->colWidth,0,ArraySize(p->colWidth));
|
memset(p->colWidth,0,sizeof(p->colWidth));
|
||||||
p->colWidth[0] = 4; /* addr */
|
p->colWidth[0] = 4; /* addr */
|
||||||
p->colWidth[1] = 13; /* opcode */
|
p->colWidth[1] = 13; /* opcode */
|
||||||
p->colWidth[2] = 4; /* P1 */
|
p->colWidth[2] = 4; /* P1 */
|
||||||
|
@@ -3775,19 +3775,19 @@ int sqlite3_data_count(sqlite3_stmt *pStmt);
|
|||||||
**
|
**
|
||||||
** <tr><td> NULL <td> INTEGER <td> Result is 0
|
** <tr><td> NULL <td> INTEGER <td> Result is 0
|
||||||
** <tr><td> NULL <td> FLOAT <td> Result is 0.0
|
** <tr><td> NULL <td> FLOAT <td> Result is 0.0
|
||||||
** <tr><td> NULL <td> TEXT <td> Result is NULL pointer
|
** <tr><td> NULL <td> TEXT <td> Result is a NULL pointer
|
||||||
** <tr><td> NULL <td> BLOB <td> Result is NULL pointer
|
** <tr><td> NULL <td> BLOB <td> Result is a NULL pointer
|
||||||
** <tr><td> INTEGER <td> FLOAT <td> Convert from integer to float
|
** <tr><td> INTEGER <td> FLOAT <td> Convert from integer to float
|
||||||
** <tr><td> INTEGER <td> TEXT <td> ASCII rendering of the integer
|
** <tr><td> INTEGER <td> TEXT <td> ASCII rendering of the integer
|
||||||
** <tr><td> INTEGER <td> BLOB <td> Same as INTEGER->TEXT
|
** <tr><td> INTEGER <td> BLOB <td> Same as INTEGER->TEXT
|
||||||
** <tr><td> FLOAT <td> INTEGER <td> Convert from float to integer
|
** <tr><td> FLOAT <td> INTEGER <td> [CAST] to INTEGER
|
||||||
** <tr><td> FLOAT <td> TEXT <td> ASCII rendering of the float
|
** <tr><td> FLOAT <td> TEXT <td> ASCII rendering of the float
|
||||||
** <tr><td> FLOAT <td> BLOB <td> Same as FLOAT->TEXT
|
** <tr><td> FLOAT <td> BLOB <td> [CAST] to BLOB
|
||||||
** <tr><td> TEXT <td> INTEGER <td> Use atoi()
|
** <tr><td> TEXT <td> INTEGER <td> [CAST] to INTEGER
|
||||||
** <tr><td> TEXT <td> FLOAT <td> Use atof()
|
** <tr><td> TEXT <td> FLOAT <td> [CAST] to REAL
|
||||||
** <tr><td> TEXT <td> BLOB <td> No change
|
** <tr><td> TEXT <td> BLOB <td> No change
|
||||||
** <tr><td> BLOB <td> INTEGER <td> Convert to TEXT then use atoi()
|
** <tr><td> BLOB <td> INTEGER <td> [CAST] to INTEGER
|
||||||
** <tr><td> BLOB <td> FLOAT <td> Convert to TEXT then use atof()
|
** <tr><td> BLOB <td> FLOAT <td> [CAST] to REAL
|
||||||
** <tr><td> BLOB <td> TEXT <td> Add a zero terminator if needed
|
** <tr><td> BLOB <td> TEXT <td> Add a zero terminator if needed
|
||||||
** </table>
|
** </table>
|
||||||
** </blockquote>)^
|
** </blockquote>)^
|
||||||
|
67
src/vdbe.c
67
src/vdbe.c
@@ -3520,38 +3520,28 @@ case OP_SeekGt: { /* jump, in3 */
|
|||||||
pc = pOp->p2 - 1;
|
pc = pOp->p2 - 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/* If we reach this point, then the P3 value must be a floating
|
|
||||||
** point number. */
|
|
||||||
assert( (pIn3->flags & MEM_Real)!=0 );
|
|
||||||
|
|
||||||
if( (iKey==SMALLEST_INT64 && pIn3->r<(double)iKey)
|
/* If the approximation iKey is larger than the actual real search
|
||||||
|| (iKey==LARGEST_INT64 && pIn3->r>(double)iKey)
|
** term, substitute >= for > and < for <=. e.g. if the search term
|
||||||
){
|
** is 4.9 and the integer approximation 5:
|
||||||
/* The P3 value is too large in magnitude to be expressed as an
|
**
|
||||||
** integer. */
|
** (x > 4.9) -> (x >= 5)
|
||||||
res = 1;
|
** (x <= 4.9) -> (x < 5)
|
||||||
if( pIn3->r<0 ){
|
*/
|
||||||
if( oc>=OP_SeekGe ){ assert( oc==OP_SeekGe || oc==OP_SeekGt );
|
if( pIn3->r<(double)iKey ){
|
||||||
rc = sqlite3BtreeFirst(pC->pCursor, &res);
|
assert( OP_SeekGe==(OP_SeekGt-1) );
|
||||||
if( rc!=SQLITE_OK ) goto abort_due_to_error;
|
assert( OP_SeekLt==(OP_SeekLe-1) );
|
||||||
}
|
assert( (OP_SeekLe & 0x0001)==(OP_SeekGt & 0x0001) );
|
||||||
}else{
|
if( (oc & 0x0001)==(OP_SeekGt & 0x0001) ) oc--;
|
||||||
if( oc<=OP_SeekLe ){ assert( oc==OP_SeekLt || oc==OP_SeekLe );
|
}
|
||||||
rc = sqlite3BtreeLast(pC->pCursor, &res);
|
|
||||||
if( rc!=SQLITE_OK ) goto abort_due_to_error;
|
/* If the approximation iKey is smaller than the actual real search
|
||||||
}
|
** term, substitute <= for < and > for >=. */
|
||||||
}
|
else if( pIn3->r>(double)iKey ){
|
||||||
if( res ){
|
assert( OP_SeekLe==(OP_SeekLt+1) );
|
||||||
pc = pOp->p2 - 1;
|
assert( OP_SeekGt==(OP_SeekGe+1) );
|
||||||
}
|
assert( (OP_SeekLt & 0x0001)==(OP_SeekGe & 0x0001) );
|
||||||
break;
|
if( (oc & 0x0001)==(OP_SeekLt & 0x0001) ) oc++;
|
||||||
}else if( oc==OP_SeekLt || oc==OP_SeekGe ){
|
|
||||||
/* Use the ceiling() function to convert real->int */
|
|
||||||
if( pIn3->r > (double)iKey ) iKey++;
|
|
||||||
}else{
|
|
||||||
/* Use the floor() function to convert real->int */
|
|
||||||
assert( oc==OP_SeekLe || oc==OP_SeekGt );
|
|
||||||
if( pIn3->r < (double)iKey ) iKey--;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
rc = sqlite3BtreeMovetoUnpacked(pC->pCursor, 0, (u64)iKey, 0, &res);
|
rc = sqlite3BtreeMovetoUnpacked(pC->pCursor, 0, (u64)iKey, 0, &res);
|
||||||
@@ -4084,6 +4074,7 @@ case OP_InsertInt: {
|
|||||||
if( db->xPreUpdateCallback
|
if( db->xPreUpdateCallback
|
||||||
&& pOp->p4type==P4_TABLE
|
&& pOp->p4type==P4_TABLE
|
||||||
&& (!(pOp->p5 & OPFLAG_ISUPDATE) || pC->rowidIsValid==0)
|
&& (!(pOp->p5 & OPFLAG_ISUPDATE) || pC->rowidIsValid==0)
|
||||||
|
&& HasRowid(pTab)
|
||||||
){
|
){
|
||||||
sqlite3VdbePreUpdateHook(p, pC, SQLITE_INSERT, zDb, pTab, iKey, pOp->p2);
|
sqlite3VdbePreUpdateHook(p, pC, SQLITE_INSERT, zDb, pTab, iKey, pOp->p2);
|
||||||
}
|
}
|
||||||
@@ -4113,7 +4104,7 @@ case OP_InsertInt: {
|
|||||||
pC->cacheStatus = CACHE_STALE;
|
pC->cacheStatus = CACHE_STALE;
|
||||||
|
|
||||||
/* Invoke the update-hook if required. */
|
/* Invoke the update-hook if required. */
|
||||||
if( rc==SQLITE_OK && db->xUpdateCallback && op ){
|
if( rc==SQLITE_OK && db->xUpdateCallback && op && HasRowid(pTab) ){
|
||||||
db->xUpdateCallback(db->pUpdateArg, op, zDb, pTab->zName, iKey);
|
db->xUpdateCallback(db->pUpdateArg, op, zDb, pTab->zName, iKey);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -4153,12 +4144,11 @@ case OP_Delete: {
|
|||||||
int opflags;
|
int opflags;
|
||||||
|
|
||||||
opflags = pOp->p2;
|
opflags = pOp->p2;
|
||||||
iKey = 0;
|
|
||||||
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
|
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
|
||||||
pC = p->apCsr[pOp->p1];
|
pC = p->apCsr[pOp->p1];
|
||||||
assert( pC!=0 );
|
assert( pC!=0 );
|
||||||
assert( pC->pCursor!=0 ); /* Only valid for real tables, no pseudotables */
|
assert( pC->pCursor!=0 ); /* Only valid for real tables, no pseudotables */
|
||||||
assert( pOp->p4type==P4_TABLE || pOp->p4type==P4_NOTUSED );
|
iKey = pC->lastRowid; /* Only used for the update hook */
|
||||||
|
|
||||||
/* The OP_Delete opcode always follows an OP_NotExists or OP_Last or
|
/* The OP_Delete opcode always follows an OP_NotExists or OP_Last or
|
||||||
** OP_Column on the same table without any intervening operations that
|
** OP_Column on the same table without any intervening operations that
|
||||||
@@ -4176,16 +4166,15 @@ case OP_Delete: {
|
|||||||
*/
|
*/
|
||||||
if( pOp->p4.z && HAS_UPDATE_HOOK(db) ){
|
if( pOp->p4.z && HAS_UPDATE_HOOK(db) ){
|
||||||
assert( pC->iDb>=0 );
|
assert( pC->iDb>=0 );
|
||||||
assert( pC->isTable );
|
assert( pC->rowidIsValid || !HasRowid(pOp->p4.pTab) );
|
||||||
assert( pC->rowidIsValid ); /* lastRowid set by previous OP_NotFound */
|
|
||||||
iKey = pC->lastRowid;
|
iKey = pC->lastRowid;
|
||||||
zDb = db->aDb[pC->iDb].zName;
|
zDb = db->aDb[pC->iDb].zName;
|
||||||
pTab = pOp->p4.pTab;
|
pTab = pOp->p4.pTab;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
|
#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
|
||||||
/* Invoke the pre-update-hook if required. */
|
/* Invoke the pre-update-hook if required. */
|
||||||
if( db->xPreUpdateCallback && pOp->p4.z ){
|
if( db->xPreUpdateCallback && pOp->p4.z && HasRowid(pTab) ){
|
||||||
assert( !(opflags & OPFLAG_ISUPDATE) || (aMem[pOp->p3].flags & MEM_Int) );
|
assert( !(opflags & OPFLAG_ISUPDATE) || (aMem[pOp->p3].flags & MEM_Int) );
|
||||||
sqlite3VdbePreUpdateHook(p, pC,
|
sqlite3VdbePreUpdateHook(p, pC,
|
||||||
(opflags & OPFLAG_ISUPDATE) ? SQLITE_UPDATE : SQLITE_DELETE,
|
(opflags & OPFLAG_ISUPDATE) ? SQLITE_UPDATE : SQLITE_DELETE,
|
||||||
@@ -4205,7 +4194,7 @@ case OP_Delete: {
|
|||||||
if( opflags & OPFLAG_NCHANGE ){
|
if( opflags & OPFLAG_NCHANGE ){
|
||||||
p->nChange++;
|
p->nChange++;
|
||||||
assert( pOp->p4.z );
|
assert( pOp->p4.z );
|
||||||
if( rc==SQLITE_OK && db->xUpdateCallback ){
|
if( rc==SQLITE_OK && db->xUpdateCallback && HasRowid(pTab) ){
|
||||||
db->xUpdateCallback(db->pUpdateArg, SQLITE_DELETE, zDb, pTab->zName,iKey);
|
db->xUpdateCallback(db->pUpdateArg, SQLITE_DELETE, zDb, pTab->zName,iKey);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -728,27 +728,6 @@ static Mem *columnMem(sqlite3_stmt *pStmt, int i){
|
|||||||
sqlite3_mutex_enter(pVm->db->mutex);
|
sqlite3_mutex_enter(pVm->db->mutex);
|
||||||
pOut = &pVm->pResultSet[i];
|
pOut = &pVm->pResultSet[i];
|
||||||
}else{
|
}else{
|
||||||
/* If the value passed as the second argument is out of range, return
|
|
||||||
** a pointer to the following static Mem object which contains the
|
|
||||||
** value SQL NULL. Even though the Mem structure contains an element
|
|
||||||
** of type i64, on certain architectures (x86) with certain compiler
|
|
||||||
** switches (-Os), gcc may align this Mem object on a 4-byte boundary
|
|
||||||
** instead of an 8-byte one. This all works fine, except that when
|
|
||||||
** running with SQLITE_DEBUG defined the SQLite code sometimes assert()s
|
|
||||||
** that a Mem structure is located on an 8-byte boundary. To prevent
|
|
||||||
** these assert()s from failing, when building with SQLITE_DEBUG defined
|
|
||||||
** using gcc, we force nullMem to be 8-byte aligned using the magical
|
|
||||||
** __attribute__((aligned(8))) macro. */
|
|
||||||
static const Mem nullMem
|
|
||||||
#if defined(SQLITE_DEBUG) && defined(__GNUC__)
|
|
||||||
__attribute__((aligned(8)))
|
|
||||||
#endif
|
|
||||||
= {0, "", (double)0, {0}, 0, MEM_Null, SQLITE_NULL, 0,
|
|
||||||
#ifdef SQLITE_DEBUG
|
|
||||||
0, 0, /* pScopyFrom, pFiller */
|
|
||||||
#endif
|
|
||||||
0, 0 };
|
|
||||||
|
|
||||||
if( pVm && ALWAYS(pVm->db) ){
|
if( pVm && ALWAYS(pVm->db) ){
|
||||||
sqlite3_mutex_enter(pVm->db->mutex);
|
sqlite3_mutex_enter(pVm->db->mutex);
|
||||||
sqlite3Error(pVm->db, SQLITE_RANGE, 0);
|
sqlite3Error(pVm->db, SQLITE_RANGE, 0);
|
||||||
|
@@ -3921,12 +3921,14 @@ static int whereLoopAddBtreeIndex(
|
|||||||
|
|
||||||
/* Consider using a skip-scan if there are no WHERE clause constraints
|
/* Consider using a skip-scan if there are no WHERE clause constraints
|
||||||
** available for the left-most terms of the index, and if the average
|
** available for the left-most terms of the index, and if the average
|
||||||
** number of repeats in the left-most terms is at least 50.
|
** number of repeats in the left-most terms is at least 18. The magic
|
||||||
|
** number 18 was found by experimentation to be the payoff point where
|
||||||
|
** skip-scan become faster than a full-scan.
|
||||||
*/
|
*/
|
||||||
if( pTerm==0
|
if( pTerm==0
|
||||||
&& saved_nEq==saved_nSkip
|
&& saved_nEq==saved_nSkip
|
||||||
&& saved_nEq+1<pProbe->nKeyCol
|
&& saved_nEq+1<pProbe->nKeyCol
|
||||||
&& pProbe->aiRowEst[saved_nEq+1]>50 /* TUNING: Minimum for skip-scan */
|
&& pProbe->aiRowEst[saved_nEq+1]>=18 /* TUNING: Minimum for skip-scan */
|
||||||
){
|
){
|
||||||
LogEst nIter;
|
LogEst nIter;
|
||||||
pNew->u.btree.nEq++;
|
pNew->u.btree.nEq++;
|
||||||
|
@@ -1103,7 +1103,7 @@ do_catchsql_test e_createtable-3.11.5 {
|
|||||||
# EVIDENCE-OF: R-52382-54248 Each table in SQLite may have at most one
|
# EVIDENCE-OF: R-52382-54248 Each table in SQLite may have at most one
|
||||||
# PRIMARY KEY.
|
# PRIMARY KEY.
|
||||||
#
|
#
|
||||||
# EVIDENCE-OF: R-62315-57691 An error is rasied if more than one PRIMARY
|
# EVIDENCE-OF: R-31826-01813 An error is raised if more than one PRIMARY
|
||||||
# KEY clause appears in a CREATE TABLE statement.
|
# KEY clause appears in a CREATE TABLE statement.
|
||||||
#
|
#
|
||||||
# To test the two above, show that zero primary keys is Ok, one primary
|
# To test the two above, show that zero primary keys is Ok, one primary
|
||||||
@@ -1654,6 +1654,10 @@ do_execsql_test 4.19.4 { SELECT * FROM t5 } {}
|
|||||||
# of the special case-independent names "rowid", "oid", or "_rowid_" in
|
# of the special case-independent names "rowid", "oid", or "_rowid_" in
|
||||||
# place of a column name.
|
# place of a column name.
|
||||||
#
|
#
|
||||||
|
# EVIDENCE-OF: R-06726-07466 A column name can be any of the names
|
||||||
|
# defined in the CREATE TABLE statement or one of the following special
|
||||||
|
# identifiers: "ROWID", "OID", or "_ROWID_".
|
||||||
|
#
|
||||||
drop_all_tables
|
drop_all_tables
|
||||||
do_execsql_test 5.1.0 {
|
do_execsql_test 5.1.0 {
|
||||||
CREATE TABLE t1(x, y);
|
CREATE TABLE t1(x, y);
|
||||||
@@ -1678,6 +1682,10 @@ do_createtable_tests 5.1 {
|
|||||||
# explicitly declared column and cannot be used to retrieve the integer
|
# explicitly declared column and cannot be used to retrieve the integer
|
||||||
# rowid value.
|
# rowid value.
|
||||||
#
|
#
|
||||||
|
# EVIDENCE-OF: R-44615-33286 The special identifiers only refer to the
|
||||||
|
# row key if the CREATE TABLE statement does not define a real column
|
||||||
|
# with the same name.
|
||||||
|
#
|
||||||
do_execsql_test 5.2.0 {
|
do_execsql_test 5.2.0 {
|
||||||
CREATE TABLE t2(oid, b);
|
CREATE TABLE t2(oid, b);
|
||||||
CREATE TABLE t3(a, _rowid_);
|
CREATE TABLE t3(a, _rowid_);
|
||||||
|
@@ -1407,10 +1407,12 @@ do_test e_expr-26.1.6 { set ::evalcount } {5}
|
|||||||
#-------------------------------------------------------------------------
|
#-------------------------------------------------------------------------
|
||||||
# Test statements related to CAST expressions.
|
# Test statements related to CAST expressions.
|
||||||
#
|
#
|
||||||
# EVIDENCE-OF: R-65079-31758 Application of a CAST expression is
|
# EVIDENCE-OF: R-20854-17109 A CAST conversion is similar to the
|
||||||
# different to application of a column affinity, as with a CAST
|
# conversion that takes place when a column affinity is applied to a
|
||||||
# expression the storage class conversion is forced even if it is lossy
|
# value except that with the CAST operator the conversion always takes
|
||||||
# and irrreversible.
|
# place even if the conversion lossy and irreversible, whereas column
|
||||||
|
# affinity only changes the data type of a value if the change is
|
||||||
|
# lossless and reversible.
|
||||||
#
|
#
|
||||||
do_execsql_test e_expr-27.1.1 {
|
do_execsql_test e_expr-27.1.1 {
|
||||||
CREATE TABLE t3(a TEXT, b REAL, c INTEGER);
|
CREATE TABLE t3(a TEXT, b REAL, c INTEGER);
|
||||||
@@ -1594,17 +1596,20 @@ do_expr_test e_expr-30.4.1 { CAST('' AS INTEGER) } integer 0
|
|||||||
do_expr_test e_expr-30.4.2 { CAST('not a number' AS INTEGER) } integer 0
|
do_expr_test e_expr-30.4.2 { CAST('not a number' AS INTEGER) } integer 0
|
||||||
do_expr_test e_expr-30.4.3 { CAST('XXI' AS INTEGER) } integer 0
|
do_expr_test e_expr-30.4.3 { CAST('XXI' AS INTEGER) } integer 0
|
||||||
|
|
||||||
# EVIDENCE-OF: R-00741-38776 A cast of a REAL value into an INTEGER will
|
# EVIDENCE-OF: R-02752-50091 A cast of a REAL value into an INTEGER
|
||||||
# truncate the fractional part of the REAL.
|
# results in the integer between the REAL value and zero that is closest
|
||||||
|
# to the REAL value.
|
||||||
#
|
#
|
||||||
do_expr_test e_expr-31.1.1 { CAST(3.14159 AS INTEGER) } integer 3
|
do_expr_test e_expr-31.1.1 { CAST(3.14159 AS INTEGER) } integer 3
|
||||||
do_expr_test e_expr-31.1.2 { CAST(1.99999 AS INTEGER) } integer 1
|
do_expr_test e_expr-31.1.2 { CAST(1.99999 AS INTEGER) } integer 1
|
||||||
do_expr_test e_expr-31.1.3 { CAST(-1.99999 AS INTEGER) } integer -1
|
do_expr_test e_expr-31.1.3 { CAST(-1.99999 AS INTEGER) } integer -1
|
||||||
do_expr_test e_expr-31.1.4 { CAST(-0.99999 AS INTEGER) } integer 0
|
do_expr_test e_expr-31.1.4 { CAST(-0.99999 AS INTEGER) } integer 0
|
||||||
|
|
||||||
# EVIDENCE-OF: R-49503-28105 If a REAL is too large to be represented as
|
# EVIDENCE-OF: R-51517-40824 If a REAL is greater than the greatest
|
||||||
# an INTEGER then the result of the cast is the largest negative
|
# possible signed integer (+9223372036854775807) then the result is the
|
||||||
# integer: -9223372036854775808.
|
# greatest possible signed integer and if the REAL is less than the
|
||||||
|
# least possible signed integer (-9223372036854775808) then the result
|
||||||
|
# is the least possible signed integer.
|
||||||
#
|
#
|
||||||
do_expr_test e_expr-31.2.1 { CAST(2e+50 AS INT) } integer 9223372036854775807
|
do_expr_test e_expr-31.2.1 { CAST(2e+50 AS INT) } integer 9223372036854775807
|
||||||
do_expr_test e_expr-31.2.2 { CAST(-2e+50 AS INT) } integer -9223372036854775808
|
do_expr_test e_expr-31.2.2 { CAST(-2e+50 AS INT) } integer -9223372036854775808
|
||||||
@@ -1847,5 +1852,43 @@ foreach {tn expr} {
|
|||||||
do_expr_test e_expr-36.4.$tn $expr null {}
|
do_expr_test e_expr-36.4.$tn $expr null {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# EVIDENCE-OF: R-62477-06476 For example, the values NULL, 0.0, 0,
|
||||||
|
# 'english' and '0' are all considered to be false.
|
||||||
|
#
|
||||||
|
do_execsql_test e_expr-37.1 {
|
||||||
|
SELECT CASE WHEN NULL THEN 'true' ELSE 'false' END;
|
||||||
|
} {false}
|
||||||
|
do_execsql_test e_expr-37.2 {
|
||||||
|
SELECT CASE WHEN 0.0 THEN 'true' ELSE 'false' END;
|
||||||
|
} {false}
|
||||||
|
do_execsql_test e_expr-37.3 {
|
||||||
|
SELECT CASE WHEN 0 THEN 'true' ELSE 'false' END;
|
||||||
|
} {false}
|
||||||
|
do_execsql_test e_expr-37.4 {
|
||||||
|
SELECT CASE WHEN 'engligh' THEN 'true' ELSE 'false' END;
|
||||||
|
} {false}
|
||||||
|
do_execsql_test e_expr-37.5 {
|
||||||
|
SELECT CASE WHEN '0' THEN 'true' ELSE 'false' END;
|
||||||
|
} {false}
|
||||||
|
|
||||||
|
# EVIDENCE-OF: R-55532-10108 Values 1, 1.0, 0.1, -0.1 and '1english' are
|
||||||
|
# considered to be true.
|
||||||
|
#
|
||||||
|
do_execsql_test e_expr-37.6 {
|
||||||
|
SELECT CASE WHEN 1 THEN 'true' ELSE 'false' END;
|
||||||
|
} {true}
|
||||||
|
do_execsql_test e_expr-37.7 {
|
||||||
|
SELECT CASE WHEN 1.0 THEN 'true' ELSE 'false' END;
|
||||||
|
} {true}
|
||||||
|
do_execsql_test e_expr-37.8 {
|
||||||
|
SELECT CASE WHEN 0.1 THEN 'true' ELSE 'false' END;
|
||||||
|
} {true}
|
||||||
|
do_execsql_test e_expr-37.9 {
|
||||||
|
SELECT CASE WHEN -0.1 THEN 'true' ELSE 'false' END;
|
||||||
|
} {true}
|
||||||
|
do_execsql_test e_expr-37.10 {
|
||||||
|
SELECT CASE WHEN '1english' THEN 'true' ELSE 'false' END;
|
||||||
|
} {true}
|
||||||
|
|
||||||
|
|
||||||
finish_test
|
finish_test
|
||||||
|
@@ -128,21 +128,52 @@ db2 close
|
|||||||
# depopulation of indices, to make sure the update-hook is not
|
# depopulation of indices, to make sure the update-hook is not
|
||||||
# invoked incorrectly.
|
# invoked incorrectly.
|
||||||
#
|
#
|
||||||
|
# EVIDENCE-OF: R-21999-45122 The sqlite3_update_hook() interface
|
||||||
|
# registers a callback function with the database connection identified
|
||||||
|
# by the first argument to be invoked whenever a row is updated,
|
||||||
|
# inserted or deleted in a rowid table.
|
||||||
|
|
||||||
# Simple tests
|
# Simple tests
|
||||||
do_test hook-4.1.1 {
|
do_test hook-4.1.1a {
|
||||||
catchsql {
|
catchsql {
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
}
|
}
|
||||||
|
unset -nocomplain ::update_hook
|
||||||
|
set ::update_hook {}
|
||||||
|
db update_hook [list lappend ::update_hook]
|
||||||
|
#
|
||||||
|
# EVIDENCE-OF: R-52223-27275 The update hook is not invoked when
|
||||||
|
# internal system tables are modified (i.e. sqlite_master and
|
||||||
|
# sqlite_sequence).
|
||||||
|
#
|
||||||
execsql {
|
execsql {
|
||||||
CREATE TABLE t1(a INTEGER PRIMARY KEY, b);
|
CREATE TABLE t1(a INTEGER PRIMARY KEY, b);
|
||||||
|
CREATE TABLE t1w(a INT PRIMARY KEY, b) WITHOUT ROWID;
|
||||||
|
}
|
||||||
|
set ::update_hook
|
||||||
|
} {}
|
||||||
|
do_test hook-4.1.1b {
|
||||||
|
execsql {
|
||||||
INSERT INTO t1 VALUES(1, 'one');
|
INSERT INTO t1 VALUES(1, 'one');
|
||||||
INSERT INTO t1 VALUES(2, 'two');
|
INSERT INTO t1 VALUES(2, 'two');
|
||||||
INSERT INTO t1 VALUES(3, 'three');
|
INSERT INTO t1 VALUES(3, 'three');
|
||||||
|
INSERT INTO t1w SELECT * FROM t1;
|
||||||
}
|
}
|
||||||
db update_hook [list lappend ::update_hook]
|
|
||||||
} {}
|
} {}
|
||||||
|
|
||||||
|
# EVIDENCE-OF: R-15506-57666 The second callback argument is one of
|
||||||
|
# SQLITE_INSERT, SQLITE_DELETE, or SQLITE_UPDATE, depending on the
|
||||||
|
# operation that caused the callback to be invoked.
|
||||||
|
#
|
||||||
|
# EVIDENCE-OF: R-29213-61195 The third and fourth arguments to the
|
||||||
|
# callback contain pointers to the database and table name containing
|
||||||
|
# the affected row.
|
||||||
|
#
|
||||||
|
# EVIDENCE-OF: R-30809-57812 The final callback parameter is the rowid
|
||||||
|
# of the row.
|
||||||
|
#
|
||||||
do_test hook-4.1.2 {
|
do_test hook-4.1.2 {
|
||||||
|
set ::update_hook {}
|
||||||
execsql {
|
execsql {
|
||||||
INSERT INTO t1 VALUES(4, 'four');
|
INSERT INTO t1 VALUES(4, 'four');
|
||||||
DELETE FROM t1 WHERE b = 'two';
|
DELETE FROM t1 WHERE b = 'two';
|
||||||
@@ -160,6 +191,24 @@ do_test hook-4.1.2 {
|
|||||||
DELETE main t1 4 \
|
DELETE main t1 4 \
|
||||||
]
|
]
|
||||||
|
|
||||||
|
# EVIDENCE-OF: R-61808-14344 The sqlite3_update_hook() interface does
|
||||||
|
# not fire callbacks for changes to a WITHOUT ROWID table.
|
||||||
|
#
|
||||||
|
# EVIDENCE-OF: R-33257-44249 The update hook is not invoked when WITHOUT
|
||||||
|
# ROWID tables are modified.
|
||||||
|
#
|
||||||
|
breakpoint
|
||||||
|
do_test hook-4.1.2w {
|
||||||
|
set ::update_hook {}
|
||||||
|
execsql {
|
||||||
|
INSERT INTO t1w VALUES(4, 'four');
|
||||||
|
DELETE FROM t1w WHERE b = 'two';
|
||||||
|
UPDATE t1w SET b = '' WHERE a = 1 OR a = 3;
|
||||||
|
DELETE FROM t1w WHERE 1; -- Avoid the truncate optimization (for now)
|
||||||
|
}
|
||||||
|
set ::update_hook
|
||||||
|
} {}
|
||||||
|
|
||||||
ifcapable trigger {
|
ifcapable trigger {
|
||||||
# Update hook is not invoked for changes to sqlite_master
|
# Update hook is not invoked for changes to sqlite_master
|
||||||
#
|
#
|
||||||
|
@@ -36,6 +36,17 @@ do_test lastinsert-1.1 {
|
|||||||
}
|
}
|
||||||
} {0 3}
|
} {0 3}
|
||||||
|
|
||||||
|
# EVIDENCE-OF: R-47220-63683 The sqlite3_last_insert_rowid() function
|
||||||
|
# does not work for WITHOUT ROWID tables.
|
||||||
|
#
|
||||||
|
do_test lastinsert-1.1w {
|
||||||
|
catchsql {
|
||||||
|
create table t1w (k integer primary key) WITHOUT ROWID;
|
||||||
|
insert into t1w values (123456);
|
||||||
|
select last_insert_rowid(); -- returns 3 from above.
|
||||||
|
}
|
||||||
|
} {0 3}
|
||||||
|
|
||||||
# LIRID unchanged after an update on a table
|
# LIRID unchanged after an update on a table
|
||||||
do_test lastinsert-1.2 {
|
do_test lastinsert-1.2 {
|
||||||
catchsql {
|
catchsql {
|
||||||
|
@@ -12,7 +12,9 @@
|
|||||||
# focus of this file is testing the magic ROWID column that is
|
# focus of this file is testing the magic ROWID column that is
|
||||||
# found on all tables.
|
# found on all tables.
|
||||||
#
|
#
|
||||||
# $Id: rowid.test,v 1.21 2009/06/26 15:14:55 drh Exp $
|
# EVIDENCE-OF: R-36924-43758 By default, every row in SQLite has a
|
||||||
|
# special column, usually called the "rowid", that uniquely identifies
|
||||||
|
# that row within the table.
|
||||||
|
|
||||||
set testdir [file dirname $argv0]
|
set testdir [file dirname $argv0]
|
||||||
source $testdir/tester.tcl
|
source $testdir/tester.tcl
|
||||||
|
190
test/skipscan2.test
Normal file
190
test/skipscan2.test
Normal file
@@ -0,0 +1,190 @@
|
|||||||
|
# 2013-11-27
|
||||||
|
#
|
||||||
|
# The author disclaims copyright to this source code. In place of
|
||||||
|
# a legal notice, here is a blessing:
|
||||||
|
#
|
||||||
|
# May you do good and not evil.
|
||||||
|
# May you find forgiveness for yourself and forgive others.
|
||||||
|
# May you share freely, never taking more than you give.
|
||||||
|
#
|
||||||
|
#***********************************************************************
|
||||||
|
#
|
||||||
|
# This file implements tests of the "skip-scan" query strategy.
|
||||||
|
#
|
||||||
|
# The test cases in this file are derived from the description of
|
||||||
|
# the skip-scan query strategy in the "optoverview.html" document.
|
||||||
|
#
|
||||||
|
|
||||||
|
set testdir [file dirname $argv0]
|
||||||
|
source $testdir/tester.tcl
|
||||||
|
|
||||||
|
do_execsql_test skipscan2-1.1 {
|
||||||
|
CREATE TABLE people(
|
||||||
|
name TEXT PRIMARY KEY,
|
||||||
|
role TEXT NOT NULL,
|
||||||
|
height INT NOT NULL, -- in cm
|
||||||
|
CHECK( role IN ('student','teacher') )
|
||||||
|
);
|
||||||
|
CREATE INDEX people_idx1 ON people(role, height);
|
||||||
|
} {}
|
||||||
|
do_execsql_test skipscan2-1.2 {
|
||||||
|
INSERT INTO people VALUES('Alice','student',156);
|
||||||
|
INSERT INTO people VALUES('Bob','student',161);
|
||||||
|
INSERT INTO people VALUES('Cindy','student',155);
|
||||||
|
INSERT INTO people VALUES('David','student',181);
|
||||||
|
INSERT INTO people VALUES('Emily','teacher',158);
|
||||||
|
INSERT INTO people VALUES('Fred','student',163);
|
||||||
|
INSERT INTO people VALUES('Ginny','student',169);
|
||||||
|
INSERT INTO people VALUES('Harold','student',172);
|
||||||
|
INSERT INTO people VALUES('Imma','student',179);
|
||||||
|
INSERT INTO people VALUES('Jack','student',181);
|
||||||
|
INSERT INTO people VALUES('Karen','student',163);
|
||||||
|
INSERT INTO people VALUES('Logan','student',177);
|
||||||
|
INSERT INTO people VALUES('Megan','teacher',159);
|
||||||
|
INSERT INTO people VALUES('Nathan','student',163);
|
||||||
|
INSERT INTO people VALUES('Olivia','student',161);
|
||||||
|
INSERT INTO people VALUES('Patrick','teacher',180);
|
||||||
|
INSERT INTO people VALUES('Quiana','student',182);
|
||||||
|
INSERT INTO people VALUES('Robert','student',159);
|
||||||
|
INSERT INTO people VALUES('Sally','student',166);
|
||||||
|
INSERT INTO people VALUES('Tom','student',171);
|
||||||
|
INSERT INTO people VALUES('Ursula','student',170);
|
||||||
|
INSERT INTO people VALUES('Vance','student',179);
|
||||||
|
INSERT INTO people VALUES('Willma','student',175);
|
||||||
|
INSERT INTO people VALUES('Xavier','teacher',185);
|
||||||
|
INSERT INTO people VALUES('Yvonne','student',149);
|
||||||
|
INSERT INTO people VALUES('Zach','student',170);
|
||||||
|
}
|
||||||
|
|
||||||
|
# Without ANALYZE, a skip-scan is not used
|
||||||
|
#
|
||||||
|
do_execsql_test skipscan2-1.3 {
|
||||||
|
SELECT name FROM people WHERE height>=180 ORDER BY +name;
|
||||||
|
} {David Jack Patrick Quiana Xavier}
|
||||||
|
do_execsql_test skipscan2-1.3eqp {
|
||||||
|
EXPLAIN QUERY PLAN
|
||||||
|
SELECT name FROM people WHERE height>=180 ORDER BY +name;
|
||||||
|
} {~/*INDEX people_idx1 */}
|
||||||
|
|
||||||
|
# Now do an ANALYZE. A skip-scan can be used after ANALYZE.
|
||||||
|
#
|
||||||
|
do_execsql_test skipscan2-1.4 {
|
||||||
|
ANALYZE;
|
||||||
|
-- We do not have enough people above to actually force the use
|
||||||
|
-- of a skip-scan. So make a manual adjustment to the stat1 table
|
||||||
|
-- to make it seem like there are many more.
|
||||||
|
UPDATE sqlite_stat1 SET stat='10000 5000 20' WHERE idx='people_idx1';
|
||||||
|
ANALYZE sqlite_master;
|
||||||
|
}
|
||||||
|
db cache flush
|
||||||
|
do_execsql_test skipscan2-1.5 {
|
||||||
|
SELECT name FROM people WHERE height>=180 ORDER BY +name;
|
||||||
|
} {David Jack Patrick Quiana Xavier}
|
||||||
|
do_execsql_test skipscan2-1.5eqp {
|
||||||
|
EXPLAIN QUERY PLAN
|
||||||
|
SELECT name FROM people WHERE height>=180 ORDER BY +name;
|
||||||
|
} {/*INDEX people_idx1 */}
|
||||||
|
|
||||||
|
# Same answer with other formulations of the same query
|
||||||
|
#
|
||||||
|
do_execsql_test skipscan2-1.6 {
|
||||||
|
SELECT name FROM people
|
||||||
|
WHERE role IN (SELECT DISTINCT role FROM people)
|
||||||
|
AND height>=180 ORDER BY +name;
|
||||||
|
} {David Jack Patrick Quiana Xavier}
|
||||||
|
do_execsql_test skipscan2-1.7 {
|
||||||
|
SELECT name FROM people WHERE role='teacher' AND height>=180
|
||||||
|
UNION ALL
|
||||||
|
SELECT name FROM people WHERE role='student' AND height>=180
|
||||||
|
ORDER BY 1;
|
||||||
|
} {David Jack Patrick Quiana Xavier}
|
||||||
|
|
||||||
|
# Add 8 more people, bringing the total to 34. Then the number of
|
||||||
|
# duplicates in the left-column of the index will be 17 and
|
||||||
|
# skip-scan should not be used after an (unfudged) ANALYZE.
|
||||||
|
#
|
||||||
|
do_execsql_test skipscan2-1.8 {
|
||||||
|
INSERT INTO people VALUES('Angie','student',166);
|
||||||
|
INSERT INTO people VALUES('Brad','student',176);
|
||||||
|
INSERT INTO people VALUES('Claire','student',168);
|
||||||
|
INSERT INTO people VALUES('Donald','student',162);
|
||||||
|
INSERT INTO people VALUES('Elaine','student',177);
|
||||||
|
INSERT INTO people VALUES('Frazier','student',159);
|
||||||
|
INSERT INTO people VALUES('Grace','student',179);
|
||||||
|
INSERT INTO people VALUES('Horace','student',166);
|
||||||
|
ANALYZE;
|
||||||
|
SELECT stat FROM sqlite_stat1 WHERE idx='people_idx1';
|
||||||
|
} {{34 17 2}}
|
||||||
|
db cache flush
|
||||||
|
do_execsql_test skipscan2-1.9 {
|
||||||
|
SELECT name FROM people WHERE height>=180 ORDER BY +name;
|
||||||
|
} {David Jack Patrick Quiana Xavier}
|
||||||
|
do_execsql_test skipscan2-1.9eqp {
|
||||||
|
EXPLAIN QUERY PLAN
|
||||||
|
SELECT name FROM people WHERE height>=180 ORDER BY +name;
|
||||||
|
} {~/*INDEX people_idx1 */}
|
||||||
|
|
||||||
|
# Add 2 more people, bringing the total to 36. Then the number of
|
||||||
|
# duplicates in the left-column of the index will be 18 and
|
||||||
|
# skip-scan will be used after an (unfudged) ANALYZE.
|
||||||
|
#
|
||||||
|
do_execsql_test skipscan2-1.10 {
|
||||||
|
INSERT INTO people VALUES('Ingrad','student',155);
|
||||||
|
INSERT INTO people VALUES('Jacob','student',179);
|
||||||
|
ANALYZE;
|
||||||
|
SELECT stat FROM sqlite_stat1 WHERE idx='people_idx1';
|
||||||
|
} {{36 18 2}}
|
||||||
|
db cache flush
|
||||||
|
do_execsql_test skipscan2-1.11 {
|
||||||
|
SELECT name FROM people WHERE height>=180 ORDER BY +name;
|
||||||
|
} {David Jack Patrick Quiana Xavier}
|
||||||
|
do_execsql_test skipscan2-1.11eqp {
|
||||||
|
EXPLAIN QUERY PLAN
|
||||||
|
SELECT name FROM people WHERE height>=180 ORDER BY +name;
|
||||||
|
} {/*INDEX people_idx1 */}
|
||||||
|
|
||||||
|
|
||||||
|
# Repeat using a WITHOUT ROWID table.
|
||||||
|
#
|
||||||
|
do_execsql_test skipscan2-2.1 {
|
||||||
|
CREATE TABLE peoplew(
|
||||||
|
name TEXT PRIMARY KEY,
|
||||||
|
role TEXT NOT NULL,
|
||||||
|
height INT NOT NULL, -- in cm
|
||||||
|
CHECK( role IN ('student','teacher') )
|
||||||
|
) WITHOUT ROWID;
|
||||||
|
CREATE INDEX peoplew_idx1 ON peoplew(role, height);
|
||||||
|
INSERT INTO peoplew(name,role,height)
|
||||||
|
SELECT name, role, height FROM people;
|
||||||
|
ALTER TABLE people RENAME TO old_people;
|
||||||
|
SELECT name FROM peoplew WHERE height>=180 ORDER BY +name;
|
||||||
|
} {David Jack Patrick Quiana Xavier}
|
||||||
|
do_execsql_test skipscan2-2.2 {
|
||||||
|
SELECT name FROM peoplew
|
||||||
|
WHERE role IN (SELECT DISTINCT role FROM peoplew)
|
||||||
|
AND height>=180 ORDER BY +name;
|
||||||
|
} {David Jack Patrick Quiana Xavier}
|
||||||
|
do_execsql_test skipscan2-2.2 {
|
||||||
|
SELECT name FROM peoplew WHERE role='teacher' AND height>=180
|
||||||
|
UNION ALL
|
||||||
|
SELECT name FROM peoplew WHERE role='student' AND height>=180
|
||||||
|
ORDER BY 1;
|
||||||
|
} {David Jack Patrick Quiana Xavier}
|
||||||
|
|
||||||
|
# Now do an ANALYZE. A skip-scan can be used after ANALYZE.
|
||||||
|
#
|
||||||
|
do_execsql_test skipscan2-2.4 {
|
||||||
|
ANALYZE;
|
||||||
|
}
|
||||||
|
db cache flush
|
||||||
|
do_execsql_test skipscan2-2.5 {
|
||||||
|
SELECT name FROM peoplew WHERE height>=180 ORDER BY +name;
|
||||||
|
} {David Jack Patrick Quiana Xavier}
|
||||||
|
do_execsql_test skipscan2-2.5eqp {
|
||||||
|
EXPLAIN QUERY PLAN
|
||||||
|
SELECT name FROM peoplew WHERE height>=180 ORDER BY +name;
|
||||||
|
} {/*INDEX peoplew_idx1 */}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
finish_test
|
@@ -122,8 +122,8 @@ static int integerValue(const char *zArg){
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if( v>=2147483648 ) fatal_error("parameter to large - max 2147483648");
|
if( v>0x7fffffff ) fatal_error("parameter too large - max 2147483648");
|
||||||
return isNeg? -v : v;
|
return (int)(isNeg? -v : v);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return the current wall-clock time, in milliseconds */
|
/* Return the current wall-clock time, in milliseconds */
|
||||||
@@ -256,8 +256,8 @@ void speedtest1_begin_test(int iTestNum, const char *zTestName, ...){
|
|||||||
sqlite3_free(zName);
|
sqlite3_free(zName);
|
||||||
g.nResult = 0;
|
g.nResult = 0;
|
||||||
g.iStart = speedtest1_timestamp();
|
g.iStart = speedtest1_timestamp();
|
||||||
g.x = 2903710987;
|
g.x = 0xad131d0b;
|
||||||
g.y = 1157229256;
|
g.y = 0x44f9eac8;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Complete a test case */
|
/* Complete a test case */
|
||||||
|
201
test/without_rowid5.test
Normal file
201
test/without_rowid5.test
Normal file
@@ -0,0 +1,201 @@
|
|||||||
|
# 2013-11-26
|
||||||
|
#
|
||||||
|
# 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.
|
||||||
|
#
|
||||||
|
#***********************************************************************
|
||||||
|
#
|
||||||
|
# Requirements testing for WITHOUT ROWID tables.
|
||||||
|
#
|
||||||
|
|
||||||
|
set testdir [file dirname $argv0]
|
||||||
|
source $testdir/tester.tcl
|
||||||
|
|
||||||
|
|
||||||
|
# EVIDENCE-OF: R-36924-43758 By default, every row in SQLite has a
|
||||||
|
# special column, usually called the "rowid", that uniquely identifies
|
||||||
|
# that row within the table.
|
||||||
|
#
|
||||||
|
# EVIDENCE-OF: R-32341-39358 However if the phrase "WITHOUT ROWID" is
|
||||||
|
# added to the end of a CREATE TABLE statement, then the special "rowid"
|
||||||
|
# column is omitted.
|
||||||
|
#
|
||||||
|
do_execsql_test without_rowid5-1.1 {
|
||||||
|
CREATE TABLE t1(a PRIMARY KEY,b,c);
|
||||||
|
CREATE TABLE t1w(a PRIMARY KEY,b,c) WITHOUT ROWID;
|
||||||
|
INSERT INTO t1 VALUES(1565,681,1148),(1429,1190,1619),(425,358,1306);
|
||||||
|
INSERT INTO t1w SELECT a,b,c FROM t1;
|
||||||
|
SELECT rowid, _rowid_, oid FROM t1 ORDER BY a DESC;
|
||||||
|
} {1 1 1 2 2 2 3 3 3}
|
||||||
|
do_catchsql_test without_rowid5-1.2 {
|
||||||
|
SELECT rowid FROM t1w;
|
||||||
|
} {1 {no such column: rowid}}
|
||||||
|
do_catchsql_test without_rowid5-1.3 {
|
||||||
|
SELECT _rowid_ FROM t1w;
|
||||||
|
} {1 {no such column: _rowid_}}
|
||||||
|
do_catchsql_test without_rowid5-1.4 {
|
||||||
|
SELECT oid FROM t1w;
|
||||||
|
} {1 {no such column: oid}}
|
||||||
|
|
||||||
|
# EVIDENCE-OF: R-00217-01605 To create a WITHOUT ROWID table, simply add
|
||||||
|
# the keywords "WITHOUT ROWID" to the end of the CREATE TABLE statement.
|
||||||
|
# For example: CREATE TABLE IF NOT EXISTS wordcount( word TEXT PRIMARY
|
||||||
|
# KEY, cnt INTEGER ) WITHOUT ROWID;
|
||||||
|
#
|
||||||
|
do_execsql_test without_rowid5-2.1 {
|
||||||
|
CREATE TABLE IF NOT EXISTS wordcount(
|
||||||
|
word TEXT PRIMARY KEY,
|
||||||
|
cnt INTEGER
|
||||||
|
) WITHOUT ROWID;
|
||||||
|
INSERT INTO wordcount VALUES('one',1);
|
||||||
|
} {}
|
||||||
|
do_catchsql_test without_rowid5-2.2 {
|
||||||
|
SELECT rowid FROM wordcount;
|
||||||
|
} {1 {no such column: rowid}}
|
||||||
|
|
||||||
|
# EVIDENCE-OF: R-24770-17719 As with all SQL syntax, the case of the
|
||||||
|
# keywords does not matter. One can write "WITHOUT rowid" or "without
|
||||||
|
# rowid" or "WiThOuT rOwId" and it will mean the same thing.
|
||||||
|
#
|
||||||
|
do_execsql_test without_rowid5-2.3 {
|
||||||
|
CREATE TABLE IF NOT EXISTS wordcount_b(
|
||||||
|
word TEXT PRIMARY KEY,
|
||||||
|
cnt INTEGER
|
||||||
|
) WITHOUT rowid;
|
||||||
|
INSERT INTO wordcount_b VALUES('one',1);
|
||||||
|
} {}
|
||||||
|
do_catchsql_test without_rowid5-2.4 {
|
||||||
|
SELECT rowid FROM wordcount_b;
|
||||||
|
} {1 {no such column: rowid}}
|
||||||
|
do_execsql_test without_rowid5-2.5 {
|
||||||
|
CREATE TABLE IF NOT EXISTS wordcount_c(
|
||||||
|
word TEXT PRIMARY KEY,
|
||||||
|
cnt INTEGER
|
||||||
|
) without rowid;
|
||||||
|
INSERT INTO wordcount_c VALUES('one',1);
|
||||||
|
} {}
|
||||||
|
do_catchsql_test without_rowid5-2.6 {
|
||||||
|
SELECT rowid FROM wordcount_c;
|
||||||
|
} {1 {no such column: rowid}}
|
||||||
|
do_execsql_test without_rowid5-2.7 {
|
||||||
|
CREATE TABLE IF NOT EXISTS wordcount_d(
|
||||||
|
word TEXT PRIMARY KEY,
|
||||||
|
cnt INTEGER
|
||||||
|
) WITHOUT rowid;
|
||||||
|
INSERT INTO wordcount_d VALUES('one',1);
|
||||||
|
} {}
|
||||||
|
do_catchsql_test without_rowid5-2.8 {
|
||||||
|
SELECT rowid FROM wordcount_d;
|
||||||
|
} {1 {no such column: rowid}}
|
||||||
|
|
||||||
|
# EVIDENCE-OF: R-01418-51310 However, only "rowid" works as the keyword
|
||||||
|
# in the CREATE TABLE statement.
|
||||||
|
#
|
||||||
|
do_catchsql_test without_rowid5-3.1 {
|
||||||
|
CREATE TABLE IF NOT EXISTS error1(
|
||||||
|
word TEXT PRIMARY KEY,
|
||||||
|
cnt INTEGER
|
||||||
|
) WITHOUT _rowid_;
|
||||||
|
} {1 {unknown table option: _rowid_}}
|
||||||
|
do_catchsql_test without_rowid5-3.2 {
|
||||||
|
CREATE TABLE IF NOT EXISTS error2(
|
||||||
|
word TEXT PRIMARY KEY,
|
||||||
|
cnt INTEGER
|
||||||
|
) WITHOUT oid;
|
||||||
|
} {1 {unknown table option: oid}}
|
||||||
|
|
||||||
|
# EVIDENCE-OF: R-58033-17334 An error is raised if a CREATE TABLE
|
||||||
|
# statement with the WITHOUT ROWID clause lacks a PRIMARY KEY.
|
||||||
|
#
|
||||||
|
# EVIDENCE-OF: R-63443-09418 Every WITHOUT ROWID table must have a
|
||||||
|
# PRIMARY KEY.
|
||||||
|
#
|
||||||
|
# EVIDENCE-OF: R-27966-31616 An attempt to create a WITHOUT ROWID table
|
||||||
|
# without a PRIMARY KEY results in an error.
|
||||||
|
#
|
||||||
|
do_catchsql_test without_rowid5-4.1 {
|
||||||
|
CREATE TABLE IF NOT EXISTS error3(
|
||||||
|
word TEXT UNIQUE,
|
||||||
|
cnt INTEGER
|
||||||
|
) WITHOUT ROWID;
|
||||||
|
} {1 {PRIMARY KEY missing on table error3}}
|
||||||
|
|
||||||
|
# EVIDENCE-OF: R-48230-36247 The special behaviors associated "INTEGER
|
||||||
|
# PRIMARY KEY" do not apply on WITHOUT ROWID tables.
|
||||||
|
#
|
||||||
|
do_execsql_test without_rowid5-5.1 {
|
||||||
|
CREATE TABLE ipk(key INTEGER PRIMARY KEY, val TEXT) WITHOUT ROWID;
|
||||||
|
INSERT INTO ipk VALUES('rival','bonus'); -- ok to insert non-integer key
|
||||||
|
SELECT * FROM ipk;
|
||||||
|
} {rival bonus}
|
||||||
|
do_catchsql_test without_rowid5-5.2 {
|
||||||
|
INSERT INTO ipk VALUES(NULL,'sample'); -- no automatic generation of keys
|
||||||
|
} {1 {NOT NULL constraint failed: ipk.key}}
|
||||||
|
|
||||||
|
# EVIDENCE-OF: R-33142-02092 AUTOINCREMENT does not work on WITHOUT
|
||||||
|
# ROWID tables.
|
||||||
|
#
|
||||||
|
# EVIDENCE-OF: R-53084-07740 An error is raised if the "AUTOINCREMENT"
|
||||||
|
# keyword is used in the CREATE TABLE statement for a WITHOUT ROWID
|
||||||
|
# table.
|
||||||
|
#
|
||||||
|
do_catchsql_test without_rowid5-5.3 {
|
||||||
|
CREATE TABLE ipk2(key INTEGER PRIMARY KEY AUTOINCREMENT, val TEXT)WITHOUT ROWID;
|
||||||
|
} {1 {AUTOINCREMENT not allowed on WITHOUT ROWID tables}}
|
||||||
|
|
||||||
|
# EVIDENCE-OF: R-27831-00579 NOT NULL is enforced on every column of the
|
||||||
|
# PRIMARY KEY in a WITHOUT ROWID table.
|
||||||
|
#
|
||||||
|
# EVIDENCE-OF: R-29781-51289 So, ordinary rowid tables in SQLite violate
|
||||||
|
# the SQL standard and allow NULL values in PRIMARY KEY fields.
|
||||||
|
#
|
||||||
|
# EVIDENCE-OF: R-27472-62612 But WITHOUT ROWID tables do follow the
|
||||||
|
# standard and will throw an error on any attempt to insert a NULL into
|
||||||
|
# a PRIMARY KEY column.
|
||||||
|
#
|
||||||
|
do_execsql_test without_rowid5-5.4 {
|
||||||
|
CREATE TABLE nn(a, b, c, d, e, PRIMARY KEY(c,a,e));
|
||||||
|
CREATE TABLE nnw(a, b, c, d, e, PRIMARY KEY(c,a,e)) WITHOUT ROWID;
|
||||||
|
INSERT INTO nn VALUES(1,2,3,4,5);
|
||||||
|
INSERT INTO nnw VALUES(1,2,3,4,5);
|
||||||
|
} {}
|
||||||
|
do_execsql_test without_rowid5-5.5 {
|
||||||
|
INSERT INTO nn VALUES(NULL, 3,4,5,6);
|
||||||
|
INSERT INTO nn VALUES(3,4,NULL,7,8);
|
||||||
|
INSERT INTO nn VALUES(4,5,6,7,NULL);
|
||||||
|
SELECT count(*) FROM nn;
|
||||||
|
} {4}
|
||||||
|
do_catchsql_test without_rowid5-5.6 {
|
||||||
|
INSERT INTO nnw VALUES(NULL, 3,4,5,6);
|
||||||
|
} {1 {NOT NULL constraint failed: nnw.a}}
|
||||||
|
do_catchsql_test without_rowid5-5.7 {
|
||||||
|
INSERT INTO nnw VALUES(3,4,NULL,7,8)
|
||||||
|
} {1 {NOT NULL constraint failed: nnw.c}}
|
||||||
|
do_catchsql_test without_rowid5-5.8 {
|
||||||
|
INSERT INTO nnw VALUES(4,5,6,7,NULL)
|
||||||
|
} {1 {NOT NULL constraint failed: nnw.e}}
|
||||||
|
do_execsql_test without_rowid5-5.9 {
|
||||||
|
SELECT count(*) FROM nnw;
|
||||||
|
} {1}
|
||||||
|
|
||||||
|
# EVIDENCE-OF: R-12643-30541 The incremental blob I/O mechanism does not
|
||||||
|
# work for WITHOUT ROWID tables.
|
||||||
|
#
|
||||||
|
# EVIDENCE-OF: R-25760-33257 The sqlite3_blob_open() interface will fail
|
||||||
|
# for a WITHOUT ROWID table.
|
||||||
|
#
|
||||||
|
do_execsql_test without_rowid5-6.1 {
|
||||||
|
CREATE TABLE b1(a INTEGER PRIMARY KEY, b BLOB) WITHOUT ROWID;
|
||||||
|
INSERT INTO b1 VALUES(1,x'0102030405060708090a0b0c0d0e0f');
|
||||||
|
} {}
|
||||||
|
do_test without_rowid5-6.2 {
|
||||||
|
set rc [catch {db incrblob b1 b 1} msg]
|
||||||
|
lappend rc $msg
|
||||||
|
} {1 {cannot open table without rowid: b1}}
|
||||||
|
|
||||||
|
|
||||||
|
finish_test
|
Reference in New Issue
Block a user