From 3e13a01e946b7df16a5b3702ac016b5784945a90 Mon Sep 17 00:00:00 2001 From: shess Date: Wed, 25 Mar 2015 08:22:38 -0700 Subject: [PATCH] [sqlite 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 Review URL: https://codereview.chromium.org/1022423004 Cr-Commit-Position: refs/heads/master@{#322165} --- third_party/sqlite/amalgamation/sqlite3.c | 24 +-- .../0018-backport-Fix-collation-dequoting.patch | 205 +++++++++++++++++++++ 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 +++++- 7 files changed, 285 insertions(+), 26 deletions(-) create mode 100644 third_party/sqlite/patches/0018-backport-Fix-collation-dequoting.patch diff --git a/third_party/sqlite/amalgamation/sqlite3.c b/third_party/sqlite/amalgamation/sqlite3.c index 7d748a5cd6b2..82dc78033a0b 100644 --- a/third_party/sqlite/amalgamation/sqlite3.c +++ b/third_party/sqlite/amalgamation/sqlite3.c @@ -12996,7 +12996,7 @@ SQLITE_PRIVATE int sqlite3ReadSchema(Parse *pParse); SQLITE_PRIVATE CollSeq *sqlite3FindCollSeq(sqlite3*,u8 enc, const char*,int); SQLITE_PRIVATE CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char*zName); SQLITE_PRIVATE CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr); -SQLITE_PRIVATE Expr *sqlite3ExprAddCollateToken(Parse *pParse, Expr*, const Token*); +SQLITE_PRIVATE Expr *sqlite3ExprAddCollateToken(Parse *pParse, Expr*, const Token*, int); SQLITE_PRIVATE Expr *sqlite3ExprAddCollateString(Parse*,Expr*,const char*); SQLITE_PRIVATE Expr *sqlite3ExprSkipCollate(Expr*); SQLITE_PRIVATE int sqlite3CheckCollSeq(Parse *, CollSeq *); @@ -80848,10 +80848,11 @@ SQLITE_PRIVATE char sqlite3ExprAffinity(Expr *pExpr){ SQLITE_PRIVATE 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; @@ -80865,7 +80866,7 @@ SQLITE_PRIVATE Expr *sqlite3ExprAddCollateString(Parse *pParse, Expr *pExpr, con assert( zC!=0 ); s.z = zC; s.n = sqlite3Strlen30(s.z); - return sqlite3ExprAddCollateToken(pParse, pExpr, &s); + return sqlite3ExprAddCollateToken(pParse, pExpr, &s, 0); } /* @@ -114998,7 +114999,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); @@ -115018,11 +115019,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); @@ -115030,7 +115030,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); @@ -123107,7 +123107,7 @@ static void yy_reduce( break; case 193: /* expr ::= expr COLLATE ID|STRING */ { - yygotominor.yy346.pExpr = sqlite3ExprAddCollateToken(pParse, yymsp[-2].minor.yy346.pExpr, &yymsp[0].minor.yy0); + yygotominor.yy346.pExpr = sqlite3ExprAddCollateToken(pParse, yymsp[-2].minor.yy346.pExpr, &yymsp[0].minor.yy0, 1); yygotominor.yy346.zStart = yymsp[-2].minor.yy346.zStart; yygotominor.yy346.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n]; } @@ -123387,7 +123387,7 @@ static void yy_reduce( break; case 244: /* idxlist ::= idxlist COMMA nm collate sortorder */ { - Expr *p = sqlite3ExprAddCollateToken(pParse, 0, &yymsp[-1].minor.yy0); + Expr *p = sqlite3ExprAddCollateToken(pParse, 0, &yymsp[-1].minor.yy0, 1); yygotominor.yy14 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy14, p); sqlite3ExprListSetName(pParse,yygotominor.yy14,&yymsp[-2].minor.yy0,1); sqlite3ExprListCheckLength(pParse, yygotominor.yy14, "index"); @@ -123396,7 +123396,7 @@ static void yy_reduce( break; case 245: /* idxlist ::= nm collate sortorder */ { - Expr *p = sqlite3ExprAddCollateToken(pParse, 0, &yymsp[-1].minor.yy0); + Expr *p = sqlite3ExprAddCollateToken(pParse, 0, &yymsp[-1].minor.yy0, 1); yygotominor.yy14 = sqlite3ExprListAppend(pParse,0, p); sqlite3ExprListSetName(pParse, yygotominor.yy14, &yymsp[-2].minor.yy0, 1); sqlite3ExprListCheckLength(pParse, yygotominor.yy14, "index"); 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 000000000000..f8f1597bbc25 --- /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 +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 + diff --git a/third_party/sqlite/src/src/expr.c b/third_party/sqlite/src/src/expr.c index 65f211e3aea2..2d96c8d8e6cf 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 877827e68d7c..d888cff92d7f 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 9d6a7d82b29c..264f4fe7a59b 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 bc0110779ea0..793b01d1678e 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 20854157d3a1..0716ac743fd4 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.11.4.GIT