0
0
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:
danielk1977 2007-05-29 12:11:29 +00:00
parent 331bf02e0e
commit bcbb04e501
6 changed files with 84 additions and 25 deletions

View File

@ -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

View File

@ -1 +1 @@
1abf784fe27cdc61b6b944b79d024ea98eb5289e
f9a95e92dfaaa61ec0a44b9b7017b07929c94d26

View File

@ -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 ){

View File

@ -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 *);

View File

@ -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
View 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