SQLite

Check-in [9740aa95a3]
Login

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

Overview
Comment:Minor tweaks to collating sequences. We'll hold of making major changes until 3.4.0, since we'll likely end up with some minor technical imcompatibilities. (CVS 3626)
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 9740aa95a3f848fc663c88263a911fbc76ada243
User & Date: drh 2007-02-02 12:44:37.000
Context
2007-02-05
14:21
Set the MEM_Term flag when an internal string has a nul-terminator appended to it. Fix for #2213. (CVS 3627) (check-in: fc969ad991 user: danielk1977 tags: trunk)
2007-02-02
12:44
Minor tweaks to collating sequences. We'll hold of making major changes until 3.4.0, since we'll likely end up with some minor technical imcompatibilities. (CVS 3626) (check-in: 9740aa95a3 user: drh tags: trunk)
12:33
Fix typos in the pragma documentation. Ticket #2210. (CVS 3625) (check-in: f0c66ad8e9 user: drh tags: trunk)
Changes
Side-by-Side Diff Ignore Whitespace Patch
Changes to src/build.c.
18
19
20
21
22
23
24
25

26
27
28
29
30
31
32
18
19
20
21
22
23
24

25
26
27
28
29
30
31
32







-
+







**     CREATE INDEX
**     DROP INDEX
**     creating ID lists
**     BEGIN TRANSACTION
**     COMMIT
**     ROLLBACK
**
** $Id: build.c,v 1.412 2006/12/16 16:25:15 drh Exp $
** $Id: build.c,v 1.413 2007/02/02 12:44:37 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

/*
** This routine is called when a new SQL statement is beginning to
** be parsed.  Initialize the pParse structure as needed.
1218
1219
1220
1221
1222
1223
1224




1225
1226
1227
1228
1229
1230
1231
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235







+
+
+
+







** request it. If the collation factory does not supply such a sequence,
** and the sequence is available in another text encoding, then that is
** returned instead.
**
** If no versions of the requested collations sequence are available, or
** another error occurs, NULL is returned and an error message written into
** pParse.
**
** This routine is a wrapper around sqlite3FindCollSeq().  This routine
** invokes the collation factory if the named collation cannot be found
** and generates an error message.
*/
CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char *zName, int nName){
  sqlite3 *db = pParse->db;
  u8 enc = ENC(db);
  u8 initbusy = db->init.busy;
  CollSeq *pColl;

2453
2454
2455
2456
2457
2458
2459
2460

2461
2462
2463
2464
2465
2466
2467
2468
2469






2470
2471
2472
2473
2474
2475
2476
2457
2458
2459
2460
2461
2462
2463

2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486







-
+









+
+
+
+
+
+







  ** load the column indices into the Index structure.  Report an error
  ** if any column is not found.
  */
  for(i=0, pListItem=pList->a; i<pList->nExpr; i++, pListItem++){
    const char *zColName = pListItem->zName;
    Column *pTabCol;
    int requestedSortOrder;
    char *zColl;                   /* Collation sequence */
    char *zColl;                   /* Collation sequence name */

    for(j=0, pTabCol=pTab->aCol; j<pTab->nCol; j++, pTabCol++){
      if( sqlite3StrICmp(zColName, pTabCol->zName)==0 ) break;
    }
    if( j>=pTab->nCol ){
      sqlite3ErrorMsg(pParse, "table %s has no column named %s",
        pTab->zName, zColName);
      goto exit_create_index;
    }
    /* TODO:  Add a test to make sure that the same column is not named
    ** more than once within the same index.  Only the first instance of
    ** the column will ever be used by the optimizer.  Note that using the
    ** same column more than once cannot be an error because that would 
    ** break backwards compatibility - it needs to be a warning.
    */
    pIndex->aiColumn[i] = j;
    if( pListItem->pExpr ){
      assert( pListItem->pExpr->pColl );
      zColl = zExtra;
      strcpy(zExtra, pListItem->pExpr->pColl->zName);
      zExtra += (strlen(zColl) + 1);
    }else{
Changes to src/callback.c.
9
10
11
12
13
14
15
16

17
18
19
20
21
22
23
9
10
11
12
13
14
15

16
17
18
19
20
21
22
23







-
+







**    May you share freely, never taking more than you give.
**
*************************************************************************
**
** This file contains functions used to access the internal hash tables
** of user defined functions and collation sequences.
**
** $Id: callback.c,v 1.15 2006/05/24 12:43:27 drh Exp $
** $Id: callback.c,v 1.16 2007/02/02 12:44:37 drh Exp $
*/

#include "sqliteInt.h"

/*
** Invoke the 'collation needed' callback to request a collation sequence
** in the database text encoding of name zName, length nName.
191
192
193
194
195
196
197





198
199
200
201
202
203
204
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209







+
+
+
+
+







/*
** Parameter zName points to a UTF-8 encoded string nName bytes long.
** Return the CollSeq* pointer for the collation sequence named zName
** for the encoding 'enc' from the database 'db'.
**
** If the entry specified is not found and 'create' is true, then create a
** new entry.  Otherwise return NULL.
**
** A separate function sqlite3LocateCollSeq() is a wrapper around
** this routine.  sqlite3LocateCollSeq() invokes the collation factory
** if necessary and generates an error message if the collating sequence
** cannot be found.
*/
CollSeq *sqlite3FindCollSeq(
  sqlite3 *db,
  u8 enc,
  const char *zName,
  int nName,
  int create
Changes to src/expr.c.
8
9
10
11
12
13
14
15

16
17
18
19
20
21
22
8
9
10
11
12
13
14

15
16
17
18
19
20
21
22







-
+







**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains routines used for analyzing expressions and
** for generating VDBE code that evaluates expressions in SQLite.
**
** $Id: expr.c,v 1.273 2007/02/01 23:02:45 drh Exp $
** $Id: expr.c,v 1.274 2007/02/02 12:44:37 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

/*
** Return the 'affinity' of the expression pExpr if any.
**
48
49
50
51
52
53
54



55
56
57
58
59
60
61
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64







+
+
+







#endif
  return pExpr->affinity;
}

/*
** Set the collating sequence for expression pExpr to be the collating
** sequence named by pToken.   Return a pointer to the revised expression.
** The collating sequence is marked as "explicit" using the EP_ExpCollate
** flag.  An explicit collating sequence will override implicit
** collating sequences.
*/
Expr *sqlite3ExprSetColl(Parse *pParse, Expr *pExpr, Token *pName){
  CollSeq *pColl;
  if( pExpr==0 ) return 0;
  pColl = sqlite3LocateCollSeq(pParse, (char*)pName->z, pName->n);
  if( pColl ){
    pExpr->pColl = pColl;
216
217
218
219
220
221
222
223
224












225
226
227
228
229
230
231
219
220
221
222
223
224
225


226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244







-
-
+
+
+
+
+
+
+
+
+
+
+
+







  pNew->op = op;
  pNew->pLeft = pLeft;
  pNew->pRight = pRight;
  pNew->iAgg = -1;
  if( pToken ){
    assert( pToken->dyn==0 );
    pNew->span = pNew->token = *pToken;
  }else if( pLeft && pRight ){
    sqlite3ExprSpan(pNew, &pLeft->span, &pRight->span);
  }else if( pLeft ){
    if( pRight ){
      sqlite3ExprSpan(pNew, &pLeft->span, &pRight->span);
      if( pRight->flags && EP_ExpCollate ){
        pNew->flags |= EP_ExpCollate;
        pNew->pColl = pRight->pColl;
      }
    }
    if( pLeft->flags && EP_ExpCollate ){
      pNew->flags |= EP_ExpCollate;
      pNew->pColl = pLeft->pColl;
    }
  }
  return pNew;
}

/*
** Works like sqlite3Expr() but frees its pLeft and pRight arguments
** if it fails due to a malloc problem.
Changes to src/parse.y.
10
11
12
13
14
15
16
17

18
19
20
21
22
23
24
10
11
12
13
14
15
16

17
18
19
20
21
22
23
24







-
+







**
*************************************************************************
** This file contains SQLite's grammar for SQL.  Process this file
** using the lemon parser generator to generate C code that runs
** the parser.  Lemon will also generate a header file containing
** numeric codes for all of the tokens.
**
** @(#) $Id: parse.y,v 1.214 2007/02/01 23:02:45 drh Exp $
** @(#) $Id: parse.y,v 1.215 2007/02/02 12:44:37 drh Exp $
*/

// All token codes are small integers with #defines that begin with "TK_"
%token_prefix TK_

// The type of the data attached to each token is Token.  This is also the
// default type for non-terminals.
200
201
202
203
204
205
206
207


208
209
210
211
212
213
214
200
201
202
203
204
205
206

207
208
209
210
211
212
213
214
215







-
+
+







%right NOT.
%left IS MATCH LIKE_KW BETWEEN IN ISNULL NOTNULL NE EQ.
%left GT LE LT GE.
%right ESCAPE.
%left BITAND BITOR LSHIFT RSHIFT.
%left PLUS MINUS.
%left STAR SLASH REM.
%left CONCAT COLLATE.
%left CONCAT.
%left COLLATE.
%right UMINUS UPLUS BITNOT.

// And "ids" is an identifer-or-string.
//
%type ids {Token}
ids(A) ::= ID|STRING(X).   {A = X;}

522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
523
524
525
526
527
528
529

530
531
532
533


534
535
536
537
538
539
540







-




-
-







sortlist(A) ::= sortitem(Y) sortorder(Z). {
  A = sqlite3ExprListAppend(0,Y,0);
  if( A && A->a ) A->a[0].sortOrder = Z;
}
sortitem(A) ::= expr(X).   {A = X;}

%type sortorder {int}
%type collate {Token}

sortorder(A) ::= ASC.           {A = SQLITE_SO_ASC;}
sortorder(A) ::= DESC.          {A = SQLITE_SO_DESC;}
sortorder(A) ::= .              {A = SQLITE_SO_ASC;}
collate(C) ::= .                {C.z = 0; C.n = 0;}
collate(C) ::= COLLATE id(X).   {C = X;}

%type groupby_opt {ExprList*}
%destructor groupby_opt {sqlite3ExprListDelete($$);}
groupby_opt(A) ::= .                      {A = 0;}
groupby_opt(A) ::= GROUP BY exprlist(X).  {A = X;}

%type having_opt {Expr*}
876
877
878
879
880
881
882




883
884
885
886
887
888
889
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891







+
+
+
+







    if( p ) p->pColl = sqlite3LocateCollSeq(pParse, (char*)C.z, C.n);
  }
  A = sqlite3ExprListAppend(0, p, &Y);
  if( A ) A->a[A->nExpr-1].sortOrder = Z;
}
idxitem(A) ::= nm(X).              {A = X;}

%type collate {Token}
collate(C) ::= .                {C.z = 0; C.n = 0;}
collate(C) ::= COLLATE id(X).   {C = X;}


///////////////////////////// The DROP INDEX command /////////////////////////
//
cmd ::= DROP INDEX ifexists(E) fullname(X).   {sqlite3DropIndex(pParse, X, E);}

///////////////////////////// The VACUUM command /////////////////////////////
//