mirror of
https://github.com/sqlite/sqlite.git
synced 2024-12-01 17:23:42 +01:00
Consider explicit collate clauses when matching WHERE constraints to indices. Fix for #2391. (CVS 4040)
FossilOrigin-Name: f9a95e92dfaaa61ec0a44b9b7017b07929c94d26
This commit is contained in:
parent
331bf02e0e
commit
bcbb04e501
17
manifest
17
manifest
@ -1,5 +1,5 @@
|
||||
C Add\ssome\stests\sto\sverify\sthat\sthe\sparameter\sto\sthe\sincremental_vacuum\spragma\sis\sworking.\sIt\sis.\s(CVS\s4039)
|
||||
D 2007-05-24T10:18:22
|
||||
C Consider\sexplicit\scollate\sclauses\swhen\smatching\sWHERE\sconstraints\sto\sindices.\sFix\sfor\s#2391.\s(CVS\s4040)
|
||||
D 2007-05-29T12:11:30
|
||||
F Makefile.in a42354804b50c2708ce72cf79e4daa30f50191b5
|
||||
F Makefile.linux-gcc 2d8574d1ba75f129aba2019f0b959db380a90935
|
||||
F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028
|
||||
@ -71,7 +71,7 @@ F src/complete.c 7d1a44be8f37de125fcafd3d3a018690b3799675
|
||||
F src/date.c 6049db7d5a8fdf2c677ff7d58fa31d4f6593c988
|
||||
F src/delete.c 5c0d89b3ef7d48fe1f5124bfe8341f982747fe29
|
||||
F src/experimental.c 1b2d1a6cd62ecc39610e97670332ca073c50792b
|
||||
F src/expr.c 436f1d3e5addf95c195016b518cd2f44a6f5f081
|
||||
F src/expr.c 7243b6c01b976662873bbba397640fb4cbed76bc
|
||||
F src/func.c dfd0dd496dac46c2b14a88292cd9e141aae3ba63
|
||||
F src/hash.c 67b23e14f0257b69a3e8aa663e4eeadc1a2b6fd5
|
||||
F src/hash.h 1b3f7e2609141fd571f62199fc38687d262e9564
|
||||
@ -105,7 +105,7 @@ F src/server.c 087b92a39d883e3fa113cae259d64e4c7438bc96
|
||||
F src/shell.c d07ae326b3815d80f71c69b3c7584382e47f6447
|
||||
F src/sqlite.h.in b174b5508467deec4034c6c8a21f0354b498b46b
|
||||
F src/sqlite3ext.h 7d0d363ea7327e817ef0dfe1b7eee1f171b72890
|
||||
F src/sqliteInt.h 58edde37943f4f8155986f0c33735ba31fc66e9f
|
||||
F src/sqliteInt.h 853d50bfeb72586faada449061a8dcd61f8db42d
|
||||
F src/table.c a8de75bcedf84d4060d804264b067ab3b1a3561d
|
||||
F src/tclsqlite.c f425c7583665ef78dd8397b2de0b8e0028e80ce2
|
||||
F src/test1.c 0ec120a4652ee95268a5a45e1e1adee13be9ae28
|
||||
@ -142,7 +142,7 @@ F src/vdbeblob.c 96f3572fdc45eda5be06e6372b612bc30742d9f0
|
||||
F src/vdbefifo.c 3ca8049c561d5d67cbcb94dc909ae9bb68c0bf8f
|
||||
F src/vdbemem.c 332875a5fc9ac482e00701db5487ceb7f6fc1adc
|
||||
F src/vtab.c c5ebebf615b2f29499fbe97a584c4bb342632aa0
|
||||
F src/where.c f3920748cc650fc25ac916215500bdb90dee568e
|
||||
F src/where.c 1c27ddb2f19976175fecdcf8f5a0ca23596917fb
|
||||
F tclinstaller.tcl 4356d9d94d2b5ed5e68f9f0c80c4df3048dd7617
|
||||
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
|
||||
F test/all.test 93a40a7612b3c5e6efd1f5b98496a8b02a45cfdb
|
||||
@ -382,6 +382,7 @@ F test/tkt2251.test 3f0549213386ed911715665a908ff2bb7a871002
|
||||
F test/tkt2285.test c618085f0c13ec3347e607f83c34ada0721b4bfa
|
||||
F test/tkt2332.test cb1bb0ed1ae6a3b9ff412520ed4a496745f4ffa5
|
||||
F test/tkt2339.test 7016415bda86af1406a27260ac46f44885617606
|
||||
F test/tkt2391.test ab7a11be7402da8b51a5be603425367aa0684567
|
||||
F test/trace.test 75ffc1b992c780d054748a656e3e7fd674f18567
|
||||
F test/trans.test 3fe1b9e03b523482eee2b869858c5c1eca7b218b
|
||||
F test/trigger1.test b361161cf20614024cc1e52ea0bdec250776b2ae
|
||||
@ -494,7 +495,7 @@ F www/tclsqlite.tcl bb0d1357328a42b1993d78573e587c6dcbc964b9
|
||||
F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
|
||||
F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b
|
||||
F www/whentouse.tcl fc46eae081251c3c181bd79c5faef8195d7991a5
|
||||
P e8ae6214bfef4230096b6b56e688e9d4cd93f1b8
|
||||
R 114bb7154f3f00accbd22be991d205a9
|
||||
P 1abf784fe27cdc61b6b944b79d024ea98eb5289e
|
||||
R 2231e0859ae00b3b5f9f014c6b668680
|
||||
U danielk1977
|
||||
Z 3f53a4a2d46ad174a9eb3dc8ca1b824d
|
||||
Z b43a8281516bbb9de3a5fb2d18123729
|
||||
|
@ -1 +1 @@
|
||||
1abf784fe27cdc61b6b944b79d024ea98eb5289e
|
||||
f9a95e92dfaaa61ec0a44b9b7017b07929c94d26
|
18
src/expr.c
18
src/expr.c
@ -12,7 +12,7 @@
|
||||
** This file contains routines used for analyzing expressions and
|
||||
** for generating VDBE code that evaluates expressions in SQLite.
|
||||
**
|
||||
** $Id: expr.c,v 1.294 2007/05/15 07:00:34 danielk1977 Exp $
|
||||
** $Id: expr.c,v 1.295 2007/05/29 12:11:30 danielk1977 Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
#include <ctype.h>
|
||||
@ -171,15 +171,21 @@ static int binaryCompareP1(Expr *pExpr1, Expr *pExpr2, int jumpIfNull){
|
||||
** used. Otherwise the collation sequence for the right hand expression
|
||||
** is used, or the default (BINARY) if neither expression has a collating
|
||||
** type.
|
||||
**
|
||||
** Argument pRight (but not pLeft) may be a null pointer. In this case,
|
||||
** it is not considered.
|
||||
*/
|
||||
static CollSeq* binaryCompareCollSeq(Parse *pParse, Expr *pLeft, Expr *pRight){
|
||||
CollSeq* sqlite3BinaryCompareCollSeq(
|
||||
Parse *pParse,
|
||||
Expr *pLeft,
|
||||
Expr *pRight
|
||||
){
|
||||
CollSeq *pColl;
|
||||
assert( pLeft );
|
||||
assert( pRight );
|
||||
if( pLeft->flags & EP_ExpCollate ){
|
||||
assert( pLeft->pColl );
|
||||
pColl = pLeft->pColl;
|
||||
}else if( pRight->flags & EP_ExpCollate ){
|
||||
}else if( pRight && pRight->flags & EP_ExpCollate ){
|
||||
assert( pRight->pColl );
|
||||
pColl = pRight->pColl;
|
||||
}else{
|
||||
@ -203,7 +209,7 @@ static int codeCompare(
|
||||
int jumpIfNull /* If true, jump if either operand is NULL */
|
||||
){
|
||||
int p1 = binaryCompareP1(pLeft, pRight, jumpIfNull);
|
||||
CollSeq *p3 = binaryCompareCollSeq(pParse, pLeft, pRight);
|
||||
CollSeq *p3 = sqlite3BinaryCompareCollSeq(pParse, pLeft, pRight);
|
||||
return sqlite3VdbeOp3(pParse->pVdbe, opcode, p1, dest, (void*)p3, P3_COLLSEQ);
|
||||
}
|
||||
|
||||
@ -1533,7 +1539,7 @@ void sqlite3CodeSubselect(Parse *pParse, Expr *pExpr){
|
||||
}
|
||||
pEList = pExpr->pSelect->pEList;
|
||||
if( pEList && pEList->nExpr>0 ){
|
||||
keyInfo.aColl[0] = binaryCompareCollSeq(pParse, pExpr->pLeft,
|
||||
keyInfo.aColl[0] = sqlite3BinaryCompareCollSeq(pParse, pExpr->pLeft,
|
||||
pEList->a[0].pExpr);
|
||||
}
|
||||
}else if( pExpr->pList ){
|
||||
|
@ -11,7 +11,7 @@
|
||||
*************************************************************************
|
||||
** Internal interface definitions for SQLite.
|
||||
**
|
||||
** @(#) $Id: sqliteInt.h,v 1.569 2007/05/16 17:28:43 danielk1977 Exp $
|
||||
** @(#) $Id: sqliteInt.h,v 1.570 2007/05/29 12:11:30 danielk1977 Exp $
|
||||
*/
|
||||
#ifndef _SQLITEINT_H_
|
||||
#define _SQLITEINT_H_
|
||||
@ -1569,7 +1569,7 @@ extern const unsigned char sqlite3UtfTrans1[];
|
||||
** be encoded as a multi-byte character. Any multi-byte character that
|
||||
** attempts to encode a value between 0x00 and 0x7f is rendered as 0xfffd.
|
||||
**
|
||||
** * These macros never allow a UTF16 surragate value to be encoded.
|
||||
** * These macros never allow a UTF16 surrogate value to be encoded.
|
||||
** If a multi-byte character attempts to encode a value between
|
||||
** 0xd800 and 0xe000 then it is rendered as 0xfffd.
|
||||
**
|
||||
@ -1954,6 +1954,7 @@ FuncDef *sqlite3VtabOverloadFunction(FuncDef*, int nArg, Expr*);
|
||||
void sqlite3InvalidFunction(sqlite3_context*,int,sqlite3_value**);
|
||||
int sqlite3Reprepare(Vdbe*);
|
||||
void sqlite3ExprListCheckLength(Parse*, ExprList*, int, const char*);
|
||||
CollSeq* sqlite3BinaryCompareCollSeq(Parse *, Expr *, Expr *);
|
||||
|
||||
#if SQLITE_MAX_EXPR_DEPTH>0
|
||||
void sqlite3ExprSetHeight(Expr *);
|
||||
|
18
src/where.c
18
src/where.c
@ -16,7 +16,7 @@
|
||||
** so is applicable. Because this module is responsible for selecting
|
||||
** indices, you might also think of this module as the "query optimizer".
|
||||
**
|
||||
** $Id: where.c,v 1.248 2007/05/04 13:15:57 drh Exp $
|
||||
** $Id: where.c,v 1.249 2007/05/29 12:11:30 danielk1977 Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
|
||||
@ -452,15 +452,17 @@ static WhereTerm *findTerm(
|
||||
|
||||
idxaff = pIdx->pTable->aCol[iColumn].affinity;
|
||||
if( !sqlite3IndexAffinityOk(pX, idxaff) ) continue;
|
||||
pColl = sqlite3ExprCollSeq(pParse, pX->pLeft);
|
||||
|
||||
/* Figure out the collation sequence required from an index for
|
||||
** it to be useful for optimising expression pX. Store this
|
||||
** value in variable pColl.
|
||||
*/
|
||||
assert(pX->pLeft);
|
||||
pColl = sqlite3BinaryCompareCollSeq(pParse, pX->pLeft, pX->pRight);
|
||||
if( !pColl ){
|
||||
if( pX->pRight ){
|
||||
pColl = sqlite3ExprCollSeq(pParse, pX->pRight);
|
||||
}
|
||||
if( !pColl ){
|
||||
pColl = pParse->db->pDfltColl;
|
||||
}
|
||||
pColl = pParse->db->pDfltColl;
|
||||
}
|
||||
|
||||
for(j=0; j<pIdx->nColumn && pIdx->aiColumn[j]!=iColumn; j++){}
|
||||
assert( j<pIdx->nColumn );
|
||||
if( sqlite3StrICmp(pColl->zName, pIdx->azColl[j]) ) continue;
|
||||
|
49
test/tkt2391.test
Normal file
49
test/tkt2391.test
Normal file
@ -0,0 +1,49 @@
|
||||
#
|
||||
# 2007 May 28
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
#***********************************************************************
|
||||
# $Id: tkt2391.test,v 1.1 2007/05/29 12:11:30 danielk1977 Exp $
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
|
||||
do_test tkt2391.1 {
|
||||
execsql {
|
||||
CREATE TABLE folders(folderid, parentid, foldername COLLATE binary);
|
||||
INSERT INTO folders VALUES(1, 3, 'FolderA');
|
||||
INSERT INTO folders VALUES(1, 3, 'folderB');
|
||||
INSERT INTO folders VALUES(4, 0, 'FolderC');
|
||||
}
|
||||
} {}
|
||||
|
||||
do_test tkt2391.2 {
|
||||
execsql {
|
||||
SELECT count(*) FROM folders WHERE foldername < 'FolderC';
|
||||
}
|
||||
} {1}
|
||||
|
||||
do_test tkt2391.3 {
|
||||
execsql {
|
||||
SELECT count(*) FROM folders WHERE foldername < 'FolderC' COLLATE nocase;
|
||||
}
|
||||
} {2}
|
||||
|
||||
# This demonstrates the bug. Creating the index causes SQLite to ignore
|
||||
# the "COLLATE nocase" clause and use the default collation sequence
|
||||
# for column "foldername" instead (happens to be BINARY in this case).
|
||||
#
|
||||
do_test tkt2391.4 {
|
||||
execsql {
|
||||
CREATE INDEX f_i ON folders(foldername);
|
||||
SELECT count(*) FROM folders WHERE foldername < 'FolderC' COLLATE nocase;
|
||||
}
|
||||
} {2}
|
||||
|
||||
finish_test
|
Loading…
Reference in New Issue
Block a user