-C Modify\sthe\sorder\sof\sassert()\smacros\sin\svdbe.c\sas\sper\sthe\ssuggestion\sin\s#2768.\s(CVS\s4536)
-D 2007-11-12T08:09:35
+C Allow\scollation\ssequence\snames\sto\sbe\squoted.\sTicket\s#2744.\s(CVS\s4537)
+D 2007-11-12T09:50:26
F Makefile.in 30c7e3ba426ddb253b8ef037d1873425da6009a8
F Makefile.linux-gcc 65241babba6faf1152bf86574477baab19190499
F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028
F src/btree.c 008ce6b6bbcf00dfa3b1eca41bd3560fb287fd52
F src/btree.h d0736ebca4b6eafbdd823c46a8de574cea078211
F src/btreeInt.h 4330c19b8314545fdb209cc77e2a57f6a5290e9c
-F src/build.c d4ace66c2612d8973a17afdfe34b2a62f1a80178
+F src/build.c b58dd7c7a763a228196022ec0d51781ed6995cde
F src/callback.c 77b302b0d41468dcda78c70e706e5b84577f0fa0
F src/complete.c 4cf68fd75d60257524cbe74f87351b9848399131
F src/date.c 49c5a6d2de6c12000905b4d36868b07d3011bbf6
F src/delete.c 034b87768c4135a22038a86a205f9d2d5f68a143
F src/experimental.c 1b2d1a6cd62ecc39610e97670332ca073c50792b
-F src/expr.c 23fac3749024deeaaa6c25b6b5c521e8d140a2c5
+F src/expr.c 7977bb9680ebeeabfa3214d936778baaa26dcc0c
F src/func.c 73b4974e5ff03cc71345cc3a33b0022f7b99974a
F src/hash.c 45a7005aac044b6c86bd7e49c44bc15d30006d6c
F src/hash.h 031cd9f915aff27e12262cb9eb570ac1b8326b53
F src/os_win.h 41a946bea10f61c158ce8645e7646b29d44f122b
F src/pager.c c5ffa55c299663b579fbcb430752c1e79d302c5b
F src/pager.h d783e7f184afdc33adff37ba58d4e029bd8793b3
-F src/parse.y 2d2ce439dc6184621fb0b86f4fc5aca7f391a590
+F src/parse.y 9640f5b930b1d0bfd05d7428da6f762305567cbb
F src/pragma.c 363e548dafb52327face8d99757ab56a7b1c1b26
F src/prepare.c 663284f62a73a48b89f5f4e769e155fefba60384
F src/printf.c 96c8d55315a13fc53cb3754cb15046f3ff891ea2
F src/shell.c 0b9dd90afc34f28b8786638155d32f6248d0bf0a
F src/sqlite.h.in 3844177d389d58bd4a8be4ee81eefb01a084ed72
F src/sqlite3ext.h a93f59cdee3638dc0c9c086f80df743a4e68c3cb
-F src/sqliteInt.h 7fd5cfa357d7aefe22cd2bcdfabcca4e7d5ab5b2
+F src/sqliteInt.h 4e6fdeb5630ead97bcec60b941e7a72203c64b9e
F src/sqliteLimit.h 15ffe2116746c27ace2b428a26a4fcd6dba6fa65
F src/table.c 1aeb9eab57b4235db86fe15a35dec76fb445a9c4
F src/tclsqlite.c 29bb44a88e02ca4d2017113b7b1acc839582d57a
F test/collate6.test 8be65a182abaac8011a622131486dafb8076e907
F test/collate7.test e23677b1fd271505302643a98178952bb65b6f21
F test/collate8.test 7ed2461305ac959886a064dc1e3cf15e155a183f
+F test/collate9.test 0867eabc1222ab0bc308fc09a7fb30770334c3cd
F test/colmeta.test 6505c73ab58796afcb7c89ba9f429d573fbc6e53
F test/conflict.test 79b5214ef7a52f3e58a50ae5c60c37e7594d04e9
F test/corrupt.test 18c7a995b1af76a8c8600b996257f2c7b7bff083
F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b
F www/whentouse.tcl fc46eae081251c3c181bd79c5faef8195d7991a5
-P 3391f4139ccfe62cc27739a06567c422ddae9c69
-R 9bae5c8582864d5a42b9bca9b6ebf6ec
+P af5af5dc2608f369f0f4274ca06974b365424e72
+R 6609950e4e33ca146fe5280a3d429455
U danielk1977
-Z eedea99e32136cad94caf09bae94e010
+Z 68349a41f440456331fc2acbb07fcff1
-af5af5dc2608f369f0f4274ca06974b365424e72
\ No newline at end of file
+06749ac7afeea4adbdeb9315f3819d5224534c66
\ No newline at end of file
** COMMIT
** ROLLBACK
**
-** $Id: build.c,v 1.447 2007/10/15 07:08:44 danielk1977 Exp $
+** $Id: build.c,v 1.448 2007/11/12 09:50:26 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
** Set the collation function of the most recently parsed table column
** to the CollSeq given.
*/
-void sqlite3AddCollateType(Parse *pParse, const char *zType, int nType){
+void sqlite3AddCollateType(Parse *pParse, Token *pToken){
Table *p;
int i;
+ char *zColl; /* Dequoted name of collation sequence */
if( (p = pParse->pNewTable)==0 ) return;
i = p->nCol-1;
- if( sqlite3LocateCollSeq(pParse, zType, nType) ){
+ zColl = sqlite3NameFromToken(pParse->db, pToken);
+ if( !zColl ) return;
+
+ if( sqlite3LocateCollSeq(pParse, zColl, -1) ){
Index *pIdx;
- p->aCol[i].zColl = sqlite3DbStrNDup(pParse->db, zType, nType);
+ p->aCol[i].zColl = zColl;
/* If the column is declared as "<name> PRIMARY KEY COLLATE <type>",
** then an index may have been created on this column before the
pIdx->azColl[0] = p->aCol[i].zColl;
}
}
+ }else{
+ sqlite3_free(zColl);
}
}
reindexDatabases(pParse, 0);
return;
}else if( pName2==0 || pName2->z==0 ){
+ char *zColl;
assert( pName1->z );
- pColl = sqlite3FindCollSeq(db, ENC(db), (char*)pName1->z, pName1->n, 0);
+ zColl = sqlite3NameFromToken(pParse->db, pName1);
+ if( !zColl ) return;
+ pColl = sqlite3FindCollSeq(db, ENC(db), zColl, -1, 0);
if( pColl ){
- char *zColl = sqlite3DbStrNDup(db, (const char *)pName1->z, pName1->n);
if( zColl ){
reindexDatabases(pParse, zColl);
sqlite3_free(zColl);
}
return;
}
+ sqlite3_free(zColl);
}
iDb = sqlite3TwoPartName(pParse, pName1, pName2, &pObjName);
if( iDb<0 ) return;
** This file contains routines used for analyzing expressions and
** for generating VDBE code that evaluates expressions in SQLite.
**
-** $Id: expr.c,v 1.315 2007/10/23 18:55:49 drh Exp $
+** $Id: expr.c,v 1.316 2007/11/12 09:50:26 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
** collating sequences.
*/
Expr *sqlite3ExprSetColl(Parse *pParse, Expr *pExpr, Token *pName){
+ char *zColl = 0; /* Dequoted name of collation sequence */
CollSeq *pColl;
- if( pExpr==0 ) return 0;
- pColl = sqlite3LocateCollSeq(pParse, (char*)pName->z, pName->n);
- if( pColl ){
- pExpr->pColl = pColl;
- pExpr->flags |= EP_ExpCollate;
+ zColl = sqlite3NameFromToken(pParse->db, pName);
+ if( pExpr && zColl ){
+ pColl = sqlite3LocateCollSeq(pParse, zColl, -1);
+ if( pColl ){
+ pExpr->pColl = pColl;
+ pExpr->flags |= EP_ExpCollate;
+ }
}
+ sqlite3_free(zColl);
return pExpr;
}
** the parser. Lemon will also generate a header file containing
** numeric codes for all of the tokens.
**
-** @(#) $Id: parse.y,v 1.234 2007/08/21 10:44:16 drh Exp $
+** @(#) $Id: parse.y,v 1.235 2007/11/12 09:50:26 danielk1977 Exp $
*/
// All token codes are small integers with #defines that begin with "TK_"
ccons ::= REFERENCES nm(T) idxlist_opt(TA) refargs(R).
{sqlite3CreateForeignKey(pParse,0,&T,TA,R);}
ccons ::= defer_subclause(D). {sqlite3DeferForeignKey(pParse,D);}
-ccons ::= COLLATE id(C). {sqlite3AddCollateType(pParse, (char*)C.z, C.n);}
+ccons ::= COLLATE ids(C). {sqlite3AddCollateType(pParse, &C);}
// The optional AUTOINCREMENT keyword
%type autoinc {int}
Expr *pExpr = A = sqlite3PExpr(pParse, TK_VARIABLE, 0, 0, pToken);
sqlite3ExprAssignVarNumber(pParse, pExpr);
}
-expr(A) ::= expr(E) COLLATE id(C). {
+expr(A) ::= expr(E) COLLATE ids(C). {
A = sqlite3ExprSetColl(pParse, E, &C);
}
%ifndef SQLITE_OMIT_CAST
Expr *p = 0;
if( C.n>0 ){
p = sqlite3PExpr(pParse, TK_COLUMN, 0, 0, 0);
- if( p ) p->pColl = sqlite3LocateCollSeq(pParse, (char*)C.z, C.n);
+ sqlite3ExprSetColl(pParse, p, &C);
}
A = sqlite3ExprListAppend(pParse,X, p, &Y);
sqlite3ExprListCheckLength(pParse, A, SQLITE_MAX_COLUMN, "index");
Expr *p = 0;
if( C.n>0 ){
p = sqlite3PExpr(pParse, TK_COLUMN, 0, 0, 0);
- if( p ) p->pColl = sqlite3LocateCollSeq(pParse, (char*)C.z, C.n);
+ sqlite3ExprSetColl(pParse, p, &C);
}
A = sqlite3ExprListAppend(pParse,0, p, &Y);
sqlite3ExprListCheckLength(pParse, A, SQLITE_MAX_COLUMN, "index");
%type collate {Token}
collate(C) ::= . {C.z = 0; C.n = 0;}
-collate(C) ::= COLLATE id(X). {C = X;}
+collate(C) ::= COLLATE ids(X). {C = X;}
///////////////////////////// The DROP INDEX command /////////////////////////
*************************************************************************
** Internal interface definitions for SQLite.
**
-** @(#) $Id: sqliteInt.h,v 1.617 2007/10/23 15:59:18 drh Exp $
+** @(#) $Id: sqliteInt.h,v 1.618 2007/11/12 09:50:26 danielk1977 Exp $
*/
#ifndef _SQLITEINT_H_
#define _SQLITEINT_H_
void sqlite3AddCheckConstraint(Parse*, Expr*);
void sqlite3AddColumnType(Parse*,Token*);
void sqlite3AddDefaultValue(Parse*,Expr*);
-void sqlite3AddCollateType(Parse*, const char*, int);
+void sqlite3AddCollateType(Parse*, Token*);
void sqlite3EndTable(Parse*,Token*,Token*,Select*);
void sqlite3CreateView(Parse*,Token*,Token*,Token*,Select*,int,int);
--- /dev/null
+#
+# 2007 November 12
+#
+# 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.
+#
+#***********************************************************************
+# This file implements regression tests for SQLite library. The
+# focus of this script is making sure that the names of collation
+# sequences may be quoted using double quotes in SQL statements.
+#
+# $Id: collate9.test,v 1.1 2007/11/12 09:50:26 danielk1977 Exp $
+
+set testdir [file dirname $argv0]
+source $testdir/tester.tcl
+
+proc reverse_sort {lhs rhs} {
+ return [string compare $rhs $lhs]
+}
+db collate "reverse sort" reverse_sort
+
+# This procedure executes the SQL. Then it checks to see if the OP_Sort
+# opcode was executed. If an OP_Sort did occur, then "sort" is appended
+# to the result. If no OP_Sort happened, then "nosort" is appended.
+#
+# This procedure is used to check to make sure sorting is or is not
+# occurring as expected.
+#
+proc cksort {sql} {
+ set ::sqlite_sort_count 0
+ set data [execsql $sql]
+ if {$::sqlite_sort_count} {set x sort} {set x nosort}
+ lappend data $x
+ return $data
+}
+
+# Test plan:
+#
+# collate9-1.* - Test collation sequences attached to table columns
+# collate9-2.* - Test collation sequences attached to expressions
+# collate9-3.* - Test collation sequences attached to an index
+# collate9-4.* - Test collation sequences as an argument to REINDEX
+#
+
+do_test collate9-1.1 {
+ execsql {
+ CREATE TABLE xy(x COLLATE "reverse sort", y COLLATE binary);
+ INSERT INTO xy VALUES('one', 'one');
+ INSERT INTO xy VALUES('two', 'two');
+ INSERT INTO xy VALUES('three', 'three');
+ }
+} {}
+do_test collate9-1.2 {
+ execsql {
+ SELECT x FROM xy ORDER BY x
+ }
+} {two three one}
+do_test collate9-1.3 {
+ execsql {
+ SELECT y FROM xy ORDER BY y
+ }
+} {one three two}
+do_test collate9-1.4 {
+ cksort {
+ SELECT x FROM xy ORDER BY x
+ }
+} {two three one sort}
+do_test collate9-1.5 {
+ execsql {
+ CREATE INDEX xy_i ON xy(x)
+ }
+} {}
+do_test collate9-1.6 {
+ cksort {
+ SELECT x FROM xy ORDER BY x
+ }
+} {two three one nosort}
+
+do_test collate9-2.1 {
+ execsql {
+ SELECT x, x < 'seven' FROM xy ORDER BY x
+ }
+} {two 1 three 1 one 0}
+do_test collate9-2.2 {
+ execsql {
+ SELECT y, y < 'seven' FROM xy ORDER BY x
+ }
+} {two 0 three 0 one 1}
+do_test collate9-2.3 {
+ execsql {
+ SELECT y, y COLLATE "reverse sort" < 'seven' FROM xy ORDER BY x
+ }
+} {two 1 three 1 one 0}
+do_test collate9-2.4 {
+ execsql {
+ SELECT y FROM xy ORDER BY y
+ }
+} {one three two}
+do_test collate9-2.5 {
+ execsql {
+ SELECT y FROM xy ORDER BY y COLLATE "reverse sort"
+ }
+} {two three one}
+
+do_test collate9-3.1 {
+ execsql {
+ CREATE INDEX xy_i2 ON xy(y COLLATE "reverse sort");
+ }
+} {}
+do_test collate9-3.2 {
+ cksort {
+ SELECT y FROM xy ORDER BY y
+ }
+} {one three two sort}
+do_test collate9-3.3 {
+ cksort {
+ SELECT y FROM xy ORDER BY y COLLATE "reverse sort"
+ }
+} {two three one nosort}
+
+ifcapable reindex {
+ do_test collate9-4.1 {
+ execsql {
+ REINDEX "reverse sort"
+ }
+ } {}
+
+ # Modify the "reverse sort" collation so that it now sorts in the same
+ # order as binary.
+ proc reverse_sort {lhs rhs} {
+ return [string compare $lhs $rhs]
+ }
+
+ # The integrity check should now fail because the indexes created using
+ # "reverse sort" are no longer in sync with the collation sequence
+ # implementation.
+ do_test collate9-4.2 {
+ expr {"ok" eq [execsql { PRAGMA integrity_check }]}
+ } {0}
+
+ do_test collate9-4.3 {
+ execsql {
+ REINDEX "reverse sort"
+ }
+ } {}
+
+ # Integrity check should now pass.
+ do_test collate9-4.4 {
+ expr {"ok" eq [execsql { PRAGMA integrity_check }]}
+ } {1}
+
+ do_test collate9-4.5 {
+ cksort {
+ SELECT x FROM xy ORDER BY x COLLATE "reverse sort"
+ }
+ } {one three two nosort}
+}
+
+finish_test
+