mirror of
https://github.com/sqlite/sqlite.git
synced 2025-11-05 04:30:38 +03:00
Merge the latest trunk fixes into the sessions branch.
FossilOrigin-Name: 131a2d3116436ca6304777c9c5d46b7c4051d949
This commit is contained in:
20
manifest
20
manifest
@@ -1,5 +1,5 @@
|
||||
C Merge\sall\srecent\strunk\schanges\sinto\sthe\ssessions\sbranch.
|
||||
D 2015-02-21T15:13:50.198
|
||||
C Merge\sthe\slatest\strunk\sfixes\sinto\sthe\ssessions\sbranch.
|
||||
D 2015-02-25T14:02:53.832
|
||||
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
||||
F Makefile.in e63f98067fef9d9112380e3aec9881f56d49f77e
|
||||
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
|
||||
@@ -248,8 +248,8 @@ F src/random.c ba2679f80ec82c4190062d756f22d0c358180696
|
||||
F src/resolve.c f4d79e31ffa5820c2e3d1740baa5e9b190425f2b
|
||||
F src/rowset.c eccf6af6d620aaa4579bd3b72c1b6395d9e9fa1e
|
||||
F src/select.c e46cef4c224549b439384c88fc7f57ba064dad54
|
||||
F src/shell.c 75e9d6dc85586c4a8e52f3be44c3a23dd3ef8d0d
|
||||
F src/sqlite.h.in e26cf36c3dc7099d6fcef864e362ee26261cc082
|
||||
F src/shell.c f21e2cec006b04d4d871209016286157279d70e0
|
||||
F src/sqlite.h.in 763e178cf0e47056a0abc572a42eacb5d1164196
|
||||
F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad
|
||||
F src/sqlite3ext.h 17d487c3c91b0b8c584a32fbeb393f6f795eea7d
|
||||
F src/sqliteInt.h 1e1c08093c57dbd7c5d0b6d945f1c1d039f1128e
|
||||
@@ -323,7 +323,7 @@ F src/vtab.c 699f2b8d509cfe379c33dde33827875d5b030e01
|
||||
F src/wal.c 39303f2c9db02a4e422cd8eb2c8760420c6a51fe
|
||||
F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4
|
||||
F src/walker.c c253b95b4ee44b21c406e2a1052636c31ea27804
|
||||
F src/where.c d46de821bc604a4fd36fa3928c086950e91aafb1
|
||||
F src/where.c a50d5082b0fecd2bcf1725cdd012732d9d1e9d5c
|
||||
F src/whereInt.h d3633e9b592103241b74b0ec76185f3e5b8b62e0
|
||||
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
|
||||
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
|
||||
@@ -367,7 +367,7 @@ F test/autoinc.test c58912526998a39e11f66b533e23cfabea7f25b7
|
||||
F test/autoindex1.test 6ff78b94f43a59616c06c11c55b12935173506d7
|
||||
F test/autoindex2.test af7e595c6864cc6ef5fc38d5db579a3e34940cb8
|
||||
F test/autoindex3.test a3be0d1a53a7d2edff208a5e442312957047e972
|
||||
F test/autoindex4.test fc807f9efd158bec60f5dfdf34ebe46fb274612d
|
||||
F test/autoindex4.test 49d3cd791a9baa16fb461d7ea3de80d019a819cf
|
||||
F test/autovacuum.test 941892505d2c0f410a0cb5970dfa1c7c4e5f6e74
|
||||
F test/autovacuum_ioerr2.test 8a367b224183ad801e0e24dcb7d1501f45f244b4
|
||||
F test/avtrans.test 0252654f4295ddda3b2cce0e894812259e655a85
|
||||
@@ -669,7 +669,7 @@ F test/index2.test ee83c6b5e3173a3d7137140d945d9a5d4fdfb9d6
|
||||
F test/index3.test 55a90cff99834305e8141df7afaef39674b57062
|
||||
F test/index4.test ab92e736d5946840236cd61ac3191f91a7856bf6
|
||||
F test/index5.test 25b0b451aceed4ac5f7d49f856f6de7257470b3e
|
||||
F test/index6.test fb370966ac3cd0989053dd5385757b5c3e24ab6a
|
||||
F test/index6.test 3ae54e53c53f2adcacda269237d8e52bdb05a481
|
||||
F test/index7.test 917cf1e1c7439bb155abbeabec511b28945e157b
|
||||
F test/indexedby.test b2f22f3e693a53813aa3f50b812eb609ba6df1ec
|
||||
F test/indexfault.test 31d4ab9a7d2f6e9616933eb079722362a883eb1d
|
||||
@@ -1257,7 +1257,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1
|
||||
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
|
||||
F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32
|
||||
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
|
||||
P ae7eef117f28a5dae7a05805f2d31ac532a9fcc5 c299e55a661c04f71ab43cb8aed04f8ece6e0567
|
||||
R b7f8fa563aa6e3bf4b2e063495f61f72
|
||||
P f36bb5fa5c5e3430808fe35d58f45559a216d341 03bbb947192b0c28d960604eae12e5fc2fa6e74e
|
||||
R fea8faac07d1963bbee76d04f5507233
|
||||
U drh
|
||||
Z 87039a26f4b6e7975795e319beedb047
|
||||
Z 94f89bcaf784abbabd110bdd6f219892
|
||||
|
||||
@@ -1 +1 @@
|
||||
f36bb5fa5c5e3430808fe35d58f45559a216d341
|
||||
131a2d3116436ca6304777c9c5d46b7c4051d949
|
||||
52
src/shell.c
52
src/shell.c
@@ -59,18 +59,38 @@
|
||||
# include <readline/readline.h>
|
||||
# include <readline/history.h>
|
||||
#endif
|
||||
|
||||
#if HAVE_EDITLINE
|
||||
# undef HAVE_READLINE
|
||||
# define HAVE_READLINE 1
|
||||
# include <editline/readline.h>
|
||||
#endif
|
||||
#if !HAVE_READLINE
|
||||
# define add_history(X)
|
||||
# define read_history(X)
|
||||
# define write_history(X)
|
||||
# define stifle_history(X)
|
||||
|
||||
#if HAVE_EDITLINE || HAVE_READLINE
|
||||
|
||||
# define shell_add_history(X) add_history(X)
|
||||
# define shell_read_history(X) read_history(X)
|
||||
# define shell_write_history(X) write_history(X)
|
||||
# define shell_stifle_history(X) stifle_history(X)
|
||||
# define shell_readline(X) readline(X)
|
||||
|
||||
#elif HAVE_LINENOISE
|
||||
|
||||
# include "linenoise.h"
|
||||
# define shell_add_history(X) linenoiseHistoryAdd(X)
|
||||
# define shell_read_history(X) linenoiseHistoryLoad(X)
|
||||
# define shell_write_history(X) linenoiseHistorySave(X)
|
||||
# define shell_stifle_history(X) linenoiseHistorySetMaxLen(X)
|
||||
# define shell_readline(X) linenoise(X)
|
||||
|
||||
#else
|
||||
|
||||
# define shell_read_history(X)
|
||||
# define shell_write_history(X)
|
||||
# define shell_stifle_history(X)
|
||||
|
||||
# define SHELL_USE_LOCAL_GETLINE 1
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(_WIN32) || defined(WIN32)
|
||||
# include <io.h>
|
||||
# include <fcntl.h>
|
||||
@@ -451,14 +471,14 @@ static char *one_input_line(FILE *in, char *zPrior, int isContinuation){
|
||||
zResult = local_getline(zPrior, in);
|
||||
}else{
|
||||
zPrompt = isContinuation ? continuePrompt : mainPrompt;
|
||||
#if HAVE_READLINE
|
||||
free(zPrior);
|
||||
zResult = readline(zPrompt);
|
||||
if( zResult && *zResult ) add_history(zResult);
|
||||
#else
|
||||
#if SHELL_USE_LOCAL_GETLINE
|
||||
printf("%s", zPrompt);
|
||||
fflush(stdout);
|
||||
zResult = local_getline(zPrior, stdin);
|
||||
#else
|
||||
free(zPrior);
|
||||
zResult = shell_readline(zPrompt);
|
||||
if( zResult && *zResult ) shell_add_history(zResult);
|
||||
#endif
|
||||
}
|
||||
return zResult;
|
||||
@@ -4917,13 +4937,11 @@ int main(int argc, char **argv){
|
||||
sqlite3_snprintf(nHistory, zHistory,"%s/.sqlite_history", zHome);
|
||||
}
|
||||
}
|
||||
#if HAVE_READLINE
|
||||
if( zHistory ) read_history(zHistory);
|
||||
#endif
|
||||
if( zHistory ) shell_read_history(zHistory);
|
||||
rc = process_input(&data, 0);
|
||||
if( zHistory ){
|
||||
stifle_history(100);
|
||||
write_history(zHistory);
|
||||
shell_stifle_history(100);
|
||||
shell_write_history(zHistory);
|
||||
free(zHistory);
|
||||
}
|
||||
}else{
|
||||
|
||||
@@ -2232,6 +2232,10 @@ void sqlite3_free_table(char **result);
|
||||
**
|
||||
** These routines are work-alikes of the "printf()" family of functions
|
||||
** from the standard C library.
|
||||
** These routines understand most of the common K&R formatting options,
|
||||
** plus some additional non-standard formats, detailed below.
|
||||
** Note that some of the more obscure formatting options from recent
|
||||
** C-library standards are omitted from this implementation.
|
||||
**
|
||||
** ^The sqlite3_mprintf() and sqlite3_vmprintf() routines write their
|
||||
** results into memory obtained from [sqlite3_malloc()].
|
||||
@@ -2264,7 +2268,7 @@ void sqlite3_free_table(char **result);
|
||||
** These routines all implement some additional formatting
|
||||
** options that are useful for constructing SQL statements.
|
||||
** All of the usual printf() formatting options apply. In addition, there
|
||||
** is are "%q", "%Q", and "%z" options.
|
||||
** is are "%q", "%Q", "%w" and "%z" options.
|
||||
**
|
||||
** ^(The %q option works like %s in that it substitutes a nul-terminated
|
||||
** string from the argument list. But %q also doubles every '\'' character.
|
||||
@@ -2317,6 +2321,12 @@ void sqlite3_free_table(char **result);
|
||||
** The code above will render a correct SQL statement in the zSQL
|
||||
** variable even if the zText variable is a NULL pointer.
|
||||
**
|
||||
** ^(The "%w" formatting option is like "%q" except that it expects to
|
||||
** be contained within double-quotes instead of single quotes, and it
|
||||
** escapes the double-quote character instead of the single-quote
|
||||
** character.)^ The "%w" formatting option is intended for safely inserting
|
||||
** table and column names into a constructed SQL statement.
|
||||
**
|
||||
** ^(The "%z" formatting option works like "%s" but with the
|
||||
** addition that after the string has been read and copied into
|
||||
** the result, [sqlite3_free()] is called on the input string.)^
|
||||
|
||||
16
src/where.c
16
src/where.c
@@ -1612,11 +1612,16 @@ static void constructAutomaticIndex(
|
||||
pLoop = pLevel->pWLoop;
|
||||
idxCols = 0;
|
||||
for(pTerm=pWC->a; pTerm<pWCEnd; pTerm++){
|
||||
Expr *pExpr = pTerm->pExpr;
|
||||
assert( !ExprHasProperty(pExpr, EP_FromJoin) /* prereq always non-zero */
|
||||
|| pExpr->iRightJoinTable!=pSrc->iCursor /* for the right-hand */
|
||||
|| pLoop->prereq!=0 ); /* table of a LEFT JOIN */
|
||||
if( pLoop->prereq==0
|
||||
&& (pTerm->wtFlags & TERM_VIRTUAL)==0
|
||||
&& sqlite3ExprIsTableConstant(pTerm->pExpr, pSrc->iCursor) ){
|
||||
&& !ExprHasProperty(pExpr, EP_FromJoin)
|
||||
&& sqlite3ExprIsTableConstant(pExpr, pSrc->iCursor) ){
|
||||
pPartial = sqlite3ExprAnd(pParse->db, pPartial,
|
||||
sqlite3ExprDup(pParse->db, pTerm->pExpr, 0));
|
||||
sqlite3ExprDup(pParse->db, pExpr, 0));
|
||||
}
|
||||
if( termCanDriveIndex(pTerm, pSrc, notReady) ){
|
||||
int iCol = pTerm->u.leftColumn;
|
||||
@@ -4694,7 +4699,12 @@ static int whereUsablePartialIndex(int iTab, WhereClause *pWC, Expr *pWhere){
|
||||
int i;
|
||||
WhereTerm *pTerm;
|
||||
for(i=0, pTerm=pWC->a; i<pWC->nTerm; i++, pTerm++){
|
||||
if( sqlite3ExprImpliesExpr(pTerm->pExpr, pWhere, iTab) ) return 1;
|
||||
Expr *pExpr = pTerm->pExpr;
|
||||
if( sqlite3ExprImpliesExpr(pExpr, pWhere, iTab)
|
||||
&& (!ExprHasProperty(pExpr, EP_FromJoin) || pExpr->iRightJoinTable==iTab)
|
||||
){
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -49,4 +49,35 @@ do_execsql_test autoindex4-2.0 {
|
||||
ORDER BY rowid;
|
||||
} {1 123 654 | 0 555 444 | 4 234 987 |}
|
||||
|
||||
# Ticket [2326c258d02ead33d]
|
||||
# Two joins, one with and the other without an ORDER BY clause.
|
||||
# The one without ORDER BY correctly returns two rows of result.
|
||||
# The one with ORDER BY returns no rows.
|
||||
#
|
||||
do_execsql_test autoindex4-3.0 {
|
||||
CREATE TABLE A(Name text);
|
||||
CREATE TABLE Items(ItemName text , Name text);
|
||||
INSERT INTO Items VALUES('Item1','Parent');
|
||||
INSERT INTO Items VALUES('Item2','Parent');
|
||||
CREATE TABLE B(Name text);
|
||||
|
||||
SELECT Items.ItemName
|
||||
FROM Items
|
||||
LEFT JOIN A ON (A.Name = Items.ItemName and Items.ItemName = 'dummy')
|
||||
LEFT JOIN B ON (B.Name = Items.ItemName)
|
||||
WHERE Items.Name = 'Parent'
|
||||
ORDER BY Items.ItemName;
|
||||
} {Item1 Item2}
|
||||
do_execsql_test autoindex4-3.1 {
|
||||
CREATE INDEX Items_x1 ON Items(ItemName,Name) WHERE ItemName = 'dummy';
|
||||
|
||||
SELECT Items.ItemName
|
||||
FROM Items
|
||||
LEFT JOIN A ON (A.Name = Items.ItemName and Items.ItemName = 'dummy')
|
||||
LEFT JOIN B ON (B.Name = Items.ItemName)
|
||||
WHERE Items.Name = 'Parent'
|
||||
ORDER BY Items.ItemName;
|
||||
} {Item1 Item2}
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -267,5 +267,64 @@ do_execsql_test index6-6.2 {
|
||||
PRAGMA integrity_check;
|
||||
} {ok}
|
||||
|
||||
# Test case for ticket [2326c258d02ead33d69faa63de8f4686b9b1b9d9] on
|
||||
# 2015-02-24. Any use of a partial index qualifying constraint inside
|
||||
# the ON clause of a LEFT JOIN was causing incorrect results for all
|
||||
# versions of SQLite 3.8.0 through 3.8.8.
|
||||
#
|
||||
do_execsql_test index6-7.0 {
|
||||
CREATE TABLE t7a(x);
|
||||
CREATE TABLE t7b(y);
|
||||
INSERT INTO t7a(x) VALUES(1);
|
||||
CREATE INDEX t7ax ON t7a(x) WHERE x=99;
|
||||
PRAGMA automatic_index=OFF;
|
||||
SELECT * FROM t7a LEFT JOIN t7b ON (x=99) ORDER BY x;
|
||||
} {1 {}}
|
||||
do_execsql_test index6-7.1 {
|
||||
INSERT INTO t7b(y) VALUES(2);
|
||||
SELECT * FROM t7a JOIN t7b ON (x=99) ORDER BY x;
|
||||
} {}
|
||||
do_execsql_test index6-7.2 {
|
||||
INSERT INTO t7a(x) VALUES(99);
|
||||
SELECT * FROM t7a LEFT JOIN t7b ON (x=99) ORDER BY x;
|
||||
} {1 {} 99 2}
|
||||
do_execsql_test index6-7.3 {
|
||||
SELECT * FROM t7a JOIN t7b ON (x=99) ORDER BY x;
|
||||
} {99 2}
|
||||
do_execsql_test index6-7.4 {
|
||||
EXPLAIN QUERY PLAN
|
||||
SELECT * FROM t7a JOIN t7b ON (x=99) ORDER BY x;
|
||||
} {/USING COVERING INDEX t7ax/}
|
||||
|
||||
|
||||
do_execsql_test index6-8.0 {
|
||||
CREATE TABLE t8a(a,b);
|
||||
CREATE TABLE t8b(x,y);
|
||||
CREATE INDEX i8c ON t8b(y) WHERE x = 'value';
|
||||
|
||||
INSERT INTO t8a VALUES(1, 'one');
|
||||
INSERT INTO t8a VALUES(2, 'two');
|
||||
INSERT INTO t8a VALUES(3, 'three');
|
||||
|
||||
INSERT INTO t8b VALUES('value', 1);
|
||||
INSERT INTO t8b VALUES('dummy', 2);
|
||||
INSERT INTO t8b VALUES('value', 3);
|
||||
INSERT INTO t8b VALUES('dummy', 4);
|
||||
} {}
|
||||
|
||||
do_eqp_test index6-8.1 {
|
||||
SELECT * FROM t8a LEFT JOIN t8b ON (x = 'value' AND y = a)
|
||||
} {
|
||||
0 0 0 {SCAN TABLE t8a}
|
||||
0 1 1 {SEARCH TABLE t8b USING INDEX i8c (y=?)}
|
||||
}
|
||||
|
||||
do_execsql_test index6-8.2 {
|
||||
SELECT * FROM t8a LEFT JOIN t8b ON (x = 'value' AND y = a)
|
||||
} {
|
||||
1 one value 1
|
||||
2 two {} {}
|
||||
3 three value 3
|
||||
}
|
||||
|
||||
finish_test
|
||||
|
||||
Reference in New Issue
Block a user