Merge latest trunk changes with this branch.
FossilOrigin-Name: 08f74c45ecf711a2373af578d44470add9082377
This commit is contained in:
commit
3d40759803
18
configure
vendored
18
configure
vendored
@ -1,6 +1,6 @@
|
||||
#! /bin/sh
|
||||
# Guess values for system-dependent variables and create Makefiles.
|
||||
# Generated by GNU Autoconf 2.62 for sqlite 3.7.17.
|
||||
# Generated by GNU Autoconf 2.62 for sqlite 3.8.0.
|
||||
#
|
||||
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
|
||||
# 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
|
||||
@ -743,8 +743,8 @@ SHELL=${CONFIG_SHELL-/bin/sh}
|
||||
# Identity of this package.
|
||||
PACKAGE_NAME='sqlite'
|
||||
PACKAGE_TARNAME='sqlite'
|
||||
PACKAGE_VERSION='3.7.17'
|
||||
PACKAGE_STRING='sqlite 3.7.17'
|
||||
PACKAGE_VERSION='3.8.0'
|
||||
PACKAGE_STRING='sqlite 3.8.0'
|
||||
PACKAGE_BUGREPORT=''
|
||||
|
||||
# Factoring default headers for most tests.
|
||||
@ -1484,7 +1484,7 @@ if test "$ac_init_help" = "long"; then
|
||||
# Omit some internal or obsolete options to make the list less imposing.
|
||||
# This message is too long to be a string in the A/UX 3.1 sh.
|
||||
cat <<_ACEOF
|
||||
\`configure' configures sqlite 3.7.17 to adapt to many kinds of systems.
|
||||
\`configure' configures sqlite 3.8.0 to adapt to many kinds of systems.
|
||||
|
||||
Usage: $0 [OPTION]... [VAR=VALUE]...
|
||||
|
||||
@ -1549,7 +1549,7 @@ fi
|
||||
|
||||
if test -n "$ac_init_help"; then
|
||||
case $ac_init_help in
|
||||
short | recursive ) echo "Configuration of sqlite 3.7.17:";;
|
||||
short | recursive ) echo "Configuration of sqlite 3.8.0:";;
|
||||
esac
|
||||
cat <<\_ACEOF
|
||||
|
||||
@ -1665,7 +1665,7 @@ fi
|
||||
test -n "$ac_init_help" && exit $ac_status
|
||||
if $ac_init_version; then
|
||||
cat <<\_ACEOF
|
||||
sqlite configure 3.7.17
|
||||
sqlite configure 3.8.0
|
||||
generated by GNU Autoconf 2.62
|
||||
|
||||
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
|
||||
@ -1679,7 +1679,7 @@ cat >config.log <<_ACEOF
|
||||
This file contains any messages produced by compilers while
|
||||
running configure, to aid debugging if configure makes a mistake.
|
||||
|
||||
It was created by sqlite $as_me 3.7.17, which was
|
||||
It was created by sqlite $as_me 3.8.0, which was
|
||||
generated by GNU Autoconf 2.62. Invocation command line was
|
||||
|
||||
$ $0 $@
|
||||
@ -14032,7 +14032,7 @@ exec 6>&1
|
||||
# report actual input values of CONFIG_FILES etc. instead of their
|
||||
# values after options handling.
|
||||
ac_log="
|
||||
This file was extended by sqlite $as_me 3.7.17, which was
|
||||
This file was extended by sqlite $as_me 3.8.0, which was
|
||||
generated by GNU Autoconf 2.62. Invocation command line was
|
||||
|
||||
CONFIG_FILES = $CONFIG_FILES
|
||||
@ -14085,7 +14085,7 @@ Report bugs to <bug-autoconf@gnu.org>."
|
||||
_ACEOF
|
||||
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
|
||||
ac_cs_version="\\
|
||||
sqlite config.status 3.7.17
|
||||
sqlite config.status 3.8.0
|
||||
configured by $0, generated by GNU Autoconf 2.62,
|
||||
with options \\"`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"
|
||||
|
||||
|
@ -429,6 +429,7 @@ static void vtshimAuxDestructor(void *pXAux){
|
||||
assert( pAux->pAllVtab==0 );
|
||||
if( !pAux->bDisposed && pAux->xChildDestroy ){
|
||||
pAux->xChildDestroy(pAux->pChildAux);
|
||||
pAux->xChildDestroy = 0;
|
||||
}
|
||||
sqlite3_free(pAux->zName);
|
||||
sqlite3_free(pAux->pMod);
|
||||
@ -527,7 +528,10 @@ void sqlite3_dispose_module(void *pX){
|
||||
pAux->pMod->xDisconnect(pVtab->pChild);
|
||||
}
|
||||
pAux->bDisposed = 1;
|
||||
if( pAux->xChildDestroy ) pAux->xChildDestroy(pAux->pChildAux);
|
||||
if( pAux->xChildDestroy ){
|
||||
pAux->xChildDestroy(pAux->pChildAux);
|
||||
pAux->xChildDestroy = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
50
manifest
50
manifest
@ -1,5 +1,5 @@
|
||||
C Fix\stypos\sin\sa\scomment\sin\sanalyze.c.\sNo\scode\schanges.
|
||||
D 2013-08-07T16:38:33.619
|
||||
C Merge\slatest\strunk\schanges\swith\sthis\sbranch.
|
||||
D 2013-08-07T18:42:27.752
|
||||
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
||||
F Makefile.in 5e41da95d92656a5004b03d3576e8b226858a28e
|
||||
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
|
||||
@ -38,7 +38,7 @@ F autoconf/tea/win/rules.vc c511f222b80064096b705dbeb97060ee1d6b6d63
|
||||
F config.guess 226d9a188c6196f3033ffc651cbc9dcee1a42977
|
||||
F config.h.in 0921066a13130082764ab4ab6456f7b5bebe56de
|
||||
F config.sub 9ebe4c3b3dab6431ece34f16828b594fb420da55
|
||||
F configure 8bb8bd13d3c918c4c1c73480930e81f955ac298a x
|
||||
F configure 27e9279a219b652bd1c53439353a5e5be70214b2 x
|
||||
F configure.ac 81c43d151d0b0e406be056394cc9ff4cb3fd0444
|
||||
F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad
|
||||
F doc/lemon.html 334dbf6621b8fb8790297ec1abf3cfa4621709d1
|
||||
@ -115,7 +115,7 @@ F ext/misc/percentile.c bcbee3c061b884eccb80e21651daaae8e1e43c63
|
||||
F ext/misc/regexp.c af92cdaa5058fcec1451e49becc7ba44dba023dc
|
||||
F ext/misc/rot13.c 1ac6f95f99b575907b9b09c81a349114cf9be45a
|
||||
F ext/misc/spellfix.c 5e1d547e9a2aed13897fa91bac924333f62fd2d9
|
||||
F ext/misc/vtshim.c 5fb6be7fe37659a8cbd1e16982d74cceacbc4543
|
||||
F ext/misc/vtshim.c babb0dc2bf116029e3e7c9a618b8a1377045303e
|
||||
F ext/misc/wholenumber.c 784b12543d60702ebdd47da936e278aa03076212
|
||||
F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761
|
||||
F ext/rtree/rtree.c db516d7e59a14c92df10b552789509f2b632df3a
|
||||
@ -144,7 +144,7 @@ F mkdll.sh 7d09b23c05d56532e9d44a50868eb4b12ff4f74a
|
||||
F mkextu.sh 416f9b7089d80e5590a29692c9d9280a10dbad9f
|
||||
F mkextw.sh d2a981497b404d6498f5ff3e3b1f3816bdfcb338
|
||||
F mkopcodec.awk f6fccee29e68493bfd90a2e0466ede5fa94dd2fc
|
||||
F mkopcodeh.awk 29b84656502eee5f444c3147f331ee686956ab0e
|
||||
F mkopcodeh.awk e7334b45c023b5ee2efc6e8f479560c2026fa34a
|
||||
F mkso.sh fd21c06b063bb16a5d25deea1752c2da6ac3ed83
|
||||
F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271
|
||||
F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504
|
||||
@ -166,13 +166,13 @@ F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7
|
||||
F src/btree.c 15ea4e980ba5edeb9b495f001e86a0688f46ee2c
|
||||
F src/btree.h 6fa8a3ff2483d0bb64a9f0105a8cedeac9e00cca
|
||||
F src/btreeInt.h eecc84f02375b2bb7a44abbcbbe3747dde73edb2
|
||||
F src/build.c b2771cc57484ee4225a9eb6e57e6933be3f96e3b
|
||||
F src/build.c c2e4d057c833b616c6e32e690c29c03ba949b571
|
||||
F src/callback.c d7e46f40c3cf53c43550b7da7a1d0479910b62cc
|
||||
F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac
|
||||
F src/ctime.c 177fa0cbf28b8deda3f216603beee0b883408a40
|
||||
F src/date.c 067a81c9942c497aafd2c260e13add8a7d0c7dd4
|
||||
F src/delete.c 2317c814866d9aa71fea16b3faf4fdd4d6a49b94
|
||||
F src/expr.c 2068a7c17e45f8bee6e44205b059aa30acbc71c5
|
||||
F src/expr.c 0bbb44462a19169189b2709fbbd800950521b5ae
|
||||
F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
|
||||
F src/fkey.c 914a6bbd987d857c41ac9d244efa6641f36faadb
|
||||
F src/func.c 5c50c1ea31fd864b0fe921fe1a8d4c55acd609ef
|
||||
@ -206,7 +206,7 @@ F src/os_unix.c 9eafa5458cf2ff684ddccff82c9bb113c7cad847
|
||||
F src/os_win.c 1d84f2079d9b91f91a4b5dbfa5e08f1b1a0ed0ff
|
||||
F src/pager.c 5d2f7475260a8588f9c441bb309d2b7eaa7ded3b
|
||||
F src/pager.h 5cb78b8e1adfd5451e600be7719f5a99d87ac3b1
|
||||
F src/parse.y 599bc6338f3a6a7e1d656669a5667b9d77aea86b
|
||||
F src/parse.y 27c6b4138497d6f8360ba7847da6ed48033f957f
|
||||
F src/pcache.c f8043b433a57aba85384a531e3937a804432a346
|
||||
F src/pcache.h a5e4f5d9f5d592051d91212c5949517971ae6222
|
||||
F src/pcache1.c d23d07716de96c7c0c2503ec5051a4384c3fb938
|
||||
@ -216,12 +216,12 @@ F src/printf.c 41c49dac366a3a411190001a8ab495fa8887974e
|
||||
F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50
|
||||
F src/resolve.c 17e670996729ac41aadf6a31f57b4e6f29b3d819
|
||||
F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0
|
||||
F src/select.c 20369c82dc38eb4a77b458c8f6e353ef550580c9
|
||||
F src/shell.c cb075e24f125e08cc6deb4d8837b0b7ff394e65d
|
||||
F src/sqlite.h.in 442c109e0c3447c34b1794971ecdb673ce08a843
|
||||
F src/select.c 8b148eb851f384412aea57091659d14b369918ca
|
||||
F src/shell.c 128eb16ccec68509a4a2f1948f2483819bf63425
|
||||
F src/sqlite.h.in bd1451ba1ab681022a53bccc3c39580ba094a3ff
|
||||
F src/sqlite3.rc fea433eb0a59f4c9393c8e6d76a6e2596b1fe0c0
|
||||
F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc
|
||||
F src/sqliteInt.h 42adcd08a254fe14d8a369cf6381cf15e2e2e971
|
||||
F src/sqliteInt.h dfb02189a27dac993ee6635017dd3d6926508f5a
|
||||
F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d
|
||||
F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158
|
||||
F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e
|
||||
@ -236,30 +236,30 @@ F src/test7.c 126b886b53f0358b92aba9b81d3fcbfbe9a93cd6
|
||||
F src/test8.c 7ee77ea522ae34aa691dfe407139dec80d4fc039
|
||||
F src/test9.c bea1e8cf52aa93695487badedd6e1886c321ea60
|
||||
F src/test_async.c 21e11293a2f72080eda70e1124e9102044531cd8
|
||||
F src/test_autoext.c 32cff3d01cdd3202486e623c3f8103ed04cb57fa
|
||||
F src/test_autoext.c dea8a01a7153b9adc97bd26161e4226329546e12
|
||||
F src/test_backup.c 3875e899222b651e18b662f86e0e50daa946344e
|
||||
F src/test_btree.c 5b89601dcb42a33ba8b820a6b763cc9cb48bac16
|
||||
F src/test_config.c 636ecd15a6ba18bf97a590b5a21f47573c8c2b65
|
||||
F src/test_demovfs.c 20a4975127993f4959890016ae9ce5535a880094
|
||||
F src/test_demovfs.c 69b2085076654ebc18014cbc6386f04409c959a9
|
||||
F src/test_devsym.c e7498904e72ba7491d142d5c83b476c4e76993bc
|
||||
F src/test_fs.c 8f786bfd0ad48030cf2a06fb1f050e9c60a150d7
|
||||
F src/test_fs.c ced436e3d4b8e4681328409b8081051ce614e28f
|
||||
F src/test_func.c fcd238feb694332d5962ee08578ef30ff4ac6559
|
||||
F src/test_hexio.c abfdecb6fa58c354623978efceb088ca18e379cd
|
||||
F src/test_init.c 3cbad7ce525aec925f8fda2192d576d47f0d478a
|
||||
F src/test_intarray.c 87847c71c3c36889c0bcc9c4baf9d31881665d61
|
||||
F src/test_intarray.h b999bb18d090b8d9d9c49d36ec37ef8f341fe169
|
||||
F src/test_intarray.h 2ece66438cfd177b78d1bfda7a4180cd3a10844d
|
||||
F src/test_journal.c f5c0a05b7b3d5930db769b5ee6c3766dc2221a64
|
||||
F src/test_loadext.c df586c27176e3c2cb2e099c78da67bf14379a56e
|
||||
F src/test_malloc.c a105801222c0514f8befa2a1712a95505cce099a
|
||||
F src/test_multiplex.c 5d691eeb6cb6aa7888da28eba5e62a9a857d3c0f
|
||||
F src/test_multiplex.h 9b63b95f07acedee425fdfe49a47197c9bf5f9d8
|
||||
F src/test_multiplex.h 110a8c4d356e0aa464ca8730375608a9a0b61ae1
|
||||
F src/test_mutex.c 293042d623ebba969160f471a82aa1551626454f
|
||||
F src/test_onefile.c 0396f220561f3b4eedc450cef26d40c593c69a25
|
||||
F src/test_osinst.c 90a845c8183013d80eccb1f29e8805608516edba
|
||||
F src/test_pcache.c a5cd24730cb43c5b18629043314548c9169abb00
|
||||
F src/test_quota.c 30c64f0ef84734f2231a686df41ed882b0c59bc0
|
||||
F src/test_quota.h 8761e463b25e75ebc078bd67d70e39b9c817a0cb
|
||||
F src/test_rtree.c 1d764c352b5348bb2869ff5f54aff8eadcb96041
|
||||
F src/test_rtree.c f3d1d12538dccb75fd916e3fa58f250edbdd3b47
|
||||
F src/test_schema.c cd12a2223c3a394f4d07bb93bdf6d344c5c121b6
|
||||
F src/test_server.c 2f99eb2837dfa06a4aacf24af24c6affdf66a84f
|
||||
F src/test_sqllog.c c1c1bbedbcaf82b93d83e4f9dd990e62476a680e
|
||||
@ -277,11 +277,11 @@ F src/update.c 7d9d38e4f341ada7d79035ea969cdefb8b9014d1
|
||||
F src/utf.c 6fc6c88d50448c469c5c196acf21617a24f90269
|
||||
F src/util.c f566b5138099a2df8533b190d0dcc74b7dfbe0c9
|
||||
F src/vacuum.c d9c5759f4c5a438bb43c2086f72c5d2edabc36c8
|
||||
F src/vdbe.c 91fa72a040cb1065045fce5e84196be093e29918
|
||||
F src/vdbe.c a3c98ec54d27b30b67b6247ed0a29268de11dc17
|
||||
F src/vdbe.h 4f554b5627f26710c4c36d919110a3fc611ca5c4
|
||||
F src/vdbeInt.h e9b7c6b165a31a4715c5aa97223d20d265515231
|
||||
F src/vdbeapi.c 4d13580bd058b39623e8fcfc233b7df4b8191e8b
|
||||
F src/vdbeaux.c 4389b3692969b4415fcfd00de36818a02f84df28
|
||||
F src/vdbeaux.c a6ea36a9dc714e1128a0173249a0532ddcab0489
|
||||
F src/vdbeblob.c 5dc79627775bd9a9b494dd956e26297946417d69
|
||||
F src/vdbemem.c f0512045147702adec3ca6388663e243c17d2ea4
|
||||
F src/vdbesort.c 3937e06b2a0e354500e17dc206ef4c35770a5017
|
||||
@ -290,7 +290,7 @@ F src/vtab.c 2e8b489db47e20ae36cd247932dc671c9ded0624
|
||||
F src/wal.c 7dc3966ef98b74422267e7e6e46e07ff6c6eb1b4
|
||||
F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4
|
||||
F src/walker.c 4fa43583d0a84b48f93b1e88f11adf2065be4e73
|
||||
F src/where.c 4e188dc4a1f668d761750eb27e603616179806d0
|
||||
F src/where.c 0051a3640491a67ce2d4abcbffc687a818bb49f7
|
||||
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
|
||||
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
|
||||
F test/aggnested.test 45c0201e28045ad38a530b5a144b73cd4aa2cfd6
|
||||
@ -591,7 +591,7 @@ F test/index2.test ee83c6b5e3173a3d7137140d945d9a5d4fdfb9d6
|
||||
F test/index3.test 423a25c789fc8cc51aaf2a4370bbdde2d9e9eed7
|
||||
F test/index4.test 2983216eb8c86ee62d9ed7cb206b5cc3331c0026
|
||||
F test/index5.test fc07c14193c0430814e7a08b5da46888ee795c33
|
||||
F test/index6.test 0005b3093012c6d0f20cc54d9057210221216143
|
||||
F test/index6.test 5be279e46e5f40e2dcc67d9b2aecdb5b0031db18
|
||||
F test/indexedby.test 0e959308707c808515c3a51363f7a9835027108c
|
||||
F test/indexfault.test 31d4ab9a7d2f6e9616933eb079722362a883eb1d
|
||||
F test/init.test 15c823093fdabbf7b531fe22cf037134d09587a7
|
||||
@ -1106,7 +1106,7 @@ F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
|
||||
F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381
|
||||
F tool/wherecosttest.c f407dc4c79786982a475261866a161cd007947ae
|
||||
F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac
|
||||
P 13ed5ac13562e7a39905d70fd47059f4d8001bba
|
||||
R 084c38143e1dba830587618d10f058e0
|
||||
P 812ed0c58fc5f729a2d4f16775fad6724cc367a6 0ad83ceb79767738bd06a28840cf84da0464ab4f
|
||||
R d674ab11a2de1d9766d2ac27cc923b51
|
||||
U dan
|
||||
Z 1a4859355b309a8c52cef488ffe4e611
|
||||
Z 85dc674af92c540fb0c7cdb1bc5adf5a
|
||||
|
@ -1 +1 @@
|
||||
812ed0c58fc5f729a2d4f16775fad6724cc367a6
|
||||
08f74c45ecf711a2373af578d44470add9082377
|
@ -35,7 +35,7 @@
|
||||
|
||||
# Remember the TK_ values from the parse.h file
|
||||
/^#define TK_/ {
|
||||
tk[$2] = 0+$3
|
||||
tk[$2] = 0+$3 # tk[x] holds the numeric value for TK symbol X
|
||||
}
|
||||
|
||||
# Scan for "case OP_aaaa:" lines in the vdbe.c file
|
||||
@ -43,7 +43,7 @@
|
||||
name = $2
|
||||
sub(/:/,"",name)
|
||||
sub("\r","",name)
|
||||
op[name] = -1
|
||||
op[name] = -1 # op[x] holds the numeric value for OP symbol x
|
||||
jump[name] = 0
|
||||
out2_prerelease[name] = 0
|
||||
in1[name] = 0
|
||||
@ -55,9 +55,11 @@
|
||||
if($i=="same" && $(i+1)=="as"){
|
||||
sym = $(i+2)
|
||||
sub(/,/,"",sym)
|
||||
op[name] = tk[sym]
|
||||
used[op[name]] = 1
|
||||
sameas[op[name]] = sym
|
||||
val = tk[sym]
|
||||
op[name] = val
|
||||
used[val] = 1
|
||||
sameas[val] = sym
|
||||
def[val] = name
|
||||
}
|
||||
x = $i
|
||||
sub(",","",x)
|
||||
@ -90,31 +92,55 @@ END {
|
||||
order[n_op++] = "OP_Noop";
|
||||
op["OP_Explain"] = -1;
|
||||
order[n_op++] = "OP_Explain";
|
||||
|
||||
# Assign small values to opcodes that are processed by resolveP2Values()
|
||||
# to make code generation for the switch() statement smaller and faster.
|
||||
for(i=0; i<n_op; i++){
|
||||
name = order[i];
|
||||
if( op[name]>=0 ) continue;
|
||||
if( name=="OP_Function" \
|
||||
|| name=="OP_AggStep" \
|
||||
|| name=="OP_Transaction" \
|
||||
|| name=="OP_AutoCommit" \
|
||||
|| name=="OP_Savepoint" \
|
||||
|| name=="OP_Checkpoint" \
|
||||
|| name=="OP_Vacuum" \
|
||||
|| name=="OP_JournalMode" \
|
||||
|| name=="OP_VUpdate" \
|
||||
|| name=="OP_VFilter" \
|
||||
|| name=="OP_Next" \
|
||||
|| name=="OP_SorterNext" \
|
||||
|| name=="OP_Prev" \
|
||||
){
|
||||
cnt++
|
||||
while( used[cnt] ) cnt++
|
||||
op[name] = cnt
|
||||
used[cnt] = 1
|
||||
def[cnt] = name
|
||||
}
|
||||
}
|
||||
|
||||
# Generate the numeric values for opcodes
|
||||
for(i=0; i<n_op; i++){
|
||||
name = order[i];
|
||||
if( op[name]<0 ){
|
||||
cnt++
|
||||
while( used[cnt] ) cnt++
|
||||
op[name] = cnt
|
||||
used[cnt] = 1
|
||||
def[cnt] = name
|
||||
}
|
||||
used[op[name]] = 1;
|
||||
if( op[name]>max ) max = op[name]
|
||||
printf "#define %-25s %15d", name, op[name]
|
||||
if( sameas[op[name]] ) {
|
||||
printf " /* same as %-12s*/", sameas[op[name]]
|
||||
}
|
||||
max = cnt
|
||||
for(i=1; i<=max; i++){
|
||||
if( !used[i] ){
|
||||
def[i] = "OP_NotUsed_" i
|
||||
}
|
||||
printf "#define %-25s %15d", def[i], i
|
||||
if( sameas[i] ){
|
||||
printf " /* same as %-12s*/", sameas[i]
|
||||
}
|
||||
printf "\n"
|
||||
|
||||
}
|
||||
seenUnused = 0;
|
||||
for(i=1; i<max; i++){
|
||||
if( !used[i] ){
|
||||
if( !seenUnused ){
|
||||
printf "\n/* The following opcode values are never used */\n"
|
||||
seenUnused = 1
|
||||
}
|
||||
printf "#define %-25s %15d\n", sprintf( "OP_NotUsed_%-3d", i ), i
|
||||
}
|
||||
}
|
||||
|
||||
# Generate the bitvectors:
|
||||
@ -123,12 +149,9 @@ END {
|
||||
# bit 1: pushes a result onto stack
|
||||
# bit 2: output to p1. release p1 before opcode runs
|
||||
#
|
||||
for(i=0; i<=max; i++) bv[i] = 0;
|
||||
for(i=0; i<n_op; i++){
|
||||
name = order[i];
|
||||
x = op[name]
|
||||
for(i=0; i<=max; i++){
|
||||
name = def[i]
|
||||
a0 = a1 = a2 = a3 = a4 = a5 = a6 = a7 = 0
|
||||
# a7 = a9 = a10 = a11 = a12 = a13 = a14 = a15 = 0
|
||||
if( jump[name] ) a0 = 1;
|
||||
if( out2_prerelease[name] ) a1 = 2;
|
||||
if( in1[name] ) a2 = 4;
|
||||
@ -136,8 +159,7 @@ END {
|
||||
if( in3[name] ) a4 = 16;
|
||||
if( out2[name] ) a5 = 32;
|
||||
if( out3[name] ) a6 = 64;
|
||||
# bv[x] = a0+a1+a2+a3+a4+a5+a6+a7+a8+a9+a10+a11+a12+a13+a14+a15;
|
||||
bv[x] = a0+a1+a2+a3+a4+a5+a6+a7;
|
||||
bv[i] = a0+a1+a2+a3+a4+a5+a6+a7;
|
||||
}
|
||||
print "\n"
|
||||
print "/* Properties such as \"out2\" or \"jump\" that are specified in"
|
||||
|
11
src/build.c
11
src/build.c
@ -3805,25 +3805,20 @@ void sqlite3Reindex(Parse *pParse, Token *pName1, Token *pName2){
|
||||
KeyInfo *sqlite3IndexKeyinfo(Parse *pParse, Index *pIdx){
|
||||
int i;
|
||||
int nCol = pIdx->nColumn;
|
||||
int nBytes = sizeof(KeyInfo) + (nCol-1)*sizeof(CollSeq*) + nCol;
|
||||
sqlite3 *db = pParse->db;
|
||||
KeyInfo *pKey = (KeyInfo *)sqlite3DbMallocZero(db, nBytes);
|
||||
KeyInfo *pKey;
|
||||
|
||||
pKey = sqlite3KeyInfoAlloc(pParse->db, nCol);
|
||||
if( pKey ){
|
||||
pKey->db = pParse->db;
|
||||
pKey->aSortOrder = (u8 *)&(pKey->aColl[nCol]);
|
||||
assert( &pKey->aSortOrder[nCol]==&(((u8 *)pKey)[nBytes]) );
|
||||
for(i=0; i<nCol; i++){
|
||||
char *zColl = pIdx->azColl[i];
|
||||
assert( zColl );
|
||||
pKey->aColl[i] = sqlite3LocateCollSeq(pParse, zColl);
|
||||
pKey->aSortOrder[i] = pIdx->aSortOrder[i];
|
||||
}
|
||||
pKey->nField = (u16)nCol;
|
||||
}
|
||||
|
||||
if( pParse->nErr ){
|
||||
sqlite3DbFree(db, pKey);
|
||||
sqlite3DbFree(pParse->db, pKey);
|
||||
pKey = 0;
|
||||
}
|
||||
return pKey;
|
||||
|
27
src/expr.c
27
src/expr.c
@ -1692,10 +1692,9 @@ int sqlite3CodeSubselect(
|
||||
switch( pExpr->op ){
|
||||
case TK_IN: {
|
||||
char affinity; /* Affinity of the LHS of the IN */
|
||||
KeyInfo keyInfo; /* Keyinfo for the generated table */
|
||||
static u8 sortOrder = 0; /* Fake aSortOrder for keyInfo */
|
||||
int addr; /* Address of OP_OpenEphemeral instruction */
|
||||
Expr *pLeft = pExpr->pLeft; /* the LHS of the IN operator */
|
||||
KeyInfo *pKeyInfo = 0; /* Key information */
|
||||
|
||||
if( rMayHaveNull ){
|
||||
sqlite3VdbeAddOp2(v, OP_Null, 0, rMayHaveNull);
|
||||
@ -1719,9 +1718,7 @@ int sqlite3CodeSubselect(
|
||||
pExpr->iTable = pParse->nTab++;
|
||||
addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pExpr->iTable, !isRowid);
|
||||
if( rMayHaveNull==0 ) sqlite3VdbeChangeP5(v, BTREE_UNORDERED);
|
||||
memset(&keyInfo, 0, sizeof(keyInfo));
|
||||
keyInfo.nField = 1;
|
||||
keyInfo.aSortOrder = &sortOrder;
|
||||
pKeyInfo = isRowid ? 0 : sqlite3KeyInfoAlloc(pParse->db, 1);
|
||||
|
||||
if( ExprHasProperty(pExpr, EP_xIsSelect) ){
|
||||
/* Case 1: expr IN (SELECT ...)
|
||||
@ -1737,14 +1734,17 @@ int sqlite3CodeSubselect(
|
||||
dest.affSdst = (u8)affinity;
|
||||
assert( (pExpr->iTable&0x0000FFFF)==pExpr->iTable );
|
||||
pExpr->x.pSelect->iLimit = 0;
|
||||
testcase( pKeyInfo==0 ); /* Caused by OOM in sqlite3KeyInfoAlloc() */
|
||||
if( sqlite3Select(pParse, pExpr->x.pSelect, &dest) ){
|
||||
sqlite3DbFree(pParse->db, pKeyInfo);
|
||||
return 0;
|
||||
}
|
||||
pEList = pExpr->x.pSelect->pEList;
|
||||
if( ALWAYS(pEList!=0 && pEList->nExpr>0) ){
|
||||
keyInfo.aColl[0] = sqlite3BinaryCompareCollSeq(pParse, pExpr->pLeft,
|
||||
pEList->a[0].pExpr);
|
||||
}
|
||||
assert( pKeyInfo!=0 ); /* OOM will cause exit after sqlite3Select() */
|
||||
assert( pEList!=0 );
|
||||
assert( pEList->nExpr>0 );
|
||||
pKeyInfo->aColl[0] = sqlite3BinaryCompareCollSeq(pParse, pExpr->pLeft,
|
||||
pEList->a[0].pExpr);
|
||||
}else if( ALWAYS(pExpr->x.pList!=0) ){
|
||||
/* Case 2: expr IN (exprlist)
|
||||
**
|
||||
@ -1761,8 +1761,9 @@ int sqlite3CodeSubselect(
|
||||
if( !affinity ){
|
||||
affinity = SQLITE_AFF_NONE;
|
||||
}
|
||||
keyInfo.aColl[0] = sqlite3ExprCollSeq(pParse, pExpr->pLeft);
|
||||
keyInfo.aSortOrder = &sortOrder;
|
||||
if( pKeyInfo ){
|
||||
pKeyInfo->aColl[0] = sqlite3ExprCollSeq(pParse, pExpr->pLeft);
|
||||
}
|
||||
|
||||
/* Loop through each expression in <exprlist>. */
|
||||
r1 = sqlite3GetTempReg(pParse);
|
||||
@ -1801,8 +1802,8 @@ int sqlite3CodeSubselect(
|
||||
sqlite3ReleaseTempReg(pParse, r1);
|
||||
sqlite3ReleaseTempReg(pParse, r2);
|
||||
}
|
||||
if( !isRowid ){
|
||||
sqlite3VdbeChangeP4(v, addr, (void *)&keyInfo, P4_KEYINFO);
|
||||
if( pKeyInfo ){
|
||||
sqlite3VdbeChangeP4(v, addr, (void *)pKeyInfo, P4_KEYINFO_HANDOFF);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -417,6 +417,7 @@ select(A) ::= select(X) multiselect_op(Y) oneselect(Z). {
|
||||
if( Z ){
|
||||
Z->op = (u8)Y;
|
||||
Z->pPrior = X;
|
||||
if( Y!=TK_ALL ) pParse->hasCompound = 1;
|
||||
}else{
|
||||
sqlite3SelectDelete(pParse->db, X);
|
||||
}
|
||||
|
57
src/select.c
57
src/select.c
@ -802,6 +802,25 @@ static void selectInnerLoop(
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Allocate a KeyInfo object sufficient for an index of N columns.
|
||||
**
|
||||
** Actually, always allocate one extra column for the rowid at the end
|
||||
** of the index. So the KeyInfo returned will have space sufficient for
|
||||
** N+1 columns.
|
||||
*/
|
||||
KeyInfo *sqlite3KeyInfoAlloc(sqlite3 *db, int N){
|
||||
KeyInfo *p = sqlite3DbMallocZero(db,
|
||||
sizeof(KeyInfo) + (N+1)*(sizeof(CollSeq*)+1));
|
||||
if( p ){
|
||||
p->aSortOrder = (u8*)&p->aColl[N+1];
|
||||
p->nField = (u16)N;
|
||||
p->enc = ENC(db);
|
||||
p->db = db;
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
/*
|
||||
** Given an expression list, generate a KeyInfo structure that records
|
||||
** the collating sequence for each expression in that expression list.
|
||||
@ -818,25 +837,19 @@ static void selectInnerLoop(
|
||||
** P4_KEYINFO_HANDOFF is the usual way of dealing with this.
|
||||
*/
|
||||
static KeyInfo *keyInfoFromExprList(Parse *pParse, ExprList *pList){
|
||||
sqlite3 *db = pParse->db;
|
||||
int nExpr;
|
||||
KeyInfo *pInfo;
|
||||
struct ExprList_item *pItem;
|
||||
sqlite3 *db = pParse->db;
|
||||
int i;
|
||||
|
||||
nExpr = pList->nExpr;
|
||||
pInfo = sqlite3DbMallocZero(db, sizeof(*pInfo) + nExpr*(sizeof(CollSeq*)+1) );
|
||||
pInfo = sqlite3KeyInfoAlloc(db, nExpr);
|
||||
if( pInfo ){
|
||||
pInfo->aSortOrder = (u8*)&pInfo->aColl[nExpr];
|
||||
pInfo->nField = (u16)nExpr;
|
||||
pInfo->enc = ENC(db);
|
||||
pInfo->db = db;
|
||||
for(i=0, pItem=pList->a; i<nExpr; i++, pItem++){
|
||||
CollSeq *pColl;
|
||||
pColl = sqlite3ExprCollSeq(pParse, pItem->pExpr);
|
||||
if( !pColl ){
|
||||
pColl = db->pDfltColl;
|
||||
}
|
||||
if( !pColl ) pColl = db->pDfltColl;
|
||||
pInfo->aColl[i] = pColl;
|
||||
pInfo->aSortOrder[i] = pItem->sortOrder;
|
||||
}
|
||||
@ -1942,23 +1955,17 @@ static int multiSelect(
|
||||
|
||||
assert( p->pRightmost==p );
|
||||
nCol = p->pEList->nExpr;
|
||||
pKeyInfo = sqlite3DbMallocZero(db,
|
||||
sizeof(*pKeyInfo)+nCol*(sizeof(CollSeq*) + 1));
|
||||
pKeyInfo = sqlite3KeyInfoAlloc(db, nCol);
|
||||
if( !pKeyInfo ){
|
||||
rc = SQLITE_NOMEM;
|
||||
goto multi_select_end;
|
||||
}
|
||||
|
||||
pKeyInfo->enc = ENC(db);
|
||||
pKeyInfo->nField = (u16)nCol;
|
||||
|
||||
for(i=0, apColl=pKeyInfo->aColl; i<nCol; i++, apColl++){
|
||||
*apColl = multiSelectCollSeq(pParse, p, i);
|
||||
if( 0==*apColl ){
|
||||
*apColl = db->pDfltColl;
|
||||
}
|
||||
}
|
||||
pKeyInfo->aSortOrder = (u8*)apColl;
|
||||
|
||||
for(pLoop=p; pLoop; pLoop=pLoop->pPrior){
|
||||
for(i=0; i<2; i++){
|
||||
@ -2327,12 +2334,8 @@ static int multiSelectOrderBy(
|
||||
assert( pItem->iOrderByCol>0 && pItem->iOrderByCol<=p->pEList->nExpr );
|
||||
aPermute[i] = pItem->iOrderByCol - 1;
|
||||
}
|
||||
pKeyMerge =
|
||||
sqlite3DbMallocRaw(db, sizeof(*pKeyMerge)+nOrderBy*(sizeof(CollSeq*)+1));
|
||||
pKeyMerge = sqlite3KeyInfoAlloc(db, nOrderBy);
|
||||
if( pKeyMerge ){
|
||||
pKeyMerge->aSortOrder = (u8*)&pKeyMerge->aColl[nOrderBy];
|
||||
pKeyMerge->nField = (u16)nOrderBy;
|
||||
pKeyMerge->enc = ENC(db);
|
||||
for(i=0; i<nOrderBy; i++){
|
||||
CollSeq *pColl;
|
||||
Expr *pTerm = pOrderBy->a[i].pExpr;
|
||||
@ -2369,12 +2372,8 @@ static int multiSelectOrderBy(
|
||||
regPrev = pParse->nMem+1;
|
||||
pParse->nMem += nExpr+1;
|
||||
sqlite3VdbeAddOp2(v, OP_Integer, 0, regPrev);
|
||||
pKeyDup = sqlite3DbMallocZero(db,
|
||||
sizeof(*pKeyDup) + nExpr*(sizeof(CollSeq*)+1) );
|
||||
pKeyDup = sqlite3KeyInfoAlloc(db, nExpr);
|
||||
if( pKeyDup ){
|
||||
pKeyDup->aSortOrder = (u8*)&pKeyDup->aColl[nExpr];
|
||||
pKeyDup->nField = (u16)nExpr;
|
||||
pKeyDup->enc = ENC(db);
|
||||
for(i=0; i<nExpr; i++){
|
||||
pKeyDup->aColl[i] = multiSelectCollSeq(pParse, p, i);
|
||||
pKeyDup->aSortOrder[i] = 0;
|
||||
@ -3640,10 +3639,12 @@ static int exprWalkNoop(Walker *NotUsed, Expr *NotUsed2){
|
||||
static void sqlite3SelectExpand(Parse *pParse, Select *pSelect){
|
||||
Walker w;
|
||||
memset(&w, 0, sizeof(w));
|
||||
w.xSelectCallback = convertCompoundSelectToSubquery;
|
||||
w.xExprCallback = exprWalkNoop;
|
||||
w.pParse = pParse;
|
||||
sqlite3WalkSelect(&w, pSelect);
|
||||
if( pParse->hasCompound ){
|
||||
w.xSelectCallback = convertCompoundSelectToSubquery;
|
||||
sqlite3WalkSelect(&w, pSelect);
|
||||
}
|
||||
w.xSelectCallback = selectExpander;
|
||||
sqlite3WalkSelect(&w, pSelect);
|
||||
}
|
||||
|
147
src/shell.c
147
src/shell.c
@ -53,7 +53,6 @@
|
||||
# include <readline/history.h>
|
||||
#endif
|
||||
#if !defined(HAVE_EDITLINE) && (!defined(HAVE_READLINE) || HAVE_READLINE!=1)
|
||||
# define readline(p) local_getline(p,stdin,0)
|
||||
# define add_history(X)
|
||||
# define read_history(X)
|
||||
# define write_history(X)
|
||||
@ -337,23 +336,13 @@ static void shellstaticFunc(
|
||||
** to the text. NULL is returned at end of file, or if malloc()
|
||||
** fails.
|
||||
**
|
||||
** The interface is like "readline" but no command-line editing
|
||||
** is done.
|
||||
** If zLine is not NULL then it is a malloced buffer returned from
|
||||
** a previous call to this routine that may be reused.
|
||||
*/
|
||||
static char *local_getline(char *zPrompt, FILE *in, int csvFlag){
|
||||
char *zLine;
|
||||
int nLine;
|
||||
int n;
|
||||
int inQuote = 0;
|
||||
static char *local_getline(char *zLine, FILE *in){
|
||||
int nLine = zLine==0 ? 0 : 100;
|
||||
int n = 0;
|
||||
|
||||
if( zPrompt && *zPrompt ){
|
||||
printf("%s",zPrompt);
|
||||
fflush(stdout);
|
||||
}
|
||||
nLine = 100;
|
||||
zLine = malloc( nLine );
|
||||
if( zLine==0 ) return 0;
|
||||
n = 0;
|
||||
while( 1 ){
|
||||
if( n+100>nLine ){
|
||||
nLine = nLine*2 + 100;
|
||||
@ -368,42 +357,48 @@ static char *local_getline(char *zPrompt, FILE *in, int csvFlag){
|
||||
zLine[n] = 0;
|
||||
break;
|
||||
}
|
||||
while( zLine[n] ){
|
||||
if( zLine[n]=='"' ) inQuote = !inQuote;
|
||||
n++;
|
||||
}
|
||||
if( n>0 && zLine[n-1]=='\n' && (!inQuote || !csvFlag) ){
|
||||
while( zLine[n] ) n++;
|
||||
if( n>0 && zLine[n-1]=='\n' ){
|
||||
n--;
|
||||
if( n>0 && zLine[n-1]=='\r' ) n--;
|
||||
zLine[n] = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
zLine = realloc( zLine, n+1 );
|
||||
return zLine;
|
||||
}
|
||||
|
||||
/*
|
||||
** Retrieve a single line of input text.
|
||||
**
|
||||
** zPrior is a string of prior text retrieved. If not the empty
|
||||
** string, then issue a continuation prompt.
|
||||
** If in==0 then read from standard input and prompt before each line.
|
||||
** If isContinuation is true, then a continuation prompt is appropriate.
|
||||
** If isContinuation is zero, then the main prompt should be used.
|
||||
**
|
||||
** If zPrior is not NULL then it is a buffer from a prior call to this
|
||||
** routine that can be reused.
|
||||
**
|
||||
** The result is stored in space obtained from malloc() and must either
|
||||
** be freed by the caller or else passed back into this routine via the
|
||||
** zPrior argument for reuse.
|
||||
*/
|
||||
static char *one_input_line(const char *zPrior, FILE *in){
|
||||
static char *one_input_line(FILE *in, char *zPrior, int isContinuation){
|
||||
char *zPrompt;
|
||||
char *zResult;
|
||||
if( in!=0 ){
|
||||
return local_getline(0, in, 0);
|
||||
}
|
||||
if( zPrior && zPrior[0] ){
|
||||
zPrompt = continuePrompt;
|
||||
zResult = local_getline(zPrior, in);
|
||||
}else{
|
||||
zPrompt = mainPrompt;
|
||||
}
|
||||
zResult = readline(zPrompt);
|
||||
zPrompt = isContinuation ? continuePrompt : mainPrompt;
|
||||
#if defined(HAVE_READLINE) && HAVE_READLINE==1
|
||||
if( zResult && *zResult ) add_history(zResult);
|
||||
free(zPrior);
|
||||
zResult = readline(zPrompt);
|
||||
if( zResult && *zResult ) add_history(zResult);
|
||||
#else
|
||||
printf("%s", zPrompt);
|
||||
fflush(stdout);
|
||||
zResult = local_getline(zPrior, stdin);
|
||||
#endif
|
||||
}
|
||||
return zResult;
|
||||
}
|
||||
|
||||
@ -1995,6 +1990,7 @@ static int do_meta_command(char *zLine, struct callback_data *p){
|
||||
int nCol; /* Number of columns in the table */
|
||||
int nByte; /* Number of bytes in an SQL string */
|
||||
int i, j; /* Loop counters */
|
||||
int needCommit; /* True to COMMIT or ROLLBACK at end */
|
||||
int nSep; /* Number of bytes in p->separator[] */
|
||||
char *zSql; /* An SQL statement */
|
||||
CSVReader sCsv; /* Reader context */
|
||||
@ -2096,6 +2092,8 @@ static int do_meta_command(char *zLine, struct callback_data *p){
|
||||
xCloser(sCsv.in);
|
||||
return 1;
|
||||
}
|
||||
needCommit = sqlite3_get_autocommit(db);
|
||||
if( needCommit ) sqlite3_exec(db, "BEGIN", 0, 0, 0);
|
||||
do{
|
||||
int startLine = sCsv.nLine;
|
||||
for(i=0; i<nCol; i++){
|
||||
@ -2132,7 +2130,7 @@ static int do_meta_command(char *zLine, struct callback_data *p){
|
||||
xCloser(sCsv.in);
|
||||
sqlite3_free(sCsv.z);
|
||||
sqlite3_finalize(pStmt);
|
||||
sqlite3_exec(p->db, "COMMIT", 0, 0, 0);
|
||||
if( needCommit ) sqlite3_exec(db, "COMMIT", 0, 0, 0);
|
||||
}else
|
||||
|
||||
if( c=='i' && strncmp(azArg[0], "indices", n)==0 && nArg<3 ){
|
||||
@ -2781,7 +2779,7 @@ static int do_meta_command(char *zLine, struct callback_data *p){
|
||||
** Return TRUE if a semicolon occurs anywhere in the first N characters
|
||||
** of string z[].
|
||||
*/
|
||||
static int _contains_semicolon(const char *z, int N){
|
||||
static int line_contains_semicolon(const char *z, int N){
|
||||
int i;
|
||||
for(i=0; i<N; i++){ if( z[i]==';' ) return 1; }
|
||||
return 0;
|
||||
@ -2816,7 +2814,7 @@ static int _all_whitespace(const char *z){
|
||||
** than a semi-colon. The SQL Server style "go" command is understood
|
||||
** as is the Oracle "/".
|
||||
*/
|
||||
static int _is_command_terminator(const char *zLine){
|
||||
static int line_is_command_terminator(const char *zLine){
|
||||
while( IsSpace(zLine[0]) ){ zLine++; };
|
||||
if( zLine[0]=='/' && _all_whitespace(&zLine[1]) ){
|
||||
return 1; /* Oracle */
|
||||
@ -2832,7 +2830,7 @@ static int _is_command_terminator(const char *zLine){
|
||||
** Return true if zSql is a complete SQL statement. Return false if it
|
||||
** ends in the middle of a string literal or C-style comment.
|
||||
*/
|
||||
static int _is_complete(char *zSql, int nSql){
|
||||
static int line_is_complete(char *zSql, int nSql){
|
||||
int rc;
|
||||
if( zSql==0 ) return 1;
|
||||
zSql[nSql] = ';';
|
||||
@ -2852,20 +2850,21 @@ static int _is_complete(char *zSql, int nSql){
|
||||
** Return the number of errors.
|
||||
*/
|
||||
static int process_input(struct callback_data *p, FILE *in){
|
||||
char *zLine = 0;
|
||||
char *zSql = 0;
|
||||
int nSql = 0;
|
||||
int nSqlPrior = 0;
|
||||
char *zErrMsg;
|
||||
int rc;
|
||||
int errCnt = 0;
|
||||
int lineno = 0;
|
||||
int startline = 0;
|
||||
char *zLine = 0; /* A single input line */
|
||||
char *zSql = 0; /* Accumulated SQL text */
|
||||
int nLine; /* Length of current line */
|
||||
int nSql = 0; /* Bytes of zSql[] used */
|
||||
int nAlloc = 0; /* Allocated zSql[] space */
|
||||
int nSqlPrior = 0; /* Bytes of zSql[] used by prior line */
|
||||
char *zErrMsg; /* Error message returned */
|
||||
int rc; /* Error code */
|
||||
int errCnt = 0; /* Number of errors seen */
|
||||
int lineno = 0; /* Current line number */
|
||||
int startline = 0; /* Line number for start of current input */
|
||||
|
||||
while( errCnt==0 || !bail_on_error || (in==0 && stdin_is_interactive) ){
|
||||
fflush(p->out);
|
||||
free(zLine);
|
||||
zLine = one_input_line(zSql, in);
|
||||
zLine = one_input_line(in, zLine, nSql>0);
|
||||
if( zLine==0 ){
|
||||
/* End of input */
|
||||
if( stdin_is_interactive ) printf("\n");
|
||||
@ -2876,7 +2875,7 @@ static int process_input(struct callback_data *p, FILE *in){
|
||||
seenInterrupt = 0;
|
||||
}
|
||||
lineno++;
|
||||
if( (zSql==0 || zSql[0]==0) && _all_whitespace(zLine) ) continue;
|
||||
if( nSql==0 && _all_whitespace(zLine) ) continue;
|
||||
if( zLine && zLine[0]=='.' && nSql==0 ){
|
||||
if( p->echoOn ) printf("%s\n", zLine);
|
||||
rc = do_meta_command(zLine, p);
|
||||
@ -2887,35 +2886,31 @@ static int process_input(struct callback_data *p, FILE *in){
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if( _is_command_terminator(zLine) && _is_complete(zSql, nSql) ){
|
||||
if( line_is_command_terminator(zLine) && line_is_complete(zSql, nSql) ){
|
||||
memcpy(zLine,";",2);
|
||||
}
|
||||
nSqlPrior = nSql;
|
||||
if( zSql==0 ){
|
||||
int i;
|
||||
for(i=0; zLine[i] && IsSpace(zLine[i]); i++){}
|
||||
if( zLine[i]!=0 ){
|
||||
nSql = strlen30(zLine);
|
||||
zSql = malloc( nSql+3 );
|
||||
if( zSql==0 ){
|
||||
fprintf(stderr, "Error: out of memory\n");
|
||||
exit(1);
|
||||
}
|
||||
memcpy(zSql, zLine, nSql+1);
|
||||
startline = lineno;
|
||||
}
|
||||
}else{
|
||||
int len = strlen30(zLine);
|
||||
zSql = realloc( zSql, nSql + len + 4 );
|
||||
nLine = strlen30(zLine);
|
||||
if( nSql+nLine+2>=nAlloc ){
|
||||
nAlloc = nSql+nLine+100;
|
||||
zSql = realloc(zSql, nAlloc);
|
||||
if( zSql==0 ){
|
||||
fprintf(stderr,"Error: out of memory\n");
|
||||
fprintf(stderr, "Error: out of memory\n");
|
||||
exit(1);
|
||||
}
|
||||
zSql[nSql++] = '\n';
|
||||
memcpy(&zSql[nSql], zLine, len+1);
|
||||
nSql += len;
|
||||
}
|
||||
if( zSql && _contains_semicolon(&zSql[nSqlPrior], nSql-nSqlPrior)
|
||||
nSqlPrior = nSql;
|
||||
if( nSql==0 ){
|
||||
int i;
|
||||
for(i=0; zLine[i] && IsSpace(zLine[i]); i++){}
|
||||
memcpy(zSql, zLine+i, nLine+1-i);
|
||||
startline = lineno;
|
||||
nSql = nLine-i;
|
||||
}else{
|
||||
zSql[nSql++] = '\n';
|
||||
memcpy(zSql+nSql, zLine, nLine+1);
|
||||
nSql += nLine;
|
||||
}
|
||||
if( nSql && line_contains_semicolon(&zSql[nSqlPrior], nSql-nSqlPrior)
|
||||
&& sqlite3_complete(zSql) ){
|
||||
p->cnt = 0;
|
||||
open_db(p);
|
||||
@ -2939,16 +2934,12 @@ static int process_input(struct callback_data *p, FILE *in){
|
||||
}
|
||||
errCnt++;
|
||||
}
|
||||
free(zSql);
|
||||
zSql = 0;
|
||||
nSql = 0;
|
||||
}else if( zSql && _all_whitespace(zSql) ){
|
||||
free(zSql);
|
||||
zSql = 0;
|
||||
}else if( nSql && _all_whitespace(zSql) ){
|
||||
nSql = 0;
|
||||
}
|
||||
}
|
||||
if( zSql ){
|
||||
if( nSql ){
|
||||
if( !_all_whitespace(zSql) ){
|
||||
fprintf(stderr, "Error: incomplete SQL: %s\n", zSql);
|
||||
}
|
||||
|
@ -7228,4 +7228,4 @@ int sqlite3_vtab_on_conflict(sqlite3 *);
|
||||
#ifdef __cplusplus
|
||||
} /* End of the 'extern "C"' block */
|
||||
#endif
|
||||
#endif
|
||||
#endif /* _SQLITE3_H_ */
|
||||
|
@ -1464,12 +1464,16 @@ struct FKey {
|
||||
** An instance of the following structure is passed as the first
|
||||
** argument to sqlite3VdbeKeyCompare and is used to control the
|
||||
** comparison of the two index keys.
|
||||
**
|
||||
** Note that aSortOrder[] and aColl[] have nField+1 slots. There
|
||||
** are nField slots for the columns of an index then one extra slot
|
||||
** for the rowid at the end.
|
||||
*/
|
||||
struct KeyInfo {
|
||||
sqlite3 *db; /* The database connection */
|
||||
u8 enc; /* Text encoding - one of the SQLITE_UTF* values */
|
||||
u16 nField; /* Number of entries in aColl[] */
|
||||
u8 *aSortOrder; /* Sort order for each column. May be NULL */
|
||||
u16 nField; /* Maximum index for aColl[] and aSortOrder[] */
|
||||
u8 *aSortOrder; /* Sort order for each column. */
|
||||
CollSeq *aColl[1]; /* Collating sequence for each term of the key */
|
||||
};
|
||||
|
||||
@ -2069,6 +2073,7 @@ struct Select {
|
||||
#define SF_Values 0x0080 /* Synthesized from VALUES clause */
|
||||
#define SF_Materialize 0x0100 /* Force materialization of views */
|
||||
#define SF_NestedFrom 0x0200 /* Part of a parenthesized FROM clause */
|
||||
#define SF_MaybeConvert 0x0400 /* Need convertCompoundSelectToSubquery() */
|
||||
|
||||
|
||||
/*
|
||||
@ -2190,6 +2195,7 @@ struct Parse {
|
||||
u8 iColCache; /* Next entry in aColCache[] to replace */
|
||||
u8 isMultiWrite; /* True if statement may modify/insert multiple rows */
|
||||
u8 mayAbort; /* True if statement may throw an ABORT exception */
|
||||
u8 hasCompound; /* Need to invoke convertCompoundSelectToSubquery() */
|
||||
int aTempReg[8]; /* Holding area for temporary registers */
|
||||
int nRangeReg; /* Size of the temporary register block */
|
||||
int iRangeReg; /* First register in temporary register block */
|
||||
@ -3078,6 +3084,7 @@ void sqlite3MinimumFileFormat(Parse*, int, int);
|
||||
void sqlite3SchemaClear(void *);
|
||||
Schema *sqlite3SchemaGet(sqlite3 *, Btree *);
|
||||
int sqlite3SchemaToIndex(sqlite3 *db, Schema *);
|
||||
KeyInfo *sqlite3KeyInfoAlloc(sqlite3*,int);
|
||||
KeyInfo *sqlite3IndexKeyinfo(Parse *, Index *);
|
||||
int sqlite3CreateFunc(sqlite3 *, const char *, int, int, void *,
|
||||
void (*)(sqlite3_context*,int,sqlite3_value **),
|
||||
|
@ -208,13 +208,13 @@ int Sqlitetest_autoext_Init(Tcl_Interp *interp){
|
||||
autoExtCubeObjCmd, 0, 0);
|
||||
Tcl_CreateObjCommand(interp, "sqlite3_auto_extension_broken",
|
||||
autoExtBrokenObjCmd, 0, 0);
|
||||
#endif
|
||||
Tcl_CreateObjCommand(interp, "sqlite3_cancel_auto_extension_sqr",
|
||||
cancelAutoExtSqrObjCmd, 0, 0);
|
||||
Tcl_CreateObjCommand(interp, "sqlite3_cancel_auto_extension_cube",
|
||||
cancelAutoExtCubeObjCmd, 0, 0);
|
||||
Tcl_CreateObjCommand(interp, "sqlite3_cancel_auto_extension_broken",
|
||||
cancelAutoExtBrokenObjCmd, 0, 0);
|
||||
#endif
|
||||
Tcl_CreateObjCommand(interp, "sqlite3_reset_auto_extension",
|
||||
resetAutoExtObjCmd, 0, 0);
|
||||
return TCL_OK;
|
||||
|
@ -536,7 +536,7 @@ static int demoFullPathname(
|
||||
if( zPath[0]=='/' ){
|
||||
zDir[0] = '\0';
|
||||
}else{
|
||||
getcwd(zDir, sizeof(zDir));
|
||||
if( getcwd(zDir, sizeof(zDir))==0 ) return SQLITE_IOERR;
|
||||
}
|
||||
zDir[MAXPATHNAME] = '\0';
|
||||
|
||||
|
@ -195,6 +195,7 @@ static int fsColumn(sqlite3_vtab_cursor *cur, sqlite3_context *ctx, int i){
|
||||
const char *zFile = (const char *)sqlite3_column_text(pCur->pStmt, 1);
|
||||
struct stat sbuf;
|
||||
int fd;
|
||||
int n;
|
||||
|
||||
fd = open(zFile, O_RDONLY);
|
||||
if( fd<0 ) return SQLITE_IOERR;
|
||||
@ -214,8 +215,9 @@ static int fsColumn(sqlite3_vtab_cursor *cur, sqlite3_context *ctx, int i){
|
||||
pCur->nAlloc = nNew;
|
||||
}
|
||||
|
||||
read(fd, pCur->zBuf, sbuf.st_size);
|
||||
n = (int)read(fd, pCur->zBuf, sbuf.st_size);
|
||||
close(fd);
|
||||
if( n!=sbuf.st_size ) return SQLITE_ERROR;
|
||||
pCur->nBuf = sbuf.st_size;
|
||||
pCur->zBuf[pCur->nBuf] = '\0';
|
||||
|
||||
|
@ -75,6 +75,8 @@
|
||||
** action to free the intarray objects.
|
||||
*/
|
||||
#include "sqlite3.h"
|
||||
#ifndef _INTARRAY_H_
|
||||
#define _INTARRAY_H_
|
||||
|
||||
/*
|
||||
** Make sure we can call this stuff from C++.
|
||||
@ -123,3 +125,4 @@ int sqlite3_intarray_bind(
|
||||
#ifdef __cplusplus
|
||||
} /* End of the 'extern "C"' block */
|
||||
#endif
|
||||
#endif /* _INTARRAY_H_ */
|
||||
|
@ -96,4 +96,4 @@ extern int sqlite3_multiplex_shutdown(void);
|
||||
} /* End of the 'extern "C"' block */
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#endif /* _TEST_MULTIPLEX_H */
|
||||
|
@ -14,6 +14,7 @@
|
||||
*/
|
||||
|
||||
#include <sqlite3.h>
|
||||
#include <tcl.h>
|
||||
|
||||
/* Solely for the UNUSED_PARAMETER() macro. */
|
||||
#include "sqliteInt.h"
|
||||
|
@ -555,7 +555,7 @@ int sqlite3VdbeExec(
|
||||
int iCompare = 0; /* Result of last OP_Compare operation */
|
||||
unsigned nVmStep = 0; /* Number of virtual machine steps */
|
||||
#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
|
||||
unsigned nProgressLimit; /* Invoke xProgress() when nVmStep reaches this */
|
||||
unsigned nProgressLimit = 0;/* Invoke xProgress() when nVmStep reaches this */
|
||||
#endif
|
||||
Mem *aMem = p->aMem; /* Copy of p->aMem */
|
||||
Mem *pIn1 = 0; /* 1st input operand */
|
||||
|
116
src/vdbeaux.c
116
src/vdbeaux.c
@ -407,40 +407,60 @@ static void resolveP2Values(Vdbe *p, int *pMaxFuncArgs){
|
||||
for(pOp=p->aOp, i=p->nOp-1; i>=0; i--, pOp++){
|
||||
u8 opcode = pOp->opcode;
|
||||
|
||||
pOp->opflags = sqlite3OpcodeProperty[opcode];
|
||||
if( opcode==OP_Function || opcode==OP_AggStep ){
|
||||
if( pOp->p5>nMaxArgs ) nMaxArgs = pOp->p5;
|
||||
}else if( opcode==OP_Transaction ){
|
||||
if( pOp->p2!=0 ) p->readOnly = 0;
|
||||
p->bIsReader = 1;
|
||||
}else if( opcode==OP_AutoCommit || opcode==OP_Savepoint ){
|
||||
p->bIsReader = 1;
|
||||
}else if( opcode==OP_Vacuum
|
||||
|| opcode==OP_JournalMode
|
||||
/* NOTE: Be sure to update mkopcodeh.awk when adding or removing
|
||||
** cases from this switch! */
|
||||
switch( opcode ){
|
||||
case OP_Function:
|
||||
case OP_AggStep: {
|
||||
if( pOp->p5>nMaxArgs ) nMaxArgs = pOp->p5;
|
||||
break;
|
||||
}
|
||||
case OP_Transaction: {
|
||||
if( pOp->p2!=0 ) p->readOnly = 0;
|
||||
/* fall thru */
|
||||
}
|
||||
case OP_AutoCommit:
|
||||
case OP_Savepoint: {
|
||||
p->bIsReader = 1;
|
||||
break;
|
||||
}
|
||||
#ifndef SQLITE_OMIT_WAL
|
||||
|| opcode==OP_Checkpoint
|
||||
case OP_Checkpoint:
|
||||
#endif
|
||||
){
|
||||
p->readOnly = 0;
|
||||
p->bIsReader = 1;
|
||||
case OP_Vacuum:
|
||||
case OP_JournalMode: {
|
||||
p->readOnly = 0;
|
||||
p->bIsReader = 1;
|
||||
break;
|
||||
}
|
||||
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
||||
}else if( opcode==OP_VUpdate ){
|
||||
if( pOp->p2>nMaxArgs ) nMaxArgs = pOp->p2;
|
||||
}else if( opcode==OP_VFilter ){
|
||||
int n;
|
||||
assert( p->nOp - i >= 3 );
|
||||
assert( pOp[-1].opcode==OP_Integer );
|
||||
n = pOp[-1].p1;
|
||||
if( n>nMaxArgs ) nMaxArgs = n;
|
||||
case OP_VUpdate: {
|
||||
if( pOp->p2>nMaxArgs ) nMaxArgs = pOp->p2;
|
||||
break;
|
||||
}
|
||||
case OP_VFilter: {
|
||||
int n;
|
||||
assert( p->nOp - i >= 3 );
|
||||
assert( pOp[-1].opcode==OP_Integer );
|
||||
n = pOp[-1].p1;
|
||||
if( n>nMaxArgs ) nMaxArgs = n;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}else if( opcode==OP_Next || opcode==OP_SorterNext ){
|
||||
pOp->p4.xAdvance = sqlite3BtreeNext;
|
||||
pOp->p4type = P4_ADVANCE;
|
||||
}else if( opcode==OP_Prev ){
|
||||
pOp->p4.xAdvance = sqlite3BtreePrevious;
|
||||
pOp->p4type = P4_ADVANCE;
|
||||
case OP_Next:
|
||||
case OP_SorterNext: {
|
||||
pOp->p4.xAdvance = sqlite3BtreeNext;
|
||||
pOp->p4type = P4_ADVANCE;
|
||||
break;
|
||||
}
|
||||
case OP_Prev: {
|
||||
pOp->p4.xAdvance = sqlite3BtreePrevious;
|
||||
pOp->p4type = P4_ADVANCE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
pOp->opflags = sqlite3OpcodeProperty[opcode];
|
||||
if( (pOp->opflags & OPFLG_JUMP)!=0 && pOp->p2<0 ){
|
||||
assert( -1-pOp->p2<p->nLabel );
|
||||
pOp->p2 = aLabel[-1-pOp->p2];
|
||||
@ -729,20 +749,13 @@ void sqlite3VdbeChangeP4(Vdbe *p, int addr, const char *zP4, int n){
|
||||
pOp->p4.p = 0;
|
||||
pOp->p4type = P4_NOTUSED;
|
||||
}else if( n==P4_KEYINFO ){
|
||||
KeyInfo *pKeyInfo;
|
||||
int nField, nByte;
|
||||
KeyInfo *pOrig, *pNew;
|
||||
|
||||
nField = ((KeyInfo*)zP4)->nField;
|
||||
nByte = sizeof(*pKeyInfo) + (nField-1)*sizeof(pKeyInfo->aColl[0]) + nField;
|
||||
pKeyInfo = sqlite3DbMallocRaw(0, nByte);
|
||||
pOp->p4.pKeyInfo = pKeyInfo;
|
||||
if( pKeyInfo ){
|
||||
u8 *aSortOrder;
|
||||
memcpy((char*)pKeyInfo, zP4, nByte - nField);
|
||||
aSortOrder = pKeyInfo->aSortOrder;
|
||||
assert( aSortOrder!=0 );
|
||||
pKeyInfo->aSortOrder = (unsigned char*)&pKeyInfo->aColl[nField];
|
||||
memcpy(pKeyInfo->aSortOrder, aSortOrder, nField);
|
||||
pOrig = (KeyInfo*)zP4;
|
||||
pOp->p4.pKeyInfo = pNew = sqlite3KeyInfoAlloc(db, pOrig->nField);
|
||||
if( pNew ){
|
||||
memcpy(pNew->aColl, pOrig->aColl, pOrig->nField*sizeof(pNew->aColl[0]));
|
||||
memcpy(pNew->aSortOrder, pOrig->aSortOrder, pOrig->nField);
|
||||
pOp->p4type = P4_KEYINFO;
|
||||
}else{
|
||||
p->db->mallocFailed = 1;
|
||||
@ -2993,7 +3006,6 @@ int sqlite3VdbeRecordCompare(
|
||||
u32 idx1; /* Offset into aKey[] of next header element */
|
||||
u32 szHdr1; /* Number of bytes in header */
|
||||
int i = 0;
|
||||
int nField;
|
||||
int rc = 0;
|
||||
const unsigned char *aKey1 = (const unsigned char *)pKey1;
|
||||
KeyInfo *pKeyInfo;
|
||||
@ -3016,14 +3028,25 @@ int sqlite3VdbeRecordCompare(
|
||||
|
||||
idx1 = getVarint32(aKey1, szHdr1);
|
||||
d1 = szHdr1;
|
||||
nField = pKeyInfo->nField;
|
||||
assert( pKeyInfo->nField+1>=pPKey2->nField );
|
||||
assert( pKeyInfo->aSortOrder!=0 );
|
||||
while( idx1<szHdr1 && i<pPKey2->nField ){
|
||||
u32 serial_type1;
|
||||
|
||||
/* Read the serial types for the next element in each key. */
|
||||
idx1 += getVarint32( aKey1+idx1, serial_type1 );
|
||||
if( d1+sqlite3VdbeSerialTypeLen(serial_type1)>(u32)nKey1 ) break;
|
||||
|
||||
/* Verify that there is enough key space remaining to avoid
|
||||
** a buffer overread. The "d1+serial_type1+2" subexpression will
|
||||
** always be greater than or equal to the amount of required key space.
|
||||
** Use that approximation to avoid the more expensive call to
|
||||
** sqlite3VdbeSerialTypeLen() in the common case.
|
||||
*/
|
||||
if( d1+serial_type1+2>(u32)nKey1
|
||||
&& d1+sqlite3VdbeSerialTypeLen(serial_type1)>(u32)nKey1
|
||||
){
|
||||
break;
|
||||
}
|
||||
|
||||
/* Extract the values to be compared.
|
||||
*/
|
||||
@ -3031,13 +3054,12 @@ int sqlite3VdbeRecordCompare(
|
||||
|
||||
/* Do the comparison
|
||||
*/
|
||||
rc = sqlite3MemCompare(&mem1, &pPKey2->aMem[i],
|
||||
i<nField ? pKeyInfo->aColl[i] : 0);
|
||||
rc = sqlite3MemCompare(&mem1, &pPKey2->aMem[i], pKeyInfo->aColl[i]);
|
||||
if( rc!=0 ){
|
||||
assert( mem1.zMalloc==0 ); /* See comment below */
|
||||
|
||||
/* Invert the result if we are using DESC sort order. */
|
||||
if( i<nField && pKeyInfo->aSortOrder[i] ){
|
||||
if( pKeyInfo->aSortOrder[i] ){
|
||||
rc = -rc;
|
||||
}
|
||||
|
||||
|
33
src/where.c
33
src/where.c
@ -33,7 +33,7 @@
|
||||
# define WHERETRACE(K,X)
|
||||
#endif
|
||||
|
||||
/* Forward reference
|
||||
/* Forward references
|
||||
*/
|
||||
typedef struct WhereClause WhereClause;
|
||||
typedef struct WhereMaskSet WhereMaskSet;
|
||||
@ -55,14 +55,15 @@ typedef struct WhereOrSet WhereOrSet;
|
||||
** So all costs can be stored in a 16-bit unsigned integer without risk
|
||||
** of overflow.
|
||||
**
|
||||
** Costs are estimates, so don't go to the computational trouble to compute
|
||||
** 10*log2(X) exactly. Instead, a close estimate is used. Any value of
|
||||
** X<=1 is stored as 0. X=2 is 10. X=3 is 16. X=1000 is 99. etc.
|
||||
** Costs are estimates, so no effort is made to compute 10*log2(X) exactly.
|
||||
** Instead, a close estimate is used. Any value of X<=1 is stored as 0.
|
||||
** X=2 is 10. X=3 is 16. X=1000 is 99. etc.
|
||||
**
|
||||
** The tool/wherecosttest.c source file implements a command-line program
|
||||
** that will convert between WhereCost to integers and do addition and
|
||||
** multiplication on WhereCost values. That command-line program is a
|
||||
** useful utility to have around when working with this module.
|
||||
** that will convert WhereCosts to integers, convert integers to WhereCosts
|
||||
** and do addition and multiplication on WhereCost values. The wherecosttest
|
||||
** command-line program is a useful utility to have around when working with
|
||||
** this module.
|
||||
*/
|
||||
typedef unsigned short int WhereCost;
|
||||
|
||||
@ -165,8 +166,8 @@ struct WhereOrCost {
|
||||
};
|
||||
|
||||
/* The WhereOrSet object holds a set of possible WhereOrCosts that
|
||||
** correspond to the subquery(s) of OR-clause processing. At most
|
||||
** favorable N_OR_COST elements are retained.
|
||||
** correspond to the subquery(s) of OR-clause processing. Only the
|
||||
** best N_OR_COST elements are retained.
|
||||
*/
|
||||
#define N_OR_COST 3
|
||||
struct WhereOrSet {
|
||||
@ -232,9 +233,9 @@ struct WherePath {
|
||||
**
|
||||
** (t1.X <op> <expr>) OR (t1.Y <op> <expr>) OR ....
|
||||
**
|
||||
** In this second case, wtFlag as the TERM_ORINFO set and eOperator==WO_OR
|
||||
** In this second case, wtFlag has the TERM_ORINFO bit set and eOperator==WO_OR
|
||||
** and the WhereTerm.u.pOrInfo field points to auxiliary information that
|
||||
** is collected about the
|
||||
** is collected about the OR clause.
|
||||
**
|
||||
** If a term in the WHERE clause does not match either of the two previous
|
||||
** categories, then eOperator==0. The WhereTerm.pExpr field is still set
|
||||
@ -751,7 +752,7 @@ static void createMask(WhereMaskSet *pMaskSet, int iCursor){
|
||||
}
|
||||
|
||||
/*
|
||||
** These routine walk (recursively) an expression tree and generates
|
||||
** These routines walk (recursively) an expression tree and generate
|
||||
** a bitmask indicating which tables are used in that expression
|
||||
** tree.
|
||||
*/
|
||||
@ -1268,10 +1269,10 @@ static void transferJoinMarkings(Expr *pDerived, Expr *pBase){
|
||||
** From another point of view, "indexable" means that the subterm could
|
||||
** potentially be used with an index if an appropriate index exists.
|
||||
** This analysis does not consider whether or not the index exists; that
|
||||
** is something the bestIndex() routine will determine. This analysis
|
||||
** only looks at whether subterms appropriate for indexing exist.
|
||||
** is decided elsewhere. This analysis only looks at whether subterms
|
||||
** appropriate for indexing exist.
|
||||
**
|
||||
** All examples A through E above all satisfy case 2. But if a term
|
||||
** All examples A through E above satisfy case 2. But if a term
|
||||
** also statisfies case 1 (such as B) we know that the optimizer will
|
||||
** always prefer case 1, so in that case we pretend that case 2 is not
|
||||
** satisfied.
|
||||
@ -1938,7 +1939,7 @@ static int isDistinctRedundant(
|
||||
}
|
||||
|
||||
/*
|
||||
** The (an approximate) sum of two WhereCosts. This computation is
|
||||
** Find (an approximate) sum of two WhereCosts. This computation is
|
||||
** not a simple "+" operator because WhereCost is stored as a logarithmic
|
||||
** value.
|
||||
**
|
||||
|
@ -144,12 +144,21 @@ do_test index6-2.2 {
|
||||
SELECT * FROM t2 WHERE a=5;
|
||||
}
|
||||
} {/.* TABLE t2 USING INDEX t2a1 .*/}
|
||||
do_test index6-2.3 {
|
||||
execsql {
|
||||
EXPLAIN QUERY PLAN
|
||||
SELECT * FROM t2 WHERE a IS NOT NULL;
|
||||
}
|
||||
} {/.* TABLE t2 USING INDEX t2a1 .*/}
|
||||
ifcapable stat4 {
|
||||
do_test index6-2.3stat4 {
|
||||
execsql {
|
||||
EXPLAIN QUERY PLAN
|
||||
SELECT * FROM t2 WHERE a IS NOT NULL;
|
||||
}
|
||||
} {/.* TABLE t2 USING INDEX t2a1 .*/}
|
||||
} else {
|
||||
do_test index6-2.3stat4 {
|
||||
execsql {
|
||||
EXPLAIN QUERY PLAN
|
||||
SELECT * FROM t2 WHERE a IS NOT NULL AND a>0;
|
||||
}
|
||||
} {/.* TABLE t2 USING INDEX t2a1 .*/}
|
||||
}
|
||||
do_test index6-2.4 {
|
||||
execsql {
|
||||
EXPLAIN QUERY PLAN
|
||||
|
Loading…
Reference in New Issue
Block a user