/ Check-in [eddc05e7]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Fix a problem causing collation sequence names to be dequoted multiple times under some circumstances.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: eddc05e7bb31fae74daa86e0504a3478b99fa0f2
User & Date: dan 2015-03-20 08:43:59
References
2015-05-20
19:34
Fix a problem causing collation sequence names to be dequoted multiple times under some circumstances. Cherrypick of [eddc05e7bb31]. check-in: fc1a4f29 user: dan tags: branch-3.8.6
Context
2015-05-20
19:34
Fix a problem causing collation sequence names to be dequoted multiple times under some circumstances. Cherrypick of [eddc05e7bb31]. check-in: fc1a4f29 user: dan tags: branch-3.8.6
2015-03-20
20:30
Where possible insert the set of new keys for each index in sorted order within "INSERT INTO ... SELECT" statements. check-in: 0a7f2051 user: dan tags: insert-select-opt
16:54
Provide the BTREE_SEEK_EQ hint to the b-tree layer. check-in: 3c367004 user: drh tags: trunk
14:57
Provide the BTREE_SEEK_EQ hint to the b-tree layer. check-in: e750830f user: drh tags: seek-eq
08:43
Fix a problem causing collation sequence names to be dequoted multiple times under some circumstances. check-in: eddc05e7 user: dan tags: trunk
2015-03-19
20:09
If a virtual table is created with a malformed UTF8 name in a UTF16 database, make sure that does not cause problems. check-in: b74cb0a9 user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/expr.c.

    65     65   **
    66     66   ** If a memory allocation error occurs, that fact is recorded in pParse->db
    67     67   ** and the pExpr parameter is returned unchanged.
    68     68   */
    69     69   Expr *sqlite3ExprAddCollateToken(
    70     70     Parse *pParse,           /* Parsing context */
    71     71     Expr *pExpr,             /* Add the "COLLATE" clause to this expression */
    72         -  const Token *pCollName   /* Name of collating sequence */
           72  +  const Token *pCollName,  /* Name of collating sequence */
           73  +  int dequote              /* True to dequote pCollName */
    73     74   ){
    74     75     if( pCollName->n>0 ){
    75         -    Expr *pNew = sqlite3ExprAlloc(pParse->db, TK_COLLATE, pCollName, 1);
           76  +    Expr *pNew = sqlite3ExprAlloc(pParse->db, TK_COLLATE, pCollName, dequote);
    76     77       if( pNew ){
    77     78         pNew->pLeft = pExpr;
    78     79         pNew->flags |= EP_Collate|EP_Skip;
    79     80         pExpr = pNew;
    80     81       }
    81     82     }
    82     83     return pExpr;
    83     84   }
    84     85   Expr *sqlite3ExprAddCollateString(Parse *pParse, Expr *pExpr, const char *zC){
    85     86     Token s;
    86     87     assert( zC!=0 );
    87     88     s.z = zC;
    88     89     s.n = sqlite3Strlen30(s.z);
    89         -  return sqlite3ExprAddCollateToken(pParse, pExpr, &s);
           90  +  return sqlite3ExprAddCollateToken(pParse, pExpr, &s, 0);
    90     91   }
    91     92   
    92     93   /*
    93     94   ** Skip over any TK_COLLATE or TK_AS operators and any unlikely()
    94     95   ** or likelihood() function at the root of an expression.
    95     96   */
    96     97   Expr *sqlite3ExprSkipCollate(Expr *pExpr){

Changes to src/parse.y.

   856    856     }else{
   857    857       spanExpr(&A, pParse, TK_VARIABLE, &X);
   858    858       sqlite3ExprAssignVarNumber(pParse, A.pExpr);
   859    859     }
   860    860     spanSet(&A, &X, &X);
   861    861   }
   862    862   expr(A) ::= expr(E) COLLATE ids(C). {
   863         -  A.pExpr = sqlite3ExprAddCollateToken(pParse, E.pExpr, &C);
          863  +  A.pExpr = sqlite3ExprAddCollateToken(pParse, E.pExpr, &C, 1);
   864    864     A.zStart = E.zStart;
   865    865     A.zEnd = &C.z[C.n];
   866    866   }
   867    867   %ifndef SQLITE_OMIT_CAST
   868    868   expr(A) ::= CAST(X) LP expr(E) AS typetoken(T) RP(Y). {
   869    869     A.pExpr = sqlite3PExpr(pParse, TK_CAST, E.pExpr, 0, &T);
   870    870     spanSet(&A,&X,&Y);
................................................................................
  1202   1202   %destructor idxlist {sqlite3ExprListDelete(pParse->db, $$);}
  1203   1203   %type idxlist_opt {ExprList*}
  1204   1204   %destructor idxlist_opt {sqlite3ExprListDelete(pParse->db, $$);}
  1205   1205   
  1206   1206   idxlist_opt(A) ::= .                         {A = 0;}
  1207   1207   idxlist_opt(A) ::= LP idxlist(X) RP.         {A = X;}
  1208   1208   idxlist(A) ::= idxlist(X) COMMA nm(Y) collate(C) sortorder(Z).  {
  1209         -  Expr *p = sqlite3ExprAddCollateToken(pParse, 0, &C);
         1209  +  Expr *p = sqlite3ExprAddCollateToken(pParse, 0, &C, 1);
  1210   1210     A = sqlite3ExprListAppend(pParse,X, p);
  1211   1211     sqlite3ExprListSetName(pParse,A,&Y,1);
  1212   1212     sqlite3ExprListCheckLength(pParse, A, "index");
  1213   1213     if( A ) A->a[A->nExpr-1].sortOrder = (u8)Z;
  1214   1214   }
  1215   1215   idxlist(A) ::= nm(Y) collate(C) sortorder(Z). {
  1216         -  Expr *p = sqlite3ExprAddCollateToken(pParse, 0, &C);
         1216  +  Expr *p = sqlite3ExprAddCollateToken(pParse, 0, &C, 1);
  1217   1217     A = sqlite3ExprListAppend(pParse,0, p);
  1218   1218     sqlite3ExprListSetName(pParse, A, &Y, 1);
  1219   1219     sqlite3ExprListCheckLength(pParse, A, "index");
  1220   1220     if( A ) A->a[A->nExpr-1].sortOrder = (u8)Z;
  1221   1221   }
  1222   1222   
  1223   1223   %type collate {Token}

Changes to src/sqliteInt.h.

  3475   3475   #endif
  3476   3476   
  3477   3477   const char *sqlite3ErrStr(int);
  3478   3478   int sqlite3ReadSchema(Parse *pParse);
  3479   3479   CollSeq *sqlite3FindCollSeq(sqlite3*,u8 enc, const char*,int);
  3480   3480   CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char*zName);
  3481   3481   CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr);
  3482         -Expr *sqlite3ExprAddCollateToken(Parse *pParse, Expr*, const Token*);
         3482  +Expr *sqlite3ExprAddCollateToken(Parse *pParse, Expr*, const Token*, int);
  3483   3483   Expr *sqlite3ExprAddCollateString(Parse*,Expr*,const char*);
  3484   3484   Expr *sqlite3ExprSkipCollate(Expr*);
  3485   3485   int sqlite3CheckCollSeq(Parse *, CollSeq *);
  3486   3486   int sqlite3CheckObjectName(Parse *, const char *);
  3487   3487   void sqlite3VdbeSetChanges(sqlite3 *, int);
  3488   3488   int sqlite3AddInt64(i64*,i64);
  3489   3489   int sqlite3SubInt64(i64*,i64);

Changes to src/where.c.

  1360   1360     ){
  1361   1361       Expr *pLeft;       /* LHS of LIKE/GLOB operator */
  1362   1362       Expr *pStr2;       /* Copy of pStr1 - RHS of LIKE/GLOB operator */
  1363   1363       Expr *pNewExpr1;
  1364   1364       Expr *pNewExpr2;
  1365   1365       int idxNew1;
  1366   1366       int idxNew2;
  1367         -    Token sCollSeqName;  /* Name of collating sequence */
         1367  +    const char *zCollSeqName;     /* Name of collating sequence */
  1368   1368       const u16 wtFlags = TERM_LIKEOPT | TERM_VIRTUAL | TERM_DYNAMIC;
  1369   1369   
  1370   1370       pLeft = pExpr->x.pList->a[1].pExpr;
  1371   1371       pStr2 = sqlite3ExprDup(db, pStr1, 0);
  1372   1372   
  1373   1373       /* Convert the lower bound to upper-case and the upper bound to
  1374   1374       ** lower-case (upper-case is less than lower-case in ASCII) so that
................................................................................
  1396   1396           ** LIKE on all candidate expressions by clearing the isComplete flag
  1397   1397           */
  1398   1398           if( c=='A'-1 ) isComplete = 0;
  1399   1399           c = sqlite3UpperToLower[c];
  1400   1400         }
  1401   1401         *pC = c + 1;
  1402   1402       }
  1403         -    sCollSeqName.z = noCase ? "NOCASE" : "BINARY";
  1404         -    sCollSeqName.n = 6;
         1403  +    zCollSeqName = noCase ? "NOCASE" : "BINARY";
  1405   1404       pNewExpr1 = sqlite3ExprDup(db, pLeft, 0);
  1406   1405       pNewExpr1 = sqlite3PExpr(pParse, TK_GE,
  1407         -           sqlite3ExprAddCollateToken(pParse,pNewExpr1,&sCollSeqName),
         1406  +           sqlite3ExprAddCollateString(pParse,pNewExpr1,zCollSeqName),
  1408   1407              pStr1, 0);
  1409   1408       transferJoinMarkings(pNewExpr1, pExpr);
  1410   1409       idxNew1 = whereClauseInsert(pWC, pNewExpr1, wtFlags);
  1411   1410       testcase( idxNew1==0 );
  1412   1411       exprAnalyze(pSrc, pWC, idxNew1);
  1413   1412       pNewExpr2 = sqlite3ExprDup(db, pLeft, 0);
  1414   1413       pNewExpr2 = sqlite3PExpr(pParse, TK_LT,
  1415         -           sqlite3ExprAddCollateToken(pParse,pNewExpr2,&sCollSeqName),
         1414  +           sqlite3ExprAddCollateString(pParse,pNewExpr2,zCollSeqName),
  1416   1415              pStr2, 0);
  1417   1416       transferJoinMarkings(pNewExpr2, pExpr);
  1418   1417       idxNew2 = whereClauseInsert(pWC, pNewExpr2, wtFlags);
  1419   1418       testcase( idxNew2==0 );
  1420   1419       exprAnalyze(pSrc, pWC, idxNew2);
  1421   1420       pTerm = &pWC->a[idxTerm];
  1422   1421       if( isComplete ){

Changes to test/collate1.test.

     6      6   #
     7      7   #    May you do good and not evil.
     8      8   #    May you find forgiveness for yourself and forgive others.
     9      9   #    May you share freely, never taking more than you give.
    10     10   #
    11     11   #***********************************************************************
    12     12   # This file implements regression tests for SQLite library.  The
    13         -# focus of this script is page cache subsystem.
           13  +# focus of this script is testing collation sequences.
    14     14   #
    15         -# $Id: collate1.test,v 1.5 2007/02/01 23:02:46 drh Exp $
    16     15   
    17     16   set testdir [file dirname $argv0]
    18     17   source $testdir/tester.tcl
           18  +set testprefix collate1
    19     19   
    20     20   #
    21     21   # Tests are roughly organised as follows:
    22     22   #
    23     23   # collate1-1.* - Single-field ORDER BY with an explicit COLLATE clause.
    24     24   # collate1-2.* - Multi-field ORDER BY with an explicit COLLATE clause.
    25     25   # collate1-3.* - ORDER BY using a default collation type. Also that an 
................................................................................
   329    329   } {1}
   330    330   do_test collate1-5.3 {
   331    331     execsql {
   332    332       SELECT id FROM c5 WHERE c='abc' ORDER BY id;
   333    333     }
   334    334   } {1 2}
   335    335   
          336  +
          337  +
          338  +#-------------------------------------------------------------------------
          339  +# Fix problems with handling collation sequences named '"""'.
          340  +#
          341  +do_execsql_test 6.1 {
          342  +  SELECT """""""";
          343  +} {\"\"\"}
          344  +
          345  +do_catchsql_test 6.2 {
          346  +  CREATE TABLE x1(a);
          347  +  SELECT a FROM x1 ORDER BY a COLLATE """""""";
          348  +} {1 {no such collation sequence: """}}
          349  +
          350  +do_catchsql_test 6.3 {
          351  +  SELECT a FROM x1 ORDER BY 1 COLLATE """""""";
          352  +} {1 {no such collation sequence: """}}
          353  +
          354  +do_catchsql_test 6.4 {
          355  +  SELECT 0 UNION SELECT 0 ORDER BY 1 COLLATE """""""";
          356  +} {1 {no such collation sequence: """}}
          357  +
          358  +db collate {"""} [list string compare -nocase]
          359  +
          360  +do_execsql_test 6.5 {
          361  +  PRAGMA foreign_keys = ON;
          362  +  CREATE TABLE p1(a PRIMARY KEY COLLATE '"""');
          363  +  CREATE TABLE c1(x, y REFERENCES p1);
          364  +} {}
          365  +
          366  +do_execsql_test 6.6 { 
          367  +  INSERT INTO p1 VALUES('abc'); 
          368  +  INSERT INTO c1 VALUES(1, 'ABC'); 
          369  +}
          370  +
          371  +ifcapable foreignkey {
          372  +  do_catchsql_test 6.7 { 
          373  +    DELETE FROM p1 WHERE rowid = 1 
          374  +  } {1 {FOREIGN KEY constraint failed}}
          375  +}
          376  +
          377  +do_execsql_test 6.8 { 
          378  +  INSERT INTO p1 VALUES('abb');
          379  +  INSERT INTO p1 VALUES('wxz');
          380  +  INSERT INTO p1 VALUES('wxy');
          381  +
          382  +  INSERT INTO c1 VALUES(2, 'abb');
          383  +  INSERT INTO c1 VALUES(3, 'wxz');
          384  +  INSERT INTO c1 VALUES(4, 'WXY');
          385  +  SELECT x, y FROM c1 ORDER BY y COLLATE """""""";
          386  +} {2 abb 1 ABC 4 WXY 3 wxz}
          387  +
   336    388   finish_test
          389  +
          390  +