1 |
# Fix a problem causing collation sequence names to be dequoted multiple times |
2 |
# under some circumstances. |
3 |
# Upstream original patch: https://www.sqlite.org/src/info/eddc05e7bb31fae7 |
4 |
|
5 |
diff -up sqlite-src-3071700/src/expr.c.old sqlite-src-3071700/src/expr.c |
6 |
--- sqlite-src-3071700/src/expr.c.old 2015-07-23 10:26:11.220420294 +0200 |
7 |
+++ sqlite-src-3071700/src/expr.c 2015-07-23 10:26:47.468601833 +0200 |
8 |
@@ -65,9 +65,9 @@ char sqlite3ExprAffinity(Expr *pExpr){ |
9 |
** If a memory allocation error occurs, that fact is recorded in pParse->db |
10 |
** and the pExpr parameter is returned unchanged. |
11 |
*/ |
12 |
-Expr *sqlite3ExprAddCollateToken(Parse *pParse, Expr *pExpr, Token *pCollName){ |
13 |
+Expr *sqlite3ExprAddCollateToken(Parse *pParse, Expr *pExpr, Token *pCollName, int dequote){ |
14 |
if( pCollName->n>0 ){ |
15 |
- Expr *pNew = sqlite3ExprAlloc(pParse->db, TK_COLLATE, pCollName, 1); |
16 |
+ Expr *pNew = sqlite3ExprAlloc(pParse->db, TK_COLLATE, pCollName, dequote); |
17 |
if( pNew ){ |
18 |
pNew->pLeft = pExpr; |
19 |
pNew->flags |= EP_Collate; |
20 |
@@ -81,7 +81,7 @@ Expr *sqlite3ExprAddCollateString(Parse |
21 |
assert( zC!=0 ); |
22 |
s.z = zC; |
23 |
s.n = sqlite3Strlen30(s.z); |
24 |
- return sqlite3ExprAddCollateToken(pParse, pExpr, &s); |
25 |
+ return sqlite3ExprAddCollateToken(pParse, pExpr, &s, 0); |
26 |
} |
27 |
|
28 |
/* |
29 |
diff -up sqlite-src-3071700/src/parse.y.old sqlite-src-3071700/src/parse.y |
30 |
--- sqlite-src-3071700/src/parse.y.old 2015-07-23 10:27:00.595682612 +0200 |
31 |
+++ sqlite-src-3071700/src/parse.y 2015-07-23 10:27:47.850973405 +0200 |
32 |
@@ -818,7 +818,7 @@ expr(A) ::= VARIABLE(X). { |
33 |
spanSet(&A, &X, &X); |
34 |
} |
35 |
expr(A) ::= expr(E) COLLATE ids(C). { |
36 |
- A.pExpr = sqlite3ExprAddCollateToken(pParse, E.pExpr, &C); |
37 |
+ A.pExpr = sqlite3ExprAddCollateToken(pParse, E.pExpr, &C, 1); |
38 |
A.zStart = E.zStart; |
39 |
A.zEnd = &C.z[C.n]; |
40 |
} |
41 |
@@ -1143,14 +1143,14 @@ uniqueflag(A) ::= . {A = OE_None; |
42 |
idxlist_opt(A) ::= . {A = 0;} |
43 |
idxlist_opt(A) ::= LP idxlist(X) RP. {A = X;} |
44 |
idxlist(A) ::= idxlist(X) COMMA nm(Y) collate(C) sortorder(Z). { |
45 |
- Expr *p = sqlite3ExprAddCollateToken(pParse, 0, &C); |
46 |
+ Expr *p = sqlite3ExprAddCollateToken(pParse, 0, &C, 1); |
47 |
A = sqlite3ExprListAppend(pParse,X, p); |
48 |
sqlite3ExprListSetName(pParse,A,&Y,1); |
49 |
sqlite3ExprListCheckLength(pParse, A, "index"); |
50 |
if( A ) A->a[A->nExpr-1].sortOrder = (u8)Z; |
51 |
} |
52 |
idxlist(A) ::= nm(Y) collate(C) sortorder(Z). { |
53 |
- Expr *p = sqlite3ExprAddCollateToken(pParse, 0, &C); |
54 |
+ Expr *p = sqlite3ExprAddCollateToken(pParse, 0, &C, 1); |
55 |
A = sqlite3ExprListAppend(pParse,0, p); |
56 |
sqlite3ExprListSetName(pParse, A, &Y, 1); |
57 |
sqlite3ExprListCheckLength(pParse, A, "index"); |
58 |
diff -up sqlite-src-3071700/src/sqliteInt.h.old sqlite-src-3071700/src/sqliteInt.h |
59 |
--- sqlite-src-3071700/src/sqliteInt.h.old 2015-07-23 10:34:54.516598956 +0200 |
60 |
+++ sqlite-src-3071700/src/sqliteInt.h 2015-07-23 10:35:12.908712134 +0200 |
61 |
@@ -3103,7 +3103,7 @@ int sqlite3ReadSchema(Parse *pParse); |
62 |
CollSeq *sqlite3FindCollSeq(sqlite3*,u8 enc, const char*,int); |
63 |
CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char*zName); |
64 |
CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr); |
65 |
-Expr *sqlite3ExprAddCollateToken(Parse *pParse, Expr*, Token*); |
66 |
+Expr *sqlite3ExprAddCollateToken(Parse *pParse, Expr*, Token*, int); |
67 |
Expr *sqlite3ExprAddCollateString(Parse*,Expr*,const char*); |
68 |
Expr *sqlite3ExprSkipCollate(Expr*); |
69 |
int sqlite3CheckCollSeq(Parse *, CollSeq *); |
70 |
diff -up sqlite-src-3071700/src/where.c.old sqlite-src-3071700/src/where.c |
71 |
--- sqlite-src-3071700/src/where.c.old 2015-07-23 10:35:22.365770330 +0200 |
72 |
+++ sqlite-src-3071700/src/where.c 2015-07-23 10:38:03.460761652 +0200 |
73 |
@@ -1389,7 +1389,7 @@ static void exprAnalyze( |
74 |
Expr *pNewExpr2; |
75 |
int idxNew1; |
76 |
int idxNew2; |
77 |
- Token sCollSeqName; /* Name of collating sequence */ |
78 |
+ const char *zCollSeqName; /* Name of collating sequence */ |
79 |
|
80 |
pLeft = pExpr->x.pList->a[1].pExpr; |
81 |
pStr2 = sqlite3ExprDup(db, pStr1, 0); |
82 |
@@ -1411,11 +1411,10 @@ static void exprAnalyze( |
83 |
} |
84 |
*pC = c + 1; |
85 |
} |
86 |
- sCollSeqName.z = noCase ? "NOCASE" : "BINARY"; |
87 |
- sCollSeqName.n = 6; |
88 |
+ zCollSeqName = noCase ? "NOCASE" : "BINARY"; |
89 |
pNewExpr1 = sqlite3ExprDup(db, pLeft, 0); |
90 |
pNewExpr1 = sqlite3PExpr(pParse, TK_GE, |
91 |
- sqlite3ExprAddCollateToken(pParse,pNewExpr1,&sCollSeqName), |
92 |
+ sqlite3ExprAddCollateString(pParse,pNewExpr1,zCollSeqName), |
93 |
pStr1, 0); |
94 |
idxNew1 = whereClauseInsert(pWC, pNewExpr1, TERM_VIRTUAL|TERM_DYNAMIC); |
95 |
testcase( idxNew1==0 ); |
96 |
@@ -1421,7 +1421,7 @@ static void exprAnalyze( |
97 |
exprAnalyze(pSrc, pWC, idxNew1); |
98 |
pNewExpr2 = sqlite3ExprDup(db, pLeft, 0); |
99 |
pNewExpr2 = sqlite3PExpr(pParse, TK_LT, |
100 |
- sqlite3ExprAddCollateToken(pParse,pNewExpr2,&sCollSeqName), |
101 |
+ sqlite3ExprAddCollateString(pParse,pNewExpr2,zCollSeqName), |
102 |
pStr2, 0); |
103 |
idxNew2 = whereClauseInsert(pWC, pNewExpr2, TERM_VIRTUAL|TERM_DYNAMIC); |
104 |
testcase( idxNew2==0 ); |
105 |
diff -up sqlite-src-3071700/test/collate1.test.old sqlite-src-3071700/test/collate1.test |
106 |
--- sqlite-src-3071700/test/collate1.test.old 2015-07-23 10:38:58.858102547 +0200 |
107 |
+++ sqlite-src-3071700/test/collate1.test 2015-07-23 10:40:30.474666325 +0200 |
108 |
@@ -10,12 +10,13 @@ |
109 |
# |
110 |
#*********************************************************************** |
111 |
# This file implements regression tests for SQLite library. The |
112 |
-# focus of this script is page cache subsystem. |
113 |
+# focus of this script is testing collation sequences. |
114 |
# |
115 |
# $Id: collate1.test,v 1.5 2007/02/01 23:02:46 drh Exp $ |
116 |
|
117 |
set testdir [file dirname $argv0] |
118 |
source $testdir/tester.tcl |
119 |
+set testprefix collate1 |
120 |
|
121 |
# |
122 |
# Tests are roughly organised as follows: |
123 |
@@ -305,4 +306,54 @@ do_test collate1-4.5 { |
124 |
} |
125 |
} {} |
126 |
|
127 |
+#------------------------------------------------------------------------- |
128 |
+# Fix problems with handling collation sequences named '"""'. |
129 |
+# |
130 |
+do_execsql_test 6.1 { |
131 |
+ SELECT """"""""; |
132 |
+} {\"\"\"} |
133 |
+ |
134 |
+do_catchsql_test 6.2 { |
135 |
+ CREATE TABLE x1(a); |
136 |
+ SELECT a FROM x1 ORDER BY a COLLATE """"""""; |
137 |
+} {1 {no such collation sequence: """}} |
138 |
+ |
139 |
+do_catchsql_test 6.3 { |
140 |
+ SELECT a FROM x1 ORDER BY 1 COLLATE """"""""; |
141 |
+} {1 {no such collation sequence: """}} |
142 |
+ |
143 |
+do_catchsql_test 6.4 { |
144 |
+ SELECT 0 UNION SELECT 0 ORDER BY 1 COLLATE """"""""; |
145 |
+} {1 {no such collation sequence: """}} |
146 |
+ |
147 |
+db collate {"""} [list string compare -nocase] |
148 |
+ |
149 |
+do_execsql_test 6.5 { |
150 |
+ PRAGMA foreign_keys = ON; |
151 |
+ CREATE TABLE p1(a PRIMARY KEY COLLATE '"""'); |
152 |
+ CREATE TABLE c1(x, y REFERENCES p1); |
153 |
+} {} |
154 |
+ |
155 |
+do_execsql_test 6.6 { |
156 |
+ INSERT INTO p1 VALUES('abc'); |
157 |
+ INSERT INTO c1 VALUES(1, 'ABC'); |
158 |
+} |
159 |
+ |
160 |
+ifcapable foreignkey { |
161 |
+ do_catchsql_test 6.7 { |
162 |
+ DELETE FROM p1 WHERE rowid = 1 |
163 |
+ } {1 {foreign key constraint failed}} |
164 |
+} |
165 |
+ |
166 |
+do_execsql_test 6.8 { |
167 |
+ INSERT INTO p1 VALUES('abb'); |
168 |
+ INSERT INTO p1 VALUES('wxz'); |
169 |
+ INSERT INTO p1 VALUES('wxy'); |
170 |
+ |
171 |
+ INSERT INTO c1 VALUES(2, 'abb'); |
172 |
+ INSERT INTO c1 VALUES(3, 'wxz'); |
173 |
+ INSERT INTO c1 VALUES(4, 'WXY'); |
174 |
+ SELECT x, y FROM c1 ORDER BY y COLLATE """"""""; |
175 |
+} {2 abb 1 ABC 4 WXY 3 wxz} |
176 |
+ |
177 |
finish_test |