/ Check-in [ea061d2e]
Login

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

Overview
Comment:Rearrange code so that SSE can invoke the collation factory. (CVS 2482)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:ea061d2ed3b25908fcfcb88e35ba612e5832a217
User & Date: danielk1977 2005-05-25 10:45:10
Context
2005-05-26
12:37
Fix minor problems with the SSE hooks. (CVS 2483) check-in: 3516ca29 user: danielk1977 tags: trunk
2005-05-25
10:45
Rearrange code so that SSE can invoke the collation factory. (CVS 2482) check-in: ea061d2e user: danielk1977 tags: trunk
04:11
Split main.c into two files to make building without the parser easier. (CVS 2481) check-in: d50915fa user: danielk1977 tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/build.c.

    18     18   **     CREATE INDEX
    19     19   **     DROP INDEX
    20     20   **     creating ID lists
    21     21   **     BEGIN TRANSACTION
    22     22   **     COMMIT
    23     23   **     ROLLBACK
    24     24   **
    25         -** $Id: build.c,v 1.322 2005/05/24 20:19:58 drh Exp $
           25  +** $Id: build.c,v 1.323 2005/05/25 10:45:10 danielk1977 Exp $
    26     26   */
    27     27   #include "sqliteInt.h"
    28     28   #include <ctype.h>
    29     29   
    30     30   /*
    31     31   ** This routine is called when a new SQL statement is beginning to
    32     32   ** be parsed.  Initialize the pParse structure as needed.
................................................................................
  1073   1073     */
  1074   1074     for(pIdx = p->pIndex; pIdx; pIdx=pIdx->pNext){
  1075   1075       assert( pIdx->nColumn==1 );
  1076   1076       if( pIdx->aiColumn[0]==i ) pIdx->keyInfo.aColl[0] = pColl;
  1077   1077     }
  1078   1078   }
  1079   1079   
  1080         -/*
  1081         -** Invoke the 'collation needed' callback to request a collation sequence
  1082         -** in the database text encoding of name zName, length nName.
  1083         -** If the collation sequence
  1084         -*/
  1085         -static void callCollNeeded(sqlite3 *db, const char *zName, int nName){
  1086         -  assert( !db->xCollNeeded || !db->xCollNeeded16 );
  1087         -  if( nName<0 ) nName = strlen(zName);
  1088         -  if( db->xCollNeeded ){
  1089         -    char *zExternal = sqliteStrNDup(zName, nName);
  1090         -    if( !zExternal ) return;
  1091         -    db->xCollNeeded(db->pCollNeededArg, db, (int)db->enc, zExternal);
  1092         -    sqliteFree(zExternal);
  1093         -  }
  1094         -#ifndef SQLITE_OMIT_UTF16
  1095         -  if( db->xCollNeeded16 ){
  1096         -    char const *zExternal;
  1097         -    sqlite3_value *pTmp = sqlite3GetTransientValue(db);
  1098         -    sqlite3ValueSetStr(pTmp, -1, zName, SQLITE_UTF8, SQLITE_STATIC);
  1099         -    zExternal = sqlite3ValueText(pTmp, SQLITE_UTF16NATIVE);
  1100         -    if( !zExternal ) return;
  1101         -    db->xCollNeeded16(db->pCollNeededArg, db, (int)db->enc, zExternal);
  1102         -  }
  1103         -#endif
  1104         -}
  1105         -
  1106         -/*
  1107         -** This routine is called if the collation factory fails to deliver a
  1108         -** collation function in the best encoding but there may be other versions
  1109         -** of this collation function (for other text encodings) available. Use one
  1110         -** of these instead if they exist. Avoid a UTF-8 <-> UTF-16 conversion if
  1111         -** possible.
  1112         -*/
  1113         -static int synthCollSeq(Parse *pParse, CollSeq *pColl){
  1114         -  CollSeq *pColl2;
  1115         -  char *z = pColl->zName;
  1116         -  int n = strlen(z);
  1117         -  sqlite3 *db = pParse->db;
  1118         -  int i;
  1119         -  static const u8 aEnc[] = { SQLITE_UTF16BE, SQLITE_UTF16LE, SQLITE_UTF8 };
  1120         -  for(i=0; i<3; i++){
  1121         -    pColl2 = sqlite3FindCollSeq(db, aEnc[i], z, n, 0);
  1122         -    if( pColl2->xCmp!=0 ){
  1123         -      memcpy(pColl, pColl2, sizeof(CollSeq));
  1124         -      return SQLITE_OK;
  1125         -    }
  1126         -  }
  1127         -  if( pParse->nErr==0 ){
  1128         -    sqlite3ErrorMsg(pParse, "no such collation sequence: %.*s", n, z);
  1129         -  }
  1130         -  pParse->nErr++;
  1131         -  return SQLITE_ERROR;
  1132         -}
  1133         -
  1134         -/*
  1135         -** This routine is called on a collation sequence before it is used to
  1136         -** check that it is defined. An undefined collation sequence exists when
  1137         -** a database is loaded that contains references to collation sequences
  1138         -** that have not been defined by sqlite3_create_collation() etc.
  1139         -**
  1140         -** If required, this routine calls the 'collation needed' callback to
  1141         -** request a definition of the collating sequence. If this doesn't work, 
  1142         -** an equivalent collating sequence that uses a text encoding different
  1143         -** from the main database is substituted, if one is available.
  1144         -*/
  1145         -int sqlite3CheckCollSeq(Parse *pParse, CollSeq *pColl){
  1146         -  if( pColl && !pColl->xCmp ){
  1147         -    /* No collation sequence of this type for this encoding is registered.
  1148         -    ** Call the collation factory to see if it can supply us with one.
  1149         -    */
  1150         -    callCollNeeded(pParse->db, pColl->zName, strlen(pColl->zName));
  1151         -    if( !pColl->xCmp && synthCollSeq(pParse, pColl) ){
  1152         -      return SQLITE_ERROR;
  1153         -    }
  1154         -  }
  1155         -  return SQLITE_OK;
  1156         -}
  1157         -
  1158   1080   /*
  1159   1081   ** Call sqlite3CheckCollSeq() for all collating sequences in an index,
  1160   1082   ** in order to verify that all the necessary collating sequences are
  1161   1083   ** loaded.
  1162   1084   */
  1163   1085   int sqlite3CheckIndexCollSeq(Parse *pParse, Index *pIdx){
  1164   1086     if( pIdx ){
................................................................................
  1183   1105   ** returned instead.
  1184   1106   **
  1185   1107   ** If no versions of the requested collations sequence are available, or
  1186   1108   ** another error occurs, NULL is returned and an error message written into
  1187   1109   ** pParse.
  1188   1110   */
  1189   1111   CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char *zName, int nName){
  1190         -  u8 enc = pParse->db->enc;
  1191         -  u8 initbusy = pParse->db->init.busy;
  1192         -  CollSeq *pColl = sqlite3FindCollSeq(pParse->db, enc, zName, nName, initbusy);
  1193         -  if( nName<0 ) nName = strlen(zName);
         1112  +  sqlite3 *db = pParse->db;
         1113  +  u8 enc = db->enc;
         1114  +  u8 initbusy = db->init.busy;
         1115  +
         1116  +  CollSeq *pColl = sqlite3FindCollSeq(db, enc, zName, nName, initbusy);
  1194   1117     if( !initbusy && (!pColl || !pColl->xCmp) ){
  1195         -    /* No collation sequence of this type for this encoding is registered.
  1196         -    ** Call the collation factory to see if it can supply us with one.
  1197         -    */
  1198         -    callCollNeeded(pParse->db, zName, nName);
  1199         -    pColl = sqlite3FindCollSeq(pParse->db, enc, zName, nName, 0);
  1200         -    if( pColl && !pColl->xCmp ){
  1201         -      /* There may be a version of the collation sequence that requires
  1202         -      ** translation between encodings. Search for it with synthCollSeq().
  1203         -      */
  1204         -      if( synthCollSeq(pParse, pColl) ){
  1205         -        return 0;
         1118  +    pColl = sqlite3GetCollSeq(db, pColl, zName, nName);
         1119  +    if( !pColl ){
         1120  +      if( nName<0 ){
         1121  +        nName = strlen(zName);
  1206   1122         }
  1207         -    }
  1208         -  }
  1209         -
  1210         -  /* If nothing has been found, write the error message into pParse */
  1211         -  if( !initbusy && (!pColl || !pColl->xCmp) ){
  1212         -    if( pParse->nErr==0 ){
  1213   1123         sqlite3ErrorMsg(pParse, "no such collation sequence: %.*s", nName, zName);
         1124  +      pColl = 0;
  1214   1125       }
  1215         -    pColl = 0;
  1216   1126     }
         1127  +
  1217   1128     return pColl;
  1218   1129   }
  1219   1130   
  1220   1131   
  1221   1132   /*
  1222   1133   ** Generate code that will increment the schema cookie.
  1223   1134   **

Changes to src/callback.c.

     9      9   **    May you share freely, never taking more than you give.
    10     10   **
    11     11   *************************************************************************
    12     12   **
    13     13   ** This file contains functions used to access the internal hash tables
    14     14   ** of user defined functions and collation sequences.
    15     15   **
    16         -** $Id: callback.c,v 1.1 2005/05/24 12:01:02 danielk1977 Exp $
           16  +** $Id: callback.c,v 1.2 2005/05/25 10:45:10 danielk1977 Exp $
    17     17   */
    18     18   
    19     19   #include "sqliteInt.h"
           20  +
           21  +/*
           22  +** Invoke the 'collation needed' callback to request a collation sequence
           23  +** in the database text encoding of name zName, length nName.
           24  +** If the collation sequence
           25  +*/
           26  +static void callCollNeeded(sqlite3 *db, const char *zName, int nName){
           27  +  assert( !db->xCollNeeded || !db->xCollNeeded16 );
           28  +  if( nName<0 ) nName = strlen(zName);
           29  +  if( db->xCollNeeded ){
           30  +    char *zExternal = sqliteStrNDup(zName, nName);
           31  +    if( !zExternal ) return;
           32  +    db->xCollNeeded(db->pCollNeededArg, db, (int)db->enc, zExternal);
           33  +    sqliteFree(zExternal);
           34  +  }
           35  +#ifndef SQLITE_OMIT_UTF16
           36  +  if( db->xCollNeeded16 ){
           37  +    char const *zExternal;
           38  +    sqlite3_value *pTmp = sqlite3GetTransientValue(db);
           39  +    sqlite3ValueSetStr(pTmp, -1, zName, SQLITE_UTF8, SQLITE_STATIC);
           40  +    zExternal = sqlite3ValueText(pTmp, SQLITE_UTF16NATIVE);
           41  +    if( !zExternal ) return;
           42  +    db->xCollNeeded16(db->pCollNeededArg, db, (int)db->enc, zExternal);
           43  +  }
           44  +#endif
           45  +}
           46  +
           47  +/*
           48  +** This routine is called if the collation factory fails to deliver a
           49  +** collation function in the best encoding but there may be other versions
           50  +** of this collation function (for other text encodings) available. Use one
           51  +** of these instead if they exist. Avoid a UTF-8 <-> UTF-16 conversion if
           52  +** possible.
           53  +*/
           54  +static int synthCollSeq(sqlite3 *db, CollSeq *pColl){
           55  +  CollSeq *pColl2;
           56  +  char *z = pColl->zName;
           57  +  int n = strlen(z);
           58  +  int i;
           59  +  static const u8 aEnc[] = { SQLITE_UTF16BE, SQLITE_UTF16LE, SQLITE_UTF8 };
           60  +  for(i=0; i<3; i++){
           61  +    pColl2 = sqlite3FindCollSeq(db, aEnc[i], z, n, 0);
           62  +    if( pColl2->xCmp!=0 ){
           63  +      memcpy(pColl, pColl2, sizeof(CollSeq));
           64  +      return SQLITE_OK;
           65  +    }
           66  +  }
           67  +  return SQLITE_ERROR;
           68  +}
           69  +
           70  +/*
           71  +** This function is responsible for invoking the collation factory callback
           72  +** or substituting a collation sequence of a different encoding when the
           73  +** requested collation sequence is not available in the database native
           74  +** encoding.
           75  +** 
           76  +** If it is not NULL, then pColl must point to the database native encoding 
           77  +** collation sequence with name zName, length nName.
           78  +**
           79  +** The return value is either the collation sequence to be used in database
           80  +** db for collation type name zName, length nName, or NULL, if no collation
           81  +** sequence can be found.
           82  +*/
           83  +CollSeq *sqlite3GetCollSeq(
           84  +  sqlite3* db, 
           85  +  CollSeq *pColl, 
           86  +  const char *zName, 
           87  +  int nName
           88  +){
           89  +  CollSeq *p;
           90  +
           91  +  p = pColl;
           92  +  if( !p ){
           93  +    p = sqlite3FindCollSeq(db, db->enc, zName, nName, 0);
           94  +  }
           95  +  if( !p || !p->xCmp ){
           96  +    /* No collation sequence of this type for this encoding is registered.
           97  +    ** Call the collation factory to see if it can supply us with one.
           98  +    */
           99  +    callCollNeeded(db, zName, nName);
          100  +    p = sqlite3FindCollSeq(db, db->enc, zName, nName, 0);
          101  +  }
          102  +  if( p && !p->xCmp && synthCollSeq(db, p) ){
          103  +    p = 0;
          104  +  }
          105  +  assert( !p || p->xCmp );
          106  +  return p;
          107  +}
          108  +
          109  +/*
          110  +** This routine is called on a collation sequence before it is used to
          111  +** check that it is defined. An undefined collation sequence exists when
          112  +** a database is loaded that contains references to collation sequences
          113  +** that have not been defined by sqlite3_create_collation() etc.
          114  +**
          115  +** If required, this routine calls the 'collation needed' callback to
          116  +** request a definition of the collating sequence. If this doesn't work, 
          117  +** an equivalent collating sequence that uses a text encoding different
          118  +** from the main database is substituted, if one is available.
          119  +*/
          120  +int sqlite3CheckCollSeq(Parse *pParse, CollSeq *pColl){
          121  +  if( pColl ){
          122  +    const char *zName = pColl->zName;
          123  +    CollSeq *p = sqlite3GetCollSeq(pParse->db, pColl, zName, -1);
          124  +    if( !p ){
          125  +      if( pParse->nErr==0 ){
          126  +        sqlite3ErrorMsg(pParse, "no such collation sequence: %s", zName);
          127  +      }
          128  +      pParse->nErr++;
          129  +      return SQLITE_ERROR;
          130  +    }
          131  +  }
          132  +  return SQLITE_OK;
          133  +}
          134  +
          135  +
    20    136   
    21    137   /*
    22    138   ** Locate and return an entry from the db.aCollSeq hash table. If the entry
    23    139   ** specified by zName and nName is not found and parameter 'create' is
    24    140   ** true, then create a new entry. Otherwise return NULL.
    25    141   **
    26    142   ** Each pointer stored in the sqlite3.aCollSeq hash table contains an

Changes to src/sqliteInt.h.

     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   ** Internal interface definitions for SQLite.
    13     13   **
    14         -** @(#) $Id: sqliteInt.h,v 1.383 2005/05/24 20:19:59 drh Exp $
           14  +** @(#) $Id: sqliteInt.h,v 1.384 2005/05/25 10:45:10 danielk1977 Exp $
    15     15   */
    16     16   #ifndef _SQLITEINT_H_
    17     17   #define _SQLITEINT_H_
    18     18   
    19     19   /*
    20     20   ** These #defines should enable >2GB file support on Posix if the
    21     21   ** underlying operating system supports it.  If the OS lacks
................................................................................
  1557   1557   void sqlite3ExpirePreparedStatements(sqlite3*);
  1558   1558   void sqlite3CodeSubselect(Parse *, Expr *);
  1559   1559   int sqlite3SelectResolve(Parse *, Select *, NameContext *);
  1560   1560   void sqlite3ColumnDefault(Vdbe *, Table *, int);
  1561   1561   void sqlite3AlterFinishAddColumn(Parse *, Token *);
  1562   1562   void sqlite3AlterBeginAddColumn(Parse *, SrcList *);
  1563   1563   const char *sqlite3TestErrorName(int);
         1564  +CollSeq *sqlite3GetCollSeq(sqlite3*, CollSeq *, const char *, int);
  1564   1565   
  1565   1566   #ifdef SQLITE_SSE
  1566   1567   #include "sseInt.h"
  1567   1568   #endif
  1568   1569   
  1569   1570   #endif