1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-11-09 14:21:03 +03:00

First cut at adding the COLLATE operator. Regression tests pass (or at least

the quick set does) and a few new tests have been added.  But many more
tests are needed.  Rules for combining collations need to be worked out. (CVS 3624)

FossilOrigin-Name: 85cca7cd252d46ba71d302a89bc67c56146ec552
This commit is contained in:
drh
2007-02-01 23:02:45 +00:00
parent 3e701a187e
commit 8b4c40d8ac
9 changed files with 200 additions and 44 deletions

View File

@@ -1,5 +1,5 @@
C Fix\sa\sbug\sin\sthe\scopy\smethod\sof\sthe\sTCL\sinterface.\s\sTicket\s#2201.\s(CVS\s3623) 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-01T01:53:44 D 2007-02-01T23:02:45
F Makefile.in 7fa74bf4359aa899da5586e394d17735f221315f F Makefile.in 7fa74bf4359aa899da5586e394d17735f221315f
F Makefile.linux-gcc 2d8574d1ba75f129aba2019f0b959db380a90935 F Makefile.linux-gcc 2d8574d1ba75f129aba2019f0b959db380a90935
F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028 F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028
@@ -65,7 +65,7 @@ F src/complete.c 7d1a44be8f37de125fcafd3d3a018690b3799675
F src/date.c 393c73fc027597e008dcd81454544659e978b05c F src/date.c 393c73fc027597e008dcd81454544659e978b05c
F src/delete.c 804384761144fe1a5035b99f4bd7d706976831bd F src/delete.c 804384761144fe1a5035b99f4bd7d706976831bd
F src/experimental.c 1b2d1a6cd62ecc39610e97670332ca073c50792b F src/experimental.c 1b2d1a6cd62ecc39610e97670332ca073c50792b
F src/expr.c ec0b5d9dd6f69425302c255d88475511f5d8b5c9 F src/expr.c 4ece4d575fa8686535877bbfb2e9d74093a4aa94
F src/func.c b7e1e220a6795ecae7649815145ea5f8644dfa5f F src/func.c b7e1e220a6795ecae7649815145ea5f8644dfa5f
F src/hash.c 449f3d6620193aa557f5d86cbc5cc6b87702b185 F src/hash.c 449f3d6620193aa557f5d86cbc5cc6b87702b185
F src/hash.h 1b3f7e2609141fd571f62199fc38687d262e9564 F src/hash.h 1b3f7e2609141fd571f62199fc38687d262e9564
@@ -87,17 +87,17 @@ F src/os_win.c 8736cf3a49fd651a6538857480f302807d57814c
F src/os_win.h 41a946bea10f61c158ce8645e7646b29d44f122b F src/os_win.h 41a946bea10f61c158ce8645e7646b29d44f122b
F src/pager.c d6ad66eb119602cb2e6a097f8f635372ba677d23 F src/pager.c d6ad66eb119602cb2e6a097f8f635372ba677d23
F src/pager.h 2e6d42f4ae004ae748a037b8468112b851c447a7 F src/pager.h 2e6d42f4ae004ae748a037b8468112b851c447a7
F src/parse.y 31ea08df1305100abd5bcee61b4a01c4e43cbd35 F src/parse.y ebf4253e3710452953cd1ba8171beb86f47f7f57
F src/pragma.c 5091300911670ddaa552bfa12c45cbca1bb7e7d6 F src/pragma.c 5091300911670ddaa552bfa12c45cbca1bb7e7d6
F src/prepare.c 484389c6811415b8f23d259ac9c029613e1c72c3 F src/prepare.c 484389c6811415b8f23d259ac9c029613e1c72c3
F src/printf.c aade23a789d7cc88b397ec0d33a0a01a33a7a9c1 F src/printf.c aade23a789d7cc88b397ec0d33a0a01a33a7a9c1
F src/random.c 6119474a6f6917f708c1dee25b9a8e519a620e88 F src/random.c 6119474a6f6917f708c1dee25b9a8e519a620e88
F src/select.c 628f49827d5a94ed9b6246efb8dc9f5c24e413f1 F src/select.c 63b2163f35fd2570a02dab5759979644c4405f1c
F src/server.c 087b92a39d883e3fa113cae259d64e4c7438bc96 F src/server.c 087b92a39d883e3fa113cae259d64e4c7438bc96
F src/shell.c d13ca007cd18192c07a668aeddcdd6a9fe639be9 F src/shell.c d13ca007cd18192c07a668aeddcdd6a9fe639be9
F src/sqlite.h.in 6b7383baf76070214f6381f603328ca9b22a7fae F src/sqlite.h.in 6b7383baf76070214f6381f603328ca9b22a7fae
F src/sqlite3ext.h 011c75fd6459a61454514af07c7a4f1f5c767f27 F src/sqlite3ext.h 011c75fd6459a61454514af07c7a4f1f5c767f27
F src/sqliteInt.h f6053066ba92ed66507661fe6a78c31ca856b6f8 F src/sqliteInt.h 650d05a8c530ee3c28ad8b19684d70f889458e60
F src/table.c 6d0da66dde26ee75614ed8f584a1996467088d06 F src/table.c 6d0da66dde26ee75614ed8f584a1996467088d06
F src/tclsqlite.c cd2b3b86ab07c0e0779f6c6e71e72c6c7dc1e704 F src/tclsqlite.c cd2b3b86ab07c0e0779f6c6e71e72c6c7dc1e704
F src/test1.c 053f5224697efaefff1f4c647fd90fdea9346cc5 F src/test1.c 053f5224697efaefff1f4c647fd90fdea9346cc5
@@ -172,8 +172,8 @@ F test/capi3b.test 5f0bc94b104e11086b1103b20277e1910f59c7f4
F test/capi3c.test 5961df13666c994890ffd44f0143cf92897d18dc F test/capi3c.test 5961df13666c994890ffd44f0143cf92897d18dc
F test/cast.test f88e7b6946e9a467cf4bb142d92bb65a83747fc2 F test/cast.test f88e7b6946e9a467cf4bb142d92bb65a83747fc2
F test/check.test e5ea0c1a06c10e81e3434ca029e2c4a562f2b673 F test/check.test e5ea0c1a06c10e81e3434ca029e2c4a562f2b673
F test/collate1.test add9454cef160677bb8b34148b8f277ce7f9f1c4 F test/collate1.test e3eaa48c21e150814be1a7b852d2a8af24458d04
F test/collate2.test 224a632ba04907c049804b08162efd234aa7871f F test/collate2.test 701d9651c5707024fd86a20649af9ea55e2c0eb8
F test/collate3.test 947a77f5b8227e037a7094d0e338a5504f155cc4 F test/collate3.test 947a77f5b8227e037a7094d0e338a5504f155cc4
F test/collate4.test daf498e294dcd596b961d425c3f2dda117e4717e F test/collate4.test daf498e294dcd596b961d425c3f2dda117e4717e
F test/collate5.test 8fb4e7e0241839356bd8710f437c32efb47bfff8 F test/collate5.test 8fb4e7e0241839356bd8710f437c32efb47bfff8
@@ -406,7 +406,7 @@ F www/fullscanb.gif f7c94cb227f060511f8909e10f570157263e9a25
F www/index-ex1-x-b.gif f9b1d85c3fa2435cf38b15970c7e3aa1edae23a3 F www/index-ex1-x-b.gif f9b1d85c3fa2435cf38b15970c7e3aa1edae23a3
F www/index.tcl 7f67d421e4c1f48083c178bee460a27220f4fcc1 F www/index.tcl 7f67d421e4c1f48083c178bee460a27220f4fcc1
F www/indirect1b1.gif adfca361d2df59e34f9c5cac52a670c2bfc303a1 F www/indirect1b1.gif adfca361d2df59e34f9c5cac52a670c2bfc303a1
F www/lang.tcl aa6d599679cbd5612d7fd7b1ae733ac1221c2a76 F www/lang.tcl 65d0aa787aa55619dd7a8497306ea539f1201bf3
F www/lockingv3.tcl f59b19d6c8920a931f096699d6faaf61c05db55f F www/lockingv3.tcl f59b19d6c8920a931f096699d6faaf61c05db55f
F www/mingw.tcl d96b451568c5d28545fefe0c80bee3431c73f69c F www/mingw.tcl d96b451568c5d28545fefe0c80bee3431c73f69c
F www/nulls.tcl ec35193f92485b87b90a994a01d0171b58823fcf F www/nulls.tcl ec35193f92485b87b90a994a01d0171b58823fcf
@@ -428,7 +428,7 @@ F www/tclsqlite.tcl bb0d1357328a42b1993d78573e587c6dcbc964b9
F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0 F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b
F www/whentouse.tcl 97e2b5cd296f7d8057e11f44427dea8a4c2db513 F www/whentouse.tcl 97e2b5cd296f7d8057e11f44427dea8a4c2db513
P 505dce8f4e8717341e04f49f6f382719c3c704f1 P 936263966ea70792e8abb712730f78cafa1fdbad
R 4143445bb3574091269b3a2a42f03d6f R 2d8d95cad338f4e2489cbc3239cd084f
U drh U drh
Z 96cc038466dba8dfd6f53c6f8d4f749d Z f3d08231d49c025fe236a57faf179faf

View File

@@ -1 +1 @@
936263966ea70792e8abb712730f78cafa1fdbad 85cca7cd252d46ba71d302a89bc67c56146ec552

View File

@@ -12,7 +12,7 @@
** This file contains routines used for analyzing expressions and ** This file contains routines used for analyzing expressions and
** for generating VDBE code that evaluates expressions in SQLite. ** 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 "sqliteInt.h"
#include <ctype.h> #include <ctype.h>
@@ -49,6 +49,21 @@ char sqlite3ExprAffinity(Expr *pExpr){
return pExpr->affinity; 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 ** Return the default collation sequence for the expression pExpr. If
** there is no default collation type, return 0. ** there is no default collation type, return 0.
@@ -890,7 +905,9 @@ static int lookupName(
/* Substitute the rowid (column -1) for the INTEGER PRIMARY KEY */ /* Substitute the rowid (column -1) for the INTEGER PRIMARY KEY */
pExpr->iColumn = j==pTab->iPKey ? -1 : j; pExpr->iColumn = j==pTab->iPKey ? -1 : j;
pExpr->affinity = pTab->aCol[j].affinity; pExpr->affinity = pTab->aCol[j].affinity;
if( (pExpr->flags & EP_ExpCollate)==0 ){
pExpr->pColl = sqlite3FindCollSeq(db, ENC(db), zColl,-1, 0); pExpr->pColl = sqlite3FindCollSeq(db, ENC(db), zColl,-1, 0);
}
if( i<pSrcList->nSrc-1 ){ if( i<pSrcList->nSrc-1 ){
if( pItem[1].jointype & JT_NATURAL ){ if( pItem[1].jointype & JT_NATURAL ){
/* If this match occurred in the left table of a natural join, /* If this match occurred in the left table of a natural join,
@@ -946,7 +963,9 @@ static int lookupName(
cnt++; cnt++;
pExpr->iColumn = iCol==pTab->iPKey ? -1 : iCol; pExpr->iColumn = iCol==pTab->iPKey ? -1 : iCol;
pExpr->affinity = pTab->aCol[iCol].affinity; pExpr->affinity = pTab->aCol[iCol].affinity;
if( (pExpr->flags & EP_ExpCollate)==0 ){
pExpr->pColl = sqlite3FindCollSeq(db, ENC(db), zColl,-1, 0); pExpr->pColl = sqlite3FindCollSeq(db, ENC(db), zColl,-1, 0);
}
pExpr->pTab = pTab; pExpr->pTab = pTab;
break; break;
} }

View File

@@ -14,7 +14,7 @@
** the parser. Lemon will also generate a header file containing ** the parser. Lemon will also generate a header file containing
** numeric codes for all of the tokens. ** 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_" // All token codes are small integers with #defines that begin with "TK_"
@@ -204,7 +204,7 @@ id(A) ::= ID(X). {A = X;}
%left BITAND BITOR LSHIFT RSHIFT. %left BITAND BITOR LSHIFT RSHIFT.
%left PLUS MINUS. %left PLUS MINUS.
%left STAR SLASH REM. %left STAR SLASH REM.
%left CONCAT. %left CONCAT COLLATE.
%right UMINUS UPLUS BITNOT. %right UMINUS UPLUS BITNOT.
// And "ids" is an identifer-or-string. // And "ids" is an identifer-or-string.
@@ -515,12 +515,12 @@ using_opt(U) ::= . {U = 0;}
orderby_opt(A) ::= . {A = 0;} orderby_opt(A) ::= . {A = 0;}
orderby_opt(A) ::= ORDER BY sortlist(X). {A = X;} orderby_opt(A) ::= ORDER BY sortlist(X). {A = X;}
sortlist(A) ::= sortlist(X) COMMA sortitem(Y) collate(C) sortorder(Z). { sortlist(A) ::= sortlist(X) COMMA sortitem(Y) sortorder(Z). {
A = sqlite3ExprListAppend(X,Y,C.n>0?&C:0); A = sqlite3ExprListAppend(X,Y,0);
if( A ) A->a[A->nExpr-1].sortOrder = Z; if( A ) A->a[A->nExpr-1].sortOrder = Z;
} }
sortlist(A) ::= sortitem(Y) collate(C) sortorder(Z). { sortlist(A) ::= sortitem(Y) sortorder(Z). {
A = sqlite3ExprListAppend(0,Y,C.n>0?&C:0); A = sqlite3ExprListAppend(0,Y,0);
if( A && A->a ) A->a[0].sortOrder = Z; if( A && A->a ) A->a[0].sortOrder = Z;
} }
sortitem(A) ::= expr(X). {A = X;} sortitem(A) ::= expr(X). {A = X;}
@@ -642,6 +642,9 @@ expr(A) ::= VARIABLE(X). {
Expr *pExpr = A = sqlite3Expr(TK_VARIABLE, 0, 0, pToken); Expr *pExpr = A = sqlite3Expr(TK_VARIABLE, 0, 0, pToken);
sqlite3ExprAssignVarNumber(pParse, pExpr); sqlite3ExprAssignVarNumber(pParse, pExpr);
} }
expr(A) ::= expr(E) COLLATE id(C). {
A = sqlite3ExprSetColl(pParse, E, &C);
}
%ifndef SQLITE_OMIT_CAST %ifndef SQLITE_OMIT_CAST
expr(A) ::= CAST(X) LP expr(E) AS typetoken(T) RP(Y). { expr(A) ::= CAST(X) LP expr(E) AS typetoken(T) RP(Y). {
A = sqlite3Expr(TK_CAST, E, 0, &T); A = sqlite3Expr(TK_CAST, E, 0, &T);

View File

@@ -12,7 +12,7 @@
** This file contains C code routines that are called by the parser ** This file contains C code routines that are called by the parser
** to handle SELECT statements in SQLite. ** 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" #include "sqliteInt.h"
@@ -1952,10 +1952,9 @@ static int multiSelect(
apColl = pKeyInfo->aColl; apColl = pKeyInfo->aColl;
for(i=0; i<nOrderByExpr; i++, pOTerm++, apColl++, pSortOrder++){ for(i=0; i<nOrderByExpr; i++, pOTerm++, apColl++, pSortOrder++){
Expr *pExpr = pOTerm->pExpr; Expr *pExpr = pOTerm->pExpr;
char *zName = pOTerm->zName; if( (pExpr->flags & EP_ExpCollate) ){
assert( pExpr->op==TK_COLUMN && pExpr->iColumn<nCol ); assert( pExpr->pColl!=0 );
if( zName ){ *apColl = pExpr->pColl;
*apColl = sqlite3LocateCollSeq(pParse, zName, -1);
}else{ }else{
*apColl = aCopy[pExpr->iColumn]; *apColl = aCopy[pExpr->iColumn];
} }
@@ -2478,8 +2477,14 @@ static int processOrderGroupBy(
Expr *pE = pOrderBy->a[i].pExpr; Expr *pE = pOrderBy->a[i].pExpr;
if( sqlite3ExprIsInteger(pE, &iCol) ){ if( sqlite3ExprIsInteger(pE, &iCol) ){
if( iCol>0 && iCol<=pEList->nExpr ){ if( iCol>0 && iCol<=pEList->nExpr ){
CollSeq *pColl = pE->pColl;
int flags = pE->flags & EP_ExpCollate;
sqlite3ExprDelete(pE); sqlite3ExprDelete(pE);
pE = pOrderBy->a[i].pExpr = sqlite3ExprDup(pEList->a[iCol-1].pExpr); pE = pOrderBy->a[i].pExpr = sqlite3ExprDup(pEList->a[iCol-1].pExpr);
if( pColl && flags ){
pE->pColl = pColl;
pE->flags |= flags;
}
}else{ }else{
sqlite3ErrorMsg(pParse, sqlite3ErrorMsg(pParse,
"%s BY column number %d out of range - should be " "%s BY column number %d out of range - should be "
@@ -2914,23 +2919,15 @@ int sqlite3Select(
} }
#endif #endif
/* If there is an ORDER BY clause, resolve any collation sequences /* If there is an ORDER BY clause, then this sorting
** names that have been explicitly specified and create a sorting index. ** index might end up being unused if the data can be
**
** 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 ** extracted in pre-sorted order. If that is the case, then the
** OP_OpenEphemeral instruction will be changed to an OP_Noop once ** OP_OpenEphemeral instruction will be changed to an OP_Noop once
** we figure out that the sorting index is not needed. The addrSortIndex ** we figure out that the sorting index is not needed. The addrSortIndex
** variable is used to facilitate that change. ** variable is used to facilitate that change.
*/ */
if( pOrderBy ){ if( pOrderBy ){
struct ExprList_item *pTerm;
KeyInfo *pKeyInfo; 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 ){ if( pParse->nErr ){
goto select_end; goto select_end;
} }

View File

@@ -11,7 +11,7 @@
************************************************************************* *************************************************************************
** Internal interface definitions for SQLite. ** 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_ #ifndef _SQLITEINT_H_
#define _SQLITEINT_H_ #define _SQLITEINT_H_
@@ -1021,6 +1021,7 @@ struct Expr {
#define EP_VarSelect 0x20 /* pSelect is correlated, not constant */ #define EP_VarSelect 0x20 /* pSelect is correlated, not constant */
#define EP_Dequoted 0x40 /* True if the string has been dequoted */ #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_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 ** These macros can be used to test, set, or clear bits in the
@@ -1777,6 +1778,7 @@ int sqlite3ReadSchema(Parse *pParse);
CollSeq *sqlite3FindCollSeq(sqlite3*,u8 enc, const char *,int,int); CollSeq *sqlite3FindCollSeq(sqlite3*,u8 enc, const char *,int,int);
CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char *zName, int nName); CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char *zName, int nName);
CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr); CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr);
Expr *sqlite3ExprSetColl(Parse *pParse, Expr *, Token *);
int sqlite3CheckCollSeq(Parse *, CollSeq *); int sqlite3CheckCollSeq(Parse *, CollSeq *);
int sqlite3CheckIndexCollSeq(Parse *, Index *); int sqlite3CheckIndexCollSeq(Parse *, Index *);
int sqlite3CheckObjectName(Parse *, const char *); int sqlite3CheckObjectName(Parse *, const char *);

View File

@@ -12,7 +12,7 @@
# This file implements regression tests for SQLite library. The # This file implements regression tests for SQLite library. The
# focus of this script is page cache subsystem. # 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] set testdir [file dirname $argv0]
source $testdir/tester.tcl source $testdir/tester.tcl
@@ -90,6 +90,21 @@ do_test collate1-1.4 {
} }
} {{} 0x2D 0x119} } {{} 0x2D 0x119}
do_test collate1-1.5 { 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 { execsql {
DROP TABLE collate1t1; DROP TABLE collate1t1;
} }
@@ -133,7 +148,59 @@ do_test collate1-2.6 {
ORDER BY 1 COLLATE binary ASC, 2 COLLATE hex ASC; ORDER BY 1 COLLATE binary ASC, 2 COLLATE hex ASC;
} }
} {{} {} 11 0x11 11 0x101 5 0xA 5 0x11 7 0xA} } {{} {} 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 { execsql {
DROP TABLE collate1t1; DROP TABLE collate1t1;
} }
@@ -180,6 +247,12 @@ do_test collate1-3.5 {
SELECT a as c1, b as c2 FROM collate1t1 ORDER BY c1 COLLATE binary; SELECT a as c1, b as c2 FROM collate1t1 ORDER BY c1 COLLATE binary;
} }
} {{} {} 0x45 69 0x5 5 1 1} } {{} {} 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 { do_test collate1-3.6 {
execsql { execsql {
DROP TABLE collate1t1; DROP TABLE collate1t1;
@@ -220,6 +293,11 @@ do_test collate1-4.4 {
SELECT c1||'' FROM collate1t1 ORDER BY 1; SELECT c1||'' FROM collate1t1 ORDER BY 1;
} }
} {{} 1 101 12} } {{} 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 { do_test collate1-4.5 {
execsql { execsql {
DROP TABLE collate1t1; DROP TABLE collate1t1;

View File

@@ -12,7 +12,7 @@
# This file implements regression tests for SQLite library. The # This file implements regression tests for SQLite library. The
# focus of this script is page cache subsystem. # 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] set testdir [file dirname $argv0]
source $testdir/tester.tcl source $testdir/tester.tcl
@@ -98,16 +98,67 @@ do_test collate2-1.1 {
SELECT a FROM collate2t1 WHERE a > 'aa' ORDER BY 1; SELECT a FROM collate2t1 WHERE a > 'aa' ORDER BY 1;
} }
} {ab bA bB ba bb} } {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 { do_test collate2-1.2 {
execsql { execsql {
SELECT b FROM collate2t1 WHERE b > 'aa' ORDER BY 1, oid; SELECT b FROM collate2t1 WHERE b > 'aa' ORDER BY 1, oid;
} }
} {ab aB Ab AB ba bA Ba BA bb bB Bb BB} } {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 { do_test collate2-1.3 {
execsql { execsql {
SELECT c FROM collate2t1 WHERE c > 'aa' ORDER BY 1; SELECT c FROM collate2t1 WHERE c > 'aa' ORDER BY 1;
} }
} {ba Ab Bb ab bb} } {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 { do_test collate2-1.4 {
execsql { execsql {
SELECT a FROM collate2t1 WHERE a < 'aa' ORDER BY 1; SELECT a FROM collate2t1 WHERE a < 'aa' ORDER BY 1;

View File

@@ -1,7 +1,7 @@
# #
# Run this Tcl script to generate the lang-*.html files. # 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 source common.tcl
if {[llength $argv]>0} { if {[llength $argv]>0} {
@@ -1007,7 +1007,8 @@ Syntax {expr} {
<expr> [NOT] IN [<database-name> .] <table-name> | <expr> [NOT] IN [<database-name> .] <table-name> |
[EXISTS] ( <select-statement> ) | [EXISTS] ( <select-statement> ) |
CASE [<expr>] LP WHEN <expr> THEN <expr> RPPLUS [ELSE <expr>] END | 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-op} {
LIKE | GLOB | REGEXP | MATCH LIKE | GLOB | REGEXP | MATCH
} }
@@ -1032,12 +1033,17 @@ AND
OR</font> OR</font>
</pre></blockquote> </pre></blockquote>
<p>Supported unary operators are these:</p> <p>Supported unary prefix operators are these:</p>
<blockquote><pre> <blockquote><pre>
<font color="#2c2cf0"><big>- + ! ~ NOT</big></font> <font color="#2c2cf0"><big>- + ! ~ NOT</big></font>
</pre></blockquote> </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 <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 to strings, numbers, or blobs and it always gives as its result the
value of the operand.</p> value of the operand.</p>