-C Fix\sa\sbug\sin\sthe\scopy\smethod\sof\sthe\sTCL\sinterface.\s\sTicket\s#2201.\s(CVS\s3623)
-D 2007-02-01T01:53:44
+C First\scut\sat\sadding\sthe\sCOLLATE\soperator.\s\sRegression\stests\spass\s(or\sat\sleast\nthe\squick\sset\sdoes)\sand\sa\sfew\snew\stests\shave\sbeen\sadded.\s\sBut\smany\smore\ntests\sare\sneeded.\s\sRules\sfor\scombining\scollations\sneed\sto\sbe\sworked\sout.\s(CVS\s3624)
+D 2007-02-01T23:02:45
F Makefile.in 7fa74bf4359aa899da5586e394d17735f221315f
F Makefile.linux-gcc 2d8574d1ba75f129aba2019f0b959db380a90935
F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028
F src/date.c 393c73fc027597e008dcd81454544659e978b05c
F src/delete.c 804384761144fe1a5035b99f4bd7d706976831bd
F src/experimental.c 1b2d1a6cd62ecc39610e97670332ca073c50792b
-F src/expr.c ec0b5d9dd6f69425302c255d88475511f5d8b5c9
+F src/expr.c 4ece4d575fa8686535877bbfb2e9d74093a4aa94
F src/func.c b7e1e220a6795ecae7649815145ea5f8644dfa5f
F src/hash.c 449f3d6620193aa557f5d86cbc5cc6b87702b185
F src/hash.h 1b3f7e2609141fd571f62199fc38687d262e9564
F src/os_win.h 41a946bea10f61c158ce8645e7646b29d44f122b
F src/pager.c d6ad66eb119602cb2e6a097f8f635372ba677d23
F src/pager.h 2e6d42f4ae004ae748a037b8468112b851c447a7
-F src/parse.y 31ea08df1305100abd5bcee61b4a01c4e43cbd35
+F src/parse.y ebf4253e3710452953cd1ba8171beb86f47f7f57
F src/pragma.c 5091300911670ddaa552bfa12c45cbca1bb7e7d6
F src/prepare.c 484389c6811415b8f23d259ac9c029613e1c72c3
F src/printf.c aade23a789d7cc88b397ec0d33a0a01a33a7a9c1
F src/random.c 6119474a6f6917f708c1dee25b9a8e519a620e88
-F src/select.c 628f49827d5a94ed9b6246efb8dc9f5c24e413f1
+F src/select.c 63b2163f35fd2570a02dab5759979644c4405f1c
F src/server.c 087b92a39d883e3fa113cae259d64e4c7438bc96
F src/shell.c d13ca007cd18192c07a668aeddcdd6a9fe639be9
F src/sqlite.h.in 6b7383baf76070214f6381f603328ca9b22a7fae
F src/sqlite3ext.h 011c75fd6459a61454514af07c7a4f1f5c767f27
-F src/sqliteInt.h f6053066ba92ed66507661fe6a78c31ca856b6f8
+F src/sqliteInt.h 650d05a8c530ee3c28ad8b19684d70f889458e60
F src/table.c 6d0da66dde26ee75614ed8f584a1996467088d06
F src/tclsqlite.c cd2b3b86ab07c0e0779f6c6e71e72c6c7dc1e704
F src/test1.c 053f5224697efaefff1f4c647fd90fdea9346cc5
F test/capi3c.test 5961df13666c994890ffd44f0143cf92897d18dc
F test/cast.test f88e7b6946e9a467cf4bb142d92bb65a83747fc2
F test/check.test e5ea0c1a06c10e81e3434ca029e2c4a562f2b673
-F test/collate1.test add9454cef160677bb8b34148b8f277ce7f9f1c4
-F test/collate2.test 224a632ba04907c049804b08162efd234aa7871f
+F test/collate1.test e3eaa48c21e150814be1a7b852d2a8af24458d04
+F test/collate2.test 701d9651c5707024fd86a20649af9ea55e2c0eb8
F test/collate3.test 947a77f5b8227e037a7094d0e338a5504f155cc4
F test/collate4.test daf498e294dcd596b961d425c3f2dda117e4717e
F test/collate5.test 8fb4e7e0241839356bd8710f437c32efb47bfff8
F www/index-ex1-x-b.gif f9b1d85c3fa2435cf38b15970c7e3aa1edae23a3
F www/index.tcl 7f67d421e4c1f48083c178bee460a27220f4fcc1
F www/indirect1b1.gif adfca361d2df59e34f9c5cac52a670c2bfc303a1
-F www/lang.tcl aa6d599679cbd5612d7fd7b1ae733ac1221c2a76
+F www/lang.tcl 65d0aa787aa55619dd7a8497306ea539f1201bf3
F www/lockingv3.tcl f59b19d6c8920a931f096699d6faaf61c05db55f
F www/mingw.tcl d96b451568c5d28545fefe0c80bee3431c73f69c
F www/nulls.tcl ec35193f92485b87b90a994a01d0171b58823fcf
F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b
F www/whentouse.tcl 97e2b5cd296f7d8057e11f44427dea8a4c2db513
-P 505dce8f4e8717341e04f49f6f382719c3c704f1
-R 4143445bb3574091269b3a2a42f03d6f
+P 936263966ea70792e8abb712730f78cafa1fdbad
+R 2d8d95cad338f4e2489cbc3239cd084f
U drh
-Z 96cc038466dba8dfd6f53c6f8d4f749d
+Z f3d08231d49c025fe236a57faf179faf
-936263966ea70792e8abb712730f78cafa1fdbad
\ No newline at end of file
+85cca7cd252d46ba71d302a89bc67c56146ec552
\ No newline at end of file
** This file contains routines used for analyzing expressions and
** for generating VDBE code that evaluates expressions in SQLite.
**
-** $Id: expr.c,v 1.272 2007/02/01 01:40:44 drh Exp $
+** $Id: expr.c,v 1.273 2007/02/01 23:02:45 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
return pExpr->affinity;
}
+/*
+** Set the collating sequence for expression pExpr to be the collating
+** sequence named by pToken. Return a pointer to the revised expression.
+*/
+Expr *sqlite3ExprSetColl(Parse *pParse, Expr *pExpr, Token *pName){
+ CollSeq *pColl;
+ if( pExpr==0 ) return 0;
+ pColl = sqlite3LocateCollSeq(pParse, (char*)pName->z, pName->n);
+ if( pColl ){
+ pExpr->pColl = pColl;
+ pExpr->flags |= EP_ExpCollate;
+ }
+ return pExpr;
+}
+
/*
** Return the default collation sequence for the expression pExpr. If
** there is no default collation type, return 0.
/* Substitute the rowid (column -1) for the INTEGER PRIMARY KEY */
pExpr->iColumn = j==pTab->iPKey ? -1 : j;
pExpr->affinity = pTab->aCol[j].affinity;
- pExpr->pColl = sqlite3FindCollSeq(db, ENC(db), zColl,-1, 0);
+ if( (pExpr->flags & EP_ExpCollate)==0 ){
+ pExpr->pColl = sqlite3FindCollSeq(db, ENC(db), zColl,-1, 0);
+ }
if( i<pSrcList->nSrc-1 ){
if( pItem[1].jointype & JT_NATURAL ){
/* If this match occurred in the left table of a natural join,
cnt++;
pExpr->iColumn = iCol==pTab->iPKey ? -1 : iCol;
pExpr->affinity = pTab->aCol[iCol].affinity;
- pExpr->pColl = sqlite3FindCollSeq(db, ENC(db), zColl,-1, 0);
+ if( (pExpr->flags & EP_ExpCollate)==0 ){
+ pExpr->pColl = sqlite3FindCollSeq(db, ENC(db), zColl,-1, 0);
+ }
pExpr->pTab = pTab;
break;
}
** the parser. Lemon will also generate a header file containing
** numeric codes for all of the tokens.
**
-** @(#) $Id: parse.y,v 1.213 2007/01/27 02:38:30 drh Exp $
+** @(#) $Id: parse.y,v 1.214 2007/02/01 23:02:45 drh Exp $
*/
// All token codes are small integers with #defines that begin with "TK_"
%left BITAND BITOR LSHIFT RSHIFT.
%left PLUS MINUS.
%left STAR SLASH REM.
-%left CONCAT.
+%left CONCAT COLLATE.
%right UMINUS UPLUS BITNOT.
// And "ids" is an identifer-or-string.
orderby_opt(A) ::= . {A = 0;}
orderby_opt(A) ::= ORDER BY sortlist(X). {A = X;}
-sortlist(A) ::= sortlist(X) COMMA sortitem(Y) collate(C) sortorder(Z). {
- A = sqlite3ExprListAppend(X,Y,C.n>0?&C:0);
+sortlist(A) ::= sortlist(X) COMMA sortitem(Y) sortorder(Z). {
+ A = sqlite3ExprListAppend(X,Y,0);
if( A ) A->a[A->nExpr-1].sortOrder = Z;
}
-sortlist(A) ::= sortitem(Y) collate(C) sortorder(Z). {
- A = sqlite3ExprListAppend(0,Y,C.n>0?&C:0);
+sortlist(A) ::= sortitem(Y) sortorder(Z). {
+ A = sqlite3ExprListAppend(0,Y,0);
if( A && A->a ) A->a[0].sortOrder = Z;
}
sortitem(A) ::= expr(X). {A = X;}
Expr *pExpr = A = sqlite3Expr(TK_VARIABLE, 0, 0, pToken);
sqlite3ExprAssignVarNumber(pParse, pExpr);
}
+expr(A) ::= expr(E) COLLATE id(C). {
+ A = sqlite3ExprSetColl(pParse, E, &C);
+}
%ifndef SQLITE_OMIT_CAST
expr(A) ::= CAST(X) LP expr(E) AS typetoken(T) RP(Y). {
A = sqlite3Expr(TK_CAST, E, 0, &T);
** This file contains C code routines that are called by the parser
** to handle SELECT statements in SQLite.
**
-** $Id: select.c,v 1.325 2007/01/26 19:23:33 drh Exp $
+** $Id: select.c,v 1.326 2007/02/01 23:02:45 drh Exp $
*/
#include "sqliteInt.h"
apColl = pKeyInfo->aColl;
for(i=0; i<nOrderByExpr; i++, pOTerm++, apColl++, pSortOrder++){
Expr *pExpr = pOTerm->pExpr;
- char *zName = pOTerm->zName;
- assert( pExpr->op==TK_COLUMN && pExpr->iColumn<nCol );
- if( zName ){
- *apColl = sqlite3LocateCollSeq(pParse, zName, -1);
+ if( (pExpr->flags & EP_ExpCollate) ){
+ assert( pExpr->pColl!=0 );
+ *apColl = pExpr->pColl;
}else{
*apColl = aCopy[pExpr->iColumn];
}
Expr *pE = pOrderBy->a[i].pExpr;
if( sqlite3ExprIsInteger(pE, &iCol) ){
if( iCol>0 && iCol<=pEList->nExpr ){
+ CollSeq *pColl = pE->pColl;
+ int flags = pE->flags & EP_ExpCollate;
sqlite3ExprDelete(pE);
pE = pOrderBy->a[i].pExpr = sqlite3ExprDup(pEList->a[iCol-1].pExpr);
+ if( pColl && flags ){
+ pE->pColl = pColl;
+ pE->flags |= flags;
+ }
}else{
sqlite3ErrorMsg(pParse,
"%s BY column number %d out of range - should be "
}
#endif
- /* If there is an ORDER BY clause, resolve any collation sequences
- ** names that have been explicitly specified and create a sorting index.
- **
- ** This sorting index might end up being unused if the data can be
+ /* If there is an ORDER BY clause, then this sorting
+ ** index might end up being unused if the data can be
** extracted in pre-sorted order. If that is the case, then the
** OP_OpenEphemeral instruction will be changed to an OP_Noop once
** we figure out that the sorting index is not needed. The addrSortIndex
** variable is used to facilitate that change.
*/
if( pOrderBy ){
- struct ExprList_item *pTerm;
KeyInfo *pKeyInfo;
- for(i=0, pTerm=pOrderBy->a; i<pOrderBy->nExpr; i++, pTerm++){
- if( pTerm->zName ){
- pTerm->pExpr->pColl = sqlite3LocateCollSeq(pParse, pTerm->zName, -1);
- }
- }
if( pParse->nErr ){
goto select_end;
}
*************************************************************************
** Internal interface definitions for SQLite.
**
-** @(#) $Id: sqliteInt.h,v 1.534 2007/02/01 01:40:44 drh Exp $
+** @(#) $Id: sqliteInt.h,v 1.535 2007/02/01 23:02:45 drh Exp $
*/
#ifndef _SQLITEINT_H_
#define _SQLITEINT_H_
#define EP_VarSelect 0x20 /* pSelect is correlated, not constant */
#define EP_Dequoted 0x40 /* True if the string has been dequoted */
#define EP_InfixFunc 0x80 /* True for an infix function: LIKE, GLOB, etc */
+#define EP_ExpCollate 0x100 /* Collating sequence specified explicitly */
/*
** These macros can be used to test, set, or clear bits in the
CollSeq *sqlite3FindCollSeq(sqlite3*,u8 enc, const char *,int,int);
CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char *zName, int nName);
CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr);
+Expr *sqlite3ExprSetColl(Parse *pParse, Expr *, Token *);
int sqlite3CheckCollSeq(Parse *, CollSeq *);
int sqlite3CheckIndexCollSeq(Parse *, Index *);
int sqlite3CheckObjectName(Parse *, const char *);
# This file implements regression tests for SQLite library. The
# focus of this script is page cache subsystem.
#
-# $Id: collate1.test,v 1.4 2005/11/01 15:48:25 drh Exp $
+# $Id: collate1.test,v 1.5 2007/02/01 23:02:46 drh Exp $
set testdir [file dirname $argv0]
source $testdir/tester.tcl
}
} {{} 0x2D 0x119}
do_test collate1-1.5 {
+ execsql {
+ SELECT c2 COLLATE hex FROM collate1t1 ORDER BY 1
+ }
+} {{} 0x2D 0x119}
+do_test collate1-1.6 {
+ execsql {
+ SELECT c2 COLLATE hex FROM collate1t1 ORDER BY 1 ASC
+ }
+} {{} 0x2D 0x119}
+do_test collate1-1.7 {
+ execsql {
+ SELECT c2 COLLATE hex FROM collate1t1 ORDER BY 1 DESC
+ }
+} {0x119 0x2D {}}
+do_test collate1-1.99 {
execsql {
DROP TABLE collate1t1;
}
ORDER BY 1 COLLATE binary ASC, 2 COLLATE hex ASC;
}
} {{} {} 11 0x11 11 0x101 5 0xA 5 0x11 7 0xA}
-do_test collate1-2.7 {
+do_test collate1-2.12.1 {
+ execsql {
+ SELECT c1 COLLATE numeric, c2 FROM collate1t1
+ ORDER BY 1, 2 COLLATE hex;
+ }
+} {{} {} 5 0xA 5 0x11 7 0xA 11 0x11 11 0x101}
+do_test collate1-2.12.2 {
+ execsql {
+ SELECT c1 COLLATE hex, c2 FROM collate1t1
+ ORDER BY 1 COLLATE numeric, 2 COLLATE hex;
+ }
+} {{} {} 5 0xA 5 0x11 7 0xA 11 0x11 11 0x101}
+do_test collate1-2.12.3 {
+ execsql {
+ SELECT c1, c2 COLLATE hex FROM collate1t1
+ ORDER BY 1 COLLATE numeric, 2;
+ }
+} {{} {} 5 0xA 5 0x11 7 0xA 11 0x11 11 0x101}
+do_test collate1-2.12.4 {
+ execsql {
+ SELECT c1 COLLATE numeric, c2 COLLATE hex
+ FROM collate1t1
+ ORDER BY 1, 2;
+ }
+} {{} {} 5 0xA 5 0x11 7 0xA 11 0x11 11 0x101}
+do_test collate1-2.13 {
+ execsql {
+ SELECT c1 COLLATE binary, c2 COLLATE hex
+ FROM collate1t1
+ ORDER BY 1, 2;
+ }
+} {{} {} 11 0x11 11 0x101 5 0xA 5 0x11 7 0xA}
+do_test collate1-2.14 {
+ execsql {
+ SELECT c1, c2
+ FROM collate1t1 ORDER BY 1 COLLATE binary DESC, 2 COLLATE hex;
+ }
+} {7 0xA 5 0xA 5 0x11 11 0x11 11 0x101 {} {}}
+do_test collate1-2.15 {
+ execsql {
+ SELECT c1 COLLATE binary, c2 COLLATE hex
+ FROM collate1t1
+ ORDER BY 1 DESC, 2 DESC;
+ }
+} {7 0xA 5 0x11 5 0xA 11 0x101 11 0x11 {} {}}
+do_test collate1-2.16 {
+ execsql {
+ SELECT c1 COLLATE hex, c2 COLLATE binary
+ FROM collate1t1
+ ORDER BY 1 COLLATE binary ASC, 2 COLLATE hex ASC;
+ }
+} {{} {} 11 0x11 11 0x101 5 0xA 5 0x11 7 0xA}
+do_test collate1-2.99 {
execsql {
DROP TABLE collate1t1;
}
SELECT a as c1, b as c2 FROM collate1t1 ORDER BY c1 COLLATE binary;
}
} {{} {} 0x45 69 0x5 5 1 1}
+do_test collate1-3.5.1 {
+ execsql {
+ SELECT a COLLATE binary as c1, b as c2
+ FROM collate1t1 ORDER BY c1;
+ }
+} {{} {} 0x45 69 0x5 5 1 1}
do_test collate1-3.6 {
execsql {
DROP TABLE collate1t1;
SELECT c1||'' FROM collate1t1 ORDER BY 1;
}
} {{} 1 101 12}
+do_test collate1-4.4.1 {
+ execsql {
+ SELECT (c1||'') COLLATE numeric FROM collate1t1 ORDER BY 1;
+ }
+} {{} 1 12 101}
do_test collate1-4.5 {
execsql {
DROP TABLE collate1t1;
# This file implements regression tests for SQLite library. The
# focus of this script is page cache subsystem.
#
-# $Id: collate2.test,v 1.4 2005/01/21 03:12:16 danielk1977 Exp $
+# $Id: collate2.test,v 1.5 2007/02/01 23:02:46 drh Exp $
set testdir [file dirname $argv0]
source $testdir/tester.tcl
SELECT a FROM collate2t1 WHERE a > 'aa' ORDER BY 1;
}
} {ab bA bB ba bb}
+do_test collate2-1.1.1 {
+ execsql {
+ SELECT a FROM collate2t1 WHERE a COLLATE binary > 'aa' ORDER BY 1;
+ }
+} {ab bA bB ba bb}
+do_test collate2-1.1.2 {
+ execsql {
+ SELECT a FROM collate2t1 WHERE b COLLATE binary > 'aa' ORDER BY 1;
+ }
+} {ab bA bB ba bb}
+do_test collate2-1.1.3 {
+ execsql {
+ SELECT a FROM collate2t1 WHERE c COLLATE binary > 'aa' ORDER BY 1;
+ }
+} {ab bA bB ba bb}
do_test collate2-1.2 {
execsql {
SELECT b FROM collate2t1 WHERE b > 'aa' ORDER BY 1, oid;
}
} {ab aB Ab AB ba bA Ba BA bb bB Bb BB}
+do_test collate2-1.2.1 {
+ execsql {
+ SELECT b FROM collate2t1 WHERE a COLLATE nocase > 'aa'
+ ORDER BY 1, oid;
+ }
+} {ab aB Ab AB ba bA Ba BA bb bB Bb BB}
+do_test collate2-1.2.2 {
+ execsql {
+ SELECT b FROM collate2t1 WHERE b COLLATE nocase > 'aa'
+ ORDER BY 1, oid;
+ }
+} {ab aB Ab AB ba bA Ba BA bb bB Bb BB}
+do_test collate2-1.2.3 {
+ execsql {
+ SELECT b FROM collate2t1 WHERE c COLLATE nocase > 'aa'
+ ORDER BY 1, oid;
+ }
+} {ab aB Ab AB ba bA Ba BA bb bB Bb BB}
do_test collate2-1.3 {
execsql {
SELECT c FROM collate2t1 WHERE c > 'aa' ORDER BY 1;
}
} {ba Ab Bb ab bb}
+do_test collate2-1.3.1 {
+ execsql {
+ SELECT c FROM collate2t1 WHERE a COLLATE backwards > 'aa'
+ ORDER BY 1;
+ }
+} {ba Ab Bb ab bb}
+do_test collate2-1.3.2 {
+ execsql {
+ SELECT c FROM collate2t1 WHERE b COLLATE backwards > 'aa'
+ ORDER BY 1;
+ }
+} {ba Ab Bb ab bb}
+do_test collate2-1.3.3 {
+ execsql {
+ SELECT c FROM collate2t1 WHERE c COLLATE backwards > 'aa'
+ ORDER BY 1;
+ }
+} {ba Ab Bb ab bb}
do_test collate2-1.4 {
execsql {
SELECT a FROM collate2t1 WHERE a < 'aa' ORDER BY 1;
#
# Run this Tcl script to generate the lang-*.html files.
#
-set rcsid {$Id: lang.tcl,v 1.120 2007/01/29 17:58:28 drh Exp $}
+set rcsid {$Id: lang.tcl,v 1.121 2007/02/01 23:02:46 drh Exp $}
source common.tcl
if {[llength $argv]>0} {
<expr> [NOT] IN [<database-name> .] <table-name> |
[EXISTS] ( <select-statement> ) |
CASE [<expr>] LP WHEN <expr> THEN <expr> RPPLUS [ELSE <expr>] END |
-CAST ( <expr> AS <type> )
+CAST ( <expr> AS <type> ) |
+<expr> COLLATE <collation-name>
} {like-op} {
LIKE | GLOB | REGEXP | MATCH
}
OR</font>
</pre></blockquote>
-<p>Supported unary operators are these:</p>
+<p>Supported unary prefix operators are these:</p>
<blockquote><pre>
<font color="#2c2cf0"><big>- + ! ~ NOT</big></font>
</pre></blockquote>
+<p>The COLLATE operator can be thought of as a unary postfix
+operator. The COLLATE operator has the highest precedence.
+It always binds more tightly than any prefix unary operator or
+any binary operator.</p>
+
<p>The unary operator [Operator +] is a no-op. It can be applied
to strings, numbers, or blobs and it always gives as its result the
value of the operand.</p>