-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
-C Merge\sin\schanges\sup\sto\sand\sincluding\sthe\s3.6.23.1\srelease.
-D 2010-06-16T19:48:57
+C Cherrypick\sthe\schanges\sfor\senhancement\srequests\s[e090183531fc27474]\s\n(use\sindices\son\sLIKE\swith\sno\swildcards)\sand\s[4711020446da7d93d993]\n(use\snocase\sindex\sfor\sLIKE\seven\sif\sthe\scolumn\sis\sbinary)\sinto\sthe\n3.6.23.1\srelease\sof\sthe\sApple-OSX\sbranch.
+D 2010-08-17T23:13:42
F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
F Makefile.in b12be4429b75eca982a5646752652efde58e8f29
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
F src/ctime.c ceb247eb31620bba66a94c3f697db489a1652353
F src/date.c 485a4409a384310e6d93fd1104a9d0a8658becd9
F src/delete.c 610dc008e88a9599f905f5cbe9577ac9c36e0581
-F src/expr.c 6baed2a0448d494233d9c0a610eea018ab386a32
+F src/expr.c 6bb1f6a7213061c325b679c3aa0aa2358094ad7f
F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
F src/fkey.c e2116672a6bd610dc888e27df292ebc7999c9bb0
F src/func.c cc68e721c25b9ad0d5c2d9e173298cfc1818fe4c
F src/os_win.c bc65553f911439a6b1aa3cf22f34e5ea1c4aa394
F src/pager.c e39ac887694a6644135f5e4151fe293b5397dd64
F src/pager.h 1b32faf2e578ac3e7bcf9c9d11217128261c5c54
-F src/parse.y ace5c7a125d9f2a410e431ee3209034105045f7e
+F src/parse.y 07fdc757efdb43bac77120f3b50db15d5fe7f5db
F src/pcache.c 4956b41d6ba913f7a8a56fbf32be78caed0e45c2
F src/pcache.h c683390d50f856d4cd8e24342ae62027d1bb6050
F src/pcache1.c 2bb2261190b42a348038f5b1c285c8cef415fcc8
F src/shell.c c40427c7245535a04a9cb4a417b6cc05c022e6a4
F src/sqlite.h.in f9a9be1bce911669a259f7c747bf05635cb360b5
F src/sqlite3ext.h 69dfb8116af51b84a029cddb3b35062354270c89
-F src/sqliteInt.h 6873f7f4c24fcdceece8777f2a1cbec049df77a0
+F src/sqliteInt.h 4ac68f515068deb0435b8e4de46844368e95018a
F src/sqliteLimit.h 3afab2291762b5d09ae20c18feb8e9fa935a60a6
F src/status.c d329385a2cba3ea49d9d68af0ad84b22d46b4f40
F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e
F src/vdbetrace.c 864cef96919323482ebd9986f2132435115e9cc2
F src/vtab.c 606adf51cd6d4ba51a8c6dccede06a6f7b0dd72d
F src/walker.c 3112bb3afe1d85dc52317cb1d752055e9a781f8f
-F src/where.c 399ea4c090284c9d16f76d685b9b44e8b9b4442b
+F src/where.c 0777e1f8f1cd88ce37da41d6bbd54b8307705ee4
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
F test/alias.test 4529fbc152f190268a15f9384a5651bbbabc9d87
F test/all.test 14165b3e32715b700b5f0cbf8f6e3833dda0be45
F test/altermalloc.test e81ac9657ed25c6c5bb09bebfa5a047cd8e4acfc
F test/analyze.test ad5329098fe4de4a96852231d53e3e9e6283ad4b
F test/analyze2.test a2ad7b0a4e13801ee3968fe70f22aff52326569c
-F test/analyze3.test 506203875258ffd8ffa879b9c3c5432022d2b6d8
+F test/analyze3.test 535bf0762f49fa96885efe8568738276c2204a2a
F test/async.test 8c75d31b8330f8b70cf2571b014d4476a063efdb
F test/async2.test bf5e2ca2c96763b4cba3d016249ad7259a5603b6
F test/async3.test 93edaa9122f498e56ea98c36c72abc407f4fb11e
F test/keyword1.test a2400977a2e4fde43bf33754c2929fda34dbca05
F test/lastinsert.test 474d519c68cb79d07ecae56a763aa7f322c72f51
F test/laststmtchanges.test ae613f53819206b3222771828d024154d51db200
-F test/like.test 4b594af9eddfd01018df1e9b1d18721aff619fa7
+F test/like.test 565d240313f15a8afa8d7098dc9fe303c1e2a496
F test/like2.test 3b2ee13149ba4a8a60b59756f4e5d345573852da
F test/limit.test 2db7b3b34fb925b8e847d583d2eb67531d0ce67e
F test/loadext.test 0393ce12d9616aa87597dd0ec88181de181f6db0
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
-P 5c0afe70a5ee2b378896bf30426823dc5ae4e95c 776679af588625f13307369770979bccae7cf03a
-R 90e27fcea4f7f54474c3a0fb8671dd73
+P 21ca87f69125a9e7124c6ddc566d17f64661b0d3
+R 746b72865ced8034924c2cc1c718a49c
U drh
-Z b8746f44feb03a04fe1e2272410b2363
+Z bb87ab062eae07f981b513eb1b914158
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (GNU/Linux)
-iD8DBQFMGSqsoxKgR168RlERAtaeAJwOjCShd/QM6A+bZt7Sd1NRZQnhYgCdEZRm
-OPl6AbsNdGPQiQAPLtVWZiQ=
-=hX2q
+iD8DBQFMaxeqoxKgR168RlERAsD4AJ9c9h3cETIYGap5CjJMrATUO3T+cACgjLkN
+T2aAsvx2yasC+G+Gv6NOb3E=
+=s+Bg
-----END PGP SIGNATURE-----
-21ca87f69125a9e7124c6ddc566d17f64661b0d3
\ No newline at end of file
+220cca50da08c5166afa3d2364fdf7f8e7308836
\ No newline at end of file
return pExpr->affinity;
}
+/*
+** Set the explicit collating sequence for an expression to the
+** collating sequence supplied in the second argument.
+*/
+Expr *sqlite3ExprSetColl(Expr *pExpr, CollSeq *pColl){
+ if( pExpr && pColl ){
+ pExpr->pColl = pColl;
+ pExpr->flags |= EP_ExpCollate;
+ }
+ return pExpr;
+}
+
/*
** Set the collating sequence for expression pExpr to be the collating
** sequence named by pToken. Return a pointer to the revised expression.
** flag. An explicit collating sequence will override implicit
** collating sequences.
*/
-Expr *sqlite3ExprSetColl(Parse *pParse, Expr *pExpr, Token *pCollName){
+Expr *sqlite3ExprSetCollByToken(Parse *pParse, Expr *pExpr, Token *pCollName){
char *zColl = 0; /* Dequoted name of collation sequence */
CollSeq *pColl;
sqlite3 *db = pParse->db;
zColl = sqlite3NameFromToken(db, pCollName);
- if( pExpr && zColl ){
- pColl = sqlite3LocateCollSeq(pParse, zColl);
- if( pColl ){
- pExpr->pColl = pColl;
- pExpr->flags |= EP_ExpCollate;
- }
- }
+ pColl = sqlite3LocateCollSeq(pParse, zColl);
+ sqlite3ExprSetColl(pExpr, pColl);
sqlite3DbFree(db, zColl);
return pExpr;
}
spanSet(&A, &X, &X);
}
expr(A) ::= expr(E) COLLATE ids(C). {
- A.pExpr = sqlite3ExprSetColl(pParse, E.pExpr, &C);
+ A.pExpr = sqlite3ExprSetCollByToken(pParse, E.pExpr, &C);
A.zStart = E.zStart;
A.zEnd = &C.z[C.n];
}
Expr *p = 0;
if( C.n>0 ){
p = sqlite3Expr(pParse->db, TK_COLUMN, 0);
- sqlite3ExprSetColl(pParse, p, &C);
+ sqlite3ExprSetCollByToken(pParse, p, &C);
}
A = sqlite3ExprListAppend(pParse,X, p);
sqlite3ExprListSetName(pParse,A,&Y,1);
Expr *p = 0;
if( C.n>0 ){
p = sqlite3PExpr(pParse, TK_COLUMN, 0, 0, 0);
- sqlite3ExprSetColl(pParse, p, &C);
+ sqlite3ExprSetCollByToken(pParse, p, &C);
}
A = sqlite3ExprListAppend(pParse,0, p);
sqlite3ExprListSetName(pParse, A, &Y, 1);
CollSeq *sqlite3FindCollSeq(sqlite3*,u8 enc, const char*,int);
CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char*zName);
CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr);
-Expr *sqlite3ExprSetColl(Parse *pParse, Expr *, Token *);
+Expr *sqlite3ExprSetColl(Expr*, CollSeq*);
+Expr *sqlite3ExprSetCollByToken(Parse *pParse, Expr*, Token*);
int sqlite3CheckCollSeq(Parse *, CollSeq *);
int sqlite3CheckObjectName(Parse *, const char *);
void sqlite3VdbeSetChanges(sqlite3 *, int);
int c; /* One character in z[] */
int cnt; /* Number of non-wildcard prefix characters */
char wc[3]; /* Wildcard characters */
- CollSeq *pColl; /* Collating sequence for LHS */
sqlite3 *db = pParse->db; /* Database connection */
sqlite3_value *pVal = 0;
int op; /* Opcode of pRight */
return 0;
}
assert( pLeft->iColumn!=(-1) ); /* Because IPK never has AFF_TEXT */
- pColl = sqlite3ExprCollSeq(pParse, pLeft);
- if( pColl==0 ) return 0; /* Happens when LHS has an undefined collation */
- if( (pColl->type!=SQLITE_COLL_BINARY || *pnoCase) &&
- (pColl->type!=SQLITE_COLL_NOCASE || !*pnoCase) ){
- /* IMP: R-09003-32046 For the GLOB operator, the column must use the
- ** default BINARY collating sequence.
- ** IMP: R-41408-28306 For the LIKE operator, if case_sensitive_like mode
- ** is enabled then the column must use the default BINARY collating
- ** sequence, or if case_sensitive_like mode is disabled then the column
- ** must use the built-in NOCASE collating sequence.
- */
- return 0;
- }
pRight = pList->a[0].pExpr;
op = pRight->op;
while( (c=z[cnt])!=0 && c!=wc[0] && c!=wc[1] && c!=wc[2] ){
cnt++;
}
- if( cnt!=0 && c!=0 && 255!=(u8)z[cnt-1] ){
+ if( cnt!=0 && 255!=(u8)z[cnt-1] ){
Expr *pPrefix;
- *pisComplete = z[cnt]==wc[0] && z[cnt+1]==0;
+ *pisComplete = c==wc[0] && z[cnt+1]==0;
pPrefix = sqlite3Expr(db, TK_STRING, z);
if( pPrefix ) pPrefix->u.zToken[cnt] = 0;
*ppPrefix = pPrefix;
Expr *pNewExpr2;
int idxNew1;
int idxNew2;
+ CollSeq *pColl; /* Collating sequence to use */
pLeft = pExpr->x.pList->a[1].pExpr;
pStr2 = sqlite3ExprDup(db, pStr1, 0);
}
*pC = c + 1;
}
- pNewExpr1 = sqlite3PExpr(pParse, TK_GE, sqlite3ExprDup(db,pLeft,0),pStr1,0);
+ pColl = sqlite3FindCollSeq(db, SQLITE_UTF8, noCase ? "NOCASE" : "BINARY",0);
+ pNewExpr1 = sqlite3PExpr(pParse, TK_GE,
+ sqlite3ExprSetColl(sqlite3ExprDup(db,pLeft,0), pColl),
+ pStr1, 0);
idxNew1 = whereClauseInsert(pWC, pNewExpr1, TERM_VIRTUAL|TERM_DYNAMIC);
testcase( idxNew1==0 );
exprAnalyze(pSrc, pWC, idxNew1);
- pNewExpr2 = sqlite3PExpr(pParse, TK_LT, sqlite3ExprDup(db,pLeft,0),pStr2,0);
+ pNewExpr2 = sqlite3PExpr(pParse, TK_LT,
+ sqlite3ExprSetColl(sqlite3ExprDup(db,pLeft,0), pColl),
+ pStr2, 0);
idxNew2 = whereClauseInsert(pWC, pNewExpr2, TERM_VIRTUAL|TERM_DYNAMIC);
testcase( idxNew2==0 );
exprAnalyze(pSrc, pWC, idxNew2);
set like "%a"
sf_execsql { SELECT count(*) FROM t1 WHERE b LIKE $like }
} {999 999 100}
+do_test analyze3-2.6 {
+ set like "a"
+ sf_execsql { SELECT count(*) FROM t1 WHERE b LIKE $like }
+} {101 0 0}
+do_test analyze3-2.7 {
+ set like "ab"
+ sf_execsql { SELECT count(*) FROM t1 WHERE b LIKE $like }
+} {11 0 0}
+do_test analyze3-2.8 {
+ set like "abc"
+ sf_execsql { SELECT count(*) FROM t1 WHERE b LIKE $like }
+} {2 0 1}
+do_test analyze3-2.9 {
+ set like "a_c"
+ sf_execsql { SELECT count(*) FROM t1 WHERE b LIKE $like }
+} {101 0 10}
#-------------------------------------------------------------------------
set sqlite_like_count
} 0
+# The LIKE optimization still works when the RHS is a string with no
+# wildcard. Ticket [e090183531fc2747]
+#
+do_test like-3.4.2 {
+ queryplan {
+ SELECT x FROM t1 WHERE x LIKE 'a' ORDER BY 1;
+ }
+} {a nosort {} i1}
+do_test like-3.4.3 {
+ queryplan {
+ SELECT x FROM t1 WHERE x LIKE 'ab' ORDER BY 1;
+ }
+} {ab nosort {} i1}
+do_test like-3.4.4 {
+ queryplan {
+ SELECT x FROM t1 WHERE x LIKE 'abcd' ORDER BY 1;
+ }
+} {abcd nosort {} i1}
+do_test like-3.4.5 {
+ queryplan {
+ SELECT x FROM t1 WHERE x LIKE 'abcde' ORDER BY 1;
+ }
+} {nosort {} i1}
+
+
# Partial optimization when the pattern does not end in '%'
#
do_test like-3.5 {
set sqlite_like_count
} 6
+# GLOB optimization when there is no wildcard. Ticket [e090183531fc2747]
+#
+do_test like-3.25 {
+ queryplan {
+ SELECT x FROM t1 WHERE x GLOB 'a' ORDER BY 1;
+ }
+} {a nosort {} i1}
+do_test like-3.26 {
+ queryplan {
+ SELECT x FROM t1 WHERE x GLOB 'abcd' ORDER BY 1;
+ }
+} {abcd nosort {} i1}
+do_test like-3.27 {
+ queryplan {
+ SELECT x FROM t1 WHERE x GLOB 'abcde' ORDER BY 1;
+ }
+} {nosort {} i1}
+
+
+
# No optimization if the LHS of the LIKE is not a column name or
# if the RHS is not a string.
#
}
} {12 123 scan 5 like 6}
+# LIKE and GLOB where the default collating sequence is not appropriate
+# but an index with the appropriate collating sequence exists.
+#
+do_test like-11.0 {
+ execsql {
+ CREATE TABLE t11(
+ a INTEGER PRIMARY KEY,
+ b TEXT COLLATE nocase,
+ c TEXT COLLATE binary
+ );
+ INSERT INTO t11 VALUES(1, 'a','a');
+ INSERT INTO t11 VALUES(2, 'ab','ab');
+ INSERT INTO t11 VALUES(3, 'abc','abc');
+ INSERT INTO t11 VALUES(4, 'abcd','abcd');
+ INSERT INTO t11 VALUES(5, 'A','A');
+ INSERT INTO t11 VALUES(6, 'AB','AB');
+ INSERT INTO t11 VALUES(7, 'ABC','ABC');
+ INSERT INTO t11 VALUES(8, 'ABCD','ABCD');
+ INSERT INTO t11 VALUES(9, 'x','x');
+ INSERT INTO t11 VALUES(10, 'yz','yz');
+ INSERT INTO t11 VALUES(11, 'X','X');
+ INSERT INTO t11 VALUES(12, 'YZ','YZ');
+ SELECT count(*) FROM t11;
+ }
+} {12}
+do_test like-11.1 {
+ queryplan {
+ PRAGMA case_sensitive_like=OFF;
+ SELECT b FROM t11 WHERE b LIKE 'abc%' ORDER BY a;
+ }
+} {abc abcd ABC ABCD nosort t11 *}
+do_test like-11.2 {
+ queryplan {
+ PRAGMA case_sensitive_like=ON;
+ SELECT b FROM t11 WHERE b LIKE 'abc%' ORDER BY a;
+ }
+} {abc abcd nosort t11 *}
+do_test like-11.3 {
+ queryplan {
+ PRAGMA case_sensitive_like=OFF;
+ CREATE INDEX t11b ON t11(b);
+ SELECT b FROM t11 WHERE b LIKE 'abc%' ORDER BY a;
+ }
+} {abc abcd ABC ABCD sort {} t11b}
+do_test like-11.4 {
+ queryplan {
+ PRAGMA case_sensitive_like=ON;
+ SELECT b FROM t11 WHERE b LIKE 'abc%' ORDER BY a;
+ }
+} {abc abcd nosort t11 *}
+do_test like-11.5 {
+ queryplan {
+ PRAGMA case_sensitive_like=OFF;
+ DROP INDEX t11b;
+ CREATE INDEX t11bnc ON t11(b COLLATE nocase);
+ SELECT b FROM t11 WHERE b LIKE 'abc%' ORDER BY a;
+ }
+} {abc abcd ABC ABCD sort {} t11bnc}
+do_test like-11.6 {
+ queryplan {
+ CREATE INDEX t11bb ON t11(b COLLATE binary);
+ SELECT b FROM t11 WHERE b LIKE 'abc%' ORDER BY a;
+ }
+} {abc abcd ABC ABCD sort {} t11bnc}
+do_test like-11.7 {
+ queryplan {
+ PRAGMA case_sensitive_like=ON;
+ SELECT b FROM t11 WHERE b LIKE 'abc%' ORDER BY a;
+ }
+} {abc abcd sort {} t11bb}
+do_test like-11.8 {
+ queryplan {
+ PRAGMA case_sensitive_like=OFF;
+ SELECT b FROM t11 WHERE b GLOB 'abc*' ORDER BY a;
+ }
+} {abc abcd sort {} t11bb}
+do_test like-11.9 {
+ queryplan {
+ CREATE INDEX t11cnc ON t11(c COLLATE nocase);
+ CREATE INDEX t11cb ON t11(c COLLATE binary);
+ SELECT c FROM t11 WHERE c LIKE 'abc%' ORDER BY a;
+ }
+} {abc abcd ABC ABCD sort {} t11cnc}
+do_test like-11.10 {
+ queryplan {
+ SELECT c FROM t11 WHERE c GLOB 'abc*' ORDER BY a;
+ }
+} {abc abcd sort {} t11cb}
+
finish_test