Index: third_party/sqlite/patches/0018-backport-Fix-collation-dequoting.patch |
diff --git a/third_party/sqlite/patches/0018-backport-Fix-collation-dequoting.patch b/third_party/sqlite/patches/0018-backport-Fix-collation-dequoting.patch |
new file mode 100644 |
index 0000000000000000000000000000000000000000..f8f1597bbc2561f8bb1cfeefbd3fee685f888006 |
--- /dev/null |
+++ b/third_party/sqlite/patches/0018-backport-Fix-collation-dequoting.patch |
@@ -0,0 +1,205 @@ |
+From f4b79cfaefb87fa2c37a860c5a64f320a5265f99 Mon Sep 17 00:00:00 2001 |
+From: Scott Hess <shess@chromium.org> |
+Date: Mon, 23 Mar 2015 11:24:11 -0700 |
+Subject: [PATCH] [backport] Fix collation dequoting. |
+ |
+Backport https://www.sqlite.org/src/info/eddc05e7bb31fae7 |
+"Fix a problem causing collation sequence names to be dequoted |
+multiple times under some circumstances." |
+ |
+BUG=469082 |
+--- |
+ third_party/sqlite/src/src/expr.c | 7 ++-- |
+ third_party/sqlite/src/src/parse.y | 6 ++-- |
+ third_party/sqlite/src/src/sqliteInt.h | 2 +- |
+ third_party/sqlite/src/src/where.c | 9 +++-- |
+ third_party/sqlite/src/test/collate1.test | 58 +++++++++++++++++++++++++++++-- |
+ 5 files changed, 68 insertions(+), 14 deletions(-) |
+ |
+diff --git a/third_party/sqlite/src/src/expr.c b/third_party/sqlite/src/src/expr.c |
+index 65f211e..2d96c8d 100644 |
+--- a/third_party/sqlite/src/src/expr.c |
++++ b/third_party/sqlite/src/src/expr.c |
+@@ -69,10 +69,11 @@ char sqlite3ExprAffinity(Expr *pExpr){ |
+ Expr *sqlite3ExprAddCollateToken( |
+ Parse *pParse, /* Parsing context */ |
+ Expr *pExpr, /* Add the "COLLATE" clause to this expression */ |
+- const Token *pCollName /* Name of collating sequence */ |
++ const Token *pCollName, /* Name of collating sequence */ |
++ int dequote /* True to dequote pCollName */ |
+ ){ |
+ if( pCollName->n>0 ){ |
+- Expr *pNew = sqlite3ExprAlloc(pParse->db, TK_COLLATE, pCollName, 1); |
++ Expr *pNew = sqlite3ExprAlloc(pParse->db, TK_COLLATE, pCollName, dequote); |
+ if( pNew ){ |
+ pNew->pLeft = pExpr; |
+ pNew->flags |= EP_Collate|EP_Skip; |
+@@ -86,7 +87,7 @@ Expr *sqlite3ExprAddCollateString(Parse *pParse, Expr *pExpr, const char *zC){ |
+ assert( zC!=0 ); |
+ s.z = zC; |
+ s.n = sqlite3Strlen30(s.z); |
+- return sqlite3ExprAddCollateToken(pParse, pExpr, &s); |
++ return sqlite3ExprAddCollateToken(pParse, pExpr, &s, 0); |
+ } |
+ |
+ /* |
+diff --git a/third_party/sqlite/src/src/parse.y b/third_party/sqlite/src/src/parse.y |
+index 877827e..d888cff 100644 |
+--- a/third_party/sqlite/src/src/parse.y |
++++ b/third_party/sqlite/src/src/parse.y |
+@@ -854,7 +854,7 @@ expr(A) ::= VARIABLE(X). { |
+ spanSet(&A, &X, &X); |
+ } |
+ expr(A) ::= expr(E) COLLATE ids(C). { |
+- A.pExpr = sqlite3ExprAddCollateToken(pParse, E.pExpr, &C); |
++ A.pExpr = sqlite3ExprAddCollateToken(pParse, E.pExpr, &C, 1); |
+ A.zStart = E.zStart; |
+ A.zEnd = &C.z[C.n]; |
+ } |
+@@ -1200,14 +1200,14 @@ uniqueflag(A) ::= . {A = OE_None;} |
+ idxlist_opt(A) ::= . {A = 0;} |
+ idxlist_opt(A) ::= LP idxlist(X) RP. {A = X;} |
+ idxlist(A) ::= idxlist(X) COMMA nm(Y) collate(C) sortorder(Z). { |
+- Expr *p = sqlite3ExprAddCollateToken(pParse, 0, &C); |
++ Expr *p = sqlite3ExprAddCollateToken(pParse, 0, &C, 1); |
+ A = sqlite3ExprListAppend(pParse,X, p); |
+ sqlite3ExprListSetName(pParse,A,&Y,1); |
+ sqlite3ExprListCheckLength(pParse, A, "index"); |
+ if( A ) A->a[A->nExpr-1].sortOrder = (u8)Z; |
+ } |
+ idxlist(A) ::= nm(Y) collate(C) sortorder(Z). { |
+- Expr *p = sqlite3ExprAddCollateToken(pParse, 0, &C); |
++ Expr *p = sqlite3ExprAddCollateToken(pParse, 0, &C, 1); |
+ A = sqlite3ExprListAppend(pParse,0, p); |
+ sqlite3ExprListSetName(pParse, A, &Y, 1); |
+ sqlite3ExprListCheckLength(pParse, A, "index"); |
+diff --git a/third_party/sqlite/src/src/sqliteInt.h b/third_party/sqlite/src/src/sqliteInt.h |
+index 9d6a7d8..264f4fe 100644 |
+--- a/third_party/sqlite/src/src/sqliteInt.h |
++++ b/third_party/sqlite/src/src/sqliteInt.h |
+@@ -3462,7 +3462,7 @@ int sqlite3ReadSchema(Parse *pParse); |
+ CollSeq *sqlite3FindCollSeq(sqlite3*,u8 enc, const char*,int); |
+ CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char*zName); |
+ CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr); |
+-Expr *sqlite3ExprAddCollateToken(Parse *pParse, Expr*, const Token*); |
++Expr *sqlite3ExprAddCollateToken(Parse *pParse, Expr*, const Token*, int); |
+ Expr *sqlite3ExprAddCollateString(Parse*,Expr*,const char*); |
+ Expr *sqlite3ExprSkipCollate(Expr*); |
+ int sqlite3CheckCollSeq(Parse *, CollSeq *); |
+diff --git a/third_party/sqlite/src/src/where.c b/third_party/sqlite/src/src/where.c |
+index bc01107..793b01d 100644 |
+--- a/third_party/sqlite/src/src/where.c |
++++ b/third_party/sqlite/src/src/where.c |
+@@ -1252,7 +1252,7 @@ static void exprAnalyze( |
+ Expr *pNewExpr2; |
+ int idxNew1; |
+ int idxNew2; |
+- Token sCollSeqName; /* Name of collating sequence */ |
++ const char *zCollSeqName; /* Name of collating sequence */ |
+ |
+ pLeft = pExpr->x.pList->a[1].pExpr; |
+ pStr2 = sqlite3ExprDup(db, pStr1, 0); |
+@@ -1272,11 +1272,10 @@ static void exprAnalyze( |
+ } |
+ *pC = c + 1; |
+ } |
+- sCollSeqName.z = noCase ? "NOCASE" : "BINARY"; |
+- sCollSeqName.n = 6; |
++ zCollSeqName = noCase ? "NOCASE" : "BINARY"; |
+ pNewExpr1 = sqlite3ExprDup(db, pLeft, 0); |
+ pNewExpr1 = sqlite3PExpr(pParse, TK_GE, |
+- sqlite3ExprAddCollateToken(pParse,pNewExpr1,&sCollSeqName), |
++ sqlite3ExprAddCollateString(pParse,pNewExpr1,zCollSeqName), |
+ pStr1, 0); |
+ transferJoinMarkings(pNewExpr1, pExpr); |
+ idxNew1 = whereClauseInsert(pWC, pNewExpr1, TERM_VIRTUAL|TERM_DYNAMIC); |
+@@ -1284,7 +1283,7 @@ static void exprAnalyze( |
+ exprAnalyze(pSrc, pWC, idxNew1); |
+ pNewExpr2 = sqlite3ExprDup(db, pLeft, 0); |
+ pNewExpr2 = sqlite3PExpr(pParse, TK_LT, |
+- sqlite3ExprAddCollateToken(pParse,pNewExpr2,&sCollSeqName), |
++ sqlite3ExprAddCollateString(pParse,pNewExpr2,zCollSeqName), |
+ pStr2, 0); |
+ transferJoinMarkings(pNewExpr2, pExpr); |
+ idxNew2 = whereClauseInsert(pWC, pNewExpr2, TERM_VIRTUAL|TERM_DYNAMIC); |
+diff --git a/third_party/sqlite/src/test/collate1.test b/third_party/sqlite/src/test/collate1.test |
+index 2085415..0716ac7 100644 |
+--- a/third_party/sqlite/src/test/collate1.test |
++++ b/third_party/sqlite/src/test/collate1.test |
+@@ -10,12 +10,12 @@ |
+ # |
+ #*********************************************************************** |
+ # This file implements regression tests for SQLite library. The |
+-# focus of this script is page cache subsystem. |
++# focus of this script is testing collation sequences. |
+ # |
+-# $Id: collate1.test,v 1.5 2007/02/01 23:02:46 drh Exp $ |
+ |
+ set testdir [file dirname $argv0] |
+ source $testdir/tester.tcl |
++set testprefix collate1 |
+ |
+ # |
+ # Tests are roughly organised as follows: |
+@@ -333,4 +333,58 @@ do_test collate1-5.3 { |
+ } |
+ } {1 2} |
+ |
++ |
++ |
++#------------------------------------------------------------------------- |
++# Fix problems with handling collation sequences named '"""'. |
++# |
++do_execsql_test 6.1 { |
++ SELECT """"""""; |
++} {\"\"\"} |
++ |
++do_catchsql_test 6.2 { |
++ CREATE TABLE x1(a); |
++ SELECT a FROM x1 ORDER BY a COLLATE """"""""; |
++} {1 {no such collation sequence: """}} |
++ |
++do_catchsql_test 6.3 { |
++ SELECT a FROM x1 ORDER BY 1 COLLATE """"""""; |
++} {1 {no such collation sequence: """}} |
++ |
++do_catchsql_test 6.4 { |
++ SELECT 0 UNION SELECT 0 ORDER BY 1 COLLATE """"""""; |
++} {1 {no such collation sequence: """}} |
++ |
++db collate {"""} [list string compare -nocase] |
++ |
++do_execsql_test 6.5 { |
++ PRAGMA foreign_keys = ON; |
++ CREATE TABLE p1(a PRIMARY KEY COLLATE '"""'); |
++ CREATE TABLE c1(x, y REFERENCES p1); |
++} {} |
++ |
++do_execsql_test 6.6 { |
++ INSERT INTO p1 VALUES('abc'); |
++ INSERT INTO c1 VALUES(1, 'ABC'); |
++} |
++ |
++ifcapable foreignkey { |
++ do_catchsql_test 6.7 { |
++ DELETE FROM p1 WHERE rowid = 1 |
++ } {1 {FOREIGN KEY constraint failed}} |
++} |
++ |
++do_execsql_test 6.8 { |
++ INSERT INTO p1 VALUES('abb'); |
++ INSERT INTO p1 VALUES('wxz'); |
++ INSERT INTO p1 VALUES('wxy'); |
++ |
++ INSERT INTO c1 VALUES(2, 'abb'); |
++ INSERT INTO c1 VALUES(3, 'wxz'); |
++ INSERT INTO c1 VALUES(4, 'WXY'); |
++ SELECT x, y FROM c1 ORDER BY y COLLATE """"""""; |
++} {2 abb 1 ABC 4 WXY 3 wxz} |
++ |
+ finish_test |
++ |
++ |
+-- |
+2.2.1 |
+ |