/ Check-in [9740aa95]
Login
SQLite training in Houston TX on 2019-11-05 (details)
Part of the 2019 Tcl Conference

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 | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 9740aa95a3f848fc663c88263a911fbc76ada243
User & Date: drh 2007-02-02 12:44:37
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: fc969ad9 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: 9740aa95 user: drh tags: trunk
12:33
Fix typos in the pragma documentation. Ticket #2210. (CVS 3625) check-in: f0c66ad8 user: drh tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/build.c.

18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
....
1218
1219
1220
1221
1222
1223
1224




1225
1226
1227
1228
1229
1230
1231
....
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469






2470
2471
2472
2473
2474
2475
2476
**     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 $
*/
#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.
................................................................................
** 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.




*/
CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char *zName, int nName){
  sqlite3 *db = pParse->db;
  u8 enc = ENC(db);
  u8 initbusy = db->init.busy;
  CollSeq *pColl;

................................................................................
  ** 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 */

    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;
    }






    pIndex->aiColumn[i] = j;
    if( pListItem->pExpr ){
      assert( pListItem->pExpr->pColl );
      zColl = zExtra;
      strcpy(zExtra, pListItem->pExpr->pColl->zName);
      zExtra += (strlen(zColl) + 1);
    }else{







|







 







>
>
>
>







 







|









>
>
>
>
>
>







18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
....
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
....
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
**     CREATE INDEX
**     DROP INDEX
**     creating ID lists
**     BEGIN TRANSACTION
**     COMMIT
**     ROLLBACK
**
** $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.
................................................................................
** 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;

................................................................................
  ** 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 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
...
191
192
193
194
195
196
197





198
199
200
201
202
203
204
**    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 $
*/

#include "sqliteInt.h"

/*
** Invoke the 'collation needed' callback to request a collation sequence
** in the database text encoding of name zName, length nName.
................................................................................
/*
** 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.





*/
CollSeq *sqlite3FindCollSeq(
  sqlite3 *db,
  u8 enc,
  const char *zName,
  int nName,
  int create







|







 







>
>
>
>
>







9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
...
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
**    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.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.
................................................................................
/*
** 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
..
48
49
50
51
52
53
54



55
56
57
58
59
60
61
...
216
217
218
219
220
221
222
223

224









225
226
227
228
229
230
231
**    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 $
*/
#include "sqliteInt.h"
#include <ctype.h>

/*
** Return the 'affinity' of the expression pExpr if any.
**
................................................................................
#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.



*/
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;
................................................................................
  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);









  }
  return pNew;
}

/*
** Works like sqlite3Expr() but frees its pLeft and pRight arguments
** if it fails due to a malloc problem.







|







 







>
>
>







 







|
>
|
>
>
>
>
>
>
>
>
>







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
..
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
...
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
**    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.274 2007/02/02 12:44:37 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

/*
** Return the 'affinity' of the expression pExpr if any.
**
................................................................................
#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;
................................................................................
  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 ){
    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
...
200
201
202
203
204
205
206
207

208
209
210
211
212
213
214
...
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
...
876
877
878
879
880
881
882




883
884
885
886
887
888
889
**
*************************************************************************
** 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 $
*/

// 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.
................................................................................
%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.

%right UMINUS UPLUS BITNOT.

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

................................................................................
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*}
................................................................................
    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;}






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

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







|







 







|
>







 







<




<
<







 







>
>
>
>







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
...
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
...
523
524
525
526
527
528
529

530
531
532
533


534
535
536
537
538
539
540
...
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
**
*************************************************************************
** 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.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.
................................................................................
%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.
%left COLLATE.
%right UMINUS UPLUS BITNOT.

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

................................................................................
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}


sortorder(A) ::= ASC.           {A = SQLITE_SO_ASC;}
sortorder(A) ::= DESC.          {A = SQLITE_SO_DESC;}
sortorder(A) ::= .              {A = SQLITE_SO_ASC;}



%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*}
................................................................................
    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 /////////////////////////////
//