|
|
c0e712 |
# Fix a problem causing collation sequence names to be dequoted multiple times
|
|
|
c0e712 |
# under some circumstances.
|
|
|
c0e712 |
# Upstream original patch: https://www.sqlite.org/src/info/eddc05e7bb31fae7
|
|
|
c0e712 |
|
|
|
c0e712 |
diff -up sqlite-src-3071700/src/expr.c.old sqlite-src-3071700/src/expr.c
|
|
|
c0e712 |
--- sqlite-src-3071700/src/expr.c.old 2015-07-23 10:26:11.220420294 +0200
|
|
|
c0e712 |
+++ sqlite-src-3071700/src/expr.c 2015-07-23 10:26:47.468601833 +0200
|
|
|
c0e712 |
@@ -65,9 +65,9 @@ char sqlite3ExprAffinity(Expr *pExpr){
|
|
|
c0e712 |
** If a memory allocation error occurs, that fact is recorded in pParse->db
|
|
|
c0e712 |
** and the pExpr parameter is returned unchanged.
|
|
|
c0e712 |
*/
|
|
|
c0e712 |
-Expr *sqlite3ExprAddCollateToken(Parse *pParse, Expr *pExpr, Token *pCollName){
|
|
|
c0e712 |
+Expr *sqlite3ExprAddCollateToken(Parse *pParse, Expr *pExpr, Token *pCollName, int dequote){
|
|
|
c0e712 |
if( pCollName->n>0 ){
|
|
|
c0e712 |
- Expr *pNew = sqlite3ExprAlloc(pParse->db, TK_COLLATE, pCollName, 1);
|
|
|
c0e712 |
+ Expr *pNew = sqlite3ExprAlloc(pParse->db, TK_COLLATE, pCollName, dequote);
|
|
|
c0e712 |
if( pNew ){
|
|
|
c0e712 |
pNew->pLeft = pExpr;
|
|
|
c0e712 |
pNew->flags |= EP_Collate;
|
|
|
c0e712 |
@@ -81,7 +81,7 @@ Expr *sqlite3ExprAddCollateString(Parse
|
|
|
c0e712 |
assert( zC!=0 );
|
|
|
c0e712 |
s.z = zC;
|
|
|
c0e712 |
s.n = sqlite3Strlen30(s.z);
|
|
|
c0e712 |
- return sqlite3ExprAddCollateToken(pParse, pExpr, &s);
|
|
|
c0e712 |
+ return sqlite3ExprAddCollateToken(pParse, pExpr, &s, 0);
|
|
|
c0e712 |
}
|
|
|
c0e712 |
|
|
|
c0e712 |
/*
|
|
|
c0e712 |
diff -up sqlite-src-3071700/src/parse.y.old sqlite-src-3071700/src/parse.y
|
|
|
c0e712 |
--- sqlite-src-3071700/src/parse.y.old 2015-07-23 10:27:00.595682612 +0200
|
|
|
c0e712 |
+++ sqlite-src-3071700/src/parse.y 2015-07-23 10:27:47.850973405 +0200
|
|
|
c0e712 |
@@ -818,7 +818,7 @@ expr(A) ::= VARIABLE(X). {
|
|
|
c0e712 |
spanSet(&A, &X, &X);
|
|
|
c0e712 |
}
|
|
|
c0e712 |
expr(A) ::= expr(E) COLLATE ids(C). {
|
|
|
c0e712 |
- A.pExpr = sqlite3ExprAddCollateToken(pParse, E.pExpr, &C);
|
|
|
c0e712 |
+ A.pExpr = sqlite3ExprAddCollateToken(pParse, E.pExpr, &C, 1);
|
|
|
c0e712 |
A.zStart = E.zStart;
|
|
|
c0e712 |
A.zEnd = &C.z[C.n];
|
|
|
c0e712 |
}
|
|
|
c0e712 |
@@ -1143,14 +1143,14 @@ uniqueflag(A) ::= . {A = OE_None;
|
|
|
c0e712 |
idxlist_opt(A) ::= . {A = 0;}
|
|
|
c0e712 |
idxlist_opt(A) ::= LP idxlist(X) RP. {A = X;}
|
|
|
c0e712 |
idxlist(A) ::= idxlist(X) COMMA nm(Y) collate(C) sortorder(Z). {
|
|
|
c0e712 |
- Expr *p = sqlite3ExprAddCollateToken(pParse, 0, &C);
|
|
|
c0e712 |
+ Expr *p = sqlite3ExprAddCollateToken(pParse, 0, &C, 1);
|
|
|
c0e712 |
A = sqlite3ExprListAppend(pParse,X, p);
|
|
|
c0e712 |
sqlite3ExprListSetName(pParse,A,&Y,1);
|
|
|
c0e712 |
sqlite3ExprListCheckLength(pParse, A, "index");
|
|
|
c0e712 |
if( A ) A->a[A->nExpr-1].sortOrder = (u8)Z;
|
|
|
c0e712 |
}
|
|
|
c0e712 |
idxlist(A) ::= nm(Y) collate(C) sortorder(Z). {
|
|
|
c0e712 |
- Expr *p = sqlite3ExprAddCollateToken(pParse, 0, &C);
|
|
|
c0e712 |
+ Expr *p = sqlite3ExprAddCollateToken(pParse, 0, &C, 1);
|
|
|
c0e712 |
A = sqlite3ExprListAppend(pParse,0, p);
|
|
|
c0e712 |
sqlite3ExprListSetName(pParse, A, &Y, 1);
|
|
|
c0e712 |
sqlite3ExprListCheckLength(pParse, A, "index");
|
|
|
c0e712 |
diff -up sqlite-src-3071700/src/sqliteInt.h.old sqlite-src-3071700/src/sqliteInt.h
|
|
|
c0e712 |
--- sqlite-src-3071700/src/sqliteInt.h.old 2015-07-23 10:34:54.516598956 +0200
|
|
|
c0e712 |
+++ sqlite-src-3071700/src/sqliteInt.h 2015-07-23 10:35:12.908712134 +0200
|
|
|
c0e712 |
@@ -3103,7 +3103,7 @@ int sqlite3ReadSchema(Parse *pParse);
|
|
|
c0e712 |
CollSeq *sqlite3FindCollSeq(sqlite3*,u8 enc, const char*,int);
|
|
|
c0e712 |
CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char*zName);
|
|
|
c0e712 |
CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr);
|
|
|
c0e712 |
-Expr *sqlite3ExprAddCollateToken(Parse *pParse, Expr*, Token*);
|
|
|
c0e712 |
+Expr *sqlite3ExprAddCollateToken(Parse *pParse, Expr*, Token*, int);
|
|
|
c0e712 |
Expr *sqlite3ExprAddCollateString(Parse*,Expr*,const char*);
|
|
|
c0e712 |
Expr *sqlite3ExprSkipCollate(Expr*);
|
|
|
c0e712 |
int sqlite3CheckCollSeq(Parse *, CollSeq *);
|
|
|
c0e712 |
diff -up sqlite-src-3071700/src/where.c.old sqlite-src-3071700/src/where.c
|
|
|
c0e712 |
--- sqlite-src-3071700/src/where.c.old 2015-07-23 10:35:22.365770330 +0200
|
|
|
c0e712 |
+++ sqlite-src-3071700/src/where.c 2015-07-23 10:38:03.460761652 +0200
|
|
|
c0e712 |
@@ -1389,7 +1389,7 @@ static void exprAnalyze(
|
|
|
c0e712 |
Expr *pNewExpr2;
|
|
|
c0e712 |
int idxNew1;
|
|
|
c0e712 |
int idxNew2;
|
|
|
c0e712 |
- Token sCollSeqName; /* Name of collating sequence */
|
|
|
c0e712 |
+ const char *zCollSeqName; /* Name of collating sequence */
|
|
|
c0e712 |
|
|
|
c0e712 |
pLeft = pExpr->x.pList->a[1].pExpr;
|
|
|
c0e712 |
pStr2 = sqlite3ExprDup(db, pStr1, 0);
|
|
|
c0e712 |
@@ -1411,11 +1411,10 @@ static void exprAnalyze(
|
|
|
c0e712 |
}
|
|
|
c0e712 |
*pC = c + 1;
|
|
|
c0e712 |
}
|
|
|
c0e712 |
- sCollSeqName.z = noCase ? "NOCASE" : "BINARY";
|
|
|
c0e712 |
- sCollSeqName.n = 6;
|
|
|
c0e712 |
+ zCollSeqName = noCase ? "NOCASE" : "BINARY";
|
|
|
c0e712 |
pNewExpr1 = sqlite3ExprDup(db, pLeft, 0);
|
|
|
c0e712 |
pNewExpr1 = sqlite3PExpr(pParse, TK_GE,
|
|
|
c0e712 |
- sqlite3ExprAddCollateToken(pParse,pNewExpr1,&sCollSeqName),
|
|
|
c0e712 |
+ sqlite3ExprAddCollateString(pParse,pNewExpr1,zCollSeqName),
|
|
|
c0e712 |
pStr1, 0);
|
|
|
c0e712 |
idxNew1 = whereClauseInsert(pWC, pNewExpr1, TERM_VIRTUAL|TERM_DYNAMIC);
|
|
|
c0e712 |
testcase( idxNew1==0 );
|
|
|
c0e712 |
@@ -1421,7 +1421,7 @@ static void exprAnalyze(
|
|
|
c0e712 |
exprAnalyze(pSrc, pWC, idxNew1);
|
|
|
c0e712 |
pNewExpr2 = sqlite3ExprDup(db, pLeft, 0);
|
|
|
c0e712 |
pNewExpr2 = sqlite3PExpr(pParse, TK_LT,
|
|
|
c0e712 |
- sqlite3ExprAddCollateToken(pParse,pNewExpr2,&sCollSeqName),
|
|
|
c0e712 |
+ sqlite3ExprAddCollateString(pParse,pNewExpr2,zCollSeqName),
|
|
|
c0e712 |
pStr2, 0);
|
|
|
c0e712 |
idxNew2 = whereClauseInsert(pWC, pNewExpr2, TERM_VIRTUAL|TERM_DYNAMIC);
|
|
|
c0e712 |
testcase( idxNew2==0 );
|
|
|
c0e712 |
diff -up sqlite-src-3071700/test/collate1.test.old sqlite-src-3071700/test/collate1.test
|
|
|
c0e712 |
--- sqlite-src-3071700/test/collate1.test.old 2015-07-23 10:38:58.858102547 +0200
|
|
|
c0e712 |
+++ sqlite-src-3071700/test/collate1.test 2015-07-23 10:40:30.474666325 +0200
|
|
|
c0e712 |
@@ -10,12 +10,13 @@
|
|
|
c0e712 |
#
|
|
|
c0e712 |
#***********************************************************************
|
|
|
c0e712 |
# This file implements regression tests for SQLite library. The
|
|
|
c0e712 |
-# focus of this script is page cache subsystem.
|
|
|
c0e712 |
+# focus of this script is testing collation sequences.
|
|
|
c0e712 |
#
|
|
|
c0e712 |
# $Id: collate1.test,v 1.5 2007/02/01 23:02:46 drh Exp $
|
|
|
c0e712 |
|
|
|
c0e712 |
set testdir [file dirname $argv0]
|
|
|
c0e712 |
source $testdir/tester.tcl
|
|
|
c0e712 |
+set testprefix collate1
|
|
|
c0e712 |
|
|
|
c0e712 |
#
|
|
|
c0e712 |
# Tests are roughly organised as follows:
|
|
|
c0e712 |
@@ -305,4 +306,54 @@ do_test collate1-4.5 {
|
|
|
c0e712 |
}
|
|
|
c0e712 |
} {}
|
|
|
c0e712 |
|
|
|
c0e712 |
+#-------------------------------------------------------------------------
|
|
|
c0e712 |
+# Fix problems with handling collation sequences named '"""'.
|
|
|
c0e712 |
+#
|
|
|
c0e712 |
+do_execsql_test 6.1 {
|
|
|
c0e712 |
+ SELECT """""""";
|
|
|
c0e712 |
+} {\"\"\"}
|
|
|
c0e712 |
+
|
|
|
c0e712 |
+do_catchsql_test 6.2 {
|
|
|
c0e712 |
+ CREATE TABLE x1(a);
|
|
|
c0e712 |
+ SELECT a FROM x1 ORDER BY a COLLATE """""""";
|
|
|
c0e712 |
+} {1 {no such collation sequence: """}}
|
|
|
c0e712 |
+
|
|
|
c0e712 |
+do_catchsql_test 6.3 {
|
|
|
c0e712 |
+ SELECT a FROM x1 ORDER BY 1 COLLATE """""""";
|
|
|
c0e712 |
+} {1 {no such collation sequence: """}}
|
|
|
c0e712 |
+
|
|
|
c0e712 |
+do_catchsql_test 6.4 {
|
|
|
c0e712 |
+ SELECT 0 UNION SELECT 0 ORDER BY 1 COLLATE """""""";
|
|
|
c0e712 |
+} {1 {no such collation sequence: """}}
|
|
|
c0e712 |
+
|
|
|
c0e712 |
+db collate {"""} [list string compare -nocase]
|
|
|
c0e712 |
+
|
|
|
c0e712 |
+do_execsql_test 6.5 {
|
|
|
c0e712 |
+ PRAGMA foreign_keys = ON;
|
|
|
c0e712 |
+ CREATE TABLE p1(a PRIMARY KEY COLLATE '"""');
|
|
|
c0e712 |
+ CREATE TABLE c1(x, y REFERENCES p1);
|
|
|
c0e712 |
+} {}
|
|
|
c0e712 |
+
|
|
|
c0e712 |
+do_execsql_test 6.6 {
|
|
|
c0e712 |
+ INSERT INTO p1 VALUES('abc');
|
|
|
c0e712 |
+ INSERT INTO c1 VALUES(1, 'ABC');
|
|
|
c0e712 |
+}
|
|
|
c0e712 |
+
|
|
|
c0e712 |
+ifcapable foreignkey {
|
|
|
c0e712 |
+ do_catchsql_test 6.7 {
|
|
|
c0e712 |
+ DELETE FROM p1 WHERE rowid = 1
|
|
|
c0e712 |
+ } {1 {foreign key constraint failed}}
|
|
|
c0e712 |
+}
|
|
|
c0e712 |
+
|
|
|
c0e712 |
+do_execsql_test 6.8 {
|
|
|
c0e712 |
+ INSERT INTO p1 VALUES('abb');
|
|
|
c0e712 |
+ INSERT INTO p1 VALUES('wxz');
|
|
|
c0e712 |
+ INSERT INTO p1 VALUES('wxy');
|
|
|
c0e712 |
+
|
|
|
c0e712 |
+ INSERT INTO c1 VALUES(2, 'abb');
|
|
|
c0e712 |
+ INSERT INTO c1 VALUES(3, 'wxz');
|
|
|
c0e712 |
+ INSERT INTO c1 VALUES(4, 'WXY');
|
|
|
c0e712 |
+ SELECT x, y FROM c1 ORDER BY y COLLATE """""""";
|
|
|
c0e712 |
+} {2 abb 1 ABC 4 WXY 3 wxz}
|
|
|
c0e712 |
+
|
|
|
c0e712 |
finish_test
|